Skip to content

Commit 1a3ec66

Browse files
committed
feat(json-crdt): 🎸 add type which infers schema from JSON CRDT nodes
1 parent 6d478b8 commit 1a3ec66

File tree

2 files changed

+72
-0
lines changed

2 files changed

+72
-0
lines changed
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import {s} from '../../../json-crdt-patch';
2+
import {Model} from '../../model';
3+
import {JsonNodeToSchema, SchemaToJsonNode} from '../types';
4+
5+
describe('can infer schema of JSON CRDT nodes', () => {
6+
test('con', () => {
7+
const schema1 = s.con(123);
8+
const schema2: JsonNodeToSchema<SchemaToJsonNode<typeof schema1>> = schema1;
9+
});
10+
11+
test('val', () => {
12+
const schema1 = s.val(s.con(true));
13+
const schema2: JsonNodeToSchema<SchemaToJsonNode<typeof schema1>> = schema1;
14+
});
15+
16+
test('obj', () => {
17+
const schema1 = s.obj({
18+
hello: s.con('world'),
19+
});
20+
const schema2: JsonNodeToSchema<SchemaToJsonNode<typeof schema1>> = schema1;
21+
});
22+
23+
test('vec', () => {
24+
const schema1 = s.vec(s.con(1), s.val(s.con(2)));
25+
const schema2: JsonNodeToSchema<SchemaToJsonNode<typeof schema1>> = schema1;
26+
});
27+
28+
test('str', () => {
29+
const schema1 = s.str('asdf');
30+
const schema2: JsonNodeToSchema<SchemaToJsonNode<typeof schema1>> = schema1;
31+
});
32+
33+
test('bin', () => {
34+
const schema1 = s.bin(new Uint8Array([1, 2, 3]));
35+
const schema2: JsonNodeToSchema<SchemaToJsonNode<typeof schema1>> = schema1;
36+
});
37+
38+
test('arr', () => {
39+
const schema1 = s.arr([s.con(1), s.val(s.con(2))]);
40+
const schema2: JsonNodeToSchema<SchemaToJsonNode<typeof schema1>> = schema1;
41+
});
42+
43+
test('from typed model', () => {
44+
const model = Model.withLogicalClock().setSchema(s.obj({
45+
id: s.con('asdf'),
46+
age: s.val(s.con(42)),
47+
}));
48+
type Node = ReturnType<typeof model.root.node>;
49+
type Schema = JsonNodeToSchema<Node>;
50+
const schema: Schema = s.obj({
51+
id: s.con('asdf'),
52+
age: s.val(s.con(42)),
53+
});
54+
});
55+
});

src/json-crdt/schema/types.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,20 @@ export type SchemaToJsonNode<S> = S extends builder.str<infer T>
1717
: S extends builder.arr<infer T>
1818
? nodes.ArrNode<SchemaToJsonNode<T>>
1919
: nodes.JsonNode;
20+
21+
// prettier-ignore
22+
export type JsonNodeToSchema<N> = N extends nodes.StrNode<infer T>
23+
? builder.str<T>
24+
: N extends nodes.BinNode
25+
? builder.bin
26+
: N extends nodes.ConNode<infer T>
27+
? builder.con<T>
28+
: N extends nodes.ValNode<infer T>
29+
? builder.val<JsonNodeToSchema<T>>
30+
: N extends nodes.VecNode<infer T>
31+
? builder.vec<{[K in keyof T]: JsonNodeToSchema<T[K]>}>
32+
: N extends nodes.ObjNode<infer T>
33+
? builder.obj<{[K in keyof T]: JsonNodeToSchema<T[K]>}>
34+
: N extends nodes.ArrNode<infer T>
35+
? builder.arr<JsonNodeToSchema<T>>
36+
: builder.con<undefined>;

0 commit comments

Comments
 (0)