@milaboratories/pl-middle-layer 1.61.11 → 1.62.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -36,6 +36,14 @@ const LibRenderer = {
36
36
  return tx.createValue(_milaboratories_pl_model_backend.PlTemplateLibV1.type, JSON.stringify(_milaboratories_pl_model_backend.PlTemplateLibV1.fromV3Data(resource, getSourceCode(resource.name, sources, resource.sourceHash)).data));
37
37
  }
38
38
  };
39
+ const WasmRenderer = {
40
+ updateCacheKey(resource, hash, sources) {
41
+ hash.update(_milaboratories_pl_model_backend.PlWasmV1.type.name).update(_milaboratories_pl_model_backend.PlWasmV1.type.version).update(resource.name).update(resource.version).update(getSourceCode(resource.name, sources, resource.sourceHash));
42
+ },
43
+ render(resource, tx, _creator, sources) {
44
+ return tx.createValue(_milaboratories_pl_model_backend.PlWasmV1.type, JSON.stringify(_milaboratories_pl_model_backend.PlWasmV1.fromV3Data(resource, getSourceCode(resource.name, sources, resource.sourceHash)).data));
45
+ }
46
+ };
39
47
  const SoftwareInfoRenderer = {
40
48
  updateCacheKey(resource, hash, sources) {
41
49
  hash.update(_milaboratories_pl_model_backend.PlTemplateSoftwareV1.type.name).update(_milaboratories_pl_model_backend.PlTemplateSoftwareV1.type.version).update(resource.name).update(resource.version).update(getSourceCode(resource.name, sources, resource.sourceHash));
@@ -71,6 +79,10 @@ const TemplateRenderer = {
71
79
  hash.update("tpl:" + tplId);
72
80
  this.updateCacheKey(tpl, hash, sources);
73
81
  }
82
+ for (const [wasmId, wasm] of srt(Object.entries(resource.wasm ?? {}))) {
83
+ hash.update("wasm:" + wasmId);
84
+ WasmRenderer.updateCacheKey(wasm, hash, sources);
85
+ }
74
86
  },
75
87
  render(resource, tx, _creator, sources) {
76
88
  const tplRef = tx.createStruct(_milaboratories_pl_model_backend.PlTemplateV1.type, JSON.stringify(_milaboratories_pl_model_backend.PlTemplateV1.fromV3Data(resource, getSourceCode(resource.name, sources, resource.sourceHash)).data));
@@ -94,6 +106,11 @@ const TemplateRenderer = {
94
106
  tx.createField(fld, "Input");
95
107
  tx.setField(fld, _creator(depTpl, TemplateRenderer, sources));
96
108
  }
109
+ for (const [wasmId, wasm] of Object.entries(resource.wasm ?? {})) {
110
+ const fld = _milaboratories_pl_model_backend.PlTemplateV1.wasmField(tplRef, wasmId);
111
+ tx.createField(fld, "Input");
112
+ tx.setField(fld, _creator(wasm, WasmRenderer, sources));
113
+ }
97
114
  tx.lock(tplRef);
98
115
  if (!resource.hashOverride) return tplRef;
99
116
  const overrideRef = tx.createStruct(_milaboratories_pl_model_backend.PlTemplateOverrideV1.type, JSON.stringify(_milaboratories_pl_model_backend.PlTemplateOverrideV1.fromV3Data(resource)));
@@ -1 +1 @@
1
- {"version":3,"file":"direct_template_loader_v3.cjs","names":["PlTemplateLibV1","PlTemplateSoftwareV1","PlTemplateV1","PlTemplateOverrideV1"],"sources":["../../../src/mutator/template/direct_template_loader_v3.ts"],"sourcesContent":["import type { AnyRef, AnyResourceRef, PlTransaction } from \"@milaboratories/pl-client\";\nimport type { Hash } from \"node:crypto\";\nimport { createHash } from \"node:crypto\";\nimport type {\n CompiledTemplateV3,\n TemplateDataV3,\n TemplateLibDataV3,\n TemplateSoftwareDataV3,\n} from \"@milaboratories/pl-model-backend\";\nimport {\n PlTemplateLibV1,\n PlTemplateSoftwareV1,\n PlTemplateV1,\n PlTemplateOverrideV1,\n} from \"@milaboratories/pl-model-backend\";\nimport { notEmpty } from \"@milaboratories/ts-helpers\";\n\n/**\n * Renders the tree of templates by caching all resource ids\n * by their cache keys.\n * It's different from v2 version because we provide\n * the hash map of the code of all sources everywhere.\n * It does a double-dispatch on the node type (template, library etc),\n * and creates resources.\n *\n * IMO, it'd be clearer to rewrite it with Visitor pattern, and separate\n * tree traversing and operations on it, but I don't have time to do it now.\n */\nexport function createTemplateV3Tree(tx: PlTransaction, tplData: CompiledTemplateV3): AnyRef {\n const resourceCache = new Map<string, AnyResourceRef>();\n\n const createResourceCached = <T>(\n resource: T,\n renderer: Renderer<T>,\n hashToSource: Record<string, string>,\n ): AnyResourceRef => {\n const key: Hash = createHash(\"sha256\");\n renderer.updateCacheKey(resource, key, hashToSource);\n\n const rKey = key.digest(\"hex\");\n\n if (!resourceCache.has(rKey)) {\n const rId = renderer.render(resource, tx, createResourceCached, hashToSource);\n resourceCache.set(rKey, rId);\n }\n\n return resourceCache.get(rKey)!;\n };\n\n return createResourceCached(tplData.template, TemplateRenderer, tplData.hashToSource);\n}\n\ntype Renderer<T> = {\n /** Updates the cache key by adding all info of the artifact. */\n updateCacheKey: CacheKey<T>;\n /** Create resources for all dependencies recursively and then for this artifact. */\n render: (\n resource: T,\n tx: PlTransaction,\n creator: Creator,\n sources: Record<string, string>,\n ) => AnyResourceRef;\n};\ntype CacheKey<T> = (resource: T, key: Hash, sources: Record<string, string>) => void;\ntype Creator = <T>(\n resource: T,\n renderer: Renderer<T>,\n sources: Record<string, string>,\n) => AnyResourceRef;\n\nconst LibRenderer: Renderer<TemplateLibDataV3> = {\n updateCacheKey(resource, hash, sources) {\n hash\n .update(PlTemplateLibV1.type.name)\n .update(PlTemplateLibV1.type.version)\n .update(resource.name)\n .update(resource.version)\n .update(getSourceCode(resource.name, sources, resource.sourceHash));\n },\n render(resource, tx, _creator, sources) {\n return tx.createValue(\n PlTemplateLibV1.type,\n JSON.stringify(\n PlTemplateLibV1.fromV3Data(\n resource,\n getSourceCode(resource.name, sources, resource.sourceHash),\n ).data,\n ),\n );\n },\n};\n\nconst SoftwareInfoRenderer: Renderer<TemplateSoftwareDataV3> = {\n updateCacheKey(resource, hash, sources) {\n hash\n .update(PlTemplateSoftwareV1.type.name)\n .update(PlTemplateSoftwareV1.type.version)\n .update(resource.name)\n .update(resource.version)\n .update(getSourceCode(resource.name, sources, resource.sourceHash));\n },\n render(resource, tx, _creator, sources) {\n const sw = PlTemplateSoftwareV1.fromV3Data(\n resource,\n getSourceCode(resource.name, sources, resource.sourceHash),\n );\n const ref = tx.createStruct(PlTemplateSoftwareV1.type, sw.data);\n tx.setKValue(ref, PlTemplateSoftwareV1.metaNameKey, JSON.stringify(sw.name));\n tx.lock(ref);\n return ref;\n },\n};\n\nconst TemplateRenderer: Renderer<TemplateDataV3> = {\n updateCacheKey(resource, hash, sources) {\n hash\n .update(PlTemplateV1.type.name)\n .update(PlTemplateV1.type.version)\n .update(resource.hashOverride ?? \"no-override\")\n .update(resource.name)\n .update(resource.version)\n .update(getSourceCode(resource.name, sources, resource.sourceHash));\n\n const srt = <T>(entries: [string, T][]): [string, T][] => {\n entries.sort((a, b) => (a[0] === b[0] ? 0 : a[0] < b[0] ? -1 : 1));\n return entries;\n };\n\n for (const [libId, lib] of srt(Object.entries(resource.libs ?? {}))) {\n hash.update(\"lib:\" + libId);\n LibRenderer.updateCacheKey(lib, hash, sources);\n }\n for (const [swId, sw] of srt(Object.entries(resource.software ?? {}))) {\n hash.update(\"soft:\" + swId);\n SoftwareInfoRenderer.updateCacheKey(sw, hash, sources);\n }\n for (const [swId, sw] of srt(Object.entries(resource.assets ?? {}))) {\n hash.update(\"asset:\" + swId);\n SoftwareInfoRenderer.updateCacheKey(sw, hash, sources);\n }\n for (const [tplId, tpl] of srt(Object.entries(resource.templates ?? {}))) {\n hash.update(\"tpl:\" + tplId);\n this.updateCacheKey(tpl, hash, sources);\n }\n },\n render(resource, tx, _creator, sources) {\n const tplRef = tx.createStruct(\n PlTemplateV1.type,\n JSON.stringify(\n PlTemplateV1.fromV3Data(\n resource,\n getSourceCode(resource.name, sources, resource.sourceHash),\n ).data,\n ),\n );\n // Render libraries\n for (const [libId, lib] of Object.entries(resource.libs ?? {})) {\n const fld = PlTemplateV1.libField(tplRef, libId);\n tx.createField(fld, \"Input\");\n tx.setField(fld, _creator(lib, LibRenderer, sources));\n }\n\n // Render software and assets\n for (const [swId, sw] of Object.entries(resource.software ?? {})) {\n const fld = PlTemplateV1.swField(tplRef, swId);\n tx.createField(fld, \"Input\");\n tx.setField(fld, _creator(sw, SoftwareInfoRenderer, sources));\n }\n for (const [swId, sw] of Object.entries(resource.assets ?? {})) {\n const fld = PlTemplateV1.swField(tplRef, swId);\n tx.createField(fld, \"Input\");\n tx.setField(fld, _creator(sw, SoftwareInfoRenderer, sources));\n }\n\n // Render dependency templates\n for (const [depTplId, depTpl] of Object.entries(resource.templates ?? {})) {\n const fld = PlTemplateV1.tplField(tplRef, depTplId);\n tx.createField(fld, \"Input\");\n tx.setField(fld, _creator(depTpl, TemplateRenderer, sources));\n }\n\n tx.lock(tplRef);\n\n if (!resource.hashOverride) return tplRef;\n\n // Override template hash with proxy resource, when hash override is configured for template\n const overrideRef = tx.createStruct(\n PlTemplateOverrideV1.type,\n JSON.stringify(PlTemplateOverrideV1.fromV3Data(resource)),\n );\n const fld = PlTemplateOverrideV1.tplField(overrideRef);\n tx.createField(fld, \"Service\");\n tx.setField(fld, tplRef);\n tx.lock(overrideRef);\n return overrideRef;\n },\n};\n\n/**\n * Gets a source code of the artifact by its source hash.\n * the source hash was calculated and stored by tengo compiler\n * and is different from the hash we're using for caching here.\n */\nfunction getSourceCode(name: string, sources: Record<string, string>, sourceHash: string): string {\n return notEmpty(\n sources[sourceHash],\n `trying to get \"${name}\" source: sources map doesn't contain source hash ${sourceHash}`,\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"direct_template_loader_v3.cjs","names":["PlTemplateLibV1","PlWasmV1","PlTemplateSoftwareV1","PlTemplateV1","PlTemplateOverrideV1"],"sources":["../../../src/mutator/template/direct_template_loader_v3.ts"],"sourcesContent":["import type { AnyRef, AnyResourceRef, PlTransaction } from \"@milaboratories/pl-client\";\nimport type { Hash } from \"node:crypto\";\nimport { createHash } from \"node:crypto\";\nimport type {\n CompiledTemplateV3,\n TemplateDataV3,\n TemplateLibDataV3,\n TemplateSoftwareDataV3,\n TemplateWasmDataV3,\n} from \"@milaboratories/pl-model-backend\";\nimport {\n PlTemplateLibV1,\n PlTemplateSoftwareV1,\n PlTemplateV1,\n PlTemplateOverrideV1,\n PlWasmV1,\n} from \"@milaboratories/pl-model-backend\";\nimport { notEmpty } from \"@milaboratories/ts-helpers\";\n\n/**\n * Renders the tree of templates by caching all resource ids\n * by their cache keys.\n * It's different from v2 version because we provide\n * the hash map of the code of all sources everywhere.\n * It does a double-dispatch on the node type (template, library etc),\n * and creates resources.\n *\n * IMO, it'd be clearer to rewrite it with Visitor pattern, and separate\n * tree traversing and operations on it, but I don't have time to do it now.\n */\nexport function createTemplateV3Tree(tx: PlTransaction, tplData: CompiledTemplateV3): AnyRef {\n const resourceCache = new Map<string, AnyResourceRef>();\n\n const createResourceCached = <T>(\n resource: T,\n renderer: Renderer<T>,\n hashToSource: Record<string, string>,\n ): AnyResourceRef => {\n const key: Hash = createHash(\"sha256\");\n renderer.updateCacheKey(resource, key, hashToSource);\n\n const rKey = key.digest(\"hex\");\n\n if (!resourceCache.has(rKey)) {\n const rId = renderer.render(resource, tx, createResourceCached, hashToSource);\n resourceCache.set(rKey, rId);\n }\n\n return resourceCache.get(rKey)!;\n };\n\n return createResourceCached(tplData.template, TemplateRenderer, tplData.hashToSource);\n}\n\ntype Renderer<T> = {\n /** Updates the cache key by adding all info of the artifact. */\n updateCacheKey: CacheKey<T>;\n /** Create resources for all dependencies recursively and then for this artifact. */\n render: (\n resource: T,\n tx: PlTransaction,\n creator: Creator,\n sources: Record<string, string>,\n ) => AnyResourceRef;\n};\ntype CacheKey<T> = (resource: T, key: Hash, sources: Record<string, string>) => void;\ntype Creator = <T>(\n resource: T,\n renderer: Renderer<T>,\n sources: Record<string, string>,\n) => AnyResourceRef;\n\nconst LibRenderer: Renderer<TemplateLibDataV3> = {\n updateCacheKey(resource, hash, sources) {\n hash\n .update(PlTemplateLibV1.type.name)\n .update(PlTemplateLibV1.type.version)\n .update(resource.name)\n .update(resource.version)\n .update(getSourceCode(resource.name, sources, resource.sourceHash));\n },\n render(resource, tx, _creator, sources) {\n return tx.createValue(\n PlTemplateLibV1.type,\n JSON.stringify(\n PlTemplateLibV1.fromV3Data(\n resource,\n getSourceCode(resource.name, sources, resource.sourceHash),\n ).data,\n ),\n );\n },\n};\n\nconst WasmRenderer: Renderer<TemplateWasmDataV3> = {\n updateCacheKey(resource, hash, sources) {\n hash\n .update(PlWasmV1.type.name)\n .update(PlWasmV1.type.version)\n .update(resource.name)\n .update(resource.version)\n .update(getSourceCode(resource.name, sources, resource.sourceHash));\n },\n render(resource, tx, _creator, sources) {\n return tx.createValue(\n PlWasmV1.type,\n JSON.stringify(\n PlWasmV1.fromV3Data(resource, getSourceCode(resource.name, sources, resource.sourceHash))\n .data,\n ),\n );\n },\n};\n\nconst SoftwareInfoRenderer: Renderer<TemplateSoftwareDataV3> = {\n updateCacheKey(resource, hash, sources) {\n hash\n .update(PlTemplateSoftwareV1.type.name)\n .update(PlTemplateSoftwareV1.type.version)\n .update(resource.name)\n .update(resource.version)\n .update(getSourceCode(resource.name, sources, resource.sourceHash));\n },\n render(resource, tx, _creator, sources) {\n const sw = PlTemplateSoftwareV1.fromV3Data(\n resource,\n getSourceCode(resource.name, sources, resource.sourceHash),\n );\n const ref = tx.createStruct(PlTemplateSoftwareV1.type, sw.data);\n tx.setKValue(ref, PlTemplateSoftwareV1.metaNameKey, JSON.stringify(sw.name));\n tx.lock(ref);\n return ref;\n },\n};\n\nconst TemplateRenderer: Renderer<TemplateDataV3> = {\n updateCacheKey(resource, hash, sources) {\n hash\n .update(PlTemplateV1.type.name)\n .update(PlTemplateV1.type.version)\n .update(resource.hashOverride ?? \"no-override\")\n .update(resource.name)\n .update(resource.version)\n .update(getSourceCode(resource.name, sources, resource.sourceHash));\n\n const srt = <T>(entries: [string, T][]): [string, T][] => {\n entries.sort((a, b) => (a[0] === b[0] ? 0 : a[0] < b[0] ? -1 : 1));\n return entries;\n };\n\n for (const [libId, lib] of srt(Object.entries(resource.libs ?? {}))) {\n hash.update(\"lib:\" + libId);\n LibRenderer.updateCacheKey(lib, hash, sources);\n }\n for (const [swId, sw] of srt(Object.entries(resource.software ?? {}))) {\n hash.update(\"soft:\" + swId);\n SoftwareInfoRenderer.updateCacheKey(sw, hash, sources);\n }\n for (const [swId, sw] of srt(Object.entries(resource.assets ?? {}))) {\n hash.update(\"asset:\" + swId);\n SoftwareInfoRenderer.updateCacheKey(sw, hash, sources);\n }\n for (const [tplId, tpl] of srt(Object.entries(resource.templates ?? {}))) {\n hash.update(\"tpl:\" + tplId);\n this.updateCacheKey(tpl, hash, sources);\n }\n for (const [wasmId, wasm] of srt(Object.entries(resource.wasm ?? {}))) {\n hash.update(\"wasm:\" + wasmId);\n WasmRenderer.updateCacheKey(wasm, hash, sources);\n }\n },\n render(resource, tx, _creator, sources) {\n const tplRef = tx.createStruct(\n PlTemplateV1.type,\n JSON.stringify(\n PlTemplateV1.fromV3Data(\n resource,\n getSourceCode(resource.name, sources, resource.sourceHash),\n ).data,\n ),\n );\n // Render libraries\n for (const [libId, lib] of Object.entries(resource.libs ?? {})) {\n const fld = PlTemplateV1.libField(tplRef, libId);\n tx.createField(fld, \"Input\");\n tx.setField(fld, _creator(lib, LibRenderer, sources));\n }\n\n // Render software and assets\n for (const [swId, sw] of Object.entries(resource.software ?? {})) {\n const fld = PlTemplateV1.swField(tplRef, swId);\n tx.createField(fld, \"Input\");\n tx.setField(fld, _creator(sw, SoftwareInfoRenderer, sources));\n }\n for (const [swId, sw] of Object.entries(resource.assets ?? {})) {\n const fld = PlTemplateV1.swField(tplRef, swId);\n tx.createField(fld, \"Input\");\n tx.setField(fld, _creator(sw, SoftwareInfoRenderer, sources));\n }\n\n // Render dependency templates\n for (const [depTplId, depTpl] of Object.entries(resource.templates ?? {})) {\n const fld = PlTemplateV1.tplField(tplRef, depTplId);\n tx.createField(fld, \"Input\");\n tx.setField(fld, _creator(depTpl, TemplateRenderer, sources));\n }\n\n // Render wasm dependencies. The field name (alias) feeds straight into\n // the backend's TengoTemplateV1.wasm map and becomes the lookup key in\n // RuntimeV1.deps.Wasm consumed by plapi.loadWasm.\n for (const [wasmId, wasm] of Object.entries(resource.wasm ?? {})) {\n const fld = PlTemplateV1.wasmField(tplRef, wasmId);\n tx.createField(fld, \"Input\");\n tx.setField(fld, _creator(wasm, WasmRenderer, sources));\n }\n\n tx.lock(tplRef);\n\n if (!resource.hashOverride) return tplRef;\n\n // Override template hash with proxy resource, when hash override is configured for template\n const overrideRef = tx.createStruct(\n PlTemplateOverrideV1.type,\n JSON.stringify(PlTemplateOverrideV1.fromV3Data(resource)),\n );\n const fld = PlTemplateOverrideV1.tplField(overrideRef);\n tx.createField(fld, \"Service\");\n tx.setField(fld, tplRef);\n tx.lock(overrideRef);\n return overrideRef;\n },\n};\n\n/**\n * Gets a source code of the artifact by its source hash.\n * the source hash was calculated and stored by tengo compiler\n * and is different from the hash we're using for caching here.\n */\nfunction getSourceCode(name: string, sources: Record<string, string>, sourceHash: string): string {\n return notEmpty(\n sources[sourceHash],\n `trying to get \"${name}\" source: sources map doesn't contain source hash ${sourceHash}`,\n );\n}\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { notEmpty } from "@milaboratories/ts-helpers";
2
2
  import { createHash } from "node:crypto";
3
- import { PlTemplateLibV1, PlTemplateOverrideV1, PlTemplateSoftwareV1, PlTemplateV1 } from "@milaboratories/pl-model-backend";
3
+ import { PlTemplateLibV1, PlTemplateOverrideV1, PlTemplateSoftwareV1, PlTemplateV1, PlWasmV1 } from "@milaboratories/pl-model-backend";
4
4
  //#region src/mutator/template/direct_template_loader_v3.ts
5
5
  /**
6
6
  * Renders the tree of templates by caching all resource ids
@@ -35,6 +35,14 @@ const LibRenderer = {
35
35
  return tx.createValue(PlTemplateLibV1.type, JSON.stringify(PlTemplateLibV1.fromV3Data(resource, getSourceCode(resource.name, sources, resource.sourceHash)).data));
36
36
  }
37
37
  };
38
+ const WasmRenderer = {
39
+ updateCacheKey(resource, hash, sources) {
40
+ hash.update(PlWasmV1.type.name).update(PlWasmV1.type.version).update(resource.name).update(resource.version).update(getSourceCode(resource.name, sources, resource.sourceHash));
41
+ },
42
+ render(resource, tx, _creator, sources) {
43
+ return tx.createValue(PlWasmV1.type, JSON.stringify(PlWasmV1.fromV3Data(resource, getSourceCode(resource.name, sources, resource.sourceHash)).data));
44
+ }
45
+ };
38
46
  const SoftwareInfoRenderer = {
39
47
  updateCacheKey(resource, hash, sources) {
40
48
  hash.update(PlTemplateSoftwareV1.type.name).update(PlTemplateSoftwareV1.type.version).update(resource.name).update(resource.version).update(getSourceCode(resource.name, sources, resource.sourceHash));
@@ -70,6 +78,10 @@ const TemplateRenderer = {
70
78
  hash.update("tpl:" + tplId);
71
79
  this.updateCacheKey(tpl, hash, sources);
72
80
  }
81
+ for (const [wasmId, wasm] of srt(Object.entries(resource.wasm ?? {}))) {
82
+ hash.update("wasm:" + wasmId);
83
+ WasmRenderer.updateCacheKey(wasm, hash, sources);
84
+ }
73
85
  },
74
86
  render(resource, tx, _creator, sources) {
75
87
  const tplRef = tx.createStruct(PlTemplateV1.type, JSON.stringify(PlTemplateV1.fromV3Data(resource, getSourceCode(resource.name, sources, resource.sourceHash)).data));
@@ -93,6 +105,11 @@ const TemplateRenderer = {
93
105
  tx.createField(fld, "Input");
94
106
  tx.setField(fld, _creator(depTpl, TemplateRenderer, sources));
95
107
  }
108
+ for (const [wasmId, wasm] of Object.entries(resource.wasm ?? {})) {
109
+ const fld = PlTemplateV1.wasmField(tplRef, wasmId);
110
+ tx.createField(fld, "Input");
111
+ tx.setField(fld, _creator(wasm, WasmRenderer, sources));
112
+ }
96
113
  tx.lock(tplRef);
97
114
  if (!resource.hashOverride) return tplRef;
98
115
  const overrideRef = tx.createStruct(PlTemplateOverrideV1.type, JSON.stringify(PlTemplateOverrideV1.fromV3Data(resource)));
@@ -1 +1 @@
1
- {"version":3,"file":"direct_template_loader_v3.js","names":[],"sources":["../../../src/mutator/template/direct_template_loader_v3.ts"],"sourcesContent":["import type { AnyRef, AnyResourceRef, PlTransaction } from \"@milaboratories/pl-client\";\nimport type { Hash } from \"node:crypto\";\nimport { createHash } from \"node:crypto\";\nimport type {\n CompiledTemplateV3,\n TemplateDataV3,\n TemplateLibDataV3,\n TemplateSoftwareDataV3,\n} from \"@milaboratories/pl-model-backend\";\nimport {\n PlTemplateLibV1,\n PlTemplateSoftwareV1,\n PlTemplateV1,\n PlTemplateOverrideV1,\n} from \"@milaboratories/pl-model-backend\";\nimport { notEmpty } from \"@milaboratories/ts-helpers\";\n\n/**\n * Renders the tree of templates by caching all resource ids\n * by their cache keys.\n * It's different from v2 version because we provide\n * the hash map of the code of all sources everywhere.\n * It does a double-dispatch on the node type (template, library etc),\n * and creates resources.\n *\n * IMO, it'd be clearer to rewrite it with Visitor pattern, and separate\n * tree traversing and operations on it, but I don't have time to do it now.\n */\nexport function createTemplateV3Tree(tx: PlTransaction, tplData: CompiledTemplateV3): AnyRef {\n const resourceCache = new Map<string, AnyResourceRef>();\n\n const createResourceCached = <T>(\n resource: T,\n renderer: Renderer<T>,\n hashToSource: Record<string, string>,\n ): AnyResourceRef => {\n const key: Hash = createHash(\"sha256\");\n renderer.updateCacheKey(resource, key, hashToSource);\n\n const rKey = key.digest(\"hex\");\n\n if (!resourceCache.has(rKey)) {\n const rId = renderer.render(resource, tx, createResourceCached, hashToSource);\n resourceCache.set(rKey, rId);\n }\n\n return resourceCache.get(rKey)!;\n };\n\n return createResourceCached(tplData.template, TemplateRenderer, tplData.hashToSource);\n}\n\ntype Renderer<T> = {\n /** Updates the cache key by adding all info of the artifact. */\n updateCacheKey: CacheKey<T>;\n /** Create resources for all dependencies recursively and then for this artifact. */\n render: (\n resource: T,\n tx: PlTransaction,\n creator: Creator,\n sources: Record<string, string>,\n ) => AnyResourceRef;\n};\ntype CacheKey<T> = (resource: T, key: Hash, sources: Record<string, string>) => void;\ntype Creator = <T>(\n resource: T,\n renderer: Renderer<T>,\n sources: Record<string, string>,\n) => AnyResourceRef;\n\nconst LibRenderer: Renderer<TemplateLibDataV3> = {\n updateCacheKey(resource, hash, sources) {\n hash\n .update(PlTemplateLibV1.type.name)\n .update(PlTemplateLibV1.type.version)\n .update(resource.name)\n .update(resource.version)\n .update(getSourceCode(resource.name, sources, resource.sourceHash));\n },\n render(resource, tx, _creator, sources) {\n return tx.createValue(\n PlTemplateLibV1.type,\n JSON.stringify(\n PlTemplateLibV1.fromV3Data(\n resource,\n getSourceCode(resource.name, sources, resource.sourceHash),\n ).data,\n ),\n );\n },\n};\n\nconst SoftwareInfoRenderer: Renderer<TemplateSoftwareDataV3> = {\n updateCacheKey(resource, hash, sources) {\n hash\n .update(PlTemplateSoftwareV1.type.name)\n .update(PlTemplateSoftwareV1.type.version)\n .update(resource.name)\n .update(resource.version)\n .update(getSourceCode(resource.name, sources, resource.sourceHash));\n },\n render(resource, tx, _creator, sources) {\n const sw = PlTemplateSoftwareV1.fromV3Data(\n resource,\n getSourceCode(resource.name, sources, resource.sourceHash),\n );\n const ref = tx.createStruct(PlTemplateSoftwareV1.type, sw.data);\n tx.setKValue(ref, PlTemplateSoftwareV1.metaNameKey, JSON.stringify(sw.name));\n tx.lock(ref);\n return ref;\n },\n};\n\nconst TemplateRenderer: Renderer<TemplateDataV3> = {\n updateCacheKey(resource, hash, sources) {\n hash\n .update(PlTemplateV1.type.name)\n .update(PlTemplateV1.type.version)\n .update(resource.hashOverride ?? \"no-override\")\n .update(resource.name)\n .update(resource.version)\n .update(getSourceCode(resource.name, sources, resource.sourceHash));\n\n const srt = <T>(entries: [string, T][]): [string, T][] => {\n entries.sort((a, b) => (a[0] === b[0] ? 0 : a[0] < b[0] ? -1 : 1));\n return entries;\n };\n\n for (const [libId, lib] of srt(Object.entries(resource.libs ?? {}))) {\n hash.update(\"lib:\" + libId);\n LibRenderer.updateCacheKey(lib, hash, sources);\n }\n for (const [swId, sw] of srt(Object.entries(resource.software ?? {}))) {\n hash.update(\"soft:\" + swId);\n SoftwareInfoRenderer.updateCacheKey(sw, hash, sources);\n }\n for (const [swId, sw] of srt(Object.entries(resource.assets ?? {}))) {\n hash.update(\"asset:\" + swId);\n SoftwareInfoRenderer.updateCacheKey(sw, hash, sources);\n }\n for (const [tplId, tpl] of srt(Object.entries(resource.templates ?? {}))) {\n hash.update(\"tpl:\" + tplId);\n this.updateCacheKey(tpl, hash, sources);\n }\n },\n render(resource, tx, _creator, sources) {\n const tplRef = tx.createStruct(\n PlTemplateV1.type,\n JSON.stringify(\n PlTemplateV1.fromV3Data(\n resource,\n getSourceCode(resource.name, sources, resource.sourceHash),\n ).data,\n ),\n );\n // Render libraries\n for (const [libId, lib] of Object.entries(resource.libs ?? {})) {\n const fld = PlTemplateV1.libField(tplRef, libId);\n tx.createField(fld, \"Input\");\n tx.setField(fld, _creator(lib, LibRenderer, sources));\n }\n\n // Render software and assets\n for (const [swId, sw] of Object.entries(resource.software ?? {})) {\n const fld = PlTemplateV1.swField(tplRef, swId);\n tx.createField(fld, \"Input\");\n tx.setField(fld, _creator(sw, SoftwareInfoRenderer, sources));\n }\n for (const [swId, sw] of Object.entries(resource.assets ?? {})) {\n const fld = PlTemplateV1.swField(tplRef, swId);\n tx.createField(fld, \"Input\");\n tx.setField(fld, _creator(sw, SoftwareInfoRenderer, sources));\n }\n\n // Render dependency templates\n for (const [depTplId, depTpl] of Object.entries(resource.templates ?? {})) {\n const fld = PlTemplateV1.tplField(tplRef, depTplId);\n tx.createField(fld, \"Input\");\n tx.setField(fld, _creator(depTpl, TemplateRenderer, sources));\n }\n\n tx.lock(tplRef);\n\n if (!resource.hashOverride) return tplRef;\n\n // Override template hash with proxy resource, when hash override is configured for template\n const overrideRef = tx.createStruct(\n PlTemplateOverrideV1.type,\n JSON.stringify(PlTemplateOverrideV1.fromV3Data(resource)),\n );\n const fld = PlTemplateOverrideV1.tplField(overrideRef);\n tx.createField(fld, \"Service\");\n tx.setField(fld, tplRef);\n tx.lock(overrideRef);\n return overrideRef;\n },\n};\n\n/**\n * Gets a source code of the artifact by its source hash.\n * the source hash was calculated and stored by tengo compiler\n * and is different from the hash we're using for caching here.\n */\nfunction getSourceCode(name: string, sources: Record<string, string>, sourceHash: string): string {\n return notEmpty(\n sources[sourceHash],\n `trying to get \"${name}\" source: sources map doesn't contain source hash ${sourceHash}`,\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"direct_template_loader_v3.js","names":[],"sources":["../../../src/mutator/template/direct_template_loader_v3.ts"],"sourcesContent":["import type { AnyRef, AnyResourceRef, PlTransaction } from \"@milaboratories/pl-client\";\nimport type { Hash } from \"node:crypto\";\nimport { createHash } from \"node:crypto\";\nimport type {\n CompiledTemplateV3,\n TemplateDataV3,\n TemplateLibDataV3,\n TemplateSoftwareDataV3,\n TemplateWasmDataV3,\n} from \"@milaboratories/pl-model-backend\";\nimport {\n PlTemplateLibV1,\n PlTemplateSoftwareV1,\n PlTemplateV1,\n PlTemplateOverrideV1,\n PlWasmV1,\n} from \"@milaboratories/pl-model-backend\";\nimport { notEmpty } from \"@milaboratories/ts-helpers\";\n\n/**\n * Renders the tree of templates by caching all resource ids\n * by their cache keys.\n * It's different from v2 version because we provide\n * the hash map of the code of all sources everywhere.\n * It does a double-dispatch on the node type (template, library etc),\n * and creates resources.\n *\n * IMO, it'd be clearer to rewrite it with Visitor pattern, and separate\n * tree traversing and operations on it, but I don't have time to do it now.\n */\nexport function createTemplateV3Tree(tx: PlTransaction, tplData: CompiledTemplateV3): AnyRef {\n const resourceCache = new Map<string, AnyResourceRef>();\n\n const createResourceCached = <T>(\n resource: T,\n renderer: Renderer<T>,\n hashToSource: Record<string, string>,\n ): AnyResourceRef => {\n const key: Hash = createHash(\"sha256\");\n renderer.updateCacheKey(resource, key, hashToSource);\n\n const rKey = key.digest(\"hex\");\n\n if (!resourceCache.has(rKey)) {\n const rId = renderer.render(resource, tx, createResourceCached, hashToSource);\n resourceCache.set(rKey, rId);\n }\n\n return resourceCache.get(rKey)!;\n };\n\n return createResourceCached(tplData.template, TemplateRenderer, tplData.hashToSource);\n}\n\ntype Renderer<T> = {\n /** Updates the cache key by adding all info of the artifact. */\n updateCacheKey: CacheKey<T>;\n /** Create resources for all dependencies recursively and then for this artifact. */\n render: (\n resource: T,\n tx: PlTransaction,\n creator: Creator,\n sources: Record<string, string>,\n ) => AnyResourceRef;\n};\ntype CacheKey<T> = (resource: T, key: Hash, sources: Record<string, string>) => void;\ntype Creator = <T>(\n resource: T,\n renderer: Renderer<T>,\n sources: Record<string, string>,\n) => AnyResourceRef;\n\nconst LibRenderer: Renderer<TemplateLibDataV3> = {\n updateCacheKey(resource, hash, sources) {\n hash\n .update(PlTemplateLibV1.type.name)\n .update(PlTemplateLibV1.type.version)\n .update(resource.name)\n .update(resource.version)\n .update(getSourceCode(resource.name, sources, resource.sourceHash));\n },\n render(resource, tx, _creator, sources) {\n return tx.createValue(\n PlTemplateLibV1.type,\n JSON.stringify(\n PlTemplateLibV1.fromV3Data(\n resource,\n getSourceCode(resource.name, sources, resource.sourceHash),\n ).data,\n ),\n );\n },\n};\n\nconst WasmRenderer: Renderer<TemplateWasmDataV3> = {\n updateCacheKey(resource, hash, sources) {\n hash\n .update(PlWasmV1.type.name)\n .update(PlWasmV1.type.version)\n .update(resource.name)\n .update(resource.version)\n .update(getSourceCode(resource.name, sources, resource.sourceHash));\n },\n render(resource, tx, _creator, sources) {\n return tx.createValue(\n PlWasmV1.type,\n JSON.stringify(\n PlWasmV1.fromV3Data(resource, getSourceCode(resource.name, sources, resource.sourceHash))\n .data,\n ),\n );\n },\n};\n\nconst SoftwareInfoRenderer: Renderer<TemplateSoftwareDataV3> = {\n updateCacheKey(resource, hash, sources) {\n hash\n .update(PlTemplateSoftwareV1.type.name)\n .update(PlTemplateSoftwareV1.type.version)\n .update(resource.name)\n .update(resource.version)\n .update(getSourceCode(resource.name, sources, resource.sourceHash));\n },\n render(resource, tx, _creator, sources) {\n const sw = PlTemplateSoftwareV1.fromV3Data(\n resource,\n getSourceCode(resource.name, sources, resource.sourceHash),\n );\n const ref = tx.createStruct(PlTemplateSoftwareV1.type, sw.data);\n tx.setKValue(ref, PlTemplateSoftwareV1.metaNameKey, JSON.stringify(sw.name));\n tx.lock(ref);\n return ref;\n },\n};\n\nconst TemplateRenderer: Renderer<TemplateDataV3> = {\n updateCacheKey(resource, hash, sources) {\n hash\n .update(PlTemplateV1.type.name)\n .update(PlTemplateV1.type.version)\n .update(resource.hashOverride ?? \"no-override\")\n .update(resource.name)\n .update(resource.version)\n .update(getSourceCode(resource.name, sources, resource.sourceHash));\n\n const srt = <T>(entries: [string, T][]): [string, T][] => {\n entries.sort((a, b) => (a[0] === b[0] ? 0 : a[0] < b[0] ? -1 : 1));\n return entries;\n };\n\n for (const [libId, lib] of srt(Object.entries(resource.libs ?? {}))) {\n hash.update(\"lib:\" + libId);\n LibRenderer.updateCacheKey(lib, hash, sources);\n }\n for (const [swId, sw] of srt(Object.entries(resource.software ?? {}))) {\n hash.update(\"soft:\" + swId);\n SoftwareInfoRenderer.updateCacheKey(sw, hash, sources);\n }\n for (const [swId, sw] of srt(Object.entries(resource.assets ?? {}))) {\n hash.update(\"asset:\" + swId);\n SoftwareInfoRenderer.updateCacheKey(sw, hash, sources);\n }\n for (const [tplId, tpl] of srt(Object.entries(resource.templates ?? {}))) {\n hash.update(\"tpl:\" + tplId);\n this.updateCacheKey(tpl, hash, sources);\n }\n for (const [wasmId, wasm] of srt(Object.entries(resource.wasm ?? {}))) {\n hash.update(\"wasm:\" + wasmId);\n WasmRenderer.updateCacheKey(wasm, hash, sources);\n }\n },\n render(resource, tx, _creator, sources) {\n const tplRef = tx.createStruct(\n PlTemplateV1.type,\n JSON.stringify(\n PlTemplateV1.fromV3Data(\n resource,\n getSourceCode(resource.name, sources, resource.sourceHash),\n ).data,\n ),\n );\n // Render libraries\n for (const [libId, lib] of Object.entries(resource.libs ?? {})) {\n const fld = PlTemplateV1.libField(tplRef, libId);\n tx.createField(fld, \"Input\");\n tx.setField(fld, _creator(lib, LibRenderer, sources));\n }\n\n // Render software and assets\n for (const [swId, sw] of Object.entries(resource.software ?? {})) {\n const fld = PlTemplateV1.swField(tplRef, swId);\n tx.createField(fld, \"Input\");\n tx.setField(fld, _creator(sw, SoftwareInfoRenderer, sources));\n }\n for (const [swId, sw] of Object.entries(resource.assets ?? {})) {\n const fld = PlTemplateV1.swField(tplRef, swId);\n tx.createField(fld, \"Input\");\n tx.setField(fld, _creator(sw, SoftwareInfoRenderer, sources));\n }\n\n // Render dependency templates\n for (const [depTplId, depTpl] of Object.entries(resource.templates ?? {})) {\n const fld = PlTemplateV1.tplField(tplRef, depTplId);\n tx.createField(fld, \"Input\");\n tx.setField(fld, _creator(depTpl, TemplateRenderer, sources));\n }\n\n // Render wasm dependencies. The field name (alias) feeds straight into\n // the backend's TengoTemplateV1.wasm map and becomes the lookup key in\n // RuntimeV1.deps.Wasm consumed by plapi.loadWasm.\n for (const [wasmId, wasm] of Object.entries(resource.wasm ?? {})) {\n const fld = PlTemplateV1.wasmField(tplRef, wasmId);\n tx.createField(fld, \"Input\");\n tx.setField(fld, _creator(wasm, WasmRenderer, sources));\n }\n\n tx.lock(tplRef);\n\n if (!resource.hashOverride) return tplRef;\n\n // Override template hash with proxy resource, when hash override is configured for template\n const overrideRef = tx.createStruct(\n PlTemplateOverrideV1.type,\n JSON.stringify(PlTemplateOverrideV1.fromV3Data(resource)),\n );\n const fld = PlTemplateOverrideV1.tplField(overrideRef);\n tx.createField(fld, \"Service\");\n tx.setField(fld, tplRef);\n tx.lock(overrideRef);\n return overrideRef;\n },\n};\n\n/**\n * Gets a source code of the artifact by its source hash.\n * the source hash was calculated and stored by tengo compiler\n * and is different from the hash we're using for caching here.\n */\nfunction getSourceCode(name: string, sources: Record<string, string>, sourceHash: string): string {\n return notEmpty(\n sources[sourceHash],\n `trying to get \"${name}\" source: sources map doesn't contain source hash ${sourceHash}`,\n );\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@milaboratories/pl-middle-layer",
3
- "version": "1.61.11",
3
+ "version": "1.62.0",
4
4
  "description": "Pl Middle Layer",
5
5
  "keywords": [],
6
6
  "license": "UNLICENSED",
@@ -30,24 +30,24 @@
30
30
  "utility-types": "^3.11.0",
31
31
  "yaml": "^2.8.0",
32
32
  "zod": "~3.25.76",
33
- "@milaboratories/helpers": "1.14.2",
34
33
  "@milaboratories/computable": "2.9.4",
35
- "@milaboratories/pf-spec-driver": "1.3.20",
36
- "@milaboratories/pf-driver": "1.4.15",
37
- "@milaboratories/pl-client": "3.9.2",
38
- "@milaboratories/pl-http": "1.2.4",
34
+ "@milaboratories/pf-driver": "1.4.17",
35
+ "@milaboratories/pl-client": "3.10.0",
36
+ "@milaboratories/pf-spec-driver": "1.3.22",
39
37
  "@milaboratories/pl-deployments": "3.0.1",
40
- "@milaboratories/pl-errors": "1.4.14",
41
- "@milaboratories/pl-model-backend": "1.3.5",
38
+ "@milaboratories/pl-drivers": "1.14.15",
39
+ "@milaboratories/helpers": "1.14.2",
40
+ "@milaboratories/pl-errors": "1.4.15",
42
41
  "@milaboratories/pl-model-common": "1.42.0",
43
- "@milaboratories/pl-drivers": "1.14.14",
44
- "@milaboratories/pl-model-middle-layer": "1.23.0",
42
+ "@milaboratories/pl-http": "1.2.4",
43
+ "@milaboratories/pl-model-backend": "1.4.0",
44
+ "@milaboratories/pl-model-middle-layer": "1.25.0",
45
+ "@milaboratories/pl-tree": "1.12.5",
45
46
  "@milaboratories/resolve-helper": "1.1.3",
46
- "@milaboratories/pl-tree": "1.12.4",
47
+ "@platforma-sdk/model": "1.77.17",
47
48
  "@milaboratories/ts-helpers": "1.8.2",
48
- "@platforma-sdk/model": "1.77.15",
49
- "@platforma-sdk/workflow-tengo": "6.0.0",
50
- "@platforma-sdk/block-tools": "2.9.3"
49
+ "@platforma-sdk/workflow-tengo": "6.1.0",
50
+ "@platforma-sdk/block-tools": "2.10.0"
51
51
  },
52
52
  "devDependencies": {
53
53
  "@types/node": "~24.5.2",
@@ -56,9 +56,9 @@
56
56
  "semver": "^7.7.2",
57
57
  "typescript": "~5.9.3",
58
58
  "vitest": "^4.1.3",
59
+ "@milaboratories/ts-configs": "1.2.3",
59
60
  "@milaboratories/build-configs": "2.0.0",
60
- "@milaboratories/ts-builder": "1.5.0",
61
- "@milaboratories/ts-configs": "1.2.3"
61
+ "@milaboratories/ts-builder": "1.5.0"
62
62
  },
63
63
  "engines": {
64
64
  "node": ">=22.19.0"
@@ -6,12 +6,14 @@ import type {
6
6
  TemplateDataV3,
7
7
  TemplateLibDataV3,
8
8
  TemplateSoftwareDataV3,
9
+ TemplateWasmDataV3,
9
10
  } from "@milaboratories/pl-model-backend";
10
11
  import {
11
12
  PlTemplateLibV1,
12
13
  PlTemplateSoftwareV1,
13
14
  PlTemplateV1,
14
15
  PlTemplateOverrideV1,
16
+ PlWasmV1,
15
17
  } from "@milaboratories/pl-model-backend";
16
18
  import { notEmpty } from "@milaboratories/ts-helpers";
17
19
 
@@ -90,6 +92,26 @@ const LibRenderer: Renderer<TemplateLibDataV3> = {
90
92
  },
91
93
  };
92
94
 
95
+ const WasmRenderer: Renderer<TemplateWasmDataV3> = {
96
+ updateCacheKey(resource, hash, sources) {
97
+ hash
98
+ .update(PlWasmV1.type.name)
99
+ .update(PlWasmV1.type.version)
100
+ .update(resource.name)
101
+ .update(resource.version)
102
+ .update(getSourceCode(resource.name, sources, resource.sourceHash));
103
+ },
104
+ render(resource, tx, _creator, sources) {
105
+ return tx.createValue(
106
+ PlWasmV1.type,
107
+ JSON.stringify(
108
+ PlWasmV1.fromV3Data(resource, getSourceCode(resource.name, sources, resource.sourceHash))
109
+ .data,
110
+ ),
111
+ );
112
+ },
113
+ };
114
+
93
115
  const SoftwareInfoRenderer: Renderer<TemplateSoftwareDataV3> = {
94
116
  updateCacheKey(resource, hash, sources) {
95
117
  hash
@@ -142,6 +164,10 @@ const TemplateRenderer: Renderer<TemplateDataV3> = {
142
164
  hash.update("tpl:" + tplId);
143
165
  this.updateCacheKey(tpl, hash, sources);
144
166
  }
167
+ for (const [wasmId, wasm] of srt(Object.entries(resource.wasm ?? {}))) {
168
+ hash.update("wasm:" + wasmId);
169
+ WasmRenderer.updateCacheKey(wasm, hash, sources);
170
+ }
145
171
  },
146
172
  render(resource, tx, _creator, sources) {
147
173
  const tplRef = tx.createStruct(
@@ -179,6 +205,15 @@ const TemplateRenderer: Renderer<TemplateDataV3> = {
179
205
  tx.setField(fld, _creator(depTpl, TemplateRenderer, sources));
180
206
  }
181
207
 
208
+ // Render wasm dependencies. The field name (alias) feeds straight into
209
+ // the backend's TengoTemplateV1.wasm map and becomes the lookup key in
210
+ // RuntimeV1.deps.Wasm consumed by plapi.loadWasm.
211
+ for (const [wasmId, wasm] of Object.entries(resource.wasm ?? {})) {
212
+ const fld = PlTemplateV1.wasmField(tplRef, wasmId);
213
+ tx.createField(fld, "Input");
214
+ tx.setField(fld, _creator(wasm, WasmRenderer, sources));
215
+ }
216
+
182
217
  tx.lock(tplRef);
183
218
 
184
219
  if (!resource.hashOverride) return tplRef;