@platforma-sdk/model 1.59.0 → 1.60.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.
Files changed (140) hide show
  1. package/dist/block_storage.cjs.map +1 -1
  2. package/dist/block_storage.d.ts +1 -11
  3. package/dist/block_storage.js.map +1 -1
  4. package/dist/block_storage_callbacks.cjs.map +1 -1
  5. package/dist/block_storage_callbacks.js.map +1 -1
  6. package/dist/columns/column_collection_builder.cjs +215 -0
  7. package/dist/columns/column_collection_builder.cjs.map +1 -0
  8. package/dist/columns/column_collection_builder.d.ts +112 -0
  9. package/dist/columns/column_collection_builder.js +214 -0
  10. package/dist/columns/column_collection_builder.js.map +1 -0
  11. package/dist/columns/column_selector.cjs +122 -0
  12. package/dist/columns/column_selector.cjs.map +1 -0
  13. package/dist/columns/column_selector.d.ts +41 -0
  14. package/dist/columns/column_selector.js +118 -0
  15. package/dist/columns/column_selector.js.map +1 -0
  16. package/dist/columns/column_snapshot.cjs +20 -0
  17. package/dist/columns/column_snapshot.cjs.map +1 -0
  18. package/dist/columns/column_snapshot.d.ts +39 -0
  19. package/dist/columns/column_snapshot.js +18 -0
  20. package/dist/columns/column_snapshot.js.map +1 -0
  21. package/dist/columns/column_snapshot_provider.cjs +112 -0
  22. package/dist/columns/column_snapshot_provider.cjs.map +1 -0
  23. package/dist/columns/column_snapshot_provider.d.ts +73 -0
  24. package/dist/columns/column_snapshot_provider.js +107 -0
  25. package/dist/columns/column_snapshot_provider.js.map +1 -0
  26. package/dist/columns/ctx_column_sources.cjs +84 -0
  27. package/dist/columns/ctx_column_sources.cjs.map +1 -0
  28. package/dist/columns/ctx_column_sources.d.ts +33 -0
  29. package/dist/columns/ctx_column_sources.js +82 -0
  30. package/dist/columns/ctx_column_sources.js.map +1 -0
  31. package/dist/columns/index.cjs +5 -0
  32. package/dist/columns/index.d.ts +5 -0
  33. package/dist/columns/index.js +5 -0
  34. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV2.cjs +111 -0
  35. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV2.cjs.map +1 -0
  36. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV2.d.ts +25 -0
  37. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV2.js +110 -0
  38. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV2.js.map +1 -0
  39. package/dist/components/PlDataTable/{table.cjs → createPlDataTable/createPlDataTableV3.cjs} +54 -54
  40. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.cjs.map +1 -0
  41. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.d.ts +39 -0
  42. package/dist/components/PlDataTable/{table.js → createPlDataTable/createPlDataTableV3.js} +53 -53
  43. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.js.map +1 -0
  44. package/dist/components/PlDataTable/createPlDataTable/index.cjs +12 -0
  45. package/dist/components/PlDataTable/createPlDataTable/index.cjs.map +1 -0
  46. package/dist/components/PlDataTable/createPlDataTable/index.d.ts +15 -0
  47. package/dist/components/PlDataTable/createPlDataTable/index.js +12 -0
  48. package/dist/components/PlDataTable/createPlDataTable/index.js.map +1 -0
  49. package/dist/components/PlDataTable/createPlDataTableSheet.cjs +18 -0
  50. package/dist/components/PlDataTable/createPlDataTableSheet.cjs.map +1 -0
  51. package/dist/components/PlDataTable/createPlDataTableSheet.d.ts +11 -0
  52. package/dist/components/PlDataTable/createPlDataTableSheet.js +17 -0
  53. package/dist/components/PlDataTable/createPlDataTableSheet.js.map +1 -0
  54. package/dist/components/PlDataTable/index.cjs +4 -1
  55. package/dist/components/PlDataTable/index.d.ts +5 -2
  56. package/dist/components/PlDataTable/index.js +4 -1
  57. package/dist/components/PlDataTable/state-migration.cjs.map +1 -1
  58. package/dist/components/PlDataTable/state-migration.d.ts +2 -2
  59. package/dist/components/PlDataTable/state-migration.js.map +1 -1
  60. package/dist/components/PlDataTable/{v4.d.ts → typesV4.d.ts} +2 -2
  61. package/dist/components/PlDataTable/{v5.d.ts → typesV5.d.ts} +2 -2
  62. package/dist/components/index.cjs +4 -1
  63. package/dist/components/index.d.ts +5 -2
  64. package/dist/components/index.js +4 -1
  65. package/dist/index.cjs +44 -16
  66. package/dist/index.d.ts +17 -5
  67. package/dist/index.js +15 -3
  68. package/dist/labels/derive_distinct_labels.cjs +156 -0
  69. package/dist/labels/derive_distinct_labels.cjs.map +1 -0
  70. package/dist/labels/derive_distinct_labels.d.ts +29 -0
  71. package/dist/labels/derive_distinct_labels.js +155 -0
  72. package/dist/labels/derive_distinct_labels.js.map +1 -0
  73. package/dist/labels/index.cjs +2 -0
  74. package/dist/labels/index.d.ts +2 -0
  75. package/dist/labels/index.js +2 -0
  76. package/dist/labels/write_labels_to_specs.cjs +15 -0
  77. package/dist/labels/write_labels_to_specs.cjs.map +1 -0
  78. package/dist/labels/write_labels_to_specs.d.ts +9 -0
  79. package/dist/labels/write_labels_to_specs.js +14 -0
  80. package/dist/labels/write_labels_to_specs.js.map +1 -0
  81. package/dist/package.cjs +1 -1
  82. package/dist/package.js +1 -1
  83. package/dist/render/api.cjs +11 -2
  84. package/dist/render/api.cjs.map +1 -1
  85. package/dist/render/api.d.ts +9 -5
  86. package/dist/render/api.js +12 -3
  87. package/dist/render/api.js.map +1 -1
  88. package/dist/render/index.d.ts +2 -1
  89. package/dist/render/index.js +1 -1
  90. package/dist/render/internal.cjs.map +1 -1
  91. package/dist/render/internal.d.ts +5 -2
  92. package/dist/render/internal.js.map +1 -1
  93. package/dist/render/util/column_collection.cjs +3 -3
  94. package/dist/render/util/column_collection.cjs.map +1 -1
  95. package/dist/render/util/column_collection.d.ts +3 -2
  96. package/dist/render/util/column_collection.js +4 -4
  97. package/dist/render/util/column_collection.js.map +1 -1
  98. package/dist/render/util/index.d.ts +2 -1
  99. package/dist/render/util/index.js +1 -1
  100. package/dist/render/util/label.cjs +7 -134
  101. package/dist/render/util/label.cjs.map +1 -1
  102. package/dist/render/util/label.d.ts +5 -50
  103. package/dist/render/util/label.js +8 -132
  104. package/dist/render/util/label.js.map +1 -1
  105. package/dist/render/util/split_selectors.d.ts +2 -2
  106. package/package.json +8 -6
  107. package/src/block_storage.ts +0 -11
  108. package/src/block_storage_callbacks.ts +1 -1
  109. package/src/columns/column_collection_builder.test.ts +427 -0
  110. package/src/columns/column_collection_builder.ts +455 -0
  111. package/src/columns/column_selector.test.ts +472 -0
  112. package/src/columns/column_selector.ts +212 -0
  113. package/src/columns/column_snapshot.ts +55 -0
  114. package/src/columns/column_snapshot_provider.ts +177 -0
  115. package/src/columns/ctx_column_sources.ts +107 -0
  116. package/src/columns/expand_by_partition.test.ts +289 -0
  117. package/src/columns/expand_by_partition.ts +187 -0
  118. package/src/columns/index.ts +5 -0
  119. package/src/components/PlDataTable/createPlDataTable/createPlDataTableV2.ts +193 -0
  120. package/src/components/PlDataTable/{table.ts → createPlDataTable/createPlDataTableV3.ts} +134 -70
  121. package/src/components/PlDataTable/createPlDataTable/index.ts +27 -0
  122. package/src/components/PlDataTable/createPlDataTableSheet.ts +20 -0
  123. package/src/components/PlDataTable/index.ts +6 -4
  124. package/src/components/PlDataTable/state-migration.ts +2 -2
  125. package/src/index.ts +2 -1
  126. package/src/labels/derive_distinct_labels.test.ts +461 -0
  127. package/src/labels/derive_distinct_labels.ts +289 -0
  128. package/src/labels/index.ts +2 -0
  129. package/src/labels/write_labels_to_specs.ts +12 -0
  130. package/src/render/api.ts +25 -3
  131. package/src/render/internal.ts +20 -1
  132. package/src/render/util/column_collection.ts +9 -6
  133. package/src/render/util/label.test.ts +1 -1
  134. package/src/render/util/label.ts +19 -235
  135. package/src/render/util/split_selectors.ts +3 -3
  136. package/dist/components/PlDataTable/table.cjs.map +0 -1
  137. package/dist/components/PlDataTable/table.d.ts +0 -30
  138. package/dist/components/PlDataTable/table.js.map +0 -1
  139. /package/src/components/PlDataTable/{v4.ts → typesV4.ts} +0 -0
  140. /package/src/components/PlDataTable/{v5.ts → typesV5.ts} +0 -0
@@ -0,0 +1,187 @@
1
+ import type {
2
+ AxisFilterByIdx,
3
+ AxisFilterValue,
4
+ AxisId,
5
+ PartitionedDataInfoEntries,
6
+ } from "@milaboratories/pl-model-common";
7
+ import {
8
+ canonicalizeAxisId,
9
+ entriesToDataInfo,
10
+ getAxisId,
11
+ isPartitionedDataInfoEntries,
12
+ } from "@milaboratories/pl-model-common";
13
+ import type { TreeNodeAccessor } from "../render/accessor";
14
+ import { filterDataInfoEntries } from "../render/util/axis_filtering";
15
+ import { convertOrParsePColumnData, getUniquePartitionKeys } from "../render/util/pcolumn_data";
16
+ import type { ColumnSnapshot } from "./column_snapshot";
17
+ import { createReadyColumnData } from "./column_snapshot";
18
+
19
+ // --- Types ---
20
+
21
+ export interface SplitAxis {
22
+ /** Index of the axis in the column's axesSpec to split by. */
23
+ readonly idx: number;
24
+ }
25
+
26
+ export interface ExpandByPartitionOpts {
27
+ /** Resolve axis values to human-readable labels. */
28
+ axisLabels?: (axisId: AxisId) => undefined | Record<string | number, string>;
29
+ }
30
+
31
+ export interface ExpandByPartitionResult {
32
+ /** Expanded snapshots (one per key combination per original snapshot). */
33
+ readonly items: ColumnSnapshot[];
34
+ /** False if any column's data was not ready for splitting. */
35
+ readonly complete: boolean;
36
+ }
37
+
38
+ // --- Implementation ---
39
+
40
+ /**
41
+ * Expand snapshots by splitting along partition axes.
42
+ *
43
+ * For each snapshot, reads partition data, enumerates unique keys on the
44
+ * split axes, and produces one output snapshot per key combination —
45
+ * with the split axes removed from `axesSpec` and a `pl7.app/trace`
46
+ * annotation recording the split origin.
47
+ *
48
+ * Returns `{ items: [], complete: false }` when any snapshot's data
49
+ * is not ready (status !== 'ready' or partition data unavailable).
50
+ */
51
+ export function expandByPartition(
52
+ snapshots: ColumnSnapshot[],
53
+ splitAxes: SplitAxis[],
54
+ opts?: ExpandByPartitionOpts,
55
+ ): ExpandByPartitionResult {
56
+ if (splitAxes.length === 0) {
57
+ return { items: snapshots, complete: true };
58
+ }
59
+
60
+ const splitAxisIdxs = splitAxes.map((a) => a.idx).sort((a, b) => a - b);
61
+ const result: ColumnSnapshot[] = [];
62
+
63
+ for (const snapshot of snapshots) {
64
+ if (snapshot.dataStatus !== "ready" || snapshot.data === undefined) {
65
+ return { items: [], complete: false };
66
+ }
67
+
68
+ const rawData = snapshot.data.get();
69
+ const dataEntries = convertOrParsePColumnData(rawData as TreeNodeAccessor | undefined);
70
+
71
+ if (dataEntries === undefined) {
72
+ return { items: [], complete: false };
73
+ }
74
+
75
+ if (!isPartitionedDataInfoEntries(dataEntries)) {
76
+ throw new Error(
77
+ `Splitting requires Partitioned DataInfoEntries, but got ${dataEntries.type} for column ${String(snapshot.id)}`,
78
+ );
79
+ }
80
+
81
+ const uniqueKeys = getUniquePartitionKeys(dataEntries);
82
+
83
+ const maxSplitIdx = splitAxisIdxs[splitAxisIdxs.length - 1];
84
+ if (maxSplitIdx >= dataEntries.partitionKeyLength) {
85
+ throw new Error(
86
+ `Not enough partition keys (${dataEntries.partitionKeyLength}) for requested split axes (max index ${maxSplitIdx}) in column ${snapshot.spec.name}`,
87
+ );
88
+ }
89
+
90
+ // Resolve labels for each split axis
91
+ const axesLabels: (undefined | Record<string | number, string>)[] = splitAxisIdxs.map((idx) =>
92
+ opts?.axisLabels?.(getAxisId(snapshot.spec.axesSpec[idx])),
93
+ );
94
+
95
+ // Generate all key combinations across split axes
96
+ const keyCombinations = generateKeyCombinations(uniqueKeys, splitAxisIdxs);
97
+ if (keyCombinations.length === 0) continue;
98
+
99
+ // Build adjusted axesSpec (remove split axes in reverse order)
100
+ const newAxesSpec = [...snapshot.spec.axesSpec];
101
+ for (let i = splitAxisIdxs.length - 1; i >= 0; i--) {
102
+ newAxesSpec.splice(splitAxisIdxs[i], 1);
103
+ }
104
+
105
+ for (const keyCombo of keyCombinations) {
106
+ const axisFilters: AxisFilterByIdx[] = keyCombo.map(
107
+ (value, sAxisIdx): AxisFilterByIdx => [splitAxisIdxs[sAxisIdx], value as AxisFilterValue],
108
+ );
109
+
110
+ const traceEntries = keyCombo.map((value, sAxisIdx) => {
111
+ const axisIdx = splitAxisIdxs[sAxisIdx];
112
+ const axisId = getAxisId(snapshot.spec.axesSpec[axisIdx]);
113
+ const labelMap = axesLabels[sAxisIdx];
114
+ const label = labelMap?.[value] ?? String(value);
115
+ return {
116
+ type: `split:${canonicalizeAxisId(axisId)}`,
117
+ label,
118
+ importance: 1_000_000,
119
+ };
120
+ });
121
+
122
+ const filteredData = filterDataInfoEntries(
123
+ dataEntries as PartitionedDataInfoEntries<TreeNodeAccessor>,
124
+ axisFilters,
125
+ );
126
+
127
+ const adjustedSpec = {
128
+ ...snapshot.spec,
129
+ axesSpec: newAxesSpec,
130
+ annotations: {
131
+ ...snapshot.spec.annotations,
132
+ "pl7.app/trace": JSON.stringify(traceEntries),
133
+ },
134
+ };
135
+
136
+ result.push({
137
+ id: snapshot.id,
138
+ spec: adjustedSpec,
139
+ dataStatus: "ready",
140
+ data: createReadyColumnData(() => entriesToDataInfo(filteredData)),
141
+ });
142
+ }
143
+ }
144
+
145
+ return { items: result, complete: true };
146
+ }
147
+
148
+ const MAX_KEY_COMBINATIONS = 10_000;
149
+
150
+ function generateKeyCombinations(
151
+ uniqueKeys: (string | number)[][],
152
+ splitAxisIdxs: number[],
153
+ ): (string | number)[][] {
154
+ const combinations: (string | number)[][] = [];
155
+
156
+ function generate(currentCombo: (string | number)[], sAxisIdx: number): void {
157
+ if (sAxisIdx >= splitAxisIdxs.length) {
158
+ combinations.push([...currentCombo]);
159
+ if (combinations.length > MAX_KEY_COMBINATIONS) {
160
+ throw new Error("Too many key combinations, aborting.");
161
+ }
162
+ return;
163
+ }
164
+
165
+ const axisIdx = splitAxisIdxs[sAxisIdx];
166
+ if (axisIdx >= uniqueKeys.length) {
167
+ throw new Error(
168
+ `Axis index ${axisIdx} out of bounds for unique keys array (length ${uniqueKeys.length})`,
169
+ );
170
+ }
171
+
172
+ const axisValues = uniqueKeys[axisIdx];
173
+ if (!axisValues || axisValues.length === 0) {
174
+ combinations.length = 0;
175
+ return;
176
+ }
177
+
178
+ for (const val of axisValues) {
179
+ currentCombo.push(val);
180
+ generate(currentCombo, sAxisIdx + 1);
181
+ currentCombo.pop();
182
+ }
183
+ }
184
+
185
+ generate([], 0);
186
+ return combinations;
187
+ }
@@ -0,0 +1,5 @@
1
+ export * from "./column_snapshot";
2
+ export * from "./column_snapshot_provider";
3
+ export * from "./column_selector";
4
+ export * from "./column_collection_builder";
5
+ export * from "./ctx_column_sources";
@@ -0,0 +1,193 @@
1
+ import type {
2
+ AxisId,
3
+ PColumn,
4
+ PObjectId,
5
+ PTableColumnId,
6
+ PTableColumnIdAxis,
7
+ PTableColumnIdColumn,
8
+ CanonicalizedJson,
9
+ } from "@milaboratories/pl-model-common";
10
+ import {
11
+ Annotation,
12
+ canonicalizeJson,
13
+ getAxisId,
14
+ getColumnIdAndSpec,
15
+ isLinkerColumn,
16
+ uniqueBy,
17
+ parseJson,
18
+ } from "@milaboratories/pl-model-common";
19
+ import type { PColumnDataUniversal, RenderCtxBase } from "../../../render";
20
+ import { allPColumnsReady, deriveLabels } from "../../../render";
21
+ import { identity } from "es-toolkit";
22
+ import type { CreatePlDataTableOps, PlDataTableFilters, PlDataTableModel } from "../typesV5";
23
+ import { upgradePlDataTableStateV2 } from "../state-migration";
24
+ import type { PlDataTableStateV2 } from "../state-migration";
25
+ import { getAllLabelColumns, getMatchingLabelColumns } from "../labels";
26
+ import { collectFilterSpecColumns } from "../../../filters/traverse";
27
+ import { isEmpty } from "es-toolkit/compat";
28
+ import { createPTableDef, isColumnOptional } from "./createPlDataTableV3";
29
+
30
+ export type createPlDataTableOptionsV2 = {
31
+ columns: PColumn<PColumnDataUniversal>[];
32
+ tableState?: PlDataTableStateV2;
33
+ options?: CreatePlDataTableOps;
34
+ };
35
+
36
+ /**
37
+ * Create p-table spec and handle given ui table state
38
+ *
39
+ * @param ctx context
40
+ * @param columns column list
41
+ * @param tableState table ui state
42
+ * @returns PlAgDataTableV2 table source
43
+ */
44
+ export function createPlDataTableV2<A, U>(
45
+ ctx: RenderCtxBase<A, U>,
46
+ columns: createPlDataTableOptionsV2["columns"],
47
+ tableState?: createPlDataTableOptionsV2["tableState"],
48
+ options?: createPlDataTableOptionsV2["options"],
49
+ ): PlDataTableModel | undefined {
50
+ if (columns.length === 0) return undefined;
51
+
52
+ const tableStateNormalized = upgradePlDataTableStateV2(tableState);
53
+
54
+ const allLabelColumns = getAllLabelColumns(ctx.resultPool);
55
+ if (!allLabelColumns) return undefined;
56
+
57
+ let fullLabelColumns = getMatchingLabelColumns(columns.map(getColumnIdAndSpec), allLabelColumns);
58
+ fullLabelColumns = deriveLabels(fullLabelColumns, identity, { includeNativeLabel: true }).map(
59
+ (v) => {
60
+ return {
61
+ ...v.value,
62
+ spec: {
63
+ ...v.value.spec,
64
+ annotations: {
65
+ ...v.value.spec.annotations,
66
+ [Annotation.Label]: v.label,
67
+ },
68
+ },
69
+ };
70
+ },
71
+ );
72
+
73
+ const fullColumns = [...columns, ...fullLabelColumns];
74
+
75
+ const fullColumnsAxes = uniqueBy(
76
+ fullColumns.flatMap((c) => c.spec.axesSpec.map((a) => getAxisId(a))),
77
+ (a) => canonicalizeJson<AxisId>(a),
78
+ );
79
+ const fullColumnsIds: PTableColumnId[] = [
80
+ ...fullColumnsAxes.map((a) => ({ type: "axis", id: a }) satisfies PTableColumnIdAxis),
81
+ ...fullColumns.map((c) => ({ type: "column", id: c.id }) satisfies PTableColumnIdColumn),
82
+ ];
83
+ const fullColumnsIdsSet = new Set(fullColumnsIds.map((c) => canonicalizeJson<PTableColumnId>(c)));
84
+ const isValidColumnId = (id: string): boolean =>
85
+ fullColumnsIdsSet.has(id as CanonicalizedJson<PTableColumnId>);
86
+
87
+ // -- Filtering validation --
88
+ const stateFilters = tableStateNormalized.pTableParams.filters;
89
+ const opsFilters = options?.filters ?? null;
90
+ const filters: null | PlDataTableFilters =
91
+ stateFilters != null && opsFilters != null
92
+ ? { type: "and", filters: [stateFilters, opsFilters] }
93
+ : (stateFilters ?? opsFilters);
94
+ const filterColumns = filters ? collectFilterSpecColumns(filters) : [];
95
+ const firstInvalidFilterColumn = filterColumns.find((col) => !isValidColumnId(col));
96
+ if (firstInvalidFilterColumn)
97
+ throw new Error(
98
+ `Invalid filter column ${firstInvalidFilterColumn}: column reference does not match the table columns`,
99
+ );
100
+
101
+ // -- Sorting validation --
102
+ const userSorting = tableStateNormalized.pTableParams.sorting;
103
+ const sorting = (isEmpty(userSorting) ? options?.sorting : userSorting) ?? [];
104
+ const firstInvalidSortingColumn = sorting.find(
105
+ (s) => !isValidColumnId(canonicalizeJson<PTableColumnId>(s.column)),
106
+ );
107
+ if (firstInvalidSortingColumn)
108
+ throw new Error(
109
+ `Invalid sorting column ${JSON.stringify(firstInvalidSortingColumn.column)}: column reference does not match the table columns`,
110
+ );
111
+
112
+ const coreJoinType = options?.coreJoinType ?? "full";
113
+ const fullDef = createPTableDef({
114
+ columns,
115
+ labelColumns: fullLabelColumns,
116
+ coreJoinType,
117
+ filters,
118
+ sorting,
119
+ coreColumnPredicate: options?.coreColumnPredicate,
120
+ });
121
+
122
+ const fullHandle = ctx.createPTableV2(fullDef);
123
+ const pframeHandle = ctx.createPFrame(fullColumns);
124
+ if (!fullHandle || !pframeHandle) return undefined;
125
+
126
+ const hiddenColumns = new Set<PObjectId>(
127
+ ((): PObjectId[] => {
128
+ // Inner join works as a filter - all columns must be present
129
+ if (coreJoinType === "inner") return [];
130
+
131
+ const hiddenColIds = tableStateNormalized.pTableParams.hiddenColIds;
132
+ if (hiddenColIds) return hiddenColIds;
133
+
134
+ return columns.filter((c) => isColumnOptional(c.spec)).map((c) => c.id);
135
+ })(),
136
+ );
137
+
138
+ // Preserve linker columns
139
+ columns.filter((c) => isLinkerColumn(c.spec)).forEach((c) => hiddenColumns.delete(c.id));
140
+
141
+ // Preserve core columns as they change the shape of join.
142
+ const coreColumnPredicate = options?.coreColumnPredicate;
143
+ if (coreColumnPredicate) {
144
+ const coreColumns = columns.flatMap((c) =>
145
+ coreColumnPredicate(getColumnIdAndSpec(c)) ? [c.id] : [],
146
+ );
147
+ coreColumns.forEach((c) => hiddenColumns.delete(c));
148
+ }
149
+
150
+ // Preserve sorted columns from being hidden
151
+ sorting
152
+ .map((s) => s.column)
153
+ .filter((c): c is PTableColumnIdColumn => c.type === "column")
154
+ .forEach((c) => hiddenColumns.delete(c.id));
155
+
156
+ // Preserve filter columns from being hidden
157
+ if (filters) {
158
+ collectFilterSpecColumns(filters)
159
+ .flatMap((c) => {
160
+ const obj = parseJson(c);
161
+ return obj.type === "column" ? [obj.id] : [];
162
+ })
163
+ .forEach((c) => hiddenColumns.delete(c));
164
+ }
165
+
166
+ const visibleColumns = columns.filter((c) => !hiddenColumns.has(c.id));
167
+ const visibleLabelColumns = getMatchingLabelColumns(
168
+ visibleColumns.map(getColumnIdAndSpec),
169
+ allLabelColumns,
170
+ );
171
+
172
+ // if at least one column is not yet computed, we can't show the table
173
+ if (!allPColumnsReady([...visibleColumns, ...visibleLabelColumns])) return undefined;
174
+
175
+ const visibleDef = createPTableDef({
176
+ columns: visibleColumns,
177
+ labelColumns: visibleLabelColumns,
178
+ coreJoinType,
179
+ filters,
180
+ sorting,
181
+ coreColumnPredicate,
182
+ });
183
+ const visibleHandle = ctx.createPTableV2(visibleDef);
184
+
185
+ if (!visibleHandle) return undefined;
186
+
187
+ return {
188
+ sourceId: tableStateNormalized.pTableParams.sourceId,
189
+ fullTableHandle: fullHandle,
190
+ fullPframeHandle: pframeHandle,
191
+ visibleTableHandle: visibleHandle,
192
+ } satisfies PlDataTableModel;
193
+ }