@platforma-sdk/model 1.76.4 → 1.77.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 (62) hide show
  1. package/dist/columns/column_collection_builder.cjs +6 -3
  2. package/dist/columns/column_collection_builder.cjs.map +1 -1
  3. package/dist/columns/column_collection_builder.js +6 -3
  4. package/dist/columns/column_collection_builder.js.map +1 -1
  5. package/dist/components/PlDataTable/createPlDataTable/createPTableDefV2.cjs.map +1 -1
  6. package/dist/components/PlDataTable/createPlDataTable/createPTableDefV2.js.map +1 -1
  7. package/dist/components/PlDataTable/createPlDataTable/createPTableDefV3.cjs.map +1 -1
  8. package/dist/components/PlDataTable/createPlDataTable/createPTableDefV3.js.map +1 -1
  9. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV2.cjs.map +1 -1
  10. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV2.d.ts +1 -1
  11. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV2.js.map +1 -1
  12. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.cjs.map +1 -1
  13. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.d.ts +1 -1
  14. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.js.map +1 -1
  15. package/dist/components/PlDataTable/createPlDataTable/index.cjs.map +1 -1
  16. package/dist/components/PlDataTable/createPlDataTable/index.js.map +1 -1
  17. package/dist/components/PlDataTable/createPlDataTableSheet.cjs.map +1 -1
  18. package/dist/components/PlDataTable/createPlDataTableSheet.d.ts +1 -1
  19. package/dist/components/PlDataTable/createPlDataTableSheet.js.map +1 -1
  20. package/dist/components/PlDataTable/index.d.ts +1 -1
  21. package/dist/components/PlDataTable/state-migration.cjs +32 -1
  22. package/dist/components/PlDataTable/state-migration.cjs.map +1 -1
  23. package/dist/components/PlDataTable/state-migration.d.ts +4 -3
  24. package/dist/components/PlDataTable/state-migration.d.ts.map +1 -1
  25. package/dist/components/PlDataTable/state-migration.js +33 -2
  26. package/dist/components/PlDataTable/state-migration.js.map +1 -1
  27. package/dist/components/PlDataTable/typesV6.d.ts +26 -84
  28. package/dist/components/PlDataTable/typesV6.d.ts.map +1 -1
  29. package/dist/components/PlDataTable/typesV7.d.ts +98 -0
  30. package/dist/components/PlDataTable/typesV7.d.ts.map +1 -0
  31. package/dist/components/PlDatasetSelector/build_dataset_options.cjs +5 -1
  32. package/dist/components/PlDatasetSelector/build_dataset_options.cjs.map +1 -1
  33. package/dist/components/PlDatasetSelector/build_dataset_options.d.ts +6 -1
  34. package/dist/components/PlDatasetSelector/build_dataset_options.d.ts.map +1 -1
  35. package/dist/components/PlDatasetSelector/build_dataset_options.js +5 -1
  36. package/dist/components/PlDatasetSelector/build_dataset_options.js.map +1 -1
  37. package/dist/components/PlDatasetSelector/filter_discovery.cjs +21 -30
  38. package/dist/components/PlDatasetSelector/filter_discovery.cjs.map +1 -1
  39. package/dist/components/PlDatasetSelector/filter_discovery.d.ts +20 -20
  40. package/dist/components/PlDatasetSelector/filter_discovery.d.ts.map +1 -1
  41. package/dist/components/PlDatasetSelector/filter_discovery.js +21 -30
  42. package/dist/components/PlDatasetSelector/filter_discovery.js.map +1 -1
  43. package/dist/components/PlDatasetSelector/index.d.ts +1 -1
  44. package/dist/components/index.d.ts +2 -2
  45. package/dist/index.d.ts +3 -3
  46. package/dist/package.cjs +1 -1
  47. package/dist/package.js +1 -1
  48. package/package.json +5 -5
  49. package/src/columns/column_collection_builder.ts +12 -3
  50. package/src/components/PlDataTable/createPlDataTable/createPTableDefV2.ts +1 -1
  51. package/src/components/PlDataTable/createPlDataTable/createPTableDefV3.ts +1 -1
  52. package/src/components/PlDataTable/createPlDataTable/createPlDataTableV2.ts +1 -1
  53. package/src/components/PlDataTable/createPlDataTable/createPlDataTableV3.ts +1 -1
  54. package/src/components/PlDataTable/createPlDataTable/index.ts +1 -1
  55. package/src/components/PlDataTable/createPlDataTableSheet.ts +1 -1
  56. package/src/components/PlDataTable/index.ts +1 -1
  57. package/src/components/PlDataTable/state-migration.ts +71 -13
  58. package/src/components/PlDataTable/typesV6.ts +16 -138
  59. package/src/components/PlDataTable/typesV7.ts +151 -0
  60. package/src/components/PlDatasetSelector/build_dataset_options.ts +10 -2
  61. package/src/components/PlDatasetSelector/filter_discovery.test.ts +116 -19
  62. package/src/components/PlDatasetSelector/filter_discovery.ts +46 -39
@@ -1 +1 @@
1
- {"version":3,"file":"state-migration.js","names":[],"sources":["../../../src/components/PlDataTable/state-migration.ts"],"sourcesContent":["import type {\n AxisId,\n CanonicalizedJson,\n PObjectId,\n PTableColumnId,\n PTableColumnSpec,\n PTableRecordFilter,\n PTableSorting,\n} from \"@milaboratories/pl-model-common\";\nimport { canonicalizeJson, parseJsonSafely } from \"@milaboratories/pl-model-common\";\nimport { distillFilterSpec } from \"../../filters\";\nimport type { PlDataTableFilterState, PlTableFilter } from \"./typesV4\";\nimport type {\n PlDataTableFiltersWithMeta,\n PlDataTableGridStateCore,\n PlDataTableSheetState,\n PlDataTableStateV2CacheEntry,\n PlDataTableStateV2Normalized,\n PTableParamsV2,\n} from \"./typesV6\";\nimport type {\n PlDataTableGridStateV5,\n PlDataTableV5ColIdJson,\n PlDataTableV5ColIdWrapper,\n} from \"./typesV5\";\nimport { isNil } from \"es-toolkit\";\n\n/**\n * PlDataTableV2 persisted state\n */\nexport type PlDataTableStateV2 =\n // Old versions of the state\n | {\n // no version\n gridState: {\n columnOrder?: {\n orderedColIds: CanonicalizedJson<PTableColumnSpec>[];\n };\n sort?: {\n sortModel: {\n colId: CanonicalizedJson<PTableColumnSpec>;\n sort: \"asc\" | \"desc\";\n }[];\n };\n columnVisibility?: {\n hiddenColIds: CanonicalizedJson<PTableColumnSpec>[];\n };\n sourceId?: string;\n sheets?: Record<CanonicalizedJson<AxisId>, string | number>;\n };\n pTableParams?: {\n sorting?: PTableSorting[];\n filters?: PTableRecordFilter[];\n };\n }\n | {\n version: 2;\n stateCache: {\n sourceId: string;\n gridState: {\n columnOrder?: {\n orderedColIds: CanonicalizedJson<PTableColumnSpec>[];\n };\n sort?: {\n sortModel: {\n colId: CanonicalizedJson<PTableColumnSpec>;\n sort: \"asc\" | \"desc\";\n }[];\n };\n columnVisibility?: {\n hiddenColIds: CanonicalizedJson<PTableColumnSpec>[];\n };\n };\n sheetsState: PlDataTableSheetState[];\n }[];\n pTableParams: {\n hiddenColIds: PObjectId[] | null;\n filters: PTableRecordFilter[];\n sorting: PTableSorting[];\n };\n }\n | {\n version: 3;\n stateCache: {\n sourceId: string;\n gridState: {\n columnOrder?: {\n orderedColIds: CanonicalizedJson<PTableColumnSpec>[];\n };\n sort?: {\n sortModel: {\n colId: CanonicalizedJson<PTableColumnSpec>;\n sort: \"asc\" | \"desc\";\n }[];\n };\n columnVisibility?: {\n hiddenColIds: CanonicalizedJson<PTableColumnSpec>[];\n };\n };\n sheetsState: PlDataTableSheetState[];\n filtersState: PlDataTableFilterState[];\n }[];\n pTableParams: PTableParamsV2;\n }\n | {\n version: 4;\n stateCache: {\n sourceId: string;\n gridState: PlDataTableGridStateCore;\n sheetsState: PlDataTableSheetState[];\n filtersState: PlDataTableFilterState[];\n }[];\n /** Old format; only fields used in migration are typed */\n pTableParams: {\n sourceId: string | null;\n hiddenColIds: PObjectId[] | null;\n sorting: PTableSorting[];\n };\n }\n // v5 stored colIds as `{source, labeled}` wrappers; only the gridState shape differs.\n | {\n version: 5;\n stateCache: {\n sourceId: string;\n gridState: PlDataTableGridStateV5;\n sheetsState: PlDataTableSheetState[];\n filtersState: null | PlDataTableFiltersWithMeta;\n defaultFiltersState: null | PlDataTableFiltersWithMeta;\n searchString?: string;\n }[];\n pTableParams: PTableParamsV2;\n }\n // Normalized state\n | PlDataTableStateV2Normalized;\n\n/** Upgrade PlDataTableStateV2 to the latest version */\nexport function upgradePlDataTableStateV2(\n state: PlDataTableStateV2 | undefined,\n): PlDataTableStateV2Normalized {\n // Block just added, had no state, model started earlier than the UI\n if (!state) {\n return createPlDataTableStateV2();\n }\n // v1 -> v2\n if (!(\"version\" in state)) {\n // Non upgradeable as sourceId calculation algorithm has changed, resetting state to default\n state = createPlDataTableStateV2();\n }\n // v2 -> v3\n if (state.version === 2) {\n state = {\n version: 3,\n stateCache: state.stateCache.map((entry) => ({\n ...entry,\n filtersState: [],\n })),\n pTableParams: createDefaultPTableParams(),\n };\n }\n // v3 -> v4\n if (state.version === 3) {\n // Non upgradeable as column ids calculation algorithm has changed, resetting state to default\n state = createPlDataTableStateV2();\n }\n // v4 -> v6: migrate per-column filters to tree-based format (skips v5).\n // v4 gridState already used bare PTableColumnSpec colIds, so we jump\n // straight to v6 without going through the v5 wrapper format.\n if (state.version === 4) {\n state = migrateV4toV6(state);\n }\n // v5 -> v6: unwrap `{source, labeled}` colIds in gridState back to bare PTableColumnSpec.\n if (state.version === 5) {\n state = migrateV5toV6(state);\n }\n return state;\n}\n\n/** Migrate v5 to v6: unwrap `{source, labeled}` colIds in gridState. */\nfunction migrateV5toV6(\n state: Extract<PlDataTableStateV2, { version: 5 }>,\n): PlDataTableStateV2Normalized {\n // pTableParams reset: v5 stored DiscoveredPColumnId-based hiddenColIds with\n // empty-array fields (e.g. `{column, path: [], columnQualifications: [], ...}`).\n // v6 distills empty fields, so the same logical column serialises differently\n // and lookups would silently miss every previously-hidden discovered column.\n // gridState colIds are derived from PTableColumnSpec and unaffected.\n return {\n version: 6,\n stateCache: state.stateCache.map((entry) => ({\n ...entry,\n gridState: unwrapV5GridState(entry.gridState),\n })),\n pTableParams: createDefaultPTableParams(),\n };\n}\n\n/** Convert v5 wrapped colId JSON to bare PTableColumnSpec JSON, taking `.source`.\n * gridState colIds may include the row-number sentinel (a JSON-stringified\n * literal, not a wrapped spec) — those pass through unchanged. */\nfunction unwrapV5ColId(json: string): string {\n const parsed: unknown = parseJsonSafely(json as CanonicalizedJson<unknown>);\n return !isNil(parsed) && typeof parsed === \"object\" && \"source\" in parsed\n ? canonicalizeJson((parsed as PlDataTableV5ColIdWrapper).source)\n : json;\n}\n\nfunction unwrapV5GridState(gridState: PlDataTableGridStateV5): PlDataTableGridStateCore {\n const unwrapAs = (json: PlDataTableV5ColIdJson) =>\n unwrapV5ColId(json) as CanonicalizedJson<PTableColumnSpec>;\n return {\n columnOrder: gridState.columnOrder\n ? { orderedColIds: gridState.columnOrder.orderedColIds.map(unwrapAs) }\n : undefined,\n sort: gridState.sort\n ? {\n sortModel: gridState.sort.sortModel.map((s) => ({\n colId: unwrapAs(s.colId),\n sort: s.sort,\n })),\n }\n : undefined,\n columnVisibility: gridState.columnVisibility\n ? { hiddenColIds: gridState.columnVisibility.hiddenColIds.map(unwrapAs) }\n : undefined,\n };\n}\n\n/** Migrate v4 state to v6: convert per-column filters to tree-based format (skips v5). */\nfunction migrateV4toV6(\n state: Extract<PlDataTableStateV2, { version: 4 }>,\n): PlDataTableStateV2Normalized {\n let idCounter = 0;\n const nextId = () => ++idCounter;\n\n const migratedCache: PlDataTableStateV2CacheEntry[] = state.stateCache.map((entry) => {\n const leaves: PlDataTableFiltersWithMeta[\"filters\"] = [];\n for (const f of entry.filtersState) {\n if (f.filter !== null && !f.filter.disabled) {\n const column = canonicalizeJson(f.id);\n leaves.push(migrateTableFilter(column, f.filter.value, nextId));\n }\n }\n const filtersState: PlDataTableFiltersWithMeta | null =\n leaves.length > 0 ? { id: nextId(), type: \"and\", filters: leaves } : null;\n\n return {\n sourceId: entry.sourceId,\n gridState: entry.gridState,\n sheetsState: entry.sheetsState,\n filtersState,\n defaultFiltersState: null,\n };\n });\n\n const oldSourceId = state.pTableParams.sourceId;\n const currentCache = oldSourceId\n ? migratedCache.find((e) => e.sourceId === oldSourceId)\n : undefined;\n\n return {\n version: 6,\n stateCache: migratedCache,\n pTableParams:\n currentCache && oldSourceId\n ? {\n sourceId: oldSourceId,\n hiddenColIds:\n state.pTableParams.hiddenColIds?.map((id) => ({ type: \"column\" as const, id })) ??\n null,\n filters: distillFilterSpec(currentCache.filtersState),\n defaultFilters: null,\n sorting: state.pTableParams.sorting,\n }\n : createDefaultPTableParams(),\n };\n}\n\n/** Migrate a single per-column PlTableFilter to a tree-based FilterSpec node */\nfunction migrateTableFilter(\n column: CanonicalizedJson<PTableColumnId>,\n filter: PlTableFilter,\n nextId: () => number,\n): PlDataTableFiltersWithMeta[\"filters\"][number] {\n const id = nextId();\n switch (filter.type) {\n case \"isNA\":\n return { id, type: \"isNA\", column };\n case \"isNotNA\":\n return { id, type: \"isNotNA\", column };\n case \"number_equals\":\n return { id, type: \"equal\", column, x: filter.reference };\n case \"number_notEquals\":\n return { id, type: \"notEqual\", column, x: filter.reference };\n case \"number_greaterThan\":\n return { id, type: \"greaterThan\", column, x: filter.reference };\n case \"number_greaterThanOrEqualTo\":\n return { id, type: \"greaterThanOrEqual\", column, x: filter.reference };\n case \"number_lessThan\":\n return { id, type: \"lessThan\", column, x: filter.reference };\n case \"number_lessThanOrEqualTo\":\n return { id, type: \"lessThanOrEqual\", column, x: filter.reference };\n case \"number_between\":\n return {\n id,\n type: \"and\",\n filters: [\n filter.includeLowerBound\n ? { id: nextId(), type: \"greaterThanOrEqual\" as const, column, x: filter.lowerBound }\n : { id: nextId(), type: \"greaterThan\" as const, column, x: filter.lowerBound },\n filter.includeUpperBound\n ? { id: nextId(), type: \"lessThanOrEqual\" as const, column, x: filter.upperBound }\n : { id: nextId(), type: \"lessThan\" as const, column, x: filter.upperBound },\n ],\n };\n case \"string_equals\":\n return { id, type: \"patternEquals\", column, value: filter.reference };\n case \"string_notEquals\":\n return { id, type: \"patternNotEquals\", column, value: filter.reference };\n case \"string_contains\":\n return { id, type: \"patternContainSubsequence\", column, value: filter.reference };\n case \"string_doesNotContain\":\n return { id, type: \"patternNotContainSubsequence\", column, value: filter.reference };\n case \"string_matches\":\n return { id, type: \"patternMatchesRegularExpression\", column, value: filter.reference };\n case \"string_doesNotMatch\":\n return {\n id,\n type: \"not\",\n filter: {\n id: nextId(),\n type: \"patternMatchesRegularExpression\",\n column,\n value: filter.reference,\n },\n };\n case \"string_containsFuzzyMatch\":\n return {\n id,\n type: \"patternFuzzyContainSubsequence\",\n column,\n value: filter.reference,\n maxEdits: filter.maxEdits,\n substitutionsOnly: filter.substitutionsOnly,\n ...(filter.wildcard !== undefined ? { wildcard: filter.wildcard } : {}),\n };\n }\n}\n\nexport function createDefaultPTableParams(): PTableParamsV2 {\n return {\n sourceId: null,\n hiddenColIds: null,\n filters: null,\n defaultFilters: null,\n sorting: [],\n };\n}\n\nexport function createPlDataTableStateV2(): PlDataTableStateV2Normalized {\n return {\n version: 6,\n stateCache: [],\n pTableParams: createDefaultPTableParams(),\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"state-migration.js","names":[],"sources":["../../../src/components/PlDataTable/state-migration.ts"],"sourcesContent":["import type {\n AxisId,\n CanonicalizedJson,\n PObjectId,\n PTableColumnId,\n PTableColumnSpec,\n PTableRecordFilter,\n PTableSorting,\n} from \"@milaboratories/pl-model-common\";\nimport {\n canonicalizeJson,\n getPTableColumnId,\n parseJsonSafely,\n} from \"@milaboratories/pl-model-common\";\nimport { distillFilterSpec } from \"../../filters\";\nimport type { PlDataTableFilterState, PlTableFilter } from \"./typesV4\";\nimport type {\n PlDataTableFiltersWithMeta,\n PlDataTableGridStateCore,\n PlDataTableSheetState,\n PlDataTableStateV2CacheEntry,\n PlDataTableStateV2Normalized,\n PlTableColumnIdJson,\n PTableParamsV2,\n} from \"./typesV7\";\nimport type {\n PlDataTableGridStateV6,\n PlDataTableStateV2V6,\n PlDataTableStateV2V6CacheEntry,\n PlDataTableV6ColIdJson,\n} from \"./typesV6\";\nimport type {\n PlDataTableGridStateV5,\n PlDataTableV5ColIdJson,\n PlDataTableV5ColIdWrapper,\n} from \"./typesV5\";\nimport { isNil } from \"es-toolkit\";\n\n/**\n * PlDataTableV2 persisted state\n */\nexport type PlDataTableStateV2 =\n // Old versions of the state\n | {\n // no version\n gridState: {\n columnOrder?: {\n orderedColIds: CanonicalizedJson<PTableColumnSpec>[];\n };\n sort?: {\n sortModel: {\n colId: CanonicalizedJson<PTableColumnSpec>;\n sort: \"asc\" | \"desc\";\n }[];\n };\n columnVisibility?: {\n hiddenColIds: CanonicalizedJson<PTableColumnSpec>[];\n };\n sourceId?: string;\n sheets?: Record<CanonicalizedJson<AxisId>, string | number>;\n };\n pTableParams?: {\n sorting?: PTableSorting[];\n filters?: PTableRecordFilter[];\n };\n }\n | {\n version: 2;\n stateCache: {\n sourceId: string;\n gridState: {\n columnOrder?: {\n orderedColIds: CanonicalizedJson<PTableColumnSpec>[];\n };\n sort?: {\n sortModel: {\n colId: CanonicalizedJson<PTableColumnSpec>;\n sort: \"asc\" | \"desc\";\n }[];\n };\n columnVisibility?: {\n hiddenColIds: CanonicalizedJson<PTableColumnSpec>[];\n };\n };\n sheetsState: PlDataTableSheetState[];\n }[];\n pTableParams: {\n hiddenColIds: PObjectId[] | null;\n filters: PTableRecordFilter[];\n sorting: PTableSorting[];\n };\n }\n | {\n version: 3;\n stateCache: {\n sourceId: string;\n gridState: {\n columnOrder?: {\n orderedColIds: CanonicalizedJson<PTableColumnSpec>[];\n };\n sort?: {\n sortModel: {\n colId: CanonicalizedJson<PTableColumnSpec>;\n sort: \"asc\" | \"desc\";\n }[];\n };\n columnVisibility?: {\n hiddenColIds: CanonicalizedJson<PTableColumnSpec>[];\n };\n };\n sheetsState: PlDataTableSheetState[];\n filtersState: PlDataTableFilterState[];\n }[];\n pTableParams: PTableParamsV2;\n }\n | {\n version: 4;\n stateCache: {\n sourceId: string;\n gridState: PlDataTableGridStateV6;\n sheetsState: PlDataTableSheetState[];\n filtersState: PlDataTableFilterState[];\n }[];\n /** Old format; only fields used in migration are typed */\n pTableParams: {\n sourceId: string | null;\n hiddenColIds: PObjectId[] | null;\n sorting: PTableSorting[];\n };\n }\n // v5 stored colIds as `{source, labeled}` wrappers; only the gridState shape differs.\n | {\n version: 5;\n stateCache: {\n sourceId: string;\n gridState: PlDataTableGridStateV5;\n sheetsState: PlDataTableSheetState[];\n filtersState: null | PlDataTableFiltersWithMeta;\n defaultFiltersState: null | PlDataTableFiltersWithMeta;\n searchString?: string;\n }[];\n pTableParams: PTableParamsV2;\n }\n // v6 stored colIds as canonicalized full `PTableColumnSpec` (including\n // annotations + `pl7.app/trace`). v7 strips down to `PTableColumnId`.\n | PlDataTableStateV2V6\n // Normalized state\n | PlDataTableStateV2Normalized;\n\n/** Upgrade PlDataTableStateV2 to the latest version */\nexport function upgradePlDataTableStateV2(\n state: PlDataTableStateV2 | undefined,\n): PlDataTableStateV2Normalized {\n // Block just added, had no state, model started earlier than the UI\n if (!state) {\n return createPlDataTableStateV2();\n }\n // v1 -> v2\n if (!(\"version\" in state)) {\n // Non upgradeable as sourceId calculation algorithm has changed, resetting state to default\n state = createPlDataTableStateV2();\n }\n // v2 -> v3\n if (state.version === 2) {\n state = {\n version: 3,\n stateCache: state.stateCache.map((entry) => ({\n ...entry,\n filtersState: [],\n })),\n pTableParams: createDefaultPTableParams(),\n };\n }\n // v3 -> v4\n if (state.version === 3) {\n // Non upgradeable as column ids calculation algorithm has changed, resetting state to default\n state = createPlDataTableStateV2();\n }\n // v4 -> v6: migrate per-column filters to tree-based format (skips v5).\n // v4 gridState already used bare PTableColumnSpec colIds, so we jump\n // straight to v6 without going through the v5 wrapper format.\n if (state.version === 4) {\n state = migrateV4toV6(state);\n }\n // v5 -> v6: unwrap `{source, labeled}` colIds in gridState back to bare PTableColumnSpec.\n if (state.version === 5) {\n state = migrateV5toV6(state);\n }\n // v6 -> v7: shrink colIds from full PTableColumnSpec to PTableColumnId.\n if (state.version === 6) {\n state = migrateV6toV7(state);\n }\n return state;\n}\n\n/** Migrate v5 to v6: unwrap `{source, labeled}` colIds in gridState. */\nfunction migrateV5toV6(state: Extract<PlDataTableStateV2, { version: 5 }>): PlDataTableStateV2V6 {\n // pTableParams reset: v5 stored DiscoveredPColumnId-based hiddenColIds with\n // empty-array fields (e.g. `{column, path: [], columnQualifications: [], ...}`).\n // v6 distills empty fields, so the same logical column serialises differently\n // and lookups would silently miss every previously-hidden discovered column.\n // gridState colIds are derived from PTableColumnSpec and unaffected.\n return {\n version: 6,\n stateCache: state.stateCache.map((entry) => ({\n ...entry,\n gridState: unwrapV5GridState(entry.gridState),\n })),\n pTableParams: createDefaultPTableParams(),\n };\n}\n\n/** Convert v5 wrapped colId JSON to bare PTableColumnSpec JSON, taking `.source`.\n * gridState colIds may include the row-number sentinel (a JSON-stringified\n * literal, not a wrapped spec) — those pass through unchanged. */\nfunction unwrapV5ColId(json: string): string {\n const parsed: unknown = parseJsonSafely(json as CanonicalizedJson<unknown>);\n return !isNil(parsed) && typeof parsed === \"object\" && \"source\" in parsed\n ? canonicalizeJson((parsed as PlDataTableV5ColIdWrapper).source)\n : json;\n}\n\nfunction unwrapV5GridState(gridState: PlDataTableGridStateV5): PlDataTableGridStateV6 {\n const unwrapAs = (json: PlDataTableV5ColIdJson) => unwrapV5ColId(json) as PlDataTableV6ColIdJson;\n return {\n columnOrder: gridState.columnOrder\n ? { orderedColIds: gridState.columnOrder.orderedColIds.map(unwrapAs) }\n : undefined,\n sort: gridState.sort\n ? {\n sortModel: gridState.sort.sortModel.map((s) => ({\n colId: unwrapAs(s.colId),\n sort: s.sort,\n })),\n }\n : undefined,\n columnVisibility: gridState.columnVisibility\n ? { hiddenColIds: gridState.columnVisibility.hiddenColIds.map(unwrapAs) }\n : undefined,\n };\n}\n\n/** Migrate v6 to v7: rewrite each colId from a full PTableColumnSpec to its\n * compact PTableColumnId (drops annotations/spec body, ~16× smaller per column). */\nfunction migrateV6toV7(state: PlDataTableStateV2V6): PlDataTableStateV2Normalized {\n return {\n version: 7,\n stateCache: state.stateCache.map(\n (entry): PlDataTableStateV2CacheEntry => ({\n ...entry,\n gridState: shrinkV6GridState(entry.gridState),\n }),\n ),\n pTableParams: state.pTableParams,\n };\n}\n\n/** Convert a v6 fat colId (canonicalized PTableColumnSpec) to a v7 compact colId\n * (canonicalized PTableColumnId). The row-number sentinel is a string literal,\n * not a spec — pass it through unchanged. */\nfunction shrinkV6ColId(json: PlDataTableV6ColIdJson): PlTableColumnIdJson {\n const parsed: unknown = parseJsonSafely(json);\n if (!isNil(parsed) && typeof parsed === \"object\" && \"type\" in parsed && \"id\" in parsed) {\n return canonicalizeJson(getPTableColumnId(parsed as PTableColumnSpec));\n }\n return json as unknown as PlTableColumnIdJson;\n}\n\nfunction shrinkV6GridState(gridState: PlDataTableGridStateV6): PlDataTableGridStateCore {\n return {\n columnOrder: gridState.columnOrder\n ? { orderedColIds: gridState.columnOrder.orderedColIds.map(shrinkV6ColId) }\n : undefined,\n sort: gridState.sort\n ? {\n sortModel: gridState.sort.sortModel.map((s) => ({\n colId: shrinkV6ColId(s.colId),\n sort: s.sort,\n })),\n }\n : undefined,\n columnVisibility: gridState.columnVisibility\n ? { hiddenColIds: gridState.columnVisibility.hiddenColIds.map(shrinkV6ColId) }\n : undefined,\n };\n}\n\n/** Migrate v4 state to v6: convert per-column filters to tree-based format (skips v5). */\nfunction migrateV4toV6(state: Extract<PlDataTableStateV2, { version: 4 }>): PlDataTableStateV2V6 {\n let idCounter = 0;\n const nextId = () => ++idCounter;\n\n const migratedCache: PlDataTableStateV2V6CacheEntry[] = state.stateCache.map((entry) => {\n const leaves: PlDataTableFiltersWithMeta[\"filters\"] = [];\n for (const f of entry.filtersState) {\n if (f.filter !== null && !f.filter.disabled) {\n const column = canonicalizeJson(f.id);\n leaves.push(migrateTableFilter(column, f.filter.value, nextId));\n }\n }\n const filtersState: PlDataTableFiltersWithMeta | null =\n leaves.length > 0 ? { id: nextId(), type: \"and\", filters: leaves } : null;\n\n return {\n sourceId: entry.sourceId,\n gridState: entry.gridState,\n sheetsState: entry.sheetsState,\n filtersState,\n defaultFiltersState: null,\n };\n });\n\n const oldSourceId = state.pTableParams.sourceId;\n const currentCache = oldSourceId\n ? migratedCache.find((e) => e.sourceId === oldSourceId)\n : undefined;\n\n return {\n version: 6,\n stateCache: migratedCache,\n pTableParams:\n currentCache && oldSourceId\n ? {\n sourceId: oldSourceId,\n hiddenColIds:\n state.pTableParams.hiddenColIds?.map((id) => ({ type: \"column\" as const, id })) ??\n null,\n filters: distillFilterSpec(currentCache.filtersState),\n defaultFilters: null,\n sorting: state.pTableParams.sorting,\n }\n : createDefaultPTableParams(),\n };\n}\n\n/** Migrate a single per-column PlTableFilter to a tree-based FilterSpec node */\nfunction migrateTableFilter(\n column: CanonicalizedJson<PTableColumnId>,\n filter: PlTableFilter,\n nextId: () => number,\n): PlDataTableFiltersWithMeta[\"filters\"][number] {\n const id = nextId();\n switch (filter.type) {\n case \"isNA\":\n return { id, type: \"isNA\", column };\n case \"isNotNA\":\n return { id, type: \"isNotNA\", column };\n case \"number_equals\":\n return { id, type: \"equal\", column, x: filter.reference };\n case \"number_notEquals\":\n return { id, type: \"notEqual\", column, x: filter.reference };\n case \"number_greaterThan\":\n return { id, type: \"greaterThan\", column, x: filter.reference };\n case \"number_greaterThanOrEqualTo\":\n return { id, type: \"greaterThanOrEqual\", column, x: filter.reference };\n case \"number_lessThan\":\n return { id, type: \"lessThan\", column, x: filter.reference };\n case \"number_lessThanOrEqualTo\":\n return { id, type: \"lessThanOrEqual\", column, x: filter.reference };\n case \"number_between\":\n return {\n id,\n type: \"and\",\n filters: [\n filter.includeLowerBound\n ? { id: nextId(), type: \"greaterThanOrEqual\" as const, column, x: filter.lowerBound }\n : { id: nextId(), type: \"greaterThan\" as const, column, x: filter.lowerBound },\n filter.includeUpperBound\n ? { id: nextId(), type: \"lessThanOrEqual\" as const, column, x: filter.upperBound }\n : { id: nextId(), type: \"lessThan\" as const, column, x: filter.upperBound },\n ],\n };\n case \"string_equals\":\n return { id, type: \"patternEquals\", column, value: filter.reference };\n case \"string_notEquals\":\n return { id, type: \"patternNotEquals\", column, value: filter.reference };\n case \"string_contains\":\n return { id, type: \"patternContainSubsequence\", column, value: filter.reference };\n case \"string_doesNotContain\":\n return { id, type: \"patternNotContainSubsequence\", column, value: filter.reference };\n case \"string_matches\":\n return { id, type: \"patternMatchesRegularExpression\", column, value: filter.reference };\n case \"string_doesNotMatch\":\n return {\n id,\n type: \"not\",\n filter: {\n id: nextId(),\n type: \"patternMatchesRegularExpression\",\n column,\n value: filter.reference,\n },\n };\n case \"string_containsFuzzyMatch\":\n return {\n id,\n type: \"patternFuzzyContainSubsequence\",\n column,\n value: filter.reference,\n maxEdits: filter.maxEdits,\n substitutionsOnly: filter.substitutionsOnly,\n ...(filter.wildcard !== undefined ? { wildcard: filter.wildcard } : {}),\n };\n }\n}\n\nexport function createDefaultPTableParams(): PTableParamsV2 {\n return {\n sourceId: null,\n hiddenColIds: null,\n filters: null,\n defaultFilters: null,\n sorting: [],\n };\n}\n\nexport function createPlDataTableStateV2(): PlDataTableStateV2Normalized {\n return {\n version: 7,\n stateCache: [],\n pTableParams: createDefaultPTableParams(),\n };\n}\n"],"mappings":"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"}
@@ -1,98 +1,40 @@
1
- import { FilterSpecLeaf as FilterSpecLeaf$1 } from "../../filters/types.js";
2
- import { AxisId, AxisSpec, CanonicalizedJson, ListOptionBase, PColumnIdAndSpec, PFrameHandle, PTableColumnId, PTableColumnSpec, PTableHandle, PTableSorting, RootFilterSpec } from "@milaboratories/pl-model-common";
3
- import { Nil } from "@milaboratories/helpers";
1
+ import { PTableParamsV2, PlDataTableFiltersWithMeta, PlDataTableSheetState } from "./typesV7.js";
2
+ import { CanonicalizedJson, PTableColumnSpec } from "@milaboratories/pl-model-common";
4
3
 
5
4
  //#region src/components/PlDataTable/typesV6.d.ts
6
- type PlTableColumnIdJson = CanonicalizedJson<PTableColumnSpec>;
7
- type PlDataTableGridStateCore = {
8
- /** Includes column ordering */columnOrder?: {
9
- /** All colIds in order */orderedColIds: PlTableColumnIdJson[];
10
- }; /** Includes current sort columns and direction */
5
+ /**
6
+ * v6 colId scheme: bare canonicalized `PTableColumnSpec` (full spec including
7
+ * all annotations and `pl7.app/trace`). v7 dropped the spec body and now uses
8
+ * `CanonicalizedJson<PTableColumnId>` orders of magnitude smaller.
9
+ */
10
+ type PlDataTableV6ColIdJson = CanonicalizedJson<PTableColumnSpec>;
11
+ type PlDataTableGridStateV6 = {
12
+ columnOrder?: {
13
+ orderedColIds: PlDataTableV6ColIdJson[];
14
+ };
11
15
  sort?: {
12
- /** Sorted columns and directions in order */sortModel: {
13
- /** Column Id to apply the sort to. */colId: PlTableColumnIdJson; /** Sort direction */
16
+ sortModel: {
17
+ colId: PlDataTableV6ColIdJson;
14
18
  sort: "asc" | "desc";
15
19
  }[];
16
- }; /** Includes column visibility */
20
+ };
17
21
  columnVisibility?: {
18
- /** All colIds which were hidden */hiddenColIds: PlTableColumnIdJson[];
22
+ hiddenColIds: PlDataTableV6ColIdJson[];
19
23
  };
20
24
  };
21
- type PlDataTableSheet = {
22
- /** spec of the axis to use */axis: AxisSpec; /** options to show in the filter dropdown */
23
- options: ListOptionBase<string | number>[]; /** default (selected) value */
24
- defaultValue?: string | number;
25
- };
26
- type PlDataTableSheetState = {
27
- /** id of the axis */axisId: AxisId; /** selected value */
28
- value: string | number;
29
- };
30
- /** Tree-based filter state compatible with PlAdvancedFilter's RootFilter */
31
- type PlDataTableFilterMeta = {
32
- id: number;
33
- source?: "table-filter" | "table-search";
34
- isExpanded?: boolean;
35
- isSuppressed?: boolean;
36
- };
37
- type PlDataTableFilterSpecLeaf = FilterSpecLeaf$1<CanonicalizedJson<PTableColumnId>>;
38
- type PlDataTableFilters = RootFilterSpec<PlDataTableFilterSpecLeaf>;
39
- type PlDataTableFiltersWithMeta = RootFilterSpec<PlDataTableFilterSpecLeaf, PlDataTableFilterMeta>;
40
- type PlDataTableStateV2CacheEntry = {
41
- /** DataSource identifier for state management */sourceId: string; /** Internal ag-grid state */
42
- gridState: PlDataTableGridStateCore; /** Sheets state */
43
- sheetsState: PlDataTableSheetState[]; /** User filters state (tree-based, compatible with PlAdvancedFilter) */
44
- filtersState: null | PlDataTableFiltersWithMeta; /** Default filters state from model (snapshot of defaults) */
45
- defaultFiltersState: null | PlDataTableFiltersWithMeta; /** Fast search string */
46
- searchString?: string;
47
- };
48
- type PTableParamsV2 = {
49
- sourceId: null;
50
- hiddenColIds: null;
51
- sorting: [];
52
- filters: null;
53
- defaultFilters: null;
54
- } | {
25
+ type PlDataTableStateV2V6CacheEntry = {
55
26
  sourceId: string;
56
- hiddenColIds: null | PTableColumnId[];
57
- sorting: PTableSorting[];
58
- filters: null | PlDataTableFilters;
59
- defaultFilters: null | PlDataTableFilters;
27
+ gridState: PlDataTableGridStateV6;
28
+ sheetsState: PlDataTableSheetState[];
29
+ filtersState: null | PlDataTableFiltersWithMeta;
30
+ defaultFiltersState: null | PlDataTableFiltersWithMeta;
31
+ searchString?: string;
60
32
  };
61
- type PlDataTableStateV2Normalized = {
62
- /** Version for upgrades */version: 6; /** Internal states, LRU cache for 5 sourceId-s */
63
- stateCache: PlDataTableStateV2CacheEntry[]; /** PTable params derived from the cache state for the current sourceId */
33
+ type PlDataTableStateV2V6 = {
34
+ version: 6;
35
+ stateCache: PlDataTableStateV2V6CacheEntry[];
64
36
  pTableParams: PTableParamsV2;
65
37
  };
66
- /** PlAgDataTable model */
67
- type PlDataTableModel = {
68
- /** DataSource identifier for state management */sourceId: null | string; /** p-table including all columns, used to show the full specification of the table */
69
- fullTableHandle?: PTableHandle; /** p-frame handle */
70
- fullPframeHandle?: PFrameHandle; /** p-table including only visible columns, used to get the data */
71
- visibleTableHandle?: PTableHandle; /** Default filters from model options, surfaced for UI display */
72
- defaultFilters?: Nil | PlDataTableFilters;
73
- };
74
- type CreatePlDataTableOps = {
75
- /** Filters for columns and non-partitioned axes */filters?: PlDataTableFilters; /** Sorting to columns hidden from user */
76
- sorting?: PTableSorting[];
77
- /**
78
- * Selects columns for which will be inner-joined to the table.
79
- *
80
- * Default behaviour: all columns are considered to be core
81
- */
82
- coreColumnPredicate?: (spec: PColumnIdAndSpec) => boolean;
83
- /**
84
- * Determines how core columns should be joined together:
85
- * inner - so user will only see records present in all core columns
86
- * full - so user will only see records present in any of the core columns
87
- *
88
- * All non-core columns will be left joined to the table produced by the core
89
- * columns, in other words records form the pool of non-core columns will only
90
- * make their way into the final table if core table contains corresponding key.
91
- *
92
- * Default: 'full'
93
- */
94
- coreJoinType?: "inner" | "full";
95
- };
96
38
  //#endregion
97
- export { CreatePlDataTableOps, PTableParamsV2, PlDataTableFilterMeta, PlDataTableFilterSpecLeaf, PlDataTableFilters, PlDataTableFiltersWithMeta, PlDataTableGridStateCore, PlDataTableModel, PlDataTableSheet, PlDataTableSheetState, PlDataTableStateV2CacheEntry, PlDataTableStateV2Normalized, PlTableColumnIdJson };
39
+ export { PlDataTableGridStateV6, PlDataTableStateV2V6 };
98
40
  //# sourceMappingURL=typesV6.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"typesV6.d.ts","names":[],"sources":["../../../src/components/PlDataTable/typesV6.ts"],"mappings":";;;;;KAgBY,mBAAA,GAAsB,iBAAA,CAAkB,gBAAA;AAAA,KAExC,wBAAA;iCAEV,WAAA;IAJ6B,0BAM3B,aAAA,EAAe,mBAAA;EAAA,GANiD;EASlE,IAAA;IAPkC,6CAShC,SAAA;MALe,sCAOb,KAAA,EAAO,mBAAA,EAQK;MANZ,IAAA;IAAA;EAAA,GATF;EAaF,gBAAA;IAVA,mCAYE,YAAA,EAAc,mBAAA;EAAA;AAAA;AAAA,KAIN,gBAAA;EANV,8BAQA,IAAA,EAAM,QAAA,EANU;EAQhB,OAAA,EAAS,cAAA,qBAR0B;EAUnC,YAAA;AAAA;AAAA,KAGU,qBAAA;EALa,qBAOvB,MAAA,EAAQ,MAAA,EATF;EAWN,KAAA;AAAA;;KAIU,qBAAA;EACV,EAAA;EACA,MAAA;EACA,UAAA;EACA,YAAA;AAAA;AAAA,KAEU,yBAAA,GAA4B,gBAAA,CAAe,iBAAA,CAAkB,cAAA;AAAA,KAC7D,kBAAA,GAAqB,cAAA,CAAe,yBAAA;AAAA,KACpC,0BAAA,GAA6B,cAAA,CACvC,yBAAA,EACA,qBAAA;AAAA,KAGU,4BAAA;EAjBL,iDAmBL,QAAA,UAf+B;EAiB/B,SAAA,EAAW,wBAAA,EAjBoB;EAmB/B,WAAA,EAAa,qBAAA,IAjBb;EAmBA,YAAA,SAAqB,0BAAA,EAjBrB;EAmBA,mBAAA,SAA4B,0BAAA,EAnBhB;EAqBZ,YAAA;AAAA;AAAA,KAGU,cAAA;EAEN,QAAA;EACA,YAAA;EACA,OAAA;EACA,OAAA;EACA,cAAA;AAAA;EAGA,QAAA;EACA,YAAA,SAAqB,cAAA;EACrB,OAAA,EAAS,aAAA;EACT,OAAA,SAAgB,kBAAA;EAChB,cAAA,SAAuB,kBAAA;AAAA;AAAA,KAGjB,4BAAA;EArCqB,2BAuC/B,OAAA,KAtCU;EAwCV,UAAA,EAAY,4BAAA;EAEZ,YAAA,EAAc,cAAA;AAAA;;KAIJ,gBAAA;EA9C2C,iDAgDrD,QAAA,iBA/CA;EAiDA,eAAA,GAAkB,YAAA,EAhDG;EAkDrB,gBAAA,GAAmB,YAAA,EA/CT;EAiDV,kBAAA,GAAqB,YAAA;EAErB,cAAA,GAAiB,GAAA,GAAM,kBAAA;AAAA;AAAA,KAGb,oBAAA;EA5CkB,mDA8C5B,OAAA,GAAU,kBAAA,EA9C4C;EAiDtD,OAAA,GAAU,aAAA;EAvDV;;;;;EA8DA,mBAAA,IAAuB,IAAA,EAAM,gBAAA;EAxD7B;;;;;AAKF;;;;;;EAgEE,YAAA;AAAA"}
1
+ {"version":3,"file":"typesV6.d.ts","names":[],"sources":["../../../src/components/PlDataTable/typesV6.ts"],"mappings":";;;;;;AAQA;;;KAAY,sBAAA,GAAyB,iBAAA,CAAkB,gBAAA;AAAA,KAE3C,sBAAA;EACV,WAAA;IAAgB,aAAA,EAAe,sBAAA;EAAA;EAC/B,IAAA;IAAS,SAAA;MAAa,KAAA,EAAO,sBAAA;MAAwB,IAAA;IAAA;EAAA;EACrD,gBAAA;IAAqB,YAAA,EAAc,sBAAA;EAAA;AAAA;AAAA,KAGzB,8BAAA;EACV,QAAA;EACA,SAAA,EAAW,sBAAA;EACX,WAAA,EAAa,qBAAA;EACb,YAAA,SAAqB,0BAAA;EACrB,mBAAA,SAA4B,0BAAA;EAC5B,YAAA;AAAA;AAAA,KAGU,oBAAA;EACV,OAAA;EACA,UAAA,EAAY,8BAAA;EACZ,YAAA,EAAc,cAAA;AAAA"}
@@ -0,0 +1,98 @@
1
+ import { FilterSpecLeaf as FilterSpecLeaf$1 } from "../../filters/types.js";
2
+ import { AxisId, AxisSpec, CanonicalizedJson, ListOptionBase, PColumnIdAndSpec, PFrameHandle, PTableColumnId, PTableHandle, PTableSorting, RootFilterSpec } from "@milaboratories/pl-model-common";
3
+ import { Nil } from "@milaboratories/helpers";
4
+
5
+ //#region src/components/PlDataTable/typesV7.d.ts
6
+ type PlTableColumnIdJson = CanonicalizedJson<PTableColumnId>;
7
+ type PlDataTableGridStateCore = {
8
+ /** Includes column ordering */columnOrder?: {
9
+ /** All colIds in order */orderedColIds: PlTableColumnIdJson[];
10
+ }; /** Includes current sort columns and direction */
11
+ sort?: {
12
+ /** Sorted columns and directions in order */sortModel: {
13
+ /** Column Id to apply the sort to. */colId: PlTableColumnIdJson; /** Sort direction */
14
+ sort: "asc" | "desc";
15
+ }[];
16
+ }; /** Includes column visibility */
17
+ columnVisibility?: {
18
+ /** All colIds which were hidden */hiddenColIds: PlTableColumnIdJson[];
19
+ };
20
+ };
21
+ type PlDataTableSheet = {
22
+ /** spec of the axis to use */axis: AxisSpec; /** options to show in the filter dropdown */
23
+ options: ListOptionBase<string | number>[]; /** default (selected) value */
24
+ defaultValue?: string | number;
25
+ };
26
+ type PlDataTableSheetState = {
27
+ /** id of the axis */axisId: AxisId; /** selected value */
28
+ value: string | number;
29
+ };
30
+ /** Tree-based filter state compatible with PlAdvancedFilter's RootFilter */
31
+ type PlDataTableFilterMeta = {
32
+ id: number;
33
+ source?: "table-filter" | "table-search";
34
+ isExpanded?: boolean;
35
+ isSuppressed?: boolean;
36
+ };
37
+ type PlDataTableFilterSpecLeaf = FilterSpecLeaf$1<CanonicalizedJson<PTableColumnId>>;
38
+ type PlDataTableFilters = RootFilterSpec<PlDataTableFilterSpecLeaf>;
39
+ type PlDataTableFiltersWithMeta = RootFilterSpec<PlDataTableFilterSpecLeaf, PlDataTableFilterMeta>;
40
+ type PlDataTableStateV2CacheEntry = {
41
+ /** DataSource identifier for state management */sourceId: string; /** Internal ag-grid state */
42
+ gridState: PlDataTableGridStateCore; /** Sheets state */
43
+ sheetsState: PlDataTableSheetState[]; /** User filters state (tree-based, compatible with PlAdvancedFilter) */
44
+ filtersState: null | PlDataTableFiltersWithMeta; /** Default filters state from model (snapshot of defaults) */
45
+ defaultFiltersState: null | PlDataTableFiltersWithMeta; /** Fast search string */
46
+ searchString?: string;
47
+ };
48
+ type PTableParamsV2 = {
49
+ sourceId: null;
50
+ hiddenColIds: null;
51
+ sorting: [];
52
+ filters: null;
53
+ defaultFilters: null;
54
+ } | {
55
+ sourceId: string;
56
+ hiddenColIds: null | PTableColumnId[];
57
+ sorting: PTableSorting[];
58
+ filters: null | PlDataTableFilters;
59
+ defaultFilters: null | PlDataTableFilters;
60
+ };
61
+ type PlDataTableStateV2Normalized = {
62
+ /** Version for upgrades */version: 7; /** Internal states, LRU cache for 5 sourceId-s */
63
+ stateCache: PlDataTableStateV2CacheEntry[]; /** PTable params derived from the cache state for the current sourceId */
64
+ pTableParams: PTableParamsV2;
65
+ };
66
+ /** PlAgDataTable model */
67
+ type PlDataTableModel = {
68
+ /** DataSource identifier for state management */sourceId: null | string; /** p-table including all columns, used to show the full specification of the table */
69
+ fullTableHandle?: PTableHandle; /** p-frame handle */
70
+ fullPframeHandle?: PFrameHandle; /** p-table including only visible columns, used to get the data */
71
+ visibleTableHandle?: PTableHandle; /** Default filters from model options, surfaced for UI display */
72
+ defaultFilters?: Nil | PlDataTableFilters;
73
+ };
74
+ type CreatePlDataTableOps = {
75
+ /** Filters for columns and non-partitioned axes */filters?: PlDataTableFilters; /** Sorting to columns hidden from user */
76
+ sorting?: PTableSorting[];
77
+ /**
78
+ * Selects columns for which will be inner-joined to the table.
79
+ *
80
+ * Default behaviour: all columns are considered to be core
81
+ */
82
+ coreColumnPredicate?: (spec: PColumnIdAndSpec) => boolean;
83
+ /**
84
+ * Determines how core columns should be joined together:
85
+ * inner - so user will only see records present in all core columns
86
+ * full - so user will only see records present in any of the core columns
87
+ *
88
+ * All non-core columns will be left joined to the table produced by the core
89
+ * columns, in other words records form the pool of non-core columns will only
90
+ * make their way into the final table if core table contains corresponding key.
91
+ *
92
+ * Default: 'full'
93
+ */
94
+ coreJoinType?: "inner" | "full";
95
+ };
96
+ //#endregion
97
+ export { CreatePlDataTableOps, PTableParamsV2, PlDataTableFilterMeta, PlDataTableFilterSpecLeaf, PlDataTableFilters, PlDataTableFiltersWithMeta, PlDataTableGridStateCore, PlDataTableModel, PlDataTableSheet, PlDataTableSheetState, PlDataTableStateV2CacheEntry, PlDataTableStateV2Normalized, PlTableColumnIdJson };
98
+ //# sourceMappingURL=typesV7.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"typesV7.d.ts","names":[],"sources":["../../../src/components/PlDataTable/typesV7.ts"],"mappings":";;;;;KAeY,mBAAA,GAAsB,iBAAA,CAAkB,cAAA;AAAA,KAExC,wBAAA;iCAEV,WAAA;IAJ6B,0BAM3B,aAAA,EAAe,mBAAA;EAAA,GAN+C;EAShE,IAAA;IAPkC,6CAShC,SAAA;MALe,sCAOb,KAAA,EAAO,mBAAA,EAQK;MANZ,IAAA;IAAA;EAAA,GATF;EAaF,gBAAA;IAVA,mCAYE,YAAA,EAAc,mBAAA;EAAA;AAAA;AAAA,KAIN,gBAAA;EANV,8BAQA,IAAA,EAAM,QAAA,EANU;EAQhB,OAAA,EAAS,cAAA,qBAR0B;EAUnC,YAAA;AAAA;AAAA,KAGU,qBAAA;EALa,qBAOvB,MAAA,EAAQ,MAAA,EATF;EAWN,KAAA;AAAA;;KAIU,qBAAA;EACV,EAAA;EACA,MAAA;EACA,UAAA;EACA,YAAA;AAAA;AAAA,KAEU,yBAAA,GAA4B,gBAAA,CAAe,iBAAA,CAAkB,cAAA;AAAA,KAC7D,kBAAA,GAAqB,cAAA,CAAe,yBAAA;AAAA,KACpC,0BAAA,GAA6B,cAAA,CACvC,yBAAA,EACA,qBAAA;AAAA,KAGU,4BAAA;EAjBL,iDAmBL,QAAA,UAf+B;EAiB/B,SAAA,EAAW,wBAAA,EAjBoB;EAmB/B,WAAA,EAAa,qBAAA,IAjBb;EAmBA,YAAA,SAAqB,0BAAA,EAjBrB;EAmBA,mBAAA,SAA4B,0BAAA,EAnBhB;EAqBZ,YAAA;AAAA;AAAA,KAGU,cAAA;EAEN,QAAA;EACA,YAAA;EACA,OAAA;EACA,OAAA;EACA,cAAA;AAAA;EAGA,QAAA;EACA,YAAA,SAAqB,cAAA;EACrB,OAAA,EAAS,aAAA;EACT,OAAA,SAAgB,kBAAA;EAChB,cAAA,SAAuB,kBAAA;AAAA;AAAA,KAGjB,4BAAA;EArCqB,2BAuC/B,OAAA,KAtCU;EAwCV,UAAA,EAAY,4BAAA;EAEZ,YAAA,EAAc,cAAA;AAAA;;KAIJ,gBAAA;EA9C2C,iDAgDrD,QAAA,iBA/CA;EAiDA,eAAA,GAAkB,YAAA,EAhDG;EAkDrB,gBAAA,GAAmB,YAAA,EA/CT;EAiDV,kBAAA,GAAqB,YAAA;EAErB,cAAA,GAAiB,GAAA,GAAM,kBAAA;AAAA;AAAA,KAGb,oBAAA;EA5CkB,mDA8C5B,OAAA,GAAU,kBAAA,EA9C4C;EAiDtD,OAAA,GAAU,aAAA;EAvDV;;;;;EA8DA,mBAAA,IAAuB,IAAA,EAAM,gBAAA;EAxD7B;;;;;AAKF;;;;;;EAgEE,YAAA;AAAA"}
@@ -37,7 +37,11 @@ function buildDatasetOptions(ctx, opts) {
37
37
  });
38
38
  enrichmentCollection = enrichmentSources !== void 0 ? new require_column_collection_builder.ColumnCollectionBuilder(pframeSpec).addSources(enrichmentSources).build({ anchors: { main: datasetSpec } }) : void 0;
39
39
  const filterMatches = require_filter_discovery.findFilterColumns(filterCollection).filter((m) => filterPredicate(m.column.spec));
40
- const filters = filterMatches.length === 0 ? void 0 : require_filter_discovery.filterMatchesToOptions(filterMatches, refMap, opts?.labelOptions);
40
+ const filters = filterMatches.length === 0 ? void 0 : require_filter_discovery.filterMatchesToOptions(filterMatches, {
41
+ refsByObjectId: refMap,
42
+ datasetSpec,
43
+ labelOptions: opts?.labelOptions
44
+ });
41
45
  let enrichments;
42
46
  if (enrichmentCollection && withEnrichments) {
43
47
  const enrichmentVariants = require_enrichment_discovery.findEnrichmentColumns(enrichmentCollection, {
@@ -1 +1 @@
1
- {"version":3,"file":"build_dataset_options.cjs","names":["buildRefMap","ResultPoolColumnSnapshotProvider","collectCtxColumnSnapshotProviders","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 type { AnchoredColumnCollection } from \"../../columns/column_collection_builder\";\nimport { ColumnCollectionBuilder } from \"../../columns/column_collection_builder\";\nimport {\n ResultPoolColumnSnapshotProvider,\n collectCtxColumnSnapshotProviders,\n} 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\ntype SpecPredicateOption =\n | MultiColumnSelector\n | MultiColumnSelector[]\n | ((spec: PObjectSpec) => boolean);\n\nfunction toPredicate(opt: SpecPredicateOption | undefined): (spec: PObjectSpec) => boolean {\n if (opt === undefined) return () => true;\n return typeof opt === \"function\" ? opt : multiColumnSelectorsToPredicate(opt);\n}\n\nexport type BuildDatasetOptions = {\n /** Which result pool columns qualify as datasets. Defaults to all. */\n primary?: SpecPredicateOption;\n /**\n * Restricts which result pool columns are considered as filters. Intersected\n * with the built-in `pl7.app/isSubset: \"true\"` constraint. Defaults to\n * accept-all.\n */\n filter?: SpecPredicateOption;\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?: SpecPredicateOption;\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 primaryPredicate = toPredicate(opts?.primary);\n const filterPredicate = toPredicate(opts?.filter);\n\n const options = ctx.resultPool.getOptions(primaryPredicate, { refsWithEnrichments: true });\n if (options.length === 0) return [];\n\n const refMap = buildRefMap(ctx.resultPool.getSpecs().entries);\n const pframeSpec = ctx.getService(\"pframeSpec\");\n\n const withEnrichments = opts?.withEnrichments ?? false;\n const filterSource = new ResultPoolColumnSnapshotProvider(ctx.resultPool);\n // Hoisted out of the per-option loop: collectCtxColumnSnapshotProviders\n // walks the entire output tree, so calling it once per dataset option would\n // be O(N × tree).\n const enrichmentSources = withEnrichments ? collectCtxColumnSnapshotProviders(ctx) : undefined;\n\n return options.map((primary: Option): DatasetOption => {\n const datasetSpec = ctx.resultPool.getPColumnSpecByRef(primary.ref);\n if (!datasetSpec) return { primary };\n\n // Allocations happen inside try so a throw on the second build()\n // still disposes the first collection.\n let filterCollection: AnchoredColumnCollection | undefined;\n let enrichmentCollection: AnchoredColumnCollection | undefined;\n try {\n // ResultPoolColumnSnapshotProvider is always complete;\n // allowPartialColumnList narrows the return type to non-undefined.\n filterCollection = new ColumnCollectionBuilder(pframeSpec)\n .addSource(filterSource)\n .build({ anchors: { main: datasetSpec }, allowPartialColumnList: true });\n\n enrichmentCollection =\n enrichmentSources !== undefined\n ? new ColumnCollectionBuilder(pframeSpec)\n .addSources(enrichmentSources)\n .build({ anchors: { main: datasetSpec } })\n : undefined;\n\n const filterMatches = findFilterColumns(filterCollection).filter((m) =>\n filterPredicate(m.column.spec),\n );\n const filters =\n filterMatches.length === 0\n ? undefined\n : filterMatchesToOptions(filterMatches, refMap, opts?.labelOptions);\n\n let enrichments;\n if (enrichmentCollection && withEnrichments) {\n const enrichmentVariants = findEnrichmentColumns(enrichmentCollection, {\n maxHops: opts?.enrichmentMaxHops,\n ...(typeof withEnrichments === \"function\"\n ? { predicate: withEnrichments }\n : { include: 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 filterCollection?.dispose();\n enrichmentCollection?.dispose();\n }\n });\n}\n"],"mappings":";;;;;;;AAmBA,SAAS,YAAY,KAAsE;AACzF,KAAI,QAAQ,KAAA,EAAW,cAAa;AACpC,QAAO,OAAO,QAAQ,aAAa,OAAA,GAAA,gCAAA,iCAAsC,IAAI;;;;;;;;AA6B/E,SAAgB,oBACd,KACA,MAC6B;CAC7B,MAAM,mBAAmB,YAAY,MAAM,QAAQ;CACnD,MAAM,kBAAkB,YAAY,MAAM,OAAO;CAEjD,MAAM,UAAU,IAAI,WAAW,WAAW,kBAAkB,EAAE,qBAAqB,MAAM,CAAC;AAC1F,KAAI,QAAQ,WAAW,EAAG,QAAO,EAAE;CAEnC,MAAM,SAASA,yBAAAA,YAAY,IAAI,WAAW,UAAU,CAAC,QAAQ;CAC7D,MAAM,aAAa,IAAI,WAAW,aAAa;CAE/C,MAAM,kBAAkB,MAAM,mBAAmB;CACjD,MAAM,eAAe,IAAIC,2BAAAA,iCAAiC,IAAI,WAAW;CAIzE,MAAM,oBAAoB,kBAAkBC,2BAAAA,kCAAkC,IAAI,GAAG,KAAA;AAErF,QAAO,QAAQ,KAAK,YAAmC;EACrD,MAAM,cAAc,IAAI,WAAW,oBAAoB,QAAQ,IAAI;AACnE,MAAI,CAAC,YAAa,QAAO,EAAE,SAAS;EAIpC,IAAI;EACJ,IAAI;AACJ,MAAI;AAGF,sBAAmB,IAAIC,kCAAAA,wBAAwB,WAAW,CACvD,UAAU,aAAa,CACvB,MAAM;IAAE,SAAS,EAAE,MAAM,aAAa;IAAE,wBAAwB;IAAM,CAAC;AAE1E,0BACE,sBAAsB,KAAA,IAClB,IAAIA,kCAAAA,wBAAwB,WAAW,CACpC,WAAW,kBAAkB,CAC7B,MAAM,EAAE,SAAS,EAAE,MAAM,aAAa,EAAE,CAAC,GAC5C,KAAA;GAEN,MAAM,gBAAgBC,yBAAAA,kBAAkB,iBAAiB,CAAC,QAAQ,MAChE,gBAAgB,EAAE,OAAO,KAAK,CAC/B;GACD,MAAM,UACJ,cAAc,WAAW,IACrB,KAAA,IACAC,yBAAAA,uBAAuB,eAAe,QAAQ,MAAM,aAAa;GAEvE,IAAI;AACJ,OAAI,wBAAwB,iBAAiB;IAC3C,MAAM,qBAAqBC,6BAAAA,sBAAsB,sBAAsB;KACrE,SAAS,MAAM;KACf,GAAI,OAAO,oBAAoB,aAC3B,EAAE,WAAW,iBAAiB,GAC9B,EAAE,SAAS,iBAAiB;KACjC,CAAC;AACF,QAAI,mBAAmB,SAAS,EAC9B,eAAcC,6BAAAA,yBAAyB,oBAAoB,MAAM,aAAa;;AAIlF,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,qBAAkB,SAAS;AAC3B,yBAAsB,SAAS;;GAEjC"}
1
+ {"version":3,"file":"build_dataset_options.cjs","names":["buildRefMap","ResultPoolColumnSnapshotProvider","collectCtxColumnSnapshotProviders","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 type { AnchoredColumnCollection } from \"../../columns/column_collection_builder\";\nimport { ColumnCollectionBuilder } from \"../../columns/column_collection_builder\";\nimport {\n ResultPoolColumnSnapshotProvider,\n collectCtxColumnSnapshotProviders,\n} 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\ntype SpecPredicateOption =\n | MultiColumnSelector\n | MultiColumnSelector[]\n | ((spec: PObjectSpec) => boolean);\n\nfunction toPredicate(opt: SpecPredicateOption | undefined): (spec: PObjectSpec) => boolean {\n if (opt === undefined) return () => true;\n return typeof opt === \"function\" ? opt : multiColumnSelectorsToPredicate(opt);\n}\n\nexport type BuildDatasetOptions = {\n /** Which result pool columns qualify as datasets. Defaults to all. */\n primary?: SpecPredicateOption;\n /**\n * Restricts which result pool columns are considered as filters. Intersected\n * with the built-in `pl7.app/isSubset: \"true\"` constraint. Defaults to\n * accept-all.\n */\n filter?: SpecPredicateOption;\n /**\n * Formatting options forwarded to label derivation for both filter and\n * enrichment rows. `formatters.native` on the filter path is overridden\n * — see `FilterMatchOptions.labelOptions`.\n */\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?: SpecPredicateOption;\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 primaryPredicate = toPredicate(opts?.primary);\n const filterPredicate = toPredicate(opts?.filter);\n\n const options = ctx.resultPool.getOptions(primaryPredicate, { refsWithEnrichments: true });\n if (options.length === 0) return [];\n\n const refMap = buildRefMap(ctx.resultPool.getSpecs().entries);\n const pframeSpec = ctx.getService(\"pframeSpec\");\n\n const withEnrichments = opts?.withEnrichments ?? false;\n const filterSource = new ResultPoolColumnSnapshotProvider(ctx.resultPool);\n // Hoisted out of the per-option loop: collectCtxColumnSnapshotProviders\n // walks the entire output tree, so calling it once per dataset option would\n // be O(N × tree).\n const enrichmentSources = withEnrichments ? collectCtxColumnSnapshotProviders(ctx) : undefined;\n\n return options.map((primary: Option): DatasetOption => {\n const datasetSpec = ctx.resultPool.getPColumnSpecByRef(primary.ref);\n if (!datasetSpec) return { primary };\n\n // Allocations happen inside try so a throw on the second build()\n // still disposes the first collection.\n let filterCollection: AnchoredColumnCollection | undefined;\n let enrichmentCollection: AnchoredColumnCollection | undefined;\n try {\n // ResultPoolColumnSnapshotProvider is always complete;\n // allowPartialColumnList narrows the return type to non-undefined.\n filterCollection = new ColumnCollectionBuilder(pframeSpec)\n .addSource(filterSource)\n .build({ anchors: { main: datasetSpec }, allowPartialColumnList: true });\n\n enrichmentCollection =\n enrichmentSources !== undefined\n ? new ColumnCollectionBuilder(pframeSpec)\n .addSources(enrichmentSources)\n .build({ anchors: { main: datasetSpec } })\n : undefined;\n\n const filterMatches = findFilterColumns(filterCollection).filter((m) =>\n filterPredicate(m.column.spec),\n );\n const filters =\n filterMatches.length === 0\n ? undefined\n : filterMatchesToOptions(filterMatches, {\n refsByObjectId: refMap,\n datasetSpec,\n labelOptions: opts?.labelOptions,\n });\n\n let enrichments;\n if (enrichmentCollection && withEnrichments) {\n const enrichmentVariants = findEnrichmentColumns(enrichmentCollection, {\n maxHops: opts?.enrichmentMaxHops,\n ...(typeof withEnrichments === \"function\"\n ? { predicate: withEnrichments }\n : { include: 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 filterCollection?.dispose();\n enrichmentCollection?.dispose();\n }\n });\n}\n"],"mappings":";;;;;;;AAmBA,SAAS,YAAY,KAAsE;AACzF,KAAI,QAAQ,KAAA,EAAW,cAAa;AACpC,QAAO,OAAO,QAAQ,aAAa,OAAA,GAAA,gCAAA,iCAAsC,IAAI;;;;;;;;AAiC/E,SAAgB,oBACd,KACA,MAC6B;CAC7B,MAAM,mBAAmB,YAAY,MAAM,QAAQ;CACnD,MAAM,kBAAkB,YAAY,MAAM,OAAO;CAEjD,MAAM,UAAU,IAAI,WAAW,WAAW,kBAAkB,EAAE,qBAAqB,MAAM,CAAC;AAC1F,KAAI,QAAQ,WAAW,EAAG,QAAO,EAAE;CAEnC,MAAM,SAASA,yBAAAA,YAAY,IAAI,WAAW,UAAU,CAAC,QAAQ;CAC7D,MAAM,aAAa,IAAI,WAAW,aAAa;CAE/C,MAAM,kBAAkB,MAAM,mBAAmB;CACjD,MAAM,eAAe,IAAIC,2BAAAA,iCAAiC,IAAI,WAAW;CAIzE,MAAM,oBAAoB,kBAAkBC,2BAAAA,kCAAkC,IAAI,GAAG,KAAA;AAErF,QAAO,QAAQ,KAAK,YAAmC;EACrD,MAAM,cAAc,IAAI,WAAW,oBAAoB,QAAQ,IAAI;AACnE,MAAI,CAAC,YAAa,QAAO,EAAE,SAAS;EAIpC,IAAI;EACJ,IAAI;AACJ,MAAI;AAGF,sBAAmB,IAAIC,kCAAAA,wBAAwB,WAAW,CACvD,UAAU,aAAa,CACvB,MAAM;IAAE,SAAS,EAAE,MAAM,aAAa;IAAE,wBAAwB;IAAM,CAAC;AAE1E,0BACE,sBAAsB,KAAA,IAClB,IAAIA,kCAAAA,wBAAwB,WAAW,CACpC,WAAW,kBAAkB,CAC7B,MAAM,EAAE,SAAS,EAAE,MAAM,aAAa,EAAE,CAAC,GAC5C,KAAA;GAEN,MAAM,gBAAgBC,yBAAAA,kBAAkB,iBAAiB,CAAC,QAAQ,MAChE,gBAAgB,EAAE,OAAO,KAAK,CAC/B;GACD,MAAM,UACJ,cAAc,WAAW,IACrB,KAAA,IACAC,yBAAAA,uBAAuB,eAAe;IACpC,gBAAgB;IAChB;IACA,cAAc,MAAM;IACrB,CAAC;GAER,IAAI;AACJ,OAAI,wBAAwB,iBAAiB;IAC3C,MAAM,qBAAqBC,6BAAAA,sBAAsB,sBAAsB;KACrE,SAAS,MAAM;KACf,GAAI,OAAO,oBAAoB,aAC3B,EAAE,WAAW,iBAAiB,GAC9B,EAAE,SAAS,iBAAiB;KACjC,CAAC;AACF,QAAI,mBAAmB,SAAS,EAC9B,eAAcC,6BAAAA,yBAAyB,oBAAoB,MAAM,aAAa;;AAIlF,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,qBAAkB,SAAS;AAC3B,yBAAsB,SAAS;;GAEjC"}
@@ -12,7 +12,12 @@ type BuildDatasetOptions = {
12
12
  * with the built-in `pl7.app/isSubset: "true"` constraint. Defaults to
13
13
  * accept-all.
14
14
  */
15
- filter?: SpecPredicateOption; /** Formatting options for filter labels. */
15
+ filter?: SpecPredicateOption;
16
+ /**
17
+ * Formatting options forwarded to label derivation for both filter and
18
+ * enrichment rows. `formatters.native` on the filter path is overridden
19
+ * — see `FilterMatchOptions.labelOptions`.
20
+ */
16
21
  labelOptions?: DeriveLabelsOptions;
17
22
  /**
18
23
  * Enables enrichment discovery and filters hits attached to
@@ -1 +1 @@
1
- {"version":3,"file":"build_dataset_options.d.ts","names":[],"sources":["../../../src/components/PlDatasetSelector/build_dataset_options.ts"],"mappings":";;;;;;KAcK,mBAAA,GACD,mBAAA,GACA,mBAAA,OACE,IAAA,EAAM,WAAA;AAAA,KAOA,mBAAA;wEAEV,OAAA,GAAU,mBAAA;EAZY;;;;;EAkBtB,MAAA,GAAS,mBAAA,EAfY;EAiBrB,YAAA,GAAe,mBAAA;EAlBb;;;;EAuBF,eAAA,GAAkB,mBAAA,EAfR;EAiBV,iBAAA;AAAA;;;;;;;iBASc,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":";;;;;;KAcK,mBAAA,GACD,mBAAA,GACA,mBAAA,OACE,IAAA,EAAM,WAAA;AAAA,KAOA,mBAAA;wEAEV,OAAA,GAAU,mBAAA;EAZY;;;;;EAkBtB,MAAA,GAAS,mBAAA;EAfY;;;;;EAqBrB,YAAA,GAAe,mBAAA;EArBM;AAOvB;;;EAmBE,eAAA,GAAkB,mBAAA,EAXT;EAaT,iBAAA;AAAA;;;;;;;iBASc,mBAAA,CACd,GAAA,EAAK,aAAA,EACL,IAAA,GAAO,mBAAA,GACN,aAAA"}
@@ -36,7 +36,11 @@ function buildDatasetOptions(ctx, opts) {
36
36
  });
37
37
  enrichmentCollection = enrichmentSources !== void 0 ? new ColumnCollectionBuilder(pframeSpec).addSources(enrichmentSources).build({ anchors: { main: datasetSpec } }) : void 0;
38
38
  const filterMatches = findFilterColumns(filterCollection).filter((m) => filterPredicate(m.column.spec));
39
- const filters = filterMatches.length === 0 ? void 0 : filterMatchesToOptions(filterMatches, refMap, opts?.labelOptions);
39
+ const filters = filterMatches.length === 0 ? void 0 : filterMatchesToOptions(filterMatches, {
40
+ refsByObjectId: refMap,
41
+ datasetSpec,
42
+ labelOptions: opts?.labelOptions
43
+ });
40
44
  let enrichments;
41
45
  if (enrichmentCollection && withEnrichments) {
42
46
  const enrichmentVariants = findEnrichmentColumns(enrichmentCollection, {
@@ -1 +1 @@
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 type { AnchoredColumnCollection } from \"../../columns/column_collection_builder\";\nimport { ColumnCollectionBuilder } from \"../../columns/column_collection_builder\";\nimport {\n ResultPoolColumnSnapshotProvider,\n collectCtxColumnSnapshotProviders,\n} 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\ntype SpecPredicateOption =\n | MultiColumnSelector\n | MultiColumnSelector[]\n | ((spec: PObjectSpec) => boolean);\n\nfunction toPredicate(opt: SpecPredicateOption | undefined): (spec: PObjectSpec) => boolean {\n if (opt === undefined) return () => true;\n return typeof opt === \"function\" ? opt : multiColumnSelectorsToPredicate(opt);\n}\n\nexport type BuildDatasetOptions = {\n /** Which result pool columns qualify as datasets. Defaults to all. */\n primary?: SpecPredicateOption;\n /**\n * Restricts which result pool columns are considered as filters. Intersected\n * with the built-in `pl7.app/isSubset: \"true\"` constraint. Defaults to\n * accept-all.\n */\n filter?: SpecPredicateOption;\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?: SpecPredicateOption;\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 primaryPredicate = toPredicate(opts?.primary);\n const filterPredicate = toPredicate(opts?.filter);\n\n const options = ctx.resultPool.getOptions(primaryPredicate, { refsWithEnrichments: true });\n if (options.length === 0) return [];\n\n const refMap = buildRefMap(ctx.resultPool.getSpecs().entries);\n const pframeSpec = ctx.getService(\"pframeSpec\");\n\n const withEnrichments = opts?.withEnrichments ?? false;\n const filterSource = new ResultPoolColumnSnapshotProvider(ctx.resultPool);\n // Hoisted out of the per-option loop: collectCtxColumnSnapshotProviders\n // walks the entire output tree, so calling it once per dataset option would\n // be O(N × tree).\n const enrichmentSources = withEnrichments ? collectCtxColumnSnapshotProviders(ctx) : undefined;\n\n return options.map((primary: Option): DatasetOption => {\n const datasetSpec = ctx.resultPool.getPColumnSpecByRef(primary.ref);\n if (!datasetSpec) return { primary };\n\n // Allocations happen inside try so a throw on the second build()\n // still disposes the first collection.\n let filterCollection: AnchoredColumnCollection | undefined;\n let enrichmentCollection: AnchoredColumnCollection | undefined;\n try {\n // ResultPoolColumnSnapshotProvider is always complete;\n // allowPartialColumnList narrows the return type to non-undefined.\n filterCollection = new ColumnCollectionBuilder(pframeSpec)\n .addSource(filterSource)\n .build({ anchors: { main: datasetSpec }, allowPartialColumnList: true });\n\n enrichmentCollection =\n enrichmentSources !== undefined\n ? new ColumnCollectionBuilder(pframeSpec)\n .addSources(enrichmentSources)\n .build({ anchors: { main: datasetSpec } })\n : undefined;\n\n const filterMatches = findFilterColumns(filterCollection).filter((m) =>\n filterPredicate(m.column.spec),\n );\n const filters =\n filterMatches.length === 0\n ? undefined\n : filterMatchesToOptions(filterMatches, refMap, opts?.labelOptions);\n\n let enrichments;\n if (enrichmentCollection && withEnrichments) {\n const enrichmentVariants = findEnrichmentColumns(enrichmentCollection, {\n maxHops: opts?.enrichmentMaxHops,\n ...(typeof withEnrichments === \"function\"\n ? { predicate: withEnrichments }\n : { include: 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 filterCollection?.dispose();\n enrichmentCollection?.dispose();\n }\n });\n}\n"],"mappings":";;;;;;AAmBA,SAAS,YAAY,KAAsE;AACzF,KAAI,QAAQ,KAAA,EAAW,cAAa;AACpC,QAAO,OAAO,QAAQ,aAAa,MAAM,gCAAgC,IAAI;;;;;;;;AA6B/E,SAAgB,oBACd,KACA,MAC6B;CAC7B,MAAM,mBAAmB,YAAY,MAAM,QAAQ;CACnD,MAAM,kBAAkB,YAAY,MAAM,OAAO;CAEjD,MAAM,UAAU,IAAI,WAAW,WAAW,kBAAkB,EAAE,qBAAqB,MAAM,CAAC;AAC1F,KAAI,QAAQ,WAAW,EAAG,QAAO,EAAE;CAEnC,MAAM,SAAS,YAAY,IAAI,WAAW,UAAU,CAAC,QAAQ;CAC7D,MAAM,aAAa,IAAI,WAAW,aAAa;CAE/C,MAAM,kBAAkB,MAAM,mBAAmB;CACjD,MAAM,eAAe,IAAI,iCAAiC,IAAI,WAAW;CAIzE,MAAM,oBAAoB,kBAAkB,kCAAkC,IAAI,GAAG,KAAA;AAErF,QAAO,QAAQ,KAAK,YAAmC;EACrD,MAAM,cAAc,IAAI,WAAW,oBAAoB,QAAQ,IAAI;AACnE,MAAI,CAAC,YAAa,QAAO,EAAE,SAAS;EAIpC,IAAI;EACJ,IAAI;AACJ,MAAI;AAGF,sBAAmB,IAAI,wBAAwB,WAAW,CACvD,UAAU,aAAa,CACvB,MAAM;IAAE,SAAS,EAAE,MAAM,aAAa;IAAE,wBAAwB;IAAM,CAAC;AAE1E,0BACE,sBAAsB,KAAA,IAClB,IAAI,wBAAwB,WAAW,CACpC,WAAW,kBAAkB,CAC7B,MAAM,EAAE,SAAS,EAAE,MAAM,aAAa,EAAE,CAAC,GAC5C,KAAA;GAEN,MAAM,gBAAgB,kBAAkB,iBAAiB,CAAC,QAAQ,MAChE,gBAAgB,EAAE,OAAO,KAAK,CAC/B;GACD,MAAM,UACJ,cAAc,WAAW,IACrB,KAAA,IACA,uBAAuB,eAAe,QAAQ,MAAM,aAAa;GAEvE,IAAI;AACJ,OAAI,wBAAwB,iBAAiB;IAC3C,MAAM,qBAAqB,sBAAsB,sBAAsB;KACrE,SAAS,MAAM;KACf,GAAI,OAAO,oBAAoB,aAC3B,EAAE,WAAW,iBAAiB,GAC9B,EAAE,SAAS,iBAAiB;KACjC,CAAC;AACF,QAAI,mBAAmB,SAAS,EAC9B,eAAc,yBAAyB,oBAAoB,MAAM,aAAa;;AAIlF,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,qBAAkB,SAAS;AAC3B,yBAAsB,SAAS;;GAEjC"}
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 type { AnchoredColumnCollection } from \"../../columns/column_collection_builder\";\nimport { ColumnCollectionBuilder } from \"../../columns/column_collection_builder\";\nimport {\n ResultPoolColumnSnapshotProvider,\n collectCtxColumnSnapshotProviders,\n} 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\ntype SpecPredicateOption =\n | MultiColumnSelector\n | MultiColumnSelector[]\n | ((spec: PObjectSpec) => boolean);\n\nfunction toPredicate(opt: SpecPredicateOption | undefined): (spec: PObjectSpec) => boolean {\n if (opt === undefined) return () => true;\n return typeof opt === \"function\" ? opt : multiColumnSelectorsToPredicate(opt);\n}\n\nexport type BuildDatasetOptions = {\n /** Which result pool columns qualify as datasets. Defaults to all. */\n primary?: SpecPredicateOption;\n /**\n * Restricts which result pool columns are considered as filters. Intersected\n * with the built-in `pl7.app/isSubset: \"true\"` constraint. Defaults to\n * accept-all.\n */\n filter?: SpecPredicateOption;\n /**\n * Formatting options forwarded to label derivation for both filter and\n * enrichment rows. `formatters.native` on the filter path is overridden\n * — see `FilterMatchOptions.labelOptions`.\n */\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?: SpecPredicateOption;\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 primaryPredicate = toPredicate(opts?.primary);\n const filterPredicate = toPredicate(opts?.filter);\n\n const options = ctx.resultPool.getOptions(primaryPredicate, { refsWithEnrichments: true });\n if (options.length === 0) return [];\n\n const refMap = buildRefMap(ctx.resultPool.getSpecs().entries);\n const pframeSpec = ctx.getService(\"pframeSpec\");\n\n const withEnrichments = opts?.withEnrichments ?? false;\n const filterSource = new ResultPoolColumnSnapshotProvider(ctx.resultPool);\n // Hoisted out of the per-option loop: collectCtxColumnSnapshotProviders\n // walks the entire output tree, so calling it once per dataset option would\n // be O(N × tree).\n const enrichmentSources = withEnrichments ? collectCtxColumnSnapshotProviders(ctx) : undefined;\n\n return options.map((primary: Option): DatasetOption => {\n const datasetSpec = ctx.resultPool.getPColumnSpecByRef(primary.ref);\n if (!datasetSpec) return { primary };\n\n // Allocations happen inside try so a throw on the second build()\n // still disposes the first collection.\n let filterCollection: AnchoredColumnCollection | undefined;\n let enrichmentCollection: AnchoredColumnCollection | undefined;\n try {\n // ResultPoolColumnSnapshotProvider is always complete;\n // allowPartialColumnList narrows the return type to non-undefined.\n filterCollection = new ColumnCollectionBuilder(pframeSpec)\n .addSource(filterSource)\n .build({ anchors: { main: datasetSpec }, allowPartialColumnList: true });\n\n enrichmentCollection =\n enrichmentSources !== undefined\n ? new ColumnCollectionBuilder(pframeSpec)\n .addSources(enrichmentSources)\n .build({ anchors: { main: datasetSpec } })\n : undefined;\n\n const filterMatches = findFilterColumns(filterCollection).filter((m) =>\n filterPredicate(m.column.spec),\n );\n const filters =\n filterMatches.length === 0\n ? undefined\n : filterMatchesToOptions(filterMatches, {\n refsByObjectId: refMap,\n datasetSpec,\n labelOptions: opts?.labelOptions,\n });\n\n let enrichments;\n if (enrichmentCollection && withEnrichments) {\n const enrichmentVariants = findEnrichmentColumns(enrichmentCollection, {\n maxHops: opts?.enrichmentMaxHops,\n ...(typeof withEnrichments === \"function\"\n ? { predicate: withEnrichments }\n : { include: 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 filterCollection?.dispose();\n enrichmentCollection?.dispose();\n }\n });\n}\n"],"mappings":";;;;;;AAmBA,SAAS,YAAY,KAAsE;AACzF,KAAI,QAAQ,KAAA,EAAW,cAAa;AACpC,QAAO,OAAO,QAAQ,aAAa,MAAM,gCAAgC,IAAI;;;;;;;;AAiC/E,SAAgB,oBACd,KACA,MAC6B;CAC7B,MAAM,mBAAmB,YAAY,MAAM,QAAQ;CACnD,MAAM,kBAAkB,YAAY,MAAM,OAAO;CAEjD,MAAM,UAAU,IAAI,WAAW,WAAW,kBAAkB,EAAE,qBAAqB,MAAM,CAAC;AAC1F,KAAI,QAAQ,WAAW,EAAG,QAAO,EAAE;CAEnC,MAAM,SAAS,YAAY,IAAI,WAAW,UAAU,CAAC,QAAQ;CAC7D,MAAM,aAAa,IAAI,WAAW,aAAa;CAE/C,MAAM,kBAAkB,MAAM,mBAAmB;CACjD,MAAM,eAAe,IAAI,iCAAiC,IAAI,WAAW;CAIzE,MAAM,oBAAoB,kBAAkB,kCAAkC,IAAI,GAAG,KAAA;AAErF,QAAO,QAAQ,KAAK,YAAmC;EACrD,MAAM,cAAc,IAAI,WAAW,oBAAoB,QAAQ,IAAI;AACnE,MAAI,CAAC,YAAa,QAAO,EAAE,SAAS;EAIpC,IAAI;EACJ,IAAI;AACJ,MAAI;AAGF,sBAAmB,IAAI,wBAAwB,WAAW,CACvD,UAAU,aAAa,CACvB,MAAM;IAAE,SAAS,EAAE,MAAM,aAAa;IAAE,wBAAwB;IAAM,CAAC;AAE1E,0BACE,sBAAsB,KAAA,IAClB,IAAI,wBAAwB,WAAW,CACpC,WAAW,kBAAkB,CAC7B,MAAM,EAAE,SAAS,EAAE,MAAM,aAAa,EAAE,CAAC,GAC5C,KAAA;GAEN,MAAM,gBAAgB,kBAAkB,iBAAiB,CAAC,QAAQ,MAChE,gBAAgB,EAAE,OAAO,KAAK,CAC/B;GACD,MAAM,UACJ,cAAc,WAAW,IACrB,KAAA,IACA,uBAAuB,eAAe;IACpC,gBAAgB;IAChB;IACA,cAAc,MAAM;IACrB,CAAC;GAER,IAAI;AACJ,OAAI,wBAAwB,iBAAiB;IAC3C,MAAM,qBAAqB,sBAAsB,sBAAsB;KACrE,SAAS,MAAM;KACf,GAAI,OAAO,oBAAoB,aAC3B,EAAE,WAAW,iBAAiB,GAC9B,EAAE,SAAS,iBAAiB;KACjC,CAAC;AACF,QAAI,mBAAmB,SAAS,EAC9B,eAAc,yBAAyB,oBAAoB,MAAM,aAAa;;AAIlF,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,qBAAkB,SAAS;AAC3B,yBAAsB,SAAS;;GAEjC"}
@@ -5,12 +5,8 @@ let canonicalize = require("canonicalize");
5
5
  canonicalize = require_runtime.__toESM(canonicalize);
6
6
  //#region src/components/PlDatasetSelector/filter_discovery.ts
7
7
  /**
8
- * Matches columns annotated `pl7.app/isSubset: "true"` whose axes ⊆ anchor axes.
9
- *
10
- * The axes-subset constraint is enforced by `mode: "enrichment"`, which sets
11
- * `allowFloatingHitAxes: false` — every axis of the matched column must be
12
- * present in the anchor's axes. See `matchingModeToConstraints()` in
13
- * `column_collection_builder.ts`.
8
+ * Columns annotated `pl7.app/isSubset: "true"` whose axes ⊆ anchor axes.
9
+ * The axes-subset constraint comes from `mode: "enrichment"`.
14
10
  */
15
11
  function findFilterColumns(collection) {
16
12
  return collection.findColumns({
@@ -19,42 +15,37 @@ function findFilterColumns(collection) {
19
15
  });
20
16
  }
21
17
  /**
22
- * Derive labeled options from filter column matches, for use in DatasetOption.filters.
23
- *
24
- * Entries whose column id has no PlRef in `refsByObjectId` are silently
25
- * skipped — they cannot be exposed as user-selectable options.
26
- *
27
- * @param matches - from findFilterColumns()
28
- * @param refsByObjectId - from {@link buildRefMap}
29
- * @param labelOptions - forwarded to deriveDistinctLabels()
18
+ * Derive labels for filter column matches (for `DatasetOption.filters`).
19
+ * Matches whose column id is missing from `refsByObjectId` are silently
20
+ * dropped they cannot be exposed as selectable options.
30
21
  */
31
- function filterMatchesToOptions(matches, refsByObjectId, labelOptions) {
22
+ function filterMatchesToOptions(matches, options) {
32
23
  if (matches.length === 0) return [];
33
- const flattened = matches.flatMap((match) => {
24
+ const { refsByObjectId, datasetSpec, labelOptions } = options;
25
+ const entries = matches.flatMap((match) => {
34
26
  const ref = refsByObjectId.get(match.column.id);
35
27
  if (ref === void 0) return [];
36
28
  return match.variants.map((variant) => ({
37
- match,
38
- variant,
39
- ref
29
+ ref,
30
+ spec: match.column.spec,
31
+ linkerPath: variant.path.map((p) => ({ spec: p.linker.spec }))
40
32
  }));
41
33
  });
42
- const labels = require_derive_distinct_labels.deriveDistinctLabels(flattened.map(({ match, variant }) => ({
43
- spec: match.column.spec,
44
- linkerPath: variant.path.map((p) => ({ spec: p.linker.spec }))
45
- })), labelOptions);
46
- return flattened.map(({ ref }, i) => ({
34
+ const labels = require_derive_distinct_labels.deriveDistinctLabels([...entries, { spec: datasetSpec }], {
35
+ ...labelOptions,
36
+ formatters: {
37
+ ...labelOptions?.formatters,
38
+ native: () => void 0
39
+ }
40
+ });
41
+ return entries.map(({ ref }, i) => ({
47
42
  ref,
48
43
  label: labels[i]
49
44
  }));
50
45
  }
51
- /**
52
- * Usage: `buildRefMap(ctx.resultPool.getSpecs().entries)`
53
- */
46
+ /** Build the `refsByObjectId` map from `ctx.resultPool.getSpecs().entries`. */
54
47
  function buildRefMap(entries) {
55
- const map = /* @__PURE__ */ new Map();
56
- for (const entry of entries) map.set((0, canonicalize.default)(entry.ref), entry.ref);
57
- return map;
48
+ return new Map(entries.map((e) => [(0, canonicalize.default)(e.ref), e.ref]));
58
49
  }
59
50
  //#endregion
60
51
  exports.buildRefMap = buildRefMap;
@@ -1 +1 @@
1
- {"version":3,"file":"filter_discovery.cjs","names":["Annotation","deriveDistinctLabels"],"sources":["../../../src/components/PlDatasetSelector/filter_discovery.ts"],"sourcesContent":["import { Annotation } from \"@milaboratories/pl-model-common\";\nimport type { Option, PlRef, PObjectId } from \"@milaboratories/pl-model-common\";\nimport canonicalize from \"canonicalize\";\nimport type {\n AnchoredColumnCollection,\n ColumnMatch,\n} from \"../../columns/column_collection_builder\";\nimport {\n deriveDistinctLabels,\n type DeriveLabelsOptions,\n type Entry,\n} from \"../../labels/derive_distinct_labels\";\n\n/**\n * Matches columns annotated `pl7.app/isSubset: \"true\"` whose axes ⊆ anchor axes.\n *\n * The axes-subset constraint is enforced by `mode: \"enrichment\"`, which sets\n * `allowFloatingHitAxes: false` — every axis of the matched column must be\n * present in the anchor's axes. See `matchingModeToConstraints()` in\n * `column_collection_builder.ts`.\n */\nexport function findFilterColumns(collection: AnchoredColumnCollection): ColumnMatch[] {\n return collection.findColumns({\n mode: \"enrichment\",\n include: {\n annotations: { [Annotation.IsSubset]: \"true\" },\n },\n });\n}\n\n/**\n * Derive labeled options from filter column matches, for use in DatasetOption.filters.\n *\n * Entries whose column id has no PlRef in `refsByObjectId` are silently\n * skippedthey cannot be exposed as user-selectable options.\n *\n * @param matches - from findFilterColumns()\n * @param refsByObjectId - from {@link buildRefMap}\n * @param labelOptions - forwarded to deriveDistinctLabels()\n */\nexport function filterMatchesToOptions(\n matches: ColumnMatch[],\n refsByObjectId: ReadonlyMap<PObjectId, PlRef>,\n labelOptions?: DeriveLabelsOptions,\n): Option[] {\n if (matches.length === 0) return [];\n\n // Each ColumnMatch can be reached via multiple variants (different linker\n // paths / qualifications). We emit one Option per variant so the user can\n // pick a specific path `deriveDistinctLabels` disambiguates labels by\n // path. All variants of a match share a column id, so the ref lookup\n // happens once per match.\n const flattened = matches.flatMap((match) => {\n const ref = refsByObjectId.get(match.column.id);\n if (ref === undefined) return [];\n return match.variants.map((variant) => ({ match, variant, ref }));\n });\n\n const entries: Entry[] = flattened.map(({ match, variant }) => ({\n spec: match.column.spec,\n linkerPath: variant.path.map((p) => ({ spec: p.linker.spec })),\n }));\n\n const labels = deriveDistinctLabels(entries, labelOptions);\n\n return flattened.map(({ ref }, i) => ({ ref, label: labels[i] }));\n}\n\n/**\n * Usage: `buildRefMap(ctx.resultPool.getSpecs().entries)`\n */\nexport function buildRefMap(entries: readonly { readonly ref: PlRef }[]): Map<PObjectId, PlRef> {\n const map = new Map<PObjectId, PlRef>();\n for (const entry of entries) {\n map.set(canonicalize(entry.ref)! as PObjectId, entry.ref);\n }\n return map;\n}\n"],"mappings":";;;;;;;;;;;;;;AAqBA,SAAgB,kBAAkB,YAAqD;AACrF,QAAO,WAAW,YAAY;EAC5B,MAAM;EACN,SAAS,EACP,aAAa,GAAGA,gCAAAA,WAAW,WAAW,QAAQ,EAC/C;EACF,CAAC;;;;;;;;;;;;AAaJ,SAAgB,uBACd,SACA,gBACA,cACU;AACV,KAAI,QAAQ,WAAW,EAAG,QAAO,EAAE;CAOnC,MAAM,YAAY,QAAQ,SAAS,UAAU;EAC3C,MAAM,MAAM,eAAe,IAAI,MAAM,OAAO,GAAG;AAC/C,MAAI,QAAQ,KAAA,EAAW,QAAO,EAAE;AAChC,SAAO,MAAM,SAAS,KAAK,aAAa;GAAE;GAAO;GAAS;GAAK,EAAE;GACjE;CAOF,MAAM,SAASC,+BAAAA,qBALU,UAAU,KAAK,EAAE,OAAO,eAAe;EAC9D,MAAM,MAAM,OAAO;EACnB,YAAY,QAAQ,KAAK,KAAK,OAAO,EAAE,MAAM,EAAE,OAAO,MAAM,EAAE;EAC/D,EAAE,EAE0C,aAAa;AAE1D,QAAO,UAAU,KAAK,EAAE,OAAO,OAAO;EAAE;EAAK,OAAO,OAAO;EAAI,EAAE;;;;;AAMnE,SAAgB,YAAY,SAAoE;CAC9F,MAAM,sBAAM,IAAI,KAAuB;AACvC,MAAK,MAAM,SAAS,QAClB,KAAI,KAAA,GAAA,aAAA,SAAiB,MAAM,IAAI,EAAgB,MAAM,IAAI;AAE3D,QAAO"}
1
+ {"version":3,"file":"filter_discovery.cjs","names":["Annotation","deriveDistinctLabels"],"sources":["../../../src/components/PlDatasetSelector/filter_discovery.ts"],"sourcesContent":["import { Annotation } from \"@milaboratories/pl-model-common\";\nimport type { Option, PlRef, PObjectId, PObjectSpec } from \"@milaboratories/pl-model-common\";\nimport canonicalize from \"canonicalize\";\nimport type {\n AnchoredColumnCollection,\n ColumnMatch,\n} from \"../../columns/column_collection_builder\";\nimport {\n deriveDistinctLabels,\n type DeriveLabelsOptions,\n type Entry,\n} from \"../../labels/derive_distinct_labels\";\n\n/**\n * Columns annotated `pl7.app/isSubset: \"true\"` whose axes ⊆ anchor axes.\n * The axes-subset constraint comes from `mode: \"enrichment\"`.\n */\nexport function findFilterColumns(collection: AnchoredColumnCollection): ColumnMatch[] {\n return collection.findColumns({\n mode: \"enrichment\",\n include: {\n annotations: { [Annotation.IsSubset]: \"true\" },\n },\n });\n}\n\nexport type FilterMatchOptions = {\n /** Maps result-pool column id back to its source PlRef (see {@link buildRefMap}). */\n refsByObjectId: ReadonlyMap<PObjectId, PlRef>;\n /** Spec of the dataset the filters are subsets of. */\n datasetSpec: PObjectSpec;\n /**\n * Forwarded to `deriveDistinctLabels`. Any `formatters.native` caller\n * sets is silently overridden the function relies on a no-op native\n * formatter to keep the algorithm from short-circuiting on filters'\n * inherited `pl7.app/label`.\n */\n labelOptions?: DeriveLabelsOptions;\n};\n\n/**\n * Derive labels for filter column matches (for `DatasetOption.filters`).\n * Matches whose column id is missing from `refsByObjectId` are silently\n * dropped they cannot be exposed as selectable options.\n */\nexport function filterMatchesToOptions(\n matches: ColumnMatch[],\n options: FilterMatchOptions,\n): Option[] {\n if (matches.length === 0) return [];\n\n const { refsByObjectId, datasetSpec, labelOptions } = options;\n\n // One entry per match-variant (different paths to the same column are\n // exposed as separate Options). The `ref` field rides along on the\n // Entry-shaped objects via structural typing; `deriveDistinctLabels`\n // ignores extra fields.\n const entries = matches.flatMap((match): (Entry & { ref: PlRef })[] => {\n const ref = refsByObjectId.get(match.column.id);\n if (ref === undefined) return [];\n return match.variants.map((variant) => ({\n ref,\n spec: match.column.spec,\n linkerPath: variant.path.map((p) => ({ spec: p.linker.spec })),\n }));\n });\n\n // Appending the dataset forces a discriminating trace step into every\n // filter label (yielding e.g. \"Bulk / Top 10\"); the dataset's own label\n // is dropped because we only zip `entries`. Native label is force-\n // suppressed (the override sits after caller's spread) — filters\n // inherit the dataset's `pl7.app/label` and would otherwise satisfy\n // uniqueness before any trace step is consulted.\n const labels = deriveDistinctLabels([...entries, { spec: datasetSpec }], {\n ...labelOptions,\n formatters: { ...labelOptions?.formatters, native: () => undefined },\n });\n\n return entries.map(({ ref }, i) => ({ ref, label: labels[i] }));\n}\n\n/** Build the `refsByObjectId` map from `ctx.resultPool.getSpecs().entries`. */\nexport function buildRefMap(entries: readonly { readonly ref: PlRef }[]): Map<PObjectId, PlRef> {\n return new Map(entries.map((e) => [canonicalize(e.ref)! as PObjectId, e.ref]));\n}\n"],"mappings":";;;;;;;;;;AAiBA,SAAgB,kBAAkB,YAAqD;AACrF,QAAO,WAAW,YAAY;EAC5B,MAAM;EACN,SAAS,EACP,aAAa,GAAGA,gCAAAA,WAAW,WAAW,QAAQ,EAC/C;EACF,CAAC;;;;;;;AAsBJ,SAAgB,uBACd,SACA,SACU;AACV,KAAI,QAAQ,WAAW,EAAG,QAAO,EAAE;CAEnC,MAAM,EAAE,gBAAgB,aAAa,iBAAiB;CAMtD,MAAM,UAAU,QAAQ,SAAS,UAAsC;EACrE,MAAM,MAAM,eAAe,IAAI,MAAM,OAAO,GAAG;AAC/C,MAAI,QAAQ,KAAA,EAAW,QAAO,EAAE;AAChC,SAAO,MAAM,SAAS,KAAK,aAAa;GACtC;GACA,MAAM,MAAM,OAAO;GACnB,YAAY,QAAQ,KAAK,KAAK,OAAO,EAAE,MAAM,EAAE,OAAO,MAAM,EAAE;GAC/D,EAAE;GACH;CAQF,MAAM,SAASC,+BAAAA,qBAAqB,CAAC,GAAG,SAAS,EAAE,MAAM,aAAa,CAAC,EAAE;EACvE,GAAG;EACH,YAAY;GAAE,GAAG,cAAc;GAAY,cAAc,KAAA;GAAW;EACrE,CAAC;AAEF,QAAO,QAAQ,KAAK,EAAE,OAAO,OAAO;EAAE;EAAK,OAAO,OAAO;EAAI,EAAE;;;AAIjE,SAAgB,YAAY,SAAoE;AAC9F,QAAO,IAAI,IAAI,QAAQ,KAAK,MAAM,EAAA,GAAA,aAAA,SAAc,EAAE,IAAI,EAAgB,EAAE,IAAI,CAAC,CAAC"}
@@ -1,34 +1,34 @@
1
1
  import { AnchoredColumnCollection, ColumnMatch } from "../../columns/column_collection_builder.js";
2
2
  import { DeriveLabelsOptions } from "../../labels/derive_distinct_labels.js";
3
- import { Option, PObjectId, PlRef } from "@milaboratories/pl-model-common";
3
+ import { Option, PObjectId, PObjectSpec, PlRef } from "@milaboratories/pl-model-common";
4
4
 
5
5
  //#region src/components/PlDatasetSelector/filter_discovery.d.ts
6
6
  /**
7
- * Matches columns annotated `pl7.app/isSubset: "true"` whose axes ⊆ anchor axes.
8
- *
9
- * The axes-subset constraint is enforced by `mode: "enrichment"`, which sets
10
- * `allowFloatingHitAxes: false` — every axis of the matched column must be
11
- * present in the anchor's axes. See `matchingModeToConstraints()` in
12
- * `column_collection_builder.ts`.
7
+ * Columns annotated `pl7.app/isSubset: "true"` whose axes ⊆ anchor axes.
8
+ * The axes-subset constraint comes from `mode: "enrichment"`.
13
9
  */
14
10
  declare function findFilterColumns(collection: AnchoredColumnCollection): ColumnMatch[];
11
+ type FilterMatchOptions = {
12
+ /** Maps result-pool column id back to its source PlRef (see {@link buildRefMap}). */refsByObjectId: ReadonlyMap<PObjectId, PlRef>; /** Spec of the dataset the filters are subsets of. */
13
+ datasetSpec: PObjectSpec;
14
+ /**
15
+ * Forwarded to `deriveDistinctLabels`. Any `formatters.native` caller
16
+ * sets is silently overridden — the function relies on a no-op native
17
+ * formatter to keep the algorithm from short-circuiting on filters'
18
+ * inherited `pl7.app/label`.
19
+ */
20
+ labelOptions?: DeriveLabelsOptions;
21
+ };
15
22
  /**
16
- * Derive labeled options from filter column matches, for use in DatasetOption.filters.
17
- *
18
- * Entries whose column id has no PlRef in `refsByObjectId` are silently
19
- * skipped — they cannot be exposed as user-selectable options.
20
- *
21
- * @param matches - from findFilterColumns()
22
- * @param refsByObjectId - from {@link buildRefMap}
23
- * @param labelOptions - forwarded to deriveDistinctLabels()
24
- */
25
- declare function filterMatchesToOptions(matches: ColumnMatch[], refsByObjectId: ReadonlyMap<PObjectId, PlRef>, labelOptions?: DeriveLabelsOptions): Option[];
26
- /**
27
- * Usage: `buildRefMap(ctx.resultPool.getSpecs().entries)`
23
+ * Derive labels for filter column matches (for `DatasetOption.filters`).
24
+ * Matches whose column id is missing from `refsByObjectId` are silently
25
+ * dropped they cannot be exposed as selectable options.
28
26
  */
27
+ declare function filterMatchesToOptions(matches: ColumnMatch[], options: FilterMatchOptions): Option[];
28
+ /** Build the `refsByObjectId` map from `ctx.resultPool.getSpecs().entries`. */
29
29
  declare function buildRefMap(entries: readonly {
30
30
  readonly ref: PlRef;
31
31
  }[]): Map<PObjectId, PlRef>;
32
32
  //#endregion
33
- export { buildRefMap, filterMatchesToOptions, findFilterColumns };
33
+ export { FilterMatchOptions, buildRefMap, filterMatchesToOptions, findFilterColumns };
34
34
  //# sourceMappingURL=filter_discovery.d.ts.map