@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.
- package/dist/mutator/template/direct_template_loader_v3.cjs +17 -0
- package/dist/mutator/template/direct_template_loader_v3.cjs.map +1 -1
- package/dist/mutator/template/direct_template_loader_v3.js +18 -1
- package/dist/mutator/template/direct_template_loader_v3.js.map +1 -1
- package/package.json +16 -16
- package/src/mutator/template/direct_template_loader_v3.ts +35 -0
|
@@ -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.
|
|
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-
|
|
36
|
-
"@milaboratories/
|
|
37
|
-
"@milaboratories/
|
|
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-
|
|
41
|
-
"@milaboratories/
|
|
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-
|
|
44
|
-
"@milaboratories/pl-model-
|
|
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
|
-
"@
|
|
47
|
+
"@platforma-sdk/model": "1.77.17",
|
|
47
48
|
"@milaboratories/ts-helpers": "1.8.2",
|
|
48
|
-
"@platforma-sdk/
|
|
49
|
-
"@platforma-sdk/
|
|
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;
|