@platforma-sdk/model 1.65.9 → 1.66.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. package/dist/block_model.cjs +8 -11
  2. package/dist/block_model.cjs.map +1 -1
  3. package/dist/block_model.d.ts.map +1 -1
  4. package/dist/block_model.js +8 -10
  5. package/dist/block_model.js.map +1 -1
  6. package/dist/columns/column_collection_builder.cjs +61 -74
  7. package/dist/columns/column_collection_builder.cjs.map +1 -1
  8. package/dist/columns/column_collection_builder.d.ts +16 -22
  9. package/dist/columns/column_collection_builder.d.ts.map +1 -1
  10. package/dist/columns/column_collection_builder.js +62 -75
  11. package/dist/columns/column_collection_builder.js.map +1 -1
  12. package/dist/columns/column_selector.cjs.map +1 -1
  13. package/dist/columns/column_selector.d.ts +1 -1
  14. package/dist/columns/column_selector.js.map +1 -1
  15. package/dist/columns/column_snapshot.cjs.map +1 -1
  16. package/dist/columns/column_snapshot.d.ts +4 -4
  17. package/dist/columns/column_snapshot.d.ts.map +1 -1
  18. package/dist/columns/column_snapshot.js.map +1 -1
  19. package/dist/columns/ctx_column_sources.cjs.map +1 -1
  20. package/dist/columns/ctx_column_sources.d.ts +1 -1
  21. package/dist/columns/ctx_column_sources.d.ts.map +1 -1
  22. package/dist/columns/ctx_column_sources.js.map +1 -1
  23. package/dist/components/PlDataTable/createPlDataTable/createPTableDefV2.cjs +2 -2
  24. package/dist/components/PlDataTable/createPlDataTable/createPTableDefV2.cjs.map +1 -1
  25. package/dist/components/PlDataTable/createPlDataTable/createPTableDefV2.js +2 -2
  26. package/dist/components/PlDataTable/createPlDataTable/createPTableDefV2.js.map +1 -1
  27. package/dist/components/PlDataTable/createPlDataTable/createPTableDefV3.cjs +17 -18
  28. package/dist/components/PlDataTable/createPlDataTable/createPTableDefV3.cjs.map +1 -1
  29. package/dist/components/PlDataTable/createPlDataTable/createPTableDefV3.js +17 -18
  30. package/dist/components/PlDataTable/createPlDataTable/createPTableDefV3.js.map +1 -1
  31. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.cjs +99 -91
  32. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.cjs.map +1 -1
  33. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.d.ts +16 -16
  34. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.d.ts.map +1 -1
  35. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.js +102 -94
  36. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.js.map +1 -1
  37. package/dist/components/PlDataTable/createPlDataTable/discoverColumns.cjs +32 -23
  38. package/dist/components/PlDataTable/createPlDataTable/discoverColumns.cjs.map +1 -1
  39. package/dist/components/PlDataTable/createPlDataTable/discoverColumns.d.ts +5 -5
  40. package/dist/components/PlDataTable/createPlDataTable/discoverColumns.d.ts.map +1 -1
  41. package/dist/components/PlDataTable/createPlDataTable/discoverColumns.js +33 -24
  42. package/dist/components/PlDataTable/createPlDataTable/discoverColumns.js.map +1 -1
  43. package/dist/components/PlDataTable/createPlDataTable/index.cjs.map +1 -1
  44. package/dist/components/PlDataTable/createPlDataTable/index.d.ts +2 -3
  45. package/dist/components/PlDataTable/createPlDataTable/index.d.ts.map +1 -1
  46. package/dist/components/PlDataTable/createPlDataTable/index.js.map +1 -1
  47. package/dist/components/PlDataTable/createPlDataTable/utils.cjs +133 -16
  48. package/dist/components/PlDataTable/createPlDataTable/utils.cjs.map +1 -1
  49. package/dist/components/PlDataTable/createPlDataTable/utils.d.ts +8 -6
  50. package/dist/components/PlDataTable/createPlDataTable/utils.d.ts.map +1 -1
  51. package/dist/components/PlDataTable/createPlDataTable/utils.js +130 -17
  52. package/dist/components/PlDataTable/createPlDataTable/utils.js.map +1 -1
  53. package/dist/components/PlDataTable/labels.cjs +1 -2
  54. package/dist/components/PlDataTable/labels.cjs.map +1 -1
  55. package/dist/components/PlDataTable/labels.js +1 -2
  56. package/dist/components/PlDataTable/labels.js.map +1 -1
  57. package/dist/filters/distill.cjs +73 -30
  58. package/dist/filters/distill.cjs.map +1 -1
  59. package/dist/filters/distill.d.ts.map +1 -1
  60. package/dist/filters/distill.js +73 -30
  61. package/dist/filters/distill.js.map +1 -1
  62. package/dist/index.cjs +19 -15
  63. package/dist/index.d.ts +4 -2
  64. package/dist/index.js +6 -4
  65. package/dist/labels/derive_distinct_tooltips.cjs +85 -0
  66. package/dist/labels/derive_distinct_tooltips.cjs.map +1 -0
  67. package/dist/labels/derive_distinct_tooltips.d.ts +17 -0
  68. package/dist/labels/derive_distinct_tooltips.d.ts.map +1 -0
  69. package/dist/labels/derive_distinct_tooltips.js +84 -0
  70. package/dist/labels/derive_distinct_tooltips.js.map +1 -0
  71. package/dist/labels/index.cjs +1 -0
  72. package/dist/labels/index.d.ts +2 -1
  73. package/dist/labels/index.js +1 -0
  74. package/dist/package.cjs +1 -1
  75. package/dist/package.js +1 -1
  76. package/dist/render/api.cjs +8 -13
  77. package/dist/render/api.cjs.map +1 -1
  78. package/dist/render/api.d.ts +8 -11
  79. package/dist/render/api.d.ts.map +1 -1
  80. package/dist/render/api.js +8 -13
  81. package/dist/render/api.js.map +1 -1
  82. package/dist/services/get_services.cjs +19 -0
  83. package/dist/services/get_services.cjs.map +1 -0
  84. package/dist/services/get_services.d.ts +7 -0
  85. package/dist/services/get_services.d.ts.map +1 -0
  86. package/dist/services/get_services.js +19 -0
  87. package/dist/services/get_services.js.map +1 -0
  88. package/dist/services/index.cjs +1 -0
  89. package/dist/services/index.d.ts +2 -1
  90. package/dist/services/index.js +1 -0
  91. package/dist/services/service_bridge.cjs +4 -4
  92. package/dist/services/service_bridge.cjs.map +1 -1
  93. package/dist/services/service_bridge.d.ts +4 -4
  94. package/dist/services/service_bridge.d.ts.map +1 -1
  95. package/dist/services/service_bridge.js +4 -4
  96. package/dist/services/service_bridge.js.map +1 -1
  97. package/package.json +6 -6
  98. package/src/block_model.ts +8 -11
  99. package/src/columns/column_collection_builder.test.ts +75 -30
  100. package/src/columns/column_collection_builder.ts +96 -133
  101. package/src/columns/column_selector.ts +1 -1
  102. package/src/columns/column_snapshot.ts +7 -4
  103. package/src/columns/ctx_column_sources.ts +1 -3
  104. package/src/components/PFrameForGraphs.test.ts +4 -4
  105. package/src/components/PlDataTable/createPlDataTable/createPTableDefV2.ts +2 -2
  106. package/src/components/PlDataTable/createPlDataTable/createPTableDefV3.ts +44 -21
  107. package/src/components/PlDataTable/createPlDataTable/createPlDataTableV3.ts +202 -218
  108. package/src/components/PlDataTable/createPlDataTable/discoverColumns.ts +69 -56
  109. package/src/components/PlDataTable/createPlDataTable/index.ts +6 -7
  110. package/src/components/PlDataTable/createPlDataTable/utils.test.ts +97 -1
  111. package/src/components/PlDataTable/createPlDataTable/utils.ts +190 -35
  112. package/src/components/PlDataTable/labels.ts +3 -7
  113. package/src/filters/distill.test.ts +91 -0
  114. package/src/filters/distill.ts +102 -46
  115. package/src/labels/derive_distinct_tooltips.test.ts +233 -0
  116. package/src/labels/derive_distinct_tooltips.ts +130 -0
  117. package/src/labels/index.ts +1 -0
  118. package/src/render/api.ts +15 -50
  119. package/src/services/get_services.ts +28 -0
  120. package/src/services/index.ts +1 -0
  121. package/src/services/service_bridge.ts +5 -5
@@ -1,10 +1,10 @@
1
1
  import { TreeNodeAccessor } from "../render/accessor.js";
2
- import { createColumnSnapshot } from "./column_snapshot.js";
2
+ import { getService } from "../services/get_services.js";
3
+ import "../services/index.js";
3
4
  import { ArrayColumnProvider, toColumnSnapshotProvider } from "./column_snapshot_provider.js";
4
5
  import { convertColumnSelectorToMultiColumnSelector } from "./column_selector.js";
5
- import { AnchoredIdDeriver, canonicalizeJson, deriveNativeId, getAxesId, isPColumnSpec } from "@milaboratories/pl-model-common";
6
+ import { deriveNativeId, isPColumnSpec } from "@milaboratories/pl-model-common";
6
7
  import { throwError } from "@milaboratories/helpers";
7
- import { uniqBy } from "es-toolkit";
8
8
  //#region src/columns/column_collection_builder.ts
9
9
  /**
10
10
  * Mutable builder that accumulates column sources, then produces
@@ -15,7 +15,7 @@ import { uniqBy } from "es-toolkit";
15
15
  */
16
16
  var ColumnCollectionBuilder = class {
17
17
  providers = [];
18
- constructor(specDriver) {
18
+ constructor(specDriver = getService("pframeSpec")) {
19
19
  this.specDriver = specDriver;
20
20
  }
21
21
  /**
@@ -59,11 +59,6 @@ var ColumnCollectionImpl = class {
59
59
  [Symbol.dispose]() {
60
60
  this.dispose();
61
61
  }
62
- getColumn(id) {
63
- const col = this.columns.get(id);
64
- if (col === void 0) return void 0;
65
- return this.toSnapshot(col);
66
- }
67
62
  findColumns(options) {
68
63
  const includeColumns = options?.include ? toMultiColumnSelectors(options.include) : void 0;
69
64
  const excludeColumns = options?.exclude ? toMultiColumnSelectors(options.exclude) : void 0;
@@ -73,30 +68,18 @@ var ColumnCollectionImpl = class {
73
68
  axes: [],
74
69
  maxHops: 0,
75
70
  constraints: matchingModeToConstraints("enrichment")
76
- }).hits.map((hit) => this.columns.get(hit.hit.columnId)).filter((col) => col !== void 0).map((col) => this.toSnapshot(col));
77
- }
78
- toSnapshot(col) {
79
- return remapSnapshot(col.id, col);
71
+ }).hits.map((hit) => this.columns.get(hit.hit.columnId)).filter((col) => col !== void 0);
80
72
  }
81
73
  };
82
74
  var AnchoredColumnCollectionImpl = class {
83
75
  anchorsMap;
84
76
  columnsMap;
85
- idDeriver;
86
- uniqAnchorAxes;
87
- idToOriginalIdMap;
88
77
  specFrameEntry;
89
78
  constructor(specDriver, options) {
90
79
  this.specDriver = specDriver;
91
80
  this.specFrameEntry = this.specDriver.createSpecFrame(Object.fromEntries(options.columns.map((col) => [col.id, col.spec])));
92
81
  this.columnsMap = new Map(options.columns.map((col) => [col.id, col]));
93
82
  this.anchorsMap = resolveAnchorMap(options.anchors, options.columns, this.specDriver.discoverColumns.bind(this.specDriver, this.specFrameEntry.key));
94
- this.idDeriver = new AnchoredIdDeriver(Object.fromEntries(Array.from(this.anchorsMap.entries()).map(([k, v]) => [k, v.spec])));
95
- this.uniqAnchorAxes = uniqBy(Array.from(this.anchorsMap.values(), ({ spec }) => ({
96
- axesSpec: spec.axesSpec,
97
- qualifications: []
98
- })), (axis) => canonicalizeJson(getAxesId(axis.axesSpec)) + canonicalizeJson(axis.qualifications));
99
- this.idToOriginalIdMap = new Map(options.columns.map((col) => [this.idDeriver.deriveS(col.spec), col.id]));
100
83
  }
101
84
  dispose() {
102
85
  this.specFrameEntry.unref();
@@ -107,43 +90,45 @@ var AnchoredColumnCollectionImpl = class {
107
90
  getAnchors() {
108
91
  return this.anchorsMap;
109
92
  }
110
- getColumn(id) {
111
- const origId = this.idToOriginalIdMap.get(id);
112
- if (origId === void 0) return void 0;
113
- const col = this.columnsMap.get(origId);
114
- if (col === void 0) return void 0;
115
- return remapSnapshot(id, col);
116
- }
117
93
  findColumns(options) {
118
94
  const constraints = matchingModeToConstraints(options?.mode ?? "enrichment");
119
95
  const includeColumns = options?.include ? toMultiColumnSelectors(options.include) : void 0;
120
96
  const excludeColumns = options?.exclude ? toMultiColumnSelectors(options.exclude) : void 0;
121
- const response = this.specDriver.discoverColumns(this.specFrameEntry.key, {
97
+ const anchors = Array.from(this.anchorsMap.values());
98
+ const byColumn = this.specDriver.discoverColumns(this.specFrameEntry.key, {
122
99
  includeColumns,
123
100
  excludeColumns,
124
101
  constraints,
125
102
  maxHops: options?.maxHops ?? 4,
126
- axes: this.uniqAnchorAxes
127
- });
128
- const results = [];
129
- for (const hit of response.hits) {
103
+ axes: anchors.map((anchor) => ({
104
+ axesSpec: anchor.spec.axesSpec,
105
+ qualifications: []
106
+ }))
107
+ }).hits.reduce((acc, hit) => {
130
108
  const origId = hit.hit.columnId;
131
109
  const col = this.columnsMap.get(origId) ?? throwError(`Column with id ${origId} not found in collection`);
132
- const associatedId = this.idDeriver.deriveS(col.spec);
133
- results.push({
134
- path: hit.path.map((step) => {
135
- if (step.type !== "linker") throw new Error(`Unexpected discover-columns step type: ${step.type}`);
136
- return {
137
- linker: remapSnapshot(this.idDeriver.deriveS(step.linker.spec), this.columnsMap.get(step.linker.columnId) ?? throwError(`Linker column with id ${step.linker.columnId} not found in collection`)),
138
- qualifications: step.qualifications
139
- };
140
- }),
141
- column: remapSnapshot(associatedId, col),
142
- variants: hit.mappingVariants,
143
- originalId: origId
110
+ const path = hit.path.map((step) => {
111
+ if (step.type !== "linker") throw new Error(`Unexpected discover-columns step type: ${step.type}`);
112
+ return {
113
+ linker: this.columnsMap.get(step.linker.columnId) ?? throwError(`Linker column with id ${step.linker.columnId} not found in collection`),
114
+ qualifications: step.qualifications
115
+ };
144
116
  });
145
- }
146
- return results;
117
+ const variants = hit.mappingVariants.map((v) => ({
118
+ path,
119
+ qualifications: remapFromIdxToId(v.qualifications, anchors),
120
+ distinctiveQualifications: remapFromIdxToId(v.distinctiveQualifications, anchors)
121
+ }));
122
+ const existing = acc.get(origId);
123
+ return acc.set(origId, existing === void 0 ? {
124
+ column: col,
125
+ variants
126
+ } : {
127
+ ...existing,
128
+ variants: [...existing.variants, ...variants]
129
+ });
130
+ }, /* @__PURE__ */ new Map());
131
+ return Array.from(byColumn.values());
147
132
  }
148
133
  };
149
134
  /**
@@ -164,40 +149,34 @@ function collectColumns(providers) {
164
149
  }
165
150
  return result;
166
151
  }
167
- /** Create a new snapshot with a different ID, preserving data accessors. */
168
- function remapSnapshot(id, col) {
169
- return createColumnSnapshot(id, col.spec, col.data, col.dataStatus);
170
- }
171
- /** Normalize SDK ColumnSelectorInput to MultiColumnSelector[]. */
152
+ /** Normalize ColumnSelector (relaxed, single or array) to MultiColumnSelector[]. */
172
153
  function toMultiColumnSelectors(input) {
173
154
  return convertColumnSelectorToMultiColumnSelector(input);
174
155
  }
175
156
  /**
176
- * Resolve each anchor value to a PColumnSpec.
177
- * - PColumnSpec: used directly
178
- * - PObjectId (string): looked up in the collected column map
157
+ * Resolve each anchor entry to a ColumnSnapshot from the collected columns.
158
+ * - PObjectId (string): looked up by id in the collected columns
159
+ * - PColumnSpec: matched by deriveNativeId against collected columns
160
+ * - RelaxedColumnSelector: resolved via discoverColumns in "exact" mode;
161
+ * must match exactly one column
162
+ * Throws on unresolved, ambiguous, or duplicated matches. Requires at least one
163
+ * anchor to resolve.
179
164
  */
180
165
  function resolveAnchorMap(anchors, columns, discoverColumns) {
181
166
  const result = /* @__PURE__ */ new Map();
182
167
  const resovedIds = /* @__PURE__ */ new Set();
183
168
  const getDuplicateError = (key) => `Anchor "${key}": selector matched a column that was already matched by another anchor; please refine the selector to match a different column`;
184
- for (const [key, anchor] of Object.entries(anchors)) if (typeof anchor === "string") {
185
- const found = columns.find((col) => col.id === anchor) ?? throwError(`Anchor "${key}": column with id "${anchor}" not found in sources`);
186
- if (resovedIds.has(found.id)) throwError(getDuplicateError(key));
187
- result.set(key, {
188
- columnId: found.id,
189
- spec: found.spec
190
- });
169
+ for (const [name, anchor] of Object.entries(anchors)) if (typeof anchor === "string") {
170
+ const found = columns.find((col) => col.id === anchor) ?? throwError(`Anchor "${name}": column with id "${anchor}" not found in sources`);
171
+ if (resovedIds.has(found.id)) throwError(getDuplicateError(name));
172
+ result.set(name, found);
191
173
  resovedIds.add(found.id);
192
174
  } else if ("kind" in anchor) {
193
- if (!isPColumnSpec(anchor)) throwError(`Anchor "${key}": invalid PColumnSpec`);
175
+ if (!isPColumnSpec(anchor)) throwError(`Anchor "${name}": invalid PColumnSpec`);
194
176
  const nativeId = deriveNativeId(anchor);
195
- const found = columns.find((col) => deriveNativeId(col.spec) === nativeId) ?? throwError(`Anchor "${key}": no column matching spec found in sources`);
196
- if (resovedIds.has(found.id)) throwError(getDuplicateError(key));
197
- result.set(key, {
198
- columnId: found.id,
199
- spec: anchor
200
- });
177
+ const found = columns.find((col) => deriveNativeId(col.spec) === nativeId) ?? throwError(`Anchor "${name}": no column matching spec found in sources`);
178
+ if (resovedIds.has(found.id)) throwError(getDuplicateError(name));
179
+ result.set(name, found);
201
180
  resovedIds.add(found.id);
202
181
  } else {
203
182
  const matched = discoverColumns({
@@ -207,15 +186,23 @@ function resolveAnchorMap(anchors, columns, discoverColumns) {
207
186
  maxHops: 0,
208
187
  constraints: matchingModeToConstraints("exact")
209
188
  });
210
- if (matched.hits.length === 0) throwError(`Anchor "${key}": no columns matched selector`);
211
- if (matched.hits.length > 1) throwError(`Anchor "${key}": selector is ambiguous and matched multiple columns; please refine the selector to match exactly one column`);
212
- if (resovedIds.has(matched.hits[0].hit.columnId)) throwError(getDuplicateError(key));
213
- result.set(key, matched.hits[0].hit);
214
- resovedIds.add(matched.hits[0].hit.columnId);
189
+ if (matched.hits.length === 0) throwError(`Anchor "${name}": no columns matched selector`);
190
+ if (matched.hits.length > 1) throwError(`Anchor "${name}": selector is ambiguous and matched multiple columns; please refine the selector to match exactly one column`);
191
+ if (resovedIds.has(matched.hits[0].hit.columnId)) throwError(getDuplicateError(name));
192
+ const id = matched.hits[0].hit.columnId;
193
+ const snap = columns.find((col) => col.id === id) ?? throwError(`Anchor "${name}": matched column with id "${id}" not found in sources`);
194
+ result.set(name, snap);
195
+ resovedIds.add(snap.id);
215
196
  }
216
197
  if (resovedIds.size === 0) throwError("At least one anchor must be resolved to a valid column");
217
198
  return result;
218
199
  }
200
+ function remapFromIdxToId(qualifications, anchors) {
201
+ return {
202
+ forQueries: qualifications.forQueries.reduce((acc, qs, i) => anchors[i] ? (acc[anchors[i].id] = qs, acc) : acc, {}),
203
+ forHit: qualifications.forHit
204
+ };
205
+ }
219
206
  function matchingModeToConstraints(mode) {
220
207
  switch (mode) {
221
208
  case "enrichment": return {
@@ -1 +1 @@
1
- {"version":3,"file":"column_collection_builder.js","names":[],"sources":["../../src/columns/column_collection_builder.ts"],"sourcesContent":["import type {\n AxisQualification,\n ColumnAxesWithQualifications,\n DiscoverColumnsConstraints,\n DiscoverColumnsRequest,\n DiscoverColumnsResponse,\n MultiColumnSelector,\n NativePObjectId,\n PColumnIdAndSpec,\n PColumnSpec,\n PObjectId,\n SUniversalPColumnId,\n} from \"@milaboratories/pl-model-common\";\nimport {\n AnchoredIdDeriver,\n canonicalizeJson,\n deriveNativeId,\n getAxesId,\n isPColumnSpec,\n} from \"@milaboratories/pl-model-common\";\nimport type { ColumnSelector, RelaxedColumnSelector } from \"./column_selector\";\nimport { convertColumnSelectorToMultiColumnSelector } from \"./column_selector\";\nimport { TreeNodeAccessor } from \"../render/accessor\";\nimport type { ColumnSnapshot } from \"./column_snapshot\";\nimport { createColumnSnapshot } from \"./column_snapshot\";\nimport type { ColumnSnapshotProvider, ColumnSource } from \"./column_snapshot_provider\";\nimport { ArrayColumnProvider, toColumnSnapshotProvider } from \"./column_snapshot_provider\";\n\nimport type { PFrameSpecDriver, PoolEntry, SpecFrameHandle } from \"@milaboratories/pl-model-common\";\nimport { throwError } from \"@milaboratories/helpers\";\nimport { uniqBy } from \"es-toolkit\";\n\n// --- FindColumnsOptions ---\n\n/** Options for plain collection findColumns. */\nexport interface FindColumnsOptions {\n /** Include columns matching these selectors. If omitted, includes all columns. */\n include?: ColumnSelector;\n /** Exclude columns matching these selectors. */\n exclude?: ColumnSelector;\n}\n\n// --- ColumnCollection ---\n\n/** Plain collection — no axis context, selector-based filtering only. */\nexport interface ColumnCollection extends Disposable {\n /** Release the underlying spec frame WASM resource. */\n dispose(): void;\n\n /** Point lookup by provider-native ID. */\n getColumn(id: PObjectId): undefined | ColumnSnapshot<PObjectId>;\n\n /** Find columns matching selectors. Returns flat list of snapshots.\n * No axis compatibility matching, no linker traversal.\n * Never returns undefined — the \"not ready\" state was absorbed by the builder. */\n findColumns(options?: FindColumnsOptions): ColumnSnapshot<PObjectId>[];\n}\n\n// --- AnchoredColumnCollection ---\n\n/** Axis-aware column collection with anchored identity derivation. */\nexport interface AnchoredColumnCollection extends Disposable {\n /** Release the underlying spec frame WASM resource. */\n dispose(): void;\n\n /** List of anchors used for discovery, with their resolved specs. */\n getAnchors(): Map<string, PColumnIdAndSpec>;\n\n /** Point lookup by anchored ID. */\n getColumn(id: SUniversalPColumnId): undefined | ColumnSnapshot<SUniversalPColumnId>;\n\n /** Axis-aware column discovery. */\n findColumns(options?: AnchoredFindColumnsOptions): ColumnMatch[];\n}\n\n/** Controls axis matching behavior for anchored discovery. */\nexport type MatchingMode = \"enrichment\" | \"related\" | \"exact\";\n\n/** Options for anchored collection findColumns. */\nexport interface AnchoredFindColumnsOptions extends FindColumnsOptions {\n /** Controls axis matching behavior. Default: 'enrichment'. */\n mode?: MatchingMode;\n /** Maximum linker hops for cross-domain discovery (0 = direct only, default: 4). */\n maxHops?: number;\n}\n\n/** Result of anchored discovery — column snapshot + routing info. */\nexport interface ColumnMatch {\n /** Column snapshot with anchored SUniversalPColumnId. */\n readonly column: ColumnSnapshot<SUniversalPColumnId>;\n /** Provider-native ID — for lookups back to the source provider. */\n readonly originalId: PObjectId;\n /** Match variants — different paths/qualifications that reach this column. */\n readonly variants: MatchVariant[];\n /** Linker steps traversed to reach this hit; empty for direct matches. */\n readonly path: {\n linker: ColumnSnapshot<SUniversalPColumnId>;\n qualifications: AxisQualification[];\n }[];\n}\n\n/** Qualifications needed for both query (already-integrated) columns and the hit column. */\nexport interface MatchQualifications {\n /** Qualifications for each query (already-integrated) column set. */\n readonly forQueries: AxisQualification[][];\n /** Qualifications for the hit column. */\n readonly forHit: AxisQualification[];\n}\n\n/** A single mapping variant describing how a hit column can be integrated. */\nexport interface MatchVariant {\n /** Full qualifications needed for integration. */\n readonly qualifications: MatchQualifications;\n /** Distinctive (minimal) qualifications needed for integration. */\n readonly distinctiveQualifications: MatchQualifications;\n}\n\n// --- Build options ---\n\nexport interface BuildOptions {\n allowPartialColumnList?: true;\n}\n\nexport type AnchorEntry = PObjectId | PColumnSpec | RelaxedColumnSelector;\n\nexport interface AnchoredBuildOptions extends BuildOptions {\n anchors: Record<string, AnchorEntry>;\n}\n\n// --- ColumnCollectionBuilder ---\n\n/**\n * Mutable builder that accumulates column sources, then produces\n * a ColumnCollection (plain) or AnchoredColumnCollection (with anchors).\n *\n * Each output lambda creates its own builder — a constraint of the\n * computable framework where each output tracks its own dependencies.\n */\nexport class ColumnCollectionBuilder {\n private readonly providers: ColumnSnapshotProvider[] = [];\n\n constructor(private readonly specDriver: PFrameSpecDriver) {}\n\n /**\n * Register a column source. Sources added first take precedence for dedup.\n * Does NOT accept undefined — if a source isn't available yet,\n * the caller should return undefined from the output lambda.\n */\n addSource(source: ColumnSource | TreeNodeAccessor): this {\n if (source instanceof TreeNodeAccessor) {\n const columns = source.getPColumns();\n if (columns) this.providers.push(new ArrayColumnProvider(columns));\n } else {\n this.providers.push(toColumnSnapshotProvider(source));\n }\n return this;\n }\n\n addSources(sources: (ColumnSource | TreeNodeAccessor)[]): this {\n for (const source of sources) {\n this.addSource(source);\n }\n return this;\n }\n\n /** Plain collection — selector-based filtering, PObjectId namespace. */\n build(): undefined | ColumnCollection;\n build(options: {\n allowPartialColumnList: true;\n }): ColumnCollection & { readonly columnListComplete: boolean };\n /** Anchored collection — axis-aware discovery, SUniversalPColumnId namespace. */\n build(\n options: AnchoredBuildOptions & { allowPartialColumnList: true },\n ): AnchoredColumnCollection & { readonly columnListComplete: boolean };\n build(options: AnchoredBuildOptions): undefined | AnchoredColumnCollection;\n build(\n options?: BuildOptions | AnchoredBuildOptions,\n ):\n | undefined\n | ColumnCollection\n | AnchoredColumnCollection\n | (ColumnCollection & { readonly columnListComplete: boolean })\n | (AnchoredColumnCollection & { readonly columnListComplete: boolean }) {\n const allowPartial = options?.allowPartialColumnList === true;\n\n // Check column list completeness\n const allComplete = this.providers.every((p) => p.isColumnListComplete());\n if (!allComplete && !allowPartial) return undefined;\n\n // Collect all columns, dedup by native ID (first source wins)\n const columns = collectColumns(this.providers);\n const hasAnchors = options !== undefined && \"anchors\" in options;\n\n if (hasAnchors) {\n return new AnchoredColumnCollectionImpl(this.specDriver, {\n anchors: options.anchors,\n columns,\n });\n } else {\n return new ColumnCollectionImpl(this.specDriver, {\n columns,\n });\n }\n }\n}\n\n// --- ColumnCollectionImpl ---\n\ninterface ColumnCollectionImplOptions {\n readonly columns: ColumnSnapshot<PObjectId>[];\n}\n\nclass ColumnCollectionImpl implements ColumnCollection, Disposable {\n private readonly columns: Map<PObjectId, ColumnSnapshot<PObjectId>>;\n private readonly specFrameEntry: PoolEntry<SpecFrameHandle>;\n\n constructor(\n private readonly specDriver: PFrameSpecDriver,\n options: ColumnCollectionImplOptions,\n ) {\n this.columns = new Map(options.columns.map((col) => [col.id, col]));\n this.specFrameEntry = this.specDriver.createSpecFrame(\n Object.fromEntries(options.columns.map((col) => [col.id, col.spec])),\n );\n }\n\n dispose(): void {\n this.specFrameEntry.unref();\n }\n\n [Symbol.dispose](): void {\n this.dispose();\n }\n\n getColumn(id: PObjectId): undefined | ColumnSnapshot<PObjectId> {\n const col = this.columns.get(id);\n if (col === undefined) return undefined;\n return this.toSnapshot(col);\n }\n\n findColumns(options?: FindColumnsOptions): ColumnSnapshot<PObjectId>[] {\n const includeColumns = options?.include ? toMultiColumnSelectors(options.include) : undefined;\n const excludeColumns = options?.exclude ? toMultiColumnSelectors(options.exclude) : undefined;\n\n const response = this.specDriver.discoverColumns(this.specFrameEntry.key, {\n includeColumns,\n excludeColumns,\n axes: [],\n maxHops: 0,\n constraints: matchingModeToConstraints(\"enrichment\"),\n });\n\n // Map hits back to snapshots\n const results = response.hits\n .map((hit) => this.columns.get(hit.hit.columnId as PObjectId))\n .filter((col): col is ColumnSnapshot<PObjectId> => col !== undefined)\n .map((col) => this.toSnapshot(col));\n\n return results;\n }\n\n private toSnapshot(col: ColumnSnapshot<PObjectId>): ColumnSnapshot<PObjectId> {\n return remapSnapshot(col.id, col);\n }\n}\n\n// --- AnchoredColumnCollectionImpl ---\n\ninterface AnchoredColumnCollectionImplOptions extends ColumnCollectionImplOptions {\n readonly anchors: Record<string, AnchorEntry>;\n}\n\nclass AnchoredColumnCollectionImpl implements AnchoredColumnCollection, Disposable {\n private readonly anchorsMap: Map<string, PColumnIdAndSpec>;\n private readonly columnsMap: Map<PObjectId, ColumnSnapshot<PObjectId>>;\n\n private readonly idDeriver: AnchoredIdDeriver;\n private readonly uniqAnchorAxes: ColumnAxesWithQualifications[];\n private readonly idToOriginalIdMap: Map<SUniversalPColumnId, PObjectId>;\n private readonly specFrameEntry: PoolEntry<SpecFrameHandle>;\n\n constructor(\n private readonly specDriver: PFrameSpecDriver,\n options: AnchoredColumnCollectionImplOptions,\n ) {\n // Create spec frame from all collected columns\n this.specFrameEntry = this.specDriver.createSpecFrame(\n Object.fromEntries(options.columns.map((col) => [col.id, col.spec])),\n );\n this.columnsMap = new Map(options.columns.map((col) => [col.id, col]));\n this.anchorsMap = resolveAnchorMap(\n options.anchors,\n options.columns,\n this.specDriver.discoverColumns.bind(this.specDriver, this.specFrameEntry.key),\n );\n this.idDeriver = new AnchoredIdDeriver(\n Object.fromEntries(\n Array.from(this.anchorsMap.entries()).map(([k, v]) => [k, v.spec] as const),\n ),\n );\n this.uniqAnchorAxes = uniqBy(\n Array.from(this.anchorsMap.values(), ({ spec }) => ({\n axesSpec: spec.axesSpec,\n qualifications: [],\n })),\n (axis) => canonicalizeJson(getAxesId(axis.axesSpec)) + canonicalizeJson(axis.qualifications),\n );\n this.idToOriginalIdMap = new Map(\n options.columns.map((col) => [this.idDeriver.deriveS(col.spec), col.id] as const),\n );\n }\n\n dispose(): void {\n this.specFrameEntry.unref();\n }\n\n [Symbol.dispose](): void {\n this.dispose();\n }\n\n getAnchors(): Map<string, PColumnIdAndSpec> {\n return this.anchorsMap;\n }\n\n getColumn(id: SUniversalPColumnId): undefined | ColumnSnapshot<SUniversalPColumnId> {\n const origId = this.idToOriginalIdMap.get(id);\n if (origId === undefined) return undefined;\n const col = this.columnsMap.get(origId);\n if (col === undefined) return undefined;\n return remapSnapshot(id, col);\n }\n\n findColumns(options?: AnchoredFindColumnsOptions): ColumnMatch[] {\n const mode = options?.mode ?? \"enrichment\";\n const constraints = matchingModeToConstraints(mode);\n const includeColumns = options?.include ? toMultiColumnSelectors(options.include) : undefined;\n const excludeColumns = options?.exclude ? toMultiColumnSelectors(options.exclude) : undefined;\n\n const response = this.specDriver.discoverColumns(this.specFrameEntry.key, {\n includeColumns,\n excludeColumns,\n constraints,\n maxHops: options?.maxHops ?? 4,\n axes: this.uniqAnchorAxes,\n });\n\n // Map every WASM discovery hit to a ColumnMatch.\n // The same physical column may appear multiple times when reachable through\n // different linker paths — each hit becomes a separate ColumnMatch so that\n // the caller can expand them into distinct table columns.\n const results: ColumnMatch[] = [];\n for (const hit of response.hits) {\n const origId = hit.hit.columnId as PObjectId;\n const col =\n this.columnsMap.get(origId) ??\n throwError(`Column with id ${origId} not found in collection`);\n const associatedId = this.idDeriver.deriveS(col.spec);\n\n results.push({\n path: hit.path.map((step) => {\n if (step.type !== \"linker\")\n throw new Error(`Unexpected discover-columns step type: ${step.type}`);\n return {\n linker: remapSnapshot(\n this.idDeriver.deriveS(step.linker.spec),\n this.columnsMap.get(step.linker.columnId) ??\n throwError(`Linker column with id ${step.linker.columnId} not found in collection`),\n ),\n qualifications: step.qualifications,\n };\n }),\n column: remapSnapshot(associatedId, col),\n variants: hit.mappingVariants,\n originalId: origId,\n });\n }\n\n return results;\n }\n}\n\n/**\n * Collect all columns from all providers, dedup by NativePObjectId.\n * First source wins.\n */\nfunction collectColumns(providers: ColumnSnapshotProvider[]): ColumnSnapshot<PObjectId>[] {\n const seen = new Set<NativePObjectId>();\n const result: ColumnSnapshot<PObjectId>[] = [];\n\n for (const provider of providers) {\n const columns = provider.getAllColumns();\n for (const col of columns) {\n const nativeId = deriveNativeId(col.spec);\n if (seen.has(nativeId)) continue;\n seen.add(nativeId);\n result.push(col);\n }\n }\n\n return result;\n}\n\n// --- Shared snapshot helpers ---\n\n/** Create a new snapshot with a different ID, preserving data accessors. */\nfunction remapSnapshot<Id extends PObjectId>(\n id: Id,\n col: ColumnSnapshot<PObjectId>,\n): ColumnSnapshot<Id> {\n return createColumnSnapshot(id, col.spec, col.data, col.dataStatus);\n}\n\n/** Normalize SDK ColumnSelectorInput to MultiColumnSelector[]. */\nfunction toMultiColumnSelectors(input: ColumnSelector): MultiColumnSelector[] {\n return convertColumnSelectorToMultiColumnSelector(input);\n}\n\n// --- Anchor resolution ---\n\n/**\n * Resolve each anchor value to a PColumnSpec.\n * - PColumnSpec: used directly\n * - PObjectId (string): looked up in the collected column map\n */\nfunction resolveAnchorMap(\n anchors: Record<string, AnchorEntry>,\n columns: ColumnSnapshot<PObjectId>[],\n discoverColumns: (request: DiscoverColumnsRequest) => DiscoverColumnsResponse,\n): Map<string, PColumnIdAndSpec> {\n const result = new Map<string, PColumnIdAndSpec>();\n const resovedIds = new Set<PObjectId>();\n const getDuplicateError = (key: string) =>\n `Anchor \"${key}\": selector matched a column that was already matched by another anchor; please refine the selector to match a different column`;\n\n for (const [key, anchor] of Object.entries(anchors)) {\n if (typeof anchor === \"string\") {\n const found =\n columns.find((col) => col.id === anchor) ??\n throwError(`Anchor \"${key}\": column with id \"${anchor}\" not found in sources`);\n if (resovedIds.has(found.id)) {\n throwError(getDuplicateError(key));\n }\n result.set(key, { columnId: found.id, spec: found.spec });\n resovedIds.add(found.id);\n } else if (\"kind\" in anchor) {\n if (!isPColumnSpec(anchor)) throwError(`Anchor \"${key}\": invalid PColumnSpec`);\n const nativeId = deriveNativeId(anchor);\n const found =\n columns.find((col) => deriveNativeId(col.spec) === nativeId) ??\n throwError(`Anchor \"${key}\": no column matching spec found in sources`);\n if (resovedIds.has(found.id)) {\n throwError(getDuplicateError(key));\n }\n result.set(key, { columnId: found.id, spec: anchor });\n resovedIds.add(found.id);\n } else {\n const matched = discoverColumns({\n includeColumns: toMultiColumnSelectors(anchor),\n excludeColumns: undefined,\n axes: [],\n maxHops: 0,\n constraints: matchingModeToConstraints(\"exact\"),\n });\n if (matched.hits.length === 0) {\n throwError(`Anchor \"${key}\": no columns matched selector`);\n }\n if (matched.hits.length > 1) {\n throwError(\n `Anchor \"${key}\": selector is ambiguous and matched multiple columns; please refine the selector to match exactly one column`,\n );\n }\n if (resovedIds.has(matched.hits[0].hit.columnId as PObjectId)) {\n throwError(getDuplicateError(key));\n }\n\n result.set(key, matched.hits[0].hit);\n resovedIds.add(matched.hits[0].hit.columnId);\n }\n }\n\n if (resovedIds.size === 0) {\n throwError(\"At least one anchor must be resolved to a valid column\");\n }\n\n return result;\n}\n\n// --- MatchingMode → DiscoverColumnsConstraints ---\n\nfunction matchingModeToConstraints(mode: MatchingMode): DiscoverColumnsConstraints {\n switch (mode) {\n case \"enrichment\":\n return {\n allowFloatingSourceAxes: true,\n allowFloatingHitAxes: false,\n allowSourceQualifications: true,\n allowHitQualifications: true,\n };\n case \"related\":\n return {\n allowFloatingSourceAxes: true,\n allowFloatingHitAxes: true,\n allowSourceQualifications: true,\n allowHitQualifications: true,\n };\n case \"exact\":\n return {\n allowFloatingSourceAxes: false,\n allowFloatingHitAxes: false,\n allowSourceQualifications: false,\n allowHitQualifications: false,\n };\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"column_collection_builder.js","names":[],"sources":["../../src/columns/column_collection_builder.ts"],"sourcesContent":["import type {\n AxisQualification,\n DiscoverColumnsConstraints,\n DiscoverColumnsRequest,\n DiscoverColumnsResponse,\n MultiColumnSelector,\n NativePObjectId,\n PColumnSpec,\n PObjectId,\n} from \"@milaboratories/pl-model-common\";\nimport { deriveNativeId, isPColumnSpec } from \"@milaboratories/pl-model-common\";\nimport type { ColumnSelector, RelaxedColumnSelector } from \"./column_selector\";\nimport { convertColumnSelectorToMultiColumnSelector } from \"./column_selector\";\nimport { TreeNodeAccessor } from \"../render/accessor\";\nimport type { ColumnSnapshot } from \"./column_snapshot\";\nimport type { ColumnSnapshotProvider, ColumnSource } from \"./column_snapshot_provider\";\nimport { ArrayColumnProvider, toColumnSnapshotProvider } from \"./column_snapshot_provider\";\n\nimport type { PFrameSpecDriver, PoolEntry, SpecFrameHandle } from \"@milaboratories/pl-model-common\";\nimport { throwError } from \"@milaboratories/helpers\";\nimport { getService } from \"../services\";\n\n// --- FindColumnsOptions ---\n\n/** Options for plain collection findColumns. */\nexport interface FindColumnsOptions {\n /** Include columns matching these selectors. If omitted, includes all columns. */\n include?: ColumnSelector;\n /** Exclude columns matching these selectors. */\n exclude?: ColumnSelector;\n}\n\n// --- ColumnCollection ---\n\n/** Plain collection — no axis context, selector-based filtering only. */\nexport interface ColumnCollection extends Disposable {\n /** Release the underlying spec frame WASM resource. */\n dispose(): void;\n\n /** Find columns matching selectors. Returns flat list of snapshots.\n * No axis compatibility matching, no linker traversal.\n * Never returns undefined — the \"not ready\" state was absorbed by the builder. */\n findColumns(options?: FindColumnsOptions): ColumnSnapshot<PObjectId>[];\n}\n\n// --- AnchoredColumnCollection ---\n\n/** Axis-aware column collection with anchored identity derivation. */\nexport interface AnchoredColumnCollection extends Disposable {\n /** Release the underlying spec frame WASM resource. */\n dispose(): void;\n\n /** List of anchors used for discovery, with their resolved specs. */\n getAnchors(): Map<string, ColumnSnapshot<PObjectId>>;\n\n /** Axis-aware column discovery. */\n findColumns(options?: AnchoredFindColumnsOptions): ColumnMatch[];\n}\n\n/** Controls axis matching behavior for anchored discovery. */\nexport type MatchingMode = \"enrichment\" | \"related\" | \"exact\";\n\n/** Options for anchored collection findColumns. */\nexport interface AnchoredFindColumnsOptions extends FindColumnsOptions {\n /** Controls axis matching behavior. Default: 'enrichment'. */\n mode?: MatchingMode;\n /** Maximum linker hops for cross-domain discovery (0 = direct only, default: 4). */\n maxHops?: number;\n}\n\n/** Result of anchored discovery — column snapshot + routing info. */\nexport interface ColumnMatch {\n /** Column snapshot with anchored SUniversalPColumnId. */\n readonly column: ColumnSnapshot<PObjectId>;\n /** Match variants — different ways (paths/qualifications) to reach this column. */\n readonly variants: MatchVariant[];\n}\n\n/** A single mapping variant describing how a hit column can be integrated. */\nexport interface MatchVariant {\n /** Full qualifications needed for integration. */\n readonly qualifications: MatchQualifications;\n /** Distinctive (minimal) qualifications needed for integration. */\n readonly distinctiveQualifications: MatchQualifications;\n /** Linker steps traversed to reach this hit; empty for direct matches. */\n readonly path: {\n linker: ColumnSnapshot<PObjectId>;\n qualifications: AxisQualification[];\n }[];\n}\n\n/** Qualifications needed for both already-integrated anchor columns and the hit column. */\nexport interface MatchQualifications {\n /** Qualifications for already-integrated anchor columns */\n readonly forQueries: Record<PObjectId, AxisQualification[]>;\n /** Qualifications for the hit column. */\n readonly forHit: AxisQualification[];\n}\n\n// --- Build options ---\n\nexport interface BuildOptions {\n allowPartialColumnList?: true;\n}\n\nexport type AnchorEntry = PObjectId | PColumnSpec | RelaxedColumnSelector;\n\nexport interface AnchoredBuildOptions extends BuildOptions {\n anchors: Record<string, AnchorEntry>;\n}\n\n// --- ColumnCollectionBuilder ---\n\n/**\n * Mutable builder that accumulates column sources, then produces\n * a ColumnCollection (plain) or AnchoredColumnCollection (with anchors).\n *\n * Each output lambda creates its own builder — a constraint of the\n * computable framework where each output tracks its own dependencies.\n */\nexport class ColumnCollectionBuilder {\n private readonly providers: ColumnSnapshotProvider[] = [];\n\n constructor(private readonly specDriver: PFrameSpecDriver = getService(\"pframeSpec\")) {}\n\n /**\n * Register a column source. Sources added first take precedence for dedup.\n * Does NOT accept undefined — if a source isn't available yet,\n * the caller should return undefined from the output lambda.\n */\n addSource(source: ColumnSource | TreeNodeAccessor): this {\n if (source instanceof TreeNodeAccessor) {\n const columns = source.getPColumns();\n if (columns) this.providers.push(new ArrayColumnProvider(columns));\n } else {\n this.providers.push(toColumnSnapshotProvider(source));\n }\n return this;\n }\n\n addSources(sources: (ColumnSource | TreeNodeAccessor)[]): this {\n for (const source of sources) {\n this.addSource(source);\n }\n return this;\n }\n\n /** Plain collection — selector-based filtering, PObjectId namespace. */\n build(): undefined | ColumnCollection;\n build(options: {\n allowPartialColumnList: true;\n }): ColumnCollection & { readonly columnListComplete: boolean };\n /** Anchored collection — axis-aware discovery, SUniversalPColumnId namespace. */\n build(\n options: AnchoredBuildOptions & { allowPartialColumnList: true },\n ): AnchoredColumnCollection & { readonly columnListComplete: boolean };\n build(options: AnchoredBuildOptions): undefined | AnchoredColumnCollection;\n build(\n options?: BuildOptions | AnchoredBuildOptions,\n ):\n | undefined\n | ColumnCollection\n | AnchoredColumnCollection\n | (ColumnCollection & { readonly columnListComplete: boolean })\n | (AnchoredColumnCollection & { readonly columnListComplete: boolean }) {\n const allowPartial = options?.allowPartialColumnList === true;\n\n // Check column list completeness\n const allComplete = this.providers.every((p) => p.isColumnListComplete());\n if (!allComplete && !allowPartial) return undefined;\n\n // Collect all columns, dedup by native ID (first source wins)\n const columns = collectColumns(this.providers);\n const hasAnchors = options !== undefined && \"anchors\" in options;\n\n if (hasAnchors) {\n return new AnchoredColumnCollectionImpl(this.specDriver, {\n anchors: options.anchors,\n columns,\n });\n } else {\n return new ColumnCollectionImpl(this.specDriver, {\n columns,\n });\n }\n }\n}\n\n// --- ColumnCollectionImpl ---\n\ninterface ColumnCollectionImplOptions {\n readonly columns: ColumnSnapshot<PObjectId>[];\n}\n\nclass ColumnCollectionImpl implements ColumnCollection, Disposable {\n private readonly columns: Map<PObjectId, ColumnSnapshot<PObjectId>>;\n private readonly specFrameEntry: PoolEntry<SpecFrameHandle>;\n\n constructor(\n private readonly specDriver: PFrameSpecDriver,\n options: ColumnCollectionImplOptions,\n ) {\n this.columns = new Map(options.columns.map((col) => [col.id, col]));\n this.specFrameEntry = this.specDriver.createSpecFrame(\n Object.fromEntries(options.columns.map((col) => [col.id, col.spec])),\n );\n }\n\n dispose(): void {\n this.specFrameEntry.unref();\n }\n\n [Symbol.dispose](): void {\n this.dispose();\n }\n\n findColumns(options?: FindColumnsOptions): ColumnSnapshot<PObjectId>[] {\n const includeColumns = options?.include ? toMultiColumnSelectors(options.include) : undefined;\n const excludeColumns = options?.exclude ? toMultiColumnSelectors(options.exclude) : undefined;\n\n const response = this.specDriver.discoverColumns(this.specFrameEntry.key, {\n includeColumns,\n excludeColumns,\n axes: [],\n maxHops: 0,\n constraints: matchingModeToConstraints(\"enrichment\"),\n });\n\n // Map hits back to snapshots\n const results = response.hits\n .map((hit) => this.columns.get(hit.hit.columnId as PObjectId))\n .filter((col): col is ColumnSnapshot<PObjectId> => col !== undefined);\n\n return results;\n }\n}\n\n// --- AnchoredColumnCollectionImpl ---\n\ninterface AnchoredColumnCollectionImplOptions extends ColumnCollectionImplOptions {\n readonly anchors: Record<string, AnchorEntry>;\n}\n\nclass AnchoredColumnCollectionImpl implements AnchoredColumnCollection, Disposable {\n private readonly anchorsMap: Map<string, ColumnSnapshot<PObjectId>>;\n private readonly columnsMap: Map<PObjectId, ColumnSnapshot<PObjectId>>;\n private readonly specFrameEntry: PoolEntry<SpecFrameHandle>;\n\n constructor(\n private readonly specDriver: PFrameSpecDriver,\n options: AnchoredColumnCollectionImplOptions,\n ) {\n // Create spec frame from all collected columns\n this.specFrameEntry = this.specDriver.createSpecFrame(\n Object.fromEntries(options.columns.map((col) => [col.id, col.spec])),\n );\n this.columnsMap = new Map(options.columns.map((col) => [col.id, col]));\n this.anchorsMap = resolveAnchorMap(\n options.anchors,\n options.columns,\n this.specDriver.discoverColumns.bind(this.specDriver, this.specFrameEntry.key),\n );\n }\n\n dispose(): void {\n this.specFrameEntry.unref();\n }\n\n [Symbol.dispose](): void {\n this.dispose();\n }\n\n getAnchors(): Map<string, ColumnSnapshot<PObjectId>> {\n return this.anchorsMap;\n }\n\n findColumns(options?: AnchoredFindColumnsOptions): ColumnMatch[] {\n const mode = options?.mode ?? \"enrichment\";\n const constraints = matchingModeToConstraints(mode);\n const includeColumns = options?.include ? toMultiColumnSelectors(options.include) : undefined;\n const excludeColumns = options?.exclude ? toMultiColumnSelectors(options.exclude) : undefined;\n const anchors = Array.from(this.anchorsMap.values());\n const response = this.specDriver.discoverColumns(this.specFrameEntry.key, {\n includeColumns,\n excludeColumns,\n constraints,\n maxHops: options?.maxHops ?? 4,\n axes: anchors.map((anchor) => ({\n axesSpec: anchor.spec.axesSpec,\n qualifications: [],\n })),\n });\n\n const byColumn = response.hits.reduce<Map<PObjectId, ColumnMatch>>((acc, hit) => {\n const origId = hit.hit.columnId as PObjectId;\n const col =\n this.columnsMap.get(origId) ??\n throwError(`Column with id ${origId} not found in collection`);\n\n const path = hit.path.map((step) => {\n if (step.type !== \"linker\") {\n throw new Error(`Unexpected discover-columns step type: ${step.type}`);\n }\n\n return {\n linker:\n this.columnsMap.get(step.linker.columnId) ??\n throwError(`Linker column with id ${step.linker.columnId} not found in collection`),\n qualifications: step.qualifications,\n };\n });\n const variants: MatchVariant[] = hit.mappingVariants.map((v) => ({\n path,\n qualifications: remapFromIdxToId(v.qualifications, anchors),\n distinctiveQualifications: remapFromIdxToId(v.distinctiveQualifications, anchors),\n }));\n const existing = acc.get(origId);\n return acc.set(\n origId,\n existing === undefined\n ? { column: col, variants }\n : { ...existing, variants: [...existing.variants, ...variants] },\n );\n }, new Map());\n\n return Array.from(byColumn.values());\n }\n}\n\n/**\n * Collect all columns from all providers, dedup by NativePObjectId.\n * First source wins.\n */\nfunction collectColumns(providers: ColumnSnapshotProvider[]): ColumnSnapshot<PObjectId>[] {\n const seen = new Set<NativePObjectId>();\n const result: ColumnSnapshot<PObjectId>[] = [];\n\n for (const provider of providers) {\n const columns = provider.getAllColumns();\n for (const col of columns) {\n const nativeId = deriveNativeId(col.spec);\n if (seen.has(nativeId)) continue;\n seen.add(nativeId);\n result.push(col);\n }\n }\n\n return result;\n}\n\n// --- Shared snapshot helpers ---\n\n/** Normalize ColumnSelector (relaxed, single or array) to MultiColumnSelector[]. */\nfunction toMultiColumnSelectors(input: ColumnSelector): MultiColumnSelector[] {\n return convertColumnSelectorToMultiColumnSelector(input);\n}\n\n// --- Anchor resolution ---\n\n/**\n * Resolve each anchor entry to a ColumnSnapshot from the collected columns.\n * - PObjectId (string): looked up by id in the collected columns\n * - PColumnSpec: matched by deriveNativeId against collected columns\n * - RelaxedColumnSelector: resolved via discoverColumns in \"exact\" mode;\n * must match exactly one column\n * Throws on unresolved, ambiguous, or duplicated matches. Requires at least one\n * anchor to resolve.\n */\nfunction resolveAnchorMap(\n anchors: Record<string, AnchorEntry>,\n columns: ColumnSnapshot<PObjectId>[],\n discoverColumns: (request: DiscoverColumnsRequest) => DiscoverColumnsResponse,\n): Map<string, ColumnSnapshot<PObjectId>> {\n const result = new Map<string, ColumnSnapshot<PObjectId>>();\n const resovedIds = new Set<PObjectId>();\n const getDuplicateError = (key: string) =>\n `Anchor \"${key}\": selector matched a column that was already matched by another anchor; please refine the selector to match a different column`;\n\n for (const [name, anchor] of Object.entries(anchors)) {\n if (typeof anchor === \"string\") {\n const found =\n columns.find((col) => col.id === anchor) ??\n throwError(`Anchor \"${name}\": column with id \"${anchor}\" not found in sources`);\n if (resovedIds.has(found.id)) {\n throwError(getDuplicateError(name));\n }\n result.set(name, found);\n resovedIds.add(found.id);\n } else if (\"kind\" in anchor) {\n if (!isPColumnSpec(anchor)) throwError(`Anchor \"${name}\": invalid PColumnSpec`);\n const nativeId = deriveNativeId(anchor);\n const found =\n columns.find((col) => deriveNativeId(col.spec) === nativeId) ??\n throwError(`Anchor \"${name}\": no column matching spec found in sources`);\n if (resovedIds.has(found.id)) {\n throwError(getDuplicateError(name));\n }\n result.set(name, found);\n resovedIds.add(found.id);\n } else {\n const matched = discoverColumns({\n includeColumns: toMultiColumnSelectors(anchor),\n excludeColumns: undefined,\n axes: [],\n maxHops: 0,\n constraints: matchingModeToConstraints(\"exact\"),\n });\n\n if (matched.hits.length === 0) {\n throwError(`Anchor \"${name}\": no columns matched selector`);\n }\n if (matched.hits.length > 1) {\n throwError(\n `Anchor \"${name}\": selector is ambiguous and matched multiple columns; please refine the selector to match exactly one column`,\n );\n }\n if (resovedIds.has(matched.hits[0].hit.columnId as PObjectId)) {\n throwError(getDuplicateError(name));\n }\n\n const id = matched.hits[0].hit.columnId as PObjectId;\n const snap =\n columns.find((col) => col.id === id) ??\n throwError(`Anchor \"${name}\": matched column with id \"${id}\" not found in sources`);\n result.set(name, snap);\n resovedIds.add(snap.id);\n }\n }\n\n if (resovedIds.size === 0) {\n throwError(\"At least one anchor must be resolved to a valid column\");\n }\n\n return result;\n}\n\nfunction remapFromIdxToId(\n qualifications: {\n forQueries: AxisQualification[][];\n forHit: AxisQualification[];\n },\n anchors: ColumnSnapshot<PObjectId>[],\n): MatchQualifications {\n const forQueries = qualifications.forQueries.reduce<Record<PObjectId, AxisQualification[]>>(\n (acc, qs, i) => (anchors[i] ? ((acc[anchors[i].id] = qs), acc) : acc),\n {},\n );\n return { forQueries, forHit: qualifications.forHit };\n}\n\n// --- MatchingMode → DiscoverColumnsConstraints ---\n\nfunction matchingModeToConstraints(mode: MatchingMode): DiscoverColumnsConstraints {\n switch (mode) {\n case \"enrichment\":\n return {\n allowFloatingSourceAxes: true,\n allowFloatingHitAxes: false,\n allowSourceQualifications: true,\n allowHitQualifications: true,\n };\n case \"related\":\n return {\n allowFloatingSourceAxes: true,\n allowFloatingHitAxes: true,\n allowSourceQualifications: true,\n allowHitQualifications: true,\n };\n case \"exact\":\n return {\n allowFloatingSourceAxes: false,\n allowFloatingHitAxes: false,\n allowSourceQualifications: false,\n allowHitQualifications: false,\n };\n }\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"column_selector.cjs","names":[],"sources":["../../src/columns/column_selector.ts"],"sourcesContent":["import type {\n AxisValueType,\n ColumnValueType,\n MultiAxisSelector,\n MultiColumnSelector,\n StringMatcher,\n} from \"@milaboratories/pl-model-common\";\n\nexport type { StringMatcher } from \"@milaboratories/pl-model-common\";\n\n// --- Relaxed types ---\n\n/** Relaxed string matcher input: plain string, single matcher, or array of mixed. */\nexport type RelaxedStringMatchers = string | StringMatcher | (string | StringMatcher)[];\n\n/** Relaxed record matcher: values can be plain strings or relaxed matchers. */\nexport type RelaxedRecord = Record<string, RelaxedStringMatchers>;\n\n/** Relaxed axis selector — accepts plain strings where strict requires StringMatcher[]. */\nexport interface RelaxedAxisSelector {\n name?: RelaxedStringMatchers;\n type?: AxisValueType | AxisValueType[];\n domain?: RelaxedRecord;\n contextDomain?: RelaxedRecord;\n annotations?: RelaxedRecord;\n}\n\n/** Relaxed column selector — convenient hand-written form. */\nexport interface RelaxedColumnSelector {\n name?: RelaxedStringMatchers;\n type?: ColumnValueType | ColumnValueType[];\n domain?: RelaxedRecord;\n contextDomain?: RelaxedRecord;\n annotations?: RelaxedRecord;\n axes?: RelaxedAxisSelector[];\n partialAxesMatch?: boolean;\n}\n\n/** Input that normalizes to ColumnSelector[]. */\nexport type ColumnSelector = RelaxedColumnSelector | RelaxedColumnSelector[];\n\n// --- Normalization ---\n\nfunction normalizeStringMatchers(input: RelaxedStringMatchers): StringMatcher[] {\n if (typeof input === \"string\") return [{ type: \"regex\", value: input }];\n if (!Array.isArray(input)) return [input];\n return input.map((v) =>\n typeof v === \"string\" ? ({ type: \"regex\", value: v } satisfies StringMatcher) : v,\n );\n}\n\nfunction normalizeRecord(input: RelaxedRecord): Record<string, StringMatcher[]> {\n const result: Record<string, StringMatcher[]> = {};\n for (const [key, value] of Object.entries(input)) {\n result[key] = normalizeStringMatchers(value);\n }\n return result;\n}\n\nfunction normalizeTypes<T>(input: T | T[]): T[] {\n return Array.isArray(input) ? input : [input];\n}\n\ntype Mutable<T> = { -readonly [K in keyof T]: T[K] };\n\nexport function convertRelaxedAxisSelectorToMultiAxisSelector(\n input: RelaxedAxisSelector,\n): MultiAxisSelector {\n const result: Mutable<MultiAxisSelector> = {};\n if (input.name !== undefined) result.name = normalizeStringMatchers(input.name);\n if (input.type !== undefined) result.type = normalizeTypes(input.type);\n if (input.domain !== undefined) result.domain = normalizeRecord(input.domain);\n if (input.contextDomain !== undefined)\n result.contextDomain = normalizeRecord(input.contextDomain);\n if (input.annotations !== undefined) result.annotations = normalizeRecord(input.annotations);\n return result;\n}\n\nexport function convertRelaxedColumnSelectorToMultiColumnSelector(\n input: RelaxedColumnSelector,\n): MultiColumnSelector {\n const result: Mutable<MultiColumnSelector> = {};\n if (input.name !== undefined) result.name = normalizeStringMatchers(input.name);\n if (input.type !== undefined) result.type = normalizeTypes(input.type);\n if (input.domain !== undefined) result.domain = normalizeRecord(input.domain);\n if (input.contextDomain !== undefined)\n result.contextDomain = normalizeRecord(input.contextDomain);\n if (input.annotations !== undefined) result.annotations = normalizeRecord(input.annotations);\n if (input.axes !== undefined)\n result.axes = input.axes.map(convertRelaxedAxisSelectorToMultiAxisSelector);\n if (input.partialAxesMatch !== undefined) result.partialAxesMatch = input.partialAxesMatch;\n return result;\n}\n\nexport function convertColumnSelectorToMultiColumnSelector(\n input: ColumnSelector,\n): MultiColumnSelector[] {\n const arr = Array.isArray(input) ? input : [input];\n return arr.map(convertRelaxedColumnSelectorToMultiColumnSelector);\n}\n"],"mappings":";AA2CA,SAAS,wBAAwB,OAA+C;AAC9E,KAAI,OAAO,UAAU,SAAU,QAAO,CAAC;EAAE,MAAM;EAAS,OAAO;EAAO,CAAC;AACvE,KAAI,CAAC,MAAM,QAAQ,MAAM,CAAE,QAAO,CAAC,MAAM;AACzC,QAAO,MAAM,KAAK,MAChB,OAAO,MAAM,WAAY;EAAE,MAAM;EAAS,OAAO;EAAG,GAA4B,EACjF;;AAGH,SAAS,gBAAgB,OAAuD;CAC9E,MAAM,SAA0C,EAAE;AAClD,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,MAAM,CAC9C,QAAO,OAAO,wBAAwB,MAAM;AAE9C,QAAO;;AAGT,SAAS,eAAkB,OAAqB;AAC9C,QAAO,MAAM,QAAQ,MAAM,GAAG,QAAQ,CAAC,MAAM;;AAK/C,SAAgB,8CACd,OACmB;CACnB,MAAM,SAAqC,EAAE;AAC7C,KAAI,MAAM,SAAS,KAAA,EAAW,QAAO,OAAO,wBAAwB,MAAM,KAAK;AAC/E,KAAI,MAAM,SAAS,KAAA,EAAW,QAAO,OAAO,eAAe,MAAM,KAAK;AACtE,KAAI,MAAM,WAAW,KAAA,EAAW,QAAO,SAAS,gBAAgB,MAAM,OAAO;AAC7E,KAAI,MAAM,kBAAkB,KAAA,EAC1B,QAAO,gBAAgB,gBAAgB,MAAM,cAAc;AAC7D,KAAI,MAAM,gBAAgB,KAAA,EAAW,QAAO,cAAc,gBAAgB,MAAM,YAAY;AAC5F,QAAO;;AAGT,SAAgB,kDACd,OACqB;CACrB,MAAM,SAAuC,EAAE;AAC/C,KAAI,MAAM,SAAS,KAAA,EAAW,QAAO,OAAO,wBAAwB,MAAM,KAAK;AAC/E,KAAI,MAAM,SAAS,KAAA,EAAW,QAAO,OAAO,eAAe,MAAM,KAAK;AACtE,KAAI,MAAM,WAAW,KAAA,EAAW,QAAO,SAAS,gBAAgB,MAAM,OAAO;AAC7E,KAAI,MAAM,kBAAkB,KAAA,EAC1B,QAAO,gBAAgB,gBAAgB,MAAM,cAAc;AAC7D,KAAI,MAAM,gBAAgB,KAAA,EAAW,QAAO,cAAc,gBAAgB,MAAM,YAAY;AAC5F,KAAI,MAAM,SAAS,KAAA,EACjB,QAAO,OAAO,MAAM,KAAK,IAAI,8CAA8C;AAC7E,KAAI,MAAM,qBAAqB,KAAA,EAAW,QAAO,mBAAmB,MAAM;AAC1E,QAAO;;AAGT,SAAgB,2CACd,OACuB;AAEvB,SADY,MAAM,QAAQ,MAAM,GAAG,QAAQ,CAAC,MAAM,EACvC,IAAI,kDAAkD"}
1
+ {"version":3,"file":"column_selector.cjs","names":[],"sources":["../../src/columns/column_selector.ts"],"sourcesContent":["import type {\n AxisValueType,\n ColumnValueType,\n MultiAxisSelector,\n MultiColumnSelector,\n StringMatcher,\n} from \"@milaboratories/pl-model-common\";\n\nexport type { StringMatcher } from \"@milaboratories/pl-model-common\";\n\n// --- Relaxed types ---\n\n/** Relaxed string matcher input: plain string, single matcher, or array of mixed. */\nexport type RelaxedStringMatchers = string | StringMatcher | (string | StringMatcher)[];\n\n/** Relaxed record matcher: values can be plain strings or relaxed matchers. */\nexport type RelaxedRecord = Record<string, RelaxedStringMatchers>;\n\n/** Relaxed axis selector — accepts plain strings where strict requires StringMatcher[]. */\nexport interface RelaxedAxisSelector {\n name?: RelaxedStringMatchers;\n type?: AxisValueType | AxisValueType[];\n domain?: RelaxedRecord;\n contextDomain?: RelaxedRecord;\n annotations?: RelaxedRecord;\n}\n\n/** Relaxed column selector — convenient hand-written form. */\nexport interface RelaxedColumnSelector {\n name?: RelaxedStringMatchers;\n type?: ColumnValueType | ColumnValueType[];\n domain?: RelaxedRecord;\n contextDomain?: RelaxedRecord;\n annotations?: RelaxedRecord;\n axes?: RelaxedAxisSelector[];\n partialAxesMatch?: boolean;\n}\n\n/** One or many relaxed column selectors; normalizes to MultiColumnSelector[]. */\nexport type ColumnSelector = RelaxedColumnSelector | RelaxedColumnSelector[];\n\n// --- Normalization ---\n\nfunction normalizeStringMatchers(input: RelaxedStringMatchers): StringMatcher[] {\n if (typeof input === \"string\") return [{ type: \"regex\", value: input }];\n if (!Array.isArray(input)) return [input];\n return input.map((v) =>\n typeof v === \"string\" ? ({ type: \"regex\", value: v } satisfies StringMatcher) : v,\n );\n}\n\nfunction normalizeRecord(input: RelaxedRecord): Record<string, StringMatcher[]> {\n const result: Record<string, StringMatcher[]> = {};\n for (const [key, value] of Object.entries(input)) {\n result[key] = normalizeStringMatchers(value);\n }\n return result;\n}\n\nfunction normalizeTypes<T>(input: T | T[]): T[] {\n return Array.isArray(input) ? input : [input];\n}\n\ntype Mutable<T> = { -readonly [K in keyof T]: T[K] };\n\nexport function convertRelaxedAxisSelectorToMultiAxisSelector(\n input: RelaxedAxisSelector,\n): MultiAxisSelector {\n const result: Mutable<MultiAxisSelector> = {};\n if (input.name !== undefined) result.name = normalizeStringMatchers(input.name);\n if (input.type !== undefined) result.type = normalizeTypes(input.type);\n if (input.domain !== undefined) result.domain = normalizeRecord(input.domain);\n if (input.contextDomain !== undefined)\n result.contextDomain = normalizeRecord(input.contextDomain);\n if (input.annotations !== undefined) result.annotations = normalizeRecord(input.annotations);\n return result;\n}\n\nexport function convertRelaxedColumnSelectorToMultiColumnSelector(\n input: RelaxedColumnSelector,\n): MultiColumnSelector {\n const result: Mutable<MultiColumnSelector> = {};\n if (input.name !== undefined) result.name = normalizeStringMatchers(input.name);\n if (input.type !== undefined) result.type = normalizeTypes(input.type);\n if (input.domain !== undefined) result.domain = normalizeRecord(input.domain);\n if (input.contextDomain !== undefined)\n result.contextDomain = normalizeRecord(input.contextDomain);\n if (input.annotations !== undefined) result.annotations = normalizeRecord(input.annotations);\n if (input.axes !== undefined)\n result.axes = input.axes.map(convertRelaxedAxisSelectorToMultiAxisSelector);\n if (input.partialAxesMatch !== undefined) result.partialAxesMatch = input.partialAxesMatch;\n return result;\n}\n\nexport function convertColumnSelectorToMultiColumnSelector(\n input: ColumnSelector,\n): MultiColumnSelector[] {\n const arr = Array.isArray(input) ? input : [input];\n return arr.map(convertRelaxedColumnSelectorToMultiColumnSelector);\n}\n"],"mappings":";AA2CA,SAAS,wBAAwB,OAA+C;AAC9E,KAAI,OAAO,UAAU,SAAU,QAAO,CAAC;EAAE,MAAM;EAAS,OAAO;EAAO,CAAC;AACvE,KAAI,CAAC,MAAM,QAAQ,MAAM,CAAE,QAAO,CAAC,MAAM;AACzC,QAAO,MAAM,KAAK,MAChB,OAAO,MAAM,WAAY;EAAE,MAAM;EAAS,OAAO;EAAG,GAA4B,EACjF;;AAGH,SAAS,gBAAgB,OAAuD;CAC9E,MAAM,SAA0C,EAAE;AAClD,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,MAAM,CAC9C,QAAO,OAAO,wBAAwB,MAAM;AAE9C,QAAO;;AAGT,SAAS,eAAkB,OAAqB;AAC9C,QAAO,MAAM,QAAQ,MAAM,GAAG,QAAQ,CAAC,MAAM;;AAK/C,SAAgB,8CACd,OACmB;CACnB,MAAM,SAAqC,EAAE;AAC7C,KAAI,MAAM,SAAS,KAAA,EAAW,QAAO,OAAO,wBAAwB,MAAM,KAAK;AAC/E,KAAI,MAAM,SAAS,KAAA,EAAW,QAAO,OAAO,eAAe,MAAM,KAAK;AACtE,KAAI,MAAM,WAAW,KAAA,EAAW,QAAO,SAAS,gBAAgB,MAAM,OAAO;AAC7E,KAAI,MAAM,kBAAkB,KAAA,EAC1B,QAAO,gBAAgB,gBAAgB,MAAM,cAAc;AAC7D,KAAI,MAAM,gBAAgB,KAAA,EAAW,QAAO,cAAc,gBAAgB,MAAM,YAAY;AAC5F,QAAO;;AAGT,SAAgB,kDACd,OACqB;CACrB,MAAM,SAAuC,EAAE;AAC/C,KAAI,MAAM,SAAS,KAAA,EAAW,QAAO,OAAO,wBAAwB,MAAM,KAAK;AAC/E,KAAI,MAAM,SAAS,KAAA,EAAW,QAAO,OAAO,eAAe,MAAM,KAAK;AACtE,KAAI,MAAM,WAAW,KAAA,EAAW,QAAO,SAAS,gBAAgB,MAAM,OAAO;AAC7E,KAAI,MAAM,kBAAkB,KAAA,EAC1B,QAAO,gBAAgB,gBAAgB,MAAM,cAAc;AAC7D,KAAI,MAAM,gBAAgB,KAAA,EAAW,QAAO,cAAc,gBAAgB,MAAM,YAAY;AAC5F,KAAI,MAAM,SAAS,KAAA,EACjB,QAAO,OAAO,MAAM,KAAK,IAAI,8CAA8C;AAC7E,KAAI,MAAM,qBAAqB,KAAA,EAAW,QAAO,mBAAmB,MAAM;AAC1E,QAAO;;AAGT,SAAgB,2CACd,OACuB;AAEvB,SADY,MAAM,QAAQ,MAAM,GAAG,QAAQ,CAAC,MAAM,EACvC,IAAI,kDAAkD"}
@@ -23,7 +23,7 @@ interface RelaxedColumnSelector {
23
23
  axes?: RelaxedAxisSelector[];
24
24
  partialAxesMatch?: boolean;
25
25
  }
26
- /** Input that normalizes to ColumnSelector[]. */
26
+ /** One or many relaxed column selectors; normalizes to MultiColumnSelector[]. */
27
27
  type ColumnSelector = RelaxedColumnSelector | RelaxedColumnSelector[];
28
28
  declare function convertRelaxedAxisSelectorToMultiAxisSelector(input: RelaxedAxisSelector): MultiAxisSelector;
29
29
  declare function convertRelaxedColumnSelectorToMultiColumnSelector(input: RelaxedColumnSelector): MultiColumnSelector;
@@ -1 +1 @@
1
- {"version":3,"file":"column_selector.js","names":[],"sources":["../../src/columns/column_selector.ts"],"sourcesContent":["import type {\n AxisValueType,\n ColumnValueType,\n MultiAxisSelector,\n MultiColumnSelector,\n StringMatcher,\n} from \"@milaboratories/pl-model-common\";\n\nexport type { StringMatcher } from \"@milaboratories/pl-model-common\";\n\n// --- Relaxed types ---\n\n/** Relaxed string matcher input: plain string, single matcher, or array of mixed. */\nexport type RelaxedStringMatchers = string | StringMatcher | (string | StringMatcher)[];\n\n/** Relaxed record matcher: values can be plain strings or relaxed matchers. */\nexport type RelaxedRecord = Record<string, RelaxedStringMatchers>;\n\n/** Relaxed axis selector — accepts plain strings where strict requires StringMatcher[]. */\nexport interface RelaxedAxisSelector {\n name?: RelaxedStringMatchers;\n type?: AxisValueType | AxisValueType[];\n domain?: RelaxedRecord;\n contextDomain?: RelaxedRecord;\n annotations?: RelaxedRecord;\n}\n\n/** Relaxed column selector — convenient hand-written form. */\nexport interface RelaxedColumnSelector {\n name?: RelaxedStringMatchers;\n type?: ColumnValueType | ColumnValueType[];\n domain?: RelaxedRecord;\n contextDomain?: RelaxedRecord;\n annotations?: RelaxedRecord;\n axes?: RelaxedAxisSelector[];\n partialAxesMatch?: boolean;\n}\n\n/** Input that normalizes to ColumnSelector[]. */\nexport type ColumnSelector = RelaxedColumnSelector | RelaxedColumnSelector[];\n\n// --- Normalization ---\n\nfunction normalizeStringMatchers(input: RelaxedStringMatchers): StringMatcher[] {\n if (typeof input === \"string\") return [{ type: \"regex\", value: input }];\n if (!Array.isArray(input)) return [input];\n return input.map((v) =>\n typeof v === \"string\" ? ({ type: \"regex\", value: v } satisfies StringMatcher) : v,\n );\n}\n\nfunction normalizeRecord(input: RelaxedRecord): Record<string, StringMatcher[]> {\n const result: Record<string, StringMatcher[]> = {};\n for (const [key, value] of Object.entries(input)) {\n result[key] = normalizeStringMatchers(value);\n }\n return result;\n}\n\nfunction normalizeTypes<T>(input: T | T[]): T[] {\n return Array.isArray(input) ? input : [input];\n}\n\ntype Mutable<T> = { -readonly [K in keyof T]: T[K] };\n\nexport function convertRelaxedAxisSelectorToMultiAxisSelector(\n input: RelaxedAxisSelector,\n): MultiAxisSelector {\n const result: Mutable<MultiAxisSelector> = {};\n if (input.name !== undefined) result.name = normalizeStringMatchers(input.name);\n if (input.type !== undefined) result.type = normalizeTypes(input.type);\n if (input.domain !== undefined) result.domain = normalizeRecord(input.domain);\n if (input.contextDomain !== undefined)\n result.contextDomain = normalizeRecord(input.contextDomain);\n if (input.annotations !== undefined) result.annotations = normalizeRecord(input.annotations);\n return result;\n}\n\nexport function convertRelaxedColumnSelectorToMultiColumnSelector(\n input: RelaxedColumnSelector,\n): MultiColumnSelector {\n const result: Mutable<MultiColumnSelector> = {};\n if (input.name !== undefined) result.name = normalizeStringMatchers(input.name);\n if (input.type !== undefined) result.type = normalizeTypes(input.type);\n if (input.domain !== undefined) result.domain = normalizeRecord(input.domain);\n if (input.contextDomain !== undefined)\n result.contextDomain = normalizeRecord(input.contextDomain);\n if (input.annotations !== undefined) result.annotations = normalizeRecord(input.annotations);\n if (input.axes !== undefined)\n result.axes = input.axes.map(convertRelaxedAxisSelectorToMultiAxisSelector);\n if (input.partialAxesMatch !== undefined) result.partialAxesMatch = input.partialAxesMatch;\n return result;\n}\n\nexport function convertColumnSelectorToMultiColumnSelector(\n input: ColumnSelector,\n): MultiColumnSelector[] {\n const arr = Array.isArray(input) ? input : [input];\n return arr.map(convertRelaxedColumnSelectorToMultiColumnSelector);\n}\n"],"mappings":";AA2CA,SAAS,wBAAwB,OAA+C;AAC9E,KAAI,OAAO,UAAU,SAAU,QAAO,CAAC;EAAE,MAAM;EAAS,OAAO;EAAO,CAAC;AACvE,KAAI,CAAC,MAAM,QAAQ,MAAM,CAAE,QAAO,CAAC,MAAM;AACzC,QAAO,MAAM,KAAK,MAChB,OAAO,MAAM,WAAY;EAAE,MAAM;EAAS,OAAO;EAAG,GAA4B,EACjF;;AAGH,SAAS,gBAAgB,OAAuD;CAC9E,MAAM,SAA0C,EAAE;AAClD,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,MAAM,CAC9C,QAAO,OAAO,wBAAwB,MAAM;AAE9C,QAAO;;AAGT,SAAS,eAAkB,OAAqB;AAC9C,QAAO,MAAM,QAAQ,MAAM,GAAG,QAAQ,CAAC,MAAM;;AAK/C,SAAgB,8CACd,OACmB;CACnB,MAAM,SAAqC,EAAE;AAC7C,KAAI,MAAM,SAAS,KAAA,EAAW,QAAO,OAAO,wBAAwB,MAAM,KAAK;AAC/E,KAAI,MAAM,SAAS,KAAA,EAAW,QAAO,OAAO,eAAe,MAAM,KAAK;AACtE,KAAI,MAAM,WAAW,KAAA,EAAW,QAAO,SAAS,gBAAgB,MAAM,OAAO;AAC7E,KAAI,MAAM,kBAAkB,KAAA,EAC1B,QAAO,gBAAgB,gBAAgB,MAAM,cAAc;AAC7D,KAAI,MAAM,gBAAgB,KAAA,EAAW,QAAO,cAAc,gBAAgB,MAAM,YAAY;AAC5F,QAAO;;AAGT,SAAgB,kDACd,OACqB;CACrB,MAAM,SAAuC,EAAE;AAC/C,KAAI,MAAM,SAAS,KAAA,EAAW,QAAO,OAAO,wBAAwB,MAAM,KAAK;AAC/E,KAAI,MAAM,SAAS,KAAA,EAAW,QAAO,OAAO,eAAe,MAAM,KAAK;AACtE,KAAI,MAAM,WAAW,KAAA,EAAW,QAAO,SAAS,gBAAgB,MAAM,OAAO;AAC7E,KAAI,MAAM,kBAAkB,KAAA,EAC1B,QAAO,gBAAgB,gBAAgB,MAAM,cAAc;AAC7D,KAAI,MAAM,gBAAgB,KAAA,EAAW,QAAO,cAAc,gBAAgB,MAAM,YAAY;AAC5F,KAAI,MAAM,SAAS,KAAA,EACjB,QAAO,OAAO,MAAM,KAAK,IAAI,8CAA8C;AAC7E,KAAI,MAAM,qBAAqB,KAAA,EAAW,QAAO,mBAAmB,MAAM;AAC1E,QAAO;;AAGT,SAAgB,2CACd,OACuB;AAEvB,SADY,MAAM,QAAQ,MAAM,GAAG,QAAQ,CAAC,MAAM,EACvC,IAAI,kDAAkD"}
1
+ {"version":3,"file":"column_selector.js","names":[],"sources":["../../src/columns/column_selector.ts"],"sourcesContent":["import type {\n AxisValueType,\n ColumnValueType,\n MultiAxisSelector,\n MultiColumnSelector,\n StringMatcher,\n} from \"@milaboratories/pl-model-common\";\n\nexport type { StringMatcher } from \"@milaboratories/pl-model-common\";\n\n// --- Relaxed types ---\n\n/** Relaxed string matcher input: plain string, single matcher, or array of mixed. */\nexport type RelaxedStringMatchers = string | StringMatcher | (string | StringMatcher)[];\n\n/** Relaxed record matcher: values can be plain strings or relaxed matchers. */\nexport type RelaxedRecord = Record<string, RelaxedStringMatchers>;\n\n/** Relaxed axis selector — accepts plain strings where strict requires StringMatcher[]. */\nexport interface RelaxedAxisSelector {\n name?: RelaxedStringMatchers;\n type?: AxisValueType | AxisValueType[];\n domain?: RelaxedRecord;\n contextDomain?: RelaxedRecord;\n annotations?: RelaxedRecord;\n}\n\n/** Relaxed column selector — convenient hand-written form. */\nexport interface RelaxedColumnSelector {\n name?: RelaxedStringMatchers;\n type?: ColumnValueType | ColumnValueType[];\n domain?: RelaxedRecord;\n contextDomain?: RelaxedRecord;\n annotations?: RelaxedRecord;\n axes?: RelaxedAxisSelector[];\n partialAxesMatch?: boolean;\n}\n\n/** One or many relaxed column selectors; normalizes to MultiColumnSelector[]. */\nexport type ColumnSelector = RelaxedColumnSelector | RelaxedColumnSelector[];\n\n// --- Normalization ---\n\nfunction normalizeStringMatchers(input: RelaxedStringMatchers): StringMatcher[] {\n if (typeof input === \"string\") return [{ type: \"regex\", value: input }];\n if (!Array.isArray(input)) return [input];\n return input.map((v) =>\n typeof v === \"string\" ? ({ type: \"regex\", value: v } satisfies StringMatcher) : v,\n );\n}\n\nfunction normalizeRecord(input: RelaxedRecord): Record<string, StringMatcher[]> {\n const result: Record<string, StringMatcher[]> = {};\n for (const [key, value] of Object.entries(input)) {\n result[key] = normalizeStringMatchers(value);\n }\n return result;\n}\n\nfunction normalizeTypes<T>(input: T | T[]): T[] {\n return Array.isArray(input) ? input : [input];\n}\n\ntype Mutable<T> = { -readonly [K in keyof T]: T[K] };\n\nexport function convertRelaxedAxisSelectorToMultiAxisSelector(\n input: RelaxedAxisSelector,\n): MultiAxisSelector {\n const result: Mutable<MultiAxisSelector> = {};\n if (input.name !== undefined) result.name = normalizeStringMatchers(input.name);\n if (input.type !== undefined) result.type = normalizeTypes(input.type);\n if (input.domain !== undefined) result.domain = normalizeRecord(input.domain);\n if (input.contextDomain !== undefined)\n result.contextDomain = normalizeRecord(input.contextDomain);\n if (input.annotations !== undefined) result.annotations = normalizeRecord(input.annotations);\n return result;\n}\n\nexport function convertRelaxedColumnSelectorToMultiColumnSelector(\n input: RelaxedColumnSelector,\n): MultiColumnSelector {\n const result: Mutable<MultiColumnSelector> = {};\n if (input.name !== undefined) result.name = normalizeStringMatchers(input.name);\n if (input.type !== undefined) result.type = normalizeTypes(input.type);\n if (input.domain !== undefined) result.domain = normalizeRecord(input.domain);\n if (input.contextDomain !== undefined)\n result.contextDomain = normalizeRecord(input.contextDomain);\n if (input.annotations !== undefined) result.annotations = normalizeRecord(input.annotations);\n if (input.axes !== undefined)\n result.axes = input.axes.map(convertRelaxedAxisSelectorToMultiAxisSelector);\n if (input.partialAxesMatch !== undefined) result.partialAxesMatch = input.partialAxesMatch;\n return result;\n}\n\nexport function convertColumnSelectorToMultiColumnSelector(\n input: ColumnSelector,\n): MultiColumnSelector[] {\n const arr = Array.isArray(input) ? input : [input];\n return arr.map(convertRelaxedColumnSelectorToMultiColumnSelector);\n}\n"],"mappings":";AA2CA,SAAS,wBAAwB,OAA+C;AAC9E,KAAI,OAAO,UAAU,SAAU,QAAO,CAAC;EAAE,MAAM;EAAS,OAAO;EAAO,CAAC;AACvE,KAAI,CAAC,MAAM,QAAQ,MAAM,CAAE,QAAO,CAAC,MAAM;AACzC,QAAO,MAAM,KAAK,MAChB,OAAO,MAAM,WAAY;EAAE,MAAM;EAAS,OAAO;EAAG,GAA4B,EACjF;;AAGH,SAAS,gBAAgB,OAAuD;CAC9E,MAAM,SAA0C,EAAE;AAClD,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,MAAM,CAC9C,QAAO,OAAO,wBAAwB,MAAM;AAE9C,QAAO;;AAGT,SAAS,eAAkB,OAAqB;AAC9C,QAAO,MAAM,QAAQ,MAAM,GAAG,QAAQ,CAAC,MAAM;;AAK/C,SAAgB,8CACd,OACmB;CACnB,MAAM,SAAqC,EAAE;AAC7C,KAAI,MAAM,SAAS,KAAA,EAAW,QAAO,OAAO,wBAAwB,MAAM,KAAK;AAC/E,KAAI,MAAM,SAAS,KAAA,EAAW,QAAO,OAAO,eAAe,MAAM,KAAK;AACtE,KAAI,MAAM,WAAW,KAAA,EAAW,QAAO,SAAS,gBAAgB,MAAM,OAAO;AAC7E,KAAI,MAAM,kBAAkB,KAAA,EAC1B,QAAO,gBAAgB,gBAAgB,MAAM,cAAc;AAC7D,KAAI,MAAM,gBAAgB,KAAA,EAAW,QAAO,cAAc,gBAAgB,MAAM,YAAY;AAC5F,QAAO;;AAGT,SAAgB,kDACd,OACqB;CACrB,MAAM,SAAuC,EAAE;AAC/C,KAAI,MAAM,SAAS,KAAA,EAAW,QAAO,OAAO,wBAAwB,MAAM,KAAK;AAC/E,KAAI,MAAM,SAAS,KAAA,EAAW,QAAO,OAAO,eAAe,MAAM,KAAK;AACtE,KAAI,MAAM,WAAW,KAAA,EAAW,QAAO,SAAS,gBAAgB,MAAM,OAAO;AAC7E,KAAI,MAAM,kBAAkB,KAAA,EAC1B,QAAO,gBAAgB,gBAAgB,MAAM,cAAc;AAC7D,KAAI,MAAM,gBAAgB,KAAA,EAAW,QAAO,cAAc,gBAAgB,MAAM,YAAY;AAC5F,KAAI,MAAM,SAAS,KAAA,EACjB,QAAO,OAAO,MAAM,KAAK,IAAI,8CAA8C;AAC7E,KAAI,MAAM,qBAAqB,KAAA,EAAW,QAAO,mBAAmB,MAAM;AAC1E,QAAO;;AAGT,SAAgB,2CACd,OACuB;AAEvB,SADY,MAAM,QAAQ,MAAM,GAAG,QAAQ,CAAC,MAAM,EACvC,IAAI,kDAAkD"}
@@ -1 +1 @@
1
- {"version":3,"file":"column_snapshot.cjs","names":[],"sources":["../../src/columns/column_snapshot.ts"],"sourcesContent":["import type { PColumnSpec, PObjectId, SUniversalPColumnId } from \"@milaboratories/pl-model-common\";\nimport type { PColumnDataUniversal } from \"../render/internal\";\n\n// --- ColumnSnapshot ---\n\n/** Data status of a column snapshot. */\nexport type ColumnDataStatus = \"ready\" | \"computing\" | \"absent\";\n\n/**\n * Immutable snapshot of a column: spec, data status, and lazy data accessor.\n *\n * - `dataStatus` is readable without marking the render context unstable.\n * - `data` holds an active object when data exists (ready or computing),\n * or `undefined` when data is permanently absent.\n */\nexport interface ColumnSnapshot<Id extends PObjectId | SUniversalPColumnId> {\n readonly id: Id;\n readonly spec: PColumnSpec;\n readonly dataStatus: ColumnDataStatus;\n\n /**\n * Lazy data accessor.\n * - `'ready'`: `data.get()` returns column data, context stays stable.\n * - `'computing'`: `data.get()` returns `undefined`, marks context unstable.\n * - `'absent'`: `data` is `undefined` — no active object, no instability.\n */\n readonly data: ColumnData | undefined;\n}\n\n// --- ColumnData ---\n\n/**\n * Active object wrapping lazy column data access.\n * Accessing data on a computing column marks the render context unstable.\n */\nexport interface ColumnData {\n get(): PColumnDataUniversal | undefined;\n}\n\n/** Creates a ColumnData active object for a ready column. */\nexport function createReadyColumnData(getData: () => PColumnDataUniversal | undefined): ColumnData {\n return { get: getData };\n}\n\n// --- Snapshot construction helpers ---\n\n/** Creates a ColumnSnapshot from parts. */\nexport function createColumnSnapshot<Id extends PObjectId>(\n id: Id,\n spec: PColumnSpec,\n data: undefined | ColumnData,\n dataStatus: ColumnDataStatus,\n): ColumnSnapshot<Id> {\n return { id, spec, data, dataStatus };\n}\n"],"mappings":";;AAwCA,SAAgB,sBAAsB,SAA6D;AACjG,QAAO,EAAE,KAAK,SAAS;;;AAMzB,SAAgB,qBACd,IACA,MACA,MACA,YACoB;AACpB,QAAO;EAAE;EAAI;EAAM;EAAM;EAAY"}
1
+ {"version":3,"file":"column_snapshot.cjs","names":[],"sources":["../../src/columns/column_snapshot.ts"],"sourcesContent":["import type { PColumnSpec, PObjectId, SUniversalPColumnId } from \"@milaboratories/pl-model-common\";\nimport type { PColumnDataUniversal } from \"../render/internal\";\n\n// --- ColumnSnapshot ---\n\n/** Data status of a column snapshot. */\nexport type ColumnDataStatus = \"ready\" | \"computing\" | \"absent\";\n\n/**\n * Immutable snapshot of a column: spec, data status, and lazy data accessor.\n *\n * - `dataStatus` is readable without marking the render context unstable.\n * - `data` holds an active object when data exists (ready or computing),\n * or `undefined` when data is permanently absent.\n */\nexport interface ColumnSnapshot<\n Id extends PObjectId | SUniversalPColumnId,\n Data = PColumnDataUniversal,\n> {\n readonly id: Id;\n readonly spec: PColumnSpec;\n readonly dataStatus: ColumnDataStatus;\n\n /**\n * Lazy data accessor.\n * - `'ready'`: `data.get()` returns column data, context stays stable.\n * - `'computing'`: `data.get()` returns `undefined`, marks context unstable.\n * - `'absent'`: `data` is `undefined` — no active object, no instability.\n */\n readonly data: ColumnData<Data> | undefined;\n}\n\n// --- ColumnData ---\n\n/**\n * Active object wrapping lazy column data access.\n * Accessing data on a computing column marks the render context unstable.\n */\nexport interface ColumnData<Data = PColumnDataUniversal> {\n get(): Data | undefined;\n}\n\n/** Creates a ColumnData active object for a ready column. */\nexport function createReadyColumnData(getData: () => PColumnDataUniversal | undefined): ColumnData {\n return { get: getData };\n}\n\n// --- Snapshot construction helpers ---\n\n/** Creates a ColumnSnapshot from parts. */\nexport function createColumnSnapshot<Id extends PObjectId>(\n id: Id,\n spec: PColumnSpec,\n data: undefined | ColumnData,\n dataStatus: ColumnDataStatus,\n): ColumnSnapshot<Id> {\n return { id, spec, data, dataStatus };\n}\n"],"mappings":";;AA2CA,SAAgB,sBAAsB,SAA6D;AACjG,QAAO,EAAE,KAAK,SAAS;;;AAMzB,SAAgB,qBACd,IACA,MACA,MACA,YACoB;AACpB,QAAO;EAAE;EAAI;EAAM;EAAM;EAAY"}
@@ -11,7 +11,7 @@ type ColumnDataStatus = "ready" | "computing" | "absent";
11
11
  * - `data` holds an active object when data exists (ready or computing),
12
12
  * or `undefined` when data is permanently absent.
13
13
  */
14
- interface ColumnSnapshot<Id extends PObjectId | SUniversalPColumnId> {
14
+ interface ColumnSnapshot<Id extends PObjectId | SUniversalPColumnId, Data = PColumnDataUniversal> {
15
15
  readonly id: Id;
16
16
  readonly spec: PColumnSpec;
17
17
  readonly dataStatus: ColumnDataStatus;
@@ -21,14 +21,14 @@ interface ColumnSnapshot<Id extends PObjectId | SUniversalPColumnId> {
21
21
  * - `'computing'`: `data.get()` returns `undefined`, marks context unstable.
22
22
  * - `'absent'`: `data` is `undefined` — no active object, no instability.
23
23
  */
24
- readonly data: ColumnData | undefined;
24
+ readonly data: ColumnData<Data> | undefined;
25
25
  }
26
26
  /**
27
27
  * Active object wrapping lazy column data access.
28
28
  * Accessing data on a computing column marks the render context unstable.
29
29
  */
30
- interface ColumnData {
31
- get(): PColumnDataUniversal | undefined;
30
+ interface ColumnData<Data = PColumnDataUniversal> {
31
+ get(): Data | undefined;
32
32
  }
33
33
  /** Creates a ColumnData active object for a ready column. */
34
34
  declare function createReadyColumnData(getData: () => PColumnDataUniversal | undefined): ColumnData;
@@ -1 +1 @@
1
- {"version":3,"file":"column_snapshot.d.ts","names":[],"sources":["../../src/columns/column_snapshot.ts"],"mappings":";;;;;KAMY,gBAAA;AAAZ;;;;;AASA;;AATA,UASiB,cAAA,YAA0B,SAAA,GAAY,mBAAA;EAAA,SAC5C,EAAA,EAAI,EAAA;EAAA,SACJ,IAAA,EAAM,WAAA;EAAA,SACN,UAAA,EAAY,gBAAA;EADN;;;;;;EAAA,SASN,IAAA,EAAM,UAAA;AAAA;;;;;UASA,UAAA;EACf,GAAA,IAAO,oBAAA;AAAA;;iBAIO,qBAAA,CAAsB,OAAA,QAAe,oBAAA,eAAmC,UAAA;;iBAOxE,oBAAA,YAAgC,SAAA,CAAA,CAC9C,EAAA,EAAI,EAAA,EACJ,IAAA,EAAM,WAAA,EACN,IAAA,cAAkB,UAAA,EAClB,UAAA,EAAY,gBAAA,GACX,cAAA,CAAe,EAAA"}
1
+ {"version":3,"file":"column_snapshot.d.ts","names":[],"sources":["../../src/columns/column_snapshot.ts"],"mappings":";;;;;KAMY,gBAAA;AAAZ;;;;;AASA;;AATA,UASiB,cAAA,YACJ,SAAA,GAAY,mBAAA,SAChB,oBAAA;EAAA,SAEE,EAAA,EAAI,EAAA;EAAA,SACJ,IAAA,EAAM,WAAA;EAAA,SACN,UAAA,EAAY,gBAAA;EAFR;;;;;;EAAA,SAUJ,IAAA,EAAM,UAAA,CAAW,IAAA;AAAA;;;;;UASX,UAAA,QAAkB,oBAAA;EACjC,GAAA,IAAO,IAAA;AAAA;;iBAIO,qBAAA,CAAsB,OAAA,QAAe,oBAAA,eAAmC,UAAA;;iBAOxE,oBAAA,YAAgC,SAAA,CAAA,CAC9C,EAAA,EAAI,EAAA,EACJ,IAAA,EAAM,WAAA,EACN,IAAA,cAAkB,UAAA,EAClB,UAAA,EAAY,gBAAA,GACX,cAAA,CAAe,EAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"column_snapshot.js","names":[],"sources":["../../src/columns/column_snapshot.ts"],"sourcesContent":["import type { PColumnSpec, PObjectId, SUniversalPColumnId } from \"@milaboratories/pl-model-common\";\nimport type { PColumnDataUniversal } from \"../render/internal\";\n\n// --- ColumnSnapshot ---\n\n/** Data status of a column snapshot. */\nexport type ColumnDataStatus = \"ready\" | \"computing\" | \"absent\";\n\n/**\n * Immutable snapshot of a column: spec, data status, and lazy data accessor.\n *\n * - `dataStatus` is readable without marking the render context unstable.\n * - `data` holds an active object when data exists (ready or computing),\n * or `undefined` when data is permanently absent.\n */\nexport interface ColumnSnapshot<Id extends PObjectId | SUniversalPColumnId> {\n readonly id: Id;\n readonly spec: PColumnSpec;\n readonly dataStatus: ColumnDataStatus;\n\n /**\n * Lazy data accessor.\n * - `'ready'`: `data.get()` returns column data, context stays stable.\n * - `'computing'`: `data.get()` returns `undefined`, marks context unstable.\n * - `'absent'`: `data` is `undefined` — no active object, no instability.\n */\n readonly data: ColumnData | undefined;\n}\n\n// --- ColumnData ---\n\n/**\n * Active object wrapping lazy column data access.\n * Accessing data on a computing column marks the render context unstable.\n */\nexport interface ColumnData {\n get(): PColumnDataUniversal | undefined;\n}\n\n/** Creates a ColumnData active object for a ready column. */\nexport function createReadyColumnData(getData: () => PColumnDataUniversal | undefined): ColumnData {\n return { get: getData };\n}\n\n// --- Snapshot construction helpers ---\n\n/** Creates a ColumnSnapshot from parts. */\nexport function createColumnSnapshot<Id extends PObjectId>(\n id: Id,\n spec: PColumnSpec,\n data: undefined | ColumnData,\n dataStatus: ColumnDataStatus,\n): ColumnSnapshot<Id> {\n return { id, spec, data, dataStatus };\n}\n"],"mappings":";;AAwCA,SAAgB,sBAAsB,SAA6D;AACjG,QAAO,EAAE,KAAK,SAAS;;;AAMzB,SAAgB,qBACd,IACA,MACA,MACA,YACoB;AACpB,QAAO;EAAE;EAAI;EAAM;EAAM;EAAY"}
1
+ {"version":3,"file":"column_snapshot.js","names":[],"sources":["../../src/columns/column_snapshot.ts"],"sourcesContent":["import type { PColumnSpec, PObjectId, SUniversalPColumnId } from \"@milaboratories/pl-model-common\";\nimport type { PColumnDataUniversal } from \"../render/internal\";\n\n// --- ColumnSnapshot ---\n\n/** Data status of a column snapshot. */\nexport type ColumnDataStatus = \"ready\" | \"computing\" | \"absent\";\n\n/**\n * Immutable snapshot of a column: spec, data status, and lazy data accessor.\n *\n * - `dataStatus` is readable without marking the render context unstable.\n * - `data` holds an active object when data exists (ready or computing),\n * or `undefined` when data is permanently absent.\n */\nexport interface ColumnSnapshot<\n Id extends PObjectId | SUniversalPColumnId,\n Data = PColumnDataUniversal,\n> {\n readonly id: Id;\n readonly spec: PColumnSpec;\n readonly dataStatus: ColumnDataStatus;\n\n /**\n * Lazy data accessor.\n * - `'ready'`: `data.get()` returns column data, context stays stable.\n * - `'computing'`: `data.get()` returns `undefined`, marks context unstable.\n * - `'absent'`: `data` is `undefined` — no active object, no instability.\n */\n readonly data: ColumnData<Data> | undefined;\n}\n\n// --- ColumnData ---\n\n/**\n * Active object wrapping lazy column data access.\n * Accessing data on a computing column marks the render context unstable.\n */\nexport interface ColumnData<Data = PColumnDataUniversal> {\n get(): Data | undefined;\n}\n\n/** Creates a ColumnData active object for a ready column. */\nexport function createReadyColumnData(getData: () => PColumnDataUniversal | undefined): ColumnData {\n return { get: getData };\n}\n\n// --- Snapshot construction helpers ---\n\n/** Creates a ColumnSnapshot from parts. */\nexport function createColumnSnapshot<Id extends PObjectId>(\n id: Id,\n spec: PColumnSpec,\n data: undefined | ColumnData,\n dataStatus: ColumnDataStatus,\n): ColumnSnapshot<Id> {\n return { id, spec, data, dataStatus };\n}\n"],"mappings":";;AA2CA,SAAgB,sBAAsB,SAA6D;AACjG,QAAO,EAAE,KAAK,SAAS;;;AAMzB,SAAgB,qBACd,IACA,MACA,MACA,YACoB;AACpB,QAAO;EAAE;EAAI;EAAM;EAAM;EAAY"}
@@ -1 +1 @@
1
- {"version":3,"file":"ctx_column_sources.cjs","names":["ResourceTypeName","OutputColumnProvider"],"sources":["../../src/columns/ctx_column_sources.ts"],"sourcesContent":["import type { PColumnSpec, PObjectId } from \"@milaboratories/pl-model-common\";\nimport { TreeNodeAccessor } from \"../render/accessor\";\nimport type { RenderCtxBase, ResultPool } from \"../render\";\nimport type { ColumnSnapshot } from \"./column_snapshot\";\nimport type { ColumnDataStatus } from \"./column_snapshot\";\nimport type { ColumnSnapshotProvider } from \"./column_snapshot_provider\";\nimport { OutputColumnProvider } from \"./column_snapshot_provider\";\nimport { ResourceTypeName } from \"@milaboratories/pl-model-common\";\nimport type { ValueOf } from \"@milaboratories/helpers\";\n\n/**\n * Collect ColumnSnapshotProviders from all render context sources:\n *\n * - **resultPool** — all upstream columns (always included)\n * - **outputs** — PFrame fields from block execution outputs\n * - **prerun** — PFrame fields from prerun/staging results\n *\n * Returns an array of providers suitable for `ColumnCollectionBuilder.addSource()`.\n */\nexport function collectCtxColumnSnapshotProviders<A, U, S>(\n ctx: RenderCtxBase<A, U, S>,\n): ColumnSnapshotProvider[] {\n const providers: ColumnSnapshotProvider[] = [];\n\n // ResultPool — all upstream columns\n providers.push(new ResultPoolColumnSnapshotProvider(ctx.resultPool));\n\n // Outputs — each PFrame-like output field becomes a provider\n const outputs = ctx.outputs;\n if (outputs) {\n providers.push(...collectPFrameProviders(outputs));\n }\n\n // Prerun — same treatment as outputs\n const prerun = ctx.prerun;\n if (prerun) {\n providers.push(...collectPFrameProviders(prerun));\n }\n\n return providers;\n}\n\n/**\n * Adapter wrapping ResultPool into the new ColumnSnapshotProvider interface.\n *\n * - `isColumnListComplete()` always returns true — the result pool\n * is a stable snapshot within a single render cycle.\n * - Data status is derived from the underlying TreeNodeAccessor:\n * ready (getIsReadyOrError), computing, or absent (no data resource).\n */\nexport class ResultPoolColumnSnapshotProvider implements ColumnSnapshotProvider {\n constructor(private readonly pool: ResultPool) {}\n\n getAllColumns(): ColumnSnapshot<PObjectId>[] {\n const pColumns = this.pool.selectColumns(() => true);\n return pColumns.map((col) => toSnapshot(col.id, col.spec, col.data));\n }\n\n isColumnListComplete(): boolean {\n return true;\n }\n}\n\nfunction toSnapshot(\n id: PObjectId,\n spec: PColumnSpec,\n accessor: TreeNodeAccessor | undefined,\n): ColumnSnapshot<PObjectId> {\n if (accessor === undefined) {\n return { id, spec, dataStatus: \"absent\" as ColumnDataStatus, data: undefined };\n }\n const isReady = accessor.getIsReadyOrError();\n return {\n id,\n spec,\n dataStatus: (isReady ? \"ready\" : \"computing\") as ColumnDataStatus,\n data: { get: () => (isReady ? accessor : undefined) },\n };\n}\n\n/**\n * Recursively walk the output tree starting from `accessor`.\n * - If a node's resourceType is PFrame → wrap it as OutputColumnProvider.\n * - If a node's resourceType is StdMap/std/map → recurse into its output fields.\n * - Otherwise → skip (leaf of unknown type).\n */\nfunction collectPFrameProviders(accessor: TreeNodeAccessor): ColumnSnapshotProvider[] {\n const out: ColumnSnapshotProvider[] = [];\n walkTree(accessor, out);\n return out;\n}\n\nfunction walkTree(node: TreeNodeAccessor, out: ColumnSnapshotProvider[]): void {\n const typeName = node.resourceType.name as ValueOf<typeof ResourceTypeName>;\n\n if (typeName === ResourceTypeName.PFrame) {\n out.push(new OutputColumnProvider(node));\n return;\n }\n\n if (typeName === ResourceTypeName.StdMap || typeName === ResourceTypeName.StdMapSlash) {\n for (const field of node.listInputFields()) {\n const child = node.resolve(field);\n if (child) walkTree(child, out);\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;AAmBA,SAAgB,kCACd,KAC0B;CAC1B,MAAM,YAAsC,EAAE;AAG9C,WAAU,KAAK,IAAI,iCAAiC,IAAI,WAAW,CAAC;CAGpE,MAAM,UAAU,IAAI;AACpB,KAAI,QACF,WAAU,KAAK,GAAG,uBAAuB,QAAQ,CAAC;CAIpD,MAAM,SAAS,IAAI;AACnB,KAAI,OACF,WAAU,KAAK,GAAG,uBAAuB,OAAO,CAAC;AAGnD,QAAO;;;;;;;;;;AAWT,IAAa,mCAAb,MAAgF;CAC9E,YAAY,MAAmC;AAAlB,OAAA,OAAA;;CAE7B,gBAA6C;AAE3C,SADiB,KAAK,KAAK,oBAAoB,KAAK,CACpC,KAAK,QAAQ,WAAW,IAAI,IAAI,IAAI,MAAM,IAAI,KAAK,CAAC;;CAGtE,uBAAgC;AAC9B,SAAO;;;AAIX,SAAS,WACP,IACA,MACA,UAC2B;AAC3B,KAAI,aAAa,KAAA,EACf,QAAO;EAAE;EAAI;EAAM,YAAY;EAA8B,MAAM,KAAA;EAAW;CAEhF,MAAM,UAAU,SAAS,mBAAmB;AAC5C,QAAO;EACL;EACA;EACA,YAAa,UAAU,UAAU;EACjC,MAAM,EAAE,WAAY,UAAU,WAAW,KAAA,GAAY;EACtD;;;;;;;;AASH,SAAS,uBAAuB,UAAsD;CACpF,MAAM,MAAgC,EAAE;AACxC,UAAS,UAAU,IAAI;AACvB,QAAO;;AAGT,SAAS,SAAS,MAAwB,KAAqC;CAC7E,MAAM,WAAW,KAAK,aAAa;AAEnC,KAAI,aAAaA,gCAAAA,iBAAiB,QAAQ;AACxC,MAAI,KAAK,IAAIC,iCAAAA,qBAAqB,KAAK,CAAC;AACxC;;AAGF,KAAI,aAAaD,gCAAAA,iBAAiB,UAAU,aAAaA,gCAAAA,iBAAiB,YACxE,MAAK,MAAM,SAAS,KAAK,iBAAiB,EAAE;EAC1C,MAAM,QAAQ,KAAK,QAAQ,MAAM;AACjC,MAAI,MAAO,UAAS,OAAO,IAAI"}
1
+ {"version":3,"file":"ctx_column_sources.cjs","names":["ResourceTypeName","OutputColumnProvider"],"sources":["../../src/columns/ctx_column_sources.ts"],"sourcesContent":["import type { PColumnSpec, PObjectId } from \"@milaboratories/pl-model-common\";\nimport { TreeNodeAccessor } from \"../render/accessor\";\nimport type { RenderCtxBase, ResultPool } from \"../render\";\nimport type { ColumnSnapshot } from \"./column_snapshot\";\nimport type { ColumnDataStatus } from \"./column_snapshot\";\nimport type { ColumnSnapshotProvider } from \"./column_snapshot_provider\";\nimport { OutputColumnProvider } from \"./column_snapshot_provider\";\nimport { ResourceTypeName } from \"@milaboratories/pl-model-common\";\nimport type { ValueOf } from \"@milaboratories/helpers\";\n\n/**\n * Collect ColumnSnapshotProviders from all render context sources:\n *\n * - **resultPool** — all upstream columns (always included)\n * - **outputs** — PFrame fields from block execution outputs\n * - **prerun** — PFrame fields from prerun/staging results\n *\n * Returns an array of providers suitable for `ColumnCollectionBuilder.addSource()`.\n */\nexport function collectCtxColumnSnapshotProviders(ctx: RenderCtxBase): ColumnSnapshotProvider[] {\n const providers: ColumnSnapshotProvider[] = [];\n\n // ResultPool — all upstream columns\n providers.push(new ResultPoolColumnSnapshotProvider(ctx.resultPool));\n\n // Outputs — each PFrame-like output field becomes a provider\n const outputs = ctx.outputs;\n if (outputs) {\n providers.push(...collectPFrameProviders(outputs));\n }\n\n // Prerun — same treatment as outputs\n const prerun = ctx.prerun;\n if (prerun) {\n providers.push(...collectPFrameProviders(prerun));\n }\n\n return providers;\n}\n\n/**\n * Adapter wrapping ResultPool into the new ColumnSnapshotProvider interface.\n *\n * - `isColumnListComplete()` always returns true — the result pool\n * is a stable snapshot within a single render cycle.\n * - Data status is derived from the underlying TreeNodeAccessor:\n * ready (getIsReadyOrError), computing, or absent (no data resource).\n */\nexport class ResultPoolColumnSnapshotProvider implements ColumnSnapshotProvider {\n constructor(private readonly pool: ResultPool) {}\n\n getAllColumns(): ColumnSnapshot<PObjectId>[] {\n const pColumns = this.pool.selectColumns(() => true);\n return pColumns.map((col) => toSnapshot(col.id, col.spec, col.data));\n }\n\n isColumnListComplete(): boolean {\n return true;\n }\n}\n\nfunction toSnapshot(\n id: PObjectId,\n spec: PColumnSpec,\n accessor: TreeNodeAccessor | undefined,\n): ColumnSnapshot<PObjectId> {\n if (accessor === undefined) {\n return { id, spec, dataStatus: \"absent\" as ColumnDataStatus, data: undefined };\n }\n const isReady = accessor.getIsReadyOrError();\n return {\n id,\n spec,\n dataStatus: (isReady ? \"ready\" : \"computing\") as ColumnDataStatus,\n data: { get: () => (isReady ? accessor : undefined) },\n };\n}\n\n/**\n * Recursively walk the output tree starting from `accessor`.\n * - If a node's resourceType is PFrame → wrap it as OutputColumnProvider.\n * - If a node's resourceType is StdMap/std/map → recurse into its output fields.\n * - Otherwise → skip (leaf of unknown type).\n */\nfunction collectPFrameProviders(accessor: TreeNodeAccessor): ColumnSnapshotProvider[] {\n const out: ColumnSnapshotProvider[] = [];\n walkTree(accessor, out);\n return out;\n}\n\nfunction walkTree(node: TreeNodeAccessor, out: ColumnSnapshotProvider[]): void {\n const typeName = node.resourceType.name as ValueOf<typeof ResourceTypeName>;\n\n if (typeName === ResourceTypeName.PFrame) {\n out.push(new OutputColumnProvider(node));\n return;\n }\n\n if (typeName === ResourceTypeName.StdMap || typeName === ResourceTypeName.StdMapSlash) {\n for (const field of node.listInputFields()) {\n const child = node.resolve(field);\n if (child) walkTree(child, out);\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;AAmBA,SAAgB,kCAAkC,KAA8C;CAC9F,MAAM,YAAsC,EAAE;AAG9C,WAAU,KAAK,IAAI,iCAAiC,IAAI,WAAW,CAAC;CAGpE,MAAM,UAAU,IAAI;AACpB,KAAI,QACF,WAAU,KAAK,GAAG,uBAAuB,QAAQ,CAAC;CAIpD,MAAM,SAAS,IAAI;AACnB,KAAI,OACF,WAAU,KAAK,GAAG,uBAAuB,OAAO,CAAC;AAGnD,QAAO;;;;;;;;;;AAWT,IAAa,mCAAb,MAAgF;CAC9E,YAAY,MAAmC;AAAlB,OAAA,OAAA;;CAE7B,gBAA6C;AAE3C,SADiB,KAAK,KAAK,oBAAoB,KAAK,CACpC,KAAK,QAAQ,WAAW,IAAI,IAAI,IAAI,MAAM,IAAI,KAAK,CAAC;;CAGtE,uBAAgC;AAC9B,SAAO;;;AAIX,SAAS,WACP,IACA,MACA,UAC2B;AAC3B,KAAI,aAAa,KAAA,EACf,QAAO;EAAE;EAAI;EAAM,YAAY;EAA8B,MAAM,KAAA;EAAW;CAEhF,MAAM,UAAU,SAAS,mBAAmB;AAC5C,QAAO;EACL;EACA;EACA,YAAa,UAAU,UAAU;EACjC,MAAM,EAAE,WAAY,UAAU,WAAW,KAAA,GAAY;EACtD;;;;;;;;AASH,SAAS,uBAAuB,UAAsD;CACpF,MAAM,MAAgC,EAAE;AACxC,UAAS,UAAU,IAAI;AACvB,QAAO;;AAGT,SAAS,SAAS,MAAwB,KAAqC;CAC7E,MAAM,WAAW,KAAK,aAAa;AAEnC,KAAI,aAAaA,gCAAAA,iBAAiB,QAAQ;AACxC,MAAI,KAAK,IAAIC,iCAAAA,qBAAqB,KAAK,CAAC;AACxC;;AAGF,KAAI,aAAaD,gCAAAA,iBAAiB,UAAU,aAAaA,gCAAAA,iBAAiB,YACxE,MAAK,MAAM,SAAS,KAAK,iBAAiB,EAAE;EAC1C,MAAM,QAAQ,KAAK,QAAQ,MAAM;AACjC,MAAI,MAAO,UAAS,OAAO,IAAI"}
@@ -13,7 +13,7 @@ import { PObjectId } from "@milaboratories/pl-model-common";
13
13
  *
14
14
  * Returns an array of providers suitable for `ColumnCollectionBuilder.addSource()`.
15
15
  */
16
- declare function collectCtxColumnSnapshotProviders<A, U, S>(ctx: RenderCtxBase<A, U, S>): ColumnSnapshotProvider[];
16
+ declare function collectCtxColumnSnapshotProviders(ctx: RenderCtxBase): ColumnSnapshotProvider[];
17
17
  /**
18
18
  * Adapter wrapping ResultPool into the new ColumnSnapshotProvider interface.
19
19
  *
@@ -1 +1 @@
1
- {"version":3,"file":"ctx_column_sources.d.ts","names":[],"sources":["../../src/columns/ctx_column_sources.ts"],"mappings":";;;;;;;;;AAmBA;;;;;;iBAAgB,iCAAA,SAAA,CACd,GAAA,EAAK,aAAA,CAAc,CAAA,EAAG,CAAA,EAAG,CAAA,IACxB,sBAAA;;;;;;;;;cA6BU,gCAAA,YAA4C,sBAAA;EAAA,iBAC1B,IAAA;cAAA,IAAA,EAAM,UAAA;EAEnC,aAAA,CAAA,GAAiB,cAAA,CAAe,SAAA;EAKhC,oBAAA,CAAA;AAAA"}
1
+ {"version":3,"file":"ctx_column_sources.d.ts","names":[],"sources":["../../src/columns/ctx_column_sources.ts"],"mappings":";;;;;;;;;AAmBA;;;;;;iBAAgB,iCAAA,CAAkC,GAAA,EAAK,aAAA,GAAgB,sBAAA;;;AA6BvE;;;;;;cAAa,gCAAA,YAA4C,sBAAA;EAAA,iBAC1B,IAAA;cAAA,IAAA,EAAM,UAAA;EAEnC,aAAA,CAAA,GAAiB,cAAA,CAAe,SAAA;EAKhC,oBAAA,CAAA;AAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"ctx_column_sources.js","names":[],"sources":["../../src/columns/ctx_column_sources.ts"],"sourcesContent":["import type { PColumnSpec, PObjectId } from \"@milaboratories/pl-model-common\";\nimport { TreeNodeAccessor } from \"../render/accessor\";\nimport type { RenderCtxBase, ResultPool } from \"../render\";\nimport type { ColumnSnapshot } from \"./column_snapshot\";\nimport type { ColumnDataStatus } from \"./column_snapshot\";\nimport type { ColumnSnapshotProvider } from \"./column_snapshot_provider\";\nimport { OutputColumnProvider } from \"./column_snapshot_provider\";\nimport { ResourceTypeName } from \"@milaboratories/pl-model-common\";\nimport type { ValueOf } from \"@milaboratories/helpers\";\n\n/**\n * Collect ColumnSnapshotProviders from all render context sources:\n *\n * - **resultPool** — all upstream columns (always included)\n * - **outputs** — PFrame fields from block execution outputs\n * - **prerun** — PFrame fields from prerun/staging results\n *\n * Returns an array of providers suitable for `ColumnCollectionBuilder.addSource()`.\n */\nexport function collectCtxColumnSnapshotProviders<A, U, S>(\n ctx: RenderCtxBase<A, U, S>,\n): ColumnSnapshotProvider[] {\n const providers: ColumnSnapshotProvider[] = [];\n\n // ResultPool — all upstream columns\n providers.push(new ResultPoolColumnSnapshotProvider(ctx.resultPool));\n\n // Outputs — each PFrame-like output field becomes a provider\n const outputs = ctx.outputs;\n if (outputs) {\n providers.push(...collectPFrameProviders(outputs));\n }\n\n // Prerun — same treatment as outputs\n const prerun = ctx.prerun;\n if (prerun) {\n providers.push(...collectPFrameProviders(prerun));\n }\n\n return providers;\n}\n\n/**\n * Adapter wrapping ResultPool into the new ColumnSnapshotProvider interface.\n *\n * - `isColumnListComplete()` always returns true — the result pool\n * is a stable snapshot within a single render cycle.\n * - Data status is derived from the underlying TreeNodeAccessor:\n * ready (getIsReadyOrError), computing, or absent (no data resource).\n */\nexport class ResultPoolColumnSnapshotProvider implements ColumnSnapshotProvider {\n constructor(private readonly pool: ResultPool) {}\n\n getAllColumns(): ColumnSnapshot<PObjectId>[] {\n const pColumns = this.pool.selectColumns(() => true);\n return pColumns.map((col) => toSnapshot(col.id, col.spec, col.data));\n }\n\n isColumnListComplete(): boolean {\n return true;\n }\n}\n\nfunction toSnapshot(\n id: PObjectId,\n spec: PColumnSpec,\n accessor: TreeNodeAccessor | undefined,\n): ColumnSnapshot<PObjectId> {\n if (accessor === undefined) {\n return { id, spec, dataStatus: \"absent\" as ColumnDataStatus, data: undefined };\n }\n const isReady = accessor.getIsReadyOrError();\n return {\n id,\n spec,\n dataStatus: (isReady ? \"ready\" : \"computing\") as ColumnDataStatus,\n data: { get: () => (isReady ? accessor : undefined) },\n };\n}\n\n/**\n * Recursively walk the output tree starting from `accessor`.\n * - If a node's resourceType is PFrame → wrap it as OutputColumnProvider.\n * - If a node's resourceType is StdMap/std/map → recurse into its output fields.\n * - Otherwise → skip (leaf of unknown type).\n */\nfunction collectPFrameProviders(accessor: TreeNodeAccessor): ColumnSnapshotProvider[] {\n const out: ColumnSnapshotProvider[] = [];\n walkTree(accessor, out);\n return out;\n}\n\nfunction walkTree(node: TreeNodeAccessor, out: ColumnSnapshotProvider[]): void {\n const typeName = node.resourceType.name as ValueOf<typeof ResourceTypeName>;\n\n if (typeName === ResourceTypeName.PFrame) {\n out.push(new OutputColumnProvider(node));\n return;\n }\n\n if (typeName === ResourceTypeName.StdMap || typeName === ResourceTypeName.StdMapSlash) {\n for (const field of node.listInputFields()) {\n const child = node.resolve(field);\n if (child) walkTree(child, out);\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;AAmBA,SAAgB,kCACd,KAC0B;CAC1B,MAAM,YAAsC,EAAE;AAG9C,WAAU,KAAK,IAAI,iCAAiC,IAAI,WAAW,CAAC;CAGpE,MAAM,UAAU,IAAI;AACpB,KAAI,QACF,WAAU,KAAK,GAAG,uBAAuB,QAAQ,CAAC;CAIpD,MAAM,SAAS,IAAI;AACnB,KAAI,OACF,WAAU,KAAK,GAAG,uBAAuB,OAAO,CAAC;AAGnD,QAAO;;;;;;;;;;AAWT,IAAa,mCAAb,MAAgF;CAC9E,YAAY,MAAmC;AAAlB,OAAA,OAAA;;CAE7B,gBAA6C;AAE3C,SADiB,KAAK,KAAK,oBAAoB,KAAK,CACpC,KAAK,QAAQ,WAAW,IAAI,IAAI,IAAI,MAAM,IAAI,KAAK,CAAC;;CAGtE,uBAAgC;AAC9B,SAAO;;;AAIX,SAAS,WACP,IACA,MACA,UAC2B;AAC3B,KAAI,aAAa,KAAA,EACf,QAAO;EAAE;EAAI;EAAM,YAAY;EAA8B,MAAM,KAAA;EAAW;CAEhF,MAAM,UAAU,SAAS,mBAAmB;AAC5C,QAAO;EACL;EACA;EACA,YAAa,UAAU,UAAU;EACjC,MAAM,EAAE,WAAY,UAAU,WAAW,KAAA,GAAY;EACtD;;;;;;;;AASH,SAAS,uBAAuB,UAAsD;CACpF,MAAM,MAAgC,EAAE;AACxC,UAAS,UAAU,IAAI;AACvB,QAAO;;AAGT,SAAS,SAAS,MAAwB,KAAqC;CAC7E,MAAM,WAAW,KAAK,aAAa;AAEnC,KAAI,aAAa,iBAAiB,QAAQ;AACxC,MAAI,KAAK,IAAI,qBAAqB,KAAK,CAAC;AACxC;;AAGF,KAAI,aAAa,iBAAiB,UAAU,aAAa,iBAAiB,YACxE,MAAK,MAAM,SAAS,KAAK,iBAAiB,EAAE;EAC1C,MAAM,QAAQ,KAAK,QAAQ,MAAM;AACjC,MAAI,MAAO,UAAS,OAAO,IAAI"}
1
+ {"version":3,"file":"ctx_column_sources.js","names":[],"sources":["../../src/columns/ctx_column_sources.ts"],"sourcesContent":["import type { PColumnSpec, PObjectId } from \"@milaboratories/pl-model-common\";\nimport { TreeNodeAccessor } from \"../render/accessor\";\nimport type { RenderCtxBase, ResultPool } from \"../render\";\nimport type { ColumnSnapshot } from \"./column_snapshot\";\nimport type { ColumnDataStatus } from \"./column_snapshot\";\nimport type { ColumnSnapshotProvider } from \"./column_snapshot_provider\";\nimport { OutputColumnProvider } from \"./column_snapshot_provider\";\nimport { ResourceTypeName } from \"@milaboratories/pl-model-common\";\nimport type { ValueOf } from \"@milaboratories/helpers\";\n\n/**\n * Collect ColumnSnapshotProviders from all render context sources:\n *\n * - **resultPool** — all upstream columns (always included)\n * - **outputs** — PFrame fields from block execution outputs\n * - **prerun** — PFrame fields from prerun/staging results\n *\n * Returns an array of providers suitable for `ColumnCollectionBuilder.addSource()`.\n */\nexport function collectCtxColumnSnapshotProviders(ctx: RenderCtxBase): ColumnSnapshotProvider[] {\n const providers: ColumnSnapshotProvider[] = [];\n\n // ResultPool — all upstream columns\n providers.push(new ResultPoolColumnSnapshotProvider(ctx.resultPool));\n\n // Outputs — each PFrame-like output field becomes a provider\n const outputs = ctx.outputs;\n if (outputs) {\n providers.push(...collectPFrameProviders(outputs));\n }\n\n // Prerun — same treatment as outputs\n const prerun = ctx.prerun;\n if (prerun) {\n providers.push(...collectPFrameProviders(prerun));\n }\n\n return providers;\n}\n\n/**\n * Adapter wrapping ResultPool into the new ColumnSnapshotProvider interface.\n *\n * - `isColumnListComplete()` always returns true — the result pool\n * is a stable snapshot within a single render cycle.\n * - Data status is derived from the underlying TreeNodeAccessor:\n * ready (getIsReadyOrError), computing, or absent (no data resource).\n */\nexport class ResultPoolColumnSnapshotProvider implements ColumnSnapshotProvider {\n constructor(private readonly pool: ResultPool) {}\n\n getAllColumns(): ColumnSnapshot<PObjectId>[] {\n const pColumns = this.pool.selectColumns(() => true);\n return pColumns.map((col) => toSnapshot(col.id, col.spec, col.data));\n }\n\n isColumnListComplete(): boolean {\n return true;\n }\n}\n\nfunction toSnapshot(\n id: PObjectId,\n spec: PColumnSpec,\n accessor: TreeNodeAccessor | undefined,\n): ColumnSnapshot<PObjectId> {\n if (accessor === undefined) {\n return { id, spec, dataStatus: \"absent\" as ColumnDataStatus, data: undefined };\n }\n const isReady = accessor.getIsReadyOrError();\n return {\n id,\n spec,\n dataStatus: (isReady ? \"ready\" : \"computing\") as ColumnDataStatus,\n data: { get: () => (isReady ? accessor : undefined) },\n };\n}\n\n/**\n * Recursively walk the output tree starting from `accessor`.\n * - If a node's resourceType is PFrame → wrap it as OutputColumnProvider.\n * - If a node's resourceType is StdMap/std/map → recurse into its output fields.\n * - Otherwise → skip (leaf of unknown type).\n */\nfunction collectPFrameProviders(accessor: TreeNodeAccessor): ColumnSnapshotProvider[] {\n const out: ColumnSnapshotProvider[] = [];\n walkTree(accessor, out);\n return out;\n}\n\nfunction walkTree(node: TreeNodeAccessor, out: ColumnSnapshotProvider[]): void {\n const typeName = node.resourceType.name as ValueOf<typeof ResourceTypeName>;\n\n if (typeName === ResourceTypeName.PFrame) {\n out.push(new OutputColumnProvider(node));\n return;\n }\n\n if (typeName === ResourceTypeName.StdMap || typeName === ResourceTypeName.StdMapSlash) {\n for (const field of node.listInputFields()) {\n const child = node.resolve(field);\n if (child) walkTree(child, out);\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;AAmBA,SAAgB,kCAAkC,KAA8C;CAC9F,MAAM,YAAsC,EAAE;AAG9C,WAAU,KAAK,IAAI,iCAAiC,IAAI,WAAW,CAAC;CAGpE,MAAM,UAAU,IAAI;AACpB,KAAI,QACF,WAAU,KAAK,GAAG,uBAAuB,QAAQ,CAAC;CAIpD,MAAM,SAAS,IAAI;AACnB,KAAI,OACF,WAAU,KAAK,GAAG,uBAAuB,OAAO,CAAC;AAGnD,QAAO;;;;;;;;;;AAWT,IAAa,mCAAb,MAAgF;CAC9E,YAAY,MAAmC;AAAlB,OAAA,OAAA;;CAE7B,gBAA6C;AAE3C,SADiB,KAAK,KAAK,oBAAoB,KAAK,CACpC,KAAK,QAAQ,WAAW,IAAI,IAAI,IAAI,MAAM,IAAI,KAAK,CAAC;;CAGtE,uBAAgC;AAC9B,SAAO;;;AAIX,SAAS,WACP,IACA,MACA,UAC2B;AAC3B,KAAI,aAAa,KAAA,EACf,QAAO;EAAE;EAAI;EAAM,YAAY;EAA8B,MAAM,KAAA;EAAW;CAEhF,MAAM,UAAU,SAAS,mBAAmB;AAC5C,QAAO;EACL;EACA;EACA,YAAa,UAAU,UAAU;EACjC,MAAM,EAAE,WAAY,UAAU,WAAW,KAAA,GAAY;EACtD;;;;;;;;AASH,SAAS,uBAAuB,UAAsD;CACpF,MAAM,MAAgC,EAAE;AACxC,UAAS,UAAU,IAAI;AACvB,QAAO;;AAGT,SAAS,SAAS,MAAwB,KAAqC;CAC7E,MAAM,WAAW,KAAK,aAAa;AAEnC,KAAI,aAAa,iBAAiB,QAAQ;AACxC,MAAI,KAAK,IAAI,qBAAqB,KAAK,CAAC;AACxC;;AAGF,KAAI,aAAa,iBAAiB,UAAU,aAAa,iBAAiB,YACxE,MAAK,MAAM,SAAS,KAAK,iBAAiB,EAAE;EAC1C,MAAM,QAAQ,KAAK,QAAQ,MAAM;AACjC,MAAI,MAAO,UAAS,OAAO,IAAI"}
@@ -13,8 +13,8 @@ function createPTableDefV2(params) {
13
13
  }
14
14
  secondaryColumns.push(...params.labelColumns);
15
15
  return require_createPTableDefV3.createPTableDefV3({
16
- primaryColumns: coreColumns,
17
- secondaryGroups: secondaryColumns.map((c) => [c]),
16
+ primary: coreColumns.map((column) => ({ column })),
17
+ secondary: secondaryColumns.map((column) => ({ entries: [{ column }] })),
18
18
  primaryJoinType: params.coreJoinType,
19
19
  filters: params.filters,
20
20
  sorting: params.sorting
@@ -1 +1 @@
1
- {"version":3,"file":"createPTableDefV2.cjs","names":["createPTableDefV3"],"sources":["../../../../src/components/PlDataTable/createPlDataTable/createPTableDefV2.ts"],"sourcesContent":["import type {\n PColumn,\n PColumnIdAndSpec,\n PTableSorting,\n PTableDefV2,\n DataInfo,\n PColumnValues,\n} from \"@milaboratories/pl-model-common\";\nimport { getColumnIdAndSpec } from \"@milaboratories/pl-model-common\";\nimport type { PColumnDataUniversal, TreeNodeAccessor } from \"../../../render\";\nimport { isFunction } from \"es-toolkit\";\nimport type { PlDataTableFilters } from \"../typesV5\";\nimport { createPTableDefV3 } from \"./createPTableDefV3\";\n\nexport function createPTableDefV2(params: {\n columns: PColumn<PColumnDataUniversal>[];\n labelColumns: PColumn<PColumnDataUniversal>[];\n coreJoinType: \"inner\" | \"full\";\n filters: null | PlDataTableFilters;\n sorting: PTableSorting[];\n coreColumnPredicate?: (spec: PColumnIdAndSpec) => boolean;\n}): PTableDefV2<PColumn<TreeNodeAccessor | PColumnValues | DataInfo<TreeNodeAccessor>>> {\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 primaryColumns: coreColumns,\n secondaryGroups: secondaryColumns.map((c) => [c]),\n primaryJoinType: params.coreJoinType,\n filters: params.filters,\n sorting: params.sorting,\n });\n}\n"],"mappings":";;;;;AAcA,SAAgB,kBAAkB,QAOsD;CACtF,IAAI,cAAc,OAAO;CACzB,MAAM,mBAA0C,EAAE;AAElD,MAAA,GAAA,WAAA,YAAe,OAAO,oBAAoB,EAAE;AAC1C,gBAAc,EAAE;AAChB,OAAK,MAAM,KAAK,OAAO,QACrB,KAAI,OAAO,qBAAA,GAAA,gCAAA,oBAAuC,EAAE,CAAC,CAAE,aAAY,KAAK,EAAE;MACrE,kBAAiB,KAAK,EAAE;;AAGjC,kBAAiB,KAAK,GAAG,OAAO,aAAa;AAE7C,QAAOA,0BAAAA,kBAAkB;EACvB,gBAAgB;EAChB,iBAAiB,iBAAiB,KAAK,MAAM,CAAC,EAAE,CAAC;EACjD,iBAAiB,OAAO;EACxB,SAAS,OAAO;EAChB,SAAS,OAAO;EACjB,CAAC"}
1
+ {"version":3,"file":"createPTableDefV2.cjs","names":["createPTableDefV3"],"sources":["../../../../src/components/PlDataTable/createPlDataTable/createPTableDefV2.ts"],"sourcesContent":["import type {\n PColumn,\n PColumnIdAndSpec,\n PTableSorting,\n PTableDefV2,\n DataInfo,\n PColumnValues,\n} from \"@milaboratories/pl-model-common\";\nimport { getColumnIdAndSpec } from \"@milaboratories/pl-model-common\";\nimport type { PColumnDataUniversal, TreeNodeAccessor } from \"../../../render\";\nimport { isFunction } from \"es-toolkit\";\nimport type { PlDataTableFilters } from \"../typesV5\";\nimport { createPTableDefV3 } from \"./createPTableDefV3\";\n\nexport function createPTableDefV2(params: {\n columns: PColumn<PColumnDataUniversal>[];\n labelColumns: PColumn<PColumnDataUniversal>[];\n coreJoinType: \"inner\" | \"full\";\n filters: null | PlDataTableFilters;\n sorting: PTableSorting[];\n coreColumnPredicate?: (spec: PColumnIdAndSpec) => boolean;\n}): PTableDefV2<PColumn<TreeNodeAccessor | PColumnValues | DataInfo<TreeNodeAccessor>>> {\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) => ({ column })),\n secondary: secondaryColumns.map((column) => ({ entries: [{ column }] })),\n primaryJoinType: params.coreJoinType,\n filters: params.filters,\n sorting: params.sorting,\n });\n}\n"],"mappings":";;;;;AAcA,SAAgB,kBAAkB,QAOsD;CACtF,IAAI,cAAc,OAAO;CACzB,MAAM,mBAA0C,EAAE;AAElD,MAAA,GAAA,WAAA,YAAe,OAAO,oBAAoB,EAAE;AAC1C,gBAAc,EAAE;AAChB,OAAK,MAAM,KAAK,OAAO,QACrB,KAAI,OAAO,qBAAA,GAAA,gCAAA,oBAAuC,EAAE,CAAC,CAAE,aAAY,KAAK,EAAE;MACrE,kBAAiB,KAAK,EAAE;;AAGjC,kBAAiB,KAAK,GAAG,OAAO,aAAa;AAE7C,QAAOA,0BAAAA,kBAAkB;EACvB,SAAS,YAAY,KAAK,YAAY,EAAE,QAAQ,EAAE;EAClD,WAAW,iBAAiB,KAAK,YAAY,EAAE,SAAS,CAAC,EAAE,QAAQ,CAAC,EAAE,EAAE;EACxE,iBAAiB,OAAO;EACxB,SAAS,OAAO;EAChB,SAAS,OAAO;EACjB,CAAC"}
@@ -12,8 +12,8 @@ function createPTableDefV2(params) {
12
12
  }
13
13
  secondaryColumns.push(...params.labelColumns);
14
14
  return createPTableDefV3({
15
- primaryColumns: coreColumns,
16
- secondaryGroups: secondaryColumns.map((c) => [c]),
15
+ primary: coreColumns.map((column) => ({ column })),
16
+ secondary: secondaryColumns.map((column) => ({ entries: [{ column }] })),
17
17
  primaryJoinType: params.coreJoinType,
18
18
  filters: params.filters,
19
19
  sorting: params.sorting
@@ -1 +1 @@
1
- {"version":3,"file":"createPTableDefV2.js","names":[],"sources":["../../../../src/components/PlDataTable/createPlDataTable/createPTableDefV2.ts"],"sourcesContent":["import type {\n PColumn,\n PColumnIdAndSpec,\n PTableSorting,\n PTableDefV2,\n DataInfo,\n PColumnValues,\n} from \"@milaboratories/pl-model-common\";\nimport { getColumnIdAndSpec } from \"@milaboratories/pl-model-common\";\nimport type { PColumnDataUniversal, TreeNodeAccessor } from \"../../../render\";\nimport { isFunction } from \"es-toolkit\";\nimport type { PlDataTableFilters } from \"../typesV5\";\nimport { createPTableDefV3 } from \"./createPTableDefV3\";\n\nexport function createPTableDefV2(params: {\n columns: PColumn<PColumnDataUniversal>[];\n labelColumns: PColumn<PColumnDataUniversal>[];\n coreJoinType: \"inner\" | \"full\";\n filters: null | PlDataTableFilters;\n sorting: PTableSorting[];\n coreColumnPredicate?: (spec: PColumnIdAndSpec) => boolean;\n}): PTableDefV2<PColumn<TreeNodeAccessor | PColumnValues | DataInfo<TreeNodeAccessor>>> {\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 primaryColumns: coreColumns,\n secondaryGroups: secondaryColumns.map((c) => [c]),\n primaryJoinType: params.coreJoinType,\n filters: params.filters,\n sorting: params.sorting,\n });\n}\n"],"mappings":";;;;AAcA,SAAgB,kBAAkB,QAOsD;CACtF,IAAI,cAAc,OAAO;CACzB,MAAM,mBAA0C,EAAE;AAElD,KAAI,WAAW,OAAO,oBAAoB,EAAE;AAC1C,gBAAc,EAAE;AAChB,OAAK,MAAM,KAAK,OAAO,QACrB,KAAI,OAAO,oBAAoB,mBAAmB,EAAE,CAAC,CAAE,aAAY,KAAK,EAAE;MACrE,kBAAiB,KAAK,EAAE;;AAGjC,kBAAiB,KAAK,GAAG,OAAO,aAAa;AAE7C,QAAO,kBAAkB;EACvB,gBAAgB;EAChB,iBAAiB,iBAAiB,KAAK,MAAM,CAAC,EAAE,CAAC;EACjD,iBAAiB,OAAO;EACxB,SAAS,OAAO;EAChB,SAAS,OAAO;EACjB,CAAC"}
1
+ {"version":3,"file":"createPTableDefV2.js","names":[],"sources":["../../../../src/components/PlDataTable/createPlDataTable/createPTableDefV2.ts"],"sourcesContent":["import type {\n PColumn,\n PColumnIdAndSpec,\n PTableSorting,\n PTableDefV2,\n DataInfo,\n PColumnValues,\n} from \"@milaboratories/pl-model-common\";\nimport { getColumnIdAndSpec } from \"@milaboratories/pl-model-common\";\nimport type { PColumnDataUniversal, TreeNodeAccessor } from \"../../../render\";\nimport { isFunction } from \"es-toolkit\";\nimport type { PlDataTableFilters } from \"../typesV5\";\nimport { createPTableDefV3 } from \"./createPTableDefV3\";\n\nexport function createPTableDefV2(params: {\n columns: PColumn<PColumnDataUniversal>[];\n labelColumns: PColumn<PColumnDataUniversal>[];\n coreJoinType: \"inner\" | \"full\";\n filters: null | PlDataTableFilters;\n sorting: PTableSorting[];\n coreColumnPredicate?: (spec: PColumnIdAndSpec) => boolean;\n}): PTableDefV2<PColumn<TreeNodeAccessor | PColumnValues | DataInfo<TreeNodeAccessor>>> {\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) => ({ column })),\n secondary: secondaryColumns.map((column) => ({ entries: [{ column }] })),\n primaryJoinType: params.coreJoinType,\n filters: params.filters,\n sorting: params.sorting,\n });\n}\n"],"mappings":";;;;AAcA,SAAgB,kBAAkB,QAOsD;CACtF,IAAI,cAAc,OAAO;CACzB,MAAM,mBAA0C,EAAE;AAElD,KAAI,WAAW,OAAO,oBAAoB,EAAE;AAC1C,gBAAc,EAAE;AAChB,OAAK,MAAM,KAAK,OAAO,QACrB,KAAI,OAAO,oBAAoB,mBAAmB,EAAE,CAAC,CAAE,aAAY,KAAK,EAAE;MACrE,kBAAiB,KAAK,EAAE;;AAGjC,kBAAiB,KAAK,GAAG,OAAO,aAAa;AAE7C,QAAO,kBAAkB;EACvB,SAAS,YAAY,KAAK,YAAY,EAAE,QAAQ,EAAE;EAClD,WAAW,iBAAiB,KAAK,YAAY,EAAE,SAAS,CAAC,EAAE,QAAQ,CAAC,EAAE,EAAE;EACxE,iBAAiB,OAAO;EACxB,SAAS,OAAO;EAChB,SAAS,OAAO;EACjB,CAAC"}