@milaboratories/pl-tree 1.9.22 → 1.10.0

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/src/accessors.ts CHANGED
@@ -5,13 +5,17 @@ import type {
5
5
  ComputableHooks,
6
6
  UsageGuard,
7
7
  } from "@milaboratories/computable";
8
- import type { ResourceId, ResourceType, OptionalResourceId } from "@milaboratories/pl-client";
8
+ import type {
9
+ SignedResourceId,
10
+ ResourceType,
11
+ OptionalSignedResourceId,
12
+ } from "@milaboratories/pl-client";
9
13
  import {
10
14
  resourceIdToString,
11
15
  resourceTypesEqual,
12
16
  resourceTypeToString,
13
17
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
14
- NullResourceId,
18
+ NullSignedResourceId,
15
19
  } from "@milaboratories/pl-client";
16
20
  import type { ValueAndError } from "./value_and_error";
17
21
  import { mapValueAndError } from "./value_and_error";
@@ -71,7 +75,7 @@ export class PlTreeEntry implements AccessorProvider<PlTreeEntryAccessor> {
71
75
 
72
76
  constructor(
73
77
  private readonly accessorData: TreeAccessorData,
74
- public readonly rid: ResourceId,
78
+ public readonly rid: SignedResourceId, // only for runtime. Not exposing rid at all causes too much pain. Never persist this anywhere.
75
79
  ) {}
76
80
 
77
81
  public createAccessor(ctx: ComputableCtx, guard: UsageGuard): PlTreeEntryAccessor {
@@ -81,6 +85,14 @@ export class PlTreeEntry implements AccessorProvider<PlTreeEntryAccessor> {
81
85
  });
82
86
  }
83
87
 
88
+ /**
89
+ * Tree TreeEntry ID suitable for persistence and use in names (files/objects/whatever), as it does not
90
+ * contain signature which can change from session to session.
91
+ */
92
+ public get id(): string {
93
+ return resourceIdToString(this.rid);
94
+ }
95
+
84
96
  public toJSON(): string {
85
97
  return this.toString();
86
98
  }
@@ -94,7 +106,7 @@ function getResourceFromTree(
94
106
  accessorData: TreeAccessorData,
95
107
  tree: PlTreeState,
96
108
  instanceData: TreeAccessorInstanceData,
97
- rid: ResourceId,
109
+ rid: SignedResourceId,
98
110
  ops: ResourceTraversalOps,
99
111
  ): PlTreeNodeAccessor {
100
112
  const acc = new PlTreeNodeAccessor(
@@ -130,7 +142,7 @@ export class PlTreeEntryAccessor {
130
142
  constructor(
131
143
  private readonly accessorData: TreeAccessorData,
132
144
  private readonly tree: PlTreeState,
133
- private readonly rid: ResourceId,
145
+ private readonly rid: SignedResourceId,
134
146
  private readonly instanceData: TreeAccessorInstanceData,
135
147
  ) {}
136
148
 
@@ -150,7 +162,7 @@ export class PlTreeEntryAccessor {
150
162
  * Helper type to simplify implementation of APIs requiring type information.
151
163
  * */
152
164
  export type ResourceInfo = {
153
- readonly id: ResourceId;
165
+ readonly id: SignedResourceId;
154
166
  readonly type: ResourceType;
155
167
  };
156
168
 
@@ -166,7 +178,7 @@ export function treeEntryToResourceInfo(res: PlTreeEntry | ResourceInfo, ctx: Co
166
178
 
167
179
  /**
168
180
  * API contracts:
169
- * - API never return {@link NullResourceId}, absence of link is always modeled as `undefined`
181
+ * - API never return {@link NullSignedResourceId}, absence of link is always modeled as `undefined`
170
182
  *
171
183
  * Important: never store instances of this class, always get fresh instance from {@link PlTreeState} accessor.
172
184
  * */
@@ -180,12 +192,12 @@ export class PlTreeNodeAccessor {
180
192
  private readonly instanceData: TreeAccessorInstanceData,
181
193
  ) {}
182
194
 
183
- public get id(): ResourceId {
195
+ public get id(): SignedResourceId {
184
196
  this.instanceData.guard();
185
197
  return this.resource.id;
186
198
  }
187
199
 
188
- public get originalId(): OptionalResourceId {
200
+ public get originalId(): OptionalSignedResourceId {
189
201
  this.instanceData.guard();
190
202
  return this.resource.originalResourceId;
191
203
  }
@@ -199,7 +211,10 @@ export class PlTreeNodeAccessor {
199
211
  return { id: this.id, type: this.resourceType };
200
212
  }
201
213
 
202
- private getResourceFromTree(rid: ResourceId, ops: ResourceTraversalOps): PlTreeNodeAccessor {
214
+ private getResourceFromTree(
215
+ rid: SignedResourceId,
216
+ ops: ResourceTraversalOps,
217
+ ): PlTreeNodeAccessor {
203
218
  return getResourceFromTree(this.accessorData, this.tree, this.instanceData, rid, ops);
204
219
  }
205
220
 
@@ -1,6 +1,9 @@
1
1
  import { expect, test } from "vitest";
2
2
  import { Computable } from "@milaboratories/computable";
3
- import { DefaultFinalResourceDataPredicate, ResourceId } from "@milaboratories/pl-client";
3
+ import {
4
+ createSignedResourceId,
5
+ DefaultFinalResourceDataPredicate,
6
+ } from "@milaboratories/pl-client";
4
7
  import { z } from "zod";
5
8
  import { InferSnapshot, makeResourceSnapshot, rsSchema } from "./snapshot";
6
9
  import { PlTreeState } from "./state";
@@ -14,6 +17,8 @@ import {
14
17
  iField,
15
18
  } from "./test_utils";
16
19
 
20
+ const rid = createSignedResourceId;
21
+
17
22
  // schema definition
18
23
  const MyTestResourceState = rsSchema({
19
24
  data: z.object({
@@ -96,7 +101,3 @@ test("simple snapshot test", async () => {
96
101
  expect((await c1.getValueOrError()).type).toStrictEqual("error");
97
102
  expect(c1.isChanged()).toBeFalsy();
98
103
  });
99
-
100
- function rid(id: bigint): ResourceId {
101
- return id as ResourceId;
102
- }
package/src/snapshot.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { ResourceId, ResourceType } from "@milaboratories/pl-client";
1
+ import type { SignedResourceId, ResourceType } from "@milaboratories/pl-client";
2
2
  import type { Optional, Writable } from "utility-types";
3
3
  import type { ZodType, z } from "zod";
4
4
  import type { PlTreeNodeAccessor } from "./accessors";
@@ -13,10 +13,10 @@ import { notEmpty } from "@milaboratories/ts-helpers";
13
13
  */
14
14
  export type ResourceSnapshot<
15
15
  Data = undefined,
16
- Fields extends Record<string, ResourceId | undefined> | undefined = undefined,
16
+ Fields extends Record<string, SignedResourceId | undefined> | undefined = undefined,
17
17
  KV extends Record<string, unknown> | undefined = undefined,
18
18
  > = {
19
- readonly id: ResourceId;
19
+ readonly id: SignedResourceId;
20
20
  readonly type: ResourceType;
21
21
  readonly data: Data;
22
22
  readonly fields: Fields;
@@ -26,7 +26,7 @@ export type ResourceSnapshot<
26
26
  /** The most generic type of ResourceSnapshot. */
27
27
  type ResourceSnapshotGeneric = ResourceSnapshot<
28
28
  unknown,
29
- Record<string, ResourceId | undefined> | undefined,
29
+ Record<string, SignedResourceId | undefined> | undefined,
30
30
  Record<string, unknown> | undefined
31
31
  >;
32
32
 
@@ -80,8 +80,8 @@ type InferFieldsType<Fields extends Record<string, boolean> | undefined> = Field
80
80
  ? undefined
81
81
  : {
82
82
  [FieldName in keyof Fields]: Fields[FieldName] extends true
83
- ? ResourceId
84
- : ResourceId | undefined;
83
+ ? SignedResourceId
84
+ : SignedResourceId | undefined;
85
85
  };
86
86
 
87
87
  /**
@@ -132,7 +132,7 @@ export function makeResourceSnapshot<Schema extends ResourceSnapshotSchemaGeneri
132
132
  }
133
133
 
134
134
  if (schema.fields !== undefined) {
135
- const fields: Record<string, ResourceId | undefined> = {};
135
+ const fields: Record<string, SignedResourceId | undefined> = {};
136
136
  // even if field is not defined, corresponding object field
137
137
  // with "undefined" value will still be added
138
138
  for (const [fieldName, required] of Object.entries(schema.fields))
@@ -165,9 +165,9 @@ export function makeResourceSnapshot<Schema extends ResourceSnapshotSchemaGeneri
165
165
 
166
166
  /** @deprecated */
167
167
  export type ResourceWithData = {
168
- readonly id: ResourceId;
168
+ readonly id: SignedResourceId;
169
169
  readonly type: ResourceType;
170
- readonly fields: Map<string, ResourceId | undefined>;
170
+ readonly fields: Map<string, SignedResourceId | undefined>;
171
171
  readonly data?: Uint8Array;
172
172
  };
173
173
 
@@ -181,7 +181,7 @@ export function treeEntryToResourceWithData(
181
181
  const node = ctx.accessor(res).node();
182
182
  const info = node.resourceInfo;
183
183
 
184
- const fValues: [string, ResourceId | undefined][] = fields.map((name) => [
184
+ const fValues: [string, SignedResourceId | undefined][] = fields.map((name) => [
185
185
  name,
186
186
  node.getField(name)?.value?.id,
187
187
  ]);
@@ -198,7 +198,7 @@ export function treeEntryToResourceWithData(
198
198
 
199
199
  /** @deprecated */
200
200
  export type ResourceWithMetadata = {
201
- readonly id: ResourceId;
201
+ readonly id: SignedResourceId;
202
202
  readonly type: ResourceType;
203
203
  readonly metadata: Record<string, any>;
204
204
  };
package/src/state.test.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  import { expect, test } from "vitest";
2
2
  import { Computable } from "@milaboratories/computable";
3
3
  import {
4
+ createSignedResourceId,
4
5
  DefaultFinalResourceDataPredicate,
5
- NullResourceId,
6
- ResourceId,
6
+ NullSignedResourceId,
7
7
  } from "@milaboratories/pl-client";
8
8
  import { isPlTreeEntry, isPlTreeEntryAccessor, isPlTreeNodeAccessor } from "./accessors";
9
9
  import { PlTreeState } from "./state";
@@ -18,9 +18,7 @@ import {
18
18
  TestValueResourceState1,
19
19
  } from "./test_utils";
20
20
 
21
- function rid(id: bigint): ResourceId {
22
- return id as ResourceId;
23
- }
21
+ const rid = createSignedResourceId;
24
22
 
25
23
  test("simple tree test 1", async () => {
26
24
  const tree = new PlTreeState(TestDynamicRootId1, DefaultFinalResourceDataPredicate);
@@ -54,11 +52,11 @@ test("simple tree test 1", async () => {
54
52
  expect(c1.isChanged()).toBeFalsy();
55
53
 
56
54
  tree.updateFromResourceData([
57
- { ...TestDynamicRootState1, fields: [dField("b"), dField("a", rid(rid(1n)))] },
58
- { ...TestStructuralResourceState1, id: rid(rid(1n)), fields: [iField("b", rid(rid(2n)))] },
55
+ { ...TestDynamicRootState1, fields: [dField("b"), dField("a", rid(1n))] },
56
+ { ...TestStructuralResourceState1, id: rid(1n), fields: [iField("b", rid(2n))] },
59
57
  {
60
58
  ...TestValueResourceState1,
61
- id: rid(rid(2n)),
59
+ id: rid(2n),
62
60
  data: new TextEncoder().encode("Test1"),
63
61
  },
64
62
  ]);
@@ -85,11 +83,11 @@ test("simple tree kv test", async () => {
85
83
  expect(c1.isChanged()).toBeFalsy();
86
84
 
87
85
  tree.updateFromResourceData([
88
- { ...TestDynamicRootState1, fields: [dField("b"), dField("a", rid(rid(1n)))] },
89
- { ...TestStructuralResourceState1, id: rid(rid(1n)), fields: [iField("b", rid(rid(2n)))] },
86
+ { ...TestDynamicRootState1, fields: [dField("b"), dField("a", rid(1n))] },
87
+ { ...TestStructuralResourceState1, id: rid(1n), fields: [iField("b", rid(2n))] },
90
88
  {
91
89
  ...TestValueResourceState1,
92
- id: rid(rid(2n)),
90
+ id: rid(2n),
93
91
  data: new TextEncoder().encode("Test1"),
94
92
  },
95
93
  ]);
@@ -101,7 +99,7 @@ test("simple tree kv test", async () => {
101
99
  tree.updateFromResourceData([
102
100
  {
103
101
  ...TestValueResourceState1,
104
- id: rid(rid(2n)),
102
+ id: rid(2n),
105
103
  data: new TextEncoder().encode("Test1"),
106
104
  kv: [{ key: "thekey", value: Buffer.from("thevalue") }],
107
105
  },
@@ -114,7 +112,7 @@ test("simple tree kv test", async () => {
114
112
  tree.updateFromResourceData([
115
113
  {
116
114
  ...TestValueResourceState1,
117
- id: rid(rid(2n)),
115
+ id: rid(2n),
118
116
  data: new TextEncoder().encode("Test1"),
119
117
  kv: [],
120
118
  },
@@ -197,7 +195,7 @@ test("field error", async () => {
197
195
  tree.updateFromResourceData([
198
196
  {
199
197
  ...TestDynamicRootState1,
200
- fields: [dField("b", NullResourceId, rid(7n))],
198
+ fields: [dField("b", NullSignedResourceId, rid(7n))],
201
199
  },
202
200
  {
203
201
  ...TestErrorResourceState2,
package/src/state.ts CHANGED
@@ -4,16 +4,16 @@ import type {
4
4
  FieldStatus,
5
5
  FieldType,
6
6
  KeyValue,
7
- OptionalResourceId,
7
+ OptionalSignedResourceId,
8
8
  ResourceData,
9
- ResourceId,
9
+ SignedResourceId,
10
10
  ResourceKind,
11
11
  ResourceType,
12
12
  } from "@milaboratories/pl-client";
13
13
  import {
14
- isNotNullResourceId,
15
- isNullResourceId,
16
- NullResourceId,
14
+ isNotNullSignedResourceId,
15
+ isNullSignedResourceId,
16
+ NullSignedResourceId,
17
17
  resourceIdToString,
18
18
  stringifyWithResourceId,
19
19
  } from "@milaboratories/pl-client";
@@ -42,8 +42,8 @@ class PlTreeField implements FieldData {
42
42
  constructor(
43
43
  public readonly name: string,
44
44
  public type: FieldType,
45
- public value: OptionalResourceId,
46
- public error: OptionalResourceId,
45
+ public value: OptionalSignedResourceId,
46
+ public error: OptionalSignedResourceId,
47
47
  public status: FieldStatus,
48
48
  public valueIsFinal: boolean,
49
49
  /** Last version of resource this field was observed, used to garbage collect fields in tree patching procedure */
@@ -98,8 +98,8 @@ export class PlTreeResource implements ResourceDataWithFinalState {
98
98
  // kvChangedGlobal? = new ChangeSource();
99
99
  kvChangedPerKey? = new KeyedChangeSource();
100
100
 
101
- readonly id: ResourceId;
102
- originalResourceId: OptionalResourceId;
101
+ readonly id: SignedResourceId;
102
+ originalResourceId: OptionalSignedResourceId;
103
103
 
104
104
  readonly kind: ResourceKind;
105
105
  readonly type: ResourceType;
@@ -108,7 +108,7 @@ export class PlTreeResource implements ResourceDataWithFinalState {
108
108
  private dataAsString?: string;
109
109
  private dataAsJson?: unknown;
110
110
 
111
- error: OptionalResourceId;
111
+ error: OptionalSignedResourceId;
112
112
 
113
113
  inputsLocked: boolean;
114
114
  outputsLocked: boolean;
@@ -162,17 +162,17 @@ export class PlTreeResource implements ResourceDataWithFinalState {
162
162
  | (Omit<GetFieldStep, "errorIfFieldNotFound"> & { errorIfFieldNotFound: true })
163
163
  | (Omit<GetFieldStep, "errorIfFieldNotSet"> & { errorIfFieldNotSet: true }),
164
164
  onUnstable: (marker: string) => void,
165
- ): ValueAndError<ResourceId>;
165
+ ): ValueAndError<SignedResourceId>;
166
166
  public getField(
167
167
  watcher: Watcher,
168
168
  _step: string | GetFieldStep,
169
169
  onUnstable: (marker: string) => void,
170
- ): ValueAndError<ResourceId> | undefined;
170
+ ): ValueAndError<SignedResourceId> | undefined;
171
171
  public getField(
172
172
  watcher: Watcher,
173
173
  _step: string | GetFieldStep,
174
174
  onUnstable: (marker: string) => void = () => {},
175
- ): ValueAndError<ResourceId> | undefined {
175
+ ): ValueAndError<SignedResourceId> | undefined {
176
176
  const step: FieldTraversalStep = typeof _step === "string" ? { field: _step } : _step;
177
177
 
178
178
  const field = this.fieldsMap.get(step.field);
@@ -208,9 +208,9 @@ export class PlTreeResource implements ResourceDataWithFinalState {
208
208
  `Unexpected field type: expected ${step.assertFieldType} but got ${field.type} for the field name ${step.field}`,
209
209
  );
210
210
 
211
- const ret = {} as ValueAndError<ResourceId>;
212
- if (isNotNullResourceId(field.value)) ret.value = field.value;
213
- if (isNotNullResourceId(field.error)) ret.error = field.error;
211
+ const ret = {} as ValueAndError<SignedResourceId>;
212
+ if (isNotNullSignedResourceId(field.value)) ret.value = field.value;
213
+ if (isNotNullSignedResourceId(field.error)) ret.error = field.error;
214
214
  if (ret.value === undefined && ret.error === undefined)
215
215
  // this method returns value and error of the field, thus those values are considered to be accessed;
216
216
  // any existing but not resolved field here is considered to be unstable, in the sense it is
@@ -237,9 +237,9 @@ export class PlTreeResource implements ResourceDataWithFinalState {
237
237
 
238
238
  public get isReadyOrError(): boolean {
239
239
  return (
240
- this.error !== NullResourceId ||
240
+ this.error !== NullSignedResourceId ||
241
241
  this.resourceReady ||
242
- this.originalResourceId !== NullResourceId
242
+ this.originalResourceId !== NullSignedResourceId
243
243
  );
244
244
  }
245
245
 
@@ -255,8 +255,8 @@ export class PlTreeResource implements ResourceDataWithFinalState {
255
255
  return this.isReadyOrError;
256
256
  }
257
257
 
258
- public getError(watcher: Watcher): ResourceId | undefined {
259
- if (isNullResourceId(this.error)) {
258
+ public getError(watcher: Watcher): SignedResourceId | undefined {
259
+ if (isNullSignedResourceId(this.error)) {
260
260
  this.resourceStateChange?.attachWatcher(watcher);
261
261
  return undefined;
262
262
  } else {
@@ -387,7 +387,7 @@ export class PlTreeResource implements ResourceDataWithFinalState {
387
387
 
388
388
  export class PlTreeState {
389
389
  /** resource heap */
390
- private resources: Map<ResourceId, PlTreeResource> = new Map();
390
+ private resources: Map<SignedResourceId, PlTreeResource> = new Map();
391
391
  private readonly resourcesAdded = new ChangeSource();
392
392
  /** Resets to false if any invalid state transitions are registered,
393
393
  * after that tree will produce errors for any read or write operations */
@@ -396,7 +396,7 @@ export class PlTreeState {
396
396
 
397
397
  constructor(
398
398
  /** This will be the only resource not deleted during GC round */
399
- public readonly root: ResourceId,
399
+ public readonly root: SignedResourceId,
400
400
  public readonly isFinalPredicate: FinalResourceDataPredicate,
401
401
  ) {}
402
402
 
@@ -408,7 +408,7 @@ export class PlTreeState {
408
408
  if (!this._isValid) throw new Error(this.invalidationMessage ?? "tree is in invalid state");
409
409
  }
410
410
 
411
- public get(watcher: Watcher, rid: ResourceId): PlTreeResource {
411
+ public get(watcher: Watcher, rid: SignedResourceId): PlTreeResource {
412
412
  this.checkValid();
413
413
  const res = this.resources.get(rid);
414
414
  if (res === undefined) {
@@ -425,8 +425,8 @@ export class PlTreeState {
425
425
  this.checkValid();
426
426
 
427
427
  // All resources for which recount should be incremented, first are aggregated in this list
428
- const incrementRefs: ResourceId[] = [];
429
- const decrementRefs: ResourceId[] = [];
428
+ const incrementRefs: SignedResourceId[] = [];
429
+ const decrementRefs: SignedResourceId[] = [];
430
430
 
431
431
  // patching / creating resources
432
432
  for (const rd of resourceData) {
@@ -456,7 +456,7 @@ export class PlTreeState {
456
456
 
457
457
  // duplicate / original
458
458
  if (resource.originalResourceId !== rd.originalResourceId) {
459
- if (resource.originalResourceId !== NullResourceId)
459
+ if (resource.originalResourceId !== NullSignedResourceId)
460
460
  unexpectedTransitionError("originalResourceId can't change after it is set");
461
461
  resource.originalResourceId = rd.originalResourceId;
462
462
  // duplicate status of the resource counts as ready for the external observer
@@ -467,11 +467,11 @@ export class PlTreeState {
467
467
  }
468
468
 
469
469
  // error
470
- if (resource.error !== rd.error) {
471
- if (isNotNullResourceId(resource.error))
470
+ if (isNotNullSignedResourceId(rd.error) && resource.error !== rd.error) {
471
+ if (isNotNullSignedResourceId(resource.error))
472
472
  unexpectedTransitionError("resource can't change attached error after it is set");
473
473
  resource.error = rd.error;
474
- incrementRefs.push(resource.error as ResourceId);
474
+ incrementRefs.push(resource.error);
475
475
  notEmpty(resource.resourceStateChange).markChanged(
476
476
  `error changed for ${resourceIdToString(resource.id)}`,
477
477
  );
@@ -494,8 +494,8 @@ export class PlTreeState {
494
494
  fd.valueIsFinal,
495
495
  resource.version,
496
496
  );
497
- if (isNotNullResourceId(fd.value)) incrementRefs.push(fd.value);
498
- if (isNotNullResourceId(fd.error)) incrementRefs.push(fd.error);
497
+ if (isNotNullSignedResourceId(fd.value)) incrementRefs.push(fd.value);
498
+ if (isNotNullSignedResourceId(fd.error)) incrementRefs.push(fd.error);
499
499
 
500
500
  if (fd.type === "Input" || fd.type === "Service") {
501
501
  if (resource.inputsLocked)
@@ -559,9 +559,9 @@ export class PlTreeState {
559
559
 
560
560
  // field value
561
561
  if (field.value !== fd.value) {
562
- if (isNotNullResourceId(field.value)) decrementRefs.push(field.value);
562
+ if (isNotNullSignedResourceId(field.value)) decrementRefs.push(field.value);
563
563
  field.value = fd.value;
564
- if (isNotNullResourceId(fd.value)) incrementRefs.push(fd.value);
564
+ if (isNotNullSignedResourceId(fd.value)) incrementRefs.push(fd.value);
565
565
  field.change.markChanged(
566
566
  `field ${fd.name} value changed in ${resourceIdToString(resource.id)}`,
567
567
  );
@@ -570,9 +570,9 @@ export class PlTreeState {
570
570
 
571
571
  // field error
572
572
  if (field.error !== fd.error) {
573
- if (isNotNullResourceId(field.error)) decrementRefs.push(field.error);
573
+ if (isNotNullSignedResourceId(field.error)) decrementRefs.push(field.error);
574
574
  field.error = fd.error;
575
- if (isNotNullResourceId(fd.error)) incrementRefs.push(fd.error);
575
+ if (isNotNullSignedResourceId(fd.error)) incrementRefs.push(fd.error);
576
576
  field.change.markChanged(
577
577
  `field ${fd.name} error changed in ${resourceIdToString(resource.id)}`,
578
578
  );
@@ -611,8 +611,8 @@ export class PlTreeState {
611
611
  );
612
612
  fields.delete(fieldName);
613
613
 
614
- if (isNotNullResourceId(field.value)) decrementRefs.push(field.value);
615
- if (isNotNullResourceId(field.error)) decrementRefs.push(field.error);
614
+ if (isNotNullSignedResourceId(field.value)) decrementRefs.push(field.value);
615
+ if (isNotNullSignedResourceId(field.error)) decrementRefs.push(field.error);
616
616
 
617
617
  notEmpty(resource!.dynamicFieldListChanged).markChanged(
618
618
  `dynamic field ${fieldName} removed from ${resourceIdToString(resource!.id)}`,
@@ -700,7 +700,7 @@ export class PlTreeState {
700
700
 
701
701
  resource = new PlTreeResource(rd);
702
702
  resource.verifyReadyState();
703
- if (isNotNullResourceId(resource.error)) incrementRefs.push(resource.error);
703
+ if (isNotNullSignedResourceId(resource.error)) incrementRefs.push(resource.error);
704
704
  for (const fd of rd.fields) {
705
705
  const field = new PlTreeField(
706
706
  fd.name,
@@ -711,8 +711,8 @@ export class PlTreeState {
711
711
  fd.valueIsFinal,
712
712
  InitialResourceVersion,
713
713
  );
714
- if (isNotNullResourceId(fd.value)) incrementRefs.push(fd.value);
715
- if (isNotNullResourceId(fd.error)) incrementRefs.push(fd.error);
714
+ if (isNotNullSignedResourceId(fd.value)) incrementRefs.push(fd.value);
715
+ if (isNotNullSignedResourceId(fd.error)) incrementRefs.push(fd.error);
716
716
  resource.fieldsMap.set(fd.name, field);
717
717
  }
718
718
 
@@ -741,7 +741,7 @@ export class PlTreeState {
741
741
  // recursively applying refCount decrements / doing garbage collection
742
742
  let currentRefs = decrementRefs;
743
743
  while (currentRefs.length > 0) {
744
- const nextRefs: ResourceId[] = [];
744
+ const nextRefs: SignedResourceId[] = [];
745
745
  for (const rid of currentRefs) {
746
746
  const res = this.resources.get(rid);
747
747
  if (!res) {
@@ -754,13 +754,13 @@ export class PlTreeState {
754
754
  if (res.refCount === 0 && res.id !== this.root) {
755
755
  // removing fields
756
756
  res.fieldsMap.forEach((field) => {
757
- if (isNotNullResourceId(field.value)) nextRefs.push(field.value);
758
- if (isNotNullResourceId(field.error)) nextRefs.push(field.error);
757
+ if (isNotNullSignedResourceId(field.value)) nextRefs.push(field.value);
758
+ if (isNotNullSignedResourceId(field.error)) nextRefs.push(field.error);
759
759
  field.change.markChanged(
760
760
  `field ${field.name} removed during garbage collection of ${resourceIdToString(res.id)}`,
761
761
  );
762
762
  });
763
- if (isNotNullResourceId(res.error)) nextRefs.push(res.error);
763
+ if (isNotNullSignedResourceId(res.error)) nextRefs.push(res.error);
764
764
  res.resourceRemoved.markChanged(
765
765
  `resource removed during garbage collection: ${resourceIdToString(res.id)}`,
766
766
  );
@@ -782,12 +782,12 @@ export class PlTreeState {
782
782
  }
783
783
 
784
784
  /** @deprecated use "entry" instead */
785
- public accessor(rid: ResourceId = this.root): PlTreeEntry {
785
+ public accessor(rid: SignedResourceId = this.root): PlTreeEntry {
786
786
  this.checkValid();
787
787
  return this.entry(rid);
788
788
  }
789
789
 
790
- public entry(rid: ResourceId = this.root): PlTreeEntry {
790
+ public entry(rid: SignedResourceId = this.root): PlTreeEntry {
791
791
  this.checkValid();
792
792
  return new PlTreeEntry({ treeProvider: () => this }, rid);
793
793
  }
package/src/sync.ts CHANGED
@@ -1,11 +1,11 @@
1
1
  import type {
2
2
  FieldData,
3
- OptionalResourceId,
3
+ OptionalSignedResourceId,
4
4
  PlTransaction,
5
- ResourceId,
5
+ SignedResourceId,
6
6
  } from "@milaboratories/pl-client";
7
7
  import Denque from "denque";
8
- import { isNullResourceId } from "@milaboratories/pl-client";
8
+ import { isNullSignedResourceId } from "@milaboratories/pl-client";
9
9
  import type { ExtendedResourceData, PlTreeState } from "./state";
10
10
  import { ConcurrencyLimitingExecutor, msToHumanReadable } from "@milaboratories/ts-helpers";
11
11
 
@@ -16,12 +16,12 @@ export interface TreeLoadingRequest {
16
16
  /** Resource to prime the traversal algorithm. It is ok, if some of them
17
17
  * doesn't exist anymore. Should not contain elements from final resource
18
18
  * set. */
19
- readonly seedResources: ResourceId[];
19
+ readonly seedResources: SignedResourceId[];
20
20
 
21
21
  /** Resource ids for which state is already known and not expected to change.
22
22
  * Algorithm will not continue traversal over those ids, and states will not
23
23
  * be retrieved for them. */
24
- readonly finalResources: Set<ResourceId>;
24
+ readonly finalResources: Set<SignedResourceId>;
25
25
 
26
26
  /** This function is applied to each resource data field list, before
27
27
  * using it continue traversal. This modification also is applied to
@@ -37,8 +37,8 @@ export function constructTreeLoadingRequest(
37
37
  tree: PlTreeState,
38
38
  pruningFunction?: PruningFunction,
39
39
  ): TreeLoadingRequest {
40
- const seedResources: ResourceId[] = [];
41
- const finalResources = new Set<ResourceId>();
40
+ const seedResources: SignedResourceId[] = [];
41
+ const finalResources = new Set<SignedResourceId>();
42
42
  tree.forEachResource((res) => {
43
43
  if (res.finalState) finalResources.add(res.id);
44
44
  else seedResources.push(res.id);
@@ -120,11 +120,11 @@ export async function loadTreeState(
120
120
  let numberOfRoundTrips = 0;
121
121
 
122
122
  // tracking resources we already requested or queued
123
- const requested = new Set<ResourceId>();
123
+ const requested = new Set<SignedResourceId>();
124
124
 
125
125
  /** Mark a resource for fetching. Deduplicates and respects final-resource set. */
126
- const requestState = (rid: OptionalResourceId) => {
127
- if (isNullResourceId(rid) || requested.has(rid)) return;
126
+ const requestState = (rid: OptionalSignedResourceId) => {
127
+ if (isNullSignedResourceId(rid) || requested.has(rid)) return;
128
128
 
129
129
  if (finalResources.has(rid)) {
130
130
  if (stats) stats.finalResourcesSkipped++;
@@ -3,7 +3,7 @@ import { PlTreeEntry } from "./accessors";
3
3
  import type {
4
4
  FinalResourceDataPredicate,
5
5
  PlClient,
6
- ResourceId,
6
+ SignedResourceId,
7
7
  TxOps,
8
8
  } from "@milaboratories/pl-client";
9
9
  import { isTimeoutOrCancelError } from "@milaboratories/pl-client";
@@ -52,7 +52,7 @@ export class SynchronizedTreeState {
52
52
 
53
53
  private constructor(
54
54
  private readonly pl: PlClient,
55
- private readonly root: ResourceId,
55
+ private readonly root: SignedResourceId,
56
56
  ops: SynchronizedTreeOps,
57
57
  private readonly logger?: MiLogger,
58
58
  ) {
@@ -71,12 +71,12 @@ export class SynchronizedTreeState {
71
71
  }
72
72
 
73
73
  /** @deprecated use "entry" instead */
74
- public accessor(rid: ResourceId = this.root): PlTreeEntry {
74
+ public accessor(rid: SignedResourceId = this.root): PlTreeEntry {
75
75
  if (this.terminated) throw new Error("tree synchronization is terminated");
76
76
  return this.entry(rid);
77
77
  }
78
78
 
79
- public entry(rid: ResourceId = this.root): PlTreeEntry {
79
+ public entry(rid: SignedResourceId = this.root): PlTreeEntry {
80
80
  if (this.terminated) throw new Error("tree synchronization is terminated");
81
81
  return new PlTreeEntry({ treeProvider: () => this.state, hooks: this.hooks }, rid);
82
82
  }
@@ -260,7 +260,7 @@ export class SynchronizedTreeState {
260
260
 
261
261
  public static async init(
262
262
  pl: PlClient,
263
- root: ResourceId,
263
+ root: SignedResourceId,
264
264
  ops: SynchronizedTreeOps,
265
265
  logger?: MiLogger,
266
266
  ) {