@platforma-sdk/model 1.63.12 → 1.65.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (162) hide show
  1. package/dist/columns/column_collection_builder.cjs +105 -92
  2. package/dist/columns/column_collection_builder.cjs.map +1 -1
  3. package/dist/columns/column_collection_builder.d.ts +13 -12
  4. package/dist/columns/column_collection_builder.d.ts.map +1 -1
  5. package/dist/columns/column_collection_builder.js +107 -94
  6. package/dist/columns/column_collection_builder.js.map +1 -1
  7. package/dist/columns/column_selector.cjs +8 -80
  8. package/dist/columns/column_selector.cjs.map +1 -1
  9. package/dist/columns/column_selector.d.ts +6 -14
  10. package/dist/columns/column_selector.d.ts.map +1 -1
  11. package/dist/columns/column_selector.js +6 -77
  12. package/dist/columns/column_selector.js.map +1 -1
  13. package/dist/columns/column_snapshot.cjs +3 -3
  14. package/dist/columns/column_snapshot.cjs.map +1 -1
  15. package/dist/columns/column_snapshot.d.ts +3 -3
  16. package/dist/columns/column_snapshot.d.ts.map +1 -1
  17. package/dist/columns/column_snapshot.js +3 -3
  18. package/dist/columns/column_snapshot.js.map +1 -1
  19. package/dist/columns/column_snapshot_provider.cjs +1 -1
  20. package/dist/columns/column_snapshot_provider.cjs.map +1 -1
  21. package/dist/columns/column_snapshot_provider.d.ts +8 -8
  22. package/dist/columns/column_snapshot_provider.d.ts.map +1 -1
  23. package/dist/columns/column_snapshot_provider.js +1 -1
  24. package/dist/columns/column_snapshot_provider.js.map +1 -1
  25. package/dist/columns/ctx_column_sources.cjs.map +1 -1
  26. package/dist/columns/ctx_column_sources.d.ts +2 -1
  27. package/dist/columns/ctx_column_sources.d.ts.map +1 -1
  28. package/dist/columns/ctx_column_sources.js.map +1 -1
  29. package/dist/columns/expand_by_partition.cjs +106 -0
  30. package/dist/columns/expand_by_partition.cjs.map +1 -0
  31. package/dist/columns/expand_by_partition.d.ts +33 -0
  32. package/dist/columns/expand_by_partition.d.ts.map +1 -0
  33. package/dist/columns/expand_by_partition.js +105 -0
  34. package/dist/columns/expand_by_partition.js.map +1 -0
  35. package/dist/columns/index.cjs +1 -0
  36. package/dist/columns/index.d.ts +4 -3
  37. package/dist/columns/index.js +1 -0
  38. package/dist/components/PlDataTable/createPlDataTable/createPTableDefV2.cjs +26 -0
  39. package/dist/components/PlDataTable/createPlDataTable/createPTableDefV2.cjs.map +1 -0
  40. package/dist/components/PlDataTable/createPlDataTable/createPTableDefV2.js +25 -0
  41. package/dist/components/PlDataTable/createPlDataTable/createPTableDefV2.js.map +1 -0
  42. package/dist/components/PlDataTable/createPlDataTable/createPTableDefV3.cjs +68 -0
  43. package/dist/components/PlDataTable/createPlDataTable/createPTableDefV3.cjs.map +1 -0
  44. package/dist/components/PlDataTable/createPlDataTable/createPTableDefV3.js +67 -0
  45. package/dist/components/PlDataTable/createPlDataTable/createPTableDefV3.js.map +1 -0
  46. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV2.cjs +27 -17
  47. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV2.cjs.map +1 -1
  48. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV2.d.ts +4 -0
  49. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV2.d.ts.map +1 -1
  50. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV2.js +28 -18
  51. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV2.js.map +1 -1
  52. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.cjs +258 -175
  53. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.cjs.map +1 -1
  54. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.d.ts +37 -21
  55. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.d.ts.map +1 -1
  56. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.js +261 -175
  57. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.js.map +1 -1
  58. package/dist/components/PlDataTable/createPlDataTable/discoverColumns.cjs +64 -0
  59. package/dist/components/PlDataTable/createPlDataTable/discoverColumns.cjs.map +1 -0
  60. package/dist/components/PlDataTable/createPlDataTable/discoverColumns.d.ts +17 -0
  61. package/dist/components/PlDataTable/createPlDataTable/discoverColumns.d.ts.map +1 -0
  62. package/dist/components/PlDataTable/createPlDataTable/discoverColumns.js +63 -0
  63. package/dist/components/PlDataTable/createPlDataTable/discoverColumns.js.map +1 -0
  64. package/dist/components/PlDataTable/createPlDataTable/index.cjs +2 -1
  65. package/dist/components/PlDataTable/createPlDataTable/index.cjs.map +1 -1
  66. package/dist/components/PlDataTable/createPlDataTable/index.d.ts +2 -1
  67. package/dist/components/PlDataTable/createPlDataTable/index.d.ts.map +1 -1
  68. package/dist/components/PlDataTable/createPlDataTable/index.js +2 -1
  69. package/dist/components/PlDataTable/createPlDataTable/index.js.map +1 -1
  70. package/dist/components/PlDataTable/createPlDataTable/utils.cjs +109 -0
  71. package/dist/components/PlDataTable/createPlDataTable/utils.cjs.map +1 -0
  72. package/dist/components/PlDataTable/createPlDataTable/utils.d.ts +19 -0
  73. package/dist/components/PlDataTable/createPlDataTable/utils.d.ts.map +1 -0
  74. package/dist/components/PlDataTable/createPlDataTable/utils.js +102 -0
  75. package/dist/components/PlDataTable/createPlDataTable/utils.js.map +1 -0
  76. package/dist/components/PlDataTable/index.cjs +3 -1
  77. package/dist/components/PlDataTable/index.d.ts +5 -3
  78. package/dist/components/PlDataTable/index.js +3 -1
  79. package/dist/components/PlDataTable/labels.cjs +25 -11
  80. package/dist/components/PlDataTable/labels.cjs.map +1 -1
  81. package/dist/components/PlDataTable/labels.js +25 -11
  82. package/dist/components/PlDataTable/labels.js.map +1 -1
  83. package/dist/components/PlDataTable/state-migration.cjs +8 -2
  84. package/dist/components/PlDataTable/state-migration.cjs.map +1 -1
  85. package/dist/components/PlDataTable/state-migration.d.ts.map +1 -1
  86. package/dist/components/PlDataTable/state-migration.js +8 -2
  87. package/dist/components/PlDataTable/state-migration.js.map +1 -1
  88. package/dist/components/PlDataTable/typesV5.d.ts +23 -15
  89. package/dist/components/PlDataTable/typesV5.d.ts.map +1 -1
  90. package/dist/components/index.cjs +3 -1
  91. package/dist/components/index.d.ts +4 -2
  92. package/dist/components/index.js +3 -1
  93. package/dist/index.cjs +13 -9
  94. package/dist/index.d.ts +9 -7
  95. package/dist/index.js +6 -4
  96. package/dist/labels/derive_distinct_labels.cjs +39 -27
  97. package/dist/labels/derive_distinct_labels.cjs.map +1 -1
  98. package/dist/labels/derive_distinct_labels.d.ts +15 -15
  99. package/dist/labels/derive_distinct_labels.d.ts.map +1 -1
  100. package/dist/labels/derive_distinct_labels.js +39 -27
  101. package/dist/labels/derive_distinct_labels.js.map +1 -1
  102. package/dist/labels/index.cjs +0 -1
  103. package/dist/labels/index.d.ts +1 -2
  104. package/dist/labels/index.js +0 -1
  105. package/dist/package.cjs +1 -1
  106. package/dist/package.js +1 -1
  107. package/dist/render/api.cjs +10 -3
  108. package/dist/render/api.cjs.map +1 -1
  109. package/dist/render/api.d.ts +2 -2
  110. package/dist/render/api.d.ts.map +1 -1
  111. package/dist/render/api.js +10 -3
  112. package/dist/render/api.js.map +1 -1
  113. package/dist/render/util/column_collection.cjs +3 -3
  114. package/dist/render/util/column_collection.cjs.map +1 -1
  115. package/dist/render/util/column_collection.d.ts.map +1 -1
  116. package/dist/render/util/column_collection.js +3 -3
  117. package/dist/render/util/column_collection.js.map +1 -1
  118. package/dist/render/util/label.cjs +2 -2
  119. package/dist/render/util/label.cjs.map +1 -1
  120. package/dist/render/util/label.js +2 -2
  121. package/dist/render/util/label.js.map +1 -1
  122. package/dist/render/util/pcolumn_data.cjs.map +1 -1
  123. package/dist/render/util/pcolumn_data.d.ts +2 -2
  124. package/dist/render/util/pcolumn_data.d.ts.map +1 -1
  125. package/dist/render/util/pcolumn_data.js.map +1 -1
  126. package/package.json +7 -7
  127. package/src/columns/column_collection_builder.test.ts +40 -27
  128. package/src/columns/column_collection_builder.ts +176 -131
  129. package/src/columns/column_selector.test.ts +17 -399
  130. package/src/columns/column_selector.ts +14 -127
  131. package/src/columns/column_snapshot.ts +5 -5
  132. package/src/columns/column_snapshot_provider.ts +11 -10
  133. package/src/columns/ctx_column_sources.ts +2 -2
  134. package/src/columns/expand_by_partition.test.ts +4 -4
  135. package/src/columns/expand_by_partition.ts +4 -3
  136. package/src/columns/index.ts +1 -0
  137. package/src/components/PlDataTable/createPlDataTable/createPTableDefV2.ts +42 -0
  138. package/src/components/PlDataTable/createPlDataTable/createPTableDefV3.ts +89 -0
  139. package/src/components/PlDataTable/createPlDataTable/createPlDataTableV2.ts +51 -19
  140. package/src/components/PlDataTable/createPlDataTable/createPlDataTableV3.ts +500 -313
  141. package/src/components/PlDataTable/createPlDataTable/discoverColumns.ts +122 -0
  142. package/src/components/PlDataTable/createPlDataTable/index.ts +4 -2
  143. package/src/components/PlDataTable/createPlDataTable/utils.test.ts +257 -0
  144. package/src/components/PlDataTable/createPlDataTable/utils.ts +160 -0
  145. package/src/components/PlDataTable/index.ts +15 -2
  146. package/src/components/PlDataTable/labels.ts +29 -18
  147. package/src/components/PlDataTable/state-migration.ts +6 -1
  148. package/src/components/PlDataTable/typesV5.ts +25 -12
  149. package/src/labels/derive_distinct_labels.test.ts +143 -45
  150. package/src/labels/derive_distinct_labels.ts +102 -49
  151. package/src/labels/index.ts +0 -1
  152. package/src/render/api.ts +15 -5
  153. package/src/render/util/column_collection.ts +4 -3
  154. package/src/render/util/label.ts +2 -2
  155. package/src/render/util/pcolumn_data.ts +5 -3
  156. package/dist/labels/write_labels_to_specs.cjs +0 -14
  157. package/dist/labels/write_labels_to_specs.cjs.map +0 -1
  158. package/dist/labels/write_labels_to_specs.d.ts +0 -7
  159. package/dist/labels/write_labels_to_specs.d.ts.map +0 -1
  160. package/dist/labels/write_labels_to_specs.js +0 -13
  161. package/dist/labels/write_labels_to_specs.js.map +0 -1
  162. package/src/labels/write_labels_to_specs.ts +0 -12
@@ -18,7 +18,7 @@ function normalizeRecord(input) {
18
18
  function normalizeTypes(input) {
19
19
  return Array.isArray(input) ? input : [input];
20
20
  }
21
- function normalizeAxisSelector(input) {
21
+ function convertRelaxedAxisSelectorToMultiAxisSelector(input) {
22
22
  const result = {};
23
23
  if (input.name !== void 0) result.name = normalizeStringMatchers(input.name);
24
24
  if (input.type !== void 0) result.type = normalizeTypes(input.type);
@@ -27,92 +27,21 @@ function normalizeAxisSelector(input) {
27
27
  if (input.annotations !== void 0) result.annotations = normalizeRecord(input.annotations);
28
28
  return result;
29
29
  }
30
- /** Normalize relaxed input to strict ColumnSelector[]. */
31
- function normalizeSelectors(input) {
32
- return (Array.isArray(input) ? input : [input]).map(normalizeSingleSelector);
33
- }
34
- function normalizeSingleSelector(input) {
30
+ function convertRelaxedColumnSelectorToMultiColumnSelector(input) {
35
31
  const result = {};
36
32
  if (input.name !== void 0) result.name = normalizeStringMatchers(input.name);
37
33
  if (input.type !== void 0) result.type = normalizeTypes(input.type);
38
34
  if (input.domain !== void 0) result.domain = normalizeRecord(input.domain);
39
35
  if (input.contextDomain !== void 0) result.contextDomain = normalizeRecord(input.contextDomain);
40
36
  if (input.annotations !== void 0) result.annotations = normalizeRecord(input.annotations);
41
- if (input.axes !== void 0) result.axes = input.axes.map(normalizeAxisSelector);
37
+ if (input.axes !== void 0) result.axes = input.axes.map(convertRelaxedAxisSelectorToMultiAxisSelector);
42
38
  if (input.partialAxesMatch !== void 0) result.partialAxesMatch = input.partialAxesMatch;
43
39
  return result;
44
40
  }
45
- function matchStringValue(value, matchers) {
46
- return matchers.some((m) => {
47
- if (m.type === "exact") return value === m.value;
48
- return new RegExp(`^(?:${m.value})$`).test(value);
49
- });
50
- }
51
- function matchRecordField(actual, required) {
52
- const record = actual ?? {};
53
- for (const [key, matchers] of Object.entries(required)) {
54
- const value = record[key];
55
- if (value === void 0) return false;
56
- if (!matchStringValue(value, matchers)) return false;
57
- }
58
- return true;
59
- }
60
- /** Get combined domain: column's own domain merged with all axis domains. */
61
- function getCombinedDomain(spec) {
62
- const result = {};
63
- if (spec.domain) Object.assign(result, spec.domain);
64
- for (const axis of spec.axesSpec) if (axis.domain) Object.assign(result, axis.domain);
65
- return result;
66
- }
67
- /** Get combined context domain: column's own contextDomain merged with all axis contextDomains. */
68
- function getCombinedContextDomain(spec) {
69
- const result = {};
70
- if (spec.contextDomain) Object.assign(result, spec.contextDomain);
71
- for (const axis of spec.axesSpec) if ("contextDomain" in axis && axis.contextDomain) Object.assign(result, axis.contextDomain);
72
- return result;
73
- }
74
- function matchAxisSelector(axis, selector) {
75
- if (selector.name !== void 0 && !matchStringValue(axis.name, selector.name)) return false;
76
- if (selector.type !== void 0 && !selector.type.includes(axis.type)) return false;
77
- if (selector.domain !== void 0 && !matchRecordField(axis.domain, selector.domain)) return false;
78
- if (selector.contextDomain !== void 0 && !matchRecordField("contextDomain" in axis ? axis.contextDomain : void 0, selector.contextDomain)) return false;
79
- if (selector.annotations !== void 0 && !matchRecordField(axis.annotations, selector.annotations)) return false;
80
- return true;
81
- }
82
- /** Check if a PColumnSpec matches a single strict ColumnSelector. */
83
- function matchColumn(spec, selector) {
84
- if (selector.name !== void 0 && !matchStringValue(spec.name, selector.name)) return false;
85
- if (selector.type !== void 0 && !selector.type.includes(spec.valueType)) return false;
86
- if (selector.domain !== void 0) {
87
- if (!matchRecordField(getCombinedDomain(spec), selector.domain)) return false;
88
- }
89
- if (selector.contextDomain !== void 0) {
90
- if (!matchRecordField(getCombinedContextDomain(spec), selector.contextDomain)) return false;
91
- }
92
- if (selector.annotations !== void 0) {
93
- if (!matchRecordField(spec.annotations, selector.annotations)) return false;
94
- }
95
- if (selector.axes !== void 0) if (selector.partialAxesMatch ?? true) {
96
- for (const axisSel of selector.axes) if (!spec.axesSpec.some((axis) => matchAxisSelector(axis, axisSel))) return false;
97
- } else {
98
- if (spec.axesSpec.length !== selector.axes.length) return false;
99
- for (let i = 0; i < selector.axes.length; i++) if (!matchAxisSelector(spec.axesSpec[i], selector.axes[i])) return false;
100
- }
101
- return true;
102
- }
103
- /** Check if a PColumnSpec matches any of the selectors (OR across array). */
104
- function matchColumnSelectors(selectors, spec) {
105
- return selectors.some((sel) => matchColumn(spec, sel));
106
- }
107
- /**
108
- * Convert selector input to a predicate function.
109
- * Normalizes relaxed form, then returns a function that OR-matches.
110
- */
111
- function columnSelectorsToPredicate(input) {
112
- const selectors = normalizeSelectors(input);
113
- return (spec) => matchColumnSelectors(selectors, spec);
41
+ function convertColumnSelectorToMultiColumnSelector(input) {
42
+ return (Array.isArray(input) ? input : [input]).map(convertRelaxedColumnSelectorToMultiColumnSelector);
114
43
  }
115
44
  //#endregion
116
- export { columnSelectorsToPredicate, matchColumn, matchColumnSelectors, normalizeSelectors };
45
+ export { convertColumnSelectorToMultiColumnSelector, convertRelaxedAxisSelectorToMultiAxisSelector, convertRelaxedColumnSelectorToMultiColumnSelector };
117
46
 
118
47
  //# sourceMappingURL=column_selector.js.map
@@ -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 PColumnSpec,\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 ColumnSelectorInput = 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\nfunction normalizeAxisSelector(input: RelaxedAxisSelector): 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\n/** Normalize relaxed input to strict ColumnSelector[]. */\nexport function normalizeSelectors(input: ColumnSelectorInput): MultiColumnSelector[] {\n const arr = Array.isArray(input) ? input : [input];\n return arr.map(normalizeSingleSelector);\n}\n\nfunction normalizeSingleSelector(input: RelaxedColumnSelector): 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) result.axes = input.axes.map(normalizeAxisSelector);\n if (input.partialAxesMatch !== undefined) result.partialAxesMatch = input.partialAxesMatch;\n return result;\n}\n\n// --- Matching ---\n\nfunction matchStringValue(value: string, matchers: StringMatcher[]): boolean {\n return matchers.some((m) => {\n if (m.type === \"exact\") return value === m.value;\n return new RegExp(`^(?:${m.value})$`).test(value);\n });\n}\n\nfunction matchRecordField(\n actual: Record<string, string> | undefined,\n required: Record<string, StringMatcher[]>,\n): boolean {\n const record = actual ?? {};\n for (const [key, matchers] of Object.entries(required)) {\n const value = record[key];\n if (value === undefined) return false;\n if (!matchStringValue(value, matchers)) return false;\n }\n return true;\n}\n\n/** Get combined domain: column's own domain merged with all axis domains. */\nfunction getCombinedDomain(spec: PColumnSpec): Record<string, string> {\n const result: Record<string, string> = {};\n if (spec.domain) Object.assign(result, spec.domain);\n for (const axis of spec.axesSpec) {\n if (axis.domain) Object.assign(result, axis.domain);\n }\n return result;\n}\n\n/** Get combined context domain: column's own contextDomain merged with all axis contextDomains. */\nfunction getCombinedContextDomain(spec: PColumnSpec): Record<string, string> {\n const result: Record<string, string> = {};\n if (spec.contextDomain) Object.assign(result, spec.contextDomain);\n for (const axis of spec.axesSpec) {\n if (\"contextDomain\" in axis && axis.contextDomain) Object.assign(result, axis.contextDomain);\n }\n return result;\n}\n\nfunction matchAxisSelector(\n axis: PColumnSpec[\"axesSpec\"][number],\n selector: MultiAxisSelector,\n): boolean {\n if (selector.name !== undefined && !matchStringValue(axis.name, selector.name)) return false;\n if (selector.type !== undefined && !selector.type.includes(axis.type)) return false;\n if (selector.domain !== undefined && !matchRecordField(axis.domain, selector.domain))\n return false;\n if (\n selector.contextDomain !== undefined &&\n !matchRecordField(\n \"contextDomain\" in axis ? (axis.contextDomain as Record<string, string>) : undefined,\n selector.contextDomain,\n )\n )\n return false;\n if (\n selector.annotations !== undefined &&\n !matchRecordField(axis.annotations, selector.annotations)\n )\n return false;\n return true;\n}\n\n/** Check if a PColumnSpec matches a single strict ColumnSelector. */\nexport function matchColumn(spec: PColumnSpec, selector: MultiColumnSelector): boolean {\n if (selector.name !== undefined && !matchStringValue(spec.name, selector.name)) return false;\n if (selector.type !== undefined && !selector.type.includes(spec.valueType)) return false;\n\n if (selector.domain !== undefined) {\n const combined = getCombinedDomain(spec);\n if (!matchRecordField(combined, selector.domain)) return false;\n }\n\n if (selector.contextDomain !== undefined) {\n const combined = getCombinedContextDomain(spec);\n if (!matchRecordField(combined, selector.contextDomain)) return false;\n }\n\n if (selector.annotations !== undefined) {\n if (!matchRecordField(spec.annotations, selector.annotations)) return false;\n }\n\n if (selector.axes !== undefined) {\n const partialMatch = selector.partialAxesMatch ?? true;\n if (partialMatch) {\n for (const axisSel of selector.axes) {\n if (!spec.axesSpec.some((axis) => matchAxisSelector(axis, axisSel))) return false;\n }\n } else {\n if (spec.axesSpec.length !== selector.axes.length) return false;\n for (let i = 0; i < selector.axes.length; i++) {\n if (!matchAxisSelector(spec.axesSpec[i], selector.axes[i])) return false;\n }\n }\n }\n\n return true;\n}\n\n/** Check if a PColumnSpec matches any of the selectors (OR across array). */\nexport function matchColumnSelectors(selectors: MultiColumnSelector[], spec: PColumnSpec): boolean {\n return selectors.some((sel) => matchColumn(spec, sel));\n}\n\n/**\n * Convert selector input to a predicate function.\n * Normalizes relaxed form, then returns a function that OR-matches.\n */\nexport function columnSelectorsToPredicate(\n input: ColumnSelectorInput,\n): (spec: PColumnSpec) => boolean {\n const selectors = normalizeSelectors(input);\n return (spec) => matchColumnSelectors(selectors, spec);\n}\n"],"mappings":";AA4CA,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,SAAS,sBAAsB,OAA+C;CAC5E,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;;;AAIT,SAAgB,mBAAmB,OAAmD;AAEpF,SADY,MAAM,QAAQ,MAAM,GAAG,QAAQ,CAAC,MAAM,EACvC,IAAI,wBAAwB;;AAGzC,SAAS,wBAAwB,OAAmD;CAClF,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,EAAW,QAAO,OAAO,MAAM,KAAK,IAAI,sBAAsB;AACjF,KAAI,MAAM,qBAAqB,KAAA,EAAW,QAAO,mBAAmB,MAAM;AAC1E,QAAO;;AAKT,SAAS,iBAAiB,OAAe,UAAoC;AAC3E,QAAO,SAAS,MAAM,MAAM;AAC1B,MAAI,EAAE,SAAS,QAAS,QAAO,UAAU,EAAE;AAC3C,SAAO,IAAI,OAAO,OAAO,EAAE,MAAM,IAAI,CAAC,KAAK,MAAM;GACjD;;AAGJ,SAAS,iBACP,QACA,UACS;CACT,MAAM,SAAS,UAAU,EAAE;AAC3B,MAAK,MAAM,CAAC,KAAK,aAAa,OAAO,QAAQ,SAAS,EAAE;EACtD,MAAM,QAAQ,OAAO;AACrB,MAAI,UAAU,KAAA,EAAW,QAAO;AAChC,MAAI,CAAC,iBAAiB,OAAO,SAAS,CAAE,QAAO;;AAEjD,QAAO;;;AAIT,SAAS,kBAAkB,MAA2C;CACpE,MAAM,SAAiC,EAAE;AACzC,KAAI,KAAK,OAAQ,QAAO,OAAO,QAAQ,KAAK,OAAO;AACnD,MAAK,MAAM,QAAQ,KAAK,SACtB,KAAI,KAAK,OAAQ,QAAO,OAAO,QAAQ,KAAK,OAAO;AAErD,QAAO;;;AAIT,SAAS,yBAAyB,MAA2C;CAC3E,MAAM,SAAiC,EAAE;AACzC,KAAI,KAAK,cAAe,QAAO,OAAO,QAAQ,KAAK,cAAc;AACjE,MAAK,MAAM,QAAQ,KAAK,SACtB,KAAI,mBAAmB,QAAQ,KAAK,cAAe,QAAO,OAAO,QAAQ,KAAK,cAAc;AAE9F,QAAO;;AAGT,SAAS,kBACP,MACA,UACS;AACT,KAAI,SAAS,SAAS,KAAA,KAAa,CAAC,iBAAiB,KAAK,MAAM,SAAS,KAAK,CAAE,QAAO;AACvF,KAAI,SAAS,SAAS,KAAA,KAAa,CAAC,SAAS,KAAK,SAAS,KAAK,KAAK,CAAE,QAAO;AAC9E,KAAI,SAAS,WAAW,KAAA,KAAa,CAAC,iBAAiB,KAAK,QAAQ,SAAS,OAAO,CAClF,QAAO;AACT,KACE,SAAS,kBAAkB,KAAA,KAC3B,CAAC,iBACC,mBAAmB,OAAQ,KAAK,gBAA2C,KAAA,GAC3E,SAAS,cACV,CAED,QAAO;AACT,KACE,SAAS,gBAAgB,KAAA,KACzB,CAAC,iBAAiB,KAAK,aAAa,SAAS,YAAY,CAEzD,QAAO;AACT,QAAO;;;AAIT,SAAgB,YAAY,MAAmB,UAAwC;AACrF,KAAI,SAAS,SAAS,KAAA,KAAa,CAAC,iBAAiB,KAAK,MAAM,SAAS,KAAK,CAAE,QAAO;AACvF,KAAI,SAAS,SAAS,KAAA,KAAa,CAAC,SAAS,KAAK,SAAS,KAAK,UAAU,CAAE,QAAO;AAEnF,KAAI,SAAS,WAAW,KAAA;MAElB,CAAC,iBADY,kBAAkB,KAAK,EACR,SAAS,OAAO,CAAE,QAAO;;AAG3D,KAAI,SAAS,kBAAkB,KAAA;MAEzB,CAAC,iBADY,yBAAyB,KAAK,EACf,SAAS,cAAc,CAAE,QAAO;;AAGlE,KAAI,SAAS,gBAAgB,KAAA;MACvB,CAAC,iBAAiB,KAAK,aAAa,SAAS,YAAY,CAAE,QAAO;;AAGxE,KAAI,SAAS,SAAS,KAAA,EAEpB,KADqB,SAAS,oBAAoB;OAE3C,MAAM,WAAW,SAAS,KAC7B,KAAI,CAAC,KAAK,SAAS,MAAM,SAAS,kBAAkB,MAAM,QAAQ,CAAC,CAAE,QAAO;QAEzE;AACL,MAAI,KAAK,SAAS,WAAW,SAAS,KAAK,OAAQ,QAAO;AAC1D,OAAK,IAAI,IAAI,GAAG,IAAI,SAAS,KAAK,QAAQ,IACxC,KAAI,CAAC,kBAAkB,KAAK,SAAS,IAAI,SAAS,KAAK,GAAG,CAAE,QAAO;;AAKzE,QAAO;;;AAIT,SAAgB,qBAAqB,WAAkC,MAA4B;AACjG,QAAO,UAAU,MAAM,QAAQ,YAAY,MAAM,IAAI,CAAC;;;;;;AAOxD,SAAgB,2BACd,OACgC;CAChC,MAAM,YAAY,mBAAmB,MAAM;AAC3C,SAAQ,SAAS,qBAAqB,WAAW,KAAK"}
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"}
@@ -4,12 +4,12 @@ function createReadyColumnData(getData) {
4
4
  return { get: getData };
5
5
  }
6
6
  /** Creates a ColumnSnapshot from parts. */
7
- function createColumnSnapshot(id, spec, dataStatus, data) {
7
+ function createColumnSnapshot(id, spec, data, dataStatus) {
8
8
  return {
9
9
  id,
10
10
  spec,
11
- dataStatus,
12
- data
11
+ data,
12
+ dataStatus
13
13
  };
14
14
  }
15
15
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"column_snapshot.cjs","names":[],"sources":["../../src/columns/column_snapshot.ts"],"sourcesContent":["import type { PColumnSpec, PObjectId } 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 = PObjectId> {\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 = PObjectId>(\n id: Id,\n spec: PColumnSpec,\n dataStatus: ColumnDataStatus,\n data: ColumnData | undefined,\n): ColumnSnapshot<Id> {\n return { id, spec, dataStatus, data };\n}\n"],"mappings":";;AAwCA,SAAgB,sBAAsB,SAA6D;AACjG,QAAO,EAAE,KAAK,SAAS;;;AAMzB,SAAgB,qBACd,IACA,MACA,YACA,MACoB;AACpB,QAAO;EAAE;EAAI;EAAM;EAAY;EAAM"}
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,5 +1,5 @@
1
1
  import { PColumnDataUniversal } from "../render/internal.js";
2
- import { PColumnSpec, PObjectId } from "@milaboratories/pl-model-common";
2
+ import { PColumnSpec, PObjectId, SUniversalPColumnId } from "@milaboratories/pl-model-common";
3
3
 
4
4
  //#region src/columns/column_snapshot.d.ts
5
5
  /** Data status of a column snapshot. */
@@ -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 = PObjectId> {
14
+ interface ColumnSnapshot<Id extends PObjectId | SUniversalPColumnId> {
15
15
  readonly id: Id;
16
16
  readonly spec: PColumnSpec;
17
17
  readonly dataStatus: ColumnDataStatus;
@@ -33,7 +33,7 @@ interface ColumnData {
33
33
  /** Creates a ColumnData active object for a ready column. */
34
34
  declare function createReadyColumnData(getData: () => PColumnDataUniversal | undefined): ColumnData;
35
35
  /** Creates a ColumnSnapshot from parts. */
36
- declare function createColumnSnapshot<Id extends PObjectId = PObjectId>(id: Id, spec: PColumnSpec, dataStatus: ColumnDataStatus, data: ColumnData | undefined): ColumnSnapshot<Id>;
36
+ declare function createColumnSnapshot<Id extends PObjectId>(id: Id, spec: PColumnSpec, data: undefined | ColumnData, dataStatus: ColumnDataStatus): ColumnSnapshot<Id>;
37
37
  //#endregion
38
38
  export { ColumnData, ColumnDataStatus, ColumnSnapshot, createColumnSnapshot, createReadyColumnData };
39
39
  //# sourceMappingURL=column_snapshot.d.ts.map
@@ -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,SAAA;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,GAAY,SAAA,CAAA,CAC1D,EAAA,EAAI,EAAA,EACJ,IAAA,EAAM,WAAA,EACN,UAAA,EAAY,gBAAA,EACZ,IAAA,EAAM,UAAA,eACL,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,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"}
@@ -4,12 +4,12 @@ function createReadyColumnData(getData) {
4
4
  return { get: getData };
5
5
  }
6
6
  /** Creates a ColumnSnapshot from parts. */
7
- function createColumnSnapshot(id, spec, dataStatus, data) {
7
+ function createColumnSnapshot(id, spec, data, dataStatus) {
8
8
  return {
9
9
  id,
10
10
  spec,
11
- dataStatus,
12
- data
11
+ data,
12
+ dataStatus
13
13
  };
14
14
  }
15
15
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"column_snapshot.js","names":[],"sources":["../../src/columns/column_snapshot.ts"],"sourcesContent":["import type { PColumnSpec, PObjectId } 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 = PObjectId> {\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 = PObjectId>(\n id: Id,\n spec: PColumnSpec,\n dataStatus: ColumnDataStatus,\n data: ColumnData | undefined,\n): ColumnSnapshot<Id> {\n return { id, spec, dataStatus, data };\n}\n"],"mappings":";;AAwCA,SAAgB,sBAAsB,SAA6D;AACjG,QAAO,EAAE,KAAK,SAAS;;;AAMzB,SAAgB,qBACd,IACA,MACA,YACA,MACoB;AACpB,QAAO;EAAE;EAAI;EAAM;EAAY;EAAM"}
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"}
@@ -92,7 +92,7 @@ function isColumnSnapshotArray(source) {
92
92
  /**
93
93
  * Normalize any ColumnSource into a ColumnSnapshotProvider.
94
94
  * - ColumnSnapshotProvider → returned as-is
95
- * - ColumnSnapshot[] → wrapped in SnapshotColumnProvider
95
+ * - ColumnSnapshot<PObjectId>[] → wrapped in SnapshotColumnProvider
96
96
  * - PColumn[] → wrapped in ArrayColumnProvider
97
97
  */
98
98
  function toColumnSnapshotProvider(source) {
@@ -1 +1 @@
1
- {"version":3,"file":"column_snapshot_provider.cjs","names":[],"sources":["../../src/columns/column_snapshot_provider.ts"],"sourcesContent":["import { PColumn } from \"@milaboratories/pl-model-common\";\nimport { TreeNodeAccessor } from \"../render/accessor\";\nimport type { PColumnDataUniversal } from \"../render/internal\";\nimport type { ColumnDataStatus, ColumnSnapshot } from \"./column_snapshot\";\n\n// --- ColumnProvider ---\n\n/**\n * Data source interface for column enumeration.\n *\n * Knows nothing about the render framework, stability tracking, labels,\n * anchoring, or splitting. All that complexity lives in the collection layer.\n */\nexport interface ColumnSnapshotProvider {\n /** Returns all currently known columns. */\n getAllColumns(): ColumnSnapshot[];\n\n /** Whether the provider has finished enumerating all its columns.\n * Calling this may mark the render context unstable — it touches\n * the reactive tree to check field resolution state. */\n isColumnListComplete(): boolean;\n}\n\n// --- ColumnSource ---\n\n/**\n * Union of types that can serve as column sources for helpers and builders.\n * Does NOT include TreeNodeAccessor — call `.toColumnSource()` on it first.\n */\nexport type ColumnSource =\n | ColumnSnapshotProvider\n | ColumnSnapshot[]\n | PColumn<PColumnDataUniversal | undefined>[];\n\n// --- ArrayColumnProvider ---\n\n/**\n * Simple provider wrapping an array of PColumns.\n * Always complete, data status always 'ready'.\n */\nexport class ArrayColumnProvider implements ColumnSnapshotProvider {\n private readonly columns: ColumnSnapshot[];\n\n constructor(columns: PColumn<PColumnDataUniversal | undefined>[]) {\n this.columns = columns.map((col) => ({\n id: col.id,\n spec: col.spec,\n dataStatus: \"ready\" as const,\n data: { get: () => col.data },\n }));\n }\n\n getAllColumns(): ColumnSnapshot[] {\n return this.columns;\n }\n\n isColumnListComplete(): boolean {\n return true;\n }\n}\n\n// --- SnapshotColumnProvider ---\n\n/**\n * Provider wrapping an array of ColumnSnapshots.\n * Always complete. Data status taken from each snapshot.\n */\nexport class SnapshotColumnProvider implements ColumnSnapshotProvider {\n constructor(private readonly snapshots: ColumnSnapshot[]) {}\n\n getAllColumns(): ColumnSnapshot[] {\n return this.snapshots;\n }\n\n isColumnListComplete(): boolean {\n return true;\n }\n}\n\n// --- OutputColumnProvider ---\n\nexport interface OutputColumnProviderOpts {\n /** When true and the accessor is final, columns with no ready data get status 'absent'. */\n allowPermanentAbsence?: boolean;\n}\n\n/**\n * Provider wrapping a TreeNodeAccessor (output/prerun resolve result).\n * Detects data status from accessor readiness state.\n */\nexport class OutputColumnProvider implements ColumnSnapshotProvider {\n constructor(\n private readonly accessor: TreeNodeAccessor,\n private readonly opts?: OutputColumnProviderOpts,\n ) {}\n\n getAllColumns(): ColumnSnapshot[] {\n return this.getColumns();\n }\n\n isColumnListComplete(): boolean {\n return this.accessor.getInputsLocked();\n }\n\n private getColumns(): ColumnSnapshot[] {\n const pColumns = this.accessor.getPColumns();\n if (pColumns === undefined) return [];\n\n const isFinal = this.accessor.getIsFinal();\n const allowAbsence = this.opts?.allowPermanentAbsence === true;\n\n return pColumns.map((col) => {\n const dataAccessor = col.data;\n const isReady = dataAccessor.getIsReadyOrError();\n\n let dataStatus: ColumnDataStatus;\n if (isReady) {\n dataStatus = \"ready\";\n } else if (allowAbsence && isFinal) {\n dataStatus = \"absent\";\n } else {\n dataStatus = \"computing\";\n }\n\n return {\n id: col.id,\n spec: col.spec,\n dataStatus,\n data: { get: () => (isReady ? dataAccessor : undefined) },\n };\n });\n }\n}\n\n// --- Source normalization ---\n\n/** Checks if a value is a ColumnSnapshotProvider (duck-typing). */\nexport function isColumnSnapshotProvider(source: unknown): source is ColumnSnapshotProvider {\n return (\n typeof source === \"object\" &&\n source !== null &&\n \"getAllColumns\" in source &&\n \"isColumnListComplete\" in source &&\n typeof (source as ColumnSnapshotProvider).getAllColumns === \"function\" &&\n typeof (source as ColumnSnapshotProvider).isColumnListComplete === \"function\"\n );\n}\n\n/** Checks if a value looks like a PColumn (has id, spec, data). */\nfunction isPColumnArray(source: unknown): source is PColumn<PColumnDataUniversal | undefined>[] {\n if (!Array.isArray(source)) return false;\n if (source.length === 0) return true; // empty array — treat as PColumn[]\n const first = source[0];\n return \"id\" in first && \"spec\" in first && \"data\" in first && !(\"dataStatus\" in first);\n}\n\n/** Checks if a value looks like a ColumnSnapshot array. */\nfunction isColumnSnapshotArray(source: unknown): source is ColumnSnapshot[] {\n if (!Array.isArray(source)) return false;\n if (source.length === 0) return true; // empty array — treat as snapshots\n const first = source[0];\n return \"id\" in first && \"spec\" in first && \"dataStatus\" in first;\n}\n\n/**\n * Normalize any ColumnSource into a ColumnSnapshotProvider.\n * - ColumnSnapshotProvider → returned as-is\n * - ColumnSnapshot[] → wrapped in SnapshotColumnProvider\n * - PColumn[] → wrapped in ArrayColumnProvider\n */\nexport function toColumnSnapshotProvider(source: ColumnSource): ColumnSnapshotProvider {\n if (isColumnSnapshotProvider(source)) return source;\n if (isColumnSnapshotArray(source)) return new SnapshotColumnProvider(source);\n if (isPColumnArray(source)) return new ArrayColumnProvider(source);\n // Should not reach here given the type union, but be safe\n throw new Error(\"Unknown ColumnSource type\");\n}\n"],"mappings":";;;;;AAwCA,IAAa,sBAAb,MAAmE;CACjE;CAEA,YAAY,SAAsD;AAChE,OAAK,UAAU,QAAQ,KAAK,SAAS;GACnC,IAAI,IAAI;GACR,MAAM,IAAI;GACV,YAAY;GACZ,MAAM,EAAE,WAAW,IAAI,MAAM;GAC9B,EAAE;;CAGL,gBAAkC;AAChC,SAAO,KAAK;;CAGd,uBAAgC;AAC9B,SAAO;;;;;;;AAUX,IAAa,yBAAb,MAAsE;CACpE,YAAY,WAA8C;AAA7B,OAAA,YAAA;;CAE7B,gBAAkC;AAChC,SAAO,KAAK;;CAGd,uBAAgC;AAC9B,SAAO;;;;;;;AAeX,IAAa,uBAAb,MAAoE;CAClE,YACE,UACA,MACA;AAFiB,OAAA,WAAA;AACA,OAAA,OAAA;;CAGnB,gBAAkC;AAChC,SAAO,KAAK,YAAY;;CAG1B,uBAAgC;AAC9B,SAAO,KAAK,SAAS,iBAAiB;;CAGxC,aAAuC;EACrC,MAAM,WAAW,KAAK,SAAS,aAAa;AAC5C,MAAI,aAAa,KAAA,EAAW,QAAO,EAAE;EAErC,MAAM,UAAU,KAAK,SAAS,YAAY;EAC1C,MAAM,eAAe,KAAK,MAAM,0BAA0B;AAE1D,SAAO,SAAS,KAAK,QAAQ;GAC3B,MAAM,eAAe,IAAI;GACzB,MAAM,UAAU,aAAa,mBAAmB;GAEhD,IAAI;AACJ,OAAI,QACF,cAAa;YACJ,gBAAgB,QACzB,cAAa;OAEb,cAAa;AAGf,UAAO;IACL,IAAI,IAAI;IACR,MAAM,IAAI;IACV;IACA,MAAM,EAAE,WAAY,UAAU,eAAe,KAAA,GAAY;IAC1D;IACD;;;;AAON,SAAgB,yBAAyB,QAAmD;AAC1F,QACE,OAAO,WAAW,YAClB,WAAW,QACX,mBAAmB,UACnB,0BAA0B,UAC1B,OAAQ,OAAkC,kBAAkB,cAC5D,OAAQ,OAAkC,yBAAyB;;;AAKvE,SAAS,eAAe,QAAwE;AAC9F,KAAI,CAAC,MAAM,QAAQ,OAAO,CAAE,QAAO;AACnC,KAAI,OAAO,WAAW,EAAG,QAAO;CAChC,MAAM,QAAQ,OAAO;AACrB,QAAO,QAAQ,SAAS,UAAU,SAAS,UAAU,SAAS,EAAE,gBAAgB;;;AAIlF,SAAS,sBAAsB,QAA6C;AAC1E,KAAI,CAAC,MAAM,QAAQ,OAAO,CAAE,QAAO;AACnC,KAAI,OAAO,WAAW,EAAG,QAAO;CAChC,MAAM,QAAQ,OAAO;AACrB,QAAO,QAAQ,SAAS,UAAU,SAAS,gBAAgB;;;;;;;;AAS7D,SAAgB,yBAAyB,QAA8C;AACrF,KAAI,yBAAyB,OAAO,CAAE,QAAO;AAC7C,KAAI,sBAAsB,OAAO,CAAE,QAAO,IAAI,uBAAuB,OAAO;AAC5E,KAAI,eAAe,OAAO,CAAE,QAAO,IAAI,oBAAoB,OAAO;AAElE,OAAM,IAAI,MAAM,4BAA4B"}
1
+ {"version":3,"file":"column_snapshot_provider.cjs","names":[],"sources":["../../src/columns/column_snapshot_provider.ts"],"sourcesContent":["import type { PObjectId } from \"@milaboratories/pl-model-common\";\nimport { PColumn } from \"@milaboratories/pl-model-common\";\nimport { TreeNodeAccessor } from \"../render/accessor\";\nimport type { PColumnDataUniversal } from \"../render/internal\";\nimport type { ColumnDataStatus, ColumnSnapshot } from \"./column_snapshot\";\n\n// --- ColumnProvider ---\n\n/**\n * Data source interface for column enumeration.\n *\n * Knows nothing about the render framework, stability tracking, labels,\n * anchoring, or splitting. All that complexity lives in the collection layer.\n */\nexport interface ColumnSnapshotProvider {\n /** Returns all currently known columns. */\n getAllColumns(): ColumnSnapshot<PObjectId>[];\n\n /** Whether the provider has finished enumerating all its columns.\n * Calling this may mark the render context unstable — it touches\n * the reactive tree to check field resolution state. */\n isColumnListComplete(): boolean;\n}\n\n// --- ColumnSource ---\n\n/**\n * Union of types that can serve as column sources for helpers and builders.\n * Does NOT include TreeNodeAccessor — call `.toColumnSource()` on it first.\n */\nexport type ColumnSource =\n | ColumnSnapshotProvider\n | ColumnSnapshot<PObjectId>[]\n | PColumn<PColumnDataUniversal | undefined>[];\n\n// --- ArrayColumnProvider ---\n\n/**\n * Simple provider wrapping an array of PColumns.\n * Always complete, data status always 'ready'.\n */\nexport class ArrayColumnProvider implements ColumnSnapshotProvider {\n private readonly columns: ColumnSnapshot<PObjectId>[];\n\n constructor(columns: PColumn<PColumnDataUniversal | undefined>[]) {\n this.columns = columns.map((col) => ({\n id: col.id,\n spec: col.spec,\n dataStatus: \"ready\" as const,\n data: { get: () => col.data },\n }));\n }\n\n getAllColumns(): ColumnSnapshot<PObjectId>[] {\n return this.columns;\n }\n\n isColumnListComplete(): boolean {\n return true;\n }\n}\n\n// --- SnapshotColumnProvider ---\n\n/**\n * Provider wrapping an array of ColumnSnapshots.\n * Always complete. Data status taken from each snapshot.\n */\nexport class SnapshotColumnProvider implements ColumnSnapshotProvider {\n constructor(private readonly snapshots: ColumnSnapshot<PObjectId>[]) {}\n\n getAllColumns(): ColumnSnapshot<PObjectId>[] {\n return this.snapshots;\n }\n\n isColumnListComplete(): boolean {\n return true;\n }\n}\n\n// --- OutputColumnProvider ---\n\nexport interface OutputColumnProviderOpts {\n /** When true and the accessor is final, columns with no ready data get status 'absent'. */\n allowPermanentAbsence?: boolean;\n}\n\n/**\n * Provider wrapping a TreeNodeAccessor (output/prerun resolve result).\n * Detects data status from accessor readiness state.\n */\nexport class OutputColumnProvider implements ColumnSnapshotProvider {\n constructor(\n private readonly accessor: TreeNodeAccessor,\n private readonly opts?: OutputColumnProviderOpts,\n ) {}\n\n getAllColumns(): ColumnSnapshot<PObjectId>[] {\n return this.getColumns();\n }\n\n isColumnListComplete(): boolean {\n return this.accessor.getInputsLocked();\n }\n\n private getColumns(): ColumnSnapshot<PObjectId>[] {\n const pColumns = this.accessor.getPColumns();\n if (pColumns === undefined) return [];\n\n const isFinal = this.accessor.getIsFinal();\n const allowAbsence = this.opts?.allowPermanentAbsence === true;\n\n return pColumns.map((col) => {\n const dataAccessor = col.data;\n const isReady = dataAccessor.getIsReadyOrError();\n\n let dataStatus: ColumnDataStatus;\n if (isReady) {\n dataStatus = \"ready\";\n } else if (allowAbsence && isFinal) {\n dataStatus = \"absent\";\n } else {\n dataStatus = \"computing\";\n }\n\n return {\n id: col.id,\n spec: col.spec,\n dataStatus,\n data: { get: () => (isReady ? dataAccessor : undefined) },\n };\n });\n }\n}\n\n// --- Source normalization ---\n\n/** Checks if a value is a ColumnSnapshotProvider (duck-typing). */\nexport function isColumnSnapshotProvider(source: unknown): source is ColumnSnapshotProvider {\n return (\n typeof source === \"object\" &&\n source !== null &&\n \"getAllColumns\" in source &&\n \"isColumnListComplete\" in source &&\n typeof (source as ColumnSnapshotProvider).getAllColumns === \"function\" &&\n typeof (source as ColumnSnapshotProvider).isColumnListComplete === \"function\"\n );\n}\n\n/** Checks if a value looks like a PColumn (has id, spec, data). */\nfunction isPColumnArray(source: unknown): source is PColumn<PColumnDataUniversal | undefined>[] {\n if (!Array.isArray(source)) return false;\n if (source.length === 0) return true; // empty array — treat as PColumn[]\n const first = source[0];\n return \"id\" in first && \"spec\" in first && \"data\" in first && !(\"dataStatus\" in first);\n}\n\n/** Checks if a value looks like a ColumnSnapshot array. */\nfunction isColumnSnapshotArray(source: unknown): source is ColumnSnapshot<PObjectId>[] {\n if (!Array.isArray(source)) return false;\n if (source.length === 0) return true; // empty array — treat as snapshots\n const first = source[0];\n return \"id\" in first && \"spec\" in first && \"dataStatus\" in first;\n}\n\n/**\n * Normalize any ColumnSource into a ColumnSnapshotProvider.\n * - ColumnSnapshotProvider → returned as-is\n * - ColumnSnapshot<PObjectId>[] → wrapped in SnapshotColumnProvider\n * - PColumn[] → wrapped in ArrayColumnProvider\n */\nexport function toColumnSnapshotProvider(source: ColumnSource): ColumnSnapshotProvider {\n if (isColumnSnapshotProvider(source)) return source;\n if (isColumnSnapshotArray(source)) return new SnapshotColumnProvider(source);\n if (isPColumnArray(source)) return new ArrayColumnProvider(source);\n // Should not reach here given the type union, but be safe\n throw new Error(\"Unknown ColumnSource type\");\n}\n"],"mappings":";;;;;AAyCA,IAAa,sBAAb,MAAmE;CACjE;CAEA,YAAY,SAAsD;AAChE,OAAK,UAAU,QAAQ,KAAK,SAAS;GACnC,IAAI,IAAI;GACR,MAAM,IAAI;GACV,YAAY;GACZ,MAAM,EAAE,WAAW,IAAI,MAAM;GAC9B,EAAE;;CAGL,gBAA6C;AAC3C,SAAO,KAAK;;CAGd,uBAAgC;AAC9B,SAAO;;;;;;;AAUX,IAAa,yBAAb,MAAsE;CACpE,YAAY,WAAyD;AAAxC,OAAA,YAAA;;CAE7B,gBAA6C;AAC3C,SAAO,KAAK;;CAGd,uBAAgC;AAC9B,SAAO;;;;;;;AAeX,IAAa,uBAAb,MAAoE;CAClE,YACE,UACA,MACA;AAFiB,OAAA,WAAA;AACA,OAAA,OAAA;;CAGnB,gBAA6C;AAC3C,SAAO,KAAK,YAAY;;CAG1B,uBAAgC;AAC9B,SAAO,KAAK,SAAS,iBAAiB;;CAGxC,aAAkD;EAChD,MAAM,WAAW,KAAK,SAAS,aAAa;AAC5C,MAAI,aAAa,KAAA,EAAW,QAAO,EAAE;EAErC,MAAM,UAAU,KAAK,SAAS,YAAY;EAC1C,MAAM,eAAe,KAAK,MAAM,0BAA0B;AAE1D,SAAO,SAAS,KAAK,QAAQ;GAC3B,MAAM,eAAe,IAAI;GACzB,MAAM,UAAU,aAAa,mBAAmB;GAEhD,IAAI;AACJ,OAAI,QACF,cAAa;YACJ,gBAAgB,QACzB,cAAa;OAEb,cAAa;AAGf,UAAO;IACL,IAAI,IAAI;IACR,MAAM,IAAI;IACV;IACA,MAAM,EAAE,WAAY,UAAU,eAAe,KAAA,GAAY;IAC1D;IACD;;;;AAON,SAAgB,yBAAyB,QAAmD;AAC1F,QACE,OAAO,WAAW,YAClB,WAAW,QACX,mBAAmB,UACnB,0BAA0B,UAC1B,OAAQ,OAAkC,kBAAkB,cAC5D,OAAQ,OAAkC,yBAAyB;;;AAKvE,SAAS,eAAe,QAAwE;AAC9F,KAAI,CAAC,MAAM,QAAQ,OAAO,CAAE,QAAO;AACnC,KAAI,OAAO,WAAW,EAAG,QAAO;CAChC,MAAM,QAAQ,OAAO;AACrB,QAAO,QAAQ,SAAS,UAAU,SAAS,UAAU,SAAS,EAAE,gBAAgB;;;AAIlF,SAAS,sBAAsB,QAAwD;AACrF,KAAI,CAAC,MAAM,QAAQ,OAAO,CAAE,QAAO;AACnC,KAAI,OAAO,WAAW,EAAG,QAAO;CAChC,MAAM,QAAQ,OAAO;AACrB,QAAO,QAAQ,SAAS,UAAU,SAAS,gBAAgB;;;;;;;;AAS7D,SAAgB,yBAAyB,QAA8C;AACrF,KAAI,yBAAyB,OAAO,CAAE,QAAO;AAC7C,KAAI,sBAAsB,OAAO,CAAE,QAAO,IAAI,uBAAuB,OAAO;AAC5E,KAAI,eAAe,OAAO,CAAE,QAAO,IAAI,oBAAoB,OAAO;AAElE,OAAM,IAAI,MAAM,4BAA4B"}
@@ -1,7 +1,7 @@
1
1
  import { PColumnDataUniversal } from "../render/internal.js";
2
2
  import { TreeNodeAccessor } from "../render/accessor.js";
3
3
  import { ColumnSnapshot } from "./column_snapshot.js";
4
- import { PColumn } from "@milaboratories/pl-model-common";
4
+ import { PColumn, PObjectId } from "@milaboratories/pl-model-common";
5
5
 
6
6
  //#region src/columns/column_snapshot_provider.d.ts
7
7
  /**
@@ -12,7 +12,7 @@ import { PColumn } from "@milaboratories/pl-model-common";
12
12
  */
13
13
  interface ColumnSnapshotProvider {
14
14
  /** Returns all currently known columns. */
15
- getAllColumns(): ColumnSnapshot[];
15
+ getAllColumns(): ColumnSnapshot<PObjectId>[];
16
16
  /** Whether the provider has finished enumerating all its columns.
17
17
  * Calling this may mark the render context unstable — it touches
18
18
  * the reactive tree to check field resolution state. */
@@ -22,7 +22,7 @@ interface ColumnSnapshotProvider {
22
22
  * Union of types that can serve as column sources for helpers and builders.
23
23
  * Does NOT include TreeNodeAccessor — call `.toColumnSource()` on it first.
24
24
  */
25
- type ColumnSource = ColumnSnapshotProvider | ColumnSnapshot[] | PColumn<PColumnDataUniversal | undefined>[];
25
+ type ColumnSource = ColumnSnapshotProvider | ColumnSnapshot<PObjectId>[] | PColumn<PColumnDataUniversal | undefined>[];
26
26
  /**
27
27
  * Simple provider wrapping an array of PColumns.
28
28
  * Always complete, data status always 'ready'.
@@ -30,7 +30,7 @@ type ColumnSource = ColumnSnapshotProvider | ColumnSnapshot[] | PColumn<PColumnD
30
30
  declare class ArrayColumnProvider implements ColumnSnapshotProvider {
31
31
  private readonly columns;
32
32
  constructor(columns: PColumn<PColumnDataUniversal | undefined>[]);
33
- getAllColumns(): ColumnSnapshot[];
33
+ getAllColumns(): ColumnSnapshot<PObjectId>[];
34
34
  isColumnListComplete(): boolean;
35
35
  }
36
36
  /**
@@ -39,8 +39,8 @@ declare class ArrayColumnProvider implements ColumnSnapshotProvider {
39
39
  */
40
40
  declare class SnapshotColumnProvider implements ColumnSnapshotProvider {
41
41
  private readonly snapshots;
42
- constructor(snapshots: ColumnSnapshot[]);
43
- getAllColumns(): ColumnSnapshot[];
42
+ constructor(snapshots: ColumnSnapshot<PObjectId>[]);
43
+ getAllColumns(): ColumnSnapshot<PObjectId>[];
44
44
  isColumnListComplete(): boolean;
45
45
  }
46
46
  interface OutputColumnProviderOpts {
@@ -55,7 +55,7 @@ declare class OutputColumnProvider implements ColumnSnapshotProvider {
55
55
  private readonly accessor;
56
56
  private readonly opts?;
57
57
  constructor(accessor: TreeNodeAccessor, opts?: OutputColumnProviderOpts | undefined);
58
- getAllColumns(): ColumnSnapshot[];
58
+ getAllColumns(): ColumnSnapshot<PObjectId>[];
59
59
  isColumnListComplete(): boolean;
60
60
  private getColumns;
61
61
  }
@@ -64,7 +64,7 @@ declare function isColumnSnapshotProvider(source: unknown): source is ColumnSnap
64
64
  /**
65
65
  * Normalize any ColumnSource into a ColumnSnapshotProvider.
66
66
  * - ColumnSnapshotProvider → returned as-is
67
- * - ColumnSnapshot[] → wrapped in SnapshotColumnProvider
67
+ * - ColumnSnapshot<PObjectId>[] → wrapped in SnapshotColumnProvider
68
68
  * - PColumn[] → wrapped in ArrayColumnProvider
69
69
  */
70
70
  declare function toColumnSnapshotProvider(source: ColumnSource): ColumnSnapshotProvider;
@@ -1 +1 @@
1
- {"version":3,"file":"column_snapshot_provider.d.ts","names":[],"sources":["../../src/columns/column_snapshot_provider.ts"],"mappings":";;;;;;;;AAaA;;;;UAAiB,sBAAA;EAEE;EAAjB,aAAA,IAAiB,cAAA;EAKG;;AAStB;EATE,oBAAA;AAAA;;;;;KASU,YAAA,GACR,sBAAA,GACA,cAAA,KACA,OAAA,CAAQ,oBAAA;;;;;cAQC,mBAAA,YAA+B,sBAAA;EAAA,iBACzB,OAAA;cAEL,OAAA,EAAS,OAAA,CAAQ,oBAAA;EAS7B,aAAA,CAAA,GAAiB,cAAA;EAIjB,oBAAA,CAAA;AAAA;;;;;cAWW,sBAAA,YAAkC,sBAAA;EAAA,iBAChB,SAAA;cAAA,SAAA,EAAW,cAAA;EAExC,aAAA,CAAA,GAAiB,cAAA;EAIjB,oBAAA,CAAA;AAAA;AAAA,UAOe,wBAAA;EAtCH;EAwCZ,qBAAA;AAAA;;;;AAhBF;cAuBa,oBAAA,YAAgC,sBAAA;EAAA,iBAExB,QAAA;EAAA,iBACA,IAAA;cADA,QAAA,EAAU,gBAAA,EACV,IAAA,GAAO,wBAAA;EAG1B,aAAA,CAAA,GAAiB,cAAA;EAIjB,oBAAA,CAAA;EAAA,QAIQ,UAAA;AAAA;;iBAiCM,wBAAA,CAAyB,MAAA,YAAkB,MAAA,IAAU,sBAAA;;;;;;;iBAiCrD,wBAAA,CAAyB,MAAA,EAAQ,YAAA,GAAe,sBAAA"}
1
+ {"version":3,"file":"column_snapshot_provider.d.ts","names":[],"sources":["../../src/columns/column_snapshot_provider.ts"],"mappings":";;;;;;;AAcA;;;;;UAAiB,sBAAA;EAEiB;EAAhC,aAAA,IAAiB,cAAA,CAAe,SAAA;EAKZ;;AAStB;EATE,oBAAA;AAAA;;;;;KASU,YAAA,GACR,sBAAA,GACA,cAAA,CAAe,SAAA,MACf,OAAA,CAAQ,oBAAA;;;;;cAQC,mBAAA,YAA+B,sBAAA;EAAA,iBACzB,OAAA;cAEL,OAAA,EAAS,OAAA,CAAQ,oBAAA;EAS7B,aAAA,CAAA,GAAiB,cAAA,CAAe,SAAA;EAIhC,oBAAA,CAAA;AAAA;;;;;cAWW,sBAAA,YAAkC,sBAAA;EAAA,iBAChB,SAAA;cAAA,SAAA,EAAW,cAAA,CAAe,SAAA;EAEvD,aAAA,CAAA,GAAiB,cAAA,CAAe,SAAA;EAIhC,oBAAA,CAAA;AAAA;AAAA,UAOe,wBAAA;;EAEf,qBAAA;AAAA;;;;;cAOW,oBAAA,YAAgC,sBAAA;EAAA,iBAExB,QAAA;EAAA,iBACA,IAAA;cADA,QAAA,EAAU,gBAAA,EACV,IAAA,GAAO,wBAAA;EAG1B,aAAA,CAAA,GAAiB,cAAA,CAAe,SAAA;EAIhC,oBAAA,CAAA;EAAA,QAIQ,UAAA;AAAA;;iBAiCM,wBAAA,CAAyB,MAAA,YAAkB,MAAA,IAAU,sBAAA;;;;;;;iBAiCrD,wBAAA,CAAyB,MAAA,EAAQ,YAAA,GAAe,sBAAA"}
@@ -92,7 +92,7 @@ function isColumnSnapshotArray(source) {
92
92
  /**
93
93
  * Normalize any ColumnSource into a ColumnSnapshotProvider.
94
94
  * - ColumnSnapshotProvider → returned as-is
95
- * - ColumnSnapshot[] → wrapped in SnapshotColumnProvider
95
+ * - ColumnSnapshot<PObjectId>[] → wrapped in SnapshotColumnProvider
96
96
  * - PColumn[] → wrapped in ArrayColumnProvider
97
97
  */
98
98
  function toColumnSnapshotProvider(source) {
@@ -1 +1 @@
1
- {"version":3,"file":"column_snapshot_provider.js","names":[],"sources":["../../src/columns/column_snapshot_provider.ts"],"sourcesContent":["import { PColumn } from \"@milaboratories/pl-model-common\";\nimport { TreeNodeAccessor } from \"../render/accessor\";\nimport type { PColumnDataUniversal } from \"../render/internal\";\nimport type { ColumnDataStatus, ColumnSnapshot } from \"./column_snapshot\";\n\n// --- ColumnProvider ---\n\n/**\n * Data source interface for column enumeration.\n *\n * Knows nothing about the render framework, stability tracking, labels,\n * anchoring, or splitting. All that complexity lives in the collection layer.\n */\nexport interface ColumnSnapshotProvider {\n /** Returns all currently known columns. */\n getAllColumns(): ColumnSnapshot[];\n\n /** Whether the provider has finished enumerating all its columns.\n * Calling this may mark the render context unstable — it touches\n * the reactive tree to check field resolution state. */\n isColumnListComplete(): boolean;\n}\n\n// --- ColumnSource ---\n\n/**\n * Union of types that can serve as column sources for helpers and builders.\n * Does NOT include TreeNodeAccessor — call `.toColumnSource()` on it first.\n */\nexport type ColumnSource =\n | ColumnSnapshotProvider\n | ColumnSnapshot[]\n | PColumn<PColumnDataUniversal | undefined>[];\n\n// --- ArrayColumnProvider ---\n\n/**\n * Simple provider wrapping an array of PColumns.\n * Always complete, data status always 'ready'.\n */\nexport class ArrayColumnProvider implements ColumnSnapshotProvider {\n private readonly columns: ColumnSnapshot[];\n\n constructor(columns: PColumn<PColumnDataUniversal | undefined>[]) {\n this.columns = columns.map((col) => ({\n id: col.id,\n spec: col.spec,\n dataStatus: \"ready\" as const,\n data: { get: () => col.data },\n }));\n }\n\n getAllColumns(): ColumnSnapshot[] {\n return this.columns;\n }\n\n isColumnListComplete(): boolean {\n return true;\n }\n}\n\n// --- SnapshotColumnProvider ---\n\n/**\n * Provider wrapping an array of ColumnSnapshots.\n * Always complete. Data status taken from each snapshot.\n */\nexport class SnapshotColumnProvider implements ColumnSnapshotProvider {\n constructor(private readonly snapshots: ColumnSnapshot[]) {}\n\n getAllColumns(): ColumnSnapshot[] {\n return this.snapshots;\n }\n\n isColumnListComplete(): boolean {\n return true;\n }\n}\n\n// --- OutputColumnProvider ---\n\nexport interface OutputColumnProviderOpts {\n /** When true and the accessor is final, columns with no ready data get status 'absent'. */\n allowPermanentAbsence?: boolean;\n}\n\n/**\n * Provider wrapping a TreeNodeAccessor (output/prerun resolve result).\n * Detects data status from accessor readiness state.\n */\nexport class OutputColumnProvider implements ColumnSnapshotProvider {\n constructor(\n private readonly accessor: TreeNodeAccessor,\n private readonly opts?: OutputColumnProviderOpts,\n ) {}\n\n getAllColumns(): ColumnSnapshot[] {\n return this.getColumns();\n }\n\n isColumnListComplete(): boolean {\n return this.accessor.getInputsLocked();\n }\n\n private getColumns(): ColumnSnapshot[] {\n const pColumns = this.accessor.getPColumns();\n if (pColumns === undefined) return [];\n\n const isFinal = this.accessor.getIsFinal();\n const allowAbsence = this.opts?.allowPermanentAbsence === true;\n\n return pColumns.map((col) => {\n const dataAccessor = col.data;\n const isReady = dataAccessor.getIsReadyOrError();\n\n let dataStatus: ColumnDataStatus;\n if (isReady) {\n dataStatus = \"ready\";\n } else if (allowAbsence && isFinal) {\n dataStatus = \"absent\";\n } else {\n dataStatus = \"computing\";\n }\n\n return {\n id: col.id,\n spec: col.spec,\n dataStatus,\n data: { get: () => (isReady ? dataAccessor : undefined) },\n };\n });\n }\n}\n\n// --- Source normalization ---\n\n/** Checks if a value is a ColumnSnapshotProvider (duck-typing). */\nexport function isColumnSnapshotProvider(source: unknown): source is ColumnSnapshotProvider {\n return (\n typeof source === \"object\" &&\n source !== null &&\n \"getAllColumns\" in source &&\n \"isColumnListComplete\" in source &&\n typeof (source as ColumnSnapshotProvider).getAllColumns === \"function\" &&\n typeof (source as ColumnSnapshotProvider).isColumnListComplete === \"function\"\n );\n}\n\n/** Checks if a value looks like a PColumn (has id, spec, data). */\nfunction isPColumnArray(source: unknown): source is PColumn<PColumnDataUniversal | undefined>[] {\n if (!Array.isArray(source)) return false;\n if (source.length === 0) return true; // empty array — treat as PColumn[]\n const first = source[0];\n return \"id\" in first && \"spec\" in first && \"data\" in first && !(\"dataStatus\" in first);\n}\n\n/** Checks if a value looks like a ColumnSnapshot array. */\nfunction isColumnSnapshotArray(source: unknown): source is ColumnSnapshot[] {\n if (!Array.isArray(source)) return false;\n if (source.length === 0) return true; // empty array — treat as snapshots\n const first = source[0];\n return \"id\" in first && \"spec\" in first && \"dataStatus\" in first;\n}\n\n/**\n * Normalize any ColumnSource into a ColumnSnapshotProvider.\n * - ColumnSnapshotProvider → returned as-is\n * - ColumnSnapshot[] → wrapped in SnapshotColumnProvider\n * - PColumn[] → wrapped in ArrayColumnProvider\n */\nexport function toColumnSnapshotProvider(source: ColumnSource): ColumnSnapshotProvider {\n if (isColumnSnapshotProvider(source)) return source;\n if (isColumnSnapshotArray(source)) return new SnapshotColumnProvider(source);\n if (isPColumnArray(source)) return new ArrayColumnProvider(source);\n // Should not reach here given the type union, but be safe\n throw new Error(\"Unknown ColumnSource type\");\n}\n"],"mappings":";;;;;AAwCA,IAAa,sBAAb,MAAmE;CACjE;CAEA,YAAY,SAAsD;AAChE,OAAK,UAAU,QAAQ,KAAK,SAAS;GACnC,IAAI,IAAI;GACR,MAAM,IAAI;GACV,YAAY;GACZ,MAAM,EAAE,WAAW,IAAI,MAAM;GAC9B,EAAE;;CAGL,gBAAkC;AAChC,SAAO,KAAK;;CAGd,uBAAgC;AAC9B,SAAO;;;;;;;AAUX,IAAa,yBAAb,MAAsE;CACpE,YAAY,WAA8C;AAA7B,OAAA,YAAA;;CAE7B,gBAAkC;AAChC,SAAO,KAAK;;CAGd,uBAAgC;AAC9B,SAAO;;;;;;;AAeX,IAAa,uBAAb,MAAoE;CAClE,YACE,UACA,MACA;AAFiB,OAAA,WAAA;AACA,OAAA,OAAA;;CAGnB,gBAAkC;AAChC,SAAO,KAAK,YAAY;;CAG1B,uBAAgC;AAC9B,SAAO,KAAK,SAAS,iBAAiB;;CAGxC,aAAuC;EACrC,MAAM,WAAW,KAAK,SAAS,aAAa;AAC5C,MAAI,aAAa,KAAA,EAAW,QAAO,EAAE;EAErC,MAAM,UAAU,KAAK,SAAS,YAAY;EAC1C,MAAM,eAAe,KAAK,MAAM,0BAA0B;AAE1D,SAAO,SAAS,KAAK,QAAQ;GAC3B,MAAM,eAAe,IAAI;GACzB,MAAM,UAAU,aAAa,mBAAmB;GAEhD,IAAI;AACJ,OAAI,QACF,cAAa;YACJ,gBAAgB,QACzB,cAAa;OAEb,cAAa;AAGf,UAAO;IACL,IAAI,IAAI;IACR,MAAM,IAAI;IACV;IACA,MAAM,EAAE,WAAY,UAAU,eAAe,KAAA,GAAY;IAC1D;IACD;;;;AAON,SAAgB,yBAAyB,QAAmD;AAC1F,QACE,OAAO,WAAW,YAClB,WAAW,QACX,mBAAmB,UACnB,0BAA0B,UAC1B,OAAQ,OAAkC,kBAAkB,cAC5D,OAAQ,OAAkC,yBAAyB;;;AAKvE,SAAS,eAAe,QAAwE;AAC9F,KAAI,CAAC,MAAM,QAAQ,OAAO,CAAE,QAAO;AACnC,KAAI,OAAO,WAAW,EAAG,QAAO;CAChC,MAAM,QAAQ,OAAO;AACrB,QAAO,QAAQ,SAAS,UAAU,SAAS,UAAU,SAAS,EAAE,gBAAgB;;;AAIlF,SAAS,sBAAsB,QAA6C;AAC1E,KAAI,CAAC,MAAM,QAAQ,OAAO,CAAE,QAAO;AACnC,KAAI,OAAO,WAAW,EAAG,QAAO;CAChC,MAAM,QAAQ,OAAO;AACrB,QAAO,QAAQ,SAAS,UAAU,SAAS,gBAAgB;;;;;;;;AAS7D,SAAgB,yBAAyB,QAA8C;AACrF,KAAI,yBAAyB,OAAO,CAAE,QAAO;AAC7C,KAAI,sBAAsB,OAAO,CAAE,QAAO,IAAI,uBAAuB,OAAO;AAC5E,KAAI,eAAe,OAAO,CAAE,QAAO,IAAI,oBAAoB,OAAO;AAElE,OAAM,IAAI,MAAM,4BAA4B"}
1
+ {"version":3,"file":"column_snapshot_provider.js","names":[],"sources":["../../src/columns/column_snapshot_provider.ts"],"sourcesContent":["import type { PObjectId } from \"@milaboratories/pl-model-common\";\nimport { PColumn } from \"@milaboratories/pl-model-common\";\nimport { TreeNodeAccessor } from \"../render/accessor\";\nimport type { PColumnDataUniversal } from \"../render/internal\";\nimport type { ColumnDataStatus, ColumnSnapshot } from \"./column_snapshot\";\n\n// --- ColumnProvider ---\n\n/**\n * Data source interface for column enumeration.\n *\n * Knows nothing about the render framework, stability tracking, labels,\n * anchoring, or splitting. All that complexity lives in the collection layer.\n */\nexport interface ColumnSnapshotProvider {\n /** Returns all currently known columns. */\n getAllColumns(): ColumnSnapshot<PObjectId>[];\n\n /** Whether the provider has finished enumerating all its columns.\n * Calling this may mark the render context unstable — it touches\n * the reactive tree to check field resolution state. */\n isColumnListComplete(): boolean;\n}\n\n// --- ColumnSource ---\n\n/**\n * Union of types that can serve as column sources for helpers and builders.\n * Does NOT include TreeNodeAccessor — call `.toColumnSource()` on it first.\n */\nexport type ColumnSource =\n | ColumnSnapshotProvider\n | ColumnSnapshot<PObjectId>[]\n | PColumn<PColumnDataUniversal | undefined>[];\n\n// --- ArrayColumnProvider ---\n\n/**\n * Simple provider wrapping an array of PColumns.\n * Always complete, data status always 'ready'.\n */\nexport class ArrayColumnProvider implements ColumnSnapshotProvider {\n private readonly columns: ColumnSnapshot<PObjectId>[];\n\n constructor(columns: PColumn<PColumnDataUniversal | undefined>[]) {\n this.columns = columns.map((col) => ({\n id: col.id,\n spec: col.spec,\n dataStatus: \"ready\" as const,\n data: { get: () => col.data },\n }));\n }\n\n getAllColumns(): ColumnSnapshot<PObjectId>[] {\n return this.columns;\n }\n\n isColumnListComplete(): boolean {\n return true;\n }\n}\n\n// --- SnapshotColumnProvider ---\n\n/**\n * Provider wrapping an array of ColumnSnapshots.\n * Always complete. Data status taken from each snapshot.\n */\nexport class SnapshotColumnProvider implements ColumnSnapshotProvider {\n constructor(private readonly snapshots: ColumnSnapshot<PObjectId>[]) {}\n\n getAllColumns(): ColumnSnapshot<PObjectId>[] {\n return this.snapshots;\n }\n\n isColumnListComplete(): boolean {\n return true;\n }\n}\n\n// --- OutputColumnProvider ---\n\nexport interface OutputColumnProviderOpts {\n /** When true and the accessor is final, columns with no ready data get status 'absent'. */\n allowPermanentAbsence?: boolean;\n}\n\n/**\n * Provider wrapping a TreeNodeAccessor (output/prerun resolve result).\n * Detects data status from accessor readiness state.\n */\nexport class OutputColumnProvider implements ColumnSnapshotProvider {\n constructor(\n private readonly accessor: TreeNodeAccessor,\n private readonly opts?: OutputColumnProviderOpts,\n ) {}\n\n getAllColumns(): ColumnSnapshot<PObjectId>[] {\n return this.getColumns();\n }\n\n isColumnListComplete(): boolean {\n return this.accessor.getInputsLocked();\n }\n\n private getColumns(): ColumnSnapshot<PObjectId>[] {\n const pColumns = this.accessor.getPColumns();\n if (pColumns === undefined) return [];\n\n const isFinal = this.accessor.getIsFinal();\n const allowAbsence = this.opts?.allowPermanentAbsence === true;\n\n return pColumns.map((col) => {\n const dataAccessor = col.data;\n const isReady = dataAccessor.getIsReadyOrError();\n\n let dataStatus: ColumnDataStatus;\n if (isReady) {\n dataStatus = \"ready\";\n } else if (allowAbsence && isFinal) {\n dataStatus = \"absent\";\n } else {\n dataStatus = \"computing\";\n }\n\n return {\n id: col.id,\n spec: col.spec,\n dataStatus,\n data: { get: () => (isReady ? dataAccessor : undefined) },\n };\n });\n }\n}\n\n// --- Source normalization ---\n\n/** Checks if a value is a ColumnSnapshotProvider (duck-typing). */\nexport function isColumnSnapshotProvider(source: unknown): source is ColumnSnapshotProvider {\n return (\n typeof source === \"object\" &&\n source !== null &&\n \"getAllColumns\" in source &&\n \"isColumnListComplete\" in source &&\n typeof (source as ColumnSnapshotProvider).getAllColumns === \"function\" &&\n typeof (source as ColumnSnapshotProvider).isColumnListComplete === \"function\"\n );\n}\n\n/** Checks if a value looks like a PColumn (has id, spec, data). */\nfunction isPColumnArray(source: unknown): source is PColumn<PColumnDataUniversal | undefined>[] {\n if (!Array.isArray(source)) return false;\n if (source.length === 0) return true; // empty array — treat as PColumn[]\n const first = source[0];\n return \"id\" in first && \"spec\" in first && \"data\" in first && !(\"dataStatus\" in first);\n}\n\n/** Checks if a value looks like a ColumnSnapshot array. */\nfunction isColumnSnapshotArray(source: unknown): source is ColumnSnapshot<PObjectId>[] {\n if (!Array.isArray(source)) return false;\n if (source.length === 0) return true; // empty array — treat as snapshots\n const first = source[0];\n return \"id\" in first && \"spec\" in first && \"dataStatus\" in first;\n}\n\n/**\n * Normalize any ColumnSource into a ColumnSnapshotProvider.\n * - ColumnSnapshotProvider → returned as-is\n * - ColumnSnapshot<PObjectId>[] → wrapped in SnapshotColumnProvider\n * - PColumn[] → wrapped in ArrayColumnProvider\n */\nexport function toColumnSnapshotProvider(source: ColumnSource): ColumnSnapshotProvider {\n if (isColumnSnapshotProvider(source)) return source;\n if (isColumnSnapshotArray(source)) return new SnapshotColumnProvider(source);\n if (isPColumnArray(source)) return new ArrayColumnProvider(source);\n // Should not reach here given the type union, but be safe\n throw new Error(\"Unknown ColumnSource type\");\n}\n"],"mappings":";;;;;AAyCA,IAAa,sBAAb,MAAmE;CACjE;CAEA,YAAY,SAAsD;AAChE,OAAK,UAAU,QAAQ,KAAK,SAAS;GACnC,IAAI,IAAI;GACR,MAAM,IAAI;GACV,YAAY;GACZ,MAAM,EAAE,WAAW,IAAI,MAAM;GAC9B,EAAE;;CAGL,gBAA6C;AAC3C,SAAO,KAAK;;CAGd,uBAAgC;AAC9B,SAAO;;;;;;;AAUX,IAAa,yBAAb,MAAsE;CACpE,YAAY,WAAyD;AAAxC,OAAA,YAAA;;CAE7B,gBAA6C;AAC3C,SAAO,KAAK;;CAGd,uBAAgC;AAC9B,SAAO;;;;;;;AAeX,IAAa,uBAAb,MAAoE;CAClE,YACE,UACA,MACA;AAFiB,OAAA,WAAA;AACA,OAAA,OAAA;;CAGnB,gBAA6C;AAC3C,SAAO,KAAK,YAAY;;CAG1B,uBAAgC;AAC9B,SAAO,KAAK,SAAS,iBAAiB;;CAGxC,aAAkD;EAChD,MAAM,WAAW,KAAK,SAAS,aAAa;AAC5C,MAAI,aAAa,KAAA,EAAW,QAAO,EAAE;EAErC,MAAM,UAAU,KAAK,SAAS,YAAY;EAC1C,MAAM,eAAe,KAAK,MAAM,0BAA0B;AAE1D,SAAO,SAAS,KAAK,QAAQ;GAC3B,MAAM,eAAe,IAAI;GACzB,MAAM,UAAU,aAAa,mBAAmB;GAEhD,IAAI;AACJ,OAAI,QACF,cAAa;YACJ,gBAAgB,QACzB,cAAa;OAEb,cAAa;AAGf,UAAO;IACL,IAAI,IAAI;IACR,MAAM,IAAI;IACV;IACA,MAAM,EAAE,WAAY,UAAU,eAAe,KAAA,GAAY;IAC1D;IACD;;;;AAON,SAAgB,yBAAyB,QAAmD;AAC1F,QACE,OAAO,WAAW,YAClB,WAAW,QACX,mBAAmB,UACnB,0BAA0B,UAC1B,OAAQ,OAAkC,kBAAkB,cAC5D,OAAQ,OAAkC,yBAAyB;;;AAKvE,SAAS,eAAe,QAAwE;AAC9F,KAAI,CAAC,MAAM,QAAQ,OAAO,CAAE,QAAO;AACnC,KAAI,OAAO,WAAW,EAAG,QAAO;CAChC,MAAM,QAAQ,OAAO;AACrB,QAAO,QAAQ,SAAS,UAAU,SAAS,UAAU,SAAS,EAAE,gBAAgB;;;AAIlF,SAAS,sBAAsB,QAAwD;AACrF,KAAI,CAAC,MAAM,QAAQ,OAAO,CAAE,QAAO;AACnC,KAAI,OAAO,WAAW,EAAG,QAAO;CAChC,MAAM,QAAQ,OAAO;AACrB,QAAO,QAAQ,SAAS,UAAU,SAAS,gBAAgB;;;;;;;;AAS7D,SAAgB,yBAAyB,QAA8C;AACrF,KAAI,yBAAyB,OAAO,CAAE,QAAO;AAC7C,KAAI,sBAAsB,OAAO,CAAE,QAAO,IAAI,uBAAuB,OAAO;AAC5E,KAAI,eAAe,OAAO,CAAE,QAAO,IAAI,oBAAoB,OAAO;AAElE,OAAM,IAAI,MAAM,4BAA4B"}
@@ -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[] {\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 {\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,gBAAkC;AAEhC,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,UACgB;AAChB,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<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,6 +1,7 @@
1
1
  import { RenderCtxBase, ResultPool } from "../render/api.js";
2
2
  import { ColumnSnapshot } from "./column_snapshot.js";
3
3
  import { ColumnSnapshotProvider } from "./column_snapshot_provider.js";
4
+ import { PObjectId } from "@milaboratories/pl-model-common";
4
5
 
5
6
  //#region src/columns/ctx_column_sources.d.ts
6
7
  /**
@@ -24,7 +25,7 @@ declare function collectCtxColumnSnapshotProviders<A, U, S>(ctx: RenderCtxBase<A
24
25
  declare class ResultPoolColumnSnapshotProvider implements ColumnSnapshotProvider {
25
26
  private readonly pool;
26
27
  constructor(pool: ResultPool);
27
- getAllColumns(): ColumnSnapshot[];
28
+ getAllColumns(): ColumnSnapshot<PObjectId>[];
28
29
  isColumnListComplete(): boolean;
29
30
  }
30
31
  //#endregion
@@ -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;EAKjB,oBAAA,CAAA;AAAA"}
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 +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[] {\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 {\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,gBAAkC;AAEhC,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,UACgB;AAChB,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<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"}
@@ -0,0 +1,106 @@
1
+ require("../_virtual/_rolldown/runtime.cjs");
2
+ const require_axis_filtering = require("../render/util/axis_filtering.cjs");
3
+ const require_pcolumn_data = require("../render/util/pcolumn_data.cjs");
4
+ const require_column_snapshot = require("./column_snapshot.cjs");
5
+ let _milaboratories_pl_model_common = require("@milaboratories/pl-model-common");
6
+ //#region src/columns/expand_by_partition.ts
7
+ /**
8
+ * Expand snapshots by splitting along partition axes.
9
+ *
10
+ * For each snapshot, reads partition data, enumerates unique keys on the
11
+ * split axes, and produces one output snapshot per key combination —
12
+ * with the split axes removed from `axesSpec` and a `pl7.app/trace`
13
+ * annotation recording the split origin.
14
+ *
15
+ * Returns `{ items: [], complete: false }` when any snapshot's data
16
+ * is not ready (status !== 'ready' or partition data unavailable).
17
+ */
18
+ function expandByPartition(snapshots, splitAxes, opts) {
19
+ if (splitAxes.length === 0) return {
20
+ items: snapshots,
21
+ complete: true
22
+ };
23
+ const splitAxisIdxs = splitAxes.map((a) => a.idx).sort((a, b) => a - b);
24
+ const result = [];
25
+ for (const snapshot of snapshots) {
26
+ if (snapshot.dataStatus !== "ready" || snapshot.data === void 0) return {
27
+ items: [],
28
+ complete: false
29
+ };
30
+ const dataEntries = require_pcolumn_data.convertOrParsePColumnData(snapshot.data.get());
31
+ if (dataEntries === void 0) return {
32
+ items: [],
33
+ complete: false
34
+ };
35
+ if (!(0, _milaboratories_pl_model_common.isPartitionedDataInfoEntries)(dataEntries)) throw new Error(`Splitting requires Partitioned DataInfoEntries, but got ${dataEntries.type} for column ${String(snapshot.id)}`);
36
+ const uniqueKeys = require_pcolumn_data.getUniquePartitionKeys(dataEntries);
37
+ const maxSplitIdx = splitAxisIdxs[splitAxisIdxs.length - 1];
38
+ if (maxSplitIdx >= dataEntries.partitionKeyLength) throw new Error(`Not enough partition keys (${dataEntries.partitionKeyLength}) for requested split axes (max index ${maxSplitIdx}) in column ${snapshot.spec.name}`);
39
+ const axesLabels = splitAxisIdxs.map((idx) => opts?.axisLabels?.((0, _milaboratories_pl_model_common.getAxisId)(snapshot.spec.axesSpec[idx])));
40
+ const keyCombinations = generateKeyCombinations(uniqueKeys, splitAxisIdxs);
41
+ if (keyCombinations.length === 0) continue;
42
+ const newAxesSpec = [...snapshot.spec.axesSpec];
43
+ for (let i = splitAxisIdxs.length - 1; i >= 0; i--) newAxesSpec.splice(splitAxisIdxs[i], 1);
44
+ for (const keyCombo of keyCombinations) {
45
+ const axisFilters = keyCombo.map((value, sAxisIdx) => [splitAxisIdxs[sAxisIdx], value]);
46
+ const traceEntries = keyCombo.map((value, sAxisIdx) => {
47
+ const axisIdx = splitAxisIdxs[sAxisIdx];
48
+ const axisId = (0, _milaboratories_pl_model_common.getAxisId)(snapshot.spec.axesSpec[axisIdx]);
49
+ const label = axesLabels[sAxisIdx]?.[value] ?? String(value);
50
+ return {
51
+ type: `split:${(0, _milaboratories_pl_model_common.canonicalizeAxisId)(axisId)}`,
52
+ label,
53
+ importance: 1e6
54
+ };
55
+ });
56
+ const filteredData = require_axis_filtering.filterDataInfoEntries(dataEntries, axisFilters);
57
+ const adjustedSpec = {
58
+ ...snapshot.spec,
59
+ axesSpec: newAxesSpec,
60
+ annotations: {
61
+ ...snapshot.spec.annotations,
62
+ "pl7.app/trace": JSON.stringify(traceEntries)
63
+ }
64
+ };
65
+ result.push({
66
+ id: snapshot.id,
67
+ spec: adjustedSpec,
68
+ dataStatus: "ready",
69
+ data: require_column_snapshot.createReadyColumnData(() => (0, _milaboratories_pl_model_common.entriesToDataInfo)(filteredData))
70
+ });
71
+ }
72
+ }
73
+ return {
74
+ items: result,
75
+ complete: true
76
+ };
77
+ }
78
+ const MAX_KEY_COMBINATIONS = 1e4;
79
+ function generateKeyCombinations(uniqueKeys, splitAxisIdxs) {
80
+ const combinations = [];
81
+ function generate(currentCombo, sAxisIdx) {
82
+ if (sAxisIdx >= splitAxisIdxs.length) {
83
+ combinations.push([...currentCombo]);
84
+ if (combinations.length > MAX_KEY_COMBINATIONS) throw new Error("Too many key combinations, aborting.");
85
+ return;
86
+ }
87
+ const axisIdx = splitAxisIdxs[sAxisIdx];
88
+ if (axisIdx >= uniqueKeys.length) throw new Error(`Axis index ${axisIdx} out of bounds for unique keys array (length ${uniqueKeys.length})`);
89
+ const axisValues = uniqueKeys[axisIdx];
90
+ if (!axisValues || axisValues.length === 0) {
91
+ combinations.length = 0;
92
+ return;
93
+ }
94
+ for (const val of axisValues) {
95
+ currentCombo.push(val);
96
+ generate(currentCombo, sAxisIdx + 1);
97
+ currentCombo.pop();
98
+ }
99
+ }
100
+ generate([], 0);
101
+ return combinations;
102
+ }
103
+ //#endregion
104
+ exports.expandByPartition = expandByPartition;
105
+
106
+ //# sourceMappingURL=expand_by_partition.cjs.map