@platforma-sdk/model 1.63.1 → 1.64.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_virtual/_rolldown/runtime.cjs +12 -22
- package/dist/_virtual/_rolldown/runtime.js +6 -11
- package/dist/annotations/converter.cjs +4 -5
- package/dist/annotations/converter.cjs.map +1 -1
- package/dist/annotations/converter.d.ts.map +1 -0
- package/dist/annotations/converter.js +1 -2
- package/dist/annotations/converter.js.map +1 -1
- package/dist/annotations/index.cjs +1 -1
- package/dist/annotations/index.js +1 -1
- package/dist/annotations/types.d.ts +0 -1
- package/dist/annotations/types.d.ts.map +1 -0
- package/dist/bconfig/index.cjs +2 -2
- package/dist/bconfig/index.js +2 -2
- package/dist/bconfig/lambdas.d.ts +0 -1
- package/dist/bconfig/lambdas.d.ts.map +1 -0
- package/dist/bconfig/normalization.cjs +4 -5
- package/dist/bconfig/normalization.cjs.map +1 -1
- package/dist/bconfig/normalization.d.ts.map +1 -0
- package/dist/bconfig/normalization.js +1 -2
- package/dist/bconfig/normalization.js.map +1 -1
- package/dist/bconfig/types.cjs +1 -2
- package/dist/bconfig/types.cjs.map +1 -1
- package/dist/bconfig/types.d.ts +0 -1
- package/dist/bconfig/types.d.ts.map +1 -0
- package/dist/bconfig/types.js +1 -1
- package/dist/bconfig/util.d.ts.map +1 -0
- package/dist/bconfig/v3.d.ts.map +1 -0
- package/dist/block_api_v1.d.ts.map +1 -0
- package/dist/block_api_v2.d.ts.map +1 -0
- package/dist/block_api_v3.d.ts.map +1 -0
- package/dist/block_migrations.cjs +2 -3
- package/dist/block_migrations.cjs.map +1 -1
- package/dist/block_migrations.d.ts.map +1 -0
- package/dist/block_migrations.js +1 -2
- package/dist/block_migrations.js.map +1 -1
- package/dist/block_model.cjs +16 -17
- package/dist/block_model.cjs.map +1 -1
- package/dist/block_model.d.ts +0 -2
- package/dist/block_model.d.ts.map +1 -0
- package/dist/block_model.js +4 -5
- package/dist/block_model.js.map +1 -1
- package/dist/block_model_legacy.cjs +10 -11
- package/dist/block_model_legacy.cjs.map +1 -1
- package/dist/block_model_legacy.d.ts +0 -3
- package/dist/block_model_legacy.d.ts.map +1 -0
- package/dist/block_model_legacy.js +1 -2
- package/dist/block_model_legacy.js.map +1 -1
- package/dist/block_state_patch.d.ts.map +1 -0
- package/dist/block_state_util.cjs +1 -2
- package/dist/block_state_util.cjs.map +1 -1
- package/dist/block_state_util.d.ts.map +1 -0
- package/dist/block_state_util.js +1 -1
- package/dist/block_state_util.js.map +1 -1
- package/dist/block_storage.cjs +5 -12
- package/dist/block_storage.cjs.map +1 -1
- package/dist/block_storage.d.ts.map +1 -0
- package/dist/block_storage.js +5 -11
- package/dist/block_storage.js.map +1 -1
- package/dist/block_storage_callbacks.cjs +4 -5
- package/dist/block_storage_callbacks.cjs.map +1 -1
- package/dist/block_storage_callbacks.js +3 -4
- package/dist/block_storage_callbacks.js.map +1 -1
- package/dist/block_storage_facade.cjs +2 -3
- package/dist/block_storage_facade.cjs.map +1 -1
- package/dist/block_storage_facade.d.ts +0 -1
- package/dist/block_storage_facade.d.ts.map +1 -0
- package/dist/block_storage_facade.js +1 -2
- package/dist/block_storage_facade.js.map +1 -1
- package/dist/columns/column_collection_builder.cjs +111 -99
- package/dist/columns/column_collection_builder.cjs.map +1 -1
- package/dist/columns/column_collection_builder.d.ts +13 -12
- package/dist/columns/column_collection_builder.d.ts.map +1 -0
- package/dist/columns/column_collection_builder.js +108 -96
- package/dist/columns/column_collection_builder.js.map +1 -1
- package/dist/columns/column_selector.cjs +9 -82
- package/dist/columns/column_selector.cjs.map +1 -1
- package/dist/columns/column_selector.d.ts +6 -14
- package/dist/columns/column_selector.d.ts.map +1 -0
- package/dist/columns/column_selector.js +7 -78
- package/dist/columns/column_selector.js.map +1 -1
- package/dist/columns/column_snapshot.cjs +4 -5
- package/dist/columns/column_snapshot.cjs.map +1 -1
- package/dist/columns/column_snapshot.d.ts +3 -3
- package/dist/columns/column_snapshot.d.ts.map +1 -0
- package/dist/columns/column_snapshot.js +4 -4
- package/dist/columns/column_snapshot.js.map +1 -1
- package/dist/columns/column_snapshot_provider.cjs +2 -3
- package/dist/columns/column_snapshot_provider.cjs.map +1 -1
- package/dist/columns/column_snapshot_provider.d.ts +8 -8
- package/dist/columns/column_snapshot_provider.d.ts.map +1 -0
- package/dist/columns/column_snapshot_provider.js +2 -2
- package/dist/columns/column_snapshot_provider.js.map +1 -1
- package/dist/columns/ctx_column_sources.cjs +3 -4
- package/dist/columns/ctx_column_sources.cjs.map +1 -1
- package/dist/columns/ctx_column_sources.d.ts +2 -2
- package/dist/columns/ctx_column_sources.d.ts.map +1 -0
- package/dist/columns/ctx_column_sources.js +1 -2
- package/dist/columns/ctx_column_sources.js.map +1 -1
- package/dist/columns/expand_by_partition.cjs +106 -0
- package/dist/columns/expand_by_partition.cjs.map +1 -0
- package/dist/columns/expand_by_partition.d.ts +33 -0
- package/dist/columns/expand_by_partition.d.ts.map +1 -0
- package/dist/columns/expand_by_partition.js +105 -0
- package/dist/columns/expand_by_partition.js.map +1 -0
- package/dist/columns/index.cjs +6 -5
- package/dist/columns/index.d.ts +4 -3
- package/dist/columns/index.js +6 -5
- package/dist/components/PFrameForGraphs.cjs +4 -5
- package/dist/components/PFrameForGraphs.cjs.map +1 -1
- package/dist/components/PFrameForGraphs.d.ts +0 -1
- package/dist/components/PFrameForGraphs.d.ts.map +1 -0
- package/dist/components/PFrameForGraphs.js +2 -3
- package/dist/components/PFrameForGraphs.js.map +1 -1
- package/dist/components/PlAnnotations/filter.d.ts.map +1 -0
- package/dist/components/PlAnnotations/filters_ui.cjs +1 -2
- package/dist/components/PlAnnotations/filters_ui.cjs.map +1 -1
- package/dist/components/PlAnnotations/filters_ui.d.ts +0 -2
- package/dist/components/PlAnnotations/filters_ui.d.ts.map +1 -0
- package/dist/components/PlAnnotations/filters_ui.js +1 -1
- package/dist/components/PlAnnotations/filters_ui.js.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV2.cjs +26 -0
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV2.cjs.map +1 -0
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV2.js +25 -0
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV2.js.map +1 -0
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV3.cjs +68 -0
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV3.cjs.map +1 -0
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV3.js +67 -0
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV3.js.map +1 -0
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV2.cjs +28 -18
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV2.cjs.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV2.d.ts +4 -1
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV2.d.ts.map +1 -0
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV2.js +22 -12
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV2.js.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.cjs +262 -181
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.cjs.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.d.ts +37 -23
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.d.ts.map +1 -0
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.js +261 -177
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.js.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/discoverColumns.cjs +64 -0
- package/dist/components/PlDataTable/createPlDataTable/discoverColumns.cjs.map +1 -0
- package/dist/components/PlDataTable/createPlDataTable/discoverColumns.d.ts +17 -0
- package/dist/components/PlDataTable/createPlDataTable/discoverColumns.d.ts.map +1 -0
- package/dist/components/PlDataTable/createPlDataTable/discoverColumns.js +63 -0
- package/dist/components/PlDataTable/createPlDataTable/discoverColumns.js.map +1 -0
- package/dist/components/PlDataTable/createPlDataTable/index.cjs +4 -4
- package/dist/components/PlDataTable/createPlDataTable/index.cjs.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/index.d.ts +2 -2
- package/dist/components/PlDataTable/createPlDataTable/index.d.ts.map +1 -0
- package/dist/components/PlDataTable/createPlDataTable/index.js +3 -3
- package/dist/components/PlDataTable/createPlDataTable/index.js.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/utils.cjs +109 -0
- package/dist/components/PlDataTable/createPlDataTable/utils.cjs.map +1 -0
- package/dist/components/PlDataTable/createPlDataTable/utils.d.ts +19 -0
- package/dist/components/PlDataTable/createPlDataTable/utils.d.ts.map +1 -0
- package/dist/components/PlDataTable/createPlDataTable/utils.js +102 -0
- package/dist/components/PlDataTable/createPlDataTable/utils.js.map +1 -0
- package/dist/components/PlDataTable/createPlDataTableSheet.cjs +1 -2
- package/dist/components/PlDataTable/createPlDataTableSheet.cjs.map +1 -1
- package/dist/components/PlDataTable/createPlDataTableSheet.d.ts +0 -1
- package/dist/components/PlDataTable/createPlDataTableSheet.d.ts.map +1 -0
- package/dist/components/PlDataTable/createPlDataTableSheet.js +1 -1
- package/dist/components/PlDataTable/index.cjs +7 -5
- package/dist/components/PlDataTable/index.d.ts +4 -2
- package/dist/components/PlDataTable/index.js +7 -5
- package/dist/components/PlDataTable/labels.cjs +27 -14
- package/dist/components/PlDataTable/labels.cjs.map +1 -1
- package/dist/components/PlDataTable/labels.js +26 -13
- package/dist/components/PlDataTable/labels.js.map +1 -1
- package/dist/components/PlDataTable/state-migration.cjs +8 -6
- package/dist/components/PlDataTable/state-migration.cjs.map +1 -1
- package/dist/components/PlDataTable/state-migration.d.ts.map +1 -0
- package/dist/components/PlDataTable/state-migration.js +5 -3
- package/dist/components/PlDataTable/state-migration.js.map +1 -1
- package/dist/components/PlDataTable/typesV4.d.ts.map +1 -0
- package/dist/components/PlDataTable/typesV5.d.ts +5 -5
- package/dist/components/PlDataTable/typesV5.d.ts.map +1 -0
- package/dist/components/PlMultiSequenceAlignment.cjs +2 -3
- package/dist/components/PlMultiSequenceAlignment.cjs.map +1 -1
- package/dist/components/PlMultiSequenceAlignment.d.ts.map +1 -0
- package/dist/components/PlMultiSequenceAlignment.js +1 -2
- package/dist/components/PlMultiSequenceAlignment.js.map +1 -1
- package/dist/components/PlSelectionModel.cjs +1 -2
- package/dist/components/PlSelectionModel.cjs.map +1 -1
- package/dist/components/PlSelectionModel.d.ts.map +1 -0
- package/dist/components/PlSelectionModel.js +1 -1
- package/dist/components/index.cjs +13 -11
- package/dist/components/index.d.ts +3 -3
- package/dist/components/index.js +12 -10
- package/dist/config/actions.cjs +1 -2
- package/dist/config/actions.cjs.map +1 -1
- package/dist/config/actions.d.ts.map +1 -0
- package/dist/config/actions.js +1 -1
- package/dist/config/actions_kinds.d.ts.map +1 -0
- package/dist/config/index.cjs +1 -1
- package/dist/config/index.js +1 -1
- package/dist/config/model.d.ts.map +1 -0
- package/dist/config/model_meta.d.ts.map +1 -0
- package/dist/config/type_engine.d.ts.map +1 -0
- package/dist/config/type_util.d.ts.map +1 -0
- package/dist/env_value.cjs +1 -2
- package/dist/env_value.cjs.map +1 -1
- package/dist/env_value.d.ts.map +1 -0
- package/dist/env_value.js +1 -1
- package/dist/env_value.js.map +1 -1
- package/dist/filters/converters/filterToQuery.cjs +3 -4
- package/dist/filters/converters/filterToQuery.cjs.map +1 -1
- package/dist/filters/converters/filterToQuery.d.ts.map +1 -0
- package/dist/filters/converters/filterToQuery.js +1 -2
- package/dist/filters/converters/filterToQuery.js.map +1 -1
- package/dist/filters/converters/filterUiToExpressionImpl.cjs +3 -4
- package/dist/filters/converters/filterUiToExpressionImpl.cjs.map +1 -1
- package/dist/filters/converters/filterUiToExpressionImpl.d.ts.map +1 -0
- package/dist/filters/converters/filterUiToExpressionImpl.js +1 -2
- package/dist/filters/converters/filterUiToExpressionImpl.js.map +1 -1
- package/dist/filters/converters/index.cjs +2 -2
- package/dist/filters/converters/index.js +2 -2
- package/dist/filters/distill.cjs +3 -4
- package/dist/filters/distill.cjs.map +1 -1
- package/dist/filters/distill.d.ts.map +1 -0
- package/dist/filters/distill.js +1 -2
- package/dist/filters/distill.js.map +1 -1
- package/dist/filters/index.cjs +4 -4
- package/dist/filters/index.d.ts +0 -1
- package/dist/filters/index.js +3 -3
- package/dist/filters/traverse.cjs +1 -2
- package/dist/filters/traverse.cjs.map +1 -1
- package/dist/filters/traverse.js +1 -1
- package/dist/filters/traverse.js.map +1 -1
- package/dist/filters/types.d.ts.map +1 -0
- package/dist/index.cjs +89 -83
- package/dist/index.d.ts +8 -15
- package/dist/index.js +8 -9
- package/dist/internal.cjs +1 -2
- 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 +41 -30
- package/dist/labels/derive_distinct_labels.cjs.map +1 -1
- package/dist/labels/derive_distinct_labels.d.ts +15 -15
- package/dist/labels/derive_distinct_labels.d.ts.map +1 -0
- package/dist/labels/derive_distinct_labels.js +40 -29
- package/dist/labels/derive_distinct_labels.js.map +1 -1
- package/dist/labels/index.cjs +1 -2
- package/dist/labels/index.d.ts +1 -2
- package/dist/labels/index.js +1 -2
- package/dist/package.cjs +7 -8
- package/dist/package.js +2 -2
- package/dist/pframe.cjs +2 -3
- package/dist/pframe.cjs.map +1 -1
- package/dist/pframe.d.ts.map +1 -0
- package/dist/pframe.js +1 -2
- package/dist/pframe.js.map +1 -1
- package/dist/pframe_utils/axes.cjs +2 -3
- package/dist/pframe_utils/axes.cjs.map +1 -1
- package/dist/pframe_utils/axes.d.ts +0 -1
- package/dist/pframe_utils/axes.d.ts.map +1 -0
- package/dist/pframe_utils/axes.js +1 -2
- package/dist/pframe_utils/axes.js.map +1 -1
- package/dist/pframe_utils/columns.cjs +5 -6
- package/dist/pframe_utils/columns.cjs.map +1 -1
- package/dist/pframe_utils/columns.d.ts +0 -1
- package/dist/pframe_utils/columns.d.ts.map +1 -0
- package/dist/pframe_utils/columns.js +1 -2
- package/dist/pframe_utils/columns.js.map +1 -1
- package/dist/pframe_utils/index.cjs +3 -4
- package/dist/pframe_utils/index.cjs.map +1 -1
- package/dist/pframe_utils/index.d.ts.map +1 -0
- package/dist/pframe_utils/index.js +2 -3
- package/dist/pframe_utils/index.js.map +1 -1
- package/dist/platforma.d.ts.map +1 -0
- package/dist/plugin_handle.cjs +1 -2
- package/dist/plugin_handle.cjs.map +1 -1
- package/dist/plugin_handle.d.ts.map +1 -0
- package/dist/plugin_handle.js +1 -1
- package/dist/plugin_model.cjs +3 -4
- package/dist/plugin_model.cjs.map +1 -1
- package/dist/plugin_model.d.ts +0 -1
- package/dist/plugin_model.d.ts.map +1 -0
- package/dist/plugin_model.js +1 -2
- package/dist/plugin_model.js.map +1 -1
- package/dist/raw_globals.cjs +3 -4
- package/dist/raw_globals.cjs.map +1 -1
- package/dist/raw_globals.d.ts.map +1 -0
- package/dist/raw_globals.js +1 -2
- package/dist/raw_globals.js.map +1 -1
- package/dist/ref_util.cjs +3 -4
- package/dist/ref_util.cjs.map +1 -1
- package/dist/ref_util.d.ts +0 -2
- package/dist/ref_util.d.ts.map +1 -0
- package/dist/ref_util.js +1 -2
- package/dist/ref_util.js.map +1 -1
- package/dist/render/accessor.cjs +4 -5
- package/dist/render/accessor.cjs.map +1 -1
- package/dist/render/accessor.d.ts.map +1 -0
- package/dist/render/accessor.js +1 -2
- package/dist/render/accessor.js.map +1 -1
- package/dist/render/api.cjs +20 -14
- package/dist/render/api.cjs.map +1 -1
- package/dist/render/api.d.ts +2 -3
- package/dist/render/api.d.ts.map +1 -0
- package/dist/render/api.js +11 -5
- package/dist/render/api.js.map +1 -1
- package/dist/render/future.cjs +2 -3
- package/dist/render/future.cjs.map +1 -1
- package/dist/render/future.d.ts.map +1 -0
- package/dist/render/future.js +1 -2
- package/dist/render/future.js.map +1 -1
- package/dist/render/index.cjs +8 -8
- package/dist/render/index.d.ts +1 -2
- package/dist/render/index.js +7 -7
- package/dist/render/internal.cjs +7 -9
- package/dist/render/internal.cjs.map +1 -1
- package/dist/render/internal.d.ts.map +1 -0
- package/dist/render/internal.js +1 -2
- package/dist/render/internal.js.map +1 -1
- package/dist/render/traversal_ops.d.ts.map +1 -0
- package/dist/render/util/axis_filtering.cjs +1 -2
- package/dist/render/util/axis_filtering.cjs.map +1 -1
- package/dist/render/util/axis_filtering.d.ts.map +1 -0
- package/dist/render/util/axis_filtering.js +1 -1
- package/dist/render/util/column_collection.cjs +8 -9
- package/dist/render/util/column_collection.cjs.map +1 -1
- package/dist/render/util/column_collection.d.ts +0 -1
- package/dist/render/util/column_collection.d.ts.map +1 -0
- package/dist/render/util/column_collection.js +4 -5
- package/dist/render/util/column_collection.js.map +1 -1
- package/dist/render/util/index.cjs +4 -4
- package/dist/render/util/index.js +4 -4
- package/dist/render/util/label.cjs +4 -5
- package/dist/render/util/label.cjs.map +1 -1
- package/dist/render/util/label.d.ts.map +1 -0
- package/dist/render/util/label.js +3 -4
- package/dist/render/util/label.js.map +1 -1
- package/dist/render/util/pcolumn_data.cjs +9 -10
- package/dist/render/util/pcolumn_data.cjs.map +1 -1
- package/dist/render/util/pcolumn_data.d.ts +2 -2
- package/dist/render/util/pcolumn_data.d.ts.map +1 -0
- package/dist/render/util/pcolumn_data.js +7 -8
- package/dist/render/util/pcolumn_data.js.map +1 -1
- package/dist/render/util/pframe_upgraders.cjs +1 -2
- package/dist/render/util/pframe_upgraders.cjs.map +1 -1
- package/dist/render/util/pframe_upgraders.js +1 -1
- package/dist/render/util/split_selectors.d.ts.map +1 -0
- package/dist/services/block_services.cjs +2 -3
- package/dist/services/block_services.cjs.map +1 -1
- package/dist/services/block_services.d.ts +2 -2
- package/dist/services/block_services.d.ts.map +1 -0
- package/dist/services/block_services.js +1 -2
- package/dist/services/block_services.js.map +1 -1
- package/dist/services/index.cjs +2 -2
- package/dist/services/index.js +2 -2
- package/dist/services/service_bridge.cjs +1 -2
- package/dist/services/service_bridge.cjs.map +1 -1
- package/dist/services/service_bridge.d.ts.map +1 -0
- package/dist/services/service_bridge.js +1 -1
- package/dist/services/service_resolve.d.ts.map +1 -0
- package/dist/version.cjs +2 -4
- package/dist/version.cjs.map +1 -1
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +1 -2
- package/dist/version.js.map +1 -1
- package/package.json +13 -13
- package/src/columns/column_collection_builder.test.ts +40 -27
- package/src/columns/column_collection_builder.ts +176 -131
- package/src/columns/column_selector.test.ts +17 -399
- package/src/columns/column_selector.ts +14 -127
- package/src/columns/column_snapshot.ts +5 -5
- package/src/columns/column_snapshot_provider.ts +11 -10
- package/src/columns/ctx_column_sources.ts +2 -2
- package/src/columns/expand_by_partition.test.ts +4 -4
- package/src/columns/expand_by_partition.ts +4 -3
- package/src/columns/index.ts +1 -0
- package/src/components/PlDataTable/createPlDataTable/createPTableDefV2.ts +42 -0
- package/src/components/PlDataTable/createPlDataTable/createPTableDefV3.ts +89 -0
- package/src/components/PlDataTable/createPlDataTable/createPlDataTableV2.ts +39 -11
- package/src/components/PlDataTable/createPlDataTable/createPlDataTableV3.ts +502 -313
- package/src/components/PlDataTable/createPlDataTable/discoverColumns.ts +122 -0
- package/src/components/PlDataTable/createPlDataTable/index.ts +4 -2
- package/src/components/PlDataTable/createPlDataTable/utils.test.ts +257 -0
- package/src/components/PlDataTable/createPlDataTable/utils.ts +160 -0
- package/src/components/PlDataTable/index.ts +13 -2
- package/src/components/PlDataTable/labels.ts +29 -18
- package/src/components/PlDataTable/state-migration.ts +3 -1
- package/src/components/PlDataTable/typesV5.ts +4 -4
- package/src/labels/derive_distinct_labels.test.ts +143 -45
- package/src/labels/derive_distinct_labels.ts +102 -49
- package/src/labels/index.ts +0 -1
- package/src/render/api.ts +15 -5
- package/src/render/util/column_collection.ts +4 -3
- package/src/render/util/label.ts +2 -2
- package/src/render/util/pcolumn_data.ts +5 -3
- package/dist/labels/write_labels_to_specs.cjs +0 -15
- package/dist/labels/write_labels_to_specs.cjs.map +0 -1
- package/dist/labels/write_labels_to_specs.d.ts +0 -9
- package/dist/labels/write_labels_to_specs.js +0 -14
- package/dist/labels/write_labels_to_specs.js.map +0 -1
- package/src/labels/write_labels_to_specs.ts +0 -12
|
@@ -1,380 +1,569 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
AxisId,
|
|
3
3
|
CanonicalizedJson,
|
|
4
|
-
|
|
4
|
+
FilterSpecNode,
|
|
5
5
|
PColumn,
|
|
6
|
-
PColumnIdAndSpec,
|
|
7
|
-
PColumnValues,
|
|
8
6
|
PObjectId,
|
|
9
7
|
PTableColumnId,
|
|
10
8
|
PTableColumnIdAxis,
|
|
11
9
|
PTableColumnIdColumn,
|
|
12
|
-
PTableDefV2,
|
|
13
10
|
PTableSorting,
|
|
14
|
-
SpecQuery,
|
|
15
|
-
SingleAxisSelector,
|
|
16
|
-
SpecQueryExpression,
|
|
17
|
-
SpecQueryJoinEntry,
|
|
18
11
|
PColumnSpec,
|
|
19
|
-
PlRef,
|
|
20
12
|
MultiColumnSelector,
|
|
13
|
+
SUniversalPColumnId,
|
|
21
14
|
} from "@milaboratories/pl-model-common";
|
|
22
15
|
import {
|
|
23
|
-
Annotation,
|
|
24
16
|
canonicalizeJson,
|
|
25
17
|
getAxisId,
|
|
26
18
|
getColumnIdAndSpec,
|
|
27
|
-
isLinkerColumn,
|
|
28
|
-
readAnnotation,
|
|
29
|
-
isBooleanExpression,
|
|
30
19
|
parseJson,
|
|
31
20
|
uniqueBy,
|
|
32
21
|
} from "@milaboratories/pl-model-common";
|
|
33
|
-
import {
|
|
34
|
-
import {
|
|
35
|
-
import type { RenderCtxBase, TreeNodeAccessor, PColumnDataUniversal } from "../../../render";
|
|
36
|
-
import { allPColumnsReady } from "../../../render";
|
|
37
|
-
import { isFunction, isNil } from "es-toolkit";
|
|
22
|
+
import { collectFilterSpecColumns, traverseFilterSpec } from "../../../filters/traverse";
|
|
23
|
+
import type { RenderCtxBase, PColumnDataUniversal } from "../../../render";
|
|
38
24
|
import { isEmpty } from "es-toolkit/compat";
|
|
39
|
-
import {
|
|
40
|
-
import type { PlDataTableFilters, PlDataTableModel } from "../typesV5";
|
|
25
|
+
import type { PlDataTableFilters, PlDataTableFilterSpecLeaf, PlDataTableModel } from "../typesV5";
|
|
41
26
|
import { upgradePlDataTableStateV2 } from "../state-migration";
|
|
42
27
|
import type { PlDataTableStateV2 } from "../state-migration";
|
|
43
|
-
import type {
|
|
28
|
+
import type { ColumnMatch, ColumnSnapshot, MatchingMode } from "../../../columns";
|
|
44
29
|
import { Services, type RequireServices } from "@milaboratories/pl-model-common";
|
|
45
|
-
import { ColumnCollectionBuilder } from "../../../columns";
|
|
46
|
-
import { isColumnSnapshotProvider } from "../../../columns/column_snapshot_provider";
|
|
47
|
-
import { collectCtxColumnSnapshotProviders } from "../../../columns/ctx_column_sources";
|
|
48
30
|
import { getAllLabelColumns, getMatchingLabelColumns } from "../labels";
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
columns: PColumn<PColumnDataUniversal>[];
|
|
65
|
-
labelColumns: PColumn<PColumnDataUniversal>[];
|
|
66
|
-
coreJoinType: "inner" | "full";
|
|
67
|
-
filters: null | PlDataTableFilters;
|
|
68
|
-
sorting: PTableSorting[];
|
|
69
|
-
coreColumnPredicate?: (spec: PColumnIdAndSpec) => boolean;
|
|
70
|
-
}): PTableDefV2<PColumn<TreeNodeAccessor | PColumnValues | DataInfo<TreeNodeAccessor>>> {
|
|
71
|
-
let coreColumns = params.columns;
|
|
72
|
-
const secondaryColumns: typeof params.columns = [];
|
|
73
|
-
|
|
74
|
-
if (isFunction(params.coreColumnPredicate)) {
|
|
75
|
-
coreColumns = [];
|
|
76
|
-
for (const c of params.columns)
|
|
77
|
-
if (params.coreColumnPredicate(getColumnIdAndSpec(c))) coreColumns.push(c);
|
|
78
|
-
else secondaryColumns.push(c);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
secondaryColumns.push(...params.labelColumns);
|
|
82
|
-
|
|
83
|
-
// Build SpecQuery directly from columns
|
|
84
|
-
const coreJoinQuery: SpecQuery<
|
|
85
|
-
PColumn<TreeNodeAccessor | PColumnValues | DataInfo<TreeNodeAccessor>>
|
|
86
|
-
> = {
|
|
87
|
-
type: params.coreJoinType === "inner" ? "innerJoin" : "fullJoin",
|
|
88
|
-
entries: coreColumns.map((c) => joinEntry({ type: "column", column: c })),
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
let query: SpecQuery<PColumn<TreeNodeAccessor | PColumnValues | DataInfo<TreeNodeAccessor>>> = {
|
|
92
|
-
type: "outerJoin",
|
|
93
|
-
primary: joinEntry(coreJoinQuery),
|
|
94
|
-
secondary: secondaryColumns.map((c) => joinEntry({ type: "column", column: c })),
|
|
95
|
-
};
|
|
96
|
-
|
|
97
|
-
// Apply filters
|
|
98
|
-
if (params.filters !== null) {
|
|
99
|
-
const nonEmpty = distillFilterSpec(params.filters);
|
|
100
|
-
|
|
101
|
-
if (!isNil(nonEmpty)) {
|
|
102
|
-
const pridicate = filterSpecToSpecQueryExpr(nonEmpty);
|
|
103
|
-
if (!isBooleanExpression(pridicate)) {
|
|
104
|
-
throw new Error(
|
|
105
|
-
`Filter conversion produced a non-boolean expression (got type "${pridicate.type}"), expected a boolean predicate for query filtering`,
|
|
106
|
-
);
|
|
107
|
-
}
|
|
108
|
-
query = {
|
|
109
|
-
type: "filter",
|
|
110
|
-
input: query,
|
|
111
|
-
predicate: pridicate,
|
|
112
|
-
};
|
|
31
|
+
import type { DeriveLabelsOptions } from "../../../labels/derive_distinct_labels";
|
|
32
|
+
import {
|
|
33
|
+
deriveAllLabels,
|
|
34
|
+
isColumnHidden,
|
|
35
|
+
isColumnOptional,
|
|
36
|
+
withLabelAnnotations,
|
|
37
|
+
withTableVisualAnnotations,
|
|
38
|
+
} from "./utils";
|
|
39
|
+
import { createPTableDefV3 } from "./createPTableDefV3";
|
|
40
|
+
import { discoverTableColumnSnaphots, type DiscoveredTableColumnOptions } from "./discoverColumns";
|
|
41
|
+
import { isNil, RequiredBy, throwError, type Nil } from "@milaboratories/helpers";
|
|
42
|
+
|
|
43
|
+
export type createPlDataTableOptionsV3 = (
|
|
44
|
+
| {
|
|
45
|
+
discoverColumnOptions: DiscoveredTableColumnOptions;
|
|
113
46
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
sortBy: params.sorting.map((s) => ({
|
|
122
|
-
expression: columnIdToExpr(s.column),
|
|
123
|
-
ascending: s.ascending,
|
|
124
|
-
nullsFirst: !s.naAndAbsentAreLeastValues,
|
|
125
|
-
})),
|
|
126
|
-
};
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
return { query };
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
/** Check if column should be omitted from the table */
|
|
133
|
-
export function isColumnHidden(spec: { annotations?: Annotation }): boolean {
|
|
134
|
-
return readAnnotation(spec, Annotation.Table.Visibility) === "hidden";
|
|
135
|
-
}
|
|
47
|
+
| {
|
|
48
|
+
columns: Nil | TableColumnSnapshot<SUniversalPColumnId>[];
|
|
49
|
+
}
|
|
50
|
+
) & {
|
|
51
|
+
filters?: PlDataTableFilters;
|
|
52
|
+
sorting?: PTableSorting[];
|
|
53
|
+
primaryJoinType?: "inner" | "full";
|
|
136
54
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
}
|
|
55
|
+
tableState?: PlDataTableStateV2;
|
|
56
|
+
labelsOptions?: DeriveLabelsOptions;
|
|
57
|
+
columnsDisplayOptions?: ColumnsDisplayOptions;
|
|
58
|
+
};
|
|
141
59
|
|
|
142
60
|
/** Structured source config — selectors/anchors instead of raw ColumnSource. */
|
|
143
|
-
type ColumnsSelectorConfig = {
|
|
61
|
+
export type ColumnsSelectorConfig = {
|
|
144
62
|
include?: MultiColumnSelector | MultiColumnSelector[];
|
|
145
63
|
exclude?: MultiColumnSelector | MultiColumnSelector[];
|
|
146
|
-
anchors?: Record<string, PlRef | PObjectId | PColumnSpec>;
|
|
147
64
|
mode?: MatchingMode;
|
|
148
65
|
maxHops?: number;
|
|
149
66
|
};
|
|
150
67
|
|
|
151
|
-
export type
|
|
152
|
-
|
|
153
|
-
|
|
68
|
+
export type ColumnsDisplayOptions = {
|
|
69
|
+
/** Column ordering rules. Higher priority = further left. First matching rule wins. */
|
|
70
|
+
ordering?: ColumnOrderRule[];
|
|
71
|
+
/** Column visibility rules. First matching rule wins. Unmatched columns use default visibility. */
|
|
72
|
+
visibility?: ColumnVisibilityRule[];
|
|
73
|
+
};
|
|
154
74
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
75
|
+
export type ColumnOrderRule = {
|
|
76
|
+
match: ColumnMatcher;
|
|
77
|
+
/** Higher number = further left in table */
|
|
78
|
+
priority: number;
|
|
79
|
+
};
|
|
160
80
|
|
|
161
|
-
|
|
81
|
+
export type ColumnVisibilityRule = {
|
|
82
|
+
match: ColumnMatcher;
|
|
83
|
+
visibility: "default" | "optional" | "hidden";
|
|
162
84
|
};
|
|
163
85
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
//
|
|
167
|
-
// /** Column visibility rules. First matching rule wins. Unmatched columns use default visibility. */
|
|
168
|
-
// visibility?: ColumnVisibilityRule[];
|
|
169
|
-
// }
|
|
170
|
-
|
|
171
|
-
// interface ColumnOrderRule {
|
|
172
|
-
// match: ColumnMatcher;
|
|
173
|
-
// /** Higher number = further left in table */
|
|
174
|
-
// priority: number;
|
|
175
|
-
// }
|
|
176
|
-
|
|
177
|
-
// interface ColumnVisibilityRule {
|
|
178
|
-
// match: ColumnMatcher;
|
|
179
|
-
// visibility: "default" | "optional" | "hidden";
|
|
180
|
-
// }
|
|
181
|
-
|
|
182
|
-
// type ColumnMatcher =
|
|
183
|
-
// | ((spec: PColumnSpec) => boolean)
|
|
184
|
-
// | { name: string | string[] }
|
|
185
|
-
// | { annotation: Record<string, string> }
|
|
186
|
-
// | { ids: Set<string> };
|
|
86
|
+
export type ColumnMatcher = (spec: PColumnSpec) => boolean;
|
|
87
|
+
|
|
88
|
+
// Main Function
|
|
187
89
|
|
|
188
90
|
export function createPlDataTableV3<A, U, S extends RequireServices<typeof Services.PFrameSpec>>(
|
|
189
91
|
ctx: RenderCtxBase<A, U, S>,
|
|
190
92
|
options: createPlDataTableOptionsV3,
|
|
191
93
|
): PlDataTableModel | undefined {
|
|
192
|
-
const
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
const
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
94
|
+
const state = upgradePlDataTableStateV2(options.tableState);
|
|
95
|
+
const primaryJoinType = options.primaryJoinType ?? "full";
|
|
96
|
+
|
|
97
|
+
const discovered =
|
|
98
|
+
"discoverColumnOptions" in options
|
|
99
|
+
? discoverTableColumnSnaphots(ctx, options.discoverColumnOptions)
|
|
100
|
+
: options.columns;
|
|
101
|
+
if (isNil(discovered) || discovered.length === 0) return undefined;
|
|
102
|
+
|
|
103
|
+
const splited = splitDiscoveredColumns(discovered);
|
|
104
|
+
const resolved = resolveDiscoveredColumns(splited, discovered);
|
|
105
|
+
|
|
106
|
+
const labelColumns = getMatchingLabelColumns(resolved.all, getAllLabelColumns(ctx));
|
|
107
|
+
|
|
108
|
+
const derivedLabels = deriveAllLabels({
|
|
109
|
+
columns: discovered.map((dc) => ({
|
|
110
|
+
id: dc.id,
|
|
111
|
+
spec: dc.spec,
|
|
112
|
+
linkerPath: dc.linkerPath?.map((lp) => ({ spec: lp.linker.spec })),
|
|
113
|
+
})),
|
|
114
|
+
labelColumns,
|
|
115
|
+
deriveLabelsOptions: {
|
|
116
|
+
includeNativeLabel: true,
|
|
117
|
+
...options.labelsOptions,
|
|
118
|
+
},
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
const annotated = annotateColumnGroups(
|
|
122
|
+
resolved,
|
|
123
|
+
labelColumns,
|
|
124
|
+
derivedLabels,
|
|
125
|
+
options.columnsDisplayOptions,
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
const columnIsAvailable = createColumnValidationById([
|
|
129
|
+
...annotated.direct,
|
|
130
|
+
...annotated.linked.flatMap((lc) => [...(annotated.linkers.get(lc.id) ?? []), lc]),
|
|
131
|
+
...annotated.labels,
|
|
132
|
+
]);
|
|
133
|
+
|
|
134
|
+
const filters = mergeFilters(
|
|
135
|
+
state.pTableParams.filters,
|
|
136
|
+
remapFilterColumnIds(options.filters, discovered),
|
|
137
|
+
);
|
|
138
|
+
validateFilters(filters, columnIsAvailable);
|
|
139
|
+
|
|
140
|
+
const sorting = resolveSorting(
|
|
141
|
+
state.pTableParams.sorting,
|
|
142
|
+
remapSortingColumnIds(options.sorting, discovered),
|
|
143
|
+
);
|
|
144
|
+
validateSorting(sorting, columnIsAvailable);
|
|
145
|
+
|
|
146
|
+
const primaryColumnIds = new Set<PObjectId>(
|
|
147
|
+
discovered.filter((dc) => dc.isPrimary).map((dc) => dc.id),
|
|
148
|
+
);
|
|
149
|
+
const primaryColumns = annotated.direct.filter((c) => primaryColumnIds.has(c.id));
|
|
150
|
+
const secondaryColumns = annotated.direct.filter((c) => !primaryColumnIds.has(c.id));
|
|
151
|
+
|
|
152
|
+
if (primaryColumns.length === 0) return undefined;
|
|
153
|
+
|
|
154
|
+
const fullDef = createPTableDefV3({
|
|
155
|
+
primaryJoinType,
|
|
156
|
+
primaryColumns,
|
|
157
|
+
secondaryGroups: [
|
|
158
|
+
...secondaryColumns.map((c) => [c]),
|
|
159
|
+
...annotated.linked.map((lc) => [...(annotated.linkers.get(lc.id) ?? []), lc]),
|
|
160
|
+
...annotated.labels.map((c) => [c]),
|
|
161
|
+
],
|
|
162
|
+
filters,
|
|
163
|
+
sorting,
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
const fullHandle = ctx.createPTableV2(fullDef);
|
|
167
|
+
const pframeHandle = ctx.createPFrame([
|
|
168
|
+
...annotated.direct,
|
|
169
|
+
...annotated.linked,
|
|
170
|
+
...annotated.labels,
|
|
171
|
+
...uniqueBy([...annotated.linkers.values()].flat(), (c) => c.id),
|
|
172
|
+
]);
|
|
173
|
+
if (!fullHandle || !pframeHandle) return undefined;
|
|
174
|
+
|
|
175
|
+
const hiddenSpecs = state.pTableParams.hiddenColIds;
|
|
176
|
+
|
|
177
|
+
const hiddenColumnIds = computeHiddenColumns(
|
|
178
|
+
[...annotated.direct, ...annotated.linked],
|
|
179
|
+
sorting,
|
|
180
|
+
filters,
|
|
181
|
+
hiddenSpecs,
|
|
182
|
+
);
|
|
183
|
+
|
|
184
|
+
const visible = buildVisibleColumns(annotated, hiddenColumnIds, labelColumns);
|
|
185
|
+
const visibleNonCoreDirect = secondaryColumns.filter((c) => !hiddenColumnIds.has(c.id));
|
|
186
|
+
const visibleLinkedGroups = buildVisibleLinkedGroups(
|
|
187
|
+
visible.direct,
|
|
188
|
+
visible.linked,
|
|
189
|
+
annotated.linkers,
|
|
190
|
+
hiddenSpecs,
|
|
191
|
+
);
|
|
192
|
+
|
|
193
|
+
const visibleDef = createPTableDefV3({
|
|
194
|
+
primaryJoinType,
|
|
195
|
+
primaryColumns,
|
|
196
|
+
secondaryGroups: [
|
|
197
|
+
...visibleNonCoreDirect.map((c) => [c]),
|
|
198
|
+
...visibleLinkedGroups,
|
|
199
|
+
...visible.labels.map((c) => [c]),
|
|
200
|
+
],
|
|
201
|
+
filters,
|
|
202
|
+
sorting,
|
|
203
|
+
});
|
|
204
|
+
const visibleHandle = ctx.createPTableV2(visibleDef);
|
|
205
|
+
if (!visibleHandle) return undefined;
|
|
206
|
+
|
|
207
|
+
return {
|
|
208
|
+
sourceId: state.pTableParams.sourceId,
|
|
209
|
+
fullTableHandle: fullHandle,
|
|
210
|
+
fullPframeHandle: pframeHandle,
|
|
211
|
+
visibleTableHandle: visibleHandle,
|
|
212
|
+
} satisfies PlDataTableModel;
|
|
213
|
+
}
|
|
227
214
|
|
|
228
|
-
|
|
229
|
-
|
|
215
|
+
/** A single column discovered from sources — normalized from raw ColumnSnapshot/ColumnMatch. */
|
|
216
|
+
export type TableColumnSnapshot<Id extends PObjectId | SUniversalPColumnId> = ColumnSnapshot<Id> & {
|
|
217
|
+
readonly isPrimary?: boolean;
|
|
218
|
+
readonly originalId?: PObjectId;
|
|
219
|
+
readonly linkerPath?: ColumnMatch["path"];
|
|
220
|
+
};
|
|
230
221
|
|
|
231
|
-
|
|
232
|
-
const allLabelColumns = getAllLabelColumns(ctx.resultPool);
|
|
233
|
-
if (!allLabelColumns) return undefined;
|
|
222
|
+
type TableColumn = PColumn<undefined | PColumnDataUniversal>;
|
|
234
223
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
224
|
+
type SplitDiscoveredColumns = {
|
|
225
|
+
readonly direct: TableColumnSnapshot<SUniversalPColumnId>[];
|
|
226
|
+
readonly linked: TableColumnSnapshot<SUniversalPColumnId>[];
|
|
227
|
+
};
|
|
239
228
|
|
|
240
|
-
|
|
229
|
+
type ResolvedColumns = {
|
|
230
|
+
readonly direct: TableColumn[];
|
|
231
|
+
readonly linked: TableColumn[];
|
|
232
|
+
readonly linkers: Map<PObjectId, TableColumn[]>;
|
|
233
|
+
readonly all: TableColumn[];
|
|
234
|
+
};
|
|
241
235
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
...fullColumnsAxes.map((a) => ({ type: "axis", id: a }) satisfies PTableColumnIdAxis),
|
|
249
|
-
...fullColumns.map((c) => ({ type: "column", id: c.id }) satisfies PTableColumnIdColumn),
|
|
250
|
-
];
|
|
251
|
-
const fullColumnsIdsSet = new Set(
|
|
252
|
-
fullColumnsIds.map((c) => canonicalizeJson<PTableColumnId>(c)),
|
|
253
|
-
);
|
|
254
|
-
const isValidColumnId = (id: string): boolean =>
|
|
255
|
-
fullColumnsIdsSet.has(id as CanonicalizedJson<PTableColumnId>);
|
|
256
|
-
|
|
257
|
-
// Step 6: Filtering validation
|
|
258
|
-
const stateFilters = tableStateNormalized.pTableParams.filters;
|
|
259
|
-
const opsFilters = options?.filters ?? null;
|
|
260
|
-
const filters: null | PlDataTableFilters =
|
|
261
|
-
stateFilters != null && opsFilters != null
|
|
262
|
-
? { type: "and", filters: [stateFilters, opsFilters] }
|
|
263
|
-
: (stateFilters ?? opsFilters);
|
|
264
|
-
const filterColumns = filters ? collectFilterSpecColumns(filters) : [];
|
|
265
|
-
const firstInvalidFilterColumn = filterColumns.find((col) => !isValidColumnId(col));
|
|
266
|
-
if (firstInvalidFilterColumn)
|
|
267
|
-
throw new Error(
|
|
268
|
-
`Invalid filter column ${firstInvalidFilterColumn}: column reference does not match the table columns`,
|
|
269
|
-
);
|
|
270
|
-
|
|
271
|
-
// Step 7: Sorting validation
|
|
272
|
-
const userSorting = tableStateNormalized.pTableParams.sorting;
|
|
273
|
-
const sorting = (isEmpty(userSorting) ? options?.sorting : userSorting) ?? [];
|
|
274
|
-
const firstInvalidSortingColumn = sorting.find(
|
|
275
|
-
(s) => !isValidColumnId(canonicalizeJson<PTableColumnId>(s.column)),
|
|
276
|
-
);
|
|
277
|
-
if (firstInvalidSortingColumn)
|
|
278
|
-
throw new Error(
|
|
279
|
-
`Invalid sorting column ${JSON.stringify(firstInvalidSortingColumn.column)}: column reference does not match the table columns`,
|
|
280
|
-
);
|
|
281
|
-
|
|
282
|
-
// Step 8: Build full table definition and handles
|
|
283
|
-
const coreJoinType = options?.coreJoinType ?? "full";
|
|
284
|
-
const fullDef = createPTableDef({
|
|
285
|
-
columns,
|
|
286
|
-
labelColumns: fullLabelColumns,
|
|
287
|
-
coreJoinType,
|
|
288
|
-
filters,
|
|
289
|
-
sorting,
|
|
290
|
-
coreColumnPredicate: options?.coreColumnPredicate,
|
|
291
|
-
});
|
|
236
|
+
type AnnotatedColumnGroups = {
|
|
237
|
+
readonly direct: TableColumn[];
|
|
238
|
+
readonly linked: TableColumn[];
|
|
239
|
+
readonly linkers: Map<PObjectId, TableColumn[]>;
|
|
240
|
+
readonly labels: TableColumn[];
|
|
241
|
+
};
|
|
292
242
|
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
243
|
+
type VisibleColumns = {
|
|
244
|
+
readonly direct: TableColumn[];
|
|
245
|
+
readonly linked: TableColumn[];
|
|
246
|
+
readonly labels: PColumn<PColumnDataUniversal>[];
|
|
247
|
+
};
|
|
296
248
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
249
|
+
/** Split discovered columns into direct (no linker path) and linked (with linker path). */
|
|
250
|
+
function splitDiscoveredColumns(
|
|
251
|
+
columns: TableColumnSnapshot<SUniversalPColumnId>[],
|
|
252
|
+
): SplitDiscoveredColumns {
|
|
253
|
+
return {
|
|
254
|
+
direct: columns.filter((dc) => isNil(dc.linkerPath) || dc.linkerPath.length === 0),
|
|
255
|
+
linked: columns.filter((dc) => !isNil(dc.linkerPath) && dc.linkerPath.length > 0),
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/** Resolve DiscoveredColumn snapshots into PColumn objects with lazily-evaluated data. */
|
|
260
|
+
function resolveDiscoveredColumns(
|
|
261
|
+
split: SplitDiscoveredColumns,
|
|
262
|
+
allDiscovered: TableColumnSnapshot<SUniversalPColumnId>[],
|
|
263
|
+
): ResolvedColumns {
|
|
264
|
+
const linked = split.linked.map(resolveSnapshot);
|
|
265
|
+
const linkers = new Map<PObjectId, TableColumn[]>(
|
|
266
|
+
split.linked
|
|
267
|
+
.filter(
|
|
268
|
+
(dc): dc is RequiredBy<TableColumnSnapshot<SUniversalPColumnId>, "linkerPath"> =>
|
|
269
|
+
!isNil(dc.linkerPath),
|
|
270
|
+
)
|
|
271
|
+
.map((dc, i) => [linked[i].id, dc.linkerPath.map((s) => resolveSnapshot(s.linker))]),
|
|
272
|
+
);
|
|
273
|
+
|
|
274
|
+
return {
|
|
275
|
+
all: allDiscovered.map(resolveSnapshot),
|
|
276
|
+
direct: split.direct.map(resolveSnapshot),
|
|
277
|
+
linked,
|
|
278
|
+
linkers,
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/** Annotate all column groups with derived labels and display options. */
|
|
283
|
+
function annotateColumnGroups(
|
|
284
|
+
resolved: ResolvedColumns,
|
|
285
|
+
labelColumns: PColumn<PColumnDataUniversal>[],
|
|
286
|
+
derivedLabels: Record<string, string>,
|
|
287
|
+
displayOptions: ColumnsDisplayOptions | undefined,
|
|
288
|
+
): AnnotatedColumnGroups {
|
|
289
|
+
const direct = withTableVisualAnnotations(
|
|
290
|
+
displayOptions,
|
|
291
|
+
withLabelAnnotations(derivedLabels, resolved.direct),
|
|
292
|
+
);
|
|
293
|
+
const linked = withTableVisualAnnotations(
|
|
294
|
+
displayOptions,
|
|
295
|
+
withLabelAnnotations(derivedLabels, resolved.linked),
|
|
296
|
+
);
|
|
297
|
+
const linkers = new Map<PObjectId, TableColumn[]>(
|
|
298
|
+
[...resolved.linkers].map(([id, cols]) => [id, withLabelAnnotations(derivedLabels, cols)]),
|
|
299
|
+
);
|
|
300
|
+
const labels = withLabelAnnotations(derivedLabels, labelColumns);
|
|
301
|
+
|
|
302
|
+
return { direct, linked, linkers, labels };
|
|
303
|
+
}
|
|
302
304
|
|
|
303
|
-
|
|
304
|
-
|
|
305
|
+
/** Build an index of all valid column IDs (axes + columns) for filter/sorting validation. */
|
|
306
|
+
function createColumnValidationById(fullColumns: TableColumn[]) {
|
|
307
|
+
const axisIds = uniqueBy(
|
|
308
|
+
fullColumns.flatMap((c) => c.spec.axesSpec.map(getAxisId)),
|
|
309
|
+
(a) => canonicalizeJson<AxisId>(a),
|
|
310
|
+
);
|
|
305
311
|
|
|
306
|
-
|
|
307
|
-
|
|
312
|
+
const allIds: PTableColumnId[] = [
|
|
313
|
+
...axisIds.map((a) => ({ type: "axis", id: a }) satisfies PTableColumnIdAxis),
|
|
314
|
+
...fullColumns.map((c) => ({ type: "column", id: c.id }) satisfies PTableColumnIdColumn),
|
|
315
|
+
];
|
|
316
|
+
|
|
317
|
+
const validIdSet = new Set(allIds.map((c) => canonicalizeJson<PTableColumnId>(c)));
|
|
318
|
+
|
|
319
|
+
return (id: string): boolean => {
|
|
320
|
+
return validIdSet.has(id as CanonicalizedJson<PTableColumnId>);
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
/** Merge filters from table state and options into a single filter spec. */
|
|
325
|
+
function mergeFilters(
|
|
326
|
+
stateFilters: PlDataTableFilters | null,
|
|
327
|
+
optionsFilters: PlDataTableFilters | null | undefined,
|
|
328
|
+
): Nil | PlDataTableFilters {
|
|
329
|
+
const normalized = optionsFilters ?? null;
|
|
330
|
+
return stateFilters !== null && normalized !== null
|
|
331
|
+
? { type: "and", filters: [stateFilters, normalized] }
|
|
332
|
+
: (stateFilters ?? normalized);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/** Validate that all column references in filters exist in the table. */
|
|
336
|
+
function validateFilters(
|
|
337
|
+
filters: Nil | PlDataTableFilters,
|
|
338
|
+
isValidColumnId: (id: string) => boolean,
|
|
339
|
+
): void {
|
|
340
|
+
if (filters == null) return;
|
|
341
|
+
const filterColumns = collectFilterSpecColumns(filters);
|
|
342
|
+
const firstInvalid = filterColumns.find((col) => !isValidColumnId(col));
|
|
343
|
+
if (firstInvalid !== undefined) {
|
|
344
|
+
throw new Error(
|
|
345
|
+
`Invalid filter column ${firstInvalid}: column reference does not match the table columns`,
|
|
308
346
|
);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
/** Pick user sorting from state if non-empty, otherwise fall back to options default. */
|
|
351
|
+
function resolveSorting(
|
|
352
|
+
userSorting: PTableSorting[],
|
|
353
|
+
defaultSorting: Nil | PTableSorting[],
|
|
354
|
+
): PTableSorting[] {
|
|
355
|
+
return (isEmpty(userSorting) ? defaultSorting : userSorting) ?? [];
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
/** Validate that all column references in sorting exist in the table. */
|
|
359
|
+
function validateSorting(sorting: PTableSorting[], isValidColumnId: (id: string) => boolean): void {
|
|
360
|
+
const firstInvalid = sorting.find(
|
|
361
|
+
(s) => !isValidColumnId(canonicalizeJson<PTableColumnId>(s.column)),
|
|
362
|
+
);
|
|
363
|
+
if (firstInvalid !== undefined) {
|
|
364
|
+
throw new Error(
|
|
365
|
+
`Invalid sorting column ${JSON.stringify(firstInvalid.column)}: column reference does not match the table columns`,
|
|
366
|
+
);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/** Determine which columns should be hidden based on state or optional-column defaults. */
|
|
371
|
+
function computeHiddenColumns(
|
|
372
|
+
columns: TableColumn[],
|
|
373
|
+
sorting: Nil | PTableSorting[],
|
|
374
|
+
filters: Nil | PlDataTableFilters,
|
|
375
|
+
hiddenSpecs: Nil | PTableColumnId[],
|
|
376
|
+
): Set<PObjectId> {
|
|
377
|
+
const alwaysHidden = columns.filter((c) => isColumnHidden(c.spec)).map((c) => c.id);
|
|
378
|
+
const optionalHidden = !isNil(hiddenSpecs)
|
|
379
|
+
? hiddenSpecs.filter((s): s is PTableColumnIdColumn => s.type === "column").map((s) => s.id)
|
|
380
|
+
: columns.filter((c) => isColumnOptional(c.spec)).map((c) => c.id);
|
|
381
|
+
const initial = [...alwaysHidden, ...optionalHidden];
|
|
382
|
+
const preserved = collectPreservedColumnIds(sorting, filters);
|
|
383
|
+
|
|
384
|
+
return new Set(initial.filter((id) => !preserved.has(id)));
|
|
385
|
+
}
|
|
309
386
|
|
|
310
|
-
|
|
311
|
-
|
|
387
|
+
/**
|
|
388
|
+
* Build visible linked column groups. Non-hidden groups are included fully;
|
|
389
|
+
* hidden groups are trimmed to only the prefix that brings axes not yet
|
|
390
|
+
* covered by earlier groups (visible or previously trimmed).
|
|
391
|
+
*/
|
|
392
|
+
function buildVisibleLinkedGroups(
|
|
393
|
+
direct: TableColumn[],
|
|
394
|
+
linked: TableColumn[],
|
|
395
|
+
linkers: Map<PObjectId, TableColumn[]>,
|
|
396
|
+
hiddenSpecs: PTableColumnId[] | null,
|
|
397
|
+
): TableColumn[][] {
|
|
398
|
+
const result: TableColumn[][] = [];
|
|
399
|
+
const coveredAxisIds = new Set<CanonicalizedJson<AxisId>>();
|
|
400
|
+
|
|
401
|
+
const collectAxes = (group: TableColumn[]) => {
|
|
402
|
+
for (const col of group) {
|
|
403
|
+
for (const as of col.spec.axesSpec) {
|
|
404
|
+
coveredAxisIds.add(canonicalizeJson(getAxisId(as)));
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
};
|
|
408
|
+
|
|
409
|
+
collectAxes(direct);
|
|
410
|
+
|
|
411
|
+
for (const lc of linked) {
|
|
412
|
+
const group = [...(linkers.get(lc.id) ?? []), lc];
|
|
413
|
+
result.push(group);
|
|
414
|
+
collectAxes(group);
|
|
415
|
+
}
|
|
312
416
|
|
|
313
|
-
|
|
314
|
-
const
|
|
315
|
-
if (
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
);
|
|
319
|
-
coreColumns.forEach((c) => hiddenColumns.delete(c));
|
|
417
|
+
for (const group of linkers.values()) {
|
|
418
|
+
const trimmed = trimGroupByVisibleAxes(group, hiddenSpecs, coveredAxisIds);
|
|
419
|
+
if (trimmed.length > 0) {
|
|
420
|
+
result.push(trimmed);
|
|
421
|
+
collectAxes(trimmed);
|
|
320
422
|
}
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
return result;
|
|
426
|
+
}
|
|
321
427
|
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
428
|
+
/**
|
|
429
|
+
* For a linked column group [linker1, ..., linkerN, column], find the rightmost
|
|
430
|
+
* element that has at least one non-hidden and not-yet-covered axis.
|
|
431
|
+
* Return the prefix up to and including that element.
|
|
432
|
+
* If no element has such an axis, return empty array.
|
|
433
|
+
*/
|
|
434
|
+
function trimGroupByVisibleAxes(
|
|
435
|
+
group: TableColumn[],
|
|
436
|
+
hiddenSpecs: PTableColumnId[] | null,
|
|
437
|
+
coveredAxisIds: Set<CanonicalizedJson<AxisId>>,
|
|
438
|
+
): TableColumn[] {
|
|
439
|
+
if (hiddenSpecs === null) return group;
|
|
440
|
+
|
|
441
|
+
const hiddenAxisIds = new Set(
|
|
442
|
+
hiddenSpecs
|
|
443
|
+
.filter((s): s is PTableColumnIdAxis => s.type === "axis")
|
|
444
|
+
.map((s) => canonicalizeJson(s.id)),
|
|
445
|
+
);
|
|
446
|
+
|
|
447
|
+
const uncoveredAxisIds = new Set(
|
|
448
|
+
group
|
|
449
|
+
.flatMap((c) => c.spec.axesSpec.map((as) => canonicalizeJson(getAxisId(as))))
|
|
450
|
+
.filter((id) => !hiddenAxisIds.has(id) && !coveredAxisIds.has(id)),
|
|
451
|
+
);
|
|
452
|
+
|
|
453
|
+
let lastNeeded = -1;
|
|
454
|
+
for (let i = 0; i < group.length; i++) {
|
|
455
|
+
const newAxes = group[i].spec.axesSpec
|
|
456
|
+
.map((as) => canonicalizeJson(getAxisId(as)))
|
|
457
|
+
.filter((id) => uncoveredAxisIds.has(id));
|
|
458
|
+
if (newAxes.length > 0) {
|
|
459
|
+
for (const id of newAxes) uncoveredAxisIds.delete(id);
|
|
460
|
+
lastNeeded = i;
|
|
336
461
|
}
|
|
462
|
+
}
|
|
463
|
+
return lastNeeded === -1 ? [] : group.slice(0, lastNeeded + 1);
|
|
464
|
+
}
|
|
337
465
|
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
466
|
+
/** Collect IDs of columns that must remain visible (sorted, filtered). */
|
|
467
|
+
function collectPreservedColumnIds(
|
|
468
|
+
sorting: Nil | PTableSorting[],
|
|
469
|
+
filters: Nil | PlDataTableFilters,
|
|
470
|
+
): Set<PObjectId> {
|
|
471
|
+
const sortedIds = (sorting ?? [])
|
|
472
|
+
.map((s) => s.column)
|
|
473
|
+
.filter((c): c is PTableColumnIdColumn => c.type === "column")
|
|
474
|
+
.map((c) => c.id);
|
|
475
|
+
|
|
476
|
+
const filterIds = !isNil(filters)
|
|
477
|
+
? collectFilterSpecColumns(filters).flatMap((c) => {
|
|
478
|
+
const obj = parseJson(c);
|
|
479
|
+
return obj.type === "column" ? [obj.id] : [];
|
|
480
|
+
})
|
|
481
|
+
: [];
|
|
482
|
+
|
|
483
|
+
return new Set<PObjectId>([...sortedIds, ...filterIds]);
|
|
484
|
+
}
|
|
344
485
|
|
|
345
|
-
|
|
486
|
+
/** Filter annotated columns to only visible ones, re-matching label columns for the visible subset. */
|
|
487
|
+
function buildVisibleColumns(
|
|
488
|
+
annotated: AnnotatedColumnGroups,
|
|
489
|
+
hiddenColumns: Set<PObjectId>,
|
|
490
|
+
originalLabelColumns: PColumn<PColumnDataUniversal>[],
|
|
491
|
+
): VisibleColumns {
|
|
492
|
+
const direct = annotated.direct.filter((c) => !hiddenColumns.has(c.id));
|
|
493
|
+
const linked = annotated.linked.filter((c) => !hiddenColumns.has(c.id));
|
|
494
|
+
const labels = getMatchingLabelColumns(
|
|
495
|
+
[...direct, ...linked].map(getColumnIdAndSpec),
|
|
496
|
+
originalLabelColumns,
|
|
497
|
+
);
|
|
498
|
+
return { direct, linked, labels };
|
|
499
|
+
}
|
|
346
500
|
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
501
|
+
/** Resolve a ColumnSnapshot to a PColumn with lazily-evaluated data. */
|
|
502
|
+
function resolveSnapshot(
|
|
503
|
+
snap: ColumnSnapshot<PObjectId>,
|
|
504
|
+
): PColumn<undefined | PColumnDataUniversal> {
|
|
505
|
+
return { id: snap.id, spec: snap.spec, data: snap.data?.get() };
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
/** Remap column references in sorting entries. */
|
|
509
|
+
function remapSortingColumnIds(
|
|
510
|
+
sorting: Nil | PTableSorting[],
|
|
511
|
+
columns: TableColumnSnapshot<PObjectId | SUniversalPColumnId>[],
|
|
512
|
+
): Nil | PTableSorting[] {
|
|
513
|
+
return sorting?.map((s) => {
|
|
514
|
+
if (s.column.type === "axis") return s; // Axis references are unaffected by column ID remapping
|
|
356
515
|
|
|
357
|
-
|
|
516
|
+
const id = s.column.id;
|
|
517
|
+
const column =
|
|
518
|
+
columns.find((c) => (c.originalId ?? c.id) === id) ??
|
|
519
|
+
throwError(`Column ID "${id}" in sorting does not match any discovered column`);
|
|
358
520
|
|
|
359
521
|
return {
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
}
|
|
522
|
+
...s,
|
|
523
|
+
column: {
|
|
524
|
+
type: "column",
|
|
525
|
+
id: column.id,
|
|
526
|
+
},
|
|
527
|
+
};
|
|
528
|
+
});
|
|
368
529
|
}
|
|
369
530
|
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
531
|
+
type PlDataTableFilterNode = FilterSpecNode<PlDataTableFilterSpecLeaf>;
|
|
532
|
+
|
|
533
|
+
/** Remap column references in a filter tree. */
|
|
534
|
+
function remapFilterColumnIds(
|
|
535
|
+
filters: Nil | PlDataTableFilters,
|
|
536
|
+
columns: TableColumnSnapshot<PObjectId | SUniversalPColumnId>[],
|
|
537
|
+
): Nil | PlDataTableFilters {
|
|
538
|
+
if (isNil(filters)) return filters;
|
|
539
|
+
|
|
540
|
+
const map = (
|
|
541
|
+
tableColumnId: CanonicalizedJson<PTableColumnId>,
|
|
542
|
+
): CanonicalizedJson<PTableColumnId> => {
|
|
543
|
+
const parsed = parseJson<PTableColumnId>(tableColumnId);
|
|
544
|
+
if (parsed.type === "axis") return tableColumnId; // Axis references are unaffected by column ID remapping
|
|
545
|
+
|
|
546
|
+
const originalId = parsed.id;
|
|
547
|
+
const column =
|
|
548
|
+
columns.find((c) => (c.originalId ?? c.id) === originalId) ??
|
|
549
|
+
throwError(`Column ID "${parsed.id}" in filters does not match any discovered column`);
|
|
550
|
+
|
|
551
|
+
return canonicalizeJson<PTableColumnId>({
|
|
552
|
+
type: "column",
|
|
553
|
+
id: column.id,
|
|
554
|
+
});
|
|
555
|
+
};
|
|
556
|
+
|
|
557
|
+
return traverseFilterSpec(filters, {
|
|
558
|
+
leaf: (leaf): PlDataTableFilterNode => {
|
|
559
|
+
if (leaf.type === undefined) return leaf;
|
|
560
|
+
const result = { ...leaf };
|
|
561
|
+
if ("column" in result) result.column = map(result.column);
|
|
562
|
+
if ("rhs" in result) result.rhs = map(result.rhs);
|
|
563
|
+
return result;
|
|
564
|
+
},
|
|
565
|
+
and: (results): PlDataTableFilterNode => ({ type: "and", filters: results }),
|
|
566
|
+
or: (results): PlDataTableFilterNode => ({ type: "or", filters: results }),
|
|
567
|
+
not: (result): PlDataTableFilterNode => ({ type: "not", filter: result }),
|
|
568
|
+
}) as PlDataTableFilters;
|
|
380
569
|
}
|