@milaboratories/pl-tree 1.8.33 → 1.8.35
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/accessors.cjs +23 -23
- package/dist/accessors.cjs.map +1 -1
- package/dist/accessors.d.ts +10 -10
- package/dist/accessors.d.ts.map +1 -1
- package/dist/accessors.js +23 -23
- package/dist/accessors.js.map +1 -1
- package/dist/dump.cjs.map +1 -1
- package/dist/dump.d.ts +1 -1
- package/dist/dump.js.map +1 -1
- package/dist/index.d.ts +9 -9
- package/dist/snapshot.cjs +3 -3
- package/dist/snapshot.cjs.map +1 -1
- package/dist/snapshot.d.ts +12 -12
- package/dist/snapshot.js +3 -3
- package/dist/snapshot.js.map +1 -1
- package/dist/state.cjs +33 -33
- package/dist/state.cjs.map +1 -1
- package/dist/state.d.ts +10 -10
- package/dist/state.d.ts.map +1 -1
- package/dist/state.js +33 -33
- package/dist/state.js.map +1 -1
- package/dist/sync.cjs +1 -1
- package/dist/sync.cjs.map +1 -1
- package/dist/sync.d.ts +2 -2
- package/dist/sync.d.ts.map +1 -1
- package/dist/sync.js +1 -1
- package/dist/sync.js.map +1 -1
- package/dist/synchronized_tree.cjs +11 -11
- package/dist/synchronized_tree.cjs.map +1 -1
- package/dist/synchronized_tree.d.ts +6 -6
- package/dist/synchronized_tree.d.ts.map +1 -1
- package/dist/synchronized_tree.js +11 -11
- package/dist/synchronized_tree.js.map +1 -1
- package/dist/test_utils.d.ts +12 -12
- package/dist/test_utils.d.ts.map +1 -1
- package/dist/traversal_ops.d.ts +1 -1
- package/dist/value_or_error.d.ts.map +1 -1
- package/package.json +23 -22
- package/src/accessors.ts +44 -43
- package/src/dump.ts +1 -1
- package/src/index.ts +9 -9
- package/src/snapshot.test.ts +29 -29
- package/src/snapshot.ts +26 -26
- package/src/state.test.ts +88 -85
- package/src/state.ts +123 -71
- package/src/sync.test.ts +31 -31
- package/src/sync.ts +6 -8
- package/src/synchronized_tree.test.ts +60 -60
- package/src/synchronized_tree.ts +41 -38
- package/src/test_utils.ts +33 -35
- package/src/traversal_ops.ts +1 -1
- package/src/value_or_error.ts +6 -6
package/src/snapshot.test.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { expect, test } from
|
|
2
|
-
import { Computable } from
|
|
3
|
-
import { DefaultFinalResourceDataPredicate, ResourceId } from
|
|
4
|
-
import { z } from
|
|
5
|
-
import { InferSnapshot, makeResourceSnapshot, rsSchema } from
|
|
6
|
-
import { PlTreeState } from
|
|
1
|
+
import { expect, test } from "vitest";
|
|
2
|
+
import { Computable } from "@milaboratories/computable";
|
|
3
|
+
import { DefaultFinalResourceDataPredicate, ResourceId } from "@milaboratories/pl-client";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
import { InferSnapshot, makeResourceSnapshot, rsSchema } from "./snapshot";
|
|
6
|
+
import { PlTreeState } from "./state";
|
|
7
7
|
import {
|
|
8
8
|
TestDynamicRootId1,
|
|
9
9
|
TestDynamicRootState1,
|
|
@@ -11,26 +11,26 @@ import {
|
|
|
11
11
|
TestStructuralResourceType1,
|
|
12
12
|
TestValueResourceState1,
|
|
13
13
|
dField,
|
|
14
|
-
iField
|
|
15
|
-
} from
|
|
14
|
+
iField,
|
|
15
|
+
} from "./test_utils";
|
|
16
16
|
|
|
17
17
|
// schema definition
|
|
18
18
|
const MyTestResourceState = rsSchema({
|
|
19
19
|
data: z.object({
|
|
20
|
-
jf: z.number()
|
|
20
|
+
jf: z.number(),
|
|
21
21
|
}),
|
|
22
22
|
fields: { b: true, c: false },
|
|
23
|
-
kv: { thekey: z.string() }
|
|
23
|
+
kv: { thekey: z.string() },
|
|
24
24
|
});
|
|
25
25
|
|
|
26
26
|
// type derived from schema for out users and us
|
|
27
27
|
type MyTestResourceState = InferSnapshot<typeof MyTestResourceState>;
|
|
28
28
|
|
|
29
|
-
test(
|
|
29
|
+
test("simple snapshot test", async () => {
|
|
30
30
|
const tree = new PlTreeState(TestDynamicRootId1, DefaultFinalResourceDataPredicate);
|
|
31
31
|
|
|
32
32
|
const c1 = Computable.make((ctx) => {
|
|
33
|
-
const accessor = ctx.accessor(tree.entry()).node().traverse(
|
|
33
|
+
const accessor = ctx.accessor(tree.entry()).node().traverse("a");
|
|
34
34
|
if (accessor == undefined) return undefined;
|
|
35
35
|
|
|
36
36
|
const result: MyTestResourceState = makeResourceSnapshot(accessor, MyTestResourceState);
|
|
@@ -38,31 +38,31 @@ test('simple snapshot test', async () => {
|
|
|
38
38
|
});
|
|
39
39
|
|
|
40
40
|
tree.updateFromResourceData([
|
|
41
|
-
{ ...TestDynamicRootState1, fields: [dField(
|
|
41
|
+
{ ...TestDynamicRootState1, fields: [dField("b"), dField("a", rid(1n))] },
|
|
42
42
|
{
|
|
43
43
|
...TestStructuralResourceState1,
|
|
44
44
|
id: rid(1n),
|
|
45
|
-
fields: [iField(
|
|
46
|
-
data: new TextEncoder().encode(`{"jf": 0}`)
|
|
45
|
+
fields: [iField("b", rid(2n))],
|
|
46
|
+
data: new TextEncoder().encode(`{"jf": 0}`),
|
|
47
47
|
},
|
|
48
48
|
{
|
|
49
49
|
...TestValueResourceState1,
|
|
50
|
-
id: rid(2n)
|
|
51
|
-
}
|
|
50
|
+
id: rid(2n),
|
|
51
|
+
},
|
|
52
52
|
]);
|
|
53
53
|
|
|
54
54
|
expect(c1.isChanged()).toBeTruthy();
|
|
55
|
-
expect((await c1.getValueOrError()).type).toStrictEqual(
|
|
55
|
+
expect((await c1.getValueOrError()).type).toStrictEqual("error");
|
|
56
56
|
expect(c1.isChanged()).toBeFalsy();
|
|
57
57
|
|
|
58
58
|
tree.updateFromResourceData([
|
|
59
59
|
{
|
|
60
60
|
...TestValueResourceState1,
|
|
61
61
|
id: rid(1n),
|
|
62
|
-
fields: [iField(
|
|
62
|
+
fields: [iField("b", rid(2n))],
|
|
63
63
|
data: new TextEncoder().encode(`{"jf": 0}`),
|
|
64
|
-
kv: [{ key:
|
|
65
|
-
}
|
|
64
|
+
kv: [{ key: "thekey", value: Buffer.from('"thevalue"') }],
|
|
65
|
+
},
|
|
66
66
|
]);
|
|
67
67
|
|
|
68
68
|
expect(c1.isChanged()).toBeTruthy();
|
|
@@ -70,15 +70,15 @@ test('simple snapshot test', async () => {
|
|
|
70
70
|
id: rid(1n),
|
|
71
71
|
type: TestStructuralResourceType1,
|
|
72
72
|
data: {
|
|
73
|
-
jf: 0
|
|
73
|
+
jf: 0,
|
|
74
74
|
},
|
|
75
75
|
fields: {
|
|
76
76
|
b: rid(2n),
|
|
77
|
-
c: undefined
|
|
77
|
+
c: undefined,
|
|
78
78
|
},
|
|
79
79
|
kv: {
|
|
80
|
-
thekey:
|
|
81
|
-
}
|
|
80
|
+
thekey: "thevalue",
|
|
81
|
+
},
|
|
82
82
|
} as MyTestResourceState);
|
|
83
83
|
expect(c1.isChanged()).toBeFalsy();
|
|
84
84
|
|
|
@@ -86,14 +86,14 @@ test('simple snapshot test', async () => {
|
|
|
86
86
|
{
|
|
87
87
|
...TestValueResourceState1,
|
|
88
88
|
id: rid(1n),
|
|
89
|
-
fields: [iField(
|
|
89
|
+
fields: [iField("b", rid(2n))],
|
|
90
90
|
data: new TextEncoder().encode(`{"jf": 0}`),
|
|
91
|
-
kv: [{ key:
|
|
92
|
-
}
|
|
91
|
+
kv: [{ key: "thekey", value: Buffer.from("123") }], // thekey type changed to number (invalid accordig to zod schema)
|
|
92
|
+
},
|
|
93
93
|
]);
|
|
94
94
|
|
|
95
95
|
expect(c1.isChanged()).toBeTruthy();
|
|
96
|
-
expect((await c1.getValueOrError()).type).toStrictEqual(
|
|
96
|
+
expect((await c1.getValueOrError()).type).toStrictEqual("error");
|
|
97
97
|
expect(c1.isChanged()).toBeFalsy();
|
|
98
98
|
});
|
|
99
99
|
|
package/src/snapshot.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import type { ResourceId, ResourceType } from
|
|
2
|
-
import type { Optional, Writable } from
|
|
3
|
-
import type { ZodType, z } from
|
|
4
|
-
import type { PlTreeNodeAccessor } from
|
|
5
|
-
import { PlTreeEntry, PlTreeEntryAccessor } from
|
|
6
|
-
import type { ComputableCtx } from
|
|
7
|
-
import { notEmpty } from
|
|
1
|
+
import type { ResourceId, ResourceType } from "@milaboratories/pl-client";
|
|
2
|
+
import type { Optional, Writable } from "utility-types";
|
|
3
|
+
import type { ZodType, z } from "zod";
|
|
4
|
+
import type { PlTreeNodeAccessor } from "./accessors";
|
|
5
|
+
import { PlTreeEntry, PlTreeEntryAccessor } from "./accessors";
|
|
6
|
+
import type { ComputableCtx } from "@milaboratories/computable";
|
|
7
|
+
import { notEmpty } from "@milaboratories/ts-helpers";
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* A DTO that can be generated from a tree node to make a snapshot of specific parts of it's state.
|
|
@@ -32,9 +32,9 @@ type ResourceSnapshotGeneric = ResourceSnapshot<
|
|
|
32
32
|
|
|
33
33
|
/** Request that we'll pass to getResourceSnapshot function. We infer the type of ResourceSnapshot from this. */
|
|
34
34
|
export type ResourceSnapshotSchema<
|
|
35
|
-
Data extends ZodType |
|
|
35
|
+
Data extends ZodType | "raw" | undefined = undefined,
|
|
36
36
|
Fields extends Record<string, boolean> | undefined = undefined,
|
|
37
|
-
KV extends Record<string, ZodType |
|
|
37
|
+
KV extends Record<string, ZodType | "raw"> | undefined = undefined,
|
|
38
38
|
> = {
|
|
39
39
|
readonly data: Data;
|
|
40
40
|
readonly fields: Fields;
|
|
@@ -43,9 +43,9 @@ export type ResourceSnapshotSchema<
|
|
|
43
43
|
|
|
44
44
|
/** Creates ResourceSnapshotSchema. It converts an optional schema type to schema type. */
|
|
45
45
|
export function rsSchema<
|
|
46
|
-
const Data extends ZodType |
|
|
46
|
+
const Data extends ZodType | "raw" | undefined = undefined,
|
|
47
47
|
const Fields extends Record<string, boolean> | undefined = undefined,
|
|
48
|
-
const KV extends Record<string, ZodType |
|
|
48
|
+
const KV extends Record<string, ZodType | "raw"> | undefined = undefined,
|
|
49
49
|
>(
|
|
50
50
|
schema: Optional<ResourceSnapshotSchema<Data, Fields, KV>>,
|
|
51
51
|
): ResourceSnapshotSchema<Data, Fields, KV> {
|
|
@@ -54,9 +54,9 @@ export function rsSchema<
|
|
|
54
54
|
|
|
55
55
|
/** The most generic type of ResourceSnapshotSchema. */
|
|
56
56
|
type ResourceSnapshotSchemaGeneric = ResourceSnapshotSchema<
|
|
57
|
-
ZodType |
|
|
57
|
+
ZodType | "raw" | undefined,
|
|
58
58
|
Record<string, boolean> | undefined,
|
|
59
|
-
Record<string, ZodType |
|
|
59
|
+
Record<string, ZodType | "raw"> | undefined
|
|
60
60
|
>;
|
|
61
61
|
|
|
62
62
|
/**
|
|
@@ -64,7 +64,7 @@ type ResourceSnapshotSchemaGeneric = ResourceSnapshotSchema<
|
|
|
64
64
|
* if it's Zod, we'll parse it via zod.
|
|
65
65
|
* Or else we just got undefined in the field.
|
|
66
66
|
*/
|
|
67
|
-
type InferDataType<Data extends ZodType |
|
|
67
|
+
type InferDataType<Data extends ZodType | "raw" | undefined> = Data extends "raw"
|
|
68
68
|
? Uint8Array
|
|
69
69
|
: Data extends ZodType
|
|
70
70
|
? z.infer<Data>
|
|
@@ -89,7 +89,7 @@ type InferFieldsType<Fields extends Record<string, boolean> | undefined> = Field
|
|
|
89
89
|
* If one of values is Zod, we'll get KV and converts it to Zod schema.
|
|
90
90
|
* If the value is 'raw', just returns bytes.
|
|
91
91
|
*/
|
|
92
|
-
type InferKVType<KV extends Record<string, ZodType |
|
|
92
|
+
type InferKVType<KV extends Record<string, ZodType | "raw"> | undefined> = KV extends undefined
|
|
93
93
|
? undefined
|
|
94
94
|
: {
|
|
95
95
|
[FieldName in keyof KV]: KV[FieldName] extends ZodType ? z.infer<KV[FieldName]> : Uint8Array;
|
|
@@ -97,37 +97,37 @@ type InferKVType<KV extends Record<string, ZodType | 'raw'> | undefined> = KV ex
|
|
|
97
97
|
|
|
98
98
|
/** Infer ResourceSnapshot from ResourceShapshotSchema, S can be any ResourceSnapshotSchema. */
|
|
99
99
|
export type InferSnapshot<S extends ResourceSnapshotSchemaGeneric> = ResourceSnapshot<
|
|
100
|
-
InferDataType<S[
|
|
101
|
-
InferFieldsType<S[
|
|
102
|
-
InferKVType<S[
|
|
100
|
+
InferDataType<S["data"]>,
|
|
101
|
+
InferFieldsType<S["fields"]>,
|
|
102
|
+
InferKVType<S["kv"]>
|
|
103
103
|
>;
|
|
104
104
|
|
|
105
105
|
/** Gets a ResourceSnapshot from PlTreeEntry. */
|
|
106
106
|
export function makeResourceSnapshot<Schema extends ResourceSnapshotSchemaGeneric>(
|
|
107
107
|
res: PlTreeEntry,
|
|
108
108
|
schema: Schema,
|
|
109
|
-
ctx: ComputableCtx
|
|
109
|
+
ctx: ComputableCtx,
|
|
110
110
|
): InferSnapshot<Schema>;
|
|
111
111
|
export function makeResourceSnapshot<Schema extends ResourceSnapshotSchemaGeneric>(
|
|
112
112
|
res: PlTreeEntryAccessor | PlTreeNodeAccessor,
|
|
113
|
-
schema: Schema
|
|
113
|
+
schema: Schema,
|
|
114
114
|
): InferSnapshot<Schema>;
|
|
115
115
|
export function makeResourceSnapshot<Schema extends ResourceSnapshotSchemaGeneric>(
|
|
116
116
|
res: PlTreeEntry | PlTreeEntryAccessor | PlTreeNodeAccessor,
|
|
117
117
|
schema: Schema,
|
|
118
118
|
ctx?: ComputableCtx,
|
|
119
119
|
): InferSnapshot<Schema> {
|
|
120
|
-
const node
|
|
121
|
-
|
|
120
|
+
const node =
|
|
121
|
+
res instanceof PlTreeEntry
|
|
122
122
|
? notEmpty(ctx).accessor(res).node()
|
|
123
123
|
: res instanceof PlTreeEntryAccessor
|
|
124
124
|
? res.node()
|
|
125
125
|
: res;
|
|
126
126
|
const info = node.resourceInfo;
|
|
127
|
-
const result: Optional<Writable<ResourceSnapshotGeneric>,
|
|
127
|
+
const result: Optional<Writable<ResourceSnapshotGeneric>, "data" | "fields" | "kv"> = { ...info };
|
|
128
128
|
|
|
129
129
|
if (schema.data !== undefined) {
|
|
130
|
-
if (schema.data ===
|
|
130
|
+
if (schema.data === "raw") result.data = node.getData();
|
|
131
131
|
else result.data = schema.data.parse(node.getDataAsJson());
|
|
132
132
|
}
|
|
133
133
|
|
|
@@ -151,10 +151,10 @@ export function makeResourceSnapshot<Schema extends ResourceSnapshotSchemaGeneri
|
|
|
151
151
|
|
|
152
152
|
if (value === undefined) {
|
|
153
153
|
throw new Error(`Key not found ${fieldName}`);
|
|
154
|
-
} else if (type ===
|
|
154
|
+
} else if (type === "raw") {
|
|
155
155
|
kv[fieldName] = value;
|
|
156
156
|
} else {
|
|
157
|
-
kv[fieldName] = type.parse(JSON.parse(Buffer.from(value).toString(
|
|
157
|
+
kv[fieldName] = type.parse(JSON.parse(Buffer.from(value).toString("utf-8")));
|
|
158
158
|
}
|
|
159
159
|
}
|
|
160
160
|
result.kv = kv;
|
package/src/state.test.ts
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
import { expect, test } from
|
|
2
|
-
import { Computable } from
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import { expect, test } from "vitest";
|
|
2
|
+
import { Computable } from "@milaboratories/computable";
|
|
3
|
+
import {
|
|
4
|
+
DefaultFinalResourceDataPredicate,
|
|
5
|
+
NullResourceId,
|
|
6
|
+
ResourceId,
|
|
7
|
+
} from "@milaboratories/pl-client";
|
|
8
|
+
import { isPlTreeEntry, isPlTreeEntryAccessor, isPlTreeNodeAccessor } from "./accessors";
|
|
9
|
+
import { PlTreeState } from "./state";
|
|
6
10
|
import {
|
|
7
11
|
dField,
|
|
8
12
|
iField,
|
|
@@ -11,15 +15,14 @@ import {
|
|
|
11
15
|
TestDynamicRootState1,
|
|
12
16
|
TestErrorResourceState2,
|
|
13
17
|
TestStructuralResourceState1,
|
|
14
|
-
TestValueResourceState1
|
|
15
|
-
} from
|
|
16
|
-
|
|
18
|
+
TestValueResourceState1,
|
|
19
|
+
} from "./test_utils";
|
|
17
20
|
|
|
18
21
|
function rid(id: bigint): ResourceId {
|
|
19
22
|
return id as ResourceId;
|
|
20
23
|
}
|
|
21
24
|
|
|
22
|
-
test(
|
|
25
|
+
test("simple tree test 1", async () => {
|
|
23
26
|
const tree = new PlTreeState(TestDynamicRootId1, DefaultFinalResourceDataPredicate);
|
|
24
27
|
const entry = tree.entry();
|
|
25
28
|
expect(isPlTreeEntry(entry)).toStrictEqual(true);
|
|
@@ -28,7 +31,7 @@ test('simple tree test 1', async () => {
|
|
|
28
31
|
expect(isPlTreeEntryAccessor(eAcc)).toStrictEqual(true);
|
|
29
32
|
const nAcc = eAcc.node();
|
|
30
33
|
expect(isPlTreeNodeAccessor(nAcc)).toStrictEqual(true);
|
|
31
|
-
return nAcc.traverse(
|
|
34
|
+
return nAcc.traverse("a", "b")?.getDataAsString();
|
|
32
35
|
});
|
|
33
36
|
|
|
34
37
|
expect(c1.isChanged()).toBeTruthy();
|
|
@@ -40,39 +43,39 @@ test('simple tree test 1', async () => {
|
|
|
40
43
|
expect(await c1.getValue()).toBeUndefined();
|
|
41
44
|
expect(c1.isChanged()).toBeFalsy();
|
|
42
45
|
|
|
43
|
-
tree.updateFromResourceData([{ ...TestDynamicRootState1, fields: [dField(
|
|
46
|
+
tree.updateFromResourceData([{ ...TestDynamicRootState1, fields: [dField("b")] }]);
|
|
44
47
|
expect(c1.isChanged()).toBeTruthy();
|
|
45
48
|
expect(await c1.getValue()).toBeUndefined();
|
|
46
49
|
expect(c1.isChanged()).toBeFalsy();
|
|
47
50
|
|
|
48
|
-
tree.updateFromResourceData([{ ...TestDynamicRootState1, fields: [dField(
|
|
51
|
+
tree.updateFromResourceData([{ ...TestDynamicRootState1, fields: [dField("b"), dField("a")] }]);
|
|
49
52
|
expect(c1.isChanged()).toBeTruthy();
|
|
50
53
|
expect(await c1.getValue()).toBeUndefined();
|
|
51
54
|
expect(c1.isChanged()).toBeFalsy();
|
|
52
55
|
|
|
53
56
|
tree.updateFromResourceData([
|
|
54
|
-
{ ...TestDynamicRootState1, fields: [dField(
|
|
55
|
-
{ ...TestStructuralResourceState1, id: rid(rid(1n)), fields: [iField(
|
|
57
|
+
{ ...TestDynamicRootState1, fields: [dField("b"), dField("a", rid(rid(1n)))] },
|
|
58
|
+
{ ...TestStructuralResourceState1, id: rid(rid(1n)), fields: [iField("b", rid(rid(2n)))] },
|
|
56
59
|
{
|
|
57
60
|
...TestValueResourceState1,
|
|
58
61
|
id: rid(rid(2n)),
|
|
59
|
-
data: new TextEncoder().encode(
|
|
60
|
-
}
|
|
62
|
+
data: new TextEncoder().encode("Test1"),
|
|
63
|
+
},
|
|
61
64
|
]);
|
|
62
65
|
expect(c1.isChanged()).toBeTruthy();
|
|
63
|
-
expect(await c1.getValue()).toStrictEqual(
|
|
66
|
+
expect(await c1.getValue()).toStrictEqual("Test1");
|
|
64
67
|
expect(c1.isChanged()).toBeFalsy();
|
|
65
68
|
|
|
66
|
-
tree.updateFromResourceData([{ ...TestDynamicRootState1, fields: [dField(
|
|
69
|
+
tree.updateFromResourceData([{ ...TestDynamicRootState1, fields: [dField("a")] }]);
|
|
67
70
|
expect(c1.isChanged()).toBeTruthy();
|
|
68
71
|
expect(await c1.getValue()).toBeUndefined();
|
|
69
72
|
expect(c1.isChanged()).toBeFalsy();
|
|
70
73
|
});
|
|
71
74
|
|
|
72
|
-
test(
|
|
75
|
+
test("simple tree kv test", async () => {
|
|
73
76
|
const tree = new PlTreeState(TestDynamicRootId1, DefaultFinalResourceDataPredicate);
|
|
74
77
|
const c1 = Computable.make((c) =>
|
|
75
|
-
c.accessor(tree.entry()).node().traverse(
|
|
78
|
+
c.accessor(tree.entry()).node().traverse("a", "b")?.getKeyValueAsString("thekey"),
|
|
76
79
|
);
|
|
77
80
|
|
|
78
81
|
expect(JSON.stringify(tree.entry())).toMatch(/^"\[ENTRY:/);
|
|
@@ -82,13 +85,13 @@ test('simple tree kv test', async () => {
|
|
|
82
85
|
expect(c1.isChanged()).toBeFalsy();
|
|
83
86
|
|
|
84
87
|
tree.updateFromResourceData([
|
|
85
|
-
{ ...TestDynamicRootState1, fields: [dField(
|
|
86
|
-
{ ...TestStructuralResourceState1, id: rid(rid(1n)), fields: [iField(
|
|
88
|
+
{ ...TestDynamicRootState1, fields: [dField("b"), dField("a", rid(rid(1n)))] },
|
|
89
|
+
{ ...TestStructuralResourceState1, id: rid(rid(1n)), fields: [iField("b", rid(rid(2n)))] },
|
|
87
90
|
{
|
|
88
91
|
...TestValueResourceState1,
|
|
89
92
|
id: rid(rid(2n)),
|
|
90
|
-
data: new TextEncoder().encode(
|
|
91
|
-
}
|
|
93
|
+
data: new TextEncoder().encode("Test1"),
|
|
94
|
+
},
|
|
92
95
|
]);
|
|
93
96
|
|
|
94
97
|
expect(c1.isChanged()).toBeTruthy();
|
|
@@ -99,22 +102,22 @@ test('simple tree kv test', async () => {
|
|
|
99
102
|
{
|
|
100
103
|
...TestValueResourceState1,
|
|
101
104
|
id: rid(rid(2n)),
|
|
102
|
-
data: new TextEncoder().encode(
|
|
103
|
-
kv: [{ key:
|
|
104
|
-
}
|
|
105
|
+
data: new TextEncoder().encode("Test1"),
|
|
106
|
+
kv: [{ key: "thekey", value: Buffer.from("thevalue") }],
|
|
107
|
+
},
|
|
105
108
|
]);
|
|
106
109
|
|
|
107
110
|
expect(c1.isChanged()).toBeTruthy();
|
|
108
|
-
expect(await c1.getValue()).toEqual(
|
|
111
|
+
expect(await c1.getValue()).toEqual("thevalue");
|
|
109
112
|
expect(c1.isChanged()).toBeFalsy();
|
|
110
113
|
|
|
111
114
|
tree.updateFromResourceData([
|
|
112
115
|
{
|
|
113
116
|
...TestValueResourceState1,
|
|
114
117
|
id: rid(rid(2n)),
|
|
115
|
-
data: new TextEncoder().encode(
|
|
116
|
-
kv: []
|
|
117
|
-
}
|
|
118
|
+
data: new TextEncoder().encode("Test1"),
|
|
119
|
+
kv: [],
|
|
120
|
+
},
|
|
118
121
|
]);
|
|
119
122
|
|
|
120
123
|
expect(c1.isChanged()).toBeTruthy();
|
|
@@ -122,17 +125,17 @@ test('simple tree kv test', async () => {
|
|
|
122
125
|
expect(c1.isChanged()).toBeFalsy();
|
|
123
126
|
});
|
|
124
127
|
|
|
125
|
-
test(
|
|
128
|
+
test("partial tree update", async () => {
|
|
126
129
|
const tree = new PlTreeState(TestDynamicRootId1, DefaultFinalResourceDataPredicate);
|
|
127
130
|
const c1 = Computable.make((c) =>
|
|
128
131
|
c
|
|
129
132
|
.accessor(tree.entry())
|
|
130
133
|
.node()
|
|
131
134
|
.traverse(
|
|
132
|
-
{ field:
|
|
133
|
-
{ field:
|
|
135
|
+
{ field: "a", assertFieldType: "Dynamic" },
|
|
136
|
+
{ field: "b", assertFieldType: "Dynamic" },
|
|
134
137
|
)
|
|
135
|
-
?.getDataAsString()
|
|
138
|
+
?.getDataAsString(),
|
|
136
139
|
);
|
|
137
140
|
|
|
138
141
|
expect(c1.isChanged()).toBeTruthy();
|
|
@@ -140,16 +143,16 @@ test('partial tree update', async () => {
|
|
|
140
143
|
expect(c1.isChanged()).toBeFalsy();
|
|
141
144
|
|
|
142
145
|
tree.updateFromResourceData([
|
|
143
|
-
{ ...TestDynamicRootState1, fields: [dField(
|
|
144
|
-
{ ...TestStructuralResourceState1, id: rid(1n), fields: [dField(
|
|
146
|
+
{ ...TestDynamicRootState1, fields: [dField("b"), dField("a", rid(1n))] },
|
|
147
|
+
{ ...TestStructuralResourceState1, id: rid(1n), fields: [dField("b", rid(2n))] },
|
|
145
148
|
{
|
|
146
149
|
...TestValueResourceState1,
|
|
147
150
|
id: rid(2n),
|
|
148
|
-
data: new TextEncoder().encode(
|
|
149
|
-
}
|
|
151
|
+
data: new TextEncoder().encode("Test1"),
|
|
152
|
+
},
|
|
150
153
|
]);
|
|
151
154
|
expect(c1.isChanged()).toBeTruthy();
|
|
152
|
-
expect(await c1.getValue()).toStrictEqual(
|
|
155
|
+
expect(await c1.getValue()).toStrictEqual("Test1");
|
|
153
156
|
expect(c1.isChanged()).toBeFalsy();
|
|
154
157
|
|
|
155
158
|
tree.updateFromResourceData([{ ...TestStructuralResourceState1, id: rid(1n), fields: [] }]);
|
|
@@ -158,10 +161,10 @@ test('partial tree update', async () => {
|
|
|
158
161
|
expect(c1.isChanged()).toBeFalsy();
|
|
159
162
|
});
|
|
160
163
|
|
|
161
|
-
test(
|
|
164
|
+
test("resource error", async () => {
|
|
162
165
|
const tree = new PlTreeState(TestDynamicRootId1, DefaultFinalResourceDataPredicate);
|
|
163
166
|
const c1 = Computable.make((c) =>
|
|
164
|
-
c.accessor(tree.entry()).node().traverse(
|
|
167
|
+
c.accessor(tree.entry()).node().traverse("a", "b")?.getKeyValueAsString("thekey"),
|
|
165
168
|
);
|
|
166
169
|
|
|
167
170
|
expect(c1.isChanged()).toBeTruthy();
|
|
@@ -174,17 +177,17 @@ test('resource error', async () => {
|
|
|
174
177
|
...TestErrorResourceState2,
|
|
175
178
|
id: rid(7n),
|
|
176
179
|
data: Buffer.from('"error"'),
|
|
177
|
-
fields: []
|
|
178
|
-
}
|
|
180
|
+
fields: [],
|
|
181
|
+
},
|
|
179
182
|
]);
|
|
180
183
|
|
|
181
|
-
expect((await c1.getValueOrError()).type).toEqual(
|
|
184
|
+
expect((await c1.getValueOrError()).type).toEqual("error");
|
|
182
185
|
});
|
|
183
186
|
|
|
184
|
-
test(
|
|
187
|
+
test("field error", async () => {
|
|
185
188
|
const tree = new PlTreeState(TestDynamicRootId1, DefaultFinalResourceDataPredicate);
|
|
186
189
|
const c1 = Computable.make((c) =>
|
|
187
|
-
c.accessor(tree.entry()).node().traverse(
|
|
190
|
+
c.accessor(tree.entry()).node().traverse("b", "a")?.getKeyValueAsString("thekey"),
|
|
188
191
|
);
|
|
189
192
|
|
|
190
193
|
expect(c1.isChanged()).toBeTruthy();
|
|
@@ -194,53 +197,53 @@ test('field error', async () => {
|
|
|
194
197
|
tree.updateFromResourceData([
|
|
195
198
|
{
|
|
196
199
|
...TestDynamicRootState1,
|
|
197
|
-
fields: [dField(
|
|
200
|
+
fields: [dField("b", NullResourceId, rid(7n))],
|
|
198
201
|
},
|
|
199
202
|
{
|
|
200
203
|
...TestErrorResourceState2,
|
|
201
204
|
id: rid(7n),
|
|
202
205
|
data: Buffer.from('"error"'),
|
|
203
|
-
fields: []
|
|
204
|
-
}
|
|
206
|
+
fields: [],
|
|
207
|
+
},
|
|
205
208
|
]);
|
|
206
209
|
|
|
207
|
-
expect((await c1.getValueOrError()).type).toEqual(
|
|
210
|
+
expect((await c1.getValueOrError()).type).toEqual("error");
|
|
208
211
|
});
|
|
209
212
|
|
|
210
|
-
test(
|
|
213
|
+
test("exception - deletion of input field", () => {
|
|
211
214
|
const tree = new PlTreeState(TestDynamicRootId1, DefaultFinalResourceDataPredicate);
|
|
212
215
|
|
|
213
216
|
tree.updateFromResourceData([
|
|
214
|
-
{ ...TestDynamicRootState1, fields: [dField(
|
|
215
|
-
{ ...TestStructuralResourceState1, id: rid(1n), fields: [iField(
|
|
217
|
+
{ ...TestDynamicRootState1, fields: [dField("b"), dField("a", rid(1n))] },
|
|
218
|
+
{ ...TestStructuralResourceState1, id: rid(1n), fields: [iField("b", rid(2n))] },
|
|
216
219
|
{
|
|
217
220
|
...TestValueResourceState1,
|
|
218
221
|
id: rid(2n),
|
|
219
|
-
data: new TextEncoder().encode(
|
|
220
|
-
}
|
|
222
|
+
data: new TextEncoder().encode("Test1"),
|
|
223
|
+
},
|
|
221
224
|
]);
|
|
222
225
|
|
|
223
226
|
expect(() =>
|
|
224
|
-
tree.updateFromResourceData([{ ...TestStructuralResourceState1, id: rid(1n), fields: [] }])
|
|
227
|
+
tree.updateFromResourceData([{ ...TestStructuralResourceState1, id: rid(1n), fields: [] }]),
|
|
225
228
|
).toThrow(/removal of Input field/);
|
|
226
229
|
});
|
|
227
230
|
|
|
228
|
-
test(
|
|
231
|
+
test("exception - addition of input field", () => {
|
|
229
232
|
const tree = new PlTreeState(TestDynamicRootId1, DefaultFinalResourceDataPredicate);
|
|
230
233
|
|
|
231
234
|
tree.updateFromResourceData([
|
|
232
|
-
{ ...TestDynamicRootState1, fields: [dField(
|
|
235
|
+
{ ...TestDynamicRootState1, fields: [dField("b"), dField("a", rid(1n))] },
|
|
233
236
|
{
|
|
234
237
|
...TestStructuralResourceState1,
|
|
235
238
|
id: rid(1n),
|
|
236
|
-
fields: [iField(
|
|
237
|
-
...ResourceReady
|
|
239
|
+
fields: [iField("b", rid(2n))],
|
|
240
|
+
...ResourceReady,
|
|
238
241
|
},
|
|
239
242
|
{
|
|
240
243
|
...TestValueResourceState1,
|
|
241
244
|
id: rid(2n),
|
|
242
|
-
data: new TextEncoder().encode(
|
|
243
|
-
}
|
|
245
|
+
data: new TextEncoder().encode("Test1"),
|
|
246
|
+
},
|
|
244
247
|
]);
|
|
245
248
|
|
|
246
249
|
expect(() =>
|
|
@@ -248,71 +251,71 @@ test('exception - addition of input field', () => {
|
|
|
248
251
|
{
|
|
249
252
|
...TestStructuralResourceState1,
|
|
250
253
|
id: rid(1n),
|
|
251
|
-
fields: [iField(
|
|
252
|
-
...ResourceReady
|
|
253
|
-
}
|
|
254
|
-
])
|
|
254
|
+
fields: [iField("b", rid(2n)), iField("df")],
|
|
255
|
+
...ResourceReady,
|
|
256
|
+
},
|
|
257
|
+
]),
|
|
255
258
|
).toThrow(/adding Input/);
|
|
256
259
|
});
|
|
257
260
|
|
|
258
|
-
test(
|
|
261
|
+
test("exception - ready without locks 1", () => {
|
|
259
262
|
const tree = new PlTreeState(TestDynamicRootId1, DefaultFinalResourceDataPredicate);
|
|
260
263
|
|
|
261
264
|
expect(() =>
|
|
262
265
|
tree.updateFromResourceData([
|
|
263
266
|
{
|
|
264
267
|
...TestDynamicRootState1,
|
|
265
|
-
fields: [dField(
|
|
268
|
+
fields: [dField("b"), dField("a", rid(1n))],
|
|
266
269
|
},
|
|
267
270
|
{
|
|
268
271
|
...TestStructuralResourceState1,
|
|
269
272
|
id: rid(1n),
|
|
270
|
-
fields: [iField(
|
|
271
|
-
resourceReady: true
|
|
273
|
+
fields: [iField("b", rid(2n))],
|
|
274
|
+
resourceReady: true,
|
|
272
275
|
},
|
|
273
276
|
{
|
|
274
277
|
...TestValueResourceState1,
|
|
275
278
|
id: rid(2n),
|
|
276
|
-
data: new TextEncoder().encode(
|
|
277
|
-
}
|
|
278
|
-
])
|
|
279
|
+
data: new TextEncoder().encode("Test1"),
|
|
280
|
+
},
|
|
281
|
+
]),
|
|
279
282
|
).toThrow(/ready without input or output lock/);
|
|
280
283
|
});
|
|
281
284
|
|
|
282
|
-
test(
|
|
285
|
+
test("exception - ready without locks 2", () => {
|
|
283
286
|
const tree = new PlTreeState(TestDynamicRootId1, DefaultFinalResourceDataPredicate);
|
|
284
287
|
|
|
285
288
|
tree.updateFromResourceData([
|
|
286
|
-
{ ...TestDynamicRootState1, fields: [dField(
|
|
289
|
+
{ ...TestDynamicRootState1, fields: [dField("b"), dField("a", rid(1n))] },
|
|
287
290
|
{
|
|
288
291
|
...TestStructuralResourceState1,
|
|
289
292
|
id: rid(1n),
|
|
290
|
-
fields: [iField(
|
|
293
|
+
fields: [iField("b", rid(2n))],
|
|
291
294
|
},
|
|
292
295
|
{
|
|
293
296
|
...TestValueResourceState1,
|
|
294
297
|
id: rid(2n),
|
|
295
|
-
data: new TextEncoder().encode(
|
|
296
|
-
}
|
|
298
|
+
data: new TextEncoder().encode("Test1"),
|
|
299
|
+
},
|
|
297
300
|
]);
|
|
298
301
|
|
|
299
302
|
expect(() =>
|
|
300
303
|
tree.updateFromResourceData([
|
|
301
304
|
{
|
|
302
305
|
...TestDynamicRootState1,
|
|
303
|
-
fields: [dField(
|
|
306
|
+
fields: [dField("b"), dField("a", rid(1n))],
|
|
304
307
|
},
|
|
305
308
|
{
|
|
306
309
|
...TestStructuralResourceState1,
|
|
307
310
|
id: rid(1n),
|
|
308
|
-
fields: [iField(
|
|
309
|
-
resourceReady: true
|
|
311
|
+
fields: [iField("b", rid(2n))],
|
|
312
|
+
resourceReady: true,
|
|
310
313
|
},
|
|
311
314
|
{
|
|
312
315
|
...TestValueResourceState1,
|
|
313
316
|
id: rid(2n),
|
|
314
|
-
data: new TextEncoder().encode(
|
|
315
|
-
}
|
|
316
|
-
])
|
|
317
|
+
data: new TextEncoder().encode("Test1"),
|
|
318
|
+
},
|
|
319
|
+
]),
|
|
317
320
|
).toThrow(/ready without input or output lock/);
|
|
318
321
|
});
|