@resourcexjs/core
v2.22.0
Published
ResourceX Core - Resource management layer
Readme
@resourcexjs/core
Core primitives and types for ResourceX - the resource management protocol for AI Agents.
Note: For most use cases, use the main
resourcexjspackage. This package is for low-level operations.
Installation
npm install @resourcexjs/core
# or
bun add @resourcexjs/coreCore 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=latestAPI
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:
versionis accepted as an alias fortagfor 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 errorsComplete 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
