@milaboratories/pl-tree 1.8.33 → 1.8.35
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/accessors.cjs +23 -23
- package/dist/accessors.cjs.map +1 -1
- package/dist/accessors.d.ts +10 -10
- package/dist/accessors.d.ts.map +1 -1
- package/dist/accessors.js +23 -23
- package/dist/accessors.js.map +1 -1
- package/dist/dump.cjs.map +1 -1
- package/dist/dump.d.ts +1 -1
- package/dist/dump.js.map +1 -1
- package/dist/index.d.ts +9 -9
- package/dist/snapshot.cjs +3 -3
- package/dist/snapshot.cjs.map +1 -1
- package/dist/snapshot.d.ts +12 -12
- package/dist/snapshot.js +3 -3
- package/dist/snapshot.js.map +1 -1
- package/dist/state.cjs +33 -33
- package/dist/state.cjs.map +1 -1
- package/dist/state.d.ts +10 -10
- package/dist/state.d.ts.map +1 -1
- package/dist/state.js +33 -33
- package/dist/state.js.map +1 -1
- package/dist/sync.cjs +1 -1
- package/dist/sync.cjs.map +1 -1
- package/dist/sync.d.ts +2 -2
- package/dist/sync.d.ts.map +1 -1
- package/dist/sync.js +1 -1
- package/dist/sync.js.map +1 -1
- package/dist/synchronized_tree.cjs +11 -11
- package/dist/synchronized_tree.cjs.map +1 -1
- package/dist/synchronized_tree.d.ts +6 -6
- package/dist/synchronized_tree.d.ts.map +1 -1
- package/dist/synchronized_tree.js +11 -11
- package/dist/synchronized_tree.js.map +1 -1
- package/dist/test_utils.d.ts +12 -12
- package/dist/test_utils.d.ts.map +1 -1
- package/dist/traversal_ops.d.ts +1 -1
- package/dist/value_or_error.d.ts.map +1 -1
- package/package.json +23 -22
- package/src/accessors.ts +44 -43
- package/src/dump.ts +1 -1
- package/src/index.ts +9 -9
- package/src/snapshot.test.ts +29 -29
- package/src/snapshot.ts +26 -26
- package/src/state.test.ts +88 -85
- package/src/state.ts +123 -71
- package/src/sync.test.ts +31 -31
- package/src/sync.ts +6 -8
- package/src/synchronized_tree.test.ts +60 -60
- package/src/synchronized_tree.ts +41 -38
- package/src/test_utils.ts +33 -35
- package/src/traversal_ops.ts +1 -1
- package/src/value_or_error.ts +6 -6
package/dist/dump.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dump.js","sources":["../src/dump.ts"],"sourcesContent":["import type { ExtendedResourceData } from
|
|
1
|
+
{"version":3,"file":"dump.js","sources":["../src/dump.ts"],"sourcesContent":["import type { ExtendedResourceData } from \"./state\";\n\nexport type ResourceStats = {\n /** Number of resources of this type */\n count: number;\n /** Total number of bytes in the field names of all resources of this type */\n fieldNameBytes: number;\n /** Total number of fields in all resources of this type */\n fieldsCount: number;\n /** Total number of bytes in the data of all resources of this type */\n dataBytes: number;\n /** Total number of key-value records in all resources of this type */\n kvCount: number;\n /** Total number of bytes in the key-value records of all resources of this type */\n kvBytes: number;\n};\n\n/**\n * A map of resource type statistics, keyed by the resource type name and version.\n *\n * @type {Record<string, ResourceStats>}\n */\nexport type TreeDumpStats = {\n total: ResourceStats;\n byResourceType: Record<`${string}/${string}`, ResourceStats>;\n};\n\n/**\n * Analyzes a collection of resources and generates statistics grouped by resource type.\n *\n * This function processes an array of ExtendedResourceData and calculates various metrics\n * for each unique resource type, including:\n * - Count of resources\n * - Total bytes in field names\n * - Total number of fields\n * - Total bytes in resource data\n * - Total number of key-value records\n * - Total bytes in key-value records\n *\n * The statistics are organized by resource type using a key in the format \"typeName/version\".\n *\n * @param dumpStats - Array of ExtendedResourceData objects to analyze\n * @returns A DumpStats object containing statistics for each resource type\n * @example\n * ```typescript\n * const resources = [...]; // Array of ExtendedResourceData\n * const stats = treeDumpStats(resources);\n * // stats = {\n * // \"MyResource/1\": {\n * // count: 5,\n * // fieldNameBytes: 150,\n * // fieldsCount: 10,\n * // dataBytes: 1024,\n * // kvCount: 3,\n * // kvBytes: 256\n * // },\n * // ...\n * // }\n * ```\n */\nexport function treeDumpStats(dumpStats: ExtendedResourceData[]): TreeDumpStats {\n const stats: TreeDumpStats = {\n total: {\n count: 0,\n fieldNameBytes: 0,\n fieldsCount: 0,\n dataBytes: 0,\n kvCount: 0,\n kvBytes: 0,\n },\n byResourceType: {},\n };\n\n for (const resource of dumpStats) {\n const typeKey = `${resource.type.name}/${resource.type.version}` as const;\n if (!stats.byResourceType[typeKey]) {\n stats.byResourceType[typeKey] = {\n count: 0,\n fieldNameBytes: 0,\n fieldsCount: 0,\n dataBytes: 0,\n kvCount: 0,\n kvBytes: 0,\n };\n }\n\n const typeStats = stats.byResourceType[typeKey];\n typeStats.count++;\n stats.total.count++;\n\n for (const field of resource.fields) {\n typeStats.fieldNameBytes += field.name.length;\n typeStats.fieldsCount++;\n stats.total.fieldNameBytes += field.name.length;\n stats.total.fieldsCount++;\n }\n\n if (resource.data) {\n const dataLength = resource.data?.length ?? 0;\n typeStats.dataBytes += dataLength;\n stats.total.dataBytes += dataLength;\n }\n\n typeStats.kvCount += resource.kv.length;\n stats.total.kvCount += resource.kv.length;\n\n for (const kv of resource.kv) {\n const kvLength = kv.key.length + kv.value.length;\n typeStats.kvBytes += kvLength;\n stats.total.kvBytes += kvLength;\n }\n }\n\n return stats;\n}\n"],"names":[],"mappings":"AA2BA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCG;AACG,SAAU,aAAa,CAAC,SAAiC,EAAA;AAC7D,IAAA,MAAM,KAAK,GAAkB;AAC3B,QAAA,KAAK,EAAE;AACL,YAAA,KAAK,EAAE,CAAC;AACR,YAAA,cAAc,EAAE,CAAC;AACjB,YAAA,WAAW,EAAE,CAAC;AACd,YAAA,SAAS,EAAE,CAAC;AACZ,YAAA,OAAO,EAAE,CAAC;AACV,YAAA,OAAO,EAAE,CAAC;AACX,SAAA;AACD,QAAA,cAAc,EAAE,EAAE;KACnB;AAED,IAAA,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE;AAChC,QAAA,MAAM,OAAO,GAAG,CAAA,EAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAA,CAAA,EAAI,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAW;QACzE,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE;AAClC,YAAA,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,GAAG;AAC9B,gBAAA,KAAK,EAAE,CAAC;AACR,gBAAA,cAAc,EAAE,CAAC;AACjB,gBAAA,WAAW,EAAE,CAAC;AACd,gBAAA,SAAS,EAAE,CAAC;AACZ,gBAAA,OAAO,EAAE,CAAC;AACV,gBAAA,OAAO,EAAE,CAAC;aACX;QACH;QAEA,MAAM,SAAS,GAAG,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC;QAC/C,SAAS,CAAC,KAAK,EAAE;AACjB,QAAA,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE;AAEnB,QAAA,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,MAAM,EAAE;YACnC,SAAS,CAAC,cAAc,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM;YAC7C,SAAS,CAAC,WAAW,EAAE;YACvB,KAAK,CAAC,KAAK,CAAC,cAAc,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM;AAC/C,YAAA,KAAK,CAAC,KAAK,CAAC,WAAW,EAAE;QAC3B;AAEA,QAAA,IAAI,QAAQ,CAAC,IAAI,EAAE;YACjB,MAAM,UAAU,GAAG,QAAQ,CAAC,IAAI,EAAE,MAAM,IAAI,CAAC;AAC7C,YAAA,SAAS,CAAC,SAAS,IAAI,UAAU;AACjC,YAAA,KAAK,CAAC,KAAK,CAAC,SAAS,IAAI,UAAU;QACrC;QAEA,SAAS,CAAC,OAAO,IAAI,QAAQ,CAAC,EAAE,CAAC,MAAM;QACvC,KAAK,CAAC,KAAK,CAAC,OAAO,IAAI,QAAQ,CAAC,EAAE,CAAC,MAAM;AAEzC,QAAA,KAAK,MAAM,EAAE,IAAI,QAAQ,CAAC,EAAE,EAAE;AAC5B,YAAA,MAAM,QAAQ,GAAG,EAAE,CAAC,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,KAAK,CAAC,MAAM;AAChD,YAAA,SAAS,CAAC,OAAO,IAAI,QAAQ;AAC7B,YAAA,KAAK,CAAC,KAAK,CAAC,OAAO,IAAI,QAAQ;QACjC;IACF;AAEA,IAAA,OAAO,KAAK;AACd;;;;"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
export * from
|
|
2
|
-
export * from
|
|
3
|
-
export * from
|
|
4
|
-
export * from
|
|
5
|
-
export * from
|
|
6
|
-
export * from
|
|
7
|
-
export * from
|
|
8
|
-
export * from
|
|
9
|
-
export * from
|
|
1
|
+
export * from "./traversal_ops";
|
|
2
|
+
export * from "./state";
|
|
3
|
+
export * from "./sync";
|
|
4
|
+
export * from "./accessors";
|
|
5
|
+
export * from "./snapshot";
|
|
6
|
+
export * from "./synchronized_tree";
|
|
7
|
+
export * from "./value_and_error";
|
|
8
|
+
export * from "./value_or_error";
|
|
9
|
+
export * from "./dump";
|
|
10
10
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/snapshot.cjs
CHANGED
|
@@ -16,7 +16,7 @@ function makeResourceSnapshot(res, schema, ctx) {
|
|
|
16
16
|
const info = node.resourceInfo;
|
|
17
17
|
const result = { ...info };
|
|
18
18
|
if (schema.data !== undefined) {
|
|
19
|
-
if (schema.data ===
|
|
19
|
+
if (schema.data === "raw")
|
|
20
20
|
result.data = node.getData();
|
|
21
21
|
else
|
|
22
22
|
result.data = schema.data.parse(node.getDataAsJson());
|
|
@@ -40,11 +40,11 @@ function makeResourceSnapshot(res, schema, ctx) {
|
|
|
40
40
|
if (value === undefined) {
|
|
41
41
|
throw new Error(`Key not found ${fieldName}`);
|
|
42
42
|
}
|
|
43
|
-
else if (type ===
|
|
43
|
+
else if (type === "raw") {
|
|
44
44
|
kv[fieldName] = value;
|
|
45
45
|
}
|
|
46
46
|
else {
|
|
47
|
-
kv[fieldName] = type.parse(JSON.parse(Buffer.from(value).toString(
|
|
47
|
+
kv[fieldName] = type.parse(JSON.parse(Buffer.from(value).toString("utf-8")));
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
result.kv = kv;
|
package/dist/snapshot.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"snapshot.cjs","sources":["../src/snapshot.ts"],"sourcesContent":["import type { ResourceId, ResourceType } from '@milaboratories/pl-client';\nimport type { Optional, Writable } from 'utility-types';\nimport type { ZodType, z } from 'zod';\nimport type { PlTreeNodeAccessor } from './accessors';\nimport { PlTreeEntry, PlTreeEntryAccessor } from './accessors';\nimport type { ComputableCtx } from '@milaboratories/computable';\nimport { notEmpty } from '@milaboratories/ts-helpers';\n\n/**\n * A DTO that can be generated from a tree node to make a snapshot of specific parts of it's state.\n * Such snapshots can then be used in core that requires this information without the need of\n * retrieving state from the tree.\n */\nexport type ResourceSnapshot<\n Data = undefined,\n Fields extends Record<string, ResourceId | undefined> | undefined = undefined,\n KV extends Record<string, unknown> | undefined = undefined,\n> = {\n readonly id: ResourceId;\n readonly type: ResourceType;\n readonly data: Data;\n readonly fields: Fields;\n readonly kv: KV;\n};\n\n/** The most generic type of ResourceSnapshot. */\ntype ResourceSnapshotGeneric = ResourceSnapshot<\n unknown,\n Record<string, ResourceId | undefined> | undefined,\n Record<string, unknown> | undefined\n>;\n\n/** Request that we'll pass to getResourceSnapshot function. We infer the type of ResourceSnapshot from this. */\nexport type ResourceSnapshotSchema<\n Data extends ZodType | 'raw' | undefined = undefined,\n Fields extends Record<string, boolean> | undefined = undefined,\n KV extends Record<string, ZodType | 'raw'> | undefined = undefined,\n> = {\n readonly data: Data;\n readonly fields: Fields;\n readonly kv: KV;\n};\n\n/** Creates ResourceSnapshotSchema. It converts an optional schema type to schema type. */\nexport function rsSchema<\n const Data extends ZodType | 'raw' | undefined = undefined,\n const Fields extends Record<string, boolean> | undefined = undefined,\n const KV extends Record<string, ZodType | 'raw'> | undefined = undefined,\n>(\n schema: Optional<ResourceSnapshotSchema<Data, Fields, KV>>,\n): ResourceSnapshotSchema<Data, Fields, KV> {\n return schema as any;\n}\n\n/** The most generic type of ResourceSnapshotSchema. */\ntype ResourceSnapshotSchemaGeneric = ResourceSnapshotSchema<\n ZodType | 'raw' | undefined,\n Record<string, boolean> | undefined,\n Record<string, ZodType | 'raw'> | undefined\n>;\n\n/**\n * If Data is 'raw' in schema, we'll get bytes,\n * if it's Zod, we'll parse it via zod.\n * Or else we just got undefined in the field.\n */\ntype InferDataType<Data extends ZodType | 'raw' | undefined> = Data extends 'raw'\n ? Uint8Array\n : Data extends ZodType\n ? z.infer<Data>\n : undefined;\n\n/**\n * If Fields is a record of field names to booleans,\n * then if the value of the field is true, we'll require this field and throw a Error if it wasn't found.\n * If it's false and doesn't exist, we'll return undefined.\n * If Fields type is undefined, we won't set fields at all.\n */\ntype InferFieldsType<Fields extends Record<string, boolean> | undefined> = Fields extends undefined\n ? undefined\n : {\n [FieldName in keyof Fields]: Fields[FieldName] extends true\n ? ResourceId\n : ResourceId | undefined;\n };\n\n/**\n * If KV is undefined, won't set it.\n * If one of values is Zod, we'll get KV and converts it to Zod schema.\n * If the value is 'raw', just returns bytes.\n */\ntype InferKVType<KV extends Record<string, ZodType | 'raw'> | undefined> = KV extends undefined\n ? undefined\n : {\n [FieldName in keyof KV]: KV[FieldName] extends ZodType ? z.infer<KV[FieldName]> : Uint8Array;\n };\n\n/** Infer ResourceSnapshot from ResourceShapshotSchema, S can be any ResourceSnapshotSchema. */\nexport type InferSnapshot<S extends ResourceSnapshotSchemaGeneric> = ResourceSnapshot<\n InferDataType<S['data']>,\n InferFieldsType<S['fields']>,\n InferKVType<S['kv']>\n>;\n\n/** Gets a ResourceSnapshot from PlTreeEntry. */\nexport function makeResourceSnapshot<Schema extends ResourceSnapshotSchemaGeneric>(\n res: PlTreeEntry,\n schema: Schema,\n ctx: ComputableCtx\n): InferSnapshot<Schema>;\nexport function makeResourceSnapshot<Schema extends ResourceSnapshotSchemaGeneric>(\n res: PlTreeEntryAccessor | PlTreeNodeAccessor,\n schema: Schema\n): InferSnapshot<Schema>;\nexport function makeResourceSnapshot<Schema extends ResourceSnapshotSchemaGeneric>(\n res: PlTreeEntry | PlTreeEntryAccessor | PlTreeNodeAccessor,\n schema: Schema,\n ctx?: ComputableCtx,\n): InferSnapshot<Schema> {\n const node\n = res instanceof PlTreeEntry\n ? notEmpty(ctx).accessor(res).node()\n : res instanceof PlTreeEntryAccessor\n ? res.node()\n : res;\n const info = node.resourceInfo;\n const result: Optional<Writable<ResourceSnapshotGeneric>, 'data' | 'fields' | 'kv'> = { ...info };\n\n if (schema.data !== undefined) {\n if (schema.data === 'raw') result.data = node.getData();\n else result.data = schema.data.parse(node.getDataAsJson());\n }\n\n if (schema.fields !== undefined) {\n const fields: Record<string, ResourceId | undefined> = {};\n // even if field is not defined, corresponding object field\n // with \"undefined\" value will still be added\n for (const [fieldName, required] of Object.entries(schema.fields))\n fields[fieldName] = node.traverse({\n field: fieldName,\n errorIfFieldNotSet: required,\n stableIfNotFound: !required,\n })?.id;\n result.fields = fields;\n }\n\n if (schema.kv !== undefined) {\n const kv: Record<string, unknown> = {};\n for (const [fieldName, type] of Object.entries(schema.kv)) {\n const value = node.getKeyValue(fieldName);\n\n if (value === undefined) {\n throw new Error(`Key not found ${fieldName}`);\n } else if (type === 'raw') {\n kv[fieldName] = value;\n } else {\n kv[fieldName] = type.parse(JSON.parse(Buffer.from(value).toString('utf-8')));\n }\n }\n result.kv = kv;\n }\n\n return result as any;\n}\n\n/** @deprecated */\nexport type ResourceWithData = {\n readonly id: ResourceId;\n readonly type: ResourceType;\n readonly fields: Map<string, ResourceId | undefined>;\n readonly data?: Uint8Array;\n};\n\n/** @deprecated */\nexport function treeEntryToResourceWithData(\n res: PlTreeEntry | ResourceWithData,\n fields: string[],\n ctx: ComputableCtx,\n): ResourceWithData {\n if (res instanceof PlTreeEntry) {\n const node = ctx.accessor(res).node();\n const info = node.resourceInfo;\n\n const fValues: [string, ResourceId | undefined][] = fields.map((name) => [\n name,\n node.getField(name)?.value?.id,\n ]);\n\n return {\n ...info,\n fields: new Map(fValues),\n data: node.getData() ?? new Uint8Array(),\n };\n }\n\n return res;\n}\n\n/** @deprecated */\nexport type ResourceWithMetadata = {\n readonly id: ResourceId;\n readonly type: ResourceType;\n readonly metadata: Record<string, any>;\n};\n\n/** @deprecated */\nexport function treeEntryToResourceWithMetadata(\n res: PlTreeEntry | ResourceWithMetadata,\n mdKeys: string[],\n ctx: ComputableCtx,\n): ResourceWithMetadata {\n if (!(res instanceof PlTreeEntry)) return res;\n\n const node = ctx.accessor(res).node();\n const info = node.resourceInfo;\n const mdEntries: [string, any][] = mdKeys.map((k) => [k, node.getKeyValue(k)]);\n\n return {\n ...info,\n metadata: Object.fromEntries(mdEntries),\n };\n}\n"],"names":["PlTreeEntry","notEmpty","PlTreeEntryAccessor"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"snapshot.cjs","sources":["../src/snapshot.ts"],"sourcesContent":["import type { ResourceId, ResourceType } from \"@milaboratories/pl-client\";\nimport type { Optional, Writable } from \"utility-types\";\nimport type { ZodType, z } from \"zod\";\nimport type { PlTreeNodeAccessor } from \"./accessors\";\nimport { PlTreeEntry, PlTreeEntryAccessor } from \"./accessors\";\nimport type { ComputableCtx } from \"@milaboratories/computable\";\nimport { notEmpty } from \"@milaboratories/ts-helpers\";\n\n/**\n * A DTO that can be generated from a tree node to make a snapshot of specific parts of it's state.\n * Such snapshots can then be used in core that requires this information without the need of\n * retrieving state from the tree.\n */\nexport type ResourceSnapshot<\n Data = undefined,\n Fields extends Record<string, ResourceId | undefined> | undefined = undefined,\n KV extends Record<string, unknown> | undefined = undefined,\n> = {\n readonly id: ResourceId;\n readonly type: ResourceType;\n readonly data: Data;\n readonly fields: Fields;\n readonly kv: KV;\n};\n\n/** The most generic type of ResourceSnapshot. */\ntype ResourceSnapshotGeneric = ResourceSnapshot<\n unknown,\n Record<string, ResourceId | undefined> | undefined,\n Record<string, unknown> | undefined\n>;\n\n/** Request that we'll pass to getResourceSnapshot function. We infer the type of ResourceSnapshot from this. */\nexport type ResourceSnapshotSchema<\n Data extends ZodType | \"raw\" | undefined = undefined,\n Fields extends Record<string, boolean> | undefined = undefined,\n KV extends Record<string, ZodType | \"raw\"> | undefined = undefined,\n> = {\n readonly data: Data;\n readonly fields: Fields;\n readonly kv: KV;\n};\n\n/** Creates ResourceSnapshotSchema. It converts an optional schema type to schema type. */\nexport function rsSchema<\n const Data extends ZodType | \"raw\" | undefined = undefined,\n const Fields extends Record<string, boolean> | undefined = undefined,\n const KV extends Record<string, ZodType | \"raw\"> | undefined = undefined,\n>(\n schema: Optional<ResourceSnapshotSchema<Data, Fields, KV>>,\n): ResourceSnapshotSchema<Data, Fields, KV> {\n return schema as any;\n}\n\n/** The most generic type of ResourceSnapshotSchema. */\ntype ResourceSnapshotSchemaGeneric = ResourceSnapshotSchema<\n ZodType | \"raw\" | undefined,\n Record<string, boolean> | undefined,\n Record<string, ZodType | \"raw\"> | undefined\n>;\n\n/**\n * If Data is 'raw' in schema, we'll get bytes,\n * if it's Zod, we'll parse it via zod.\n * Or else we just got undefined in the field.\n */\ntype InferDataType<Data extends ZodType | \"raw\" | undefined> = Data extends \"raw\"\n ? Uint8Array\n : Data extends ZodType\n ? z.infer<Data>\n : undefined;\n\n/**\n * If Fields is a record of field names to booleans,\n * then if the value of the field is true, we'll require this field and throw a Error if it wasn't found.\n * If it's false and doesn't exist, we'll return undefined.\n * If Fields type is undefined, we won't set fields at all.\n */\ntype InferFieldsType<Fields extends Record<string, boolean> | undefined> = Fields extends undefined\n ? undefined\n : {\n [FieldName in keyof Fields]: Fields[FieldName] extends true\n ? ResourceId\n : ResourceId | undefined;\n };\n\n/**\n * If KV is undefined, won't set it.\n * If one of values is Zod, we'll get KV and converts it to Zod schema.\n * If the value is 'raw', just returns bytes.\n */\ntype InferKVType<KV extends Record<string, ZodType | \"raw\"> | undefined> = KV extends undefined\n ? undefined\n : {\n [FieldName in keyof KV]: KV[FieldName] extends ZodType ? z.infer<KV[FieldName]> : Uint8Array;\n };\n\n/** Infer ResourceSnapshot from ResourceShapshotSchema, S can be any ResourceSnapshotSchema. */\nexport type InferSnapshot<S extends ResourceSnapshotSchemaGeneric> = ResourceSnapshot<\n InferDataType<S[\"data\"]>,\n InferFieldsType<S[\"fields\"]>,\n InferKVType<S[\"kv\"]>\n>;\n\n/** Gets a ResourceSnapshot from PlTreeEntry. */\nexport function makeResourceSnapshot<Schema extends ResourceSnapshotSchemaGeneric>(\n res: PlTreeEntry,\n schema: Schema,\n ctx: ComputableCtx,\n): InferSnapshot<Schema>;\nexport function makeResourceSnapshot<Schema extends ResourceSnapshotSchemaGeneric>(\n res: PlTreeEntryAccessor | PlTreeNodeAccessor,\n schema: Schema,\n): InferSnapshot<Schema>;\nexport function makeResourceSnapshot<Schema extends ResourceSnapshotSchemaGeneric>(\n res: PlTreeEntry | PlTreeEntryAccessor | PlTreeNodeAccessor,\n schema: Schema,\n ctx?: ComputableCtx,\n): InferSnapshot<Schema> {\n const node =\n res instanceof PlTreeEntry\n ? notEmpty(ctx).accessor(res).node()\n : res instanceof PlTreeEntryAccessor\n ? res.node()\n : res;\n const info = node.resourceInfo;\n const result: Optional<Writable<ResourceSnapshotGeneric>, \"data\" | \"fields\" | \"kv\"> = { ...info };\n\n if (schema.data !== undefined) {\n if (schema.data === \"raw\") result.data = node.getData();\n else result.data = schema.data.parse(node.getDataAsJson());\n }\n\n if (schema.fields !== undefined) {\n const fields: Record<string, ResourceId | undefined> = {};\n // even if field is not defined, corresponding object field\n // with \"undefined\" value will still be added\n for (const [fieldName, required] of Object.entries(schema.fields))\n fields[fieldName] = node.traverse({\n field: fieldName,\n errorIfFieldNotSet: required,\n stableIfNotFound: !required,\n })?.id;\n result.fields = fields;\n }\n\n if (schema.kv !== undefined) {\n const kv: Record<string, unknown> = {};\n for (const [fieldName, type] of Object.entries(schema.kv)) {\n const value = node.getKeyValue(fieldName);\n\n if (value === undefined) {\n throw new Error(`Key not found ${fieldName}`);\n } else if (type === \"raw\") {\n kv[fieldName] = value;\n } else {\n kv[fieldName] = type.parse(JSON.parse(Buffer.from(value).toString(\"utf-8\")));\n }\n }\n result.kv = kv;\n }\n\n return result as any;\n}\n\n/** @deprecated */\nexport type ResourceWithData = {\n readonly id: ResourceId;\n readonly type: ResourceType;\n readonly fields: Map<string, ResourceId | undefined>;\n readonly data?: Uint8Array;\n};\n\n/** @deprecated */\nexport function treeEntryToResourceWithData(\n res: PlTreeEntry | ResourceWithData,\n fields: string[],\n ctx: ComputableCtx,\n): ResourceWithData {\n if (res instanceof PlTreeEntry) {\n const node = ctx.accessor(res).node();\n const info = node.resourceInfo;\n\n const fValues: [string, ResourceId | undefined][] = fields.map((name) => [\n name,\n node.getField(name)?.value?.id,\n ]);\n\n return {\n ...info,\n fields: new Map(fValues),\n data: node.getData() ?? new Uint8Array(),\n };\n }\n\n return res;\n}\n\n/** @deprecated */\nexport type ResourceWithMetadata = {\n readonly id: ResourceId;\n readonly type: ResourceType;\n readonly metadata: Record<string, any>;\n};\n\n/** @deprecated */\nexport function treeEntryToResourceWithMetadata(\n res: PlTreeEntry | ResourceWithMetadata,\n mdKeys: string[],\n ctx: ComputableCtx,\n): ResourceWithMetadata {\n if (!(res instanceof PlTreeEntry)) return res;\n\n const node = ctx.accessor(res).node();\n const info = node.resourceInfo;\n const mdEntries: [string, any][] = mdKeys.map((k) => [k, node.getKeyValue(k)]);\n\n return {\n ...info,\n metadata: Object.fromEntries(mdEntries),\n };\n}\n"],"names":["PlTreeEntry","notEmpty","PlTreeEntryAccessor"],"mappings":"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"}
|
package/dist/snapshot.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type { ResourceId, ResourceType } from
|
|
2
|
-
import type { Optional } from
|
|
3
|
-
import type { ZodType, z } from
|
|
4
|
-
import type { PlTreeNodeAccessor } from
|
|
5
|
-
import { PlTreeEntry, PlTreeEntryAccessor } from
|
|
6
|
-
import type { ComputableCtx } from
|
|
1
|
+
import type { ResourceId, ResourceType } from "@milaboratories/pl-client";
|
|
2
|
+
import type { Optional } from "utility-types";
|
|
3
|
+
import type { ZodType, z } from "zod";
|
|
4
|
+
import type { PlTreeNodeAccessor } from "./accessors";
|
|
5
|
+
import { PlTreeEntry, PlTreeEntryAccessor } from "./accessors";
|
|
6
|
+
import type { ComputableCtx } from "@milaboratories/computable";
|
|
7
7
|
/**
|
|
8
8
|
* A DTO that can be generated from a tree node to make a snapshot of specific parts of it's state.
|
|
9
9
|
* Such snapshots can then be used in core that requires this information without the need of
|
|
@@ -17,21 +17,21 @@ export type ResourceSnapshot<Data = undefined, Fields extends Record<string, Res
|
|
|
17
17
|
readonly kv: KV;
|
|
18
18
|
};
|
|
19
19
|
/** Request that we'll pass to getResourceSnapshot function. We infer the type of ResourceSnapshot from this. */
|
|
20
|
-
export type ResourceSnapshotSchema<Data extends ZodType |
|
|
20
|
+
export type ResourceSnapshotSchema<Data extends ZodType | "raw" | undefined = undefined, Fields extends Record<string, boolean> | undefined = undefined, KV extends Record<string, ZodType | "raw"> | undefined = undefined> = {
|
|
21
21
|
readonly data: Data;
|
|
22
22
|
readonly fields: Fields;
|
|
23
23
|
readonly kv: KV;
|
|
24
24
|
};
|
|
25
25
|
/** Creates ResourceSnapshotSchema. It converts an optional schema type to schema type. */
|
|
26
|
-
export declare function rsSchema<const Data extends ZodType |
|
|
26
|
+
export declare function rsSchema<const Data extends ZodType | "raw" | undefined = undefined, const Fields extends Record<string, boolean> | undefined = undefined, const KV extends Record<string, ZodType | "raw"> | undefined = undefined>(schema: Optional<ResourceSnapshotSchema<Data, Fields, KV>>): ResourceSnapshotSchema<Data, Fields, KV>;
|
|
27
27
|
/** The most generic type of ResourceSnapshotSchema. */
|
|
28
|
-
type ResourceSnapshotSchemaGeneric = ResourceSnapshotSchema<ZodType |
|
|
28
|
+
type ResourceSnapshotSchemaGeneric = ResourceSnapshotSchema<ZodType | "raw" | undefined, Record<string, boolean> | undefined, Record<string, ZodType | "raw"> | undefined>;
|
|
29
29
|
/**
|
|
30
30
|
* If Data is 'raw' in schema, we'll get bytes,
|
|
31
31
|
* if it's Zod, we'll parse it via zod.
|
|
32
32
|
* Or else we just got undefined in the field.
|
|
33
33
|
*/
|
|
34
|
-
type InferDataType<Data extends ZodType |
|
|
34
|
+
type InferDataType<Data extends ZodType | "raw" | undefined> = Data extends "raw" ? Uint8Array : Data extends ZodType ? z.infer<Data> : undefined;
|
|
35
35
|
/**
|
|
36
36
|
* If Fields is a record of field names to booleans,
|
|
37
37
|
* then if the value of the field is true, we'll require this field and throw a Error if it wasn't found.
|
|
@@ -46,11 +46,11 @@ type InferFieldsType<Fields extends Record<string, boolean> | undefined> = Field
|
|
|
46
46
|
* If one of values is Zod, we'll get KV and converts it to Zod schema.
|
|
47
47
|
* If the value is 'raw', just returns bytes.
|
|
48
48
|
*/
|
|
49
|
-
type InferKVType<KV extends Record<string, ZodType |
|
|
49
|
+
type InferKVType<KV extends Record<string, ZodType | "raw"> | undefined> = KV extends undefined ? undefined : {
|
|
50
50
|
[FieldName in keyof KV]: KV[FieldName] extends ZodType ? z.infer<KV[FieldName]> : Uint8Array;
|
|
51
51
|
};
|
|
52
52
|
/** Infer ResourceSnapshot from ResourceShapshotSchema, S can be any ResourceSnapshotSchema. */
|
|
53
|
-
export type InferSnapshot<S extends ResourceSnapshotSchemaGeneric> = ResourceSnapshot<InferDataType<S[
|
|
53
|
+
export type InferSnapshot<S extends ResourceSnapshotSchemaGeneric> = ResourceSnapshot<InferDataType<S["data"]>, InferFieldsType<S["fields"]>, InferKVType<S["kv"]>>;
|
|
54
54
|
/** Gets a ResourceSnapshot from PlTreeEntry. */
|
|
55
55
|
export declare function makeResourceSnapshot<Schema extends ResourceSnapshotSchemaGeneric>(res: PlTreeEntry, schema: Schema, ctx: ComputableCtx): InferSnapshot<Schema>;
|
|
56
56
|
export declare function makeResourceSnapshot<Schema extends ResourceSnapshotSchemaGeneric>(res: PlTreeEntryAccessor | PlTreeNodeAccessor, schema: Schema): InferSnapshot<Schema>;
|
package/dist/snapshot.js
CHANGED
|
@@ -14,7 +14,7 @@ function makeResourceSnapshot(res, schema, ctx) {
|
|
|
14
14
|
const info = node.resourceInfo;
|
|
15
15
|
const result = { ...info };
|
|
16
16
|
if (schema.data !== undefined) {
|
|
17
|
-
if (schema.data ===
|
|
17
|
+
if (schema.data === "raw")
|
|
18
18
|
result.data = node.getData();
|
|
19
19
|
else
|
|
20
20
|
result.data = schema.data.parse(node.getDataAsJson());
|
|
@@ -38,11 +38,11 @@ function makeResourceSnapshot(res, schema, ctx) {
|
|
|
38
38
|
if (value === undefined) {
|
|
39
39
|
throw new Error(`Key not found ${fieldName}`);
|
|
40
40
|
}
|
|
41
|
-
else if (type ===
|
|
41
|
+
else if (type === "raw") {
|
|
42
42
|
kv[fieldName] = value;
|
|
43
43
|
}
|
|
44
44
|
else {
|
|
45
|
-
kv[fieldName] = type.parse(JSON.parse(Buffer.from(value).toString(
|
|
45
|
+
kv[fieldName] = type.parse(JSON.parse(Buffer.from(value).toString("utf-8")));
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
48
|
result.kv = kv;
|
package/dist/snapshot.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"snapshot.js","sources":["../src/snapshot.ts"],"sourcesContent":["import type { ResourceId, ResourceType } from '@milaboratories/pl-client';\nimport type { Optional, Writable } from 'utility-types';\nimport type { ZodType, z } from 'zod';\nimport type { PlTreeNodeAccessor } from './accessors';\nimport { PlTreeEntry, PlTreeEntryAccessor } from './accessors';\nimport type { ComputableCtx } from '@milaboratories/computable';\nimport { notEmpty } from '@milaboratories/ts-helpers';\n\n/**\n * A DTO that can be generated from a tree node to make a snapshot of specific parts of it's state.\n * Such snapshots can then be used in core that requires this information without the need of\n * retrieving state from the tree.\n */\nexport type ResourceSnapshot<\n Data = undefined,\n Fields extends Record<string, ResourceId | undefined> | undefined = undefined,\n KV extends Record<string, unknown> | undefined = undefined,\n> = {\n readonly id: ResourceId;\n readonly type: ResourceType;\n readonly data: Data;\n readonly fields: Fields;\n readonly kv: KV;\n};\n\n/** The most generic type of ResourceSnapshot. */\ntype ResourceSnapshotGeneric = ResourceSnapshot<\n unknown,\n Record<string, ResourceId | undefined> | undefined,\n Record<string, unknown> | undefined\n>;\n\n/** Request that we'll pass to getResourceSnapshot function. We infer the type of ResourceSnapshot from this. */\nexport type ResourceSnapshotSchema<\n Data extends ZodType | 'raw' | undefined = undefined,\n Fields extends Record<string, boolean> | undefined = undefined,\n KV extends Record<string, ZodType | 'raw'> | undefined = undefined,\n> = {\n readonly data: Data;\n readonly fields: Fields;\n readonly kv: KV;\n};\n\n/** Creates ResourceSnapshotSchema. It converts an optional schema type to schema type. */\nexport function rsSchema<\n const Data extends ZodType | 'raw' | undefined = undefined,\n const Fields extends Record<string, boolean> | undefined = undefined,\n const KV extends Record<string, ZodType | 'raw'> | undefined = undefined,\n>(\n schema: Optional<ResourceSnapshotSchema<Data, Fields, KV>>,\n): ResourceSnapshotSchema<Data, Fields, KV> {\n return schema as any;\n}\n\n/** The most generic type of ResourceSnapshotSchema. */\ntype ResourceSnapshotSchemaGeneric = ResourceSnapshotSchema<\n ZodType | 'raw' | undefined,\n Record<string, boolean> | undefined,\n Record<string, ZodType | 'raw'> | undefined\n>;\n\n/**\n * If Data is 'raw' in schema, we'll get bytes,\n * if it's Zod, we'll parse it via zod.\n * Or else we just got undefined in the field.\n */\ntype InferDataType<Data extends ZodType | 'raw' | undefined> = Data extends 'raw'\n ? Uint8Array\n : Data extends ZodType\n ? z.infer<Data>\n : undefined;\n\n/**\n * If Fields is a record of field names to booleans,\n * then if the value of the field is true, we'll require this field and throw a Error if it wasn't found.\n * If it's false and doesn't exist, we'll return undefined.\n * If Fields type is undefined, we won't set fields at all.\n */\ntype InferFieldsType<Fields extends Record<string, boolean> | undefined> = Fields extends undefined\n ? undefined\n : {\n [FieldName in keyof Fields]: Fields[FieldName] extends true\n ? ResourceId\n : ResourceId | undefined;\n };\n\n/**\n * If KV is undefined, won't set it.\n * If one of values is Zod, we'll get KV and converts it to Zod schema.\n * If the value is 'raw', just returns bytes.\n */\ntype InferKVType<KV extends Record<string, ZodType | 'raw'> | undefined> = KV extends undefined\n ? undefined\n : {\n [FieldName in keyof KV]: KV[FieldName] extends ZodType ? z.infer<KV[FieldName]> : Uint8Array;\n };\n\n/** Infer ResourceSnapshot from ResourceShapshotSchema, S can be any ResourceSnapshotSchema. */\nexport type InferSnapshot<S extends ResourceSnapshotSchemaGeneric> = ResourceSnapshot<\n InferDataType<S['data']>,\n InferFieldsType<S['fields']>,\n InferKVType<S['kv']>\n>;\n\n/** Gets a ResourceSnapshot from PlTreeEntry. */\nexport function makeResourceSnapshot<Schema extends ResourceSnapshotSchemaGeneric>(\n res: PlTreeEntry,\n schema: Schema,\n ctx: ComputableCtx\n): InferSnapshot<Schema>;\nexport function makeResourceSnapshot<Schema extends ResourceSnapshotSchemaGeneric>(\n res: PlTreeEntryAccessor | PlTreeNodeAccessor,\n schema: Schema\n): InferSnapshot<Schema>;\nexport function makeResourceSnapshot<Schema extends ResourceSnapshotSchemaGeneric>(\n res: PlTreeEntry | PlTreeEntryAccessor | PlTreeNodeAccessor,\n schema: Schema,\n ctx?: ComputableCtx,\n): InferSnapshot<Schema> {\n const node\n = res instanceof PlTreeEntry\n ? notEmpty(ctx).accessor(res).node()\n : res instanceof PlTreeEntryAccessor\n ? res.node()\n : res;\n const info = node.resourceInfo;\n const result: Optional<Writable<ResourceSnapshotGeneric>, 'data' | 'fields' | 'kv'> = { ...info };\n\n if (schema.data !== undefined) {\n if (schema.data === 'raw') result.data = node.getData();\n else result.data = schema.data.parse(node.getDataAsJson());\n }\n\n if (schema.fields !== undefined) {\n const fields: Record<string, ResourceId | undefined> = {};\n // even if field is not defined, corresponding object field\n // with \"undefined\" value will still be added\n for (const [fieldName, required] of Object.entries(schema.fields))\n fields[fieldName] = node.traverse({\n field: fieldName,\n errorIfFieldNotSet: required,\n stableIfNotFound: !required,\n })?.id;\n result.fields = fields;\n }\n\n if (schema.kv !== undefined) {\n const kv: Record<string, unknown> = {};\n for (const [fieldName, type] of Object.entries(schema.kv)) {\n const value = node.getKeyValue(fieldName);\n\n if (value === undefined) {\n throw new Error(`Key not found ${fieldName}`);\n } else if (type === 'raw') {\n kv[fieldName] = value;\n } else {\n kv[fieldName] = type.parse(JSON.parse(Buffer.from(value).toString('utf-8')));\n }\n }\n result.kv = kv;\n }\n\n return result as any;\n}\n\n/** @deprecated */\nexport type ResourceWithData = {\n readonly id: ResourceId;\n readonly type: ResourceType;\n readonly fields: Map<string, ResourceId | undefined>;\n readonly data?: Uint8Array;\n};\n\n/** @deprecated */\nexport function treeEntryToResourceWithData(\n res: PlTreeEntry | ResourceWithData,\n fields: string[],\n ctx: ComputableCtx,\n): ResourceWithData {\n if (res instanceof PlTreeEntry) {\n const node = ctx.accessor(res).node();\n const info = node.resourceInfo;\n\n const fValues: [string, ResourceId | undefined][] = fields.map((name) => [\n name,\n node.getField(name)?.value?.id,\n ]);\n\n return {\n ...info,\n fields: new Map(fValues),\n data: node.getData() ?? new Uint8Array(),\n };\n }\n\n return res;\n}\n\n/** @deprecated */\nexport type ResourceWithMetadata = {\n readonly id: ResourceId;\n readonly type: ResourceType;\n readonly metadata: Record<string, any>;\n};\n\n/** @deprecated */\nexport function treeEntryToResourceWithMetadata(\n res: PlTreeEntry | ResourceWithMetadata,\n mdKeys: string[],\n ctx: ComputableCtx,\n): ResourceWithMetadata {\n if (!(res instanceof PlTreeEntry)) return res;\n\n const node = ctx.accessor(res).node();\n const info = node.resourceInfo;\n const mdEntries: [string, any][] = mdKeys.map((k) => [k, node.getKeyValue(k)]);\n\n return {\n ...info,\n metadata: Object.fromEntries(mdEntries),\n };\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"snapshot.js","sources":["../src/snapshot.ts"],"sourcesContent":["import type { ResourceId, ResourceType } from \"@milaboratories/pl-client\";\nimport type { Optional, Writable } from \"utility-types\";\nimport type { ZodType, z } from \"zod\";\nimport type { PlTreeNodeAccessor } from \"./accessors\";\nimport { PlTreeEntry, PlTreeEntryAccessor } from \"./accessors\";\nimport type { ComputableCtx } from \"@milaboratories/computable\";\nimport { notEmpty } from \"@milaboratories/ts-helpers\";\n\n/**\n * A DTO that can be generated from a tree node to make a snapshot of specific parts of it's state.\n * Such snapshots can then be used in core that requires this information without the need of\n * retrieving state from the tree.\n */\nexport type ResourceSnapshot<\n Data = undefined,\n Fields extends Record<string, ResourceId | undefined> | undefined = undefined,\n KV extends Record<string, unknown> | undefined = undefined,\n> = {\n readonly id: ResourceId;\n readonly type: ResourceType;\n readonly data: Data;\n readonly fields: Fields;\n readonly kv: KV;\n};\n\n/** The most generic type of ResourceSnapshot. */\ntype ResourceSnapshotGeneric = ResourceSnapshot<\n unknown,\n Record<string, ResourceId | undefined> | undefined,\n Record<string, unknown> | undefined\n>;\n\n/** Request that we'll pass to getResourceSnapshot function. We infer the type of ResourceSnapshot from this. */\nexport type ResourceSnapshotSchema<\n Data extends ZodType | \"raw\" | undefined = undefined,\n Fields extends Record<string, boolean> | undefined = undefined,\n KV extends Record<string, ZodType | \"raw\"> | undefined = undefined,\n> = {\n readonly data: Data;\n readonly fields: Fields;\n readonly kv: KV;\n};\n\n/** Creates ResourceSnapshotSchema. It converts an optional schema type to schema type. */\nexport function rsSchema<\n const Data extends ZodType | \"raw\" | undefined = undefined,\n const Fields extends Record<string, boolean> | undefined = undefined,\n const KV extends Record<string, ZodType | \"raw\"> | undefined = undefined,\n>(\n schema: Optional<ResourceSnapshotSchema<Data, Fields, KV>>,\n): ResourceSnapshotSchema<Data, Fields, KV> {\n return schema as any;\n}\n\n/** The most generic type of ResourceSnapshotSchema. */\ntype ResourceSnapshotSchemaGeneric = ResourceSnapshotSchema<\n ZodType | \"raw\" | undefined,\n Record<string, boolean> | undefined,\n Record<string, ZodType | \"raw\"> | undefined\n>;\n\n/**\n * If Data is 'raw' in schema, we'll get bytes,\n * if it's Zod, we'll parse it via zod.\n * Or else we just got undefined in the field.\n */\ntype InferDataType<Data extends ZodType | \"raw\" | undefined> = Data extends \"raw\"\n ? Uint8Array\n : Data extends ZodType\n ? z.infer<Data>\n : undefined;\n\n/**\n * If Fields is a record of field names to booleans,\n * then if the value of the field is true, we'll require this field and throw a Error if it wasn't found.\n * If it's false and doesn't exist, we'll return undefined.\n * If Fields type is undefined, we won't set fields at all.\n */\ntype InferFieldsType<Fields extends Record<string, boolean> | undefined> = Fields extends undefined\n ? undefined\n : {\n [FieldName in keyof Fields]: Fields[FieldName] extends true\n ? ResourceId\n : ResourceId | undefined;\n };\n\n/**\n * If KV is undefined, won't set it.\n * If one of values is Zod, we'll get KV and converts it to Zod schema.\n * If the value is 'raw', just returns bytes.\n */\ntype InferKVType<KV extends Record<string, ZodType | \"raw\"> | undefined> = KV extends undefined\n ? undefined\n : {\n [FieldName in keyof KV]: KV[FieldName] extends ZodType ? z.infer<KV[FieldName]> : Uint8Array;\n };\n\n/** Infer ResourceSnapshot from ResourceShapshotSchema, S can be any ResourceSnapshotSchema. */\nexport type InferSnapshot<S extends ResourceSnapshotSchemaGeneric> = ResourceSnapshot<\n InferDataType<S[\"data\"]>,\n InferFieldsType<S[\"fields\"]>,\n InferKVType<S[\"kv\"]>\n>;\n\n/** Gets a ResourceSnapshot from PlTreeEntry. */\nexport function makeResourceSnapshot<Schema extends ResourceSnapshotSchemaGeneric>(\n res: PlTreeEntry,\n schema: Schema,\n ctx: ComputableCtx,\n): InferSnapshot<Schema>;\nexport function makeResourceSnapshot<Schema extends ResourceSnapshotSchemaGeneric>(\n res: PlTreeEntryAccessor | PlTreeNodeAccessor,\n schema: Schema,\n): InferSnapshot<Schema>;\nexport function makeResourceSnapshot<Schema extends ResourceSnapshotSchemaGeneric>(\n res: PlTreeEntry | PlTreeEntryAccessor | PlTreeNodeAccessor,\n schema: Schema,\n ctx?: ComputableCtx,\n): InferSnapshot<Schema> {\n const node =\n res instanceof PlTreeEntry\n ? notEmpty(ctx).accessor(res).node()\n : res instanceof PlTreeEntryAccessor\n ? res.node()\n : res;\n const info = node.resourceInfo;\n const result: Optional<Writable<ResourceSnapshotGeneric>, \"data\" | \"fields\" | \"kv\"> = { ...info };\n\n if (schema.data !== undefined) {\n if (schema.data === \"raw\") result.data = node.getData();\n else result.data = schema.data.parse(node.getDataAsJson());\n }\n\n if (schema.fields !== undefined) {\n const fields: Record<string, ResourceId | undefined> = {};\n // even if field is not defined, corresponding object field\n // with \"undefined\" value will still be added\n for (const [fieldName, required] of Object.entries(schema.fields))\n fields[fieldName] = node.traverse({\n field: fieldName,\n errorIfFieldNotSet: required,\n stableIfNotFound: !required,\n })?.id;\n result.fields = fields;\n }\n\n if (schema.kv !== undefined) {\n const kv: Record<string, unknown> = {};\n for (const [fieldName, type] of Object.entries(schema.kv)) {\n const value = node.getKeyValue(fieldName);\n\n if (value === undefined) {\n throw new Error(`Key not found ${fieldName}`);\n } else if (type === \"raw\") {\n kv[fieldName] = value;\n } else {\n kv[fieldName] = type.parse(JSON.parse(Buffer.from(value).toString(\"utf-8\")));\n }\n }\n result.kv = kv;\n }\n\n return result as any;\n}\n\n/** @deprecated */\nexport type ResourceWithData = {\n readonly id: ResourceId;\n readonly type: ResourceType;\n readonly fields: Map<string, ResourceId | undefined>;\n readonly data?: Uint8Array;\n};\n\n/** @deprecated */\nexport function treeEntryToResourceWithData(\n res: PlTreeEntry | ResourceWithData,\n fields: string[],\n ctx: ComputableCtx,\n): ResourceWithData {\n if (res instanceof PlTreeEntry) {\n const node = ctx.accessor(res).node();\n const info = node.resourceInfo;\n\n const fValues: [string, ResourceId | undefined][] = fields.map((name) => [\n name,\n node.getField(name)?.value?.id,\n ]);\n\n return {\n ...info,\n fields: new Map(fValues),\n data: node.getData() ?? new Uint8Array(),\n };\n }\n\n return res;\n}\n\n/** @deprecated */\nexport type ResourceWithMetadata = {\n readonly id: ResourceId;\n readonly type: ResourceType;\n readonly metadata: Record<string, any>;\n};\n\n/** @deprecated */\nexport function treeEntryToResourceWithMetadata(\n res: PlTreeEntry | ResourceWithMetadata,\n mdKeys: string[],\n ctx: ComputableCtx,\n): ResourceWithMetadata {\n if (!(res instanceof PlTreeEntry)) return res;\n\n const node = ctx.accessor(res).node();\n const info = node.resourceInfo;\n const mdEntries: [string, any][] = mdKeys.map((k) => [k, node.getKeyValue(k)]);\n\n return {\n ...info,\n metadata: Object.fromEntries(mdEntries),\n };\n}\n"],"names":[],"mappings":"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"}
|
package/dist/state.cjs
CHANGED
|
@@ -109,14 +109,14 @@ class PlTreeResource {
|
|
|
109
109
|
return [...this.fieldsMap.values()];
|
|
110
110
|
}
|
|
111
111
|
getField(watcher, _step, onUnstable = () => { }) {
|
|
112
|
-
const step = typeof _step ===
|
|
112
|
+
const step = typeof _step === "string" ? { field: _step } : _step;
|
|
113
113
|
const field = this.fieldsMap.get(step.field);
|
|
114
114
|
if (field === undefined) {
|
|
115
115
|
if (step.errorIfFieldNotFound || step.errorIfFieldNotSet)
|
|
116
116
|
throw new Error(`Field "${step.field}" not found in resource ${plClient.resourceIdToString(this.id)}`);
|
|
117
117
|
if (!this.inputsLocked)
|
|
118
118
|
this.inputAndServiceFieldListChanged?.attachWatcher(watcher);
|
|
119
|
-
else if (step.assertFieldType ===
|
|
119
|
+
else if (step.assertFieldType === "Service" || step.assertFieldType === "Input") {
|
|
120
120
|
if (step.allowPermanentAbsence)
|
|
121
121
|
// stable absence of field
|
|
122
122
|
return undefined;
|
|
@@ -125,7 +125,7 @@ class PlTreeResource {
|
|
|
125
125
|
}
|
|
126
126
|
if (!this.outputsLocked)
|
|
127
127
|
this.outputFieldListChanged?.attachWatcher(watcher);
|
|
128
|
-
else if (step.assertFieldType ===
|
|
128
|
+
else if (step.assertFieldType === "Output") {
|
|
129
129
|
if (step.allowPermanentAbsence)
|
|
130
130
|
// stable absence of field
|
|
131
131
|
return undefined;
|
|
@@ -134,7 +134,7 @@ class PlTreeResource {
|
|
|
134
134
|
}
|
|
135
135
|
this.dynamicFieldListChanged?.attachWatcher(watcher);
|
|
136
136
|
if (!this._finalState && !step.stableIfNotFound)
|
|
137
|
-
onUnstable(
|
|
137
|
+
onUnstable("field_not_found:" + step.field);
|
|
138
138
|
return undefined;
|
|
139
139
|
}
|
|
140
140
|
else {
|
|
@@ -149,7 +149,7 @@ class PlTreeResource {
|
|
|
149
149
|
// this method returns value and error of the field, thus those values are considered to be accessed;
|
|
150
150
|
// any existing but not resolved field here is considered to be unstable, in the sense it is
|
|
151
151
|
// considered to acquire some resolved value eventually
|
|
152
|
-
onUnstable(
|
|
152
|
+
onUnstable("field_not_resolved:" + step.field);
|
|
153
153
|
field.change.attachWatcher(watcher);
|
|
154
154
|
return ret;
|
|
155
155
|
}
|
|
@@ -167,9 +167,9 @@ class PlTreeResource {
|
|
|
167
167
|
return this.outputsLocked;
|
|
168
168
|
}
|
|
169
169
|
get isReadyOrError() {
|
|
170
|
-
return (this.error !== plClient.NullResourceId
|
|
171
|
-
|
|
172
|
-
|
|
170
|
+
return (this.error !== plClient.NullResourceId ||
|
|
171
|
+
this.resourceReady ||
|
|
172
|
+
this.originalResourceId !== plClient.NullResourceId);
|
|
173
173
|
}
|
|
174
174
|
getIsFinal(watcher) {
|
|
175
175
|
this.finalChanged?.attachWatcher(watcher);
|
|
@@ -194,7 +194,7 @@ class PlTreeResource {
|
|
|
194
194
|
listInputFields(watcher) {
|
|
195
195
|
const ret = [];
|
|
196
196
|
this.fieldsMap.forEach((field, name) => {
|
|
197
|
-
if (field.type ===
|
|
197
|
+
if (field.type === "Input" || field.type === "Service")
|
|
198
198
|
ret.push(name);
|
|
199
199
|
});
|
|
200
200
|
if (!this.inputsLocked)
|
|
@@ -204,7 +204,7 @@ class PlTreeResource {
|
|
|
204
204
|
listOutputFields(watcher) {
|
|
205
205
|
const ret = [];
|
|
206
206
|
this.fieldsMap.forEach((field, name) => {
|
|
207
|
-
if (field.type ===
|
|
207
|
+
if (field.type === "Output")
|
|
208
208
|
ret.push(name);
|
|
209
209
|
});
|
|
210
210
|
if (!this.outputsLocked)
|
|
@@ -214,7 +214,7 @@ class PlTreeResource {
|
|
|
214
214
|
listDynamicFields(watcher) {
|
|
215
215
|
const ret = [];
|
|
216
216
|
this.fieldsMap.forEach((field, name) => {
|
|
217
|
-
if (field.type !==
|
|
217
|
+
if (field.type !== "Input" && field.type !== "Output")
|
|
218
218
|
ret.push(name);
|
|
219
219
|
});
|
|
220
220
|
this.dynamicFieldListChanged?.attachWatcher(watcher);
|
|
@@ -280,7 +280,7 @@ class PlTreeResource {
|
|
|
280
280
|
if (this._finalState)
|
|
281
281
|
return;
|
|
282
282
|
this._finalState = true;
|
|
283
|
-
tsHelpers.notEmpty(this.finalChanged).markChanged(
|
|
283
|
+
tsHelpers.notEmpty(this.finalChanged).markChanged("marked final");
|
|
284
284
|
this.finalChanged = undefined;
|
|
285
285
|
this.resourceStateChange = undefined;
|
|
286
286
|
this.dynamicFieldListChanged = undefined;
|
|
@@ -292,16 +292,16 @@ class PlTreeResource {
|
|
|
292
292
|
}
|
|
293
293
|
/** Used for invalidation */
|
|
294
294
|
markAllChanged() {
|
|
295
|
-
this.fieldsMap.forEach((field) => field.change.markChanged(
|
|
296
|
-
this.finalChanged?.markChanged(
|
|
297
|
-
this.resourceStateChange?.markChanged(
|
|
298
|
-
this.lockedChange?.markChanged(
|
|
299
|
-
this.inputAndServiceFieldListChanged?.markChanged(
|
|
300
|
-
this.outputFieldListChanged?.markChanged(
|
|
301
|
-
this.dynamicFieldListChanged?.markChanged(
|
|
295
|
+
this.fieldsMap.forEach((field) => field.change.markChanged("marked all changed"));
|
|
296
|
+
this.finalChanged?.markChanged("marked all changed");
|
|
297
|
+
this.resourceStateChange?.markChanged("marked all changed");
|
|
298
|
+
this.lockedChange?.markChanged("marked all changed");
|
|
299
|
+
this.inputAndServiceFieldListChanged?.markChanged("marked all changed");
|
|
300
|
+
this.outputFieldListChanged?.markChanged("marked all changed");
|
|
301
|
+
this.dynamicFieldListChanged?.markChanged("marked all changed");
|
|
302
302
|
// this.kvChangedGlobal?.markChanged('marked all changed');
|
|
303
|
-
this.kvChangedPerKey?.markAllChanged(
|
|
304
|
-
this.resourceRemoved.markChanged(
|
|
303
|
+
this.kvChangedPerKey?.markAllChanged("marked all changed");
|
|
304
|
+
this.resourceRemoved.markChanged("marked all changed");
|
|
305
305
|
}
|
|
306
306
|
}
|
|
307
307
|
class PlTreeState {
|
|
@@ -325,7 +325,7 @@ class PlTreeState {
|
|
|
325
325
|
}
|
|
326
326
|
checkValid() {
|
|
327
327
|
if (!this._isValid)
|
|
328
|
-
throw new Error(this.invalidationMessage ??
|
|
328
|
+
throw new Error(this.invalidationMessage ?? "tree is in invalid state");
|
|
329
329
|
}
|
|
330
330
|
get(watcher, rid) {
|
|
331
331
|
this.checkValid();
|
|
@@ -357,14 +357,14 @@ class PlTreeState {
|
|
|
357
357
|
if (resource !== undefined) {
|
|
358
358
|
// updating existing resource
|
|
359
359
|
if (resource.finalState)
|
|
360
|
-
unexpectedTransitionError(
|
|
360
|
+
unexpectedTransitionError("resource state can\t be updated after it is marked as final");
|
|
361
361
|
let changed = false;
|
|
362
362
|
// updating resource version, even if it was not changed
|
|
363
363
|
resource.version += 1;
|
|
364
364
|
// duplicate / original
|
|
365
365
|
if (resource.originalResourceId !== rd.originalResourceId) {
|
|
366
366
|
if (resource.originalResourceId !== plClient.NullResourceId)
|
|
367
|
-
unexpectedTransitionError(
|
|
367
|
+
unexpectedTransitionError("originalResourceId can't change after it is set");
|
|
368
368
|
resource.originalResourceId = rd.originalResourceId;
|
|
369
369
|
// duplicate status of the resource counts as ready for the external observer
|
|
370
370
|
tsHelpers.notEmpty(resource.resourceStateChange).markChanged(`originalResourceId changed for ${plClient.resourceIdToString(resource.id)}`);
|
|
@@ -373,7 +373,7 @@ class PlTreeState {
|
|
|
373
373
|
// error
|
|
374
374
|
if (resource.error !== rd.error) {
|
|
375
375
|
if (plClient.isNotNullResourceId(resource.error))
|
|
376
|
-
unexpectedTransitionError(
|
|
376
|
+
unexpectedTransitionError("resource can't change attached error after it is set");
|
|
377
377
|
resource.error = rd.error;
|
|
378
378
|
incrementRefs.push(resource.error);
|
|
379
379
|
tsHelpers.notEmpty(resource.resourceStateChange).markChanged(`error changed for ${plClient.resourceIdToString(resource.id)}`);
|
|
@@ -389,12 +389,12 @@ class PlTreeState {
|
|
|
389
389
|
incrementRefs.push(fd.value);
|
|
390
390
|
if (plClient.isNotNullResourceId(fd.error))
|
|
391
391
|
incrementRefs.push(fd.error);
|
|
392
|
-
if (fd.type ===
|
|
392
|
+
if (fd.type === "Input" || fd.type === "Service") {
|
|
393
393
|
if (resource.inputsLocked)
|
|
394
394
|
unexpectedTransitionError(`adding ${fd.type} (${fd.name}) field while inputs locked`);
|
|
395
395
|
tsHelpers.notEmpty(resource.inputAndServiceFieldListChanged).markChanged(`new ${fd.type} field ${fd.name} added to ${plClient.resourceIdToString(resource.id)}`);
|
|
396
396
|
}
|
|
397
|
-
else if (fd.type ===
|
|
397
|
+
else if (fd.type === "Output") {
|
|
398
398
|
if (resource.outputsLocked)
|
|
399
399
|
unexpectedTransitionError(`adding ${fd.type} (${fd.name}) field while outputs locked`);
|
|
400
400
|
tsHelpers.notEmpty(resource.outputFieldListChanged).markChanged(`new ${fd.type} field ${fd.name} added to ${plClient.resourceIdToString(resource.id)}`);
|
|
@@ -409,15 +409,15 @@ class PlTreeState {
|
|
|
409
409
|
// change of old field
|
|
410
410
|
// in principle this transition is possible, see assertions below
|
|
411
411
|
if (field.type !== fd.type) {
|
|
412
|
-
if (field.type !==
|
|
412
|
+
if (field.type !== "Dynamic")
|
|
413
413
|
unexpectedTransitionError(`field changed type ${field.type} -> ${fd.type}`);
|
|
414
414
|
tsHelpers.notEmpty(resource.dynamicFieldListChanged).markChanged(`field ${fd.name} changed type from Dynamic to ${fd.type} in ${plClient.resourceIdToString(resource.id)}`);
|
|
415
|
-
if (field.type ===
|
|
415
|
+
if (field.type === "Input" || field.type === "Service") {
|
|
416
416
|
if (resource.inputsLocked)
|
|
417
417
|
unexpectedTransitionError(`adding input field "${fd.name}", while corresponding list is locked`);
|
|
418
418
|
tsHelpers.notEmpty(resource.inputAndServiceFieldListChanged).markChanged(`field ${fd.name} changed to type ${fd.type} in ${plClient.resourceIdToString(resource.id)}`);
|
|
419
419
|
}
|
|
420
|
-
if (field.type ===
|
|
420
|
+
if (field.type === "Output") {
|
|
421
421
|
if (resource.outputsLocked)
|
|
422
422
|
unexpectedTransitionError(`adding output field "${fd.name}", while corresponding list is locked`);
|
|
423
423
|
tsHelpers.notEmpty(resource.outputFieldListChanged).markChanged(`field ${fd.name} changed to type ${fd.type} in ${plClient.resourceIdToString(resource.id)}`);
|
|
@@ -464,7 +464,7 @@ class PlTreeState {
|
|
|
464
464
|
// detecting removed fields
|
|
465
465
|
resource.fieldsMap.forEach((field, fieldName, fields) => {
|
|
466
466
|
if (field.resourceVersion !== resource.version) {
|
|
467
|
-
if (field.type ===
|
|
467
|
+
if (field.type === "Input" || field.type === "Service" || field.type === "Output")
|
|
468
468
|
unexpectedTransitionError(`removal of ${field.type} field ${fieldName}`);
|
|
469
469
|
field.change.markChanged(`dynamic field ${fieldName} removed from ${plClient.resourceIdToString(resource.id)}`);
|
|
470
470
|
fields.delete(fieldName);
|
|
@@ -478,7 +478,7 @@ class PlTreeState {
|
|
|
478
478
|
// inputsLocked
|
|
479
479
|
if (resource.inputsLocked !== rd.inputsLocked) {
|
|
480
480
|
if (resource.inputsLocked)
|
|
481
|
-
unexpectedTransitionError(
|
|
481
|
+
unexpectedTransitionError("inputs unlocking is not permitted");
|
|
482
482
|
resource.inputsLocked = rd.inputsLocked;
|
|
483
483
|
tsHelpers.notEmpty(resource.lockedChange).markChanged(`inputs locked for ${plClient.resourceIdToString(resource.id)}`);
|
|
484
484
|
changed = true;
|
|
@@ -486,7 +486,7 @@ class PlTreeState {
|
|
|
486
486
|
// outputsLocked
|
|
487
487
|
if (resource.outputsLocked !== rd.outputsLocked) {
|
|
488
488
|
if (resource.outputsLocked)
|
|
489
|
-
unexpectedTransitionError(
|
|
489
|
+
unexpectedTransitionError("outputs unlocking is not permitted");
|
|
490
490
|
resource.outputsLocked = rd.outputsLocked;
|
|
491
491
|
tsHelpers.notEmpty(resource.lockedChange).markChanged(`outputs locked for ${plClient.resourceIdToString(resource.id)}`);
|
|
492
492
|
changed = true;
|