@platforma-sdk/model 1.79.15 → 1.79.20
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/annotations/converter.cjs +0 -1
- package/dist/annotations/converter.cjs.map +1 -1
- package/dist/annotations/converter.d.ts.map +1 -1
- package/dist/annotations/converter.js.map +1 -1
- package/dist/annotations/index.cjs +2 -1
- package/dist/annotations/index.d.ts +2 -1
- package/dist/annotations/index.js +2 -1
- package/dist/bconfig/index.cjs +5 -2
- package/dist/bconfig/index.d.ts +2 -1
- package/dist/bconfig/index.js +3 -2
- package/dist/bconfig/lambdas.d.ts.map +1 -1
- package/dist/bconfig/normalization.cjs +0 -1
- package/dist/bconfig/normalization.cjs.map +1 -1
- package/dist/bconfig/normalization.d.ts.map +1 -1
- package/dist/bconfig/normalization.js.map +1 -1
- package/dist/bconfig/types.cjs.map +1 -1
- package/dist/bconfig/types.d.ts.map +1 -1
- package/dist/bconfig/types.js.map +1 -1
- package/dist/bconfig/util.d.ts.map +1 -1
- package/dist/bconfig/v3.d.ts.map +1 -1
- package/dist/block_api_v1.d.ts.map +1 -1
- package/dist/block_migrations.cjs +3 -0
- package/dist/block_migrations.cjs.map +1 -1
- package/dist/block_migrations.d.ts +1 -1
- package/dist/block_migrations.d.ts.map +1 -1
- package/dist/block_migrations.js +1 -1
- package/dist/block_migrations.js.map +1 -1
- package/dist/block_model.cjs +1 -1
- package/dist/block_model.cjs.map +1 -1
- package/dist/block_model.d.ts.map +1 -1
- package/dist/block_model.js +1 -0
- package/dist/block_model.js.map +1 -1
- package/dist/block_model_legacy.cjs +1 -1
- package/dist/block_model_legacy.cjs.map +1 -1
- package/dist/block_model_legacy.d.ts.map +1 -1
- package/dist/block_model_legacy.js +1 -0
- package/dist/block_model_legacy.js.map +1 -1
- package/dist/block_state_patch.d.ts.map +1 -1
- package/dist/block_state_util.cjs +2 -0
- package/dist/block_state_util.cjs.map +1 -1
- package/dist/block_state_util.d.ts.map +1 -1
- package/dist/block_state_util.js +2 -0
- package/dist/block_state_util.js.map +1 -1
- package/dist/block_storage.cjs.map +1 -1
- package/dist/block_storage.d.ts +1 -1
- package/dist/block_storage.d.ts.map +1 -1
- package/dist/block_storage.js.map +1 -1
- package/dist/block_storage_callbacks.cjs +1 -1
- package/dist/block_storage_callbacks.cjs.map +1 -1
- package/dist/block_storage_callbacks.js +1 -1
- package/dist/block_storage_callbacks.js.map +1 -1
- package/dist/block_storage_facade.cjs.map +1 -1
- package/dist/block_storage_facade.d.ts.map +1 -1
- package/dist/block_storage_facade.js.map +1 -1
- package/dist/columns/column_collection_builder.cjs +3 -1
- package/dist/columns/column_collection_builder.cjs.map +1 -1
- package/dist/columns/column_collection_builder.d.ts.map +1 -1
- package/dist/columns/column_collection_builder.js +3 -0
- 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.map +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.map +1 -1
- package/dist/columns/column_snapshot.js.map +1 -1
- package/dist/columns/column_snapshot_provider.cjs +3 -1
- package/dist/columns/column_snapshot_provider.cjs.map +1 -1
- package/dist/columns/column_snapshot_provider.d.ts.map +1 -1
- package/dist/columns/column_snapshot_provider.js +3 -0
- package/dist/columns/column_snapshot_provider.js.map +1 -1
- package/dist/columns/ctx_column_sources.cjs +1 -1
- package/dist/columns/ctx_column_sources.cjs.map +1 -1
- package/dist/columns/ctx_column_sources.d.ts.map +1 -1
- package/dist/columns/ctx_column_sources.js +1 -0
- package/dist/columns/ctx_column_sources.js.map +1 -1
- package/dist/columns/expand_by_partition.cjs +0 -1
- package/dist/columns/expand_by_partition.cjs.map +1 -1
- package/dist/columns/expand_by_partition.d.ts.map +1 -1
- package/dist/columns/expand_by_partition.js.map +1 -1
- package/dist/columns/index.cjs +20 -6
- package/dist/columns/index.d.ts +2 -1
- package/dist/columns/index.js +7 -6
- package/dist/components/PFrameForGraphs.cjs +3 -2
- package/dist/components/PFrameForGraphs.cjs.map +1 -1
- package/dist/components/PFrameForGraphs.d.ts +1 -1
- package/dist/components/PFrameForGraphs.d.ts.map +1 -1
- package/dist/components/PFrameForGraphs.js +2 -2
- package/dist/components/PFrameForGraphs.js.map +1 -1
- package/dist/components/PlAnnotations/filter.d.ts.map +1 -1
- package/dist/components/PlAnnotations/filters_ui.cjs.map +1 -1
- package/dist/components/PlAnnotations/filters_ui.d.ts.map +1 -1
- package/dist/components/PlAnnotations/filters_ui.js.map +1 -1
- package/dist/components/PlAnnotations/index.d.ts +2 -1
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV2.cjs +0 -1
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV2.cjs.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV2.js.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV3.cjs +0 -1
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV3.cjs.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV3.js.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV2.cjs +0 -1
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV2.cjs.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV2.d.ts.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV2.js.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.cjs +1 -2
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.cjs.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.d.ts.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.js +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.js.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/discoverColumns.cjs +0 -1
- package/dist/components/PlDataTable/createPlDataTable/discoverColumns.cjs.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/discoverColumns.js.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/index.cjs +2 -1
- package/dist/components/PlDataTable/createPlDataTable/index.cjs.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/index.d.ts +1 -1
- package/dist/components/PlDataTable/createPlDataTable/index.d.ts.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/index.js +2 -2
- package/dist/components/PlDataTable/createPlDataTable/index.js.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/utils.cjs +0 -1
- package/dist/components/PlDataTable/createPlDataTable/utils.cjs.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/utils.d.ts +1 -1
- package/dist/components/PlDataTable/createPlDataTable/utils.d.ts.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/utils.js.map +1 -1
- package/dist/components/PlDataTable/createPlDataTableSheet.cjs.map +1 -1
- package/dist/components/PlDataTable/createPlDataTableSheet.d.ts.map +1 -1
- package/dist/components/PlDataTable/createPlDataTableSheet.js.map +1 -1
- package/dist/components/PlDataTable/index.cjs +19 -7
- package/dist/components/PlDataTable/index.d.ts +2 -1
- package/dist/components/PlDataTable/index.js +8 -7
- package/dist/components/PlDataTable/labels.cjs +0 -1
- package/dist/components/PlDataTable/labels.cjs.map +1 -1
- package/dist/components/PlDataTable/labels.js.map +1 -1
- package/dist/components/PlDataTable/state-migration.cjs +0 -1
- package/dist/components/PlDataTable/state-migration.cjs.map +1 -1
- package/dist/components/PlDataTable/state-migration.d.ts.map +1 -1
- package/dist/components/PlDataTable/state-migration.js.map +1 -1
- package/dist/components/PlDataTable/typesV4.d.ts +1 -1
- package/dist/components/PlDataTable/typesV4.d.ts.map +1 -1
- package/dist/components/PlDataTable/typesV5.d.ts +1 -1
- package/dist/components/PlDataTable/typesV5.d.ts.map +1 -1
- package/dist/components/PlDataTable/typesV6.d.ts +1 -1
- package/dist/components/PlDataTable/typesV6.d.ts.map +1 -1
- package/dist/components/PlDataTable/typesV7.d.ts.map +1 -1
- package/dist/components/PlDatasetSelector/build_dataset_options.cjs +0 -1
- package/dist/components/PlDatasetSelector/build_dataset_options.cjs.map +1 -1
- package/dist/components/PlDatasetSelector/build_dataset_options.js.map +1 -1
- package/dist/components/PlDatasetSelector/dataset_selection.cjs.map +1 -1
- package/dist/components/PlDatasetSelector/dataset_selection.d.ts.map +1 -1
- package/dist/components/PlDatasetSelector/dataset_selection.js.map +1 -1
- package/dist/components/PlDatasetSelector/enrichment_discovery.cjs +0 -1
- package/dist/components/PlDatasetSelector/enrichment_discovery.cjs.map +1 -1
- package/dist/components/PlDatasetSelector/enrichment_discovery.js.map +1 -1
- package/dist/components/PlDatasetSelector/filter_discovery.cjs +1 -1
- package/dist/components/PlDatasetSelector/filter_discovery.cjs.map +1 -1
- package/dist/components/PlDatasetSelector/filter_discovery.d.ts.map +1 -1
- package/dist/components/PlDatasetSelector/filter_discovery.js.map +1 -1
- package/dist/components/PlDatasetSelector/index.cjs +9 -3
- package/dist/components/PlDatasetSelector/index.d.ts +2 -1
- package/dist/components/PlDatasetSelector/index.js +4 -3
- package/dist/components/PlMultiSequenceAlignment.cjs +0 -1
- package/dist/components/PlMultiSequenceAlignment.cjs.map +1 -1
- package/dist/components/PlMultiSequenceAlignment.d.ts.map +1 -1
- package/dist/components/PlMultiSequenceAlignment.js.map +1 -1
- package/dist/components/PlSelectionModel.cjs.map +1 -1
- package/dist/components/PlSelectionModel.d.ts.map +1 -1
- package/dist/components/PlSelectionModel.js.map +1 -1
- package/dist/components/index.cjs +44 -15
- package/dist/components/index.d.ts +2 -1
- package/dist/components/index.js +16 -15
- package/dist/config/actions.cjs.map +1 -1
- package/dist/config/actions.d.ts.map +1 -1
- package/dist/config/actions.js.map +1 -1
- package/dist/config/actions_kinds.d.ts.map +1 -1
- package/dist/config/index.cjs +33 -1
- package/dist/config/index.d.ts +2 -1
- package/dist/config/index.js +2 -1
- package/dist/config/model.d.ts.map +1 -1
- package/dist/config/type_engine.d.ts.map +1 -1
- package/dist/config/type_util.d.ts +1 -1
- package/dist/config/type_util.d.ts.map +1 -1
- package/dist/env_value.cjs.map +1 -1
- package/dist/env_value.d.ts.map +1 -1
- package/dist/env_value.js.map +1 -1
- package/dist/filters/converters/filterToQuery.cjs +0 -1
- package/dist/filters/converters/filterToQuery.cjs.map +1 -1
- package/dist/filters/converters/filterToQuery.d.ts.map +1 -1
- package/dist/filters/converters/filterToQuery.js.map +1 -1
- package/dist/filters/converters/filterUiToExpressionImpl.cjs +0 -1
- package/dist/filters/converters/filterUiToExpressionImpl.cjs.map +1 -1
- package/dist/filters/converters/filterUiToExpressionImpl.d.ts.map +1 -1
- package/dist/filters/converters/filterUiToExpressionImpl.js.map +1 -1
- package/dist/filters/converters/index.cjs +5 -2
- package/dist/filters/converters/index.d.ts +2 -1
- package/dist/filters/converters/index.js +3 -2
- package/dist/filters/distill.cjs +1 -2
- package/dist/filters/distill.cjs.map +1 -1
- package/dist/filters/distill.d.ts.map +1 -1
- package/dist/filters/distill.js +1 -1
- package/dist/filters/distill.js.map +1 -1
- package/dist/filters/index.cjs +7 -3
- package/dist/filters/index.d.ts +2 -1
- package/dist/filters/index.js +4 -3
- package/dist/filters/traverse.cjs.map +1 -1
- package/dist/filters/traverse.js.map +1 -1
- package/dist/filters/types.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/internal.cjs +2 -0
- package/dist/internal.cjs.map +1 -1
- package/dist/internal.js +1 -1
- package/dist/internal.js.map +1 -1
- package/dist/labels/derive_distinct_labels.cjs +2 -3
- package/dist/labels/derive_distinct_labels.cjs.map +1 -1
- package/dist/labels/derive_distinct_labels.d.ts.map +1 -1
- package/dist/labels/derive_distinct_labels.js +2 -2
- package/dist/labels/derive_distinct_labels.js.map +1 -1
- package/dist/labels/derive_distinct_tooltips.cjs +0 -1
- package/dist/labels/derive_distinct_tooltips.cjs.map +1 -1
- package/dist/labels/derive_distinct_tooltips.d.ts.map +1 -1
- package/dist/labels/derive_distinct_tooltips.js.map +1 -1
- package/dist/labels/index.cjs +4 -2
- package/dist/labels/index.d.ts +2 -1
- package/dist/labels/index.js +3 -2
- package/dist/package.cjs +1 -1
- package/dist/package.js +1 -1
- package/dist/pframe.cjs +1 -0
- package/dist/pframe.cjs.map +1 -1
- package/dist/pframe.d.ts.map +1 -1
- package/dist/pframe.js +1 -0
- package/dist/pframe.js.map +1 -1
- package/dist/pframe_utils/axes.cjs +0 -1
- package/dist/pframe_utils/axes.cjs.map +1 -1
- package/dist/pframe_utils/axes.d.ts.map +1 -1
- package/dist/pframe_utils/axes.js.map +1 -1
- package/dist/pframe_utils/columns.cjs +0 -1
- package/dist/pframe_utils/columns.cjs.map +1 -1
- package/dist/pframe_utils/columns.d.ts.map +1 -1
- package/dist/pframe_utils/columns.js.map +1 -1
- package/dist/pframe_utils/index.cjs +3 -2
- package/dist/pframe_utils/index.cjs.map +1 -1
- package/dist/pframe_utils/index.d.ts +1 -1
- package/dist/pframe_utils/index.d.ts.map +1 -1
- package/dist/pframe_utils/index.js +2 -2
- package/dist/pframe_utils/index.js.map +1 -1
- package/dist/platforma.d.ts.map +1 -1
- package/dist/plugin_handle.cjs.map +1 -1
- package/dist/plugin_handle.d.ts.map +1 -1
- package/dist/plugin_handle.js.map +1 -1
- package/dist/plugin_model.cjs +5 -0
- package/dist/plugin_model.cjs.map +1 -1
- package/dist/plugin_model.d.ts +1 -1
- package/dist/plugin_model.d.ts.map +1 -1
- package/dist/plugin_model.js +3 -1
- package/dist/plugin_model.js.map +1 -1
- package/dist/raw_globals.cjs.map +1 -1
- package/dist/raw_globals.d.ts.map +1 -1
- package/dist/raw_globals.js.map +1 -1
- package/dist/ref_util.cjs.map +1 -1
- package/dist/ref_util.d.ts.map +1 -1
- package/dist/ref_util.js.map +1 -1
- package/dist/render/accessor.cjs +2 -1
- package/dist/render/accessor.cjs.map +1 -1
- package/dist/render/accessor.d.ts.map +1 -1
- package/dist/render/accessor.js +2 -0
- package/dist/render/accessor.js.map +1 -1
- package/dist/render/api.cjs +5 -2
- package/dist/render/api.cjs.map +1 -1
- package/dist/render/api.d.ts.map +1 -1
- package/dist/render/api.js +4 -1
- package/dist/render/api.js.map +1 -1
- package/dist/render/future.cjs +2 -0
- package/dist/render/future.cjs.map +1 -1
- package/dist/render/future.d.ts.map +1 -1
- package/dist/render/future.js +2 -0
- package/dist/render/future.js.map +1 -1
- package/dist/render/index.cjs +34 -7
- package/dist/render/index.d.ts +2 -1
- package/dist/render/index.js +8 -7
- package/dist/render/internal.cjs +3 -0
- package/dist/render/internal.cjs.map +1 -1
- package/dist/render/internal.d.ts +1 -1
- package/dist/render/internal.d.ts.map +1 -1
- package/dist/render/internal.js +1 -1
- package/dist/render/internal.js.map +1 -1
- package/dist/render/traversal_ops.d.ts.map +1 -1
- package/dist/render/util/axis_filtering.cjs.map +1 -1
- package/dist/render/util/axis_filtering.d.ts.map +1 -1
- package/dist/render/util/axis_filtering.js.map +1 -1
- package/dist/render/util/column_collection.cjs +2 -1
- package/dist/render/util/column_collection.cjs.map +1 -1
- package/dist/render/util/column_collection.d.ts.map +1 -1
- package/dist/render/util/column_collection.js +1 -0
- package/dist/render/util/column_collection.js.map +1 -1
- package/dist/render/util/index.cjs +23 -4
- package/dist/render/util/index.d.ts +2 -1
- package/dist/render/util/index.js +5 -4
- package/dist/render/util/label.cjs.map +1 -1
- package/dist/render/util/label.d.ts +1 -1
- package/dist/render/util/label.d.ts.map +1 -1
- package/dist/render/util/label.js.map +1 -1
- package/dist/render/util/pcolumn_data.cjs +8 -11
- package/dist/render/util/pcolumn_data.cjs.map +1 -1
- package/dist/render/util/pcolumn_data.d.ts.map +1 -1
- package/dist/render/util/pcolumn_data.js +8 -10
- package/dist/render/util/pcolumn_data.js.map +1 -1
- package/dist/render/util/pframe_upgraders.cjs.map +1 -1
- package/dist/render/util/pframe_upgraders.js.map +1 -1
- package/dist/render/util/split_selectors.d.ts +1 -1
- package/dist/render/util/split_selectors.d.ts.map +1 -1
- package/dist/services/block_services.cjs +0 -1
- package/dist/services/block_services.cjs.map +1 -1
- package/dist/services/block_services.d.ts +1 -3
- package/dist/services/block_services.d.ts.map +1 -1
- package/dist/services/block_services.js.map +1 -1
- package/dist/services/get_services.cjs.map +1 -1
- package/dist/services/get_services.d.ts.map +1 -1
- package/dist/services/get_services.js.map +1 -1
- package/dist/services/index.cjs +8 -3
- package/dist/services/index.d.ts +2 -1
- package/dist/services/index.js +4 -3
- package/dist/services/service_bridge.cjs.map +1 -1
- package/dist/services/service_bridge.d.ts.map +1 -1
- package/dist/services/service_bridge.js.map +1 -1
- package/dist/services/service_resolve.d.ts.map +1 -1
- package/dist/version.cjs.map +1 -1
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js.map +1 -1
- package/package.json +8 -8
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"block_storage_facade.d.ts","names":[],"sources":["../src/block_storage_facade.ts"],"mappings":";;;;;;;;;cA8Da,4BAAA;;;;;;;;;;cAeA,2BAAA;EAAA;;;;;;;;;;;cAyBA,yBAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;UA0BI,kBAAA;EAuDR;;;;;;;EAAA,CA/CN,2BAAA,CAA4B,kBAAA,IAC3B,kBAAA,EAAoB,eAAA,EACpB,OAAA,EAAS,oBAAA,KACN,eAAA;EAmD8D;AAIrE
|
|
1
|
+
{"version":3,"file":"block_storage_facade.d.ts","names":[],"sources":["../src/block_storage_facade.ts"],"mappings":";;;;;;;;;cA8Da,4BAAA;;;;;;;;;;cAeA,2BAAA;EAAA;;;;;;;;;;;cAyBA,yBAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;UA0BI,kBAAA;EAuDR;;;;;;;EAAA,CA/CN,2BAAA,CAA4B,kBAAA,IAC3B,kBAAA,EAAoB,eAAA,EACpB,OAAA,EAAS,oBAAA,KACN,eAAA;EAmD8D;AAIrE;;;;AAAqE;EAJA,CA3ClE,2BAAA,CAA4B,gBAAA,IAC3B,WAAA,EAAa,eAAA,iBACV,eAAA;;;;;;;GAQJ,2BAAA,CAA4B,cAAA,IAAkB,kBAAA,EAAoB,eAAA;IAC7D,KAAA;EAAA;IAEA,KAAA;IACA,cAAA,EAAgB,eAAA;IAChB,IAAA;EAAA;;;;;;;GASL,2BAAA,CAA4B,UAAA,IAC3B,WAAA,EAAa,eAAA;IACR,KAAA;EAAA;IAAoB,KAAA;IAAmB,KAAA;EAAA;;;;;;;GAQ7C,2BAAA,CAA4B,gBAAA,IAC3B,WAAA,EAAa,eAAA;IACR,KAAA;EAAA;IAAoB,KAAA;IAAmB,KAAA;EAAA;;;;;;GAO7C,2BAAA,CAA4B,cAAA,SAAuB,eAAA;AAAA;;iBAItC,uBAAA,CAAwB,SAA6B,EAAlB,kBAAkB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"block_storage_facade.js","names":[],"sources":["../src/block_storage_facade.ts"],"sourcesContent":["/**\n * Block Storage Facade - Contract between bundled blocks and middle layer.\n *\n * ============================================================================\n * VERSIONING\n * ============================================================================\n *\n * Blocks declare their model API version via the `requiresModelAPIVersion` feature flag\n * (see BlockCodeKnownFeatureFlags). This determines how the middle layer manages block state:\n *\n * - Version 1: Legacy BlockModel - state is {args, uiState}, managed directly by middle layer\n * - Version 2: BlockModelV3 - uses blockStorage with VM-based callbacks (this facade)\n *\n * This facade (BlockStorageFacade) is used by blocks with `requiresModelAPIVersion: 2`.\n * The version number matches the model API version for clarity.\n *\n * ============================================================================\n * BACKWARD COMPATIBILITY WARNING\n * ============================================================================\n *\n * This file documents the FACADE between the SDK (bundled into blocks) and the\n * middle layer. Once a block is published, its SDK version is frozen. The middle\n * layer must support ALL previously released callback signatures indefinitely.\n *\n * RULES:\n * 1. NEVER change the signature of existing callbacks\n * 2. NEVER remove existing callbacks\n * 3. New callbacks CAN be added (old blocks won't register them, middle layer\n * should handle missing callbacks gracefully)\n * 4. Callback return types can be EXTENDED (add optional fields) but not changed\n * 5. Callback parameter types should remain compatible (middle layer may need\n * to handle both old and new formats)\n *\n * The facade consists of callbacks registered via `tryRegisterCallback()` with\n * the `__pl_` prefix. These are registered by the SDK when a block loads and\n * called by the middle layer to perform operations.\n *\n * ============================================================================\n * WHAT CAN BE CHANGED FREELY\n * ============================================================================\n *\n * - Middle layer code (lib/node/pl-middle-layer)\n * - SDK internal implementation (as long as callback contracts are preserved)\n * - SDK exports used ONLY by middle layer (not by blocks themselves)\n * - New SDK features that don't affect existing callbacks\n *\n * @module block_storage_facade\n */\n\nimport type { MutateStoragePayload } from \"./block_storage\";\nimport type { ConfigRenderLambda } from \"./bconfig\";\nimport { createRenderLambda, tryRegisterCallback } from \"./internal\";\nimport type { StringifiedJson } from \"@milaboratories/pl-model-common\";\n\n// =============================================================================\n// Facade Version\n// =============================================================================\n\n/**\n * The current facade version. This value is used for `requiresModelAPIVersion`\n * feature flag in BlockModelV3.\n */\nexport const BLOCK_STORAGE_FACADE_VERSION = 2;\n\n// =============================================================================\n// Facade Callback Names\n// =============================================================================\n\n/**\n * All facade callback names as constants.\n * These are the source of truth - the interface is derived from these.\n *\n * IMPORTANT: When adding a new callback:\n * 1. Add the constant here\n * 2. Add the callback signature to FacadeCallbackTypes below\n * 3. The BlockStorageFacade type will automatically include it\n */\nexport const BlockStorageFacadeCallbacks = {\n StorageApplyUpdate: \"__pl_storage_applyUpdate\",\n StorageDebugView: \"__pl_storage_debugView\",\n StorageMigrate: \"__pl_storage_migrate\",\n ArgsDerive: \"__pl_args_derive\",\n PrerunArgsDerive: \"__pl_prerunArgs_derive\",\n StorageInitial: \"__pl_storage_initial\",\n} as const;\n\n/**\n * Creates a map of lambda handles from a callbacks constant object.\n * Keys are the callback string values (e.g., '__pl_storage_applyUpdate').\n */\nfunction createFacadeHandles<T extends Record<string, string>>(\n callbacks: T,\n): { [K in T[keyof T]]: ConfigRenderLambda } {\n return Object.fromEntries(\n Object.values(callbacks).map((handle) => [handle, createRenderLambda({ handle })]),\n ) as { [K in T[keyof T]]: ConfigRenderLambda };\n}\n\n/**\n * Lambda handles for facade callbacks.\n * Used by the middle layer to invoke callbacks via executeSingleLambda().\n */\nexport const BlockStorageFacadeHandles = createFacadeHandles(BlockStorageFacadeCallbacks);\n\n// =============================================================================\n// Facade Interface (source of truth for callback signatures)\n// =============================================================================\n\n/**\n * The complete facade interface between bundled blocks (SDK) and middle layer.\n *\n * This interface defines ALL callbacks that a block registers. The middle layer\n * calls these callbacks to perform storage operations.\n *\n * ALL types are inlined to simplify versioning - when a callback changes,\n * the entire signature is visible in one place.\n *\n * BACKWARD COMPATIBILITY:\n * - This interface can only be EXTENDED, never shrunk\n * - Existing callback signatures MUST NOT change\n * - Middle layer should use Partial<BlockStorageFacade> when dealing with\n * blocks of unknown version (older blocks may not have all callbacks)\n *\n * Each callback is documented with:\n * - Purpose and when it's called\n * - Parameter descriptions\n * - Return value description\n */\nexport interface BlockStorageFacade {\n /**\n * Apply state update to storage.\n * Called when UI updates block state (setState) or plugin data.\n * @param currentStorageJson - Current storage as JSON string\n * @param payload - Update payload with operation type and value\n * @returns Updated storage as JSON string\n */\n [BlockStorageFacadeCallbacks.StorageApplyUpdate]: (\n currentStorageJson: StringifiedJson,\n payload: MutateStoragePayload,\n ) => StringifiedJson;\n\n /**\n * Get debug view of storage.\n * Called by developer tools to inspect storage state.\n * @param storageJson - Storage as JSON string (or undefined for new blocks)\n * @returns JSON string containing StorageDebugView\n */\n [BlockStorageFacadeCallbacks.StorageDebugView]: (\n storageJson: StringifiedJson | undefined,\n ) => StringifiedJson;\n\n /**\n * Run storage migration.\n * Called when block loads to migrate data to latest version.\n * @param currentStorageJson - Current storage as JSON string (or undefined for new blocks)\n * @returns Migration result - either error or success with new storage\n */\n [BlockStorageFacadeCallbacks.StorageMigrate]: (currentStorageJson: StringifiedJson | undefined) =>\n | { error: string }\n | {\n error?: undefined;\n newStorageJson: StringifiedJson;\n info: string;\n };\n\n /**\n * Derive args from storage.\n * Called to get block configuration args from storage.\n * @param storageJson - Storage as JSON string\n * @returns Args derivation result - either error or derived value\n */\n [BlockStorageFacadeCallbacks.ArgsDerive]: (\n storageJson: StringifiedJson,\n ) => { error: string } | { error?: undefined; value: unknown };\n\n /**\n * Derive prerunArgs from storage.\n * Called to get prerun args; falls back to args callback if not registered.\n * @param storageJson - Storage as JSON string\n * @returns Args derivation result - either error or derived value\n */\n [BlockStorageFacadeCallbacks.PrerunArgsDerive]: (\n storageJson: StringifiedJson,\n ) => { error: string } | { error?: undefined; value: unknown };\n\n /**\n * Get initial storage JSON for new blocks.\n * Called when creating a new block to get complete initial storage.\n * @returns Initial storage as JSON string\n */\n [BlockStorageFacadeCallbacks.StorageInitial]: () => StringifiedJson;\n}\n\n/** Register all facade callbacks at once. Ensures all required callbacks are provided. */\nexport function registerFacadeCallbacks(callbacks: BlockStorageFacade): void {\n for (const key of Object.values(BlockStorageFacadeCallbacks)) {\n tryRegisterCallback(key, callbacks[key] as (...args: any[]) => any);\n }\n}\n"],"mappings":";;;;;;AA8DA,MAAa,+BAA+B;;;;;;;;;;AAe5C,MAAa,8BAA8B;CACzC,oBAAoB;CACpB,kBAAkB;CAClB,gBAAgB;CAChB,YAAY;CACZ,kBAAkB;CAClB,gBAAgB;
|
|
1
|
+
{"version":3,"file":"block_storage_facade.js","names":[],"sources":["../src/block_storage_facade.ts"],"sourcesContent":["/**\n * Block Storage Facade - Contract between bundled blocks and middle layer.\n *\n * ============================================================================\n * VERSIONING\n * ============================================================================\n *\n * Blocks declare their model API version via the `requiresModelAPIVersion` feature flag\n * (see BlockCodeKnownFeatureFlags). This determines how the middle layer manages block state:\n *\n * - Version 1: Legacy BlockModel - state is {args, uiState}, managed directly by middle layer\n * - Version 2: BlockModelV3 - uses blockStorage with VM-based callbacks (this facade)\n *\n * This facade (BlockStorageFacade) is used by blocks with `requiresModelAPIVersion: 2`.\n * The version number matches the model API version for clarity.\n *\n * ============================================================================\n * BACKWARD COMPATIBILITY WARNING\n * ============================================================================\n *\n * This file documents the FACADE between the SDK (bundled into blocks) and the\n * middle layer. Once a block is published, its SDK version is frozen. The middle\n * layer must support ALL previously released callback signatures indefinitely.\n *\n * RULES:\n * 1. NEVER change the signature of existing callbacks\n * 2. NEVER remove existing callbacks\n * 3. New callbacks CAN be added (old blocks won't register them, middle layer\n * should handle missing callbacks gracefully)\n * 4. Callback return types can be EXTENDED (add optional fields) but not changed\n * 5. Callback parameter types should remain compatible (middle layer may need\n * to handle both old and new formats)\n *\n * The facade consists of callbacks registered via `tryRegisterCallback()` with\n * the `__pl_` prefix. These are registered by the SDK when a block loads and\n * called by the middle layer to perform operations.\n *\n * ============================================================================\n * WHAT CAN BE CHANGED FREELY\n * ============================================================================\n *\n * - Middle layer code (lib/node/pl-middle-layer)\n * - SDK internal implementation (as long as callback contracts are preserved)\n * - SDK exports used ONLY by middle layer (not by blocks themselves)\n * - New SDK features that don't affect existing callbacks\n *\n * @module block_storage_facade\n */\n\nimport type { MutateStoragePayload } from \"./block_storage\";\nimport type { ConfigRenderLambda } from \"./bconfig\";\nimport { createRenderLambda, tryRegisterCallback } from \"./internal\";\nimport type { StringifiedJson } from \"@milaboratories/pl-model-common\";\n\n// =============================================================================\n// Facade Version\n// =============================================================================\n\n/**\n * The current facade version. This value is used for `requiresModelAPIVersion`\n * feature flag in BlockModelV3.\n */\nexport const BLOCK_STORAGE_FACADE_VERSION = 2;\n\n// =============================================================================\n// Facade Callback Names\n// =============================================================================\n\n/**\n * All facade callback names as constants.\n * These are the source of truth - the interface is derived from these.\n *\n * IMPORTANT: When adding a new callback:\n * 1. Add the constant here\n * 2. Add the callback signature to FacadeCallbackTypes below\n * 3. The BlockStorageFacade type will automatically include it\n */\nexport const BlockStorageFacadeCallbacks = {\n StorageApplyUpdate: \"__pl_storage_applyUpdate\",\n StorageDebugView: \"__pl_storage_debugView\",\n StorageMigrate: \"__pl_storage_migrate\",\n ArgsDerive: \"__pl_args_derive\",\n PrerunArgsDerive: \"__pl_prerunArgs_derive\",\n StorageInitial: \"__pl_storage_initial\",\n} as const;\n\n/**\n * Creates a map of lambda handles from a callbacks constant object.\n * Keys are the callback string values (e.g., '__pl_storage_applyUpdate').\n */\nfunction createFacadeHandles<T extends Record<string, string>>(\n callbacks: T,\n): { [K in T[keyof T]]: ConfigRenderLambda } {\n return Object.fromEntries(\n Object.values(callbacks).map((handle) => [handle, createRenderLambda({ handle })]),\n ) as { [K in T[keyof T]]: ConfigRenderLambda };\n}\n\n/**\n * Lambda handles for facade callbacks.\n * Used by the middle layer to invoke callbacks via executeSingleLambda().\n */\nexport const BlockStorageFacadeHandles = createFacadeHandles(BlockStorageFacadeCallbacks);\n\n// =============================================================================\n// Facade Interface (source of truth for callback signatures)\n// =============================================================================\n\n/**\n * The complete facade interface between bundled blocks (SDK) and middle layer.\n *\n * This interface defines ALL callbacks that a block registers. The middle layer\n * calls these callbacks to perform storage operations.\n *\n * ALL types are inlined to simplify versioning - when a callback changes,\n * the entire signature is visible in one place.\n *\n * BACKWARD COMPATIBILITY:\n * - This interface can only be EXTENDED, never shrunk\n * - Existing callback signatures MUST NOT change\n * - Middle layer should use Partial<BlockStorageFacade> when dealing with\n * blocks of unknown version (older blocks may not have all callbacks)\n *\n * Each callback is documented with:\n * - Purpose and when it's called\n * - Parameter descriptions\n * - Return value description\n */\nexport interface BlockStorageFacade {\n /**\n * Apply state update to storage.\n * Called when UI updates block state (setState) or plugin data.\n * @param currentStorageJson - Current storage as JSON string\n * @param payload - Update payload with operation type and value\n * @returns Updated storage as JSON string\n */\n [BlockStorageFacadeCallbacks.StorageApplyUpdate]: (\n currentStorageJson: StringifiedJson,\n payload: MutateStoragePayload,\n ) => StringifiedJson;\n\n /**\n * Get debug view of storage.\n * Called by developer tools to inspect storage state.\n * @param storageJson - Storage as JSON string (or undefined for new blocks)\n * @returns JSON string containing StorageDebugView\n */\n [BlockStorageFacadeCallbacks.StorageDebugView]: (\n storageJson: StringifiedJson | undefined,\n ) => StringifiedJson;\n\n /**\n * Run storage migration.\n * Called when block loads to migrate data to latest version.\n * @param currentStorageJson - Current storage as JSON string (or undefined for new blocks)\n * @returns Migration result - either error or success with new storage\n */\n [BlockStorageFacadeCallbacks.StorageMigrate]: (currentStorageJson: StringifiedJson | undefined) =>\n | { error: string }\n | {\n error?: undefined;\n newStorageJson: StringifiedJson;\n info: string;\n };\n\n /**\n * Derive args from storage.\n * Called to get block configuration args from storage.\n * @param storageJson - Storage as JSON string\n * @returns Args derivation result - either error or derived value\n */\n [BlockStorageFacadeCallbacks.ArgsDerive]: (\n storageJson: StringifiedJson,\n ) => { error: string } | { error?: undefined; value: unknown };\n\n /**\n * Derive prerunArgs from storage.\n * Called to get prerun args; falls back to args callback if not registered.\n * @param storageJson - Storage as JSON string\n * @returns Args derivation result - either error or derived value\n */\n [BlockStorageFacadeCallbacks.PrerunArgsDerive]: (\n storageJson: StringifiedJson,\n ) => { error: string } | { error?: undefined; value: unknown };\n\n /**\n * Get initial storage JSON for new blocks.\n * Called when creating a new block to get complete initial storage.\n * @returns Initial storage as JSON string\n */\n [BlockStorageFacadeCallbacks.StorageInitial]: () => StringifiedJson;\n}\n\n/** Register all facade callbacks at once. Ensures all required callbacks are provided. */\nexport function registerFacadeCallbacks(callbacks: BlockStorageFacade): void {\n for (const key of Object.values(BlockStorageFacadeCallbacks)) {\n tryRegisterCallback(key, callbacks[key] as (...args: any[]) => any);\n }\n}\n"],"mappings":";;;;;;AA8DA,MAAa,+BAA+B;;;;;;;;;;AAe5C,MAAa,8BAA8B;CACzC,oBAAoB;CACpB,kBAAkB;CAClB,gBAAgB;CAChB,YAAY;CACZ,kBAAkB;CAClB,gBAAgB;AAClB;;;;;AAMA,SAAS,oBACP,WAC2C;CAC3C,OAAO,OAAO,YACZ,OAAO,OAAO,SAAS,CAAC,CAAC,KAAK,WAAW,CAAC,QAAQ,mBAAmB,EAAE,OAAO,CAAC,CAAC,CAAC,CACnF;AACF;;;;;AAMA,MAAa,4BAA4B,oBAAoB,2BAA2B;;AA4FxF,SAAgB,wBAAwB,WAAqC;CAC3E,KAAK,MAAM,OAAO,OAAO,OAAO,2BAA2B,GACzD,oBAAoB,KAAK,UAAU,IAA+B;AAEtE"}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
require("../_virtual/_rolldown/runtime.cjs");
|
|
2
1
|
const require_accessor = require("../render/accessor.cjs");
|
|
3
2
|
const require_get_services = require("../services/get_services.cjs");
|
|
4
3
|
require("../services/index.cjs");
|
|
@@ -15,6 +14,7 @@ let _milaboratories_helpers = require("@milaboratories/helpers");
|
|
|
15
14
|
* computable framework where each output tracks its own dependencies.
|
|
16
15
|
*/
|
|
17
16
|
var ColumnCollectionBuilder = class {
|
|
17
|
+
specDriver;
|
|
18
18
|
providers = [];
|
|
19
19
|
constructor(specDriver = require_get_services.getService("pframeSpec")) {
|
|
20
20
|
this.specDriver = specDriver;
|
|
@@ -47,6 +47,7 @@ var ColumnCollectionBuilder = class {
|
|
|
47
47
|
}
|
|
48
48
|
};
|
|
49
49
|
var ColumnCollectionImpl = class {
|
|
50
|
+
specDriver;
|
|
50
51
|
columns;
|
|
51
52
|
specFrameEntry;
|
|
52
53
|
constructor(specDriver, options) {
|
|
@@ -73,6 +74,7 @@ var ColumnCollectionImpl = class {
|
|
|
73
74
|
}
|
|
74
75
|
};
|
|
75
76
|
var AnchoredColumnCollectionImpl = class {
|
|
77
|
+
specDriver;
|
|
76
78
|
anchorsMap;
|
|
77
79
|
columnsMap;
|
|
78
80
|
specFrameEntry;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"column_collection_builder.cjs","names":["getService","TreeNodeAccessor","ArrayColumnProvider","toColumnSnapshotProvider","convertColumnSelectorToMultiColumnSelector"],"sources":["../../src/columns/column_collection_builder.ts"],"sourcesContent":["import type {\n AxisQualification,\n DiscoverColumnsConstraints,\n DiscoverColumnsRequest,\n DiscoverColumnsResponse,\n MultiColumnSelector,\n NativePObjectId,\n PColumnSpec,\n PObjectId,\n} from \"@milaboratories/pl-model-common\";\nimport { deriveNativeId, isPColumnSpec } from \"@milaboratories/pl-model-common\";\nimport type { ColumnSelector, RelaxedColumnSelector } from \"./column_selector\";\nimport { convertColumnSelectorToMultiColumnSelector } from \"./column_selector\";\nimport { TreeNodeAccessor } from \"../render/accessor\";\nimport type { ColumnSnapshot } from \"./column_snapshot\";\nimport type { ColumnSnapshotProvider, ColumnSource } from \"./column_snapshot_provider\";\nimport { ArrayColumnProvider, toColumnSnapshotProvider } from \"./column_snapshot_provider\";\n\nimport type { PFrameSpecDriver, PoolEntry, SpecFrameHandle } from \"@milaboratories/pl-model-common\";\nimport { throwError } from \"@milaboratories/helpers\";\nimport { getService } from \"../services\";\n\n/** Options for plain collection findColumns. */\nexport interface FindColumnsOptions {\n /** Include columns matching these selectors. If omitted, includes all columns. */\n include?: ColumnSelector;\n /** Exclude columns matching these selectors. */\n exclude?: ColumnSelector;\n}\n\n/** Plain collection — no axis context, selector-based filtering only. */\nexport interface ColumnCollection extends Disposable {\n /** Release the underlying spec frame WASM resource. */\n dispose(): void;\n\n /** Find columns matching selectors. Returns flat list of snapshots.\n * No axis compatibility matching, no linker traversal.\n * Never returns undefined — the \"not ready\" state was absorbed by the builder. */\n findColumns(options?: FindColumnsOptions): ColumnSnapshot<PObjectId>[];\n}\n\n/** Axis-aware column collection with anchored identity derivation. */\nexport interface AnchoredColumnCollection extends Disposable {\n /** Release the underlying spec frame WASM resource. */\n dispose(): void;\n\n /** List of anchors used for discovery, with their resolved specs. */\n getAnchors(): Map<string, ColumnSnapshot<PObjectId>>;\n\n /** Axis-aware column discovery. */\n findColumns(options?: AnchoredFindColumnsOptions): ColumnMatch[];\n\n /** Variant discovery with detailed mapping info for each hit. */\n findColumnVariants(options?: AnchoredFindColumnsOptions): ColumnVariant[];\n}\n\n/** Controls axis matching behavior for anchored discovery. */\nexport type MatchingMode = \"enrichment\" | \"related\" | \"exact\";\n\n/** Options for anchored collection findColumns. */\nexport interface AnchoredFindColumnsOptions extends FindColumnsOptions {\n /** Controls axis matching behavior. Default: 'enrichment'. */\n mode?: MatchingMode;\n /** Maximum linker hops for cross-domain discovery (0 = direct only, default: 4). */\n maxHops?: number;\n}\n\n/** Result of anchored discovery — column snapshot + routing info. */\nexport interface ColumnMatch {\n /** Column snapshot with anchored SUniversalPColumnId. */\n readonly column: ColumnSnapshot<PObjectId>;\n /** Match variants — different ways (paths/qualifications) to reach this column. */\n readonly variants: MatchVariant[];\n}\n\nexport interface ColumnVariant<Id extends PObjectId = PObjectId> {\n /** Column snapshot with anchored SUniversalPColumnId. */\n readonly column: ColumnSnapshot<Id>;\n /** Linker steps traversed to reach this hit; empty for direct matches. */\n readonly path?: { linker: ColumnSnapshot<PObjectId> }[];\n /** Full qualifications needed for integration. */\n readonly qualifications?: MatchQualifications;\n}\n\n/** A single mapping variant describing how a hit column can be integrated. */\nexport interface MatchVariant {\n /** Full qualifications needed for integration. */\n readonly qualifications: MatchQualifications;\n /** Linker steps traversed to reach this hit; empty for direct matches. */\n readonly path: { linker: ColumnSnapshot<PObjectId> }[];\n}\n\n/** Qualifications needed for both already-integrated anchor columns and the hit column. */\nexport interface MatchQualifications {\n /** Qualifications for already-integrated anchor columns */\n readonly forQueries?: Record<PObjectId, AxisQualification[]>;\n /** Qualifications for the hit column. */\n readonly forHit?: AxisQualification[];\n}\n\nexport interface BuildOptions {\n allowPartialColumnList?: true;\n}\n\nexport type AnchorEntry = PObjectId | PColumnSpec | RelaxedColumnSelector;\n\nexport interface AnchoredBuildOptions extends BuildOptions {\n anchors: Record<string, AnchorEntry>;\n}\n\n/**\n * Mutable builder that accumulates column sources, then produces\n * a ColumnCollection (plain) or AnchoredColumnCollection (with anchors).\n *\n * Each output lambda creates its own builder — a constraint of the\n * computable framework where each output tracks its own dependencies.\n */\nexport class ColumnCollectionBuilder {\n private readonly providers: ColumnSnapshotProvider[] = [];\n\n constructor(private readonly specDriver: PFrameSpecDriver = getService(\"pframeSpec\")) {}\n\n /**\n * Register a column source. Sources added first take precedence for dedup.\n * Does NOT accept undefined — if a source isn't available yet,\n * the caller should return undefined from the output lambda.\n */\n addSource(source: ColumnSource | TreeNodeAccessor): this {\n if (source instanceof TreeNodeAccessor) {\n const columns = source.getPColumns();\n if (columns) this.providers.push(new ArrayColumnProvider(columns));\n } else {\n this.providers.push(toColumnSnapshotProvider(source));\n }\n return this;\n }\n\n addSources(sources: (ColumnSource | TreeNodeAccessor)[]): this {\n for (const source of sources) {\n this.addSource(source);\n }\n return this;\n }\n\n /** Plain collection — selector-based filtering, PObjectId namespace. */\n build(): undefined | ColumnCollection;\n build(options: {\n allowPartialColumnList: true;\n }): ColumnCollection & { readonly columnListComplete: boolean };\n /** Anchored collection — axis-aware discovery, SUniversalPColumnId namespace. */\n build(\n options: AnchoredBuildOptions & { allowPartialColumnList: true },\n ): AnchoredColumnCollection & { readonly columnListComplete: boolean };\n build(options: AnchoredBuildOptions): undefined | AnchoredColumnCollection;\n build(\n options?: BuildOptions | AnchoredBuildOptions,\n ):\n | undefined\n | ColumnCollection\n | AnchoredColumnCollection\n | (ColumnCollection & { readonly columnListComplete: boolean })\n | (AnchoredColumnCollection & { readonly columnListComplete: boolean }) {\n const allowPartial = options?.allowPartialColumnList === true;\n\n // Check column list completeness\n const allComplete = this.providers.every((p) => p.isColumnListComplete());\n if (!allComplete && !allowPartial) return undefined;\n\n // Collect all columns, dedup by native ID (first source wins)\n const columns = collectColumns(this.providers);\n const hasAnchors = options !== undefined && \"anchors\" in options;\n\n if (hasAnchors) {\n return new AnchoredColumnCollectionImpl(this.specDriver, {\n anchors: options.anchors,\n columns,\n });\n } else {\n return new ColumnCollectionImpl(this.specDriver, {\n columns,\n });\n }\n }\n}\n\ninterface ColumnCollectionImplOptions {\n readonly columns: ColumnSnapshot<PObjectId>[];\n}\n\nclass ColumnCollectionImpl implements ColumnCollection, Disposable {\n private readonly columns: Map<PObjectId, ColumnSnapshot<PObjectId>>;\n private readonly specFrameEntry: PoolEntry<SpecFrameHandle>;\n\n constructor(\n private readonly specDriver: PFrameSpecDriver,\n options: ColumnCollectionImplOptions,\n ) {\n this.columns = new Map(options.columns.map((col) => [col.id, col]));\n this.specFrameEntry = this.specDriver.createSpecFrame(\n Object.fromEntries(options.columns.map((col) => [col.id, col.spec])),\n );\n }\n\n dispose(): void {\n this.specFrameEntry.unref();\n }\n\n [Symbol.dispose](): void {\n this.dispose();\n }\n\n findColumns(options?: FindColumnsOptions): ColumnSnapshot<PObjectId>[] {\n const includeColumns = options?.include ? toMultiColumnSelectors(options.include) : undefined;\n const excludeColumns = options?.exclude ? toMultiColumnSelectors(options.exclude) : undefined;\n\n const response = this.specDriver.discoverColumns(this.specFrameEntry.key, {\n includeColumns,\n excludeColumns,\n axes: [],\n maxHops: 0,\n constraints: matchingModeToConstraints(\"enrichment\"),\n });\n\n // Map hits back to snapshots\n const results = response.hits\n .map((hit) => this.columns.get(hit.hit.columnId as PObjectId))\n .filter((col): col is ColumnSnapshot<PObjectId> => col !== undefined);\n\n return results;\n }\n}\n\ninterface AnchoredColumnCollectionImplOptions extends ColumnCollectionImplOptions {\n readonly anchors: Record<string, AnchorEntry>;\n}\n\nclass AnchoredColumnCollectionImpl implements AnchoredColumnCollection, Disposable {\n private readonly anchorsMap: Map<string, ColumnSnapshot<PObjectId>>;\n private readonly columnsMap: Map<PObjectId, ColumnSnapshot<PObjectId>>;\n private readonly specFrameEntry: PoolEntry<SpecFrameHandle>;\n\n constructor(\n private readonly specDriver: PFrameSpecDriver,\n options: AnchoredColumnCollectionImplOptions,\n ) {\n // Create spec frame from all collected columns\n this.specFrameEntry = this.specDriver.createSpecFrame(\n Object.fromEntries(options.columns.map((col) => [col.id, col.spec])),\n );\n this.columnsMap = new Map(options.columns.map((col) => [col.id, col]));\n this.anchorsMap = resolveAnchorMap(\n options.anchors,\n options.columns,\n this.specDriver.discoverColumns.bind(this.specDriver, this.specFrameEntry.key),\n );\n }\n\n dispose(): void {\n this.specFrameEntry.unref();\n }\n\n [Symbol.dispose](): void {\n this.dispose();\n }\n\n getAnchors(): Map<string, ColumnSnapshot<PObjectId>> {\n return this.anchorsMap;\n }\n\n findColumns(options?: AnchoredFindColumnsOptions): ColumnMatch[] {\n const mode = options?.mode ?? \"enrichment\";\n const constraints = matchingModeToConstraints(mode);\n const includeColumns = options?.include ? toMultiColumnSelectors(options.include) : undefined;\n const excludeColumns = options?.exclude ? toMultiColumnSelectors(options.exclude) : undefined;\n const anchors = Array.from(this.anchorsMap.values());\n const response = this.specDriver.discoverColumns(this.specFrameEntry.key, {\n includeColumns,\n excludeColumns,\n constraints,\n maxHops: options?.maxHops ?? 4,\n axes: anchors.map((anchor) => ({\n axesSpec: anchor.spec.axesSpec,\n qualifications: [],\n })),\n });\n\n const byColumn = response.hits.reduce<Map<PObjectId, ColumnMatch>>((acc, hit) => {\n const origId = hit.hit.columnId as PObjectId;\n const col =\n this.columnsMap.get(origId) ??\n throwError(`Column with id ${origId} not found in collection`);\n\n const path = hit.path.map((step) => {\n if (step.type !== \"linker\") {\n throw new Error(`Unexpected discover-columns step type: ${step.type}`);\n }\n\n return {\n linker:\n this.columnsMap.get(step.linker.columnId) ??\n throwError(`Linker column with id ${step.linker.columnId} not found in collection`),\n };\n });\n const variants: MatchVariant[] = hit.mappingVariants.map((v) => ({\n path,\n qualifications: remapFromIdxToId(v.qualifications, anchors),\n }));\n const existing = acc.get(origId);\n return acc.set(\n origId,\n existing === undefined\n ? { column: col, variants }\n : { ...existing, variants: [...existing.variants, ...variants] },\n );\n }, new Map());\n\n return Array.from(byColumn.values());\n }\n\n findColumnVariants(options?: AnchoredFindColumnsOptions): ColumnVariant[] {\n const matches = this.findColumns(options);\n return matches.flatMap((match) =>\n match.variants.map((variant) => ({\n column: match.column,\n path: variant.path,\n qualifications: variant.qualifications,\n })),\n );\n }\n}\n\n/**\n * Collect all columns from all providers, dedup by NativePObjectId.\n * First source wins.\n */\nfunction collectColumns(providers: ColumnSnapshotProvider[]): ColumnSnapshot<PObjectId>[] {\n const seen = new Set<NativePObjectId>();\n const result: ColumnSnapshot<PObjectId>[] = [];\n\n for (const provider of providers) {\n const columns = provider.getAllColumns();\n for (const col of columns) {\n const nativeId = deriveNativeId(col.spec);\n if (seen.has(nativeId)) continue;\n seen.add(nativeId);\n result.push(col);\n }\n }\n\n return result;\n}\n\n/** Normalize ColumnSelector (relaxed, single or array) to MultiColumnSelector[]. */\nfunction toMultiColumnSelectors(input: ColumnSelector): MultiColumnSelector[] {\n return convertColumnSelectorToMultiColumnSelector(input);\n}\n\n/**\n * Resolve each anchor entry to a ColumnSnapshot from the collected columns.\n * - PObjectId (string): looked up by id in the collected columns\n * - PColumnSpec: matched by deriveNativeId against collected columns\n * - RelaxedColumnSelector: resolved via discoverColumns in \"exact\" mode;\n * must match exactly one column\n * Throws on unresolved, ambiguous, or duplicated matches. Requires at least one\n * anchor to resolve.\n */\nfunction resolveAnchorMap(\n anchors: Record<string, AnchorEntry>,\n columns: ColumnSnapshot<PObjectId>[],\n discoverColumns: (request: DiscoverColumnsRequest) => DiscoverColumnsResponse,\n): Map<string, ColumnSnapshot<PObjectId>> {\n const result = new Map<string, ColumnSnapshot<PObjectId>>();\n const resovedIds = new Set<PObjectId>();\n const getDuplicateError = (key: string) =>\n `Anchor \"${key}\": selector matched a column that was already matched by another anchor; please refine the selector to match a different column`;\n\n // O(1) lookup maps built lazily — only when an anchor of the matching kind is\n // encountered. Avoids O(anchors × columns) `deriveNativeId` calls, which were\n // tripping the QuickJS interrupt deadline on tables with many anchors.\n let byId: Map<PObjectId, ColumnSnapshot<PObjectId>> | undefined;\n let byNativeId: Map<NativePObjectId, ColumnSnapshot<PObjectId>> | undefined;\n\n for (const [name, anchor] of Object.entries(anchors)) {\n if (typeof anchor === \"string\") {\n if (byId === undefined) byId = new Map(columns.map((col) => [col.id, col]));\n const found =\n byId.get(anchor) ??\n throwError(`Anchor \"${name}\": column with id \"${anchor}\" not found in sources`);\n if (resovedIds.has(found.id)) {\n throwError(getDuplicateError(name));\n }\n result.set(name, found);\n resovedIds.add(found.id);\n } else if (\"kind\" in anchor) {\n if (!isPColumnSpec(anchor)) throwError(`Anchor \"${name}\": invalid PColumnSpec`);\n if (byNativeId === undefined) {\n byNativeId = new Map(columns.map((col) => [deriveNativeId(col.spec), col]));\n }\n const found =\n byNativeId.get(deriveNativeId(anchor)) ??\n throwError(`Anchor \"${name}\": no column matching spec found in sources`);\n if (resovedIds.has(found.id)) {\n throwError(getDuplicateError(name));\n }\n result.set(name, found);\n resovedIds.add(found.id);\n } else {\n const matched = discoverColumns({\n includeColumns: toMultiColumnSelectors(anchor),\n excludeColumns: undefined,\n axes: [],\n maxHops: 0,\n constraints: matchingModeToConstraints(\"related\"),\n });\n\n if (matched.hits.length === 0) {\n throwError(`Anchor \"${name}\": no columns matched selector`);\n }\n if (matched.hits.length > 1) {\n throwError(\n `Anchor \"${name}\": selector is ambiguous and matched multiple columns; please refine the selector to match exactly one column`,\n );\n }\n if (resovedIds.has(matched.hits[0].hit.columnId as PObjectId)) {\n throwError(getDuplicateError(name));\n }\n\n const id = matched.hits[0].hit.columnId as PObjectId;\n const snap =\n columns.find((col) => col.id === id) ??\n throwError(`Anchor \"${name}\": matched column with id \"${id}\" not found in sources`);\n result.set(name, snap);\n resovedIds.add(snap.id);\n }\n }\n\n if (resovedIds.size === 0) {\n throwError(\"At least one anchor must be resolved to a valid column\");\n }\n\n return result;\n}\n\nfunction remapFromIdxToId(\n qualifications: {\n forQueries: AxisQualification[][];\n forHit: AxisQualification[];\n },\n anchors: ColumnSnapshot<PObjectId>[],\n): MatchQualifications {\n const forQueries = qualifications.forQueries.reduce(\n (acc, qs, i) => (anchors[i] && qs.length > 0 ? acc.set(anchors[i].id, qs) : acc),\n new Map<PObjectId, AxisQualification[]>(),\n );\n return {\n forQueries: forQueries.size > 0 ? Object.fromEntries(forQueries) : undefined,\n forHit: qualifications.forHit.length > 0 ? qualifications.forHit : undefined,\n };\n}\n\nfunction matchingModeToConstraints(mode: MatchingMode): DiscoverColumnsConstraints {\n switch (mode) {\n case \"enrichment\":\n return {\n allowFloatingSourceAxes: true,\n allowFloatingHitAxes: false,\n allowSourceQualifications: true,\n allowHitQualifications: true,\n };\n case \"related\":\n return {\n allowFloatingSourceAxes: true,\n allowFloatingHitAxes: true,\n allowSourceQualifications: true,\n allowHitQualifications: true,\n };\n case \"exact\":\n return {\n allowFloatingSourceAxes: false,\n allowFloatingHitAxes: false,\n allowSourceQualifications: false,\n allowHitQualifications: false,\n };\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"column_collection_builder.cjs","names":["getService","TreeNodeAccessor","ArrayColumnProvider","toColumnSnapshotProvider","convertColumnSelectorToMultiColumnSelector"],"sources":["../../src/columns/column_collection_builder.ts"],"sourcesContent":["import type {\n AxisQualification,\n DiscoverColumnsConstraints,\n DiscoverColumnsRequest,\n DiscoverColumnsResponse,\n MultiColumnSelector,\n NativePObjectId,\n PColumnSpec,\n PObjectId,\n} from \"@milaboratories/pl-model-common\";\nimport { deriveNativeId, isPColumnSpec } from \"@milaboratories/pl-model-common\";\nimport type { ColumnSelector, RelaxedColumnSelector } from \"./column_selector\";\nimport { convertColumnSelectorToMultiColumnSelector } from \"./column_selector\";\nimport { TreeNodeAccessor } from \"../render/accessor\";\nimport type { ColumnSnapshot } from \"./column_snapshot\";\nimport type { ColumnSnapshotProvider, ColumnSource } from \"./column_snapshot_provider\";\nimport { ArrayColumnProvider, toColumnSnapshotProvider } from \"./column_snapshot_provider\";\n\nimport type { PFrameSpecDriver, PoolEntry, SpecFrameHandle } from \"@milaboratories/pl-model-common\";\nimport { throwError } from \"@milaboratories/helpers\";\nimport { getService } from \"../services\";\n\n/** Options for plain collection findColumns. */\nexport interface FindColumnsOptions {\n /** Include columns matching these selectors. If omitted, includes all columns. */\n include?: ColumnSelector;\n /** Exclude columns matching these selectors. */\n exclude?: ColumnSelector;\n}\n\n/** Plain collection — no axis context, selector-based filtering only. */\nexport interface ColumnCollection extends Disposable {\n /** Release the underlying spec frame WASM resource. */\n dispose(): void;\n\n /** Find columns matching selectors. Returns flat list of snapshots.\n * No axis compatibility matching, no linker traversal.\n * Never returns undefined — the \"not ready\" state was absorbed by the builder. */\n findColumns(options?: FindColumnsOptions): ColumnSnapshot<PObjectId>[];\n}\n\n/** Axis-aware column collection with anchored identity derivation. */\nexport interface AnchoredColumnCollection extends Disposable {\n /** Release the underlying spec frame WASM resource. */\n dispose(): void;\n\n /** List of anchors used for discovery, with their resolved specs. */\n getAnchors(): Map<string, ColumnSnapshot<PObjectId>>;\n\n /** Axis-aware column discovery. */\n findColumns(options?: AnchoredFindColumnsOptions): ColumnMatch[];\n\n /** Variant discovery with detailed mapping info for each hit. */\n findColumnVariants(options?: AnchoredFindColumnsOptions): ColumnVariant[];\n}\n\n/** Controls axis matching behavior for anchored discovery. */\nexport type MatchingMode = \"enrichment\" | \"related\" | \"exact\";\n\n/** Options for anchored collection findColumns. */\nexport interface AnchoredFindColumnsOptions extends FindColumnsOptions {\n /** Controls axis matching behavior. Default: 'enrichment'. */\n mode?: MatchingMode;\n /** Maximum linker hops for cross-domain discovery (0 = direct only, default: 4). */\n maxHops?: number;\n}\n\n/** Result of anchored discovery — column snapshot + routing info. */\nexport interface ColumnMatch {\n /** Column snapshot with anchored SUniversalPColumnId. */\n readonly column: ColumnSnapshot<PObjectId>;\n /** Match variants — different ways (paths/qualifications) to reach this column. */\n readonly variants: MatchVariant[];\n}\n\nexport interface ColumnVariant<Id extends PObjectId = PObjectId> {\n /** Column snapshot with anchored SUniversalPColumnId. */\n readonly column: ColumnSnapshot<Id>;\n /** Linker steps traversed to reach this hit; empty for direct matches. */\n readonly path?: { linker: ColumnSnapshot<PObjectId> }[];\n /** Full qualifications needed for integration. */\n readonly qualifications?: MatchQualifications;\n}\n\n/** A single mapping variant describing how a hit column can be integrated. */\nexport interface MatchVariant {\n /** Full qualifications needed for integration. */\n readonly qualifications: MatchQualifications;\n /** Linker steps traversed to reach this hit; empty for direct matches. */\n readonly path: { linker: ColumnSnapshot<PObjectId> }[];\n}\n\n/** Qualifications needed for both already-integrated anchor columns and the hit column. */\nexport interface MatchQualifications {\n /** Qualifications for already-integrated anchor columns */\n readonly forQueries?: Record<PObjectId, AxisQualification[]>;\n /** Qualifications for the hit column. */\n readonly forHit?: AxisQualification[];\n}\n\nexport interface BuildOptions {\n allowPartialColumnList?: true;\n}\n\nexport type AnchorEntry = PObjectId | PColumnSpec | RelaxedColumnSelector;\n\nexport interface AnchoredBuildOptions extends BuildOptions {\n anchors: Record<string, AnchorEntry>;\n}\n\n/**\n * Mutable builder that accumulates column sources, then produces\n * a ColumnCollection (plain) or AnchoredColumnCollection (with anchors).\n *\n * Each output lambda creates its own builder — a constraint of the\n * computable framework where each output tracks its own dependencies.\n */\nexport class ColumnCollectionBuilder {\n private readonly providers: ColumnSnapshotProvider[] = [];\n\n constructor(private readonly specDriver: PFrameSpecDriver = getService(\"pframeSpec\")) {}\n\n /**\n * Register a column source. Sources added first take precedence for dedup.\n * Does NOT accept undefined — if a source isn't available yet,\n * the caller should return undefined from the output lambda.\n */\n addSource(source: ColumnSource | TreeNodeAccessor): this {\n if (source instanceof TreeNodeAccessor) {\n const columns = source.getPColumns();\n if (columns) this.providers.push(new ArrayColumnProvider(columns));\n } else {\n this.providers.push(toColumnSnapshotProvider(source));\n }\n return this;\n }\n\n addSources(sources: (ColumnSource | TreeNodeAccessor)[]): this {\n for (const source of sources) {\n this.addSource(source);\n }\n return this;\n }\n\n /** Plain collection — selector-based filtering, PObjectId namespace. */\n build(): undefined | ColumnCollection;\n build(options: {\n allowPartialColumnList: true;\n }): ColumnCollection & { readonly columnListComplete: boolean };\n /** Anchored collection — axis-aware discovery, SUniversalPColumnId namespace. */\n build(\n options: AnchoredBuildOptions & { allowPartialColumnList: true },\n ): AnchoredColumnCollection & { readonly columnListComplete: boolean };\n build(options: AnchoredBuildOptions): undefined | AnchoredColumnCollection;\n build(\n options?: BuildOptions | AnchoredBuildOptions,\n ):\n | undefined\n | ColumnCollection\n | AnchoredColumnCollection\n | (ColumnCollection & { readonly columnListComplete: boolean })\n | (AnchoredColumnCollection & { readonly columnListComplete: boolean }) {\n const allowPartial = options?.allowPartialColumnList === true;\n\n // Check column list completeness\n const allComplete = this.providers.every((p) => p.isColumnListComplete());\n if (!allComplete && !allowPartial) return undefined;\n\n // Collect all columns, dedup by native ID (first source wins)\n const columns = collectColumns(this.providers);\n const hasAnchors = options !== undefined && \"anchors\" in options;\n\n if (hasAnchors) {\n return new AnchoredColumnCollectionImpl(this.specDriver, {\n anchors: options.anchors,\n columns,\n });\n } else {\n return new ColumnCollectionImpl(this.specDriver, {\n columns,\n });\n }\n }\n}\n\ninterface ColumnCollectionImplOptions {\n readonly columns: ColumnSnapshot<PObjectId>[];\n}\n\nclass ColumnCollectionImpl implements ColumnCollection, Disposable {\n private readonly columns: Map<PObjectId, ColumnSnapshot<PObjectId>>;\n private readonly specFrameEntry: PoolEntry<SpecFrameHandle>;\n\n constructor(\n private readonly specDriver: PFrameSpecDriver,\n options: ColumnCollectionImplOptions,\n ) {\n this.columns = new Map(options.columns.map((col) => [col.id, col]));\n this.specFrameEntry = this.specDriver.createSpecFrame(\n Object.fromEntries(options.columns.map((col) => [col.id, col.spec])),\n );\n }\n\n dispose(): void {\n this.specFrameEntry.unref();\n }\n\n [Symbol.dispose](): void {\n this.dispose();\n }\n\n findColumns(options?: FindColumnsOptions): ColumnSnapshot<PObjectId>[] {\n const includeColumns = options?.include ? toMultiColumnSelectors(options.include) : undefined;\n const excludeColumns = options?.exclude ? toMultiColumnSelectors(options.exclude) : undefined;\n\n const response = this.specDriver.discoverColumns(this.specFrameEntry.key, {\n includeColumns,\n excludeColumns,\n axes: [],\n maxHops: 0,\n constraints: matchingModeToConstraints(\"enrichment\"),\n });\n\n // Map hits back to snapshots\n const results = response.hits\n .map((hit) => this.columns.get(hit.hit.columnId as PObjectId))\n .filter((col): col is ColumnSnapshot<PObjectId> => col !== undefined);\n\n return results;\n }\n}\n\ninterface AnchoredColumnCollectionImplOptions extends ColumnCollectionImplOptions {\n readonly anchors: Record<string, AnchorEntry>;\n}\n\nclass AnchoredColumnCollectionImpl implements AnchoredColumnCollection, Disposable {\n private readonly anchorsMap: Map<string, ColumnSnapshot<PObjectId>>;\n private readonly columnsMap: Map<PObjectId, ColumnSnapshot<PObjectId>>;\n private readonly specFrameEntry: PoolEntry<SpecFrameHandle>;\n\n constructor(\n private readonly specDriver: PFrameSpecDriver,\n options: AnchoredColumnCollectionImplOptions,\n ) {\n // Create spec frame from all collected columns\n this.specFrameEntry = this.specDriver.createSpecFrame(\n Object.fromEntries(options.columns.map((col) => [col.id, col.spec])),\n );\n this.columnsMap = new Map(options.columns.map((col) => [col.id, col]));\n this.anchorsMap = resolveAnchorMap(\n options.anchors,\n options.columns,\n this.specDriver.discoverColumns.bind(this.specDriver, this.specFrameEntry.key),\n );\n }\n\n dispose(): void {\n this.specFrameEntry.unref();\n }\n\n [Symbol.dispose](): void {\n this.dispose();\n }\n\n getAnchors(): Map<string, ColumnSnapshot<PObjectId>> {\n return this.anchorsMap;\n }\n\n findColumns(options?: AnchoredFindColumnsOptions): ColumnMatch[] {\n const mode = options?.mode ?? \"enrichment\";\n const constraints = matchingModeToConstraints(mode);\n const includeColumns = options?.include ? toMultiColumnSelectors(options.include) : undefined;\n const excludeColumns = options?.exclude ? toMultiColumnSelectors(options.exclude) : undefined;\n const anchors = Array.from(this.anchorsMap.values());\n const response = this.specDriver.discoverColumns(this.specFrameEntry.key, {\n includeColumns,\n excludeColumns,\n constraints,\n maxHops: options?.maxHops ?? 4,\n axes: anchors.map((anchor) => ({\n axesSpec: anchor.spec.axesSpec,\n qualifications: [],\n })),\n });\n\n const byColumn = response.hits.reduce<Map<PObjectId, ColumnMatch>>((acc, hit) => {\n const origId = hit.hit.columnId as PObjectId;\n const col =\n this.columnsMap.get(origId) ??\n throwError(`Column with id ${origId} not found in collection`);\n\n const path = hit.path.map((step) => {\n if (step.type !== \"linker\") {\n throw new Error(`Unexpected discover-columns step type: ${step.type}`);\n }\n\n return {\n linker:\n this.columnsMap.get(step.linker.columnId) ??\n throwError(`Linker column with id ${step.linker.columnId} not found in collection`),\n };\n });\n const variants: MatchVariant[] = hit.mappingVariants.map((v) => ({\n path,\n qualifications: remapFromIdxToId(v.qualifications, anchors),\n }));\n const existing = acc.get(origId);\n return acc.set(\n origId,\n existing === undefined\n ? { column: col, variants }\n : { ...existing, variants: [...existing.variants, ...variants] },\n );\n }, new Map());\n\n return Array.from(byColumn.values());\n }\n\n findColumnVariants(options?: AnchoredFindColumnsOptions): ColumnVariant[] {\n const matches = this.findColumns(options);\n return matches.flatMap((match) =>\n match.variants.map((variant) => ({\n column: match.column,\n path: variant.path,\n qualifications: variant.qualifications,\n })),\n );\n }\n}\n\n/**\n * Collect all columns from all providers, dedup by NativePObjectId.\n * First source wins.\n */\nfunction collectColumns(providers: ColumnSnapshotProvider[]): ColumnSnapshot<PObjectId>[] {\n const seen = new Set<NativePObjectId>();\n const result: ColumnSnapshot<PObjectId>[] = [];\n\n for (const provider of providers) {\n const columns = provider.getAllColumns();\n for (const col of columns) {\n const nativeId = deriveNativeId(col.spec);\n if (seen.has(nativeId)) continue;\n seen.add(nativeId);\n result.push(col);\n }\n }\n\n return result;\n}\n\n/** Normalize ColumnSelector (relaxed, single or array) to MultiColumnSelector[]. */\nfunction toMultiColumnSelectors(input: ColumnSelector): MultiColumnSelector[] {\n return convertColumnSelectorToMultiColumnSelector(input);\n}\n\n/**\n * Resolve each anchor entry to a ColumnSnapshot from the collected columns.\n * - PObjectId (string): looked up by id in the collected columns\n * - PColumnSpec: matched by deriveNativeId against collected columns\n * - RelaxedColumnSelector: resolved via discoverColumns in \"exact\" mode;\n * must match exactly one column\n * Throws on unresolved, ambiguous, or duplicated matches. Requires at least one\n * anchor to resolve.\n */\nfunction resolveAnchorMap(\n anchors: Record<string, AnchorEntry>,\n columns: ColumnSnapshot<PObjectId>[],\n discoverColumns: (request: DiscoverColumnsRequest) => DiscoverColumnsResponse,\n): Map<string, ColumnSnapshot<PObjectId>> {\n const result = new Map<string, ColumnSnapshot<PObjectId>>();\n const resovedIds = new Set<PObjectId>();\n const getDuplicateError = (key: string) =>\n `Anchor \"${key}\": selector matched a column that was already matched by another anchor; please refine the selector to match a different column`;\n\n // O(1) lookup maps built lazily — only when an anchor of the matching kind is\n // encountered. Avoids O(anchors × columns) `deriveNativeId` calls, which were\n // tripping the QuickJS interrupt deadline on tables with many anchors.\n let byId: Map<PObjectId, ColumnSnapshot<PObjectId>> | undefined;\n let byNativeId: Map<NativePObjectId, ColumnSnapshot<PObjectId>> | undefined;\n\n for (const [name, anchor] of Object.entries(anchors)) {\n if (typeof anchor === \"string\") {\n if (byId === undefined) byId = new Map(columns.map((col) => [col.id, col]));\n const found =\n byId.get(anchor) ??\n throwError(`Anchor \"${name}\": column with id \"${anchor}\" not found in sources`);\n if (resovedIds.has(found.id)) {\n throwError(getDuplicateError(name));\n }\n result.set(name, found);\n resovedIds.add(found.id);\n } else if (\"kind\" in anchor) {\n if (!isPColumnSpec(anchor)) throwError(`Anchor \"${name}\": invalid PColumnSpec`);\n if (byNativeId === undefined) {\n byNativeId = new Map(columns.map((col) => [deriveNativeId(col.spec), col]));\n }\n const found =\n byNativeId.get(deriveNativeId(anchor)) ??\n throwError(`Anchor \"${name}\": no column matching spec found in sources`);\n if (resovedIds.has(found.id)) {\n throwError(getDuplicateError(name));\n }\n result.set(name, found);\n resovedIds.add(found.id);\n } else {\n const matched = discoverColumns({\n includeColumns: toMultiColumnSelectors(anchor),\n excludeColumns: undefined,\n axes: [],\n maxHops: 0,\n constraints: matchingModeToConstraints(\"related\"),\n });\n\n if (matched.hits.length === 0) {\n throwError(`Anchor \"${name}\": no columns matched selector`);\n }\n if (matched.hits.length > 1) {\n throwError(\n `Anchor \"${name}\": selector is ambiguous and matched multiple columns; please refine the selector to match exactly one column`,\n );\n }\n if (resovedIds.has(matched.hits[0].hit.columnId as PObjectId)) {\n throwError(getDuplicateError(name));\n }\n\n const id = matched.hits[0].hit.columnId as PObjectId;\n const snap =\n columns.find((col) => col.id === id) ??\n throwError(`Anchor \"${name}\": matched column with id \"${id}\" not found in sources`);\n result.set(name, snap);\n resovedIds.add(snap.id);\n }\n }\n\n if (resovedIds.size === 0) {\n throwError(\"At least one anchor must be resolved to a valid column\");\n }\n\n return result;\n}\n\nfunction remapFromIdxToId(\n qualifications: {\n forQueries: AxisQualification[][];\n forHit: AxisQualification[];\n },\n anchors: ColumnSnapshot<PObjectId>[],\n): MatchQualifications {\n const forQueries = qualifications.forQueries.reduce(\n (acc, qs, i) => (anchors[i] && qs.length > 0 ? acc.set(anchors[i].id, qs) : acc),\n new Map<PObjectId, AxisQualification[]>(),\n );\n return {\n forQueries: forQueries.size > 0 ? Object.fromEntries(forQueries) : undefined,\n forHit: qualifications.forHit.length > 0 ? qualifications.forHit : undefined,\n };\n}\n\nfunction matchingModeToConstraints(mode: MatchingMode): DiscoverColumnsConstraints {\n switch (mode) {\n case \"enrichment\":\n return {\n allowFloatingSourceAxes: true,\n allowFloatingHitAxes: false,\n allowSourceQualifications: true,\n allowHitQualifications: true,\n };\n case \"related\":\n return {\n allowFloatingSourceAxes: true,\n allowFloatingHitAxes: true,\n allowSourceQualifications: true,\n allowHitQualifications: true,\n };\n case \"exact\":\n return {\n allowFloatingSourceAxes: false,\n allowFloatingHitAxes: false,\n allowSourceQualifications: false,\n allowHitQualifications: false,\n };\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"column_collection_builder.d.ts","names":[],"sources":["../../src/columns/column_collection_builder.ts"],"mappings":";;;;;;;;UAuBiB,kBAAA;EAAkB;EAEjC,OAAA,GAAU,cAAA;EAEc;EAAxB,OAAA,GAAU,
|
|
1
|
+
{"version":3,"file":"column_collection_builder.d.ts","names":[],"sources":["../../src/columns/column_collection_builder.ts"],"mappings":";;;;;;;;UAuBiB,kBAAA;EAAkB;EAEjC,OAAA,GAAU,cAAA;EAEc;EAAxB,OAAA,GAAU,cAAc;AAAA;;UAIT,gBAAA,SAAyB,UAAA;EAJhB;EAMxB,OAAA;EAFe;;;EAOf,WAAA,CAAY,OAAA,GAAU,kBAAA,GAAqB,cAAA,CAAe,SAAA;AAAA;;UAI3C,wBAAA,SAAiC,UAAA;EAXE;EAalD,OAAA;EAbwC;EAgBxC,UAAA,IAAc,GAAA,SAAY,cAAA,CAAe,SAAA;EATzC;EAYA,WAAA,CAAY,OAAA,GAAU,0BAAA,GAA6B,WAAA;EAZvC;EAeZ,kBAAA,CAAmB,OAAA,GAAU,0BAAA,GAA6B,aAAA;AAAA;;KAIhD,YAAA;AAfZ;AAAA,UAkBiB,0BAAA,SAAmC,kBAAkB;;EAEpE,IAAA,GAAO,YAAA;EAfmB;EAiB1B,OAAA;AAAA;;UAIe,WAAA;EAf2C;EAAA,SAiBjD,MAAA,EAAQ,cAAA,CAAe,SAAA;EA5B0B;EAAA,SA8BjD,QAAA,EAAU,YAAA;AAAA;AAAA,UAGJ,aAAA,YAAyB,SAAA,GAAY,SAAA;EA5BpD;EAAA,SA8BS,MAAA,EAAQ,cAAA,CAAe,EAAA;EA9BN;EAAA,SAgCjB,IAAA;IAAS,MAAA,EAAQ,cAAA,CAAe,SAAA;EAAA;EA7B7B;EAAA,SA+BH,cAAA,GAAiB,mBAAA;AAAA;;UAIX,YAAA;EAhC2C;EAAA,SAkCjD,cAAA,EAAgB,mBAAA;EAlC8C;EAAA,SAoC9D,IAAA;IAAQ,MAAA,EAAQ,cAAA,CAAe,SAAA;EAAA;AAAA;AAhClB;AAAA,UAoCP,mBAAA;EAjC2B;EAAA,SAmCjC,UAAA,GAAa,MAAA,CAAO,SAAA,EAAW,iBAAA;EAnC4B;EAAA,SAqC3D,MAAA,GAAS,iBAAA;AAAA;AAAA,UAGH,YAAA;EACf,sBAAsB;AAAA;AAAA,KAGZ,WAAA,GAAc,SAAA,GAAY,WAAA,GAAc,qBAAA;AAAA,UAEnC,oBAAA,SAA6B,YAAA;EAC5C,OAAA,EAAS,MAAA,SAAe,WAAA;AAAA;;;;;;;;cAUb,uBAAA;EAAA,iBAGkB,UAAA;EAAA,iBAFZ,SAAA;cAEY,UAAA,GAAY,gBAAA;EAhDV;AAGjC;;;;EAoDE,SAAA,CAAU,MAAA,EAAQ,YAAA,GAAe,gBAAA;EAUjC,UAAA,CAAW,OAAA,GAAU,YAAA,GAAe,gBAAA;EA5DnB;EAoEjB,KAAA,gBAAqB,gBAAA;EACrB,KAAA,CAAM,OAAA;IACJ,sBAAA;EAAA,IACE,gBAAA;IAAA,SAA8B,kBAAA;EAAA;EAzEM;EA2ExC,KAAA,CACE,OAAA,EAAS,oBAAA;IAAyB,sBAAA;EAAA,IACjC,wBAAA;IAAA,SAAsC,kBAAA;EAAA;EACzC,KAAA,CAAM,OAAA,EAAS,oBAAA,eAAmC,wBAAA;AAAA"}
|
|
@@ -14,6 +14,7 @@ import { throwError } from "@milaboratories/helpers";
|
|
|
14
14
|
* computable framework where each output tracks its own dependencies.
|
|
15
15
|
*/
|
|
16
16
|
var ColumnCollectionBuilder = class {
|
|
17
|
+
specDriver;
|
|
17
18
|
providers = [];
|
|
18
19
|
constructor(specDriver = getService("pframeSpec")) {
|
|
19
20
|
this.specDriver = specDriver;
|
|
@@ -46,6 +47,7 @@ var ColumnCollectionBuilder = class {
|
|
|
46
47
|
}
|
|
47
48
|
};
|
|
48
49
|
var ColumnCollectionImpl = class {
|
|
50
|
+
specDriver;
|
|
49
51
|
columns;
|
|
50
52
|
specFrameEntry;
|
|
51
53
|
constructor(specDriver, options) {
|
|
@@ -72,6 +74,7 @@ var ColumnCollectionImpl = class {
|
|
|
72
74
|
}
|
|
73
75
|
};
|
|
74
76
|
var AnchoredColumnCollectionImpl = class {
|
|
77
|
+
specDriver;
|
|
75
78
|
anchorsMap;
|
|
76
79
|
columnsMap;
|
|
77
80
|
specFrameEntry;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"column_collection_builder.js","names":[],"sources":["../../src/columns/column_collection_builder.ts"],"sourcesContent":["import type {\n AxisQualification,\n DiscoverColumnsConstraints,\n DiscoverColumnsRequest,\n DiscoverColumnsResponse,\n MultiColumnSelector,\n NativePObjectId,\n PColumnSpec,\n PObjectId,\n} from \"@milaboratories/pl-model-common\";\nimport { deriveNativeId, isPColumnSpec } from \"@milaboratories/pl-model-common\";\nimport type { ColumnSelector, RelaxedColumnSelector } from \"./column_selector\";\nimport { convertColumnSelectorToMultiColumnSelector } from \"./column_selector\";\nimport { TreeNodeAccessor } from \"../render/accessor\";\nimport type { ColumnSnapshot } from \"./column_snapshot\";\nimport type { ColumnSnapshotProvider, ColumnSource } from \"./column_snapshot_provider\";\nimport { ArrayColumnProvider, toColumnSnapshotProvider } from \"./column_snapshot_provider\";\n\nimport type { PFrameSpecDriver, PoolEntry, SpecFrameHandle } from \"@milaboratories/pl-model-common\";\nimport { throwError } from \"@milaboratories/helpers\";\nimport { getService } from \"../services\";\n\n/** Options for plain collection findColumns. */\nexport interface FindColumnsOptions {\n /** Include columns matching these selectors. If omitted, includes all columns. */\n include?: ColumnSelector;\n /** Exclude columns matching these selectors. */\n exclude?: ColumnSelector;\n}\n\n/** Plain collection — no axis context, selector-based filtering only. */\nexport interface ColumnCollection extends Disposable {\n /** Release the underlying spec frame WASM resource. */\n dispose(): void;\n\n /** Find columns matching selectors. Returns flat list of snapshots.\n * No axis compatibility matching, no linker traversal.\n * Never returns undefined — the \"not ready\" state was absorbed by the builder. */\n findColumns(options?: FindColumnsOptions): ColumnSnapshot<PObjectId>[];\n}\n\n/** Axis-aware column collection with anchored identity derivation. */\nexport interface AnchoredColumnCollection extends Disposable {\n /** Release the underlying spec frame WASM resource. */\n dispose(): void;\n\n /** List of anchors used for discovery, with their resolved specs. */\n getAnchors(): Map<string, ColumnSnapshot<PObjectId>>;\n\n /** Axis-aware column discovery. */\n findColumns(options?: AnchoredFindColumnsOptions): ColumnMatch[];\n\n /** Variant discovery with detailed mapping info for each hit. */\n findColumnVariants(options?: AnchoredFindColumnsOptions): ColumnVariant[];\n}\n\n/** Controls axis matching behavior for anchored discovery. */\nexport type MatchingMode = \"enrichment\" | \"related\" | \"exact\";\n\n/** Options for anchored collection findColumns. */\nexport interface AnchoredFindColumnsOptions extends FindColumnsOptions {\n /** Controls axis matching behavior. Default: 'enrichment'. */\n mode?: MatchingMode;\n /** Maximum linker hops for cross-domain discovery (0 = direct only, default: 4). */\n maxHops?: number;\n}\n\n/** Result of anchored discovery — column snapshot + routing info. */\nexport interface ColumnMatch {\n /** Column snapshot with anchored SUniversalPColumnId. */\n readonly column: ColumnSnapshot<PObjectId>;\n /** Match variants — different ways (paths/qualifications) to reach this column. */\n readonly variants: MatchVariant[];\n}\n\nexport interface ColumnVariant<Id extends PObjectId = PObjectId> {\n /** Column snapshot with anchored SUniversalPColumnId. */\n readonly column: ColumnSnapshot<Id>;\n /** Linker steps traversed to reach this hit; empty for direct matches. */\n readonly path?: { linker: ColumnSnapshot<PObjectId> }[];\n /** Full qualifications needed for integration. */\n readonly qualifications?: MatchQualifications;\n}\n\n/** A single mapping variant describing how a hit column can be integrated. */\nexport interface MatchVariant {\n /** Full qualifications needed for integration. */\n readonly qualifications: MatchQualifications;\n /** Linker steps traversed to reach this hit; empty for direct matches. */\n readonly path: { linker: ColumnSnapshot<PObjectId> }[];\n}\n\n/** Qualifications needed for both already-integrated anchor columns and the hit column. */\nexport interface MatchQualifications {\n /** Qualifications for already-integrated anchor columns */\n readonly forQueries?: Record<PObjectId, AxisQualification[]>;\n /** Qualifications for the hit column. */\n readonly forHit?: AxisQualification[];\n}\n\nexport interface BuildOptions {\n allowPartialColumnList?: true;\n}\n\nexport type AnchorEntry = PObjectId | PColumnSpec | RelaxedColumnSelector;\n\nexport interface AnchoredBuildOptions extends BuildOptions {\n anchors: Record<string, AnchorEntry>;\n}\n\n/**\n * Mutable builder that accumulates column sources, then produces\n * a ColumnCollection (plain) or AnchoredColumnCollection (with anchors).\n *\n * Each output lambda creates its own builder — a constraint of the\n * computable framework where each output tracks its own dependencies.\n */\nexport class ColumnCollectionBuilder {\n private readonly providers: ColumnSnapshotProvider[] = [];\n\n constructor(private readonly specDriver: PFrameSpecDriver = getService(\"pframeSpec\")) {}\n\n /**\n * Register a column source. Sources added first take precedence for dedup.\n * Does NOT accept undefined — if a source isn't available yet,\n * the caller should return undefined from the output lambda.\n */\n addSource(source: ColumnSource | TreeNodeAccessor): this {\n if (source instanceof TreeNodeAccessor) {\n const columns = source.getPColumns();\n if (columns) this.providers.push(new ArrayColumnProvider(columns));\n } else {\n this.providers.push(toColumnSnapshotProvider(source));\n }\n return this;\n }\n\n addSources(sources: (ColumnSource | TreeNodeAccessor)[]): this {\n for (const source of sources) {\n this.addSource(source);\n }\n return this;\n }\n\n /** Plain collection — selector-based filtering, PObjectId namespace. */\n build(): undefined | ColumnCollection;\n build(options: {\n allowPartialColumnList: true;\n }): ColumnCollection & { readonly columnListComplete: boolean };\n /** Anchored collection — axis-aware discovery, SUniversalPColumnId namespace. */\n build(\n options: AnchoredBuildOptions & { allowPartialColumnList: true },\n ): AnchoredColumnCollection & { readonly columnListComplete: boolean };\n build(options: AnchoredBuildOptions): undefined | AnchoredColumnCollection;\n build(\n options?: BuildOptions | AnchoredBuildOptions,\n ):\n | undefined\n | ColumnCollection\n | AnchoredColumnCollection\n | (ColumnCollection & { readonly columnListComplete: boolean })\n | (AnchoredColumnCollection & { readonly columnListComplete: boolean }) {\n const allowPartial = options?.allowPartialColumnList === true;\n\n // Check column list completeness\n const allComplete = this.providers.every((p) => p.isColumnListComplete());\n if (!allComplete && !allowPartial) return undefined;\n\n // Collect all columns, dedup by native ID (first source wins)\n const columns = collectColumns(this.providers);\n const hasAnchors = options !== undefined && \"anchors\" in options;\n\n if (hasAnchors) {\n return new AnchoredColumnCollectionImpl(this.specDriver, {\n anchors: options.anchors,\n columns,\n });\n } else {\n return new ColumnCollectionImpl(this.specDriver, {\n columns,\n });\n }\n }\n}\n\ninterface ColumnCollectionImplOptions {\n readonly columns: ColumnSnapshot<PObjectId>[];\n}\n\nclass ColumnCollectionImpl implements ColumnCollection, Disposable {\n private readonly columns: Map<PObjectId, ColumnSnapshot<PObjectId>>;\n private readonly specFrameEntry: PoolEntry<SpecFrameHandle>;\n\n constructor(\n private readonly specDriver: PFrameSpecDriver,\n options: ColumnCollectionImplOptions,\n ) {\n this.columns = new Map(options.columns.map((col) => [col.id, col]));\n this.specFrameEntry = this.specDriver.createSpecFrame(\n Object.fromEntries(options.columns.map((col) => [col.id, col.spec])),\n );\n }\n\n dispose(): void {\n this.specFrameEntry.unref();\n }\n\n [Symbol.dispose](): void {\n this.dispose();\n }\n\n findColumns(options?: FindColumnsOptions): ColumnSnapshot<PObjectId>[] {\n const includeColumns = options?.include ? toMultiColumnSelectors(options.include) : undefined;\n const excludeColumns = options?.exclude ? toMultiColumnSelectors(options.exclude) : undefined;\n\n const response = this.specDriver.discoverColumns(this.specFrameEntry.key, {\n includeColumns,\n excludeColumns,\n axes: [],\n maxHops: 0,\n constraints: matchingModeToConstraints(\"enrichment\"),\n });\n\n // Map hits back to snapshots\n const results = response.hits\n .map((hit) => this.columns.get(hit.hit.columnId as PObjectId))\n .filter((col): col is ColumnSnapshot<PObjectId> => col !== undefined);\n\n return results;\n }\n}\n\ninterface AnchoredColumnCollectionImplOptions extends ColumnCollectionImplOptions {\n readonly anchors: Record<string, AnchorEntry>;\n}\n\nclass AnchoredColumnCollectionImpl implements AnchoredColumnCollection, Disposable {\n private readonly anchorsMap: Map<string, ColumnSnapshot<PObjectId>>;\n private readonly columnsMap: Map<PObjectId, ColumnSnapshot<PObjectId>>;\n private readonly specFrameEntry: PoolEntry<SpecFrameHandle>;\n\n constructor(\n private readonly specDriver: PFrameSpecDriver,\n options: AnchoredColumnCollectionImplOptions,\n ) {\n // Create spec frame from all collected columns\n this.specFrameEntry = this.specDriver.createSpecFrame(\n Object.fromEntries(options.columns.map((col) => [col.id, col.spec])),\n );\n this.columnsMap = new Map(options.columns.map((col) => [col.id, col]));\n this.anchorsMap = resolveAnchorMap(\n options.anchors,\n options.columns,\n this.specDriver.discoverColumns.bind(this.specDriver, this.specFrameEntry.key),\n );\n }\n\n dispose(): void {\n this.specFrameEntry.unref();\n }\n\n [Symbol.dispose](): void {\n this.dispose();\n }\n\n getAnchors(): Map<string, ColumnSnapshot<PObjectId>> {\n return this.anchorsMap;\n }\n\n findColumns(options?: AnchoredFindColumnsOptions): ColumnMatch[] {\n const mode = options?.mode ?? \"enrichment\";\n const constraints = matchingModeToConstraints(mode);\n const includeColumns = options?.include ? toMultiColumnSelectors(options.include) : undefined;\n const excludeColumns = options?.exclude ? toMultiColumnSelectors(options.exclude) : undefined;\n const anchors = Array.from(this.anchorsMap.values());\n const response = this.specDriver.discoverColumns(this.specFrameEntry.key, {\n includeColumns,\n excludeColumns,\n constraints,\n maxHops: options?.maxHops ?? 4,\n axes: anchors.map((anchor) => ({\n axesSpec: anchor.spec.axesSpec,\n qualifications: [],\n })),\n });\n\n const byColumn = response.hits.reduce<Map<PObjectId, ColumnMatch>>((acc, hit) => {\n const origId = hit.hit.columnId as PObjectId;\n const col =\n this.columnsMap.get(origId) ??\n throwError(`Column with id ${origId} not found in collection`);\n\n const path = hit.path.map((step) => {\n if (step.type !== \"linker\") {\n throw new Error(`Unexpected discover-columns step type: ${step.type}`);\n }\n\n return {\n linker:\n this.columnsMap.get(step.linker.columnId) ??\n throwError(`Linker column with id ${step.linker.columnId} not found in collection`),\n };\n });\n const variants: MatchVariant[] = hit.mappingVariants.map((v) => ({\n path,\n qualifications: remapFromIdxToId(v.qualifications, anchors),\n }));\n const existing = acc.get(origId);\n return acc.set(\n origId,\n existing === undefined\n ? { column: col, variants }\n : { ...existing, variants: [...existing.variants, ...variants] },\n );\n }, new Map());\n\n return Array.from(byColumn.values());\n }\n\n findColumnVariants(options?: AnchoredFindColumnsOptions): ColumnVariant[] {\n const matches = this.findColumns(options);\n return matches.flatMap((match) =>\n match.variants.map((variant) => ({\n column: match.column,\n path: variant.path,\n qualifications: variant.qualifications,\n })),\n );\n }\n}\n\n/**\n * Collect all columns from all providers, dedup by NativePObjectId.\n * First source wins.\n */\nfunction collectColumns(providers: ColumnSnapshotProvider[]): ColumnSnapshot<PObjectId>[] {\n const seen = new Set<NativePObjectId>();\n const result: ColumnSnapshot<PObjectId>[] = [];\n\n for (const provider of providers) {\n const columns = provider.getAllColumns();\n for (const col of columns) {\n const nativeId = deriveNativeId(col.spec);\n if (seen.has(nativeId)) continue;\n seen.add(nativeId);\n result.push(col);\n }\n }\n\n return result;\n}\n\n/** Normalize ColumnSelector (relaxed, single or array) to MultiColumnSelector[]. */\nfunction toMultiColumnSelectors(input: ColumnSelector): MultiColumnSelector[] {\n return convertColumnSelectorToMultiColumnSelector(input);\n}\n\n/**\n * Resolve each anchor entry to a ColumnSnapshot from the collected columns.\n * - PObjectId (string): looked up by id in the collected columns\n * - PColumnSpec: matched by deriveNativeId against collected columns\n * - RelaxedColumnSelector: resolved via discoverColumns in \"exact\" mode;\n * must match exactly one column\n * Throws on unresolved, ambiguous, or duplicated matches. Requires at least one\n * anchor to resolve.\n */\nfunction resolveAnchorMap(\n anchors: Record<string, AnchorEntry>,\n columns: ColumnSnapshot<PObjectId>[],\n discoverColumns: (request: DiscoverColumnsRequest) => DiscoverColumnsResponse,\n): Map<string, ColumnSnapshot<PObjectId>> {\n const result = new Map<string, ColumnSnapshot<PObjectId>>();\n const resovedIds = new Set<PObjectId>();\n const getDuplicateError = (key: string) =>\n `Anchor \"${key}\": selector matched a column that was already matched by another anchor; please refine the selector to match a different column`;\n\n // O(1) lookup maps built lazily — only when an anchor of the matching kind is\n // encountered. Avoids O(anchors × columns) `deriveNativeId` calls, which were\n // tripping the QuickJS interrupt deadline on tables with many anchors.\n let byId: Map<PObjectId, ColumnSnapshot<PObjectId>> | undefined;\n let byNativeId: Map<NativePObjectId, ColumnSnapshot<PObjectId>> | undefined;\n\n for (const [name, anchor] of Object.entries(anchors)) {\n if (typeof anchor === \"string\") {\n if (byId === undefined) byId = new Map(columns.map((col) => [col.id, col]));\n const found =\n byId.get(anchor) ??\n throwError(`Anchor \"${name}\": column with id \"${anchor}\" not found in sources`);\n if (resovedIds.has(found.id)) {\n throwError(getDuplicateError(name));\n }\n result.set(name, found);\n resovedIds.add(found.id);\n } else if (\"kind\" in anchor) {\n if (!isPColumnSpec(anchor)) throwError(`Anchor \"${name}\": invalid PColumnSpec`);\n if (byNativeId === undefined) {\n byNativeId = new Map(columns.map((col) => [deriveNativeId(col.spec), col]));\n }\n const found =\n byNativeId.get(deriveNativeId(anchor)) ??\n throwError(`Anchor \"${name}\": no column matching spec found in sources`);\n if (resovedIds.has(found.id)) {\n throwError(getDuplicateError(name));\n }\n result.set(name, found);\n resovedIds.add(found.id);\n } else {\n const matched = discoverColumns({\n includeColumns: toMultiColumnSelectors(anchor),\n excludeColumns: undefined,\n axes: [],\n maxHops: 0,\n constraints: matchingModeToConstraints(\"related\"),\n });\n\n if (matched.hits.length === 0) {\n throwError(`Anchor \"${name}\": no columns matched selector`);\n }\n if (matched.hits.length > 1) {\n throwError(\n `Anchor \"${name}\": selector is ambiguous and matched multiple columns; please refine the selector to match exactly one column`,\n );\n }\n if (resovedIds.has(matched.hits[0].hit.columnId as PObjectId)) {\n throwError(getDuplicateError(name));\n }\n\n const id = matched.hits[0].hit.columnId as PObjectId;\n const snap =\n columns.find((col) => col.id === id) ??\n throwError(`Anchor \"${name}\": matched column with id \"${id}\" not found in sources`);\n result.set(name, snap);\n resovedIds.add(snap.id);\n }\n }\n\n if (resovedIds.size === 0) {\n throwError(\"At least one anchor must be resolved to a valid column\");\n }\n\n return result;\n}\n\nfunction remapFromIdxToId(\n qualifications: {\n forQueries: AxisQualification[][];\n forHit: AxisQualification[];\n },\n anchors: ColumnSnapshot<PObjectId>[],\n): MatchQualifications {\n const forQueries = qualifications.forQueries.reduce(\n (acc, qs, i) => (anchors[i] && qs.length > 0 ? acc.set(anchors[i].id, qs) : acc),\n new Map<PObjectId, AxisQualification[]>(),\n );\n return {\n forQueries: forQueries.size > 0 ? Object.fromEntries(forQueries) : undefined,\n forHit: qualifications.forHit.length > 0 ? qualifications.forHit : undefined,\n };\n}\n\nfunction matchingModeToConstraints(mode: MatchingMode): DiscoverColumnsConstraints {\n switch (mode) {\n case \"enrichment\":\n return {\n allowFloatingSourceAxes: true,\n allowFloatingHitAxes: false,\n allowSourceQualifications: true,\n allowHitQualifications: true,\n };\n case \"related\":\n return {\n allowFloatingSourceAxes: true,\n allowFloatingHitAxes: true,\n allowSourceQualifications: true,\n allowHitQualifications: true,\n };\n case \"exact\":\n return {\n allowFloatingSourceAxes: false,\n allowFloatingHitAxes: false,\n allowSourceQualifications: false,\n allowHitQualifications: false,\n };\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"column_collection_builder.js","names":[],"sources":["../../src/columns/column_collection_builder.ts"],"sourcesContent":["import type {\n AxisQualification,\n DiscoverColumnsConstraints,\n DiscoverColumnsRequest,\n DiscoverColumnsResponse,\n MultiColumnSelector,\n NativePObjectId,\n PColumnSpec,\n PObjectId,\n} from \"@milaboratories/pl-model-common\";\nimport { deriveNativeId, isPColumnSpec } from \"@milaboratories/pl-model-common\";\nimport type { ColumnSelector, RelaxedColumnSelector } from \"./column_selector\";\nimport { convertColumnSelectorToMultiColumnSelector } from \"./column_selector\";\nimport { TreeNodeAccessor } from \"../render/accessor\";\nimport type { ColumnSnapshot } from \"./column_snapshot\";\nimport type { ColumnSnapshotProvider, ColumnSource } from \"./column_snapshot_provider\";\nimport { ArrayColumnProvider, toColumnSnapshotProvider } from \"./column_snapshot_provider\";\n\nimport type { PFrameSpecDriver, PoolEntry, SpecFrameHandle } from \"@milaboratories/pl-model-common\";\nimport { throwError } from \"@milaboratories/helpers\";\nimport { getService } from \"../services\";\n\n/** Options for plain collection findColumns. */\nexport interface FindColumnsOptions {\n /** Include columns matching these selectors. If omitted, includes all columns. */\n include?: ColumnSelector;\n /** Exclude columns matching these selectors. */\n exclude?: ColumnSelector;\n}\n\n/** Plain collection — no axis context, selector-based filtering only. */\nexport interface ColumnCollection extends Disposable {\n /** Release the underlying spec frame WASM resource. */\n dispose(): void;\n\n /** Find columns matching selectors. Returns flat list of snapshots.\n * No axis compatibility matching, no linker traversal.\n * Never returns undefined — the \"not ready\" state was absorbed by the builder. */\n findColumns(options?: FindColumnsOptions): ColumnSnapshot<PObjectId>[];\n}\n\n/** Axis-aware column collection with anchored identity derivation. */\nexport interface AnchoredColumnCollection extends Disposable {\n /** Release the underlying spec frame WASM resource. */\n dispose(): void;\n\n /** List of anchors used for discovery, with their resolved specs. */\n getAnchors(): Map<string, ColumnSnapshot<PObjectId>>;\n\n /** Axis-aware column discovery. */\n findColumns(options?: AnchoredFindColumnsOptions): ColumnMatch[];\n\n /** Variant discovery with detailed mapping info for each hit. */\n findColumnVariants(options?: AnchoredFindColumnsOptions): ColumnVariant[];\n}\n\n/** Controls axis matching behavior for anchored discovery. */\nexport type MatchingMode = \"enrichment\" | \"related\" | \"exact\";\n\n/** Options for anchored collection findColumns. */\nexport interface AnchoredFindColumnsOptions extends FindColumnsOptions {\n /** Controls axis matching behavior. Default: 'enrichment'. */\n mode?: MatchingMode;\n /** Maximum linker hops for cross-domain discovery (0 = direct only, default: 4). */\n maxHops?: number;\n}\n\n/** Result of anchored discovery — column snapshot + routing info. */\nexport interface ColumnMatch {\n /** Column snapshot with anchored SUniversalPColumnId. */\n readonly column: ColumnSnapshot<PObjectId>;\n /** Match variants — different ways (paths/qualifications) to reach this column. */\n readonly variants: MatchVariant[];\n}\n\nexport interface ColumnVariant<Id extends PObjectId = PObjectId> {\n /** Column snapshot with anchored SUniversalPColumnId. */\n readonly column: ColumnSnapshot<Id>;\n /** Linker steps traversed to reach this hit; empty for direct matches. */\n readonly path?: { linker: ColumnSnapshot<PObjectId> }[];\n /** Full qualifications needed for integration. */\n readonly qualifications?: MatchQualifications;\n}\n\n/** A single mapping variant describing how a hit column can be integrated. */\nexport interface MatchVariant {\n /** Full qualifications needed for integration. */\n readonly qualifications: MatchQualifications;\n /** Linker steps traversed to reach this hit; empty for direct matches. */\n readonly path: { linker: ColumnSnapshot<PObjectId> }[];\n}\n\n/** Qualifications needed for both already-integrated anchor columns and the hit column. */\nexport interface MatchQualifications {\n /** Qualifications for already-integrated anchor columns */\n readonly forQueries?: Record<PObjectId, AxisQualification[]>;\n /** Qualifications for the hit column. */\n readonly forHit?: AxisQualification[];\n}\n\nexport interface BuildOptions {\n allowPartialColumnList?: true;\n}\n\nexport type AnchorEntry = PObjectId | PColumnSpec | RelaxedColumnSelector;\n\nexport interface AnchoredBuildOptions extends BuildOptions {\n anchors: Record<string, AnchorEntry>;\n}\n\n/**\n * Mutable builder that accumulates column sources, then produces\n * a ColumnCollection (plain) or AnchoredColumnCollection (with anchors).\n *\n * Each output lambda creates its own builder — a constraint of the\n * computable framework where each output tracks its own dependencies.\n */\nexport class ColumnCollectionBuilder {\n private readonly providers: ColumnSnapshotProvider[] = [];\n\n constructor(private readonly specDriver: PFrameSpecDriver = getService(\"pframeSpec\")) {}\n\n /**\n * Register a column source. Sources added first take precedence for dedup.\n * Does NOT accept undefined — if a source isn't available yet,\n * the caller should return undefined from the output lambda.\n */\n addSource(source: ColumnSource | TreeNodeAccessor): this {\n if (source instanceof TreeNodeAccessor) {\n const columns = source.getPColumns();\n if (columns) this.providers.push(new ArrayColumnProvider(columns));\n } else {\n this.providers.push(toColumnSnapshotProvider(source));\n }\n return this;\n }\n\n addSources(sources: (ColumnSource | TreeNodeAccessor)[]): this {\n for (const source of sources) {\n this.addSource(source);\n }\n return this;\n }\n\n /** Plain collection — selector-based filtering, PObjectId namespace. */\n build(): undefined | ColumnCollection;\n build(options: {\n allowPartialColumnList: true;\n }): ColumnCollection & { readonly columnListComplete: boolean };\n /** Anchored collection — axis-aware discovery, SUniversalPColumnId namespace. */\n build(\n options: AnchoredBuildOptions & { allowPartialColumnList: true },\n ): AnchoredColumnCollection & { readonly columnListComplete: boolean };\n build(options: AnchoredBuildOptions): undefined | AnchoredColumnCollection;\n build(\n options?: BuildOptions | AnchoredBuildOptions,\n ):\n | undefined\n | ColumnCollection\n | AnchoredColumnCollection\n | (ColumnCollection & { readonly columnListComplete: boolean })\n | (AnchoredColumnCollection & { readonly columnListComplete: boolean }) {\n const allowPartial = options?.allowPartialColumnList === true;\n\n // Check column list completeness\n const allComplete = this.providers.every((p) => p.isColumnListComplete());\n if (!allComplete && !allowPartial) return undefined;\n\n // Collect all columns, dedup by native ID (first source wins)\n const columns = collectColumns(this.providers);\n const hasAnchors = options !== undefined && \"anchors\" in options;\n\n if (hasAnchors) {\n return new AnchoredColumnCollectionImpl(this.specDriver, {\n anchors: options.anchors,\n columns,\n });\n } else {\n return new ColumnCollectionImpl(this.specDriver, {\n columns,\n });\n }\n }\n}\n\ninterface ColumnCollectionImplOptions {\n readonly columns: ColumnSnapshot<PObjectId>[];\n}\n\nclass ColumnCollectionImpl implements ColumnCollection, Disposable {\n private readonly columns: Map<PObjectId, ColumnSnapshot<PObjectId>>;\n private readonly specFrameEntry: PoolEntry<SpecFrameHandle>;\n\n constructor(\n private readonly specDriver: PFrameSpecDriver,\n options: ColumnCollectionImplOptions,\n ) {\n this.columns = new Map(options.columns.map((col) => [col.id, col]));\n this.specFrameEntry = this.specDriver.createSpecFrame(\n Object.fromEntries(options.columns.map((col) => [col.id, col.spec])),\n );\n }\n\n dispose(): void {\n this.specFrameEntry.unref();\n }\n\n [Symbol.dispose](): void {\n this.dispose();\n }\n\n findColumns(options?: FindColumnsOptions): ColumnSnapshot<PObjectId>[] {\n const includeColumns = options?.include ? toMultiColumnSelectors(options.include) : undefined;\n const excludeColumns = options?.exclude ? toMultiColumnSelectors(options.exclude) : undefined;\n\n const response = this.specDriver.discoverColumns(this.specFrameEntry.key, {\n includeColumns,\n excludeColumns,\n axes: [],\n maxHops: 0,\n constraints: matchingModeToConstraints(\"enrichment\"),\n });\n\n // Map hits back to snapshots\n const results = response.hits\n .map((hit) => this.columns.get(hit.hit.columnId as PObjectId))\n .filter((col): col is ColumnSnapshot<PObjectId> => col !== undefined);\n\n return results;\n }\n}\n\ninterface AnchoredColumnCollectionImplOptions extends ColumnCollectionImplOptions {\n readonly anchors: Record<string, AnchorEntry>;\n}\n\nclass AnchoredColumnCollectionImpl implements AnchoredColumnCollection, Disposable {\n private readonly anchorsMap: Map<string, ColumnSnapshot<PObjectId>>;\n private readonly columnsMap: Map<PObjectId, ColumnSnapshot<PObjectId>>;\n private readonly specFrameEntry: PoolEntry<SpecFrameHandle>;\n\n constructor(\n private readonly specDriver: PFrameSpecDriver,\n options: AnchoredColumnCollectionImplOptions,\n ) {\n // Create spec frame from all collected columns\n this.specFrameEntry = this.specDriver.createSpecFrame(\n Object.fromEntries(options.columns.map((col) => [col.id, col.spec])),\n );\n this.columnsMap = new Map(options.columns.map((col) => [col.id, col]));\n this.anchorsMap = resolveAnchorMap(\n options.anchors,\n options.columns,\n this.specDriver.discoverColumns.bind(this.specDriver, this.specFrameEntry.key),\n );\n }\n\n dispose(): void {\n this.specFrameEntry.unref();\n }\n\n [Symbol.dispose](): void {\n this.dispose();\n }\n\n getAnchors(): Map<string, ColumnSnapshot<PObjectId>> {\n return this.anchorsMap;\n }\n\n findColumns(options?: AnchoredFindColumnsOptions): ColumnMatch[] {\n const mode = options?.mode ?? \"enrichment\";\n const constraints = matchingModeToConstraints(mode);\n const includeColumns = options?.include ? toMultiColumnSelectors(options.include) : undefined;\n const excludeColumns = options?.exclude ? toMultiColumnSelectors(options.exclude) : undefined;\n const anchors = Array.from(this.anchorsMap.values());\n const response = this.specDriver.discoverColumns(this.specFrameEntry.key, {\n includeColumns,\n excludeColumns,\n constraints,\n maxHops: options?.maxHops ?? 4,\n axes: anchors.map((anchor) => ({\n axesSpec: anchor.spec.axesSpec,\n qualifications: [],\n })),\n });\n\n const byColumn = response.hits.reduce<Map<PObjectId, ColumnMatch>>((acc, hit) => {\n const origId = hit.hit.columnId as PObjectId;\n const col =\n this.columnsMap.get(origId) ??\n throwError(`Column with id ${origId} not found in collection`);\n\n const path = hit.path.map((step) => {\n if (step.type !== \"linker\") {\n throw new Error(`Unexpected discover-columns step type: ${step.type}`);\n }\n\n return {\n linker:\n this.columnsMap.get(step.linker.columnId) ??\n throwError(`Linker column with id ${step.linker.columnId} not found in collection`),\n };\n });\n const variants: MatchVariant[] = hit.mappingVariants.map((v) => ({\n path,\n qualifications: remapFromIdxToId(v.qualifications, anchors),\n }));\n const existing = acc.get(origId);\n return acc.set(\n origId,\n existing === undefined\n ? { column: col, variants }\n : { ...existing, variants: [...existing.variants, ...variants] },\n );\n }, new Map());\n\n return Array.from(byColumn.values());\n }\n\n findColumnVariants(options?: AnchoredFindColumnsOptions): ColumnVariant[] {\n const matches = this.findColumns(options);\n return matches.flatMap((match) =>\n match.variants.map((variant) => ({\n column: match.column,\n path: variant.path,\n qualifications: variant.qualifications,\n })),\n );\n }\n}\n\n/**\n * Collect all columns from all providers, dedup by NativePObjectId.\n * First source wins.\n */\nfunction collectColumns(providers: ColumnSnapshotProvider[]): ColumnSnapshot<PObjectId>[] {\n const seen = new Set<NativePObjectId>();\n const result: ColumnSnapshot<PObjectId>[] = [];\n\n for (const provider of providers) {\n const columns = provider.getAllColumns();\n for (const col of columns) {\n const nativeId = deriveNativeId(col.spec);\n if (seen.has(nativeId)) continue;\n seen.add(nativeId);\n result.push(col);\n }\n }\n\n return result;\n}\n\n/** Normalize ColumnSelector (relaxed, single or array) to MultiColumnSelector[]. */\nfunction toMultiColumnSelectors(input: ColumnSelector): MultiColumnSelector[] {\n return convertColumnSelectorToMultiColumnSelector(input);\n}\n\n/**\n * Resolve each anchor entry to a ColumnSnapshot from the collected columns.\n * - PObjectId (string): looked up by id in the collected columns\n * - PColumnSpec: matched by deriveNativeId against collected columns\n * - RelaxedColumnSelector: resolved via discoverColumns in \"exact\" mode;\n * must match exactly one column\n * Throws on unresolved, ambiguous, or duplicated matches. Requires at least one\n * anchor to resolve.\n */\nfunction resolveAnchorMap(\n anchors: Record<string, AnchorEntry>,\n columns: ColumnSnapshot<PObjectId>[],\n discoverColumns: (request: DiscoverColumnsRequest) => DiscoverColumnsResponse,\n): Map<string, ColumnSnapshot<PObjectId>> {\n const result = new Map<string, ColumnSnapshot<PObjectId>>();\n const resovedIds = new Set<PObjectId>();\n const getDuplicateError = (key: string) =>\n `Anchor \"${key}\": selector matched a column that was already matched by another anchor; please refine the selector to match a different column`;\n\n // O(1) lookup maps built lazily — only when an anchor of the matching kind is\n // encountered. Avoids O(anchors × columns) `deriveNativeId` calls, which were\n // tripping the QuickJS interrupt deadline on tables with many anchors.\n let byId: Map<PObjectId, ColumnSnapshot<PObjectId>> | undefined;\n let byNativeId: Map<NativePObjectId, ColumnSnapshot<PObjectId>> | undefined;\n\n for (const [name, anchor] of Object.entries(anchors)) {\n if (typeof anchor === \"string\") {\n if (byId === undefined) byId = new Map(columns.map((col) => [col.id, col]));\n const found =\n byId.get(anchor) ??\n throwError(`Anchor \"${name}\": column with id \"${anchor}\" not found in sources`);\n if (resovedIds.has(found.id)) {\n throwError(getDuplicateError(name));\n }\n result.set(name, found);\n resovedIds.add(found.id);\n } else if (\"kind\" in anchor) {\n if (!isPColumnSpec(anchor)) throwError(`Anchor \"${name}\": invalid PColumnSpec`);\n if (byNativeId === undefined) {\n byNativeId = new Map(columns.map((col) => [deriveNativeId(col.spec), col]));\n }\n const found =\n byNativeId.get(deriveNativeId(anchor)) ??\n throwError(`Anchor \"${name}\": no column matching spec found in sources`);\n if (resovedIds.has(found.id)) {\n throwError(getDuplicateError(name));\n }\n result.set(name, found);\n resovedIds.add(found.id);\n } else {\n const matched = discoverColumns({\n includeColumns: toMultiColumnSelectors(anchor),\n excludeColumns: undefined,\n axes: [],\n maxHops: 0,\n constraints: matchingModeToConstraints(\"related\"),\n });\n\n if (matched.hits.length === 0) {\n throwError(`Anchor \"${name}\": no columns matched selector`);\n }\n if (matched.hits.length > 1) {\n throwError(\n `Anchor \"${name}\": selector is ambiguous and matched multiple columns; please refine the selector to match exactly one column`,\n );\n }\n if (resovedIds.has(matched.hits[0].hit.columnId as PObjectId)) {\n throwError(getDuplicateError(name));\n }\n\n const id = matched.hits[0].hit.columnId as PObjectId;\n const snap =\n columns.find((col) => col.id === id) ??\n throwError(`Anchor \"${name}\": matched column with id \"${id}\" not found in sources`);\n result.set(name, snap);\n resovedIds.add(snap.id);\n }\n }\n\n if (resovedIds.size === 0) {\n throwError(\"At least one anchor must be resolved to a valid column\");\n }\n\n return result;\n}\n\nfunction remapFromIdxToId(\n qualifications: {\n forQueries: AxisQualification[][];\n forHit: AxisQualification[];\n },\n anchors: ColumnSnapshot<PObjectId>[],\n): MatchQualifications {\n const forQueries = qualifications.forQueries.reduce(\n (acc, qs, i) => (anchors[i] && qs.length > 0 ? acc.set(anchors[i].id, qs) : acc),\n new Map<PObjectId, AxisQualification[]>(),\n );\n return {\n forQueries: forQueries.size > 0 ? Object.fromEntries(forQueries) : undefined,\n forHit: qualifications.forHit.length > 0 ? qualifications.forHit : undefined,\n };\n}\n\nfunction matchingModeToConstraints(mode: MatchingMode): DiscoverColumnsConstraints {\n switch (mode) {\n case \"enrichment\":\n return {\n allowFloatingSourceAxes: true,\n allowFloatingHitAxes: false,\n allowSourceQualifications: true,\n allowHitQualifications: true,\n };\n case \"related\":\n return {\n allowFloatingSourceAxes: true,\n allowFloatingHitAxes: true,\n allowSourceQualifications: true,\n allowHitQualifications: true,\n };\n case \"exact\":\n return {\n allowFloatingSourceAxes: false,\n allowFloatingHitAxes: false,\n allowSourceQualifications: false,\n allowHitQualifications: false,\n };\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"column_selector.cjs","names":[],"sources":["../../src/columns/column_selector.ts"],"sourcesContent":["import type {\n AxisValueType,\n ColumnValueType,\n MultiAxisSelector,\n MultiColumnSelector,\n StringMatcher,\n} from \"@milaboratories/pl-model-common\";\n\nexport type { StringMatcher } from \"@milaboratories/pl-model-common\";\n\n// --- Relaxed types ---\n\n/** Relaxed string matcher input: plain string, single matcher, or array of mixed. */\nexport type RelaxedStringMatchers = string | StringMatcher | (string | StringMatcher)[];\n\n/** Relaxed record matcher: values can be plain strings or relaxed matchers. */\nexport type RelaxedRecord = Record<string, RelaxedStringMatchers>;\n\n/** Relaxed axis selector — accepts plain strings where strict requires StringMatcher[]. */\nexport interface RelaxedAxisSelector {\n name?: RelaxedStringMatchers;\n type?: AxisValueType | AxisValueType[];\n domain?: RelaxedRecord;\n contextDomain?: RelaxedRecord;\n annotations?: RelaxedRecord;\n}\n\n/** Relaxed column selector — convenient hand-written form. */\nexport interface RelaxedColumnSelector {\n name?: RelaxedStringMatchers;\n type?: ColumnValueType | ColumnValueType[];\n domain?: RelaxedRecord;\n contextDomain?: RelaxedRecord;\n annotations?: RelaxedRecord;\n axes?: RelaxedAxisSelector[];\n partialAxesMatch?: boolean;\n}\n\n/** One or many relaxed column selectors; normalizes to MultiColumnSelector[]. */\nexport type ColumnSelector = RelaxedColumnSelector | RelaxedColumnSelector[];\n\n// --- Normalization ---\n\nfunction normalizeStringMatchers(input: RelaxedStringMatchers): StringMatcher[] {\n if (typeof input === \"string\") return [{ type: \"regex\", value: input }];\n if (!Array.isArray(input)) return [input];\n return input.map((v) =>\n typeof v === \"string\" ? ({ type: \"regex\", value: v } satisfies StringMatcher) : v,\n );\n}\n\nfunction normalizeRecord(input: RelaxedRecord): Record<string, StringMatcher[]> {\n const result: Record<string, StringMatcher[]> = {};\n for (const [key, value] of Object.entries(input)) {\n result[key] = normalizeStringMatchers(value);\n }\n return result;\n}\n\nfunction normalizeTypes<T>(input: T | T[]): T[] {\n return Array.isArray(input) ? input : [input];\n}\n\ntype Mutable<T> = { -readonly [K in keyof T]: T[K] };\n\nexport function convertRelaxedAxisSelectorToMultiAxisSelector(\n input: RelaxedAxisSelector,\n): MultiAxisSelector {\n const result: Mutable<MultiAxisSelector> = {};\n if (input.name !== undefined) result.name = normalizeStringMatchers(input.name);\n if (input.type !== undefined) result.type = normalizeTypes(input.type);\n if (input.domain !== undefined) result.domain = normalizeRecord(input.domain);\n if (input.contextDomain !== undefined)\n result.contextDomain = normalizeRecord(input.contextDomain);\n if (input.annotations !== undefined) result.annotations = normalizeRecord(input.annotations);\n return result;\n}\n\nexport function convertRelaxedColumnSelectorToMultiColumnSelector(\n input: RelaxedColumnSelector,\n): MultiColumnSelector {\n const result: Mutable<MultiColumnSelector> = {};\n if (input.name !== undefined) result.name = normalizeStringMatchers(input.name);\n if (input.type !== undefined) result.type = normalizeTypes(input.type);\n if (input.domain !== undefined) result.domain = normalizeRecord(input.domain);\n if (input.contextDomain !== undefined)\n result.contextDomain = normalizeRecord(input.contextDomain);\n if (input.annotations !== undefined) result.annotations = normalizeRecord(input.annotations);\n if (input.axes !== undefined)\n result.axes = input.axes.map(convertRelaxedAxisSelectorToMultiAxisSelector);\n if (input.partialAxesMatch !== undefined) result.partialAxesMatch = input.partialAxesMatch;\n return result;\n}\n\nexport function convertColumnSelectorToMultiColumnSelector(\n input: ColumnSelector,\n): MultiColumnSelector[] {\n const arr = Array.isArray(input) ? input : [input];\n return arr.map(convertRelaxedColumnSelectorToMultiColumnSelector);\n}\n"],"mappings":";AA2CA,SAAS,wBAAwB,OAA+C;
|
|
1
|
+
{"version":3,"file":"column_selector.cjs","names":[],"sources":["../../src/columns/column_selector.ts"],"sourcesContent":["import type {\n AxisValueType,\n ColumnValueType,\n MultiAxisSelector,\n MultiColumnSelector,\n StringMatcher,\n} from \"@milaboratories/pl-model-common\";\n\nexport type { StringMatcher } from \"@milaboratories/pl-model-common\";\n\n// --- Relaxed types ---\n\n/** Relaxed string matcher input: plain string, single matcher, or array of mixed. */\nexport type RelaxedStringMatchers = string | StringMatcher | (string | StringMatcher)[];\n\n/** Relaxed record matcher: values can be plain strings or relaxed matchers. */\nexport type RelaxedRecord = Record<string, RelaxedStringMatchers>;\n\n/** Relaxed axis selector — accepts plain strings where strict requires StringMatcher[]. */\nexport interface RelaxedAxisSelector {\n name?: RelaxedStringMatchers;\n type?: AxisValueType | AxisValueType[];\n domain?: RelaxedRecord;\n contextDomain?: RelaxedRecord;\n annotations?: RelaxedRecord;\n}\n\n/** Relaxed column selector — convenient hand-written form. */\nexport interface RelaxedColumnSelector {\n name?: RelaxedStringMatchers;\n type?: ColumnValueType | ColumnValueType[];\n domain?: RelaxedRecord;\n contextDomain?: RelaxedRecord;\n annotations?: RelaxedRecord;\n axes?: RelaxedAxisSelector[];\n partialAxesMatch?: boolean;\n}\n\n/** One or many relaxed column selectors; normalizes to MultiColumnSelector[]. */\nexport type ColumnSelector = RelaxedColumnSelector | RelaxedColumnSelector[];\n\n// --- Normalization ---\n\nfunction normalizeStringMatchers(input: RelaxedStringMatchers): StringMatcher[] {\n if (typeof input === \"string\") return [{ type: \"regex\", value: input }];\n if (!Array.isArray(input)) return [input];\n return input.map((v) =>\n typeof v === \"string\" ? ({ type: \"regex\", value: v } satisfies StringMatcher) : v,\n );\n}\n\nfunction normalizeRecord(input: RelaxedRecord): Record<string, StringMatcher[]> {\n const result: Record<string, StringMatcher[]> = {};\n for (const [key, value] of Object.entries(input)) {\n result[key] = normalizeStringMatchers(value);\n }\n return result;\n}\n\nfunction normalizeTypes<T>(input: T | T[]): T[] {\n return Array.isArray(input) ? input : [input];\n}\n\ntype Mutable<T> = { -readonly [K in keyof T]: T[K] };\n\nexport function convertRelaxedAxisSelectorToMultiAxisSelector(\n input: RelaxedAxisSelector,\n): MultiAxisSelector {\n const result: Mutable<MultiAxisSelector> = {};\n if (input.name !== undefined) result.name = normalizeStringMatchers(input.name);\n if (input.type !== undefined) result.type = normalizeTypes(input.type);\n if (input.domain !== undefined) result.domain = normalizeRecord(input.domain);\n if (input.contextDomain !== undefined)\n result.contextDomain = normalizeRecord(input.contextDomain);\n if (input.annotations !== undefined) result.annotations = normalizeRecord(input.annotations);\n return result;\n}\n\nexport function convertRelaxedColumnSelectorToMultiColumnSelector(\n input: RelaxedColumnSelector,\n): MultiColumnSelector {\n const result: Mutable<MultiColumnSelector> = {};\n if (input.name !== undefined) result.name = normalizeStringMatchers(input.name);\n if (input.type !== undefined) result.type = normalizeTypes(input.type);\n if (input.domain !== undefined) result.domain = normalizeRecord(input.domain);\n if (input.contextDomain !== undefined)\n result.contextDomain = normalizeRecord(input.contextDomain);\n if (input.annotations !== undefined) result.annotations = normalizeRecord(input.annotations);\n if (input.axes !== undefined)\n result.axes = input.axes.map(convertRelaxedAxisSelectorToMultiAxisSelector);\n if (input.partialAxesMatch !== undefined) result.partialAxesMatch = input.partialAxesMatch;\n return result;\n}\n\nexport function convertColumnSelectorToMultiColumnSelector(\n input: ColumnSelector,\n): MultiColumnSelector[] {\n const arr = Array.isArray(input) ? input : [input];\n return arr.map(convertRelaxedColumnSelectorToMultiColumnSelector);\n}\n"],"mappings":";AA2CA,SAAS,wBAAwB,OAA+C;CAC9E,IAAI,OAAO,UAAU,UAAU,OAAO,CAAC;EAAE,MAAM;EAAS,OAAO;CAAM,CAAC;CACtE,IAAI,CAAC,MAAM,QAAQ,KAAK,GAAG,OAAO,CAAC,KAAK;CACxC,OAAO,MAAM,KAAK,MAChB,OAAO,MAAM,WAAY;EAAE,MAAM;EAAS,OAAO;CAAE,IAA6B,CAClF;AACF;AAEA,SAAS,gBAAgB,OAAuD;CAC9E,MAAM,SAA0C,CAAC;CACjD,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,KAAK,GAC7C,OAAO,OAAO,wBAAwB,KAAK;CAE7C,OAAO;AACT;AAEA,SAAS,eAAkB,OAAqB;CAC9C,OAAO,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC,KAAK;AAC9C;AAIA,SAAgB,8CACd,OACmB;CACnB,MAAM,SAAqC,CAAC;CAC5C,IAAI,MAAM,SAAS,KAAA,GAAW,OAAO,OAAO,wBAAwB,MAAM,IAAI;CAC9E,IAAI,MAAM,SAAS,KAAA,GAAW,OAAO,OAAO,eAAe,MAAM,IAAI;CACrE,IAAI,MAAM,WAAW,KAAA,GAAW,OAAO,SAAS,gBAAgB,MAAM,MAAM;CAC5E,IAAI,MAAM,kBAAkB,KAAA,GAC1B,OAAO,gBAAgB,gBAAgB,MAAM,aAAa;CAC5D,IAAI,MAAM,gBAAgB,KAAA,GAAW,OAAO,cAAc,gBAAgB,MAAM,WAAW;CAC3F,OAAO;AACT;AAEA,SAAgB,kDACd,OACqB;CACrB,MAAM,SAAuC,CAAC;CAC9C,IAAI,MAAM,SAAS,KAAA,GAAW,OAAO,OAAO,wBAAwB,MAAM,IAAI;CAC9E,IAAI,MAAM,SAAS,KAAA,GAAW,OAAO,OAAO,eAAe,MAAM,IAAI;CACrE,IAAI,MAAM,WAAW,KAAA,GAAW,OAAO,SAAS,gBAAgB,MAAM,MAAM;CAC5E,IAAI,MAAM,kBAAkB,KAAA,GAC1B,OAAO,gBAAgB,gBAAgB,MAAM,aAAa;CAC5D,IAAI,MAAM,gBAAgB,KAAA,GAAW,OAAO,cAAc,gBAAgB,MAAM,WAAW;CAC3F,IAAI,MAAM,SAAS,KAAA,GACjB,OAAO,OAAO,MAAM,KAAK,IAAI,6CAA6C;CAC5E,IAAI,MAAM,qBAAqB,KAAA,GAAW,OAAO,mBAAmB,MAAM;CAC1E,OAAO;AACT;AAEA,SAAgB,2CACd,OACuB;CAEvB,QADY,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC,KAAK,EAAA,CACtC,IAAI,iDAAiD;AAClE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"column_selector.d.ts","names":[],"sources":["../../src/columns/column_selector.ts"],"mappings":";;;;KAaY,qBAAA,YAAiC,aAAA,aAA0B,
|
|
1
|
+
{"version":3,"file":"column_selector.d.ts","names":[],"sources":["../../src/columns/column_selector.ts"],"mappings":";;;;KAaY,qBAAA,YAAiC,aAAA,aAA0B,aAAa;;KAGxE,aAAA,GAAgB,MAAM,SAAS,qBAAA;;UAG1B,mBAAA;EACf,IAAA,GAAO,qBAAA;EACP,IAAA,GAAO,aAAA,GAAgB,aAAA;EACvB,MAAA,GAAS,aAAA;EACT,aAAA,GAAgB,aAAA;EAChB,WAAA,GAAc,aAAA;AAAA;;UAIC,qBAAA;EACf,IAAA,GAAO,qBAAA;EACP,IAAA,GAAO,eAAA,GAAkB,eAAA;EACzB,MAAA,GAAS,aAAA;EACT,aAAA,GAAgB,aAAA;EAChB,WAAA,GAAc,aAAA;EACd,IAAA,GAAO,mBAAA;EACP,gBAAA;AAAA;;KAIU,cAAA,GAAiB,qBAAA,GAAwB,qBAAqB;AAAA,iBA0B1D,6CAAA,CACd,KAAA,EAAO,mBAAA,GACN,iBAAiB;AAAA,iBAWJ,iDAAA,CACd,KAAA,EAAO,qBAAA,GACN,mBAAmB;AAAA,iBAcN,0CAAA,CACd,KAAA,EAAO,cAAA,GACN,mBAAmB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"column_selector.js","names":[],"sources":["../../src/columns/column_selector.ts"],"sourcesContent":["import type {\n AxisValueType,\n ColumnValueType,\n MultiAxisSelector,\n MultiColumnSelector,\n StringMatcher,\n} from \"@milaboratories/pl-model-common\";\n\nexport type { StringMatcher } from \"@milaboratories/pl-model-common\";\n\n// --- Relaxed types ---\n\n/** Relaxed string matcher input: plain string, single matcher, or array of mixed. */\nexport type RelaxedStringMatchers = string | StringMatcher | (string | StringMatcher)[];\n\n/** Relaxed record matcher: values can be plain strings or relaxed matchers. */\nexport type RelaxedRecord = Record<string, RelaxedStringMatchers>;\n\n/** Relaxed axis selector — accepts plain strings where strict requires StringMatcher[]. */\nexport interface RelaxedAxisSelector {\n name?: RelaxedStringMatchers;\n type?: AxisValueType | AxisValueType[];\n domain?: RelaxedRecord;\n contextDomain?: RelaxedRecord;\n annotations?: RelaxedRecord;\n}\n\n/** Relaxed column selector — convenient hand-written form. */\nexport interface RelaxedColumnSelector {\n name?: RelaxedStringMatchers;\n type?: ColumnValueType | ColumnValueType[];\n domain?: RelaxedRecord;\n contextDomain?: RelaxedRecord;\n annotations?: RelaxedRecord;\n axes?: RelaxedAxisSelector[];\n partialAxesMatch?: boolean;\n}\n\n/** One or many relaxed column selectors; normalizes to MultiColumnSelector[]. */\nexport type ColumnSelector = RelaxedColumnSelector | RelaxedColumnSelector[];\n\n// --- Normalization ---\n\nfunction normalizeStringMatchers(input: RelaxedStringMatchers): StringMatcher[] {\n if (typeof input === \"string\") return [{ type: \"regex\", value: input }];\n if (!Array.isArray(input)) return [input];\n return input.map((v) =>\n typeof v === \"string\" ? ({ type: \"regex\", value: v } satisfies StringMatcher) : v,\n );\n}\n\nfunction normalizeRecord(input: RelaxedRecord): Record<string, StringMatcher[]> {\n const result: Record<string, StringMatcher[]> = {};\n for (const [key, value] of Object.entries(input)) {\n result[key] = normalizeStringMatchers(value);\n }\n return result;\n}\n\nfunction normalizeTypes<T>(input: T | T[]): T[] {\n return Array.isArray(input) ? input : [input];\n}\n\ntype Mutable<T> = { -readonly [K in keyof T]: T[K] };\n\nexport function convertRelaxedAxisSelectorToMultiAxisSelector(\n input: RelaxedAxisSelector,\n): MultiAxisSelector {\n const result: Mutable<MultiAxisSelector> = {};\n if (input.name !== undefined) result.name = normalizeStringMatchers(input.name);\n if (input.type !== undefined) result.type = normalizeTypes(input.type);\n if (input.domain !== undefined) result.domain = normalizeRecord(input.domain);\n if (input.contextDomain !== undefined)\n result.contextDomain = normalizeRecord(input.contextDomain);\n if (input.annotations !== undefined) result.annotations = normalizeRecord(input.annotations);\n return result;\n}\n\nexport function convertRelaxedColumnSelectorToMultiColumnSelector(\n input: RelaxedColumnSelector,\n): MultiColumnSelector {\n const result: Mutable<MultiColumnSelector> = {};\n if (input.name !== undefined) result.name = normalizeStringMatchers(input.name);\n if (input.type !== undefined) result.type = normalizeTypes(input.type);\n if (input.domain !== undefined) result.domain = normalizeRecord(input.domain);\n if (input.contextDomain !== undefined)\n result.contextDomain = normalizeRecord(input.contextDomain);\n if (input.annotations !== undefined) result.annotations = normalizeRecord(input.annotations);\n if (input.axes !== undefined)\n result.axes = input.axes.map(convertRelaxedAxisSelectorToMultiAxisSelector);\n if (input.partialAxesMatch !== undefined) result.partialAxesMatch = input.partialAxesMatch;\n return result;\n}\n\nexport function convertColumnSelectorToMultiColumnSelector(\n input: ColumnSelector,\n): MultiColumnSelector[] {\n const arr = Array.isArray(input) ? input : [input];\n return arr.map(convertRelaxedColumnSelectorToMultiColumnSelector);\n}\n"],"mappings":";AA2CA,SAAS,wBAAwB,OAA+C;
|
|
1
|
+
{"version":3,"file":"column_selector.js","names":[],"sources":["../../src/columns/column_selector.ts"],"sourcesContent":["import type {\n AxisValueType,\n ColumnValueType,\n MultiAxisSelector,\n MultiColumnSelector,\n StringMatcher,\n} from \"@milaboratories/pl-model-common\";\n\nexport type { StringMatcher } from \"@milaboratories/pl-model-common\";\n\n// --- Relaxed types ---\n\n/** Relaxed string matcher input: plain string, single matcher, or array of mixed. */\nexport type RelaxedStringMatchers = string | StringMatcher | (string | StringMatcher)[];\n\n/** Relaxed record matcher: values can be plain strings or relaxed matchers. */\nexport type RelaxedRecord = Record<string, RelaxedStringMatchers>;\n\n/** Relaxed axis selector — accepts plain strings where strict requires StringMatcher[]. */\nexport interface RelaxedAxisSelector {\n name?: RelaxedStringMatchers;\n type?: AxisValueType | AxisValueType[];\n domain?: RelaxedRecord;\n contextDomain?: RelaxedRecord;\n annotations?: RelaxedRecord;\n}\n\n/** Relaxed column selector — convenient hand-written form. */\nexport interface RelaxedColumnSelector {\n name?: RelaxedStringMatchers;\n type?: ColumnValueType | ColumnValueType[];\n domain?: RelaxedRecord;\n contextDomain?: RelaxedRecord;\n annotations?: RelaxedRecord;\n axes?: RelaxedAxisSelector[];\n partialAxesMatch?: boolean;\n}\n\n/** One or many relaxed column selectors; normalizes to MultiColumnSelector[]. */\nexport type ColumnSelector = RelaxedColumnSelector | RelaxedColumnSelector[];\n\n// --- Normalization ---\n\nfunction normalizeStringMatchers(input: RelaxedStringMatchers): StringMatcher[] {\n if (typeof input === \"string\") return [{ type: \"regex\", value: input }];\n if (!Array.isArray(input)) return [input];\n return input.map((v) =>\n typeof v === \"string\" ? ({ type: \"regex\", value: v } satisfies StringMatcher) : v,\n );\n}\n\nfunction normalizeRecord(input: RelaxedRecord): Record<string, StringMatcher[]> {\n const result: Record<string, StringMatcher[]> = {};\n for (const [key, value] of Object.entries(input)) {\n result[key] = normalizeStringMatchers(value);\n }\n return result;\n}\n\nfunction normalizeTypes<T>(input: T | T[]): T[] {\n return Array.isArray(input) ? input : [input];\n}\n\ntype Mutable<T> = { -readonly [K in keyof T]: T[K] };\n\nexport function convertRelaxedAxisSelectorToMultiAxisSelector(\n input: RelaxedAxisSelector,\n): MultiAxisSelector {\n const result: Mutable<MultiAxisSelector> = {};\n if (input.name !== undefined) result.name = normalizeStringMatchers(input.name);\n if (input.type !== undefined) result.type = normalizeTypes(input.type);\n if (input.domain !== undefined) result.domain = normalizeRecord(input.domain);\n if (input.contextDomain !== undefined)\n result.contextDomain = normalizeRecord(input.contextDomain);\n if (input.annotations !== undefined) result.annotations = normalizeRecord(input.annotations);\n return result;\n}\n\nexport function convertRelaxedColumnSelectorToMultiColumnSelector(\n input: RelaxedColumnSelector,\n): MultiColumnSelector {\n const result: Mutable<MultiColumnSelector> = {};\n if (input.name !== undefined) result.name = normalizeStringMatchers(input.name);\n if (input.type !== undefined) result.type = normalizeTypes(input.type);\n if (input.domain !== undefined) result.domain = normalizeRecord(input.domain);\n if (input.contextDomain !== undefined)\n result.contextDomain = normalizeRecord(input.contextDomain);\n if (input.annotations !== undefined) result.annotations = normalizeRecord(input.annotations);\n if (input.axes !== undefined)\n result.axes = input.axes.map(convertRelaxedAxisSelectorToMultiAxisSelector);\n if (input.partialAxesMatch !== undefined) result.partialAxesMatch = input.partialAxesMatch;\n return result;\n}\n\nexport function convertColumnSelectorToMultiColumnSelector(\n input: ColumnSelector,\n): MultiColumnSelector[] {\n const arr = Array.isArray(input) ? input : [input];\n return arr.map(convertRelaxedColumnSelectorToMultiColumnSelector);\n}\n"],"mappings":";AA2CA,SAAS,wBAAwB,OAA+C;CAC9E,IAAI,OAAO,UAAU,UAAU,OAAO,CAAC;EAAE,MAAM;EAAS,OAAO;CAAM,CAAC;CACtE,IAAI,CAAC,MAAM,QAAQ,KAAK,GAAG,OAAO,CAAC,KAAK;CACxC,OAAO,MAAM,KAAK,MAChB,OAAO,MAAM,WAAY;EAAE,MAAM;EAAS,OAAO;CAAE,IAA6B,CAClF;AACF;AAEA,SAAS,gBAAgB,OAAuD;CAC9E,MAAM,SAA0C,CAAC;CACjD,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,KAAK,GAC7C,OAAO,OAAO,wBAAwB,KAAK;CAE7C,OAAO;AACT;AAEA,SAAS,eAAkB,OAAqB;CAC9C,OAAO,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC,KAAK;AAC9C;AAIA,SAAgB,8CACd,OACmB;CACnB,MAAM,SAAqC,CAAC;CAC5C,IAAI,MAAM,SAAS,KAAA,GAAW,OAAO,OAAO,wBAAwB,MAAM,IAAI;CAC9E,IAAI,MAAM,SAAS,KAAA,GAAW,OAAO,OAAO,eAAe,MAAM,IAAI;CACrE,IAAI,MAAM,WAAW,KAAA,GAAW,OAAO,SAAS,gBAAgB,MAAM,MAAM;CAC5E,IAAI,MAAM,kBAAkB,KAAA,GAC1B,OAAO,gBAAgB,gBAAgB,MAAM,aAAa;CAC5D,IAAI,MAAM,gBAAgB,KAAA,GAAW,OAAO,cAAc,gBAAgB,MAAM,WAAW;CAC3F,OAAO;AACT;AAEA,SAAgB,kDACd,OACqB;CACrB,MAAM,SAAuC,CAAC;CAC9C,IAAI,MAAM,SAAS,KAAA,GAAW,OAAO,OAAO,wBAAwB,MAAM,IAAI;CAC9E,IAAI,MAAM,SAAS,KAAA,GAAW,OAAO,OAAO,eAAe,MAAM,IAAI;CACrE,IAAI,MAAM,WAAW,KAAA,GAAW,OAAO,SAAS,gBAAgB,MAAM,MAAM;CAC5E,IAAI,MAAM,kBAAkB,KAAA,GAC1B,OAAO,gBAAgB,gBAAgB,MAAM,aAAa;CAC5D,IAAI,MAAM,gBAAgB,KAAA,GAAW,OAAO,cAAc,gBAAgB,MAAM,WAAW;CAC3F,IAAI,MAAM,SAAS,KAAA,GACjB,OAAO,OAAO,MAAM,KAAK,IAAI,6CAA6C;CAC5E,IAAI,MAAM,qBAAqB,KAAA,GAAW,OAAO,mBAAmB,MAAM;CAC1E,OAAO;AACT;AAEA,SAAgB,2CACd,OACuB;CAEvB,QADY,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC,KAAK,EAAA,CACtC,IAAI,iDAAiD;AAClE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"column_snapshot.cjs","names":[],"sources":["../../src/columns/column_snapshot.ts"],"sourcesContent":["import type { PColumnSpec, PObjectId, SUniversalPColumnId } from \"@milaboratories/pl-model-common\";\nimport type { PColumnDataUniversal } from \"../render/internal\";\n\n// --- ColumnSnapshot ---\n\n/** Data status of a column snapshot. */\nexport type ColumnDataStatus = \"ready\" | \"computing\" | \"absent\";\n\n/**\n * Immutable snapshot of a column: spec, data status, and lazy data accessor.\n *\n * - `dataStatus` is readable without marking the render context unstable.\n * - `data` holds an active object when data exists (ready or computing),\n * or `undefined` when data is permanently absent.\n */\nexport interface ColumnSnapshot<\n Id extends PObjectId | SUniversalPColumnId,\n Data = PColumnDataUniversal,\n> {\n readonly id: Id;\n readonly spec: PColumnSpec;\n readonly dataStatus: ColumnDataStatus;\n\n /**\n * Lazy data accessor.\n * - `'ready'`: `data.get()` returns column data, context stays stable.\n * - `'computing'`: `data.get()` returns `undefined`, marks context unstable.\n * - `'absent'`: `data` is `undefined` — no active object, no instability.\n */\n readonly data: ColumnData<Data> | undefined;\n}\n\n// --- ColumnData ---\n\n/**\n * Active object wrapping lazy column data access.\n * Accessing data on a computing column marks the render context unstable.\n */\nexport interface ColumnData<Data = PColumnDataUniversal> {\n get(): Data | undefined;\n}\n\n/** Creates a ColumnData active object for a ready column. */\nexport function createReadyColumnData(getData: () => PColumnDataUniversal | undefined): ColumnData {\n return { get: getData };\n}\n\n// --- Snapshot construction helpers ---\n\n/** Creates a ColumnSnapshot from parts. */\nexport function createColumnSnapshot<Id extends PObjectId>(\n id: Id,\n spec: PColumnSpec,\n data: undefined | ColumnData,\n dataStatus: ColumnDataStatus,\n): ColumnSnapshot<Id> {\n return { id, spec, data, dataStatus };\n}\n"],"mappings":";;AA2CA,SAAgB,sBAAsB,SAA6D;
|
|
1
|
+
{"version":3,"file":"column_snapshot.cjs","names":[],"sources":["../../src/columns/column_snapshot.ts"],"sourcesContent":["import type { PColumnSpec, PObjectId, SUniversalPColumnId } from \"@milaboratories/pl-model-common\";\nimport type { PColumnDataUniversal } from \"../render/internal\";\n\n// --- ColumnSnapshot ---\n\n/** Data status of a column snapshot. */\nexport type ColumnDataStatus = \"ready\" | \"computing\" | \"absent\";\n\n/**\n * Immutable snapshot of a column: spec, data status, and lazy data accessor.\n *\n * - `dataStatus` is readable without marking the render context unstable.\n * - `data` holds an active object when data exists (ready or computing),\n * or `undefined` when data is permanently absent.\n */\nexport interface ColumnSnapshot<\n Id extends PObjectId | SUniversalPColumnId,\n Data = PColumnDataUniversal,\n> {\n readonly id: Id;\n readonly spec: PColumnSpec;\n readonly dataStatus: ColumnDataStatus;\n\n /**\n * Lazy data accessor.\n * - `'ready'`: `data.get()` returns column data, context stays stable.\n * - `'computing'`: `data.get()` returns `undefined`, marks context unstable.\n * - `'absent'`: `data` is `undefined` — no active object, no instability.\n */\n readonly data: ColumnData<Data> | undefined;\n}\n\n// --- ColumnData ---\n\n/**\n * Active object wrapping lazy column data access.\n * Accessing data on a computing column marks the render context unstable.\n */\nexport interface ColumnData<Data = PColumnDataUniversal> {\n get(): Data | undefined;\n}\n\n/** Creates a ColumnData active object for a ready column. */\nexport function createReadyColumnData(getData: () => PColumnDataUniversal | undefined): ColumnData {\n return { get: getData };\n}\n\n// --- Snapshot construction helpers ---\n\n/** Creates a ColumnSnapshot from parts. */\nexport function createColumnSnapshot<Id extends PObjectId>(\n id: Id,\n spec: PColumnSpec,\n data: undefined | ColumnData,\n dataStatus: ColumnDataStatus,\n): ColumnSnapshot<Id> {\n return { id, spec, data, dataStatus };\n}\n"],"mappings":";;AA2CA,SAAgB,sBAAsB,SAA6D;CACjG,OAAO,EAAE,KAAK,QAAQ;AACxB;;AAKA,SAAgB,qBACd,IACA,MACA,MACA,YACoB;CACpB,OAAO;EAAE;EAAI;EAAM;EAAM;CAAW;AACtC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"column_snapshot.d.ts","names":[],"sources":["../../src/columns/column_snapshot.ts"],"mappings":";;;;;KAMY,gBAAA;AAAZ
|
|
1
|
+
{"version":3,"file":"column_snapshot.d.ts","names":[],"sources":["../../src/columns/column_snapshot.ts"],"mappings":";;;;;KAMY,gBAAA;AAAZ;;;;AAA4B;AAS5B;;AATA,UASiB,cAAA,YACJ,SAAA,GAAY,mBAAA,SAChB,oBAAA;EAAA,SAEE,EAAA,EAAI,EAAA;EAAA,SACJ,IAAA,EAAM,WAAA;EAAA,SACN,UAAA,EAAY,gBAAA;EAFR;;;;;;EAAA,SAUJ,IAAA,EAAM,UAAA,CAAW,IAAA;AAAA;;;;;UASX,UAAA,QAAkB,oBAAA;EACjC,GAAA,IAAO,IAAI;AAAA;;iBAIG,qBAAA,CAAsB,OAAA,QAAe,oBAAA,eAAmC,UAAU;;iBAOlF,oBAAA,YAAgC,SAAA,EAC9C,EAAA,EAAI,EAAA,EACJ,IAAA,EAAM,WAAA,EACN,IAAA,cAAkB,UAAA,EAClB,UAAA,EAAY,gBAAA,GACX,cAAA,CAAe,EAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"column_snapshot.js","names":[],"sources":["../../src/columns/column_snapshot.ts"],"sourcesContent":["import type { PColumnSpec, PObjectId, SUniversalPColumnId } from \"@milaboratories/pl-model-common\";\nimport type { PColumnDataUniversal } from \"../render/internal\";\n\n// --- ColumnSnapshot ---\n\n/** Data status of a column snapshot. */\nexport type ColumnDataStatus = \"ready\" | \"computing\" | \"absent\";\n\n/**\n * Immutable snapshot of a column: spec, data status, and lazy data accessor.\n *\n * - `dataStatus` is readable without marking the render context unstable.\n * - `data` holds an active object when data exists (ready or computing),\n * or `undefined` when data is permanently absent.\n */\nexport interface ColumnSnapshot<\n Id extends PObjectId | SUniversalPColumnId,\n Data = PColumnDataUniversal,\n> {\n readonly id: Id;\n readonly spec: PColumnSpec;\n readonly dataStatus: ColumnDataStatus;\n\n /**\n * Lazy data accessor.\n * - `'ready'`: `data.get()` returns column data, context stays stable.\n * - `'computing'`: `data.get()` returns `undefined`, marks context unstable.\n * - `'absent'`: `data` is `undefined` — no active object, no instability.\n */\n readonly data: ColumnData<Data> | undefined;\n}\n\n// --- ColumnData ---\n\n/**\n * Active object wrapping lazy column data access.\n * Accessing data on a computing column marks the render context unstable.\n */\nexport interface ColumnData<Data = PColumnDataUniversal> {\n get(): Data | undefined;\n}\n\n/** Creates a ColumnData active object for a ready column. */\nexport function createReadyColumnData(getData: () => PColumnDataUniversal | undefined): ColumnData {\n return { get: getData };\n}\n\n// --- Snapshot construction helpers ---\n\n/** Creates a ColumnSnapshot from parts. */\nexport function createColumnSnapshot<Id extends PObjectId>(\n id: Id,\n spec: PColumnSpec,\n data: undefined | ColumnData,\n dataStatus: ColumnDataStatus,\n): ColumnSnapshot<Id> {\n return { id, spec, data, dataStatus };\n}\n"],"mappings":";;AA2CA,SAAgB,sBAAsB,SAA6D;
|
|
1
|
+
{"version":3,"file":"column_snapshot.js","names":[],"sources":["../../src/columns/column_snapshot.ts"],"sourcesContent":["import type { PColumnSpec, PObjectId, SUniversalPColumnId } from \"@milaboratories/pl-model-common\";\nimport type { PColumnDataUniversal } from \"../render/internal\";\n\n// --- ColumnSnapshot ---\n\n/** Data status of a column snapshot. */\nexport type ColumnDataStatus = \"ready\" | \"computing\" | \"absent\";\n\n/**\n * Immutable snapshot of a column: spec, data status, and lazy data accessor.\n *\n * - `dataStatus` is readable without marking the render context unstable.\n * - `data` holds an active object when data exists (ready or computing),\n * or `undefined` when data is permanently absent.\n */\nexport interface ColumnSnapshot<\n Id extends PObjectId | SUniversalPColumnId,\n Data = PColumnDataUniversal,\n> {\n readonly id: Id;\n readonly spec: PColumnSpec;\n readonly dataStatus: ColumnDataStatus;\n\n /**\n * Lazy data accessor.\n * - `'ready'`: `data.get()` returns column data, context stays stable.\n * - `'computing'`: `data.get()` returns `undefined`, marks context unstable.\n * - `'absent'`: `data` is `undefined` — no active object, no instability.\n */\n readonly data: ColumnData<Data> | undefined;\n}\n\n// --- ColumnData ---\n\n/**\n * Active object wrapping lazy column data access.\n * Accessing data on a computing column marks the render context unstable.\n */\nexport interface ColumnData<Data = PColumnDataUniversal> {\n get(): Data | undefined;\n}\n\n/** Creates a ColumnData active object for a ready column. */\nexport function createReadyColumnData(getData: () => PColumnDataUniversal | undefined): ColumnData {\n return { get: getData };\n}\n\n// --- Snapshot construction helpers ---\n\n/** Creates a ColumnSnapshot from parts. */\nexport function createColumnSnapshot<Id extends PObjectId>(\n id: Id,\n spec: PColumnSpec,\n data: undefined | ColumnData,\n dataStatus: ColumnDataStatus,\n): ColumnSnapshot<Id> {\n return { id, spec, data, dataStatus };\n}\n"],"mappings":";;AA2CA,SAAgB,sBAAsB,SAA6D;CACjG,OAAO,EAAE,KAAK,QAAQ;AACxB;;AAKA,SAAgB,qBACd,IACA,MACA,MACA,YACoB;CACpB,OAAO;EAAE;EAAI;EAAM;EAAM;CAAW;AACtC"}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
require("../_virtual/_rolldown/runtime.cjs");
|
|
2
1
|
const require_accessor = require("../render/accessor.cjs");
|
|
3
2
|
let _milaboratories_pl_model_common = require("@milaboratories/pl-model-common");
|
|
4
3
|
//#region src/columns/column_snapshot_provider.ts
|
|
@@ -49,6 +48,7 @@ var ArrayColumnProvider = class {
|
|
|
49
48
|
* Always complete. Data status taken from each snapshot.
|
|
50
49
|
*/
|
|
51
50
|
var SnapshotColumnProvider = class {
|
|
51
|
+
snapshots;
|
|
52
52
|
constructor(snapshots) {
|
|
53
53
|
this.snapshots = snapshots;
|
|
54
54
|
}
|
|
@@ -64,6 +64,8 @@ var SnapshotColumnProvider = class {
|
|
|
64
64
|
* Detects data status from accessor readiness state.
|
|
65
65
|
*/
|
|
66
66
|
var OutputColumnProvider = class {
|
|
67
|
+
accessor;
|
|
68
|
+
opts;
|
|
67
69
|
constructor(accessor, opts) {
|
|
68
70
|
this.accessor = accessor;
|
|
69
71
|
this.opts = opts;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"column_snapshot_provider.cjs","names":["TreeNodeAccessor"],"sources":["../../src/columns/column_snapshot_provider.ts"],"sourcesContent":["import type { PObjectId } from \"@milaboratories/pl-model-common\";\nimport { isDataInfo, PColumn, visitDataInfo } from \"@milaboratories/pl-model-common\";\nimport { TreeNodeAccessor } from \"../render/accessor\";\nimport type { PColumnDataUniversal } from \"../render/internal\";\nimport type { ColumnDataStatus, ColumnSnapshot } from \"./column_snapshot\";\n\n/**\n * Data source interface for column enumeration.\n *\n * Knows nothing about the render framework, stability tracking, labels,\n * anchoring, or splitting. All that complexity lives in the collection layer.\n */\nexport interface ColumnSnapshotProvider {\n /** Returns all currently known columns. */\n getAllColumns(): ColumnSnapshot<PObjectId>[];\n\n /** Whether the provider has finished enumerating all its columns.\n * Calling this may mark the render context unstable — it touches\n * the reactive tree to check field resolution state. */\n isColumnListComplete(): boolean;\n}\n\n/**\n * Union of types that can serve as column sources for helpers and builders.\n * Does NOT include TreeNodeAccessor — call `.toColumnSource()` on it first.\n */\nexport type ColumnSource =\n | ColumnSnapshotProvider\n | ColumnSnapshot<PObjectId>[]\n | PColumn<PColumnDataUniversal | undefined>[];\n\n/**\n * Simple provider wrapping an array of PColumns.\n * Always complete, data status always 'ready'.\n */\nexport class ArrayColumnProvider implements ColumnSnapshotProvider {\n private readonly columns: ColumnSnapshot<PObjectId>[];\n\n constructor(columns: PColumn<PColumnDataUniversal | undefined>[]) {\n this.columns = columns.map((col) => ({\n id: col.id,\n spec: col.spec,\n data: { get: () => col.data },\n dataStatus: this.getStatus(col.data),\n }));\n }\n\n getAllColumns(): ColumnSnapshot<PObjectId>[] {\n return this.columns;\n }\n\n isColumnListComplete(): boolean {\n return true;\n }\n\n protected getStatus(\n d: undefined | PColumnDataUniversal | (() => undefined | PColumnDataUniversal),\n ): ColumnDataStatus {\n if (d == null) {\n return \"absent\";\n }\n if (typeof d === \"function\") {\n return this.getStatus(d());\n }\n if (d instanceof TreeNodeAccessor) {\n if (d.getIsReadyOrError()) return \"ready\";\n if (d.getIsFinal()) return \"absent\";\n return \"computing\";\n }\n if (isDataInfo(d)) {\n let ready = true;\n let final = true;\n visitDataInfo(d, (v) => {\n ready &&= v.getIsReadyOrError();\n final &&= v.getIsFinal();\n });\n if (ready) return \"ready\";\n if (final) return \"absent\";\n return \"computing\";\n }\n return \"ready\";\n }\n}\n\n/**\n * Provider wrapping an array of ColumnSnapshots.\n * Always complete. Data status taken from each snapshot.\n */\nexport class SnapshotColumnProvider implements ColumnSnapshotProvider {\n constructor(private readonly snapshots: ColumnSnapshot<PObjectId>[]) {}\n\n getAllColumns(): ColumnSnapshot<PObjectId>[] {\n return this.snapshots;\n }\n\n isColumnListComplete(): boolean {\n return true;\n }\n}\n\nexport interface OutputColumnProviderOpts {\n /** When true and the accessor is final, columns with no ready data get status 'absent'. */\n allowPermanentAbsence?: boolean;\n}\n\n/**\n * Provider wrapping a TreeNodeAccessor (output/prerun resolve result).\n * Detects data status from accessor readiness state.\n */\nexport class OutputColumnProvider implements ColumnSnapshotProvider {\n constructor(\n private readonly accessor: TreeNodeAccessor,\n private readonly opts?: OutputColumnProviderOpts,\n ) {}\n\n getAllColumns(): ColumnSnapshot<PObjectId>[] {\n return this.getColumns();\n }\n\n isColumnListComplete(): boolean {\n return this.accessor.getInputsLocked();\n }\n\n private getColumns(): ColumnSnapshot<PObjectId>[] {\n const pColumns = this.accessor.getPColumns();\n if (pColumns === undefined) return [];\n\n const isFinal = this.accessor.getIsFinal();\n const allowAbsence = this.opts?.allowPermanentAbsence === true;\n\n return pColumns.map((col) => {\n const dataAccessor = col.data;\n const isReady = dataAccessor.getIsReadyOrError();\n\n let dataStatus: ColumnDataStatus;\n if (isReady) {\n dataStatus = \"ready\";\n } else if (allowAbsence && isFinal) {\n dataStatus = \"absent\";\n } else {\n dataStatus = \"computing\";\n }\n\n return {\n id: col.id,\n spec: col.spec,\n dataStatus,\n data: { get: () => (isReady ? dataAccessor : undefined) },\n };\n });\n }\n}\n\n/** Checks if a value is a ColumnSnapshotProvider (duck-typing). */\nexport function isColumnSnapshotProvider(source: unknown): source is ColumnSnapshotProvider {\n return (\n typeof source === \"object\" &&\n source !== null &&\n \"getAllColumns\" in source &&\n \"isColumnListComplete\" in source &&\n typeof (source as ColumnSnapshotProvider).getAllColumns === \"function\" &&\n typeof (source as ColumnSnapshotProvider).isColumnListComplete === \"function\"\n );\n}\n\n/** Checks if a value looks like a PColumn (has id, spec, data). */\nfunction isPColumnArray(source: unknown): source is PColumn<PColumnDataUniversal | undefined>[] {\n if (!Array.isArray(source)) return false;\n if (source.length === 0) return true; // empty array — treat as PColumn[]\n const first = source[0];\n return \"id\" in first && \"spec\" in first && \"data\" in first && !(\"dataStatus\" in first);\n}\n\n/** Checks if a value looks like a ColumnSnapshot array. */\nfunction isColumnSnapshotArray(source: unknown): source is ColumnSnapshot<PObjectId>[] {\n if (!Array.isArray(source)) return false;\n if (source.length === 0) return true; // empty array — treat as snapshots\n const first = source[0];\n return \"id\" in first && \"spec\" in first && \"dataStatus\" in first;\n}\n\n/**\n * Normalize any ColumnSource into a ColumnSnapshotProvider.\n * - ColumnSnapshotProvider → returned as-is\n * - ColumnSnapshot<PObjectId>[] → wrapped in SnapshotColumnProvider\n * - PColumn[] → wrapped in ArrayColumnProvider\n */\nexport function toColumnSnapshotProvider(source: ColumnSource): ColumnSnapshotProvider {\n if (isColumnSnapshotProvider(source)) return source;\n if (isColumnSnapshotArray(source)) return new SnapshotColumnProvider(source);\n if (isPColumnArray(source)) return new ArrayColumnProvider(source);\n // Should not reach here given the type union, but be safe\n throw new Error(\"Unknown ColumnSource type\");\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"column_snapshot_provider.cjs","names":["TreeNodeAccessor"],"sources":["../../src/columns/column_snapshot_provider.ts"],"sourcesContent":["import type { PObjectId } from \"@milaboratories/pl-model-common\";\nimport { isDataInfo, PColumn, visitDataInfo } from \"@milaboratories/pl-model-common\";\nimport { TreeNodeAccessor } from \"../render/accessor\";\nimport type { PColumnDataUniversal } from \"../render/internal\";\nimport type { ColumnDataStatus, ColumnSnapshot } from \"./column_snapshot\";\n\n/**\n * Data source interface for column enumeration.\n *\n * Knows nothing about the render framework, stability tracking, labels,\n * anchoring, or splitting. All that complexity lives in the collection layer.\n */\nexport interface ColumnSnapshotProvider {\n /** Returns all currently known columns. */\n getAllColumns(): ColumnSnapshot<PObjectId>[];\n\n /** Whether the provider has finished enumerating all its columns.\n * Calling this may mark the render context unstable — it touches\n * the reactive tree to check field resolution state. */\n isColumnListComplete(): boolean;\n}\n\n/**\n * Union of types that can serve as column sources for helpers and builders.\n * Does NOT include TreeNodeAccessor — call `.toColumnSource()` on it first.\n */\nexport type ColumnSource =\n | ColumnSnapshotProvider\n | ColumnSnapshot<PObjectId>[]\n | PColumn<PColumnDataUniversal | undefined>[];\n\n/**\n * Simple provider wrapping an array of PColumns.\n * Always complete, data status always 'ready'.\n */\nexport class ArrayColumnProvider implements ColumnSnapshotProvider {\n private readonly columns: ColumnSnapshot<PObjectId>[];\n\n constructor(columns: PColumn<PColumnDataUniversal | undefined>[]) {\n this.columns = columns.map((col) => ({\n id: col.id,\n spec: col.spec,\n data: { get: () => col.data },\n dataStatus: this.getStatus(col.data),\n }));\n }\n\n getAllColumns(): ColumnSnapshot<PObjectId>[] {\n return this.columns;\n }\n\n isColumnListComplete(): boolean {\n return true;\n }\n\n protected getStatus(\n d: undefined | PColumnDataUniversal | (() => undefined | PColumnDataUniversal),\n ): ColumnDataStatus {\n if (d == null) {\n return \"absent\";\n }\n if (typeof d === \"function\") {\n return this.getStatus(d());\n }\n if (d instanceof TreeNodeAccessor) {\n if (d.getIsReadyOrError()) return \"ready\";\n if (d.getIsFinal()) return \"absent\";\n return \"computing\";\n }\n if (isDataInfo(d)) {\n let ready = true;\n let final = true;\n visitDataInfo(d, (v) => {\n ready &&= v.getIsReadyOrError();\n final &&= v.getIsFinal();\n });\n if (ready) return \"ready\";\n if (final) return \"absent\";\n return \"computing\";\n }\n return \"ready\";\n }\n}\n\n/**\n * Provider wrapping an array of ColumnSnapshots.\n * Always complete. Data status taken from each snapshot.\n */\nexport class SnapshotColumnProvider implements ColumnSnapshotProvider {\n constructor(private readonly snapshots: ColumnSnapshot<PObjectId>[]) {}\n\n getAllColumns(): ColumnSnapshot<PObjectId>[] {\n return this.snapshots;\n }\n\n isColumnListComplete(): boolean {\n return true;\n }\n}\n\nexport interface OutputColumnProviderOpts {\n /** When true and the accessor is final, columns with no ready data get status 'absent'. */\n allowPermanentAbsence?: boolean;\n}\n\n/**\n * Provider wrapping a TreeNodeAccessor (output/prerun resolve result).\n * Detects data status from accessor readiness state.\n */\nexport class OutputColumnProvider implements ColumnSnapshotProvider {\n constructor(\n private readonly accessor: TreeNodeAccessor,\n private readonly opts?: OutputColumnProviderOpts,\n ) {}\n\n getAllColumns(): ColumnSnapshot<PObjectId>[] {\n return this.getColumns();\n }\n\n isColumnListComplete(): boolean {\n return this.accessor.getInputsLocked();\n }\n\n private getColumns(): ColumnSnapshot<PObjectId>[] {\n const pColumns = this.accessor.getPColumns();\n if (pColumns === undefined) return [];\n\n const isFinal = this.accessor.getIsFinal();\n const allowAbsence = this.opts?.allowPermanentAbsence === true;\n\n return pColumns.map((col) => {\n const dataAccessor = col.data;\n const isReady = dataAccessor.getIsReadyOrError();\n\n let dataStatus: ColumnDataStatus;\n if (isReady) {\n dataStatus = \"ready\";\n } else if (allowAbsence && isFinal) {\n dataStatus = \"absent\";\n } else {\n dataStatus = \"computing\";\n }\n\n return {\n id: col.id,\n spec: col.spec,\n dataStatus,\n data: { get: () => (isReady ? dataAccessor : undefined) },\n };\n });\n }\n}\n\n/** Checks if a value is a ColumnSnapshotProvider (duck-typing). */\nexport function isColumnSnapshotProvider(source: unknown): source is ColumnSnapshotProvider {\n return (\n typeof source === \"object\" &&\n source !== null &&\n \"getAllColumns\" in source &&\n \"isColumnListComplete\" in source &&\n typeof (source as ColumnSnapshotProvider).getAllColumns === \"function\" &&\n typeof (source as ColumnSnapshotProvider).isColumnListComplete === \"function\"\n );\n}\n\n/** Checks if a value looks like a PColumn (has id, spec, data). */\nfunction isPColumnArray(source: unknown): source is PColumn<PColumnDataUniversal | undefined>[] {\n if (!Array.isArray(source)) return false;\n if (source.length === 0) return true; // empty array — treat as PColumn[]\n const first = source[0];\n return \"id\" in first && \"spec\" in first && \"data\" in first && !(\"dataStatus\" in first);\n}\n\n/** Checks if a value looks like a ColumnSnapshot array. */\nfunction isColumnSnapshotArray(source: unknown): source is ColumnSnapshot<PObjectId>[] {\n if (!Array.isArray(source)) return false;\n if (source.length === 0) return true; // empty array — treat as snapshots\n const first = source[0];\n return \"id\" in first && \"spec\" in first && \"dataStatus\" in first;\n}\n\n/**\n * Normalize any ColumnSource into a ColumnSnapshotProvider.\n * - ColumnSnapshotProvider → returned as-is\n * - ColumnSnapshot<PObjectId>[] → wrapped in SnapshotColumnProvider\n * - PColumn[] → wrapped in ArrayColumnProvider\n */\nexport function toColumnSnapshotProvider(source: ColumnSource): ColumnSnapshotProvider {\n if (isColumnSnapshotProvider(source)) return source;\n if (isColumnSnapshotArray(source)) return new SnapshotColumnProvider(source);\n if (isPColumnArray(source)) return new ArrayColumnProvider(source);\n // Should not reach here given the type union, but be safe\n throw new Error(\"Unknown ColumnSource type\");\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"column_snapshot_provider.d.ts","names":[],"sources":["../../src/columns/column_snapshot_provider.ts"],"mappings":";;;;;;;AAYA;;;;;UAAiB,sBAAA;EAEiB;EAAhC,aAAA,IAAiB,
|
|
1
|
+
{"version":3,"file":"column_snapshot_provider.d.ts","names":[],"sources":["../../src/columns/column_snapshot_provider.ts"],"mappings":";;;;;;;AAYA;;;;;UAAiB,sBAAA;EAEiB;EAAhC,aAAA,IAAiB,cAAc,CAAC,SAAA;EAKZ;AAAA;AAOtB;EAPE,oBAAA;AAAA;;;;;KAOU,YAAA,GACR,sBAAA,GACA,cAAA,CAAe,SAAA,MACf,OAAA,CAAQ,oBAAA;;;;;cAMC,mBAAA,YAA+B,sBAAA;EAAA,iBACzB,OAAA;cAEL,OAAA,EAAS,OAAA,CAAQ,oBAAA;EAS7B,aAAA,IAAiB,cAAA,CAAe,SAAA;EAIhC,oBAAA;EAAA,UAIU,SAAA,CACR,CAAA,cAAe,oBAAA,sBAA0C,oBAAA,IACxD,gBAAA;AAAA;;;;;cA+BQ,sBAAA,YAAkC,sBAAA;EAAA,iBAChB,SAAA;cAAA,SAAA,EAAW,cAAA,CAAe,SAAA;EAEvD,aAAA,IAAiB,cAAA,CAAe,SAAA;EAIhC,oBAAA;AAAA;AAAA,UAKe,wBAAA;EAjE2B;EAmE1C,qBAAqB;AAAA;;;;;cAOV,oBAAA,YAAgC,sBAAA;EAAA,iBAExB,QAAA;EAAA,iBACA,IAAA;cADA,QAAA,EAAU,gBAAA,EACV,IAAA,GAAO,wBAAA;EAG1B,aAAA,IAAiB,cAAA,CAAe,SAAA;EAIhC,oBAAA;EAAA,QAIQ,UAAA;AAAA;;iBA+BM,wBAAA,CAAyB,MAAA,YAAkB,MAAA,IAAU,sBAAsB;AAlE3F;;;;;;AAAA,iBAmGgB,wBAAA,CAAyB,MAAA,EAAQ,YAAA,GAAe,sBAAsB"}
|
|
@@ -48,6 +48,7 @@ var ArrayColumnProvider = class {
|
|
|
48
48
|
* Always complete. Data status taken from each snapshot.
|
|
49
49
|
*/
|
|
50
50
|
var SnapshotColumnProvider = class {
|
|
51
|
+
snapshots;
|
|
51
52
|
constructor(snapshots) {
|
|
52
53
|
this.snapshots = snapshots;
|
|
53
54
|
}
|
|
@@ -63,6 +64,8 @@ var SnapshotColumnProvider = class {
|
|
|
63
64
|
* Detects data status from accessor readiness state.
|
|
64
65
|
*/
|
|
65
66
|
var OutputColumnProvider = class {
|
|
67
|
+
accessor;
|
|
68
|
+
opts;
|
|
66
69
|
constructor(accessor, opts) {
|
|
67
70
|
this.accessor = accessor;
|
|
68
71
|
this.opts = opts;
|