@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.
Files changed (52) hide show
  1. package/dist/accessors.cjs +23 -23
  2. package/dist/accessors.cjs.map +1 -1
  3. package/dist/accessors.d.ts +10 -10
  4. package/dist/accessors.d.ts.map +1 -1
  5. package/dist/accessors.js +23 -23
  6. package/dist/accessors.js.map +1 -1
  7. package/dist/dump.cjs.map +1 -1
  8. package/dist/dump.d.ts +1 -1
  9. package/dist/dump.js.map +1 -1
  10. package/dist/index.d.ts +9 -9
  11. package/dist/snapshot.cjs +3 -3
  12. package/dist/snapshot.cjs.map +1 -1
  13. package/dist/snapshot.d.ts +12 -12
  14. package/dist/snapshot.js +3 -3
  15. package/dist/snapshot.js.map +1 -1
  16. package/dist/state.cjs +33 -33
  17. package/dist/state.cjs.map +1 -1
  18. package/dist/state.d.ts +10 -10
  19. package/dist/state.d.ts.map +1 -1
  20. package/dist/state.js +33 -33
  21. package/dist/state.js.map +1 -1
  22. package/dist/sync.cjs +1 -1
  23. package/dist/sync.cjs.map +1 -1
  24. package/dist/sync.d.ts +2 -2
  25. package/dist/sync.d.ts.map +1 -1
  26. package/dist/sync.js +1 -1
  27. package/dist/sync.js.map +1 -1
  28. package/dist/synchronized_tree.cjs +11 -11
  29. package/dist/synchronized_tree.cjs.map +1 -1
  30. package/dist/synchronized_tree.d.ts +6 -6
  31. package/dist/synchronized_tree.d.ts.map +1 -1
  32. package/dist/synchronized_tree.js +11 -11
  33. package/dist/synchronized_tree.js.map +1 -1
  34. package/dist/test_utils.d.ts +12 -12
  35. package/dist/test_utils.d.ts.map +1 -1
  36. package/dist/traversal_ops.d.ts +1 -1
  37. package/dist/value_or_error.d.ts.map +1 -1
  38. package/package.json +23 -22
  39. package/src/accessors.ts +44 -43
  40. package/src/dump.ts +1 -1
  41. package/src/index.ts +9 -9
  42. package/src/snapshot.test.ts +29 -29
  43. package/src/snapshot.ts +26 -26
  44. package/src/state.test.ts +88 -85
  45. package/src/state.ts +123 -71
  46. package/src/sync.test.ts +31 -31
  47. package/src/sync.ts +6 -8
  48. package/src/synchronized_tree.test.ts +60 -60
  49. package/src/synchronized_tree.ts +41 -38
  50. package/src/test_utils.ts +33 -35
  51. package/src/traversal_ops.ts +1 -1
  52. 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 './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;;;;"}
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 './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';
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 === 'raw')
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 === 'raw') {
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('utf-8')));
47
+ kv[fieldName] = type.parse(JSON.parse(Buffer.from(value).toString("utf-8")));
48
48
  }
49
49
  }
50
50
  result.kv = kv;
@@ -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":";;;;;AA2CA;AACM,SAAU,QAAQ,CAKtB,MAA0D,EAAA;AAE1D,IAAA,OAAO,MAAa;AACtB;SA8DgB,oBAAoB,CAClC,GAA2D,EAC3D,MAAc,EACd,GAAmB,EAAA;AAEnB,IAAA,MAAM,IAAI,GACR,GAAG,YAAYA;AACb,UAAEC,kBAAQ,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI;UAChC,GAAG,YAAYC;AACf,cAAE,GAAG,CAAC,IAAI;cACR,GAAG;AACX,IAAA,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY;AAC9B,IAAA,MAAM,MAAM,GAA0E,EAAE,GAAG,IAAI,EAAE;AAEjG,IAAA,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE;AAC7B,QAAA,IAAI,MAAM,CAAC,IAAI,KAAK,KAAK;AAAE,YAAA,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE;;AAClD,YAAA,MAAM,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;IAC5D;AAEA,IAAA,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,EAAE;QAC/B,MAAM,MAAM,GAA2C,EAAE;;;AAGzD,QAAA,KAAK,MAAM,CAAC,SAAS,EAAE,QAAQ,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC;AAC/D,YAAA,MAAM,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC;AAChC,gBAAA,KAAK,EAAE,SAAS;AAChB,gBAAA,kBAAkB,EAAE,QAAQ;gBAC5B,gBAAgB,EAAE,CAAC,QAAQ;aAC5B,CAAC,EAAE,EAAE;AACR,QAAA,MAAM,CAAC,MAAM,GAAG,MAAM;IACxB;AAEA,IAAA,IAAI,MAAM,CAAC,EAAE,KAAK,SAAS,EAAE;QAC3B,MAAM,EAAE,GAA4B,EAAE;AACtC,QAAA,KAAK,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE;YACzD,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC;AAEzC,YAAA,IAAI,KAAK,KAAK,SAAS,EAAE;AACvB,gBAAA,MAAM,IAAI,KAAK,CAAC,iBAAiB,SAAS,CAAA,CAAE,CAAC;YAC/C;AAAO,iBAAA,IAAI,IAAI,KAAK,KAAK,EAAE;AACzB,gBAAA,EAAE,CAAC,SAAS,CAAC,GAAG,KAAK;YACvB;iBAAO;gBACL,EAAE,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;YAC9E;QACF;AACA,QAAA,MAAM,CAAC,EAAE,GAAG,EAAE;IAChB;AAEA,IAAA,OAAO,MAAa;AACtB;AAUA;SACgB,2BAA2B,CACzC,GAAmC,EACnC,MAAgB,EAChB,GAAkB,EAAA;AAElB,IAAA,IAAI,GAAG,YAAYF,qBAAW,EAAE;QAC9B,MAAM,IAAI,GAAG,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE;AACrC,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY;QAE9B,MAAM,OAAO,GAAuC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK;YACvE,IAAI;YACJ,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE;AAC/B,SAAA,CAAC;QAEF,OAAO;AACL,YAAA,GAAG,IAAI;AACP,YAAA,MAAM,EAAE,IAAI,GAAG,CAAC,OAAO,CAAC;YACxB,IAAI,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,IAAI,UAAU,EAAE;SACzC;IACH;AAEA,IAAA,OAAO,GAAG;AACZ;AASA;SACgB,+BAA+B,CAC7C,GAAuC,EACvC,MAAgB,EAChB,GAAkB,EAAA;AAElB,IAAA,IAAI,EAAE,GAAG,YAAYA,qBAAW,CAAC;AAAE,QAAA,OAAO,GAAG;IAE7C,MAAM,IAAI,GAAG,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE;AACrC,IAAA,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY;IAC9B,MAAM,SAAS,GAAoB,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;IAE9E,OAAO;AACL,QAAA,GAAG,IAAI;AACP,QAAA,QAAQ,EAAE,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC;KACxC;AACH;;;;;;;"}
@@ -1,9 +1,9 @@
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';
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 | 'raw' | undefined = undefined, Fields extends Record<string, boolean> | undefined = undefined, KV extends Record<string, ZodType | 'raw'> | undefined = undefined> = {
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 | '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>;
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 | 'raw' | undefined, Record<string, boolean> | undefined, Record<string, ZodType | 'raw'> | undefined>;
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 | 'raw' | undefined> = Data extends 'raw' ? Uint8Array : Data extends ZodType ? z.infer<Data> : undefined;
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 | 'raw'> | undefined> = KV extends undefined ? undefined : {
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['data']>, InferFieldsType<S['fields']>, InferKVType<S['kv']>>;
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 === 'raw')
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 === 'raw') {
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('utf-8')));
45
+ kv[fieldName] = type.parse(JSON.parse(Buffer.from(value).toString("utf-8")));
46
46
  }
47
47
  }
48
48
  result.kv = kv;
@@ -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 === 'string' ? { field: _step } : _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 === 'Service' || step.assertFieldType === 'Input') {
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 === 'Output') {
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('field_not_found:' + step.field);
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('field_not_resolved:' + step.field);
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
- || this.resourceReady
172
- || this.originalResourceId !== plClient.NullResourceId);
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 === 'Input' || field.type === 'Service')
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 === 'Output')
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 !== 'Input' && field.type !== 'Output')
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('marked final');
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('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');
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('marked all changed');
304
- this.resourceRemoved.markChanged('marked all changed');
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 ?? 'tree is in invalid state');
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('resource state can\t be updated after it is marked as final');
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('originalResourceId can\'t change after it is set');
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('resource can\'t change attached error after it is set');
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 === 'Input' || fd.type === 'Service') {
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 === 'Output') {
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 !== 'Dynamic')
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 === 'Input' || field.type === 'Service') {
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 === 'Output') {
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 === 'Input' || field.type === 'Service' || field.type === 'Output')
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('inputs unlocking is not permitted');
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('outputs unlocking is not permitted');
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;