@platforma-sdk/model 1.79.27 → 1.80.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/block_model.d.ts +2 -0
- package/dist/block_model.d.ts.map +1 -1
- package/dist/columns/column.cjs +28 -0
- package/dist/columns/column.cjs.map +1 -0
- package/dist/columns/column.d.ts +30 -0
- package/dist/columns/column.d.ts.map +1 -0
- package/dist/columns/column.js +27 -0
- package/dist/columns/column.js.map +1 -0
- package/dist/columns/column_lazy.cjs +248 -0
- package/dist/columns/column_lazy.cjs.map +1 -0
- package/dist/columns/column_lazy.d.ts +137 -0
- package/dist/columns/column_lazy.d.ts.map +1 -0
- package/dist/columns/column_lazy.js +245 -0
- package/dist/columns/column_lazy.js.map +1 -0
- package/dist/columns/column_providers/index.cjs +62 -0
- package/dist/columns/column_providers/index.cjs.map +1 -0
- package/dist/columns/column_providers/index.d.ts +30 -0
- package/dist/columns/column_providers/index.d.ts.map +1 -0
- package/dist/columns/column_providers/index.js +53 -0
- package/dist/columns/column_providers/index.js.map +1 -0
- package/dist/columns/column_providers/providers.cjs +123 -0
- package/dist/columns/column_providers/providers.cjs.map +1 -0
- package/dist/columns/column_providers/providers.d.ts +75 -0
- package/dist/columns/column_providers/providers.d.ts.map +1 -0
- package/dist/columns/column_providers/providers.js +118 -0
- package/dist/columns/column_providers/providers.js.map +1 -0
- package/dist/columns/column_providers/types.d.ts +23 -0
- package/dist/columns/column_providers/types.d.ts.map +1 -0
- package/dist/columns/column_recipes/column_discovered_recipe.cjs +180 -0
- package/dist/columns/column_recipes/column_discovered_recipe.cjs.map +1 -0
- package/dist/columns/column_recipes/column_discovered_recipe.d.ts +120 -0
- package/dist/columns/column_recipes/column_discovered_recipe.d.ts.map +1 -0
- package/dist/columns/column_recipes/column_discovered_recipe.js +180 -0
- package/dist/columns/column_recipes/column_discovered_recipe.js.map +1 -0
- package/dist/columns/column_recipes/column_filtered_recipe.cjs +133 -0
- package/dist/columns/column_recipes/column_filtered_recipe.cjs.map +1 -0
- package/dist/columns/column_recipes/column_filtered_recipe.d.ts +75 -0
- package/dist/columns/column_recipes/column_filtered_recipe.d.ts.map +1 -0
- package/dist/columns/column_recipes/column_filtered_recipe.js +133 -0
- package/dist/columns/column_recipes/column_filtered_recipe.js.map +1 -0
- package/dist/columns/column_recipes/column_overrided_recipe.cjs +101 -0
- package/dist/columns/column_recipes/column_overrided_recipe.cjs.map +1 -0
- package/dist/columns/column_recipes/column_overrided_recipe.d.ts +73 -0
- package/dist/columns/column_recipes/column_overrided_recipe.d.ts.map +1 -0
- package/dist/columns/column_recipes/column_overrided_recipe.js +101 -0
- package/dist/columns/column_recipes/column_overrided_recipe.js.map +1 -0
- package/dist/columns/column_recipes/index.cjs +72 -0
- package/dist/columns/column_recipes/index.cjs.map +1 -0
- package/dist/columns/column_recipes/index.d.ts +52 -0
- package/dist/columns/column_recipes/index.d.ts.map +1 -0
- package/dist/columns/column_recipes/index.js +68 -0
- package/dist/columns/column_recipes/index.js.map +1 -0
- package/dist/columns/column_recipes/leaf_rebrand.cjs +22 -0
- package/dist/columns/column_recipes/leaf_rebrand.cjs.map +1 -0
- package/dist/columns/column_recipes/leaf_rebrand.js +22 -0
- package/dist/columns/column_recipes/leaf_rebrand.js.map +1 -0
- package/dist/columns/column_recipes/types.d.ts +101 -0
- package/dist/columns/column_recipes/types.d.ts.map +1 -0
- package/dist/columns/columns_collection.cjs +124 -0
- package/dist/columns/columns_collection.cjs.map +1 -0
- package/dist/columns/columns_collection.d.ts +64 -0
- package/dist/columns/columns_collection.d.ts.map +1 -0
- package/dist/columns/columns_collection.js +122 -0
- package/dist/columns/columns_collection.js.map +1 -0
- package/dist/columns/derive_axis_values_labels.cjs +76 -0
- package/dist/columns/derive_axis_values_labels.cjs.map +1 -0
- package/dist/columns/derive_axis_values_labels.d.ts +30 -0
- package/dist/columns/derive_axis_values_labels.d.ts.map +1 -0
- package/dist/columns/derive_axis_values_labels.js +76 -0
- package/dist/columns/derive_axis_values_labels.js.map +1 -0
- package/dist/columns/expand_by_partition.cjs +53 -56
- package/dist/columns/expand_by_partition.cjs.map +1 -1
- package/dist/columns/expand_by_partition.d.ts +22 -18
- package/dist/columns/expand_by_partition.d.ts.map +1 -1
- package/dist/columns/expand_by_partition.js +55 -58
- package/dist/columns/expand_by_partition.js.map +1 -1
- package/dist/columns/index.cjs +44 -18
- package/dist/columns/index.d.ts +15 -7
- package/dist/columns/index.js +12 -6
- package/dist/columns/utils.cjs +186 -0
- package/dist/columns/utils.cjs.map +1 -0
- package/dist/columns/utils.d.ts +96 -0
- package/dist/columns/utils.d.ts.map +1 -0
- package/dist/columns/utils.js +179 -0
- package/dist/columns/utils.js.map +1 -0
- package/dist/components/PFrameForGraphs.cjs +1 -0
- 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 +1 -0
- package/dist/components/PFrameForGraphs.js.map +1 -1
- package/dist/components/PlDataTable/columnResolver.cjs +28 -0
- package/dist/components/PlDataTable/columnResolver.cjs.map +1 -0
- package/dist/components/PlDataTable/columnResolver.js +28 -0
- package/dist/components/PlDataTable/columnResolver.js.map +1 -0
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV2.cjs +4 -2
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV2.cjs.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV2.js +4 -2
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV2.js.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV3.cjs +20 -25
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV3.cjs.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV3.js +20 -25
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV3.js.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV2.cjs +58 -26
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV2.cjs.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV2.d.ts +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV2.d.ts.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV2.js +60 -28
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV2.js.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.cjs +224 -194
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.cjs.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.d.ts +13 -16
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.d.ts.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.js +228 -198
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.js.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/discoverColumns.cjs +40 -98
- package/dist/components/PlDataTable/createPlDataTable/discoverColumns.cjs.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/discoverColumns.d.ts +17 -8
- package/dist/components/PlDataTable/createPlDataTable/discoverColumns.d.ts.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/discoverColumns.js +40 -98
- package/dist/components/PlDataTable/createPlDataTable/discoverColumns.js.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/index.cjs +1 -1
- 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.js +2 -2
- package/dist/components/PlDataTable/createPlDataTable/index.js.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/utils.cjs +51 -169
- 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 +52 -166
- 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 +1 -1
- package/dist/components/PlDataTable/createPlDataTableSheet.js.map +1 -1
- package/dist/components/PlDataTable/index.cjs +1 -1
- package/dist/components/PlDataTable/index.d.ts +4 -4
- package/dist/components/PlDataTable/index.js +2 -2
- package/dist/components/PlDataTable/labels.cjs +0 -1
- package/dist/components/PlDataTable/labels.cjs.map +1 -1
- package/dist/components/PlDataTable/labels.js +0 -1
- package/dist/components/PlDataTable/labels.js.map +1 -1
- package/dist/components/PlDataTable/state-migration.cjs +107 -10
- package/dist/components/PlDataTable/state-migration.cjs.map +1 -1
- package/dist/components/PlDataTable/state-migration.d.ts +5 -4
- package/dist/components/PlDataTable/state-migration.d.ts.map +1 -1
- package/dist/components/PlDataTable/state-migration.js +107 -10
- package/dist/components/PlDataTable/state-migration.js.map +1 -1
- package/dist/components/PlDataTable/typesV7.d.ts +1 -36
- package/dist/components/PlDataTable/typesV7.d.ts.map +1 -1
- package/dist/components/PlDataTable/typesV8.d.ts +123 -0
- package/dist/components/PlDataTable/typesV8.d.ts.map +1 -0
- package/dist/components/PlDatasetSelector/build_dataset_options.cjs +27 -34
- package/dist/components/PlDatasetSelector/build_dataset_options.cjs.map +1 -1
- package/dist/components/PlDatasetSelector/build_dataset_options.d.ts.map +1 -1
- package/dist/components/PlDatasetSelector/build_dataset_options.js +27 -34
- package/dist/components/PlDatasetSelector/build_dataset_options.js.map +1 -1
- package/dist/components/PlDatasetSelector/enrichment_discovery.cjs +28 -33
- package/dist/components/PlDatasetSelector/enrichment_discovery.cjs.map +1 -1
- package/dist/components/PlDatasetSelector/enrichment_discovery.js +29 -34
- package/dist/components/PlDatasetSelector/enrichment_discovery.js.map +1 -1
- package/dist/components/PlDatasetSelector/filter_discovery.cjs +27 -17
- package/dist/components/PlDatasetSelector/filter_discovery.cjs.map +1 -1
- package/dist/components/PlDatasetSelector/filter_discovery.d.ts +24 -10
- package/dist/components/PlDatasetSelector/filter_discovery.d.ts.map +1 -1
- package/dist/components/PlDatasetSelector/filter_discovery.js +28 -18
- package/dist/components/PlDatasetSelector/filter_discovery.js.map +1 -1
- package/dist/components/PlDatasetSelector/index.d.ts +2 -2
- package/dist/components/index.cjs +1 -1
- package/dist/components/index.d.ts +5 -5
- package/dist/components/index.js +2 -2
- package/dist/filters/converters/filterToQuery.cjs +5 -6
- package/dist/filters/converters/filterToQuery.cjs.map +1 -1
- package/dist/filters/converters/filterToQuery.d.ts +12 -3
- package/dist/filters/converters/filterToQuery.d.ts.map +1 -1
- package/dist/filters/converters/filterToQuery.js +5 -6
- package/dist/filters/converters/filterToQuery.js.map +1 -1
- package/dist/filters/converters/index.d.ts +2 -2
- package/dist/filters/index.d.ts +2 -2
- package/dist/index.cjs +64 -35
- package/dist/index.d.ts +23 -15
- package/dist/index.js +15 -9
- package/dist/labels/derive_distinct_labels.cjs.map +1 -1
- package/dist/labels/derive_distinct_labels.d.ts +1 -2
- package/dist/labels/derive_distinct_labels.d.ts.map +1 -1
- package/dist/labels/derive_distinct_labels.js.map +1 -1
- package/dist/labels/derive_distinct_tooltips.cjs +1 -1
- package/dist/labels/derive_distinct_tooltips.cjs.map +1 -1
- package/dist/labels/derive_distinct_tooltips.d.ts +6 -3
- package/dist/labels/derive_distinct_tooltips.d.ts.map +1 -1
- package/dist/labels/derive_distinct_tooltips.js +1 -1
- package/dist/labels/derive_distinct_tooltips.js.map +1 -1
- package/dist/package.cjs +1 -1
- package/dist/package.js +1 -1
- package/dist/pframe_utils/axes.cjs.map +1 -1
- package/dist/pframe_utils/axes.d.ts +2 -2
- 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 +6 -10
- package/dist/pframe_utils/columns.cjs.map +1 -1
- package/dist/pframe_utils/columns.d.ts +4 -4
- package/dist/pframe_utils/columns.d.ts.map +1 -1
- package/dist/pframe_utils/columns.js +7 -11
- package/dist/pframe_utils/columns.js.map +1 -1
- 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.map +1 -1
- package/dist/render/accessor.cjs +15 -16
- package/dist/render/accessor.cjs.map +1 -1
- package/dist/render/accessor.d.ts +7 -10
- package/dist/render/accessor.d.ts.map +1 -1
- package/dist/render/accessor.js +15 -16
- package/dist/render/accessor.js.map +1 -1
- package/dist/render/api.cjs +34 -36
- package/dist/render/api.cjs.map +1 -1
- package/dist/render/api.d.ts +30 -20
- package/dist/render/api.d.ts.map +1 -1
- package/dist/render/api.js +35 -38
- package/dist/render/api.js.map +1 -1
- package/dist/render/index.cjs +4 -0
- package/dist/render/index.d.ts +4 -4
- package/dist/render/index.js +3 -2
- package/dist/render/internal.cjs +3 -2
- package/dist/render/internal.cjs.map +1 -1
- package/dist/render/internal.d.ts +17 -9
- package/dist/render/internal.d.ts.map +1 -1
- package/dist/render/internal.js +3 -2
- package/dist/render/internal.js.map +1 -1
- package/dist/render/util/axis_filtering.cjs.map +1 -1
- package/dist/render/util/axis_filtering.js.map +1 -1
- package/dist/render/util/column_collection.cjs +6 -4
- package/dist/render/util/column_collection.cjs.map +1 -1
- package/dist/render/util/column_collection.d.ts +9 -9
- package/dist/render/util/column_collection.d.ts.map +1 -1
- package/dist/render/util/column_collection.js +6 -4
- package/dist/render/util/column_collection.js.map +1 -1
- package/dist/render/util/index.d.ts +2 -2
- package/dist/render/util/pcolumn_data.cjs +1 -1
- package/dist/render/util/pcolumn_data.cjs.map +1 -1
- package/dist/render/util/pcolumn_data.d.ts +3 -3
- package/dist/render/util/pcolumn_data.d.ts.map +1 -1
- package/dist/render/util/pcolumn_data.js +1 -1
- package/dist/render/util/pcolumn_data.js.map +1 -1
- package/dist/services/block_services.cjs +2 -1
- package/dist/services/block_services.cjs.map +1 -1
- package/dist/services/block_services.d.ts +1 -0
- package/dist/services/block_services.d.ts.map +1 -1
- package/dist/services/block_services.js +2 -1
- package/dist/services/block_services.js.map +1 -1
- package/dist/services/get_services.cjs +2 -2
- package/dist/services/get_services.cjs.map +1 -1
- package/dist/services/get_services.d.ts +4 -1
- package/dist/services/get_services.d.ts.map +1 -1
- package/dist/services/get_services.js +2 -2
- package/dist/services/get_services.js.map +1 -1
- package/package.json +10 -8
- package/src/columns/__test_helpers__/collection_driver.ts +197 -0
- package/src/columns/__test_helpers__/stub_registry.ts +134 -0
- package/src/columns/column.ts +46 -0
- package/src/columns/column_lazy.test.ts +201 -0
- package/src/columns/column_lazy.ts +311 -0
- package/src/columns/column_providers/index.ts +78 -0
- package/src/columns/column_providers/providers.ts +193 -0
- package/src/columns/column_providers/types.ts +24 -0
- package/src/columns/column_recipes/column_discovered_recipe.ts +231 -0
- package/src/columns/column_recipes/column_filtered_recipe.ts +184 -0
- package/src/columns/column_recipes/column_overrided_recipe.ts +146 -0
- package/src/columns/column_recipes/column_recipes.test.ts +681 -0
- package/src/columns/column_recipes/index.ts +127 -0
- package/src/columns/column_recipes/leaf_rebrand.ts +28 -0
- package/src/columns/column_recipes/types.ts +113 -0
- package/src/columns/columns_collection.test.ts +164 -0
- package/src/columns/columns_collection.ts +170 -0
- package/src/columns/derive_axis_values_labels.ts +98 -0
- package/src/columns/expand_by_partition.test.ts +146 -110
- package/src/columns/expand_by_partition.ts +72 -84
- package/src/columns/index.ts +7 -5
- package/src/columns/utils.test.ts +249 -0
- package/src/columns/utils.ts +226 -0
- package/src/components/PFrameForGraphs.ts +3 -1
- package/src/components/PlAnnotations/filters_ui.test.ts +46 -47
- package/src/components/PlDataTable/columnResolver.test.ts +122 -0
- package/src/components/PlDataTable/columnResolver.ts +57 -0
- package/src/components/PlDataTable/createPlDataTable/createPTableDefV2.ts +9 -9
- package/src/components/PlDataTable/createPlDataTable/createPTableDefV3.ts +31 -63
- package/src/components/PlDataTable/createPlDataTable/createPlDataTableV2.ts +85 -58
- package/src/components/PlDataTable/createPlDataTable/createPlDataTableV3.ts +316 -354
- package/src/components/PlDataTable/createPlDataTable/discoverColumns.ts +48 -144
- package/src/components/PlDataTable/createPlDataTable/index.ts +2 -2
- package/src/components/PlDataTable/createPlDataTable/utils.test.ts +60 -69
- package/src/components/PlDataTable/createPlDataTable/utils.ts +65 -173
- package/src/components/PlDataTable/createPlDataTableSheet.ts +1 -1
- package/src/components/PlDataTable/index.ts +4 -2
- package/src/components/PlDataTable/labels.ts +4 -33
- package/src/components/PlDataTable/state-migration.ts +151 -22
- package/src/components/PlDataTable/typesV8.ts +188 -0
- package/src/components/PlDatasetSelector/build_dataset_options.ts +35 -60
- package/src/components/PlDatasetSelector/enrichment_discovery.ts +65 -61
- package/src/components/PlDatasetSelector/filter_discovery.test.ts +110 -72
- package/src/components/PlDatasetSelector/filter_discovery.ts +51 -31
- package/src/filters/converters/filterToQuery.test.ts +15 -8
- package/src/filters/converters/filterToQuery.ts +22 -9
- package/src/filters/converters/filterUiToExpressionImpl.test.ts +35 -36
- package/src/labels/derive_distinct_labels.ts +1 -1
- package/src/labels/derive_distinct_tooltips.test.ts +7 -4
- package/src/labels/derive_distinct_tooltips.ts +3 -3
- package/src/pframe_utils/axes.ts +2 -2
- package/src/pframe_utils/columns.ts +14 -23
- package/src/pframe_utils/index.ts +1 -1
- package/src/render/accessor.ts +35 -38
- package/src/render/api.ts +45 -61
- package/src/render/index.ts +2 -1
- package/src/render/internal.ts +43 -10
- package/src/render/util/axis_filtering.ts +0 -1
- package/src/render/util/column_collection.ts +17 -17
- package/src/render/util/pcolumn_data.ts +5 -9
- package/src/services/block_services.ts +1 -0
- package/src/services/get_services.ts +5 -2
- package/dist/columns/column_collection_builder.cjs +0 -241
- package/dist/columns/column_collection_builder.cjs.map +0 -1
- package/dist/columns/column_collection_builder.d.ts +0 -119
- package/dist/columns/column_collection_builder.d.ts.map +0 -1
- package/dist/columns/column_collection_builder.js +0 -241
- package/dist/columns/column_collection_builder.js.map +0 -1
- package/dist/columns/column_selector.cjs +0 -49
- package/dist/columns/column_selector.cjs.map +0 -1
- package/dist/columns/column_selector.d.ts +0 -33
- package/dist/columns/column_selector.d.ts.map +0 -1
- package/dist/columns/column_selector.js +0 -47
- package/dist/columns/column_selector.js.map +0 -1
- package/dist/columns/column_snapshot.cjs +0 -19
- package/dist/columns/column_snapshot.cjs.map +0 -1
- package/dist/columns/column_snapshot.d.ts +0 -39
- package/dist/columns/column_snapshot.d.ts.map +0 -1
- package/dist/columns/column_snapshot.js +0 -18
- package/dist/columns/column_snapshot.js.map +0 -1
- package/dist/columns/column_snapshot_provider.cjs +0 -137
- package/dist/columns/column_snapshot_provider.cjs.map +0 -1
- package/dist/columns/column_snapshot_provider.d.ts +0 -74
- package/dist/columns/column_snapshot_provider.d.ts.map +0 -1
- package/dist/columns/column_snapshot_provider.js +0 -133
- package/dist/columns/column_snapshot_provider.js.map +0 -1
- package/dist/columns/ctx_column_sources.cjs +0 -80
- package/dist/columns/ctx_column_sources.cjs.map +0 -1
- package/dist/columns/ctx_column_sources.d.ts +0 -30
- package/dist/columns/ctx_column_sources.d.ts.map +0 -1
- package/dist/columns/ctx_column_sources.js +0 -79
- package/dist/columns/ctx_column_sources.js.map +0 -1
- package/src/columns/column_collection_builder.test.ts +0 -484
- package/src/columns/column_collection_builder.ts +0 -485
- package/src/columns/column_selector.test.ts +0 -90
- package/src/columns/column_selector.ts +0 -100
- package/src/columns/column_snapshot.ts +0 -58
- package/src/columns/column_snapshot_provider.ts +0 -194
- package/src/columns/ctx_column_sources.ts +0 -99
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { Column } from "../column.js";
|
|
2
|
+
import { rebrandLeafId } from "./leaf_rebrand.js";
|
|
3
|
+
import { ColumnRecipe } from "./index.js";
|
|
4
|
+
import { ColumnOverriddenRecipe } from "./column_overrided_recipe.js";
|
|
5
|
+
import { distillColumnDiscoveredKey, extractPObjectId, stringifyColumnDiscoveredId } from "@milaboratories/pl-model-common";
|
|
6
|
+
import { throwError } from "@milaboratories/helpers";
|
|
7
|
+
//#region src/columns/column_recipes/column_discovered_recipe.ts
|
|
8
|
+
/**
|
|
9
|
+
* Recipe for columns identified by a {@link ColumnDiscoveredKey}: a base
|
|
10
|
+
* column + a `path` of linkers + qualifications.
|
|
11
|
+
*
|
|
12
|
+
* Specifics:
|
|
13
|
+
* - References more than one column (`column` + each `path[i].column`);
|
|
14
|
+
* {@link getDataStatus} aggregates across the whole set.
|
|
15
|
+
* - {@link getQuery} assembles the {@link SpecQuery} locally
|
|
16
|
+
* ({@link buildSpecQuery}) — the hit is inlined as its own recipe's query
|
|
17
|
+
* tree, linkers fold inside-out into nested `linkerJoin` nodes.
|
|
18
|
+
* - {@link getSpec} passes through to the hit column's own spec: the linker
|
|
19
|
+
* chain only enables co-indexing and does not remap the hit's `axesSpec`, so
|
|
20
|
+
* no engine round-trip is needed (mirrors the Discovered branch of
|
|
21
|
+
* `reconstructSpecFromId` on the host side).
|
|
22
|
+
*/
|
|
23
|
+
var ColumnDiscoveredRecipe = class ColumnDiscoveredRecipe {
|
|
24
|
+
key;
|
|
25
|
+
columns;
|
|
26
|
+
/**
|
|
27
|
+
* Validate the key + resolve every referenced column via
|
|
28
|
+
* {@link ColumnLazy.fromId} (which itself checks the leaf accessor reports
|
|
29
|
+
* `hasData()`). Returns `undefined` if the key is malformed or any
|
|
30
|
+
* referenced column is not yet spec-resolvable.
|
|
31
|
+
*
|
|
32
|
+
* Spec JSON is deserialized lazily on first {@link getSpec}/{@link getQuery}.
|
|
33
|
+
*/
|
|
34
|
+
static fromKey(key, opts = {}) {
|
|
35
|
+
const distilled = distillColumnDiscoveredKey(key);
|
|
36
|
+
const columns = {};
|
|
37
|
+
for (const uniId of referencedUniIdsOf(distilled)) {
|
|
38
|
+
const recipe = Column(uniId, opts);
|
|
39
|
+
if (recipe === void 0) return void 0;
|
|
40
|
+
columns[uniId] = recipe;
|
|
41
|
+
}
|
|
42
|
+
return new ColumnDiscoveredRecipe(distilled, columns);
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Static counterpart to {@link fromKey}: returns the resolution status of
|
|
46
|
+
* a {@link ColumnDiscoveredKey} without constructing the recipe. Worst-wins
|
|
47
|
+
* across every referenced {@link ColumnUniversalId} (hit + path linkers),
|
|
48
|
+
* each resolved via the top-level {@link ColumnRecipe.getStatus} dispatcher.
|
|
49
|
+
*/
|
|
50
|
+
static getStatusByKey(key, opts = {}) {
|
|
51
|
+
const distilled = distillColumnDiscoveredKey(key);
|
|
52
|
+
let worst = "present";
|
|
53
|
+
for (const uniId of referencedUniIdsOf(distilled)) {
|
|
54
|
+
const s = ColumnRecipe.getStatus(uniId, opts);
|
|
55
|
+
if (s === "absent") return "absent";
|
|
56
|
+
if (s === "resolving") worst = "resolving";
|
|
57
|
+
}
|
|
58
|
+
return worst;
|
|
59
|
+
}
|
|
60
|
+
id;
|
|
61
|
+
specCache;
|
|
62
|
+
queryCache;
|
|
63
|
+
dataStatusCache;
|
|
64
|
+
constructor(key, columns) {
|
|
65
|
+
this.key = key;
|
|
66
|
+
this.columns = columns;
|
|
67
|
+
this.id = stringifyColumnDiscoveredId(this.key);
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Universal id of the hit column (excluding path/qualifications on top).
|
|
71
|
+
* May itself be a wrapped id (Overridden / Filtered / nested Discovered) —
|
|
72
|
+
* preserves projections applied to the underlying column.
|
|
73
|
+
*/
|
|
74
|
+
getHitId() {
|
|
75
|
+
return this.key.column;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Axis qualifications attached to the hit column itself — applied to the
|
|
79
|
+
* outer-join entry that wraps this column at the consumer boundary.
|
|
80
|
+
*/
|
|
81
|
+
getColumnQualifications() {
|
|
82
|
+
return this.key.columnQualifications ?? [];
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Per-primary-column qualifications applied to the primary anchors on
|
|
86
|
+
* this group's side. Keyed by the external primary column id.
|
|
87
|
+
*/
|
|
88
|
+
getQueriesQualifications() {
|
|
89
|
+
return this.key.queriesQualifications ?? {};
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Leaf {@link PObjectId}s the recipe physically depends on: hit column +
|
|
93
|
+
* each linker in `path`, with any projection wrappers unwrapped down to
|
|
94
|
+
* their underlying storage column. Used to track real-data dependencies
|
|
95
|
+
* (e.g. {@link getDataStatus}), not projected identities.
|
|
96
|
+
*/
|
|
97
|
+
getReferencedIds() {
|
|
98
|
+
return [...new Set([...referencedUniIdsOf(this.key)].map((uniId) => extractPObjectId(uniId)))];
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Final spec of a discovered hit is just the hit column's own spec: the
|
|
102
|
+
* linker chain only enables co-indexing, it does not remap the hit's
|
|
103
|
+
* `axesSpec`, and axis qualifications live on the outer join entry (see
|
|
104
|
+
* {@link buildSpecQuery}), not in the spec. So pass through to the hit
|
|
105
|
+
* recipe's `getSpec()` — no engine round-trip needed. This mirrors the
|
|
106
|
+
* Discovered branch of `reconstructSpecFromId` on the host side.
|
|
107
|
+
*/
|
|
108
|
+
getSpec() {
|
|
109
|
+
if (this.specCache === void 0) {
|
|
110
|
+
const hit = this.columns[this.key.column] ?? throwError(`ColumnDiscoveredRecipe.getSpec: missing column ${this.key.column}`);
|
|
111
|
+
this.specCache = { value: hit.getSpec() };
|
|
112
|
+
}
|
|
113
|
+
return this.specCache.value;
|
|
114
|
+
}
|
|
115
|
+
/** IR for building the final spec — see {@link buildSpecQuery}. */
|
|
116
|
+
getQuery() {
|
|
117
|
+
if (this.queryCache === void 0) this.queryCache = { value: this.buildSpecQuery() };
|
|
118
|
+
return this.queryCache.value;
|
|
119
|
+
}
|
|
120
|
+
getDataStatus() {
|
|
121
|
+
if (this.dataStatusCache === void 0) this.dataStatusCache = { value: Object.values(this.columns).reduce((worst, lazy) => {
|
|
122
|
+
const s = lazy.getDataStatus();
|
|
123
|
+
if (s === "absent" || worst === "absent") return "absent";
|
|
124
|
+
if (s === "resolving") return "resolving";
|
|
125
|
+
return worst;
|
|
126
|
+
}, "present") };
|
|
127
|
+
return this.dataStatusCache.value;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Discovered + overrides → Overridden<Discovered>. Delegates to the
|
|
131
|
+
* flat-merge factory of ColumnOverriddenRecipe; subsequent `withSpecs`
|
|
132
|
+
* calls merge at the Overridden level (one wrapper, no nesting).
|
|
133
|
+
*/
|
|
134
|
+
withSpecs(overrides) {
|
|
135
|
+
return ColumnOverriddenRecipe.wrap(this, overrides);
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Assembles the SpecQuery for this discovered hit by folding `key.path`
|
|
139
|
+
* around the hit column.
|
|
140
|
+
*
|
|
141
|
+
* The hit (innermost) is built by inlining `columns[key.column].getQuery()`
|
|
142
|
+
* — recursing into the hit's own recipe — so wrapping layers on the hit
|
|
143
|
+
* (Overridden / Filtered / nested Discovered) appear in the produced tree.
|
|
144
|
+
* The previous `pframeSpec.buildQuery` path was a flat
|
|
145
|
+
* {@link PObjectId}-only call and could not express that.
|
|
146
|
+
*
|
|
147
|
+
* Linkers stay as plain column references on the linker side of
|
|
148
|
+
* `linkerJoin` (the spec node has no slot for a query-side linker); the
|
|
149
|
+
* linker's recipe id is used directly. The frame registered in
|
|
150
|
+
* {@link getSpec} carries each recipe's final spec under that same id, so
|
|
151
|
+
* the engine resolves linker axes from the post-projection spec.
|
|
152
|
+
*
|
|
153
|
+
* Path ordering matches {@link ColumnDiscoveredKey.path}: `path[0]` is
|
|
154
|
+
* outermost, `path[N-1]` is closest to the hit. We fold from the inside
|
|
155
|
+
* out — innermost wrap first — so the result lines up with that convention.
|
|
156
|
+
*
|
|
157
|
+
* `columnQualifications` / `queriesQualifications` are not emitted here —
|
|
158
|
+
* qualifications live on a {@link SpecQueryJoinEntry} wrapper (lost on
|
|
159
|
+
* unwrapping to {@link SpecQuery}). External consumers apply them at the
|
|
160
|
+
* outer join via {@link getColumnQualifications} / {@link getQueriesQualifications}.
|
|
161
|
+
*/
|
|
162
|
+
buildSpecQuery() {
|
|
163
|
+
const hitRecipe = this.columns[this.key.column] ?? throwError(`ColumnDiscoveredRecipe.buildSpecQuery: missing column ${this.key.column}`);
|
|
164
|
+
let query = rebrandLeafId(hitRecipe.getQuery(), hitRecipe.id, this.id);
|
|
165
|
+
const path = this.key.path ?? [];
|
|
166
|
+
for (let i = path.length - 1; i >= 0; i--) query = {
|
|
167
|
+
type: "linkerJoin",
|
|
168
|
+
linker: (this.columns[path[i].column] ?? throwError(`ColumnDiscoveredRecipe.buildSpecQuery: missing linker column ${path[i].column}`)).getQuery(),
|
|
169
|
+
secondary: [{ entry: query }]
|
|
170
|
+
};
|
|
171
|
+
return query;
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
function referencedUniIdsOf(key) {
|
|
175
|
+
return /* @__PURE__ */ new Set([key.column, ...(key.path ?? []).map((item) => item.column)]);
|
|
176
|
+
}
|
|
177
|
+
//#endregion
|
|
178
|
+
export { ColumnDiscoveredRecipe };
|
|
179
|
+
|
|
180
|
+
//# sourceMappingURL=column_discovered_recipe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"column_discovered_recipe.js","names":[],"sources":["../../../src/columns/column_recipes/column_discovered_recipe.ts"],"sourcesContent":["import {\n distillColumnDiscoveredKey,\n extractPObjectId,\n stringifyColumnDiscoveredId,\n type AxisQualification,\n type ColumnDiscoveredId,\n type ColumnDiscoveredKey,\n type ColumnUniversalId,\n type PColumnSpec,\n type PObjectId,\n type SpecOverrides,\n type SpecQuery,\n} from \"@milaboratories/pl-model-common\";\nimport type { GlobalCfgRenderCtx } from \"../../render/internal\";\nimport type { ColumnFieldStatus, ColumnResolutionStatus } from \"./types\";\nimport { ColumnRecipe } from \"./index\";\nimport { ColumnOverriddenRecipe } from \"./column_overrided_recipe\";\nimport { Column } from \"../column\";\nimport { rebrandLeafId } from \"./leaf_rebrand\";\nimport { throwError } from \"@milaboratories/helpers\";\n\n/**\n * Recipe for columns identified by a {@link ColumnDiscoveredKey}: a base\n * column + a `path` of linkers + qualifications.\n *\n * Specifics:\n * - References more than one column (`column` + each `path[i].column`);\n * {@link getDataStatus} aggregates across the whole set.\n * - {@link getQuery} assembles the {@link SpecQuery} locally\n * ({@link buildSpecQuery}) — the hit is inlined as its own recipe's query\n * tree, linkers fold inside-out into nested `linkerJoin` nodes.\n * - {@link getSpec} passes through to the hit column's own spec: the linker\n * chain only enables co-indexing and does not remap the hit's `axesSpec`, so\n * no engine round-trip is needed (mirrors the Discovered branch of\n * `reconstructSpecFromId` on the host side).\n */\nexport class ColumnDiscoveredRecipe implements ColumnRecipe<ColumnDiscoveredId> {\n /**\n * Validate the key + resolve every referenced column via\n * {@link ColumnLazy.fromId} (which itself checks the leaf accessor reports\n * `hasData()`). Returns `undefined` if the key is malformed or any\n * referenced column is not yet spec-resolvable.\n *\n * Spec JSON is deserialized lazily on first {@link getSpec}/{@link getQuery}.\n */\n static fromKey(\n key: ColumnDiscoveredKey,\n opts: { ctx?: GlobalCfgRenderCtx } = {},\n ): undefined | ColumnDiscoveredRecipe {\n const distilled = distillColumnDiscoveredKey(key);\n const columns: Record<ColumnUniversalId, Column> = {};\n for (const uniId of referencedUniIdsOf(distilled)) {\n const recipe = Column(uniId, opts);\n if (recipe === undefined) return undefined;\n columns[uniId] = recipe;\n }\n return new ColumnDiscoveredRecipe(distilled, columns);\n }\n\n /**\n * Static counterpart to {@link fromKey}: returns the resolution status of\n * a {@link ColumnDiscoveredKey} without constructing the recipe. Worst-wins\n * across every referenced {@link ColumnUniversalId} (hit + path linkers),\n * each resolved via the top-level {@link ColumnRecipe.getStatus} dispatcher.\n */\n static getStatusByKey(\n key: ColumnDiscoveredKey,\n opts: { ctx?: GlobalCfgRenderCtx } = {},\n ): ColumnResolutionStatus {\n const distilled = distillColumnDiscoveredKey(key);\n let worst: ColumnResolutionStatus = \"present\";\n for (const uniId of referencedUniIdsOf(distilled)) {\n const s = ColumnRecipe.getStatus(uniId, opts);\n if (s === \"absent\") return \"absent\";\n if (s === \"resolving\") worst = \"resolving\";\n }\n return worst;\n }\n\n readonly id: ColumnDiscoveredId;\n private specCache?: { readonly value: PColumnSpec };\n private queryCache?: { readonly value: SpecQuery };\n private dataStatusCache?: { readonly value: ColumnFieldStatus };\n\n private constructor(\n private readonly key: ColumnDiscoveredKey,\n private readonly columns: Record<ColumnUniversalId, ColumnRecipe>,\n ) {\n this.id = stringifyColumnDiscoveredId(this.key);\n }\n\n /**\n * Universal id of the hit column (excluding path/qualifications on top).\n * May itself be a wrapped id (Overridden / Filtered / nested Discovered) —\n * preserves projections applied to the underlying column.\n */\n getHitId(): ColumnUniversalId {\n return this.key.column;\n }\n\n /**\n * Axis qualifications attached to the hit column itself — applied to the\n * outer-join entry that wraps this column at the consumer boundary.\n */\n getColumnQualifications(): readonly AxisQualification[] {\n return this.key.columnQualifications ?? [];\n }\n\n /**\n * Per-primary-column qualifications applied to the primary anchors on\n * this group's side. Keyed by the external primary column id.\n */\n getQueriesQualifications(): Readonly<Record<PObjectId, AxisQualification[]>> {\n return this.key.queriesQualifications ?? {};\n }\n\n /**\n * Leaf {@link PObjectId}s the recipe physically depends on: hit column +\n * each linker in `path`, with any projection wrappers unwrapped down to\n * their underlying storage column. Used to track real-data dependencies\n * (e.g. {@link getDataStatus}), not projected identities.\n */\n getReferencedIds(): PObjectId[] {\n return [...new Set([...referencedUniIdsOf(this.key)].map((uniId) => extractPObjectId(uniId)))];\n }\n\n /**\n * Final spec of a discovered hit is just the hit column's own spec: the\n * linker chain only enables co-indexing, it does not remap the hit's\n * `axesSpec`, and axis qualifications live on the outer join entry (see\n * {@link buildSpecQuery}), not in the spec. So pass through to the hit\n * recipe's `getSpec()` — no engine round-trip needed. This mirrors the\n * Discovered branch of `reconstructSpecFromId` on the host side.\n */\n getSpec(): PColumnSpec {\n if (this.specCache === undefined) {\n const hit =\n this.columns[this.key.column] ??\n throwError(`ColumnDiscoveredRecipe.getSpec: missing column ${this.key.column}`);\n this.specCache = { value: hit.getSpec() };\n }\n return this.specCache.value;\n }\n\n /** IR for building the final spec — see {@link buildSpecQuery}. */\n getQuery(): SpecQuery {\n if (this.queryCache === undefined) {\n this.queryCache = { value: this.buildSpecQuery() };\n }\n return this.queryCache.value;\n }\n\n getDataStatus(): ColumnFieldStatus {\n if (this.dataStatusCache === undefined) {\n this.dataStatusCache = {\n value: Object.values(this.columns).reduce<ColumnFieldStatus>((worst, lazy) => {\n const s = lazy.getDataStatus();\n if (s === \"absent\" || worst === \"absent\") return \"absent\";\n if (s === \"resolving\") return \"resolving\";\n return worst;\n }, \"present\"),\n };\n }\n return this.dataStatusCache.value;\n }\n\n /**\n * Discovered + overrides → Overridden<Discovered>. Delegates to the\n * flat-merge factory of ColumnOverriddenRecipe; subsequent `withSpecs`\n * calls merge at the Overridden level (one wrapper, no nesting).\n */\n withSpecs(overrides: SpecOverrides): ColumnRecipe {\n return ColumnOverriddenRecipe.wrap(this, overrides);\n }\n\n /**\n * Assembles the SpecQuery for this discovered hit by folding `key.path`\n * around the hit column.\n *\n * The hit (innermost) is built by inlining `columns[key.column].getQuery()`\n * — recursing into the hit's own recipe — so wrapping layers on the hit\n * (Overridden / Filtered / nested Discovered) appear in the produced tree.\n * The previous `pframeSpec.buildQuery` path was a flat\n * {@link PObjectId}-only call and could not express that.\n *\n * Linkers stay as plain column references on the linker side of\n * `linkerJoin` (the spec node has no slot for a query-side linker); the\n * linker's recipe id is used directly. The frame registered in\n * {@link getSpec} carries each recipe's final spec under that same id, so\n * the engine resolves linker axes from the post-projection spec.\n *\n * Path ordering matches {@link ColumnDiscoveredKey.path}: `path[0]` is\n * outermost, `path[N-1]` is closest to the hit. We fold from the inside\n * out — innermost wrap first — so the result lines up with that convention.\n *\n * `columnQualifications` / `queriesQualifications` are not emitted here —\n * qualifications live on a {@link SpecQueryJoinEntry} wrapper (lost on\n * unwrapping to {@link SpecQuery}). External consumers apply them at the\n * outer join via {@link getColumnQualifications} / {@link getQueriesQualifications}.\n */\n private buildSpecQuery(): SpecQuery {\n // Preserve the inner hit recipe's full query tree — it may carry\n // wrappers (specOverride / sliceAxes / nested linkerJoin) that the\n // host needs to apply correctly. We only rebrand the terminal column\n // leaf to this.id so two variants of the same physical hit reached via\n // different linker chains stay distinct columns in the engine output.\n const hitRecipe =\n this.columns[this.key.column] ??\n throwError(`ColumnDiscoveredRecipe.buildSpecQuery: missing column ${this.key.column}`);\n let query: SpecQuery = rebrandLeafId(hitRecipe.getQuery(), hitRecipe.id, this.id);\n const path = this.key.path ?? [];\n\n for (let i = path.length - 1; i >= 0; i--) {\n const linker =\n this.columns[path[i].column] ??\n throwError(\n `ColumnDiscoveredRecipe.buildSpecQuery: missing linker column ${path[i].column}`,\n );\n query = {\n type: \"linkerJoin\",\n linker: linker.getQuery(),\n secondary: [{ entry: query }],\n };\n }\n return query;\n }\n}\n\nfunction referencedUniIdsOf(key: ColumnDiscoveredKey): Set<ColumnUniversalId> {\n return new Set<ColumnUniversalId>([key.column, ...(key.path ?? []).map((item) => item.column)]);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAoCA,IAAa,yBAAb,MAAa,uBAAmE;CAiD3D;CACA;;;;;;;;;CAzCnB,OAAO,QACL,KACA,OAAqC,CAAC,GACF;EACpC,MAAM,YAAY,2BAA2B,GAAG;EAChD,MAAM,UAA6C,CAAC;EACpD,KAAK,MAAM,SAAS,mBAAmB,SAAS,GAAG;GACjD,MAAM,SAAS,OAAO,OAAO,IAAI;GACjC,IAAI,WAAW,KAAA,GAAW,OAAO,KAAA;GACjC,QAAQ,SAAS;EACnB;EACA,OAAO,IAAI,uBAAuB,WAAW,OAAO;CACtD;;;;;;;CAQA,OAAO,eACL,KACA,OAAqC,CAAC,GACd;EACxB,MAAM,YAAY,2BAA2B,GAAG;EAChD,IAAI,QAAgC;EACpC,KAAK,MAAM,SAAS,mBAAmB,SAAS,GAAG;GACjD,MAAM,IAAI,aAAa,UAAU,OAAO,IAAI;GAC5C,IAAI,MAAM,UAAU,OAAO;GAC3B,IAAI,MAAM,aAAa,QAAQ;EACjC;EACA,OAAO;CACT;CAEA;CACA;CACA;CACA;CAEA,YACE,KACA,SACA;EAFiB,KAAA,MAAA;EACA,KAAA,UAAA;EAEjB,KAAK,KAAK,4BAA4B,KAAK,GAAG;CAChD;;;;;;CAOA,WAA8B;EAC5B,OAAO,KAAK,IAAI;CAClB;;;;;CAMA,0BAAwD;EACtD,OAAO,KAAK,IAAI,wBAAwB,CAAC;CAC3C;;;;;CAMA,2BAA6E;EAC3E,OAAO,KAAK,IAAI,yBAAyB,CAAC;CAC5C;;;;;;;CAQA,mBAAgC;EAC9B,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,mBAAmB,KAAK,GAAG,CAAC,CAAC,CAAC,KAAK,UAAU,iBAAiB,KAAK,CAAC,CAAC,CAAC;CAC/F;;;;;;;;;CAUA,UAAuB;EACrB,IAAI,KAAK,cAAc,KAAA,GAAW;GAChC,MAAM,MACJ,KAAK,QAAQ,KAAK,IAAI,WACtB,WAAW,kDAAkD,KAAK,IAAI,QAAQ;GAChF,KAAK,YAAY,EAAE,OAAO,IAAI,QAAQ,EAAE;EAC1C;EACA,OAAO,KAAK,UAAU;CACxB;;CAGA,WAAsB;EACpB,IAAI,KAAK,eAAe,KAAA,GACtB,KAAK,aAAa,EAAE,OAAO,KAAK,eAAe,EAAE;EAEnD,OAAO,KAAK,WAAW;CACzB;CAEA,gBAAmC;EACjC,IAAI,KAAK,oBAAoB,KAAA,GAC3B,KAAK,kBAAkB,EACrB,OAAO,OAAO,OAAO,KAAK,OAAO,CAAC,CAAC,QAA2B,OAAO,SAAS;GAC5E,MAAM,IAAI,KAAK,cAAc;GAC7B,IAAI,MAAM,YAAY,UAAU,UAAU,OAAO;GACjD,IAAI,MAAM,aAAa,OAAO;GAC9B,OAAO;EACT,GAAG,SAAS,EACd;EAEF,OAAO,KAAK,gBAAgB;CAC9B;;;;;;CAOA,UAAU,WAAwC;EAChD,OAAO,uBAAuB,KAAK,MAAM,SAAS;CACpD;;;;;;;;;;;;;;;;;;;;;;;;;;CA2BA,iBAAoC;EAMlC,MAAM,YACJ,KAAK,QAAQ,KAAK,IAAI,WACtB,WAAW,yDAAyD,KAAK,IAAI,QAAQ;EACvF,IAAI,QAAmB,cAAc,UAAU,SAAS,GAAG,UAAU,IAAI,KAAK,EAAE;EAChF,MAAM,OAAO,KAAK,IAAI,QAAQ,CAAC;EAE/B,KAAK,IAAI,IAAI,KAAK,SAAS,GAAG,KAAK,GAAG,KAMpC,QAAQ;GACN,MAAM;GACN,SANA,KAAK,QAAQ,KAAK,EAAE,CAAC,WACrB,WACE,gEAAgE,KAAK,EAAE,CAAC,QAC1E,EAAA,CAGe,SAAS;GACxB,WAAW,CAAC,EAAE,OAAO,MAAM,CAAC;EAC9B;EAEF,OAAO;CACT;AACF;AAEA,SAAS,mBAAmB,KAAkD;CAC5E,uBAAO,IAAI,IAAuB,CAAC,IAAI,QAAQ,IAAI,IAAI,QAAQ,CAAC,EAAA,CAAG,KAAK,SAAS,KAAK,MAAM,CAAC,CAAC;AAChG"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
const require_leaf_rebrand = require("./leaf_rebrand.cjs");
|
|
2
|
+
const require_index = require("./index.cjs");
|
|
3
|
+
const require_column_overrided_recipe = require("./column_overrided_recipe.cjs");
|
|
4
|
+
let _milaboratories_pl_model_common = require("@milaboratories/pl-model-common");
|
|
5
|
+
//#region src/columns/column_recipes/column_filtered_recipe.ts
|
|
6
|
+
/**
|
|
7
|
+
* Recipe wrapper that fixes the values of selected axes of an inner recipe
|
|
8
|
+
* (axis slicing). The id is `FilteredPColumnId { source: inner.id,
|
|
9
|
+
* axisFilters }`.
|
|
10
|
+
*
|
|
11
|
+
* Flat-merge invariant: `inner` is never another {@link ColumnFilteredRecipe}.
|
|
12
|
+
* Repeated {@link wrap} concatenates `axisFilters` at the current level.
|
|
13
|
+
*
|
|
14
|
+
* Layering: `withSpecs` on a Filtered recipe yields
|
|
15
|
+
* `Overridden<Filtered<inner>>` — Overridden is always the outermost layer.
|
|
16
|
+
* The reverse layering (`Filtered<Overridden<...>>`) is not reachable via
|
|
17
|
+
* the public interface.
|
|
18
|
+
*/
|
|
19
|
+
var ColumnFilteredRecipe = class ColumnFilteredRecipe {
|
|
20
|
+
inner;
|
|
21
|
+
axisFilters;
|
|
22
|
+
/**
|
|
23
|
+
* Wrap any recipe with axis filters. If `inner` is already a
|
|
24
|
+
* {@link ColumnFilteredRecipe}, concatenates `axisFilters` and returns a
|
|
25
|
+
* new Filtered sharing the original `inner`.
|
|
26
|
+
*
|
|
27
|
+
* Validates every axis index against `inner.getSpec().axesSpec` at
|
|
28
|
+
* construction — throws on an out-of-range index. After {@link wrap}, the
|
|
29
|
+
* recipe is guaranteed to be spec-complete.
|
|
30
|
+
*
|
|
31
|
+
* Order semantics: new filters are appended after existing ones, preserving
|
|
32
|
+
* their relative order. AND composition is otherwise commutative; order
|
|
33
|
+
* only affects canonicalize/equality.
|
|
34
|
+
*/
|
|
35
|
+
static wrap(col, axisFilters) {
|
|
36
|
+
const combined = col instanceof ColumnFilteredRecipe ? [...col.axisFilters, ...axisFilters] : axisFilters;
|
|
37
|
+
const base = col instanceof ColumnFilteredRecipe ? col.inner : col;
|
|
38
|
+
if (combined.length === 0) throw new Error("ColumnFilteredRecipe.wrap: at least one axis filter must be provided");
|
|
39
|
+
const innerSpec = base.getSpec();
|
|
40
|
+
const fixed = /* @__PURE__ */ new Set();
|
|
41
|
+
for (const [idx] of combined) {
|
|
42
|
+
if (innerSpec.axesSpec[idx] === void 0) throw new Error(`ColumnFilteredRecipe.wrap: axis index ${idx} out of range (inner has ${innerSpec.axesSpec.length} axes)`);
|
|
43
|
+
fixed.add(idx);
|
|
44
|
+
}
|
|
45
|
+
if (fixed.size >= innerSpec.axesSpec.length) throw new Error(`ColumnFilteredRecipe.wrap: filters fix all ${innerSpec.axesSpec.length} axes — at least one axis must remain`);
|
|
46
|
+
return new ColumnFilteredRecipe(base, combined);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Static counterpart to {@link wrap}: returns the resolution status of a
|
|
50
|
+
* {@link ColumnFilteredKey} without constructing the recipe. Axis filters
|
|
51
|
+
* do not add references — status collapses to the source's status.
|
|
52
|
+
*/
|
|
53
|
+
static getStatusByKey(key, opts = {}) {
|
|
54
|
+
if (typeof key.source !== "string") throw new Error("ColumnFilteredRecipe.getStatusByKey: filtered column with non-string source");
|
|
55
|
+
return require_index.ColumnRecipe.getStatus(key.source, opts);
|
|
56
|
+
}
|
|
57
|
+
id;
|
|
58
|
+
specCache;
|
|
59
|
+
queryCache;
|
|
60
|
+
dataStatusCache;
|
|
61
|
+
constructor(inner, axisFilters) {
|
|
62
|
+
this.inner = inner;
|
|
63
|
+
this.axisFilters = axisFilters;
|
|
64
|
+
this.id = (0, _milaboratories_pl_model_common.stringifyColumnFilteredId)({
|
|
65
|
+
source: inner.id,
|
|
66
|
+
axisFilters
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
/** Wrapped recipe — exposed so external walkers can descend. */
|
|
70
|
+
getInner() {
|
|
71
|
+
return this.inner;
|
|
72
|
+
}
|
|
73
|
+
/** Axis filters do not introduce references to other columns. */
|
|
74
|
+
getReferencedIds() {
|
|
75
|
+
return this.inner.getReferencedIds();
|
|
76
|
+
}
|
|
77
|
+
getDataStatus() {
|
|
78
|
+
if (this.dataStatusCache === void 0) this.dataStatusCache = { value: this.inner.getDataStatus() };
|
|
79
|
+
return this.dataStatusCache.value;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Final spec — the inner spec with fixed axes removed. Indices in
|
|
83
|
+
* `axisFilters` are positional against `inner.getSpec().axesSpec` and were
|
|
84
|
+
* validated at {@link wrap} time.
|
|
85
|
+
*/
|
|
86
|
+
getSpec() {
|
|
87
|
+
if (this.specCache === void 0) this.specCache = { value: (0, _milaboratories_pl_model_common.applyAxisFilters)(this.inner.getSpec(), this.axisFilters) };
|
|
88
|
+
return this.specCache.value;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Wraps the inner query in `SpecQuerySliceAxes`. Index→selector resolution
|
|
92
|
+
* goes through the inner spec — guaranteed available since {@link wrap}
|
|
93
|
+
* validated all indices at construction.
|
|
94
|
+
*/
|
|
95
|
+
getQuery() {
|
|
96
|
+
if (this.queryCache === void 0) {
|
|
97
|
+
const innerQuery = this.inner.getQuery();
|
|
98
|
+
if (this.axisFilters.length === 0) this.queryCache = { value: require_leaf_rebrand.rebrandLeafId(innerQuery, this.inner.id, this.id) };
|
|
99
|
+
else {
|
|
100
|
+
const innerSpec = this.inner.getSpec();
|
|
101
|
+
this.queryCache = { value: {
|
|
102
|
+
type: "sliceAxes",
|
|
103
|
+
input: require_leaf_rebrand.rebrandLeafId(innerQuery, this.inner.id, this.id),
|
|
104
|
+
axisFilters: this.axisFilters.map(([idx, value]) => ({
|
|
105
|
+
axisSelector: toAxisSelector(innerSpec.axesSpec[idx]),
|
|
106
|
+
constant: value
|
|
107
|
+
}))
|
|
108
|
+
} };
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return this.queryCache.value;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Filtered + overrides → Overridden<Filtered>. Overridden is always the
|
|
115
|
+
* outermost layer.
|
|
116
|
+
*/
|
|
117
|
+
withSpecs(overrides) {
|
|
118
|
+
return require_column_overrided_recipe.ColumnOverriddenRecipe.wrap(this, overrides);
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
function toAxisSelector(axis) {
|
|
122
|
+
const selector = {
|
|
123
|
+
name: axis.name,
|
|
124
|
+
type: axis.type
|
|
125
|
+
};
|
|
126
|
+
if (axis.domain !== void 0 && Object.keys(axis.domain).length > 0) selector.domain = axis.domain;
|
|
127
|
+
if (axis.contextDomain !== void 0 && Object.keys(axis.contextDomain).length > 0) selector.contextDomain = axis.contextDomain;
|
|
128
|
+
return selector;
|
|
129
|
+
}
|
|
130
|
+
//#endregion
|
|
131
|
+
exports.ColumnFilteredRecipe = ColumnFilteredRecipe;
|
|
132
|
+
|
|
133
|
+
//# sourceMappingURL=column_filtered_recipe.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"column_filtered_recipe.cjs","names":["ColumnRecipe","rebrandLeafId","ColumnOverriddenRecipe"],"sources":["../../../src/columns/column_recipes/column_filtered_recipe.ts"],"sourcesContent":["import {\n applyAxisFilters,\n stringifyColumnFilteredId,\n type AxisFilterByIdx,\n type AxisSpec,\n type ColumnFilteredId,\n type ColumnFilteredKey,\n type PColumnSpec,\n type PObjectId,\n type SingleAxisSelector,\n type SpecOverrides,\n type SpecQuery,\n} from \"@milaboratories/pl-model-common\";\nimport type { GlobalCfgRenderCtx } from \"../../render/internal\";\nimport type { ColumnFieldStatus, ColumnResolutionStatus } from \"./types\";\nimport { ColumnRecipe } from \"./index\";\nimport { ColumnOverriddenRecipe } from \"./column_overrided_recipe\";\nimport { rebrandLeafId } from \"./leaf_rebrand\";\n\n/**\n * Recipe wrapper that fixes the values of selected axes of an inner recipe\n * (axis slicing). The id is `FilteredPColumnId { source: inner.id,\n * axisFilters }`.\n *\n * Flat-merge invariant: `inner` is never another {@link ColumnFilteredRecipe}.\n * Repeated {@link wrap} concatenates `axisFilters` at the current level.\n *\n * Layering: `withSpecs` on a Filtered recipe yields\n * `Overridden<Filtered<inner>>` — Overridden is always the outermost layer.\n * The reverse layering (`Filtered<Overridden<...>>`) is not reachable via\n * the public interface.\n */\nexport class ColumnFilteredRecipe implements ColumnRecipe<ColumnFilteredId> {\n /**\n * Wrap any recipe with axis filters. If `inner` is already a\n * {@link ColumnFilteredRecipe}, concatenates `axisFilters` and returns a\n * new Filtered sharing the original `inner`.\n *\n * Validates every axis index against `inner.getSpec().axesSpec` at\n * construction — throws on an out-of-range index. After {@link wrap}, the\n * recipe is guaranteed to be spec-complete.\n *\n * Order semantics: new filters are appended after existing ones, preserving\n * their relative order. AND composition is otherwise commutative; order\n * only affects canonicalize/equality.\n */\n static wrap(col: ColumnRecipe, axisFilters: AxisFilterByIdx[]): ColumnFilteredRecipe {\n const combined =\n col instanceof ColumnFilteredRecipe ? [...col.axisFilters, ...axisFilters] : axisFilters;\n const base = col instanceof ColumnFilteredRecipe ? col.inner : col;\n\n if (combined.length === 0) {\n throw new Error(\"ColumnFilteredRecipe.wrap: at least one axis filter must be provided\");\n }\n\n const innerSpec = base.getSpec();\n const fixed = new Set<number>();\n for (const [idx] of combined) {\n if (innerSpec.axesSpec[idx] === undefined) {\n throw new Error(\n `ColumnFilteredRecipe.wrap: axis index ${idx} out of range (inner has ${innerSpec.axesSpec.length} axes)`,\n );\n }\n fixed.add(idx);\n }\n if (fixed.size >= innerSpec.axesSpec.length) {\n throw new Error(\n `ColumnFilteredRecipe.wrap: filters fix all ${innerSpec.axesSpec.length} axes — at least one axis must remain`,\n );\n }\n\n return new ColumnFilteredRecipe(base, combined);\n }\n\n /**\n * Static counterpart to {@link wrap}: returns the resolution status of a\n * {@link ColumnFilteredKey} without constructing the recipe. Axis filters\n * do not add references — status collapses to the source's status.\n */\n static getStatusByKey(\n key: ColumnFilteredKey,\n opts: { ctx?: GlobalCfgRenderCtx } = {},\n ): ColumnResolutionStatus {\n if (typeof key.source !== \"string\") {\n throw new Error(\n \"ColumnFilteredRecipe.getStatusByKey: filtered column with non-string source\",\n );\n }\n return ColumnRecipe.getStatus(key.source, opts);\n }\n\n readonly id: ColumnFilteredId;\n private specCache?: { readonly value: PColumnSpec };\n private queryCache?: { readonly value: SpecQuery };\n private dataStatusCache?: { readonly value: ColumnFieldStatus };\n\n private constructor(\n private readonly inner: ColumnRecipe,\n private readonly axisFilters: AxisFilterByIdx[],\n ) {\n this.id = stringifyColumnFilteredId({\n source: inner.id,\n axisFilters,\n });\n }\n\n /** Wrapped recipe — exposed so external walkers can descend. */\n getInner(): ColumnRecipe {\n return this.inner;\n }\n\n /** Axis filters do not introduce references to other columns. */\n getReferencedIds(): PObjectId[] {\n return this.inner.getReferencedIds();\n }\n\n getDataStatus(): ColumnFieldStatus {\n if (this.dataStatusCache === undefined) {\n this.dataStatusCache = { value: this.inner.getDataStatus() };\n }\n return this.dataStatusCache.value;\n }\n\n /**\n * Final spec — the inner spec with fixed axes removed. Indices in\n * `axisFilters` are positional against `inner.getSpec().axesSpec` and were\n * validated at {@link wrap} time.\n */\n getSpec(): PColumnSpec {\n if (this.specCache === undefined) {\n this.specCache = { value: applyAxisFilters(this.inner.getSpec(), this.axisFilters) };\n }\n return this.specCache.value;\n }\n\n /**\n * Wraps the inner query in `SpecQuerySliceAxes`. Index→selector resolution\n * goes through the inner spec — guaranteed available since {@link wrap}\n * validated all indices at construction.\n */\n getQuery(): SpecQuery {\n if (this.queryCache === undefined) {\n const innerQuery = this.inner.getQuery();\n if (this.axisFilters.length === 0) {\n // Pass-through (no filters): rebrand the inner leaf to this.id so\n // wrappers in the chain don't reintroduce the inner's id at the\n // leaf — keeps the resolver/leaf-id contract uniform.\n this.queryCache = { value: rebrandLeafId(innerQuery, this.inner.id, this.id) };\n } else {\n const innerSpec = this.inner.getSpec();\n this.queryCache = {\n value: {\n type: \"sliceAxes\",\n input: rebrandLeafId(innerQuery, this.inner.id, this.id),\n axisFilters: this.axisFilters.map(([idx, value]) => ({\n axisSelector: toAxisSelector(innerSpec.axesSpec[idx]),\n constant: value,\n })),\n },\n };\n }\n }\n return this.queryCache.value;\n }\n\n /**\n * Filtered + overrides → Overridden<Filtered>. Overridden is always the\n * outermost layer.\n */\n withSpecs(overrides: SpecOverrides): ColumnRecipe {\n return ColumnOverriddenRecipe.wrap(this, overrides);\n }\n}\n\nfunction toAxisSelector(axis: AxisSpec): SingleAxisSelector {\n const selector: SingleAxisSelector = { name: axis.name, type: axis.type };\n if (axis.domain !== undefined && Object.keys(axis.domain).length > 0) {\n selector.domain = axis.domain;\n }\n if (axis.contextDomain !== undefined && Object.keys(axis.contextDomain).length > 0) {\n selector.contextDomain = axis.contextDomain;\n }\n return selector;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAgCA,IAAa,uBAAb,MAAa,qBAA+D;CAiEvD;CACA;;;;;;;;;;;;;;CApDnB,OAAO,KAAK,KAAmB,aAAsD;EACnF,MAAM,WACJ,eAAe,uBAAuB,CAAC,GAAG,IAAI,aAAa,GAAG,WAAW,IAAI;EAC/E,MAAM,OAAO,eAAe,uBAAuB,IAAI,QAAQ;EAE/D,IAAI,SAAS,WAAW,GACtB,MAAM,IAAI,MAAM,sEAAsE;EAGxF,MAAM,YAAY,KAAK,QAAQ;EAC/B,MAAM,wBAAQ,IAAI,IAAY;EAC9B,KAAK,MAAM,CAAC,QAAQ,UAAU;GAC5B,IAAI,UAAU,SAAS,SAAS,KAAA,GAC9B,MAAM,IAAI,MACR,yCAAyC,IAAI,2BAA2B,UAAU,SAAS,OAAO,OACpG;GAEF,MAAM,IAAI,GAAG;EACf;EACA,IAAI,MAAM,QAAQ,UAAU,SAAS,QACnC,MAAM,IAAI,MACR,8CAA8C,UAAU,SAAS,OAAO,sCAC1E;EAGF,OAAO,IAAI,qBAAqB,MAAM,QAAQ;CAChD;;;;;;CAOA,OAAO,eACL,KACA,OAAqC,CAAC,GACd;EACxB,IAAI,OAAO,IAAI,WAAW,UACxB,MAAM,IAAI,MACR,6EACF;EAEF,OAAOA,cAAAA,aAAa,UAAU,IAAI,QAAQ,IAAI;CAChD;CAEA;CACA;CACA;CACA;CAEA,YACE,OACA,aACA;EAFiB,KAAA,QAAA;EACA,KAAA,cAAA;EAEjB,KAAK,MAAA,GAAA,gCAAA,0BAAA,CAA+B;GAClC,QAAQ,MAAM;GACd;EACF,CAAC;CACH;;CAGA,WAAyB;EACvB,OAAO,KAAK;CACd;;CAGA,mBAAgC;EAC9B,OAAO,KAAK,MAAM,iBAAiB;CACrC;CAEA,gBAAmC;EACjC,IAAI,KAAK,oBAAoB,KAAA,GAC3B,KAAK,kBAAkB,EAAE,OAAO,KAAK,MAAM,cAAc,EAAE;EAE7D,OAAO,KAAK,gBAAgB;CAC9B;;;;;;CAOA,UAAuB;EACrB,IAAI,KAAK,cAAc,KAAA,GACrB,KAAK,YAAY,EAAE,QAAA,GAAA,gCAAA,iBAAA,CAAwB,KAAK,MAAM,QAAQ,GAAG,KAAK,WAAW,EAAE;EAErF,OAAO,KAAK,UAAU;CACxB;;;;;;CAOA,WAAsB;EACpB,IAAI,KAAK,eAAe,KAAA,GAAW;GACjC,MAAM,aAAa,KAAK,MAAM,SAAS;GACvC,IAAI,KAAK,YAAY,WAAW,GAI9B,KAAK,aAAa,EAAE,OAAOC,qBAAAA,cAAc,YAAY,KAAK,MAAM,IAAI,KAAK,EAAE,EAAE;QACxE;IACL,MAAM,YAAY,KAAK,MAAM,QAAQ;IACrC,KAAK,aAAa,EAChB,OAAO;KACL,MAAM;KACN,OAAOA,qBAAAA,cAAc,YAAY,KAAK,MAAM,IAAI,KAAK,EAAE;KACvD,aAAa,KAAK,YAAY,KAAK,CAAC,KAAK,YAAY;MACnD,cAAc,eAAe,UAAU,SAAS,IAAI;MACpD,UAAU;KACZ,EAAE;IACJ,EACF;GACF;EACF;EACA,OAAO,KAAK,WAAW;CACzB;;;;;CAMA,UAAU,WAAwC;EAChD,OAAOC,gCAAAA,uBAAuB,KAAK,MAAM,SAAS;CACpD;AACF;AAEA,SAAS,eAAe,MAAoC;CAC1D,MAAM,WAA+B;EAAE,MAAM,KAAK;EAAM,MAAM,KAAK;CAAK;CACxE,IAAI,KAAK,WAAW,KAAA,KAAa,OAAO,KAAK,KAAK,MAAM,CAAC,CAAC,SAAS,GACjE,SAAS,SAAS,KAAK;CAEzB,IAAI,KAAK,kBAAkB,KAAA,KAAa,OAAO,KAAK,KAAK,aAAa,CAAC,CAAC,SAAS,GAC/E,SAAS,gBAAgB,KAAK;CAEhC,OAAO;AACT"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { GlobalCfgRenderCtx } from "../../render/internal.js";
|
|
2
|
+
import { ColumnFieldStatus, ColumnResolutionStatus } from "./types.js";
|
|
3
|
+
import { ColumnRecipe } from "./index.js";
|
|
4
|
+
import { AxisFilterByIdx, ColumnFilteredId, ColumnFilteredKey, PColumnSpec, PObjectId, SpecOverrides, SpecQuery } from "@milaboratories/pl-model-common";
|
|
5
|
+
|
|
6
|
+
//#region src/columns/column_recipes/column_filtered_recipe.d.ts
|
|
7
|
+
/**
|
|
8
|
+
* Recipe wrapper that fixes the values of selected axes of an inner recipe
|
|
9
|
+
* (axis slicing). The id is `FilteredPColumnId { source: inner.id,
|
|
10
|
+
* axisFilters }`.
|
|
11
|
+
*
|
|
12
|
+
* Flat-merge invariant: `inner` is never another {@link ColumnFilteredRecipe}.
|
|
13
|
+
* Repeated {@link wrap} concatenates `axisFilters` at the current level.
|
|
14
|
+
*
|
|
15
|
+
* Layering: `withSpecs` on a Filtered recipe yields
|
|
16
|
+
* `Overridden<Filtered<inner>>` — Overridden is always the outermost layer.
|
|
17
|
+
* The reverse layering (`Filtered<Overridden<...>>`) is not reachable via
|
|
18
|
+
* the public interface.
|
|
19
|
+
*/
|
|
20
|
+
declare class ColumnFilteredRecipe implements ColumnRecipe<ColumnFilteredId> {
|
|
21
|
+
private readonly inner;
|
|
22
|
+
private readonly axisFilters;
|
|
23
|
+
/**
|
|
24
|
+
* Wrap any recipe with axis filters. If `inner` is already a
|
|
25
|
+
* {@link ColumnFilteredRecipe}, concatenates `axisFilters` and returns a
|
|
26
|
+
* new Filtered sharing the original `inner`.
|
|
27
|
+
*
|
|
28
|
+
* Validates every axis index against `inner.getSpec().axesSpec` at
|
|
29
|
+
* construction — throws on an out-of-range index. After {@link wrap}, the
|
|
30
|
+
* recipe is guaranteed to be spec-complete.
|
|
31
|
+
*
|
|
32
|
+
* Order semantics: new filters are appended after existing ones, preserving
|
|
33
|
+
* their relative order. AND composition is otherwise commutative; order
|
|
34
|
+
* only affects canonicalize/equality.
|
|
35
|
+
*/
|
|
36
|
+
static wrap(col: ColumnRecipe, axisFilters: AxisFilterByIdx[]): ColumnFilteredRecipe;
|
|
37
|
+
/**
|
|
38
|
+
* Static counterpart to {@link wrap}: returns the resolution status of a
|
|
39
|
+
* {@link ColumnFilteredKey} without constructing the recipe. Axis filters
|
|
40
|
+
* do not add references — status collapses to the source's status.
|
|
41
|
+
*/
|
|
42
|
+
static getStatusByKey(key: ColumnFilteredKey, opts?: {
|
|
43
|
+
ctx?: GlobalCfgRenderCtx;
|
|
44
|
+
}): ColumnResolutionStatus;
|
|
45
|
+
readonly id: ColumnFilteredId;
|
|
46
|
+
private specCache?;
|
|
47
|
+
private queryCache?;
|
|
48
|
+
private dataStatusCache?;
|
|
49
|
+
private constructor();
|
|
50
|
+
/** Wrapped recipe — exposed so external walkers can descend. */
|
|
51
|
+
getInner(): ColumnRecipe;
|
|
52
|
+
/** Axis filters do not introduce references to other columns. */
|
|
53
|
+
getReferencedIds(): PObjectId[];
|
|
54
|
+
getDataStatus(): ColumnFieldStatus;
|
|
55
|
+
/**
|
|
56
|
+
* Final spec — the inner spec with fixed axes removed. Indices in
|
|
57
|
+
* `axisFilters` are positional against `inner.getSpec().axesSpec` and were
|
|
58
|
+
* validated at {@link wrap} time.
|
|
59
|
+
*/
|
|
60
|
+
getSpec(): PColumnSpec;
|
|
61
|
+
/**
|
|
62
|
+
* Wraps the inner query in `SpecQuerySliceAxes`. Index→selector resolution
|
|
63
|
+
* goes through the inner spec — guaranteed available since {@link wrap}
|
|
64
|
+
* validated all indices at construction.
|
|
65
|
+
*/
|
|
66
|
+
getQuery(): SpecQuery;
|
|
67
|
+
/**
|
|
68
|
+
* Filtered + overrides → Overridden<Filtered>. Overridden is always the
|
|
69
|
+
* outermost layer.
|
|
70
|
+
*/
|
|
71
|
+
withSpecs(overrides: SpecOverrides): ColumnRecipe;
|
|
72
|
+
}
|
|
73
|
+
//#endregion
|
|
74
|
+
export { ColumnFilteredRecipe };
|
|
75
|
+
//# sourceMappingURL=column_filtered_recipe.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"column_filtered_recipe.d.ts","names":[],"sources":["../../../src/columns/column_recipes/column_filtered_recipe.ts"],"mappings":";;;;;;;;AAgCA;;;;;;;;;;;cAAa,oBAAA,YAAgC,YAAA,CAAa,gBAAA;EAAA,iBAiErC,KAAA;EAAA,iBACA,WAAA;EA8BR;;;;;;;;;;;;;EAAA,OAlFJ,IAAA,CAAK,GAAA,EAAK,YAAA,EAAc,WAAA,EAAa,eAAA,KAAoB,oBAAA;EAApB;;;;;EAAA,OAiCrC,cAAA,CACL,GAAA,EAAK,iBAAA,EACL,IAAA;IAAQ,GAAA,GAAM,kBAAA;EAAA,IACb,sBAAA;EAAA,SASM,EAAA,EAAI,gBAAA;EAAA,QACL,SAAA;EAAA,QACA,UAAA;EAAA,QACA,eAAA;EAAA,QAED,WAAA;EAHC;EAcR,QAAA,IAAY,YAAA;EAXL;EAgBP,gBAAA,IAAoB,SAAA;EAIpB,aAAA,IAAiB,iBAAA;EAJjB;;;;;EAgBA,OAAA,IAAW,WAAA;EAYX;;;;;EAAA,QAAA,IAAY,SAAA;EA6BqC;AAAA;;;EAAjD,SAAA,CAAU,SAAA,EAAW,aAAA,GAAgB,YAAA;AAAA"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { rebrandLeafId } from "./leaf_rebrand.js";
|
|
2
|
+
import { ColumnRecipe } from "./index.js";
|
|
3
|
+
import { ColumnOverriddenRecipe } from "./column_overrided_recipe.js";
|
|
4
|
+
import { applyAxisFilters, stringifyColumnFilteredId } from "@milaboratories/pl-model-common";
|
|
5
|
+
//#region src/columns/column_recipes/column_filtered_recipe.ts
|
|
6
|
+
/**
|
|
7
|
+
* Recipe wrapper that fixes the values of selected axes of an inner recipe
|
|
8
|
+
* (axis slicing). The id is `FilteredPColumnId { source: inner.id,
|
|
9
|
+
* axisFilters }`.
|
|
10
|
+
*
|
|
11
|
+
* Flat-merge invariant: `inner` is never another {@link ColumnFilteredRecipe}.
|
|
12
|
+
* Repeated {@link wrap} concatenates `axisFilters` at the current level.
|
|
13
|
+
*
|
|
14
|
+
* Layering: `withSpecs` on a Filtered recipe yields
|
|
15
|
+
* `Overridden<Filtered<inner>>` — Overridden is always the outermost layer.
|
|
16
|
+
* The reverse layering (`Filtered<Overridden<...>>`) is not reachable via
|
|
17
|
+
* the public interface.
|
|
18
|
+
*/
|
|
19
|
+
var ColumnFilteredRecipe = class ColumnFilteredRecipe {
|
|
20
|
+
inner;
|
|
21
|
+
axisFilters;
|
|
22
|
+
/**
|
|
23
|
+
* Wrap any recipe with axis filters. If `inner` is already a
|
|
24
|
+
* {@link ColumnFilteredRecipe}, concatenates `axisFilters` and returns a
|
|
25
|
+
* new Filtered sharing the original `inner`.
|
|
26
|
+
*
|
|
27
|
+
* Validates every axis index against `inner.getSpec().axesSpec` at
|
|
28
|
+
* construction — throws on an out-of-range index. After {@link wrap}, the
|
|
29
|
+
* recipe is guaranteed to be spec-complete.
|
|
30
|
+
*
|
|
31
|
+
* Order semantics: new filters are appended after existing ones, preserving
|
|
32
|
+
* their relative order. AND composition is otherwise commutative; order
|
|
33
|
+
* only affects canonicalize/equality.
|
|
34
|
+
*/
|
|
35
|
+
static wrap(col, axisFilters) {
|
|
36
|
+
const combined = col instanceof ColumnFilteredRecipe ? [...col.axisFilters, ...axisFilters] : axisFilters;
|
|
37
|
+
const base = col instanceof ColumnFilteredRecipe ? col.inner : col;
|
|
38
|
+
if (combined.length === 0) throw new Error("ColumnFilteredRecipe.wrap: at least one axis filter must be provided");
|
|
39
|
+
const innerSpec = base.getSpec();
|
|
40
|
+
const fixed = /* @__PURE__ */ new Set();
|
|
41
|
+
for (const [idx] of combined) {
|
|
42
|
+
if (innerSpec.axesSpec[idx] === void 0) throw new Error(`ColumnFilteredRecipe.wrap: axis index ${idx} out of range (inner has ${innerSpec.axesSpec.length} axes)`);
|
|
43
|
+
fixed.add(idx);
|
|
44
|
+
}
|
|
45
|
+
if (fixed.size >= innerSpec.axesSpec.length) throw new Error(`ColumnFilteredRecipe.wrap: filters fix all ${innerSpec.axesSpec.length} axes — at least one axis must remain`);
|
|
46
|
+
return new ColumnFilteredRecipe(base, combined);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Static counterpart to {@link wrap}: returns the resolution status of a
|
|
50
|
+
* {@link ColumnFilteredKey} without constructing the recipe. Axis filters
|
|
51
|
+
* do not add references — status collapses to the source's status.
|
|
52
|
+
*/
|
|
53
|
+
static getStatusByKey(key, opts = {}) {
|
|
54
|
+
if (typeof key.source !== "string") throw new Error("ColumnFilteredRecipe.getStatusByKey: filtered column with non-string source");
|
|
55
|
+
return ColumnRecipe.getStatus(key.source, opts);
|
|
56
|
+
}
|
|
57
|
+
id;
|
|
58
|
+
specCache;
|
|
59
|
+
queryCache;
|
|
60
|
+
dataStatusCache;
|
|
61
|
+
constructor(inner, axisFilters) {
|
|
62
|
+
this.inner = inner;
|
|
63
|
+
this.axisFilters = axisFilters;
|
|
64
|
+
this.id = stringifyColumnFilteredId({
|
|
65
|
+
source: inner.id,
|
|
66
|
+
axisFilters
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
/** Wrapped recipe — exposed so external walkers can descend. */
|
|
70
|
+
getInner() {
|
|
71
|
+
return this.inner;
|
|
72
|
+
}
|
|
73
|
+
/** Axis filters do not introduce references to other columns. */
|
|
74
|
+
getReferencedIds() {
|
|
75
|
+
return this.inner.getReferencedIds();
|
|
76
|
+
}
|
|
77
|
+
getDataStatus() {
|
|
78
|
+
if (this.dataStatusCache === void 0) this.dataStatusCache = { value: this.inner.getDataStatus() };
|
|
79
|
+
return this.dataStatusCache.value;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Final spec — the inner spec with fixed axes removed. Indices in
|
|
83
|
+
* `axisFilters` are positional against `inner.getSpec().axesSpec` and were
|
|
84
|
+
* validated at {@link wrap} time.
|
|
85
|
+
*/
|
|
86
|
+
getSpec() {
|
|
87
|
+
if (this.specCache === void 0) this.specCache = { value: applyAxisFilters(this.inner.getSpec(), this.axisFilters) };
|
|
88
|
+
return this.specCache.value;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Wraps the inner query in `SpecQuerySliceAxes`. Index→selector resolution
|
|
92
|
+
* goes through the inner spec — guaranteed available since {@link wrap}
|
|
93
|
+
* validated all indices at construction.
|
|
94
|
+
*/
|
|
95
|
+
getQuery() {
|
|
96
|
+
if (this.queryCache === void 0) {
|
|
97
|
+
const innerQuery = this.inner.getQuery();
|
|
98
|
+
if (this.axisFilters.length === 0) this.queryCache = { value: rebrandLeafId(innerQuery, this.inner.id, this.id) };
|
|
99
|
+
else {
|
|
100
|
+
const innerSpec = this.inner.getSpec();
|
|
101
|
+
this.queryCache = { value: {
|
|
102
|
+
type: "sliceAxes",
|
|
103
|
+
input: rebrandLeafId(innerQuery, this.inner.id, this.id),
|
|
104
|
+
axisFilters: this.axisFilters.map(([idx, value]) => ({
|
|
105
|
+
axisSelector: toAxisSelector(innerSpec.axesSpec[idx]),
|
|
106
|
+
constant: value
|
|
107
|
+
}))
|
|
108
|
+
} };
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return this.queryCache.value;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Filtered + overrides → Overridden<Filtered>. Overridden is always the
|
|
115
|
+
* outermost layer.
|
|
116
|
+
*/
|
|
117
|
+
withSpecs(overrides) {
|
|
118
|
+
return ColumnOverriddenRecipe.wrap(this, overrides);
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
function toAxisSelector(axis) {
|
|
122
|
+
const selector = {
|
|
123
|
+
name: axis.name,
|
|
124
|
+
type: axis.type
|
|
125
|
+
};
|
|
126
|
+
if (axis.domain !== void 0 && Object.keys(axis.domain).length > 0) selector.domain = axis.domain;
|
|
127
|
+
if (axis.contextDomain !== void 0 && Object.keys(axis.contextDomain).length > 0) selector.contextDomain = axis.contextDomain;
|
|
128
|
+
return selector;
|
|
129
|
+
}
|
|
130
|
+
//#endregion
|
|
131
|
+
export { ColumnFilteredRecipe };
|
|
132
|
+
|
|
133
|
+
//# sourceMappingURL=column_filtered_recipe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"column_filtered_recipe.js","names":[],"sources":["../../../src/columns/column_recipes/column_filtered_recipe.ts"],"sourcesContent":["import {\n applyAxisFilters,\n stringifyColumnFilteredId,\n type AxisFilterByIdx,\n type AxisSpec,\n type ColumnFilteredId,\n type ColumnFilteredKey,\n type PColumnSpec,\n type PObjectId,\n type SingleAxisSelector,\n type SpecOverrides,\n type SpecQuery,\n} from \"@milaboratories/pl-model-common\";\nimport type { GlobalCfgRenderCtx } from \"../../render/internal\";\nimport type { ColumnFieldStatus, ColumnResolutionStatus } from \"./types\";\nimport { ColumnRecipe } from \"./index\";\nimport { ColumnOverriddenRecipe } from \"./column_overrided_recipe\";\nimport { rebrandLeafId } from \"./leaf_rebrand\";\n\n/**\n * Recipe wrapper that fixes the values of selected axes of an inner recipe\n * (axis slicing). The id is `FilteredPColumnId { source: inner.id,\n * axisFilters }`.\n *\n * Flat-merge invariant: `inner` is never another {@link ColumnFilteredRecipe}.\n * Repeated {@link wrap} concatenates `axisFilters` at the current level.\n *\n * Layering: `withSpecs` on a Filtered recipe yields\n * `Overridden<Filtered<inner>>` — Overridden is always the outermost layer.\n * The reverse layering (`Filtered<Overridden<...>>`) is not reachable via\n * the public interface.\n */\nexport class ColumnFilteredRecipe implements ColumnRecipe<ColumnFilteredId> {\n /**\n * Wrap any recipe with axis filters. If `inner` is already a\n * {@link ColumnFilteredRecipe}, concatenates `axisFilters` and returns a\n * new Filtered sharing the original `inner`.\n *\n * Validates every axis index against `inner.getSpec().axesSpec` at\n * construction — throws on an out-of-range index. After {@link wrap}, the\n * recipe is guaranteed to be spec-complete.\n *\n * Order semantics: new filters are appended after existing ones, preserving\n * their relative order. AND composition is otherwise commutative; order\n * only affects canonicalize/equality.\n */\n static wrap(col: ColumnRecipe, axisFilters: AxisFilterByIdx[]): ColumnFilteredRecipe {\n const combined =\n col instanceof ColumnFilteredRecipe ? [...col.axisFilters, ...axisFilters] : axisFilters;\n const base = col instanceof ColumnFilteredRecipe ? col.inner : col;\n\n if (combined.length === 0) {\n throw new Error(\"ColumnFilteredRecipe.wrap: at least one axis filter must be provided\");\n }\n\n const innerSpec = base.getSpec();\n const fixed = new Set<number>();\n for (const [idx] of combined) {\n if (innerSpec.axesSpec[idx] === undefined) {\n throw new Error(\n `ColumnFilteredRecipe.wrap: axis index ${idx} out of range (inner has ${innerSpec.axesSpec.length} axes)`,\n );\n }\n fixed.add(idx);\n }\n if (fixed.size >= innerSpec.axesSpec.length) {\n throw new Error(\n `ColumnFilteredRecipe.wrap: filters fix all ${innerSpec.axesSpec.length} axes — at least one axis must remain`,\n );\n }\n\n return new ColumnFilteredRecipe(base, combined);\n }\n\n /**\n * Static counterpart to {@link wrap}: returns the resolution status of a\n * {@link ColumnFilteredKey} without constructing the recipe. Axis filters\n * do not add references — status collapses to the source's status.\n */\n static getStatusByKey(\n key: ColumnFilteredKey,\n opts: { ctx?: GlobalCfgRenderCtx } = {},\n ): ColumnResolutionStatus {\n if (typeof key.source !== \"string\") {\n throw new Error(\n \"ColumnFilteredRecipe.getStatusByKey: filtered column with non-string source\",\n );\n }\n return ColumnRecipe.getStatus(key.source, opts);\n }\n\n readonly id: ColumnFilteredId;\n private specCache?: { readonly value: PColumnSpec };\n private queryCache?: { readonly value: SpecQuery };\n private dataStatusCache?: { readonly value: ColumnFieldStatus };\n\n private constructor(\n private readonly inner: ColumnRecipe,\n private readonly axisFilters: AxisFilterByIdx[],\n ) {\n this.id = stringifyColumnFilteredId({\n source: inner.id,\n axisFilters,\n });\n }\n\n /** Wrapped recipe — exposed so external walkers can descend. */\n getInner(): ColumnRecipe {\n return this.inner;\n }\n\n /** Axis filters do not introduce references to other columns. */\n getReferencedIds(): PObjectId[] {\n return this.inner.getReferencedIds();\n }\n\n getDataStatus(): ColumnFieldStatus {\n if (this.dataStatusCache === undefined) {\n this.dataStatusCache = { value: this.inner.getDataStatus() };\n }\n return this.dataStatusCache.value;\n }\n\n /**\n * Final spec — the inner spec with fixed axes removed. Indices in\n * `axisFilters` are positional against `inner.getSpec().axesSpec` and were\n * validated at {@link wrap} time.\n */\n getSpec(): PColumnSpec {\n if (this.specCache === undefined) {\n this.specCache = { value: applyAxisFilters(this.inner.getSpec(), this.axisFilters) };\n }\n return this.specCache.value;\n }\n\n /**\n * Wraps the inner query in `SpecQuerySliceAxes`. Index→selector resolution\n * goes through the inner spec — guaranteed available since {@link wrap}\n * validated all indices at construction.\n */\n getQuery(): SpecQuery {\n if (this.queryCache === undefined) {\n const innerQuery = this.inner.getQuery();\n if (this.axisFilters.length === 0) {\n // Pass-through (no filters): rebrand the inner leaf to this.id so\n // wrappers in the chain don't reintroduce the inner's id at the\n // leaf — keeps the resolver/leaf-id contract uniform.\n this.queryCache = { value: rebrandLeafId(innerQuery, this.inner.id, this.id) };\n } else {\n const innerSpec = this.inner.getSpec();\n this.queryCache = {\n value: {\n type: \"sliceAxes\",\n input: rebrandLeafId(innerQuery, this.inner.id, this.id),\n axisFilters: this.axisFilters.map(([idx, value]) => ({\n axisSelector: toAxisSelector(innerSpec.axesSpec[idx]),\n constant: value,\n })),\n },\n };\n }\n }\n return this.queryCache.value;\n }\n\n /**\n * Filtered + overrides → Overridden<Filtered>. Overridden is always the\n * outermost layer.\n */\n withSpecs(overrides: SpecOverrides): ColumnRecipe {\n return ColumnOverriddenRecipe.wrap(this, overrides);\n }\n}\n\nfunction toAxisSelector(axis: AxisSpec): SingleAxisSelector {\n const selector: SingleAxisSelector = { name: axis.name, type: axis.type };\n if (axis.domain !== undefined && Object.keys(axis.domain).length > 0) {\n selector.domain = axis.domain;\n }\n if (axis.contextDomain !== undefined && Object.keys(axis.contextDomain).length > 0) {\n selector.contextDomain = axis.contextDomain;\n }\n return selector;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAgCA,IAAa,uBAAb,MAAa,qBAA+D;CAiEvD;CACA;;;;;;;;;;;;;;CApDnB,OAAO,KAAK,KAAmB,aAAsD;EACnF,MAAM,WACJ,eAAe,uBAAuB,CAAC,GAAG,IAAI,aAAa,GAAG,WAAW,IAAI;EAC/E,MAAM,OAAO,eAAe,uBAAuB,IAAI,QAAQ;EAE/D,IAAI,SAAS,WAAW,GACtB,MAAM,IAAI,MAAM,sEAAsE;EAGxF,MAAM,YAAY,KAAK,QAAQ;EAC/B,MAAM,wBAAQ,IAAI,IAAY;EAC9B,KAAK,MAAM,CAAC,QAAQ,UAAU;GAC5B,IAAI,UAAU,SAAS,SAAS,KAAA,GAC9B,MAAM,IAAI,MACR,yCAAyC,IAAI,2BAA2B,UAAU,SAAS,OAAO,OACpG;GAEF,MAAM,IAAI,GAAG;EACf;EACA,IAAI,MAAM,QAAQ,UAAU,SAAS,QACnC,MAAM,IAAI,MACR,8CAA8C,UAAU,SAAS,OAAO,sCAC1E;EAGF,OAAO,IAAI,qBAAqB,MAAM,QAAQ;CAChD;;;;;;CAOA,OAAO,eACL,KACA,OAAqC,CAAC,GACd;EACxB,IAAI,OAAO,IAAI,WAAW,UACxB,MAAM,IAAI,MACR,6EACF;EAEF,OAAO,aAAa,UAAU,IAAI,QAAQ,IAAI;CAChD;CAEA;CACA;CACA;CACA;CAEA,YACE,OACA,aACA;EAFiB,KAAA,QAAA;EACA,KAAA,cAAA;EAEjB,KAAK,KAAK,0BAA0B;GAClC,QAAQ,MAAM;GACd;EACF,CAAC;CACH;;CAGA,WAAyB;EACvB,OAAO,KAAK;CACd;;CAGA,mBAAgC;EAC9B,OAAO,KAAK,MAAM,iBAAiB;CACrC;CAEA,gBAAmC;EACjC,IAAI,KAAK,oBAAoB,KAAA,GAC3B,KAAK,kBAAkB,EAAE,OAAO,KAAK,MAAM,cAAc,EAAE;EAE7D,OAAO,KAAK,gBAAgB;CAC9B;;;;;;CAOA,UAAuB;EACrB,IAAI,KAAK,cAAc,KAAA,GACrB,KAAK,YAAY,EAAE,OAAO,iBAAiB,KAAK,MAAM,QAAQ,GAAG,KAAK,WAAW,EAAE;EAErF,OAAO,KAAK,UAAU;CACxB;;;;;;CAOA,WAAsB;EACpB,IAAI,KAAK,eAAe,KAAA,GAAW;GACjC,MAAM,aAAa,KAAK,MAAM,SAAS;GACvC,IAAI,KAAK,YAAY,WAAW,GAI9B,KAAK,aAAa,EAAE,OAAO,cAAc,YAAY,KAAK,MAAM,IAAI,KAAK,EAAE,EAAE;QACxE;IACL,MAAM,YAAY,KAAK,MAAM,QAAQ;IACrC,KAAK,aAAa,EAChB,OAAO;KACL,MAAM;KACN,OAAO,cAAc,YAAY,KAAK,MAAM,IAAI,KAAK,EAAE;KACvD,aAAa,KAAK,YAAY,KAAK,CAAC,KAAK,YAAY;MACnD,cAAc,eAAe,UAAU,SAAS,IAAI;MACpD,UAAU;KACZ,EAAE;IACJ,EACF;GACF;EACF;EACA,OAAO,KAAK,WAAW;CACzB;;;;;CAMA,UAAU,WAAwC;EAChD,OAAO,uBAAuB,KAAK,MAAM,SAAS;CACpD;AACF;AAEA,SAAS,eAAe,MAAoC;CAC1D,MAAM,WAA+B;EAAE,MAAM,KAAK;EAAM,MAAM,KAAK;CAAK;CACxE,IAAI,KAAK,WAAW,KAAA,KAAa,OAAO,KAAK,KAAK,MAAM,CAAC,CAAC,SAAS,GACjE,SAAS,SAAS,KAAK;CAEzB,IAAI,KAAK,kBAAkB,KAAA,KAAa,OAAO,KAAK,KAAK,aAAa,CAAC,CAAC,SAAS,GAC/E,SAAS,gBAAgB,KAAK;CAEhC,OAAO;AACT"}
|