npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@resourcexjs/server

v2.10.0

Published

ResourceX Registry Server - Protocol, Handlers, and Hono Server

Readme

@resourcexjs/server

ResourceX Registry Server - HTTP API server for hosting and serving ResourceX resources.

Installation

bun add @resourcexjs/server @resourcexjs/node-provider
# or
npm install @resourcexjs/server @resourcexjs/node-provider

Overview

This package provides three levels of abstraction for building a ResourceX registry server:

  1. Hono Server - Ready-to-use server with all endpoints configured
  2. Handlers - Framework-agnostic request handlers for custom integrations
  3. Protocol - Type definitions and constants for building clients

Quick Start

import { createRegistryServer } from "@resourcexjs/server";
import { FileSystemRXAStore, FileSystemRXMStore } from "@resourcexjs/node-provider";

const server = createRegistryServer({
  rxaStore: new FileSystemRXAStore("./data/blobs"),
  rxmStore: new FileSystemRXMStore("./data/manifests"),
});

// Bun
Bun.serve({ fetch: server.fetch, port: 3000 });

// Node.js (with @hono/node-server)
import { serve } from "@hono/node-server";
serve({ fetch: server.fetch, port: 3000 });

API

createRegistryServer(config)

Creates a Hono app with all registry endpoints configured.

import { createRegistryServer } from "@resourcexjs/server";
import { FileSystemRXAStore, FileSystemRXMStore } from "@resourcexjs/node-provider";

const server = createRegistryServer({
  rxaStore: new FileSystemRXAStore("./data/blobs"),
  rxmStore: new FileSystemRXMStore("./data/manifests"),
  basePath: "", // Optional: API route prefix (default: "")
  cors: true, // Optional: Enable CORS (default: true)
});

Config Interface

interface RegistryServerConfig {
  rxaStore: RXAStore; // Content-addressable blob storage
  rxmStore: RXMStore; // Manifest storage
  basePath?: string; // API route prefix (default: "")
  cors?: boolean; // Enable CORS (default: true)
}

Handlers

Framework-agnostic handlers for custom server integrations (Next.js, Express, etc.).

import {
  handlePublish,
  handleGetResource,
  handleHeadResource,
  handleDeleteResource,
  handleGetContent,
  handleSearch,
  CASRegistry,
} from "@resourcexjs/server";
import { FileSystemRXAStore, FileSystemRXMStore } from "@resourcexjs/node-provider";

const registry = new CASRegistry(
  new FileSystemRXAStore("./data/blobs"),
  new FileSystemRXMStore("./data/manifests")
);

// Next.js Route Handler example
export async function POST(request: Request) {
  return handlePublish(request, registry);
}

Handler Functions

| Handler | Description | | ---------------------------------------------- | -------------------------------------- | | handlePublish(request, registry) | Process multipart form publish request | | handleGetResource(locator, registry) | Get resource manifest | | handleHeadResource(locator, registry) | Check resource existence | | handleDeleteResource(locator, registry) | Delete a resource | | handleGetContent(locator, registry) | Download resource archive | | handleSearch(query, limit, offset, registry) | Search resources |

API Endpoints

All endpoints are prefixed with /api/v1.

GET /api/v1/health

Health check endpoint.

Response:

{ "status": "ok" }

POST /api/v1/publish

Publish a resource to the registry.

Content-Type: multipart/form-data

Fields:

  • locator (string) - Resource locator (e.g., hello:1.0.0)
  • manifest (file) - JSON manifest file
  • content (file) - Archive file (tar.gz)

Response (201):

{ "locator": "hello:1.0.0" }

GET /api/v1/resource/:locator

Get resource manifest.

Response (200):

{
  "name": "hello",
  "type": "text",
  "tag": "1.0.0",
  "path": "prompts"
}

HEAD /api/v1/resource/:locator

Check if resource exists.

Response: 200 if exists, 404 if not.

DELETE /api/v1/resource/:locator

Delete a resource.

Response: 204 on success.

GET /api/v1/content/:locator

Download resource archive.

Response: Binary application/gzip content.

GET /api/v1/search

Search for resources.

Query Parameters:

  • q (string, optional) - Search query
  • limit (number, default: 100) - Max results
  • offset (number, default: 0) - Pagination offset

Response (200):

{
  "results": [
    {
      "locator": "hello:1.0.0",
      "name": "hello",
      "type": "text",
      "tag": "1.0.0"
    }
  ],
  "total": 1
}

Protocol

Type definitions and constants for building clients.

import {
  API_VERSION, // "v1"
  API_PREFIX, // "/api/v1"
  ENDPOINTS, // { publish, resource, content, search, health }
  CONTENT_TYPES, // { json, binary, formData }
  ERROR_CODES, // Error code constants
  buildResourceUrl, // Build resource URL
  buildContentUrl, // Build content URL
  buildPublishUrl, // Build publish URL
  buildSearchUrl, // Build search URL with params
} from "@resourcexjs/server";

// Types
import type {
  ManifestData,
  SearchQuery,
  PublishResponse,
  GetResourceResponse,
  SearchResultItem,
  SearchResponse,
  ErrorResponse,
  ErrorCode,
} from "@resourcexjs/server";

URL Builders

import { buildResourceUrl, buildSearchUrl } from "@resourcexjs/server";

const url = buildResourceUrl("https://registry.example.com", "hello:1.0.0");
// "https://registry.example.com/api/v1/resource/hello%3A1.0.0"

const searchUrl = buildSearchUrl("https://registry.example.com", {
  q: "prompt",
  limit: 10,
});
// "https://registry.example.com/api/v1/search?q=prompt&limit=10"

Error Handling

All error responses follow a consistent format:

{
  "error": "Error message",
  "code": "ERROR_CODE"
}

Error Codes

| Code | Status | Description | | -------------------- | ------ | ----------------------- | | LOCATOR_REQUIRED | 400 | Missing locator field | | MANIFEST_REQUIRED | 400 | Missing manifest file | | CONTENT_REQUIRED | 400 | Missing content file | | INVALID_MANIFEST | 400 | Invalid manifest format | | INVALID_LOCATOR | 400 | Invalid locator format | | RESOURCE_NOT_FOUND | 404 | Resource does not exist | | INTERNAL_ERROR | 500 | Internal server error |

Re-exports

For convenience, this package re-exports commonly used classes:

import { CASRegistry, FileSystemRXAStore, FileSystemRXMStore } from "@resourcexjs/server";

import type { RXAStore, RXMStore, Registry } from "@resourcexjs/server";

Storage Architecture

The server uses content-addressable storage (CAS) for efficient deduplication:

./data/
├── blobs/                        # Content-addressable blob storage
│   └── ab/
│       └── sha256:abcd1234...    # Archive data (tar.gz)
└── manifests/
    └── _local/                   # Resources stored on this server
        └── my-prompt/
            └── 1.0.0.json        # Manifest with digest reference

Note: The server stores resources without registry prefix. When a resource is published to registry.example.com/hello:1.0.0, it's stored as hello:1.0.0 on the server. The registry prefix is added by clients when they pull resources.

Related Packages

| Package | Description | | ---------------------------- | ------------------------------- | | resourcexjs | Client SDK | | @resourcexjs/core | Core primitives and CASRegistry | | @resourcexjs/node-provider | Node.js/Bun storage providers |

License

Apache-2.0