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/type

v1.1.0

Published

ResourceX Type System - Type handlers and serialization

Readme

@resourcexjs/type

Type system for ResourceX with global singleton TypeHandlerChain.

Installation

bun add @resourcexjs/type

Overview

The @resourcexjs/type package provides the type system for ResourceX, managing how different resource types are serialized, deserialized, and resolved.

Key Concepts

  • ResourceType: Defines how a resource type is handled (serialization, deserialization, resolution)
  • TypeHandlerChain: Global singleton managing all registered types
  • Builtin Types: Text, JSON, and Binary types are automatically registered

Usage

Using Builtin Types

Builtin types are automatically available:

import { globalTypeHandlerChain } from "@resourcexjs/type";

// Check if type is supported
globalTypeHandlerChain.canHandle("text"); // true
globalTypeHandlerChain.canHandle("json"); // true
globalTypeHandlerChain.canHandle("binary"); // true

// Builtin aliases
globalTypeHandlerChain.canHandle("txt"); // true (alias for text)
globalTypeHandlerChain.canHandle("config"); // true (alias for json)

Registering Custom Types

import { globalTypeHandlerChain } from "@resourcexjs/type";
import type { ResourceType } from "@resourcexjs/type";

// Define custom type
const promptType: ResourceType<string> = {
  name: "prompt",
  aliases: ["deepractice-prompt"],
  description: "AI Prompt template",
  serializer: {
    async serialize(rxr) {
      const text = await rxr.content.text();
      return Buffer.from(text, "utf-8");
    },
    async deserialize(data, manifest) {
      // ... implementation
    },
  },
  resolver: {
    async resolve(rxr) {
      return rxr.content.text();
    },
  },
};

// Register globally
globalTypeHandlerChain.register(promptType);

Query Supported Types

import { globalTypeHandlerChain } from "@resourcexjs/type";

// Get all supported types (including aliases)
const types = globalTypeHandlerChain.getSupportedTypes();
// ["text", "txt", "plaintext", "json", "config", "manifest", "binary", "bin", "blob", "raw"]

// Get handler for specific type
const handler = globalTypeHandlerChain.getHandler("text");
console.log(handler?.name); // "text"

Serialize/Deserialize

import { globalTypeHandlerChain } from "@resourcexjs/type";
import { createRXM, createRXC, parseRXL } from "@resourcexjs/core";

// Serialize RXR to Buffer
const manifest = createRXM({
  domain: "localhost",
  name: "test",
  type: "text",
  version: "1.0.0",
});

const rxr = {
  locator: parseRXL(manifest.toLocator()),
  manifest,
  content: createRXC("Hello, World!"),
};

const buffer = await globalTypeHandlerChain.serialize(rxr);
// Buffer containing "Hello, World!"

// Deserialize Buffer to RXR
const restored = await globalTypeHandlerChain.deserialize(buffer, manifest);
console.log(await restored.content.text()); // "Hello, World!"

Resolve Content

import { globalTypeHandlerChain } from "@resourcexjs/type";

// Resolve RXR to usable object
const text = await globalTypeHandlerChain.resolve<string>(rxr);
console.log(text); // "Hello, World!"

API Reference

globalTypeHandlerChain

Global singleton instance of TypeHandlerChain.

Methods

register(type: ResourceType): void

Register an extension type.

Throws: ResourceTypeError if type name or alias already exists.

globalTypeHandlerChain.register(customType);
canHandle(typeName: string): boolean

Check if a type is supported.

globalTypeHandlerChain.canHandle("text"); // true
getHandler(typeName: string): ResourceType | undefined

Get handler for a type.

const handler = globalTypeHandlerChain.getHandler("text");
getSupportedTypes(): string[]

Get all supported type names (including aliases).

const types = globalTypeHandlerChain.getSupportedTypes();
serialize(rxr: RXR): Promise<Buffer>

Serialize RXR to Buffer using appropriate type handler.

Throws: ResourceTypeError if type not supported.

deserialize(data: Buffer, manifest: RXM): Promise<RXR>

Deserialize Buffer to RXR using appropriate type handler.

Throws: ResourceTypeError if type not supported.

resolve<T>(rxr: RXR): Promise<T>

Resolve RXR content to usable object using appropriate type handler.

Throws: ResourceTypeError if type not supported.

clearExtensions(): void

Clear all extension types (for testing). Builtin types remain.

globalTypeHandlerChain.clearExtensions();

Builtin Types

Text Type

  • Name: text
  • Aliases: txt, plaintext
  • Storage: UTF-8 encoded string
  • Resolves to: string

JSON Type

  • Name: json
  • Aliases: config, manifest
  • Storage: Formatted JSON string
  • Resolves to: unknown (parsed object)

Binary Type

  • Name: binary
  • Aliases: bin, blob, raw
  • Storage: Raw bytes
  • Resolves to: Buffer

Type System Architecture

┌─────────────────────────────────────────┐
│   globalTypeHandlerChain (Singleton)    │
│                                         │
│   Builtin: text, json, binary          │
│   Extensions: custom types...           │
└─────────────────────────────────────────┘
              ↑
              │
         All packages use
         global singleton

Creating Custom Types

Example: Prompt Type

import type { ResourceType } from "@resourcexjs/type";
import { createRXC, parseRXL } from "@resourcexjs/core";

export const promptType: ResourceType<string> = {
  name: "prompt",
  aliases: ["deepractice-prompt"],
  description: "AI Prompt template with variable substitution",

  serializer: {
    async serialize(rxr) {
      const text = await rxr.content.text();
      return Buffer.from(text, "utf-8");
    },

    async deserialize(data, manifest) {
      const text = data.toString("utf-8");
      return {
        locator: parseRXL(manifest.toLocator()),
        manifest,
        content: createRXC(text),
      };
    },
  },

  resolver: {
    async resolve(rxr) {
      // Custom resolution logic
      const template = await rxr.content.text();
      return template;
    },
  },
};

Error Handling

import { ResourceTypeError } from "@resourcexjs/type";

try {
  await globalTypeHandlerChain.serialize(rxr);
} catch (error) {
  if (error instanceof ResourceTypeError) {
    console.error("Type error:", error.message);
  }
}

Testing

When testing, use clearExtensions() to reset extension types:

import { afterEach } from "bun:test";
import { globalTypeHandlerChain } from "@resourcexjs/type";

afterEach(() => {
  globalTypeHandlerChain.clearExtensions();
});

License

MIT