0.0.33 • Published 4 months ago

rtds-core v0.0.33

Weekly downloads
-
License
ISC
Repository
-
Last release
4 months ago

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

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?

0.0.20

5 months ago

0.0.21

5 months ago

0.0.22

5 months ago

0.0.23

5 months ago

0.0.24

5 months ago

0.0.25

5 months ago

0.0.30

4 months ago

0.0.31

4 months ago

0.0.32

4 months ago

0.0.33

4 months ago

0.0.26

4 months ago

0.0.27

4 months ago

0.0.28

4 months ago

0.0.29

4 months ago

0.0.19

11 months ago

0.0.18

11 months ago

0.0.17

11 months ago

0.0.16

11 months ago

0.0.15

11 months ago

0.0.14

11 months ago

0.0.13

11 months ago

0.0.12

11 months ago

0.0.11

11 months ago

0.0.10

11 months ago

0.0.9

11 months ago

0.0.8

11 months ago

0.0.7

11 months ago

0.0.6

11 months ago

0.0.5

11 months ago

0.0.4

11 months ago

0.0.2

11 months ago

0.0.1

11 months ago