Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 

README.md

@resourcexjs/core

Core primitives and types for ResourceX - the resource management protocol for AI Agents.

Note: For most use cases, use the main resourcexjs package. This package is for low-level operations.

Installation

npm install @resourcexjs/core
# or
bun add @resourcexjs/core

Core Concepts

ResourceX uses a layered architecture with six core primitives:

Primitive Description
RXD Resource Definition - content of resource.json
RXI Resource Identifier - structured identifier { registry?, path?, name, tag }
RXL Resource Locator - unified locator string (RXI string, directory path, or URL)
RXM Resource Manifest - metadata stored within the resource
RXA Resource Archive - tar.gz container for storage/transfer
RXR Resource - complete resource (RXI + RXM + RXA)

Locator Format

Docker-style format: [registry/][path/]name[:tag]

hello                           -> name=hello, tag=latest
hello:1.0.0                     -> name=hello, tag=1.0.0
prompts/hello:stable            -> path=prompts, name=hello, tag=stable
localhost:3098/hello:1.0.0      -> registry=localhost:3098, name=hello, tag=1.0.0
registry.example.com/org/hello  -> registry=registry.example.com, path=org, name=hello, tag=latest

API

parse(locator: string): RXI

Parse a locator string into an RXI object.

import { parse } from "@resourcexjs/core";

const rxi = parse("registry.example.com/prompts/hello:1.0.0");
// {
//   registry: "registry.example.com",
//   path: "prompts",
//   name: "hello",
//   tag: "1.0.0"
// }

const simple = parse("hello");
// { registry: undefined, path: undefined, name: "hello", tag: "latest" }

format(rxi: RXI): string

Format an RXI object back to a locator string.

import { format } from "@resourcexjs/core";

format({ name: "hello", tag: "latest" });
// "hello"

format({ name: "hello", tag: "1.0.0" });
// "hello:1.0.0"

format({ registry: "localhost:3098", name: "hello", tag: "1.0.0" });
// "localhost:3098/hello:1.0.0"

define(input: unknown): RXD

Parse and validate a resource definition (from resource.json).

import { define } from "@resourcexjs/core";

const rxd = define({
  name: "my-prompt",
  type: "text",
  tag: "1.0.0",
  description: "A helpful prompt",
  author: "Alice",
});
// {
//   name: "my-prompt",
//   type: "text",
//   tag: "1.0.0",
//   description: "A helpful prompt",
//   author: "Alice"
// }

Required fields: name, type

Optional fields: tag (defaults to "latest"), registry, path, description, author, license, keywords, repository

Note: version is accepted as an alias for tag for backward compatibility.

manifest(rxd: RXD): RXM

Create a manifest from a definition. Extracts core metadata fields.

import { define, manifest } from "@resourcexjs/core";

const rxd = define({
  name: "my-prompt",
  type: "text",
  tag: "1.0.0",
  description: "A helpful prompt", // not included in manifest
});

const rxm = manifest(rxd);
// { name: "my-prompt", type: "text", tag: "1.0.0" }

locate(rxm: RXM): RXI

Create an identifier from a manifest.

import { locate } from "@resourcexjs/core";

const rxi = locate({
  registry: "example.com",
  path: "prompts",
  name: "hello",
  type: "text",
  tag: "1.0.0",
});
// { registry: "example.com", path: "prompts", name: "hello", tag: "1.0.0" }

archive(files: Record<string, Buffer>): Promise<RXA>

Create an archive from files. Output is in tar.gz format.

import { archive } from "@resourcexjs/core";

// Single file
const rxa = await archive({
  content: Buffer.from("Hello, World!"),
});

// Multiple files
const rxa = await archive({
  "prompt.md": Buffer.from("# System Prompt\nYou are..."),
  "config.json": Buffer.from('{"temperature": 0.7}'),
});

// Nested directories
const rxa = await archive({
  "src/index.ts": Buffer.from("main code"),
  "src/utils/helper.ts": Buffer.from("helper code"),
});

// Access raw archive data
const buffer = await rxa.buffer(); // tar.gz Buffer
const stream = rxa.stream; // ReadableStream<Uint8Array>

extract(rxa: RXA): Promise<Record<string, Buffer>>

Extract files from an archive.

import { archive, extract } from "@resourcexjs/core";

const rxa = await archive({
  "hello.txt": Buffer.from("Hello!"),
  "world.txt": Buffer.from("World!"),
});

const files = await extract(rxa);
// {
//   "hello.txt": Buffer<...>,
//   "world.txt": Buffer<...>
// }

wrap(buffer: Buffer): RXA

Wrap an existing tar.gz buffer as an RXA. Useful for deserializing archives.

import { wrap, extract } from "@resourcexjs/core";

// From storage or network
const tarGzBuffer = await fetchFromStorage();

const rxa = wrap(tarGzBuffer);
const files = await extract(rxa);

resource(rxm: RXM, rxa: RXA): RXR

Create a complete resource from manifest and archive.

import { define, manifest, archive, resource } from "@resourcexjs/core";

const rxd = define({ name: "hello", type: "text", tag: "1.0.0" });
const rxm = manifest(rxd);
const rxa = await archive({ content: Buffer.from("Hello!") });
const rxr = resource(rxm, rxa);
// {
//   identifier: { name: "hello", tag: "1.0.0" },
//   manifest: { name: "hello", type: "text", tag: "1.0.0" },
//   archive: RXA
// }

Types

RXD - Resource Definition

The content of resource.json file. Contains all metadata for a resource in development.

interface RXD {
  readonly name: string; // Required
  readonly type: string; // Required
  readonly tag?: string; // Optional (defaults to "latest")
  readonly registry?: string;
  readonly path?: string;
  readonly description?: string;
  readonly author?: string;
  readonly license?: string;
  readonly keywords?: string[];
  readonly repository?: string;
  readonly [key: string]: unknown; // Additional fields allowed
}

RXI - Resource Identifier

Structured identifier for a resource.

interface RXI {
  readonly registry?: string; // e.g., "localhost:3098", "registry.example.com"
  readonly path?: string; // e.g., "org", "prompts"
  readonly name: string; // Resource name
  readonly tag: string; // Tag (defaults to "latest")
}

RXL - Resource Locator

Unified locator string. Can be an RXI string, directory path, or URL.

type RXL = string;

RXM - Resource Manifest

Resource metadata stored within the resource.

interface RXM {
  readonly registry?: string;
  readonly path?: string;
  readonly name: string;
  readonly type: string;
  readonly tag: string;
  readonly files?: string[]; // Package file structure
}

RXA - Resource Archive

Archive container (tar.gz format) for storage and transfer.

interface RXA {
  readonly stream: ReadableStream<Uint8Array>;
  buffer(): Promise<Buffer>;
}

RXR - Resource

Complete resource object combining identifier, manifest, and archive.

interface RXR {
  readonly identifier: RXI;
  readonly manifest: RXM;
  readonly archive: RXA;
}

Error Handling

import {
  ResourceXError,
  LocatorError,
  ManifestError,
  ContentError,
  DefinitionError,
} from "@resourcexjs/core";

try {
  parse("invalid@locator");
} catch (error) {
  if (error instanceof LocatorError) {
    console.error("Invalid locator format:", error.message);
    console.error("Locator:", error.locator);
  }
}

try {
  define({ name: "test" }); // Missing required 'type' field
} catch (error) {
  if (error instanceof DefinitionError) {
    console.error("Invalid definition:", error.message);
  }
}

Error Hierarchy

ResourceXError (base)
├── LocatorError     - RXI parsing errors
├── ManifestError    - RXM validation errors
├── ContentError     - RXA operations errors
└── DefinitionError  - RXD validation errors

Complete Example

import { define, manifest, archive, resource, extract, format, parse } from "@resourcexjs/core";
import type { RXR } from "@resourcexjs/core";

// 1. Define resource metadata
const rxd = define({
  name: "assistant-prompt",
  type: "text",
  tag: "1.0.0",
  description: "A helpful AI assistant prompt",
  author: "Example Team",
});

// 2. Create manifest from definition
const rxm = manifest(rxd);

// 3. Create archive from files
const rxa = await archive({
  content: Buffer.from("You are a helpful AI assistant."),
});

// 4. Combine into complete resource
const rxr: RXR = resource(rxm, rxa);

// 5. Access locator string
const locatorStr = format(rxr.identifier);
console.log(locatorStr); // "assistant-prompt:1.0.0"

// 6. Extract files when needed
const files = await extract(rxr.archive);
console.log(files.content.toString()); // "You are a helpful AI assistant."

Registry Layer

CASRegistry

Content-addressable storage registry for managing resources.

import { CASRegistry, MemoryRXAStore, MemoryRXMStore } from "@resourcexjs/core";

// Create with memory stores (for testing)
const cas = new CASRegistry(new MemoryRXAStore(), new MemoryRXMStore());

// Store a resource
await cas.put(rxr);

// Get a resource
const rxr = await cas.get(rxi);

// Check existence
const exists = await cas.has(rxi);

// Remove a resource
await cas.remove(rxi);

// List resources
const results = await cas.list({ query: "prompt", limit: 10 });

// Garbage collect orphaned blobs
await cas.gc();

// Clear cache by registry
await cas.clearCache("registry.example.com");

Store Interfaces (SPI)

For implementing custom storage backends:

import type { RXAStore, RXMStore, StoredRXM } from "@resourcexjs/core";

// Blob storage interface
interface RXAStore {
  get(digest: string): Promise<Buffer>;
  put(data: Buffer): Promise<string>; // Returns digest
  has(digest: string): Promise<boolean>;
  delete(digest: string): Promise<void>;
  list(): Promise<string[]>;
}

// Manifest storage interface
interface RXMStore {
  get(name: string, tag: string, registry?: string): Promise<StoredRXM | null>;
  put(manifest: StoredRXM): Promise<void>;
  has(name: string, tag: string, registry?: string): Promise<boolean>;
  delete(name: string, tag: string, registry?: string): Promise<void>;
  listTags(name: string, registry?: string): Promise<string[]>;
  search(options?: RXMSearchOptions): Promise<StoredRXM[]>;
  deleteByRegistry(registry: string): Promise<void>;
}

Provider Interface (SPI)

For implementing platform-specific providers:

import type { ResourceXProvider, ProviderConfig, ProviderStores } from "@resourcexjs/core";

interface ResourceXProvider {
  readonly platform: string;
  createStores(config: ProviderConfig): ProviderStores;
  createLoader?(config: ProviderConfig): ResourceLoader;
}

interface ProviderStores {
  rxaStore: RXAStore;
  rxmStore: RXMStore;
}

Related Packages

Package Description
resourcexjs Main client package
@resourcexjs/node-provider Node.js/Bun platform provider
@resourcexjs/server Registry server
@resourcexjs/arp Low-level I/O protocol

License

Apache-2.0