@platforma-sdk/model 1.69.0 → 1.71.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/columns/column_collection_builder.cjs +1 -4
- package/dist/columns/column_collection_builder.cjs.map +1 -1
- package/dist/columns/column_collection_builder.d.ts +0 -2
- package/dist/columns/column_collection_builder.d.ts.map +1 -1
- package/dist/columns/column_collection_builder.js +1 -4
- package/dist/columns/column_collection_builder.js.map +1 -1
- package/dist/columns/column_snapshot_provider.cjs +26 -2
- package/dist/columns/column_snapshot_provider.cjs.map +1 -1
- package/dist/columns/column_snapshot_provider.d.ts +2 -1
- package/dist/columns/column_snapshot_provider.d.ts.map +1 -1
- package/dist/columns/column_snapshot_provider.js +25 -2
- package/dist/columns/column_snapshot_provider.js.map +1 -1
- package/dist/columns/ctx_column_sources.cjs +5 -8
- package/dist/columns/ctx_column_sources.cjs.map +1 -1
- package/dist/columns/ctx_column_sources.d.ts +4 -7
- package/dist/columns/ctx_column_sources.d.ts.map +1 -1
- package/dist/columns/ctx_column_sources.js +5 -8
- package/dist/columns/ctx_column_sources.js.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.cjs +41 -24
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.cjs.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.d.ts.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.js +42 -25
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.js.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/discoverColumns.cjs +1 -2
- package/dist/components/PlDataTable/createPlDataTable/discoverColumns.cjs.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/discoverColumns.js +1 -2
- package/dist/components/PlDataTable/createPlDataTable/discoverColumns.js.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/utils.cjs +16 -4
- package/dist/components/PlDataTable/createPlDataTable/utils.cjs.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/utils.js +16 -5
- package/dist/components/PlDataTable/createPlDataTable/utils.js.map +1 -1
- package/dist/components/PlDatasetSelector/build_dataset_options.cjs +23 -11
- package/dist/components/PlDatasetSelector/build_dataset_options.cjs.map +1 -1
- package/dist/components/PlDatasetSelector/build_dataset_options.d.ts +9 -2
- package/dist/components/PlDatasetSelector/build_dataset_options.d.ts.map +1 -1
- package/dist/components/PlDatasetSelector/build_dataset_options.js +22 -11
- package/dist/components/PlDatasetSelector/build_dataset_options.js.map +1 -1
- package/dist/components/PlDatasetSelector/dataset_selection.cjs +20 -0
- package/dist/components/PlDatasetSelector/dataset_selection.cjs.map +1 -0
- package/dist/components/PlDatasetSelector/dataset_selection.d.ts +23 -0
- package/dist/components/PlDatasetSelector/dataset_selection.d.ts.map +1 -0
- package/dist/components/PlDatasetSelector/dataset_selection.js +19 -0
- package/dist/components/PlDatasetSelector/dataset_selection.js.map +1 -0
- package/dist/components/PlDatasetSelector/enrichment_discovery.cjs +75 -0
- package/dist/components/PlDatasetSelector/enrichment_discovery.cjs.map +1 -0
- package/dist/components/PlDatasetSelector/enrichment_discovery.js +73 -0
- package/dist/components/PlDatasetSelector/enrichment_discovery.js.map +1 -0
- package/dist/components/PlDatasetSelector/index.cjs +1 -0
- package/dist/components/PlDatasetSelector/index.d.ts +1 -0
- package/dist/components/PlDatasetSelector/index.js +1 -0
- package/dist/components/index.cjs +1 -0
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.js +1 -0
- package/dist/index.cjs +3 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/labels/derive_distinct_tooltips.cjs +0 -3
- package/dist/labels/derive_distinct_tooltips.cjs.map +1 -1
- package/dist/labels/derive_distinct_tooltips.js +0 -3
- package/dist/labels/derive_distinct_tooltips.js.map +1 -1
- package/dist/package.cjs +1 -1
- package/dist/package.js +1 -1
- package/dist/render/api.cjs +3 -14
- package/dist/render/api.cjs.map +1 -1
- package/dist/render/api.d.ts.map +1 -1
- package/dist/render/api.js +4 -15
- package/dist/render/api.js.map +1 -1
- package/dist/render/index.cjs +1 -1
- package/dist/render/index.js +1 -1
- package/package.json +9 -9
- package/src/columns/column_collection_builder.ts +0 -3
- package/src/columns/column_snapshot_provider.ts +30 -14
- package/src/columns/ctx_column_sources.ts +6 -12
- package/src/components/PlDataTable/createPlDataTable/createPlDataTableV3.ts +58 -44
- package/src/components/PlDataTable/createPlDataTable/discoverColumns.ts +0 -1
- package/src/components/PlDataTable/createPlDataTable/utils.ts +25 -3
- package/src/components/PlDatasetSelector/build_dataset_options.ts +48 -17
- package/src/components/PlDatasetSelector/dataset_selection.ts +37 -0
- package/src/components/PlDatasetSelector/enrichment_discovery.ts +111 -0
- package/src/components/PlDatasetSelector/index.ts +1 -0
- package/src/labels/derive_distinct_tooltips.test.ts +6 -16
- package/src/labels/derive_distinct_tooltips.ts +0 -3
- package/src/render/api.ts +5 -17
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"discoverColumns.js","names":["resolveAnchors"],"sources":["../../../../src/components/PlDataTable/createPlDataTable/discoverColumns.ts"],"sourcesContent":["import type { PColumnSpec, PlRef, PObjectId } from \"@milaboratories/pl-model-common\";\nimport { createDiscoveredPColumnId, isPlRef } from \"@milaboratories/pl-model-common\";\nimport type { RenderCtxBase } from \"../../../render\";\nimport type {\n ColumnSource,\n ColumnVariant,\n RelaxedColumnSelector,\n ColumnSnapshotProvider,\n ColumnSnapshot,\n} from \"../../../columns\";\nimport { ColumnCollectionBuilder } from \"../../../columns\";\nimport { toColumnSnapshotProvider } from \"../../../columns/column_snapshot_provider\";\nimport { collectCtxColumnSnapshotProviders } from \"../../../columns/ctx_column_sources\";\nimport { throwError } from \"@milaboratories/helpers\";\nimport type { ColumnsSelectorConfig, TableColumnVariant } from \"./createPlDataTableV3\";\n\nexport type DiscoverTableColumnOptions = {\n sources?: ColumnSource[];\n anchors: Record<string, PlRef | PObjectId | PColumnSpec | RelaxedColumnSelector>;\n selector: ColumnsSelectorConfig;\n};\n\n/** Discover columns from sources/anchors and normalize into a flat TableColumnVariant list. */\nexport function discoverTableColumnSnaphots(\n ctx: RenderCtxBase,\n options: DiscoverTableColumnOptions,\n): TableColumnVariant[] | undefined {\n // Resolve PlRef anchors to PColumnSpec\n const resolvedOptions = {\n ...options,\n anchors: resolveAnchors(ctx, options.anchors),\n };\n\n // Resolve providers\n const providers = resolveProviders(ctx, resolvedOptions.sources);\n if (providers.length === 0) return undefined;\n\n // Build collection (anchored or plain)\n const collection = new ColumnCollectionBuilder(ctx.getService(\"pframeSpec\"))\n .addSources(providers)\n .build(resolvedOptions);\n if (collection === undefined) return undefined;\n\n try {\n const variants = collection.findColumnVariants({\n ...(resolvedOptions.selector ?? {}),\n });\n const anchors = collection.getAnchors();\n return mapToTableColumnVariants(variants, anchors);\n } finally {\n collection.dispose();\n }\n}\n\n// --- Pure helper functions ---\n\n/** Resolve PlRef values in anchors to PColumnSpec via the result pool. */\nfunction resolveAnchors(\n ctx: RenderCtxBase,\n anchors: Record<string, PlRef | PObjectId | PColumnSpec | RelaxedColumnSelector>,\n): Record<string, PObjectId | PColumnSpec | RelaxedColumnSelector> {\n const result: Record<string, PObjectId | PColumnSpec | RelaxedColumnSelector> = {};\n for (const [key, value] of Object.entries(anchors)) {\n if (isPlRef(value)) {\n result[key] =\n ctx.resultPool.getPColumnSpecByRef(value) ??\n throwError(\n `Anchor ${key} with ref ${JSON.stringify(value)} could not be resolved to a PColumnSpec`,\n );\n } else {\n result[key] = value;\n }\n }\n return result;\n}\n\n/** Resolve column snapshot providers from explicit sources or context. */\nfunction resolveProviders(\n ctx: RenderCtxBase,\n sources: undefined | ColumnSource[],\n): ColumnSnapshotProvider[] {\n return sources !== undefined\n ? sources.map(toColumnSnapshotProvider)\n : collectCtxColumnSnapshotProviders(ctx);\n}\n\n/** Map column variants into TableColumnVariant list with anchor-derived isPrimary flag. */\nfunction mapToTableColumnVariants(\n variants: readonly ColumnVariant[],\n anchors: Map<string, ColumnSnapshot<PObjectId>>,\n): TableColumnVariant[] {\n const columnIdToAnchorName = new Map<PObjectId, string>(\n Array.from(anchors.entries(), ([key, { id }]) => [id, key] as const),\n );\n\n return variants.map((variant): TableColumnVariant => {\n const snap = variant.column;\n const isPrimary = columnIdToAnchorName.get(snap.id) !== undefined;\n\n const discoveredId = createDiscoveredPColumnId({\n column: snap.id,\n path: variant.path.map((p) => ({\n type: \"linker\",\n column: p.linker.id,\n
|
|
1
|
+
{"version":3,"file":"discoverColumns.js","names":["resolveAnchors"],"sources":["../../../../src/components/PlDataTable/createPlDataTable/discoverColumns.ts"],"sourcesContent":["import type { PColumnSpec, PlRef, PObjectId } from \"@milaboratories/pl-model-common\";\nimport { createDiscoveredPColumnId, isPlRef } from \"@milaboratories/pl-model-common\";\nimport type { RenderCtxBase } from \"../../../render\";\nimport type {\n ColumnSource,\n ColumnVariant,\n RelaxedColumnSelector,\n ColumnSnapshotProvider,\n ColumnSnapshot,\n} from \"../../../columns\";\nimport { ColumnCollectionBuilder } from \"../../../columns\";\nimport { toColumnSnapshotProvider } from \"../../../columns/column_snapshot_provider\";\nimport { collectCtxColumnSnapshotProviders } from \"../../../columns/ctx_column_sources\";\nimport { throwError } from \"@milaboratories/helpers\";\nimport type { ColumnsSelectorConfig, TableColumnVariant } from \"./createPlDataTableV3\";\n\nexport type DiscoverTableColumnOptions = {\n sources?: ColumnSource[];\n anchors: Record<string, PlRef | PObjectId | PColumnSpec | RelaxedColumnSelector>;\n selector: ColumnsSelectorConfig;\n};\n\n/** Discover columns from sources/anchors and normalize into a flat TableColumnVariant list. */\nexport function discoverTableColumnSnaphots(\n ctx: RenderCtxBase,\n options: DiscoverTableColumnOptions,\n): TableColumnVariant[] | undefined {\n // Resolve PlRef anchors to PColumnSpec\n const resolvedOptions = {\n ...options,\n anchors: resolveAnchors(ctx, options.anchors),\n };\n\n // Resolve providers\n const providers = resolveProviders(ctx, resolvedOptions.sources);\n if (providers.length === 0) return undefined;\n\n // Build collection (anchored or plain)\n const collection = new ColumnCollectionBuilder(ctx.getService(\"pframeSpec\"))\n .addSources(providers)\n .build(resolvedOptions);\n if (collection === undefined) return undefined;\n\n try {\n const variants = collection.findColumnVariants({\n ...(resolvedOptions.selector ?? {}),\n });\n const anchors = collection.getAnchors();\n return mapToTableColumnVariants(variants, anchors);\n } finally {\n collection.dispose();\n }\n}\n\n// --- Pure helper functions ---\n\n/** Resolve PlRef values in anchors to PColumnSpec via the result pool. */\nfunction resolveAnchors(\n ctx: RenderCtxBase,\n anchors: Record<string, PlRef | PObjectId | PColumnSpec | RelaxedColumnSelector>,\n): Record<string, PObjectId | PColumnSpec | RelaxedColumnSelector> {\n const result: Record<string, PObjectId | PColumnSpec | RelaxedColumnSelector> = {};\n for (const [key, value] of Object.entries(anchors)) {\n if (isPlRef(value)) {\n result[key] =\n ctx.resultPool.getPColumnSpecByRef(value) ??\n throwError(\n `Anchor ${key} with ref ${JSON.stringify(value)} could not be resolved to a PColumnSpec`,\n );\n } else {\n result[key] = value;\n }\n }\n return result;\n}\n\n/** Resolve column snapshot providers from explicit sources or context. */\nfunction resolveProviders(\n ctx: RenderCtxBase,\n sources: undefined | ColumnSource[],\n): ColumnSnapshotProvider[] {\n return sources !== undefined\n ? sources.map(toColumnSnapshotProvider)\n : collectCtxColumnSnapshotProviders(ctx);\n}\n\n/** Map column variants into TableColumnVariant list with anchor-derived isPrimary flag. */\nfunction mapToTableColumnVariants(\n variants: readonly ColumnVariant[],\n anchors: Map<string, ColumnSnapshot<PObjectId>>,\n): TableColumnVariant[] {\n const columnIdToAnchorName = new Map<PObjectId, string>(\n Array.from(anchors.entries(), ([key, { id }]) => [id, key] as const),\n );\n\n return variants.map((variant): TableColumnVariant => {\n const snap = variant.column;\n const isPrimary = columnIdToAnchorName.get(snap.id) !== undefined;\n\n const discoveredId = createDiscoveredPColumnId({\n column: snap.id,\n path: variant.path.map((p) => ({\n type: \"linker\",\n column: p.linker.id,\n })),\n columnQualifications: variant.qualifications.forHit,\n queriesQualifications: variant.qualifications.forQueries,\n });\n return {\n column: {\n id: discoveredId,\n spec: snap.spec,\n data: snap.data,\n dataStatus: snap.dataStatus,\n },\n path: variant.path,\n qualifications: variant.qualifications,\n originalId: snap.id,\n isPrimary,\n };\n });\n}\n"],"mappings":";;;;;;;;AAuBA,SAAgB,4BACd,KACA,SACkC;CAElC,MAAM,kBAAkB;EACtB,GAAG;EACH,SAASA,iBAAe,KAAK,QAAQ,QAAQ;EAC9C;CAGD,MAAM,YAAY,iBAAiB,KAAK,gBAAgB,QAAQ;AAChE,KAAI,UAAU,WAAW,EAAG,QAAO,KAAA;CAGnC,MAAM,aAAa,IAAI,wBAAwB,IAAI,WAAW,aAAa,CAAC,CACzE,WAAW,UAAU,CACrB,MAAM,gBAAgB;AACzB,KAAI,eAAe,KAAA,EAAW,QAAO,KAAA;AAErC,KAAI;AAKF,SAAO,yBAJU,WAAW,mBAAmB,EAC7C,GAAI,gBAAgB,YAAY,EAAE,EACnC,CAAC,EACc,WAAW,YAAY,CACW;WAC1C;AACR,aAAW,SAAS;;;;AAOxB,SAASA,iBACP,KACA,SACiE;CACjE,MAAM,SAA0E,EAAE;AAClF,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,QAAQ,CAChD,KAAI,QAAQ,MAAM,CAChB,QAAO,OACL,IAAI,WAAW,oBAAoB,MAAM,IACzC,WACE,UAAU,IAAI,YAAY,KAAK,UAAU,MAAM,CAAC,yCACjD;KAEH,QAAO,OAAO;AAGlB,QAAO;;;AAIT,SAAS,iBACP,KACA,SAC0B;AAC1B,QAAO,YAAY,KAAA,IACf,QAAQ,IAAI,yBAAyB,GACrC,kCAAkC,IAAI;;;AAI5C,SAAS,yBACP,UACA,SACsB;CACtB,MAAM,uBAAuB,IAAI,IAC/B,MAAM,KAAK,QAAQ,SAAS,GAAG,CAAC,KAAK,EAAE,UAAU,CAAC,IAAI,IAAI,CAAU,CACrE;AAED,QAAO,SAAS,KAAK,YAAgC;EACnD,MAAM,OAAO,QAAQ;EACrB,MAAM,YAAY,qBAAqB,IAAI,KAAK,GAAG,KAAK,KAAA;AAWxD,SAAO;GACL,QAAQ;IACN,IAXiB,0BAA0B;KAC7C,QAAQ,KAAK;KACb,MAAM,QAAQ,KAAK,KAAK,OAAO;MAC7B,MAAM;MACN,QAAQ,EAAE,OAAO;MAClB,EAAE;KACH,sBAAsB,QAAQ,eAAe;KAC7C,uBAAuB,QAAQ,eAAe;KAC/C,CAAC;IAIE,MAAM,KAAK;IACX,MAAM,KAAK;IACX,YAAY,KAAK;IAClB;GACD,MAAM,QAAQ;GACd,gBAAgB,QAAQ;GACxB,YAAY,KAAK;GACjB;GACD;GACD"}
|
|
@@ -108,6 +108,20 @@ function withLabelAnnotations(derivedLabels, columns) {
|
|
|
108
108
|
};
|
|
109
109
|
});
|
|
110
110
|
}
|
|
111
|
+
function withDataStatusAnnotations(columns) {
|
|
112
|
+
return columns.map((col) => {
|
|
113
|
+
return {
|
|
114
|
+
...col,
|
|
115
|
+
spec: {
|
|
116
|
+
...col.spec,
|
|
117
|
+
annotations: {
|
|
118
|
+
...col.spec.annotations,
|
|
119
|
+
[_milaboratories_pl_model_common.Annotation.DataStatus]: col.dataStatus
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
});
|
|
124
|
+
}
|
|
111
125
|
/**
|
|
112
126
|
* Writes effective display properties (OrderPriority, Visibility) from precomputed rule maps
|
|
113
127
|
* into column annotations. Returns new column objects — originals are not mutated.
|
|
@@ -170,10 +184,7 @@ function deriveAllLabels(options) {
|
|
|
170
184
|
const { columns, deriveLabelsOptions } = options;
|
|
171
185
|
return require_derive_distinct_labels.deriveDistinctLabels(columns.map((c) => ({
|
|
172
186
|
spec: c.spec,
|
|
173
|
-
linkerPath: c.linkerPath?.map((step) => ({
|
|
174
|
-
spec: step.linker.spec,
|
|
175
|
-
qualifications: step.qualifications
|
|
176
|
-
})),
|
|
187
|
+
linkerPath: c.linkerPath?.map((step) => ({ spec: step.linker.spec })),
|
|
177
188
|
qualifications: c.qualifications
|
|
178
189
|
})), deriveLabelsOptions).reduce((acc, label, index) => (acc[columns[index].id] = label, acc), {});
|
|
179
190
|
}
|
|
@@ -212,6 +223,7 @@ exports.getEffectiveVisibility = getEffectiveVisibility;
|
|
|
212
223
|
exports.getOrderPriority = getOrderPriority;
|
|
213
224
|
exports.isColumnHidden = isColumnHidden;
|
|
214
225
|
exports.isColumnOptional = isColumnOptional;
|
|
226
|
+
exports.withDataStatusAnnotations = withDataStatusAnnotations;
|
|
215
227
|
exports.withHidenAxesAnnotations = withHidenAxesAnnotations;
|
|
216
228
|
exports.withInfoAnnotations = withInfoAnnotations;
|
|
217
229
|
exports.withLabelAnnotations = withLabelAnnotations;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.cjs","names":["Annotation","ColumnCollectionBuilder","ArrayColumnProvider","deriveDistinctLabels","deriveDistinctTooltips"],"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 DiscoveredPColumnId,\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?: MatchVariant[\"path\"];\n readonly qualifications?: MatchQualifications;\n};\n\n/** Derive labels for all table elements: columns via deriveDistinctLabels, axes from label columns. */\nexport function deriveAllLabels(options: {\n columns: LabelableColumn[];\n deriveLabelsOptions?: DeriveLabelsOptions;\n}): Record<string, string> {\n const { columns, deriveLabelsOptions } = options;\n const entries = columns.map((c) => ({\n spec: c.spec,\n linkerPath: c.linkerPath?.map((step) => ({\n spec: step.linker.spec,\n qualifications: step.qualifications,\n })),\n qualifications: c.qualifications,\n }));\n const columnLabels = deriveDistinctLabels(entries, deriveLabelsOptions).reduce(\n (acc, label, index) => ((acc[columns[index].id] = label), acc),\n {} as Record<string, string>,\n );\n return columnLabels;\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};\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 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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"}
|
|
1
|
+
{"version":3,"file":"utils.cjs","names":["Annotation","ColumnCollectionBuilder","ArrayColumnProvider","deriveDistinctLabels","deriveDistinctTooltips"],"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 DiscoveredPColumnId,\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 { ColumnDataStatus, 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 {\n readonly id: PObjectId;\n readonly spec: PColumnSpec;\n },\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\nexport function withDataStatusAnnotations<\n T extends {\n readonly spec: PColumnSpec;\n readonly dataStatus: ColumnDataStatus;\n },\n>(columns: T[]): T[] {\n return columns.map((col) => {\n return {\n ...col,\n spec: {\n ...col.spec,\n annotations: {\n ...col.spec.annotations,\n [Annotation.DataStatus]: col.dataStatus,\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?: MatchVariant[\"path\"];\n readonly qualifications?: MatchQualifications;\n};\n\n/** Derive labels for all table elements: columns via deriveDistinctLabels, axes from label columns. */\nexport function deriveAllLabels(options: {\n columns: LabelableColumn[];\n deriveLabelsOptions?: DeriveLabelsOptions;\n}): Record<string, string> {\n const { columns, deriveLabelsOptions } = options;\n const entries = columns.map((c) => ({\n spec: c.spec,\n linkerPath: c.linkerPath?.map((step) => ({\n spec: step.linker.spec,\n })),\n qualifications: c.qualifications,\n }));\n const columnLabels = deriveDistinctLabels(entries, deriveLabelsOptions).reduce(\n (acc, label, index) => ((acc[columns[index].id] = label), acc),\n {} as Record<string, string>,\n );\n return columnLabels;\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};\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 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":";;;;;;;;;;AA0BA,SAAgB,eAAe,MAA6C;AAC1E,SAAA,GAAA,gCAAA,gBAAsB,MAAMA,gCAAAA,WAAW,MAAM,WAAW,KAAK;;;AAI/D,SAAgB,iBAAiB,MAA6C;AAC5E,SAAA,GAAA,gCAAA,gBAAsB,MAAMA,gCAAAA,WAAW,MAAM,WAAW,KAAK;;;AAO/D,SAAgB,uBACd,KACA,mBAC+C;CAC/C,MAAM,OAAO,mBAAmB,IAAI,IAAI,GAAG;AAC3C,KAAI,SAAS,KAAA,EAAW,QAAO,KAAK;AACpC,KAAI,eAAe,IAAI,KAAK,CAAE,QAAO;AACrC,KAAI,iBAAiB,IAAI,KAAK,CAAE,QAAO;;;AAKzC,SAAgB,iBACd,KACA,cACoB;CACpB,MAAM,OAAO,cAAc,IAAI,IAAI,GAAG;AACtC,KAAI,SAAS,KAAA,EAAW,QAAO,KAAK;AACpC,SAAA,GAAA,gCAAA,oBAA0B,IAAI,MAAMA,gCAAAA,WAAW,MAAM,cAAc;;;;;;;;;;AAWrE,SAAgB,cACd,OACA,SACA,YACmB;CACnB,MAAM,yBAAS,IAAI,KAAmB;AACtC,KAAI,MAAM,WAAW,KAAK,QAAQ,WAAW,EAAG,QAAO;CAEvD,MAAM,mBAAmB,MAAM,MAAM,SAAS,OAAO,KAAK,UAAU,WAAW;CAC/E,MAAM,qCAAqB,IAAI,KAAwB;AAEvD,KAAI,kBAAkB;EAEpB,MAAM,WADiB,WAAW,QAAQ,CACV,KAAK,OAAO;GAAE,IAAI,EAAE;GAAI,MAAM,EAAE;GAAM,MAAM,KAAA;GAAW,EAAE;EACzF,MAAM,aAAa,IAAIC,kCAAAA,wBAAwB,WAAW,CACvD,UAAU,IAAIC,iCAAAA,oBAAoB,SAAS,CAAC,CAC5C,OAAO;AACV,MAAI,eAAe,KAAA,EAAW,QAAO;AAErC,MAAI;AACF,QAAK,MAAM,QAAQ,OAAO;AACxB,QAAI,OAAO,KAAK,UAAU,WAAY;IACtC,MAAM,OAAO,WAAW,YAAY,EAAE,SAAS,KAAK,OAAO,CAAC;AAC5D,uBAAmB,IAAI,MAAM,IAAI,IAAI,KAAK,KAAK,MAAM,EAAE,GAAG,CAAC,CAAC;;YAEtD;AACR,cAAW,SAAS;;;AAIxB,MAAK,MAAM,OAAO,QAChB,MAAK,MAAM,QAAQ,MAKjB,KAHE,OAAO,KAAK,UAAU,aAClB,KAAK,MAAM,IAAI,KAAK,GACnB,mBAAmB,IAAI,KAAK,EAAE,IAAI,IAAI,GAAG,IAAI,OACvC;AACX,SAAO,IAAI,IAAI,IAAI,KAAK;AACxB;;AAIN,QAAO;;AAGT,SAAS,WAAW,SAAqC;CACvD,MAAM,uBAAO,IAAI,KAAgB;CACjC,MAAM,SAAuB,EAAE;AAC/B,MAAK,MAAM,OAAO,SAAS;AACzB,MAAI,KAAK,IAAI,IAAI,GAAG,CAAE;AACtB,OAAK,IAAI,IAAI,GAAG;AAChB,SAAO,KAAK,IAAI;;AAElB,QAAO;;;;;;;;;AAUT,SAAgB,qBAKd,eAAmD,SAAmB;AACtE,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,IAAA,GAAA,WAAA,OAAU,SAAS,GACf,EAAE,GACF,EAAE,aAAa;KAAE,GAAG,IAAI,KAAK;MAAcF,gCAAAA,WAAW,QAAQ;KAAU,EAAE;IAC9E,UAAU,IAAI,KAAK,SAAS,KAAK,SAAS;KACxC,MAAM,QAAQ,eAAA,GAAA,gCAAA,oBAAiC,KAAK;AACpD,aAAA,GAAA,WAAA,OAAa,MAAM,GACf,OACA;MAAE,GAAG;MAAM,aAAa;OAAE,GAAG,KAAK;QAAcA,gCAAAA,WAAW,QAAQ;OAAO;MAAE;MAChF;IACH;GACF;GACD;;AAGJ,SAAgB,0BAKd,SAAmB;AACnB,QAAO,QAAQ,KAAK,QAAQ;AAC1B,SAAO;GACL,GAAG;GACH,MAAM;IACJ,GAAG,IAAI;IACP,aAAa;KACX,GAAG,IAAI,KAAK;MACXA,gCAAAA,WAAW,aAAa,IAAI;KAC9B;IACF;GACF;GACD;;;;;;AAOJ,SAAgB,2BAGd,mBACA,cACA,SACK;AACL,KAAI,sBAAsB,KAAA,KAAa,iBAAiB,KAAA,EAAW,QAAO;AAC1E,QAAO,QAAQ,KAAK,QAAQ;EAC1B,MAAM,cAAc,EAAE,GAAG,IAAI,KAAK,aAAa;EAE/C,MAAM,aAAa,uBAAuB,KAAK,kBAAkB;AACjE,MAAI,EAAA,GAAA,WAAA,OAAO,WAAW,CAAE,aAAYA,gCAAAA,WAAW,MAAM,cAAc;EAEnE,MAAM,gBAAgB,iBAAiB,KAAK,aAAa;AACzD,MAAI,EAAA,GAAA,WAAA,OAAO,cAAc,CAAE,aAAYA,gCAAAA,WAAW,MAAM,iBAAiB,OAAO,cAAc;AAE9F,SAAO;GACL,GAAG;GACH,MAAM;IACJ,GAAG,IAAI;IACM;IACd;GACF;GACD;;;;;;AAOJ,SAAgB,oBAEd,UAA8C,SAAmB;AACjE,MAAA,GAAA,WAAA,OAAU,SAAS,CAAE,QAAO;AAC5B,QAAO,QAAQ,KAAK,QAAQ;EAC1B,MAAM,OAAO,SAAS,IAAI;AAC1B,OAAA,GAAA,WAAA,OAAU,KAAK,CAAE,QAAO;AACxB,SAAO;GACL,GAAG;GACH,MAAM;IACJ,GAAG,IAAI;IACP,aAAa;KAAE,GAAG,IAAI,KAAK;MAAcA,gCAAAA,WAAW,MAAM,OAAO;KAAM;IACxE;GACF;GACD;;AAGJ,SAAgB,yBACd,SACK;AACL,QAAO,QAAQ,KACZ,SACE;EACC,GAAG;EACH,MAAM;GACJ,GAAG,IAAI;GACP,UAAU,IAAI,KAAK,SAAS,KAAK,UAAU;IACzC,GAAG;IACH,aAAa;KAAE,GAAG,KAAK;MAAcA,gCAAAA,WAAW,MAAM,aAAa;KAAU;IAC9E,EAAE;GACJ;EACF,EACJ;;;AAYH,SAAgB,gBAAgB,SAGL;CACzB,MAAM,EAAE,SAAS,wBAAwB;AAYzC,QAJqBG,+BAAAA,qBAPL,QAAQ,KAAK,OAAO;EAClC,MAAM,EAAE;EACR,YAAY,EAAE,YAAY,KAAK,UAAU,EACvC,MAAM,KAAK,OAAO,MACnB,EAAE;EACH,gBAAgB,EAAE;EACnB,EAAE,EACgD,oBAAoB,CAAC,QACrE,KAAK,OAAO,WAAY,IAAI,QAAQ,OAAO,MAAM,OAAQ,MAC1D,EAAE,CACH;;;AAcH,SAAgB,kBAAkB,SAEM;CACtC,MAAM,EAAE,YAAY;CAEpB,MAAM,yBAAyB,QAAQ,QAAgC,KAAK,MAAM;AAChF,SAAO,IAAI,IAAI,EAAE,aAAa,IAAI,IAAI,EAAE,WAAW,IAAI,KAAK,EAAE;oBAC7D,IAAI,KAAK,CAAC;CAEb,MAAM,EAAE,YAAY,QAAQ,QACzB,EAAE,SAAS,eAAe,MAAM;EAC/B,MAAM,eAAe,uBAAuB,IAAI,EAAE,WAAW;EAC7D,MAAM,gBACH,YAAY,IAAI,EAAE,aAAa,YAAY,IAAI,EAAE,WAAW,IAAI,KAAK,EAAE,EACxE,YAAY,IAAI,EAAE,WAAW;AAE/B,UAAQ,KAAK;GACX,MAAM,EAAE;GACR,YAAY,EAAE;GACd,gBAAgB,EAAE;GAClB;GACA;GACD,CAAC;AAEF,SAAO;GAAE;GAAS;GAAa;IAEjC;EAAE,SAAS,EAAE;EAAoB,6BAAa,IAAI,KAAwB;EAAE,CAC7E;CAED,MAAM,WAAWC,iCAAAA,uBAAuB,QAAQ;AAEhD,QAAO,OAAO,YACZ,SAAS,SAAS,GAAG,OAAA,GAAA,WAAA,OAAa,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,QAAQ,GAAG,IAAI,EAAE,CAAU,CAAE,CAC5E"}
|
|
@@ -107,6 +107,20 @@ function withLabelAnnotations(derivedLabels, columns) {
|
|
|
107
107
|
};
|
|
108
108
|
});
|
|
109
109
|
}
|
|
110
|
+
function withDataStatusAnnotations(columns) {
|
|
111
|
+
return columns.map((col) => {
|
|
112
|
+
return {
|
|
113
|
+
...col,
|
|
114
|
+
spec: {
|
|
115
|
+
...col.spec,
|
|
116
|
+
annotations: {
|
|
117
|
+
...col.spec.annotations,
|
|
118
|
+
[Annotation.DataStatus]: col.dataStatus
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
});
|
|
123
|
+
}
|
|
110
124
|
/**
|
|
111
125
|
* Writes effective display properties (OrderPriority, Visibility) from precomputed rule maps
|
|
112
126
|
* into column annotations. Returns new column objects — originals are not mutated.
|
|
@@ -169,10 +183,7 @@ function deriveAllLabels(options) {
|
|
|
169
183
|
const { columns, deriveLabelsOptions } = options;
|
|
170
184
|
return deriveDistinctLabels(columns.map((c) => ({
|
|
171
185
|
spec: c.spec,
|
|
172
|
-
linkerPath: c.linkerPath?.map((step) => ({
|
|
173
|
-
spec: step.linker.spec,
|
|
174
|
-
qualifications: step.qualifications
|
|
175
|
-
})),
|
|
186
|
+
linkerPath: c.linkerPath?.map((step) => ({ spec: step.linker.spec })),
|
|
176
187
|
qualifications: c.qualifications
|
|
177
188
|
})), deriveLabelsOptions).reduce((acc, label, index) => (acc[columns[index].id] = label, acc), {});
|
|
178
189
|
}
|
|
@@ -204,6 +215,6 @@ function deriveAllTooltips(options) {
|
|
|
204
215
|
return Object.fromEntries(tooltips.flatMap((t, i) => isNil(t) ? [] : [[columns[i].id, t]]));
|
|
205
216
|
}
|
|
206
217
|
//#endregion
|
|
207
|
-
export { deriveAllLabels, deriveAllTooltips, evaluateRules, getEffectiveVisibility, getOrderPriority, isColumnHidden, isColumnOptional, withHidenAxesAnnotations, withInfoAnnotations, withLabelAnnotations, withTableVisualAnnotations };
|
|
218
|
+
export { deriveAllLabels, deriveAllTooltips, evaluateRules, getEffectiveVisibility, getOrderPriority, isColumnHidden, isColumnOptional, withDataStatusAnnotations, withHidenAxesAnnotations, withInfoAnnotations, withLabelAnnotations, withTableVisualAnnotations };
|
|
208
219
|
|
|
209
220
|
//# 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 PFrameSpecDriver,\n type PObjectId,\n Annotation,\n canonicalizeAxisId,\n DiscoveredPColumnId,\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?: MatchVariant[\"path\"];\n readonly qualifications?: MatchQualifications;\n};\n\n/** Derive labels for all table elements: columns via deriveDistinctLabels, axes from label columns. */\nexport function deriveAllLabels(options: {\n columns: LabelableColumn[];\n deriveLabelsOptions?: DeriveLabelsOptions;\n}): Record<string, string> {\n const { columns, deriveLabelsOptions } = options;\n const entries = columns.map((c) => ({\n spec: c.spec,\n linkerPath: c.linkerPath?.map((step) => ({\n spec: step.linker.spec,\n qualifications: step.qualifications,\n })),\n qualifications: c.qualifications,\n }));\n const columnLabels = deriveDistinctLabels(entries, deriveLabelsOptions).reduce(\n (acc, label, index) => ((acc[columns[index].id] = label), acc),\n {} as Record<string, string>,\n );\n return columnLabels;\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};\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 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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"}
|
|
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 DiscoveredPColumnId,\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 { ColumnDataStatus, 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 {\n readonly id: PObjectId;\n readonly spec: PColumnSpec;\n },\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\nexport function withDataStatusAnnotations<\n T extends {\n readonly spec: PColumnSpec;\n readonly dataStatus: ColumnDataStatus;\n },\n>(columns: T[]): T[] {\n return columns.map((col) => {\n return {\n ...col,\n spec: {\n ...col.spec,\n annotations: {\n ...col.spec.annotations,\n [Annotation.DataStatus]: col.dataStatus,\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?: MatchVariant[\"path\"];\n readonly qualifications?: MatchQualifications;\n};\n\n/** Derive labels for all table elements: columns via deriveDistinctLabels, axes from label columns. */\nexport function deriveAllLabels(options: {\n columns: LabelableColumn[];\n deriveLabelsOptions?: DeriveLabelsOptions;\n}): Record<string, string> {\n const { columns, deriveLabelsOptions } = options;\n const entries = columns.map((c) => ({\n spec: c.spec,\n linkerPath: c.linkerPath?.map((step) => ({\n spec: step.linker.spec,\n })),\n qualifications: c.qualifications,\n }));\n const columnLabels = deriveDistinctLabels(entries, deriveLabelsOptions).reduce(\n (acc, label, index) => ((acc[columns[index].id] = label), acc),\n {} as Record<string, string>,\n );\n return columnLabels;\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};\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 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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"}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
require("../../_virtual/_rolldown/runtime.cjs");
|
|
1
2
|
const require_filter_discovery = require("./filter_discovery.cjs");
|
|
2
3
|
const require_column_collection_builder = require("../../columns/column_collection_builder.cjs");
|
|
3
4
|
const require_ctx_column_sources = require("../../columns/ctx_column_sources.cjs");
|
|
5
|
+
const require_enrichment_discovery = require("./enrichment_discovery.cjs");
|
|
6
|
+
let _milaboratories_pl_model_common = require("@milaboratories/pl-model-common");
|
|
4
7
|
//#region src/components/PlDatasetSelector/build_dataset_options.ts
|
|
5
8
|
/**
|
|
6
9
|
* Usage:
|
|
@@ -9,26 +12,35 @@ const require_ctx_column_sources = require("../../columns/ctx_column_sources.cjs
|
|
|
9
12
|
* ```
|
|
10
13
|
*/
|
|
11
14
|
function buildDatasetOptions(ctx, opts) {
|
|
12
|
-
const
|
|
13
|
-
const
|
|
15
|
+
const primary = opts?.primary;
|
|
16
|
+
const primaryPredicate = primary === void 0 ? () => true : typeof primary === "function" ? primary : (0, _milaboratories_pl_model_common.multiColumnSelectorsToPredicate)(primary);
|
|
17
|
+
const options = ctx.resultPool.getOptions(primaryPredicate, { refsWithEnrichments: true });
|
|
14
18
|
if (options.length === 0) return [];
|
|
15
19
|
const columnSources = require_ctx_column_sources.collectCtxColumnSnapshotProviders(ctx);
|
|
16
20
|
const refMap = require_filter_discovery.buildRefMap(ctx.resultPool.getSpecs().entries);
|
|
17
21
|
const pframeSpec = ctx.getService("pframeSpec");
|
|
18
|
-
return options.map((
|
|
19
|
-
const datasetSpec = ctx.resultPool.getPColumnSpecByRef(
|
|
20
|
-
if (!datasetSpec) return
|
|
22
|
+
return options.map((primary) => {
|
|
23
|
+
const datasetSpec = ctx.resultPool.getPColumnSpecByRef(primary.ref);
|
|
24
|
+
if (!datasetSpec) return { primary };
|
|
21
25
|
const builder = new require_column_collection_builder.ColumnCollectionBuilder(pframeSpec);
|
|
22
26
|
for (const src of columnSources) builder.addSource(src);
|
|
23
27
|
const collection = builder.build({ anchors: { main: datasetSpec } });
|
|
24
|
-
if (!collection) return
|
|
28
|
+
if (!collection) return { primary };
|
|
25
29
|
try {
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
30
|
+
const filterMatches = require_filter_discovery.findFilterColumns(collection);
|
|
31
|
+
const filters = filterMatches.length === 0 ? void 0 : require_filter_discovery.filterMatchesToOptions(filterMatches, refMap, opts?.labelOptions);
|
|
32
|
+
let enrichments;
|
|
33
|
+
if (opts?.withEnrichments !== void 0) {
|
|
34
|
+
const enrichmentVariants = require_enrichment_discovery.findEnrichmentColumns(collection, {
|
|
35
|
+
maxHops: opts.enrichmentMaxHops,
|
|
36
|
+
...typeof opts.withEnrichments === "function" ? { predicate: opts.withEnrichments } : { include: opts.withEnrichments }
|
|
37
|
+
});
|
|
38
|
+
if (enrichmentVariants.length > 0) enrichments = require_enrichment_discovery.enrichmentVariantsToRefs(enrichmentVariants, opts.labelOptions);
|
|
39
|
+
}
|
|
29
40
|
return {
|
|
30
|
-
|
|
31
|
-
filters
|
|
41
|
+
primary,
|
|
42
|
+
...filters !== void 0 && filters.length > 0 ? { filters } : {},
|
|
43
|
+
...enrichments !== void 0 && enrichments.length > 0 ? { enrichments } : {}
|
|
32
44
|
};
|
|
33
45
|
} finally {
|
|
34
46
|
collection.dispose();
|
|
@@ -1 +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 {
|
|
1
|
+
{"version":3,"file":"build_dataset_options.cjs","names":["collectCtxColumnSnapshotProviders","buildRefMap","ColumnCollectionBuilder","findFilterColumns","filterMatchesToOptions","findEnrichmentColumns","enrichmentVariantsToRefs"],"sources":["../../../src/components/PlDatasetSelector/build_dataset_options.ts"],"sourcesContent":["import type { MultiColumnSelector, Option, PObjectSpec } from \"@milaboratories/pl-model-common\";\nimport { multiColumnSelectorsToPredicate } 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 type { DatasetOption } from \"./dataset_selection\";\nimport { buildRefMap, filterMatchesToOptions, findFilterColumns } from \"./filter_discovery\";\nimport { enrichmentVariantsToRefs, findEnrichmentColumns } from \"./enrichment_discovery\";\n\nexport type BuildDatasetOptions = {\n /** Which result pool columns qualify as datasets. Defaults to all. */\n primary?: MultiColumnSelector | MultiColumnSelector[] | ((spec: PObjectSpec) => boolean);\n /** Formatting options for filter labels. */\n labelOptions?: DeriveLabelsOptions;\n /**\n * Enables enrichment discovery and filters hits attached to\n * `DatasetOption.enrichments`. Use `() => true` to accept all; omit to disable.\n */\n withEnrichments?: MultiColumnSelector | MultiColumnSelector[] | ((spec: PObjectSpec) => boolean);\n /** Maximum linker hops considered. Only used when `withEnrichments` is set. */\n enrichmentMaxHops?: number;\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 primary = opts?.primary;\n const primaryPredicate =\n primary === undefined\n ? () => true\n : typeof primary === \"function\"\n ? primary\n : multiColumnSelectorsToPredicate(primary);\n const options = ctx.resultPool.getOptions(primaryPredicate, { 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((primary: Option): DatasetOption => {\n const datasetSpec = ctx.resultPool.getPColumnSpecByRef(primary.ref);\n if (!datasetSpec) return { primary };\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 { primary };\n\n try {\n const filterMatches = findFilterColumns(collection);\n const filters =\n filterMatches.length === 0\n ? undefined\n : filterMatchesToOptions(filterMatches, refMap, opts?.labelOptions);\n\n let enrichments;\n if (opts?.withEnrichments !== undefined) {\n const enrichmentVariants = findEnrichmentColumns(collection, {\n maxHops: opts.enrichmentMaxHops,\n ...(typeof opts.withEnrichments === \"function\"\n ? { predicate: opts.withEnrichments }\n : { include: opts.withEnrichments }),\n });\n if (enrichmentVariants.length > 0) {\n enrichments = enrichmentVariantsToRefs(enrichmentVariants, opts.labelOptions);\n }\n }\n\n return {\n primary,\n ...(filters !== undefined && filters.length > 0 ? { filters } : {}),\n ...(enrichments !== undefined && enrichments.length > 0 ? { enrichments } : {}),\n };\n } finally {\n collection.dispose();\n }\n });\n}\n"],"mappings":";;;;;;;;;;;;;AA8BA,SAAgB,oBACd,KACA,MAC6B;CAC7B,MAAM,UAAU,MAAM;CACtB,MAAM,mBACJ,YAAY,KAAA,UACF,OACN,OAAO,YAAY,aACjB,WAAA,GAAA,gCAAA,iCACgC,QAAQ;CAChD,MAAM,UAAU,IAAI,WAAW,WAAW,kBAAkB,EAAE,qBAAqB,MAAM,CAAC;AAC1F,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,YAAmC;EACrD,MAAM,cAAc,IAAI,WAAW,oBAAoB,QAAQ,IAAI;AACnE,MAAI,CAAC,YAAa,QAAO,EAAE,SAAS;EAEpC,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,EAAE,SAAS;AAEnC,MAAI;GACF,MAAM,gBAAgBC,yBAAAA,kBAAkB,WAAW;GACnD,MAAM,UACJ,cAAc,WAAW,IACrB,KAAA,IACAC,yBAAAA,uBAAuB,eAAe,QAAQ,MAAM,aAAa;GAEvE,IAAI;AACJ,OAAI,MAAM,oBAAoB,KAAA,GAAW;IACvC,MAAM,qBAAqBC,6BAAAA,sBAAsB,YAAY;KAC3D,SAAS,KAAK;KACd,GAAI,OAAO,KAAK,oBAAoB,aAChC,EAAE,WAAW,KAAK,iBAAiB,GACnC,EAAE,SAAS,KAAK,iBAAiB;KACtC,CAAC;AACF,QAAI,mBAAmB,SAAS,EAC9B,eAAcC,6BAAAA,yBAAyB,oBAAoB,KAAK,aAAa;;AAIjF,UAAO;IACL;IACA,GAAI,YAAY,KAAA,KAAa,QAAQ,SAAS,IAAI,EAAE,SAAS,GAAG,EAAE;IAClE,GAAI,gBAAgB,KAAA,KAAa,YAAY,SAAS,IAAI,EAAE,aAAa,GAAG,EAAE;IAC/E;YACO;AACR,cAAW,SAAS;;GAEtB"}
|
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
import { DeriveLabelsOptions } from "../../labels/derive_distinct_labels.js";
|
|
2
2
|
import { RenderCtxBase } from "../../render/api.js";
|
|
3
|
-
import { DatasetOption
|
|
3
|
+
import { DatasetOption } from "./dataset_selection.js";
|
|
4
|
+
import { MultiColumnSelector, PObjectSpec } from "@milaboratories/pl-model-common";
|
|
4
5
|
|
|
5
6
|
//#region src/components/PlDatasetSelector/build_dataset_options.d.ts
|
|
6
7
|
type BuildDatasetOptions = {
|
|
7
|
-
/** Which result pool columns qualify as datasets. Defaults to all. */
|
|
8
|
+
/** Which result pool columns qualify as datasets. Defaults to all. */primary?: MultiColumnSelector | MultiColumnSelector[] | ((spec: PObjectSpec) => boolean); /** Formatting options for filter labels. */
|
|
8
9
|
labelOptions?: DeriveLabelsOptions;
|
|
10
|
+
/**
|
|
11
|
+
* Enables enrichment discovery and filters hits attached to
|
|
12
|
+
* `DatasetOption.enrichments`. Use `() => true` to accept all; omit to disable.
|
|
13
|
+
*/
|
|
14
|
+
withEnrichments?: MultiColumnSelector | MultiColumnSelector[] | ((spec: PObjectSpec) => boolean); /** Maximum linker hops considered. Only used when `withEnrichments` is set. */
|
|
15
|
+
enrichmentMaxHops?: number;
|
|
9
16
|
};
|
|
10
17
|
/**
|
|
11
18
|
* Usage:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build_dataset_options.d.ts","names":[],"sources":["../../../src/components/PlDatasetSelector/build_dataset_options.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"build_dataset_options.d.ts","names":[],"sources":["../../../src/components/PlDatasetSelector/build_dataset_options.ts"],"mappings":";;;;;;KAUY,mBAAA;wEAEV,OAAA,GAAU,mBAAA,GAAsB,mBAAA,OAA0B,IAAA,EAAM,WAAA,eAFtD;EAIV,YAAA,GAAe,mBAAA;;;;;EAKf,eAAA,GAAkB,mBAAA,GAAsB,mBAAA,OAA0B,IAAA,EAAM,WAAA,eAAtD;EAElB,iBAAA;AAAA;;;;;;;iBASc,mBAAA,CACd,GAAA,EAAK,aAAA,EACL,IAAA,GAAO,mBAAA,GACN,aAAA"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { buildRefMap, filterMatchesToOptions, findFilterColumns } from "./filter_discovery.js";
|
|
2
2
|
import { ColumnCollectionBuilder } from "../../columns/column_collection_builder.js";
|
|
3
3
|
import { collectCtxColumnSnapshotProviders } from "../../columns/ctx_column_sources.js";
|
|
4
|
+
import { enrichmentVariantsToRefs, findEnrichmentColumns } from "./enrichment_discovery.js";
|
|
5
|
+
import { multiColumnSelectorsToPredicate } from "@milaboratories/pl-model-common";
|
|
4
6
|
//#region src/components/PlDatasetSelector/build_dataset_options.ts
|
|
5
7
|
/**
|
|
6
8
|
* Usage:
|
|
@@ -9,26 +11,35 @@ import { collectCtxColumnSnapshotProviders } from "../../columns/ctx_column_sour
|
|
|
9
11
|
* ```
|
|
10
12
|
*/
|
|
11
13
|
function buildDatasetOptions(ctx, opts) {
|
|
12
|
-
const
|
|
13
|
-
const
|
|
14
|
+
const primary = opts?.primary;
|
|
15
|
+
const primaryPredicate = primary === void 0 ? () => true : typeof primary === "function" ? primary : multiColumnSelectorsToPredicate(primary);
|
|
16
|
+
const options = ctx.resultPool.getOptions(primaryPredicate, { refsWithEnrichments: true });
|
|
14
17
|
if (options.length === 0) return [];
|
|
15
18
|
const columnSources = collectCtxColumnSnapshotProviders(ctx);
|
|
16
19
|
const refMap = buildRefMap(ctx.resultPool.getSpecs().entries);
|
|
17
20
|
const pframeSpec = ctx.getService("pframeSpec");
|
|
18
|
-
return options.map((
|
|
19
|
-
const datasetSpec = ctx.resultPool.getPColumnSpecByRef(
|
|
20
|
-
if (!datasetSpec) return
|
|
21
|
+
return options.map((primary) => {
|
|
22
|
+
const datasetSpec = ctx.resultPool.getPColumnSpecByRef(primary.ref);
|
|
23
|
+
if (!datasetSpec) return { primary };
|
|
21
24
|
const builder = new ColumnCollectionBuilder(pframeSpec);
|
|
22
25
|
for (const src of columnSources) builder.addSource(src);
|
|
23
26
|
const collection = builder.build({ anchors: { main: datasetSpec } });
|
|
24
|
-
if (!collection) return
|
|
27
|
+
if (!collection) return { primary };
|
|
25
28
|
try {
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
+
const filterMatches = findFilterColumns(collection);
|
|
30
|
+
const filters = filterMatches.length === 0 ? void 0 : filterMatchesToOptions(filterMatches, refMap, opts?.labelOptions);
|
|
31
|
+
let enrichments;
|
|
32
|
+
if (opts?.withEnrichments !== void 0) {
|
|
33
|
+
const enrichmentVariants = findEnrichmentColumns(collection, {
|
|
34
|
+
maxHops: opts.enrichmentMaxHops,
|
|
35
|
+
...typeof opts.withEnrichments === "function" ? { predicate: opts.withEnrichments } : { include: opts.withEnrichments }
|
|
36
|
+
});
|
|
37
|
+
if (enrichmentVariants.length > 0) enrichments = enrichmentVariantsToRefs(enrichmentVariants, opts.labelOptions);
|
|
38
|
+
}
|
|
29
39
|
return {
|
|
30
|
-
|
|
31
|
-
filters
|
|
40
|
+
primary,
|
|
41
|
+
...filters !== void 0 && filters.length > 0 ? { filters } : {},
|
|
42
|
+
...enrichments !== void 0 && enrichments.length > 0 ? { enrichments } : {}
|
|
32
43
|
};
|
|
33
44
|
} finally {
|
|
34
45
|
collection.dispose();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build_dataset_options.js","names":[],"sources":["../../../src/components/PlDatasetSelector/build_dataset_options.ts"],"sourcesContent":["import type {
|
|
1
|
+
{"version":3,"file":"build_dataset_options.js","names":[],"sources":["../../../src/components/PlDatasetSelector/build_dataset_options.ts"],"sourcesContent":["import type { MultiColumnSelector, Option, PObjectSpec } from \"@milaboratories/pl-model-common\";\nimport { multiColumnSelectorsToPredicate } 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 type { DatasetOption } from \"./dataset_selection\";\nimport { buildRefMap, filterMatchesToOptions, findFilterColumns } from \"./filter_discovery\";\nimport { enrichmentVariantsToRefs, findEnrichmentColumns } from \"./enrichment_discovery\";\n\nexport type BuildDatasetOptions = {\n /** Which result pool columns qualify as datasets. Defaults to all. */\n primary?: MultiColumnSelector | MultiColumnSelector[] | ((spec: PObjectSpec) => boolean);\n /** Formatting options for filter labels. */\n labelOptions?: DeriveLabelsOptions;\n /**\n * Enables enrichment discovery and filters hits attached to\n * `DatasetOption.enrichments`. Use `() => true` to accept all; omit to disable.\n */\n withEnrichments?: MultiColumnSelector | MultiColumnSelector[] | ((spec: PObjectSpec) => boolean);\n /** Maximum linker hops considered. Only used when `withEnrichments` is set. */\n enrichmentMaxHops?: number;\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 primary = opts?.primary;\n const primaryPredicate =\n primary === undefined\n ? () => true\n : typeof primary === \"function\"\n ? primary\n : multiColumnSelectorsToPredicate(primary);\n const options = ctx.resultPool.getOptions(primaryPredicate, { 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((primary: Option): DatasetOption => {\n const datasetSpec = ctx.resultPool.getPColumnSpecByRef(primary.ref);\n if (!datasetSpec) return { primary };\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 { primary };\n\n try {\n const filterMatches = findFilterColumns(collection);\n const filters =\n filterMatches.length === 0\n ? undefined\n : filterMatchesToOptions(filterMatches, refMap, opts?.labelOptions);\n\n let enrichments;\n if (opts?.withEnrichments !== undefined) {\n const enrichmentVariants = findEnrichmentColumns(collection, {\n maxHops: opts.enrichmentMaxHops,\n ...(typeof opts.withEnrichments === \"function\"\n ? { predicate: opts.withEnrichments }\n : { include: opts.withEnrichments }),\n });\n if (enrichmentVariants.length > 0) {\n enrichments = enrichmentVariantsToRefs(enrichmentVariants, opts.labelOptions);\n }\n }\n\n return {\n primary,\n ...(filters !== undefined && filters.length > 0 ? { filters } : {}),\n ...(enrichments !== undefined && enrichments.length > 0 ? { enrichments } : {}),\n };\n } finally {\n collection.dispose();\n }\n });\n}\n"],"mappings":";;;;;;;;;;;;AA8BA,SAAgB,oBACd,KACA,MAC6B;CAC7B,MAAM,UAAU,MAAM;CACtB,MAAM,mBACJ,YAAY,KAAA,UACF,OACN,OAAO,YAAY,aACjB,UACA,gCAAgC,QAAQ;CAChD,MAAM,UAAU,IAAI,WAAW,WAAW,kBAAkB,EAAE,qBAAqB,MAAM,CAAC;AAC1F,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,YAAmC;EACrD,MAAM,cAAc,IAAI,WAAW,oBAAoB,QAAQ,IAAI;AACnE,MAAI,CAAC,YAAa,QAAO,EAAE,SAAS;EAEpC,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,EAAE,SAAS;AAEnC,MAAI;GACF,MAAM,gBAAgB,kBAAkB,WAAW;GACnD,MAAM,UACJ,cAAc,WAAW,IACrB,KAAA,IACA,uBAAuB,eAAe,QAAQ,MAAM,aAAa;GAEvE,IAAI;AACJ,OAAI,MAAM,oBAAoB,KAAA,GAAW;IACvC,MAAM,qBAAqB,sBAAsB,YAAY;KAC3D,SAAS,KAAK;KACd,GAAI,OAAO,KAAK,oBAAoB,aAChC,EAAE,WAAW,KAAK,iBAAiB,GACnC,EAAE,SAAS,KAAK,iBAAiB;KACtC,CAAC;AACF,QAAI,mBAAmB,SAAS,EAC9B,eAAc,yBAAyB,oBAAoB,KAAK,aAAa;;AAIjF,UAAO;IACL;IACA,GAAI,YAAY,KAAA,KAAa,QAAQ,SAAS,IAAI,EAAE,SAAS,GAAG,EAAE;IAClE,GAAI,gBAAgB,KAAA,KAAa,YAAY,SAAS,IAAI,EAAE,aAAa,GAAG,EAAE;IAC/E;YACO;AACR,cAAW,SAAS;;GAEtB"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
//#region src/components/PlDatasetSelector/dataset_selection.ts
|
|
2
|
+
function isDatasetSelection(value) {
|
|
3
|
+
return typeof value === "object" && value !== null && value.__isDatasetSelection === "v1" && "primary" in value;
|
|
4
|
+
}
|
|
5
|
+
function createDatasetSelection(primary, enrichments) {
|
|
6
|
+
if (enrichments !== void 0 && enrichments.length > 0) return {
|
|
7
|
+
__isDatasetSelection: "v1",
|
|
8
|
+
primary,
|
|
9
|
+
enrichments
|
|
10
|
+
};
|
|
11
|
+
return {
|
|
12
|
+
__isDatasetSelection: "v1",
|
|
13
|
+
primary
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
//#endregion
|
|
17
|
+
exports.createDatasetSelection = createDatasetSelection;
|
|
18
|
+
exports.isDatasetSelection = isDatasetSelection;
|
|
19
|
+
|
|
20
|
+
//# sourceMappingURL=dataset_selection.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dataset_selection.cjs","names":[],"sources":["../../../src/components/PlDatasetSelector/dataset_selection.ts"],"sourcesContent":["import type { LabeledEnrichmentRefs, Option, PrimaryRef } from \"@milaboratories/pl-model-common\";\n\n/** Dataset picker entry: user picks {@link primary}, gets {@link enrichments} attached. */\nexport type DatasetOption = {\n readonly primary: Option;\n readonly filters?: readonly Option[];\n readonly enrichments?: LabeledEnrichmentRefs;\n};\n\n/**\n * Picked dataset bundle emitted by `PlDatasetSelector`. Stored opaquely in\n * block data; block authors unbundle inside their args resolver.\n */\nexport type DatasetSelection = {\n readonly __isDatasetSelection: \"v1\";\n readonly primary: PrimaryRef;\n readonly enrichments?: LabeledEnrichmentRefs;\n};\n\nexport function isDatasetSelection(value: unknown): value is DatasetSelection {\n return (\n typeof value === \"object\" &&\n value !== null &&\n (value as { __isDatasetSelection?: unknown }).__isDatasetSelection === \"v1\" &&\n \"primary\" in value\n );\n}\n\nexport function createDatasetSelection(\n primary: PrimaryRef,\n enrichments?: LabeledEnrichmentRefs,\n): DatasetSelection {\n if (enrichments !== undefined && enrichments.length > 0) {\n return { __isDatasetSelection: \"v1\", primary, enrichments };\n }\n return { __isDatasetSelection: \"v1\", primary };\n}\n"],"mappings":";AAmBA,SAAgB,mBAAmB,OAA2C;AAC5E,QACE,OAAO,UAAU,YACjB,UAAU,QACT,MAA6C,yBAAyB,QACvE,aAAa;;AAIjB,SAAgB,uBACd,SACA,aACkB;AAClB,KAAI,gBAAgB,KAAA,KAAa,YAAY,SAAS,EACpD,QAAO;EAAE,sBAAsB;EAAM;EAAS;EAAa;AAE7D,QAAO;EAAE,sBAAsB;EAAM;EAAS"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { LabeledEnrichmentRefs, Option, PrimaryRef } from "@milaboratories/pl-model-common";
|
|
2
|
+
|
|
3
|
+
//#region src/components/PlDatasetSelector/dataset_selection.d.ts
|
|
4
|
+
/** Dataset picker entry: user picks {@link primary}, gets {@link enrichments} attached. */
|
|
5
|
+
type DatasetOption = {
|
|
6
|
+
readonly primary: Option;
|
|
7
|
+
readonly filters?: readonly Option[];
|
|
8
|
+
readonly enrichments?: LabeledEnrichmentRefs;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Picked dataset bundle emitted by `PlDatasetSelector`. Stored opaquely in
|
|
12
|
+
* block data; block authors unbundle inside their args resolver.
|
|
13
|
+
*/
|
|
14
|
+
type DatasetSelection = {
|
|
15
|
+
readonly __isDatasetSelection: "v1";
|
|
16
|
+
readonly primary: PrimaryRef;
|
|
17
|
+
readonly enrichments?: LabeledEnrichmentRefs;
|
|
18
|
+
};
|
|
19
|
+
declare function isDatasetSelection(value: unknown): value is DatasetSelection;
|
|
20
|
+
declare function createDatasetSelection(primary: PrimaryRef, enrichments?: LabeledEnrichmentRefs): DatasetSelection;
|
|
21
|
+
//#endregion
|
|
22
|
+
export { DatasetOption, DatasetSelection, createDatasetSelection, isDatasetSelection };
|
|
23
|
+
//# sourceMappingURL=dataset_selection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dataset_selection.d.ts","names":[],"sources":["../../../src/components/PlDatasetSelector/dataset_selection.ts"],"mappings":";;;;KAGY,aAAA;EAAA,SACD,OAAA,EAAS,MAAA;EAAA,SACT,OAAA,YAAmB,MAAA;EAAA,SACnB,WAAA,GAAc,qBAAA;AAAA;;;;;KAOb,gBAAA;EAAA,SACD,oBAAA;EAAA,SACA,OAAA,EAAS,UAAA;EAAA,SACT,WAAA,GAAc,qBAAA;AAAA;AAAA,iBAGT,kBAAA,CAAmB,KAAA,YAAiB,KAAA,IAAS,gBAAA;AAAA,iBAS7C,sBAAA,CACd,OAAA,EAAS,UAAA,EACT,WAAA,GAAc,qBAAA,GACb,gBAAA"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
//#region src/components/PlDatasetSelector/dataset_selection.ts
|
|
2
|
+
function isDatasetSelection(value) {
|
|
3
|
+
return typeof value === "object" && value !== null && value.__isDatasetSelection === "v1" && "primary" in value;
|
|
4
|
+
}
|
|
5
|
+
function createDatasetSelection(primary, enrichments) {
|
|
6
|
+
if (enrichments !== void 0 && enrichments.length > 0) return {
|
|
7
|
+
__isDatasetSelection: "v1",
|
|
8
|
+
primary,
|
|
9
|
+
enrichments
|
|
10
|
+
};
|
|
11
|
+
return {
|
|
12
|
+
__isDatasetSelection: "v1",
|
|
13
|
+
primary
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
//#endregion
|
|
17
|
+
export { createDatasetSelection, isDatasetSelection };
|
|
18
|
+
|
|
19
|
+
//# sourceMappingURL=dataset_selection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dataset_selection.js","names":[],"sources":["../../../src/components/PlDatasetSelector/dataset_selection.ts"],"sourcesContent":["import type { LabeledEnrichmentRefs, Option, PrimaryRef } from \"@milaboratories/pl-model-common\";\n\n/** Dataset picker entry: user picks {@link primary}, gets {@link enrichments} attached. */\nexport type DatasetOption = {\n readonly primary: Option;\n readonly filters?: readonly Option[];\n readonly enrichments?: LabeledEnrichmentRefs;\n};\n\n/**\n * Picked dataset bundle emitted by `PlDatasetSelector`. Stored opaquely in\n * block data; block authors unbundle inside their args resolver.\n */\nexport type DatasetSelection = {\n readonly __isDatasetSelection: \"v1\";\n readonly primary: PrimaryRef;\n readonly enrichments?: LabeledEnrichmentRefs;\n};\n\nexport function isDatasetSelection(value: unknown): value is DatasetSelection {\n return (\n typeof value === \"object\" &&\n value !== null &&\n (value as { __isDatasetSelection?: unknown }).__isDatasetSelection === \"v1\" &&\n \"primary\" in value\n );\n}\n\nexport function createDatasetSelection(\n primary: PrimaryRef,\n enrichments?: LabeledEnrichmentRefs,\n): DatasetSelection {\n if (enrichments !== undefined && enrichments.length > 0) {\n return { __isDatasetSelection: \"v1\", primary, enrichments };\n }\n return { __isDatasetSelection: \"v1\", primary };\n}\n"],"mappings":";AAmBA,SAAgB,mBAAmB,OAA2C;AAC5E,QACE,OAAO,UAAU,YACjB,UAAU,QACT,MAA6C,yBAAyB,QACvE,aAAa;;AAIjB,SAAgB,uBACd,SACA,aACkB;AAClB,KAAI,gBAAgB,KAAA,KAAa,YAAY,SAAS,EACpD,QAAO;EAAE,sBAAsB;EAAM;EAAS;EAAa;AAE7D,QAAO;EAAE,sBAAsB;EAAM;EAAS"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
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
|
+
//#region src/components/PlDatasetSelector/enrichment_discovery.ts
|
|
5
|
+
/**
|
|
6
|
+
* True for global-form ids — `canonicalize({__isRef: true, blockId, name})` —
|
|
7
|
+
* which the workflow can resolve via bquery. Local-form ids (`resolvePath`)
|
|
8
|
+
* fail this check and are excluded from auto-discovery; prerun/outputs hops
|
|
9
|
+
* must be supplied as resolved `{spec, data}` instead.
|
|
10
|
+
*/
|
|
11
|
+
function isGloballyAddressable(id) {
|
|
12
|
+
try {
|
|
13
|
+
const decoded = JSON.parse(id);
|
|
14
|
+
return typeof decoded === "object" && decoded !== null && decoded.__isRef === true && typeof decoded.blockId === "string" && typeof decoded.name === "string";
|
|
15
|
+
} catch {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Linker-reached hits attached to the anchor primary. Drops zero-hop variants
|
|
21
|
+
* (filters / the primary itself) and structural hits (subset, linker, label
|
|
22
|
+
* columns). Narrow further with `include` selectors or a `predicate`.
|
|
23
|
+
*/
|
|
24
|
+
function findEnrichmentColumns(collection, options) {
|
|
25
|
+
const include = options?.include === void 0 ? void 0 : Array.isArray(options.include) ? options.include : [options.include];
|
|
26
|
+
const variants = collection.findColumnVariants({
|
|
27
|
+
mode: "enrichment",
|
|
28
|
+
maxHops: options?.maxHops ?? 4,
|
|
29
|
+
include,
|
|
30
|
+
exclude: [
|
|
31
|
+
{ annotations: { [_milaboratories_pl_model_common.Annotation.IsSubset]: "true" } },
|
|
32
|
+
{ annotations: { [_milaboratories_pl_model_common.Annotation.IsLinkerColumn]: "true" } },
|
|
33
|
+
{ name: _milaboratories_pl_model_common.Annotation.Label }
|
|
34
|
+
]
|
|
35
|
+
});
|
|
36
|
+
const predicate = options?.predicate;
|
|
37
|
+
return variants.filter((v) => {
|
|
38
|
+
if (v.path.length === 0) return false;
|
|
39
|
+
if (predicate !== void 0 && !predicate(v.column.spec)) return false;
|
|
40
|
+
if (!isGloballyAddressable(v.column.id)) return false;
|
|
41
|
+
if (v.path.some((p) => !isGloballyAddressable(p.linker.id))) return false;
|
|
42
|
+
return true;
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Pair each variant with a path-disambiguated label (so export headers stay
|
|
47
|
+
* unique) and carry hit/linker `PObjectId`s through verbatim. Propagates
|
|
48
|
+
* `qualifications.forHit`; `forQueries` is re-derived by the table builder.
|
|
49
|
+
*/
|
|
50
|
+
function enrichmentVariantsToRefs(variants, labelOptions) {
|
|
51
|
+
if (variants.length === 0) return [];
|
|
52
|
+
const labels = require_derive_distinct_labels.deriveDistinctLabels(variants.map((variant) => ({
|
|
53
|
+
spec: variant.column.spec,
|
|
54
|
+
linkerPath: variant.path.map((p) => ({ spec: p.linker.spec })),
|
|
55
|
+
qualifications: variant.qualifications
|
|
56
|
+
})), labelOptions);
|
|
57
|
+
return variants.map((variant, i) => {
|
|
58
|
+
const path = variant.path.map((step) => ({
|
|
59
|
+
type: "linker",
|
|
60
|
+
linker: step.linker.id
|
|
61
|
+
}));
|
|
62
|
+
return {
|
|
63
|
+
ref: (0, _milaboratories_pl_model_common.createEnrichmentRef)(variant.column.id, {
|
|
64
|
+
path,
|
|
65
|
+
qualifications: variant.qualifications.forHit
|
|
66
|
+
}),
|
|
67
|
+
label: labels[i]
|
|
68
|
+
};
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
//#endregion
|
|
72
|
+
exports.enrichmentVariantsToRefs = enrichmentVariantsToRefs;
|
|
73
|
+
exports.findEnrichmentColumns = findEnrichmentColumns;
|
|
74
|
+
|
|
75
|
+
//# sourceMappingURL=enrichment_discovery.cjs.map
|