@platforma-sdk/model 1.65.10 → 1.67.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 (151) hide show
  1. package/dist/block_model.cjs +8 -11
  2. package/dist/block_model.cjs.map +1 -1
  3. package/dist/block_model.d.ts.map +1 -1
  4. package/dist/block_model.js +8 -10
  5. package/dist/block_model.js.map +1 -1
  6. package/dist/block_state_util.cjs +2 -1
  7. package/dist/block_state_util.cjs.map +1 -1
  8. package/dist/block_state_util.js +2 -1
  9. package/dist/block_state_util.js.map +1 -1
  10. package/dist/columns/column_collection_builder.cjs +62 -75
  11. package/dist/columns/column_collection_builder.cjs.map +1 -1
  12. package/dist/columns/column_collection_builder.d.ts +17 -23
  13. package/dist/columns/column_collection_builder.d.ts.map +1 -1
  14. package/dist/columns/column_collection_builder.js +63 -76
  15. package/dist/columns/column_collection_builder.js.map +1 -1
  16. package/dist/columns/column_selector.cjs.map +1 -1
  17. package/dist/columns/column_selector.d.ts +1 -1
  18. package/dist/columns/column_selector.js.map +1 -1
  19. package/dist/columns/column_snapshot.cjs.map +1 -1
  20. package/dist/columns/column_snapshot.d.ts +4 -4
  21. package/dist/columns/column_snapshot.d.ts.map +1 -1
  22. package/dist/columns/column_snapshot.js.map +1 -1
  23. package/dist/columns/ctx_column_sources.cjs.map +1 -1
  24. package/dist/columns/ctx_column_sources.d.ts +1 -1
  25. package/dist/columns/ctx_column_sources.d.ts.map +1 -1
  26. package/dist/columns/ctx_column_sources.js.map +1 -1
  27. package/dist/columns/index.cjs +2 -2
  28. package/dist/columns/index.d.ts +1 -1
  29. package/dist/columns/index.js +2 -2
  30. package/dist/components/PlDataTable/createPlDataTable/createPTableDefV2.cjs +2 -2
  31. package/dist/components/PlDataTable/createPlDataTable/createPTableDefV2.cjs.map +1 -1
  32. package/dist/components/PlDataTable/createPlDataTable/createPTableDefV2.js +2 -2
  33. package/dist/components/PlDataTable/createPlDataTable/createPTableDefV2.js.map +1 -1
  34. package/dist/components/PlDataTable/createPlDataTable/createPTableDefV3.cjs +17 -18
  35. package/dist/components/PlDataTable/createPlDataTable/createPTableDefV3.cjs.map +1 -1
  36. package/dist/components/PlDataTable/createPlDataTable/createPTableDefV3.js +17 -18
  37. package/dist/components/PlDataTable/createPlDataTable/createPTableDefV3.js.map +1 -1
  38. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.cjs +99 -91
  39. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.cjs.map +1 -1
  40. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.d.ts +17 -17
  41. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.d.ts.map +1 -1
  42. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.js +102 -94
  43. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.js.map +1 -1
  44. package/dist/components/PlDataTable/createPlDataTable/discoverColumns.cjs +32 -23
  45. package/dist/components/PlDataTable/createPlDataTable/discoverColumns.cjs.map +1 -1
  46. package/dist/components/PlDataTable/createPlDataTable/discoverColumns.d.ts +6 -6
  47. package/dist/components/PlDataTable/createPlDataTable/discoverColumns.d.ts.map +1 -1
  48. package/dist/components/PlDataTable/createPlDataTable/discoverColumns.js +33 -24
  49. package/dist/components/PlDataTable/createPlDataTable/discoverColumns.js.map +1 -1
  50. package/dist/components/PlDataTable/createPlDataTable/index.cjs.map +1 -1
  51. package/dist/components/PlDataTable/createPlDataTable/index.d.ts +2 -3
  52. package/dist/components/PlDataTable/createPlDataTable/index.d.ts.map +1 -1
  53. package/dist/components/PlDataTable/createPlDataTable/index.js.map +1 -1
  54. package/dist/components/PlDataTable/createPlDataTable/utils.cjs +133 -16
  55. package/dist/components/PlDataTable/createPlDataTable/utils.cjs.map +1 -1
  56. package/dist/components/PlDataTable/createPlDataTable/utils.d.ts +8 -6
  57. package/dist/components/PlDataTable/createPlDataTable/utils.d.ts.map +1 -1
  58. package/dist/components/PlDataTable/createPlDataTable/utils.js +130 -17
  59. package/dist/components/PlDataTable/createPlDataTable/utils.js.map +1 -1
  60. package/dist/components/PlDataTable/labels.cjs +1 -2
  61. package/dist/components/PlDataTable/labels.cjs.map +1 -1
  62. package/dist/components/PlDataTable/labels.js +1 -2
  63. package/dist/components/PlDataTable/labels.js.map +1 -1
  64. package/dist/components/PlDatasetSelector/build_dataset_options.cjs +41 -0
  65. package/dist/components/PlDatasetSelector/build_dataset_options.cjs.map +1 -0
  66. package/dist/components/PlDatasetSelector/build_dataset_options.d.ts +19 -0
  67. package/dist/components/PlDatasetSelector/build_dataset_options.d.ts.map +1 -0
  68. package/dist/components/PlDatasetSelector/build_dataset_options.js +41 -0
  69. package/dist/components/PlDatasetSelector/build_dataset_options.js.map +1 -0
  70. package/dist/components/PlDatasetSelector/filter_discovery.cjs +60 -0
  71. package/dist/components/PlDatasetSelector/filter_discovery.cjs.map +1 -0
  72. package/dist/components/PlDatasetSelector/filter_discovery.d.ts +31 -0
  73. package/dist/components/PlDatasetSelector/filter_discovery.d.ts.map +1 -0
  74. package/dist/components/PlDatasetSelector/filter_discovery.js +56 -0
  75. package/dist/components/PlDatasetSelector/filter_discovery.js.map +1 -0
  76. package/dist/components/PlDatasetSelector/index.cjs +2 -0
  77. package/dist/components/PlDatasetSelector/index.d.ts +2 -0
  78. package/dist/components/PlDatasetSelector/index.js +2 -0
  79. package/dist/components/index.cjs +3 -0
  80. package/dist/components/index.d.ts +2 -0
  81. package/dist/components/index.js +3 -0
  82. package/dist/filters/distill.cjs +73 -30
  83. package/dist/filters/distill.cjs.map +1 -1
  84. package/dist/filters/distill.d.ts.map +1 -1
  85. package/dist/filters/distill.js +73 -30
  86. package/dist/filters/distill.js.map +1 -1
  87. package/dist/index.cjs +29 -19
  88. package/dist/index.d.ts +10 -6
  89. package/dist/index.js +12 -8
  90. package/dist/labels/derive_distinct_tooltips.cjs +85 -0
  91. package/dist/labels/derive_distinct_tooltips.cjs.map +1 -0
  92. package/dist/labels/derive_distinct_tooltips.d.ts +17 -0
  93. package/dist/labels/derive_distinct_tooltips.d.ts.map +1 -0
  94. package/dist/labels/derive_distinct_tooltips.js +84 -0
  95. package/dist/labels/derive_distinct_tooltips.js.map +1 -0
  96. package/dist/labels/index.cjs +1 -0
  97. package/dist/labels/index.d.ts +2 -1
  98. package/dist/labels/index.js +1 -0
  99. package/dist/package.cjs +1 -1
  100. package/dist/package.js +1 -1
  101. package/dist/render/api.cjs +8 -13
  102. package/dist/render/api.cjs.map +1 -1
  103. package/dist/render/api.d.ts +8 -11
  104. package/dist/render/api.d.ts.map +1 -1
  105. package/dist/render/api.js +8 -13
  106. package/dist/render/api.js.map +1 -1
  107. package/dist/services/get_services.cjs +19 -0
  108. package/dist/services/get_services.cjs.map +1 -0
  109. package/dist/services/get_services.d.ts +7 -0
  110. package/dist/services/get_services.d.ts.map +1 -0
  111. package/dist/services/get_services.js +19 -0
  112. package/dist/services/get_services.js.map +1 -0
  113. package/dist/services/index.cjs +1 -0
  114. package/dist/services/index.d.ts +2 -1
  115. package/dist/services/index.js +1 -0
  116. package/dist/services/service_bridge.cjs +4 -4
  117. package/dist/services/service_bridge.cjs.map +1 -1
  118. package/dist/services/service_bridge.d.ts +4 -4
  119. package/dist/services/service_bridge.d.ts.map +1 -1
  120. package/dist/services/service_bridge.js +4 -4
  121. package/dist/services/service_bridge.js.map +1 -1
  122. package/package.json +6 -6
  123. package/src/block_model.ts +8 -11
  124. package/src/block_state_util.ts +2 -1
  125. package/src/columns/column_collection_builder.test.ts +75 -30
  126. package/src/columns/column_collection_builder.ts +96 -133
  127. package/src/columns/column_selector.ts +1 -1
  128. package/src/columns/column_snapshot.ts +7 -4
  129. package/src/columns/ctx_column_sources.ts +1 -3
  130. package/src/components/PlDataTable/createPlDataTable/createPTableDefV2.ts +2 -2
  131. package/src/components/PlDataTable/createPlDataTable/createPTableDefV3.ts +44 -21
  132. package/src/components/PlDataTable/createPlDataTable/createPlDataTableV3.ts +202 -218
  133. package/src/components/PlDataTable/createPlDataTable/discoverColumns.ts +69 -56
  134. package/src/components/PlDataTable/createPlDataTable/index.ts +6 -7
  135. package/src/components/PlDataTable/createPlDataTable/utils.test.ts +97 -1
  136. package/src/components/PlDataTable/createPlDataTable/utils.ts +190 -35
  137. package/src/components/PlDataTable/labels.ts +3 -7
  138. package/src/components/PlDatasetSelector/build_dataset_options.ts +56 -0
  139. package/src/components/PlDatasetSelector/filter_discovery.test.ts +156 -0
  140. package/src/components/PlDatasetSelector/filter_discovery.ts +77 -0
  141. package/src/components/PlDatasetSelector/index.ts +2 -0
  142. package/src/components/index.ts +1 -0
  143. package/src/filters/distill.test.ts +91 -0
  144. package/src/filters/distill.ts +102 -46
  145. package/src/labels/derive_distinct_tooltips.test.ts +233 -0
  146. package/src/labels/derive_distinct_tooltips.ts +130 -0
  147. package/src/labels/index.ts +1 -0
  148. package/src/render/api.ts +15 -50
  149. package/src/services/get_services.ts +28 -0
  150. package/src/services/index.ts +1 -0
  151. package/src/services/service_bridge.ts +5 -5
@@ -1,4 +1,8 @@
1
1
  import { deriveDistinctLabels } from "../../../labels/derive_distinct_labels.js";
2
+ import { ArrayColumnProvider } from "../../../columns/column_snapshot_provider.js";
3
+ import { ColumnCollectionBuilder } from "../../../columns/column_collection_builder.js";
4
+ import "../../../columns/index.js";
5
+ import { deriveDistinctTooltips } from "../../../labels/derive_distinct_tooltips.js";
2
6
  import { Annotation, canonicalizeAxisId, canonicalizeJson, getAxisId, readAnnotation, readAnnotationJson } from "@milaboratories/pl-model-common";
3
7
  import { isNil } from "es-toolkit";
4
8
  //#region src/components/PlDataTable/createPlDataTable/utils.ts
@@ -10,20 +14,65 @@ function isColumnHidden(spec) {
10
14
  function isColumnOptional(spec) {
11
15
  return readAnnotation(spec, Annotation.Table.Visibility) === "optional";
12
16
  }
13
- /** Get effective visibility for a column, considering display config rules first, then annotations. */
14
- function getEffectiveVisibility(spec, displayConfig) {
15
- if (displayConfig?.visibility) {
16
- for (const rule of displayConfig.visibility) if (rule.match(spec)) return rule.visibility;
17
+ /** Get effective visibility for a column. Rule map lookup first, then annotation fallback. */
18
+ function getEffectiveVisibility(col, visibilityByColId) {
19
+ const rule = visibilityByColId?.get(col.id);
20
+ if (rule !== void 0) return rule.visibility;
21
+ if (isColumnHidden(col.spec)) return "hidden";
22
+ if (isColumnOptional(col.spec)) return "optional";
23
+ }
24
+ /** Get ordering priority for a column. Rule map lookup first, then annotation fallback. */
25
+ function getOrderPriority(col, orderByColId) {
26
+ const rule = orderByColId?.get(col.id);
27
+ if (rule !== void 0) return rule.priority;
28
+ return readAnnotationJson(col.spec, Annotation.Table.OrderPriority);
29
+ }
30
+ /**
31
+ * Evaluate display rules against a set of columns and return a map of `colId → winning rule`
32
+ * (first-match-wins, preserving original rule order).
33
+ *
34
+ * Predicate-based rules (`ColumnMatcher`) are evaluated directly on the spec.
35
+ * Selector-based rules (`ColumnSelector`) are matched via `PFrameSpecDriver.discoverColumns`
36
+ * using the same engine as `ColumnCollection.findColumns` — no client-side matcher.
37
+ */
38
+ function evaluateRules(rules, columns, pframeSpec) {
39
+ const result = /* @__PURE__ */ new Map();
40
+ if (rules.length === 0 || columns.length === 0) return result;
41
+ const hasSelectorRules = rules.some((rule) => typeof rule.match !== "function");
42
+ const selectorHitsByRule = /* @__PURE__ */ new Map();
43
+ if (hasSelectorRules) {
44
+ const pColumns = dedupeById(columns).map((c) => ({
45
+ id: c.id,
46
+ spec: c.spec,
47
+ data: void 0
48
+ }));
49
+ const collection = new ColumnCollectionBuilder(pframeSpec).addSource(new ArrayColumnProvider(pColumns)).build();
50
+ if (collection === void 0) return result;
51
+ try {
52
+ for (const rule of rules) {
53
+ if (typeof rule.match === "function") continue;
54
+ const hits = collection.findColumns({ include: rule.match });
55
+ selectorHitsByRule.set(rule, new Set(hits.map((h) => h.id)));
56
+ }
57
+ } finally {
58
+ collection.dispose();
59
+ }
60
+ }
61
+ for (const col of columns) for (const rule of rules) if (typeof rule.match === "function" ? rule.match(col.spec) : selectorHitsByRule.get(rule)?.has(col.id) ?? false) {
62
+ result.set(col.id, rule);
63
+ break;
17
64
  }
18
- if (isColumnHidden(spec)) return "hidden";
19
- if (isColumnOptional(spec)) return "optional";
65
+ return result;
20
66
  }
21
- /** Get ordering priority for a column. Display config rules first, then annotation fallback. */
22
- function getOrderPriority(spec, displayConfig) {
23
- if (displayConfig?.ordering) {
24
- for (const rule of displayConfig.ordering) if (rule.match(spec)) return rule.priority;
67
+ function dedupeById(columns) {
68
+ const seen = /* @__PURE__ */ new Set();
69
+ const result = [];
70
+ for (const col of columns) {
71
+ if (seen.has(col.id)) continue;
72
+ seen.add(col.id);
73
+ result.push(col);
25
74
  }
26
- return readAnnotationJson(spec, Annotation.Table.OrderPriority);
75
+ return result;
27
76
  }
28
77
  /**
29
78
  * Writes derived labels into column and axis annotations.
@@ -59,16 +108,16 @@ function withLabelAnnotations(derivedLabels, columns) {
59
108
  });
60
109
  }
61
110
  /**
62
- * Writes effective display properties (OrderPriority, Visibility) from ColumnDisplayOptions
111
+ * Writes effective display properties (OrderPriority, Visibility) from precomputed rule maps
63
112
  * into column annotations. Returns new column objects — originals are not mutated.
64
113
  */
65
- function withTableVisualAnnotations(displayOptions, columns) {
66
- if (displayOptions === void 0) return columns;
114
+ function withTableVisualAnnotations(visibilityByColId, orderByColId, columns) {
115
+ if (visibilityByColId === void 0 && orderByColId === void 0) return columns;
67
116
  return columns.map((col) => {
68
117
  const annotations = { ...col.spec.annotations };
69
- const visibility = getEffectiveVisibility(col.spec, displayOptions);
118
+ const visibility = getEffectiveVisibility(col, visibilityByColId);
70
119
  if (!isNil(visibility)) annotations[Annotation.Table.Visibility] = visibility;
71
- const orderPriority = getOrderPriority(col.spec, displayOptions);
120
+ const orderPriority = getOrderPriority(col, orderByColId);
72
121
  if (!isNil(orderPriority)) annotations[Annotation.Table.OrderPriority] = String(orderPriority);
73
122
  return {
74
123
  ...col,
@@ -79,6 +128,42 @@ function withTableVisualAnnotations(displayOptions, columns) {
79
128
  };
80
129
  });
81
130
  }
131
+ /**
132
+ * Writes derived info annotations into column annotations.
133
+ * Columns without an info entry are passed through unchanged.
134
+ */
135
+ function withInfoAnnotations(infoById, columns) {
136
+ if (isNil(infoById)) return columns;
137
+ return columns.map((col) => {
138
+ const info = infoById[col.id];
139
+ if (isNil(info)) return col;
140
+ return {
141
+ ...col,
142
+ spec: {
143
+ ...col.spec,
144
+ annotations: {
145
+ ...col.spec.annotations,
146
+ [Annotation.Table.Info]: info
147
+ }
148
+ }
149
+ };
150
+ });
151
+ }
152
+ function withHidenAxesAnnotations(columns) {
153
+ return columns.map((col) => ({
154
+ ...col,
155
+ spec: {
156
+ ...col.spec,
157
+ axesSpec: col.spec.axesSpec.map((axis) => ({
158
+ ...axis,
159
+ annotations: {
160
+ ...axis.annotations,
161
+ [Annotation.Table.Visibility]: "hidden"
162
+ }
163
+ }))
164
+ }
165
+ }));
166
+ }
82
167
  /** Derive labels for all table elements: columns via deriveDistinctLabels, axes from label columns. */
83
168
  function deriveAllLabels(options) {
84
169
  const { columns, labelColumns, deriveLabelsOptions } = options;
@@ -96,7 +181,35 @@ function deriveAxisLabels(columns, labelColumns) {
96
181
  for (const axisKey of axisSpecMap.keys()) result[axisKey] = readAnnotation(labelColumns.find((lc) => canonicalizeJson(getAxisId(lc.spec.axesSpec[0])) === axisKey)?.spec ?? axisSpecMap.get(axisKey) ?? {}, Annotation.Label)?.trim() ?? "Unlabeled";
97
182
  return result;
98
183
  }
184
+ /** Derive origin tooltips for columns whose qualifications or linker path carry info. */
185
+ function deriveAllTooltips(options) {
186
+ const { columns } = options;
187
+ const variantCountByOriginal = columns.reduce((acc, c) => {
188
+ return acc.set(c.originalId, (acc.get(c.originalId) ?? 0) + 1);
189
+ }, /* @__PURE__ */ new Map());
190
+ const { entries } = columns.reduce(({ entries, variantSeen }, c) => {
191
+ const variantCount = variantCountByOriginal.get(c.originalId);
192
+ const variantIndex = (variantSeen.set(c.originalId, (variantSeen.get(c.originalId) ?? 0) + 1), variantSeen.get(c.originalId));
193
+ entries.push({
194
+ spec: c.spec,
195
+ linkerPath: c.linkerPath,
196
+ qualifications: c.qualifications,
197
+ distinctiveQualifications: c.distinctiveQualifications,
198
+ variantIndex,
199
+ variantCount
200
+ });
201
+ return {
202
+ entries,
203
+ variantSeen
204
+ };
205
+ }, {
206
+ entries: [],
207
+ variantSeen: /* @__PURE__ */ new Map()
208
+ });
209
+ const tooltips = deriveDistinctTooltips(entries);
210
+ return Object.fromEntries(tooltips.flatMap((t, i) => isNil(t) ? [] : [[columns[i].id, t]]));
211
+ }
99
212
  //#endregion
100
- export { deriveAllLabels, getEffectiveVisibility, getOrderPriority, isColumnHidden, isColumnOptional, withLabelAnnotations, withTableVisualAnnotations };
213
+ export { deriveAllLabels, deriveAllTooltips, evaluateRules, getEffectiveVisibility, getOrderPriority, isColumnHidden, isColumnOptional, withHidenAxesAnnotations, withInfoAnnotations, withLabelAnnotations, withTableVisualAnnotations };
101
214
 
102
215
  //# sourceMappingURL=utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","names":[],"sources":["../../../../src/components/PlDataTable/createPlDataTable/utils.ts"],"sourcesContent":["import {\n type PColumn,\n type PColumnSpec,\n type PObjectId,\n Annotation,\n canonicalizeAxisId,\n canonicalizeJson,\n getAxisId,\n readAnnotation,\n readAnnotationJson,\n} from \"@milaboratories/pl-model-common\";\nimport {\n deriveDistinctLabels,\n type DeriveLabelsOptions,\n} from \"../../../labels/derive_distinct_labels\";\nimport type { ColumnsDisplayOptions } from \"./createPlDataTableV3\";\nimport { isNil } from \"es-toolkit\";\n\n/** Check if column should be omitted from the table */\nexport function isColumnHidden(spec: { annotations?: Annotation }): boolean {\n return readAnnotation(spec, Annotation.Table.Visibility) === \"hidden\";\n}\n\n/** Check if column is hidden by default */\nexport function isColumnOptional(spec: { annotations?: Annotation }): boolean {\n return readAnnotation(spec, Annotation.Table.Visibility) === \"optional\";\n}\n\n/** Get effective visibility for a column, considering display config rules first, then annotations. */\nexport function getEffectiveVisibility(\n spec: PColumnSpec,\n displayConfig?: ColumnsDisplayOptions,\n): undefined | \"default\" | \"optional\" | \"hidden\" {\n if (displayConfig?.visibility) {\n for (const rule of displayConfig.visibility) {\n if (rule.match(spec)) {\n return rule.visibility;\n }\n }\n }\n if (isColumnHidden(spec)) return \"hidden\";\n if (isColumnOptional(spec)) return \"optional\";\n return undefined;\n}\n\n/** Get ordering priority for a column. Display config rules first, then annotation fallback. */\nexport function getOrderPriority(\n spec: PColumnSpec,\n displayConfig?: ColumnsDisplayOptions,\n): undefined | number {\n if (displayConfig?.ordering) {\n for (const rule of displayConfig.ordering) {\n if (rule.match(spec)) {\n return rule.priority;\n }\n }\n }\n return readAnnotationJson(spec, Annotation.Table.OrderPriority);\n}\n\n/**\n * Writes derived labels into column and axis annotations.\n * Returns new column objects with modified specs — original columns are not mutated.\n *\n * For each column: writes derived label into Annotation.Label (if present in derivedLabels).\n * For each axis in column specs: writes derived axis label into AxisSpec annotations.\n */\nexport function withLabelAnnotations<Data>(\n derivedLabels: undefined | Record<string, string>,\n columns: PColumn<Data>[],\n): PColumn<Data>[] {\n if (derivedLabels === undefined) return columns;\n return columns.map((col) => {\n const colLabel = derivedLabels[col.id];\n return {\n ...col,\n spec: {\n ...col.spec,\n ...(isNil(colLabel)\n ? {}\n : { annotations: { ...col.spec.annotations, [Annotation.Label]: colLabel } }),\n axesSpec: col.spec.axesSpec.map((axis) => {\n const label = derivedLabels[canonicalizeAxisId(axis)];\n return isNil(label)\n ? axis\n : { ...axis, annotations: { ...axis.annotations, [Annotation.Label]: label } };\n }),\n },\n };\n });\n}\n\n/**\n * Writes effective display properties (OrderPriority, Visibility) from ColumnDisplayOptions\n * into column annotations. Returns new column objects — originals are not mutated.\n */\nexport function withTableVisualAnnotations<Data>(\n displayOptions: undefined | ColumnsDisplayOptions,\n columns: PColumn<Data>[],\n): PColumn<Data>[] {\n if (displayOptions === undefined) return columns;\n return columns.map((col) => {\n const annotations = { ...col.spec.annotations };\n\n const visibility = getEffectiveVisibility(col.spec, displayOptions);\n if (!isNil(visibility)) annotations[Annotation.Table.Visibility] = visibility;\n\n const orderPriority = getOrderPriority(col.spec, displayOptions);\n if (!isNil(orderPriority)) annotations[Annotation.Table.OrderPriority] = String(orderPriority);\n\n return {\n ...col,\n spec: {\n ...col.spec,\n annotations: annotations,\n },\n };\n });\n}\n\n/** Column shape required by label derivation. */\nexport type LabelableColumn = {\n readonly id: PObjectId;\n readonly spec: PColumnSpec;\n readonly linkerPath?: { spec: PColumnSpec }[];\n};\n\n/** Derive labels for all table elements: columns via deriveDistinctLabels, axes from label columns. */\nexport function deriveAllLabels(options: {\n columns: LabelableColumn[];\n labelColumns: { readonly spec: PColumnSpec }[];\n deriveLabelsOptions?: DeriveLabelsOptions;\n}): Record<string, string> {\n const { columns, labelColumns, deriveLabelsOptions } = options;\n const axisLabels = deriveAxisLabels(columns, labelColumns);\n const columnLabels = deriveDistinctLabels(columns, deriveLabelsOptions).reduce(\n (acc, label, index) => ((acc[columns[index].id] = label), acc),\n {} as Record<string, string>,\n );\n return { ...axisLabels, ...columnLabels };\n}\n\n/** Derive axis labels from matching label columns, falling back to axis spec annotations. */\nfunction deriveAxisLabels(\n columns: { readonly spec: PColumnSpec }[],\n labelColumns: { readonly spec: PColumnSpec }[],\n): Record<string, string> {\n const axisSpecMap = new Map(\n columns.flatMap((c) => c.spec.axesSpec).map((a) => [canonicalizeJson(getAxisId(a)), a]),\n );\n const result: Record<string, string> = {};\n for (const axisKey of axisSpecMap.keys()) {\n const labelCol = labelColumns.find(\n (lc) => canonicalizeJson(getAxisId(lc.spec.axesSpec[0])) === axisKey,\n );\n const source = labelCol?.spec ?? axisSpecMap.get(axisKey);\n result[axisKey] = readAnnotation(source ?? {}, Annotation.Label)?.trim() ?? \"Unlabeled\";\n }\n return result;\n}\n"],"mappings":";;;;;AAmBA,SAAgB,eAAe,MAA6C;AAC1E,QAAO,eAAe,MAAM,WAAW,MAAM,WAAW,KAAK;;;AAI/D,SAAgB,iBAAiB,MAA6C;AAC5E,QAAO,eAAe,MAAM,WAAW,MAAM,WAAW,KAAK;;;AAI/D,SAAgB,uBACd,MACA,eAC+C;AAC/C,KAAI,eAAe;OACZ,MAAM,QAAQ,cAAc,WAC/B,KAAI,KAAK,MAAM,KAAK,CAClB,QAAO,KAAK;;AAIlB,KAAI,eAAe,KAAK,CAAE,QAAO;AACjC,KAAI,iBAAiB,KAAK,CAAE,QAAO;;;AAKrC,SAAgB,iBACd,MACA,eACoB;AACpB,KAAI,eAAe;OACZ,MAAM,QAAQ,cAAc,SAC/B,KAAI,KAAK,MAAM,KAAK,CAClB,QAAO,KAAK;;AAIlB,QAAO,mBAAmB,MAAM,WAAW,MAAM,cAAc;;;;;;;;;AAUjE,SAAgB,qBACd,eACA,SACiB;AACjB,KAAI,kBAAkB,KAAA,EAAW,QAAO;AACxC,QAAO,QAAQ,KAAK,QAAQ;EAC1B,MAAM,WAAW,cAAc,IAAI;AACnC,SAAO;GACL,GAAG;GACH,MAAM;IACJ,GAAG,IAAI;IACP,GAAI,MAAM,SAAS,GACf,EAAE,GACF,EAAE,aAAa;KAAE,GAAG,IAAI,KAAK;MAAc,WAAW,QAAQ;KAAU,EAAE;IAC9E,UAAU,IAAI,KAAK,SAAS,KAAK,SAAS;KACxC,MAAM,QAAQ,cAAc,mBAAmB,KAAK;AACpD,YAAO,MAAM,MAAM,GACf,OACA;MAAE,GAAG;MAAM,aAAa;OAAE,GAAG,KAAK;QAAc,WAAW,QAAQ;OAAO;MAAE;MAChF;IACH;GACF;GACD;;;;;;AAOJ,SAAgB,2BACd,gBACA,SACiB;AACjB,KAAI,mBAAmB,KAAA,EAAW,QAAO;AACzC,QAAO,QAAQ,KAAK,QAAQ;EAC1B,MAAM,cAAc,EAAE,GAAG,IAAI,KAAK,aAAa;EAE/C,MAAM,aAAa,uBAAuB,IAAI,MAAM,eAAe;AACnE,MAAI,CAAC,MAAM,WAAW,CAAE,aAAY,WAAW,MAAM,cAAc;EAEnE,MAAM,gBAAgB,iBAAiB,IAAI,MAAM,eAAe;AAChE,MAAI,CAAC,MAAM,cAAc,CAAE,aAAY,WAAW,MAAM,iBAAiB,OAAO,cAAc;AAE9F,SAAO;GACL,GAAG;GACH,MAAM;IACJ,GAAG,IAAI;IACM;IACd;GACF;GACD;;;AAWJ,SAAgB,gBAAgB,SAIL;CACzB,MAAM,EAAE,SAAS,cAAc,wBAAwB;CACvD,MAAM,aAAa,iBAAiB,SAAS,aAAa;CAC1D,MAAM,eAAe,qBAAqB,SAAS,oBAAoB,CAAC,QACrE,KAAK,OAAO,WAAY,IAAI,QAAQ,OAAO,MAAM,OAAQ,MAC1D,EAAE,CACH;AACD,QAAO;EAAE,GAAG;EAAY,GAAG;EAAc;;;AAI3C,SAAS,iBACP,SACA,cACwB;CACxB,MAAM,cAAc,IAAI,IACtB,QAAQ,SAAS,MAAM,EAAE,KAAK,SAAS,CAAC,KAAK,MAAM,CAAC,iBAAiB,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,CACxF;CACD,MAAM,SAAiC,EAAE;AACzC,MAAK,MAAM,WAAW,YAAY,MAAM,CAKtC,QAAO,WAAW,eAJD,aAAa,MAC3B,OAAO,iBAAiB,UAAU,GAAG,KAAK,SAAS,GAAG,CAAC,KAAK,QAC9D,EACwB,QAAQ,YAAY,IAAI,QAAQ,IACd,EAAE,EAAE,WAAW,MAAM,EAAE,MAAM,IAAI;AAE9E,QAAO"}
1
+ {"version":3,"file":"utils.js","names":[],"sources":["../../../../src/components/PlDataTable/createPlDataTable/utils.ts"],"sourcesContent":["import {\n type PColumn,\n type PColumnSpec,\n type PFrameSpecDriver,\n type PObjectId,\n Annotation,\n canonicalizeAxisId,\n canonicalizeJson,\n DiscoveredPColumnId,\n getAxisId,\n readAnnotation,\n readAnnotationJson,\n} from \"@milaboratories/pl-model-common\";\nimport {\n deriveDistinctLabels,\n type DeriveLabelsOptions,\n} from \"../../../labels/derive_distinct_labels\";\nimport {\n deriveDistinctTooltips,\n type TooltipEntry,\n} from \"../../../labels/derive_distinct_tooltips\";\nimport type { MatchQualifications, MatchVariant } from \"../../../columns\";\nimport type { ColumnMatcher, ColumnOrderRule, ColumnVisibilityRule } from \"./createPlDataTableV3\";\nimport type { ColumnSelector } from \"../../../columns\";\nimport { ArrayColumnProvider, ColumnCollectionBuilder } from \"../../../columns\";\nimport { isNil } from \"es-toolkit\";\n\n/** Check if column should be omitted from the table */\nexport function isColumnHidden(spec: { annotations?: Annotation }): boolean {\n return readAnnotation(spec, Annotation.Table.Visibility) === \"hidden\";\n}\n\n/** Check if column is hidden by default */\nexport function isColumnOptional(spec: { annotations?: Annotation }): boolean {\n return readAnnotation(spec, Annotation.Table.Visibility) === \"optional\";\n}\n\n/** Column shape consumed by rule evaluation. */\nexport type RuleColumn = Pick<PColumn<PObjectId>, \"id\" | \"spec\">;\n\n/** Get effective visibility for a column. Rule map lookup first, then annotation fallback. */\nexport function getEffectiveVisibility(\n col: RuleColumn,\n visibilityByColId?: Map<PObjectId, ColumnVisibilityRule>,\n): undefined | \"default\" | \"optional\" | \"hidden\" {\n const rule = visibilityByColId?.get(col.id);\n if (rule !== undefined) return rule.visibility;\n if (isColumnHidden(col.spec)) return \"hidden\";\n if (isColumnOptional(col.spec)) return \"optional\";\n return undefined;\n}\n\n/** Get ordering priority for a column. Rule map lookup first, then annotation fallback. */\nexport function getOrderPriority(\n col: RuleColumn,\n orderByColId?: Map<PObjectId, ColumnOrderRule>,\n): undefined | number {\n const rule = orderByColId?.get(col.id);\n if (rule !== undefined) return rule.priority;\n return readAnnotationJson(col.spec, Annotation.Table.OrderPriority);\n}\n\n/**\n * Evaluate display rules against a set of columns and return a map of `colId → winning rule`\n * (first-match-wins, preserving original rule order).\n *\n * Predicate-based rules (`ColumnMatcher`) are evaluated directly on the spec.\n * Selector-based rules (`ColumnSelector`) are matched via `PFrameSpecDriver.discoverColumns`\n * using the same engine as `ColumnCollection.findColumns` — no client-side matcher.\n */\nexport function evaluateRules<R extends { match: ColumnMatcher | ColumnSelector }>(\n rules: R[],\n columns: RuleColumn[],\n pframeSpec: PFrameSpecDriver,\n): Map<PObjectId, R> {\n const result = new Map<PObjectId, R>();\n if (rules.length === 0 || columns.length === 0) return result;\n\n const hasSelectorRules = rules.some((rule) => typeof rule.match !== \"function\");\n const selectorHitsByRule = new Map<R, Set<PObjectId>>();\n\n if (hasSelectorRules) {\n const dedupedColumns = dedupeById(columns);\n const pColumns = dedupedColumns.map((c) => ({ id: c.id, spec: c.spec, data: undefined }));\n const collection = new ColumnCollectionBuilder(pframeSpec)\n .addSource(new ArrayColumnProvider(pColumns))\n .build();\n if (collection === undefined) return result;\n\n try {\n for (const rule of rules) {\n if (typeof rule.match === \"function\") continue;\n const hits = collection.findColumns({ include: rule.match });\n selectorHitsByRule.set(rule, new Set(hits.map((h) => h.id)));\n }\n } finally {\n collection.dispose();\n }\n }\n\n for (const col of columns) {\n for (const rule of rules) {\n const matches =\n typeof rule.match === \"function\"\n ? rule.match(col.spec)\n : (selectorHitsByRule.get(rule)?.has(col.id) ?? false);\n if (matches) {\n result.set(col.id, rule);\n break;\n }\n }\n }\n return result;\n}\n\nfunction dedupeById(columns: RuleColumn[]): RuleColumn[] {\n const seen = new Set<PObjectId>();\n const result: RuleColumn[] = [];\n for (const col of columns) {\n if (seen.has(col.id)) continue;\n seen.add(col.id);\n result.push(col);\n }\n return result;\n}\n\n/**\n * Writes derived labels into column and axis annotations.\n * Returns new column objects with modified specs — original columns are not mutated.\n *\n * For each column: writes derived label into Annotation.Label (if present in derivedLabels).\n * For each axis in column specs: writes derived axis label into AxisSpec annotations.\n */\nexport function withLabelAnnotations<\n T extends { readonly id: PObjectId; readonly spec: PColumnSpec },\n>(derivedLabels: undefined | Record<string, string>, columns: T[]): T[] {\n if (derivedLabels === undefined) return columns;\n return columns.map((col) => {\n const colLabel = derivedLabels[col.id];\n return {\n ...col,\n spec: {\n ...col.spec,\n ...(isNil(colLabel)\n ? {}\n : { annotations: { ...col.spec.annotations, [Annotation.Label]: colLabel } }),\n axesSpec: col.spec.axesSpec.map((axis) => {\n const label = derivedLabels[canonicalizeAxisId(axis)];\n return isNil(label)\n ? axis\n : { ...axis, annotations: { ...axis.annotations, [Annotation.Label]: label } };\n }),\n },\n } as T;\n });\n}\n\n/**\n * Writes effective display properties (OrderPriority, Visibility) from precomputed rule maps\n * into column annotations. Returns new column objects — originals are not mutated.\n */\nexport function withTableVisualAnnotations<\n T extends { readonly id: PObjectId; readonly spec: PColumnSpec },\n>(\n visibilityByColId: undefined | Map<PObjectId, ColumnVisibilityRule>,\n orderByColId: undefined | Map<PObjectId, ColumnOrderRule>,\n columns: T[],\n): T[] {\n if (visibilityByColId === undefined && orderByColId === undefined) return columns;\n return columns.map((col) => {\n const annotations = { ...col.spec.annotations };\n\n const visibility = getEffectiveVisibility(col, visibilityByColId);\n if (!isNil(visibility)) annotations[Annotation.Table.Visibility] = visibility;\n\n const orderPriority = getOrderPriority(col, orderByColId);\n if (!isNil(orderPriority)) annotations[Annotation.Table.OrderPriority] = String(orderPriority);\n\n return {\n ...col,\n spec: {\n ...col.spec,\n annotations: annotations,\n },\n } as T;\n });\n}\n\n/**\n * Writes derived info annotations into column annotations.\n * Columns without an info entry are passed through unchanged.\n */\nexport function withInfoAnnotations<\n T extends { readonly id: PObjectId; readonly spec: PColumnSpec },\n>(infoById: undefined | Record<string, string>, columns: T[]): T[] {\n if (isNil(infoById)) return columns;\n return columns.map((col) => {\n const info = infoById[col.id];\n if (isNil(info)) return col;\n return {\n ...col,\n spec: {\n ...col.spec,\n annotations: { ...col.spec.annotations, [Annotation.Table.Info]: info },\n },\n } as T;\n });\n}\n\nexport function withHidenAxesAnnotations<T extends { readonly spec: PColumnSpec }>(\n columns: T[],\n): T[] {\n return columns.map(\n (col) =>\n ({\n ...col,\n spec: {\n ...col.spec,\n axesSpec: col.spec.axesSpec.map((axis) => ({\n ...axis,\n annotations: { ...axis.annotations, [Annotation.Table.Visibility]: \"hidden\" },\n })),\n },\n }) as T,\n );\n}\n\n/** Column shape required by label derivation. */\nexport type LabelableColumn = {\n readonly id: PObjectId;\n readonly spec: PColumnSpec;\n readonly linkerPath?: { spec: PColumnSpec }[];\n};\n\n/** Derive labels for all table elements: columns via deriveDistinctLabels, axes from label columns. */\nexport function deriveAllLabels(options: {\n columns: LabelableColumn[];\n labelColumns: { readonly spec: PColumnSpec }[];\n deriveLabelsOptions?: DeriveLabelsOptions;\n}): Record<string, string> {\n const { columns, labelColumns, deriveLabelsOptions } = options;\n const axisLabels = deriveAxisLabels(columns, labelColumns);\n const columnLabels = deriveDistinctLabels(columns, deriveLabelsOptions).reduce(\n (acc, label, index) => ((acc[columns[index].id] = label), acc),\n {} as Record<string, string>,\n );\n return { ...axisLabels, ...columnLabels };\n}\n\n/** Derive axis labels from matching label columns, falling back to axis spec annotations. */\nfunction deriveAxisLabels(\n columns: { readonly spec: PColumnSpec }[],\n labelColumns: { readonly spec: PColumnSpec }[],\n): Record<string, string> {\n const axisSpecMap = new Map(\n columns.flatMap((c) => c.spec.axesSpec).map((a) => [canonicalizeJson(getAxisId(a)), a]),\n );\n const result: Record<string, string> = {};\n for (const axisKey of axisSpecMap.keys()) {\n const labelCol = labelColumns.find(\n (lc) => canonicalizeJson(getAxisId(lc.spec.axesSpec[0])) === axisKey,\n );\n const source = labelCol?.spec ?? axisSpecMap.get(axisKey);\n result[axisKey] = readAnnotation(source ?? {}, Annotation.Label)?.trim() ?? \"Unlabeled\";\n }\n return result;\n}\n\n/** Column shape required by tooltip derivation. */\nexport type TooltipableColumn = {\n readonly id: DiscoveredPColumnId;\n readonly spec: PColumnSpec;\n readonly originalId: PObjectId;\n readonly linkerPath?: MatchVariant[\"path\"];\n readonly qualifications?: MatchQualifications;\n readonly distinctiveQualifications?: MatchQualifications;\n};\n\n/** Derive origin tooltips for columns whose qualifications or linker path carry info. */\nexport function deriveAllTooltips(options: {\n columns: TooltipableColumn[];\n}): Record<DiscoveredPColumnId, string> {\n const { columns } = options;\n\n const variantCountByOriginal = columns.reduce<Map<PObjectId, number>>((acc, c) => {\n return acc.set(c.originalId, (acc.get(c.originalId) ?? 0) + 1);\n }, new Map());\n\n const { entries } = columns.reduce(\n ({ entries, variantSeen }, c) => {\n const variantCount = variantCountByOriginal.get(c.originalId);\n const variantIndex =\n (variantSeen.set(c.originalId, (variantSeen.get(c.originalId) ?? 0) + 1),\n variantSeen.get(c.originalId));\n\n entries.push({\n spec: c.spec,\n linkerPath: c.linkerPath,\n qualifications: c.qualifications,\n distinctiveQualifications: c.distinctiveQualifications,\n variantIndex,\n variantCount,\n });\n\n return { entries, variantSeen };\n },\n { entries: [] as TooltipEntry[], variantSeen: new Map<PObjectId, number>() },\n );\n\n const tooltips = deriveDistinctTooltips(entries);\n\n return Object.fromEntries(\n tooltips.flatMap((t, i) => (isNil(t) ? [] : [[columns[i].id, t] as const])),\n );\n}\n"],"mappings":"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"}
@@ -3,14 +3,13 @@ const require_column_collection_builder = require("../../columns/column_collecti
3
3
  const require_ctx_column_sources = require("../../columns/ctx_column_sources.cjs");
4
4
  require("../../columns/index.cjs");
5
5
  let _milaboratories_pl_model_common = require("@milaboratories/pl-model-common");
6
- let _milaboratories_helpers = require("@milaboratories/helpers");
7
6
  //#region src/components/PlDataTable/labels.ts
8
7
  /**
9
8
  * Get all label columns visible in the current render context
10
9
  * (result pool + block outputs + prerun).
11
10
  */
12
11
  function getAllLabelColumns(ctx) {
13
- const collection = new require_column_collection_builder.ColumnCollectionBuilder(ctx.services.pframeSpec ?? (0, _milaboratories_helpers.throwError)("PFrameSpec service is required for label discovery.")).addSources(require_ctx_column_sources.collectCtxColumnSnapshotProviders(ctx)).build({ allowPartialColumnList: true });
12
+ const collection = new require_column_collection_builder.ColumnCollectionBuilder(ctx.getService("pframeSpec")).addSources(require_ctx_column_sources.collectCtxColumnSnapshotProviders(ctx)).build({ allowPartialColumnList: true });
14
13
  try {
15
14
  return collection.findColumns({ include: {
16
15
  name: _milaboratories_pl_model_common.PColumnName.Label,
@@ -1 +1 @@
1
- {"version":3,"file":"labels.cjs","names":["ColumnCollectionBuilder","collectCtxColumnSnapshotProviders","PColumnName"],"sources":["../../../src/components/PlDataTable/labels.ts"],"sourcesContent":["import type { AxisId, PColumn, PColumnSpec, PObjectId } from \"@milaboratories/pl-model-common\";\nimport {\n getAxisId,\n isLabelColumn,\n matchAxisId,\n PColumnName,\n Services,\n type RequireServices,\n} from \"@milaboratories/pl-model-common\";\nimport type { PColumnDataUniversal, RenderCtxBase } from \"../../render\";\nimport { ColumnCollectionBuilder, collectCtxColumnSnapshotProviders } from \"../../columns\";\nimport { throwError } from \"@milaboratories/helpers\";\n\n/**\n * Get all label columns visible in the current render context\n * (result pool + block outputs + prerun).\n */\nexport function getAllLabelColumns<A, U, S extends RequireServices<typeof Services.PFrameSpec>>(\n ctx: RenderCtxBase<A, U, S>,\n): PColumn<PColumnDataUniversal>[] {\n const pframeSpec =\n ctx.services.pframeSpec ?? throwError(\"PFrameSpec service is required for label discovery.\");\n const collection = new ColumnCollectionBuilder(pframeSpec)\n .addSources(collectCtxColumnSnapshotProviders(ctx))\n .build({ allowPartialColumnList: true });\n try {\n return collection\n .findColumns({ include: { name: PColumnName.Label, axes: [] } })\n .reduce<PColumn<PColumnDataUniversal>[]>((acc, hit) => {\n const data = hit.data?.get();\n return data === undefined ? acc : [...acc, { id: hit.id, spec: hit.spec, data }];\n }, []);\n } finally {\n collection.dispose();\n }\n}\n\n/** Get label columns matching the provided columns from the result pool */\nexport function getMatchingLabelColumns(\n columns: { spec: PColumnSpec }[],\n allLabelColumns: PColumn<PColumnDataUniversal>[],\n): PColumn<PColumnDataUniversal>[] {\n // split input columns into label and value columns\n const inputLabelColumns: typeof columns = [];\n const inputValueColumns: typeof columns = [];\n for (const column of columns) {\n if (isLabelColumn(column.spec)) {\n inputLabelColumns.push(column);\n } else {\n inputValueColumns.push(column);\n }\n }\n\n // collect distinct axes of value columns\n const unlabeledAxes: AxisId[] = [];\n for (const column of inputValueColumns) {\n for (const axis of column.spec.axesSpec) {\n const axisId = getAxisId(axis);\n if (!unlabeledAxes.some((id) => matchAxisId(id, axisId))) {\n unlabeledAxes.push(axisId);\n }\n }\n }\n\n // remove axes matched by input label columns\n for (const labelColumn of inputLabelColumns) {\n const labelAxisId = getAxisId(labelColumn.spec.axesSpec[0]);\n const labelMatch = unlabeledAxes.findIndex((axisId) => matchAxisId(axisId, labelAxisId));\n if (labelMatch !== -1) {\n unlabeledAxes.splice(labelMatch, 1);\n }\n }\n\n // warning: changing this id will break backward compatibility\n const colId = (\n id: PObjectId,\n domain?: Record<string, string>,\n contextDomain?: Record<string, string>,\n ): PObjectId => {\n let wid = id.toString();\n if (domain) {\n for (const k in domain) {\n wid += k;\n wid += domain[k];\n }\n }\n if (contextDomain) {\n for (const k in contextDomain) {\n wid += k;\n wid += contextDomain[k];\n }\n }\n return wid as PObjectId;\n };\n\n // search label columns for unmatched axes\n const labelColumns: typeof allLabelColumns = [];\n for (const labelColumn of allLabelColumns) {\n const labelAxis = labelColumn.spec.axesSpec[0];\n const labelAxisId = getAxisId(labelAxis);\n const labelMatch = unlabeledAxes.findIndex((axisId) => matchAxisId(axisId, labelAxisId));\n if (labelMatch !== -1) {\n const axisId = unlabeledAxes[labelMatch];\n const dataDomainLen =\n Object.keys(axisId.domain ?? {}).length + Object.keys(axisId.contextDomain ?? {}).length;\n const labelDomainLen =\n Object.keys(labelAxis.domain ?? {}).length +\n Object.keys(labelAxis.contextDomain ?? {}).length;\n if (dataDomainLen > labelDomainLen) {\n labelColumns.push({\n id: colId(labelColumn.id, axisId.domain, axisId.contextDomain),\n spec: {\n ...labelColumn.spec,\n axesSpec: [{ ...axisId, annotations: labelAxis.annotations }],\n },\n data: labelColumn.data,\n });\n } else {\n labelColumns.push(labelColumn);\n }\n unlabeledAxes.splice(labelMatch, 1);\n }\n }\n return labelColumns;\n}\n"],"mappings":";;;;;;;;;;;AAiBA,SAAgB,mBACd,KACiC;CAGjC,MAAM,aAAa,IAAIA,kCAAAA,wBADrB,IAAI,SAAS,eAAA,GAAA,wBAAA,YAAyB,sDAAsD,CACpC,CACvD,WAAWC,2BAAAA,kCAAkC,IAAI,CAAC,CAClD,MAAM,EAAE,wBAAwB,MAAM,CAAC;AAC1C,KAAI;AACF,SAAO,WACJ,YAAY,EAAE,SAAS;GAAE,MAAMC,gCAAAA,YAAY;GAAO,MAAM,EAAE;GAAE,EAAE,CAAC,CAC/D,QAAyC,KAAK,QAAQ;GACrD,MAAM,OAAO,IAAI,MAAM,KAAK;AAC5B,UAAO,SAAS,KAAA,IAAY,MAAM,CAAC,GAAG,KAAK;IAAE,IAAI,IAAI;IAAI,MAAM,IAAI;IAAM;IAAM,CAAC;KAC/E,EAAE,CAAC;WACA;AACR,aAAW,SAAS;;;;AAKxB,SAAgB,wBACd,SACA,iBACiC;CAEjC,MAAM,oBAAoC,EAAE;CAC5C,MAAM,oBAAoC,EAAE;AAC5C,MAAK,MAAM,UAAU,QACnB,MAAA,GAAA,gCAAA,eAAkB,OAAO,KAAK,CAC5B,mBAAkB,KAAK,OAAO;KAE9B,mBAAkB,KAAK,OAAO;CAKlC,MAAM,gBAA0B,EAAE;AAClC,MAAK,MAAM,UAAU,kBACnB,MAAK,MAAM,QAAQ,OAAO,KAAK,UAAU;EACvC,MAAM,UAAA,GAAA,gCAAA,WAAmB,KAAK;AAC9B,MAAI,CAAC,cAAc,MAAM,QAAA,GAAA,gCAAA,aAAmB,IAAI,OAAO,CAAC,CACtD,eAAc,KAAK,OAAO;;AAMhC,MAAK,MAAM,eAAe,mBAAmB;EAC3C,MAAM,eAAA,GAAA,gCAAA,WAAwB,YAAY,KAAK,SAAS,GAAG;EAC3D,MAAM,aAAa,cAAc,WAAW,YAAA,GAAA,gCAAA,aAAuB,QAAQ,YAAY,CAAC;AACxF,MAAI,eAAe,GACjB,eAAc,OAAO,YAAY,EAAE;;CAKvC,MAAM,SACJ,IACA,QACA,kBACc;EACd,IAAI,MAAM,GAAG,UAAU;AACvB,MAAI,OACF,MAAK,MAAM,KAAK,QAAQ;AACtB,UAAO;AACP,UAAO,OAAO;;AAGlB,MAAI,cACF,MAAK,MAAM,KAAK,eAAe;AAC7B,UAAO;AACP,UAAO,cAAc;;AAGzB,SAAO;;CAIT,MAAM,eAAuC,EAAE;AAC/C,MAAK,MAAM,eAAe,iBAAiB;EACzC,MAAM,YAAY,YAAY,KAAK,SAAS;EAC5C,MAAM,eAAA,GAAA,gCAAA,WAAwB,UAAU;EACxC,MAAM,aAAa,cAAc,WAAW,YAAA,GAAA,gCAAA,aAAuB,QAAQ,YAAY,CAAC;AACxF,MAAI,eAAe,IAAI;GACrB,MAAM,SAAS,cAAc;AAM7B,OAJE,OAAO,KAAK,OAAO,UAAU,EAAE,CAAC,CAAC,SAAS,OAAO,KAAK,OAAO,iBAAiB,EAAE,CAAC,CAAC,SAElF,OAAO,KAAK,UAAU,UAAU,EAAE,CAAC,CAAC,SACpC,OAAO,KAAK,UAAU,iBAAiB,EAAE,CAAC,CAAC,OAE3C,cAAa,KAAK;IAChB,IAAI,MAAM,YAAY,IAAI,OAAO,QAAQ,OAAO,cAAc;IAC9D,MAAM;KACJ,GAAG,YAAY;KACf,UAAU,CAAC;MAAE,GAAG;MAAQ,aAAa,UAAU;MAAa,CAAC;KAC9D;IACD,MAAM,YAAY;IACnB,CAAC;OAEF,cAAa,KAAK,YAAY;AAEhC,iBAAc,OAAO,YAAY,EAAE;;;AAGvC,QAAO"}
1
+ {"version":3,"file":"labels.cjs","names":["ColumnCollectionBuilder","collectCtxColumnSnapshotProviders","PColumnName"],"sources":["../../../src/components/PlDataTable/labels.ts"],"sourcesContent":["import type { AxisId, PColumn, PColumnSpec, PObjectId } from \"@milaboratories/pl-model-common\";\nimport {\n getAxisId,\n isLabelColumn,\n matchAxisId,\n PColumnName,\n} from \"@milaboratories/pl-model-common\";\nimport type { PColumnDataUniversal, RenderCtxBase } from \"../../render\";\nimport { ColumnCollectionBuilder, collectCtxColumnSnapshotProviders } from \"../../columns\";\n\n/**\n * Get all label columns visible in the current render context\n * (result pool + block outputs + prerun).\n */\nexport function getAllLabelColumns<A, U>(\n ctx: RenderCtxBase<A, U>,\n): PColumn<PColumnDataUniversal>[] {\n const pframeSpec = ctx.getService(\"pframeSpec\");\n const collection = new ColumnCollectionBuilder(pframeSpec)\n .addSources(collectCtxColumnSnapshotProviders(ctx))\n .build({ allowPartialColumnList: true });\n try {\n return collection\n .findColumns({ include: { name: PColumnName.Label, axes: [] } })\n .reduce<PColumn<PColumnDataUniversal>[]>((acc, hit) => {\n const data = hit.data?.get();\n return data === undefined ? acc : [...acc, { id: hit.id, spec: hit.spec, data }];\n }, []);\n } finally {\n collection.dispose();\n }\n}\n\n/** Get label columns matching the provided columns from the result pool */\nexport function getMatchingLabelColumns(\n columns: { spec: PColumnSpec }[],\n allLabelColumns: PColumn<PColumnDataUniversal>[],\n): PColumn<PColumnDataUniversal>[] {\n // split input columns into label and value columns\n const inputLabelColumns: typeof columns = [];\n const inputValueColumns: typeof columns = [];\n for (const column of columns) {\n if (isLabelColumn(column.spec)) {\n inputLabelColumns.push(column);\n } else {\n inputValueColumns.push(column);\n }\n }\n\n // collect distinct axes of value columns\n const unlabeledAxes: AxisId[] = [];\n for (const column of inputValueColumns) {\n for (const axis of column.spec.axesSpec) {\n const axisId = getAxisId(axis);\n if (!unlabeledAxes.some((id) => matchAxisId(id, axisId))) {\n unlabeledAxes.push(axisId);\n }\n }\n }\n\n // remove axes matched by input label columns\n for (const labelColumn of inputLabelColumns) {\n const labelAxisId = getAxisId(labelColumn.spec.axesSpec[0]);\n const labelMatch = unlabeledAxes.findIndex((axisId) => matchAxisId(axisId, labelAxisId));\n if (labelMatch !== -1) {\n unlabeledAxes.splice(labelMatch, 1);\n }\n }\n\n // warning: changing this id will break backward compatibility\n const colId = (\n id: PObjectId,\n domain?: Record<string, string>,\n contextDomain?: Record<string, string>,\n ): PObjectId => {\n let wid = id.toString();\n if (domain) {\n for (const k in domain) {\n wid += k;\n wid += domain[k];\n }\n }\n if (contextDomain) {\n for (const k in contextDomain) {\n wid += k;\n wid += contextDomain[k];\n }\n }\n return wid as PObjectId;\n };\n\n // search label columns for unmatched axes\n const labelColumns: typeof allLabelColumns = [];\n for (const labelColumn of allLabelColumns) {\n const labelAxis = labelColumn.spec.axesSpec[0];\n const labelAxisId = getAxisId(labelAxis);\n const labelMatch = unlabeledAxes.findIndex((axisId) => matchAxisId(axisId, labelAxisId));\n if (labelMatch !== -1) {\n const axisId = unlabeledAxes[labelMatch];\n const dataDomainLen =\n Object.keys(axisId.domain ?? {}).length + Object.keys(axisId.contextDomain ?? {}).length;\n const labelDomainLen =\n Object.keys(labelAxis.domain ?? {}).length +\n Object.keys(labelAxis.contextDomain ?? {}).length;\n if (dataDomainLen > labelDomainLen) {\n labelColumns.push({\n id: colId(labelColumn.id, axisId.domain, axisId.contextDomain),\n spec: {\n ...labelColumn.spec,\n axesSpec: [{ ...axisId, annotations: labelAxis.annotations }],\n },\n data: labelColumn.data,\n });\n } else {\n labelColumns.push(labelColumn);\n }\n unlabeledAxes.splice(labelMatch, 1);\n }\n }\n return labelColumns;\n}\n"],"mappings":";;;;;;;;;;AAcA,SAAgB,mBACd,KACiC;CAEjC,MAAM,aAAa,IAAIA,kCAAAA,wBADJ,IAAI,WAAW,aAAa,CACW,CACvD,WAAWC,2BAAAA,kCAAkC,IAAI,CAAC,CAClD,MAAM,EAAE,wBAAwB,MAAM,CAAC;AAC1C,KAAI;AACF,SAAO,WACJ,YAAY,EAAE,SAAS;GAAE,MAAMC,gCAAAA,YAAY;GAAO,MAAM,EAAE;GAAE,EAAE,CAAC,CAC/D,QAAyC,KAAK,QAAQ;GACrD,MAAM,OAAO,IAAI,MAAM,KAAK;AAC5B,UAAO,SAAS,KAAA,IAAY,MAAM,CAAC,GAAG,KAAK;IAAE,IAAI,IAAI;IAAI,MAAM,IAAI;IAAM;IAAM,CAAC;KAC/E,EAAE,CAAC;WACA;AACR,aAAW,SAAS;;;;AAKxB,SAAgB,wBACd,SACA,iBACiC;CAEjC,MAAM,oBAAoC,EAAE;CAC5C,MAAM,oBAAoC,EAAE;AAC5C,MAAK,MAAM,UAAU,QACnB,MAAA,GAAA,gCAAA,eAAkB,OAAO,KAAK,CAC5B,mBAAkB,KAAK,OAAO;KAE9B,mBAAkB,KAAK,OAAO;CAKlC,MAAM,gBAA0B,EAAE;AAClC,MAAK,MAAM,UAAU,kBACnB,MAAK,MAAM,QAAQ,OAAO,KAAK,UAAU;EACvC,MAAM,UAAA,GAAA,gCAAA,WAAmB,KAAK;AAC9B,MAAI,CAAC,cAAc,MAAM,QAAA,GAAA,gCAAA,aAAmB,IAAI,OAAO,CAAC,CACtD,eAAc,KAAK,OAAO;;AAMhC,MAAK,MAAM,eAAe,mBAAmB;EAC3C,MAAM,eAAA,GAAA,gCAAA,WAAwB,YAAY,KAAK,SAAS,GAAG;EAC3D,MAAM,aAAa,cAAc,WAAW,YAAA,GAAA,gCAAA,aAAuB,QAAQ,YAAY,CAAC;AACxF,MAAI,eAAe,GACjB,eAAc,OAAO,YAAY,EAAE;;CAKvC,MAAM,SACJ,IACA,QACA,kBACc;EACd,IAAI,MAAM,GAAG,UAAU;AACvB,MAAI,OACF,MAAK,MAAM,KAAK,QAAQ;AACtB,UAAO;AACP,UAAO,OAAO;;AAGlB,MAAI,cACF,MAAK,MAAM,KAAK,eAAe;AAC7B,UAAO;AACP,UAAO,cAAc;;AAGzB,SAAO;;CAIT,MAAM,eAAuC,EAAE;AAC/C,MAAK,MAAM,eAAe,iBAAiB;EACzC,MAAM,YAAY,YAAY,KAAK,SAAS;EAC5C,MAAM,eAAA,GAAA,gCAAA,WAAwB,UAAU;EACxC,MAAM,aAAa,cAAc,WAAW,YAAA,GAAA,gCAAA,aAAuB,QAAQ,YAAY,CAAC;AACxF,MAAI,eAAe,IAAI;GACrB,MAAM,SAAS,cAAc;AAM7B,OAJE,OAAO,KAAK,OAAO,UAAU,EAAE,CAAC,CAAC,SAAS,OAAO,KAAK,OAAO,iBAAiB,EAAE,CAAC,CAAC,SAElF,OAAO,KAAK,UAAU,UAAU,EAAE,CAAC,CAAC,SACpC,OAAO,KAAK,UAAU,iBAAiB,EAAE,CAAC,CAAC,OAE3C,cAAa,KAAK;IAChB,IAAI,MAAM,YAAY,IAAI,OAAO,QAAQ,OAAO,cAAc;IAC9D,MAAM;KACJ,GAAG,YAAY;KACf,UAAU,CAAC;MAAE,GAAG;MAAQ,aAAa,UAAU;MAAa,CAAC;KAC9D;IACD,MAAM,YAAY;IACnB,CAAC;OAEF,cAAa,KAAK,YAAY;AAEhC,iBAAc,OAAO,YAAY,EAAE;;;AAGvC,QAAO"}
@@ -2,14 +2,13 @@ import { ColumnCollectionBuilder } from "../../columns/column_collection_builder
2
2
  import { collectCtxColumnSnapshotProviders } from "../../columns/ctx_column_sources.js";
3
3
  import "../../columns/index.js";
4
4
  import { PColumnName, getAxisId, isLabelColumn, matchAxisId } from "@milaboratories/pl-model-common";
5
- import { throwError } from "@milaboratories/helpers";
6
5
  //#region src/components/PlDataTable/labels.ts
7
6
  /**
8
7
  * Get all label columns visible in the current render context
9
8
  * (result pool + block outputs + prerun).
10
9
  */
11
10
  function getAllLabelColumns(ctx) {
12
- const collection = new ColumnCollectionBuilder(ctx.services.pframeSpec ?? throwError("PFrameSpec service is required for label discovery.")).addSources(collectCtxColumnSnapshotProviders(ctx)).build({ allowPartialColumnList: true });
11
+ const collection = new ColumnCollectionBuilder(ctx.getService("pframeSpec")).addSources(collectCtxColumnSnapshotProviders(ctx)).build({ allowPartialColumnList: true });
13
12
  try {
14
13
  return collection.findColumns({ include: {
15
14
  name: PColumnName.Label,
@@ -1 +1 @@
1
- {"version":3,"file":"labels.js","names":[],"sources":["../../../src/components/PlDataTable/labels.ts"],"sourcesContent":["import type { AxisId, PColumn, PColumnSpec, PObjectId } from \"@milaboratories/pl-model-common\";\nimport {\n getAxisId,\n isLabelColumn,\n matchAxisId,\n PColumnName,\n Services,\n type RequireServices,\n} from \"@milaboratories/pl-model-common\";\nimport type { PColumnDataUniversal, RenderCtxBase } from \"../../render\";\nimport { ColumnCollectionBuilder, collectCtxColumnSnapshotProviders } from \"../../columns\";\nimport { throwError } from \"@milaboratories/helpers\";\n\n/**\n * Get all label columns visible in the current render context\n * (result pool + block outputs + prerun).\n */\nexport function getAllLabelColumns<A, U, S extends RequireServices<typeof Services.PFrameSpec>>(\n ctx: RenderCtxBase<A, U, S>,\n): PColumn<PColumnDataUniversal>[] {\n const pframeSpec =\n ctx.services.pframeSpec ?? throwError(\"PFrameSpec service is required for label discovery.\");\n const collection = new ColumnCollectionBuilder(pframeSpec)\n .addSources(collectCtxColumnSnapshotProviders(ctx))\n .build({ allowPartialColumnList: true });\n try {\n return collection\n .findColumns({ include: { name: PColumnName.Label, axes: [] } })\n .reduce<PColumn<PColumnDataUniversal>[]>((acc, hit) => {\n const data = hit.data?.get();\n return data === undefined ? acc : [...acc, { id: hit.id, spec: hit.spec, data }];\n }, []);\n } finally {\n collection.dispose();\n }\n}\n\n/** Get label columns matching the provided columns from the result pool */\nexport function getMatchingLabelColumns(\n columns: { spec: PColumnSpec }[],\n allLabelColumns: PColumn<PColumnDataUniversal>[],\n): PColumn<PColumnDataUniversal>[] {\n // split input columns into label and value columns\n const inputLabelColumns: typeof columns = [];\n const inputValueColumns: typeof columns = [];\n for (const column of columns) {\n if (isLabelColumn(column.spec)) {\n inputLabelColumns.push(column);\n } else {\n inputValueColumns.push(column);\n }\n }\n\n // collect distinct axes of value columns\n const unlabeledAxes: AxisId[] = [];\n for (const column of inputValueColumns) {\n for (const axis of column.spec.axesSpec) {\n const axisId = getAxisId(axis);\n if (!unlabeledAxes.some((id) => matchAxisId(id, axisId))) {\n unlabeledAxes.push(axisId);\n }\n }\n }\n\n // remove axes matched by input label columns\n for (const labelColumn of inputLabelColumns) {\n const labelAxisId = getAxisId(labelColumn.spec.axesSpec[0]);\n const labelMatch = unlabeledAxes.findIndex((axisId) => matchAxisId(axisId, labelAxisId));\n if (labelMatch !== -1) {\n unlabeledAxes.splice(labelMatch, 1);\n }\n }\n\n // warning: changing this id will break backward compatibility\n const colId = (\n id: PObjectId,\n domain?: Record<string, string>,\n contextDomain?: Record<string, string>,\n ): PObjectId => {\n let wid = id.toString();\n if (domain) {\n for (const k in domain) {\n wid += k;\n wid += domain[k];\n }\n }\n if (contextDomain) {\n for (const k in contextDomain) {\n wid += k;\n wid += contextDomain[k];\n }\n }\n return wid as PObjectId;\n };\n\n // search label columns for unmatched axes\n const labelColumns: typeof allLabelColumns = [];\n for (const labelColumn of allLabelColumns) {\n const labelAxis = labelColumn.spec.axesSpec[0];\n const labelAxisId = getAxisId(labelAxis);\n const labelMatch = unlabeledAxes.findIndex((axisId) => matchAxisId(axisId, labelAxisId));\n if (labelMatch !== -1) {\n const axisId = unlabeledAxes[labelMatch];\n const dataDomainLen =\n Object.keys(axisId.domain ?? {}).length + Object.keys(axisId.contextDomain ?? {}).length;\n const labelDomainLen =\n Object.keys(labelAxis.domain ?? {}).length +\n Object.keys(labelAxis.contextDomain ?? {}).length;\n if (dataDomainLen > labelDomainLen) {\n labelColumns.push({\n id: colId(labelColumn.id, axisId.domain, axisId.contextDomain),\n spec: {\n ...labelColumn.spec,\n axesSpec: [{ ...axisId, annotations: labelAxis.annotations }],\n },\n data: labelColumn.data,\n });\n } else {\n labelColumns.push(labelColumn);\n }\n unlabeledAxes.splice(labelMatch, 1);\n }\n }\n return labelColumns;\n}\n"],"mappings":";;;;;;;;;;AAiBA,SAAgB,mBACd,KACiC;CAGjC,MAAM,aAAa,IAAI,wBADrB,IAAI,SAAS,cAAc,WAAW,sDAAsD,CACpC,CACvD,WAAW,kCAAkC,IAAI,CAAC,CAClD,MAAM,EAAE,wBAAwB,MAAM,CAAC;AAC1C,KAAI;AACF,SAAO,WACJ,YAAY,EAAE,SAAS;GAAE,MAAM,YAAY;GAAO,MAAM,EAAE;GAAE,EAAE,CAAC,CAC/D,QAAyC,KAAK,QAAQ;GACrD,MAAM,OAAO,IAAI,MAAM,KAAK;AAC5B,UAAO,SAAS,KAAA,IAAY,MAAM,CAAC,GAAG,KAAK;IAAE,IAAI,IAAI;IAAI,MAAM,IAAI;IAAM;IAAM,CAAC;KAC/E,EAAE,CAAC;WACA;AACR,aAAW,SAAS;;;;AAKxB,SAAgB,wBACd,SACA,iBACiC;CAEjC,MAAM,oBAAoC,EAAE;CAC5C,MAAM,oBAAoC,EAAE;AAC5C,MAAK,MAAM,UAAU,QACnB,KAAI,cAAc,OAAO,KAAK,CAC5B,mBAAkB,KAAK,OAAO;KAE9B,mBAAkB,KAAK,OAAO;CAKlC,MAAM,gBAA0B,EAAE;AAClC,MAAK,MAAM,UAAU,kBACnB,MAAK,MAAM,QAAQ,OAAO,KAAK,UAAU;EACvC,MAAM,SAAS,UAAU,KAAK;AAC9B,MAAI,CAAC,cAAc,MAAM,OAAO,YAAY,IAAI,OAAO,CAAC,CACtD,eAAc,KAAK,OAAO;;AAMhC,MAAK,MAAM,eAAe,mBAAmB;EAC3C,MAAM,cAAc,UAAU,YAAY,KAAK,SAAS,GAAG;EAC3D,MAAM,aAAa,cAAc,WAAW,WAAW,YAAY,QAAQ,YAAY,CAAC;AACxF,MAAI,eAAe,GACjB,eAAc,OAAO,YAAY,EAAE;;CAKvC,MAAM,SACJ,IACA,QACA,kBACc;EACd,IAAI,MAAM,GAAG,UAAU;AACvB,MAAI,OACF,MAAK,MAAM,KAAK,QAAQ;AACtB,UAAO;AACP,UAAO,OAAO;;AAGlB,MAAI,cACF,MAAK,MAAM,KAAK,eAAe;AAC7B,UAAO;AACP,UAAO,cAAc;;AAGzB,SAAO;;CAIT,MAAM,eAAuC,EAAE;AAC/C,MAAK,MAAM,eAAe,iBAAiB;EACzC,MAAM,YAAY,YAAY,KAAK,SAAS;EAC5C,MAAM,cAAc,UAAU,UAAU;EACxC,MAAM,aAAa,cAAc,WAAW,WAAW,YAAY,QAAQ,YAAY,CAAC;AACxF,MAAI,eAAe,IAAI;GACrB,MAAM,SAAS,cAAc;AAM7B,OAJE,OAAO,KAAK,OAAO,UAAU,EAAE,CAAC,CAAC,SAAS,OAAO,KAAK,OAAO,iBAAiB,EAAE,CAAC,CAAC,SAElF,OAAO,KAAK,UAAU,UAAU,EAAE,CAAC,CAAC,SACpC,OAAO,KAAK,UAAU,iBAAiB,EAAE,CAAC,CAAC,OAE3C,cAAa,KAAK;IAChB,IAAI,MAAM,YAAY,IAAI,OAAO,QAAQ,OAAO,cAAc;IAC9D,MAAM;KACJ,GAAG,YAAY;KACf,UAAU,CAAC;MAAE,GAAG;MAAQ,aAAa,UAAU;MAAa,CAAC;KAC9D;IACD,MAAM,YAAY;IACnB,CAAC;OAEF,cAAa,KAAK,YAAY;AAEhC,iBAAc,OAAO,YAAY,EAAE;;;AAGvC,QAAO"}
1
+ {"version":3,"file":"labels.js","names":[],"sources":["../../../src/components/PlDataTable/labels.ts"],"sourcesContent":["import type { AxisId, PColumn, PColumnSpec, PObjectId } from \"@milaboratories/pl-model-common\";\nimport {\n getAxisId,\n isLabelColumn,\n matchAxisId,\n PColumnName,\n} from \"@milaboratories/pl-model-common\";\nimport type { PColumnDataUniversal, RenderCtxBase } from \"../../render\";\nimport { ColumnCollectionBuilder, collectCtxColumnSnapshotProviders } from \"../../columns\";\n\n/**\n * Get all label columns visible in the current render context\n * (result pool + block outputs + prerun).\n */\nexport function getAllLabelColumns<A, U>(\n ctx: RenderCtxBase<A, U>,\n): PColumn<PColumnDataUniversal>[] {\n const pframeSpec = ctx.getService(\"pframeSpec\");\n const collection = new ColumnCollectionBuilder(pframeSpec)\n .addSources(collectCtxColumnSnapshotProviders(ctx))\n .build({ allowPartialColumnList: true });\n try {\n return collection\n .findColumns({ include: { name: PColumnName.Label, axes: [] } })\n .reduce<PColumn<PColumnDataUniversal>[]>((acc, hit) => {\n const data = hit.data?.get();\n return data === undefined ? acc : [...acc, { id: hit.id, spec: hit.spec, data }];\n }, []);\n } finally {\n collection.dispose();\n }\n}\n\n/** Get label columns matching the provided columns from the result pool */\nexport function getMatchingLabelColumns(\n columns: { spec: PColumnSpec }[],\n allLabelColumns: PColumn<PColumnDataUniversal>[],\n): PColumn<PColumnDataUniversal>[] {\n // split input columns into label and value columns\n const inputLabelColumns: typeof columns = [];\n const inputValueColumns: typeof columns = [];\n for (const column of columns) {\n if (isLabelColumn(column.spec)) {\n inputLabelColumns.push(column);\n } else {\n inputValueColumns.push(column);\n }\n }\n\n // collect distinct axes of value columns\n const unlabeledAxes: AxisId[] = [];\n for (const column of inputValueColumns) {\n for (const axis of column.spec.axesSpec) {\n const axisId = getAxisId(axis);\n if (!unlabeledAxes.some((id) => matchAxisId(id, axisId))) {\n unlabeledAxes.push(axisId);\n }\n }\n }\n\n // remove axes matched by input label columns\n for (const labelColumn of inputLabelColumns) {\n const labelAxisId = getAxisId(labelColumn.spec.axesSpec[0]);\n const labelMatch = unlabeledAxes.findIndex((axisId) => matchAxisId(axisId, labelAxisId));\n if (labelMatch !== -1) {\n unlabeledAxes.splice(labelMatch, 1);\n }\n }\n\n // warning: changing this id will break backward compatibility\n const colId = (\n id: PObjectId,\n domain?: Record<string, string>,\n contextDomain?: Record<string, string>,\n ): PObjectId => {\n let wid = id.toString();\n if (domain) {\n for (const k in domain) {\n wid += k;\n wid += domain[k];\n }\n }\n if (contextDomain) {\n for (const k in contextDomain) {\n wid += k;\n wid += contextDomain[k];\n }\n }\n return wid as PObjectId;\n };\n\n // search label columns for unmatched axes\n const labelColumns: typeof allLabelColumns = [];\n for (const labelColumn of allLabelColumns) {\n const labelAxis = labelColumn.spec.axesSpec[0];\n const labelAxisId = getAxisId(labelAxis);\n const labelMatch = unlabeledAxes.findIndex((axisId) => matchAxisId(axisId, labelAxisId));\n if (labelMatch !== -1) {\n const axisId = unlabeledAxes[labelMatch];\n const dataDomainLen =\n Object.keys(axisId.domain ?? {}).length + Object.keys(axisId.contextDomain ?? {}).length;\n const labelDomainLen =\n Object.keys(labelAxis.domain ?? {}).length +\n Object.keys(labelAxis.contextDomain ?? {}).length;\n if (dataDomainLen > labelDomainLen) {\n labelColumns.push({\n id: colId(labelColumn.id, axisId.domain, axisId.contextDomain),\n spec: {\n ...labelColumn.spec,\n axesSpec: [{ ...axisId, annotations: labelAxis.annotations }],\n },\n data: labelColumn.data,\n });\n } else {\n labelColumns.push(labelColumn);\n }\n unlabeledAxes.splice(labelMatch, 1);\n }\n }\n return labelColumns;\n}\n"],"mappings":";;;;;;;;;AAcA,SAAgB,mBACd,KACiC;CAEjC,MAAM,aAAa,IAAI,wBADJ,IAAI,WAAW,aAAa,CACW,CACvD,WAAW,kCAAkC,IAAI,CAAC,CAClD,MAAM,EAAE,wBAAwB,MAAM,CAAC;AAC1C,KAAI;AACF,SAAO,WACJ,YAAY,EAAE,SAAS;GAAE,MAAM,YAAY;GAAO,MAAM,EAAE;GAAE,EAAE,CAAC,CAC/D,QAAyC,KAAK,QAAQ;GACrD,MAAM,OAAO,IAAI,MAAM,KAAK;AAC5B,UAAO,SAAS,KAAA,IAAY,MAAM,CAAC,GAAG,KAAK;IAAE,IAAI,IAAI;IAAI,MAAM,IAAI;IAAM;IAAM,CAAC;KAC/E,EAAE,CAAC;WACA;AACR,aAAW,SAAS;;;;AAKxB,SAAgB,wBACd,SACA,iBACiC;CAEjC,MAAM,oBAAoC,EAAE;CAC5C,MAAM,oBAAoC,EAAE;AAC5C,MAAK,MAAM,UAAU,QACnB,KAAI,cAAc,OAAO,KAAK,CAC5B,mBAAkB,KAAK,OAAO;KAE9B,mBAAkB,KAAK,OAAO;CAKlC,MAAM,gBAA0B,EAAE;AAClC,MAAK,MAAM,UAAU,kBACnB,MAAK,MAAM,QAAQ,OAAO,KAAK,UAAU;EACvC,MAAM,SAAS,UAAU,KAAK;AAC9B,MAAI,CAAC,cAAc,MAAM,OAAO,YAAY,IAAI,OAAO,CAAC,CACtD,eAAc,KAAK,OAAO;;AAMhC,MAAK,MAAM,eAAe,mBAAmB;EAC3C,MAAM,cAAc,UAAU,YAAY,KAAK,SAAS,GAAG;EAC3D,MAAM,aAAa,cAAc,WAAW,WAAW,YAAY,QAAQ,YAAY,CAAC;AACxF,MAAI,eAAe,GACjB,eAAc,OAAO,YAAY,EAAE;;CAKvC,MAAM,SACJ,IACA,QACA,kBACc;EACd,IAAI,MAAM,GAAG,UAAU;AACvB,MAAI,OACF,MAAK,MAAM,KAAK,QAAQ;AACtB,UAAO;AACP,UAAO,OAAO;;AAGlB,MAAI,cACF,MAAK,MAAM,KAAK,eAAe;AAC7B,UAAO;AACP,UAAO,cAAc;;AAGzB,SAAO;;CAIT,MAAM,eAAuC,EAAE;AAC/C,MAAK,MAAM,eAAe,iBAAiB;EACzC,MAAM,YAAY,YAAY,KAAK,SAAS;EAC5C,MAAM,cAAc,UAAU,UAAU;EACxC,MAAM,aAAa,cAAc,WAAW,WAAW,YAAY,QAAQ,YAAY,CAAC;AACxF,MAAI,eAAe,IAAI;GACrB,MAAM,SAAS,cAAc;AAM7B,OAJE,OAAO,KAAK,OAAO,UAAU,EAAE,CAAC,CAAC,SAAS,OAAO,KAAK,OAAO,iBAAiB,EAAE,CAAC,CAAC,SAElF,OAAO,KAAK,UAAU,UAAU,EAAE,CAAC,CAAC,SACpC,OAAO,KAAK,UAAU,iBAAiB,EAAE,CAAC,CAAC,OAE3C,cAAa,KAAK;IAChB,IAAI,MAAM,YAAY,IAAI,OAAO,QAAQ,OAAO,cAAc;IAC9D,MAAM;KACJ,GAAG,YAAY;KACf,UAAU,CAAC;MAAE,GAAG;MAAQ,aAAa,UAAU;MAAa,CAAC;KAC9D;IACD,MAAM,YAAY;IACnB,CAAC;OAEF,cAAa,KAAK,YAAY;AAEhC,iBAAc,OAAO,YAAY,EAAE;;;AAGvC,QAAO"}
@@ -0,0 +1,41 @@
1
+ const require_filter_discovery = require("./filter_discovery.cjs");
2
+ const require_column_collection_builder = require("../../columns/column_collection_builder.cjs");
3
+ const require_ctx_column_sources = require("../../columns/ctx_column_sources.cjs");
4
+ //#region src/components/PlDatasetSelector/build_dataset_options.ts
5
+ /**
6
+ * Usage:
7
+ * ```ts
8
+ * .output("datasetOptions", (ctx) => buildDatasetOptions(ctx))
9
+ * ```
10
+ */
11
+ function buildDatasetOptions(ctx, opts) {
12
+ const predicate = opts?.selector ?? (() => true);
13
+ const options = ctx.resultPool.getOptions(predicate, { refsWithEnrichments: true });
14
+ if (options.length === 0) return [];
15
+ const columnSources = require_ctx_column_sources.collectCtxColumnSnapshotProviders(ctx);
16
+ const refMap = require_filter_discovery.buildRefMap(ctx.resultPool.getSpecs().entries);
17
+ const pframeSpec = ctx.getService("pframeSpec");
18
+ return options.map((o) => {
19
+ const datasetSpec = ctx.resultPool.getPColumnSpecByRef(o.ref);
20
+ if (!datasetSpec) return o;
21
+ const builder = new require_column_collection_builder.ColumnCollectionBuilder(pframeSpec);
22
+ for (const src of columnSources) builder.addSource(src);
23
+ const collection = builder.build({ anchors: { main: datasetSpec } });
24
+ if (!collection) return o;
25
+ try {
26
+ const matches = require_filter_discovery.findFilterColumns(collection);
27
+ if (matches.length === 0) return o;
28
+ const filters = require_filter_discovery.filterMatchesToOptions(matches, refMap, opts?.labelOptions);
29
+ return {
30
+ ...o,
31
+ filters
32
+ };
33
+ } finally {
34
+ collection.dispose();
35
+ }
36
+ });
37
+ }
38
+ //#endregion
39
+ exports.buildDatasetOptions = buildDatasetOptions;
40
+
41
+ //# sourceMappingURL=build_dataset_options.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build_dataset_options.cjs","names":["collectCtxColumnSnapshotProviders","buildRefMap","ColumnCollectionBuilder","findFilterColumns","filterMatchesToOptions"],"sources":["../../../src/components/PlDatasetSelector/build_dataset_options.ts"],"sourcesContent":["import type {\n DatasetOption,\n Option,\n PColumnSelector,\n PObjectSpec,\n} from \"@milaboratories/pl-model-common\";\nimport type { DeriveLabelsOptions } from \"../../labels/derive_distinct_labels\";\nimport type { RenderCtxBase } from \"../../render\";\nimport { ColumnCollectionBuilder } from \"../../columns/column_collection_builder\";\nimport { collectCtxColumnSnapshotProviders } from \"../../columns/ctx_column_sources\";\nimport { buildRefMap, filterMatchesToOptions, findFilterColumns } from \"./filter_discovery\";\n\nexport type BuildDatasetOptions = {\n /** Which result pool columns qualify as datasets. Defaults to all. */\n selector?: PColumnSelector | PColumnSelector[] | ((spec: PObjectSpec) => boolean);\n /** Formatting options for filter labels. */\n labelOptions?: DeriveLabelsOptions;\n};\n\n/**\n * Usage:\n * ```ts\n * .output(\"datasetOptions\", (ctx) => buildDatasetOptions(ctx))\n * ```\n */\nexport function buildDatasetOptions(\n ctx: RenderCtxBase,\n opts?: BuildDatasetOptions,\n): DatasetOption[] | undefined {\n const predicate = opts?.selector ?? (() => true);\n const options = ctx.resultPool.getOptions(predicate, { refsWithEnrichments: true });\n if (options.length === 0) return [];\n\n const columnSources = collectCtxColumnSnapshotProviders(ctx);\n const refMap = buildRefMap(ctx.resultPool.getSpecs().entries);\n const pframeSpec = ctx.getService(\"pframeSpec\");\n\n return options.map((o: Option): DatasetOption => {\n const datasetSpec = ctx.resultPool.getPColumnSpecByRef(o.ref);\n if (!datasetSpec) return o;\n\n const builder = new ColumnCollectionBuilder(pframeSpec);\n for (const src of columnSources) builder.addSource(src);\n const collection = builder.build({ anchors: { main: datasetSpec } });\n if (!collection) return o;\n\n try {\n const matches = findFilterColumns(collection);\n if (matches.length === 0) return o;\n const filters = filterMatchesToOptions(matches, refMap, opts?.labelOptions);\n return { ...o, filters };\n } finally {\n collection.dispose();\n }\n });\n}\n"],"mappings":";;;;;;;;;;AAyBA,SAAgB,oBACd,KACA,MAC6B;CAC7B,MAAM,YAAY,MAAM,mBAAmB;CAC3C,MAAM,UAAU,IAAI,WAAW,WAAW,WAAW,EAAE,qBAAqB,MAAM,CAAC;AACnF,KAAI,QAAQ,WAAW,EAAG,QAAO,EAAE;CAEnC,MAAM,gBAAgBA,2BAAAA,kCAAkC,IAAI;CAC5D,MAAM,SAASC,yBAAAA,YAAY,IAAI,WAAW,UAAU,CAAC,QAAQ;CAC7D,MAAM,aAAa,IAAI,WAAW,aAAa;AAE/C,QAAO,QAAQ,KAAK,MAA6B;EAC/C,MAAM,cAAc,IAAI,WAAW,oBAAoB,EAAE,IAAI;AAC7D,MAAI,CAAC,YAAa,QAAO;EAEzB,MAAM,UAAU,IAAIC,kCAAAA,wBAAwB,WAAW;AACvD,OAAK,MAAM,OAAO,cAAe,SAAQ,UAAU,IAAI;EACvD,MAAM,aAAa,QAAQ,MAAM,EAAE,SAAS,EAAE,MAAM,aAAa,EAAE,CAAC;AACpE,MAAI,CAAC,WAAY,QAAO;AAExB,MAAI;GACF,MAAM,UAAUC,yBAAAA,kBAAkB,WAAW;AAC7C,OAAI,QAAQ,WAAW,EAAG,QAAO;GACjC,MAAM,UAAUC,yBAAAA,uBAAuB,SAAS,QAAQ,MAAM,aAAa;AAC3E,UAAO;IAAE,GAAG;IAAG;IAAS;YAChB;AACR,cAAW,SAAS;;GAEtB"}
@@ -0,0 +1,19 @@
1
+ import { DeriveLabelsOptions } from "../../labels/derive_distinct_labels.js";
2
+ import { RenderCtxBase } from "../../render/api.js";
3
+ import { DatasetOption, PColumnSelector, PObjectSpec } from "@milaboratories/pl-model-common";
4
+
5
+ //#region src/components/PlDatasetSelector/build_dataset_options.d.ts
6
+ type BuildDatasetOptions = {
7
+ /** Which result pool columns qualify as datasets. Defaults to all. */selector?: PColumnSelector | PColumnSelector[] | ((spec: PObjectSpec) => boolean); /** Formatting options for filter labels. */
8
+ labelOptions?: DeriveLabelsOptions;
9
+ };
10
+ /**
11
+ * Usage:
12
+ * ```ts
13
+ * .output("datasetOptions", (ctx) => buildDatasetOptions(ctx))
14
+ * ```
15
+ */
16
+ declare function buildDatasetOptions(ctx: RenderCtxBase, opts?: BuildDatasetOptions): DatasetOption[] | undefined;
17
+ //#endregion
18
+ export { BuildDatasetOptions, buildDatasetOptions };
19
+ //# sourceMappingURL=build_dataset_options.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build_dataset_options.d.ts","names":[],"sources":["../../../src/components/PlDatasetSelector/build_dataset_options.ts"],"mappings":";;;;;KAYY,mBAAA;wEAEV,QAAA,GAAW,eAAA,GAAkB,eAAA,OAAsB,IAAA,EAAM,WAAA,eAF/C;EAIV,YAAA,GAAe,mBAAA;AAAA;;;;;;;iBASD,mBAAA,CACd,GAAA,EAAK,aAAA,EACL,IAAA,GAAO,mBAAA,GACN,aAAA"}
@@ -0,0 +1,41 @@
1
+ import { buildRefMap, filterMatchesToOptions, findFilterColumns } from "./filter_discovery.js";
2
+ import { ColumnCollectionBuilder } from "../../columns/column_collection_builder.js";
3
+ import { collectCtxColumnSnapshotProviders } from "../../columns/ctx_column_sources.js";
4
+ //#region src/components/PlDatasetSelector/build_dataset_options.ts
5
+ /**
6
+ * Usage:
7
+ * ```ts
8
+ * .output("datasetOptions", (ctx) => buildDatasetOptions(ctx))
9
+ * ```
10
+ */
11
+ function buildDatasetOptions(ctx, opts) {
12
+ const predicate = opts?.selector ?? (() => true);
13
+ const options = ctx.resultPool.getOptions(predicate, { refsWithEnrichments: true });
14
+ if (options.length === 0) return [];
15
+ const columnSources = collectCtxColumnSnapshotProviders(ctx);
16
+ const refMap = buildRefMap(ctx.resultPool.getSpecs().entries);
17
+ const pframeSpec = ctx.getService("pframeSpec");
18
+ return options.map((o) => {
19
+ const datasetSpec = ctx.resultPool.getPColumnSpecByRef(o.ref);
20
+ if (!datasetSpec) return o;
21
+ const builder = new ColumnCollectionBuilder(pframeSpec);
22
+ for (const src of columnSources) builder.addSource(src);
23
+ const collection = builder.build({ anchors: { main: datasetSpec } });
24
+ if (!collection) return o;
25
+ try {
26
+ const matches = findFilterColumns(collection);
27
+ if (matches.length === 0) return o;
28
+ const filters = filterMatchesToOptions(matches, refMap, opts?.labelOptions);
29
+ return {
30
+ ...o,
31
+ filters
32
+ };
33
+ } finally {
34
+ collection.dispose();
35
+ }
36
+ });
37
+ }
38
+ //#endregion
39
+ export { buildDatasetOptions };
40
+
41
+ //# sourceMappingURL=build_dataset_options.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build_dataset_options.js","names":[],"sources":["../../../src/components/PlDatasetSelector/build_dataset_options.ts"],"sourcesContent":["import type {\n DatasetOption,\n Option,\n PColumnSelector,\n PObjectSpec,\n} from \"@milaboratories/pl-model-common\";\nimport type { DeriveLabelsOptions } from \"../../labels/derive_distinct_labels\";\nimport type { RenderCtxBase } from \"../../render\";\nimport { ColumnCollectionBuilder } from \"../../columns/column_collection_builder\";\nimport { collectCtxColumnSnapshotProviders } from \"../../columns/ctx_column_sources\";\nimport { buildRefMap, filterMatchesToOptions, findFilterColumns } from \"./filter_discovery\";\n\nexport type BuildDatasetOptions = {\n /** Which result pool columns qualify as datasets. Defaults to all. */\n selector?: PColumnSelector | PColumnSelector[] | ((spec: PObjectSpec) => boolean);\n /** Formatting options for filter labels. */\n labelOptions?: DeriveLabelsOptions;\n};\n\n/**\n * Usage:\n * ```ts\n * .output(\"datasetOptions\", (ctx) => buildDatasetOptions(ctx))\n * ```\n */\nexport function buildDatasetOptions(\n ctx: RenderCtxBase,\n opts?: BuildDatasetOptions,\n): DatasetOption[] | undefined {\n const predicate = opts?.selector ?? (() => true);\n const options = ctx.resultPool.getOptions(predicate, { refsWithEnrichments: true });\n if (options.length === 0) return [];\n\n const columnSources = collectCtxColumnSnapshotProviders(ctx);\n const refMap = buildRefMap(ctx.resultPool.getSpecs().entries);\n const pframeSpec = ctx.getService(\"pframeSpec\");\n\n return options.map((o: Option): DatasetOption => {\n const datasetSpec = ctx.resultPool.getPColumnSpecByRef(o.ref);\n if (!datasetSpec) return o;\n\n const builder = new ColumnCollectionBuilder(pframeSpec);\n for (const src of columnSources) builder.addSource(src);\n const collection = builder.build({ anchors: { main: datasetSpec } });\n if (!collection) return o;\n\n try {\n const matches = findFilterColumns(collection);\n if (matches.length === 0) return o;\n const filters = filterMatchesToOptions(matches, refMap, opts?.labelOptions);\n return { ...o, filters };\n } finally {\n collection.dispose();\n }\n });\n}\n"],"mappings":";;;;;;;;;;AAyBA,SAAgB,oBACd,KACA,MAC6B;CAC7B,MAAM,YAAY,MAAM,mBAAmB;CAC3C,MAAM,UAAU,IAAI,WAAW,WAAW,WAAW,EAAE,qBAAqB,MAAM,CAAC;AACnF,KAAI,QAAQ,WAAW,EAAG,QAAO,EAAE;CAEnC,MAAM,gBAAgB,kCAAkC,IAAI;CAC5D,MAAM,SAAS,YAAY,IAAI,WAAW,UAAU,CAAC,QAAQ;CAC7D,MAAM,aAAa,IAAI,WAAW,aAAa;AAE/C,QAAO,QAAQ,KAAK,MAA6B;EAC/C,MAAM,cAAc,IAAI,WAAW,oBAAoB,EAAE,IAAI;AAC7D,MAAI,CAAC,YAAa,QAAO;EAEzB,MAAM,UAAU,IAAI,wBAAwB,WAAW;AACvD,OAAK,MAAM,OAAO,cAAe,SAAQ,UAAU,IAAI;EACvD,MAAM,aAAa,QAAQ,MAAM,EAAE,SAAS,EAAE,MAAM,aAAa,EAAE,CAAC;AACpE,MAAI,CAAC,WAAY,QAAO;AAExB,MAAI;GACF,MAAM,UAAU,kBAAkB,WAAW;AAC7C,OAAI,QAAQ,WAAW,EAAG,QAAO;GACjC,MAAM,UAAU,uBAAuB,SAAS,QAAQ,MAAM,aAAa;AAC3E,UAAO;IAAE,GAAG;IAAG;IAAS;YAChB;AACR,cAAW,SAAS;;GAEtB"}
@@ -0,0 +1,60 @@
1
+ const require_runtime = require("../../_virtual/_rolldown/runtime.cjs");
2
+ const require_derive_distinct_labels = require("../../labels/derive_distinct_labels.cjs");
3
+ let _milaboratories_pl_model_common = require("@milaboratories/pl-model-common");
4
+ let canonicalize = require("canonicalize");
5
+ canonicalize = require_runtime.__toESM(canonicalize);
6
+ //#region src/components/PlDatasetSelector/filter_discovery.ts
7
+ /**
8
+ * Matches columns annotated `pl7.app/isSubset: "true"` whose axes ⊆ anchor axes.
9
+ *
10
+ * The axes-subset constraint is enforced by `mode: "enrichment"`, which sets
11
+ * `allowFloatingHitAxes: false` — every axis of the matched column must be
12
+ * present in the anchor's axes. See `matchingModeToConstraints()` in
13
+ * `column_collection_builder.ts`.
14
+ */
15
+ function findFilterColumns(collection) {
16
+ return collection.findColumns({
17
+ mode: "enrichment",
18
+ include: { annotations: { [_milaboratories_pl_model_common.Annotation.IsSubset]: "true" } }
19
+ });
20
+ }
21
+ /**
22
+ * Derive labeled options from filter column matches, for use in DatasetOption.filters.
23
+ *
24
+ * @param matches - from findFilterColumns()
25
+ * @param refsByObjectId - from {@link buildRefMap}
26
+ * @param labelOptions - forwarded to deriveDistinctLabels()
27
+ */
28
+ function filterMatchesToOptions(matches, refsByObjectId, labelOptions) {
29
+ if (matches.length === 0) return [];
30
+ const flattened = matches.flatMap((m) => m.variants.map((v) => ({
31
+ match: m,
32
+ variant: v
33
+ })));
34
+ const labels = require_derive_distinct_labels.deriveDistinctLabels(flattened.map(({ match, variant }) => ({
35
+ spec: match.column.spec,
36
+ linkerPath: variant.path.map((p) => ({ spec: p.linker.spec }))
37
+ })), labelOptions);
38
+ return flattened.map(({ match }, i) => {
39
+ const ref = refsByObjectId.get(match.column.id);
40
+ if (ref === void 0) throw new Error(`no PlRef found for filter column ${match.column.spec.name} (id: ${match.column.id})`);
41
+ return {
42
+ ref,
43
+ label: labels[i]
44
+ };
45
+ });
46
+ }
47
+ /**
48
+ * Usage: `buildRefMap(ctx.resultPool.getSpecs().entries)`
49
+ */
50
+ function buildRefMap(entries) {
51
+ const map = /* @__PURE__ */ new Map();
52
+ for (const entry of entries) map.set((0, canonicalize.default)(entry.ref), entry.ref);
53
+ return map;
54
+ }
55
+ //#endregion
56
+ exports.buildRefMap = buildRefMap;
57
+ exports.filterMatchesToOptions = filterMatchesToOptions;
58
+ exports.findFilterColumns = findFilterColumns;
59
+
60
+ //# sourceMappingURL=filter_discovery.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filter_discovery.cjs","names":["Annotation","deriveDistinctLabels"],"sources":["../../../src/components/PlDatasetSelector/filter_discovery.ts"],"sourcesContent":["import { Annotation } from \"@milaboratories/pl-model-common\";\nimport type { Option, PlRef, PObjectId } from \"@milaboratories/pl-model-common\";\nimport canonicalize from \"canonicalize\";\nimport type {\n AnchoredColumnCollection,\n ColumnMatch,\n} from \"../../columns/column_collection_builder\";\nimport {\n deriveDistinctLabels,\n type DeriveLabelsOptions,\n type Entry,\n} from \"../../labels/derive_distinct_labels\";\n\n/**\n * Matches columns annotated `pl7.app/isSubset: \"true\"` whose axes ⊆ anchor axes.\n *\n * The axes-subset constraint is enforced by `mode: \"enrichment\"`, which sets\n * `allowFloatingHitAxes: false` — every axis of the matched column must be\n * present in the anchor's axes. See `matchingModeToConstraints()` in\n * `column_collection_builder.ts`.\n */\nexport function findFilterColumns(collection: AnchoredColumnCollection): ColumnMatch[] {\n return collection.findColumns({\n mode: \"enrichment\",\n include: {\n annotations: { [Annotation.IsSubset]: \"true\" },\n },\n });\n}\n\n/**\n * Derive labeled options from filter column matches, for use in DatasetOption.filters.\n *\n * @param matches - from findFilterColumns()\n * @param refsByObjectId - from {@link buildRefMap}\n * @param labelOptions - forwarded to deriveDistinctLabels()\n */\nexport function filterMatchesToOptions(\n matches: ColumnMatch[],\n refsByObjectId: ReadonlyMap<PObjectId, PlRef>,\n labelOptions?: DeriveLabelsOptions,\n): Option[] {\n if (matches.length === 0) return [];\n\n // Each ColumnMatch can be reached via multiple variants (different linker\n // paths / qualifications). We emit one Option per variant so the user can\n // pick a specific path — `deriveDistinctLabels` disambiguates labels by\n // path.\n const flattened = matches.flatMap((m) => m.variants.map((v) => ({ match: m, variant: v })));\n\n const entries: Entry[] = flattened.map(({ match, variant }) => ({\n spec: match.column.spec,\n linkerPath: variant.path.map((p) => ({ spec: p.linker.spec })),\n }));\n\n const labels = deriveDistinctLabels(entries, labelOptions);\n\n return flattened.map(({ match }, i) => {\n const ref = refsByObjectId.get(match.column.id);\n if (ref === undefined)\n throw new Error(\n `no PlRef found for filter column ${match.column.spec.name} (id: ${match.column.id})`,\n );\n return { ref, label: labels[i] };\n });\n}\n\n/**\n * Usage: `buildRefMap(ctx.resultPool.getSpecs().entries)`\n */\nexport function buildRefMap(entries: readonly { readonly ref: PlRef }[]): Map<PObjectId, PlRef> {\n const map = new Map<PObjectId, PlRef>();\n for (const entry of entries) {\n map.set(canonicalize(entry.ref)! as PObjectId, entry.ref);\n }\n return map;\n}\n"],"mappings":";;;;;;;;;;;;;;AAqBA,SAAgB,kBAAkB,YAAqD;AACrF,QAAO,WAAW,YAAY;EAC5B,MAAM;EACN,SAAS,EACP,aAAa,GAAGA,gCAAAA,WAAW,WAAW,QAAQ,EAC/C;EACF,CAAC;;;;;;;;;AAUJ,SAAgB,uBACd,SACA,gBACA,cACU;AACV,KAAI,QAAQ,WAAW,EAAG,QAAO,EAAE;CAMnC,MAAM,YAAY,QAAQ,SAAS,MAAM,EAAE,SAAS,KAAK,OAAO;EAAE,OAAO;EAAG,SAAS;EAAG,EAAE,CAAC;CAO3F,MAAM,SAASC,+BAAAA,qBALU,UAAU,KAAK,EAAE,OAAO,eAAe;EAC9D,MAAM,MAAM,OAAO;EACnB,YAAY,QAAQ,KAAK,KAAK,OAAO,EAAE,MAAM,EAAE,OAAO,MAAM,EAAE;EAC/D,EAAE,EAE0C,aAAa;AAE1D,QAAO,UAAU,KAAK,EAAE,SAAS,MAAM;EACrC,MAAM,MAAM,eAAe,IAAI,MAAM,OAAO,GAAG;AAC/C,MAAI,QAAQ,KAAA,EACV,OAAM,IAAI,MACR,oCAAoC,MAAM,OAAO,KAAK,KAAK,QAAQ,MAAM,OAAO,GAAG,GACpF;AACH,SAAO;GAAE;GAAK,OAAO,OAAO;GAAI;GAChC;;;;;AAMJ,SAAgB,YAAY,SAAoE;CAC9F,MAAM,sBAAM,IAAI,KAAuB;AACvC,MAAK,MAAM,SAAS,QAClB,KAAI,KAAA,GAAA,aAAA,SAAiB,MAAM,IAAI,EAAgB,MAAM,IAAI;AAE3D,QAAO"}
@@ -0,0 +1,31 @@
1
+ import { DeriveLabelsOptions } from "../../labels/derive_distinct_labels.js";
2
+ import { AnchoredColumnCollection, ColumnMatch } from "../../columns/column_collection_builder.js";
3
+ import { Option, PObjectId, PlRef } from "@milaboratories/pl-model-common";
4
+
5
+ //#region src/components/PlDatasetSelector/filter_discovery.d.ts
6
+ /**
7
+ * Matches columns annotated `pl7.app/isSubset: "true"` whose axes ⊆ anchor axes.
8
+ *
9
+ * The axes-subset constraint is enforced by `mode: "enrichment"`, which sets
10
+ * `allowFloatingHitAxes: false` — every axis of the matched column must be
11
+ * present in the anchor's axes. See `matchingModeToConstraints()` in
12
+ * `column_collection_builder.ts`.
13
+ */
14
+ declare function findFilterColumns(collection: AnchoredColumnCollection): ColumnMatch[];
15
+ /**
16
+ * Derive labeled options from filter column matches, for use in DatasetOption.filters.
17
+ *
18
+ * @param matches - from findFilterColumns()
19
+ * @param refsByObjectId - from {@link buildRefMap}
20
+ * @param labelOptions - forwarded to deriveDistinctLabels()
21
+ */
22
+ declare function filterMatchesToOptions(matches: ColumnMatch[], refsByObjectId: ReadonlyMap<PObjectId, PlRef>, labelOptions?: DeriveLabelsOptions): Option[];
23
+ /**
24
+ * Usage: `buildRefMap(ctx.resultPool.getSpecs().entries)`
25
+ */
26
+ declare function buildRefMap(entries: readonly {
27
+ readonly ref: PlRef;
28
+ }[]): Map<PObjectId, PlRef>;
29
+ //#endregion
30
+ export { buildRefMap, filterMatchesToOptions, findFilterColumns };
31
+ //# sourceMappingURL=filter_discovery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filter_discovery.d.ts","names":[],"sources":["../../../src/components/PlDatasetSelector/filter_discovery.ts"],"mappings":";;;;;;;AAqBA;;;;;;iBAAgB,iBAAA,CAAkB,UAAA,EAAY,wBAAA,GAA2B,WAAA;;;AAgBzE;;;;;iBAAgB,sBAAA,CACd,OAAA,EAAS,WAAA,IACT,cAAA,EAAgB,WAAA,CAAY,SAAA,EAAW,KAAA,GACvC,YAAA,GAAe,mBAAA,GACd,MAAA;;;;iBA6Ba,WAAA,CAAY,OAAA;EAAA,SAA6B,GAAA,EAAK,KAAA;AAAA,MAAY,GAAA,CAAI,SAAA,EAAW,KAAA"}