@platforma-sdk/model 1.69.0 → 1.70.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/dist/columns/column_collection_builder.cjs +1 -4
  2. package/dist/columns/column_collection_builder.cjs.map +1 -1
  3. package/dist/columns/column_collection_builder.d.ts +0 -2
  4. package/dist/columns/column_collection_builder.d.ts.map +1 -1
  5. package/dist/columns/column_collection_builder.js +1 -4
  6. package/dist/columns/column_collection_builder.js.map +1 -1
  7. package/dist/columns/ctx_column_sources.cjs +5 -8
  8. package/dist/columns/ctx_column_sources.cjs.map +1 -1
  9. package/dist/columns/ctx_column_sources.d.ts +4 -7
  10. package/dist/columns/ctx_column_sources.d.ts.map +1 -1
  11. package/dist/columns/ctx_column_sources.js +5 -8
  12. package/dist/columns/ctx_column_sources.js.map +1 -1
  13. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.cjs +1 -4
  14. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.cjs.map +1 -1
  15. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.js +1 -4
  16. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.js.map +1 -1
  17. package/dist/components/PlDataTable/createPlDataTable/discoverColumns.cjs +1 -2
  18. package/dist/components/PlDataTable/createPlDataTable/discoverColumns.cjs.map +1 -1
  19. package/dist/components/PlDataTable/createPlDataTable/discoverColumns.js +1 -2
  20. package/dist/components/PlDataTable/createPlDataTable/discoverColumns.js.map +1 -1
  21. package/dist/components/PlDataTable/createPlDataTable/utils.cjs +1 -4
  22. package/dist/components/PlDataTable/createPlDataTable/utils.cjs.map +1 -1
  23. package/dist/components/PlDataTable/createPlDataTable/utils.js +1 -4
  24. package/dist/components/PlDataTable/createPlDataTable/utils.js.map +1 -1
  25. package/dist/components/PlDatasetSelector/build_dataset_options.cjs +23 -11
  26. package/dist/components/PlDatasetSelector/build_dataset_options.cjs.map +1 -1
  27. package/dist/components/PlDatasetSelector/build_dataset_options.d.ts +9 -2
  28. package/dist/components/PlDatasetSelector/build_dataset_options.d.ts.map +1 -1
  29. package/dist/components/PlDatasetSelector/build_dataset_options.js +22 -11
  30. package/dist/components/PlDatasetSelector/build_dataset_options.js.map +1 -1
  31. package/dist/components/PlDatasetSelector/dataset_selection.cjs +20 -0
  32. package/dist/components/PlDatasetSelector/dataset_selection.cjs.map +1 -0
  33. package/dist/components/PlDatasetSelector/dataset_selection.d.ts +23 -0
  34. package/dist/components/PlDatasetSelector/dataset_selection.d.ts.map +1 -0
  35. package/dist/components/PlDatasetSelector/dataset_selection.js +19 -0
  36. package/dist/components/PlDatasetSelector/dataset_selection.js.map +1 -0
  37. package/dist/components/PlDatasetSelector/enrichment_discovery.cjs +75 -0
  38. package/dist/components/PlDatasetSelector/enrichment_discovery.cjs.map +1 -0
  39. package/dist/components/PlDatasetSelector/enrichment_discovery.js +73 -0
  40. package/dist/components/PlDatasetSelector/enrichment_discovery.js.map +1 -0
  41. package/dist/components/PlDatasetSelector/index.cjs +1 -0
  42. package/dist/components/PlDatasetSelector/index.d.ts +1 -0
  43. package/dist/components/PlDatasetSelector/index.js +1 -0
  44. package/dist/components/index.cjs +1 -0
  45. package/dist/components/index.d.ts +1 -0
  46. package/dist/components/index.js +1 -0
  47. package/dist/index.cjs +3 -0
  48. package/dist/index.d.ts +2 -1
  49. package/dist/index.js +2 -1
  50. package/dist/labels/derive_distinct_tooltips.cjs +0 -3
  51. package/dist/labels/derive_distinct_tooltips.cjs.map +1 -1
  52. package/dist/labels/derive_distinct_tooltips.js +0 -3
  53. package/dist/labels/derive_distinct_tooltips.js.map +1 -1
  54. package/dist/package.cjs +1 -1
  55. package/dist/package.js +1 -1
  56. package/package.json +9 -9
  57. package/src/columns/column_collection_builder.ts +0 -3
  58. package/src/columns/ctx_column_sources.ts +6 -12
  59. package/src/components/PlDataTable/createPlDataTable/createPlDataTableV3.ts +0 -1
  60. package/src/components/PlDataTable/createPlDataTable/discoverColumns.ts +0 -1
  61. package/src/components/PlDataTable/createPlDataTable/utils.ts +0 -1
  62. package/src/components/PlDatasetSelector/build_dataset_options.ts +48 -17
  63. package/src/components/PlDatasetSelector/dataset_selection.ts +37 -0
  64. package/src/components/PlDatasetSelector/enrichment_discovery.ts +111 -0
  65. package/src/components/PlDatasetSelector/index.ts +1 -0
  66. package/src/labels/derive_distinct_tooltips.test.ts +6 -16
  67. package/src/labels/derive_distinct_tooltips.ts +0 -3
@@ -1 +1 @@
1
- {"version":3,"file":"createPlDataTableV3.js","names":[],"sources":["../../../../src/components/PlDataTable/createPlDataTable/createPlDataTableV3.ts"],"sourcesContent":["import type {\n AxisId,\n CanonicalizedJson,\n FilterSpecNode,\n PColumn,\n PObjectId,\n PTableColumnId,\n PTableColumnIdAxis,\n PTableColumnIdColumn,\n PTableSorting,\n PColumnSpec,\n MultiColumnSelector,\n PFrameSpecDriver,\n DiscoveredPColumnId,\n} from \"@milaboratories/pl-model-common\";\nimport { canonicalizeJson, getAxisId, parseJson, uniqueBy } from \"@milaboratories/pl-model-common\";\nimport { collectFilterSpecColumns, traverseFilterSpec } from \"../../../filters/traverse\";\nimport type { RenderCtxBase, PColumnDataUniversal } from \"../../../render\";\nimport { isEmpty } from \"es-toolkit/compat\";\nimport type { PlDataTableFilters, PlDataTableFilterSpecLeaf, PlDataTableModel } from \"../typesV5\";\nimport { upgradePlDataTableStateV2 } from \"../state-migration\";\nimport type { PlDataTableStateV2 } from \"../state-migration\";\nimport type { ColumnSelector, ColumnSnapshot, ColumnVariant, MatchingMode } from \"../../../columns\";\nimport type { DeriveLabelsOptions } from \"../../../labels/derive_distinct_labels\";\nimport {\n deriveAllLabels,\n deriveAllTooltips,\n evaluateRules,\n isColumnHidden,\n isColumnOptional,\n withHidenAxesAnnotations,\n withLabelAnnotations,\n withTableVisualAnnotations,\n withInfoAnnotations,\n} from \"./utils\";\nimport type { PrimaryEntry, SecondaryGroup } from \"./createPTableDefV3\";\nimport { createPTableDefV3 } from \"./createPTableDefV3\";\nimport { discoverTableColumnSnaphots, type DiscoverTableColumnOptions } from \"./discoverColumns\";\nimport { isNil, isPlainObject, throwError, type Nil } from \"@milaboratories/helpers\";\nimport { flow } from \"es-toolkit\";\n\nexport type createPlDataTableOptionsV3 = {\n tableState?: PlDataTableStateV2;\n\n columns: Nil | DiscoverTableColumnOptions | TableColumnVariant[];\n filters?: PlDataTableFilters;\n sorting?: PTableSorting[];\n primaryJoinType?: \"inner\" | \"full\";\n\n labelsOptions?: DeriveLabelsOptions;\n displayOptions?: ColumnsDisplayOptions;\n};\n\n/** Structured source config — selectors/anchors instead of raw ColumnSource. */\nexport type ColumnsSelectorConfig = {\n include?: MultiColumnSelector | MultiColumnSelector[];\n exclude?: MultiColumnSelector | MultiColumnSelector[];\n mode?: MatchingMode;\n maxHops?: number;\n};\n\nexport type ColumnsDisplayOptions = {\n /** Column ordering rules. Higher priority = further left. First matching rule wins. */\n ordering?: ColumnOrderRule[];\n /** Column visibility rules. First matching rule wins. Unmatched columns use default visibility. */\n visibility?: ColumnVisibilityRule[];\n};\n\nexport type ColumnOrderRule = {\n match: ColumnMatcher | ColumnSelector;\n /** Higher number = further left in table */\n priority: number;\n};\n\nexport type ColumnVisibilityRule = {\n match: ColumnMatcher | ColumnSelector;\n visibility: \"default\" | \"optional\" | \"hidden\";\n};\n\nexport type ColumnMatcher = (spec: PColumnSpec) => boolean;\n\n// Main Function\n\nexport function createPlDataTableV3<A, U>(\n ctx: RenderCtxBase<A, U>,\n options: createPlDataTableOptionsV3,\n): PlDataTableModel | undefined {\n const pframeSpec = ctx.getService(\"pframeSpec\");\n const state = upgradePlDataTableStateV2(options.tableState);\n const primaryJoinType = options.primaryJoinType ?? \"full\";\n\n const discovered = isPlainObject(options.columns)\n ? discoverTableColumnSnaphots(ctx, options.columns)\n : options.columns;\n if (isNil(discovered) || discovered.length === 0) return undefined;\n\n const splited = splitDiscoveredColumns(discovered);\n\n const derivedLabels = deriveAllLabels({\n columns: discovered.map((dc) => ({\n id: dc.column.id,\n spec: dc.column.spec,\n linkerPath: dc.path,\n qualifications: dc.qualifications,\n })),\n deriveLabelsOptions: {\n includeNativeLabel: true,\n ...options.labelsOptions,\n },\n });\n\n const derivedTooltips = deriveAllTooltips({\n columns: discovered.map((dc) => ({\n id: dc.column.id,\n originalId: dc.originalId,\n spec: dc.column.spec,\n linkerPath: dc.path,\n qualifications: dc.qualifications,\n })),\n });\n\n const annotated = annotateColumnGroups({\n pframeSpec,\n ...splited,\n derivedLabels,\n derivedTooltips,\n displayOptions: options.displayOptions,\n });\n\n const primarySnapshots = annotated.direct.filter((c) => c.isPrimary);\n const secondarySnapshots = annotated.direct.filter((c) => !c.isPrimary);\n\n if (primarySnapshots.length === 0) return undefined;\n\n const columnIsAvailable = createColumnValidationById([\n ...annotated.direct.map((v) => v.column),\n ...annotated.linked.flatMap((lc) => [...lc.path.map((s) => s.linker), lc.column]),\n ]);\n\n const remapedDefaultFilters = remapFilterColumnIds(options.filters, discovered);\n const filters = concatFilters(\n state.pTableParams.filters,\n state.pTableParams.defaultFilters ?? remapedDefaultFilters,\n );\n validateFilters(filters, columnIsAvailable);\n\n const sorting = resolveSorting(\n state.pTableParams.sorting,\n remapSortingColumnIds(options.sorting, discovered),\n );\n validateSorting(sorting, columnIsAvailable);\n\n const primaryEntries: PrimaryEntry<undefined | PColumnDataUniversal>[] = primarySnapshots.map(\n (v) => ({ column: resolveSnapshot(v.column) }),\n );\n const secondaryGroups: SecondaryGroup<undefined | PColumnDataUniversal>[] = buildSecondaryGroups(\n secondarySnapshots,\n annotated.linked,\n );\n const fullDef = createPTableDefV3({\n primaryJoinType,\n primary: primaryEntries,\n secondary: secondaryGroups,\n filters,\n sorting,\n });\n\n const fullHandle = ctx.createPTableV2(fullDef);\n // TODO: is workaround for dropdown suggestions.\n // Pframe have not equivalent data for columns relativly to Ptable\n const pframeHandle = ctx.createPFrame([\n ...annotated.direct.map((v) => resolveSnapshot(v.column)),\n ...annotated.linked.map((v) => resolveSnapshot(v.column)),\n ...collectLinkerSnapshots(annotated.linked).map(resolveSnapshot),\n ]);\n\n const hiddenSpecs = state.pTableParams.hiddenColIds;\n const hiddenColumnIds = computeHiddenColumns(\n [...annotated.direct, ...annotated.linked].map((v) => v.column),\n sorting,\n filters,\n hiddenSpecs,\n );\n\n const visible = buildVisibleColumns(annotated, hiddenColumnIds);\n const visibleDef = createPTableDefV3({\n primaryJoinType,\n primary: primaryEntries,\n secondary: buildSecondaryGroups(\n visible.direct.filter((c) => !c.isPrimary),\n visible.linked,\n ),\n filters,\n sorting,\n });\n const visibleHandle = ctx.createPTableV2(visibleDef);\n\n return {\n sourceId: state.pTableParams.sourceId,\n fullTableHandle: fullHandle,\n fullPframeHandle: pframeHandle,\n visibleTableHandle: visibleHandle,\n defaultFilters: remapedDefaultFilters,\n } satisfies PlDataTableModel;\n}\n\nexport type TableColumnVariant = ColumnVariant<DiscoveredPColumnId> & {\n readonly originalId: PObjectId;\n readonly isPrimary?: boolean;\n};\n\ntype SplitDiscoveredColumns = {\n readonly direct: TableColumnVariant[];\n readonly linked: TableColumnVariant[];\n};\n\ntype AnnotatedColumnGroups = {\n readonly direct: TableColumnVariant[];\n readonly linked: TableColumnVariant[];\n};\n\ntype VisibleColumns = {\n readonly direct: TableColumnVariant[];\n readonly linked: TableColumnVariant[];\n};\n\n/** Split discovered columns into direct (no linker path) and linked (with linker path). */\nfunction splitDiscoveredColumns(columns: TableColumnVariant[]): SplitDiscoveredColumns {\n const direct = columns.filter((dc) => dc.path.length === 0);\n const linked = columns.filter((dc) => dc.path.length > 0);\n return { direct, linked };\n}\n\n/** All linker snapshots across the given linked columns, deduped by id. */\nfunction collectLinkerSnapshots(linked: TableColumnVariant[]): ColumnSnapshot<PObjectId>[] {\n return uniqueBy(\n linked.flatMap((lc) => lc.path.map((s) => s.linker)),\n (c) => c.id,\n );\n}\n\n/**\n * Annotate all column groups with derived labels and display-rule annotations.\n * Evaluates `displayOptions` rules against all discovered columns (direct,\n * linked, labels, linkers) and writes the winning visibility/priority into\n * column annotations via `withTableVisualAnnotations`.\n */\nfunction annotateColumnGroups(params: {\n direct: TableColumnVariant[];\n linked: TableColumnVariant[];\n derivedLabels: Record<string, string>;\n derivedTooltips: Record<string, string>;\n displayOptions?: ColumnsDisplayOptions;\n pframeSpec: PFrameSpecDriver;\n}): AnnotatedColumnGroups {\n const { direct, linked, derivedLabels, derivedTooltips, displayOptions, pframeSpec } = params;\n\n const allColumnsForRules = [\n ...direct.map((v) => v.column),\n ...linked.map((v) => v.column),\n ...collectLinkerSnapshots(linked),\n ];\n const visibilityByColId = evaluateRules(\n displayOptions?.visibility ?? [],\n allColumnsForRules,\n pframeSpec,\n );\n const orderByColId = evaluateRules(\n displayOptions?.ordering ?? [],\n allColumnsForRules,\n pframeSpec,\n );\n\n const directAnnotated = liftToVariantColumns(\n direct,\n flow(\n (cols) => withLabelAnnotations(derivedLabels, cols),\n (cols) => withInfoAnnotations(derivedTooltips, cols),\n (cols) => withTableVisualAnnotations(visibilityByColId, orderByColId, cols),\n ),\n );\n\n const linkedAnnotated = liftToVariantColumns(\n linked,\n flow(\n (cols) => withHidenAxesAnnotations(cols),\n (cols) => withLabelAnnotations(derivedLabels, cols),\n (cols) => withInfoAnnotations(derivedTooltips, cols),\n (cols) => withTableVisualAnnotations(visibilityByColId, orderByColId, cols),\n ),\n ).map((lc) => ({ ...lc, path: annotateLinkerPath(derivedLabels, lc.path) }));\n\n return {\n direct: directAnnotated,\n linked: linkedAnnotated,\n };\n}\n\n/** Lift a snapshot-array transform so it runs on the inner `column` of each variant. */\nfunction liftToVariantColumns<V extends { readonly column: ColumnSnapshot<DiscoveredPColumnId> }>(\n variants: V[],\n fn: (cols: ColumnSnapshot<DiscoveredPColumnId>[]) => ColumnSnapshot<DiscoveredPColumnId>[],\n): V[] {\n const cols = fn(variants.map((v) => v.column));\n if (cols.length !== variants.length)\n throw new Error(\n `liftToVariantColumns: fn must preserve array length (got ${cols.length}, expected ${variants.length})`,\n );\n return variants.map((v, i) => ({ ...v, column: cols[i] }));\n}\n\nfunction annotateLinkerPath(\n derivedLabels: Record<string, string>,\n path: TableColumnVariant[\"path\"],\n): TableColumnVariant[\"path\"] {\n if (path.length === 0) return path;\n const annotatedLinkers = withHidenAxesAnnotations(\n withLabelAnnotations(\n derivedLabels,\n path.map((s) => s.linker),\n ),\n );\n return path.map((s, i) => ({ ...s, linker: annotatedLinkers[i] }));\n}\n\n/** Build an index of all valid column IDs (axes + columns) for filter/sorting validation. */\nfunction createColumnValidationById(\n fullColumns: { readonly id: PObjectId; readonly spec: PColumnSpec }[],\n) {\n const axisIds = uniqueBy(\n fullColumns.flatMap((c) => c.spec.axesSpec.map(getAxisId)),\n (a) => canonicalizeJson<AxisId>(a),\n );\n\n const allIds: PTableColumnId[] = [\n ...axisIds.map((a) => ({ type: \"axis\", id: a }) satisfies PTableColumnIdAxis),\n ...fullColumns.map((c) => ({ type: \"column\", id: c.id }) satisfies PTableColumnIdColumn),\n ];\n\n const validIdSet = new Set(allIds.map((c) => canonicalizeJson<PTableColumnId>(c)));\n\n return (id: string): boolean => {\n return validIdSet.has(id as CanonicalizedJson<PTableColumnId>);\n };\n}\n\n/** Validate that all column references in filters exist in the table. */\nfunction validateFilters(\n filters: Nil | PlDataTableFilters,\n isValidColumnId: (id: string) => boolean,\n): void {\n if (filters == null) return;\n const filterColumns = collectFilterSpecColumns(filters);\n const firstInvalid = filterColumns.find((col) => !isValidColumnId(col));\n if (firstInvalid !== undefined) {\n throw new Error(\n `Invalid filter column ${firstInvalid}: column reference does not match the table columns`,\n );\n }\n}\n\n/** Merge two filter trees into one AND-combined tree. Returns the non-nil one if the other is nil. */\nfunction concatFilters(\n a: Nil | PlDataTableFilters,\n b: Nil | PlDataTableFilters,\n): Nil | PlDataTableFilters {\n if (isNil(a)) return b;\n if (isNil(b)) return a;\n return { ...a, filters: [...a.filters, ...b.filters] };\n}\n\n/** Pick user sorting from state if non-empty, otherwise fall back to options default. */\nfunction resolveSorting(\n userSorting: PTableSorting[],\n defaultSorting: Nil | PTableSorting[],\n): PTableSorting[] {\n return (isEmpty(userSorting) ? defaultSorting : userSorting) ?? [];\n}\n\n/** Validate that all column references in sorting exist in the table. */\nfunction validateSorting(sorting: PTableSorting[], isValidColumnId: (id: string) => boolean): void {\n const firstInvalid = sorting.find(\n (s) => !isValidColumnId(canonicalizeJson<PTableColumnId>(s.column)),\n );\n if (firstInvalid !== undefined) {\n throw new Error(\n `Invalid sorting column ${JSON.stringify(firstInvalid.column)}: column reference does not match the table columns`,\n );\n }\n}\n\nfunction buildSecondaryGroups(\n direct: TableColumnVariant[],\n linked: TableColumnVariant[],\n): SecondaryGroup<undefined | PColumnDataUniversal>[] {\n return [\n ...direct.map(\n (c): SecondaryGroup<undefined | PColumnDataUniversal> => ({\n entries: [{ column: resolveSnapshot(c.column), qualifications: c.qualifications.forHit }],\n primaryQualifications: c.qualifications.forQueries,\n }),\n ),\n ...linked.map(\n (lc): SecondaryGroup<undefined | PColumnDataUniversal> => ({\n entries: [\n ...lc.path.map((s) => ({\n column: resolveSnapshot(s.linker),\n qualifications: s.qualifications,\n })),\n { column: resolveSnapshot(lc.column), qualifications: lc.qualifications.forHit },\n ],\n primaryQualifications: lc.qualifications.forQueries,\n }),\n ),\n ];\n}\n\n/** Determine which columns should be hidden based on state or optional-column defaults. */\nfunction computeHiddenColumns(\n columns: { readonly id: PObjectId; readonly spec: PColumnSpec }[],\n sorting: Nil | PTableSorting[],\n filters: Nil | PlDataTableFilters,\n hiddenSpecs: Nil | PTableColumnId[],\n): Set<PObjectId> {\n const alwaysHidden = columns.filter((c) => isColumnHidden(c.spec)).map((c) => c.id);\n const optionalHidden = !isNil(hiddenSpecs)\n ? hiddenSpecs.filter((s): s is PTableColumnIdColumn => s.type === \"column\").map((s) => s.id)\n : columns.filter((c) => isColumnOptional(c.spec)).map((c) => c.id);\n const initial = [...alwaysHidden, ...optionalHidden];\n const preserved = collectPreservedColumnIds(sorting, filters);\n\n return new Set(initial.filter((id) => !preserved.has(id)));\n}\n\n/** Collect IDs of columns that must remain visible (sorted, filtered). */\nfunction collectPreservedColumnIds(\n sorting: Nil | PTableSorting[],\n filters: Nil | PlDataTableFilters,\n): Set<PObjectId> {\n const sortedIds = (sorting ?? [])\n .map((s) => s.column)\n .filter((c): c is PTableColumnIdColumn => c.type === \"column\")\n .map((c) => c.id);\n\n const filterIds = !isNil(filters)\n ? collectFilterSpecColumns(filters).flatMap((c) => {\n const obj = parseJson(c);\n return obj.type === \"column\" ? [obj.id] : [];\n })\n : [];\n\n return new Set<PObjectId>([...sortedIds, ...filterIds]);\n}\n\n/** Filter annotated columns to only visible ones, re-matching label columns for the visible subset. */\nfunction buildVisibleColumns(\n annotated: AnnotatedColumnGroups,\n hiddenColumns: Set<PObjectId>,\n): VisibleColumns {\n const direct = annotated.direct.filter((c) => !hiddenColumns.has(c.column.id));\n const linked = annotated.linked.filter((c) => !hiddenColumns.has(c.column.id));\n return { direct, linked };\n}\n\n/** Resolve a ColumnSnapshot to a PColumn with lazily-evaluated data. */\nfunction resolveSnapshot(\n snap: ColumnSnapshot<PObjectId>,\n): PColumn<undefined | PColumnDataUniversal> {\n return { id: snap.id, spec: snap.spec, data: snap.data?.get() };\n}\n\n/** Remap column references in sorting entries. */\nfunction remapSortingColumnIds(\n sorting: Nil | PTableSorting[],\n columns: TableColumnVariant[],\n): Nil | PTableSorting[] {\n return sorting?.map((s) => {\n if (s.column.type === \"axis\") return s; // Axis references are unaffected by column ID remapping\n\n const id = s.column.id;\n const column =\n columns.find((c) => (c.originalId ?? c.column.id) === id) ??\n throwError(`Column ID \"${id}\" in sorting does not match any discovered column`);\n\n return {\n ...s,\n column: {\n type: \"column\",\n id: column.column.id,\n },\n };\n });\n}\n\ntype PlDataTableFilterNode = FilterSpecNode<PlDataTableFilterSpecLeaf>;\n\n/** Remap column references in a filter tree. */\nfunction remapFilterColumnIds(\n filters: Nil | PlDataTableFilters,\n columns: TableColumnVariant[],\n): Nil | PlDataTableFilters {\n if (isNil(filters)) return filters;\n\n const map = (\n tableColumnId: CanonicalizedJson<PTableColumnId>,\n ): CanonicalizedJson<PTableColumnId> => {\n const parsed = parseJson<PTableColumnId>(tableColumnId);\n if (parsed.type === \"axis\") return tableColumnId; // Axis references are unaffected by column ID remapping\n\n const originalId = parsed.id;\n const column =\n columns.find((c) => (c.originalId ?? c.column.id) === originalId) ??\n throwError(`Column ID \"${parsed.id}\" in filters does not match any discovered column`);\n\n return canonicalizeJson<PTableColumnId>({\n type: \"column\",\n id: column.column.id,\n });\n };\n\n return traverseFilterSpec(filters, {\n leaf: (leaf): PlDataTableFilterNode => {\n if (leaf.type === undefined) return leaf;\n const result = { ...leaf };\n if (\"column\" in result) result.column = map(result.column);\n if (\"rhs\" in result) result.rhs = map(result.rhs);\n return result;\n },\n and: (results): PlDataTableFilterNode => ({ type: \"and\", filters: results }),\n or: (results): PlDataTableFilterNode => ({ type: \"or\", filters: results }),\n not: (result): PlDataTableFilterNode => ({ type: \"not\", filter: result }),\n }) as PlDataTableFilters;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"createPlDataTableV3.js","names":[],"sources":["../../../../src/components/PlDataTable/createPlDataTable/createPlDataTableV3.ts"],"sourcesContent":["import type {\n AxisId,\n CanonicalizedJson,\n FilterSpecNode,\n PColumn,\n PObjectId,\n PTableColumnId,\n PTableColumnIdAxis,\n PTableColumnIdColumn,\n PTableSorting,\n PColumnSpec,\n MultiColumnSelector,\n PFrameSpecDriver,\n DiscoveredPColumnId,\n} from \"@milaboratories/pl-model-common\";\nimport { canonicalizeJson, getAxisId, parseJson, uniqueBy } from \"@milaboratories/pl-model-common\";\nimport { collectFilterSpecColumns, traverseFilterSpec } from \"../../../filters/traverse\";\nimport type { RenderCtxBase, PColumnDataUniversal } from \"../../../render\";\nimport { isEmpty } from \"es-toolkit/compat\";\nimport type { PlDataTableFilters, PlDataTableFilterSpecLeaf, PlDataTableModel } from \"../typesV5\";\nimport { upgradePlDataTableStateV2 } from \"../state-migration\";\nimport type { PlDataTableStateV2 } from \"../state-migration\";\nimport type { ColumnSelector, ColumnSnapshot, ColumnVariant, MatchingMode } from \"../../../columns\";\nimport type { DeriveLabelsOptions } from \"../../../labels/derive_distinct_labels\";\nimport {\n deriveAllLabels,\n deriveAllTooltips,\n evaluateRules,\n isColumnHidden,\n isColumnOptional,\n withHidenAxesAnnotations,\n withLabelAnnotations,\n withTableVisualAnnotations,\n withInfoAnnotations,\n} from \"./utils\";\nimport type { PrimaryEntry, SecondaryGroup } from \"./createPTableDefV3\";\nimport { createPTableDefV3 } from \"./createPTableDefV3\";\nimport { discoverTableColumnSnaphots, type DiscoverTableColumnOptions } from \"./discoverColumns\";\nimport { isNil, isPlainObject, throwError, type Nil } from \"@milaboratories/helpers\";\nimport { flow } from \"es-toolkit\";\n\nexport type createPlDataTableOptionsV3 = {\n tableState?: PlDataTableStateV2;\n\n columns: Nil | DiscoverTableColumnOptions | TableColumnVariant[];\n filters?: PlDataTableFilters;\n sorting?: PTableSorting[];\n primaryJoinType?: \"inner\" | \"full\";\n\n labelsOptions?: DeriveLabelsOptions;\n displayOptions?: ColumnsDisplayOptions;\n};\n\n/** Structured source config — selectors/anchors instead of raw ColumnSource. */\nexport type ColumnsSelectorConfig = {\n include?: MultiColumnSelector | MultiColumnSelector[];\n exclude?: MultiColumnSelector | MultiColumnSelector[];\n mode?: MatchingMode;\n maxHops?: number;\n};\n\nexport type ColumnsDisplayOptions = {\n /** Column ordering rules. Higher priority = further left. First matching rule wins. */\n ordering?: ColumnOrderRule[];\n /** Column visibility rules. First matching rule wins. Unmatched columns use default visibility. */\n visibility?: ColumnVisibilityRule[];\n};\n\nexport type ColumnOrderRule = {\n match: ColumnMatcher | ColumnSelector;\n /** Higher number = further left in table */\n priority: number;\n};\n\nexport type ColumnVisibilityRule = {\n match: ColumnMatcher | ColumnSelector;\n visibility: \"default\" | \"optional\" | \"hidden\";\n};\n\nexport type ColumnMatcher = (spec: PColumnSpec) => boolean;\n\n// Main Function\n\nexport function createPlDataTableV3<A, U>(\n ctx: RenderCtxBase<A, U>,\n options: createPlDataTableOptionsV3,\n): PlDataTableModel | undefined {\n const pframeSpec = ctx.getService(\"pframeSpec\");\n const state = upgradePlDataTableStateV2(options.tableState);\n const primaryJoinType = options.primaryJoinType ?? \"full\";\n\n const discovered = isPlainObject(options.columns)\n ? discoverTableColumnSnaphots(ctx, options.columns)\n : options.columns;\n if (isNil(discovered) || discovered.length === 0) return undefined;\n\n const splited = splitDiscoveredColumns(discovered);\n\n const derivedLabels = deriveAllLabels({\n columns: discovered.map((dc) => ({\n id: dc.column.id,\n spec: dc.column.spec,\n linkerPath: dc.path,\n qualifications: dc.qualifications,\n })),\n deriveLabelsOptions: {\n includeNativeLabel: true,\n ...options.labelsOptions,\n },\n });\n\n const derivedTooltips = deriveAllTooltips({\n columns: discovered.map((dc) => ({\n id: dc.column.id,\n originalId: dc.originalId,\n spec: dc.column.spec,\n linkerPath: dc.path,\n qualifications: dc.qualifications,\n })),\n });\n\n const annotated = annotateColumnGroups({\n pframeSpec,\n ...splited,\n derivedLabels,\n derivedTooltips,\n displayOptions: options.displayOptions,\n });\n\n const primarySnapshots = annotated.direct.filter((c) => c.isPrimary);\n const secondarySnapshots = annotated.direct.filter((c) => !c.isPrimary);\n\n if (primarySnapshots.length === 0) return undefined;\n\n const columnIsAvailable = createColumnValidationById([\n ...annotated.direct.map((v) => v.column),\n ...annotated.linked.flatMap((lc) => [...lc.path.map((s) => s.linker), lc.column]),\n ]);\n\n const remapedDefaultFilters = remapFilterColumnIds(options.filters, discovered);\n const filters = concatFilters(\n state.pTableParams.filters,\n state.pTableParams.defaultFilters ?? remapedDefaultFilters,\n );\n validateFilters(filters, columnIsAvailable);\n\n const sorting = resolveSorting(\n state.pTableParams.sorting,\n remapSortingColumnIds(options.sorting, discovered),\n );\n validateSorting(sorting, columnIsAvailable);\n\n const primaryEntries: PrimaryEntry<undefined | PColumnDataUniversal>[] = primarySnapshots.map(\n (v) => ({ column: resolveSnapshot(v.column) }),\n );\n const secondaryGroups: SecondaryGroup<undefined | PColumnDataUniversal>[] = buildSecondaryGroups(\n secondarySnapshots,\n annotated.linked,\n );\n const fullDef = createPTableDefV3({\n primaryJoinType,\n primary: primaryEntries,\n secondary: secondaryGroups,\n filters,\n sorting,\n });\n\n const fullHandle = ctx.createPTableV2(fullDef);\n // TODO: is workaround for dropdown suggestions.\n // Pframe have not equivalent data for columns relativly to Ptable\n const pframeHandle = ctx.createPFrame([\n ...annotated.direct.map((v) => resolveSnapshot(v.column)),\n ...annotated.linked.map((v) => resolveSnapshot(v.column)),\n ...collectLinkerSnapshots(annotated.linked).map(resolveSnapshot),\n ]);\n\n const hiddenSpecs = state.pTableParams.hiddenColIds;\n const hiddenColumnIds = computeHiddenColumns(\n [...annotated.direct, ...annotated.linked].map((v) => v.column),\n sorting,\n filters,\n hiddenSpecs,\n );\n\n const visible = buildVisibleColumns(annotated, hiddenColumnIds);\n const visibleDef = createPTableDefV3({\n primaryJoinType,\n primary: primaryEntries,\n secondary: buildSecondaryGroups(\n visible.direct.filter((c) => !c.isPrimary),\n visible.linked,\n ),\n filters,\n sorting,\n });\n const visibleHandle = ctx.createPTableV2(visibleDef);\n\n return {\n sourceId: state.pTableParams.sourceId,\n fullTableHandle: fullHandle,\n fullPframeHandle: pframeHandle,\n visibleTableHandle: visibleHandle,\n defaultFilters: remapedDefaultFilters,\n } satisfies PlDataTableModel;\n}\n\nexport type TableColumnVariant = ColumnVariant<DiscoveredPColumnId> & {\n readonly originalId: PObjectId;\n readonly isPrimary?: boolean;\n};\n\ntype SplitDiscoveredColumns = {\n readonly direct: TableColumnVariant[];\n readonly linked: TableColumnVariant[];\n};\n\ntype AnnotatedColumnGroups = {\n readonly direct: TableColumnVariant[];\n readonly linked: TableColumnVariant[];\n};\n\ntype VisibleColumns = {\n readonly direct: TableColumnVariant[];\n readonly linked: TableColumnVariant[];\n};\n\n/** Split discovered columns into direct (no linker path) and linked (with linker path). */\nfunction splitDiscoveredColumns(columns: TableColumnVariant[]): SplitDiscoveredColumns {\n const direct = columns.filter((dc) => dc.path.length === 0);\n const linked = columns.filter((dc) => dc.path.length > 0);\n return { direct, linked };\n}\n\n/** All linker snapshots across the given linked columns, deduped by id. */\nfunction collectLinkerSnapshots(linked: TableColumnVariant[]): ColumnSnapshot<PObjectId>[] {\n return uniqueBy(\n linked.flatMap((lc) => lc.path.map((s) => s.linker)),\n (c) => c.id,\n );\n}\n\n/**\n * Annotate all column groups with derived labels and display-rule annotations.\n * Evaluates `displayOptions` rules against all discovered columns (direct,\n * linked, labels, linkers) and writes the winning visibility/priority into\n * column annotations via `withTableVisualAnnotations`.\n */\nfunction annotateColumnGroups(params: {\n direct: TableColumnVariant[];\n linked: TableColumnVariant[];\n derivedLabels: Record<string, string>;\n derivedTooltips: Record<string, string>;\n displayOptions?: ColumnsDisplayOptions;\n pframeSpec: PFrameSpecDriver;\n}): AnnotatedColumnGroups {\n const { direct, linked, derivedLabels, derivedTooltips, displayOptions, pframeSpec } = params;\n\n const allColumnsForRules = [\n ...direct.map((v) => v.column),\n ...linked.map((v) => v.column),\n ...collectLinkerSnapshots(linked),\n ];\n const visibilityByColId = evaluateRules(\n displayOptions?.visibility ?? [],\n allColumnsForRules,\n pframeSpec,\n );\n const orderByColId = evaluateRules(\n displayOptions?.ordering ?? [],\n allColumnsForRules,\n pframeSpec,\n );\n\n const directAnnotated = liftToVariantColumns(\n direct,\n flow(\n (cols) => withLabelAnnotations(derivedLabels, cols),\n (cols) => withInfoAnnotations(derivedTooltips, cols),\n (cols) => withTableVisualAnnotations(visibilityByColId, orderByColId, cols),\n ),\n );\n\n const linkedAnnotated = liftToVariantColumns(\n linked,\n flow(\n (cols) => withHidenAxesAnnotations(cols),\n (cols) => withLabelAnnotations(derivedLabels, cols),\n (cols) => withInfoAnnotations(derivedTooltips, cols),\n (cols) => withTableVisualAnnotations(visibilityByColId, orderByColId, cols),\n ),\n ).map((lc) => ({ ...lc, path: annotateLinkerPath(derivedLabels, lc.path) }));\n\n return {\n direct: directAnnotated,\n linked: linkedAnnotated,\n };\n}\n\n/** Lift a snapshot-array transform so it runs on the inner `column` of each variant. */\nfunction liftToVariantColumns<V extends { readonly column: ColumnSnapshot<DiscoveredPColumnId> }>(\n variants: V[],\n fn: (cols: ColumnSnapshot<DiscoveredPColumnId>[]) => ColumnSnapshot<DiscoveredPColumnId>[],\n): V[] {\n const cols = fn(variants.map((v) => v.column));\n if (cols.length !== variants.length)\n throw new Error(\n `liftToVariantColumns: fn must preserve array length (got ${cols.length}, expected ${variants.length})`,\n );\n return variants.map((v, i) => ({ ...v, column: cols[i] }));\n}\n\nfunction annotateLinkerPath(\n derivedLabels: Record<string, string>,\n path: TableColumnVariant[\"path\"],\n): TableColumnVariant[\"path\"] {\n if (path.length === 0) return path;\n const annotatedLinkers = withHidenAxesAnnotations(\n withLabelAnnotations(\n derivedLabels,\n path.map((s) => s.linker),\n ),\n );\n return path.map((s, i) => ({ ...s, linker: annotatedLinkers[i] }));\n}\n\n/** Build an index of all valid column IDs (axes + columns) for filter/sorting validation. */\nfunction createColumnValidationById(\n fullColumns: { readonly id: PObjectId; readonly spec: PColumnSpec }[],\n) {\n const axisIds = uniqueBy(\n fullColumns.flatMap((c) => c.spec.axesSpec.map(getAxisId)),\n (a) => canonicalizeJson<AxisId>(a),\n );\n\n const allIds: PTableColumnId[] = [\n ...axisIds.map((a) => ({ type: \"axis\", id: a }) satisfies PTableColumnIdAxis),\n ...fullColumns.map((c) => ({ type: \"column\", id: c.id }) satisfies PTableColumnIdColumn),\n ];\n\n const validIdSet = new Set(allIds.map((c) => canonicalizeJson<PTableColumnId>(c)));\n\n return (id: string): boolean => {\n return validIdSet.has(id as CanonicalizedJson<PTableColumnId>);\n };\n}\n\n/** Validate that all column references in filters exist in the table. */\nfunction validateFilters(\n filters: Nil | PlDataTableFilters,\n isValidColumnId: (id: string) => boolean,\n): void {\n if (filters == null) return;\n const filterColumns = collectFilterSpecColumns(filters);\n const firstInvalid = filterColumns.find((col) => !isValidColumnId(col));\n if (firstInvalid !== undefined) {\n throw new Error(\n `Invalid filter column ${firstInvalid}: column reference does not match the table columns`,\n );\n }\n}\n\n/** Merge two filter trees into one AND-combined tree. Returns the non-nil one if the other is nil. */\nfunction concatFilters(\n a: Nil | PlDataTableFilters,\n b: Nil | PlDataTableFilters,\n): Nil | PlDataTableFilters {\n if (isNil(a)) return b;\n if (isNil(b)) return a;\n return { ...a, filters: [...a.filters, ...b.filters] };\n}\n\n/** Pick user sorting from state if non-empty, otherwise fall back to options default. */\nfunction resolveSorting(\n userSorting: PTableSorting[],\n defaultSorting: Nil | PTableSorting[],\n): PTableSorting[] {\n return (isEmpty(userSorting) ? defaultSorting : userSorting) ?? [];\n}\n\n/** Validate that all column references in sorting exist in the table. */\nfunction validateSorting(sorting: PTableSorting[], isValidColumnId: (id: string) => boolean): void {\n const firstInvalid = sorting.find(\n (s) => !isValidColumnId(canonicalizeJson<PTableColumnId>(s.column)),\n );\n if (firstInvalid !== undefined) {\n throw new Error(\n `Invalid sorting column ${JSON.stringify(firstInvalid.column)}: column reference does not match the table columns`,\n );\n }\n}\n\nfunction buildSecondaryGroups(\n direct: TableColumnVariant[],\n linked: TableColumnVariant[],\n): SecondaryGroup<undefined | PColumnDataUniversal>[] {\n return [\n ...direct.map(\n (c): SecondaryGroup<undefined | PColumnDataUniversal> => ({\n entries: [{ column: resolveSnapshot(c.column), qualifications: c.qualifications.forHit }],\n primaryQualifications: c.qualifications.forQueries,\n }),\n ),\n ...linked.map(\n (lc): SecondaryGroup<undefined | PColumnDataUniversal> => ({\n entries: [\n ...lc.path.map((s) => ({\n column: resolveSnapshot(s.linker),\n })),\n { column: resolveSnapshot(lc.column), qualifications: lc.qualifications.forHit },\n ],\n primaryQualifications: lc.qualifications.forQueries,\n }),\n ),\n ];\n}\n\n/** Determine which columns should be hidden based on state or optional-column defaults. */\nfunction computeHiddenColumns(\n columns: { readonly id: PObjectId; readonly spec: PColumnSpec }[],\n sorting: Nil | PTableSorting[],\n filters: Nil | PlDataTableFilters,\n hiddenSpecs: Nil | PTableColumnId[],\n): Set<PObjectId> {\n const alwaysHidden = columns.filter((c) => isColumnHidden(c.spec)).map((c) => c.id);\n const optionalHidden = !isNil(hiddenSpecs)\n ? hiddenSpecs.filter((s): s is PTableColumnIdColumn => s.type === \"column\").map((s) => s.id)\n : columns.filter((c) => isColumnOptional(c.spec)).map((c) => c.id);\n const initial = [...alwaysHidden, ...optionalHidden];\n const preserved = collectPreservedColumnIds(sorting, filters);\n\n return new Set(initial.filter((id) => !preserved.has(id)));\n}\n\n/** Collect IDs of columns that must remain visible (sorted, filtered). */\nfunction collectPreservedColumnIds(\n sorting: Nil | PTableSorting[],\n filters: Nil | PlDataTableFilters,\n): Set<PObjectId> {\n const sortedIds = (sorting ?? [])\n .map((s) => s.column)\n .filter((c): c is PTableColumnIdColumn => c.type === \"column\")\n .map((c) => c.id);\n\n const filterIds = !isNil(filters)\n ? collectFilterSpecColumns(filters).flatMap((c) => {\n const obj = parseJson(c);\n return obj.type === \"column\" ? [obj.id] : [];\n })\n : [];\n\n return new Set<PObjectId>([...sortedIds, ...filterIds]);\n}\n\n/** Filter annotated columns to only visible ones, re-matching label columns for the visible subset. */\nfunction buildVisibleColumns(\n annotated: AnnotatedColumnGroups,\n hiddenColumns: Set<PObjectId>,\n): VisibleColumns {\n const direct = annotated.direct.filter((c) => !hiddenColumns.has(c.column.id));\n const linked = annotated.linked.filter((c) => !hiddenColumns.has(c.column.id));\n return { direct, linked };\n}\n\n/** Resolve a ColumnSnapshot to a PColumn with lazily-evaluated data. */\nfunction resolveSnapshot(\n snap: ColumnSnapshot<PObjectId>,\n): PColumn<undefined | PColumnDataUniversal> {\n return { id: snap.id, spec: snap.spec, data: snap.data?.get() };\n}\n\n/** Remap column references in sorting entries. */\nfunction remapSortingColumnIds(\n sorting: Nil | PTableSorting[],\n columns: TableColumnVariant[],\n): Nil | PTableSorting[] {\n return sorting?.map((s) => {\n if (s.column.type === \"axis\") return s; // Axis references are unaffected by column ID remapping\n\n const id = s.column.id;\n const column =\n columns.find((c) => (c.originalId ?? c.column.id) === id) ??\n throwError(`Column ID \"${id}\" in sorting does not match any discovered column`);\n\n return {\n ...s,\n column: {\n type: \"column\",\n id: column.column.id,\n },\n };\n });\n}\n\ntype PlDataTableFilterNode = FilterSpecNode<PlDataTableFilterSpecLeaf>;\n\n/** Remap column references in a filter tree. */\nfunction remapFilterColumnIds(\n filters: Nil | PlDataTableFilters,\n columns: TableColumnVariant[],\n): Nil | PlDataTableFilters {\n if (isNil(filters)) return filters;\n\n const map = (\n tableColumnId: CanonicalizedJson<PTableColumnId>,\n ): CanonicalizedJson<PTableColumnId> => {\n const parsed = parseJson<PTableColumnId>(tableColumnId);\n if (parsed.type === \"axis\") return tableColumnId; // Axis references are unaffected by column ID remapping\n\n const originalId = parsed.id;\n const column =\n columns.find((c) => (c.originalId ?? c.column.id) === originalId) ??\n throwError(`Column ID \"${parsed.id}\" in filters does not match any discovered column`);\n\n return canonicalizeJson<PTableColumnId>({\n type: \"column\",\n id: column.column.id,\n });\n };\n\n return traverseFilterSpec(filters, {\n leaf: (leaf): PlDataTableFilterNode => {\n if (leaf.type === undefined) return leaf;\n const result = { ...leaf };\n if (\"column\" in result) result.column = map(result.column);\n if (\"rhs\" in result) result.rhs = map(result.rhs);\n return result;\n },\n and: (results): PlDataTableFilterNode => ({ type: \"and\", filters: results }),\n or: (results): PlDataTableFilterNode => ({ type: \"or\", filters: results }),\n not: (result): PlDataTableFilterNode => ({ type: \"not\", filter: result }),\n }) as PlDataTableFilters;\n}\n"],"mappings":"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"}
@@ -45,8 +45,7 @@ function mapToTableColumnVariants(variants, anchors) {
45
45
  column: snap.id,
46
46
  path: variant.path.map((p) => ({
47
47
  type: "linker",
48
- column: p.linker.id,
49
- qualifications: p.qualifications
48
+ column: p.linker.id
50
49
  })),
51
50
  columnQualifications: variant.qualifications.forHit,
52
51
  queriesQualifications: variant.qualifications.forQueries
@@ -1 +1 @@
1
- {"version":3,"file":"discoverColumns.cjs","names":["ColumnCollectionBuilder","toColumnSnapshotProvider","collectCtxColumnSnapshotProviders"],"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 qualifications: p.qualifications,\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,SAAS,eAAe,KAAK,QAAQ,QAAQ;EAC9C;CAGD,MAAM,YAAY,iBAAiB,KAAK,gBAAgB,QAAQ;AAChE,KAAI,UAAU,WAAW,EAAG,QAAO,KAAA;CAGnC,MAAM,aAAa,IAAIA,kCAAAA,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,SAAS,eACP,KACA,SACiE;CACjE,MAAM,SAA0E,EAAE;AAClF,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,QAAQ,CAChD,MAAA,GAAA,gCAAA,SAAY,MAAM,CAChB,QAAO,OACL,IAAI,WAAW,oBAAoB,MAAM,KAAA,GAAA,wBAAA,YAEvC,UAAU,IAAI,YAAY,KAAK,UAAU,MAAM,CAAC,yCACjD;KAEH,QAAO,OAAO;AAGlB,QAAO;;;AAIT,SAAS,iBACP,KACA,SAC0B;AAC1B,QAAO,YAAY,KAAA,IACf,QAAQ,IAAIC,iCAAAA,yBAAyB,GACrCC,2BAAAA,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;AAYxD,SAAO;GACL,QAAQ;IACN,KAAA,GAAA,gCAAA,2BAZ2C;KAC7C,QAAQ,KAAK;KACb,MAAM,QAAQ,KAAK,KAAK,OAAO;MAC7B,MAAM;MACN,QAAQ,EAAE,OAAO;MACjB,gBAAgB,EAAE;MACnB,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"}
1
+ {"version":3,"file":"discoverColumns.cjs","names":["ColumnCollectionBuilder","toColumnSnapshotProvider","collectCtxColumnSnapshotProviders"],"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,SAAS,eAAe,KAAK,QAAQ,QAAQ;EAC9C;CAGD,MAAM,YAAY,iBAAiB,KAAK,gBAAgB,QAAQ;AAChE,KAAI,UAAU,WAAW,EAAG,QAAO,KAAA;CAGnC,MAAM,aAAa,IAAIA,kCAAAA,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,SAAS,eACP,KACA,SACiE;CACjE,MAAM,SAA0E,EAAE;AAClF,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,QAAQ,CAChD,MAAA,GAAA,gCAAA,SAAY,MAAM,CAChB,QAAO,OACL,IAAI,WAAW,oBAAoB,MAAM,KAAA,GAAA,wBAAA,YAEvC,UAAU,IAAI,YAAY,KAAK,UAAU,MAAM,CAAC,yCACjD;KAEH,QAAO,OAAO;AAGlB,QAAO;;;AAIT,SAAS,iBACP,KACA,SAC0B;AAC1B,QAAO,YAAY,KAAA,IACf,QAAQ,IAAIC,iCAAAA,yBAAyB,GACrCC,2BAAAA,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,KAAA,GAAA,gCAAA,2BAX2C;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"}
@@ -44,8 +44,7 @@ function mapToTableColumnVariants(variants, anchors) {
44
44
  column: snap.id,
45
45
  path: variant.path.map((p) => ({
46
46
  type: "linker",
47
- column: p.linker.id,
48
- qualifications: p.qualifications
47
+ column: p.linker.id
49
48
  })),
50
49
  columnQualifications: variant.qualifications.forHit,
51
50
  queriesQualifications: variant.qualifications.forQueries
@@ -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 qualifications: p.qualifications,\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;AAYxD,SAAO;GACL,QAAQ;IACN,IAZiB,0BAA0B;KAC7C,QAAQ,KAAK;KACb,MAAM,QAAQ,KAAK,KAAK,OAAO;MAC7B,MAAM;MACN,QAAQ,EAAE,OAAO;MACjB,gBAAgB,EAAE;MACnB,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"}
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"}
@@ -170,10 +170,7 @@ function deriveAllLabels(options) {
170
170
  const { columns, deriveLabelsOptions } = options;
171
171
  return require_derive_distinct_labels.deriveDistinctLabels(columns.map((c) => ({
172
172
  spec: c.spec,
173
- linkerPath: c.linkerPath?.map((step) => ({
174
- spec: step.linker.spec,
175
- qualifications: step.qualifications
176
- })),
173
+ linkerPath: c.linkerPath?.map((step) => ({ spec: step.linker.spec })),
177
174
  qualifications: c.qualifications
178
175
  })), deriveLabelsOptions).reduce((acc, label, index) => (acc[columns[index].id] = label, acc), {});
179
176
  }
@@ -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 { 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 })),\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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"}
@@ -169,10 +169,7 @@ function deriveAllLabels(options) {
169
169
  const { columns, deriveLabelsOptions } = options;
170
170
  return deriveDistinctLabels(columns.map((c) => ({
171
171
  spec: c.spec,
172
- linkerPath: c.linkerPath?.map((step) => ({
173
- spec: step.linker.spec,
174
- qualifications: step.qualifications
175
- })),
172
+ linkerPath: c.linkerPath?.map((step) => ({ spec: step.linker.spec })),
176
173
  qualifications: c.qualifications
177
174
  })), deriveLabelsOptions).reduce((acc, label, index) => (acc[columns[index].id] = label, acc), {});
178
175
  }
@@ -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 { 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 })),\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 predicate = opts?.selector ?? (() => true);
13
- const options = ctx.resultPool.getOptions(predicate, { refsWithEnrichments: true });
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((o) => {
19
- const datasetSpec = ctx.resultPool.getPColumnSpecByRef(o.ref);
20
- if (!datasetSpec) return o;
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 o;
28
+ if (!collection) return { primary };
25
29
  try {
26
- const matches = require_filter_discovery.findFilterColumns(collection);
27
- if (matches.length === 0) return o;
28
- const filters = require_filter_discovery.filterMatchesToOptions(matches, refMap, opts?.labelOptions);
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
- ...o,
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 {\n DatasetOption,\n Option,\n PColumnSelector,\n PObjectSpec,\n} from \"@milaboratories/pl-model-common\";\nimport type { DeriveLabelsOptions } from \"../../labels/derive_distinct_labels\";\nimport type { RenderCtxBase } from \"../../render\";\nimport { ColumnCollectionBuilder } from \"../../columns/column_collection_builder\";\nimport { collectCtxColumnSnapshotProviders } from \"../../columns/ctx_column_sources\";\nimport { buildRefMap, filterMatchesToOptions, findFilterColumns } from \"./filter_discovery\";\n\nexport type BuildDatasetOptions = {\n /** Which result pool columns qualify as datasets. Defaults to all. */\n selector?: PColumnSelector | PColumnSelector[] | ((spec: PObjectSpec) => boolean);\n /** Formatting options for filter labels. */\n labelOptions?: DeriveLabelsOptions;\n};\n\n/**\n * Usage:\n * ```ts\n * .output(\"datasetOptions\", (ctx) => buildDatasetOptions(ctx))\n * ```\n */\nexport function buildDatasetOptions(\n ctx: RenderCtxBase,\n opts?: BuildDatasetOptions,\n): DatasetOption[] | undefined {\n const predicate = opts?.selector ?? (() => true);\n const options = ctx.resultPool.getOptions(predicate, { refsWithEnrichments: true });\n if (options.length === 0) return [];\n\n const columnSources = collectCtxColumnSnapshotProviders(ctx);\n const refMap = buildRefMap(ctx.resultPool.getSpecs().entries);\n const pframeSpec = ctx.getService(\"pframeSpec\");\n\n return options.map((o: Option): DatasetOption => {\n const datasetSpec = ctx.resultPool.getPColumnSpecByRef(o.ref);\n if (!datasetSpec) return o;\n\n const builder = new ColumnCollectionBuilder(pframeSpec);\n for (const src of columnSources) builder.addSource(src);\n const collection = builder.build({ anchors: { main: datasetSpec } });\n if (!collection) return o;\n\n try {\n const matches = findFilterColumns(collection);\n if (matches.length === 0) return o;\n const filters = filterMatchesToOptions(matches, refMap, opts?.labelOptions);\n return { ...o, filters };\n } finally {\n collection.dispose();\n }\n });\n}\n"],"mappings":";;;;;;;;;;AAyBA,SAAgB,oBACd,KACA,MAC6B;CAC7B,MAAM,YAAY,MAAM,mBAAmB;CAC3C,MAAM,UAAU,IAAI,WAAW,WAAW,WAAW,EAAE,qBAAqB,MAAM,CAAC;AACnF,KAAI,QAAQ,WAAW,EAAG,QAAO,EAAE;CAEnC,MAAM,gBAAgBA,2BAAAA,kCAAkC,IAAI;CAC5D,MAAM,SAASC,yBAAAA,YAAY,IAAI,WAAW,UAAU,CAAC,QAAQ;CAC7D,MAAM,aAAa,IAAI,WAAW,aAAa;AAE/C,QAAO,QAAQ,KAAK,MAA6B;EAC/C,MAAM,cAAc,IAAI,WAAW,oBAAoB,EAAE,IAAI;AAC7D,MAAI,CAAC,YAAa,QAAO;EAEzB,MAAM,UAAU,IAAIC,kCAAAA,wBAAwB,WAAW;AACvD,OAAK,MAAM,OAAO,cAAe,SAAQ,UAAU,IAAI;EACvD,MAAM,aAAa,QAAQ,MAAM,EAAE,SAAS,EAAE,MAAM,aAAa,EAAE,CAAC;AACpE,MAAI,CAAC,WAAY,QAAO;AAExB,MAAI;GACF,MAAM,UAAUC,yBAAAA,kBAAkB,WAAW;AAC7C,OAAI,QAAQ,WAAW,EAAG,QAAO;GACjC,MAAM,UAAUC,yBAAAA,uBAAuB,SAAS,QAAQ,MAAM,aAAa;AAC3E,UAAO;IAAE,GAAG;IAAG;IAAS;YAChB;AACR,cAAW,SAAS;;GAEtB"}
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, PColumnSelector, PObjectSpec } from "@milaboratories/pl-model-common";
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. */selector?: PColumnSelector | PColumnSelector[] | ((spec: PObjectSpec) => boolean); /** Formatting options for filter labels. */
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":";;;;;KAYY,mBAAA;wEAEV,QAAA,GAAW,eAAA,GAAkB,eAAA,OAAsB,IAAA,EAAM,WAAA,eAF/C;EAIV,YAAA,GAAe,mBAAA;AAAA;;;;;;;iBASD,mBAAA,CACd,GAAA,EAAK,aAAA,EACL,IAAA,GAAO,mBAAA,GACN,aAAA"}
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 predicate = opts?.selector ?? (() => true);
13
- const options = ctx.resultPool.getOptions(predicate, { refsWithEnrichments: true });
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((o) => {
19
- const datasetSpec = ctx.resultPool.getPColumnSpecByRef(o.ref);
20
- if (!datasetSpec) return o;
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 o;
27
+ if (!collection) return { primary };
25
28
  try {
26
- const matches = findFilterColumns(collection);
27
- if (matches.length === 0) return o;
28
- const filters = filterMatchesToOptions(matches, refMap, opts?.labelOptions);
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
- ...o,
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 {\n DatasetOption,\n Option,\n PColumnSelector,\n PObjectSpec,\n} from \"@milaboratories/pl-model-common\";\nimport type { DeriveLabelsOptions } from \"../../labels/derive_distinct_labels\";\nimport type { RenderCtxBase } from \"../../render\";\nimport { ColumnCollectionBuilder } from \"../../columns/column_collection_builder\";\nimport { collectCtxColumnSnapshotProviders } from \"../../columns/ctx_column_sources\";\nimport { buildRefMap, filterMatchesToOptions, findFilterColumns } from \"./filter_discovery\";\n\nexport type BuildDatasetOptions = {\n /** Which result pool columns qualify as datasets. Defaults to all. */\n selector?: PColumnSelector | PColumnSelector[] | ((spec: PObjectSpec) => boolean);\n /** Formatting options for filter labels. */\n labelOptions?: DeriveLabelsOptions;\n};\n\n/**\n * Usage:\n * ```ts\n * .output(\"datasetOptions\", (ctx) => buildDatasetOptions(ctx))\n * ```\n */\nexport function buildDatasetOptions(\n ctx: RenderCtxBase,\n opts?: BuildDatasetOptions,\n): DatasetOption[] | undefined {\n const predicate = opts?.selector ?? (() => true);\n const options = ctx.resultPool.getOptions(predicate, { refsWithEnrichments: true });\n if (options.length === 0) return [];\n\n const columnSources = collectCtxColumnSnapshotProviders(ctx);\n const refMap = buildRefMap(ctx.resultPool.getSpecs().entries);\n const pframeSpec = ctx.getService(\"pframeSpec\");\n\n return options.map((o: Option): DatasetOption => {\n const datasetSpec = ctx.resultPool.getPColumnSpecByRef(o.ref);\n if (!datasetSpec) return o;\n\n const builder = new ColumnCollectionBuilder(pframeSpec);\n for (const src of columnSources) builder.addSource(src);\n const collection = builder.build({ anchors: { main: datasetSpec } });\n if (!collection) return o;\n\n try {\n const matches = findFilterColumns(collection);\n if (matches.length === 0) return o;\n const filters = filterMatchesToOptions(matches, refMap, opts?.labelOptions);\n return { ...o, filters };\n } finally {\n collection.dispose();\n }\n });\n}\n"],"mappings":";;;;;;;;;;AAyBA,SAAgB,oBACd,KACA,MAC6B;CAC7B,MAAM,YAAY,MAAM,mBAAmB;CAC3C,MAAM,UAAU,IAAI,WAAW,WAAW,WAAW,EAAE,qBAAqB,MAAM,CAAC;AACnF,KAAI,QAAQ,WAAW,EAAG,QAAO,EAAE;CAEnC,MAAM,gBAAgB,kCAAkC,IAAI;CAC5D,MAAM,SAAS,YAAY,IAAI,WAAW,UAAU,CAAC,QAAQ;CAC7D,MAAM,aAAa,IAAI,WAAW,aAAa;AAE/C,QAAO,QAAQ,KAAK,MAA6B;EAC/C,MAAM,cAAc,IAAI,WAAW,oBAAoB,EAAE,IAAI;AAC7D,MAAI,CAAC,YAAa,QAAO;EAEzB,MAAM,UAAU,IAAI,wBAAwB,WAAW;AACvD,OAAK,MAAM,OAAO,cAAe,SAAQ,UAAU,IAAI;EACvD,MAAM,aAAa,QAAQ,MAAM,EAAE,SAAS,EAAE,MAAM,aAAa,EAAE,CAAC;AACpE,MAAI,CAAC,WAAY,QAAO;AAExB,MAAI;GACF,MAAM,UAAU,kBAAkB,WAAW;AAC7C,OAAI,QAAQ,WAAW,EAAG,QAAO;GACjC,MAAM,UAAU,uBAAuB,SAAS,QAAQ,MAAM,aAAa;AAC3E,UAAO;IAAE,GAAG;IAAG;IAAS;YAChB;AACR,cAAW,SAAS;;GAEtB"}
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"}