@platforma-sdk/model 1.65.9 → 1.66.2
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/block_model.cjs +8 -11
- package/dist/block_model.cjs.map +1 -1
- package/dist/block_model.d.ts.map +1 -1
- package/dist/block_model.js +8 -10
- package/dist/block_model.js.map +1 -1
- package/dist/columns/column_collection_builder.cjs +61 -74
- package/dist/columns/column_collection_builder.cjs.map +1 -1
- package/dist/columns/column_collection_builder.d.ts +16 -22
- package/dist/columns/column_collection_builder.d.ts.map +1 -1
- package/dist/columns/column_collection_builder.js +62 -75
- package/dist/columns/column_collection_builder.js.map +1 -1
- package/dist/columns/column_selector.cjs.map +1 -1
- package/dist/columns/column_selector.d.ts +1 -1
- package/dist/columns/column_selector.js.map +1 -1
- package/dist/columns/column_snapshot.cjs.map +1 -1
- package/dist/columns/column_snapshot.d.ts +4 -4
- package/dist/columns/column_snapshot.d.ts.map +1 -1
- package/dist/columns/column_snapshot.js.map +1 -1
- package/dist/columns/ctx_column_sources.cjs.map +1 -1
- package/dist/columns/ctx_column_sources.d.ts +1 -1
- package/dist/columns/ctx_column_sources.d.ts.map +1 -1
- package/dist/columns/ctx_column_sources.js.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV2.cjs +2 -2
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV2.cjs.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV2.js +2 -2
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV2.js.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV3.cjs +17 -18
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV3.cjs.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV3.js +17 -18
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV3.js.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.cjs +99 -91
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.cjs.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.d.ts +16 -16
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.d.ts.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.js +102 -94
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.js.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/discoverColumns.cjs +32 -23
- package/dist/components/PlDataTable/createPlDataTable/discoverColumns.cjs.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/discoverColumns.d.ts +5 -5
- package/dist/components/PlDataTable/createPlDataTable/discoverColumns.d.ts.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/discoverColumns.js +33 -24
- package/dist/components/PlDataTable/createPlDataTable/discoverColumns.js.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/index.cjs.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/index.d.ts +2 -3
- package/dist/components/PlDataTable/createPlDataTable/index.d.ts.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/index.js.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/utils.cjs +133 -16
- package/dist/components/PlDataTable/createPlDataTable/utils.cjs.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/utils.d.ts +8 -6
- package/dist/components/PlDataTable/createPlDataTable/utils.d.ts.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/utils.js +130 -17
- package/dist/components/PlDataTable/createPlDataTable/utils.js.map +1 -1
- package/dist/components/PlDataTable/labels.cjs +1 -2
- package/dist/components/PlDataTable/labels.cjs.map +1 -1
- package/dist/components/PlDataTable/labels.js +1 -2
- package/dist/components/PlDataTable/labels.js.map +1 -1
- package/dist/filters/distill.cjs +73 -30
- package/dist/filters/distill.cjs.map +1 -1
- package/dist/filters/distill.d.ts.map +1 -1
- package/dist/filters/distill.js +73 -30
- package/dist/filters/distill.js.map +1 -1
- package/dist/index.cjs +19 -15
- package/dist/index.d.ts +4 -2
- package/dist/index.js +6 -4
- package/dist/labels/derive_distinct_tooltips.cjs +85 -0
- package/dist/labels/derive_distinct_tooltips.cjs.map +1 -0
- package/dist/labels/derive_distinct_tooltips.d.ts +17 -0
- package/dist/labels/derive_distinct_tooltips.d.ts.map +1 -0
- package/dist/labels/derive_distinct_tooltips.js +84 -0
- package/dist/labels/derive_distinct_tooltips.js.map +1 -0
- package/dist/labels/index.cjs +1 -0
- package/dist/labels/index.d.ts +2 -1
- package/dist/labels/index.js +1 -0
- package/dist/package.cjs +1 -1
- package/dist/package.js +1 -1
- package/dist/render/api.cjs +8 -13
- package/dist/render/api.cjs.map +1 -1
- package/dist/render/api.d.ts +8 -11
- package/dist/render/api.d.ts.map +1 -1
- package/dist/render/api.js +8 -13
- package/dist/render/api.js.map +1 -1
- package/dist/services/get_services.cjs +19 -0
- package/dist/services/get_services.cjs.map +1 -0
- package/dist/services/get_services.d.ts +7 -0
- package/dist/services/get_services.d.ts.map +1 -0
- package/dist/services/get_services.js +19 -0
- package/dist/services/get_services.js.map +1 -0
- package/dist/services/index.cjs +1 -0
- package/dist/services/index.d.ts +2 -1
- package/dist/services/index.js +1 -0
- package/dist/services/service_bridge.cjs +4 -4
- package/dist/services/service_bridge.cjs.map +1 -1
- package/dist/services/service_bridge.d.ts +4 -4
- package/dist/services/service_bridge.d.ts.map +1 -1
- package/dist/services/service_bridge.js +4 -4
- package/dist/services/service_bridge.js.map +1 -1
- package/package.json +6 -6
- package/src/block_model.ts +8 -11
- package/src/columns/column_collection_builder.test.ts +75 -30
- package/src/columns/column_collection_builder.ts +96 -133
- package/src/columns/column_selector.ts +1 -1
- package/src/columns/column_snapshot.ts +7 -4
- package/src/columns/ctx_column_sources.ts +1 -3
- package/src/components/PFrameForGraphs.test.ts +4 -4
- package/src/components/PlDataTable/createPlDataTable/createPTableDefV2.ts +2 -2
- package/src/components/PlDataTable/createPlDataTable/createPTableDefV3.ts +44 -21
- package/src/components/PlDataTable/createPlDataTable/createPlDataTableV3.ts +202 -218
- package/src/components/PlDataTable/createPlDataTable/discoverColumns.ts +69 -56
- package/src/components/PlDataTable/createPlDataTable/index.ts +6 -7
- package/src/components/PlDataTable/createPlDataTable/utils.test.ts +97 -1
- package/src/components/PlDataTable/createPlDataTable/utils.ts +190 -35
- package/src/components/PlDataTable/labels.ts +3 -7
- package/src/filters/distill.test.ts +91 -0
- package/src/filters/distill.ts +102 -46
- package/src/labels/derive_distinct_tooltips.test.ts +233 -0
- package/src/labels/derive_distinct_tooltips.ts +130 -0
- package/src/labels/index.ts +1 -0
- package/src/render/api.ts +15 -50
- package/src/services/get_services.ts +28 -0
- package/src/services/index.ts +1 -0
- package/src/services/service_bridge.ts +5 -5
package/dist/services/index.js
CHANGED
|
@@ -21,14 +21,14 @@ function buildServices(dispatch, registry) {
|
|
|
21
21
|
})));
|
|
22
22
|
}
|
|
23
23
|
/**
|
|
24
|
-
* Builds a
|
|
24
|
+
* Builds a ServiceProxy from a ServiceDispatch.
|
|
25
25
|
* Each service method call is forwarded to dispatch.callServiceMethod.
|
|
26
26
|
*/
|
|
27
|
-
function
|
|
28
|
-
return ((serviceId) => Object.freeze(Object.fromEntries(dispatch.getServiceMethods(serviceId).map((method) => [method,
|
|
27
|
+
function createServiceProxy(dispatch) {
|
|
28
|
+
return ((serviceId) => Object.freeze(Object.fromEntries(dispatch.getServiceMethods(serviceId).map((method) => [method, (...args) => dispatch.callServiceMethod(serviceId, method, ...args)]))));
|
|
29
29
|
}
|
|
30
30
|
//#endregion
|
|
31
31
|
exports.buildServices = buildServices;
|
|
32
|
-
exports.
|
|
32
|
+
exports.createServiceProxy = createServiceProxy;
|
|
33
33
|
|
|
34
34
|
//# sourceMappingURL=service_bridge.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service_bridge.cjs","names":[],"sources":["../../src/services/service_bridge.ts"],"sourcesContent":["/**\n * Runtime service bridge — builds lazy service objects from dispatch + registry.\n * Used by the UI layer to provide typed service access.\n */\n\nimport type {\n ServiceTypesLike,\n InferServiceUi,\n ServiceName,\n ServiceDispatch,\n UiServices as AllUiServices,\n} from \"@milaboratories/pl-model-common\";\nimport { UiServiceRegistry } from \"@milaboratories/pl-model-common\";\n\n// Makes a remote node service appear local.\n// Given a service ID, returns an object implementing the service's UI interface.\n// Provided by the desktop app (e.g. backed by Electron IPC).\nexport type
|
|
1
|
+
{"version":3,"file":"service_bridge.cjs","names":[],"sources":["../../src/services/service_bridge.ts"],"sourcesContent":["/**\n * Runtime service bridge — builds lazy service objects from dispatch + registry.\n * Used by the UI layer to provide typed service access.\n */\n\nimport type {\n ServiceTypesLike,\n InferServiceUi,\n ServiceName,\n ServiceDispatch,\n UiServices as AllUiServices,\n} from \"@milaboratories/pl-model-common\";\nimport { UiServiceRegistry } from \"@milaboratories/pl-model-common\";\n\n// Makes a remote node service appear local.\n// Given a service ID, returns an object implementing the service's UI interface.\n// Provided by the desktop app (e.g. backed by Electron IPC).\nexport type ServiceProxy = <S extends ServiceTypesLike>(\n serviceId: ServiceName<S>,\n) => InferServiceUi<S>;\n\n/**\n * Builds a lazy services object from ServiceDispatch and UiServiceRegistry.\n * Each service is instantiated on first access. Errors are cached to prevent\n * repeated factory calls on failure.\n */\nexport function buildServices<S extends Partial<AllUiServices> = Partial<AllUiServices>>(\n dispatch: ServiceDispatch,\n registry: UiServiceRegistry,\n): S {\n return Object.create(\n null,\n Object.fromEntries(\n dispatch.getServiceNames().map((id) => {\n let fetched = false;\n let cached: unknown;\n return [\n id,\n {\n enumerable: true,\n get() {\n if (!fetched) {\n fetched = true;\n cached = registry.get(id);\n }\n return cached;\n },\n },\n ];\n }),\n ),\n );\n}\n\n/**\n * Builds a ServiceProxy from a ServiceDispatch.\n * Each service method call is forwarded to dispatch.callServiceMethod.\n */\nexport function createServiceProxy(dispatch: ServiceDispatch): ServiceProxy {\n return ((serviceId: ServiceName) =>\n Object.freeze(\n Object.fromEntries(\n dispatch\n .getServiceMethods(serviceId)\n .map((method) => [\n method,\n (...args: unknown[]) => dispatch.callServiceMethod(serviceId, method, ...args),\n ]),\n ),\n )) as ServiceProxy;\n}\n"],"mappings":";;;;;;AA0BA,SAAgB,cACd,UACA,UACG;AACH,QAAO,OAAO,OACZ,MACA,OAAO,YACL,SAAS,iBAAiB,CAAC,KAAK,OAAO;EACrC,IAAI,UAAU;EACd,IAAI;AACJ,SAAO,CACL,IACA;GACE,YAAY;GACZ,MAAM;AACJ,QAAI,CAAC,SAAS;AACZ,eAAU;AACV,cAAS,SAAS,IAAI,GAAG;;AAE3B,WAAO;;GAEV,CACF;GACD,CACH,CACF;;;;;;AAOH,SAAgB,mBAAmB,UAAyC;AAC1E,UAAS,cACP,OAAO,OACL,OAAO,YACL,SACG,kBAAkB,UAAU,CAC5B,KAAK,WAAW,CACf,SACC,GAAG,SAAoB,SAAS,kBAAkB,WAAW,QAAQ,GAAG,KAAK,CAC/E,CAAC,CACL,CACF"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { InferServiceUi, ServiceDispatch, ServiceName, ServiceTypesLike, UiServiceRegistry, UiServices } from "@milaboratories/pl-model-common";
|
|
2
2
|
|
|
3
3
|
//#region src/services/service_bridge.d.ts
|
|
4
|
-
type
|
|
4
|
+
type ServiceProxy = <S extends ServiceTypesLike>(serviceId: ServiceName<S>) => InferServiceUi<S>;
|
|
5
5
|
/**
|
|
6
6
|
* Builds a lazy services object from ServiceDispatch and UiServiceRegistry.
|
|
7
7
|
* Each service is instantiated on first access. Errors are cached to prevent
|
|
@@ -9,10 +9,10 @@ type NodeServiceProxy = <S extends ServiceTypesLike>(serviceId: ServiceName<S>)
|
|
|
9
9
|
*/
|
|
10
10
|
declare function buildServices<S extends Partial<UiServices> = Partial<UiServices>>(dispatch: ServiceDispatch, registry: UiServiceRegistry): S;
|
|
11
11
|
/**
|
|
12
|
-
* Builds a
|
|
12
|
+
* Builds a ServiceProxy from a ServiceDispatch.
|
|
13
13
|
* Each service method call is forwarded to dispatch.callServiceMethod.
|
|
14
14
|
*/
|
|
15
|
-
declare function
|
|
15
|
+
declare function createServiceProxy(dispatch: ServiceDispatch): ServiceProxy;
|
|
16
16
|
//#endregion
|
|
17
|
-
export {
|
|
17
|
+
export { ServiceProxy, buildServices, createServiceProxy };
|
|
18
18
|
//# sourceMappingURL=service_bridge.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service_bridge.d.ts","names":[],"sources":["../../src/services/service_bridge.ts"],"mappings":";;;KAiBY,
|
|
1
|
+
{"version":3,"file":"service_bridge.d.ts","names":[],"sources":["../../src/services/service_bridge.ts"],"mappings":";;;KAiBY,YAAA,cAA0B,gBAAA,EACpC,SAAA,EAAW,WAAA,CAAY,CAAA,MACpB,cAAA,CAAe,CAAA;;;;;;iBAOJ,aAAA,WAAwB,OAAA,CAAQ,UAAA,IAAiB,OAAA,CAAQ,UAAA,EAAA,CACvE,QAAA,EAAU,eAAA,EACV,QAAA,EAAU,iBAAA,GACT,CAAA;;;;;iBA6Ba,kBAAA,CAAmB,QAAA,EAAU,eAAA,GAAkB,YAAA"}
|
|
@@ -21,13 +21,13 @@ function buildServices(dispatch, registry) {
|
|
|
21
21
|
})));
|
|
22
22
|
}
|
|
23
23
|
/**
|
|
24
|
-
* Builds a
|
|
24
|
+
* Builds a ServiceProxy from a ServiceDispatch.
|
|
25
25
|
* Each service method call is forwarded to dispatch.callServiceMethod.
|
|
26
26
|
*/
|
|
27
|
-
function
|
|
28
|
-
return ((serviceId) => Object.freeze(Object.fromEntries(dispatch.getServiceMethods(serviceId).map((method) => [method,
|
|
27
|
+
function createServiceProxy(dispatch) {
|
|
28
|
+
return ((serviceId) => Object.freeze(Object.fromEntries(dispatch.getServiceMethods(serviceId).map((method) => [method, (...args) => dispatch.callServiceMethod(serviceId, method, ...args)]))));
|
|
29
29
|
}
|
|
30
30
|
//#endregion
|
|
31
|
-
export { buildServices,
|
|
31
|
+
export { buildServices, createServiceProxy };
|
|
32
32
|
|
|
33
33
|
//# sourceMappingURL=service_bridge.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service_bridge.js","names":[],"sources":["../../src/services/service_bridge.ts"],"sourcesContent":["/**\n * Runtime service bridge — builds lazy service objects from dispatch + registry.\n * Used by the UI layer to provide typed service access.\n */\n\nimport type {\n ServiceTypesLike,\n InferServiceUi,\n ServiceName,\n ServiceDispatch,\n UiServices as AllUiServices,\n} from \"@milaboratories/pl-model-common\";\nimport { UiServiceRegistry } from \"@milaboratories/pl-model-common\";\n\n// Makes a remote node service appear local.\n// Given a service ID, returns an object implementing the service's UI interface.\n// Provided by the desktop app (e.g. backed by Electron IPC).\nexport type
|
|
1
|
+
{"version":3,"file":"service_bridge.js","names":[],"sources":["../../src/services/service_bridge.ts"],"sourcesContent":["/**\n * Runtime service bridge — builds lazy service objects from dispatch + registry.\n * Used by the UI layer to provide typed service access.\n */\n\nimport type {\n ServiceTypesLike,\n InferServiceUi,\n ServiceName,\n ServiceDispatch,\n UiServices as AllUiServices,\n} from \"@milaboratories/pl-model-common\";\nimport { UiServiceRegistry } from \"@milaboratories/pl-model-common\";\n\n// Makes a remote node service appear local.\n// Given a service ID, returns an object implementing the service's UI interface.\n// Provided by the desktop app (e.g. backed by Electron IPC).\nexport type ServiceProxy = <S extends ServiceTypesLike>(\n serviceId: ServiceName<S>,\n) => InferServiceUi<S>;\n\n/**\n * Builds a lazy services object from ServiceDispatch and UiServiceRegistry.\n * Each service is instantiated on first access. Errors are cached to prevent\n * repeated factory calls on failure.\n */\nexport function buildServices<S extends Partial<AllUiServices> = Partial<AllUiServices>>(\n dispatch: ServiceDispatch,\n registry: UiServiceRegistry,\n): S {\n return Object.create(\n null,\n Object.fromEntries(\n dispatch.getServiceNames().map((id) => {\n let fetched = false;\n let cached: unknown;\n return [\n id,\n {\n enumerable: true,\n get() {\n if (!fetched) {\n fetched = true;\n cached = registry.get(id);\n }\n return cached;\n },\n },\n ];\n }),\n ),\n );\n}\n\n/**\n * Builds a ServiceProxy from a ServiceDispatch.\n * Each service method call is forwarded to dispatch.callServiceMethod.\n */\nexport function createServiceProxy(dispatch: ServiceDispatch): ServiceProxy {\n return ((serviceId: ServiceName) =>\n Object.freeze(\n Object.fromEntries(\n dispatch\n .getServiceMethods(serviceId)\n .map((method) => [\n method,\n (...args: unknown[]) => dispatch.callServiceMethod(serviceId, method, ...args),\n ]),\n ),\n )) as ServiceProxy;\n}\n"],"mappings":";;;;;;AA0BA,SAAgB,cACd,UACA,UACG;AACH,QAAO,OAAO,OACZ,MACA,OAAO,YACL,SAAS,iBAAiB,CAAC,KAAK,OAAO;EACrC,IAAI,UAAU;EACd,IAAI;AACJ,SAAO,CACL,IACA;GACE,YAAY;GACZ,MAAM;AACJ,QAAI,CAAC,SAAS;AACZ,eAAU;AACV,cAAS,SAAS,IAAI,GAAG;;AAE3B,WAAO;;GAEV,CACF;GACD,CACH,CACF;;;;;;AAOH,SAAgB,mBAAmB,UAAyC;AAC1E,UAAS,cACP,OAAO,OACL,OAAO,YACL,SACG,kBAAkB,UAAU,CAC5B,KAAK,WAAW,CACf,SACC,GAAG,SAAoB,SAAS,kBAAkB,WAAW,QAAQ,GAAG,KAAK,CAC/E,CAAC,CACL,CACF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@platforma-sdk/model",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.66.2",
|
|
4
4
|
"description": "Platforma.bio SDK / Block Model",
|
|
5
5
|
"files": [
|
|
6
6
|
"./dist/**/*",
|
|
@@ -30,20 +30,20 @@
|
|
|
30
30
|
"fast-json-patch": "^3.1.1",
|
|
31
31
|
"utility-types": "^3.11.0",
|
|
32
32
|
"zod": "~3.25.76",
|
|
33
|
-
"@milaboratories/pl-model-common": "1.33.0",
|
|
34
|
-
"@milaboratories/pl-model-middle-layer": "1.18.1",
|
|
35
33
|
"@milaboratories/pl-error-like": "1.12.9",
|
|
36
34
|
"@milaboratories/helpers": "1.14.1",
|
|
37
|
-
"@milaboratories/
|
|
35
|
+
"@milaboratories/pl-model-common": "1.34.1",
|
|
36
|
+
"@milaboratories/pl-model-middle-layer": "1.18.3",
|
|
37
|
+
"@milaboratories/ptabler-expression-js": "1.2.13"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@vitest/coverage-istanbul": "^4.1.3",
|
|
41
41
|
"fast-json-patch": "^3.1.1",
|
|
42
42
|
"typescript": "~5.9.3",
|
|
43
43
|
"vitest": "^4.1.3",
|
|
44
|
-
"@milaboratories/pf-driver": "1.3.
|
|
44
|
+
"@milaboratories/pf-driver": "1.3.10",
|
|
45
45
|
"@milaboratories/build-configs": "2.0.0",
|
|
46
|
-
"@milaboratories/pf-spec-driver": "1.3.
|
|
46
|
+
"@milaboratories/pf-spec-driver": "1.3.2",
|
|
47
47
|
"@milaboratories/ts-builder": "1.3.2",
|
|
48
48
|
"@milaboratories/ts-configs": "1.2.3"
|
|
49
49
|
},
|
package/src/block_model.ts
CHANGED
|
@@ -6,12 +6,11 @@ import type {
|
|
|
6
6
|
BlockCodeKnownFeatureFlags,
|
|
7
7
|
BlockConfigContainer,
|
|
8
8
|
} from "@milaboratories/pl-model-common";
|
|
9
|
-
import { resolveRequiredServices } from "@milaboratories/pl-model-common";
|
|
10
9
|
import { getPlatformaInstance, isInUI, createAndRegisterRenderLambda } from "./internal";
|
|
11
10
|
import type { DataModel } from "./block_migrations";
|
|
12
11
|
import type { PlatformaV3 } from "./platforma";
|
|
13
12
|
import type { BlockDefaultUiServices } from "./services/service_resolve";
|
|
14
|
-
import {
|
|
13
|
+
import { BLOCK_SERVICE_FLAGS } from "./services/block_services";
|
|
15
14
|
import type { InferRenderFunctionReturn, RenderFunction } from "./render";
|
|
16
15
|
import { BlockRenderCtx, PluginRenderCtx } from "./render";
|
|
17
16
|
import type { PluginData, PluginModel, PluginOutputs, PluginParams } from "./plugin_model";
|
|
@@ -237,7 +236,7 @@ export class BlockModelV3<
|
|
|
237
236
|
...this.config.outputs,
|
|
238
237
|
[key]: createAndRegisterRenderLambda({
|
|
239
238
|
handle: `block-output#${key}`,
|
|
240
|
-
lambda: () => cfgOrRf(new BlockRenderCtx<Args, Data>(
|
|
239
|
+
lambda: () => cfgOrRf(new BlockRenderCtx<Args, Data>()),
|
|
241
240
|
...flags,
|
|
242
241
|
}),
|
|
243
242
|
},
|
|
@@ -335,7 +334,7 @@ export class BlockModelV3<
|
|
|
335
334
|
sections: createAndRegisterRenderLambda(
|
|
336
335
|
{
|
|
337
336
|
handle: "sections",
|
|
338
|
-
lambda: () => rf(new BlockRenderCtx<Args, Data>(
|
|
337
|
+
lambda: () => rf(new BlockRenderCtx<Args, Data>()),
|
|
339
338
|
},
|
|
340
339
|
true,
|
|
341
340
|
),
|
|
@@ -351,7 +350,7 @@ export class BlockModelV3<
|
|
|
351
350
|
...this.config,
|
|
352
351
|
title: createAndRegisterRenderLambda({
|
|
353
352
|
handle: "title",
|
|
354
|
-
lambda: () => rf(new BlockRenderCtx<Args, Data>(
|
|
353
|
+
lambda: () => rf(new BlockRenderCtx<Args, Data>()),
|
|
355
354
|
}),
|
|
356
355
|
});
|
|
357
356
|
}
|
|
@@ -363,7 +362,7 @@ export class BlockModelV3<
|
|
|
363
362
|
...this.config,
|
|
364
363
|
subtitle: createAndRegisterRenderLambda({
|
|
365
364
|
handle: "subtitle",
|
|
366
|
-
lambda: () => rf(new BlockRenderCtx<Args, Data>(
|
|
365
|
+
lambda: () => rf(new BlockRenderCtx<Args, Data>()),
|
|
367
366
|
}),
|
|
368
367
|
});
|
|
369
368
|
}
|
|
@@ -375,7 +374,7 @@ export class BlockModelV3<
|
|
|
375
374
|
...this.config,
|
|
376
375
|
tags: createAndRegisterRenderLambda({
|
|
377
376
|
handle: "tags",
|
|
378
|
-
lambda: () => rf(new BlockRenderCtx<Args, Data>(
|
|
377
|
+
lambda: () => rf(new BlockRenderCtx<Args, Data>()),
|
|
379
378
|
}),
|
|
380
379
|
});
|
|
381
380
|
}
|
|
@@ -536,8 +535,6 @@ export class BlockModelV3<
|
|
|
536
535
|
|
|
537
536
|
const { dataModel, argsFunction, prerunArgsFunction } = this.config;
|
|
538
537
|
|
|
539
|
-
const mergedServiceNames = resolveRequiredServices(this.config.featureFlags);
|
|
540
|
-
|
|
541
538
|
function getPlugin(handle: PluginHandle): PluginRecord {
|
|
542
539
|
const plugin = plugins[handle];
|
|
543
540
|
if (!plugin) throw new Error(`Plugin model not found for '${handle}'`);
|
|
@@ -577,7 +574,7 @@ export class BlockModelV3<
|
|
|
577
574
|
// Wrap plugin param lambdas: close over BlockRenderCtx creation
|
|
578
575
|
const wrappedInputs: Record<string, () => unknown> = {};
|
|
579
576
|
for (const [paramKey, paramFn] of Object.entries(inputs)) {
|
|
580
|
-
wrappedInputs[paramKey] = () => paramFn(new BlockRenderCtx(
|
|
577
|
+
wrappedInputs[paramKey] = () => paramFn(new BlockRenderCtx());
|
|
581
578
|
}
|
|
582
579
|
|
|
583
580
|
// Register plugin outputs (in config pack, evaluated by middle layer)
|
|
@@ -587,7 +584,7 @@ export class BlockModelV3<
|
|
|
587
584
|
const key = pluginOutputKey(handle, outputKey);
|
|
588
585
|
pluginOutputs[key] = createAndRegisterRenderLambda({
|
|
589
586
|
handle: key,
|
|
590
|
-
lambda: () => outputFn(new PluginRenderCtx(handle, wrappedInputs
|
|
587
|
+
lambda: () => outputFn(new PluginRenderCtx(handle, wrappedInputs)),
|
|
591
588
|
withStatus: outputFlags[outputKey]?.withStatus,
|
|
592
589
|
});
|
|
593
590
|
}
|
|
@@ -1,10 +1,4 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
AxisSpec,
|
|
3
|
-
PColumnSpec,
|
|
4
|
-
PObjectId,
|
|
5
|
-
SUniversalPColumnId,
|
|
6
|
-
} from "@milaboratories/pl-model-common";
|
|
7
|
-
import { AnchoredIdDeriver } from "@milaboratories/pl-model-common";
|
|
1
|
+
import type { AxisSpec, PColumnSpec, PObjectId } from "@milaboratories/pl-model-common";
|
|
8
2
|
import { SpecDriver } from "@milaboratories/pf-spec-driver";
|
|
9
3
|
|
|
10
4
|
import { afterEach, describe, expect, test } from "vitest";
|
|
@@ -122,25 +116,26 @@ describe("ColumnCollectionBuilder", () => {
|
|
|
122
116
|
});
|
|
123
117
|
});
|
|
124
118
|
|
|
125
|
-
describe("ColumnCollection
|
|
126
|
-
test("
|
|
119
|
+
describe("ColumnCollection lookup by id", () => {
|
|
120
|
+
test("findColumns includes snapshot with existing id", () => {
|
|
127
121
|
const spec = createSpec("col1");
|
|
128
122
|
const snap = createSnapshot("id1", spec);
|
|
129
123
|
const builder = new ColumnCollectionBuilder(createSpecFrameCtx());
|
|
130
124
|
builder.addSource([snap]);
|
|
131
125
|
|
|
132
126
|
const collection = builder.build()!;
|
|
133
|
-
const found = collection.
|
|
127
|
+
const found = collection.findColumns().find((c) => c.id === ("id1" as PObjectId));
|
|
134
128
|
expect(found).toBeDefined();
|
|
135
129
|
expect(found!.spec.name).toBe("col1");
|
|
136
130
|
});
|
|
137
131
|
|
|
138
|
-
test("
|
|
132
|
+
test("findColumns does not include missing id", () => {
|
|
139
133
|
const builder = new ColumnCollectionBuilder(createSpecFrameCtx());
|
|
140
134
|
builder.addSource([createSnapshot("id1", createSpec("col1"))]);
|
|
141
135
|
|
|
142
136
|
const collection = builder.build()!;
|
|
143
|
-
|
|
137
|
+
const found = collection.findColumns().find((c) => c.id === ("missing" as PObjectId));
|
|
138
|
+
expect(found).toBeUndefined();
|
|
144
139
|
});
|
|
145
140
|
});
|
|
146
141
|
|
|
@@ -232,7 +227,7 @@ describe("data status handling", () => {
|
|
|
232
227
|
builder.addSource([snap]);
|
|
233
228
|
const collection = builder.build()!;
|
|
234
229
|
|
|
235
|
-
const found = collection.
|
|
230
|
+
const found = collection.findColumns().find((c) => c.id === ("id1" as PObjectId))!;
|
|
236
231
|
expect(found.dataStatus).toBe("ready");
|
|
237
232
|
expect(found.data).toBeDefined();
|
|
238
233
|
expect(found.data!.get()).toBe(data);
|
|
@@ -245,7 +240,7 @@ describe("data status handling", () => {
|
|
|
245
240
|
builder.addSource([snap]);
|
|
246
241
|
const collection = builder.build()!;
|
|
247
242
|
|
|
248
|
-
const found = collection.
|
|
243
|
+
const found = collection.findColumns().find((c) => c.id === ("id1" as PObjectId))!;
|
|
249
244
|
expect(found.dataStatus).toBe("computing");
|
|
250
245
|
expect(found.data).toBeDefined();
|
|
251
246
|
|
|
@@ -260,7 +255,7 @@ describe("data status handling", () => {
|
|
|
260
255
|
builder.addSource([snap]);
|
|
261
256
|
const collection = builder.build()!;
|
|
262
257
|
|
|
263
|
-
const found = collection.
|
|
258
|
+
const found = collection.findColumns().find((c) => c.id === ("id1" as PObjectId))!;
|
|
264
259
|
expect(found.dataStatus).toBe("absent");
|
|
265
260
|
expect(found.data).toBeUndefined();
|
|
266
261
|
});
|
|
@@ -338,7 +333,7 @@ describe("AnchoredColumnCollection", () => {
|
|
|
338
333
|
);
|
|
339
334
|
});
|
|
340
335
|
|
|
341
|
-
test("
|
|
336
|
+
test("findColumns surfaces column by original PObjectId", () => {
|
|
342
337
|
const spec = createSpec("col1", { axesSpec: [sampleAxis("sample")] });
|
|
343
338
|
const snap = createSnapshot("id1", spec);
|
|
344
339
|
const builder = new ColumnCollectionBuilder(createSpecFrameCtx());
|
|
@@ -346,22 +341,22 @@ describe("AnchoredColumnCollection", () => {
|
|
|
346
341
|
|
|
347
342
|
const collection = builder.build({ anchors: { main: anchorSpec } })!;
|
|
348
343
|
|
|
349
|
-
const
|
|
350
|
-
const
|
|
351
|
-
|
|
352
|
-
const found = collection.getColumn(expectedId);
|
|
344
|
+
const matches = collection.findColumns();
|
|
345
|
+
const found = matches.find((m) => m.column.id === ("id1" as PObjectId));
|
|
353
346
|
expect(found).toBeDefined();
|
|
354
|
-
expect(found!.spec.name).toBe("col1");
|
|
355
|
-
expect(found!.id).toBe(expectedId);
|
|
347
|
+
expect(found!.column.spec.name).toBe("col1");
|
|
356
348
|
});
|
|
357
349
|
|
|
358
|
-
test("
|
|
350
|
+
test("findColumns does not include unknown id", () => {
|
|
359
351
|
const snap = createSnapshot("id1", createSpec("col1", { axesSpec: [sampleAxis("sample")] }));
|
|
360
352
|
const builder = new ColumnCollectionBuilder(createSpecFrameCtx());
|
|
361
353
|
builder.addSource([snap, anchorSnap]);
|
|
362
354
|
|
|
363
355
|
const collection = builder.build({ anchors: { main: anchorSpec } })!;
|
|
364
|
-
|
|
356
|
+
const found = collection
|
|
357
|
+
.findColumns()
|
|
358
|
+
.find((m) => m.column.id === ("not-a-real-id" as PObjectId));
|
|
359
|
+
expect(found).toBeUndefined();
|
|
365
360
|
});
|
|
366
361
|
|
|
367
362
|
test("getAnchors returns resolved anchor map", () => {
|
|
@@ -377,7 +372,7 @@ describe("AnchoredColumnCollection", () => {
|
|
|
377
372
|
expect(anchors.get("main")!.spec.name).toBe("anchor-col");
|
|
378
373
|
});
|
|
379
374
|
|
|
380
|
-
test("findColumns returns ColumnMatch with
|
|
375
|
+
test("findColumns returns ColumnMatch with column id and variants", () => {
|
|
381
376
|
const spec = createSpec("col1", { axesSpec: [sampleAxis("sample")] });
|
|
382
377
|
const snap = createSnapshot("id1", spec);
|
|
383
378
|
const builder = new ColumnCollectionBuilder(createSpecFrameCtx());
|
|
@@ -391,10 +386,61 @@ describe("AnchoredColumnCollection", () => {
|
|
|
391
386
|
expect(matches.length).toBeGreaterThanOrEqual(1);
|
|
392
387
|
const col1Match = matches.find((m) => m.column.spec.name === "col1")!;
|
|
393
388
|
expect(col1Match).toBeDefined();
|
|
394
|
-
expect(col1Match.
|
|
389
|
+
expect(col1Match.column.id).toBe("id1");
|
|
395
390
|
expect(col1Match.variants).toBeDefined();
|
|
396
391
|
});
|
|
397
392
|
|
|
393
|
+
test("variants carry forQueries keyed by anchor PObjectId", () => {
|
|
394
|
+
const spec = createSpec("col1", { axesSpec: [sampleAxis("sample")] });
|
|
395
|
+
const snap = createSnapshot("id1", spec);
|
|
396
|
+
const builder = new ColumnCollectionBuilder(createSpecFrameCtx());
|
|
397
|
+
builder.addSource([snap, anchorSnap]);
|
|
398
|
+
|
|
399
|
+
const collection = builder.build({ anchors: { main: anchorSpec } })!;
|
|
400
|
+
const matches = collection.findColumns();
|
|
401
|
+
const col1Match = matches.find((m) => m.column.spec.name === "col1")!;
|
|
402
|
+
|
|
403
|
+
expect(col1Match.variants.length).toBeGreaterThan(0);
|
|
404
|
+
for (const v of col1Match.variants) {
|
|
405
|
+
expect(v.qualifications.forQueries).toBeDefined();
|
|
406
|
+
expect(v.qualifications.forHit).toBeDefined();
|
|
407
|
+
expect(v.distinctiveQualifications.forQueries).toBeDefined();
|
|
408
|
+
expect(v.distinctiveQualifications.forHit).toBeDefined();
|
|
409
|
+
// forQueries keys are a subset of anchor ids
|
|
410
|
+
for (const key of Object.keys(v.qualifications.forQueries)) {
|
|
411
|
+
expect([anchorSnap.id]).toContain(key);
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
});
|
|
415
|
+
|
|
416
|
+
test("anchors sharing same axes group produce forQueries entries pointing to same array", () => {
|
|
417
|
+
// Two anchors with identical axesSpec share an axes-group bucket in the reverse index.
|
|
418
|
+
const sharedAxes = [sampleAxis("sample"), sampleAxis("gene")];
|
|
419
|
+
const anchorA = createSpec("anchor-a", { axesSpec: sharedAxes });
|
|
420
|
+
const anchorB = createSpec("anchor-b", { axesSpec: sharedAxes });
|
|
421
|
+
const anchorASnap = createSnapshot("anchor-a-id", anchorA);
|
|
422
|
+
const anchorBSnap = createSnapshot("anchor-b-id", anchorB);
|
|
423
|
+
|
|
424
|
+
const colSpec = createSpec("c1", { axesSpec: [sampleAxis("sample")] });
|
|
425
|
+
const colSnap = createSnapshot("c1-id", colSpec);
|
|
426
|
+
|
|
427
|
+
const builder = new ColumnCollectionBuilder(createSpecFrameCtx());
|
|
428
|
+
builder.addSource([colSnap, anchorASnap, anchorBSnap]);
|
|
429
|
+
|
|
430
|
+
const collection = builder.build({ anchors: { a: anchorA, b: anchorB } })!;
|
|
431
|
+
const matches = collection.findColumns();
|
|
432
|
+
const c1 = matches.find((m) => m.column.spec.name === "c1")!;
|
|
433
|
+
expect(c1).toBeDefined();
|
|
434
|
+
|
|
435
|
+
for (const v of c1.variants) {
|
|
436
|
+
const forQueries = v.qualifications.forQueries;
|
|
437
|
+
if (anchorASnap.id in forQueries && anchorBSnap.id in forQueries) {
|
|
438
|
+
// Shared axes group → equal qualifications for both anchor keys.
|
|
439
|
+
expect(forQueries[anchorASnap.id]).toStrictEqual(forQueries[anchorBSnap.id]);
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
});
|
|
443
|
+
|
|
398
444
|
test("findColumns exclude filters out matching columns", () => {
|
|
399
445
|
const snap1 = createSnapshot("id1", createSpec("col1", { axesSpec: [sampleAxis("sample")] }));
|
|
400
446
|
const snap2 = createSnapshot("id2", createSpec("col2", { axesSpec: [sampleAxis("sample")] }));
|
|
@@ -437,9 +483,8 @@ describe("AnchoredColumnCollection", () => {
|
|
|
437
483
|
|
|
438
484
|
const collection = builder.build({ anchors: { main: anchorSpec } })!;
|
|
439
485
|
|
|
440
|
-
const
|
|
441
|
-
|
|
442
|
-
expect(found.
|
|
443
|
-
expect(found.data!.get()).toBeUndefined();
|
|
486
|
+
const found = collection.findColumns().find((m) => m.column.id === ("id1" as PObjectId))!;
|
|
487
|
+
expect(found.column.dataStatus).toBe("computing");
|
|
488
|
+
expect(found.column.data!.get()).toBeUndefined();
|
|
444
489
|
});
|
|
445
490
|
});
|