@milaboratories/pl-middle-layer 1.74.11 → 1.74.13
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/_virtual/{_@oxc-project_runtime@0.137.0 → _@oxc-project_runtime@0.155.0}/helpers/esm/usingCtx.cjs +1 -2
- package/dist/_virtual/{_@oxc-project_runtime@0.137.0 → _@oxc-project_runtime@0.155.0}/helpers/esm/usingCtx.js +1 -2
- package/dist/_virtual/_rolldown/runtime.cjs +2 -3
- package/dist/block_registry/location_provider.cjs +1 -2
- package/dist/block_registry/location_provider.cjs.map +1 -1
- package/dist/block_registry/location_provider.js +1 -2
- package/dist/block_registry/registry-v2-provider.cjs +1 -2
- package/dist/block_registry/registry-v2-provider.cjs.map +1 -1
- package/dist/block_registry/registry-v2-provider.d.ts +0 -2
- package/dist/block_registry/registry-v2-provider.d.ts.map +1 -1
- package/dist/block_registry/registry-v2-provider.js +1 -2
- package/dist/block_registry/registry.cjs +3 -3
- package/dist/block_registry/registry.cjs.map +1 -1
- package/dist/block_registry/registry.d.ts +0 -2
- package/dist/block_registry/registry.d.ts.map +1 -1
- package/dist/block_registry/registry.js +3 -3
- package/dist/block_registry/registry.js.map +1 -1
- package/dist/block_registry/template_provider.cjs +1 -2
- package/dist/block_registry/template_provider.cjs.map +1 -1
- package/dist/block_registry/template_provider.d.ts +0 -2
- package/dist/block_registry/template_provider.d.ts.map +1 -1
- package/dist/block_registry/template_provider.js +1 -2
- package/dist/block_registry/watcher.cjs +15 -14
- package/dist/block_registry/watcher.cjs.map +1 -1
- package/dist/block_registry/watcher.d.ts +0 -2
- package/dist/block_registry/watcher.d.ts.map +1 -1
- package/dist/block_registry/watcher.js +15 -14
- package/dist/block_registry/watcher.js.map +1 -1
- package/dist/block_registry/well_known_registries.cjs +1 -2
- package/dist/block_registry/well_known_registries.d.ts +0 -2
- package/dist/block_registry/well_known_registries.d.ts.map +1 -1
- package/dist/block_registry/well_known_registries.js +1 -2
- package/dist/cfg_render/executor.cjs +1 -2
- package/dist/cfg_render/executor.cjs.map +1 -1
- package/dist/cfg_render/executor.js +1 -2
- package/dist/cfg_render/renderer.cjs +1 -2
- package/dist/cfg_render/renderer.cjs.map +1 -1
- package/dist/cfg_render/renderer.js +1 -2
- package/dist/cfg_render/traverse.cjs +1 -2
- package/dist/cfg_render/traverse.js +1 -2
- package/dist/cfg_render/util.cjs +1 -2
- package/dist/cfg_render/util.js +1 -2
- package/dist/debug/index.cjs +1 -2
- package/dist/debug/index.js +1 -2
- package/dist/dev_env/index.cjs +1 -2
- package/dist/dev_env/index.cjs.map +1 -1
- package/dist/dev_env/index.js +1 -2
- package/dist/dev_env/util.cjs +1 -2
- package/dist/dev_env/util.js +1 -2
- package/dist/js_render/column_registry.cjs +1 -2
- package/dist/js_render/column_registry.cjs.map +1 -1
- package/dist/js_render/column_registry.js +1 -2
- package/dist/js_render/computable_context.cjs +4 -4
- package/dist/js_render/computable_context.cjs.map +1 -1
- package/dist/js_render/computable_context.js +4 -4
- package/dist/js_render/computable_context.js.map +1 -1
- package/dist/js_render/context.cjs +1 -2
- package/dist/js_render/context.cjs.map +1 -1
- package/dist/js_render/context.js +1 -2
- package/dist/js_render/index.cjs +12 -9
- package/dist/js_render/index.cjs.map +1 -1
- package/dist/js_render/index.js +12 -9
- package/dist/js_render/index.js.map +1 -1
- package/dist/js_render/service_injectors.cjs +2 -3
- package/dist/js_render/service_injectors.js +2 -3
- package/dist/js_render/spec_override_collapse.cjs +1 -2
- package/dist/js_render/spec_override_collapse.cjs.map +1 -1
- package/dist/js_render/spec_override_collapse.js +1 -2
- package/dist/middle_layer/active_cfg.cjs +1 -2
- package/dist/middle_layer/active_cfg.cjs.map +1 -1
- package/dist/middle_layer/active_cfg.js +1 -2
- package/dist/middle_layer/block.cjs +1 -2
- package/dist/middle_layer/block.cjs.map +1 -1
- package/dist/middle_layer/block.js +1 -2
- package/dist/middle_layer/block_ctx.cjs +3 -3
- package/dist/middle_layer/block_ctx.cjs.map +1 -1
- package/dist/middle_layer/block_ctx.js +3 -3
- package/dist/middle_layer/block_ctx.js.map +1 -1
- package/dist/middle_layer/block_ctx_unsafe.cjs +1 -2
- package/dist/middle_layer/block_ctx_unsafe.js +1 -2
- package/dist/middle_layer/build_stamp.cjs +2 -3
- package/dist/middle_layer/build_stamp.js +2 -3
- package/dist/middle_layer/driver_kit.cjs +1 -2
- package/dist/middle_layer/driver_kit.cjs.map +1 -1
- package/dist/middle_layer/driver_kit.d.ts +0 -2
- package/dist/middle_layer/driver_kit.d.ts.map +1 -1
- package/dist/middle_layer/driver_kit.js +1 -2
- package/dist/middle_layer/finality_stop_rules.cjs +1 -2
- package/dist/middle_layer/finality_stop_rules.js +1 -2
- package/dist/middle_layer/folders.cjs +12 -8
- package/dist/middle_layer/folders.cjs.map +1 -1
- package/dist/middle_layer/folders.d.ts +0 -2
- package/dist/middle_layer/folders.d.ts.map +1 -1
- package/dist/middle_layer/folders.js +12 -8
- package/dist/middle_layer/folders.js.map +1 -1
- package/dist/middle_layer/frontend_path.cjs +1 -2
- package/dist/middle_layer/frontend_path.cjs.map +1 -1
- package/dist/middle_layer/frontend_path.js +1 -2
- package/dist/middle_layer/middle_layer.cjs +7 -6
- package/dist/middle_layer/middle_layer.cjs.map +1 -1
- package/dist/middle_layer/middle_layer.d.ts +0 -2
- package/dist/middle_layer/middle_layer.d.ts.map +1 -1
- package/dist/middle_layer/middle_layer.js +7 -6
- package/dist/middle_layer/middle_layer.js.map +1 -1
- package/dist/middle_layer/navigation_states.cjs +1 -2
- package/dist/middle_layer/navigation_states.js +1 -2
- package/dist/middle_layer/ops.cjs +10 -11
- package/dist/middle_layer/ops.cjs.map +1 -1
- package/dist/middle_layer/ops.d.ts +0 -2
- package/dist/middle_layer/ops.d.ts.map +1 -1
- package/dist/middle_layer/ops.js +10 -11
- package/dist/middle_layer/ops.js.map +1 -1
- package/dist/middle_layer/project.cjs +3 -3
- package/dist/middle_layer/project.cjs.map +1 -1
- package/dist/middle_layer/project.d.ts +3 -5
- package/dist/middle_layer/project.d.ts.map +1 -1
- package/dist/middle_layer/project.js +3 -3
- package/dist/middle_layer/project.js.map +1 -1
- package/dist/middle_layer/project_list.cjs +1 -2
- package/dist/middle_layer/project_list.cjs.map +1 -1
- package/dist/middle_layer/project_list.d.ts +0 -2
- package/dist/middle_layer/project_list.d.ts.map +1 -1
- package/dist/middle_layer/project_list.js +1 -2
- package/dist/middle_layer/project_overview.cjs +8 -5
- package/dist/middle_layer/project_overview.cjs.map +1 -1
- package/dist/middle_layer/project_overview.js +8 -5
- package/dist/middle_layer/project_overview.js.map +1 -1
- package/dist/middle_layer/project_overview_light.cjs +4 -3
- package/dist/middle_layer/project_overview_light.cjs.map +1 -1
- package/dist/middle_layer/project_overview_light.js +4 -3
- package/dist/middle_layer/project_overview_light.js.map +1 -1
- package/dist/middle_layer/render.cjs +1 -2
- package/dist/middle_layer/render.cjs.map +1 -1
- package/dist/middle_layer/render.js +1 -2
- package/dist/middle_layer/sharing_list.cjs +1 -2
- package/dist/middle_layer/sharing_list.cjs.map +1 -1
- package/dist/middle_layer/sharing_list.d.ts +0 -2
- package/dist/middle_layer/sharing_list.d.ts.map +1 -1
- package/dist/middle_layer/sharing_list.js +1 -2
- package/dist/middle_layer/sharing_list.js.map +1 -1
- package/dist/middle_layer/template_list.cjs +1 -2
- package/dist/middle_layer/template_list.cjs.map +1 -1
- package/dist/middle_layer/template_list.d.ts +0 -2
- package/dist/middle_layer/template_list.d.ts.map +1 -1
- package/dist/middle_layer/template_list.js +1 -2
- package/dist/middle_layer/tree_snapshot_store.cjs +3 -3
- package/dist/middle_layer/tree_snapshot_store.cjs.map +1 -1
- package/dist/middle_layer/tree_snapshot_store.d.ts +0 -2
- package/dist/middle_layer/tree_snapshot_store.d.ts.map +1 -1
- package/dist/middle_layer/tree_snapshot_store.js +3 -3
- package/dist/middle_layer/tree_snapshot_store.js.map +1 -1
- package/dist/middle_layer/types.d.ts +0 -2
- package/dist/middle_layer/types.d.ts.map +1 -1
- package/dist/middle_layer/util.cjs +1 -2
- package/dist/middle_layer/util.cjs.map +1 -1
- package/dist/middle_layer/util.js +1 -2
- package/dist/model/args.cjs +1 -2
- package/dist/model/args.cjs.map +1 -1
- package/dist/model/args.js +1 -2
- package/dist/model/block_pack_spec.cjs +1 -2
- package/dist/model/block_pack_spec.d.ts +0 -2
- package/dist/model/block_pack_spec.d.ts.map +1 -1
- package/dist/model/block_pack_spec.js +1 -2
- package/dist/model/frontend.d.ts +0 -2
- package/dist/model/frontend.d.ts.map +1 -1
- package/dist/model/project_helper.cjs +1 -2
- package/dist/model/project_helper.cjs.map +1 -1
- package/dist/model/project_helper.d.ts +0 -2
- package/dist/model/project_helper.d.ts.map +1 -1
- package/dist/model/project_helper.js +1 -2
- package/dist/model/project_model.cjs +1 -2
- package/dist/model/project_model.d.ts +0 -2
- package/dist/model/project_model.d.ts.map +1 -1
- package/dist/model/project_model.js +1 -2
- package/dist/model/project_model_util.cjs +1 -2
- package/dist/model/project_model_util.js +1 -2
- package/dist/model/project_model_v1.cjs +1 -2
- package/dist/model/project_model_v1.js +1 -2
- package/dist/model/sharing_model.cjs +1 -2
- package/dist/model/sharing_model.cjs.map +1 -1
- package/dist/model/sharing_model.d.ts +0 -2
- package/dist/model/sharing_model.d.ts.map +1 -1
- package/dist/model/sharing_model.js +1 -2
- package/dist/model/template_apply.cjs +1 -2
- package/dist/model/template_apply.cjs.map +1 -1
- package/dist/model/template_apply.d.ts +0 -2
- package/dist/model/template_apply.d.ts.map +1 -1
- package/dist/model/template_apply.js +1 -2
- package/dist/model/template_export.cjs +1 -2
- package/dist/model/template_export.d.ts +0 -2
- package/dist/model/template_export.d.ts.map +1 -1
- package/dist/model/template_export.js +1 -2
- package/dist/model/template_parser.cjs +1 -2
- package/dist/model/template_parser.cjs.map +1 -1
- package/dist/model/template_parser.d.ts +0 -2
- package/dist/model/template_parser.d.ts.map +1 -1
- package/dist/model/template_parser.js +1 -2
- package/dist/model/template_resolve.cjs +1 -2
- package/dist/model/template_resolve.cjs.map +1 -1
- package/dist/model/template_resolve.d.ts +0 -2
- package/dist/model/template_resolve.d.ts.map +1 -1
- package/dist/model/template_resolve.js +1 -2
- package/dist/model/template_serializer.cjs +1 -2
- package/dist/model/template_serializer.cjs.map +1 -1
- package/dist/model/template_serializer.d.ts +0 -2
- package/dist/model/template_serializer.d.ts.map +1 -1
- package/dist/model/template_serializer.js +1 -2
- package/dist/model/template_spec.d.ts +0 -2
- package/dist/model/template_spec.d.ts.map +1 -1
- package/dist/mutator/block-pack/block_pack.cjs +7 -6
- package/dist/mutator/block-pack/block_pack.cjs.map +1 -1
- package/dist/mutator/block-pack/block_pack.d.ts +0 -2
- package/dist/mutator/block-pack/block_pack.d.ts.map +1 -1
- package/dist/mutator/block-pack/block_pack.js +7 -6
- package/dist/mutator/block-pack/block_pack.js.map +1 -1
- package/dist/mutator/block-pack/frontend.cjs +1 -2
- package/dist/mutator/block-pack/frontend.cjs.map +1 -1
- package/dist/mutator/block-pack/frontend.js +1 -2
- package/dist/mutator/block-pack/required_capabilities.cjs +1 -2
- package/dist/mutator/block-pack/required_capabilities.cjs.map +1 -1
- package/dist/mutator/block-pack/required_capabilities.js +1 -2
- package/dist/mutator/context_export.cjs +1 -2
- package/dist/mutator/context_export.cjs.map +1 -1
- package/dist/mutator/context_export.js +1 -2
- package/dist/mutator/list.cjs +1 -2
- package/dist/mutator/list.cjs.map +1 -1
- package/dist/mutator/list.js +1 -2
- package/dist/mutator/migration.cjs +1 -2
- package/dist/mutator/migration.cjs.map +1 -1
- package/dist/mutator/migration.js +1 -2
- package/dist/mutator/project.cjs +30 -22
- package/dist/mutator/project.cjs.map +1 -1
- package/dist/mutator/project.d.ts +0 -2
- package/dist/mutator/project.d.ts.map +1 -1
- package/dist/mutator/project.js +30 -22
- package/dist/mutator/project.js.map +1 -1
- package/dist/mutator/sharing.cjs +1 -2
- package/dist/mutator/sharing.cjs.map +1 -1
- package/dist/mutator/sharing.js +1 -2
- package/dist/mutator/template/direct_template_loader.cjs +1 -2
- package/dist/mutator/template/direct_template_loader.cjs.map +1 -1
- package/dist/mutator/template/direct_template_loader.js +1 -2
- package/dist/mutator/template/direct_template_loader_v3.cjs +1 -2
- package/dist/mutator/template/direct_template_loader_v3.cjs.map +1 -1
- package/dist/mutator/template/direct_template_loader_v3.js +1 -2
- package/dist/mutator/template/render_block.cjs +1 -2
- package/dist/mutator/template/render_block.cjs.map +1 -1
- package/dist/mutator/template/render_block.js +1 -2
- package/dist/mutator/template/render_template.cjs +1 -2
- package/dist/mutator/template/render_template.cjs.map +1 -1
- package/dist/mutator/template/render_template.d.ts +0 -2
- package/dist/mutator/template/render_template.d.ts.map +1 -1
- package/dist/mutator/template/render_template.js +1 -2
- package/dist/mutator/template/template_cache.cjs +6 -5
- package/dist/mutator/template/template_cache.cjs.map +1 -1
- package/dist/mutator/template/template_cache.d.ts +1 -2
- package/dist/mutator/template/template_cache.d.ts.map +1 -1
- package/dist/mutator/template/template_cache.js +6 -5
- package/dist/mutator/template/template_cache.js.map +1 -1
- package/dist/mutator/template/template_loading.cjs +1 -2
- package/dist/mutator/template/template_loading.cjs.map +1 -1
- package/dist/mutator/template/template_loading.d.ts +0 -2
- package/dist/mutator/template/template_loading.d.ts.map +1 -1
- package/dist/mutator/template/template_loading.js +1 -2
- package/dist/mutator/template.cjs +1 -2
- package/dist/mutator/template.cjs.map +1 -1
- package/dist/mutator/template.js +1 -2
- package/dist/mutator/template_construct.cjs +1 -2
- package/dist/mutator/template_construct.cjs.map +1 -1
- package/dist/mutator/template_construct.js +1 -2
- package/dist/network_check/network_check.cjs +2 -3
- package/dist/network_check/network_check.cjs.map +1 -1
- package/dist/network_check/network_check.d.ts +0 -2
- package/dist/network_check/network_check.d.ts.map +1 -1
- package/dist/network_check/network_check.js +2 -3
- package/dist/network_check/network_check.js.map +1 -1
- package/dist/network_check/pings.cjs +1 -2
- package/dist/network_check/pings.cjs.map +1 -1
- package/dist/network_check/pings.js +1 -2
- package/dist/network_check/template.cjs +5 -4
- package/dist/network_check/template.cjs.map +1 -1
- package/dist/network_check/template.js +5 -4
- package/dist/network_check/template.js.map +1 -1
- package/dist/pool/data.cjs +1 -2
- package/dist/pool/data.cjs.map +1 -1
- package/dist/pool/data.d.ts +0 -2
- package/dist/pool/data.d.ts.map +1 -1
- package/dist/pool/data.js +1 -2
- package/dist/pool/driver.cjs +5 -4
- package/dist/pool/driver.cjs.map +1 -1
- package/dist/pool/driver.d.ts +0 -2
- package/dist/pool/driver.d.ts.map +1 -1
- package/dist/pool/driver.js +5 -4
- package/dist/pool/driver.js.map +1 -1
- package/dist/pool/p_object_collection.cjs +9 -8
- package/dist/pool/p_object_collection.cjs.map +1 -1
- package/dist/pool/p_object_collection.d.ts +0 -2
- package/dist/pool/p_object_collection.d.ts.map +1 -1
- package/dist/pool/p_object_collection.js +9 -8
- package/dist/pool/p_object_collection.js.map +1 -1
- package/dist/pool/result_pool.cjs +8 -7
- package/dist/pool/result_pool.cjs.map +1 -1
- package/dist/pool/result_pool.js +8 -7
- package/dist/pool/result_pool.js.map +1 -1
- package/dist/pool/upstream_block_ctx.cjs +1 -2
- package/dist/pool/upstream_block_ctx.cjs.map +1 -1
- package/dist/pool/upstream_block_ctx.js +1 -2
- package/dist/service_factories.cjs +1 -2
- package/dist/service_factories.js +1 -2
- package/dist/worker/WorkerManager.cjs +1 -2
- package/dist/worker/WorkerManager.js +1 -2
- package/dist/worker/WorkerManager.js.map +1 -1
- package/dist/worker/worker.cjs +1 -2
- package/dist/worker/worker.js +1 -2
- package/dist/worker/workerApi.cjs +1 -2
- package/dist/worker/workerApi.cjs.map +1 -1
- package/dist/worker/workerApi.js +1 -2
- package/package.json +33 -33
- package/src/middle_layer/middle_layer.ts +4 -6
- package/src/middle_layer/tree_snapshot_store.test.ts +4 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sharing.cjs","names":["newShareId","hiddenField","ProjectMetaKey","duplicateProject","newProjectFieldUuid","SharedEnvelopeResourceType"],"sources":["../../src/mutator/sharing.ts"],"sourcesContent":["import type { PlTransaction, ResourceRef, SignedResourceId } from \"@milaboratories/pl-client\";\nimport { field, isNotNullSignedResourceId } from \"@milaboratories/pl-client\";\nimport { randomUUID } from \"node:crypto\";\nimport type { FolderId, ProjectMeta } from \"@milaboratories/pl-model-middle-layer\";\nimport { normalizeDescription } from \"@milaboratories/pl-model-middle-layer\";\nimport type { ProjectId, ProjectTemplateV1, TemplateId } from \"@milaboratories/pl-model-common\";\nimport { ProjectMetaKey } from \"../model/project_model\";\nimport { duplicateProject } from \"./project\";\nimport type {\n EnvelopeData,\n EnvelopeFolder,\n EnvelopeFolderId,\n EnvelopeFolderProject,\n EnvelopeFolderTemplate,\n EnvelopeMode,\n EnvelopeProject,\n ProjectFieldUuid,\n ShareId,\n ShareHidden,\n} from \"../model/sharing_model\";\nimport {\n EnvelopeSchemaVersionCurrent,\n SharedEnvelopeResourceType,\n hiddenField,\n newProjectFieldUuid,\n newShareId,\n} from \"../model/sharing_model\";\n\n/** Field name carrying a project snapshot inside a {@link SharedEnvelopeResourceType}. */\nexport const EnvelopeProjectFieldPrefix = \"project/\";\nexport const envelopeProjectField = (uuid: ProjectFieldUuid) =>\n `${EnvelopeProjectFieldPrefix}${uuid}`;\n\n/** True for an envelope field that carries a project snapshot. */\nexport function isEnvelopeProjectField(name: string): boolean {\n return name.startsWith(EnvelopeProjectFieldPrefix);\n}\n\n/** Extracts the project field uuid from a `project/{uuid}` field name. */\nexport function envelopeProjectFieldUuid(name: string): ProjectFieldUuid {\n return name.slice(EnvelopeProjectFieldPrefix.length) as ProjectFieldUuid;\n}\n\n//\n// Donor side\n//\n\n/** One live project going into an envelope; it is snapshotted as the envelope is built. */\nexport type EnvelopeProjectSource = { projectId: ProjectId; sourceRid: SignedResourceId };\n\n/**\n * Builds one {@link SharedEnvelopeResourceType} on the donor side inside the given write\n * transaction: snapshots each source project by reference, seals the envelope with its\n * immutable {@link EnvelopeData}, and attaches the envelope under `{shareId}` on the donor's\n * outbox. The caller is responsible for issuing the per-recipient grants and committing the\n * transaction — keeping create + grant atomic.\n *\n * @returns the new envelope resource and the generated `EnvelopeData`.\n */\nexport async function buildShareEnvelope(\n tx: PlTransaction,\n outboxRid: SignedResourceId,\n sources: EnvelopeProjectSource[],\n params: {\n mode: EnvelopeMode;\n sender: string;\n title: string;\n /** ms epoch; sharedAt + ttl for a targeted share, null for share-with-everybody. */\n expiresAt: number | null;\n },\n): Promise<{ envelope: ResourceRef; data: EnvelopeData }> {\n const sharedAt = Date.now();\n const snapshots = await snapshotEnvelopeProjects(tx, sources, sharedAt);\n\n const projects: Record<ProjectFieldUuid, EnvelopeProject> = {};\n for (const { uuid, project } of snapshots) projects[uuid] = project;\n\n const data: EnvelopeData = {\n schemaVersion: EnvelopeSchemaVersionCurrent,\n shareId: newShareId(),\n sharedAt,\n expiresAt: params.expiresAt,\n mode: params.mode,\n sender: params.sender,\n title: params.title,\n payload: { kind: \"projects\", projects },\n };\n\n return { envelope: sealEnvelope(tx, outboxRid, data, snapshots), data };\n}\n\n/**\n * Builds one {@link SharedEnvelopeResourceType} carrying a template document on the donor side,\n * and attaches it under `{shareId}` on the donor's outbox. The caller issues the grant — always\n * read-only — and commits, keeping create + grant atomic.\n *\n * There is nothing to snapshot and no input field to seal: the document is the whole payload and\n * rides in the envelope's immutable `data`, which is also why the recipient needs no write access\n * (it copies no resource out of the envelope).\n *\n * @returns the new envelope resource and the generated `EnvelopeData`.\n */\nexport function buildTemplateShareEnvelope(\n tx: PlTransaction,\n outboxRid: SignedResourceId,\n template: {\n document: ProjectTemplateV1;\n label: string;\n description?: string;\n source: TemplateId;\n },\n params: {\n sender: string;\n title: string;\n /** ms epoch; sharedAt + ttl for a targeted share, null for share-with-everybody. */\n expiresAt: number | null;\n },\n): { envelope: ResourceRef; data: EnvelopeData } {\n const data: EnvelopeData = {\n schemaVersion: EnvelopeSchemaVersionCurrent,\n shareId: newShareId(),\n sharedAt: Date.now(),\n expiresAt: params.expiresAt,\n mode: \"read-only\",\n sender: params.sender,\n title: params.title,\n payload: {\n kind: \"template\",\n document: template.document,\n source: template.source,\n label: template.label,\n ...(template.description === undefined ? {} : { description: template.description }),\n from: params.sender,\n },\n };\n\n return { envelope: sealEnvelope(tx, outboxRid, data, []), data };\n}\n\n/**\n * Builds one {@link SharedEnvelopeResourceType} carrying a folder subtree: the folders, every\n * project in them snapshotted as a `project/{uuid}` field, and every template's document inline.\n * Attaches it under `{shareId}` on the donor's outbox. The caller issues the grant — writable,\n * because the recipient copies the project snapshots out — and commits.\n *\n * Folder ids are minted here and mean nothing outside this envelope: the recipient's own document\n * mints its own. What travels is the shape of the subtree.\n *\n * @returns the new envelope resource and the generated `EnvelopeData`.\n */\nexport async function buildFolderShareEnvelope(\n tx: PlTransaction,\n outboxRid: SignedResourceId,\n subtree: EnvelopeFolderSubtree,\n params: {\n sender: string;\n title: string;\n /** ms epoch; sharedAt + ttl for a targeted share, null for share-with-everybody. */\n expiresAt: number | null;\n },\n): Promise<{ envelope: ResourceRef; data: EnvelopeData }> {\n const sharedAt = Date.now();\n const snapshots = await snapshotEnvelopeProjects(tx, subtree.projects, sharedAt);\n\n const projects: Record<ProjectFieldUuid, EnvelopeFolderProject> = {};\n for (const { uuid, project, source } of snapshots)\n projects[uuid] = { ...project, folder: source.folder };\n\n const data: EnvelopeData = {\n schemaVersion: EnvelopeSchemaVersionCurrent,\n shareId: newShareId(),\n sharedAt,\n expiresAt: params.expiresAt,\n mode: \"copy\",\n sender: params.sender,\n title: params.title,\n payload: {\n kind: \"folder\",\n source: subtree.source,\n folders: subtree.folders,\n projects,\n templates: subtree.templates,\n from: params.sender,\n },\n };\n\n return { envelope: sealEnvelope(tx, outboxRid, data, snapshots), data };\n}\n\n/** A folder subtree ready to be sealed into an envelope: the folders under their envelope-local\n * ids, the live projects to snapshot, and the templates to carry whole. */\nexport interface EnvelopeFolderSubtree {\n /** Donor's own id of the shared folder, carried so a later share of it finds this one. */\n source: FolderId;\n folders: Record<EnvelopeFolderId, EnvelopeFolder>;\n projects: (EnvelopeProjectSource & { folder: EnvelopeFolderId })[];\n templates: EnvelopeFolderTemplate[];\n}\n\n//\n// Recipient side\n//\n\n/**\n * Puts a share out of this recipient's sight, as a dynamic field on their own SharingState.\n * Keyed on the shareId, so a share that replaces this one — a new shareId — is shown again.\n */\nexport function writeShareHidden(\n tx: PlTransaction,\n stateRid: SignedResourceId,\n shareId: ShareId,\n timestamp: number,\n): void {\n const value = tx.createJsonValue({ hidden: true, timestamp } satisfies ShareHidden);\n tx.createField(field(stateRid, hiddenField(shareId)), \"Dynamic\", value);\n}\n\n/** Brings a hidden share back into this recipient's list. */\nexport function clearShareHidden(\n tx: PlTransaction,\n stateRid: SignedResourceId,\n shareId: ShareId,\n): void {\n tx.removeField(field(stateRid, hiddenField(shareId)));\n}\n\n/**\n * Copies every project snapshot inside an envelope into the recipient's own project list — a\n * cross-color attach the backend permits. The source is resolved against the envelope tree, not\n * the recipient's own list.\n *\n * `label` names each copy from its snapshot's label. The caller picks the names against the\n * destination the copies land in, because that is where they have to be free; left out, each copy\n * keeps its snapshot's label.\n *\n * Each result carries the envelope field uuid it was copied from, because that uuid is what the\n * payload names a project by — a folder share reads the folder of each copy off it. Pairing by\n * position would happen to work today and quietly stop working the moment the order does.\n *\n * @returns one entry per copied project: the envelope uuid it came from and its new id.\n */\nexport async function copyEnvelopeProjectsIntoList(\n tx: PlTransaction,\n envelopeRid: SignedResourceId,\n projectListRid: SignedResourceId,\n label?: (sourceLabel: string) => string,\n): Promise<{ uuid: ProjectFieldUuid; rid: SignedResourceId }[]> {\n // Enumerate the envelope's project/{uuid} input fields (signed envelope-colored ids).\n const envelopeData = await tx.getResourceData(envelopeRid, true);\n const sources = envelopeData.fields\n .filter((f) => isEnvelopeProjectField(f.name))\n .flatMap((f) =>\n isNotNullSignedResourceId(f.value)\n ? [{ uuid: envelopeProjectFieldUuid(f.name), sourceRid: f.value }]\n : [],\n );\n\n const created: { uuid: ProjectFieldUuid; rid: SignedResourceId }[] = [];\n for (const { uuid, sourceRid } of sources) {\n const sourceMeta = await tx.getKValueJson<ProjectMeta>(sourceRid, ProjectMetaKey);\n const newLabel = label === undefined ? sourceMeta.label : label(sourceMeta.label);\n\n // Cross-color attach: a new UserProject in the recipient's color whose fields point at\n // envelope-colored resources. Fails with PermissionDenied: color mismatch on a backend\n // that lacks crossTreeRefs:v1.\n const newPrj = await duplicateProject(tx, sourceRid, { ...sourceMeta, label: newLabel });\n tx.createField(field(projectListRid, randomUUID()), \"Dynamic\", newPrj);\n\n created.push({ uuid, rid: await newPrj.globalId });\n }\n\n return created;\n}\n\n//\n// Internals\n//\n\n/** One source project snapshotted for an envelope: the field uuid it rides under, the snapshot\n * itself, and what the payload says about it. */\ntype EnvelopeSnapshot<Source extends EnvelopeProjectSource> = {\n uuid: ProjectFieldUuid;\n ref: ResourceRef;\n source: Source;\n project: EnvelopeProject;\n};\n\n/**\n * Snapshots each source project by reference, in the given order, under a freshly minted field\n * uuid. The payload entry carries the project's label and description as they were at `sharedAt`,\n * so a share list renders without traversing into the snapshot.\n */\nasync function snapshotEnvelopeProjects<Source extends EnvelopeProjectSource>(\n tx: PlTransaction,\n sources: readonly Source[],\n sharedAt: number,\n): Promise<EnvelopeSnapshot<Source>[]> {\n const snapshots: EnvelopeSnapshot<Source>[] = [];\n for (const source of sources) {\n const meta = await tx.getKValueJson<ProjectMeta>(source.sourceRid, ProjectMetaKey);\n const ref = await duplicateProject(tx, source.sourceRid, meta);\n const description = normalizeDescription(meta.description);\n snapshots.push({\n uuid: newProjectFieldUuid(),\n ref,\n source,\n project: {\n label: meta.label,\n source: source.projectId,\n updatedAt: sharedAt,\n ...(description === undefined ? {} : { description }),\n },\n });\n }\n return snapshots;\n}\n\n/**\n * Creates the envelope with its immutable `data`, attaches each snapshot as a `project/{uuid}`\n * input field, and hangs the envelope on the donor's outbox under its shareId.\n *\n * A payload that carries project snapshots has its input set sealed one-way, even when the\n * subtree it describes holds none, because such an envelope is granted writable. A template\n * payload has no input set to seal. The outbox attach happens in the same transaction, so the\n * held-resource rule keeps the ephemeral envelope alive.\n */\nfunction sealEnvelope(\n tx: PlTransaction,\n outboxRid: SignedResourceId,\n data: EnvelopeData,\n snapshots: readonly { uuid: ProjectFieldUuid; ref: ResourceRef }[],\n): ResourceRef {\n const envelope = tx.createEphemeral(SharedEnvelopeResourceType, JSON.stringify(data));\n\n for (const { uuid, ref } of snapshots)\n tx.createField(field(envelope, envelopeProjectField(uuid)), \"Input\", ref);\n if (data.payload.kind !== \"template\") tx.lockInputs(envelope);\n\n tx.createField(field(outboxRid, data.shareId), \"Dynamic\", envelope);\n return envelope;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"sharing.cjs","names":["newShareId","field","hiddenField","isNotNullSignedResourceId","ProjectMetaKey","duplicateProject","randomUUID","normalizeDescription","newProjectFieldUuid","SharedEnvelopeResourceType"],"sources":["../../src/mutator/sharing.ts"],"sourcesContent":["import type { PlTransaction, ResourceRef, SignedResourceId } from \"@milaboratories/pl-client\";\nimport { field, isNotNullSignedResourceId } from \"@milaboratories/pl-client\";\nimport { randomUUID } from \"node:crypto\";\nimport type { FolderId, ProjectMeta } from \"@milaboratories/pl-model-middle-layer\";\nimport { normalizeDescription } from \"@milaboratories/pl-model-middle-layer\";\nimport type { ProjectId, ProjectTemplateV1, TemplateId } from \"@milaboratories/pl-model-common\";\nimport { ProjectMetaKey } from \"../model/project_model\";\nimport { duplicateProject } from \"./project\";\nimport type {\n EnvelopeData,\n EnvelopeFolder,\n EnvelopeFolderId,\n EnvelopeFolderProject,\n EnvelopeFolderTemplate,\n EnvelopeMode,\n EnvelopeProject,\n ProjectFieldUuid,\n ShareId,\n ShareHidden,\n} from \"../model/sharing_model\";\nimport {\n EnvelopeSchemaVersionCurrent,\n SharedEnvelopeResourceType,\n hiddenField,\n newProjectFieldUuid,\n newShareId,\n} from \"../model/sharing_model\";\n\n/** Field name carrying a project snapshot inside a {@link SharedEnvelopeResourceType}. */\nexport const EnvelopeProjectFieldPrefix = \"project/\";\nexport const envelopeProjectField = (uuid: ProjectFieldUuid) =>\n `${EnvelopeProjectFieldPrefix}${uuid}`;\n\n/** True for an envelope field that carries a project snapshot. */\nexport function isEnvelopeProjectField(name: string): boolean {\n return name.startsWith(EnvelopeProjectFieldPrefix);\n}\n\n/** Extracts the project field uuid from a `project/{uuid}` field name. */\nexport function envelopeProjectFieldUuid(name: string): ProjectFieldUuid {\n return name.slice(EnvelopeProjectFieldPrefix.length) as ProjectFieldUuid;\n}\n\n//\n// Donor side\n//\n\n/** One live project going into an envelope; it is snapshotted as the envelope is built. */\nexport type EnvelopeProjectSource = { projectId: ProjectId; sourceRid: SignedResourceId };\n\n/**\n * Builds one {@link SharedEnvelopeResourceType} on the donor side inside the given write\n * transaction: snapshots each source project by reference, seals the envelope with its\n * immutable {@link EnvelopeData}, and attaches the envelope under `{shareId}` on the donor's\n * outbox. The caller is responsible for issuing the per-recipient grants and committing the\n * transaction — keeping create + grant atomic.\n *\n * @returns the new envelope resource and the generated `EnvelopeData`.\n */\nexport async function buildShareEnvelope(\n tx: PlTransaction,\n outboxRid: SignedResourceId,\n sources: EnvelopeProjectSource[],\n params: {\n mode: EnvelopeMode;\n sender: string;\n title: string;\n /** ms epoch; sharedAt + ttl for a targeted share, null for share-with-everybody. */\n expiresAt: number | null;\n },\n): Promise<{ envelope: ResourceRef; data: EnvelopeData }> {\n const sharedAt = Date.now();\n const snapshots = await snapshotEnvelopeProjects(tx, sources, sharedAt);\n\n const projects: Record<ProjectFieldUuid, EnvelopeProject> = {};\n for (const { uuid, project } of snapshots) projects[uuid] = project;\n\n const data: EnvelopeData = {\n schemaVersion: EnvelopeSchemaVersionCurrent,\n shareId: newShareId(),\n sharedAt,\n expiresAt: params.expiresAt,\n mode: params.mode,\n sender: params.sender,\n title: params.title,\n payload: { kind: \"projects\", projects },\n };\n\n return { envelope: sealEnvelope(tx, outboxRid, data, snapshots), data };\n}\n\n/**\n * Builds one {@link SharedEnvelopeResourceType} carrying a template document on the donor side,\n * and attaches it under `{shareId}` on the donor's outbox. The caller issues the grant — always\n * read-only — and commits, keeping create + grant atomic.\n *\n * There is nothing to snapshot and no input field to seal: the document is the whole payload and\n * rides in the envelope's immutable `data`, which is also why the recipient needs no write access\n * (it copies no resource out of the envelope).\n *\n * @returns the new envelope resource and the generated `EnvelopeData`.\n */\nexport function buildTemplateShareEnvelope(\n tx: PlTransaction,\n outboxRid: SignedResourceId,\n template: {\n document: ProjectTemplateV1;\n label: string;\n description?: string;\n source: TemplateId;\n },\n params: {\n sender: string;\n title: string;\n /** ms epoch; sharedAt + ttl for a targeted share, null for share-with-everybody. */\n expiresAt: number | null;\n },\n): { envelope: ResourceRef; data: EnvelopeData } {\n const data: EnvelopeData = {\n schemaVersion: EnvelopeSchemaVersionCurrent,\n shareId: newShareId(),\n sharedAt: Date.now(),\n expiresAt: params.expiresAt,\n mode: \"read-only\",\n sender: params.sender,\n title: params.title,\n payload: {\n kind: \"template\",\n document: template.document,\n source: template.source,\n label: template.label,\n ...(template.description === undefined ? {} : { description: template.description }),\n from: params.sender,\n },\n };\n\n return { envelope: sealEnvelope(tx, outboxRid, data, []), data };\n}\n\n/**\n * Builds one {@link SharedEnvelopeResourceType} carrying a folder subtree: the folders, every\n * project in them snapshotted as a `project/{uuid}` field, and every template's document inline.\n * Attaches it under `{shareId}` on the donor's outbox. The caller issues the grant — writable,\n * because the recipient copies the project snapshots out — and commits.\n *\n * Folder ids are minted here and mean nothing outside this envelope: the recipient's own document\n * mints its own. What travels is the shape of the subtree.\n *\n * @returns the new envelope resource and the generated `EnvelopeData`.\n */\nexport async function buildFolderShareEnvelope(\n tx: PlTransaction,\n outboxRid: SignedResourceId,\n subtree: EnvelopeFolderSubtree,\n params: {\n sender: string;\n title: string;\n /** ms epoch; sharedAt + ttl for a targeted share, null for share-with-everybody. */\n expiresAt: number | null;\n },\n): Promise<{ envelope: ResourceRef; data: EnvelopeData }> {\n const sharedAt = Date.now();\n const snapshots = await snapshotEnvelopeProjects(tx, subtree.projects, sharedAt);\n\n const projects: Record<ProjectFieldUuid, EnvelopeFolderProject> = {};\n for (const { uuid, project, source } of snapshots)\n projects[uuid] = { ...project, folder: source.folder };\n\n const data: EnvelopeData = {\n schemaVersion: EnvelopeSchemaVersionCurrent,\n shareId: newShareId(),\n sharedAt,\n expiresAt: params.expiresAt,\n mode: \"copy\",\n sender: params.sender,\n title: params.title,\n payload: {\n kind: \"folder\",\n source: subtree.source,\n folders: subtree.folders,\n projects,\n templates: subtree.templates,\n from: params.sender,\n },\n };\n\n return { envelope: sealEnvelope(tx, outboxRid, data, snapshots), data };\n}\n\n/** A folder subtree ready to be sealed into an envelope: the folders under their envelope-local\n * ids, the live projects to snapshot, and the templates to carry whole. */\nexport interface EnvelopeFolderSubtree {\n /** Donor's own id of the shared folder, carried so a later share of it finds this one. */\n source: FolderId;\n folders: Record<EnvelopeFolderId, EnvelopeFolder>;\n projects: (EnvelopeProjectSource & { folder: EnvelopeFolderId })[];\n templates: EnvelopeFolderTemplate[];\n}\n\n//\n// Recipient side\n//\n\n/**\n * Puts a share out of this recipient's sight, as a dynamic field on their own SharingState.\n * Keyed on the shareId, so a share that replaces this one — a new shareId — is shown again.\n */\nexport function writeShareHidden(\n tx: PlTransaction,\n stateRid: SignedResourceId,\n shareId: ShareId,\n timestamp: number,\n): void {\n const value = tx.createJsonValue({ hidden: true, timestamp } satisfies ShareHidden);\n tx.createField(field(stateRid, hiddenField(shareId)), \"Dynamic\", value);\n}\n\n/** Brings a hidden share back into this recipient's list. */\nexport function clearShareHidden(\n tx: PlTransaction,\n stateRid: SignedResourceId,\n shareId: ShareId,\n): void {\n tx.removeField(field(stateRid, hiddenField(shareId)));\n}\n\n/**\n * Copies every project snapshot inside an envelope into the recipient's own project list — a\n * cross-color attach the backend permits. The source is resolved against the envelope tree, not\n * the recipient's own list.\n *\n * `label` names each copy from its snapshot's label. The caller picks the names against the\n * destination the copies land in, because that is where they have to be free; left out, each copy\n * keeps its snapshot's label.\n *\n * Each result carries the envelope field uuid it was copied from, because that uuid is what the\n * payload names a project by — a folder share reads the folder of each copy off it. Pairing by\n * position would happen to work today and quietly stop working the moment the order does.\n *\n * @returns one entry per copied project: the envelope uuid it came from and its new id.\n */\nexport async function copyEnvelopeProjectsIntoList(\n tx: PlTransaction,\n envelopeRid: SignedResourceId,\n projectListRid: SignedResourceId,\n label?: (sourceLabel: string) => string,\n): Promise<{ uuid: ProjectFieldUuid; rid: SignedResourceId }[]> {\n // Enumerate the envelope's project/{uuid} input fields (signed envelope-colored ids).\n const envelopeData = await tx.getResourceData(envelopeRid, true);\n const sources = envelopeData.fields\n .filter((f) => isEnvelopeProjectField(f.name))\n .flatMap((f) =>\n isNotNullSignedResourceId(f.value)\n ? [{ uuid: envelopeProjectFieldUuid(f.name), sourceRid: f.value }]\n : [],\n );\n\n const created: { uuid: ProjectFieldUuid; rid: SignedResourceId }[] = [];\n for (const { uuid, sourceRid } of sources) {\n const sourceMeta = await tx.getKValueJson<ProjectMeta>(sourceRid, ProjectMetaKey);\n const newLabel = label === undefined ? sourceMeta.label : label(sourceMeta.label);\n\n // Cross-color attach: a new UserProject in the recipient's color whose fields point at\n // envelope-colored resources. Fails with PermissionDenied: color mismatch on a backend\n // that lacks crossTreeRefs:v1.\n const newPrj = await duplicateProject(tx, sourceRid, { ...sourceMeta, label: newLabel });\n tx.createField(field(projectListRid, randomUUID()), \"Dynamic\", newPrj);\n\n created.push({ uuid, rid: await newPrj.globalId });\n }\n\n return created;\n}\n\n//\n// Internals\n//\n\n/** One source project snapshotted for an envelope: the field uuid it rides under, the snapshot\n * itself, and what the payload says about it. */\ntype EnvelopeSnapshot<Source extends EnvelopeProjectSource> = {\n uuid: ProjectFieldUuid;\n ref: ResourceRef;\n source: Source;\n project: EnvelopeProject;\n};\n\n/**\n * Snapshots each source project by reference, in the given order, under a freshly minted field\n * uuid. The payload entry carries the project's label and description as they were at `sharedAt`,\n * so a share list renders without traversing into the snapshot.\n */\nasync function snapshotEnvelopeProjects<Source extends EnvelopeProjectSource>(\n tx: PlTransaction,\n sources: readonly Source[],\n sharedAt: number,\n): Promise<EnvelopeSnapshot<Source>[]> {\n const snapshots: EnvelopeSnapshot<Source>[] = [];\n for (const source of sources) {\n const meta = await tx.getKValueJson<ProjectMeta>(source.sourceRid, ProjectMetaKey);\n const ref = await duplicateProject(tx, source.sourceRid, meta);\n const description = normalizeDescription(meta.description);\n snapshots.push({\n uuid: newProjectFieldUuid(),\n ref,\n source,\n project: {\n label: meta.label,\n source: source.projectId,\n updatedAt: sharedAt,\n ...(description === undefined ? {} : { description }),\n },\n });\n }\n return snapshots;\n}\n\n/**\n * Creates the envelope with its immutable `data`, attaches each snapshot as a `project/{uuid}`\n * input field, and hangs the envelope on the donor's outbox under its shareId.\n *\n * A payload that carries project snapshots has its input set sealed one-way, even when the\n * subtree it describes holds none, because such an envelope is granted writable. A template\n * payload has no input set to seal. The outbox attach happens in the same transaction, so the\n * held-resource rule keeps the ephemeral envelope alive.\n */\nfunction sealEnvelope(\n tx: PlTransaction,\n outboxRid: SignedResourceId,\n data: EnvelopeData,\n snapshots: readonly { uuid: ProjectFieldUuid; ref: ResourceRef }[],\n): ResourceRef {\n const envelope = tx.createEphemeral(SharedEnvelopeResourceType, JSON.stringify(data));\n\n for (const { uuid, ref } of snapshots)\n tx.createField(field(envelope, envelopeProjectField(uuid)), \"Input\", ref);\n if (data.payload.kind !== \"template\") tx.lockInputs(envelope);\n\n tx.createField(field(outboxRid, data.shareId), \"Dynamic\", envelope);\n return envelope;\n}\n"],"mappings":"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"}
|
package/dist/mutator/sharing.js
CHANGED
|
@@ -4,7 +4,7 @@ import { duplicateProject } from "./project.js";
|
|
|
4
4
|
import { normalizeDescription } from "@milaboratories/pl-model-middle-layer";
|
|
5
5
|
import { field, isNotNullSignedResourceId } from "@milaboratories/pl-client";
|
|
6
6
|
import { randomUUID } from "node:crypto";
|
|
7
|
-
|
|
7
|
+
// src/mutator/sharing.ts
|
|
8
8
|
/** Field name carrying a project snapshot inside a {@link SharedEnvelopeResourceType}. */
|
|
9
9
|
const EnvelopeProjectFieldPrefix = "project/";
|
|
10
10
|
const envelopeProjectField = (uuid) => `${EnvelopeProjectFieldPrefix}${uuid}`;
|
|
@@ -215,7 +215,6 @@ function sealEnvelope(tx, outboxRid, data, snapshots) {
|
|
|
215
215
|
tx.createField(field(outboxRid, data.shareId), "Dynamic", envelope);
|
|
216
216
|
return envelope;
|
|
217
217
|
}
|
|
218
|
-
//#endregion
|
|
219
218
|
export { EnvelopeProjectFieldPrefix, buildFolderShareEnvelope, buildShareEnvelope, buildTemplateShareEnvelope, clearShareHidden, copyEnvelopeProjectsIntoList, envelopeProjectField, envelopeProjectFieldUuid, isEnvelopeProjectField, writeShareHidden };
|
|
220
219
|
|
|
221
220
|
//# sourceMappingURL=sharing.js.map
|
|
@@ -2,7 +2,7 @@ const require_direct_template_loader_v3 = require("./direct_template_loader_v3.c
|
|
|
2
2
|
let _milaboratories_ts_helpers = require("@milaboratories/ts-helpers");
|
|
3
3
|
let node_crypto = require("node:crypto");
|
|
4
4
|
let _milaboratories_pl_model_backend = require("@milaboratories/pl-model-backend");
|
|
5
|
-
|
|
5
|
+
// src/mutator/template/direct_template_loader.ts
|
|
6
6
|
function loadTemplateFromExplicitDirect(tx, spec) {
|
|
7
7
|
const templateInfo = (0, _milaboratories_pl_model_backend.parseTemplate)(spec.content);
|
|
8
8
|
const templateFormat = templateInfo.type;
|
|
@@ -111,7 +111,6 @@ function createTemplateV2Tree(tx, tplData) {
|
|
|
111
111
|
};
|
|
112
112
|
return createResource(tplData, TemplateRenderer);
|
|
113
113
|
}
|
|
114
|
-
//#endregion
|
|
115
114
|
exports.loadTemplateFromExplicitDirect = loadTemplateFromExplicitDirect;
|
|
116
115
|
exports.loadTemplateFromPrepared = loadTemplateFromPrepared;
|
|
117
116
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"direct_template_loader.cjs","names":["createTemplateV3Tree","PlTemplateLibV1","PlTemplateSoftwareV1","PlTemplateV1","PlTemplateOverrideV1"],"sources":["../../../src/mutator/template/direct_template_loader.ts"],"sourcesContent":["import type { AnyRef, AnyResourceRef, PlTransaction } from \"@milaboratories/pl-client\";\nimport { assertNever } from \"@milaboratories/ts-helpers\";\nimport type { ExplicitTemplate, PreparedTemplate } from \"../../model/template_spec\";\nimport type { Hash } from \"node:crypto\";\nimport { createHash } from \"node:crypto\";\nimport type {\n TemplateData,\n TemplateLibData,\n TemplateSoftwareData,\n} from \"@milaboratories/pl-model-backend\";\nimport {\n PlTemplateLibV1,\n PlTemplateSoftwareV1,\n PlTemplateV1,\n PlTemplateOverrideV1,\n parseTemplate,\n} from \"@milaboratories/pl-model-backend\";\nimport { createTemplateV3Tree } from \"./direct_template_loader_v3\";\n\nexport function loadTemplateFromExplicitDirect(tx: PlTransaction, spec: ExplicitTemplate): AnyRef {\n const templateInfo = parseTemplate(spec.content);\n\n const templateFormat = templateInfo.type;\n switch (templateFormat) {\n case \"pl.tengo-template.v2\":\n return createTemplateV2Tree(tx, templateInfo);\n case \"pl.tengo-template.v3\":\n return createTemplateV3Tree(tx, templateInfo);\n default:\n assertNever(templateFormat);\n }\n}\n\nexport function loadTemplateFromPrepared(tx: PlTransaction, spec: PreparedTemplate): AnyRef {\n const templateData = spec.data;\n\n const templateFormat = templateData.type;\n switch (templateFormat) {\n case \"pl.tengo-template.v2\":\n return createTemplateV2Tree(tx, templateData);\n case \"pl.tengo-template.v3\":\n return createTemplateV3Tree(tx, templateData);\n default:\n assertNever(templateFormat);\n }\n}\n\ntype Renderer<T> = {\n hash: Hasher<T>;\n render: (resource: T, tx: PlTransaction, creator: Creator) => AnyResourceRef;\n};\ntype Hasher<T> = (resource: T, hash: Hash) => void;\ntype Creator = <T>(resource: T, renderer: Renderer<T>) => AnyResourceRef;\n\nconst LibRenderer: Renderer<TemplateLibData> = {\n hash(resource, hash) {\n hash\n .update(PlTemplateLibV1.type.name)\n .update(PlTemplateLibV1.type.version)\n .update(resource.name)\n .update(resource.version)\n .update(resource.src);\n },\n render(resource, tx, _creator) {\n return tx.createValue(\n PlTemplateLibV1.type,\n JSON.stringify(PlTemplateLibV1.fromV2Data(resource).data),\n );\n },\n};\n\nconst SoftwareInfoRenderer: Renderer<TemplateSoftwareData> = {\n hash(resource, hash) {\n hash\n .update(PlTemplateSoftwareV1.type.name)\n .update(PlTemplateSoftwareV1.type.version)\n .update(resource.name)\n .update(resource.version)\n .update(resource.src);\n },\n render(resource, tx, _creator) {\n const sw = PlTemplateSoftwareV1.fromV2Data(resource);\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<TemplateData> = {\n hash(resource, hash) {\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(resource.src);\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.hash(lib, hash);\n }\n for (const [swId, sw] of srt(Object.entries(resource.software ?? {}))) {\n hash.update(\"soft:\" + swId);\n SoftwareInfoRenderer.hash(sw, hash);\n }\n for (const [swId, sw] of srt(Object.entries(resource.assets ?? {}))) {\n hash.update(\"asset:\" + swId);\n SoftwareInfoRenderer.hash(sw, hash);\n }\n for (const [tplId, tpl] of srt(Object.entries(resource.templates ?? {}))) {\n hash.update(\"tpl:\" + tplId);\n this.hash(tpl, hash);\n }\n },\n render(resource, tx, _creator) {\n const tplRef = tx.createStruct(\n PlTemplateV1.type,\n JSON.stringify(PlTemplateV1.fromV2Data(resource).data),\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));\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));\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));\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));\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.fromV2Data(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\nfunction createTemplateV2Tree(tx: PlTransaction, tplData: TemplateData): AnyRef {\n const resourceCache = new Map<string, AnyResourceRef>();\n\n const createResource = <T>(resource: T, renderer: Renderer<T>): AnyResourceRef => {\n const hasher: Hash = createHash(\"sha256\");\n renderer.hash(resource, hasher);\n\n const rKey = hasher.digest(\"hex\");\n\n if (!resourceCache.has(rKey)) {\n const rId = renderer.render(resource, tx, createResource);\n resourceCache.set(rKey, rId);\n }\n\n return resourceCache.get(rKey)!;\n };\n\n return createResource(tplData, TemplateRenderer);\n}\n"],"mappings":";;;;;AAmBA,SAAgB,+BAA+B,IAAmB,MAAgC;CAChG,MAAM,gBAAA,GAAA,iCAAA,cAAA,CAA6B,KAAK,OAAO;CAE/C,MAAM,iBAAiB,aAAa;CACpC,QAAQ,gBAAR;EACE,KAAK,wBACH,OAAO,qBAAqB,IAAI,YAAY;EAC9C,KAAK,wBACH,OAAOA,kCAAAA,qBAAqB,IAAI,YAAY;EAC9C,SACE,CAAA,GAAA,2BAAA,YAAA,CAAY,cAAc;CAC9B;AACF;AAEA,SAAgB,yBAAyB,IAAmB,MAAgC;CAC1F,MAAM,eAAe,KAAK;CAE1B,MAAM,iBAAiB,aAAa;CACpC,QAAQ,gBAAR;EACE,KAAK,wBACH,OAAO,qBAAqB,IAAI,YAAY;EAC9C,KAAK,wBACH,OAAOA,kCAAAA,qBAAqB,IAAI,YAAY;EAC9C,SACE,CAAA,GAAA,2BAAA,YAAA,CAAY,cAAc;CAC9B;AACF;AASA,MAAM,cAAyC;CAC7C,KAAK,UAAU,MAAM;EACnB,KACG,OAAOC,iCAAAA,gBAAgB,KAAK,IAAI,CAAC,CACjC,OAAOA,iCAAAA,gBAAgB,KAAK,OAAO,CAAC,CACpC,OAAO,SAAS,IAAI,CAAC,CACrB,OAAO,SAAS,OAAO,CAAC,CACxB,OAAO,SAAS,GAAG;CACxB;CACA,OAAO,UAAU,IAAI,UAAU;EAC7B,OAAO,GAAG,YACRA,iCAAAA,gBAAgB,MAChB,KAAK,UAAUA,iCAAAA,gBAAgB,WAAW,QAAQ,CAAC,CAAC,IAAI,CAC1D;CACF;AACF;AAEA,MAAM,uBAAuD;CAC3D,KAAK,UAAU,MAAM;EACnB,KACG,OAAOC,iCAAAA,qBAAqB,KAAK,IAAI,CAAC,CACtC,OAAOA,iCAAAA,qBAAqB,KAAK,OAAO,CAAC,CACzC,OAAO,SAAS,IAAI,CAAC,CACrB,OAAO,SAAS,OAAO,CAAC,CACxB,OAAO,SAAS,GAAG;CACxB;CACA,OAAO,UAAU,IAAI,UAAU;EAC7B,MAAM,KAAKA,iCAAAA,qBAAqB,WAAW,QAAQ;EACnD,MAAM,MAAM,GAAG,aAAaA,iCAAAA,qBAAqB,MAAM,GAAG,IAAI;EAC9D,GAAG,UAAU,KAAKA,iCAAAA,qBAAqB,aAAa,KAAK,UAAU,GAAG,IAAI,CAAC;EAC3E,GAAG,KAAK,GAAG;EACX,OAAO;CACT;AACF;AAEA,MAAM,mBAA2C;CAC/C,KAAK,UAAU,MAAM;EACnB,KACG,OAAOC,iCAAAA,aAAa,KAAK,IAAI,CAAC,CAC9B,OAAOA,iCAAAA,aAAa,KAAK,OAAO,CAAC,CACjC,OAAO,SAAS,gBAAgB,aAAa,CAAC,CAC9C,OAAO,SAAS,IAAI,CAAC,CACrB,OAAO,SAAS,OAAO,CAAC,CACxB,OAAO,SAAS,GAAG;EAEtB,MAAM,OAAU,YAA0C;GACxD,QAAQ,MAAM,GAAG,MAAO,EAAE,OAAO,EAAE,KAAK,IAAI,EAAE,KAAK,EAAE,KAAK,KAAK,CAAE;GACjE,OAAO;EACT;EAEA,KAAK,MAAM,CAAC,OAAO,QAAQ,IAAI,OAAO,QAAQ,SAAS,QAAQ,CAAC,CAAC,CAAC,GAAG;GACnE,KAAK,OAAO,SAAS,KAAK;GAC1B,YAAY,KAAK,KAAK,IAAI;EAC5B;EACA,KAAK,MAAM,CAAC,MAAM,OAAO,IAAI,OAAO,QAAQ,SAAS,YAAY,CAAC,CAAC,CAAC,GAAG;GACrE,KAAK,OAAO,UAAU,IAAI;GAC1B,qBAAqB,KAAK,IAAI,IAAI;EACpC;EACA,KAAK,MAAM,CAAC,MAAM,OAAO,IAAI,OAAO,QAAQ,SAAS,UAAU,CAAC,CAAC,CAAC,GAAG;GACnE,KAAK,OAAO,WAAW,IAAI;GAC3B,qBAAqB,KAAK,IAAI,IAAI;EACpC;EACA,KAAK,MAAM,CAAC,OAAO,QAAQ,IAAI,OAAO,QAAQ,SAAS,aAAa,CAAC,CAAC,CAAC,GAAG;GACxE,KAAK,OAAO,SAAS,KAAK;GAC1B,KAAK,KAAK,KAAK,IAAI;EACrB;CACF;CACA,OAAO,UAAU,IAAI,UAAU;EAC7B,MAAM,SAAS,GAAG,aAChBA,iCAAAA,aAAa,MACb,KAAK,UAAUA,iCAAAA,aAAa,WAAW,QAAQ,CAAC,CAAC,IAAI,CACvD;EAEA,KAAK,MAAM,CAAC,OAAO,QAAQ,OAAO,QAAQ,SAAS,QAAQ,CAAC,CAAC,GAAG;GAC9D,MAAM,MAAMA,iCAAAA,aAAa,SAAS,QAAQ,KAAK;GAC/C,GAAG,YAAY,KAAK,OAAO;GAC3B,GAAG,SAAS,KAAK,SAAS,KAAK,WAAW,CAAC;EAC7C;EAGA,KAAK,MAAM,CAAC,MAAM,OAAO,OAAO,QAAQ,SAAS,YAAY,CAAC,CAAC,GAAG;GAChE,MAAM,MAAMA,iCAAAA,aAAa,QAAQ,QAAQ,IAAI;GAC7C,GAAG,YAAY,KAAK,OAAO;GAC3B,GAAG,SAAS,KAAK,SAAS,IAAI,oBAAoB,CAAC;EACrD;EACA,KAAK,MAAM,CAAC,MAAM,OAAO,OAAO,QAAQ,SAAS,UAAU,CAAC,CAAC,GAAG;GAC9D,MAAM,MAAMA,iCAAAA,aAAa,QAAQ,QAAQ,IAAI;GAC7C,GAAG,YAAY,KAAK,OAAO;GAC3B,GAAG,SAAS,KAAK,SAAS,IAAI,oBAAoB,CAAC;EACrD;EAGA,KAAK,MAAM,CAAC,UAAU,WAAW,OAAO,QAAQ,SAAS,aAAa,CAAC,CAAC,GAAG;GACzE,MAAM,MAAMA,iCAAAA,aAAa,SAAS,QAAQ,QAAQ;GAClD,GAAG,YAAY,KAAK,OAAO;GAC3B,GAAG,SAAS,KAAK,SAAS,QAAQ,gBAAgB,CAAC;EACrD;EAEA,GAAG,KAAK,MAAM;EAEd,IAAI,CAAC,SAAS,cAAc,OAAO;EAGnC,MAAM,cAAc,GAAG,aACrBC,iCAAAA,qBAAqB,MACrB,KAAK,UAAUA,iCAAAA,qBAAqB,WAAW,QAAQ,CAAC,CAC1D;EACA,MAAM,MAAMA,iCAAAA,qBAAqB,SAAS,WAAW;EACrD,GAAG,YAAY,KAAK,SAAS;EAC7B,GAAG,SAAS,KAAK,MAAM;EACvB,GAAG,KAAK,WAAW;EACnB,OAAO;CACT;AACF;AAEA,SAAS,qBAAqB,IAAmB,SAA+B;CAC9E,MAAM,gCAAgB,IAAI,IAA4B;CAEtD,MAAM,kBAAqB,UAAa,aAA0C;EAChF,MAAM,UAAA,GAAA,YAAA,WAAA,CAA0B,QAAQ;EACxC,SAAS,KAAK,UAAU,MAAM;EAE9B,MAAM,OAAO,OAAO,OAAO,KAAK;EAEhC,IAAI,CAAC,cAAc,IAAI,IAAI,GAAG;GAC5B,MAAM,MAAM,SAAS,OAAO,UAAU,IAAI,cAAc;GACxD,cAAc,IAAI,MAAM,GAAG;EAC7B;EAEA,OAAO,cAAc,IAAI,IAAI;CAC/B;CAEA,OAAO,eAAe,SAAS,gBAAgB;AACjD"}
|
|
1
|
+
{"version":3,"file":"direct_template_loader.cjs","names":["parseTemplate","createTemplateV3Tree","PlTemplateLibV1","PlTemplateSoftwareV1","PlTemplateV1","PlTemplateOverrideV1","createHash"],"sources":["../../../src/mutator/template/direct_template_loader.ts"],"sourcesContent":["import type { AnyRef, AnyResourceRef, PlTransaction } from \"@milaboratories/pl-client\";\nimport { assertNever } from \"@milaboratories/ts-helpers\";\nimport type { ExplicitTemplate, PreparedTemplate } from \"../../model/template_spec\";\nimport type { Hash } from \"node:crypto\";\nimport { createHash } from \"node:crypto\";\nimport type {\n TemplateData,\n TemplateLibData,\n TemplateSoftwareData,\n} from \"@milaboratories/pl-model-backend\";\nimport {\n PlTemplateLibV1,\n PlTemplateSoftwareV1,\n PlTemplateV1,\n PlTemplateOverrideV1,\n parseTemplate,\n} from \"@milaboratories/pl-model-backend\";\nimport { createTemplateV3Tree } from \"./direct_template_loader_v3\";\n\nexport function loadTemplateFromExplicitDirect(tx: PlTransaction, spec: ExplicitTemplate): AnyRef {\n const templateInfo = parseTemplate(spec.content);\n\n const templateFormat = templateInfo.type;\n switch (templateFormat) {\n case \"pl.tengo-template.v2\":\n return createTemplateV2Tree(tx, templateInfo);\n case \"pl.tengo-template.v3\":\n return createTemplateV3Tree(tx, templateInfo);\n default:\n assertNever(templateFormat);\n }\n}\n\nexport function loadTemplateFromPrepared(tx: PlTransaction, spec: PreparedTemplate): AnyRef {\n const templateData = spec.data;\n\n const templateFormat = templateData.type;\n switch (templateFormat) {\n case \"pl.tengo-template.v2\":\n return createTemplateV2Tree(tx, templateData);\n case \"pl.tengo-template.v3\":\n return createTemplateV3Tree(tx, templateData);\n default:\n assertNever(templateFormat);\n }\n}\n\ntype Renderer<T> = {\n hash: Hasher<T>;\n render: (resource: T, tx: PlTransaction, creator: Creator) => AnyResourceRef;\n};\ntype Hasher<T> = (resource: T, hash: Hash) => void;\ntype Creator = <T>(resource: T, renderer: Renderer<T>) => AnyResourceRef;\n\nconst LibRenderer: Renderer<TemplateLibData> = {\n hash(resource, hash) {\n hash\n .update(PlTemplateLibV1.type.name)\n .update(PlTemplateLibV1.type.version)\n .update(resource.name)\n .update(resource.version)\n .update(resource.src);\n },\n render(resource, tx, _creator) {\n return tx.createValue(\n PlTemplateLibV1.type,\n JSON.stringify(PlTemplateLibV1.fromV2Data(resource).data),\n );\n },\n};\n\nconst SoftwareInfoRenderer: Renderer<TemplateSoftwareData> = {\n hash(resource, hash) {\n hash\n .update(PlTemplateSoftwareV1.type.name)\n .update(PlTemplateSoftwareV1.type.version)\n .update(resource.name)\n .update(resource.version)\n .update(resource.src);\n },\n render(resource, tx, _creator) {\n const sw = PlTemplateSoftwareV1.fromV2Data(resource);\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<TemplateData> = {\n hash(resource, hash) {\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(resource.src);\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.hash(lib, hash);\n }\n for (const [swId, sw] of srt(Object.entries(resource.software ?? {}))) {\n hash.update(\"soft:\" + swId);\n SoftwareInfoRenderer.hash(sw, hash);\n }\n for (const [swId, sw] of srt(Object.entries(resource.assets ?? {}))) {\n hash.update(\"asset:\" + swId);\n SoftwareInfoRenderer.hash(sw, hash);\n }\n for (const [tplId, tpl] of srt(Object.entries(resource.templates ?? {}))) {\n hash.update(\"tpl:\" + tplId);\n this.hash(tpl, hash);\n }\n },\n render(resource, tx, _creator) {\n const tplRef = tx.createStruct(\n PlTemplateV1.type,\n JSON.stringify(PlTemplateV1.fromV2Data(resource).data),\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));\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));\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));\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));\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.fromV2Data(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\nfunction createTemplateV2Tree(tx: PlTransaction, tplData: TemplateData): AnyRef {\n const resourceCache = new Map<string, AnyResourceRef>();\n\n const createResource = <T>(resource: T, renderer: Renderer<T>): AnyResourceRef => {\n const hasher: Hash = createHash(\"sha256\");\n renderer.hash(resource, hasher);\n\n const rKey = hasher.digest(\"hex\");\n\n if (!resourceCache.has(rKey)) {\n const rId = renderer.render(resource, tx, createResource);\n resourceCache.set(rKey, rId);\n }\n\n return resourceCache.get(rKey)!;\n };\n\n return createResource(tplData, TemplateRenderer);\n}\n"],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@ import { createTemplateV3Tree } from "./direct_template_loader_v3.js";
|
|
|
2
2
|
import { assertNever } from "@milaboratories/ts-helpers";
|
|
3
3
|
import { createHash } from "node:crypto";
|
|
4
4
|
import { PlTemplateLibV1, PlTemplateOverrideV1, PlTemplateSoftwareV1, PlTemplateV1, parseTemplate } from "@milaboratories/pl-model-backend";
|
|
5
|
-
|
|
5
|
+
// src/mutator/template/direct_template_loader.ts
|
|
6
6
|
function loadTemplateFromExplicitDirect(tx, spec) {
|
|
7
7
|
const templateInfo = parseTemplate(spec.content);
|
|
8
8
|
const templateFormat = templateInfo.type;
|
|
@@ -111,7 +111,6 @@ function createTemplateV2Tree(tx, tplData) {
|
|
|
111
111
|
};
|
|
112
112
|
return createResource(tplData, TemplateRenderer);
|
|
113
113
|
}
|
|
114
|
-
//#endregion
|
|
115
114
|
export { loadTemplateFromExplicitDirect, loadTemplateFromPrepared };
|
|
116
115
|
|
|
117
116
|
//# sourceMappingURL=direct_template_loader.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
let _milaboratories_ts_helpers = require("@milaboratories/ts-helpers");
|
|
2
2
|
let node_crypto = require("node:crypto");
|
|
3
3
|
let _milaboratories_pl_model_backend = require("@milaboratories/pl-model-backend");
|
|
4
|
-
|
|
4
|
+
// src/mutator/template/direct_template_loader_v3.ts
|
|
5
5
|
/**
|
|
6
6
|
* Renders the tree of templates by caching all resource ids
|
|
7
7
|
* by their cache keys.
|
|
@@ -128,7 +128,6 @@ const TemplateRenderer = {
|
|
|
128
128
|
function getSourceCode(name, sources, sourceHash) {
|
|
129
129
|
return (0, _milaboratories_ts_helpers.notEmpty)(sources[sourceHash], `trying to get "${name}" source: sources map doesn't contain source hash ${sourceHash}`);
|
|
130
130
|
}
|
|
131
|
-
//#endregion
|
|
132
131
|
exports.createTemplateV3Tree = createTemplateV3Tree;
|
|
133
132
|
|
|
134
133
|
//# sourceMappingURL=direct_template_loader_v3.cjs.map
|
|
@@ -1 +1 @@
|
|
|
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 // sourceHash is already the sha256 of this source (the hashToSource key), so hash it\n // directly instead of streaming the full source through sha256 again.\n hash\n .update(PlTemplateLibV1.type.name)\n .update(PlTemplateLibV1.type.version)\n .update(resource.name)\n .update(resource.version)\n .update(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(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(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(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
|
+
{"version":3,"file":"direct_template_loader_v3.cjs","names":["createHash","PlTemplateLibV1","PlWasmV1","PlTemplateSoftwareV1","PlTemplateV1","PlTemplateOverrideV1","notEmpty"],"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 // sourceHash is already the sha256 of this source (the hashToSource key), so hash it\n // directly instead of streaming the full source through sha256 again.\n hash\n .update(PlTemplateLibV1.type.name)\n .update(PlTemplateLibV1.type.version)\n .update(resource.name)\n .update(resource.version)\n .update(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(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(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(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,7 +1,7 @@
|
|
|
1
1
|
import { notEmpty } from "@milaboratories/ts-helpers";
|
|
2
2
|
import { createHash } from "node:crypto";
|
|
3
3
|
import { PlTemplateLibV1, PlTemplateOverrideV1, PlTemplateSoftwareV1, PlTemplateV1, PlWasmV1 } from "@milaboratories/pl-model-backend";
|
|
4
|
-
|
|
4
|
+
// src/mutator/template/direct_template_loader_v3.ts
|
|
5
5
|
/**
|
|
6
6
|
* Renders the tree of templates by caching all resource ids
|
|
7
7
|
* by their cache keys.
|
|
@@ -128,7 +128,6 @@ const TemplateRenderer = {
|
|
|
128
128
|
function getSourceCode(name, sources, sourceHash) {
|
|
129
129
|
return notEmpty(sources[sourceHash], `trying to get "${name}" source: sources map doesn't contain source hash ${sourceHash}`);
|
|
130
130
|
}
|
|
131
|
-
//#endregion
|
|
132
131
|
export { createTemplateV3Tree };
|
|
133
132
|
|
|
134
133
|
//# sourceMappingURL=direct_template_loader_v3.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const require_render_template = require("./render_template.cjs");
|
|
2
2
|
let _milaboratories_pl_client = require("@milaboratories/pl-client");
|
|
3
3
|
let node_crypto = require("node:crypto");
|
|
4
|
-
|
|
4
|
+
// src/mutator/template/render_block.ts
|
|
5
5
|
const BContextEnd = {
|
|
6
6
|
name: "BContextEnd",
|
|
7
7
|
version: "1"
|
|
@@ -29,7 +29,6 @@ function createBContextFromUpstreams(tx, upstreamCtxs) {
|
|
|
29
29
|
tx.lock(ctx);
|
|
30
30
|
return ctx;
|
|
31
31
|
}
|
|
32
|
-
//#endregion
|
|
33
32
|
exports.BContext = BContext;
|
|
34
33
|
exports.BContextEnd = BContextEnd;
|
|
35
34
|
exports.BContextMultiParentPrefix = BContextMultiParentPrefix;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render_block.cjs","names":["createRenderTemplate","Pl"],"sources":["../../../src/mutator/template/render_block.ts"],"sourcesContent":["import type { AnyRef, PlTransaction, ResourceRef, ResourceType } from \"@milaboratories/pl-client\";\nimport { field, Pl } from \"@milaboratories/pl-client\";\nimport { randomUUID } from \"node:crypto\";\nimport { createRenderTemplate } from \"./render_template\";\n\nexport const BContextEnd: ResourceType = { name: \"BContextEnd\", version: \"1\" };\nexport const BContext: ResourceType = { name: \"BContext\", version: \"1\" };\nexport const BContextId = \"id\";\nexport const BContextParent = \"parent\";\nexport const BContextMultiParentPrefix = \"parent/\";\n\n// TODO: add implementation for dual context heavy block.\n// export type BlockType =\n// | 'LightBlock'\n// | 'HeavyBlock'\n// | 'DualContextHeavyBlock';\n// moved to project model ==>>>\n\nexport type HeavyBlockInputs = {\n args: AnyRef;\n blockId: AnyRef;\n isProduction: AnyRef;\n context: AnyRef;\n};\n\nexport type HeavyBlockOutputs = {\n context: AnyRef;\n result: AnyRef;\n};\n\nexport const HeavyBlockOutputNames: (keyof HeavyBlockOutputs)[] = [\"context\", \"result\"];\n\nexport function createRenderHeavyBlock(\n tx: PlTransaction,\n tpl: AnyRef,\n inputs: HeavyBlockInputs,\n): HeavyBlockOutputs {\n return createRenderTemplate(tx, tpl, true, inputs, HeavyBlockOutputNames);\n}\n\nexport type LightBlockInputs = {\n args: AnyRef;\n blockId: AnyRef;\n stagingContext: AnyRef;\n productionContext: AnyRef;\n};\n\nexport type LightBlockOutput = {\n result: AnyRef;\n};\n\nexport const LightBlockOutputNames: (keyof LightBlockOutput)[] = [\"result\"];\n\nexport function createRenderLightBlock(\n tx: PlTransaction,\n tpl: ResourceRef,\n inputs: LightBlockInputs,\n): LightBlockOutput {\n return createRenderTemplate(tx, tpl, true, inputs, LightBlockOutputNames);\n}\n\nexport function createBContextEnd(tx: PlTransaction): ResourceRef {\n const ctx = tx.createEphemeral(BContextEnd);\n tx.lock(ctx);\n return ctx;\n}\n\nexport function createBContextFromUpstreams(tx: PlTransaction, upstreamCtxs: AnyRef[]): AnyRef {\n if (upstreamCtxs.length === 0) return createBContextEnd(tx);\n\n if (upstreamCtxs.length === 1) return upstreamCtxs[0];\n\n const ctx = tx.createEphemeral(BContext);\n\n // setting id\n tx.createField(field(ctx, BContextId), \"Input\", Pl.createPlString(tx, randomUUID()));\n\n // setting parents\n for (let i = 0; i < upstreamCtxs.length; i++)\n tx.createField(field(ctx, `${BContextMultiParentPrefix}${i}`), \"Input\", upstreamCtxs[i]);\n\n tx.lock(ctx);\n\n return ctx;\n}\n"],"mappings":";;;;AAKA,MAAa,cAA4B;CAAE,MAAM;CAAe,SAAS;AAAI;AAC7E,MAAa,WAAyB;CAAE,MAAM;CAAY,SAAS;AAAI;AAGvE,MAAa,4BAA4B;AAqBzC,MAAa,wBAAqD,CAAC,WAAW,QAAQ;AAEtF,SAAgB,uBACd,IACA,KACA,QACmB;CACnB,OAAOA,wBAAAA,qBAAqB,IAAI,KAAK,MAAM,QAAQ,qBAAqB;AAC1E;AAuBA,SAAgB,kBAAkB,IAAgC;CAChE,MAAM,MAAM,GAAG,gBAAgB,WAAW;CAC1C,GAAG,KAAK,GAAG;CACX,OAAO;AACT;AAEA,SAAgB,4BAA4B,IAAmB,cAAgC;CAC7F,IAAI,aAAa,WAAW,GAAG,OAAO,kBAAkB,EAAE;CAE1D,IAAI,aAAa,WAAW,GAAG,OAAO,aAAa;CAEnD,MAAM,MAAM,GAAG,gBAAgB,QAAQ;CAGvC,GAAG,aAAA,
|
|
1
|
+
{"version":3,"file":"render_block.cjs","names":["createRenderTemplate","field","Pl","randomUUID"],"sources":["../../../src/mutator/template/render_block.ts"],"sourcesContent":["import type { AnyRef, PlTransaction, ResourceRef, ResourceType } from \"@milaboratories/pl-client\";\nimport { field, Pl } from \"@milaboratories/pl-client\";\nimport { randomUUID } from \"node:crypto\";\nimport { createRenderTemplate } from \"./render_template\";\n\nexport const BContextEnd: ResourceType = { name: \"BContextEnd\", version: \"1\" };\nexport const BContext: ResourceType = { name: \"BContext\", version: \"1\" };\nexport const BContextId = \"id\";\nexport const BContextParent = \"parent\";\nexport const BContextMultiParentPrefix = \"parent/\";\n\n// TODO: add implementation for dual context heavy block.\n// export type BlockType =\n// | 'LightBlock'\n// | 'HeavyBlock'\n// | 'DualContextHeavyBlock';\n// moved to project model ==>>>\n\nexport type HeavyBlockInputs = {\n args: AnyRef;\n blockId: AnyRef;\n isProduction: AnyRef;\n context: AnyRef;\n};\n\nexport type HeavyBlockOutputs = {\n context: AnyRef;\n result: AnyRef;\n};\n\nexport const HeavyBlockOutputNames: (keyof HeavyBlockOutputs)[] = [\"context\", \"result\"];\n\nexport function createRenderHeavyBlock(\n tx: PlTransaction,\n tpl: AnyRef,\n inputs: HeavyBlockInputs,\n): HeavyBlockOutputs {\n return createRenderTemplate(tx, tpl, true, inputs, HeavyBlockOutputNames);\n}\n\nexport type LightBlockInputs = {\n args: AnyRef;\n blockId: AnyRef;\n stagingContext: AnyRef;\n productionContext: AnyRef;\n};\n\nexport type LightBlockOutput = {\n result: AnyRef;\n};\n\nexport const LightBlockOutputNames: (keyof LightBlockOutput)[] = [\"result\"];\n\nexport function createRenderLightBlock(\n tx: PlTransaction,\n tpl: ResourceRef,\n inputs: LightBlockInputs,\n): LightBlockOutput {\n return createRenderTemplate(tx, tpl, true, inputs, LightBlockOutputNames);\n}\n\nexport function createBContextEnd(tx: PlTransaction): ResourceRef {\n const ctx = tx.createEphemeral(BContextEnd);\n tx.lock(ctx);\n return ctx;\n}\n\nexport function createBContextFromUpstreams(tx: PlTransaction, upstreamCtxs: AnyRef[]): AnyRef {\n if (upstreamCtxs.length === 0) return createBContextEnd(tx);\n\n if (upstreamCtxs.length === 1) return upstreamCtxs[0];\n\n const ctx = tx.createEphemeral(BContext);\n\n // setting id\n tx.createField(field(ctx, BContextId), \"Input\", Pl.createPlString(tx, randomUUID()));\n\n // setting parents\n for (let i = 0; i < upstreamCtxs.length; i++)\n tx.createField(field(ctx, `${BContextMultiParentPrefix}${i}`), \"Input\", upstreamCtxs[i]);\n\n tx.lock(ctx);\n\n return ctx;\n}\n"],"mappings":";;;;AAKA,MAAa,cAA4B;CAAE,MAAM;CAAe,SAAS;AAAI;AAC7E,MAAa,WAAyB;CAAE,MAAM;CAAY,SAAS;AAAI;AAGvE,MAAa,4BAA4B;AAqBzC,MAAa,wBAAqD,CAAC,WAAW,QAAQ;AAEtF,SAAgB,uBACd,IACA,KACA,QACmB;CACnB,OAAOA,wBAAAA,qBAAqB,IAAI,KAAK,MAAM,QAAQ,qBAAqB;AAC1E;AAuBA,SAAgB,kBAAkB,IAAgC;CAChE,MAAM,MAAM,GAAG,gBAAgB,WAAW;CAC1C,GAAG,KAAK,GAAG;CACX,OAAO;AACT;AAEA,SAAgB,4BAA4B,IAAmB,cAAgC;CAC7F,IAAI,aAAa,WAAW,GAAG,OAAO,kBAAkB,EAAE;CAE1D,IAAI,aAAa,WAAW,GAAG,OAAO,aAAa;CAEnD,MAAM,MAAM,GAAG,gBAAgB,QAAQ;CAGvC,GAAG,aAAA,GAAYC,0BAAAA,MAAAA,CAAM,KAAA,IAAe,GAAG,SAASC,0BAAAA,GAAG,eAAe,KAAA,GAAIC,YAAAA,WAAAA,CAAW,CAAC,CAAC;CAGnF,KAAK,IAAI,IAAI,GAAG,IAAI,aAAa,QAAQ,KACvC,GAAG,aAAA,GAAYF,0BAAAA,MAAAA,CAAM,KAAK,GAAG,4BAA4B,GAAG,GAAG,SAAS,aAAa,EAAE;CAEzF,GAAG,KAAK,GAAG;CAEX,OAAO;AACT"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createRenderTemplate } from "./render_template.js";
|
|
2
2
|
import { Pl, field } from "@milaboratories/pl-client";
|
|
3
3
|
import { randomUUID } from "node:crypto";
|
|
4
|
-
|
|
4
|
+
// src/mutator/template/render_block.ts
|
|
5
5
|
const BContextEnd = {
|
|
6
6
|
name: "BContextEnd",
|
|
7
7
|
version: "1"
|
|
@@ -29,7 +29,6 @@ function createBContextFromUpstreams(tx, upstreamCtxs) {
|
|
|
29
29
|
tx.lock(ctx);
|
|
30
30
|
return ctx;
|
|
31
31
|
}
|
|
32
|
-
//#endregion
|
|
33
32
|
export { BContext, BContextEnd, BContextMultiParentPrefix, HeavyBlockOutputNames, createBContextEnd, createBContextFromUpstreams, createRenderHeavyBlock };
|
|
34
33
|
|
|
35
34
|
//# sourceMappingURL=render_block.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
let _milaboratories_pl_client = require("@milaboratories/pl-client");
|
|
2
|
-
|
|
2
|
+
// src/mutator/template/render_template.ts
|
|
3
3
|
const EphRenderTemplate = {
|
|
4
4
|
name: "EphRenderTemplate",
|
|
5
5
|
version: "1"
|
|
@@ -27,7 +27,6 @@ function createRenderTemplate(tx, tpl, ephemeral, inputs, outputNames) {
|
|
|
27
27
|
tx.lockInputs(rId);
|
|
28
28
|
return _milaboratories_pl_client.Pl.futureRecord(tx, rId, outputNames, "Output", "outputs/");
|
|
29
29
|
}
|
|
30
|
-
//#endregion
|
|
31
30
|
exports.createRenderTemplate = createRenderTemplate;
|
|
32
31
|
|
|
33
32
|
//# sourceMappingURL=render_template.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render_template.cjs","names":["Pl"],"sources":["../../../src/mutator/template/render_template.ts"],"sourcesContent":["import type { AnyRef, FieldRef, PlTransaction } from \"@milaboratories/pl-client\";\nimport { field, Pl } from \"@milaboratories/pl-client\";\nimport type { ResourceType } from \"@platforma-sdk/model\";\n\nconst EphRenderTemplate: ResourceType = {\n name: \"EphRenderTemplate\",\n version: \"1\",\n};\nconst RenderTemplate: ResourceType = {\n name: \"RenderTemplate\",\n version: \"1\",\n};\n\n/**\n * Creates render template operation, for a given remplate and inputs.\n *\n * @param tx transaction to use during rendering creation\n * @param tpl reference to the template resource (see {@link loadTemplate})\n * @param ephemeral true for ephemeral templates, false for pure templates\n * @param inputs map of inputs pointing to other resources or fields\n * @param outputNames names of the outputs to collect and return from this method\n */\nexport function createRenderTemplate<O extends string>(\n tx: PlTransaction,\n tpl: AnyRef,\n ephemeral: boolean,\n inputs: Pl.PlRecord,\n outputNames: O[],\n): Record<O, FieldRef> {\n if (outputNames.length === 0) throw new Error(\"Zero output names provided\");\n const rId = ephemeral ? tx.createEphemeral(EphRenderTemplate) : tx.createStruct(RenderTemplate);\n\n const tplField = field(rId, \"template\");\n const inputsField = field(rId, \"inputs\");\n\n tx.createField(tplField, \"Input\", tpl);\n tx.createField(inputsField, \"Input\", Pl.createPlMap(tx, inputs, ephemeral));\n tx.lockInputs(rId);\n\n return Pl.futureRecord(tx, rId, outputNames, \"Output\", \"outputs/\");\n}\n"],"mappings":";;AAIA,MAAM,oBAAkC;CACtC,MAAM;CACN,SAAS;AACX;AACA,MAAM,iBAA+B;CACnC,MAAM;CACN,SAAS;AACX;;;;;;;;;;AAWA,SAAgB,qBACd,IACA,KACA,WACA,QACA,aACqB;CACrB,IAAI,YAAY,WAAW,GAAG,MAAM,IAAI,MAAM,4BAA4B;CAC1E,MAAM,MAAM,YAAY,GAAG,gBAAgB,iBAAiB,IAAI,GAAG,aAAa,cAAc;CAE9F,MAAM,YAAA,
|
|
1
|
+
{"version":3,"file":"render_template.cjs","names":["field","Pl"],"sources":["../../../src/mutator/template/render_template.ts"],"sourcesContent":["import type { AnyRef, FieldRef, PlTransaction } from \"@milaboratories/pl-client\";\nimport { field, Pl } from \"@milaboratories/pl-client\";\nimport type { ResourceType } from \"@platforma-sdk/model\";\n\nconst EphRenderTemplate: ResourceType = {\n name: \"EphRenderTemplate\",\n version: \"1\",\n};\nconst RenderTemplate: ResourceType = {\n name: \"RenderTemplate\",\n version: \"1\",\n};\n\n/**\n * Creates render template operation, for a given remplate and inputs.\n *\n * @param tx transaction to use during rendering creation\n * @param tpl reference to the template resource (see {@link loadTemplate})\n * @param ephemeral true for ephemeral templates, false for pure templates\n * @param inputs map of inputs pointing to other resources or fields\n * @param outputNames names of the outputs to collect and return from this method\n */\nexport function createRenderTemplate<O extends string>(\n tx: PlTransaction,\n tpl: AnyRef,\n ephemeral: boolean,\n inputs: Pl.PlRecord,\n outputNames: O[],\n): Record<O, FieldRef> {\n if (outputNames.length === 0) throw new Error(\"Zero output names provided\");\n const rId = ephemeral ? tx.createEphemeral(EphRenderTemplate) : tx.createStruct(RenderTemplate);\n\n const tplField = field(rId, \"template\");\n const inputsField = field(rId, \"inputs\");\n\n tx.createField(tplField, \"Input\", tpl);\n tx.createField(inputsField, \"Input\", Pl.createPlMap(tx, inputs, ephemeral));\n tx.lockInputs(rId);\n\n return Pl.futureRecord(tx, rId, outputNames, \"Output\", \"outputs/\");\n}\n"],"mappings":";;AAIA,MAAM,oBAAkC;CACtC,MAAM;CACN,SAAS;AACX;AACA,MAAM,iBAA+B;CACnC,MAAM;CACN,SAAS;AACX;;;;;;;;;;AAWA,SAAgB,qBACd,IACA,KACA,WACA,QACA,aACqB;CACrB,IAAI,YAAY,WAAW,GAAG,MAAM,IAAI,MAAM,4BAA4B;CAC1E,MAAM,MAAM,YAAY,GAAG,gBAAgB,iBAAiB,IAAI,GAAG,aAAa,cAAc;CAE9F,MAAM,YAAA,GAAWA,0BAAAA,MAAAA,CAAM,KAAK,UAAU;CACtC,MAAM,eAAA,GAAcA,0BAAAA,MAAAA,CAAM,KAAK,QAAQ;CAEvC,GAAG,YAAY,UAAU,SAAS,GAAG;CACrC,GAAG,YAAY,aAAa,SAASC,0BAAAA,GAAG,YAAY,IAAI,QAAQ,SAAS,CAAC;CAC1E,GAAG,WAAW,GAAG;CAEjB,OAAOA,0BAAAA,GAAG,aAAa,IAAI,KAAK,aAAa,UAAU,UAAU;AACnE"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { AnyRef, FieldRef, Pl, PlTransaction } from "@milaboratories/pl-client";
|
|
2
|
-
//#region src/mutator/template/render_template.d.ts
|
|
3
2
|
/**
|
|
4
3
|
* Creates render template operation, for a given remplate and inputs.
|
|
5
4
|
*
|
|
@@ -10,5 +9,4 @@ import { AnyRef, FieldRef, Pl, PlTransaction } from "@milaboratories/pl-client";
|
|
|
10
9
|
* @param outputNames names of the outputs to collect and return from this method
|
|
11
10
|
*/
|
|
12
11
|
export declare function createRenderTemplate<O extends string>(tx: PlTransaction, tpl: AnyRef, ephemeral: boolean, inputs: Pl.PlRecord, outputNames: O[]): Record<O, FieldRef>;
|
|
13
|
-
//#endregion
|
|
14
12
|
//# sourceMappingURL=render_template.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render_template.d.ts","names":[],"sources":["../../../src/mutator/template/render_template.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"render_template.d.ts","names":[],"sources":["../../../src/mutator/template/render_template.ts"],"mappings":";;;;;;;;;;wBAsBgB,qBAAqB,kBACnC,IAAI,eACJ,KAAK,QACL,oBACA,QAAQ,GAAG,UACX,aAAa,MACZ,OAAO,GAAG"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Pl, field } from "@milaboratories/pl-client";
|
|
2
|
-
|
|
2
|
+
// src/mutator/template/render_template.ts
|
|
3
3
|
const EphRenderTemplate = {
|
|
4
4
|
name: "EphRenderTemplate",
|
|
5
5
|
version: "1"
|
|
@@ -27,7 +27,6 @@ function createRenderTemplate(tx, tpl, ephemeral, inputs, outputNames) {
|
|
|
27
27
|
tx.lockInputs(rId);
|
|
28
28
|
return Pl.futureRecord(tx, rId, outputNames, "Output", "outputs/");
|
|
29
29
|
}
|
|
30
|
-
//#endregion
|
|
31
30
|
export { createRenderTemplate };
|
|
32
31
|
|
|
33
32
|
//# sourceMappingURL=render_template.js.map
|
|
@@ -3,7 +3,7 @@ let _milaboratories_ts_helpers = require("@milaboratories/ts-helpers");
|
|
|
3
3
|
let _milaboratories_pl_client = require("@milaboratories/pl-client");
|
|
4
4
|
let node_crypto = require("node:crypto");
|
|
5
5
|
let _milaboratories_pl_model_backend = require("@milaboratories/pl-model-backend");
|
|
6
|
-
|
|
6
|
+
// src/mutator/template/template_cache.ts
|
|
7
7
|
const TemplateCacheType = (0, _milaboratories_pl_client.resourceType)("TemplateCache", "1");
|
|
8
8
|
const TemplateCacheFieldName = "__templateCache";
|
|
9
9
|
const BATCH_SIZE = 50;
|
|
@@ -391,7 +391,8 @@ async function materialize(pl, cacheRid, rootHash, nodes, stat) {
|
|
|
391
391
|
const newCount = (countStr ? parseInt(countStr, 10) : 0) + 1;
|
|
392
392
|
const now = Date.now().toString();
|
|
393
393
|
if (exists[allHashes.length - 1]) {
|
|
394
|
-
const
|
|
394
|
+
const rootFd = await tx.getField((0, _milaboratories_pl_client.field)(cacheRid, rootHash));
|
|
395
|
+
const rootRid = (0, _milaboratories_pl_client.ensureSignedResourceIdNotNull)(rootFd.value);
|
|
395
396
|
tx.setKValue(cacheRid, ACCESS_KEY_PREFIX + rootHash, now);
|
|
396
397
|
tx.setKValue(cacheRid, ACCESS_COUNT_KEY, newCount.toString());
|
|
397
398
|
await tx.commit();
|
|
@@ -437,7 +438,8 @@ async function materialize(pl, cacheRid, rootHash, nodes, stat) {
|
|
|
437
438
|
stat.batchCount++;
|
|
438
439
|
await pl.withWriteTx("templateCache:create", async (tx) => {
|
|
439
440
|
const newRefs = /* @__PURE__ */ new Map();
|
|
440
|
-
|
|
441
|
+
const now = Date.now().toString();
|
|
442
|
+
createBatchNodes(tx, cacheRid, batch, resolvedIds, newRefs, now);
|
|
441
443
|
await tx.commit();
|
|
442
444
|
for (const [hash, ref] of newRefs) resolvedIds.set(hash, await (0, _milaboratories_pl_client.toGlobalResourceId)(ref));
|
|
443
445
|
});
|
|
@@ -493,7 +495,7 @@ async function loadTemplateCached(pl, spec, options) {
|
|
|
493
495
|
}
|
|
494
496
|
return result.rootId;
|
|
495
497
|
} catch (e) {
|
|
496
|
-
if (attempt ===
|
|
498
|
+
if (attempt === 2) throw e;
|
|
497
499
|
stat.cacheHits = 0;
|
|
498
500
|
stat.cacheMisses = 0;
|
|
499
501
|
}
|
|
@@ -519,7 +521,6 @@ async function cacheBlockPackTemplate(pl, spec, options) {
|
|
|
519
521
|
}
|
|
520
522
|
};
|
|
521
523
|
}
|
|
522
|
-
//#endregion
|
|
523
524
|
exports.ACCESS_COUNT_KEY = ACCESS_COUNT_KEY;
|
|
524
525
|
exports.ACCESS_KEY_PREFIX = ACCESS_KEY_PREFIX;
|
|
525
526
|
exports.GC_ACCESS_THRESHOLD = GC_ACCESS_THRESHOLD;
|