UNPKG

json-joy

Version:

Collection of libraries for building collaborative editing apps.

384 lines (383 loc) 11.8 kB
import { NodeBuilder } from './DelayedValueBuilder'; import type { ITimestampStruct } from '../clock'; /** * This namespace contains all the node builders. Each node builder is a * schema for a specific node type. Each node builder has a `build` method * that takes a {@link NodeBuilder} and returns the ID of the node. */ export declare namespace nodes { /** * The `con` class represents a "con" JSON CRDT node. As the generic type * parameter, it takes the type of the raw value. * * Example: * * ```ts * s.con(0); * s.con(''); * s.con<number>(123); * s.con<0 | 1>(0); * ``` */ class con<T extends unknown | ITimestampStruct> extends NodeBuilder { readonly raw: T; readonly type = "con"; constructor(raw: T); } /** * The `str` class represents a "str" JSON CRDT node. As the generic type * parameter, it takes the type of the raw value. * * Example: * * ```ts * s.str(''); * s.str('hello'); * s.str<string>('world'); * s.str<'' | 'hello' | 'world'>('hello'); * ``` */ class str<T extends string = string> extends NodeBuilder { readonly raw: T; readonly type = "str"; constructor(raw: T); } /** * The `bin` class represents a "bin" JSON CRDT node. */ class bin extends NodeBuilder { readonly raw: Uint8Array; readonly type = "bin"; constructor(raw: Uint8Array); } /** * The `val` class represents a "val" JSON CRDT node. As the generic type * parameter, it takes the type of the inner node builder. * * Example: * * ```ts * s.val(s.con(0)); * s.val(s.str('')); * s.val(s.str('hello')); * ``` */ class val<T extends NodeBuilder> extends NodeBuilder { readonly value: T; readonly type = "val"; constructor(value: T); } /** * The `vec` class represents a "vec" JSON CRDT node. As the generic type * parameter, it takes a tuple of node builders. * * Example: * * ```ts * s.vec(s.con(0), s.con(1)); * s.vec(s.str(''), s.str('hello')); * ``` */ class vec<T extends NodeBuilder[]> extends NodeBuilder { readonly value: T; readonly type = "vec"; constructor(value: T); } /** * The `obj` class represents a "obj" JSON CRDT node. As the generic type * parameter, it takes a record of node builders. The optional generic type * parameter is a record of optional keys. * * Example: * * ```ts * s.obj({ * name: s.str(''), * age: s.con(0), * }); * ``` * * Specify optional keys as the second argument: * * ```ts * s.obj( * { * href: s.str('https://example.com'), * }, * { * title: s.str(''), * }, * ) * ``` * * Or, specify only the type, using the `optional` method: * * ```ts * s.obj({ * href: s.str('https://example.com'), * }) * .optional<nodes.obj({ * title: nodes.str, * })>() * ``` */ class obj<T extends Record<string, NodeBuilder>, O extends Record<string, NodeBuilder> = {}> extends NodeBuilder { readonly obj: T; readonly opt?: O | undefined; readonly type = "obj"; constructor(obj: T, opt?: O | undefined); optional<OO extends Record<string, NodeBuilder>>(): obj<T, O & OO>; } /** * A type alias for {@link obj}. It creates a "map" node schema, which is an * object where a key can be any string and the value is of the same type. * * Example: * * ```ts * s.map<nodes.con<number>> * ``` */ type map<R extends NodeBuilder> = obj<Record<string, R>, Record<string, R>>; /** * The `arr` class represents a "arr" JSON CRDT node. As the generic type * parameter, it an array of node builders. * * Example: * * ```ts * s.arr([s.con(0), s.con(1)]); * s.arr([s.str(''), s.str('hello')]); * ``` */ class arr<T extends NodeBuilder> extends NodeBuilder { readonly arr: T[]; readonly type = "arr"; constructor(arr: T[]); } /** * Convenience class for recursively creating a node tree from any POJO. It * uses the {@link Builder.json} method to create a JSON node. It can be used * similar to TypeScript's *any* type, where the value can be anything. * * Example: * * ```typescript * s.json({name: 'Alice', age: 30}); * ``` */ class json<T> extends NodeBuilder { readonly value: T; readonly type = "json"; constructor(value: T); } /** * Convenience class for recursively creating a node tree from any POJO. It * uses the {@link Builder.constOrJson} method to create a JSON node. It can * be used similar to TypeScript's *any* type, where the value can be anything. * * Example: * * ```typescript * s.jsonCon({name: 'Alice', age: 30}); * ``` */ class jsonCon<T> extends NodeBuilder { readonly value: T; readonly type = "jsonCon"; constructor(value: T); } /** * Creates an extension node schema. The extension node is a tuple with a * sentinel header and a data node. The sentinel header is a 3-byte * {@link Uint8Array}, which makes this "vec" node to be treated as an * extension "ext" node. * * The 3-byte header consists of the extension ID, the SID of the tuple ID, * and the time of the tuple ID: * * - 1 byte for the extension id * - 1 byte for the sid of the tuple id, modulo 256 * - 1 byte for the time of the tuple id, modulo 256 */ class ext<ID extends number, T extends NodeBuilder> extends NodeBuilder { readonly id: ID; readonly data: T; readonly type = "ext"; /** * @param id A unique extension ID. * @param data Schema of the data node of the extension. */ constructor(id: ID, data: T); } } /** * Schema builder. Use this to create a JSON CRDT model schema and the default * value. * * Example: * * ```typescript * const schema = s.obj({ * name: s.str(''), * age: s.con(0), * tags: s.arr<nodes.con<string>>([]), * }); * ``` */ export declare const schema: { /** * Creates a "con" node schema and the default value. * * @param raw Raw default value. */ con: <T extends unknown | ITimestampStruct>(raw: T) => nodes.con<T>; /** * Creates a "str" node schema and the default value. * * @param str Default value. */ str: <T extends string>(str: T) => nodes.str<T>; /** * Creates a "bin" node schema and the default value. * * @param bin Default value. */ bin: (bin: Uint8Array) => nodes.bin; /** * Creates a "val" node schema and the default value. * * @param val Default value. */ val: <T extends NodeBuilder>(val: T) => nodes.val<T>; /** * Creates a "vec" node schema and the default value. * * @param vec Default value. */ vec: <T extends NodeBuilder[]>(...vec: T) => nodes.vec<T>; /** * Creates a "obj" node schema and the default value. * * @param obj Default value, required object keys. * @param opt Default value of optional object keys. */ obj: <T extends Record<string, NodeBuilder>, O extends Record<string, NodeBuilder>>(obj: T, opt?: O) => nodes.obj<T, O>; /** * This is an alias for {@link schema.obj}. It creates a "map" node schema, * which is an object where a key can be any string and the value is of the * same type. * * @param obj Default value. */ map: <R extends NodeBuilder>(obj: Record<string, R>) => nodes.map<R>; /** * Creates an "arr" node schema and the default value. * * @param arr Default value. */ arr: <T extends NodeBuilder>(arr: T[]) => nodes.arr<T>; /** * Recursively creates a node tree from any POJO. It uses the * {@link Builder.json} method to create a JSON node. It can be used similar * to TypeScript's *any* type, where the value can be anything. * * @param value Default value. */ json: <T>(value: T) => nodes.json<T>; /** * Recursively creates a node tree from any POJO. It uses the * {@link Builder.constOrJson} method to create a JSON node. It can be used * similar to TypeScript's *any* type, where the value can be anything. * * @param value Default value. */ jsonCon: <T>(value: T) => nodes.jsonCon<T>; /** * Creates an extension node schema. * * @param id A unique extension ID. * @param data Schema of the data node of the extension. */ ext: <ID extends number, T extends NodeBuilder>(id: ID, data: T) => nodes.ext<ID, T>; }; /** * Schema builder. Use this to create a JSON CRDT model schema and the default * value. Alias for {@link schema}. */ export declare const s: { /** * Creates a "con" node schema and the default value. * * @param raw Raw default value. */ con: <T extends unknown | ITimestampStruct>(raw: T) => nodes.con<T>; /** * Creates a "str" node schema and the default value. * * @param str Default value. */ str: <T extends string>(str: T) => nodes.str<T>; /** * Creates a "bin" node schema and the default value. * * @param bin Default value. */ bin: (bin: Uint8Array) => nodes.bin; /** * Creates a "val" node schema and the default value. * * @param val Default value. */ val: <T extends NodeBuilder>(val: T) => nodes.val<T>; /** * Creates a "vec" node schema and the default value. * * @param vec Default value. */ vec: <T extends NodeBuilder[]>(...vec: T) => nodes.vec<T>; /** * Creates a "obj" node schema and the default value. * * @param obj Default value, required object keys. * @param opt Default value of optional object keys. */ obj: <T extends Record<string, NodeBuilder>, O extends Record<string, NodeBuilder>>(obj: T, opt?: O) => nodes.obj<T, O>; /** * This is an alias for {@link schema.obj}. It creates a "map" node schema, * which is an object where a key can be any string and the value is of the * same type. * * @param obj Default value. */ map: <R extends NodeBuilder>(obj: Record<string, R>) => nodes.map<R>; /** * Creates an "arr" node schema and the default value. * * @param arr Default value. */ arr: <T extends NodeBuilder>(arr: T[]) => nodes.arr<T>; /** * Recursively creates a node tree from any POJO. It uses the * {@link Builder.json} method to create a JSON node. It can be used similar * to TypeScript's *any* type, where the value can be anything. * * @param value Default value. */ json: <T>(value: T) => nodes.json<T>; /** * Recursively creates a node tree from any POJO. It uses the * {@link Builder.constOrJson} method to create a JSON node. It can be used * similar to TypeScript's *any* type, where the value can be anything. * * @param value Default value. */ jsonCon: <T>(value: T) => nodes.jsonCon<T>; /** * Creates an extension node schema. * * @param id A unique extension ID. * @param data Schema of the data node of the extension. */ ext: <ID extends number, T extends NodeBuilder>(id: ID, data: T) => nodes.ext<ID, T>; };