json-joy
Version:
Collection of libraries for building collaborative editing apps.
384 lines (383 loc) • 11.8 kB
TypeScript
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>;
};