@platforma-sdk/model 1.80.13 → 1.81.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/columns/column.cjs +9 -6
- package/dist/columns/column.cjs.map +1 -1
- package/dist/columns/column.d.ts +5 -5
- package/dist/columns/column.d.ts.map +1 -1
- package/dist/columns/column.js +10 -7
- package/dist/columns/column.js.map +1 -1
- package/dist/columns/column_providers/index.cjs.map +1 -1
- package/dist/columns/column_providers/index.d.ts.map +1 -1
- package/dist/columns/column_providers/index.js.map +1 -1
- package/dist/columns/column_providers/providers.cjs +5 -5
- package/dist/columns/column_providers/providers.cjs.map +1 -1
- package/dist/columns/column_providers/providers.d.ts +8 -8
- package/dist/columns/column_providers/providers.d.ts.map +1 -1
- package/dist/columns/column_providers/providers.js +5 -5
- package/dist/columns/column_providers/providers.js.map +1 -1
- package/dist/columns/column_providers/types.d.ts +3 -3
- package/dist/columns/column_providers/types.d.ts.map +1 -1
- package/dist/columns/column_recipes/column_discovered_recipe.cjs +1 -1
- package/dist/columns/column_recipes/column_discovered_recipe.cjs.map +1 -1
- package/dist/columns/column_recipes/column_discovered_recipe.d.ts +1 -1
- package/dist/columns/column_recipes/column_discovered_recipe.js +1 -1
- package/dist/columns/column_recipes/column_discovered_recipe.js.map +1 -1
- package/dist/columns/column_recipes/column_overrided_recipe.cjs +47 -2
- package/dist/columns/column_recipes/column_overrided_recipe.cjs.map +1 -1
- package/dist/columns/column_recipes/column_overrided_recipe.d.ts +30 -3
- package/dist/columns/column_recipes/column_overrided_recipe.d.ts.map +1 -1
- package/dist/columns/column_recipes/column_overrided_recipe.js +47 -3
- package/dist/columns/column_recipes/column_overrided_recipe.js.map +1 -1
- package/dist/columns/column_recipes/index.cjs +4 -14
- package/dist/columns/column_recipes/index.cjs.map +1 -1
- package/dist/columns/column_recipes/index.d.ts +3 -10
- package/dist/columns/column_recipes/index.d.ts.map +1 -1
- package/dist/columns/column_recipes/index.js +5 -14
- package/dist/columns/column_recipes/index.js.map +1 -1
- package/dist/columns/{column_lazy.cjs → data_column.cjs} +57 -54
- package/dist/columns/data_column.cjs.map +1 -0
- package/dist/columns/data_column.d.ts +152 -0
- package/dist/columns/data_column.d.ts.map +1 -0
- package/dist/columns/{column_lazy.js → data_column.js} +55 -52
- package/dist/columns/data_column.js.map +1 -0
- package/dist/columns/derive_axis_values_labels.cjs +4 -4
- package/dist/columns/derive_axis_values_labels.cjs.map +1 -1
- package/dist/columns/derive_axis_values_labels.d.ts +2 -2
- package/dist/columns/derive_axis_values_labels.js +4 -4
- package/dist/columns/derive_axis_values_labels.js.map +1 -1
- package/dist/columns/index.cjs +9 -9
- package/dist/columns/index.d.ts +5 -5
- package/dist/columns/index.js +5 -5
- package/dist/columns/{expand_by_partition.cjs → split_by_axes.cjs} +13 -8
- package/dist/columns/split_by_axes.cjs.map +1 -0
- package/dist/columns/{expand_by_partition.d.ts → split_by_axes.d.ts} +18 -8
- package/dist/columns/split_by_axes.d.ts.map +1 -0
- package/dist/columns/{expand_by_partition.js → split_by_axes.js} +14 -9
- package/dist/columns/split_by_axes.js.map +1 -0
- package/dist/columns/utils.cjs +50 -43
- package/dist/columns/utils.cjs.map +1 -1
- package/dist/columns/utils.d.ts +44 -19
- package/dist/columns/utils.d.ts.map +1 -1
- package/dist/columns/utils.js +50 -44
- package/dist/columns/utils.js.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV2.cjs +3 -3
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV2.cjs.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV2.js +3 -3
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV2.js.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV2.cjs +2 -2
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV2.cjs.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV2.js +2 -2
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV2.js.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.cjs +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.cjs.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.js +2 -2
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.js.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/discoverColumns.cjs +1 -1
- package/dist/components/PlDataTable/createPlDataTable/discoverColumns.cjs.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/discoverColumns.js +2 -2
- package/dist/components/PlDataTable/createPlDataTable/discoverColumns.js.map +1 -1
- package/dist/components/PlDatasetSelector/enrichment_discovery.cjs +1 -1
- package/dist/components/PlDatasetSelector/enrichment_discovery.cjs.map +1 -1
- package/dist/components/PlDatasetSelector/enrichment_discovery.js +2 -2
- package/dist/components/PlDatasetSelector/enrichment_discovery.js.map +1 -1
- package/dist/index.cjs +9 -9
- package/dist/index.d.ts +5 -5
- package/dist/index.js +5 -5
- package/dist/package.cjs +1 -1
- package/dist/package.js +1 -1
- package/package.json +9 -9
- package/src/columns/__test_helpers__/collection_driver.ts +6 -6
- package/src/columns/__test_helpers__/stub_registry.ts +4 -6
- package/src/columns/column.ts +20 -9
- package/src/columns/column_providers/index.ts +9 -3
- package/src/columns/column_providers/providers.ts +16 -15
- package/src/columns/column_providers/types.ts +3 -3
- package/src/columns/column_recipes/column_discovered_recipe.ts +1 -1
- package/src/columns/column_recipes/column_overrided_recipe.ts +58 -4
- package/src/columns/column_recipes/column_recipes.test.ts +2 -2
- package/src/columns/column_recipes/index.ts +5 -20
- package/src/columns/{column_lazy.test.ts → data_column.test.ts} +19 -19
- package/src/columns/{column_lazy.ts → data_column.ts} +105 -67
- package/src/columns/derive_axis_values_labels.ts +4 -4
- package/src/columns/index.ts +2 -2
- package/src/columns/predicates.test.ts +124 -0
- package/src/columns/{expand_by_partition.test.ts → split_by_axes.test.ts} +29 -21
- package/src/columns/{expand_by_partition.ts → split_by_axes.ts} +22 -9
- package/src/columns/utils.ts +53 -48
- package/src/components/PlDataTable/columnResolver.test.ts +3 -3
- package/src/components/PlDataTable/createPlDataTable/createPTableDefV2.ts +3 -3
- package/src/components/PlDataTable/createPlDataTable/createPlDataTableV2.ts +2 -2
- package/src/components/PlDataTable/createPlDataTable/createPlDataTableV3.ts +2 -2
- package/src/components/PlDataTable/createPlDataTable/discoverColumns.ts +2 -2
- package/src/components/PlDataTable/createPlDataTable/utils.test.ts +3 -3
- package/src/components/PlDatasetSelector/enrichment_discovery.ts +2 -2
- package/dist/columns/column_lazy.cjs.map +0 -1
- package/dist/columns/column_lazy.d.ts +0 -137
- package/dist/columns/column_lazy.d.ts.map +0 -1
- package/dist/columns/column_lazy.js.map +0 -1
- package/dist/columns/expand_by_partition.cjs.map +0 -1
- package/dist/columns/expand_by_partition.d.ts.map +0 -1
- package/dist/columns/expand_by_partition.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.cjs","names":["ColumnLazyImpl","TreeNodeAccessor","ColumnDiscoveredRecipe","ColumnOverriddenRecipe","ColumnFilteredRecipe","isColumnsCollection","ColumnsCollection","deriveDistinctLabels"],"sources":["../../src/columns/utils.ts"],"sourcesContent":["import {\n collectSpecQueryColumns,\n extractPObjectId,\n isDataInfo,\n visitDataInfo,\n type AxisQualification,\n type ColumnUniversalId,\n type PObjectId,\n} from \"@milaboratories/pl-model-common\";\nimport { throwError } from \"@milaboratories/helpers\";\nimport type { GlobalCfgRenderCtx } from \"../render/internal\";\nimport { TreeNodeAccessor } from \"../render\";\nimport { deriveDistinctLabels, type DeriveLabelsOptions } from \"../labels/derive_distinct_labels\";\nimport { ColumnLazy, ColumnLazyImpl, type ColumnLazyData } from \"./column_lazy\";\nimport { ColumnDiscoveredRecipe } from \"./column_recipes/column_discovered_recipe\";\nimport { ColumnFilteredRecipe } from \"./column_recipes/column_filtered_recipe\";\nimport { ColumnOverriddenRecipe } from \"./column_recipes/column_overrided_recipe\";\nimport type { ColumnRecipe } from \"./column_recipes/types\";\nimport { ColumnsCollection, isColumnsCollection } from \"./columns_collection\";\nimport type { ColumnsSource } from \"./column_providers/types\";\n\n/**\n * PObjectIds of every non-hit column referenced by `recipe.getQuery()`,\n * deduped in traversal order. The hit column is\n * `extractPObjectId(recipe.id)`; anything else in the query is a linker or\n * other engine-consumed column.\n *\n * Pure query walk — no registry access. Use {@link collectLinkerColumns} for\n * the resolved {@link ColumnLazy} variant.\n */\nexport function collectLinkerIds(recipe: ColumnRecipe): PObjectId[] {\n const hit = extractPObjectId(recipe.id);\n const seen = new Set<PObjectId>();\n const out: PObjectId[] = [];\n for (const id of collectSpecQueryColumns(recipe.getQuery())) {\n // Leaf ids in SpecQuery may be rich (e.g. ColumnDiscoveredId) — drop to\n // bare PObjectId before comparing/registering so we hand the ambient\n // ColumnRegistry physical ids it can resolve.\n const bare = extractPObjectId(id);\n if (bare === hit) continue;\n if (seen.has(bare)) continue;\n seen.add(bare);\n out.push(bare);\n }\n return out;\n}\n\n/**\n * {@link collectLinkerIds} resolved against the ambient context as\n * {@link ColumnLazy} instances. Throws if any id fails to resolve —\n * matches the contract of the legacy `resolveLinkers` it replaces.\n */\nexport function collectLinkerColumns(\n recipe: ColumnRecipe,\n opts: { ctx?: GlobalCfgRenderCtx } = {},\n): ColumnLazy[] {\n return collectLinkerIds(recipe).map(\n (id) =>\n ColumnLazyImpl.fromId(id, opts) ??\n throwError(`materializeLinkers: linker ${id} not resolvable`),\n );\n}\n\n/**\n * Hit-side axis qualifications for the recipe — the ones that should land on\n * the outer-join entry wrapping this column at the consumer boundary.\n *\n * Descends {@link ColumnOverriddenRecipe} / {@link ColumnFilteredRecipe} via\n * `getInner()` until it finds a {@link ColumnDiscoveredRecipe}; otherwise\n * returns `[]`. Pure recipe walk — no query-tree introspection.\n */\nexport function hitQualifications(recipe: ColumnRecipe): readonly AxisQualification[] {\n const discovered = findDiscovered(recipe);\n return discovered?.getColumnQualifications() ?? [];\n}\n\n/**\n * Per-primary-column axis qualifications for the recipe — applied to the\n * outer primary anchors on this recipe's group side. Keyed by the external\n * primary column id (NOT by columns inside this recipe's own query).\n *\n * Same walk strategy as {@link hitQualifications}.\n */\nexport function queriesQualifications(\n recipe: ColumnRecipe,\n): Readonly<Record<PObjectId, AxisQualification[]>> {\n const discovered = findDiscovered(recipe);\n return discovered?.getQueriesQualifications() ?? {};\n}\n\n/**\n * Whether the recipe's underlying data resources actually carry bytes —\n * strictly stronger than `getDataStatus() === \"present\"`, which only tells\n * that the `.data` field is wired onto the accessor.\n *\n * Walks every physical leaf the recipe depends on via\n * {@link ColumnRecipe.getReferencedIds} (resolves each id back to a\n * {@link ColumnLazy} through the ambient ctx) and ANDs `hasData()` across\n * all of them. Inline {@link PColumnValues} payloads count as present.\n *\n * Returns `false` if any leaf cannot be re-resolved in `opts.ctx` (treat as\n * \"not yet ready\") rather than throwing — this is a UI-facing predicate, not\n * a contract assertion.\n */\nexport function hasColumnData(\n recipe: ColumnRecipe,\n opts: { ctx?: GlobalCfgRenderCtx } = {},\n): boolean {\n for (const id of recipe.getReferencedIds()) {\n const lazy = ColumnLazyImpl.fromId(id, opts);\n if (lazy === undefined) return false;\n if (lazy.getDataStatus() !== \"present\") return false;\n if (!isLazyDataPresent(lazy.getData())) return false;\n }\n return true;\n}\n\nfunction isLazyDataPresent(data: ColumnLazyData): boolean {\n if (data === undefined) return false;\n if (Array.isArray(data)) return true;\n if (data instanceof TreeNodeAccessor) return data.hasData();\n if (isDataInfo(data)) {\n let ok = true;\n visitDataInfo(data, (blob) => {\n ok &&= blob.hasData();\n });\n return ok;\n }\n return false;\n}\n\n/**\n * Walk wrapper layers (Overridden, Filtered) until a {@link\n * ColumnDiscoveredRecipe} is found. Returns `undefined` if the recipe chain\n * has no Discovered layer (bare leaves and Overridden-over-leaf cases).\n *\n * Invariant from the wrapper classes themselves: there is at most one\n * Discovered layer in any recipe chain — Discovered is constructed only via\n * its own factory and is never re-wrapped by Discovered.\n */\nfunction findDiscovered(recipe: ColumnRecipe): undefined | ColumnDiscoveredRecipe {\n let current: ColumnRecipe = recipe;\n while (true) {\n if (current instanceof ColumnDiscoveredRecipe) return current;\n if (current instanceof ColumnOverriddenRecipe || current instanceof ColumnFilteredRecipe) {\n current = current.getInner();\n continue;\n }\n return undefined;\n }\n}\n\n/**\n * A recipe is a \"leaf\" (directly co-indexed on the anchor, reached without a\n * linker chain) iff its wrapper chain contains no {@link ColumnDiscoveredRecipe}.\n *\n * `Filtered` / `Overridden` over a bare leaf stay leaves; anything wrapping a\n * `Discovered` (e.g. `Overridden(Discovered(...))`) is linked. Use this — not an\n * `instanceof ColumnLazyImpl` check — to split direct vs. linker-joined columns,\n * since projections over a plain leaf are still direct.\n */\nexport function isLeafColumn(recipe: ColumnRecipe): boolean {\n return findDiscovered(recipe) === undefined;\n}\n\n/**\n * Data of the bare leaf a \"leaf\" recipe bottoms out at — reads the leaf-only\n * {@link ColumnLazy.getData} after walking the wrapper chain down via\n * {@link extractLeafColumn}. Returns `undefined` when the recipe is not a leaf (its\n * chain reaches a {@link ColumnDiscoveredRecipe}); the symmetric counterpart\n * of {@link isLeafColumn} returning `false`.\n */\nexport function getLeafColumnData(recipe: ColumnRecipe): ColumnLazyData {\n if (!isLeafColumn(recipe)) {\n throw new Error(`getLeafColumnData: recipe ${recipe.id} is not a leaf column`);\n }\n return extractLeafColumn(recipe)?.getData();\n}\n\n/**\n * Walk wrapper layers (Overridden, Filtered) down to the bare {@link ColumnLazy}\n * leaf the chain bottoms out at. Returns `undefined` if the chain reaches a\n * {@link ColumnDiscoveredRecipe} instead — i.e. the recipe is not a leaf\n * ({@link isLeafColumn} would return `false`). Mirror of {@link findDiscovered}.\n */\nfunction extractLeafColumn(recipe: ColumnRecipe): undefined | ColumnLazy {\n let current: ColumnRecipe = recipe;\n while (true) {\n if (current instanceof ColumnLazyImpl) return current;\n if (current instanceof ColumnOverriddenRecipe || current instanceof ColumnFilteredRecipe) {\n current = current.getInner();\n continue;\n }\n if (current instanceof ColumnDiscoveredRecipe) {\n throw new Error(`extractLeafColumn: recipe ${recipe.id} is not a leaf column`);\n }\n throw new Error(`extractLeafColumn: unrecognized recipe layer for ${recipe.id}`);\n }\n}\n\n/** Drop-down option built over a {@link ColumnsCollection} — universal-id valued. */\nexport type ColumnOption = {\n readonly id: ColumnUniversalId;\n readonly label: string;\n};\n\n/**\n * Enumerates every column already in `source` and renders distinct labels\n * from each recipe's spec. Filtering is the caller's job — pass a\n * {@link ColumnsCollection} that was already narrowed via `.filter(...)` /\n * `.discover(...)`, or hand over a raw {@link ColumnsSource} (provider,\n * accessor, column array, or `\"result_pool\"` / `\"current_block\"` shorthand)\n * to be wrapped on the fly.\n */\nexport function deriveColumnOptions(\n source: ColumnsCollection | ColumnsSource[],\n labelOptions: DeriveLabelsOptions = {},\n): ColumnOption[] {\n const collection = isColumnsCollection(source) ? source : ColumnsCollection(source);\n const recipes = collection.getColumns();\n const labels = deriveDistinctLabels(\n recipes.map((r) => r.getSpec()),\n labelOptions,\n );\n return recipes.map((r, i) => ({ id: r.id, label: labels[i] }));\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"utils.cjs","names":["DataColumnImpl","TreeNodeAccessor","ColumnDiscoveredRecipe","ColumnOverriddenRecipe","ColumnFilteredRecipe","DataColumnOverriddenRecipe","isColumnsCollection","ColumnsCollection","deriveDistinctLabels"],"sources":["../../src/columns/utils.ts"],"sourcesContent":["import {\n collectSpecQueryColumns,\n extractPObjectId,\n isDataInfo,\n visitDataInfo,\n type AxisQualification,\n type ColumnUniversalId,\n type PObjectId,\n} from \"@milaboratories/pl-model-common\";\nimport { throwError } from \"@milaboratories/helpers\";\nimport type { GlobalCfgRenderCtx } from \"../render/internal\";\nimport { TreeNodeAccessor } from \"../render\";\nimport { deriveDistinctLabels, type DeriveLabelsOptions } from \"../labels/derive_distinct_labels\";\nimport { DataColumnRecipe, DataColumnImpl, type ColumnData } from \"./data_column\";\nimport { ColumnDiscoveredRecipe } from \"./column_recipes/column_discovered_recipe\";\nimport { ColumnFilteredRecipe } from \"./column_recipes/column_filtered_recipe\";\nimport {\n ColumnOverriddenRecipe,\n DataColumnOverriddenRecipe,\n} from \"./column_recipes/column_overrided_recipe\";\nimport type { ColumnRecipe } from \"./column_recipes/types\";\nimport { ColumnsCollection, isColumnsCollection } from \"./columns_collection\";\nimport type { ColumnsSource } from \"./column_providers/types\";\n\n/**\n * PObjectIds of every non-hit column referenced by `recipe.getQuery()`,\n * deduped in traversal order. The hit column is\n * `extractPObjectId(recipe.id)`; anything else in the query is a linker or\n * other engine-consumed column.\n *\n * Pure query walk — no registry access. Use {@link collectLinkerColumns} for\n * the resolved {@link DataColumnRecipe} variant.\n */\nexport function collectLinkerIds(recipe: ColumnRecipe): PObjectId[] {\n const hit = extractPObjectId(recipe.id);\n const seen = new Set<PObjectId>();\n const out: PObjectId[] = [];\n for (const id of collectSpecQueryColumns(recipe.getQuery())) {\n // Leaf ids in SpecQuery may be rich (e.g. ColumnDiscoveredId) — drop to\n // bare PObjectId before comparing/registering so we hand the ambient\n // ColumnRegistry physical ids it can resolve.\n const bare = extractPObjectId(id);\n if (bare === hit) continue;\n if (seen.has(bare)) continue;\n seen.add(bare);\n out.push(bare);\n }\n return out;\n}\n\n/**\n * {@link collectLinkerIds} resolved against the ambient context as\n * {@link DataColumnRecipe} leaves. Throws if any id fails to resolve —\n * matches the contract of the legacy `resolveLinkers` it replaces.\n */\nexport function collectLinkerColumns(\n recipe: ColumnRecipe,\n opts: { ctx?: GlobalCfgRenderCtx } = {},\n): DataColumnRecipe<PObjectId>[] {\n return collectLinkerIds(recipe).map(\n (id) =>\n DataColumnImpl.fromId(id, opts) ??\n throwError(`materializeLinkers: linker ${id} not resolvable`),\n );\n}\n\n/**\n * Hit-side axis qualifications for the recipe — the ones that should land on\n * the outer-join entry wrapping this column at the consumer boundary.\n *\n * Descends {@link ColumnOverriddenRecipe} / {@link ColumnFilteredRecipe} via\n * `getInner()` until it finds a {@link ColumnDiscoveredRecipe}; otherwise\n * returns `[]`. Pure recipe walk — no query-tree introspection.\n */\nexport function hitQualifications(recipe: ColumnRecipe): readonly AxisQualification[] {\n const discovered = findDiscovered(recipe);\n return discovered?.getColumnQualifications() ?? [];\n}\n\n/**\n * Per-primary-column axis qualifications for the recipe — applied to the\n * outer primary anchors on this recipe's group side. Keyed by the external\n * primary column id (NOT by columns inside this recipe's own query).\n *\n * Same walk strategy as {@link hitQualifications}.\n */\nexport function queriesQualifications(\n recipe: ColumnRecipe,\n): Readonly<Record<PObjectId, AxisQualification[]>> {\n const discovered = findDiscovered(recipe);\n return discovered?.getQueriesQualifications() ?? {};\n}\n\n/**\n * Whether the recipe's underlying data resources actually carry bytes —\n * strictly stronger than `getDataStatus() === \"present\"`, which only tells\n * that the `.data` field is wired onto the accessor.\n *\n * Walks every physical leaf the recipe depends on via\n * {@link ColumnRecipe.getReferencedIds} (resolves each id back to a\n * {@link DataColumnRecipe} through the ambient ctx) and ANDs `hasData()` across\n * all of them. Inline {@link PColumnValues} payloads count as present.\n *\n * Returns `false` if any leaf cannot be re-resolved in `opts.ctx` (treat as\n * \"not yet ready\") rather than throwing — this is a UI-facing predicate, not\n * a contract assertion.\n */\nexport function hasColumnData(\n recipe: ColumnRecipe,\n opts: { ctx?: GlobalCfgRenderCtx } = {},\n): boolean {\n for (const id of recipe.getReferencedIds()) {\n const leaf = DataColumnImpl.fromId(id, opts);\n if (leaf === undefined) return false;\n if (leaf.getDataStatus() !== \"present\") return false;\n if (!isLeafDataPresent(leaf.getData())) return false;\n }\n return true;\n}\n\nfunction isLeafDataPresent(data: ColumnData): boolean {\n if (data === undefined) return false;\n if (Array.isArray(data)) return true;\n if (data instanceof TreeNodeAccessor) return data.hasData();\n if (isDataInfo(data)) {\n let ok = true;\n visitDataInfo(data, (blob) => {\n ok &&= blob.hasData();\n });\n return ok;\n }\n return false;\n}\n\n/**\n * Walk wrapper layers (Overridden, Filtered) until a {@link\n * ColumnDiscoveredRecipe} is found. Returns `undefined` if the recipe chain\n * has no Discovered layer (bare leaves and Overridden-over-leaf cases).\n *\n * Invariant from the wrapper classes themselves: there is at most one\n * Discovered layer in any recipe chain — Discovered is constructed only via\n * its own factory and is never re-wrapped by Discovered.\n */\nfunction findDiscovered(recipe: ColumnRecipe): undefined | ColumnDiscoveredRecipe {\n let current: ColumnRecipe = recipe;\n while (true) {\n if (current instanceof ColumnDiscoveredRecipe) return current;\n if (current instanceof ColumnOverriddenRecipe || current instanceof ColumnFilteredRecipe) {\n current = current.getInner();\n continue;\n }\n return undefined;\n }\n}\n\n/**\n * Whether the recipe reads exactly one data column — its own — rather than\n * reaching through others.\n *\n * True for a bare leaf and for projections over one (spec overrides, axis\n * slicing): those add layers but no new columns. False when the recipe gets at\n * its data through further columns, which happens when discovery reached it via\n * a linker chain.\n *\n * **Why callers care.** A recipe over a single data column is co-indexed by its\n * own axes, so its spec is the whole truth about them. One that needs other\n * columns only lines up after they are joined in, and therefore drags axes into\n * the join that its own spec never mentions — which is why it cannot serve as a\n * primary column, and why `createPlDataTableV3` splits on this.\n *\n * The count comes from {@link ColumnRecipe.getReferencedIds}, which resolves\n * through the whole wrapper chain, so no class walk is involved and foreign\n * `ColumnRecipe` implementations are handled too.\n */\nexport function hasSingleDataColumn(recipe: ColumnRecipe): boolean {\n return recipe.getReferencedIds().length === 1;\n}\n\n/**\n * @deprecated Renamed to {@link hasSingleDataColumn} — \"leaf\" read as \"you can\n * get data out of it\", which is a different question (see\n * {@link hasReachableData}). Same semantics.\n */\nexport const isLeafColumn = hasSingleDataColumn;\n\n/**\n * Whether the column's data can be read here and now, consistent with its\n * spec — narrows to {@link DataColumnRecipe}, which exposes `getData()`.\n *\n * True for a bare leaf and for a spec-override over a bare leaf. False for an\n * axis-filtered recipe (its spec has dropped axes the underlying data still\n * carries, so the two no longer line up) and for anything reached through\n * other columns (nothing to read until the engine joins them). In both of\n * those cases the data exists only engine-side: pass `recipe.id` to\n * `createPFrame` / `createPTable` instead of trying to read it.\n *\n * The distinction is settled when the recipe is built, not here — recipes that\n * carry data are instances of a class that declares `getData`. So a `true`\n * result narrows to a value that really has the method, and there is no\n * throwing path behind the guard.\n */\nexport function hasReachableData(recipe: ColumnRecipe): recipe is DataColumnRecipe {\n return recipe instanceof DataColumnImpl || recipe instanceof DataColumnOverriddenRecipe;\n}\n\n/** Drop-down option built over a {@link ColumnsCollection} — universal-id valued. */\nexport type ColumnOption = {\n readonly id: ColumnUniversalId;\n readonly label: string;\n};\n\n/**\n * Enumerates every column already in `source` and renders distinct labels\n * from each recipe's spec. Filtering is the caller's job — pass a\n * {@link ColumnsCollection} that was already narrowed via `.filter(...)` /\n * `.discover(...)`, or hand over a raw {@link ColumnsSource} (provider,\n * accessor, column array, or `\"result_pool\"` / `\"current_block\"` shorthand)\n * to be wrapped on the fly.\n */\nexport function deriveColumnOptions(\n source: ColumnsCollection | ColumnsSource[],\n labelOptions: DeriveLabelsOptions = {},\n): ColumnOption[] {\n const collection = isColumnsCollection(source) ? source : ColumnsCollection(source);\n const recipes = collection.getColumns();\n const labels = deriveDistinctLabels(\n recipes.map((r) => r.getSpec()),\n labelOptions,\n );\n return recipes.map((r, i) => ({ id: r.id, label: labels[i] }));\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAiCA,SAAgB,iBAAiB,QAAmC;CAClE,MAAM,OAAA,GAAA,gCAAA,iBAAA,CAAuB,OAAO,EAAE;CACtC,MAAM,uBAAO,IAAI,IAAe;CAChC,MAAM,MAAmB,CAAC;CAC1B,KAAK,MAAM,OAAA,GAAA,gCAAA,wBAAA,CAA8B,OAAO,SAAS,CAAC,GAAG;EAI3D,MAAM,QAAA,GAAA,gCAAA,iBAAA,CAAwB,EAAE;EAChC,IAAI,SAAS,KAAK;EAClB,IAAI,KAAK,IAAI,IAAI,GAAG;EACpB,KAAK,IAAI,IAAI;EACb,IAAI,KAAK,IAAI;CACf;CACA,OAAO;AACT;;;;;;AAOA,SAAgB,qBACd,QACA,OAAqC,CAAC,GACP;CAC/B,OAAO,iBAAiB,MAAM,CAAC,CAAC,KAC7B,OACCA,oBAAAA,eAAe,OAAO,IAAI,IAAI,MAAA,GAAA,wBAAA,WAAA,CACnB,8BAA8B,GAAG,gBAAgB,CAChE;AACF;;;;;;;;;AAUA,SAAgB,kBAAkB,QAAoD;CAEpF,OADmB,eAAe,MAClB,CAAC,EAAE,wBAAwB,KAAK,CAAC;AACnD;;;;;;;;AASA,SAAgB,sBACd,QACkD;CAElD,OADmB,eAAe,MAClB,CAAC,EAAE,yBAAyB,KAAK,CAAC;AACpD;;;;;;;;;;;;;;;AAgBA,SAAgB,cACd,QACA,OAAqC,CAAC,GAC7B;CACT,KAAK,MAAM,MAAM,OAAO,iBAAiB,GAAG;EAC1C,MAAM,OAAOA,oBAAAA,eAAe,OAAO,IAAI,IAAI;EAC3C,IAAI,SAAS,KAAA,GAAW,OAAO;EAC/B,IAAI,KAAK,cAAc,MAAM,WAAW,OAAO;EAC/C,IAAI,CAAC,kBAAkB,KAAK,QAAQ,CAAC,GAAG,OAAO;CACjD;CACA,OAAO;AACT;AAEA,SAAS,kBAAkB,MAA2B;CACpD,IAAI,SAAS,KAAA,GAAW,OAAO;CAC/B,IAAI,MAAM,QAAQ,IAAI,GAAG,OAAO;CAChC,IAAI,gBAAgBC,iBAAAA,kBAAkB,OAAO,KAAK,QAAQ;CAC1D,KAAA,GAAA,gCAAA,WAAA,CAAe,IAAI,GAAG;EACpB,IAAI,KAAK;EACT,CAAA,GAAA,gCAAA,cAAA,CAAc,OAAO,SAAS;GAC5B,OAAO,KAAK,QAAQ;EACtB,CAAC;EACD,OAAO;CACT;CACA,OAAO;AACT;;;;;;;;;;AAWA,SAAS,eAAe,QAA0D;CAChF,IAAI,UAAwB;CAC5B,OAAO,MAAM;EACX,IAAI,mBAAmBC,iCAAAA,wBAAwB,OAAO;EACtD,IAAI,mBAAmBC,gCAAAA,0BAA0B,mBAAmBC,+BAAAA,sBAAsB;GACxF,UAAU,QAAQ,SAAS;GAC3B;EACF;EACA;CACF;AACF;;;;;;;;;;;;;;;;;;;;AAqBA,SAAgB,oBAAoB,QAA+B;CACjE,OAAO,OAAO,iBAAiB,CAAC,CAAC,WAAW;AAC9C;;;;;;AAOA,MAAa,eAAe;;;;;;;;;;;;;;;;;AAkB5B,SAAgB,iBAAiB,QAAkD;CACjF,OAAO,kBAAkBJ,oBAAAA,kBAAkB,kBAAkBK,gCAAAA;AAC/D;;;;;;;;;AAgBA,SAAgB,oBACd,QACA,eAAoC,CAAC,GACrB;CAEhB,MAAM,WADaC,2BAAAA,oBAAoB,MAAM,IAAI,SAASC,2BAAAA,kBAAkB,MAAM,EAAA,CACvD,WAAW;CACtC,MAAM,SAASC,+BAAAA,qBACb,QAAQ,KAAK,MAAM,EAAE,QAAQ,CAAC,GAC9B,YACF;CACA,OAAO,QAAQ,KAAK,GAAG,OAAO;EAAE,IAAI,EAAE;EAAI,OAAO,OAAO;CAAG,EAAE;AAC/D"}
|
package/dist/columns/utils.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { GlobalCfgRenderCtx } from "../render/internal.js";
|
|
2
2
|
import { DeriveLabelsOptions } from "../labels/derive_distinct_labels.js";
|
|
3
3
|
import { ColumnRecipe } from "./column_recipes/types.js";
|
|
4
|
-
import {
|
|
4
|
+
import { DataColumnRecipe } from "./data_column.js";
|
|
5
5
|
import { ColumnsSource } from "./column_providers/types.js";
|
|
6
6
|
import { ColumnsCollection } from "./columns_collection.js";
|
|
7
7
|
import { AxisQualification, ColumnUniversalId, PObjectId } from "@milaboratories/pl-model-common";
|
|
@@ -14,17 +14,17 @@ import { AxisQualification, ColumnUniversalId, PObjectId } from "@milaboratories
|
|
|
14
14
|
* other engine-consumed column.
|
|
15
15
|
*
|
|
16
16
|
* Pure query walk — no registry access. Use {@link collectLinkerColumns} for
|
|
17
|
-
* the resolved {@link
|
|
17
|
+
* the resolved {@link DataColumnRecipe} variant.
|
|
18
18
|
*/
|
|
19
19
|
declare function collectLinkerIds(recipe: ColumnRecipe): PObjectId[];
|
|
20
20
|
/**
|
|
21
21
|
* {@link collectLinkerIds} resolved against the ambient context as
|
|
22
|
-
* {@link
|
|
22
|
+
* {@link DataColumnRecipe} leaves. Throws if any id fails to resolve —
|
|
23
23
|
* matches the contract of the legacy `resolveLinkers` it replaces.
|
|
24
24
|
*/
|
|
25
25
|
declare function collectLinkerColumns(recipe: ColumnRecipe, opts?: {
|
|
26
26
|
ctx?: GlobalCfgRenderCtx;
|
|
27
|
-
}):
|
|
27
|
+
}): DataColumnRecipe<PObjectId>[];
|
|
28
28
|
/**
|
|
29
29
|
* Hit-side axis qualifications for the recipe — the ones that should land on
|
|
30
30
|
* the outer-join entry wrapping this column at the consumer boundary.
|
|
@@ -49,7 +49,7 @@ declare function queriesQualifications(recipe: ColumnRecipe): Readonly<Record<PO
|
|
|
49
49
|
*
|
|
50
50
|
* Walks every physical leaf the recipe depends on via
|
|
51
51
|
* {@link ColumnRecipe.getReferencedIds} (resolves each id back to a
|
|
52
|
-
* {@link
|
|
52
|
+
* {@link DataColumnRecipe} through the ambient ctx) and ANDs `hasData()` across
|
|
53
53
|
* all of them. Inline {@link PColumnValues} payloads count as present.
|
|
54
54
|
*
|
|
55
55
|
* Returns `false` if any leaf cannot be re-resolved in `opts.ctx` (treat as
|
|
@@ -60,23 +60,48 @@ declare function hasColumnData(recipe: ColumnRecipe, opts?: {
|
|
|
60
60
|
ctx?: GlobalCfgRenderCtx;
|
|
61
61
|
}): boolean;
|
|
62
62
|
/**
|
|
63
|
-
*
|
|
64
|
-
*
|
|
63
|
+
* Whether the recipe reads exactly one data column — its own — rather than
|
|
64
|
+
* reaching through others.
|
|
65
65
|
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
66
|
+
* True for a bare leaf and for projections over one (spec overrides, axis
|
|
67
|
+
* slicing): those add layers but no new columns. False when the recipe gets at
|
|
68
|
+
* its data through further columns, which happens when discovery reached it via
|
|
69
|
+
* a linker chain.
|
|
70
|
+
*
|
|
71
|
+
* **Why callers care.** A recipe over a single data column is co-indexed by its
|
|
72
|
+
* own axes, so its spec is the whole truth about them. One that needs other
|
|
73
|
+
* columns only lines up after they are joined in, and therefore drags axes into
|
|
74
|
+
* the join that its own spec never mentions — which is why it cannot serve as a
|
|
75
|
+
* primary column, and why `createPlDataTableV3` splits on this.
|
|
76
|
+
*
|
|
77
|
+
* The count comes from {@link ColumnRecipe.getReferencedIds}, which resolves
|
|
78
|
+
* through the whole wrapper chain, so no class walk is involved and foreign
|
|
79
|
+
* `ColumnRecipe` implementations are handled too.
|
|
80
|
+
*/
|
|
81
|
+
declare function hasSingleDataColumn(recipe: ColumnRecipe): boolean;
|
|
82
|
+
/**
|
|
83
|
+
* @deprecated Renamed to {@link hasSingleDataColumn} — "leaf" read as "you can
|
|
84
|
+
* get data out of it", which is a different question (see
|
|
85
|
+
* {@link hasReachableData}). Same semantics.
|
|
70
86
|
*/
|
|
71
|
-
declare
|
|
87
|
+
declare const isLeafColumn: typeof hasSingleDataColumn;
|
|
72
88
|
/**
|
|
73
|
-
*
|
|
74
|
-
* {@link
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
89
|
+
* Whether the column's data can be read here and now, consistent with its
|
|
90
|
+
* spec — narrows to {@link DataColumnRecipe}, which exposes `getData()`.
|
|
91
|
+
*
|
|
92
|
+
* True for a bare leaf and for a spec-override over a bare leaf. False for an
|
|
93
|
+
* axis-filtered recipe (its spec has dropped axes the underlying data still
|
|
94
|
+
* carries, so the two no longer line up) and for anything reached through
|
|
95
|
+
* other columns (nothing to read until the engine joins them). In both of
|
|
96
|
+
* those cases the data exists only engine-side: pass `recipe.id` to
|
|
97
|
+
* `createPFrame` / `createPTable` instead of trying to read it.
|
|
98
|
+
*
|
|
99
|
+
* The distinction is settled when the recipe is built, not here — recipes that
|
|
100
|
+
* carry data are instances of a class that declares `getData`. So a `true`
|
|
101
|
+
* result narrows to a value that really has the method, and there is no
|
|
102
|
+
* throwing path behind the guard.
|
|
78
103
|
*/
|
|
79
|
-
declare function
|
|
104
|
+
declare function hasReachableData(recipe: ColumnRecipe): recipe is DataColumnRecipe;
|
|
80
105
|
/** Drop-down option built over a {@link ColumnsCollection} — universal-id valued. */
|
|
81
106
|
type ColumnOption = {
|
|
82
107
|
readonly id: ColumnUniversalId;
|
|
@@ -92,5 +117,5 @@ type ColumnOption = {
|
|
|
92
117
|
*/
|
|
93
118
|
declare function deriveColumnOptions(source: ColumnsCollection | ColumnsSource[], labelOptions?: DeriveLabelsOptions): ColumnOption[];
|
|
94
119
|
//#endregion
|
|
95
|
-
export { ColumnOption, collectLinkerColumns, collectLinkerIds, deriveColumnOptions,
|
|
120
|
+
export { ColumnOption, collectLinkerColumns, collectLinkerIds, deriveColumnOptions, hasColumnData, hasReachableData, hasSingleDataColumn, hitQualifications, isLeafColumn, queriesQualifications };
|
|
96
121
|
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","names":[],"sources":["../../src/columns/utils.ts"],"mappings":";;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"utils.d.ts","names":[],"sources":["../../src/columns/utils.ts"],"mappings":";;;;;;;;;;;AAiCA;;;;;;;iBAAgB,gBAAA,CAAiB,MAAA,EAAQ,YAAA,GAAe,SAAS;AAAA;AAsBjE;;;;AAtBiE,iBAsBjD,oBAAA,CACd,MAAA,EAAQ,YAAA,EACR,IAAA;EAAQ,GAAA,GAAM,kBAAA;AAAA,IACb,gBAAA,CAAiB,SAAA;;;;;;;;;iBAgBJ,iBAAA,CAAkB,MAAA,EAAQ,YAAA,YAAwB,iBAAiB;;AAhBtD;AAgB7B;;;;;iBAYgB,qBAAA,CACd,MAAA,EAAQ,YAAA,GACP,QAAA,CAAS,MAAA,CAAO,SAAA,EAAW,iBAAA;;;AAdqD;AAYnF;;;;;;;;;;;iBAqBgB,aAAA,CACd,MAAA,EAAQ,YAAA,EACR,IAAA;EAAQ,GAAA,GAAM,kBAAkB;AAAA;;;;AArBa;AAmB/C;;;;;;;;;;AAEyC;AAiEzC;;;;iBAAgB,mBAAA,CAAoB,MAAoB,EAAZ,YAAY;AASxD;;;;AAA+C;AAA/C,cAAa,YAAA,SAAY,mBAAsB;;;;;;;;;AAkBmC;AAKlF;;;;;;;iBALgB,gBAAA,CAAiB,MAAA,EAAQ,YAAA,GAAe,MAAA,IAAU,gBAAgB;AAOlE;AAAA,KAFJ,YAAA;EAAA,SACD,EAAA,EAAI,iBAAiB;EAAA,SACrB,KAAA;AAAA;;;;;;;;;iBAWK,mBAAA,CACd,MAAA,EAAQ,iBAAA,GAAoB,aAAA,IAC5B,YAAA,GAAc,mBAAA,GACb,YAAA"}
|
package/dist/columns/utils.js
CHANGED
|
@@ -3,8 +3,8 @@ import { deriveDistinctLabels } from "../labels/derive_distinct_labels.js";
|
|
|
3
3
|
import "../render/index.js";
|
|
4
4
|
import { ColumnDiscoveredRecipe } from "./column_recipes/column_discovered_recipe.js";
|
|
5
5
|
import { ColumnFilteredRecipe } from "./column_recipes/column_filtered_recipe.js";
|
|
6
|
-
import { ColumnOverriddenRecipe } from "./column_recipes/column_overrided_recipe.js";
|
|
7
|
-
import {
|
|
6
|
+
import { ColumnOverriddenRecipe, DataColumnOverriddenRecipe } from "./column_recipes/column_overrided_recipe.js";
|
|
7
|
+
import { DataColumnImpl } from "./data_column.js";
|
|
8
8
|
import { ColumnsCollection, isColumnsCollection } from "./columns_collection.js";
|
|
9
9
|
import { collectSpecQueryColumns, extractPObjectId, isDataInfo, visitDataInfo } from "@milaboratories/pl-model-common";
|
|
10
10
|
import { throwError } from "@milaboratories/helpers";
|
|
@@ -16,7 +16,7 @@ import { throwError } from "@milaboratories/helpers";
|
|
|
16
16
|
* other engine-consumed column.
|
|
17
17
|
*
|
|
18
18
|
* Pure query walk — no registry access. Use {@link collectLinkerColumns} for
|
|
19
|
-
* the resolved {@link
|
|
19
|
+
* the resolved {@link DataColumnRecipe} variant.
|
|
20
20
|
*/
|
|
21
21
|
function collectLinkerIds(recipe) {
|
|
22
22
|
const hit = extractPObjectId(recipe.id);
|
|
@@ -33,11 +33,11 @@ function collectLinkerIds(recipe) {
|
|
|
33
33
|
}
|
|
34
34
|
/**
|
|
35
35
|
* {@link collectLinkerIds} resolved against the ambient context as
|
|
36
|
-
* {@link
|
|
36
|
+
* {@link DataColumnRecipe} leaves. Throws if any id fails to resolve —
|
|
37
37
|
* matches the contract of the legacy `resolveLinkers` it replaces.
|
|
38
38
|
*/
|
|
39
39
|
function collectLinkerColumns(recipe, opts = {}) {
|
|
40
|
-
return collectLinkerIds(recipe).map((id) =>
|
|
40
|
+
return collectLinkerIds(recipe).map((id) => DataColumnImpl.fromId(id, opts) ?? throwError(`materializeLinkers: linker ${id} not resolvable`));
|
|
41
41
|
}
|
|
42
42
|
/**
|
|
43
43
|
* Hit-side axis qualifications for the recipe — the ones that should land on
|
|
@@ -67,7 +67,7 @@ function queriesQualifications(recipe) {
|
|
|
67
67
|
*
|
|
68
68
|
* Walks every physical leaf the recipe depends on via
|
|
69
69
|
* {@link ColumnRecipe.getReferencedIds} (resolves each id back to a
|
|
70
|
-
* {@link
|
|
70
|
+
* {@link DataColumnRecipe} through the ambient ctx) and ANDs `hasData()` across
|
|
71
71
|
* all of them. Inline {@link PColumnValues} payloads count as present.
|
|
72
72
|
*
|
|
73
73
|
* Returns `false` if any leaf cannot be re-resolved in `opts.ctx` (treat as
|
|
@@ -76,14 +76,14 @@ function queriesQualifications(recipe) {
|
|
|
76
76
|
*/
|
|
77
77
|
function hasColumnData(recipe, opts = {}) {
|
|
78
78
|
for (const id of recipe.getReferencedIds()) {
|
|
79
|
-
const
|
|
80
|
-
if (
|
|
81
|
-
if (
|
|
82
|
-
if (!
|
|
79
|
+
const leaf = DataColumnImpl.fromId(id, opts);
|
|
80
|
+
if (leaf === void 0) return false;
|
|
81
|
+
if (leaf.getDataStatus() !== "present") return false;
|
|
82
|
+
if (!isLeafDataPresent(leaf.getData())) return false;
|
|
83
83
|
}
|
|
84
84
|
return true;
|
|
85
85
|
}
|
|
86
|
-
function
|
|
86
|
+
function isLeafDataPresent(data) {
|
|
87
87
|
if (data === void 0) return false;
|
|
88
88
|
if (Array.isArray(data)) return true;
|
|
89
89
|
if (data instanceof TreeNodeAccessor) return data.hasData();
|
|
@@ -117,45 +117,51 @@ function findDiscovered(recipe) {
|
|
|
117
117
|
}
|
|
118
118
|
}
|
|
119
119
|
/**
|
|
120
|
-
*
|
|
121
|
-
*
|
|
120
|
+
* Whether the recipe reads exactly one data column — its own — rather than
|
|
121
|
+
* reaching through others.
|
|
122
122
|
*
|
|
123
|
-
*
|
|
124
|
-
*
|
|
125
|
-
*
|
|
126
|
-
*
|
|
123
|
+
* True for a bare leaf and for projections over one (spec overrides, axis
|
|
124
|
+
* slicing): those add layers but no new columns. False when the recipe gets at
|
|
125
|
+
* its data through further columns, which happens when discovery reached it via
|
|
126
|
+
* a linker chain.
|
|
127
|
+
*
|
|
128
|
+
* **Why callers care.** A recipe over a single data column is co-indexed by its
|
|
129
|
+
* own axes, so its spec is the whole truth about them. One that needs other
|
|
130
|
+
* columns only lines up after they are joined in, and therefore drags axes into
|
|
131
|
+
* the join that its own spec never mentions — which is why it cannot serve as a
|
|
132
|
+
* primary column, and why `createPlDataTableV3` splits on this.
|
|
133
|
+
*
|
|
134
|
+
* The count comes from {@link ColumnRecipe.getReferencedIds}, which resolves
|
|
135
|
+
* through the whole wrapper chain, so no class walk is involved and foreign
|
|
136
|
+
* `ColumnRecipe` implementations are handled too.
|
|
127
137
|
*/
|
|
128
|
-
function
|
|
129
|
-
return
|
|
138
|
+
function hasSingleDataColumn(recipe) {
|
|
139
|
+
return recipe.getReferencedIds().length === 1;
|
|
130
140
|
}
|
|
131
141
|
/**
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
* {@link
|
|
135
|
-
* chain reaches a {@link ColumnDiscoveredRecipe}); the symmetric counterpart
|
|
136
|
-
* of {@link isLeafColumn} returning `false`.
|
|
142
|
+
* @deprecated Renamed to {@link hasSingleDataColumn} — "leaf" read as "you can
|
|
143
|
+
* get data out of it", which is a different question (see
|
|
144
|
+
* {@link hasReachableData}). Same semantics.
|
|
137
145
|
*/
|
|
138
|
-
|
|
139
|
-
if (!isLeafColumn(recipe)) throw new Error(`getLeafColumnData: recipe ${recipe.id} is not a leaf column`);
|
|
140
|
-
return extractLeafColumn(recipe)?.getData();
|
|
141
|
-
}
|
|
146
|
+
const isLeafColumn = hasSingleDataColumn;
|
|
142
147
|
/**
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
*
|
|
146
|
-
*
|
|
148
|
+
* Whether the column's data can be read here and now, consistent with its
|
|
149
|
+
* spec — narrows to {@link DataColumnRecipe}, which exposes `getData()`.
|
|
150
|
+
*
|
|
151
|
+
* True for a bare leaf and for a spec-override over a bare leaf. False for an
|
|
152
|
+
* axis-filtered recipe (its spec has dropped axes the underlying data still
|
|
153
|
+
* carries, so the two no longer line up) and for anything reached through
|
|
154
|
+
* other columns (nothing to read until the engine joins them). In both of
|
|
155
|
+
* those cases the data exists only engine-side: pass `recipe.id` to
|
|
156
|
+
* `createPFrame` / `createPTable` instead of trying to read it.
|
|
157
|
+
*
|
|
158
|
+
* The distinction is settled when the recipe is built, not here — recipes that
|
|
159
|
+
* carry data are instances of a class that declares `getData`. So a `true`
|
|
160
|
+
* result narrows to a value that really has the method, and there is no
|
|
161
|
+
* throwing path behind the guard.
|
|
147
162
|
*/
|
|
148
|
-
function
|
|
149
|
-
|
|
150
|
-
while (true) {
|
|
151
|
-
if (current instanceof ColumnLazyImpl) return current;
|
|
152
|
-
if (current instanceof ColumnOverriddenRecipe || current instanceof ColumnFilteredRecipe) {
|
|
153
|
-
current = current.getInner();
|
|
154
|
-
continue;
|
|
155
|
-
}
|
|
156
|
-
if (current instanceof ColumnDiscoveredRecipe) throw new Error(`extractLeafColumn: recipe ${recipe.id} is not a leaf column`);
|
|
157
|
-
throw new Error(`extractLeafColumn: unrecognized recipe layer for ${recipe.id}`);
|
|
158
|
-
}
|
|
163
|
+
function hasReachableData(recipe) {
|
|
164
|
+
return recipe instanceof DataColumnImpl || recipe instanceof DataColumnOverriddenRecipe;
|
|
159
165
|
}
|
|
160
166
|
/**
|
|
161
167
|
* Enumerates every column already in `source` and renders distinct labels
|
|
@@ -174,6 +180,6 @@ function deriveColumnOptions(source, labelOptions = {}) {
|
|
|
174
180
|
}));
|
|
175
181
|
}
|
|
176
182
|
//#endregion
|
|
177
|
-
export { collectLinkerColumns, collectLinkerIds, deriveColumnOptions,
|
|
183
|
+
export { collectLinkerColumns, collectLinkerIds, deriveColumnOptions, hasColumnData, hasReachableData, hasSingleDataColumn, hitQualifications, isLeafColumn, queriesQualifications };
|
|
178
184
|
|
|
179
185
|
//# sourceMappingURL=utils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","names":[],"sources":["../../src/columns/utils.ts"],"sourcesContent":["import {\n collectSpecQueryColumns,\n extractPObjectId,\n isDataInfo,\n visitDataInfo,\n type AxisQualification,\n type ColumnUniversalId,\n type PObjectId,\n} from \"@milaboratories/pl-model-common\";\nimport { throwError } from \"@milaboratories/helpers\";\nimport type { GlobalCfgRenderCtx } from \"../render/internal\";\nimport { TreeNodeAccessor } from \"../render\";\nimport { deriveDistinctLabels, type DeriveLabelsOptions } from \"../labels/derive_distinct_labels\";\nimport { ColumnLazy, ColumnLazyImpl, type ColumnLazyData } from \"./column_lazy\";\nimport { ColumnDiscoveredRecipe } from \"./column_recipes/column_discovered_recipe\";\nimport { ColumnFilteredRecipe } from \"./column_recipes/column_filtered_recipe\";\nimport { ColumnOverriddenRecipe } from \"./column_recipes/column_overrided_recipe\";\nimport type { ColumnRecipe } from \"./column_recipes/types\";\nimport { ColumnsCollection, isColumnsCollection } from \"./columns_collection\";\nimport type { ColumnsSource } from \"./column_providers/types\";\n\n/**\n * PObjectIds of every non-hit column referenced by `recipe.getQuery()`,\n * deduped in traversal order. The hit column is\n * `extractPObjectId(recipe.id)`; anything else in the query is a linker or\n * other engine-consumed column.\n *\n * Pure query walk — no registry access. Use {@link collectLinkerColumns} for\n * the resolved {@link ColumnLazy} variant.\n */\nexport function collectLinkerIds(recipe: ColumnRecipe): PObjectId[] {\n const hit = extractPObjectId(recipe.id);\n const seen = new Set<PObjectId>();\n const out: PObjectId[] = [];\n for (const id of collectSpecQueryColumns(recipe.getQuery())) {\n // Leaf ids in SpecQuery may be rich (e.g. ColumnDiscoveredId) — drop to\n // bare PObjectId before comparing/registering so we hand the ambient\n // ColumnRegistry physical ids it can resolve.\n const bare = extractPObjectId(id);\n if (bare === hit) continue;\n if (seen.has(bare)) continue;\n seen.add(bare);\n out.push(bare);\n }\n return out;\n}\n\n/**\n * {@link collectLinkerIds} resolved against the ambient context as\n * {@link ColumnLazy} instances. Throws if any id fails to resolve —\n * matches the contract of the legacy `resolveLinkers` it replaces.\n */\nexport function collectLinkerColumns(\n recipe: ColumnRecipe,\n opts: { ctx?: GlobalCfgRenderCtx } = {},\n): ColumnLazy[] {\n return collectLinkerIds(recipe).map(\n (id) =>\n ColumnLazyImpl.fromId(id, opts) ??\n throwError(`materializeLinkers: linker ${id} not resolvable`),\n );\n}\n\n/**\n * Hit-side axis qualifications for the recipe — the ones that should land on\n * the outer-join entry wrapping this column at the consumer boundary.\n *\n * Descends {@link ColumnOverriddenRecipe} / {@link ColumnFilteredRecipe} via\n * `getInner()` until it finds a {@link ColumnDiscoveredRecipe}; otherwise\n * returns `[]`. Pure recipe walk — no query-tree introspection.\n */\nexport function hitQualifications(recipe: ColumnRecipe): readonly AxisQualification[] {\n const discovered = findDiscovered(recipe);\n return discovered?.getColumnQualifications() ?? [];\n}\n\n/**\n * Per-primary-column axis qualifications for the recipe — applied to the\n * outer primary anchors on this recipe's group side. Keyed by the external\n * primary column id (NOT by columns inside this recipe's own query).\n *\n * Same walk strategy as {@link hitQualifications}.\n */\nexport function queriesQualifications(\n recipe: ColumnRecipe,\n): Readonly<Record<PObjectId, AxisQualification[]>> {\n const discovered = findDiscovered(recipe);\n return discovered?.getQueriesQualifications() ?? {};\n}\n\n/**\n * Whether the recipe's underlying data resources actually carry bytes —\n * strictly stronger than `getDataStatus() === \"present\"`, which only tells\n * that the `.data` field is wired onto the accessor.\n *\n * Walks every physical leaf the recipe depends on via\n * {@link ColumnRecipe.getReferencedIds} (resolves each id back to a\n * {@link ColumnLazy} through the ambient ctx) and ANDs `hasData()` across\n * all of them. Inline {@link PColumnValues} payloads count as present.\n *\n * Returns `false` if any leaf cannot be re-resolved in `opts.ctx` (treat as\n * \"not yet ready\") rather than throwing — this is a UI-facing predicate, not\n * a contract assertion.\n */\nexport function hasColumnData(\n recipe: ColumnRecipe,\n opts: { ctx?: GlobalCfgRenderCtx } = {},\n): boolean {\n for (const id of recipe.getReferencedIds()) {\n const lazy = ColumnLazyImpl.fromId(id, opts);\n if (lazy === undefined) return false;\n if (lazy.getDataStatus() !== \"present\") return false;\n if (!isLazyDataPresent(lazy.getData())) return false;\n }\n return true;\n}\n\nfunction isLazyDataPresent(data: ColumnLazyData): boolean {\n if (data === undefined) return false;\n if (Array.isArray(data)) return true;\n if (data instanceof TreeNodeAccessor) return data.hasData();\n if (isDataInfo(data)) {\n let ok = true;\n visitDataInfo(data, (blob) => {\n ok &&= blob.hasData();\n });\n return ok;\n }\n return false;\n}\n\n/**\n * Walk wrapper layers (Overridden, Filtered) until a {@link\n * ColumnDiscoveredRecipe} is found. Returns `undefined` if the recipe chain\n * has no Discovered layer (bare leaves and Overridden-over-leaf cases).\n *\n * Invariant from the wrapper classes themselves: there is at most one\n * Discovered layer in any recipe chain — Discovered is constructed only via\n * its own factory and is never re-wrapped by Discovered.\n */\nfunction findDiscovered(recipe: ColumnRecipe): undefined | ColumnDiscoveredRecipe {\n let current: ColumnRecipe = recipe;\n while (true) {\n if (current instanceof ColumnDiscoveredRecipe) return current;\n if (current instanceof ColumnOverriddenRecipe || current instanceof ColumnFilteredRecipe) {\n current = current.getInner();\n continue;\n }\n return undefined;\n }\n}\n\n/**\n * A recipe is a \"leaf\" (directly co-indexed on the anchor, reached without a\n * linker chain) iff its wrapper chain contains no {@link ColumnDiscoveredRecipe}.\n *\n * `Filtered` / `Overridden` over a bare leaf stay leaves; anything wrapping a\n * `Discovered` (e.g. `Overridden(Discovered(...))`) is linked. Use this — not an\n * `instanceof ColumnLazyImpl` check — to split direct vs. linker-joined columns,\n * since projections over a plain leaf are still direct.\n */\nexport function isLeafColumn(recipe: ColumnRecipe): boolean {\n return findDiscovered(recipe) === undefined;\n}\n\n/**\n * Data of the bare leaf a \"leaf\" recipe bottoms out at — reads the leaf-only\n * {@link ColumnLazy.getData} after walking the wrapper chain down via\n * {@link extractLeafColumn}. Returns `undefined` when the recipe is not a leaf (its\n * chain reaches a {@link ColumnDiscoveredRecipe}); the symmetric counterpart\n * of {@link isLeafColumn} returning `false`.\n */\nexport function getLeafColumnData(recipe: ColumnRecipe): ColumnLazyData {\n if (!isLeafColumn(recipe)) {\n throw new Error(`getLeafColumnData: recipe ${recipe.id} is not a leaf column`);\n }\n return extractLeafColumn(recipe)?.getData();\n}\n\n/**\n * Walk wrapper layers (Overridden, Filtered) down to the bare {@link ColumnLazy}\n * leaf the chain bottoms out at. Returns `undefined` if the chain reaches a\n * {@link ColumnDiscoveredRecipe} instead — i.e. the recipe is not a leaf\n * ({@link isLeafColumn} would return `false`). Mirror of {@link findDiscovered}.\n */\nfunction extractLeafColumn(recipe: ColumnRecipe): undefined | ColumnLazy {\n let current: ColumnRecipe = recipe;\n while (true) {\n if (current instanceof ColumnLazyImpl) return current;\n if (current instanceof ColumnOverriddenRecipe || current instanceof ColumnFilteredRecipe) {\n current = current.getInner();\n continue;\n }\n if (current instanceof ColumnDiscoveredRecipe) {\n throw new Error(`extractLeafColumn: recipe ${recipe.id} is not a leaf column`);\n }\n throw new Error(`extractLeafColumn: unrecognized recipe layer for ${recipe.id}`);\n }\n}\n\n/** Drop-down option built over a {@link ColumnsCollection} — universal-id valued. */\nexport type ColumnOption = {\n readonly id: ColumnUniversalId;\n readonly label: string;\n};\n\n/**\n * Enumerates every column already in `source` and renders distinct labels\n * from each recipe's spec. Filtering is the caller's job — pass a\n * {@link ColumnsCollection} that was already narrowed via `.filter(...)` /\n * `.discover(...)`, or hand over a raw {@link ColumnsSource} (provider,\n * accessor, column array, or `\"result_pool\"` / `\"current_block\"` shorthand)\n * to be wrapped on the fly.\n */\nexport function deriveColumnOptions(\n source: ColumnsCollection | ColumnsSource[],\n labelOptions: DeriveLabelsOptions = {},\n): ColumnOption[] {\n const collection = isColumnsCollection(source) ? source : ColumnsCollection(source);\n const recipes = collection.getColumns();\n const labels = deriveDistinctLabels(\n recipes.map((r) => r.getSpec()),\n labelOptions,\n );\n return recipes.map((r, i) => ({ id: r.id, label: labels[i] }));\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"utils.js","names":[],"sources":["../../src/columns/utils.ts"],"sourcesContent":["import {\n collectSpecQueryColumns,\n extractPObjectId,\n isDataInfo,\n visitDataInfo,\n type AxisQualification,\n type ColumnUniversalId,\n type PObjectId,\n} from \"@milaboratories/pl-model-common\";\nimport { throwError } from \"@milaboratories/helpers\";\nimport type { GlobalCfgRenderCtx } from \"../render/internal\";\nimport { TreeNodeAccessor } from \"../render\";\nimport { deriveDistinctLabels, type DeriveLabelsOptions } from \"../labels/derive_distinct_labels\";\nimport { DataColumnRecipe, DataColumnImpl, type ColumnData } from \"./data_column\";\nimport { ColumnDiscoveredRecipe } from \"./column_recipes/column_discovered_recipe\";\nimport { ColumnFilteredRecipe } from \"./column_recipes/column_filtered_recipe\";\nimport {\n ColumnOverriddenRecipe,\n DataColumnOverriddenRecipe,\n} from \"./column_recipes/column_overrided_recipe\";\nimport type { ColumnRecipe } from \"./column_recipes/types\";\nimport { ColumnsCollection, isColumnsCollection } from \"./columns_collection\";\nimport type { ColumnsSource } from \"./column_providers/types\";\n\n/**\n * PObjectIds of every non-hit column referenced by `recipe.getQuery()`,\n * deduped in traversal order. The hit column is\n * `extractPObjectId(recipe.id)`; anything else in the query is a linker or\n * other engine-consumed column.\n *\n * Pure query walk — no registry access. Use {@link collectLinkerColumns} for\n * the resolved {@link DataColumnRecipe} variant.\n */\nexport function collectLinkerIds(recipe: ColumnRecipe): PObjectId[] {\n const hit = extractPObjectId(recipe.id);\n const seen = new Set<PObjectId>();\n const out: PObjectId[] = [];\n for (const id of collectSpecQueryColumns(recipe.getQuery())) {\n // Leaf ids in SpecQuery may be rich (e.g. ColumnDiscoveredId) — drop to\n // bare PObjectId before comparing/registering so we hand the ambient\n // ColumnRegistry physical ids it can resolve.\n const bare = extractPObjectId(id);\n if (bare === hit) continue;\n if (seen.has(bare)) continue;\n seen.add(bare);\n out.push(bare);\n }\n return out;\n}\n\n/**\n * {@link collectLinkerIds} resolved against the ambient context as\n * {@link DataColumnRecipe} leaves. Throws if any id fails to resolve —\n * matches the contract of the legacy `resolveLinkers` it replaces.\n */\nexport function collectLinkerColumns(\n recipe: ColumnRecipe,\n opts: { ctx?: GlobalCfgRenderCtx } = {},\n): DataColumnRecipe<PObjectId>[] {\n return collectLinkerIds(recipe).map(\n (id) =>\n DataColumnImpl.fromId(id, opts) ??\n throwError(`materializeLinkers: linker ${id} not resolvable`),\n );\n}\n\n/**\n * Hit-side axis qualifications for the recipe — the ones that should land on\n * the outer-join entry wrapping this column at the consumer boundary.\n *\n * Descends {@link ColumnOverriddenRecipe} / {@link ColumnFilteredRecipe} via\n * `getInner()` until it finds a {@link ColumnDiscoveredRecipe}; otherwise\n * returns `[]`. Pure recipe walk — no query-tree introspection.\n */\nexport function hitQualifications(recipe: ColumnRecipe): readonly AxisQualification[] {\n const discovered = findDiscovered(recipe);\n return discovered?.getColumnQualifications() ?? [];\n}\n\n/**\n * Per-primary-column axis qualifications for the recipe — applied to the\n * outer primary anchors on this recipe's group side. Keyed by the external\n * primary column id (NOT by columns inside this recipe's own query).\n *\n * Same walk strategy as {@link hitQualifications}.\n */\nexport function queriesQualifications(\n recipe: ColumnRecipe,\n): Readonly<Record<PObjectId, AxisQualification[]>> {\n const discovered = findDiscovered(recipe);\n return discovered?.getQueriesQualifications() ?? {};\n}\n\n/**\n * Whether the recipe's underlying data resources actually carry bytes —\n * strictly stronger than `getDataStatus() === \"present\"`, which only tells\n * that the `.data` field is wired onto the accessor.\n *\n * Walks every physical leaf the recipe depends on via\n * {@link ColumnRecipe.getReferencedIds} (resolves each id back to a\n * {@link DataColumnRecipe} through the ambient ctx) and ANDs `hasData()` across\n * all of them. Inline {@link PColumnValues} payloads count as present.\n *\n * Returns `false` if any leaf cannot be re-resolved in `opts.ctx` (treat as\n * \"not yet ready\") rather than throwing — this is a UI-facing predicate, not\n * a contract assertion.\n */\nexport function hasColumnData(\n recipe: ColumnRecipe,\n opts: { ctx?: GlobalCfgRenderCtx } = {},\n): boolean {\n for (const id of recipe.getReferencedIds()) {\n const leaf = DataColumnImpl.fromId(id, opts);\n if (leaf === undefined) return false;\n if (leaf.getDataStatus() !== \"present\") return false;\n if (!isLeafDataPresent(leaf.getData())) return false;\n }\n return true;\n}\n\nfunction isLeafDataPresent(data: ColumnData): boolean {\n if (data === undefined) return false;\n if (Array.isArray(data)) return true;\n if (data instanceof TreeNodeAccessor) return data.hasData();\n if (isDataInfo(data)) {\n let ok = true;\n visitDataInfo(data, (blob) => {\n ok &&= blob.hasData();\n });\n return ok;\n }\n return false;\n}\n\n/**\n * Walk wrapper layers (Overridden, Filtered) until a {@link\n * ColumnDiscoveredRecipe} is found. Returns `undefined` if the recipe chain\n * has no Discovered layer (bare leaves and Overridden-over-leaf cases).\n *\n * Invariant from the wrapper classes themselves: there is at most one\n * Discovered layer in any recipe chain — Discovered is constructed only via\n * its own factory and is never re-wrapped by Discovered.\n */\nfunction findDiscovered(recipe: ColumnRecipe): undefined | ColumnDiscoveredRecipe {\n let current: ColumnRecipe = recipe;\n while (true) {\n if (current instanceof ColumnDiscoveredRecipe) return current;\n if (current instanceof ColumnOverriddenRecipe || current instanceof ColumnFilteredRecipe) {\n current = current.getInner();\n continue;\n }\n return undefined;\n }\n}\n\n/**\n * Whether the recipe reads exactly one data column — its own — rather than\n * reaching through others.\n *\n * True for a bare leaf and for projections over one (spec overrides, axis\n * slicing): those add layers but no new columns. False when the recipe gets at\n * its data through further columns, which happens when discovery reached it via\n * a linker chain.\n *\n * **Why callers care.** A recipe over a single data column is co-indexed by its\n * own axes, so its spec is the whole truth about them. One that needs other\n * columns only lines up after they are joined in, and therefore drags axes into\n * the join that its own spec never mentions — which is why it cannot serve as a\n * primary column, and why `createPlDataTableV3` splits on this.\n *\n * The count comes from {@link ColumnRecipe.getReferencedIds}, which resolves\n * through the whole wrapper chain, so no class walk is involved and foreign\n * `ColumnRecipe` implementations are handled too.\n */\nexport function hasSingleDataColumn(recipe: ColumnRecipe): boolean {\n return recipe.getReferencedIds().length === 1;\n}\n\n/**\n * @deprecated Renamed to {@link hasSingleDataColumn} — \"leaf\" read as \"you can\n * get data out of it\", which is a different question (see\n * {@link hasReachableData}). Same semantics.\n */\nexport const isLeafColumn = hasSingleDataColumn;\n\n/**\n * Whether the column's data can be read here and now, consistent with its\n * spec — narrows to {@link DataColumnRecipe}, which exposes `getData()`.\n *\n * True for a bare leaf and for a spec-override over a bare leaf. False for an\n * axis-filtered recipe (its spec has dropped axes the underlying data still\n * carries, so the two no longer line up) and for anything reached through\n * other columns (nothing to read until the engine joins them). In both of\n * those cases the data exists only engine-side: pass `recipe.id` to\n * `createPFrame` / `createPTable` instead of trying to read it.\n *\n * The distinction is settled when the recipe is built, not here — recipes that\n * carry data are instances of a class that declares `getData`. So a `true`\n * result narrows to a value that really has the method, and there is no\n * throwing path behind the guard.\n */\nexport function hasReachableData(recipe: ColumnRecipe): recipe is DataColumnRecipe {\n return recipe instanceof DataColumnImpl || recipe instanceof DataColumnOverriddenRecipe;\n}\n\n/** Drop-down option built over a {@link ColumnsCollection} — universal-id valued. */\nexport type ColumnOption = {\n readonly id: ColumnUniversalId;\n readonly label: string;\n};\n\n/**\n * Enumerates every column already in `source` and renders distinct labels\n * from each recipe's spec. Filtering is the caller's job — pass a\n * {@link ColumnsCollection} that was already narrowed via `.filter(...)` /\n * `.discover(...)`, or hand over a raw {@link ColumnsSource} (provider,\n * accessor, column array, or `\"result_pool\"` / `\"current_block\"` shorthand)\n * to be wrapped on the fly.\n */\nexport function deriveColumnOptions(\n source: ColumnsCollection | ColumnsSource[],\n labelOptions: DeriveLabelsOptions = {},\n): ColumnOption[] {\n const collection = isColumnsCollection(source) ? source : ColumnsCollection(source);\n const recipes = collection.getColumns();\n const labels = deriveDistinctLabels(\n recipes.map((r) => r.getSpec()),\n labelOptions,\n );\n return recipes.map((r, i) => ({ id: r.id, label: labels[i] }));\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAiCA,SAAgB,iBAAiB,QAAmC;CAClE,MAAM,MAAM,iBAAiB,OAAO,EAAE;CACtC,MAAM,uBAAO,IAAI,IAAe;CAChC,MAAM,MAAmB,CAAC;CAC1B,KAAK,MAAM,MAAM,wBAAwB,OAAO,SAAS,CAAC,GAAG;EAI3D,MAAM,OAAO,iBAAiB,EAAE;EAChC,IAAI,SAAS,KAAK;EAClB,IAAI,KAAK,IAAI,IAAI,GAAG;EACpB,KAAK,IAAI,IAAI;EACb,IAAI,KAAK,IAAI;CACf;CACA,OAAO;AACT;;;;;;AAOA,SAAgB,qBACd,QACA,OAAqC,CAAC,GACP;CAC/B,OAAO,iBAAiB,MAAM,CAAC,CAAC,KAC7B,OACC,eAAe,OAAO,IAAI,IAAI,KAC9B,WAAW,8BAA8B,GAAG,gBAAgB,CAChE;AACF;;;;;;;;;AAUA,SAAgB,kBAAkB,QAAoD;CAEpF,OADmB,eAAe,MAClB,CAAC,EAAE,wBAAwB,KAAK,CAAC;AACnD;;;;;;;;AASA,SAAgB,sBACd,QACkD;CAElD,OADmB,eAAe,MAClB,CAAC,EAAE,yBAAyB,KAAK,CAAC;AACpD;;;;;;;;;;;;;;;AAgBA,SAAgB,cACd,QACA,OAAqC,CAAC,GAC7B;CACT,KAAK,MAAM,MAAM,OAAO,iBAAiB,GAAG;EAC1C,MAAM,OAAO,eAAe,OAAO,IAAI,IAAI;EAC3C,IAAI,SAAS,KAAA,GAAW,OAAO;EAC/B,IAAI,KAAK,cAAc,MAAM,WAAW,OAAO;EAC/C,IAAI,CAAC,kBAAkB,KAAK,QAAQ,CAAC,GAAG,OAAO;CACjD;CACA,OAAO;AACT;AAEA,SAAS,kBAAkB,MAA2B;CACpD,IAAI,SAAS,KAAA,GAAW,OAAO;CAC/B,IAAI,MAAM,QAAQ,IAAI,GAAG,OAAO;CAChC,IAAI,gBAAgB,kBAAkB,OAAO,KAAK,QAAQ;CAC1D,IAAI,WAAW,IAAI,GAAG;EACpB,IAAI,KAAK;EACT,cAAc,OAAO,SAAS;GAC5B,OAAO,KAAK,QAAQ;EACtB,CAAC;EACD,OAAO;CACT;CACA,OAAO;AACT;;;;;;;;;;AAWA,SAAS,eAAe,QAA0D;CAChF,IAAI,UAAwB;CAC5B,OAAO,MAAM;EACX,IAAI,mBAAmB,wBAAwB,OAAO;EACtD,IAAI,mBAAmB,0BAA0B,mBAAmB,sBAAsB;GACxF,UAAU,QAAQ,SAAS;GAC3B;EACF;EACA;CACF;AACF;;;;;;;;;;;;;;;;;;;;AAqBA,SAAgB,oBAAoB,QAA+B;CACjE,OAAO,OAAO,iBAAiB,CAAC,CAAC,WAAW;AAC9C;;;;;;AAOA,MAAa,eAAe;;;;;;;;;;;;;;;;;AAkB5B,SAAgB,iBAAiB,QAAkD;CACjF,OAAO,kBAAkB,kBAAkB,kBAAkB;AAC/D;;;;;;;;;AAgBA,SAAgB,oBACd,QACA,eAAoC,CAAC,GACrB;CAEhB,MAAM,WADa,oBAAoB,MAAM,IAAI,SAAS,kBAAkB,MAAM,EAAA,CACvD,WAAW;CACtC,MAAM,SAAS,qBACb,QAAQ,KAAK,MAAM,EAAE,QAAQ,CAAC,GAC9B,YACF;CACA,OAAO,QAAQ,KAAK,GAAG,OAAO;EAAE,IAAI,EAAE;EAAI,OAAO,OAAO;CAAG,EAAE;AAC/D"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
1
|
+
const require_data_column = require("../../../columns/data_column.cjs");
|
|
2
2
|
require("../../../columns/index.cjs");
|
|
3
3
|
const require_createPTableDefV3 = require("./createPTableDefV3.cjs");
|
|
4
4
|
let _milaboratories_pl_model_common = require("@milaboratories/pl-model-common");
|
|
@@ -14,8 +14,8 @@ function createPTableDefV2(params) {
|
|
|
14
14
|
}
|
|
15
15
|
secondaryColumns.push(...params.labelColumns);
|
|
16
16
|
return require_createPTableDefV3.createPTableDefV3({
|
|
17
|
-
primary: coreColumns.map((column) =>
|
|
18
|
-
secondary: secondaryColumns.map((column) =>
|
|
17
|
+
primary: coreColumns.map((column) => require_data_column.DataColumn.fromColumn(column)),
|
|
18
|
+
secondary: secondaryColumns.map((column) => require_data_column.DataColumn.fromColumn(column)),
|
|
19
19
|
primaryJoinType: params.coreJoinType,
|
|
20
20
|
filters: params.filters,
|
|
21
21
|
sorting: params.sorting
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createPTableDefV2.cjs","names":["createPTableDefV3","
|
|
1
|
+
{"version":3,"file":"createPTableDefV2.cjs","names":["createPTableDefV3","DataColumn"],"sources":["../../../../src/components/PlDataTable/createPlDataTable/createPTableDefV2.ts"],"sourcesContent":["import type {\n ColumnUniversalId,\n PColumn,\n PColumnIdAndSpec,\n PTableSorting,\n PTableDefV2,\n} from \"@milaboratories/pl-model-common\";\nimport { getColumnIdAndSpec } from \"@milaboratories/pl-model-common\";\nimport type { PColumnDataUniversal } from \"../../../render\";\nimport { isFunction } from \"es-toolkit\";\nimport type { PlDataTableFilters } from \"../typesV8\";\nimport { createPTableDefV3 } from \"./createPTableDefV3\";\nimport { DataColumn } from \"../../../columns\";\n\nexport function createPTableDefV2(params: {\n columns: PColumn<undefined | PColumnDataUniversal>[];\n labelColumns: PColumn<undefined | PColumnDataUniversal>[];\n coreJoinType: \"inner\" | \"full\";\n filters: null | PlDataTableFilters;\n sorting: PTableSorting[];\n coreColumnPredicate?: (spec: PColumnIdAndSpec) => boolean;\n}): PTableDefV2<ColumnUniversalId> {\n let coreColumns = params.columns;\n const secondaryColumns: typeof params.columns = [];\n\n if (isFunction(params.coreColumnPredicate)) {\n coreColumns = [];\n for (const c of params.columns)\n if (params.coreColumnPredicate(getColumnIdAndSpec(c))) coreColumns.push(c);\n else secondaryColumns.push(c);\n }\n\n secondaryColumns.push(...params.labelColumns);\n\n return createPTableDefV3({\n primary: coreColumns.map((column) => DataColumn.fromColumn(column)),\n secondary: secondaryColumns.map((column) => DataColumn.fromColumn(column)),\n primaryJoinType: params.coreJoinType,\n filters: params.filters,\n sorting: params.sorting,\n });\n}\n"],"mappings":";;;;;;AAcA,SAAgB,kBAAkB,QAOC;CACjC,IAAI,cAAc,OAAO;CACzB,MAAM,mBAA0C,CAAC;CAEjD,KAAA,GAAA,WAAA,WAAA,CAAe,OAAO,mBAAmB,GAAG;EAC1C,cAAc,CAAC;EACf,KAAK,MAAM,KAAK,OAAO,SACrB,IAAI,OAAO,qBAAA,GAAA,gCAAA,mBAAA,CAAuC,CAAC,CAAC,GAAG,YAAY,KAAK,CAAC;OACpE,iBAAiB,KAAK,CAAC;CAChC;CAEA,iBAAiB,KAAK,GAAG,OAAO,YAAY;CAE5C,OAAOA,0BAAAA,kBAAkB;EACvB,SAAS,YAAY,KAAK,WAAWC,oBAAAA,WAAW,WAAW,MAAM,CAAC;EAClE,WAAW,iBAAiB,KAAK,WAAWA,oBAAAA,WAAW,WAAW,MAAM,CAAC;EACzE,iBAAiB,OAAO;EACxB,SAAS,OAAO;EAChB,SAAS,OAAO;CAClB,CAAC;AACH"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { DataColumn } from "../../../columns/data_column.js";
|
|
2
2
|
import "../../../columns/index.js";
|
|
3
3
|
import { createPTableDefV3 } from "./createPTableDefV3.js";
|
|
4
4
|
import { getColumnIdAndSpec } from "@milaboratories/pl-model-common";
|
|
@@ -14,8 +14,8 @@ function createPTableDefV2(params) {
|
|
|
14
14
|
}
|
|
15
15
|
secondaryColumns.push(...params.labelColumns);
|
|
16
16
|
return createPTableDefV3({
|
|
17
|
-
primary: coreColumns.map((column) =>
|
|
18
|
-
secondary: secondaryColumns.map((column) =>
|
|
17
|
+
primary: coreColumns.map((column) => DataColumn.fromColumn(column)),
|
|
18
|
+
secondary: secondaryColumns.map((column) => DataColumn.fromColumn(column)),
|
|
19
19
|
primaryJoinType: params.coreJoinType,
|
|
20
20
|
filters: params.filters,
|
|
21
21
|
sorting: params.sorting
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createPTableDefV2.js","names":[],"sources":["../../../../src/components/PlDataTable/createPlDataTable/createPTableDefV2.ts"],"sourcesContent":["import type {\n ColumnUniversalId,\n PColumn,\n PColumnIdAndSpec,\n PTableSorting,\n PTableDefV2,\n} from \"@milaboratories/pl-model-common\";\nimport { getColumnIdAndSpec } from \"@milaboratories/pl-model-common\";\nimport type { PColumnDataUniversal } from \"../../../render\";\nimport { isFunction } from \"es-toolkit\";\nimport type { PlDataTableFilters } from \"../typesV8\";\nimport { createPTableDefV3 } from \"./createPTableDefV3\";\nimport {
|
|
1
|
+
{"version":3,"file":"createPTableDefV2.js","names":[],"sources":["../../../../src/components/PlDataTable/createPlDataTable/createPTableDefV2.ts"],"sourcesContent":["import type {\n ColumnUniversalId,\n PColumn,\n PColumnIdAndSpec,\n PTableSorting,\n PTableDefV2,\n} from \"@milaboratories/pl-model-common\";\nimport { getColumnIdAndSpec } from \"@milaboratories/pl-model-common\";\nimport type { PColumnDataUniversal } from \"../../../render\";\nimport { isFunction } from \"es-toolkit\";\nimport type { PlDataTableFilters } from \"../typesV8\";\nimport { createPTableDefV3 } from \"./createPTableDefV3\";\nimport { DataColumn } from \"../../../columns\";\n\nexport function createPTableDefV2(params: {\n columns: PColumn<undefined | PColumnDataUniversal>[];\n labelColumns: PColumn<undefined | PColumnDataUniversal>[];\n coreJoinType: \"inner\" | \"full\";\n filters: null | PlDataTableFilters;\n sorting: PTableSorting[];\n coreColumnPredicate?: (spec: PColumnIdAndSpec) => boolean;\n}): PTableDefV2<ColumnUniversalId> {\n let coreColumns = params.columns;\n const secondaryColumns: typeof params.columns = [];\n\n if (isFunction(params.coreColumnPredicate)) {\n coreColumns = [];\n for (const c of params.columns)\n if (params.coreColumnPredicate(getColumnIdAndSpec(c))) coreColumns.push(c);\n else secondaryColumns.push(c);\n }\n\n secondaryColumns.push(...params.labelColumns);\n\n return createPTableDefV3({\n primary: coreColumns.map((column) => DataColumn.fromColumn(column)),\n secondary: secondaryColumns.map((column) => DataColumn.fromColumn(column)),\n primaryJoinType: params.coreJoinType,\n filters: params.filters,\n sorting: params.sorting,\n });\n}\n"],"mappings":";;;;;;AAcA,SAAgB,kBAAkB,QAOC;CACjC,IAAI,cAAc,OAAO;CACzB,MAAM,mBAA0C,CAAC;CAEjD,IAAI,WAAW,OAAO,mBAAmB,GAAG;EAC1C,cAAc,CAAC;EACf,KAAK,MAAM,KAAK,OAAO,SACrB,IAAI,OAAO,oBAAoB,mBAAmB,CAAC,CAAC,GAAG,YAAY,KAAK,CAAC;OACpE,iBAAiB,KAAK,CAAC;CAChC;CAEA,iBAAiB,KAAK,GAAG,OAAO,YAAY;CAE5C,OAAO,kBAAkB;EACvB,SAAS,YAAY,KAAK,WAAW,WAAW,WAAW,MAAM,CAAC;EAClE,WAAW,iBAAiB,KAAK,WAAW,WAAW,WAAW,MAAM,CAAC;EACzE,iBAAiB,OAAO;EACxB,SAAS,OAAO;EAChB,SAAS,OAAO;CAClB,CAAC;AACH"}
|
|
@@ -2,7 +2,7 @@ const require_label = require("../../../render/util/label.cjs");
|
|
|
2
2
|
const require_pcolumn_data = require("../../../render/util/pcolumn_data.cjs");
|
|
3
3
|
const require_column_collection = require("../../../render/util/column_collection.cjs");
|
|
4
4
|
require("../../../render/index.cjs");
|
|
5
|
-
const
|
|
5
|
+
const require_data_column = require("../../../columns/data_column.cjs");
|
|
6
6
|
require("../../../columns/index.cjs");
|
|
7
7
|
const require_traverse = require("../../../filters/traverse.cjs");
|
|
8
8
|
const require_state_migration = require("../state-migration.cjs");
|
|
@@ -41,7 +41,7 @@ function createPlDataTableV2(ctx, columns, tableState, options) {
|
|
|
41
41
|
};
|
|
42
42
|
});
|
|
43
43
|
const fullColumns = [...columns, ...fullLabelColumns];
|
|
44
|
-
const resolver = require_columnResolver.createColumnResolver(fullColumns.map((c) =>
|
|
44
|
+
const resolver = require_columnResolver.createColumnResolver(fullColumns.map((c) => require_data_column.DataColumn.fromColumn(c)), { warn: ctx.logWarn.bind(ctx) });
|
|
45
45
|
const rawFilters = tableStateNormalized.pTableParams.filters;
|
|
46
46
|
const rawDefaultFilters = options?.filters ?? void 0;
|
|
47
47
|
const filters = remapFiltersThrowing(rawFilters, resolver, "filter");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createPlDataTableV2.cjs","names":["upgradePlDataTableStateV2","getMatchingLabelColumns","deriveLabels","identity","Annotation","createColumnResolver","ColumnLazyImpl","createPTableDefV2","isColumnOptional","getColumnIdAndSpec","allPColumnsReady","traverseFilterSpec","PColumnCollection","PColumnName"],"sources":["../../../../src/components/PlDataTable/createPlDataTable/createPlDataTableV2.ts"],"sourcesContent":["import type {\n ColumnUniversalId,\n FilterSpecNode,\n PColumn,\n PTableColumnIdColumn,\n PTableSorting,\n} from \"@milaboratories/pl-model-common\";\nimport {\n Annotation,\n getColumnIdAndSpec,\n isLinkerColumn,\n PColumnName,\n} from \"@milaboratories/pl-model-common\";\nimport type {\n AxisLabelProvider,\n ColumnProvider,\n PColumnDataUniversal,\n RenderCtxBase,\n} from \"../../../render\";\nimport { allPColumnsReady, deriveLabels, PColumnCollection } from \"../../../render\";\nimport { identity } from \"es-toolkit\";\nimport type {\n CreatePlDataTableOps,\n PlDataTableFilters,\n PlDataTableFilterSpecLeaf,\n PlDataTableModel,\n} from \"../typesV8\";\nimport { upgradePlDataTableStateV2 } from \"../state-migration\";\nimport type { PlDataTableStateV2 } from \"../state-migration\";\nimport { getMatchingLabelColumns } from \"../labels\";\nimport { collectFilterSpecColumns, traverseFilterSpec } from \"../../../filters/traverse\";\nimport { createPTableDefV2 } from \"./createPTableDefV2\";\nimport { isColumnOptional } from \"./utils\";\nimport { ColumnLazyImpl } from \"../../../columns\";\nimport { createColumnResolver, type ColumnResolver } from \"../columnResolver\";\nimport { isNil, type Nil } from \"@milaboratories/helpers\";\n\n/**\n * @deprecated This function is deprecated and will be removed in future. Please migrate to createPlDataTable with v3 options for improved column discovery and display configuration. See createPlDataTableOptionsV3 for details on the new options format and migration guidance.\n */\nexport type createPlDataTableOptionsV2 = {\n columns: PColumn<PColumnDataUniversal>[];\n tableState?: PlDataTableStateV2;\n options?: CreatePlDataTableOps;\n};\n\n/**\n * Create p-table spec and handle given ui table state\n *\n * @deprecated This version of createPlDataTable is deprecated and will be removed in future. Please migrate to v3 by switching to the new options format and providing necessary information for column discovery and display configuration. See createPlDataTableOptionsV3 for details.\n * @param ctx context\n * @param columns column list\n * @param tableState table ui state\n * @returns PlAgDataTableV2 table source\n */\nexport function createPlDataTableV2<A, U>(\n ctx: RenderCtxBase<A, U>,\n columns: createPlDataTableOptionsV2[\"columns\"],\n tableState?: createPlDataTableOptionsV2[\"tableState\"],\n options?: createPlDataTableOptionsV2[\"options\"],\n): PlDataTableModel | undefined {\n if (columns.length === 0) return undefined;\n\n const tableStateNormalized = upgradePlDataTableStateV2(tableState);\n const allLabelColumns = getAllLabelColumns(ctx.resultPool) ?? [];\n\n let fullLabelColumns = getMatchingLabelColumns(columns, allLabelColumns);\n fullLabelColumns = deriveLabels(fullLabelColumns, identity, { includeNativeLabel: true }).map(\n (v) => {\n return {\n ...v.value,\n spec: {\n ...v.value.spec,\n annotations: {\n ...v.value.spec.annotations,\n [Annotation.Label]: v.label,\n },\n },\n };\n },\n );\n\n const fullColumns = [...columns, ...fullLabelColumns];\n\n const resolver = createColumnResolver(\n fullColumns.map((c) => ColumnLazyImpl.fromColumn(c)),\n { warn: ctx.logWarn.bind(ctx) },\n );\n\n // -- Filtering: rewrite via resolver, throw if any reference is unresolved --\n const rawFilters = tableStateNormalized.pTableParams.filters;\n const rawDefaultFilters = options?.filters ?? undefined;\n const filters = remapFiltersThrowing(rawFilters, resolver, \"filter\");\n const defaultFilters = remapFiltersThrowing(\n rawDefaultFilters ?? null,\n resolver,\n \"default filter\",\n );\n\n // -- Sorting: rewrite via resolver, throw if any reference is unresolved --\n const userSorting = tableStateNormalized.pTableParams.sorting;\n const rawSorting = (isNil(userSorting) ? options?.sorting : userSorting) ?? [];\n const sorting = remapSortingThrowing(rawSorting, resolver);\n\n const coreJoinType = options?.coreJoinType ?? \"full\";\n const fullDef = createPTableDefV2({\n columns,\n labelColumns: fullLabelColumns,\n coreJoinType,\n filters: filters ?? null,\n sorting,\n coreColumnPredicate: options?.coreColumnPredicate,\n });\n\n const fullHandle = ctx.createPTableV2(fullDef);\n const pframeHandle = ctx.createPFrame(fullColumns);\n if (!fullHandle || !pframeHandle) return undefined;\n\n const hiddenColumns = new Set<ColumnUniversalId>(\n ((): ColumnUniversalId[] => {\n // Inner join works as a filter - all columns must be present\n if (coreJoinType === \"inner\") return [];\n\n const hiddenColIds = tableStateNormalized.pTableParams.hiddenColIds;\n if (hiddenColIds !== null) {\n return hiddenColIds\n .filter((s): s is PTableColumnIdColumn => s.type === \"column\")\n .map((s) => s.id);\n }\n\n return columns.filter((c) => isColumnOptional(c.spec)).map((c) => c.id);\n })(),\n );\n\n // Preserve linker columns\n columns.filter((c) => isLinkerColumn(c.spec)).forEach((c) => hiddenColumns.delete(c.id));\n\n // Preserve core columns as they change the shape of join.\n const coreColumnPredicate = options?.coreColumnPredicate;\n if (coreColumnPredicate) {\n const coreColumns = columns.flatMap((c) =>\n coreColumnPredicate(getColumnIdAndSpec(c)) ? [c.id] : [],\n );\n coreColumns.forEach((c) => hiddenColumns.delete(c));\n }\n\n // Preserve sorted columns from being hidden\n sorting\n .map((s) => s.column)\n .filter((c): c is PTableColumnIdColumn => c.type === \"column\")\n .forEach((c) => hiddenColumns.delete(c.id));\n\n // Preserve filter columns from being hidden\n if (filters) {\n collectFilterSpecColumns(filters)\n .flatMap((c) => (c.type === \"column\" ? [c.id] : []))\n .forEach((c) => hiddenColumns.delete(c));\n }\n\n const visibleColumns = columns.filter((c) => !hiddenColumns.has(c.id));\n const visibleLabelColumns = getMatchingLabelColumns(\n visibleColumns.map(getColumnIdAndSpec),\n allLabelColumns,\n );\n\n // if at least one column is not yet computed, we can't show the table\n if (!allPColumnsReady([...visibleColumns, ...visibleLabelColumns])) return undefined;\n\n const visibleDef = createPTableDefV2({\n columns: visibleColumns,\n labelColumns: visibleLabelColumns,\n coreJoinType,\n filters: filters ?? null,\n sorting,\n coreColumnPredicate,\n });\n const visibleHandle = ctx.createPTableV2(visibleDef);\n\n if (!visibleHandle) return undefined;\n\n return {\n sourceId: tableStateNormalized.pTableParams.sourceId,\n fullTableHandle: fullHandle,\n fullPframeHandle: pframeHandle,\n visibleTableHandle: visibleHandle,\n defaultFilters: defaultFilters ?? undefined,\n } satisfies PlDataTableModel;\n}\n\n/** Rewrite filter column refs through the resolver; throw on any unresolved ref. */\nfunction remapFiltersThrowing(\n filters: Nil | PlDataTableFilters,\n resolver: ColumnResolver,\n label: string,\n): Nil | PlDataTableFilters {\n if (isNil(filters)) return filters;\n\n type Node = FilterSpecNode<PlDataTableFilterSpecLeaf>;\n return traverseFilterSpec(filters, {\n leaf: (leaf): Node => {\n if (leaf.type === undefined) return leaf;\n const result = { ...leaf };\n if (\"column\" in result) {\n const c = resolver(result.column);\n if (isNil(c))\n throw new Error(\n `Invalid ${label} column ${JSON.stringify(result.column)}: column reference does not match the table columns`,\n );\n result.column = c;\n }\n if (\"rhs\" in result) {\n const c = resolver(result.rhs);\n if (isNil(c))\n throw new Error(\n `Invalid ${label} column ${JSON.stringify(result.rhs)}: column reference does not match the table columns`,\n );\n result.rhs = c;\n }\n return result;\n },\n and: (results): Node => ({ type: \"and\", filters: results }),\n or: (results): Node => ({ type: \"or\", filters: results }),\n not: (result): Node => ({ type: \"not\", filter: result }),\n }) as PlDataTableFilters;\n}\n\n/** Rewrite sorting column refs through the resolver; throw on any unresolved ref. */\nfunction remapSortingThrowing(sorting: PTableSorting[], resolver: ColumnResolver): PTableSorting[] {\n return sorting.map((s) => {\n const c = resolver(s.column);\n if (isNil(c))\n throw new Error(\n `Invalid sorting column ${JSON.stringify(s.column)}: column reference does not match the table columns`,\n );\n return { ...s, column: c };\n });\n}\n\nfunction getAllLabelColumns(\n resultPool: AxisLabelProvider & ColumnProvider,\n): undefined | PColumn<undefined | PColumnDataUniversal>[] {\n return new PColumnCollection()\n .addAxisLabelProvider(resultPool)\n .addColumnProvider(resultPool)\n .getColumns(\n {\n name: PColumnName.Label,\n axes: [{}], // exactly one axis\n },\n { dontWaitAllData: true, overrideLabelAnnotation: false },\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAuDA,SAAgB,oBACd,KACA,SACA,YACA,SAC8B;CAC9B,IAAI,QAAQ,WAAW,GAAG,OAAO,KAAA;CAEjC,MAAM,uBAAuBA,wBAAAA,0BAA0B,UAAU;CACjE,MAAM,kBAAkB,mBAAmB,IAAI,UAAU,KAAK,CAAC;CAE/D,IAAI,mBAAmBC,eAAAA,wBAAwB,SAAS,eAAe;CACvE,mBAAmBC,cAAAA,aAAa,kBAAkBC,WAAAA,UAAU,EAAE,oBAAoB,KAAK,CAAC,CAAC,CAAC,KACvF,MAAM;EACL,OAAO;GACL,GAAG,EAAE;GACL,MAAM;IACJ,GAAG,EAAE,MAAM;IACX,aAAa;KACX,GAAG,EAAE,MAAM,KAAK;MACfC,gCAAAA,WAAW,QAAQ,EAAE;IACxB;GACF;EACF;CACF,CACF;CAEA,MAAM,cAAc,CAAC,GAAG,SAAS,GAAG,gBAAgB;CAEpD,MAAM,WAAWC,uBAAAA,qBACf,YAAY,KAAK,MAAMC,oBAAAA,eAAe,WAAW,CAAC,CAAC,GACnD,EAAE,MAAM,IAAI,QAAQ,KAAK,GAAG,EAAE,CAChC;CAGA,MAAM,aAAa,qBAAqB,aAAa;CACrD,MAAM,oBAAoB,SAAS,WAAW,KAAA;CAC9C,MAAM,UAAU,qBAAqB,YAAY,UAAU,QAAQ;CACnE,MAAM,iBAAiB,qBACrB,qBAAqB,MACrB,UACA,gBACF;CAGA,MAAM,cAAc,qBAAqB,aAAa;CAEtD,MAAM,UAAU,uBAAA,GAAA,wBAAA,MAAA,CADU,WAAW,IAAI,SAAS,UAAU,gBAAgB,CAAC,GAC5B,QAAQ;CAEzD,MAAM,eAAe,SAAS,gBAAgB;CAC9C,MAAM,UAAUC,0BAAAA,kBAAkB;EAChC;EACA,cAAc;EACd;EACA,SAAS,WAAW;EACpB;EACA,qBAAqB,SAAS;CAChC,CAAC;CAED,MAAM,aAAa,IAAI,eAAe,OAAO;CAC7C,MAAM,eAAe,IAAI,aAAa,WAAW;CACjD,IAAI,CAAC,cAAc,CAAC,cAAc,OAAO,KAAA;CAEzC,MAAM,gBAAgB,IAAI,WACI;EAE1B,IAAI,iBAAiB,SAAS,OAAO,CAAC;EAEtC,MAAM,eAAe,qBAAqB,aAAa;EACvD,IAAI,iBAAiB,MACnB,OAAO,aACJ,QAAQ,MAAiC,EAAE,SAAS,QAAQ,CAAC,CAC7D,KAAK,MAAM,EAAE,EAAE;EAGpB,OAAO,QAAQ,QAAQ,MAAMC,cAAAA,iBAAiB,EAAE,IAAI,CAAC,CAAC,CAAC,KAAK,MAAM,EAAE,EAAE;CACxE,EAAA,CAAG,CACL;CAGA,QAAQ,QAAQ,OAAA,GAAA,gCAAA,eAAA,CAAqB,EAAE,IAAI,CAAC,CAAC,CAAC,SAAS,MAAM,cAAc,OAAO,EAAE,EAAE,CAAC;CAGvF,MAAM,sBAAsB,SAAS;CACrC,IAAI,qBAIF,QAH4B,SAAS,MACnC,qBAAA,GAAA,gCAAA,mBAAA,CAAuC,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAE/C,CAAC,CAAC,SAAS,MAAM,cAAc,OAAO,CAAC,CAAC;CAIpD,QACG,KAAK,MAAM,EAAE,MAAM,CAAC,CACpB,QAAQ,MAAiC,EAAE,SAAS,QAAQ,CAAC,CAC7D,SAAS,MAAM,cAAc,OAAO,EAAE,EAAE,CAAC;CAG5C,IAAI,SACF,iBAAA,yBAAyB,OAAO,CAAC,CAC9B,SAAS,MAAO,EAAE,SAAS,WAAW,CAAC,EAAE,EAAE,IAAI,CAAC,CAAE,CAAC,CACnD,SAAS,MAAM,cAAc,OAAO,CAAC,CAAC;CAG3C,MAAM,iBAAiB,QAAQ,QAAQ,MAAM,CAAC,cAAc,IAAI,EAAE,EAAE,CAAC;CACrE,MAAM,sBAAsBP,eAAAA,wBAC1B,eAAe,IAAIQ,gCAAAA,kBAAkB,GACrC,eACF;CAGA,IAAI,CAACC,qBAAAA,iBAAiB,CAAC,GAAG,gBAAgB,GAAG,mBAAmB,CAAC,GAAG,OAAO,KAAA;CAE3E,MAAM,aAAaH,0BAAAA,kBAAkB;EACnC,SAAS;EACT,cAAc;EACd;EACA,SAAS,WAAW;EACpB;EACA;CACF,CAAC;CACD,MAAM,gBAAgB,IAAI,eAAe,UAAU;CAEnD,IAAI,CAAC,eAAe,OAAO,KAAA;CAE3B,OAAO;EACL,UAAU,qBAAqB,aAAa;EAC5C,iBAAiB;EACjB,kBAAkB;EAClB,oBAAoB;EACpB,gBAAgB,kBAAkB,KAAA;CACpC;AACF;;AAGA,SAAS,qBACP,SACA,UACA,OAC0B;CAC1B,KAAA,GAAA,wBAAA,MAAA,CAAU,OAAO,GAAG,OAAO;CAG3B,OAAOI,iBAAAA,mBAAmB,SAAS;EACjC,OAAO,SAAe;GACpB,IAAI,KAAK,SAAS,KAAA,GAAW,OAAO;GACpC,MAAM,SAAS,EAAE,GAAG,KAAK;GACzB,IAAI,YAAY,QAAQ;IACtB,MAAM,IAAI,SAAS,OAAO,MAAM;IAChC,KAAA,GAAA,wBAAA,MAAA,CAAU,CAAC,GACT,MAAM,IAAI,MACR,WAAW,MAAM,UAAU,KAAK,UAAU,OAAO,MAAM,EAAE,oDAC3D;IACF,OAAO,SAAS;GAClB;GACA,IAAI,SAAS,QAAQ;IACnB,MAAM,IAAI,SAAS,OAAO,GAAG;IAC7B,KAAA,GAAA,wBAAA,MAAA,CAAU,CAAC,GACT,MAAM,IAAI,MACR,WAAW,MAAM,UAAU,KAAK,UAAU,OAAO,GAAG,EAAE,oDACxD;IACF,OAAO,MAAM;GACf;GACA,OAAO;EACT;EACA,MAAM,aAAmB;GAAE,MAAM;GAAO,SAAS;EAAQ;EACzD,KAAK,aAAmB;GAAE,MAAM;GAAM,SAAS;EAAQ;EACvD,MAAM,YAAkB;GAAE,MAAM;GAAO,QAAQ;EAAO;CACxD,CAAC;AACH;;AAGA,SAAS,qBAAqB,SAA0B,UAA2C;CACjG,OAAO,QAAQ,KAAK,MAAM;EACxB,MAAM,IAAI,SAAS,EAAE,MAAM;EAC3B,KAAA,GAAA,wBAAA,MAAA,CAAU,CAAC,GACT,MAAM,IAAI,MACR,0BAA0B,KAAK,UAAU,EAAE,MAAM,EAAE,oDACrD;EACF,OAAO;GAAE,GAAG;GAAG,QAAQ;EAAE;CAC3B,CAAC;AACH;AAEA,SAAS,mBACP,YACyD;CACzD,OAAO,IAAIC,0BAAAA,kBAAkB,CAAC,CAC3B,qBAAqB,UAAU,CAAC,CAChC,kBAAkB,UAAU,CAAC,CAC7B,WACC;EACE,MAAMC,gCAAAA,YAAY;EAClB,MAAM,CAAC,CAAC,CAAC;CACX,GACA;EAAE,iBAAiB;EAAM,yBAAyB;CAAM,CAC1D;AACJ"}
|
|
1
|
+
{"version":3,"file":"createPlDataTableV2.cjs","names":["upgradePlDataTableStateV2","getMatchingLabelColumns","deriveLabels","identity","Annotation","createColumnResolver","DataColumn","createPTableDefV2","isColumnOptional","getColumnIdAndSpec","allPColumnsReady","traverseFilterSpec","PColumnCollection","PColumnName"],"sources":["../../../../src/components/PlDataTable/createPlDataTable/createPlDataTableV2.ts"],"sourcesContent":["import type {\n ColumnUniversalId,\n FilterSpecNode,\n PColumn,\n PTableColumnIdColumn,\n PTableSorting,\n} from \"@milaboratories/pl-model-common\";\nimport {\n Annotation,\n getColumnIdAndSpec,\n isLinkerColumn,\n PColumnName,\n} from \"@milaboratories/pl-model-common\";\nimport type {\n AxisLabelProvider,\n ColumnProvider,\n PColumnDataUniversal,\n RenderCtxBase,\n} from \"../../../render\";\nimport { allPColumnsReady, deriveLabels, PColumnCollection } from \"../../../render\";\nimport { identity } from \"es-toolkit\";\nimport type {\n CreatePlDataTableOps,\n PlDataTableFilters,\n PlDataTableFilterSpecLeaf,\n PlDataTableModel,\n} from \"../typesV8\";\nimport { upgradePlDataTableStateV2 } from \"../state-migration\";\nimport type { PlDataTableStateV2 } from \"../state-migration\";\nimport { getMatchingLabelColumns } from \"../labels\";\nimport { collectFilterSpecColumns, traverseFilterSpec } from \"../../../filters/traverse\";\nimport { createPTableDefV2 } from \"./createPTableDefV2\";\nimport { isColumnOptional } from \"./utils\";\nimport { DataColumn } from \"../../../columns\";\nimport { createColumnResolver, type ColumnResolver } from \"../columnResolver\";\nimport { isNil, type Nil } from \"@milaboratories/helpers\";\n\n/**\n * @deprecated This function is deprecated and will be removed in future. Please migrate to createPlDataTable with v3 options for improved column discovery and display configuration. See createPlDataTableOptionsV3 for details on the new options format and migration guidance.\n */\nexport type createPlDataTableOptionsV2 = {\n columns: PColumn<PColumnDataUniversal>[];\n tableState?: PlDataTableStateV2;\n options?: CreatePlDataTableOps;\n};\n\n/**\n * Create p-table spec and handle given ui table state\n *\n * @deprecated This version of createPlDataTable is deprecated and will be removed in future. Please migrate to v3 by switching to the new options format and providing necessary information for column discovery and display configuration. See createPlDataTableOptionsV3 for details.\n * @param ctx context\n * @param columns column list\n * @param tableState table ui state\n * @returns PlAgDataTableV2 table source\n */\nexport function createPlDataTableV2<A, U>(\n ctx: RenderCtxBase<A, U>,\n columns: createPlDataTableOptionsV2[\"columns\"],\n tableState?: createPlDataTableOptionsV2[\"tableState\"],\n options?: createPlDataTableOptionsV2[\"options\"],\n): PlDataTableModel | undefined {\n if (columns.length === 0) return undefined;\n\n const tableStateNormalized = upgradePlDataTableStateV2(tableState);\n const allLabelColumns = getAllLabelColumns(ctx.resultPool) ?? [];\n\n let fullLabelColumns = getMatchingLabelColumns(columns, allLabelColumns);\n fullLabelColumns = deriveLabels(fullLabelColumns, identity, { includeNativeLabel: true }).map(\n (v) => {\n return {\n ...v.value,\n spec: {\n ...v.value.spec,\n annotations: {\n ...v.value.spec.annotations,\n [Annotation.Label]: v.label,\n },\n },\n };\n },\n );\n\n const fullColumns = [...columns, ...fullLabelColumns];\n\n const resolver = createColumnResolver(\n fullColumns.map((c) => DataColumn.fromColumn(c)),\n { warn: ctx.logWarn.bind(ctx) },\n );\n\n // -- Filtering: rewrite via resolver, throw if any reference is unresolved --\n const rawFilters = tableStateNormalized.pTableParams.filters;\n const rawDefaultFilters = options?.filters ?? undefined;\n const filters = remapFiltersThrowing(rawFilters, resolver, \"filter\");\n const defaultFilters = remapFiltersThrowing(\n rawDefaultFilters ?? null,\n resolver,\n \"default filter\",\n );\n\n // -- Sorting: rewrite via resolver, throw if any reference is unresolved --\n const userSorting = tableStateNormalized.pTableParams.sorting;\n const rawSorting = (isNil(userSorting) ? options?.sorting : userSorting) ?? [];\n const sorting = remapSortingThrowing(rawSorting, resolver);\n\n const coreJoinType = options?.coreJoinType ?? \"full\";\n const fullDef = createPTableDefV2({\n columns,\n labelColumns: fullLabelColumns,\n coreJoinType,\n filters: filters ?? null,\n sorting,\n coreColumnPredicate: options?.coreColumnPredicate,\n });\n\n const fullHandle = ctx.createPTableV2(fullDef);\n const pframeHandle = ctx.createPFrame(fullColumns);\n if (!fullHandle || !pframeHandle) return undefined;\n\n const hiddenColumns = new Set<ColumnUniversalId>(\n ((): ColumnUniversalId[] => {\n // Inner join works as a filter - all columns must be present\n if (coreJoinType === \"inner\") return [];\n\n const hiddenColIds = tableStateNormalized.pTableParams.hiddenColIds;\n if (hiddenColIds !== null) {\n return hiddenColIds\n .filter((s): s is PTableColumnIdColumn => s.type === \"column\")\n .map((s) => s.id);\n }\n\n return columns.filter((c) => isColumnOptional(c.spec)).map((c) => c.id);\n })(),\n );\n\n // Preserve linker columns\n columns.filter((c) => isLinkerColumn(c.spec)).forEach((c) => hiddenColumns.delete(c.id));\n\n // Preserve core columns as they change the shape of join.\n const coreColumnPredicate = options?.coreColumnPredicate;\n if (coreColumnPredicate) {\n const coreColumns = columns.flatMap((c) =>\n coreColumnPredicate(getColumnIdAndSpec(c)) ? [c.id] : [],\n );\n coreColumns.forEach((c) => hiddenColumns.delete(c));\n }\n\n // Preserve sorted columns from being hidden\n sorting\n .map((s) => s.column)\n .filter((c): c is PTableColumnIdColumn => c.type === \"column\")\n .forEach((c) => hiddenColumns.delete(c.id));\n\n // Preserve filter columns from being hidden\n if (filters) {\n collectFilterSpecColumns(filters)\n .flatMap((c) => (c.type === \"column\" ? [c.id] : []))\n .forEach((c) => hiddenColumns.delete(c));\n }\n\n const visibleColumns = columns.filter((c) => !hiddenColumns.has(c.id));\n const visibleLabelColumns = getMatchingLabelColumns(\n visibleColumns.map(getColumnIdAndSpec),\n allLabelColumns,\n );\n\n // if at least one column is not yet computed, we can't show the table\n if (!allPColumnsReady([...visibleColumns, ...visibleLabelColumns])) return undefined;\n\n const visibleDef = createPTableDefV2({\n columns: visibleColumns,\n labelColumns: visibleLabelColumns,\n coreJoinType,\n filters: filters ?? null,\n sorting,\n coreColumnPredicate,\n });\n const visibleHandle = ctx.createPTableV2(visibleDef);\n\n if (!visibleHandle) return undefined;\n\n return {\n sourceId: tableStateNormalized.pTableParams.sourceId,\n fullTableHandle: fullHandle,\n fullPframeHandle: pframeHandle,\n visibleTableHandle: visibleHandle,\n defaultFilters: defaultFilters ?? undefined,\n } satisfies PlDataTableModel;\n}\n\n/** Rewrite filter column refs through the resolver; throw on any unresolved ref. */\nfunction remapFiltersThrowing(\n filters: Nil | PlDataTableFilters,\n resolver: ColumnResolver,\n label: string,\n): Nil | PlDataTableFilters {\n if (isNil(filters)) return filters;\n\n type Node = FilterSpecNode<PlDataTableFilterSpecLeaf>;\n return traverseFilterSpec(filters, {\n leaf: (leaf): Node => {\n if (leaf.type === undefined) return leaf;\n const result = { ...leaf };\n if (\"column\" in result) {\n const c = resolver(result.column);\n if (isNil(c))\n throw new Error(\n `Invalid ${label} column ${JSON.stringify(result.column)}: column reference does not match the table columns`,\n );\n result.column = c;\n }\n if (\"rhs\" in result) {\n const c = resolver(result.rhs);\n if (isNil(c))\n throw new Error(\n `Invalid ${label} column ${JSON.stringify(result.rhs)}: column reference does not match the table columns`,\n );\n result.rhs = c;\n }\n return result;\n },\n and: (results): Node => ({ type: \"and\", filters: results }),\n or: (results): Node => ({ type: \"or\", filters: results }),\n not: (result): Node => ({ type: \"not\", filter: result }),\n }) as PlDataTableFilters;\n}\n\n/** Rewrite sorting column refs through the resolver; throw on any unresolved ref. */\nfunction remapSortingThrowing(sorting: PTableSorting[], resolver: ColumnResolver): PTableSorting[] {\n return sorting.map((s) => {\n const c = resolver(s.column);\n if (isNil(c))\n throw new Error(\n `Invalid sorting column ${JSON.stringify(s.column)}: column reference does not match the table columns`,\n );\n return { ...s, column: c };\n });\n}\n\nfunction getAllLabelColumns(\n resultPool: AxisLabelProvider & ColumnProvider,\n): undefined | PColumn<undefined | PColumnDataUniversal>[] {\n return new PColumnCollection()\n .addAxisLabelProvider(resultPool)\n .addColumnProvider(resultPool)\n .getColumns(\n {\n name: PColumnName.Label,\n axes: [{}], // exactly one axis\n },\n { dontWaitAllData: true, overrideLabelAnnotation: false },\n );\n}\n"],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@ import { deriveLabels } from "../../../render/util/label.js";
|
|
|
2
2
|
import { allPColumnsReady } from "../../../render/util/pcolumn_data.js";
|
|
3
3
|
import { PColumnCollection } from "../../../render/util/column_collection.js";
|
|
4
4
|
import "../../../render/index.js";
|
|
5
|
-
import {
|
|
5
|
+
import { DataColumn } from "../../../columns/data_column.js";
|
|
6
6
|
import "../../../columns/index.js";
|
|
7
7
|
import { collectFilterSpecColumns, traverseFilterSpec } from "../../../filters/traverse.js";
|
|
8
8
|
import { upgradePlDataTableStateV2 } from "../state-migration.js";
|
|
@@ -41,7 +41,7 @@ function createPlDataTableV2(ctx, columns, tableState, options) {
|
|
|
41
41
|
};
|
|
42
42
|
});
|
|
43
43
|
const fullColumns = [...columns, ...fullLabelColumns];
|
|
44
|
-
const resolver = createColumnResolver(fullColumns.map((c) =>
|
|
44
|
+
const resolver = createColumnResolver(fullColumns.map((c) => DataColumn.fromColumn(c)), { warn: ctx.logWarn.bind(ctx) });
|
|
45
45
|
const rawFilters = tableStateNormalized.pTableParams.filters;
|
|
46
46
|
const rawDefaultFilters = options?.filters ?? void 0;
|
|
47
47
|
const filters = remapFiltersThrowing(rawFilters, resolver, "filter");
|