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

rtds-core

v0.0.33

Published

RTDS is a Typescript library to create types and data structures at runtime. In a sense it is similar to other libraries like Zod, but it has a few interesting twists. RTDS also creates reactive data structures from these types, and lets you do interestin

Readme

RTDS: Run Time Data Structure

RTDS is a Typescript library to create types and data structures at runtime. In a sense it is similar to other libraries like Zod, but it has a few interesting twists. RTDS also creates reactive data structures from these types, and lets you do interesting things with them.

Features

  • create complex nested types
  • add constraints that are not possible in Typescript's type system
  • serialize the entire structure to JSON
  • validate JSON structures against the type
  • History support (undo/redo)
  • Sync state with the browser URL
  • Auto save and query to IndexedDB
  • Work with special React components to simplify view updates

Examples

Rectangle

const S = new Schema();

// Create Rect runtime type
const Rect = S.map({
  x: S.number(),
  y: S.number(),
  w: S.number(),
  h: S.number(),
});

// get the typescript type for it
type RectType = typeof Rect;

// make a rect instance
const rect = Rect.clone();

// set value
rect.get("x").set(55);

set initial values when creating an object

const S = new Schema();
// Create Rect runtime type
const Rect = S.map({
  x: S.number(),
  y: S.number(),
  w: S.number(100), // default value for width
  h: S.number(200), // default value for height
});

const rect = Rect.cloneWith({
  x: 5,
  y: 6,
  // w & h are missing, so they get the default value of 100
});

a list of objects

const S = new Schema();
// list of numbers
const Nums = S.list(S.number());
// list of strings
const Strings = S.list(S.string());
// list of booleans
const Bools = S.list(S.boolean());

// list of Points
const Point = S.map({
  x: S.number(),
  y: S.number(),
});
const Points = S.list(Point);

validate against JSON

const S = new Schema();
const Point = S.map({
  x: S.number(),
  y: S.number(),
});

expect(Point.isValid({ x: 5, y: 3 })).toBe(true);
expect(Point.isValid({ x: 5, z: 8 })).toBe(false); // z is not a valid property of Point

export to & from simple JSON

import { ObjJSON } from "./json";

const S = new Schema();
const Point = S.map({
  x: S.number(),
  y: S.number(),
});
const some_point = Point.cloneWith({ x: 50, y: 100 });
const simple_json = ObjJSON.toFlatJSON(some_point);
// simple_json looks like { x: 50, y: 100 }
const another_point = ObjJSON.fromFlatJSON(simple_json);

serialize to & from complex JSON

import { ObjJSON } from "./json";

const S = new Schema();
const Point = S.map({
  x: S.number(),
  y: S.number(),
});
const some_point = Point.cloneWith({ x: 50, y: 100 });
const json_point = ObjJSON.toJSON3(S, some_point);
/* json_point looks like
{
  id: 'id_88044',
  typeName: 'APoint',
  objType: 'map',
  values: {
    x: {
      id: 'id_75900',
      typeName: undefined,
      objType: 'atom',
      atomType: 'number',
      value: 55
    },
    y: {
      id: 'id_84910',
      typeName: undefined,
      objType: 'atom',
      atomType: 'number',
      value: 66
    }
  }
}
 */
const another_point = ObjJSON.fromJSON3(S, json_point);

set URL search params from obj

const rect = Rect.cloneWith({ x: 50, y: 60, w: 70, h: 80 });
const url = objToURLSearchParams(rect);
expect(url.get("w")).toBe("70");

use history

const S = new Schema();
const Point = S.map({
  x: S.number(),
  y: S.number(),
});
// make a list of three points
const points = S.list(Point, [Point.clone(), Point.clone(), Point.clone()]);
points.get(0).get("x").set(55);
// make a doc containing the list of points
const doc = API.map({
  name: API.string("the name"),
  points: points,
});

// create history
const history = new AHistory(doc);
// set first point x to 66
doc.get("points").get(0).get("x").set(66);
expect(doc.get("points").get(0).get("x").get()).toEqual(66);
history.doUndo();
expect(doc.get("points").get(0).get("x").get()).toEqual(55);
history.doRedo();
expect(doc.get("points").get(0).get("x").get()).toEqual(66);

Other Runtime Type libraries

  • [ ] https://marcjschmidt.de/runtime-types
  • [ ] https://github.com/samchon/typia
  • [ ] https://github.com/colinhacks/zod
  • [ ] https://typescript-rtti.org

handling transient values

When exporting json you can set an object type to be transient, meaning it will not be serialized. The challenge, then is how to un-serialize it?