Skip to content

Commit

Permalink
feat(json-crdt-patch): 馃幐 add node.json schema builder class
Browse files Browse the repository at this point in the history
  • Loading branch information
streamich committed May 2, 2024
1 parent 69e1200 commit ed6a558
Showing 1 changed file with 44 additions and 8 deletions.
52 changes: 44 additions & 8 deletions src/json-crdt-patch/builder/schema.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type {ITimestampStruct} from '../clock';
import {NodeBuilder} from './DelayedValueBuilder';
import type {ITimestampStruct} from '../clock';

/* tslint:disable no-namespace class-name */

Expand All @@ -15,7 +15,7 @@ export namespace nodes {
*
* Example:
*
* ```typescript
* ```ts
* s.con(0);
* s.con('');
* s.con<number>(123);
Expand All @@ -36,7 +36,7 @@ export namespace nodes {
*
* Example:
*
* ```typescript
* ```ts
* s.str('');
* s.str('hello');
* s.str<string>('world');
Expand Down Expand Up @@ -68,7 +68,7 @@ export namespace nodes {
*
* Example:
*
* ```typescript
* ```ts
* s.val(s.con(0));
* s.val(s.str(''));
* s.val(s.str('hello'));
Expand All @@ -93,7 +93,7 @@ export namespace nodes {
*
* Example:
*
* ```typescript
* ```ts
* s.vec(s.con(0), s.con(1));
* s.vec(s.str(''), s.str('hello'));
* ```
Expand Down Expand Up @@ -126,7 +126,7 @@ export namespace nodes {
*
* Example:
*
* ```typescript
* ```ts
* s.obj({
* name: s.str(''),
* age: s.con(0),
Expand Down Expand Up @@ -172,7 +172,7 @@ export namespace nodes {
*
* Example:
*
* ```typescript
* ```ts
* s.map<nodes.con<number>>
* ```
*/
Expand All @@ -184,7 +184,7 @@ export namespace nodes {
*
* Example:
*
* ```typescript
* ```ts
* s.arr([s.con(0), s.con(1)]);
* s.arr([s.str(''), s.str('hello')]);
* ```
Expand All @@ -205,6 +205,25 @@ export namespace nodes {
});
}
}

/**
* 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});
* ```
*/
export class json extends NodeBuilder {
public readonly type = 'json';

constructor(public readonly value: unknown) {
super((builder) => builder.json(value));
}
}
}
/* tslint:enable no-namespace class-name */

Expand All @@ -223,36 +242,42 @@ export namespace nodes {
export const schema = {
/**
* Creates a "con" node schema and the default value.
*
* @param raw Raw default value.
*/
con: <T extends unknown | ITimestampStruct>(raw: T) => new nodes.con<T>(raw),

/**
* Creates a "str" node schema and the default value.
*
* @param str Default value.
*/
str: <T extends string>(str: T) => new nodes.str<T>(str || ('' as T)),

/**
* Creates a "bin" node schema and the default value.
*
* @param bin Default value.
*/
bin: (bin: Uint8Array) => new nodes.bin(bin),

/**
* Creates a "val" node schema and the default value.
*
* @param val Default value.
*/
val: <T extends NodeBuilder>(val: T) => new nodes.val<T>(val),

/**
* Creates a "vec" node schema and the default value.
*
* @param vec Default value.
*/
vec: <T extends NodeBuilder[]>(...vec: T) => new nodes.vec<T>(vec),

/**
* Creates a "obj" node schema and the default value.
*
* @param obj Default value, required object keys.
* @param opt Default value of optional object keys.
*/
Expand All @@ -263,16 +288,27 @@ export const schema = {
* 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> =>
schema.obj<Record<string, R>, Record<string, R>>(obj),

/**
* Creates an "arr" node schema and the default value.
*
* @param arr Default value.
*/
arr: <T extends NodeBuilder>(arr: T[]) => new nodes.arr<T>(arr),

/**
* 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: (value: unknown) => new nodes.json(value),
};

/**
Expand Down

0 comments on commit ed6a558

Please sign in to comment.