@milaboratories/pl-tree 1.12.14 → 1.12.15
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 +61 -0
- package/dist/accessors.cjs.map +1 -1
- package/dist/accessors.d.ts +29 -1
- package/dist/accessors.d.ts.map +1 -1
- package/dist/accessors.js +58 -1
- package/dist/accessors.js.map +1 -1
- package/dist/index.cjs +4 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.js +2 -2
- package/dist/state.cjs +70 -9
- package/dist/state.cjs.map +1 -1
- package/dist/state.d.ts +31 -4
- package/dist/state.d.ts.map +1 -1
- package/dist/state.js +70 -9
- package/dist/state.js.map +1 -1
- package/dist/sync.cjs +3 -1
- package/dist/sync.cjs.map +1 -1
- package/dist/sync.d.ts.map +1 -1
- package/dist/sync.js +3 -1
- package/dist/sync.js.map +1 -1
- package/dist/synchronized_tree.cjs +103 -10
- package/dist/synchronized_tree.cjs.map +1 -1
- package/dist/synchronized_tree.d.ts +49 -5
- package/dist/synchronized_tree.d.ts.map +1 -1
- package/dist/synchronized_tree.js +105 -12
- package/dist/synchronized_tree.js.map +1 -1
- package/package.json +4 -4
- package/src/accessors.ts +79 -0
- package/src/state.ts +101 -12
- package/src/sync.ts +3 -2
- package/src/synchronized_tree.ts +153 -12
package/dist/accessors.cjs
CHANGED
|
@@ -262,14 +262,75 @@ var PlTreeNodeAccessor = class {
|
|
|
262
262
|
return new PlTreeEntry(this.accessorData, this.resource.id);
|
|
263
263
|
}
|
|
264
264
|
};
|
|
265
|
+
/** Reactive provider for the current root SET of a multi-root tree. Mirrors {@link PlTreeEntry}:
|
|
266
|
+
* reading it inside a Computable tracks the root set as a dependency, so the Computable
|
|
267
|
+
* recomputes when discovered roots appear or disappear. */
|
|
268
|
+
var PlTreeRootsEntry = class {
|
|
269
|
+
accessorData;
|
|
270
|
+
__pl_tree_type_marker__ = "PlTreeRootsEntry";
|
|
271
|
+
constructor(accessorData) {
|
|
272
|
+
this.accessorData = accessorData;
|
|
273
|
+
}
|
|
274
|
+
createAccessor(ctx, guard) {
|
|
275
|
+
return new PlTreeRootsAccessor(this.accessorData, this.accessorData.treeProvider(), {
|
|
276
|
+
ctx,
|
|
277
|
+
guard
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
toJSON() {
|
|
281
|
+
return "[ROOTS-ENTRY]";
|
|
282
|
+
}
|
|
283
|
+
toString() {
|
|
284
|
+
return "[ROOTS-ENTRY]";
|
|
285
|
+
}
|
|
286
|
+
};
|
|
287
|
+
function isPlTreeRootsEntry(obj) {
|
|
288
|
+
return typeof obj === "object" && obj !== null && obj["__pl_tree_type_marker__"] === "PlTreeRootsEntry";
|
|
289
|
+
}
|
|
290
|
+
/** Accessor over the current roots of a multi-root tree. Reading any of its methods tracks
|
|
291
|
+
* the root set as a dependency (via {@link PlTreeState.getRoots}). */
|
|
292
|
+
var PlTreeRootsAccessor = class {
|
|
293
|
+
accessorData;
|
|
294
|
+
tree;
|
|
295
|
+
instanceData;
|
|
296
|
+
__pl_tree_type_marker__ = "PlTreeRootsAccessor";
|
|
297
|
+
constructor(accessorData, tree, instanceData) {
|
|
298
|
+
this.accessorData = accessorData;
|
|
299
|
+
this.tree = tree;
|
|
300
|
+
this.instanceData = instanceData;
|
|
301
|
+
}
|
|
302
|
+
/** Current root ids. */
|
|
303
|
+
rootIds() {
|
|
304
|
+
this.instanceData.guard();
|
|
305
|
+
return this.tree.getRoots(this.instanceData.ctx.watcher);
|
|
306
|
+
}
|
|
307
|
+
/** Current roots as node accessors, ready to traverse. */
|
|
308
|
+
nodes(ops = {}) {
|
|
309
|
+
this.instanceData.guard();
|
|
310
|
+
if (this.accessorData.hooks !== void 0) this.instanceData.ctx.attacheHooks(this.accessorData.hooks);
|
|
311
|
+
return this.tree.getRoots(this.instanceData.ctx.watcher).map((rid) => getResourceFromTree(this.accessorData, this.tree, this.instanceData, rid, ops));
|
|
312
|
+
}
|
|
313
|
+
/** Current roots as entries, for persisting per-root sub-Computables. */
|
|
314
|
+
entries() {
|
|
315
|
+
this.instanceData.guard();
|
|
316
|
+
return this.tree.getRoots(this.instanceData.ctx.watcher).map((rid) => new PlTreeEntry(this.accessorData, rid));
|
|
317
|
+
}
|
|
318
|
+
};
|
|
319
|
+
function isPlTreeRootsAccessor(obj) {
|
|
320
|
+
return typeof obj === "object" && obj !== null && obj["__pl_tree_type_marker__"] === "PlTreeRootsAccessor";
|
|
321
|
+
}
|
|
265
322
|
//#endregion
|
|
266
323
|
exports.PlError = PlError;
|
|
267
324
|
exports.PlTreeEntry = PlTreeEntry;
|
|
268
325
|
exports.PlTreeEntryAccessor = PlTreeEntryAccessor;
|
|
269
326
|
exports.PlTreeNodeAccessor = PlTreeNodeAccessor;
|
|
327
|
+
exports.PlTreeRootsAccessor = PlTreeRootsAccessor;
|
|
328
|
+
exports.PlTreeRootsEntry = PlTreeRootsEntry;
|
|
270
329
|
exports.isPlTreeEntry = isPlTreeEntry;
|
|
271
330
|
exports.isPlTreeEntryAccessor = isPlTreeEntryAccessor;
|
|
272
331
|
exports.isPlTreeNodeAccessor = isPlTreeNodeAccessor;
|
|
332
|
+
exports.isPlTreeRootsAccessor = isPlTreeRootsAccessor;
|
|
333
|
+
exports.isPlTreeRootsEntry = isPlTreeRootsEntry;
|
|
273
334
|
exports.treeEntryToResourceInfo = treeEntryToResourceInfo;
|
|
274
335
|
|
|
275
336
|
//# sourceMappingURL=accessors.cjs.map
|
package/dist/accessors.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"accessors.cjs","names":["mapValueAndError"],"sources":["../src/accessors.ts"],"sourcesContent":["import type { PlTreeResource, PlTreeState } from \"./state\";\nimport type {\n AccessorProvider,\n ComputableCtx,\n ComputableHooks,\n UsageGuard,\n} from \"@milaboratories/computable\";\nimport type {\n SignedResourceId,\n ResourceType,\n OptionalSignedResourceId,\n} from \"@milaboratories/pl-client\";\nimport {\n resourceIdToString,\n resourceTypesEqual,\n resourceTypeToString,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n NullSignedResourceId,\n} from \"@milaboratories/pl-client\";\nimport type { ValueAndError } from \"./value_and_error\";\nimport { mapValueAndError } from \"./value_and_error\";\nimport type {\n CommonFieldTraverseOps,\n FieldTraversalStep,\n GetFieldStep,\n ResourceTraversalOps,\n} from \"./traversal_ops\";\nimport type { ValueOrError } from \"./value_or_error\";\nimport { parsePlError } from \"@milaboratories/pl-errors\";\nimport { notEmpty } from \"@milaboratories/ts-helpers\";\n/** Error encountered during traversal in field or resource. */\nexport class PlError extends Error {\n constructor(message: string) {\n super(message);\n }\n}\n\nexport type TreeAccessorData = {\n readonly treeProvider: () => PlTreeState;\n readonly hooks?: ComputableHooks;\n};\n\nexport type TreeAccessorInstanceData = {\n readonly guard: UsageGuard;\n readonly ctx: ComputableCtx;\n};\n\nexport function isPlTreeEntry(obj: unknown): obj is PlTreeEntry {\n return (\n typeof obj === \"object\" &&\n obj !== null &&\n (obj as any)[\"__pl_tree_type_marker__\"] === \"PlTreeEntry\"\n );\n}\n\nexport function isPlTreeEntryAccessor(obj: unknown): obj is PlTreeEntryAccessor {\n return (\n typeof obj === \"object\" &&\n obj !== null &&\n (obj as any)[\"__pl_tree_type_marker__\"] === \"PlTreeEntryAccessor\"\n );\n}\n\nexport function isPlTreeNodeAccessor(obj: unknown): obj is PlTreeNodeAccessor {\n return (\n typeof obj === \"object\" &&\n obj !== null &&\n (obj as any)[\"__pl_tree_type_marker__\"] === \"PlTreeNodeAccessor\"\n );\n}\n\n/** Main entry point for using PlTree in reactive setting */\nexport class PlTreeEntry implements AccessorProvider<PlTreeEntryAccessor> {\n private readonly __pl_tree_type_marker__ = \"PlTreeEntry\";\n\n constructor(\n private readonly accessorData: TreeAccessorData,\n public readonly rid: SignedResourceId, // only for runtime. Not exposing rid at all causes too much pain. Never persist this anywhere.\n ) {}\n\n public createAccessor(ctx: ComputableCtx, guard: UsageGuard): PlTreeEntryAccessor {\n return new PlTreeEntryAccessor(this.accessorData, this.accessorData.treeProvider(), this.rid, {\n ctx,\n guard,\n });\n }\n\n /**\n * Tree TreeEntry ID suitable for persistence and use in names (files/objects/whatever), as it does not\n * contain signature which can change from session to session.\n */\n public get id(): string {\n return resourceIdToString(this.rid);\n }\n\n public toJSON(): string {\n return this.toString();\n }\n\n public toString(): string {\n return `[ENTRY:${resourceIdToString(this.rid)}]`;\n }\n}\n\nfunction getResourceFromTree(\n accessorData: TreeAccessorData,\n tree: PlTreeState,\n instanceData: TreeAccessorInstanceData,\n rid: SignedResourceId,\n ops: ResourceTraversalOps,\n): PlTreeNodeAccessor {\n const acc = new PlTreeNodeAccessor(\n accessorData,\n tree,\n tree.get(instanceData.ctx.watcher, rid),\n instanceData,\n );\n\n if (!ops.ignoreError) {\n const err = acc.getError();\n if (err !== undefined)\n throw parsePlError(notEmpty(err.getDataAsString()), acc.id, acc.resourceType);\n }\n\n if (\n ops.assertResourceType !== undefined &&\n (Array.isArray(ops.assertResourceType)\n ? ops.assertResourceType.findIndex((rt) => resourceTypesEqual(rt, acc.resourceType)) === -1\n : !resourceTypesEqual(ops.assertResourceType, acc.resourceType))\n )\n throw new Error(\n // eslint-disable-next-line @typescript-eslint/no-base-to-string\n `wrong resource type ${resourceTypeToString(acc.resourceType)} but expected ${ops.assertResourceType}`,\n );\n\n return acc;\n}\n\nexport class PlTreeEntryAccessor {\n private readonly __pl_tree_type_marker__ = \"PlTreeEntryAccessor\";\n\n constructor(\n private readonly accessorData: TreeAccessorData,\n private readonly tree: PlTreeState,\n private readonly rid: SignedResourceId,\n private readonly instanceData: TreeAccessorInstanceData,\n ) {}\n\n node(ops: ResourceTraversalOps = {}): PlTreeNodeAccessor {\n this.instanceData.guard();\n\n // this is the only entry point to acquire a PlTreeNodeAccessor,\n // so this is the only point where we should attach the hooks\n if (this.accessorData.hooks !== undefined)\n this.instanceData.ctx.attacheHooks(this.accessorData.hooks);\n\n return getResourceFromTree(this.accessorData, this.tree, this.instanceData, this.rid, ops);\n }\n}\n\n/**\n * Helper type to simplify implementation of APIs requiring type information.\n * */\nexport type ResourceInfo = {\n readonly id: SignedResourceId;\n readonly type: ResourceType;\n};\n\n/**\n * Can be called only when a ctx is provided, because pl tree entry is a computable entity.\n * @deprecated\n * */\nexport function treeEntryToResourceInfo(res: PlTreeEntry | ResourceInfo, ctx: ComputableCtx) {\n if (res instanceof PlTreeEntry) return ctx.accessor(res).node().resourceInfo;\n\n return res;\n}\n\n/**\n * API contracts:\n * - API never return {@link NullSignedResourceId}, absence of link is always modeled as `undefined`\n *\n * Important: never store instances of this class, always get fresh instance from {@link PlTreeState} accessor.\n * */\nexport class PlTreeNodeAccessor {\n private readonly __pl_tree_type_marker__ = \"PlTreeNodeAccessor\";\n\n constructor(\n private readonly accessorData: TreeAccessorData,\n private readonly tree: PlTreeState,\n private readonly resource: PlTreeResource,\n private readonly instanceData: TreeAccessorInstanceData,\n ) {}\n\n public get id(): SignedResourceId {\n this.instanceData.guard();\n return this.resource.id;\n }\n\n public get originalId(): OptionalSignedResourceId {\n this.instanceData.guard();\n return this.resource.originalResourceId;\n }\n\n public get resourceType(): ResourceType {\n this.instanceData.guard();\n return this.resource.type;\n }\n\n public get resourceInfo(): ResourceInfo {\n return { id: this.id, type: this.resourceType };\n }\n\n private getResourceFromTree(\n rid: SignedResourceId,\n ops: ResourceTraversalOps,\n ): PlTreeNodeAccessor {\n return getResourceFromTree(this.accessorData, this.tree, this.instanceData, rid, ops);\n }\n\n public traverse(\n ...steps: [\n Omit<FieldTraversalStep, \"errorIfFieldNotSet\"> & {\n errorIfFieldNotSet: true;\n },\n ]\n ): PlTreeNodeAccessor;\n public traverse(...steps: (FieldTraversalStep | string)[]): PlTreeNodeAccessor | undefined;\n public traverse(...steps: (FieldTraversalStep | string)[]): PlTreeNodeAccessor | undefined {\n return this.traverseWithCommon({}, ...steps);\n }\n\n public traverseOrError(\n ...steps: [\n Omit<FieldTraversalStep, \"errorIfFieldNotSet\"> & {\n errorIfFieldNotSet: true;\n },\n ]\n ): ValueOrError<PlTreeNodeAccessor, Error>;\n public traverseOrError(\n ...steps: (FieldTraversalStep | string)[]\n ): ValueOrError<PlTreeNodeAccessor, Error> | undefined;\n public traverseOrError(\n ...steps: (FieldTraversalStep | string)[]\n ): ValueOrError<PlTreeNodeAccessor, Error> | undefined {\n return this.traverseOrErrorWithCommon({}, ...steps);\n }\n\n public traverseWithCommon(\n commonOptions: CommonFieldTraverseOps,\n ...steps: (FieldTraversalStep | string)[]\n ): PlTreeNodeAccessor | undefined {\n const result = this.traverseOrErrorWithCommon(commonOptions, ...steps);\n if (result === undefined) return undefined;\n\n if (!result.ok) throw result.error;\n return result.value;\n }\n\n public traverseOrErrorWithCommon(\n commonOptions: CommonFieldTraverseOps,\n ...steps: (FieldTraversalStep | string)[]\n ): ValueOrError<PlTreeNodeAccessor, Error> | undefined {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n let current: PlTreeNodeAccessor = this;\n\n for (const _step of steps) {\n const step: FieldTraversalStep =\n typeof _step === \"string\"\n ? {\n ...commonOptions,\n field: _step,\n }\n : { ...commonOptions, ..._step };\n\n const next = current.getField(_step);\n\n if (next === undefined) return undefined;\n\n if (step.pureFieldErrorToUndefined && next.value === undefined && next.error !== undefined)\n return undefined;\n\n if ((!step.ignoreError || next.value === undefined) && next.error !== undefined)\n return {\n ok: false,\n\n // FIXME: in next tickets we'll allow Errors to be thrown.\n error: parsePlError(\n notEmpty(next.error.getDataAsString()),\n current.id,\n current.resourceType,\n step.field,\n ),\n };\n\n if (next.value === undefined) {\n if (step.errorIfFieldNotSet)\n return {\n ok: false,\n error: new Error(\n `field have no assigned value ${step.field} of ${resourceIdToString(current.id)}`,\n ),\n };\n // existing but unpopulated field is unstable because it must be resolved at some point\n this.onUnstableLambda(\"unpopulated_field:\" + step.field);\n return undefined;\n }\n\n current = next.value;\n }\n return { ok: true, value: current };\n }\n\n private readonly onUnstableLambda = (marker: string) => {\n this.instanceData.ctx.markUnstable(marker);\n };\n\n public getField(\n _step:\n | (Omit<GetFieldStep, \"errorIfFieldNotFound\"> & { errorIfFieldNotFound: true })\n | (Omit<GetFieldStep, \"errorIfFieldNotSet\"> & { errorIfFieldNotSet: true }),\n ): ValueAndError<PlTreeNodeAccessor>;\n public getField(_step: GetFieldStep | string): ValueAndError<PlTreeNodeAccessor> | undefined;\n public getField(_step: GetFieldStep | string): ValueAndError<PlTreeNodeAccessor> | undefined {\n this.instanceData.guard();\n const step: GetFieldStep = typeof _step === \"string\" ? { field: _step } : _step;\n\n const ve = this.resource.getField(this.instanceData.ctx.watcher, step, this.onUnstableLambda);\n\n if (ve === undefined) return undefined;\n\n return mapValueAndError(ve, (rid) => this.getResourceFromTree(rid, { ignoreError: true }));\n }\n\n public getInputsLocked(): boolean {\n this.instanceData.guard();\n const result = this.resource.getInputsLocked(this.instanceData.ctx.watcher);\n if (!result) this.instanceData.ctx.markUnstable(\"inputs_unlocked:\" + this.resourceType.name);\n return result;\n }\n\n public getOutputsLocked(): boolean {\n this.instanceData.guard();\n const result = this.resource.getOutputsLocked(this.instanceData.ctx.watcher);\n if (!result) this.instanceData.ctx.markUnstable(\"outputs_unlocked:\" + this.resourceType.name);\n return result;\n }\n\n public getIsReadyOrError(): boolean {\n this.instanceData.guard();\n const result = this.resource.getIsReadyOrError(this.instanceData.ctx.watcher);\n if (!result) this.instanceData.ctx.markUnstable(\"not_ready:\" + this.resourceType.name);\n return result;\n }\n\n public getIsFinal() {\n this.instanceData.guard();\n return this.resource.getIsFinal(this.instanceData.ctx.watcher);\n }\n\n public getError(): PlTreeNodeAccessor | undefined {\n this.instanceData.guard();\n const rid = this.resource.getError(this.instanceData.ctx.watcher);\n if (rid === undefined)\n // absence of error always considered as stable\n return undefined;\n return this.getResourceFromTree(rid, {});\n }\n\n public getData(): Uint8Array | undefined {\n return this.resource.data;\n }\n\n public getDataAsString(): string | undefined {\n return this.resource.getDataAsString();\n }\n\n public getDataAsJson<T = unknown>(): T | undefined {\n return this.resource.getDataAsJson<T>();\n }\n\n public listInputFields(): string[] {\n this.instanceData.guard();\n this.getInputsLocked(); // will set unstable if not locked\n return this.resource.listInputFields(this.instanceData.ctx.watcher);\n }\n\n public listOutputFields(): string[] {\n this.instanceData.guard();\n this.getOutputsLocked(); // will set unstable if not locked\n return this.resource.listOutputFields(this.instanceData.ctx.watcher);\n }\n\n public listDynamicFields(): string[] {\n this.instanceData.guard();\n return this.resource.listDynamicFields(this.instanceData.ctx.watcher);\n }\n\n public getKeyValue(key: string, unstableIfNotFound: boolean = false): Uint8Array | undefined {\n this.instanceData.guard();\n const result = this.resource.getKeyValue(this.instanceData.ctx.watcher, key);\n if (result === undefined && unstableIfNotFound)\n this.instanceData.ctx.markUnstable(\"key_not_found_b:\" + key);\n return result;\n }\n\n /** @deprecated */\n public getKeyValueString(key: string): string | undefined {\n return this.getKeyValueAsString(key);\n }\n\n public getKeyValueAsString(key: string, unstableIfNotFound: boolean = false): string | undefined {\n this.instanceData.guard();\n const result = this.resource.getKeyValueString(this.instanceData.ctx.watcher, key);\n if (result === undefined && unstableIfNotFound)\n this.instanceData.ctx.markUnstable(\"key_not_found_s:\" + key);\n return result;\n }\n\n public getKeyValueAsJson<T = unknown>(\n key: string,\n unstableIfNotFound: boolean = false,\n ): T | undefined {\n const result = this.resource.getKeyValueAsJson<T>(this.instanceData.ctx.watcher, key);\n if (result === undefined) {\n if (unstableIfNotFound) this.instanceData.ctx.markUnstable(\"key_not_found_j:\" + key);\n return undefined;\n }\n return result;\n }\n\n /**\n * Can be used to pass a higher level accessor that will wrap the resource and throw its\n * errors on node resolution.\n * */\n public toEntryAccessor(): PlTreeEntryAccessor {\n return new PlTreeEntryAccessor(this.accessorData, this.tree, this.id, this.instanceData);\n }\n\n /** Can be passed to nested computable. */\n public persist(): PlTreeEntry {\n return new PlTreeEntry(this.accessorData, this.resource.id);\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"accessors.cjs","names":["mapValueAndError"],"sources":["../src/accessors.ts"],"sourcesContent":["import type { PlTreeResource, PlTreeState } from \"./state\";\nimport type {\n AccessorProvider,\n ComputableCtx,\n ComputableHooks,\n UsageGuard,\n} from \"@milaboratories/computable\";\nimport type {\n SignedResourceId,\n ResourceType,\n OptionalSignedResourceId,\n} from \"@milaboratories/pl-client\";\nimport {\n resourceIdToString,\n resourceTypesEqual,\n resourceTypeToString,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n NullSignedResourceId,\n} from \"@milaboratories/pl-client\";\nimport type { ValueAndError } from \"./value_and_error\";\nimport { mapValueAndError } from \"./value_and_error\";\nimport type {\n CommonFieldTraverseOps,\n FieldTraversalStep,\n GetFieldStep,\n ResourceTraversalOps,\n} from \"./traversal_ops\";\nimport type { ValueOrError } from \"./value_or_error\";\nimport { parsePlError } from \"@milaboratories/pl-errors\";\nimport { notEmpty } from \"@milaboratories/ts-helpers\";\n/** Error encountered during traversal in field or resource. */\nexport class PlError extends Error {\n constructor(message: string) {\n super(message);\n }\n}\n\nexport type TreeAccessorData = {\n readonly treeProvider: () => PlTreeState;\n readonly hooks?: ComputableHooks;\n};\n\nexport type TreeAccessorInstanceData = {\n readonly guard: UsageGuard;\n readonly ctx: ComputableCtx;\n};\n\nexport function isPlTreeEntry(obj: unknown): obj is PlTreeEntry {\n return (\n typeof obj === \"object\" &&\n obj !== null &&\n (obj as any)[\"__pl_tree_type_marker__\"] === \"PlTreeEntry\"\n );\n}\n\nexport function isPlTreeEntryAccessor(obj: unknown): obj is PlTreeEntryAccessor {\n return (\n typeof obj === \"object\" &&\n obj !== null &&\n (obj as any)[\"__pl_tree_type_marker__\"] === \"PlTreeEntryAccessor\"\n );\n}\n\nexport function isPlTreeNodeAccessor(obj: unknown): obj is PlTreeNodeAccessor {\n return (\n typeof obj === \"object\" &&\n obj !== null &&\n (obj as any)[\"__pl_tree_type_marker__\"] === \"PlTreeNodeAccessor\"\n );\n}\n\n/** Main entry point for using PlTree in reactive setting */\nexport class PlTreeEntry implements AccessorProvider<PlTreeEntryAccessor> {\n private readonly __pl_tree_type_marker__ = \"PlTreeEntry\";\n\n constructor(\n private readonly accessorData: TreeAccessorData,\n public readonly rid: SignedResourceId, // only for runtime. Not exposing rid at all causes too much pain. Never persist this anywhere.\n ) {}\n\n public createAccessor(ctx: ComputableCtx, guard: UsageGuard): PlTreeEntryAccessor {\n return new PlTreeEntryAccessor(this.accessorData, this.accessorData.treeProvider(), this.rid, {\n ctx,\n guard,\n });\n }\n\n /**\n * Tree TreeEntry ID suitable for persistence and use in names (files/objects/whatever), as it does not\n * contain signature which can change from session to session.\n */\n public get id(): string {\n return resourceIdToString(this.rid);\n }\n\n public toJSON(): string {\n return this.toString();\n }\n\n public toString(): string {\n return `[ENTRY:${resourceIdToString(this.rid)}]`;\n }\n}\n\nfunction getResourceFromTree(\n accessorData: TreeAccessorData,\n tree: PlTreeState,\n instanceData: TreeAccessorInstanceData,\n rid: SignedResourceId,\n ops: ResourceTraversalOps,\n): PlTreeNodeAccessor {\n const acc = new PlTreeNodeAccessor(\n accessorData,\n tree,\n tree.get(instanceData.ctx.watcher, rid),\n instanceData,\n );\n\n if (!ops.ignoreError) {\n const err = acc.getError();\n if (err !== undefined)\n throw parsePlError(notEmpty(err.getDataAsString()), acc.id, acc.resourceType);\n }\n\n if (\n ops.assertResourceType !== undefined &&\n (Array.isArray(ops.assertResourceType)\n ? ops.assertResourceType.findIndex((rt) => resourceTypesEqual(rt, acc.resourceType)) === -1\n : !resourceTypesEqual(ops.assertResourceType, acc.resourceType))\n )\n throw new Error(\n // eslint-disable-next-line @typescript-eslint/no-base-to-string\n `wrong resource type ${resourceTypeToString(acc.resourceType)} but expected ${ops.assertResourceType}`,\n );\n\n return acc;\n}\n\nexport class PlTreeEntryAccessor {\n private readonly __pl_tree_type_marker__ = \"PlTreeEntryAccessor\";\n\n constructor(\n private readonly accessorData: TreeAccessorData,\n private readonly tree: PlTreeState,\n private readonly rid: SignedResourceId,\n private readonly instanceData: TreeAccessorInstanceData,\n ) {}\n\n node(ops: ResourceTraversalOps = {}): PlTreeNodeAccessor {\n this.instanceData.guard();\n\n // this is the only entry point to acquire a PlTreeNodeAccessor,\n // so this is the only point where we should attach the hooks\n if (this.accessorData.hooks !== undefined)\n this.instanceData.ctx.attacheHooks(this.accessorData.hooks);\n\n return getResourceFromTree(this.accessorData, this.tree, this.instanceData, this.rid, ops);\n }\n}\n\n/**\n * Helper type to simplify implementation of APIs requiring type information.\n * */\nexport type ResourceInfo = {\n readonly id: SignedResourceId;\n readonly type: ResourceType;\n};\n\n/**\n * Can be called only when a ctx is provided, because pl tree entry is a computable entity.\n * @deprecated\n * */\nexport function treeEntryToResourceInfo(res: PlTreeEntry | ResourceInfo, ctx: ComputableCtx) {\n if (res instanceof PlTreeEntry) return ctx.accessor(res).node().resourceInfo;\n\n return res;\n}\n\n/**\n * API contracts:\n * - API never return {@link NullSignedResourceId}, absence of link is always modeled as `undefined`\n *\n * Important: never store instances of this class, always get fresh instance from {@link PlTreeState} accessor.\n * */\nexport class PlTreeNodeAccessor {\n private readonly __pl_tree_type_marker__ = \"PlTreeNodeAccessor\";\n\n constructor(\n private readonly accessorData: TreeAccessorData,\n private readonly tree: PlTreeState,\n private readonly resource: PlTreeResource,\n private readonly instanceData: TreeAccessorInstanceData,\n ) {}\n\n public get id(): SignedResourceId {\n this.instanceData.guard();\n return this.resource.id;\n }\n\n public get originalId(): OptionalSignedResourceId {\n this.instanceData.guard();\n return this.resource.originalResourceId;\n }\n\n public get resourceType(): ResourceType {\n this.instanceData.guard();\n return this.resource.type;\n }\n\n public get resourceInfo(): ResourceInfo {\n return { id: this.id, type: this.resourceType };\n }\n\n private getResourceFromTree(\n rid: SignedResourceId,\n ops: ResourceTraversalOps,\n ): PlTreeNodeAccessor {\n return getResourceFromTree(this.accessorData, this.tree, this.instanceData, rid, ops);\n }\n\n public traverse(\n ...steps: [\n Omit<FieldTraversalStep, \"errorIfFieldNotSet\"> & {\n errorIfFieldNotSet: true;\n },\n ]\n ): PlTreeNodeAccessor;\n public traverse(...steps: (FieldTraversalStep | string)[]): PlTreeNodeAccessor | undefined;\n public traverse(...steps: (FieldTraversalStep | string)[]): PlTreeNodeAccessor | undefined {\n return this.traverseWithCommon({}, ...steps);\n }\n\n public traverseOrError(\n ...steps: [\n Omit<FieldTraversalStep, \"errorIfFieldNotSet\"> & {\n errorIfFieldNotSet: true;\n },\n ]\n ): ValueOrError<PlTreeNodeAccessor, Error>;\n public traverseOrError(\n ...steps: (FieldTraversalStep | string)[]\n ): ValueOrError<PlTreeNodeAccessor, Error> | undefined;\n public traverseOrError(\n ...steps: (FieldTraversalStep | string)[]\n ): ValueOrError<PlTreeNodeAccessor, Error> | undefined {\n return this.traverseOrErrorWithCommon({}, ...steps);\n }\n\n public traverseWithCommon(\n commonOptions: CommonFieldTraverseOps,\n ...steps: (FieldTraversalStep | string)[]\n ): PlTreeNodeAccessor | undefined {\n const result = this.traverseOrErrorWithCommon(commonOptions, ...steps);\n if (result === undefined) return undefined;\n\n if (!result.ok) throw result.error;\n return result.value;\n }\n\n public traverseOrErrorWithCommon(\n commonOptions: CommonFieldTraverseOps,\n ...steps: (FieldTraversalStep | string)[]\n ): ValueOrError<PlTreeNodeAccessor, Error> | undefined {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n let current: PlTreeNodeAccessor = this;\n\n for (const _step of steps) {\n const step: FieldTraversalStep =\n typeof _step === \"string\"\n ? {\n ...commonOptions,\n field: _step,\n }\n : { ...commonOptions, ..._step };\n\n const next = current.getField(_step);\n\n if (next === undefined) return undefined;\n\n if (step.pureFieldErrorToUndefined && next.value === undefined && next.error !== undefined)\n return undefined;\n\n if ((!step.ignoreError || next.value === undefined) && next.error !== undefined)\n return {\n ok: false,\n\n // FIXME: in next tickets we'll allow Errors to be thrown.\n error: parsePlError(\n notEmpty(next.error.getDataAsString()),\n current.id,\n current.resourceType,\n step.field,\n ),\n };\n\n if (next.value === undefined) {\n if (step.errorIfFieldNotSet)\n return {\n ok: false,\n error: new Error(\n `field have no assigned value ${step.field} of ${resourceIdToString(current.id)}`,\n ),\n };\n // existing but unpopulated field is unstable because it must be resolved at some point\n this.onUnstableLambda(\"unpopulated_field:\" + step.field);\n return undefined;\n }\n\n current = next.value;\n }\n return { ok: true, value: current };\n }\n\n private readonly onUnstableLambda = (marker: string) => {\n this.instanceData.ctx.markUnstable(marker);\n };\n\n public getField(\n _step:\n | (Omit<GetFieldStep, \"errorIfFieldNotFound\"> & { errorIfFieldNotFound: true })\n | (Omit<GetFieldStep, \"errorIfFieldNotSet\"> & { errorIfFieldNotSet: true }),\n ): ValueAndError<PlTreeNodeAccessor>;\n public getField(_step: GetFieldStep | string): ValueAndError<PlTreeNodeAccessor> | undefined;\n public getField(_step: GetFieldStep | string): ValueAndError<PlTreeNodeAccessor> | undefined {\n this.instanceData.guard();\n const step: GetFieldStep = typeof _step === \"string\" ? { field: _step } : _step;\n\n const ve = this.resource.getField(this.instanceData.ctx.watcher, step, this.onUnstableLambda);\n\n if (ve === undefined) return undefined;\n\n return mapValueAndError(ve, (rid) => this.getResourceFromTree(rid, { ignoreError: true }));\n }\n\n public getInputsLocked(): boolean {\n this.instanceData.guard();\n const result = this.resource.getInputsLocked(this.instanceData.ctx.watcher);\n if (!result) this.instanceData.ctx.markUnstable(\"inputs_unlocked:\" + this.resourceType.name);\n return result;\n }\n\n public getOutputsLocked(): boolean {\n this.instanceData.guard();\n const result = this.resource.getOutputsLocked(this.instanceData.ctx.watcher);\n if (!result) this.instanceData.ctx.markUnstable(\"outputs_unlocked:\" + this.resourceType.name);\n return result;\n }\n\n public getIsReadyOrError(): boolean {\n this.instanceData.guard();\n const result = this.resource.getIsReadyOrError(this.instanceData.ctx.watcher);\n if (!result) this.instanceData.ctx.markUnstable(\"not_ready:\" + this.resourceType.name);\n return result;\n }\n\n public getIsFinal() {\n this.instanceData.guard();\n return this.resource.getIsFinal(this.instanceData.ctx.watcher);\n }\n\n public getError(): PlTreeNodeAccessor | undefined {\n this.instanceData.guard();\n const rid = this.resource.getError(this.instanceData.ctx.watcher);\n if (rid === undefined)\n // absence of error always considered as stable\n return undefined;\n return this.getResourceFromTree(rid, {});\n }\n\n public getData(): Uint8Array | undefined {\n return this.resource.data;\n }\n\n public getDataAsString(): string | undefined {\n return this.resource.getDataAsString();\n }\n\n public getDataAsJson<T = unknown>(): T | undefined {\n return this.resource.getDataAsJson<T>();\n }\n\n public listInputFields(): string[] {\n this.instanceData.guard();\n this.getInputsLocked(); // will set unstable if not locked\n return this.resource.listInputFields(this.instanceData.ctx.watcher);\n }\n\n public listOutputFields(): string[] {\n this.instanceData.guard();\n this.getOutputsLocked(); // will set unstable if not locked\n return this.resource.listOutputFields(this.instanceData.ctx.watcher);\n }\n\n public listDynamicFields(): string[] {\n this.instanceData.guard();\n return this.resource.listDynamicFields(this.instanceData.ctx.watcher);\n }\n\n public getKeyValue(key: string, unstableIfNotFound: boolean = false): Uint8Array | undefined {\n this.instanceData.guard();\n const result = this.resource.getKeyValue(this.instanceData.ctx.watcher, key);\n if (result === undefined && unstableIfNotFound)\n this.instanceData.ctx.markUnstable(\"key_not_found_b:\" + key);\n return result;\n }\n\n /** @deprecated */\n public getKeyValueString(key: string): string | undefined {\n return this.getKeyValueAsString(key);\n }\n\n public getKeyValueAsString(key: string, unstableIfNotFound: boolean = false): string | undefined {\n this.instanceData.guard();\n const result = this.resource.getKeyValueString(this.instanceData.ctx.watcher, key);\n if (result === undefined && unstableIfNotFound)\n this.instanceData.ctx.markUnstable(\"key_not_found_s:\" + key);\n return result;\n }\n\n public getKeyValueAsJson<T = unknown>(\n key: string,\n unstableIfNotFound: boolean = false,\n ): T | undefined {\n const result = this.resource.getKeyValueAsJson<T>(this.instanceData.ctx.watcher, key);\n if (result === undefined) {\n if (unstableIfNotFound) this.instanceData.ctx.markUnstable(\"key_not_found_j:\" + key);\n return undefined;\n }\n return result;\n }\n\n /**\n * Can be used to pass a higher level accessor that will wrap the resource and throw its\n * errors on node resolution.\n * */\n public toEntryAccessor(): PlTreeEntryAccessor {\n return new PlTreeEntryAccessor(this.accessorData, this.tree, this.id, this.instanceData);\n }\n\n /** Can be passed to nested computable. */\n public persist(): PlTreeEntry {\n return new PlTreeEntry(this.accessorData, this.resource.id);\n }\n}\n\n/** Reactive provider for the current root SET of a multi-root tree. Mirrors {@link PlTreeEntry}:\n * reading it inside a Computable tracks the root set as a dependency, so the Computable\n * recomputes when discovered roots appear or disappear. */\nexport class PlTreeRootsEntry implements AccessorProvider<PlTreeRootsAccessor> {\n private readonly __pl_tree_type_marker__ = \"PlTreeRootsEntry\";\n\n constructor(private readonly accessorData: TreeAccessorData) {}\n\n public createAccessor(ctx: ComputableCtx, guard: UsageGuard): PlTreeRootsAccessor {\n return new PlTreeRootsAccessor(this.accessorData, this.accessorData.treeProvider(), {\n ctx,\n guard,\n });\n }\n\n public toJSON(): string {\n return \"[ROOTS-ENTRY]\";\n }\n\n public toString(): string {\n return \"[ROOTS-ENTRY]\";\n }\n}\n\nexport function isPlTreeRootsEntry(obj: unknown): obj is PlTreeRootsEntry {\n return (\n typeof obj === \"object\" &&\n obj !== null &&\n (obj as any)[\"__pl_tree_type_marker__\"] === \"PlTreeRootsEntry\"\n );\n}\n\n/** Accessor over the current roots of a multi-root tree. Reading any of its methods tracks\n * the root set as a dependency (via {@link PlTreeState.getRoots}). */\nexport class PlTreeRootsAccessor {\n private readonly __pl_tree_type_marker__ = \"PlTreeRootsAccessor\";\n\n constructor(\n private readonly accessorData: TreeAccessorData,\n private readonly tree: PlTreeState,\n private readonly instanceData: TreeAccessorInstanceData,\n ) {}\n\n /** Current root ids. */\n public rootIds(): SignedResourceId[] {\n this.instanceData.guard();\n return this.tree.getRoots(this.instanceData.ctx.watcher);\n }\n\n /** Current roots as node accessors, ready to traverse. */\n public nodes(ops: ResourceTraversalOps = {}): PlTreeNodeAccessor[] {\n this.instanceData.guard();\n\n // mirror PlTreeEntryAccessor.node(): attach polling hooks on first node acquisition\n if (this.accessorData.hooks !== undefined)\n this.instanceData.ctx.attacheHooks(this.accessorData.hooks);\n\n return this.tree\n .getRoots(this.instanceData.ctx.watcher)\n .map((rid) => getResourceFromTree(this.accessorData, this.tree, this.instanceData, rid, ops));\n }\n\n /** Current roots as entries, for persisting per-root sub-Computables. */\n public entries(): PlTreeEntry[] {\n this.instanceData.guard();\n return this.tree\n .getRoots(this.instanceData.ctx.watcher)\n .map((rid) => new PlTreeEntry(this.accessorData, rid));\n }\n}\n\nexport function isPlTreeRootsAccessor(obj: unknown): obj is PlTreeRootsAccessor {\n return (\n typeof obj === \"object\" &&\n obj !== null &&\n (obj as any)[\"__pl_tree_type_marker__\"] === \"PlTreeRootsAccessor\"\n );\n}\n"],"mappings":";;;;;;AA+BA,IAAa,UAAb,cAA6B,MAAM;CACjC,YAAY,SAAiB;EAC3B,MAAM,OAAO;CACf;AACF;AAYA,SAAgB,cAAc,KAAkC;CAC9D,OACE,OAAO,QAAQ,YACf,QAAQ,QACP,IAAY,+BAA+B;AAEhD;AAEA,SAAgB,sBAAsB,KAA0C;CAC9E,OACE,OAAO,QAAQ,YACf,QAAQ,QACP,IAAY,+BAA+B;AAEhD;AAEA,SAAgB,qBAAqB,KAAyC;CAC5E,OACE,OAAO,QAAQ,YACf,QAAQ,QACP,IAAY,+BAA+B;AAEhD;;AAGA,IAAa,cAAb,MAA0E;CAIrD;CACD;CAJlB,0BAA2C;CAE3C,YACE,cACA,KACA;EAFiB,KAAA,eAAA;EACD,KAAA,MAAA;CACf;CAEH,eAAsB,KAAoB,OAAwC;EAChF,OAAO,IAAI,oBAAoB,KAAK,cAAc,KAAK,aAAa,aAAa,GAAG,KAAK,KAAK;GAC5F;GACA;EACF,CAAC;CACH;;;;;CAMA,IAAW,KAAa;EACtB,QAAA,GAAA,0BAAA,mBAAA,CAA0B,KAAK,GAAG;CACpC;CAEA,SAAwB;EACtB,OAAO,KAAK,SAAS;CACvB;CAEA,WAA0B;EACxB,OAAO,WAAA,GAAA,0BAAA,mBAAA,CAA6B,KAAK,GAAG,EAAE;CAChD;AACF;AAEA,SAAS,oBACP,cACA,MACA,cACA,KACA,KACoB;CACpB,MAAM,MAAM,IAAI,mBACd,cACA,MACA,KAAK,IAAI,aAAa,IAAI,SAAS,GAAG,GACtC,YACF;CAEA,IAAI,CAAC,IAAI,aAAa;EACpB,MAAM,MAAM,IAAI,SAAS;EACzB,IAAI,QAAQ,KAAA,GACV,OAAA,GAAA,0BAAA,aAAA,EAAA,GAAA,2BAAA,SAAA,CAA4B,IAAI,gBAAgB,CAAC,GAAG,IAAI,IAAI,IAAI,YAAY;CAChF;CAEA,IACE,IAAI,uBAAuB,KAAA,MAC1B,MAAM,QAAQ,IAAI,kBAAkB,IACjC,IAAI,mBAAmB,WAAW,QAAA,GAAA,0BAAA,mBAAA,CAA0B,IAAI,IAAI,YAAY,CAAC,MAAM,KACvF,EAAA,GAAA,0BAAA,mBAAA,CAAoB,IAAI,oBAAoB,IAAI,YAAY,IAEhE,MAAM,IAAI,MAER,wBAAA,GAAA,0BAAA,qBAAA,CAA4C,IAAI,YAAY,EAAE,gBAAgB,IAAI,oBACpF;CAEF,OAAO;AACT;AAEA,IAAa,sBAAb,MAAiC;CAIZ;CACA;CACA;CACA;CANnB,0BAA2C;CAE3C,YACE,cACA,MACA,KACA,cACA;EAJiB,KAAA,eAAA;EACA,KAAA,OAAA;EACA,KAAA,MAAA;EACA,KAAA,eAAA;CAChB;CAEH,KAAK,MAA4B,CAAC,GAAuB;EACvD,KAAK,aAAa,MAAM;EAIxB,IAAI,KAAK,aAAa,UAAU,KAAA,GAC9B,KAAK,aAAa,IAAI,aAAa,KAAK,aAAa,KAAK;EAE5D,OAAO,oBAAoB,KAAK,cAAc,KAAK,MAAM,KAAK,cAAc,KAAK,KAAK,GAAG;CAC3F;AACF;;;;;AAcA,SAAgB,wBAAwB,KAAiC,KAAoB;CAC3F,IAAI,eAAe,aAAa,OAAO,IAAI,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;CAEhE,OAAO;AACT;;;;;;;AAQA,IAAa,qBAAb,MAAgC;CAIX;CACA;CACA;CACA;CANnB,0BAA2C;CAE3C,YACE,cACA,MACA,UACA,cACA;EAJiB,KAAA,eAAA;EACA,KAAA,OAAA;EACA,KAAA,WAAA;EACA,KAAA,eAAA;CAChB;CAEH,IAAW,KAAuB;EAChC,KAAK,aAAa,MAAM;EACxB,OAAO,KAAK,SAAS;CACvB;CAEA,IAAW,aAAuC;EAChD,KAAK,aAAa,MAAM;EACxB,OAAO,KAAK,SAAS;CACvB;CAEA,IAAW,eAA6B;EACtC,KAAK,aAAa,MAAM;EACxB,OAAO,KAAK,SAAS;CACvB;CAEA,IAAW,eAA6B;EACtC,OAAO;GAAE,IAAI,KAAK;GAAI,MAAM,KAAK;EAAa;CAChD;CAEA,oBACE,KACA,KACoB;EACpB,OAAO,oBAAoB,KAAK,cAAc,KAAK,MAAM,KAAK,cAAc,KAAK,GAAG;CACtF;CAUA,SAAgB,GAAG,OAAwE;EACzF,OAAO,KAAK,mBAAmB,CAAC,GAAG,GAAG,KAAK;CAC7C;CAYA,gBACE,GAAG,OACkD;EACrD,OAAO,KAAK,0BAA0B,CAAC,GAAG,GAAG,KAAK;CACpD;CAEA,mBACE,eACA,GAAG,OAC6B;EAChC,MAAM,SAAS,KAAK,0BAA0B,eAAe,GAAG,KAAK;EACrE,IAAI,WAAW,KAAA,GAAW,OAAO,KAAA;EAEjC,IAAI,CAAC,OAAO,IAAI,MAAM,OAAO;EAC7B,OAAO,OAAO;CAChB;CAEA,0BACE,eACA,GAAG,OACkD;EAErD,IAAI,UAA8B;EAElC,KAAK,MAAM,SAAS,OAAO;GACzB,MAAM,OACJ,OAAO,UAAU,WACb;IACE,GAAG;IACH,OAAO;GACT,IACA;IAAE,GAAG;IAAe,GAAG;GAAM;GAEnC,MAAM,OAAO,QAAQ,SAAS,KAAK;GAEnC,IAAI,SAAS,KAAA,GAAW,OAAO,KAAA;GAE/B,IAAI,KAAK,6BAA6B,KAAK,UAAU,KAAA,KAAa,KAAK,UAAU,KAAA,GAC/E,OAAO,KAAA;GAET,KAAK,CAAC,KAAK,eAAe,KAAK,UAAU,KAAA,MAAc,KAAK,UAAU,KAAA,GACpE,OAAO;IACL,IAAI;IAGJ,QAAA,GAAA,0BAAA,aAAA,EAAA,GAAA,2BAAA,SAAA,CACW,KAAK,MAAM,gBAAgB,CAAC,GACrC,QAAQ,IACR,QAAQ,cACR,KAAK,KACP;GACF;GAEF,IAAI,KAAK,UAAU,KAAA,GAAW;IAC5B,IAAI,KAAK,oBACP,OAAO;KACL,IAAI;KACJ,uBAAO,IAAI,MACT,gCAAgC,KAAK,MAAM,OAAA,GAAA,0BAAA,mBAAA,CAAyB,QAAQ,EAAE,GAChF;IACF;IAEF,KAAK,iBAAiB,uBAAuB,KAAK,KAAK;IACvD;GACF;GAEA,UAAU,KAAK;EACjB;EACA,OAAO;GAAE,IAAI;GAAM,OAAO;EAAQ;CACpC;CAEA,oBAAqC,WAAmB;EACtD,KAAK,aAAa,IAAI,aAAa,MAAM;CAC3C;CAQA,SAAgB,OAA6E;EAC3F,KAAK,aAAa,MAAM;EACxB,MAAM,OAAqB,OAAO,UAAU,WAAW,EAAE,OAAO,MAAM,IAAI;EAE1E,MAAM,KAAK,KAAK,SAAS,SAAS,KAAK,aAAa,IAAI,SAAS,MAAM,KAAK,gBAAgB;EAE5F,IAAI,OAAO,KAAA,GAAW,OAAO,KAAA;EAE7B,OAAOA,wBAAAA,iBAAiB,KAAK,QAAQ,KAAK,oBAAoB,KAAK,EAAE,aAAa,KAAK,CAAC,CAAC;CAC3F;CAEA,kBAAkC;EAChC,KAAK,aAAa,MAAM;EACxB,MAAM,SAAS,KAAK,SAAS,gBAAgB,KAAK,aAAa,IAAI,OAAO;EAC1E,IAAI,CAAC,QAAQ,KAAK,aAAa,IAAI,aAAa,qBAAqB,KAAK,aAAa,IAAI;EAC3F,OAAO;CACT;CAEA,mBAAmC;EACjC,KAAK,aAAa,MAAM;EACxB,MAAM,SAAS,KAAK,SAAS,iBAAiB,KAAK,aAAa,IAAI,OAAO;EAC3E,IAAI,CAAC,QAAQ,KAAK,aAAa,IAAI,aAAa,sBAAsB,KAAK,aAAa,IAAI;EAC5F,OAAO;CACT;CAEA,oBAAoC;EAClC,KAAK,aAAa,MAAM;EACxB,MAAM,SAAS,KAAK,SAAS,kBAAkB,KAAK,aAAa,IAAI,OAAO;EAC5E,IAAI,CAAC,QAAQ,KAAK,aAAa,IAAI,aAAa,eAAe,KAAK,aAAa,IAAI;EACrF,OAAO;CACT;CAEA,aAAoB;EAClB,KAAK,aAAa,MAAM;EACxB,OAAO,KAAK,SAAS,WAAW,KAAK,aAAa,IAAI,OAAO;CAC/D;CAEA,WAAkD;EAChD,KAAK,aAAa,MAAM;EACxB,MAAM,MAAM,KAAK,SAAS,SAAS,KAAK,aAAa,IAAI,OAAO;EAChE,IAAI,QAAQ,KAAA,GAEV,OAAO,KAAA;EACT,OAAO,KAAK,oBAAoB,KAAK,CAAC,CAAC;CACzC;CAEA,UAAyC;EACvC,OAAO,KAAK,SAAS;CACvB;CAEA,kBAA6C;EAC3C,OAAO,KAAK,SAAS,gBAAgB;CACvC;CAEA,gBAAmD;EACjD,OAAO,KAAK,SAAS,cAAiB;CACxC;CAEA,kBAAmC;EACjC,KAAK,aAAa,MAAM;EACxB,KAAK,gBAAgB;EACrB,OAAO,KAAK,SAAS,gBAAgB,KAAK,aAAa,IAAI,OAAO;CACpE;CAEA,mBAAoC;EAClC,KAAK,aAAa,MAAM;EACxB,KAAK,iBAAiB;EACtB,OAAO,KAAK,SAAS,iBAAiB,KAAK,aAAa,IAAI,OAAO;CACrE;CAEA,oBAAqC;EACnC,KAAK,aAAa,MAAM;EACxB,OAAO,KAAK,SAAS,kBAAkB,KAAK,aAAa,IAAI,OAAO;CACtE;CAEA,YAAmB,KAAa,qBAA8B,OAA+B;EAC3F,KAAK,aAAa,MAAM;EACxB,MAAM,SAAS,KAAK,SAAS,YAAY,KAAK,aAAa,IAAI,SAAS,GAAG;EAC3E,IAAI,WAAW,KAAA,KAAa,oBAC1B,KAAK,aAAa,IAAI,aAAa,qBAAqB,GAAG;EAC7D,OAAO;CACT;;CAGA,kBAAyB,KAAiC;EACxD,OAAO,KAAK,oBAAoB,GAAG;CACrC;CAEA,oBAA2B,KAAa,qBAA8B,OAA2B;EAC/F,KAAK,aAAa,MAAM;EACxB,MAAM,SAAS,KAAK,SAAS,kBAAkB,KAAK,aAAa,IAAI,SAAS,GAAG;EACjF,IAAI,WAAW,KAAA,KAAa,oBAC1B,KAAK,aAAa,IAAI,aAAa,qBAAqB,GAAG;EAC7D,OAAO;CACT;CAEA,kBACE,KACA,qBAA8B,OACf;EACf,MAAM,SAAS,KAAK,SAAS,kBAAqB,KAAK,aAAa,IAAI,SAAS,GAAG;EACpF,IAAI,WAAW,KAAA,GAAW;GACxB,IAAI,oBAAoB,KAAK,aAAa,IAAI,aAAa,qBAAqB,GAAG;GACnF;EACF;EACA,OAAO;CACT;;;;;CAMA,kBAA8C;EAC5C,OAAO,IAAI,oBAAoB,KAAK,cAAc,KAAK,MAAM,KAAK,IAAI,KAAK,YAAY;CACzF;;CAGA,UAA8B;EAC5B,OAAO,IAAI,YAAY,KAAK,cAAc,KAAK,SAAS,EAAE;CAC5D;AACF;;;;AAKA,IAAa,mBAAb,MAA+E;CAGhD;CAF7B,0BAA2C;CAE3C,YAAY,cAAiD;EAAhC,KAAA,eAAA;CAAiC;CAE9D,eAAsB,KAAoB,OAAwC;EAChF,OAAO,IAAI,oBAAoB,KAAK,cAAc,KAAK,aAAa,aAAa,GAAG;GAClF;GACA;EACF,CAAC;CACH;CAEA,SAAwB;EACtB,OAAO;CACT;CAEA,WAA0B;EACxB,OAAO;CACT;AACF;AAEA,SAAgB,mBAAmB,KAAuC;CACxE,OACE,OAAO,QAAQ,YACf,QAAQ,QACP,IAAY,+BAA+B;AAEhD;;;AAIA,IAAa,sBAAb,MAAiC;CAIZ;CACA;CACA;CALnB,0BAA2C;CAE3C,YACE,cACA,MACA,cACA;EAHiB,KAAA,eAAA;EACA,KAAA,OAAA;EACA,KAAA,eAAA;CAChB;;CAGH,UAAqC;EACnC,KAAK,aAAa,MAAM;EACxB,OAAO,KAAK,KAAK,SAAS,KAAK,aAAa,IAAI,OAAO;CACzD;;CAGA,MAAa,MAA4B,CAAC,GAAyB;EACjE,KAAK,aAAa,MAAM;EAGxB,IAAI,KAAK,aAAa,UAAU,KAAA,GAC9B,KAAK,aAAa,IAAI,aAAa,KAAK,aAAa,KAAK;EAE5D,OAAO,KAAK,KACT,SAAS,KAAK,aAAa,IAAI,OAAO,CAAC,CACvC,KAAK,QAAQ,oBAAoB,KAAK,cAAc,KAAK,MAAM,KAAK,cAAc,KAAK,GAAG,CAAC;CAChG;;CAGA,UAAgC;EAC9B,KAAK,aAAa,MAAM;EACxB,OAAO,KAAK,KACT,SAAS,KAAK,aAAa,IAAI,OAAO,CAAC,CACvC,KAAK,QAAQ,IAAI,YAAY,KAAK,cAAc,GAAG,CAAC;CACzD;AACF;AAEA,SAAgB,sBAAsB,KAA0C;CAC9E,OACE,OAAO,QAAQ,YACf,QAAQ,QACP,IAAY,+BAA+B;AAEhD"}
|
package/dist/accessors.d.ts
CHANGED
|
@@ -116,6 +116,34 @@ declare class PlTreeNodeAccessor {
|
|
|
116
116
|
/** Can be passed to nested computable. */
|
|
117
117
|
persist(): PlTreeEntry;
|
|
118
118
|
}
|
|
119
|
+
/** Reactive provider for the current root SET of a multi-root tree. Mirrors {@link PlTreeEntry}:
|
|
120
|
+
* reading it inside a Computable tracks the root set as a dependency, so the Computable
|
|
121
|
+
* recomputes when discovered roots appear or disappear. */
|
|
122
|
+
declare class PlTreeRootsEntry implements AccessorProvider<PlTreeRootsAccessor> {
|
|
123
|
+
private readonly accessorData;
|
|
124
|
+
private readonly __pl_tree_type_marker__;
|
|
125
|
+
constructor(accessorData: TreeAccessorData);
|
|
126
|
+
createAccessor(ctx: ComputableCtx, guard: UsageGuard): PlTreeRootsAccessor;
|
|
127
|
+
toJSON(): string;
|
|
128
|
+
toString(): string;
|
|
129
|
+
}
|
|
130
|
+
declare function isPlTreeRootsEntry(obj: unknown): obj is PlTreeRootsEntry;
|
|
131
|
+
/** Accessor over the current roots of a multi-root tree. Reading any of its methods tracks
|
|
132
|
+
* the root set as a dependency (via {@link PlTreeState.getRoots}). */
|
|
133
|
+
declare class PlTreeRootsAccessor {
|
|
134
|
+
private readonly accessorData;
|
|
135
|
+
private readonly tree;
|
|
136
|
+
private readonly instanceData;
|
|
137
|
+
private readonly __pl_tree_type_marker__;
|
|
138
|
+
constructor(accessorData: TreeAccessorData, tree: PlTreeState, instanceData: TreeAccessorInstanceData);
|
|
139
|
+
/** Current root ids. */
|
|
140
|
+
rootIds(): SignedResourceId[];
|
|
141
|
+
/** Current roots as node accessors, ready to traverse. */
|
|
142
|
+
nodes(ops?: ResourceTraversalOps): PlTreeNodeAccessor[];
|
|
143
|
+
/** Current roots as entries, for persisting per-root sub-Computables. */
|
|
144
|
+
entries(): PlTreeEntry[];
|
|
145
|
+
}
|
|
146
|
+
declare function isPlTreeRootsAccessor(obj: unknown): obj is PlTreeRootsAccessor;
|
|
119
147
|
//#endregion
|
|
120
|
-
export { PlError, PlTreeEntry, PlTreeEntryAccessor, PlTreeNodeAccessor, ResourceInfo, TreeAccessorData, TreeAccessorInstanceData, isPlTreeEntry, isPlTreeEntryAccessor, isPlTreeNodeAccessor, treeEntryToResourceInfo };
|
|
148
|
+
export { PlError, PlTreeEntry, PlTreeEntryAccessor, PlTreeNodeAccessor, PlTreeRootsAccessor, PlTreeRootsEntry, ResourceInfo, TreeAccessorData, TreeAccessorInstanceData, isPlTreeEntry, isPlTreeEntryAccessor, isPlTreeNodeAccessor, isPlTreeRootsAccessor, isPlTreeRootsEntry, treeEntryToResourceInfo };
|
|
121
149
|
//# sourceMappingURL=accessors.d.ts.map
|
package/dist/accessors.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"accessors.d.ts","names":[],"sources":["../src/accessors.ts"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"accessors.d.ts","names":[],"sources":["../src/accessors.ts"],"mappings":";;;;;;;;;cA+Ba,OAAA,SAAgB,KAAK;cACpB,OAAA;AAAA;AAAA,KAKF,gBAAA;EAAA,SACD,YAAA,QAAoB,WAAA;EAAA,SACpB,KAAA,GAAQ,eAAe;AAAA;AAAA,KAGtB,wBAAA;EAAA,SACD,KAAA,EAAO,UAAA;EAAA,SACP,GAAA,EAAK,aAAa;AAAA;AAAA,iBAGb,aAAA,CAAc,GAAA,YAAe,GAAA,IAAO,WAAW;AAAA,iBAQ/C,qBAAA,CAAsB,GAAA,YAAe,GAAA,IAAO,mBAAmB;AAAA,iBAQ/D,oBAAA,CAAqB,GAAA,YAAe,GAAA,IAAO,kBAAkB;;cAShE,WAAA,YAAuB,gBAAA,CAAiB,mBAAA;EAAA,iBAIhC,YAAA;EAAA,SACD,GAAA,EAAK,gBAAA;EAAA,iBAJN,uBAAA;cAGE,YAAA,EAAc,gBAAA,EACf,GAAA,EAAK,gBAAA;EAGhB,cAAA,CAAe,GAAA,EAAK,aAAA,EAAe,KAAA,EAAO,UAAA,GAAa,mBAAA;EAtC5B;;;;EAAA,IAiDvB,EAAA;EAIJ,MAAA;EAIA,QAAA;AAAA;AAAA,cAuCI,mBAAA;EAAA,iBAIQ,YAAA;EAAA,iBACA,IAAA;EAAA,iBACA,GAAA;EAAA,iBACA,YAAA;EAAA,iBANF,uBAAA;cAGE,YAAA,EAAc,gBAAA,EACd,IAAA,EAAM,WAAA,EACN,GAAA,EAAK,gBAAA,EACL,YAAA,EAAc,wBAAA;EAGjC,IAAA,CAAK,GAAA,GAAK,oBAAA,GAA4B,kBAAA;AAAA;AArGuB;AAQ/D;;AAR+D,KAoHnD,YAAA;EAAA,SACD,EAAA,EAAI,gBAAA;EAAA,SACJ,IAAA,EAAM,YAAY;AAAA;;;AA9GkD;AAQ/E;iBA6GgB,uBAAA,CAAwB,GAAA,EAAK,WAAA,GAAc,YAAA,EAAc,GAAA,EAAK,aAAA,GAAa,YAAA;;;;;;;cAY9E,kBAAA;EAAA,iBAIQ,YAAA;EAAA,iBACA,IAAA;EAAA,iBACA,QAAA;EAAA,iBACA,YAAA;EAAA,iBANF,uBAAA;cAGE,YAAA,EAAc,gBAAA,EACd,IAAA,EAAM,WAAA,EACN,QAAA,EAAU,cAAA,EACV,YAAA,EAAc,wBAAA;EAAA,IAGtB,EAAA,IAAM,gBAAA;EAAA,IAKN,UAAA,IAAc,wBAAA;EAAA,IAKd,YAAA,IAAgB,YAAA;EAAA,IAKhB,YAAA,IAAgB,YAAA;EAAA,QAInB,mBAAA;EAOD,QAAA,IACF,KAAA,GACD,IAAA,CAAK,kBAAA;IACH,kBAAA;EAAA,KAGH,kBAAA;EACI,QAAA,IAAY,KAAA,GAAQ,kBAAA,eAAiC,kBAAA;EAKrD,eAAA,IACF,KAAA,GACD,IAAA,CAAK,kBAAA;IACH,kBAAA;EAAA,KAGH,YAAA,CAAa,kBAAA,EAAoB,KAAA;EAC7B,eAAA,IACF,KAAA,GAAQ,kBAAA,eACV,YAAA,CAAa,kBAAA,EAAoB,KAAA;EAO7B,kBAAA,CACL,aAAA,EAAe,sBAAA,KACZ,KAAA,GAAQ,kBAAA,eACV,kBAAA;EAQI,yBAAA,CACL,aAAA,EAAe,sBAAA,KACZ,KAAA,GAAQ,kBAAA,eACV,YAAA,CAAa,kBAAA,EAAoB,KAAA;EAAA,iBAmDnB,gBAAA;EAIV,QAAA,CACL,KAAA,GACK,IAAA,CAAK,YAAA;IAA0C,oBAAA;EAAA,MAC/C,IAAA,CAAK,YAAA;IAAwC,kBAAA;EAAA,KACjD,aAAA,CAAc,kBAAA;EACV,QAAA,CAAS,KAAA,EAAO,YAAA,YAAwB,aAAA,CAAc,kBAAA;EAYtD,eAAA;EAOA,gBAAA;EAOA,iBAAA;EAOA,UAAA;EAKA,QAAA,IAAY,kBAAA;EASZ,OAAA,IAAW,UAAA;EAIX,eAAA;EAIA,aAAA,iBAA8B,CAAA;EAI9B,eAAA;EAMA,gBAAA;EAMA,iBAAA;EAKA,WAAA,CAAY,GAAA,UAAa,kBAAA,aAAsC,UAAA;EA1Pd;EAmQjD,iBAAA,CAAkB,GAAA;EAIlB,mBAAA,CAAoB,GAAA,UAAa,kBAAA;EAQjC,iBAAA,cACL,GAAA,UACA,kBAAA,aACC,CAAA;EAtRgB;;;;EAmSZ,eAAA,IAAmB,mBAAA;EArSP;EA0SZ,OAAA,IAAW,WAAA;AAAA;;;;cAQP,gBAAA,YAA4B,gBAAA,CAAiB,mBAAA;EAAA,iBAG3B,YAAA;EAAA,iBAFZ,uBAAA;cAEY,YAAA,EAAc,gBAAA;EAEpC,cAAA,CAAe,GAAA,EAAK,aAAA,EAAe,KAAA,EAAO,UAAA,GAAa,mBAAA;EAOvD,MAAA;EAIA,QAAA;AAAA;AAAA,iBAKO,kBAAA,CAAmB,GAAA,YAAe,GAAA,IAAO,gBAAgB;;;cAU5D,mBAAA;EAAA,iBAIQ,YAAA;EAAA,iBACA,IAAA;EAAA,iBACA,YAAA;EAAA,iBALF,uBAAA;cAGE,YAAA,EAAc,gBAAA,EACd,IAAA,EAAM,WAAA,EACN,YAAA,EAAc,wBAAA;EAzTnB;EA6TP,OAAA,IAAW,gBAAA;;EAMX,KAAA,CAAM,GAAA,GAAK,oBAAA,GAA4B,kBAAA;EAnUW;EAgVlD,OAAA,IAAW,WAAA;AAAA;AAAA,iBAQJ,qBAAA,CAAsB,GAAA,YAAe,GAAA,IAAO,mBAAmB"}
|
package/dist/accessors.js
CHANGED
|
@@ -262,7 +262,64 @@ var PlTreeNodeAccessor = class {
|
|
|
262
262
|
return new PlTreeEntry(this.accessorData, this.resource.id);
|
|
263
263
|
}
|
|
264
264
|
};
|
|
265
|
+
/** Reactive provider for the current root SET of a multi-root tree. Mirrors {@link PlTreeEntry}:
|
|
266
|
+
* reading it inside a Computable tracks the root set as a dependency, so the Computable
|
|
267
|
+
* recomputes when discovered roots appear or disappear. */
|
|
268
|
+
var PlTreeRootsEntry = class {
|
|
269
|
+
accessorData;
|
|
270
|
+
__pl_tree_type_marker__ = "PlTreeRootsEntry";
|
|
271
|
+
constructor(accessorData) {
|
|
272
|
+
this.accessorData = accessorData;
|
|
273
|
+
}
|
|
274
|
+
createAccessor(ctx, guard) {
|
|
275
|
+
return new PlTreeRootsAccessor(this.accessorData, this.accessorData.treeProvider(), {
|
|
276
|
+
ctx,
|
|
277
|
+
guard
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
toJSON() {
|
|
281
|
+
return "[ROOTS-ENTRY]";
|
|
282
|
+
}
|
|
283
|
+
toString() {
|
|
284
|
+
return "[ROOTS-ENTRY]";
|
|
285
|
+
}
|
|
286
|
+
};
|
|
287
|
+
function isPlTreeRootsEntry(obj) {
|
|
288
|
+
return typeof obj === "object" && obj !== null && obj["__pl_tree_type_marker__"] === "PlTreeRootsEntry";
|
|
289
|
+
}
|
|
290
|
+
/** Accessor over the current roots of a multi-root tree. Reading any of its methods tracks
|
|
291
|
+
* the root set as a dependency (via {@link PlTreeState.getRoots}). */
|
|
292
|
+
var PlTreeRootsAccessor = class {
|
|
293
|
+
accessorData;
|
|
294
|
+
tree;
|
|
295
|
+
instanceData;
|
|
296
|
+
__pl_tree_type_marker__ = "PlTreeRootsAccessor";
|
|
297
|
+
constructor(accessorData, tree, instanceData) {
|
|
298
|
+
this.accessorData = accessorData;
|
|
299
|
+
this.tree = tree;
|
|
300
|
+
this.instanceData = instanceData;
|
|
301
|
+
}
|
|
302
|
+
/** Current root ids. */
|
|
303
|
+
rootIds() {
|
|
304
|
+
this.instanceData.guard();
|
|
305
|
+
return this.tree.getRoots(this.instanceData.ctx.watcher);
|
|
306
|
+
}
|
|
307
|
+
/** Current roots as node accessors, ready to traverse. */
|
|
308
|
+
nodes(ops = {}) {
|
|
309
|
+
this.instanceData.guard();
|
|
310
|
+
if (this.accessorData.hooks !== void 0) this.instanceData.ctx.attacheHooks(this.accessorData.hooks);
|
|
311
|
+
return this.tree.getRoots(this.instanceData.ctx.watcher).map((rid) => getResourceFromTree(this.accessorData, this.tree, this.instanceData, rid, ops));
|
|
312
|
+
}
|
|
313
|
+
/** Current roots as entries, for persisting per-root sub-Computables. */
|
|
314
|
+
entries() {
|
|
315
|
+
this.instanceData.guard();
|
|
316
|
+
return this.tree.getRoots(this.instanceData.ctx.watcher).map((rid) => new PlTreeEntry(this.accessorData, rid));
|
|
317
|
+
}
|
|
318
|
+
};
|
|
319
|
+
function isPlTreeRootsAccessor(obj) {
|
|
320
|
+
return typeof obj === "object" && obj !== null && obj["__pl_tree_type_marker__"] === "PlTreeRootsAccessor";
|
|
321
|
+
}
|
|
265
322
|
//#endregion
|
|
266
|
-
export { PlError, PlTreeEntry, PlTreeEntryAccessor, PlTreeNodeAccessor, isPlTreeEntry, isPlTreeEntryAccessor, isPlTreeNodeAccessor, treeEntryToResourceInfo };
|
|
323
|
+
export { PlError, PlTreeEntry, PlTreeEntryAccessor, PlTreeNodeAccessor, PlTreeRootsAccessor, PlTreeRootsEntry, isPlTreeEntry, isPlTreeEntryAccessor, isPlTreeNodeAccessor, isPlTreeRootsAccessor, isPlTreeRootsEntry, treeEntryToResourceInfo };
|
|
267
324
|
|
|
268
325
|
//# sourceMappingURL=accessors.js.map
|
package/dist/accessors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"accessors.js","names":[],"sources":["../src/accessors.ts"],"sourcesContent":["import type { PlTreeResource, PlTreeState } from \"./state\";\nimport type {\n AccessorProvider,\n ComputableCtx,\n ComputableHooks,\n UsageGuard,\n} from \"@milaboratories/computable\";\nimport type {\n SignedResourceId,\n ResourceType,\n OptionalSignedResourceId,\n} from \"@milaboratories/pl-client\";\nimport {\n resourceIdToString,\n resourceTypesEqual,\n resourceTypeToString,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n NullSignedResourceId,\n} from \"@milaboratories/pl-client\";\nimport type { ValueAndError } from \"./value_and_error\";\nimport { mapValueAndError } from \"./value_and_error\";\nimport type {\n CommonFieldTraverseOps,\n FieldTraversalStep,\n GetFieldStep,\n ResourceTraversalOps,\n} from \"./traversal_ops\";\nimport type { ValueOrError } from \"./value_or_error\";\nimport { parsePlError } from \"@milaboratories/pl-errors\";\nimport { notEmpty } from \"@milaboratories/ts-helpers\";\n/** Error encountered during traversal in field or resource. */\nexport class PlError extends Error {\n constructor(message: string) {\n super(message);\n }\n}\n\nexport type TreeAccessorData = {\n readonly treeProvider: () => PlTreeState;\n readonly hooks?: ComputableHooks;\n};\n\nexport type TreeAccessorInstanceData = {\n readonly guard: UsageGuard;\n readonly ctx: ComputableCtx;\n};\n\nexport function isPlTreeEntry(obj: unknown): obj is PlTreeEntry {\n return (\n typeof obj === \"object\" &&\n obj !== null &&\n (obj as any)[\"__pl_tree_type_marker__\"] === \"PlTreeEntry\"\n );\n}\n\nexport function isPlTreeEntryAccessor(obj: unknown): obj is PlTreeEntryAccessor {\n return (\n typeof obj === \"object\" &&\n obj !== null &&\n (obj as any)[\"__pl_tree_type_marker__\"] === \"PlTreeEntryAccessor\"\n );\n}\n\nexport function isPlTreeNodeAccessor(obj: unknown): obj is PlTreeNodeAccessor {\n return (\n typeof obj === \"object\" &&\n obj !== null &&\n (obj as any)[\"__pl_tree_type_marker__\"] === \"PlTreeNodeAccessor\"\n );\n}\n\n/** Main entry point for using PlTree in reactive setting */\nexport class PlTreeEntry implements AccessorProvider<PlTreeEntryAccessor> {\n private readonly __pl_tree_type_marker__ = \"PlTreeEntry\";\n\n constructor(\n private readonly accessorData: TreeAccessorData,\n public readonly rid: SignedResourceId, // only for runtime. Not exposing rid at all causes too much pain. Never persist this anywhere.\n ) {}\n\n public createAccessor(ctx: ComputableCtx, guard: UsageGuard): PlTreeEntryAccessor {\n return new PlTreeEntryAccessor(this.accessorData, this.accessorData.treeProvider(), this.rid, {\n ctx,\n guard,\n });\n }\n\n /**\n * Tree TreeEntry ID suitable for persistence and use in names (files/objects/whatever), as it does not\n * contain signature which can change from session to session.\n */\n public get id(): string {\n return resourceIdToString(this.rid);\n }\n\n public toJSON(): string {\n return this.toString();\n }\n\n public toString(): string {\n return `[ENTRY:${resourceIdToString(this.rid)}]`;\n }\n}\n\nfunction getResourceFromTree(\n accessorData: TreeAccessorData,\n tree: PlTreeState,\n instanceData: TreeAccessorInstanceData,\n rid: SignedResourceId,\n ops: ResourceTraversalOps,\n): PlTreeNodeAccessor {\n const acc = new PlTreeNodeAccessor(\n accessorData,\n tree,\n tree.get(instanceData.ctx.watcher, rid),\n instanceData,\n );\n\n if (!ops.ignoreError) {\n const err = acc.getError();\n if (err !== undefined)\n throw parsePlError(notEmpty(err.getDataAsString()), acc.id, acc.resourceType);\n }\n\n if (\n ops.assertResourceType !== undefined &&\n (Array.isArray(ops.assertResourceType)\n ? ops.assertResourceType.findIndex((rt) => resourceTypesEqual(rt, acc.resourceType)) === -1\n : !resourceTypesEqual(ops.assertResourceType, acc.resourceType))\n )\n throw new Error(\n // eslint-disable-next-line @typescript-eslint/no-base-to-string\n `wrong resource type ${resourceTypeToString(acc.resourceType)} but expected ${ops.assertResourceType}`,\n );\n\n return acc;\n}\n\nexport class PlTreeEntryAccessor {\n private readonly __pl_tree_type_marker__ = \"PlTreeEntryAccessor\";\n\n constructor(\n private readonly accessorData: TreeAccessorData,\n private readonly tree: PlTreeState,\n private readonly rid: SignedResourceId,\n private readonly instanceData: TreeAccessorInstanceData,\n ) {}\n\n node(ops: ResourceTraversalOps = {}): PlTreeNodeAccessor {\n this.instanceData.guard();\n\n // this is the only entry point to acquire a PlTreeNodeAccessor,\n // so this is the only point where we should attach the hooks\n if (this.accessorData.hooks !== undefined)\n this.instanceData.ctx.attacheHooks(this.accessorData.hooks);\n\n return getResourceFromTree(this.accessorData, this.tree, this.instanceData, this.rid, ops);\n }\n}\n\n/**\n * Helper type to simplify implementation of APIs requiring type information.\n * */\nexport type ResourceInfo = {\n readonly id: SignedResourceId;\n readonly type: ResourceType;\n};\n\n/**\n * Can be called only when a ctx is provided, because pl tree entry is a computable entity.\n * @deprecated\n * */\nexport function treeEntryToResourceInfo(res: PlTreeEntry | ResourceInfo, ctx: ComputableCtx) {\n if (res instanceof PlTreeEntry) return ctx.accessor(res).node().resourceInfo;\n\n return res;\n}\n\n/**\n * API contracts:\n * - API never return {@link NullSignedResourceId}, absence of link is always modeled as `undefined`\n *\n * Important: never store instances of this class, always get fresh instance from {@link PlTreeState} accessor.\n * */\nexport class PlTreeNodeAccessor {\n private readonly __pl_tree_type_marker__ = \"PlTreeNodeAccessor\";\n\n constructor(\n private readonly accessorData: TreeAccessorData,\n private readonly tree: PlTreeState,\n private readonly resource: PlTreeResource,\n private readonly instanceData: TreeAccessorInstanceData,\n ) {}\n\n public get id(): SignedResourceId {\n this.instanceData.guard();\n return this.resource.id;\n }\n\n public get originalId(): OptionalSignedResourceId {\n this.instanceData.guard();\n return this.resource.originalResourceId;\n }\n\n public get resourceType(): ResourceType {\n this.instanceData.guard();\n return this.resource.type;\n }\n\n public get resourceInfo(): ResourceInfo {\n return { id: this.id, type: this.resourceType };\n }\n\n private getResourceFromTree(\n rid: SignedResourceId,\n ops: ResourceTraversalOps,\n ): PlTreeNodeAccessor {\n return getResourceFromTree(this.accessorData, this.tree, this.instanceData, rid, ops);\n }\n\n public traverse(\n ...steps: [\n Omit<FieldTraversalStep, \"errorIfFieldNotSet\"> & {\n errorIfFieldNotSet: true;\n },\n ]\n ): PlTreeNodeAccessor;\n public traverse(...steps: (FieldTraversalStep | string)[]): PlTreeNodeAccessor | undefined;\n public traverse(...steps: (FieldTraversalStep | string)[]): PlTreeNodeAccessor | undefined {\n return this.traverseWithCommon({}, ...steps);\n }\n\n public traverseOrError(\n ...steps: [\n Omit<FieldTraversalStep, \"errorIfFieldNotSet\"> & {\n errorIfFieldNotSet: true;\n },\n ]\n ): ValueOrError<PlTreeNodeAccessor, Error>;\n public traverseOrError(\n ...steps: (FieldTraversalStep | string)[]\n ): ValueOrError<PlTreeNodeAccessor, Error> | undefined;\n public traverseOrError(\n ...steps: (FieldTraversalStep | string)[]\n ): ValueOrError<PlTreeNodeAccessor, Error> | undefined {\n return this.traverseOrErrorWithCommon({}, ...steps);\n }\n\n public traverseWithCommon(\n commonOptions: CommonFieldTraverseOps,\n ...steps: (FieldTraversalStep | string)[]\n ): PlTreeNodeAccessor | undefined {\n const result = this.traverseOrErrorWithCommon(commonOptions, ...steps);\n if (result === undefined) return undefined;\n\n if (!result.ok) throw result.error;\n return result.value;\n }\n\n public traverseOrErrorWithCommon(\n commonOptions: CommonFieldTraverseOps,\n ...steps: (FieldTraversalStep | string)[]\n ): ValueOrError<PlTreeNodeAccessor, Error> | undefined {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n let current: PlTreeNodeAccessor = this;\n\n for (const _step of steps) {\n const step: FieldTraversalStep =\n typeof _step === \"string\"\n ? {\n ...commonOptions,\n field: _step,\n }\n : { ...commonOptions, ..._step };\n\n const next = current.getField(_step);\n\n if (next === undefined) return undefined;\n\n if (step.pureFieldErrorToUndefined && next.value === undefined && next.error !== undefined)\n return undefined;\n\n if ((!step.ignoreError || next.value === undefined) && next.error !== undefined)\n return {\n ok: false,\n\n // FIXME: in next tickets we'll allow Errors to be thrown.\n error: parsePlError(\n notEmpty(next.error.getDataAsString()),\n current.id,\n current.resourceType,\n step.field,\n ),\n };\n\n if (next.value === undefined) {\n if (step.errorIfFieldNotSet)\n return {\n ok: false,\n error: new Error(\n `field have no assigned value ${step.field} of ${resourceIdToString(current.id)}`,\n ),\n };\n // existing but unpopulated field is unstable because it must be resolved at some point\n this.onUnstableLambda(\"unpopulated_field:\" + step.field);\n return undefined;\n }\n\n current = next.value;\n }\n return { ok: true, value: current };\n }\n\n private readonly onUnstableLambda = (marker: string) => {\n this.instanceData.ctx.markUnstable(marker);\n };\n\n public getField(\n _step:\n | (Omit<GetFieldStep, \"errorIfFieldNotFound\"> & { errorIfFieldNotFound: true })\n | (Omit<GetFieldStep, \"errorIfFieldNotSet\"> & { errorIfFieldNotSet: true }),\n ): ValueAndError<PlTreeNodeAccessor>;\n public getField(_step: GetFieldStep | string): ValueAndError<PlTreeNodeAccessor> | undefined;\n public getField(_step: GetFieldStep | string): ValueAndError<PlTreeNodeAccessor> | undefined {\n this.instanceData.guard();\n const step: GetFieldStep = typeof _step === \"string\" ? { field: _step } : _step;\n\n const ve = this.resource.getField(this.instanceData.ctx.watcher, step, this.onUnstableLambda);\n\n if (ve === undefined) return undefined;\n\n return mapValueAndError(ve, (rid) => this.getResourceFromTree(rid, { ignoreError: true }));\n }\n\n public getInputsLocked(): boolean {\n this.instanceData.guard();\n const result = this.resource.getInputsLocked(this.instanceData.ctx.watcher);\n if (!result) this.instanceData.ctx.markUnstable(\"inputs_unlocked:\" + this.resourceType.name);\n return result;\n }\n\n public getOutputsLocked(): boolean {\n this.instanceData.guard();\n const result = this.resource.getOutputsLocked(this.instanceData.ctx.watcher);\n if (!result) this.instanceData.ctx.markUnstable(\"outputs_unlocked:\" + this.resourceType.name);\n return result;\n }\n\n public getIsReadyOrError(): boolean {\n this.instanceData.guard();\n const result = this.resource.getIsReadyOrError(this.instanceData.ctx.watcher);\n if (!result) this.instanceData.ctx.markUnstable(\"not_ready:\" + this.resourceType.name);\n return result;\n }\n\n public getIsFinal() {\n this.instanceData.guard();\n return this.resource.getIsFinal(this.instanceData.ctx.watcher);\n }\n\n public getError(): PlTreeNodeAccessor | undefined {\n this.instanceData.guard();\n const rid = this.resource.getError(this.instanceData.ctx.watcher);\n if (rid === undefined)\n // absence of error always considered as stable\n return undefined;\n return this.getResourceFromTree(rid, {});\n }\n\n public getData(): Uint8Array | undefined {\n return this.resource.data;\n }\n\n public getDataAsString(): string | undefined {\n return this.resource.getDataAsString();\n }\n\n public getDataAsJson<T = unknown>(): T | undefined {\n return this.resource.getDataAsJson<T>();\n }\n\n public listInputFields(): string[] {\n this.instanceData.guard();\n this.getInputsLocked(); // will set unstable if not locked\n return this.resource.listInputFields(this.instanceData.ctx.watcher);\n }\n\n public listOutputFields(): string[] {\n this.instanceData.guard();\n this.getOutputsLocked(); // will set unstable if not locked\n return this.resource.listOutputFields(this.instanceData.ctx.watcher);\n }\n\n public listDynamicFields(): string[] {\n this.instanceData.guard();\n return this.resource.listDynamicFields(this.instanceData.ctx.watcher);\n }\n\n public getKeyValue(key: string, unstableIfNotFound: boolean = false): Uint8Array | undefined {\n this.instanceData.guard();\n const result = this.resource.getKeyValue(this.instanceData.ctx.watcher, key);\n if (result === undefined && unstableIfNotFound)\n this.instanceData.ctx.markUnstable(\"key_not_found_b:\" + key);\n return result;\n }\n\n /** @deprecated */\n public getKeyValueString(key: string): string | undefined {\n return this.getKeyValueAsString(key);\n }\n\n public getKeyValueAsString(key: string, unstableIfNotFound: boolean = false): string | undefined {\n this.instanceData.guard();\n const result = this.resource.getKeyValueString(this.instanceData.ctx.watcher, key);\n if (result === undefined && unstableIfNotFound)\n this.instanceData.ctx.markUnstable(\"key_not_found_s:\" + key);\n return result;\n }\n\n public getKeyValueAsJson<T = unknown>(\n key: string,\n unstableIfNotFound: boolean = false,\n ): T | undefined {\n const result = this.resource.getKeyValueAsJson<T>(this.instanceData.ctx.watcher, key);\n if (result === undefined) {\n if (unstableIfNotFound) this.instanceData.ctx.markUnstable(\"key_not_found_j:\" + key);\n return undefined;\n }\n return result;\n }\n\n /**\n * Can be used to pass a higher level accessor that will wrap the resource and throw its\n * errors on node resolution.\n * */\n public toEntryAccessor(): PlTreeEntryAccessor {\n return new PlTreeEntryAccessor(this.accessorData, this.tree, this.id, this.instanceData);\n }\n\n /** Can be passed to nested computable. */\n public persist(): PlTreeEntry {\n return new PlTreeEntry(this.accessorData, this.resource.id);\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"accessors.js","names":[],"sources":["../src/accessors.ts"],"sourcesContent":["import type { PlTreeResource, PlTreeState } from \"./state\";\nimport type {\n AccessorProvider,\n ComputableCtx,\n ComputableHooks,\n UsageGuard,\n} from \"@milaboratories/computable\";\nimport type {\n SignedResourceId,\n ResourceType,\n OptionalSignedResourceId,\n} from \"@milaboratories/pl-client\";\nimport {\n resourceIdToString,\n resourceTypesEqual,\n resourceTypeToString,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n NullSignedResourceId,\n} from \"@milaboratories/pl-client\";\nimport type { ValueAndError } from \"./value_and_error\";\nimport { mapValueAndError } from \"./value_and_error\";\nimport type {\n CommonFieldTraverseOps,\n FieldTraversalStep,\n GetFieldStep,\n ResourceTraversalOps,\n} from \"./traversal_ops\";\nimport type { ValueOrError } from \"./value_or_error\";\nimport { parsePlError } from \"@milaboratories/pl-errors\";\nimport { notEmpty } from \"@milaboratories/ts-helpers\";\n/** Error encountered during traversal in field or resource. */\nexport class PlError extends Error {\n constructor(message: string) {\n super(message);\n }\n}\n\nexport type TreeAccessorData = {\n readonly treeProvider: () => PlTreeState;\n readonly hooks?: ComputableHooks;\n};\n\nexport type TreeAccessorInstanceData = {\n readonly guard: UsageGuard;\n readonly ctx: ComputableCtx;\n};\n\nexport function isPlTreeEntry(obj: unknown): obj is PlTreeEntry {\n return (\n typeof obj === \"object\" &&\n obj !== null &&\n (obj as any)[\"__pl_tree_type_marker__\"] === \"PlTreeEntry\"\n );\n}\n\nexport function isPlTreeEntryAccessor(obj: unknown): obj is PlTreeEntryAccessor {\n return (\n typeof obj === \"object\" &&\n obj !== null &&\n (obj as any)[\"__pl_tree_type_marker__\"] === \"PlTreeEntryAccessor\"\n );\n}\n\nexport function isPlTreeNodeAccessor(obj: unknown): obj is PlTreeNodeAccessor {\n return (\n typeof obj === \"object\" &&\n obj !== null &&\n (obj as any)[\"__pl_tree_type_marker__\"] === \"PlTreeNodeAccessor\"\n );\n}\n\n/** Main entry point for using PlTree in reactive setting */\nexport class PlTreeEntry implements AccessorProvider<PlTreeEntryAccessor> {\n private readonly __pl_tree_type_marker__ = \"PlTreeEntry\";\n\n constructor(\n private readonly accessorData: TreeAccessorData,\n public readonly rid: SignedResourceId, // only for runtime. Not exposing rid at all causes too much pain. Never persist this anywhere.\n ) {}\n\n public createAccessor(ctx: ComputableCtx, guard: UsageGuard): PlTreeEntryAccessor {\n return new PlTreeEntryAccessor(this.accessorData, this.accessorData.treeProvider(), this.rid, {\n ctx,\n guard,\n });\n }\n\n /**\n * Tree TreeEntry ID suitable for persistence and use in names (files/objects/whatever), as it does not\n * contain signature which can change from session to session.\n */\n public get id(): string {\n return resourceIdToString(this.rid);\n }\n\n public toJSON(): string {\n return this.toString();\n }\n\n public toString(): string {\n return `[ENTRY:${resourceIdToString(this.rid)}]`;\n }\n}\n\nfunction getResourceFromTree(\n accessorData: TreeAccessorData,\n tree: PlTreeState,\n instanceData: TreeAccessorInstanceData,\n rid: SignedResourceId,\n ops: ResourceTraversalOps,\n): PlTreeNodeAccessor {\n const acc = new PlTreeNodeAccessor(\n accessorData,\n tree,\n tree.get(instanceData.ctx.watcher, rid),\n instanceData,\n );\n\n if (!ops.ignoreError) {\n const err = acc.getError();\n if (err !== undefined)\n throw parsePlError(notEmpty(err.getDataAsString()), acc.id, acc.resourceType);\n }\n\n if (\n ops.assertResourceType !== undefined &&\n (Array.isArray(ops.assertResourceType)\n ? ops.assertResourceType.findIndex((rt) => resourceTypesEqual(rt, acc.resourceType)) === -1\n : !resourceTypesEqual(ops.assertResourceType, acc.resourceType))\n )\n throw new Error(\n // eslint-disable-next-line @typescript-eslint/no-base-to-string\n `wrong resource type ${resourceTypeToString(acc.resourceType)} but expected ${ops.assertResourceType}`,\n );\n\n return acc;\n}\n\nexport class PlTreeEntryAccessor {\n private readonly __pl_tree_type_marker__ = \"PlTreeEntryAccessor\";\n\n constructor(\n private readonly accessorData: TreeAccessorData,\n private readonly tree: PlTreeState,\n private readonly rid: SignedResourceId,\n private readonly instanceData: TreeAccessorInstanceData,\n ) {}\n\n node(ops: ResourceTraversalOps = {}): PlTreeNodeAccessor {\n this.instanceData.guard();\n\n // this is the only entry point to acquire a PlTreeNodeAccessor,\n // so this is the only point where we should attach the hooks\n if (this.accessorData.hooks !== undefined)\n this.instanceData.ctx.attacheHooks(this.accessorData.hooks);\n\n return getResourceFromTree(this.accessorData, this.tree, this.instanceData, this.rid, ops);\n }\n}\n\n/**\n * Helper type to simplify implementation of APIs requiring type information.\n * */\nexport type ResourceInfo = {\n readonly id: SignedResourceId;\n readonly type: ResourceType;\n};\n\n/**\n * Can be called only when a ctx is provided, because pl tree entry is a computable entity.\n * @deprecated\n * */\nexport function treeEntryToResourceInfo(res: PlTreeEntry | ResourceInfo, ctx: ComputableCtx) {\n if (res instanceof PlTreeEntry) return ctx.accessor(res).node().resourceInfo;\n\n return res;\n}\n\n/**\n * API contracts:\n * - API never return {@link NullSignedResourceId}, absence of link is always modeled as `undefined`\n *\n * Important: never store instances of this class, always get fresh instance from {@link PlTreeState} accessor.\n * */\nexport class PlTreeNodeAccessor {\n private readonly __pl_tree_type_marker__ = \"PlTreeNodeAccessor\";\n\n constructor(\n private readonly accessorData: TreeAccessorData,\n private readonly tree: PlTreeState,\n private readonly resource: PlTreeResource,\n private readonly instanceData: TreeAccessorInstanceData,\n ) {}\n\n public get id(): SignedResourceId {\n this.instanceData.guard();\n return this.resource.id;\n }\n\n public get originalId(): OptionalSignedResourceId {\n this.instanceData.guard();\n return this.resource.originalResourceId;\n }\n\n public get resourceType(): ResourceType {\n this.instanceData.guard();\n return this.resource.type;\n }\n\n public get resourceInfo(): ResourceInfo {\n return { id: this.id, type: this.resourceType };\n }\n\n private getResourceFromTree(\n rid: SignedResourceId,\n ops: ResourceTraversalOps,\n ): PlTreeNodeAccessor {\n return getResourceFromTree(this.accessorData, this.tree, this.instanceData, rid, ops);\n }\n\n public traverse(\n ...steps: [\n Omit<FieldTraversalStep, \"errorIfFieldNotSet\"> & {\n errorIfFieldNotSet: true;\n },\n ]\n ): PlTreeNodeAccessor;\n public traverse(...steps: (FieldTraversalStep | string)[]): PlTreeNodeAccessor | undefined;\n public traverse(...steps: (FieldTraversalStep | string)[]): PlTreeNodeAccessor | undefined {\n return this.traverseWithCommon({}, ...steps);\n }\n\n public traverseOrError(\n ...steps: [\n Omit<FieldTraversalStep, \"errorIfFieldNotSet\"> & {\n errorIfFieldNotSet: true;\n },\n ]\n ): ValueOrError<PlTreeNodeAccessor, Error>;\n public traverseOrError(\n ...steps: (FieldTraversalStep | string)[]\n ): ValueOrError<PlTreeNodeAccessor, Error> | undefined;\n public traverseOrError(\n ...steps: (FieldTraversalStep | string)[]\n ): ValueOrError<PlTreeNodeAccessor, Error> | undefined {\n return this.traverseOrErrorWithCommon({}, ...steps);\n }\n\n public traverseWithCommon(\n commonOptions: CommonFieldTraverseOps,\n ...steps: (FieldTraversalStep | string)[]\n ): PlTreeNodeAccessor | undefined {\n const result = this.traverseOrErrorWithCommon(commonOptions, ...steps);\n if (result === undefined) return undefined;\n\n if (!result.ok) throw result.error;\n return result.value;\n }\n\n public traverseOrErrorWithCommon(\n commonOptions: CommonFieldTraverseOps,\n ...steps: (FieldTraversalStep | string)[]\n ): ValueOrError<PlTreeNodeAccessor, Error> | undefined {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n let current: PlTreeNodeAccessor = this;\n\n for (const _step of steps) {\n const step: FieldTraversalStep =\n typeof _step === \"string\"\n ? {\n ...commonOptions,\n field: _step,\n }\n : { ...commonOptions, ..._step };\n\n const next = current.getField(_step);\n\n if (next === undefined) return undefined;\n\n if (step.pureFieldErrorToUndefined && next.value === undefined && next.error !== undefined)\n return undefined;\n\n if ((!step.ignoreError || next.value === undefined) && next.error !== undefined)\n return {\n ok: false,\n\n // FIXME: in next tickets we'll allow Errors to be thrown.\n error: parsePlError(\n notEmpty(next.error.getDataAsString()),\n current.id,\n current.resourceType,\n step.field,\n ),\n };\n\n if (next.value === undefined) {\n if (step.errorIfFieldNotSet)\n return {\n ok: false,\n error: new Error(\n `field have no assigned value ${step.field} of ${resourceIdToString(current.id)}`,\n ),\n };\n // existing but unpopulated field is unstable because it must be resolved at some point\n this.onUnstableLambda(\"unpopulated_field:\" + step.field);\n return undefined;\n }\n\n current = next.value;\n }\n return { ok: true, value: current };\n }\n\n private readonly onUnstableLambda = (marker: string) => {\n this.instanceData.ctx.markUnstable(marker);\n };\n\n public getField(\n _step:\n | (Omit<GetFieldStep, \"errorIfFieldNotFound\"> & { errorIfFieldNotFound: true })\n | (Omit<GetFieldStep, \"errorIfFieldNotSet\"> & { errorIfFieldNotSet: true }),\n ): ValueAndError<PlTreeNodeAccessor>;\n public getField(_step: GetFieldStep | string): ValueAndError<PlTreeNodeAccessor> | undefined;\n public getField(_step: GetFieldStep | string): ValueAndError<PlTreeNodeAccessor> | undefined {\n this.instanceData.guard();\n const step: GetFieldStep = typeof _step === \"string\" ? { field: _step } : _step;\n\n const ve = this.resource.getField(this.instanceData.ctx.watcher, step, this.onUnstableLambda);\n\n if (ve === undefined) return undefined;\n\n return mapValueAndError(ve, (rid) => this.getResourceFromTree(rid, { ignoreError: true }));\n }\n\n public getInputsLocked(): boolean {\n this.instanceData.guard();\n const result = this.resource.getInputsLocked(this.instanceData.ctx.watcher);\n if (!result) this.instanceData.ctx.markUnstable(\"inputs_unlocked:\" + this.resourceType.name);\n return result;\n }\n\n public getOutputsLocked(): boolean {\n this.instanceData.guard();\n const result = this.resource.getOutputsLocked(this.instanceData.ctx.watcher);\n if (!result) this.instanceData.ctx.markUnstable(\"outputs_unlocked:\" + this.resourceType.name);\n return result;\n }\n\n public getIsReadyOrError(): boolean {\n this.instanceData.guard();\n const result = this.resource.getIsReadyOrError(this.instanceData.ctx.watcher);\n if (!result) this.instanceData.ctx.markUnstable(\"not_ready:\" + this.resourceType.name);\n return result;\n }\n\n public getIsFinal() {\n this.instanceData.guard();\n return this.resource.getIsFinal(this.instanceData.ctx.watcher);\n }\n\n public getError(): PlTreeNodeAccessor | undefined {\n this.instanceData.guard();\n const rid = this.resource.getError(this.instanceData.ctx.watcher);\n if (rid === undefined)\n // absence of error always considered as stable\n return undefined;\n return this.getResourceFromTree(rid, {});\n }\n\n public getData(): Uint8Array | undefined {\n return this.resource.data;\n }\n\n public getDataAsString(): string | undefined {\n return this.resource.getDataAsString();\n }\n\n public getDataAsJson<T = unknown>(): T | undefined {\n return this.resource.getDataAsJson<T>();\n }\n\n public listInputFields(): string[] {\n this.instanceData.guard();\n this.getInputsLocked(); // will set unstable if not locked\n return this.resource.listInputFields(this.instanceData.ctx.watcher);\n }\n\n public listOutputFields(): string[] {\n this.instanceData.guard();\n this.getOutputsLocked(); // will set unstable if not locked\n return this.resource.listOutputFields(this.instanceData.ctx.watcher);\n }\n\n public listDynamicFields(): string[] {\n this.instanceData.guard();\n return this.resource.listDynamicFields(this.instanceData.ctx.watcher);\n }\n\n public getKeyValue(key: string, unstableIfNotFound: boolean = false): Uint8Array | undefined {\n this.instanceData.guard();\n const result = this.resource.getKeyValue(this.instanceData.ctx.watcher, key);\n if (result === undefined && unstableIfNotFound)\n this.instanceData.ctx.markUnstable(\"key_not_found_b:\" + key);\n return result;\n }\n\n /** @deprecated */\n public getKeyValueString(key: string): string | undefined {\n return this.getKeyValueAsString(key);\n }\n\n public getKeyValueAsString(key: string, unstableIfNotFound: boolean = false): string | undefined {\n this.instanceData.guard();\n const result = this.resource.getKeyValueString(this.instanceData.ctx.watcher, key);\n if (result === undefined && unstableIfNotFound)\n this.instanceData.ctx.markUnstable(\"key_not_found_s:\" + key);\n return result;\n }\n\n public getKeyValueAsJson<T = unknown>(\n key: string,\n unstableIfNotFound: boolean = false,\n ): T | undefined {\n const result = this.resource.getKeyValueAsJson<T>(this.instanceData.ctx.watcher, key);\n if (result === undefined) {\n if (unstableIfNotFound) this.instanceData.ctx.markUnstable(\"key_not_found_j:\" + key);\n return undefined;\n }\n return result;\n }\n\n /**\n * Can be used to pass a higher level accessor that will wrap the resource and throw its\n * errors on node resolution.\n * */\n public toEntryAccessor(): PlTreeEntryAccessor {\n return new PlTreeEntryAccessor(this.accessorData, this.tree, this.id, this.instanceData);\n }\n\n /** Can be passed to nested computable. */\n public persist(): PlTreeEntry {\n return new PlTreeEntry(this.accessorData, this.resource.id);\n }\n}\n\n/** Reactive provider for the current root SET of a multi-root tree. Mirrors {@link PlTreeEntry}:\n * reading it inside a Computable tracks the root set as a dependency, so the Computable\n * recomputes when discovered roots appear or disappear. */\nexport class PlTreeRootsEntry implements AccessorProvider<PlTreeRootsAccessor> {\n private readonly __pl_tree_type_marker__ = \"PlTreeRootsEntry\";\n\n constructor(private readonly accessorData: TreeAccessorData) {}\n\n public createAccessor(ctx: ComputableCtx, guard: UsageGuard): PlTreeRootsAccessor {\n return new PlTreeRootsAccessor(this.accessorData, this.accessorData.treeProvider(), {\n ctx,\n guard,\n });\n }\n\n public toJSON(): string {\n return \"[ROOTS-ENTRY]\";\n }\n\n public toString(): string {\n return \"[ROOTS-ENTRY]\";\n }\n}\n\nexport function isPlTreeRootsEntry(obj: unknown): obj is PlTreeRootsEntry {\n return (\n typeof obj === \"object\" &&\n obj !== null &&\n (obj as any)[\"__pl_tree_type_marker__\"] === \"PlTreeRootsEntry\"\n );\n}\n\n/** Accessor over the current roots of a multi-root tree. Reading any of its methods tracks\n * the root set as a dependency (via {@link PlTreeState.getRoots}). */\nexport class PlTreeRootsAccessor {\n private readonly __pl_tree_type_marker__ = \"PlTreeRootsAccessor\";\n\n constructor(\n private readonly accessorData: TreeAccessorData,\n private readonly tree: PlTreeState,\n private readonly instanceData: TreeAccessorInstanceData,\n ) {}\n\n /** Current root ids. */\n public rootIds(): SignedResourceId[] {\n this.instanceData.guard();\n return this.tree.getRoots(this.instanceData.ctx.watcher);\n }\n\n /** Current roots as node accessors, ready to traverse. */\n public nodes(ops: ResourceTraversalOps = {}): PlTreeNodeAccessor[] {\n this.instanceData.guard();\n\n // mirror PlTreeEntryAccessor.node(): attach polling hooks on first node acquisition\n if (this.accessorData.hooks !== undefined)\n this.instanceData.ctx.attacheHooks(this.accessorData.hooks);\n\n return this.tree\n .getRoots(this.instanceData.ctx.watcher)\n .map((rid) => getResourceFromTree(this.accessorData, this.tree, this.instanceData, rid, ops));\n }\n\n /** Current roots as entries, for persisting per-root sub-Computables. */\n public entries(): PlTreeEntry[] {\n this.instanceData.guard();\n return this.tree\n .getRoots(this.instanceData.ctx.watcher)\n .map((rid) => new PlTreeEntry(this.accessorData, rid));\n }\n}\n\nexport function isPlTreeRootsAccessor(obj: unknown): obj is PlTreeRootsAccessor {\n return (\n typeof obj === \"object\" &&\n obj !== null &&\n (obj as any)[\"__pl_tree_type_marker__\"] === \"PlTreeRootsAccessor\"\n );\n}\n"],"mappings":"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"}
|
package/dist/index.cjs
CHANGED
|
@@ -11,6 +11,8 @@ exports.PlTreeEntry = require_accessors.PlTreeEntry;
|
|
|
11
11
|
exports.PlTreeEntryAccessor = require_accessors.PlTreeEntryAccessor;
|
|
12
12
|
exports.PlTreeNodeAccessor = require_accessors.PlTreeNodeAccessor;
|
|
13
13
|
exports.PlTreeResource = require_state.PlTreeResource;
|
|
14
|
+
exports.PlTreeRootsAccessor = require_accessors.PlTreeRootsAccessor;
|
|
15
|
+
exports.PlTreeRootsEntry = require_accessors.PlTreeRootsEntry;
|
|
14
16
|
exports.PlTreeState = require_state.PlTreeState;
|
|
15
17
|
exports.SynchronizedTreeState = require_synchronized_tree.SynchronizedTreeState;
|
|
16
18
|
exports.TreeStateUpdateError = require_state.TreeStateUpdateError;
|
|
@@ -20,6 +22,8 @@ exports.initialTreeLoadingStat = require_sync.initialTreeLoadingStat;
|
|
|
20
22
|
exports.isPlTreeEntry = require_accessors.isPlTreeEntry;
|
|
21
23
|
exports.isPlTreeEntryAccessor = require_accessors.isPlTreeEntryAccessor;
|
|
22
24
|
exports.isPlTreeNodeAccessor = require_accessors.isPlTreeNodeAccessor;
|
|
25
|
+
exports.isPlTreeRootsAccessor = require_accessors.isPlTreeRootsAccessor;
|
|
26
|
+
exports.isPlTreeRootsEntry = require_accessors.isPlTreeRootsEntry;
|
|
23
27
|
exports.loadTreeState = require_sync.loadTreeState;
|
|
24
28
|
exports.makeResourceSnapshot = require_snapshot.makeResourceSnapshot;
|
|
25
29
|
exports.mapValueAndError = require_value_and_error.mapValueAndError;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { CommonFieldTraverseOps, CommonTraversalOps, FieldTraversalStep, GetFieldStep, ResourceTraversalOps } from "./traversal_ops.js";
|
|
2
2
|
import { ValueAndError, mapValueAndError, mapValueAndErrorIfDefined } from "./value_and_error.js";
|
|
3
3
|
import { ValueOrError } from "./value_or_error.js";
|
|
4
|
-
import { PlError, PlTreeEntry, PlTreeEntryAccessor, PlTreeNodeAccessor, ResourceInfo, TreeAccessorData, TreeAccessorInstanceData, isPlTreeEntry, isPlTreeEntryAccessor, isPlTreeNodeAccessor, treeEntryToResourceInfo } from "./accessors.js";
|
|
4
|
+
import { PlError, PlTreeEntry, PlTreeEntryAccessor, PlTreeNodeAccessor, PlTreeRootsAccessor, PlTreeRootsEntry, ResourceInfo, TreeAccessorData, TreeAccessorInstanceData, isPlTreeEntry, isPlTreeEntryAccessor, isPlTreeNodeAccessor, isPlTreeRootsAccessor, isPlTreeRootsEntry, treeEntryToResourceInfo } from "./accessors.js";
|
|
5
5
|
import { ExtendedResourceData, PlTreeResource, PlTreeState, ResourceDataWithFinalState, TreeStateUpdateError } from "./state.js";
|
|
6
6
|
import { PruningFunction, TraversalMode, TreeLoadingRequest, TreeLoadingStat, constructTreeLoadingRequest, formatTreeLoadingStat, initialTreeLoadingStat, loadTreeState } from "./sync.js";
|
|
7
7
|
import { InferSnapshot, ResourceSnapshot, ResourceSnapshotSchema, ResourceWithData, ResourceWithMetadata, makeResourceSnapshot, rsSchema, treeEntryToResourceWithData, treeEntryToResourceWithMetadata } from "./snapshot.js";
|
|
8
|
-
import { SynchronizedTreeOps, SynchronizedTreeState } from "./synchronized_tree.js";
|
|
8
|
+
import { ExplicitRootSeed, SharedTypeSeed, SynchronizedTreeOps, SynchronizedTreeState, TreeSeed } from "./synchronized_tree.js";
|
|
9
9
|
import { ResourceStats, TreeDumpStats, treeDumpStats } from "./dump.js";
|
|
10
|
-
export { CommonFieldTraverseOps, CommonTraversalOps, ExtendedResourceData, FieldTraversalStep, GetFieldStep, InferSnapshot, PlError, PlTreeEntry, PlTreeEntryAccessor, PlTreeNodeAccessor, PlTreeResource, PlTreeState, PruningFunction, ResourceDataWithFinalState, ResourceInfo, ResourceSnapshot, ResourceSnapshotSchema, ResourceStats, ResourceTraversalOps, ResourceWithData, ResourceWithMetadata, SynchronizedTreeOps, SynchronizedTreeState, TraversalMode, TreeAccessorData, TreeAccessorInstanceData, TreeDumpStats, TreeLoadingRequest, TreeLoadingStat, TreeStateUpdateError, ValueAndError, ValueOrError, constructTreeLoadingRequest, formatTreeLoadingStat, initialTreeLoadingStat, isPlTreeEntry, isPlTreeEntryAccessor, isPlTreeNodeAccessor, loadTreeState, makeResourceSnapshot, mapValueAndError, mapValueAndErrorIfDefined, rsSchema, treeDumpStats, treeEntryToResourceInfo, treeEntryToResourceWithData, treeEntryToResourceWithMetadata };
|
|
10
|
+
export { CommonFieldTraverseOps, CommonTraversalOps, ExplicitRootSeed, ExtendedResourceData, FieldTraversalStep, GetFieldStep, InferSnapshot, PlError, PlTreeEntry, PlTreeEntryAccessor, PlTreeNodeAccessor, PlTreeResource, PlTreeRootsAccessor, PlTreeRootsEntry, PlTreeState, PruningFunction, ResourceDataWithFinalState, ResourceInfo, ResourceSnapshot, ResourceSnapshotSchema, ResourceStats, ResourceTraversalOps, ResourceWithData, ResourceWithMetadata, SharedTypeSeed, SynchronizedTreeOps, SynchronizedTreeState, TraversalMode, TreeAccessorData, TreeAccessorInstanceData, TreeDumpStats, TreeLoadingRequest, TreeLoadingStat, TreeSeed, TreeStateUpdateError, ValueAndError, ValueOrError, constructTreeLoadingRequest, formatTreeLoadingStat, initialTreeLoadingStat, isPlTreeEntry, isPlTreeEntryAccessor, isPlTreeNodeAccessor, isPlTreeRootsAccessor, isPlTreeRootsEntry, loadTreeState, makeResourceSnapshot, mapValueAndError, mapValueAndErrorIfDefined, rsSchema, treeDumpStats, treeEntryToResourceInfo, treeEntryToResourceWithData, treeEntryToResourceWithMetadata };
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { mapValueAndError, mapValueAndErrorIfDefined } from "./value_and_error.js";
|
|
2
|
-
import { PlError, PlTreeEntry, PlTreeEntryAccessor, PlTreeNodeAccessor, isPlTreeEntry, isPlTreeEntryAccessor, isPlTreeNodeAccessor, treeEntryToResourceInfo } from "./accessors.js";
|
|
2
|
+
import { PlError, PlTreeEntry, PlTreeEntryAccessor, PlTreeNodeAccessor, PlTreeRootsAccessor, PlTreeRootsEntry, isPlTreeEntry, isPlTreeEntryAccessor, isPlTreeNodeAccessor, isPlTreeRootsAccessor, isPlTreeRootsEntry, treeEntryToResourceInfo } from "./accessors.js";
|
|
3
3
|
import { PlTreeResource, PlTreeState, TreeStateUpdateError } from "./state.js";
|
|
4
4
|
import { constructTreeLoadingRequest, formatTreeLoadingStat, initialTreeLoadingStat, loadTreeState } from "./sync.js";
|
|
5
5
|
import { makeResourceSnapshot, rsSchema, treeEntryToResourceWithData, treeEntryToResourceWithMetadata } from "./snapshot.js";
|
|
6
6
|
import { SynchronizedTreeState } from "./synchronized_tree.js";
|
|
7
7
|
import { treeDumpStats } from "./dump.js";
|
|
8
|
-
export { PlError, PlTreeEntry, PlTreeEntryAccessor, PlTreeNodeAccessor, PlTreeResource, PlTreeState, SynchronizedTreeState, TreeStateUpdateError, constructTreeLoadingRequest, formatTreeLoadingStat, initialTreeLoadingStat, isPlTreeEntry, isPlTreeEntryAccessor, isPlTreeNodeAccessor, loadTreeState, makeResourceSnapshot, mapValueAndError, mapValueAndErrorIfDefined, rsSchema, treeDumpStats, treeEntryToResourceInfo, treeEntryToResourceWithData, treeEntryToResourceWithMetadata };
|
|
8
|
+
export { PlError, PlTreeEntry, PlTreeEntryAccessor, PlTreeNodeAccessor, PlTreeResource, PlTreeRootsAccessor, PlTreeRootsEntry, PlTreeState, SynchronizedTreeState, TreeStateUpdateError, constructTreeLoadingRequest, formatTreeLoadingStat, initialTreeLoadingStat, isPlTreeEntry, isPlTreeEntryAccessor, isPlTreeNodeAccessor, isPlTreeRootsAccessor, isPlTreeRootsEntry, loadTreeState, makeResourceSnapshot, mapValueAndError, mapValueAndErrorIfDefined, rsSchema, treeDumpStats, treeEntryToResourceInfo, treeEntryToResourceWithData, treeEntryToResourceWithMetadata };
|
package/dist/state.cjs
CHANGED
|
@@ -250,18 +250,31 @@ var PlTreeResource = class {
|
|
|
250
250
|
}
|
|
251
251
|
};
|
|
252
252
|
var PlTreeState = class {
|
|
253
|
-
root;
|
|
254
253
|
isFinalPredicate;
|
|
255
254
|
/** resource heap */
|
|
256
255
|
resources = /* @__PURE__ */ new Map();
|
|
257
256
|
resourcesAdded = new _milaboratories_computable.ChangeSource();
|
|
257
|
+
/** Marked when the root set changes (roots discovered or removed), so multi-root
|
|
258
|
+
* accessors that read the set recompute. */
|
|
259
|
+
rootsChanged = new _milaboratories_computable.ChangeSource();
|
|
258
260
|
/** Resets to false if any invalid state transitions are registered,
|
|
259
261
|
* after that tree will produce errors for any read or write operations */
|
|
260
262
|
_isValid = true;
|
|
261
263
|
invalidationMessage;
|
|
262
|
-
|
|
263
|
-
|
|
264
|
+
/** The set of roots — resources protected from GC. Originally a single `root`,
|
|
265
|
+
* generalized to a set so several explicit roots and dynamically-discovered shared
|
|
266
|
+
* roots can coexist in one heap. Mutated through {@link setRoots}. */
|
|
267
|
+
roots;
|
|
268
|
+
constructor(roots, isFinalPredicate) {
|
|
264
269
|
this.isFinalPredicate = isFinalPredicate;
|
|
270
|
+
this.roots = roots instanceof Set ? new Set(roots) : /* @__PURE__ */ new Set([roots]);
|
|
271
|
+
}
|
|
272
|
+
/** Backward-compatible single-root accessor. Returns the sole root and THROWS if the
|
|
273
|
+
* tree has zero or more than one root, so a multi-root tree can never be read as if it
|
|
274
|
+
* had one. Mirrors the {@link entry} guard. */
|
|
275
|
+
get root() {
|
|
276
|
+
if (this.roots.size !== 1) throw new Error(`single-root accessor used on a tree with ${this.roots.size} roots; use the multi-root API`);
|
|
277
|
+
return this.roots.values().next().value;
|
|
265
278
|
}
|
|
266
279
|
forEachResource(cb) {
|
|
267
280
|
this.resources.forEach((v) => cb(v));
|
|
@@ -269,6 +282,13 @@ var PlTreeState = class {
|
|
|
269
282
|
checkValid() {
|
|
270
283
|
if (!this._isValid) throw new Error(this.invalidationMessage ?? "tree is in invalid state");
|
|
271
284
|
}
|
|
285
|
+
/** Reactive read of the current root set. Attaches the watcher to {@link rootsChanged}
|
|
286
|
+
* so a Computable recomputes when discovered roots appear or disappear. */
|
|
287
|
+
getRoots(watcher) {
|
|
288
|
+
this.checkValid();
|
|
289
|
+
this.rootsChanged.attachWatcher(watcher);
|
|
290
|
+
return [...this.roots];
|
|
291
|
+
}
|
|
272
292
|
get(watcher, rid) {
|
|
273
293
|
this.checkValid();
|
|
274
294
|
const res = this.resources.get(rid);
|
|
@@ -443,6 +463,19 @@ var PlTreeState = class {
|
|
|
443
463
|
}
|
|
444
464
|
res.refCount++;
|
|
445
465
|
}
|
|
466
|
+
this.collectGarbage(decrementRefs);
|
|
467
|
+
if (!allowOrphanInputs) {
|
|
468
|
+
for (const rd of resourceData) if (!this.resources.has(rd.id)) {
|
|
469
|
+
this.invalidateTree();
|
|
470
|
+
throw new TreeStateUpdateError(`orphan input resource ${rd.id}`);
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
/** Runs the refcount-decrement garbage-collection cascade over the given worklist.
|
|
475
|
+
* A resource reaching refCount 0 that is not a root is removed, and its outgoing
|
|
476
|
+
* references are decremented in turn, until the worklist drains. Factored out of
|
|
477
|
+
* {@link updateFromResourceData} so {@link setRoots} can reuse the same cascade. */
|
|
478
|
+
collectGarbage(decrementRefs) {
|
|
446
479
|
let currentRefs = decrementRefs;
|
|
447
480
|
while (currentRefs.length > 0) {
|
|
448
481
|
const nextRefs = [];
|
|
@@ -453,7 +486,7 @@ var PlTreeState = class {
|
|
|
453
486
|
throw new TreeStateUpdateError(`orphan resource ${rid}`);
|
|
454
487
|
}
|
|
455
488
|
res.refCount--;
|
|
456
|
-
if (res.refCount === 0 && res.id
|
|
489
|
+
if (res.refCount === 0 && !this.roots.has(res.id)) {
|
|
457
490
|
res.fieldsMap.forEach((field) => {
|
|
458
491
|
if ((0, _milaboratories_pl_client.isNotNullSignedResourceId)(field.value)) nextRefs.push(field.value);
|
|
459
492
|
if ((0, _milaboratories_pl_client.isNotNullSignedResourceId)(field.error)) nextRefs.push(field.error);
|
|
@@ -466,11 +499,38 @@ var PlTreeState = class {
|
|
|
466
499
|
}
|
|
467
500
|
currentRefs = nextRefs;
|
|
468
501
|
}
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
502
|
+
}
|
|
503
|
+
/** Replaces the current root set with `newRoots`.
|
|
504
|
+
*
|
|
505
|
+
* Roots that leave the set lose their GC protection: each removed root present in the
|
|
506
|
+
* heap is collected directly (a root sits at refCount 0, so it is never enqueued by an
|
|
507
|
+
* ordinary decrement), and its subtree cascades to collection through the existing
|
|
508
|
+
* refcount GC — the standard removal mechanic, applied to a root. Roots newly added to
|
|
509
|
+
* the set are protected immediately; their resources arrive on the next refresh poll. */
|
|
510
|
+
setRoots(newRoots) {
|
|
511
|
+
this.checkValid();
|
|
512
|
+
const removed = [];
|
|
513
|
+
for (const rid of this.roots) if (!newRoots.has(rid)) removed.push(rid);
|
|
514
|
+
let added = false;
|
|
515
|
+
for (const rid of newRoots) if (!this.roots.has(rid)) added = true;
|
|
516
|
+
if (removed.length === 0 && !added) return;
|
|
517
|
+
this.roots.clear();
|
|
518
|
+
for (const rid of newRoots) this.roots.add(rid);
|
|
519
|
+
this.rootsChanged.markChanged("root set changed");
|
|
520
|
+
for (const rid of removed) {
|
|
521
|
+
const res = this.resources.get(rid);
|
|
522
|
+
if (res === void 0) continue;
|
|
523
|
+
if (res.refCount > 0) continue;
|
|
524
|
+
const seed = [];
|
|
525
|
+
res.fieldsMap.forEach((field) => {
|
|
526
|
+
if ((0, _milaboratories_pl_client.isNotNullSignedResourceId)(field.value)) seed.push(field.value);
|
|
527
|
+
if ((0, _milaboratories_pl_client.isNotNullSignedResourceId)(field.error)) seed.push(field.error);
|
|
528
|
+
field.change.markChanged(`field ${field.name} removed after root ${(0, _milaboratories_pl_client.resourceIdToString)(res.id)} left the root set`);
|
|
529
|
+
});
|
|
530
|
+
if ((0, _milaboratories_pl_client.isNotNullSignedResourceId)(res.error)) seed.push(res.error);
|
|
531
|
+
res.resourceRemoved.markChanged(`resource removed after leaving the root set: ${(0, _milaboratories_pl_client.resourceIdToString)(res.id)}`);
|
|
532
|
+
this.resources.delete(rid);
|
|
533
|
+
this.collectGarbage(seed);
|
|
474
534
|
}
|
|
475
535
|
}
|
|
476
536
|
/** @deprecated use "entry" instead */
|
|
@@ -485,6 +545,7 @@ var PlTreeState = class {
|
|
|
485
545
|
invalidateTree(msg) {
|
|
486
546
|
this._isValid = false;
|
|
487
547
|
this.invalidationMessage = msg;
|
|
548
|
+
this.rootsChanged.markChanged("tree invalidated");
|
|
488
549
|
this.resources.forEach((res) => {
|
|
489
550
|
res.markAllChanged();
|
|
490
551
|
});
|