@platforma-sdk/model 1.51.2 → 1.51.6

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.
@@ -211,13 +211,13 @@ function createPlDataTableV2(ctx, columns, tableState, ops) {
211
211
  ctx.logWarn(`Partition filter ${JSON.stringify(f)} does not match provided columns, skipping`);
212
212
  return valid;
213
213
  });
214
- const filters = plModelCommon.uniqueBy([...(ops?.filters ?? []), ...tableStateNormalized.pTableParams.filters], (f) => plModelCommon.canonicalizeJson(f.column)).filter((f) => {
214
+ const filters = plModelCommon.uniqueBy([...tableStateNormalized.pTableParams.filters, ...(ops?.filters ?? [])], (f) => plModelCommon.canonicalizeJson(f.column)).filter((f) => {
215
215
  const valid = isValidColumnId(f.column);
216
216
  if (!valid)
217
217
  ctx.logWarn(`Filter ${JSON.stringify(f)} does not match provided columns, skipping`);
218
218
  return valid;
219
219
  });
220
- const sorting = plModelCommon.uniqueBy([...(ops?.sorting ?? []), ...tableStateNormalized.pTableParams.sorting], (s) => plModelCommon.canonicalizeJson(s.column)).filter((s) => {
220
+ const sorting = plModelCommon.uniqueBy([...tableStateNormalized.pTableParams.sorting, ...(ops?.sorting ?? [])], (s) => plModelCommon.canonicalizeJson(s.column)).filter((s) => {
221
221
  const valid = isValidColumnId(s.column);
222
222
  if (!valid)
223
223
  ctx.logWarn(`Sorting ${JSON.stringify(s)} does not match provided columns, skipping`);
@@ -1 +1 @@
1
- {"version":3,"file":"PlDataTable.cjs","sources":["../../src/components/PlDataTable.ts"],"sourcesContent":["import type {\n AxisId,\n AxisSpec,\n CanonicalizedJson,\n DataInfo,\n ListOptionBase,\n PColumn,\n PColumnIdAndSpec,\n PColumnValues,\n PObjectId,\n PTableColumnId,\n PTableColumnIdAxis,\n PTableColumnIdColumn,\n PTableColumnSpec,\n PTableDef,\n PTableHandle,\n PTableRecordFilter,\n PTableRecordSingleValueFilterV2,\n PTableSorting,\n} from '@milaboratories/pl-model-common';\nimport {\n Annotation,\n canonicalizeJson,\n getAxisId,\n getColumnIdAndSpec,\n isLabelColumn,\n isLinkerColumn,\n matchAxisId,\n PColumnName,\n readAnnotation,\n uniqueBy,\n} from '@milaboratories/pl-model-common';\nimport type {\n AxisLabelProvider,\n ColumnProvider,\n PColumnDataUniversal,\n RenderCtx,\n TreeNodeAccessor,\n} from '../render';\nimport {\n allPColumnsReady,\n deriveLabels,\n PColumnCollection,\n} from '../render';\nimport { identity } from 'es-toolkit';\n\nexport type PlTableColumnId = {\n /** Original column spec */\n source: PTableColumnSpec;\n /** Column spec with labeled axes replaced by label columns */\n labeled: PTableColumnSpec;\n};\n\nexport type PlTableColumnIdJson = CanonicalizedJson<PlTableColumnId>;\n\nexport type PlDataTableGridStateCore = {\n /** Includes column ordering */\n columnOrder?: {\n /** All colIds in order */\n orderedColIds: PlTableColumnIdJson[];\n };\n /** Includes current sort columns and direction */\n sort?: {\n /** Sorted columns and directions in order */\n sortModel: {\n /** Column Id to apply the sort to. */\n colId: PlTableColumnIdJson;\n /** Sort direction */\n sort: 'asc' | 'desc';\n }[];\n };\n /** Includes column visibility */\n columnVisibility?: {\n /** All colIds which were hidden */\n hiddenColIds: PlTableColumnIdJson[];\n };\n};\n\nexport type PlDataTableSheet = {\n /** spec of the axis to use */\n axis: AxisSpec;\n /** options to show in the filter dropdown */\n options: ListOptionBase<string | number>[];\n /** default (selected) value */\n defaultValue?: string | number;\n};\n\nexport type PlDataTableSheetState = {\n /** id of the axis */\n axisId: AxisId;\n /** selected value */\n value: string | number;\n};\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 // Normalized state\n | PlDataTableStateV2Normalized;\n\nexport type PlDataTableStateV2CacheEntry = {\n /** DataSource identifier for state management */\n sourceId: string;\n /** Internal ag-grid state */\n gridState: PlDataTableGridStateCore;\n /** Sheets state */\n sheetsState: PlDataTableSheetState[];\n /** Filters state */\n filtersState: PlDataTableFilterState[];\n};\n\nexport type PTableParamsV2 =\n | {\n sourceId: null;\n hiddenColIds: null;\n partitionFilters: [];\n filters: [];\n sorting: [];\n }\n | {\n sourceId: string;\n hiddenColIds: PObjectId[] | null;\n partitionFilters: PTableRecordFilter[];\n filters: PTableRecordFilter[];\n sorting: PTableSorting[];\n };\n\nexport type PlDataTableStateV2Normalized = {\n /** Version for upgrades */\n version: 4;\n /** Internal states, LRU cache for 5 sourceId-s */\n stateCache: PlDataTableStateV2CacheEntry[];\n /** PTable params derived from the cache state for the current sourceId */\n pTableParams: PTableParamsV2;\n};\n\nexport function makeDefaultPTableParams(): PTableParamsV2 {\n return {\n sourceId: null,\n hiddenColIds: null,\n partitionFilters: [],\n filters: [],\n sorting: [],\n };\n}\n\n/** Create default PlDataTableStateV2 */\nexport function createPlDataTableStateV2(): PlDataTableStateV2Normalized {\n return {\n version: 4,\n stateCache: [],\n pTableParams: makeDefaultPTableParams(),\n };\n}\n\n/** Upgrade PlDataTableStateV2 to the latest version */\nexport function upgradePlDataTableStateV2(state: PlDataTableStateV2 | undefined): 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: makeDefaultPTableParams(),\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 return state;\n}\n\nexport type PlDataTableFilterState = {\n id: PTableColumnId;\n alphabetic: boolean;\n filter: null | {\n value: PlTableFilter;\n disabled: boolean;\n };\n};\n\n/** PlTableFilters filter entry */\nexport type PlTableFilterIsNotNA = {\n /** Predicate type */\n type: 'isNotNA';\n};\n\n/** PlTableFilters filter entry */\nexport type PlTableFilterIsNA = {\n /** Predicate type */\n type: 'isNA';\n};\n\n/** PlTableFilters filter entries applicable to both string and number values */\nexport type PlTableFilterCommon = PlTableFilterIsNotNA | PlTableFilterIsNA;\n\n/** PlTableFilters numeric filter entry */\nexport type PlTableFilterNumberEquals = {\n /** Predicate type */\n type: 'number_equals';\n /** Reference value */\n reference: number;\n};\n\n/** PlTableFilters numeric filter entry */\nexport type PlTableFilterNumberNotEquals = {\n /** Predicate type */\n type: 'number_notEquals';\n /** Reference value */\n reference: number;\n};\n\n/** PlTableFilters numeric filter entry */\nexport type PlTableFilterNumberGreaterThan = {\n /** Predicate type */\n type: 'number_greaterThan';\n /** Reference value */\n reference: number;\n};\n\n/** PlTableFilters numeric filter entry */\nexport type PlTableFilterNumberGreaterThanOrEqualTo = {\n /** Predicate type */\n type: 'number_greaterThanOrEqualTo';\n /** Reference value */\n reference: number;\n};\n\n/** PlTableFilters numeric filter entry */\nexport type PlTableFilterNumberLessThan = {\n /** Predicate type */\n type: 'number_lessThan';\n /** Reference value */\n reference: number;\n};\n\n/** PlTableFilters numeric filter entry */\nexport type PlTableFilterNumberLessThanOrEqualTo = {\n /** Predicate type */\n type: 'number_lessThanOrEqualTo';\n /** Reference value */\n reference: number;\n};\n\n/** PlTableFilters numeric filter entry */\nexport type PlTableFilterNumberBetween = {\n /** Predicate type */\n type: 'number_between';\n /** Reference value for the lower bound */\n lowerBound: number;\n /** Defines whether values equal to lower bound reference value should be matched */\n includeLowerBound: boolean;\n /** Reference value for the upper bound */\n upperBound: number;\n /** Defines whether values equal to upper bound reference value should be matched */\n includeUpperBound: boolean;\n};\n\n/** All PlTableFilters numeric filter entries */\nexport type PlTableFilterNumber =\n | PlTableFilterCommon\n | PlTableFilterNumberEquals\n | PlTableFilterNumberNotEquals\n | PlTableFilterNumberGreaterThan\n | PlTableFilterNumberGreaterThanOrEqualTo\n | PlTableFilterNumberLessThan\n | PlTableFilterNumberLessThanOrEqualTo\n | PlTableFilterNumberBetween;\n/** All types of PlTableFilters numeric filter entries */\nexport type PlTableFilterNumberType = PlTableFilterNumber['type'];\n\n/** PlTableFilters string filter entry */\nexport type PlTableFilterStringEquals = {\n /** Predicate type */\n type: 'string_equals';\n /** Reference value */\n reference: string;\n};\n\n/** PlTableFilters string filter entry */\nexport type PlTableFilterStringNotEquals = {\n /** Predicate type */\n type: 'string_notEquals';\n /** Reference value */\n reference: string;\n};\n\n/** PlTableFilters string filter entry */\nexport type PlTableFilterStringContains = {\n /** Predicate type */\n type: 'string_contains';\n /** Reference value */\n reference: string;\n};\n\n/** PlTableFilters string filter entry */\nexport type PlTableFilterStringDoesNotContain = {\n /** Predicate type */\n type: 'string_doesNotContain';\n /** Reference value */\n reference: string;\n};\n\n/** PlTableFilters string filter entry */\nexport type PlTableFilterStringMatches = {\n /** Predicate type */\n type: 'string_matches';\n /** Reference value */\n reference: string;\n};\n\n/** PlTableFilters string filter entry */\nexport type PlTableFilterStringDoesNotMatch = {\n /** Predicate type */\n type: 'string_doesNotMatch';\n /** Reference value */\n reference: string;\n};\n\n/** PlTableFilters string filter entry */\nexport type PlTableFilterStringContainsFuzzyMatch = {\n /** Predicate type */\n type: 'string_containsFuzzyMatch';\n /** Reference value */\n reference: string;\n /**\n * Maximum acceptable edit distance between reference value and matched substring\n * @see https://en.wikipedia.org/wiki/Edit_distance\n */\n maxEdits: number;\n /**\n * When {@link substitutionsOnly} is set to false\n * Levenshtein distance is used as edit distance (substitutions and indels)\n * @see https://en.wikipedia.org/wiki/Levenshtein_distance\n * When {@link substitutionsOnly} is set to true\n * Hamming distance is used as edit distance (substitutions only)\n * @see https://en.wikipedia.org/wiki/Hamming_distance\n */\n substitutionsOnly: boolean;\n /**\n * Single character in {@link reference} that will labelColumn any\n * single character in searched text.\n */\n wildcard?: string;\n};\n\n/** All PlTableFilters string filter entries */\nexport type PlTableFilterString =\n | PlTableFilterCommon\n | PlTableFilterStringEquals\n | PlTableFilterStringNotEquals\n | PlTableFilterStringContains\n | PlTableFilterStringDoesNotContain\n | PlTableFilterStringMatches\n | PlTableFilterStringDoesNotMatch\n | PlTableFilterStringContainsFuzzyMatch;\n/** All types of PlTableFilters string filter entries */\nexport type PlTableFilterStringType = PlTableFilterString['type'];\n\n/** All PlTableFilters filter entries */\nexport type PlTableFilter = PlTableFilterNumber | PlTableFilterString;\n/** All types of PlTableFilters filter entries */\nexport type PlTableFilterType = PlTableFilter['type'];\n\nexport type CreatePlDataTableOps = {\n /** Filters for columns and non-partitioned axes */\n filters?: PTableRecordFilter[];\n\n /** Sorting to columns hidden from user */\n sorting?: PTableSorting[];\n\n /**\n * Selects columns for which will be inner-joined to the table.\n *\n * Default behaviour: all columns are considered to be core\n */\n coreColumnPredicate?: (spec: PColumnIdAndSpec) => boolean;\n\n /**\n * Determines how core columns should be joined together:\n * inner - so user will only see records present in all core columns\n * full - so user will only see records present in any of the core columns\n *\n * All non-core columns will be left joined to the table produced by the core\n * columns, in other words records form the pool of non-core columns will only\n * make their way into the final table if core table contains corresponding key.\n *\n * Default: 'full'\n */\n coreJoinType?: 'inner' | 'full';\n};\n\n/** Get all label columns from the result pool */\nexport function getAllLabelColumns(\n resultPool: AxisLabelProvider & ColumnProvider,\n): PColumn<PColumnDataUniversal>[] | undefined {\n return new PColumnCollection()\n .addAxisLabelProvider(resultPool)\n .addColumnProvider(resultPool)\n .getColumns({\n name: PColumnName.Label,\n axes: [{}], // exactly one axis\n }, { dontWaitAllData: true, overrideLabelAnnotation: false });\n}\n\n/** Get label columns matching the provided columns from the result pool */\nexport function getMatchingLabelColumns(\n columns: PColumnIdAndSpec[],\n allLabelColumns: PColumn<PColumnDataUniversal>[],\n): PColumn<PColumnDataUniversal>[] {\n // split input columns into label and value columns\n const inputLabelColumns: typeof columns = [];\n const inputValueColumns: typeof columns = [];\n for (const column of columns) {\n if (isLabelColumn(column.spec)) {\n inputLabelColumns.push(column);\n } else {\n inputValueColumns.push(column);\n }\n }\n\n // collect distinct axes of value columns\n const unlabeledAxes: AxisId[] = [];\n for (const column of inputValueColumns) {\n for (const axis of column.spec.axesSpec) {\n const axisId = getAxisId(axis);\n if (!unlabeledAxes.some((id) => matchAxisId(id, axisId))) {\n unlabeledAxes.push(axisId);\n }\n }\n }\n\n // remove axes matched by input label columns\n for (const labelColumn of inputLabelColumns) {\n const labelAxisId = getAxisId(labelColumn.spec.axesSpec[0]);\n const labelMatch = unlabeledAxes.findIndex((axisId) => matchAxisId(axisId, labelAxisId));\n if (labelMatch !== -1) {\n unlabeledAxes.splice(labelMatch, 1);\n }\n }\n\n // warning: changing this id will break backward compatibility\n const colId = (id: PObjectId, domain?: Record<string, string>): PObjectId => {\n let wid = id.toString();\n if (domain) {\n for (const k in domain) {\n wid += k;\n wid += domain[k];\n }\n }\n return wid as PObjectId;\n };\n\n // search label columns for unmatched axes\n const labelColumns: typeof allLabelColumns = [];\n for (const labelColumn of allLabelColumns) {\n const labelAxis = labelColumn.spec.axesSpec[0];\n const labelAxisId = getAxisId(labelAxis);\n const labelMatch = unlabeledAxes.findIndex((axisId) => matchAxisId(axisId, labelAxisId));\n if (labelMatch !== -1) {\n const axisId = unlabeledAxes[labelMatch];\n const dataDomainLen = Object.keys(axisId.domain ?? {}).length;\n const labelDomainLen = Object.keys(labelAxis.domain ?? {}).length;\n if (dataDomainLen > labelDomainLen) {\n labelColumns.push({\n id: colId(labelColumn.id, axisId.domain),\n spec: {\n ...labelColumn.spec,\n axesSpec: [{ ...axisId, annotations: labelAxis.annotations }],\n },\n data: labelColumn.data,\n });\n } else {\n labelColumns.push(labelColumn);\n }\n unlabeledAxes.splice(labelMatch, 1);\n }\n }\n return labelColumns;\n}\n\nfunction createPTableDef(params: {\n columns: PColumn<PColumnDataUniversal>[];\n labelColumns: PColumn<PColumnDataUniversal>[];\n coreJoinType: 'inner' | 'full';\n partitionFilters: PTableRecordSingleValueFilterV2[];\n filters: PTableRecordSingleValueFilterV2[];\n sorting: PTableSorting[];\n coreColumnPredicate?: ((spec: PColumnIdAndSpec) => boolean);\n}): PTableDef<PColumn<TreeNodeAccessor | PColumnValues | DataInfo<TreeNodeAccessor>>> {\n let coreColumns = params.columns;\n const secondaryColumns: typeof params.columns = [];\n\n if (params.coreColumnPredicate) {\n coreColumns = [];\n for (const c of params.columns)\n if (params.coreColumnPredicate(getColumnIdAndSpec(c))) coreColumns.push(c);\n else secondaryColumns.push(c);\n }\n\n secondaryColumns.push(...params.labelColumns);\n\n return {\n src: {\n type: 'outer',\n primary: {\n type: params.coreJoinType,\n entries: coreColumns.map((c) => ({ type: 'column', column: c })),\n },\n secondary: secondaryColumns.map((c) => ({ type: 'column', column: c })),\n },\n partitionFilters: params.partitionFilters,\n filters: params.filters,\n sorting: params.sorting,\n };\n}\n\n/** PlAgDataTable model */\nexport type PlDataTableModel = {\n /** DataSource identifier for state management */\n sourceId: string | null;\n /** p-table including all columns, used to show the full specification of the table */\n fullTableHandle: PTableHandle;\n /** p-table including only visible columns, used to get the data */\n visibleTableHandle: PTableHandle;\n};\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/**\n * Create p-table spec and handle given ui table state\n *\n * @param ctx context\n * @param columns column list\n * @param tableState table ui state\n * @returns PlAgDataTableV2 table source\n */\nexport function createPlDataTableV2<A, U>(\n ctx: RenderCtx<A, U>,\n columns: PColumn<PColumnDataUniversal>[],\n tableState: PlDataTableStateV2 | undefined,\n ops?: CreatePlDataTableOps,\n): PlDataTableModel | undefined {\n if (columns.length === 0) return undefined;\n\n const tableStateNormalized = upgradePlDataTableStateV2(tableState);\n\n const allLabelColumns = getAllLabelColumns(ctx.resultPool);\n if (!allLabelColumns) return undefined;\n\n let fullLabelColumns = getMatchingLabelColumns(columns.map(getColumnIdAndSpec), allLabelColumns);\n fullLabelColumns = deriveLabels(fullLabelColumns, identity, { includeNativeLabel: true }).map((v) => {\n return {\n ...v.value,\n spec: {\n ...v.value.spec,\n annotations: {\n ...v.value.spec.annotations,\n [Annotation.Label]: v.label,\n },\n },\n };\n });\n\n const fullColumns = [...columns, ...fullLabelColumns];\n\n const fullColumnsAxes = uniqueBy(\n fullColumns.flatMap((c) => c.spec.axesSpec.map((a) => getAxisId(a))),\n (a) => canonicalizeJson<AxisId>(a),\n );\n const fullColumnsIds: PTableColumnId[] = [\n ...fullColumnsAxes.map((a) => ({ type: 'axis', id: a } satisfies PTableColumnIdAxis)),\n ...fullColumns.map((c) => ({ type: 'column', id: c.id } satisfies PTableColumnIdColumn)),\n ];\n const fullColumnsIdsSet = new Set(fullColumnsIds.map((c) => canonicalizeJson<PTableColumnId>(c)));\n const isValidColumnId = (id: PTableColumnId): boolean => fullColumnsIdsSet.has(canonicalizeJson<PTableColumnId>(id));\n\n const coreJoinType = ops?.coreJoinType ?? 'full';\n const partitionFilters: PTableRecordSingleValueFilterV2[]\n = tableStateNormalized.pTableParams.partitionFilters\n .filter((f) => {\n const valid = isValidColumnId(f.column);\n if (!valid) ctx.logWarn(`Partition filter ${JSON.stringify(f)} does not match provided columns, skipping`);\n return valid;\n });\n const filters: PTableRecordSingleValueFilterV2[]\n = uniqueBy(\n [...(ops?.filters ?? []), ...tableStateNormalized.pTableParams.filters],\n (f) => canonicalizeJson<PTableColumnId>(f.column),\n ).filter((f) => {\n const valid = isValidColumnId(f.column);\n if (!valid) ctx.logWarn(`Filter ${JSON.stringify(f)} does not match provided columns, skipping`);\n return valid;\n });\n const sorting: PTableSorting[]\n = uniqueBy(\n [...(ops?.sorting ?? []), ...tableStateNormalized.pTableParams.sorting],\n (s) => canonicalizeJson<PTableColumnId>(s.column),\n ).filter((s) => {\n const valid = isValidColumnId(s.column);\n if (!valid) ctx.logWarn(`Sorting ${JSON.stringify(s)} does not match provided columns, skipping`);\n return valid;\n });\n\n const fullDef = createPTableDef({\n columns,\n labelColumns: fullLabelColumns,\n coreJoinType,\n partitionFilters,\n filters,\n sorting,\n coreColumnPredicate: ops?.coreColumnPredicate,\n });\n const fullHandle = ctx.createPTable(fullDef);\n if (!fullHandle) return undefined;\n\n const hiddenColumns = new Set<PObjectId>(((): PObjectId[] => {\n // Inner join works as a filter - all columns must be present\n if (coreJoinType === 'inner') return [];\n\n const hiddenColIds = tableStateNormalized.pTableParams.hiddenColIds;\n if (hiddenColIds) return hiddenColIds;\n\n return columns\n .filter((c) => isColumnOptional(c.spec))\n .map((c) => c.id);\n })());\n\n // Preserve linker columns\n columns\n .filter((c) => isLinkerColumn(c.spec))\n .forEach((c) => hiddenColumns.delete(c.id));\n\n // Preserve core columns as they change the shape of join.\n const coreColumnPredicate = ops?.coreColumnPredicate;\n if (coreColumnPredicate) {\n const coreColumns = columns.flatMap((c) => coreColumnPredicate(getColumnIdAndSpec(c)) ? [c.id] : []);\n coreColumns.forEach((c) => hiddenColumns.delete(c));\n }\n\n // Filters decrease the number of result rows, sorting changes the order of result rows\n [...partitionFilters.map((f) => f.column), ...filters.map((f) => f.column), ...sorting.map((s) => s.column)]\n .filter((c): c is PTableColumnIdColumn => c.type === 'column')\n .forEach((c) => hiddenColumns.delete(c.id));\n\n const visibleColumns = columns.filter((c) => !hiddenColumns.has(c.id));\n const visibleLabelColumns = getMatchingLabelColumns(visibleColumns.map(getColumnIdAndSpec), allLabelColumns);\n\n // if at least one column is not yet computed, we can't show the table\n if (!allPColumnsReady([...visibleColumns, ...visibleLabelColumns])) return undefined;\n\n const visibleDef = createPTableDef({\n columns: visibleColumns,\n labelColumns: visibleLabelColumns,\n coreJoinType,\n partitionFilters,\n filters,\n sorting,\n coreColumnPredicate,\n });\n const visibleHandle = ctx.createPTable(visibleDef);\n if (!visibleHandle) return undefined;\n\n return {\n sourceId: tableStateNormalized.pTableParams.sourceId,\n fullTableHandle: fullHandle,\n visibleTableHandle: visibleHandle,\n } satisfies PlDataTableModel;\n}\n\n/** Create sheet entries for PlDataTable */\nexport function createPlDataTableSheet<A, U>(\n ctx: RenderCtx<A, U>,\n axis: AxisSpec,\n values: (string | number)[],\n): PlDataTableSheet {\n const labels = ctx.resultPool.findLabels(axis);\n return {\n axis,\n options: values.map((v) => ({\n value: v,\n label: labels?.[v] ?? v.toString(),\n })),\n defaultValue: values[0],\n };\n}\n"],"names":["PColumnCollection","PColumnName","isLabelColumn","getAxisId","matchAxisId","getColumnIdAndSpec","readAnnotation","Annotation","deriveLabels","identity","uniqueBy","canonicalizeJson","isLinkerColumn","allPColumnsReady"],"mappings":"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"}
1
+ {"version":3,"file":"PlDataTable.cjs","sources":["../../src/components/PlDataTable.ts"],"sourcesContent":["import type {\n AxisId,\n AxisSpec,\n CanonicalizedJson,\n DataInfo,\n ListOptionBase,\n PColumn,\n PColumnIdAndSpec,\n PColumnValues,\n PObjectId,\n PTableColumnId,\n PTableColumnIdAxis,\n PTableColumnIdColumn,\n PTableColumnSpec,\n PTableDef,\n PTableHandle,\n PTableRecordFilter,\n PTableRecordSingleValueFilterV2,\n PTableSorting,\n} from '@milaboratories/pl-model-common';\nimport {\n Annotation,\n canonicalizeJson,\n getAxisId,\n getColumnIdAndSpec,\n isLabelColumn,\n isLinkerColumn,\n matchAxisId,\n PColumnName,\n readAnnotation,\n uniqueBy,\n} from '@milaboratories/pl-model-common';\nimport type {\n AxisLabelProvider,\n ColumnProvider,\n PColumnDataUniversal,\n RenderCtx,\n TreeNodeAccessor,\n} from '../render';\nimport {\n allPColumnsReady,\n deriveLabels,\n PColumnCollection,\n} from '../render';\nimport { identity } from 'es-toolkit';\n\nexport type PlTableColumnId = {\n /** Original column spec */\n source: PTableColumnSpec;\n /** Column spec with labeled axes replaced by label columns */\n labeled: PTableColumnSpec;\n};\n\nexport type PlTableColumnIdJson = CanonicalizedJson<PlTableColumnId>;\n\nexport type PlDataTableGridStateCore = {\n /** Includes column ordering */\n columnOrder?: {\n /** All colIds in order */\n orderedColIds: PlTableColumnIdJson[];\n };\n /** Includes current sort columns and direction */\n sort?: {\n /** Sorted columns and directions in order */\n sortModel: {\n /** Column Id to apply the sort to. */\n colId: PlTableColumnIdJson;\n /** Sort direction */\n sort: 'asc' | 'desc';\n }[];\n };\n /** Includes column visibility */\n columnVisibility?: {\n /** All colIds which were hidden */\n hiddenColIds: PlTableColumnIdJson[];\n };\n};\n\nexport type PlDataTableSheet = {\n /** spec of the axis to use */\n axis: AxisSpec;\n /** options to show in the filter dropdown */\n options: ListOptionBase<string | number>[];\n /** default (selected) value */\n defaultValue?: string | number;\n};\n\nexport type PlDataTableSheetState = {\n /** id of the axis */\n axisId: AxisId;\n /** selected value */\n value: string | number;\n};\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 // Normalized state\n | PlDataTableStateV2Normalized;\n\nexport type PlDataTableStateV2CacheEntry = {\n /** DataSource identifier for state management */\n sourceId: string;\n /** Internal ag-grid state */\n gridState: PlDataTableGridStateCore;\n /** Sheets state */\n sheetsState: PlDataTableSheetState[];\n /** Filters state */\n filtersState: PlDataTableFilterState[];\n};\n\nexport type PTableParamsV2 =\n | {\n sourceId: null;\n hiddenColIds: null;\n partitionFilters: [];\n filters: [];\n sorting: [];\n }\n | {\n sourceId: string;\n hiddenColIds: PObjectId[] | null;\n partitionFilters: PTableRecordFilter[];\n filters: PTableRecordFilter[];\n sorting: PTableSorting[];\n };\n\nexport type PlDataTableStateV2Normalized = {\n /** Version for upgrades */\n version: 4;\n /** Internal states, LRU cache for 5 sourceId-s */\n stateCache: PlDataTableStateV2CacheEntry[];\n /** PTable params derived from the cache state for the current sourceId */\n pTableParams: PTableParamsV2;\n};\n\nexport function makeDefaultPTableParams(): PTableParamsV2 {\n return {\n sourceId: null,\n hiddenColIds: null,\n partitionFilters: [],\n filters: [],\n sorting: [],\n };\n}\n\n/** Create default PlDataTableStateV2 */\nexport function createPlDataTableStateV2(): PlDataTableStateV2Normalized {\n return {\n version: 4,\n stateCache: [],\n pTableParams: makeDefaultPTableParams(),\n };\n}\n\n/** Upgrade PlDataTableStateV2 to the latest version */\nexport function upgradePlDataTableStateV2(state: PlDataTableStateV2 | undefined): 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: makeDefaultPTableParams(),\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 return state;\n}\n\nexport type PlDataTableFilterState = {\n id: PTableColumnId;\n alphabetic: boolean;\n filter: null | {\n value: PlTableFilter;\n disabled: boolean;\n };\n};\n\n/** PlTableFilters filter entry */\nexport type PlTableFilterIsNotNA = {\n /** Predicate type */\n type: 'isNotNA';\n};\n\n/** PlTableFilters filter entry */\nexport type PlTableFilterIsNA = {\n /** Predicate type */\n type: 'isNA';\n};\n\n/** PlTableFilters filter entries applicable to both string and number values */\nexport type PlTableFilterCommon = PlTableFilterIsNotNA | PlTableFilterIsNA;\n\n/** PlTableFilters numeric filter entry */\nexport type PlTableFilterNumberEquals = {\n /** Predicate type */\n type: 'number_equals';\n /** Reference value */\n reference: number;\n};\n\n/** PlTableFilters numeric filter entry */\nexport type PlTableFilterNumberNotEquals = {\n /** Predicate type */\n type: 'number_notEquals';\n /** Reference value */\n reference: number;\n};\n\n/** PlTableFilters numeric filter entry */\nexport type PlTableFilterNumberGreaterThan = {\n /** Predicate type */\n type: 'number_greaterThan';\n /** Reference value */\n reference: number;\n};\n\n/** PlTableFilters numeric filter entry */\nexport type PlTableFilterNumberGreaterThanOrEqualTo = {\n /** Predicate type */\n type: 'number_greaterThanOrEqualTo';\n /** Reference value */\n reference: number;\n};\n\n/** PlTableFilters numeric filter entry */\nexport type PlTableFilterNumberLessThan = {\n /** Predicate type */\n type: 'number_lessThan';\n /** Reference value */\n reference: number;\n};\n\n/** PlTableFilters numeric filter entry */\nexport type PlTableFilterNumberLessThanOrEqualTo = {\n /** Predicate type */\n type: 'number_lessThanOrEqualTo';\n /** Reference value */\n reference: number;\n};\n\n/** PlTableFilters numeric filter entry */\nexport type PlTableFilterNumberBetween = {\n /** Predicate type */\n type: 'number_between';\n /** Reference value for the lower bound */\n lowerBound: number;\n /** Defines whether values equal to lower bound reference value should be matched */\n includeLowerBound: boolean;\n /** Reference value for the upper bound */\n upperBound: number;\n /** Defines whether values equal to upper bound reference value should be matched */\n includeUpperBound: boolean;\n};\n\n/** All PlTableFilters numeric filter entries */\nexport type PlTableFilterNumber =\n | PlTableFilterCommon\n | PlTableFilterNumberEquals\n | PlTableFilterNumberNotEquals\n | PlTableFilterNumberGreaterThan\n | PlTableFilterNumberGreaterThanOrEqualTo\n | PlTableFilterNumberLessThan\n | PlTableFilterNumberLessThanOrEqualTo\n | PlTableFilterNumberBetween;\n/** All types of PlTableFilters numeric filter entries */\nexport type PlTableFilterNumberType = PlTableFilterNumber['type'];\n\n/** PlTableFilters string filter entry */\nexport type PlTableFilterStringEquals = {\n /** Predicate type */\n type: 'string_equals';\n /** Reference value */\n reference: string;\n};\n\n/** PlTableFilters string filter entry */\nexport type PlTableFilterStringNotEquals = {\n /** Predicate type */\n type: 'string_notEquals';\n /** Reference value */\n reference: string;\n};\n\n/** PlTableFilters string filter entry */\nexport type PlTableFilterStringContains = {\n /** Predicate type */\n type: 'string_contains';\n /** Reference value */\n reference: string;\n};\n\n/** PlTableFilters string filter entry */\nexport type PlTableFilterStringDoesNotContain = {\n /** Predicate type */\n type: 'string_doesNotContain';\n /** Reference value */\n reference: string;\n};\n\n/** PlTableFilters string filter entry */\nexport type PlTableFilterStringMatches = {\n /** Predicate type */\n type: 'string_matches';\n /** Reference value */\n reference: string;\n};\n\n/** PlTableFilters string filter entry */\nexport type PlTableFilterStringDoesNotMatch = {\n /** Predicate type */\n type: 'string_doesNotMatch';\n /** Reference value */\n reference: string;\n};\n\n/** PlTableFilters string filter entry */\nexport type PlTableFilterStringContainsFuzzyMatch = {\n /** Predicate type */\n type: 'string_containsFuzzyMatch';\n /** Reference value */\n reference: string;\n /**\n * Maximum acceptable edit distance between reference value and matched substring\n * @see https://en.wikipedia.org/wiki/Edit_distance\n */\n maxEdits: number;\n /**\n * When {@link substitutionsOnly} is set to false\n * Levenshtein distance is used as edit distance (substitutions and indels)\n * @see https://en.wikipedia.org/wiki/Levenshtein_distance\n * When {@link substitutionsOnly} is set to true\n * Hamming distance is used as edit distance (substitutions only)\n * @see https://en.wikipedia.org/wiki/Hamming_distance\n */\n substitutionsOnly: boolean;\n /**\n * Single character in {@link reference} that will labelColumn any\n * single character in searched text.\n */\n wildcard?: string;\n};\n\n/** All PlTableFilters string filter entries */\nexport type PlTableFilterString =\n | PlTableFilterCommon\n | PlTableFilterStringEquals\n | PlTableFilterStringNotEquals\n | PlTableFilterStringContains\n | PlTableFilterStringDoesNotContain\n | PlTableFilterStringMatches\n | PlTableFilterStringDoesNotMatch\n | PlTableFilterStringContainsFuzzyMatch;\n/** All types of PlTableFilters string filter entries */\nexport type PlTableFilterStringType = PlTableFilterString['type'];\n\n/** All PlTableFilters filter entries */\nexport type PlTableFilter = PlTableFilterNumber | PlTableFilterString;\n/** All types of PlTableFilters filter entries */\nexport type PlTableFilterType = PlTableFilter['type'];\n\nexport type CreatePlDataTableOps = {\n /** Filters for columns and non-partitioned axes */\n filters?: PTableRecordFilter[];\n\n /** Sorting to columns hidden from user */\n sorting?: PTableSorting[];\n\n /**\n * Selects columns for which will be inner-joined to the table.\n *\n * Default behaviour: all columns are considered to be core\n */\n coreColumnPredicate?: (spec: PColumnIdAndSpec) => boolean;\n\n /**\n * Determines how core columns should be joined together:\n * inner - so user will only see records present in all core columns\n * full - so user will only see records present in any of the core columns\n *\n * All non-core columns will be left joined to the table produced by the core\n * columns, in other words records form the pool of non-core columns will only\n * make their way into the final table if core table contains corresponding key.\n *\n * Default: 'full'\n */\n coreJoinType?: 'inner' | 'full';\n};\n\n/** Get all label columns from the result pool */\nexport function getAllLabelColumns(\n resultPool: AxisLabelProvider & ColumnProvider,\n): PColumn<PColumnDataUniversal>[] | undefined {\n return new PColumnCollection()\n .addAxisLabelProvider(resultPool)\n .addColumnProvider(resultPool)\n .getColumns({\n name: PColumnName.Label,\n axes: [{}], // exactly one axis\n }, { dontWaitAllData: true, overrideLabelAnnotation: false });\n}\n\n/** Get label columns matching the provided columns from the result pool */\nexport function getMatchingLabelColumns(\n columns: PColumnIdAndSpec[],\n allLabelColumns: PColumn<PColumnDataUniversal>[],\n): PColumn<PColumnDataUniversal>[] {\n // split input columns into label and value columns\n const inputLabelColumns: typeof columns = [];\n const inputValueColumns: typeof columns = [];\n for (const column of columns) {\n if (isLabelColumn(column.spec)) {\n inputLabelColumns.push(column);\n } else {\n inputValueColumns.push(column);\n }\n }\n\n // collect distinct axes of value columns\n const unlabeledAxes: AxisId[] = [];\n for (const column of inputValueColumns) {\n for (const axis of column.spec.axesSpec) {\n const axisId = getAxisId(axis);\n if (!unlabeledAxes.some((id) => matchAxisId(id, axisId))) {\n unlabeledAxes.push(axisId);\n }\n }\n }\n\n // remove axes matched by input label columns\n for (const labelColumn of inputLabelColumns) {\n const labelAxisId = getAxisId(labelColumn.spec.axesSpec[0]);\n const labelMatch = unlabeledAxes.findIndex((axisId) => matchAxisId(axisId, labelAxisId));\n if (labelMatch !== -1) {\n unlabeledAxes.splice(labelMatch, 1);\n }\n }\n\n // warning: changing this id will break backward compatibility\n const colId = (id: PObjectId, domain?: Record<string, string>): PObjectId => {\n let wid = id.toString();\n if (domain) {\n for (const k in domain) {\n wid += k;\n wid += domain[k];\n }\n }\n return wid as PObjectId;\n };\n\n // search label columns for unmatched axes\n const labelColumns: typeof allLabelColumns = [];\n for (const labelColumn of allLabelColumns) {\n const labelAxis = labelColumn.spec.axesSpec[0];\n const labelAxisId = getAxisId(labelAxis);\n const labelMatch = unlabeledAxes.findIndex((axisId) => matchAxisId(axisId, labelAxisId));\n if (labelMatch !== -1) {\n const axisId = unlabeledAxes[labelMatch];\n const dataDomainLen = Object.keys(axisId.domain ?? {}).length;\n const labelDomainLen = Object.keys(labelAxis.domain ?? {}).length;\n if (dataDomainLen > labelDomainLen) {\n labelColumns.push({\n id: colId(labelColumn.id, axisId.domain),\n spec: {\n ...labelColumn.spec,\n axesSpec: [{ ...axisId, annotations: labelAxis.annotations }],\n },\n data: labelColumn.data,\n });\n } else {\n labelColumns.push(labelColumn);\n }\n unlabeledAxes.splice(labelMatch, 1);\n }\n }\n return labelColumns;\n}\n\nfunction createPTableDef(params: {\n columns: PColumn<PColumnDataUniversal>[];\n labelColumns: PColumn<PColumnDataUniversal>[];\n coreJoinType: 'inner' | 'full';\n partitionFilters: PTableRecordSingleValueFilterV2[];\n filters: PTableRecordSingleValueFilterV2[];\n sorting: PTableSorting[];\n coreColumnPredicate?: ((spec: PColumnIdAndSpec) => boolean);\n}): PTableDef<PColumn<TreeNodeAccessor | PColumnValues | DataInfo<TreeNodeAccessor>>> {\n let coreColumns = params.columns;\n const secondaryColumns: typeof params.columns = [];\n\n if (params.coreColumnPredicate) {\n coreColumns = [];\n for (const c of params.columns)\n if (params.coreColumnPredicate(getColumnIdAndSpec(c))) coreColumns.push(c);\n else secondaryColumns.push(c);\n }\n\n secondaryColumns.push(...params.labelColumns);\n\n return {\n src: {\n type: 'outer',\n primary: {\n type: params.coreJoinType,\n entries: coreColumns.map((c) => ({ type: 'column', column: c })),\n },\n secondary: secondaryColumns.map((c) => ({ type: 'column', column: c })),\n },\n partitionFilters: params.partitionFilters,\n filters: params.filters,\n sorting: params.sorting,\n };\n}\n\n/** PlAgDataTable model */\nexport type PlDataTableModel = {\n /** DataSource identifier for state management */\n sourceId: string | null;\n /** p-table including all columns, used to show the full specification of the table */\n fullTableHandle: PTableHandle;\n /** p-table including only visible columns, used to get the data */\n visibleTableHandle: PTableHandle;\n};\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/**\n * Create p-table spec and handle given ui table state\n *\n * @param ctx context\n * @param columns column list\n * @param tableState table ui state\n * @returns PlAgDataTableV2 table source\n */\nexport function createPlDataTableV2<A, U>(\n ctx: RenderCtx<A, U>,\n columns: PColumn<PColumnDataUniversal>[],\n tableState: PlDataTableStateV2 | undefined,\n ops?: CreatePlDataTableOps,\n): PlDataTableModel | undefined {\n if (columns.length === 0) return undefined;\n\n const tableStateNormalized = upgradePlDataTableStateV2(tableState);\n\n const allLabelColumns = getAllLabelColumns(ctx.resultPool);\n if (!allLabelColumns) return undefined;\n\n let fullLabelColumns = getMatchingLabelColumns(columns.map(getColumnIdAndSpec), allLabelColumns);\n fullLabelColumns = deriveLabels(fullLabelColumns, identity, { includeNativeLabel: true }).map((v) => {\n return {\n ...v.value,\n spec: {\n ...v.value.spec,\n annotations: {\n ...v.value.spec.annotations,\n [Annotation.Label]: v.label,\n },\n },\n };\n });\n\n const fullColumns = [...columns, ...fullLabelColumns];\n\n const fullColumnsAxes = uniqueBy(\n fullColumns.flatMap((c) => c.spec.axesSpec.map((a) => getAxisId(a))),\n (a) => canonicalizeJson<AxisId>(a),\n );\n const fullColumnsIds: PTableColumnId[] = [\n ...fullColumnsAxes.map((a) => ({ type: 'axis', id: a } satisfies PTableColumnIdAxis)),\n ...fullColumns.map((c) => ({ type: 'column', id: c.id } satisfies PTableColumnIdColumn)),\n ];\n const fullColumnsIdsSet = new Set(fullColumnsIds.map((c) => canonicalizeJson<PTableColumnId>(c)));\n const isValidColumnId = (id: PTableColumnId): boolean => fullColumnsIdsSet.has(canonicalizeJson<PTableColumnId>(id));\n\n const coreJoinType = ops?.coreJoinType ?? 'full';\n const partitionFilters: PTableRecordSingleValueFilterV2[]\n = tableStateNormalized.pTableParams.partitionFilters\n .filter((f) => {\n const valid = isValidColumnId(f.column);\n if (!valid) ctx.logWarn(`Partition filter ${JSON.stringify(f)} does not match provided columns, skipping`);\n return valid;\n });\n const filters: PTableRecordSingleValueFilterV2[]\n = uniqueBy(\n [...tableStateNormalized.pTableParams.filters, ...(ops?.filters ?? [])],\n (f) => canonicalizeJson<PTableColumnId>(f.column),\n ).filter((f) => {\n const valid = isValidColumnId(f.column);\n if (!valid) ctx.logWarn(`Filter ${JSON.stringify(f)} does not match provided columns, skipping`);\n return valid;\n });\n const sorting: PTableSorting[]\n = uniqueBy(\n [...tableStateNormalized.pTableParams.sorting, ...(ops?.sorting ?? [])],\n (s) => canonicalizeJson<PTableColumnId>(s.column),\n ).filter((s) => {\n const valid = isValidColumnId(s.column);\n if (!valid) ctx.logWarn(`Sorting ${JSON.stringify(s)} does not match provided columns, skipping`);\n return valid;\n });\n\n const fullDef = createPTableDef({\n columns,\n labelColumns: fullLabelColumns,\n coreJoinType,\n partitionFilters,\n filters,\n sorting,\n coreColumnPredicate: ops?.coreColumnPredicate,\n });\n const fullHandle = ctx.createPTable(fullDef);\n if (!fullHandle) return undefined;\n\n const hiddenColumns = new Set<PObjectId>(((): PObjectId[] => {\n // Inner join works as a filter - all columns must be present\n if (coreJoinType === 'inner') return [];\n\n const hiddenColIds = tableStateNormalized.pTableParams.hiddenColIds;\n if (hiddenColIds) return hiddenColIds;\n\n return columns\n .filter((c) => isColumnOptional(c.spec))\n .map((c) => c.id);\n })());\n\n // Preserve linker columns\n columns\n .filter((c) => isLinkerColumn(c.spec))\n .forEach((c) => hiddenColumns.delete(c.id));\n\n // Preserve core columns as they change the shape of join.\n const coreColumnPredicate = ops?.coreColumnPredicate;\n if (coreColumnPredicate) {\n const coreColumns = columns.flatMap((c) => coreColumnPredicate(getColumnIdAndSpec(c)) ? [c.id] : []);\n coreColumns.forEach((c) => hiddenColumns.delete(c));\n }\n\n // Filters decrease the number of result rows, sorting changes the order of result rows\n [...partitionFilters.map((f) => f.column), ...filters.map((f) => f.column), ...sorting.map((s) => s.column)]\n .filter((c): c is PTableColumnIdColumn => c.type === 'column')\n .forEach((c) => hiddenColumns.delete(c.id));\n\n const visibleColumns = columns.filter((c) => !hiddenColumns.has(c.id));\n const visibleLabelColumns = getMatchingLabelColumns(visibleColumns.map(getColumnIdAndSpec), allLabelColumns);\n\n // if at least one column is not yet computed, we can't show the table\n if (!allPColumnsReady([...visibleColumns, ...visibleLabelColumns])) return undefined;\n\n const visibleDef = createPTableDef({\n columns: visibleColumns,\n labelColumns: visibleLabelColumns,\n coreJoinType,\n partitionFilters,\n filters,\n sorting,\n coreColumnPredicate,\n });\n const visibleHandle = ctx.createPTable(visibleDef);\n if (!visibleHandle) return undefined;\n\n return {\n sourceId: tableStateNormalized.pTableParams.sourceId,\n fullTableHandle: fullHandle,\n visibleTableHandle: visibleHandle,\n } satisfies PlDataTableModel;\n}\n\n/** Create sheet entries for PlDataTable */\nexport function createPlDataTableSheet<A, U>(\n ctx: RenderCtx<A, U>,\n axis: AxisSpec,\n values: (string | number)[],\n): PlDataTableSheet {\n const labels = ctx.resultPool.findLabels(axis);\n return {\n axis,\n options: values.map((v) => ({\n value: v,\n label: labels?.[v] ?? v.toString(),\n })),\n defaultValue: values[0],\n };\n}\n"],"names":["PColumnCollection","PColumnName","isLabelColumn","getAxisId","matchAxisId","getColumnIdAndSpec","readAnnotation","Annotation","deriveLabels","identity","uniqueBy","canonicalizeJson","isLinkerColumn","allPColumnsReady"],"mappings":"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"}
@@ -209,13 +209,13 @@ function createPlDataTableV2(ctx, columns, tableState, ops) {
209
209
  ctx.logWarn(`Partition filter ${JSON.stringify(f)} does not match provided columns, skipping`);
210
210
  return valid;
211
211
  });
212
- const filters = uniqueBy([...(ops?.filters ?? []), ...tableStateNormalized.pTableParams.filters], (f) => canonicalizeJson(f.column)).filter((f) => {
212
+ const filters = uniqueBy([...tableStateNormalized.pTableParams.filters, ...(ops?.filters ?? [])], (f) => canonicalizeJson(f.column)).filter((f) => {
213
213
  const valid = isValidColumnId(f.column);
214
214
  if (!valid)
215
215
  ctx.logWarn(`Filter ${JSON.stringify(f)} does not match provided columns, skipping`);
216
216
  return valid;
217
217
  });
218
- const sorting = uniqueBy([...(ops?.sorting ?? []), ...tableStateNormalized.pTableParams.sorting], (s) => canonicalizeJson(s.column)).filter((s) => {
218
+ const sorting = uniqueBy([...tableStateNormalized.pTableParams.sorting, ...(ops?.sorting ?? [])], (s) => canonicalizeJson(s.column)).filter((s) => {
219
219
  const valid = isValidColumnId(s.column);
220
220
  if (!valid)
221
221
  ctx.logWarn(`Sorting ${JSON.stringify(s)} does not match provided columns, skipping`);
@@ -1 +1 @@
1
- {"version":3,"file":"PlDataTable.js","sources":["../../src/components/PlDataTable.ts"],"sourcesContent":["import type {\n AxisId,\n AxisSpec,\n CanonicalizedJson,\n DataInfo,\n ListOptionBase,\n PColumn,\n PColumnIdAndSpec,\n PColumnValues,\n PObjectId,\n PTableColumnId,\n PTableColumnIdAxis,\n PTableColumnIdColumn,\n PTableColumnSpec,\n PTableDef,\n PTableHandle,\n PTableRecordFilter,\n PTableRecordSingleValueFilterV2,\n PTableSorting,\n} from '@milaboratories/pl-model-common';\nimport {\n Annotation,\n canonicalizeJson,\n getAxisId,\n getColumnIdAndSpec,\n isLabelColumn,\n isLinkerColumn,\n matchAxisId,\n PColumnName,\n readAnnotation,\n uniqueBy,\n} from '@milaboratories/pl-model-common';\nimport type {\n AxisLabelProvider,\n ColumnProvider,\n PColumnDataUniversal,\n RenderCtx,\n TreeNodeAccessor,\n} from '../render';\nimport {\n allPColumnsReady,\n deriveLabels,\n PColumnCollection,\n} from '../render';\nimport { identity } from 'es-toolkit';\n\nexport type PlTableColumnId = {\n /** Original column spec */\n source: PTableColumnSpec;\n /** Column spec with labeled axes replaced by label columns */\n labeled: PTableColumnSpec;\n};\n\nexport type PlTableColumnIdJson = CanonicalizedJson<PlTableColumnId>;\n\nexport type PlDataTableGridStateCore = {\n /** Includes column ordering */\n columnOrder?: {\n /** All colIds in order */\n orderedColIds: PlTableColumnIdJson[];\n };\n /** Includes current sort columns and direction */\n sort?: {\n /** Sorted columns and directions in order */\n sortModel: {\n /** Column Id to apply the sort to. */\n colId: PlTableColumnIdJson;\n /** Sort direction */\n sort: 'asc' | 'desc';\n }[];\n };\n /** Includes column visibility */\n columnVisibility?: {\n /** All colIds which were hidden */\n hiddenColIds: PlTableColumnIdJson[];\n };\n};\n\nexport type PlDataTableSheet = {\n /** spec of the axis to use */\n axis: AxisSpec;\n /** options to show in the filter dropdown */\n options: ListOptionBase<string | number>[];\n /** default (selected) value */\n defaultValue?: string | number;\n};\n\nexport type PlDataTableSheetState = {\n /** id of the axis */\n axisId: AxisId;\n /** selected value */\n value: string | number;\n};\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 // Normalized state\n | PlDataTableStateV2Normalized;\n\nexport type PlDataTableStateV2CacheEntry = {\n /** DataSource identifier for state management */\n sourceId: string;\n /** Internal ag-grid state */\n gridState: PlDataTableGridStateCore;\n /** Sheets state */\n sheetsState: PlDataTableSheetState[];\n /** Filters state */\n filtersState: PlDataTableFilterState[];\n};\n\nexport type PTableParamsV2 =\n | {\n sourceId: null;\n hiddenColIds: null;\n partitionFilters: [];\n filters: [];\n sorting: [];\n }\n | {\n sourceId: string;\n hiddenColIds: PObjectId[] | null;\n partitionFilters: PTableRecordFilter[];\n filters: PTableRecordFilter[];\n sorting: PTableSorting[];\n };\n\nexport type PlDataTableStateV2Normalized = {\n /** Version for upgrades */\n version: 4;\n /** Internal states, LRU cache for 5 sourceId-s */\n stateCache: PlDataTableStateV2CacheEntry[];\n /** PTable params derived from the cache state for the current sourceId */\n pTableParams: PTableParamsV2;\n};\n\nexport function makeDefaultPTableParams(): PTableParamsV2 {\n return {\n sourceId: null,\n hiddenColIds: null,\n partitionFilters: [],\n filters: [],\n sorting: [],\n };\n}\n\n/** Create default PlDataTableStateV2 */\nexport function createPlDataTableStateV2(): PlDataTableStateV2Normalized {\n return {\n version: 4,\n stateCache: [],\n pTableParams: makeDefaultPTableParams(),\n };\n}\n\n/** Upgrade PlDataTableStateV2 to the latest version */\nexport function upgradePlDataTableStateV2(state: PlDataTableStateV2 | undefined): 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: makeDefaultPTableParams(),\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 return state;\n}\n\nexport type PlDataTableFilterState = {\n id: PTableColumnId;\n alphabetic: boolean;\n filter: null | {\n value: PlTableFilter;\n disabled: boolean;\n };\n};\n\n/** PlTableFilters filter entry */\nexport type PlTableFilterIsNotNA = {\n /** Predicate type */\n type: 'isNotNA';\n};\n\n/** PlTableFilters filter entry */\nexport type PlTableFilterIsNA = {\n /** Predicate type */\n type: 'isNA';\n};\n\n/** PlTableFilters filter entries applicable to both string and number values */\nexport type PlTableFilterCommon = PlTableFilterIsNotNA | PlTableFilterIsNA;\n\n/** PlTableFilters numeric filter entry */\nexport type PlTableFilterNumberEquals = {\n /** Predicate type */\n type: 'number_equals';\n /** Reference value */\n reference: number;\n};\n\n/** PlTableFilters numeric filter entry */\nexport type PlTableFilterNumberNotEquals = {\n /** Predicate type */\n type: 'number_notEquals';\n /** Reference value */\n reference: number;\n};\n\n/** PlTableFilters numeric filter entry */\nexport type PlTableFilterNumberGreaterThan = {\n /** Predicate type */\n type: 'number_greaterThan';\n /** Reference value */\n reference: number;\n};\n\n/** PlTableFilters numeric filter entry */\nexport type PlTableFilterNumberGreaterThanOrEqualTo = {\n /** Predicate type */\n type: 'number_greaterThanOrEqualTo';\n /** Reference value */\n reference: number;\n};\n\n/** PlTableFilters numeric filter entry */\nexport type PlTableFilterNumberLessThan = {\n /** Predicate type */\n type: 'number_lessThan';\n /** Reference value */\n reference: number;\n};\n\n/** PlTableFilters numeric filter entry */\nexport type PlTableFilterNumberLessThanOrEqualTo = {\n /** Predicate type */\n type: 'number_lessThanOrEqualTo';\n /** Reference value */\n reference: number;\n};\n\n/** PlTableFilters numeric filter entry */\nexport type PlTableFilterNumberBetween = {\n /** Predicate type */\n type: 'number_between';\n /** Reference value for the lower bound */\n lowerBound: number;\n /** Defines whether values equal to lower bound reference value should be matched */\n includeLowerBound: boolean;\n /** Reference value for the upper bound */\n upperBound: number;\n /** Defines whether values equal to upper bound reference value should be matched */\n includeUpperBound: boolean;\n};\n\n/** All PlTableFilters numeric filter entries */\nexport type PlTableFilterNumber =\n | PlTableFilterCommon\n | PlTableFilterNumberEquals\n | PlTableFilterNumberNotEquals\n | PlTableFilterNumberGreaterThan\n | PlTableFilterNumberGreaterThanOrEqualTo\n | PlTableFilterNumberLessThan\n | PlTableFilterNumberLessThanOrEqualTo\n | PlTableFilterNumberBetween;\n/** All types of PlTableFilters numeric filter entries */\nexport type PlTableFilterNumberType = PlTableFilterNumber['type'];\n\n/** PlTableFilters string filter entry */\nexport type PlTableFilterStringEquals = {\n /** Predicate type */\n type: 'string_equals';\n /** Reference value */\n reference: string;\n};\n\n/** PlTableFilters string filter entry */\nexport type PlTableFilterStringNotEquals = {\n /** Predicate type */\n type: 'string_notEquals';\n /** Reference value */\n reference: string;\n};\n\n/** PlTableFilters string filter entry */\nexport type PlTableFilterStringContains = {\n /** Predicate type */\n type: 'string_contains';\n /** Reference value */\n reference: string;\n};\n\n/** PlTableFilters string filter entry */\nexport type PlTableFilterStringDoesNotContain = {\n /** Predicate type */\n type: 'string_doesNotContain';\n /** Reference value */\n reference: string;\n};\n\n/** PlTableFilters string filter entry */\nexport type PlTableFilterStringMatches = {\n /** Predicate type */\n type: 'string_matches';\n /** Reference value */\n reference: string;\n};\n\n/** PlTableFilters string filter entry */\nexport type PlTableFilterStringDoesNotMatch = {\n /** Predicate type */\n type: 'string_doesNotMatch';\n /** Reference value */\n reference: string;\n};\n\n/** PlTableFilters string filter entry */\nexport type PlTableFilterStringContainsFuzzyMatch = {\n /** Predicate type */\n type: 'string_containsFuzzyMatch';\n /** Reference value */\n reference: string;\n /**\n * Maximum acceptable edit distance between reference value and matched substring\n * @see https://en.wikipedia.org/wiki/Edit_distance\n */\n maxEdits: number;\n /**\n * When {@link substitutionsOnly} is set to false\n * Levenshtein distance is used as edit distance (substitutions and indels)\n * @see https://en.wikipedia.org/wiki/Levenshtein_distance\n * When {@link substitutionsOnly} is set to true\n * Hamming distance is used as edit distance (substitutions only)\n * @see https://en.wikipedia.org/wiki/Hamming_distance\n */\n substitutionsOnly: boolean;\n /**\n * Single character in {@link reference} that will labelColumn any\n * single character in searched text.\n */\n wildcard?: string;\n};\n\n/** All PlTableFilters string filter entries */\nexport type PlTableFilterString =\n | PlTableFilterCommon\n | PlTableFilterStringEquals\n | PlTableFilterStringNotEquals\n | PlTableFilterStringContains\n | PlTableFilterStringDoesNotContain\n | PlTableFilterStringMatches\n | PlTableFilterStringDoesNotMatch\n | PlTableFilterStringContainsFuzzyMatch;\n/** All types of PlTableFilters string filter entries */\nexport type PlTableFilterStringType = PlTableFilterString['type'];\n\n/** All PlTableFilters filter entries */\nexport type PlTableFilter = PlTableFilterNumber | PlTableFilterString;\n/** All types of PlTableFilters filter entries */\nexport type PlTableFilterType = PlTableFilter['type'];\n\nexport type CreatePlDataTableOps = {\n /** Filters for columns and non-partitioned axes */\n filters?: PTableRecordFilter[];\n\n /** Sorting to columns hidden from user */\n sorting?: PTableSorting[];\n\n /**\n * Selects columns for which will be inner-joined to the table.\n *\n * Default behaviour: all columns are considered to be core\n */\n coreColumnPredicate?: (spec: PColumnIdAndSpec) => boolean;\n\n /**\n * Determines how core columns should be joined together:\n * inner - so user will only see records present in all core columns\n * full - so user will only see records present in any of the core columns\n *\n * All non-core columns will be left joined to the table produced by the core\n * columns, in other words records form the pool of non-core columns will only\n * make their way into the final table if core table contains corresponding key.\n *\n * Default: 'full'\n */\n coreJoinType?: 'inner' | 'full';\n};\n\n/** Get all label columns from the result pool */\nexport function getAllLabelColumns(\n resultPool: AxisLabelProvider & ColumnProvider,\n): PColumn<PColumnDataUniversal>[] | undefined {\n return new PColumnCollection()\n .addAxisLabelProvider(resultPool)\n .addColumnProvider(resultPool)\n .getColumns({\n name: PColumnName.Label,\n axes: [{}], // exactly one axis\n }, { dontWaitAllData: true, overrideLabelAnnotation: false });\n}\n\n/** Get label columns matching the provided columns from the result pool */\nexport function getMatchingLabelColumns(\n columns: PColumnIdAndSpec[],\n allLabelColumns: PColumn<PColumnDataUniversal>[],\n): PColumn<PColumnDataUniversal>[] {\n // split input columns into label and value columns\n const inputLabelColumns: typeof columns = [];\n const inputValueColumns: typeof columns = [];\n for (const column of columns) {\n if (isLabelColumn(column.spec)) {\n inputLabelColumns.push(column);\n } else {\n inputValueColumns.push(column);\n }\n }\n\n // collect distinct axes of value columns\n const unlabeledAxes: AxisId[] = [];\n for (const column of inputValueColumns) {\n for (const axis of column.spec.axesSpec) {\n const axisId = getAxisId(axis);\n if (!unlabeledAxes.some((id) => matchAxisId(id, axisId))) {\n unlabeledAxes.push(axisId);\n }\n }\n }\n\n // remove axes matched by input label columns\n for (const labelColumn of inputLabelColumns) {\n const labelAxisId = getAxisId(labelColumn.spec.axesSpec[0]);\n const labelMatch = unlabeledAxes.findIndex((axisId) => matchAxisId(axisId, labelAxisId));\n if (labelMatch !== -1) {\n unlabeledAxes.splice(labelMatch, 1);\n }\n }\n\n // warning: changing this id will break backward compatibility\n const colId = (id: PObjectId, domain?: Record<string, string>): PObjectId => {\n let wid = id.toString();\n if (domain) {\n for (const k in domain) {\n wid += k;\n wid += domain[k];\n }\n }\n return wid as PObjectId;\n };\n\n // search label columns for unmatched axes\n const labelColumns: typeof allLabelColumns = [];\n for (const labelColumn of allLabelColumns) {\n const labelAxis = labelColumn.spec.axesSpec[0];\n const labelAxisId = getAxisId(labelAxis);\n const labelMatch = unlabeledAxes.findIndex((axisId) => matchAxisId(axisId, labelAxisId));\n if (labelMatch !== -1) {\n const axisId = unlabeledAxes[labelMatch];\n const dataDomainLen = Object.keys(axisId.domain ?? {}).length;\n const labelDomainLen = Object.keys(labelAxis.domain ?? {}).length;\n if (dataDomainLen > labelDomainLen) {\n labelColumns.push({\n id: colId(labelColumn.id, axisId.domain),\n spec: {\n ...labelColumn.spec,\n axesSpec: [{ ...axisId, annotations: labelAxis.annotations }],\n },\n data: labelColumn.data,\n });\n } else {\n labelColumns.push(labelColumn);\n }\n unlabeledAxes.splice(labelMatch, 1);\n }\n }\n return labelColumns;\n}\n\nfunction createPTableDef(params: {\n columns: PColumn<PColumnDataUniversal>[];\n labelColumns: PColumn<PColumnDataUniversal>[];\n coreJoinType: 'inner' | 'full';\n partitionFilters: PTableRecordSingleValueFilterV2[];\n filters: PTableRecordSingleValueFilterV2[];\n sorting: PTableSorting[];\n coreColumnPredicate?: ((spec: PColumnIdAndSpec) => boolean);\n}): PTableDef<PColumn<TreeNodeAccessor | PColumnValues | DataInfo<TreeNodeAccessor>>> {\n let coreColumns = params.columns;\n const secondaryColumns: typeof params.columns = [];\n\n if (params.coreColumnPredicate) {\n coreColumns = [];\n for (const c of params.columns)\n if (params.coreColumnPredicate(getColumnIdAndSpec(c))) coreColumns.push(c);\n else secondaryColumns.push(c);\n }\n\n secondaryColumns.push(...params.labelColumns);\n\n return {\n src: {\n type: 'outer',\n primary: {\n type: params.coreJoinType,\n entries: coreColumns.map((c) => ({ type: 'column', column: c })),\n },\n secondary: secondaryColumns.map((c) => ({ type: 'column', column: c })),\n },\n partitionFilters: params.partitionFilters,\n filters: params.filters,\n sorting: params.sorting,\n };\n}\n\n/** PlAgDataTable model */\nexport type PlDataTableModel = {\n /** DataSource identifier for state management */\n sourceId: string | null;\n /** p-table including all columns, used to show the full specification of the table */\n fullTableHandle: PTableHandle;\n /** p-table including only visible columns, used to get the data */\n visibleTableHandle: PTableHandle;\n};\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/**\n * Create p-table spec and handle given ui table state\n *\n * @param ctx context\n * @param columns column list\n * @param tableState table ui state\n * @returns PlAgDataTableV2 table source\n */\nexport function createPlDataTableV2<A, U>(\n ctx: RenderCtx<A, U>,\n columns: PColumn<PColumnDataUniversal>[],\n tableState: PlDataTableStateV2 | undefined,\n ops?: CreatePlDataTableOps,\n): PlDataTableModel | undefined {\n if (columns.length === 0) return undefined;\n\n const tableStateNormalized = upgradePlDataTableStateV2(tableState);\n\n const allLabelColumns = getAllLabelColumns(ctx.resultPool);\n if (!allLabelColumns) return undefined;\n\n let fullLabelColumns = getMatchingLabelColumns(columns.map(getColumnIdAndSpec), allLabelColumns);\n fullLabelColumns = deriveLabels(fullLabelColumns, identity, { includeNativeLabel: true }).map((v) => {\n return {\n ...v.value,\n spec: {\n ...v.value.spec,\n annotations: {\n ...v.value.spec.annotations,\n [Annotation.Label]: v.label,\n },\n },\n };\n });\n\n const fullColumns = [...columns, ...fullLabelColumns];\n\n const fullColumnsAxes = uniqueBy(\n fullColumns.flatMap((c) => c.spec.axesSpec.map((a) => getAxisId(a))),\n (a) => canonicalizeJson<AxisId>(a),\n );\n const fullColumnsIds: PTableColumnId[] = [\n ...fullColumnsAxes.map((a) => ({ type: 'axis', id: a } satisfies PTableColumnIdAxis)),\n ...fullColumns.map((c) => ({ type: 'column', id: c.id } satisfies PTableColumnIdColumn)),\n ];\n const fullColumnsIdsSet = new Set(fullColumnsIds.map((c) => canonicalizeJson<PTableColumnId>(c)));\n const isValidColumnId = (id: PTableColumnId): boolean => fullColumnsIdsSet.has(canonicalizeJson<PTableColumnId>(id));\n\n const coreJoinType = ops?.coreJoinType ?? 'full';\n const partitionFilters: PTableRecordSingleValueFilterV2[]\n = tableStateNormalized.pTableParams.partitionFilters\n .filter((f) => {\n const valid = isValidColumnId(f.column);\n if (!valid) ctx.logWarn(`Partition filter ${JSON.stringify(f)} does not match provided columns, skipping`);\n return valid;\n });\n const filters: PTableRecordSingleValueFilterV2[]\n = uniqueBy(\n [...(ops?.filters ?? []), ...tableStateNormalized.pTableParams.filters],\n (f) => canonicalizeJson<PTableColumnId>(f.column),\n ).filter((f) => {\n const valid = isValidColumnId(f.column);\n if (!valid) ctx.logWarn(`Filter ${JSON.stringify(f)} does not match provided columns, skipping`);\n return valid;\n });\n const sorting: PTableSorting[]\n = uniqueBy(\n [...(ops?.sorting ?? []), ...tableStateNormalized.pTableParams.sorting],\n (s) => canonicalizeJson<PTableColumnId>(s.column),\n ).filter((s) => {\n const valid = isValidColumnId(s.column);\n if (!valid) ctx.logWarn(`Sorting ${JSON.stringify(s)} does not match provided columns, skipping`);\n return valid;\n });\n\n const fullDef = createPTableDef({\n columns,\n labelColumns: fullLabelColumns,\n coreJoinType,\n partitionFilters,\n filters,\n sorting,\n coreColumnPredicate: ops?.coreColumnPredicate,\n });\n const fullHandle = ctx.createPTable(fullDef);\n if (!fullHandle) return undefined;\n\n const hiddenColumns = new Set<PObjectId>(((): PObjectId[] => {\n // Inner join works as a filter - all columns must be present\n if (coreJoinType === 'inner') return [];\n\n const hiddenColIds = tableStateNormalized.pTableParams.hiddenColIds;\n if (hiddenColIds) return hiddenColIds;\n\n return columns\n .filter((c) => isColumnOptional(c.spec))\n .map((c) => c.id);\n })());\n\n // Preserve linker columns\n columns\n .filter((c) => isLinkerColumn(c.spec))\n .forEach((c) => hiddenColumns.delete(c.id));\n\n // Preserve core columns as they change the shape of join.\n const coreColumnPredicate = ops?.coreColumnPredicate;\n if (coreColumnPredicate) {\n const coreColumns = columns.flatMap((c) => coreColumnPredicate(getColumnIdAndSpec(c)) ? [c.id] : []);\n coreColumns.forEach((c) => hiddenColumns.delete(c));\n }\n\n // Filters decrease the number of result rows, sorting changes the order of result rows\n [...partitionFilters.map((f) => f.column), ...filters.map((f) => f.column), ...sorting.map((s) => s.column)]\n .filter((c): c is PTableColumnIdColumn => c.type === 'column')\n .forEach((c) => hiddenColumns.delete(c.id));\n\n const visibleColumns = columns.filter((c) => !hiddenColumns.has(c.id));\n const visibleLabelColumns = getMatchingLabelColumns(visibleColumns.map(getColumnIdAndSpec), allLabelColumns);\n\n // if at least one column is not yet computed, we can't show the table\n if (!allPColumnsReady([...visibleColumns, ...visibleLabelColumns])) return undefined;\n\n const visibleDef = createPTableDef({\n columns: visibleColumns,\n labelColumns: visibleLabelColumns,\n coreJoinType,\n partitionFilters,\n filters,\n sorting,\n coreColumnPredicate,\n });\n const visibleHandle = ctx.createPTable(visibleDef);\n if (!visibleHandle) return undefined;\n\n return {\n sourceId: tableStateNormalized.pTableParams.sourceId,\n fullTableHandle: fullHandle,\n visibleTableHandle: visibleHandle,\n } satisfies PlDataTableModel;\n}\n\n/** Create sheet entries for PlDataTable */\nexport function createPlDataTableSheet<A, U>(\n ctx: RenderCtx<A, U>,\n axis: AxisSpec,\n values: (string | number)[],\n): PlDataTableSheet {\n const labels = ctx.resultPool.findLabels(axis);\n return {\n axis,\n options: values.map((v) => ({\n value: v,\n label: labels?.[v] ?? v.toString(),\n })),\n defaultValue: values[0],\n };\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"PlDataTable.js","sources":["../../src/components/PlDataTable.ts"],"sourcesContent":["import type {\n AxisId,\n AxisSpec,\n CanonicalizedJson,\n DataInfo,\n ListOptionBase,\n PColumn,\n PColumnIdAndSpec,\n PColumnValues,\n PObjectId,\n PTableColumnId,\n PTableColumnIdAxis,\n PTableColumnIdColumn,\n PTableColumnSpec,\n PTableDef,\n PTableHandle,\n PTableRecordFilter,\n PTableRecordSingleValueFilterV2,\n PTableSorting,\n} from '@milaboratories/pl-model-common';\nimport {\n Annotation,\n canonicalizeJson,\n getAxisId,\n getColumnIdAndSpec,\n isLabelColumn,\n isLinkerColumn,\n matchAxisId,\n PColumnName,\n readAnnotation,\n uniqueBy,\n} from '@milaboratories/pl-model-common';\nimport type {\n AxisLabelProvider,\n ColumnProvider,\n PColumnDataUniversal,\n RenderCtx,\n TreeNodeAccessor,\n} from '../render';\nimport {\n allPColumnsReady,\n deriveLabels,\n PColumnCollection,\n} from '../render';\nimport { identity } from 'es-toolkit';\n\nexport type PlTableColumnId = {\n /** Original column spec */\n source: PTableColumnSpec;\n /** Column spec with labeled axes replaced by label columns */\n labeled: PTableColumnSpec;\n};\n\nexport type PlTableColumnIdJson = CanonicalizedJson<PlTableColumnId>;\n\nexport type PlDataTableGridStateCore = {\n /** Includes column ordering */\n columnOrder?: {\n /** All colIds in order */\n orderedColIds: PlTableColumnIdJson[];\n };\n /** Includes current sort columns and direction */\n sort?: {\n /** Sorted columns and directions in order */\n sortModel: {\n /** Column Id to apply the sort to. */\n colId: PlTableColumnIdJson;\n /** Sort direction */\n sort: 'asc' | 'desc';\n }[];\n };\n /** Includes column visibility */\n columnVisibility?: {\n /** All colIds which were hidden */\n hiddenColIds: PlTableColumnIdJson[];\n };\n};\n\nexport type PlDataTableSheet = {\n /** spec of the axis to use */\n axis: AxisSpec;\n /** options to show in the filter dropdown */\n options: ListOptionBase<string | number>[];\n /** default (selected) value */\n defaultValue?: string | number;\n};\n\nexport type PlDataTableSheetState = {\n /** id of the axis */\n axisId: AxisId;\n /** selected value */\n value: string | number;\n};\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 // Normalized state\n | PlDataTableStateV2Normalized;\n\nexport type PlDataTableStateV2CacheEntry = {\n /** DataSource identifier for state management */\n sourceId: string;\n /** Internal ag-grid state */\n gridState: PlDataTableGridStateCore;\n /** Sheets state */\n sheetsState: PlDataTableSheetState[];\n /** Filters state */\n filtersState: PlDataTableFilterState[];\n};\n\nexport type PTableParamsV2 =\n | {\n sourceId: null;\n hiddenColIds: null;\n partitionFilters: [];\n filters: [];\n sorting: [];\n }\n | {\n sourceId: string;\n hiddenColIds: PObjectId[] | null;\n partitionFilters: PTableRecordFilter[];\n filters: PTableRecordFilter[];\n sorting: PTableSorting[];\n };\n\nexport type PlDataTableStateV2Normalized = {\n /** Version for upgrades */\n version: 4;\n /** Internal states, LRU cache for 5 sourceId-s */\n stateCache: PlDataTableStateV2CacheEntry[];\n /** PTable params derived from the cache state for the current sourceId */\n pTableParams: PTableParamsV2;\n};\n\nexport function makeDefaultPTableParams(): PTableParamsV2 {\n return {\n sourceId: null,\n hiddenColIds: null,\n partitionFilters: [],\n filters: [],\n sorting: [],\n };\n}\n\n/** Create default PlDataTableStateV2 */\nexport function createPlDataTableStateV2(): PlDataTableStateV2Normalized {\n return {\n version: 4,\n stateCache: [],\n pTableParams: makeDefaultPTableParams(),\n };\n}\n\n/** Upgrade PlDataTableStateV2 to the latest version */\nexport function upgradePlDataTableStateV2(state: PlDataTableStateV2 | undefined): 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: makeDefaultPTableParams(),\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 return state;\n}\n\nexport type PlDataTableFilterState = {\n id: PTableColumnId;\n alphabetic: boolean;\n filter: null | {\n value: PlTableFilter;\n disabled: boolean;\n };\n};\n\n/** PlTableFilters filter entry */\nexport type PlTableFilterIsNotNA = {\n /** Predicate type */\n type: 'isNotNA';\n};\n\n/** PlTableFilters filter entry */\nexport type PlTableFilterIsNA = {\n /** Predicate type */\n type: 'isNA';\n};\n\n/** PlTableFilters filter entries applicable to both string and number values */\nexport type PlTableFilterCommon = PlTableFilterIsNotNA | PlTableFilterIsNA;\n\n/** PlTableFilters numeric filter entry */\nexport type PlTableFilterNumberEquals = {\n /** Predicate type */\n type: 'number_equals';\n /** Reference value */\n reference: number;\n};\n\n/** PlTableFilters numeric filter entry */\nexport type PlTableFilterNumberNotEquals = {\n /** Predicate type */\n type: 'number_notEquals';\n /** Reference value */\n reference: number;\n};\n\n/** PlTableFilters numeric filter entry */\nexport type PlTableFilterNumberGreaterThan = {\n /** Predicate type */\n type: 'number_greaterThan';\n /** Reference value */\n reference: number;\n};\n\n/** PlTableFilters numeric filter entry */\nexport type PlTableFilterNumberGreaterThanOrEqualTo = {\n /** Predicate type */\n type: 'number_greaterThanOrEqualTo';\n /** Reference value */\n reference: number;\n};\n\n/** PlTableFilters numeric filter entry */\nexport type PlTableFilterNumberLessThan = {\n /** Predicate type */\n type: 'number_lessThan';\n /** Reference value */\n reference: number;\n};\n\n/** PlTableFilters numeric filter entry */\nexport type PlTableFilterNumberLessThanOrEqualTo = {\n /** Predicate type */\n type: 'number_lessThanOrEqualTo';\n /** Reference value */\n reference: number;\n};\n\n/** PlTableFilters numeric filter entry */\nexport type PlTableFilterNumberBetween = {\n /** Predicate type */\n type: 'number_between';\n /** Reference value for the lower bound */\n lowerBound: number;\n /** Defines whether values equal to lower bound reference value should be matched */\n includeLowerBound: boolean;\n /** Reference value for the upper bound */\n upperBound: number;\n /** Defines whether values equal to upper bound reference value should be matched */\n includeUpperBound: boolean;\n};\n\n/** All PlTableFilters numeric filter entries */\nexport type PlTableFilterNumber =\n | PlTableFilterCommon\n | PlTableFilterNumberEquals\n | PlTableFilterNumberNotEquals\n | PlTableFilterNumberGreaterThan\n | PlTableFilterNumberGreaterThanOrEqualTo\n | PlTableFilterNumberLessThan\n | PlTableFilterNumberLessThanOrEqualTo\n | PlTableFilterNumberBetween;\n/** All types of PlTableFilters numeric filter entries */\nexport type PlTableFilterNumberType = PlTableFilterNumber['type'];\n\n/** PlTableFilters string filter entry */\nexport type PlTableFilterStringEquals = {\n /** Predicate type */\n type: 'string_equals';\n /** Reference value */\n reference: string;\n};\n\n/** PlTableFilters string filter entry */\nexport type PlTableFilterStringNotEquals = {\n /** Predicate type */\n type: 'string_notEquals';\n /** Reference value */\n reference: string;\n};\n\n/** PlTableFilters string filter entry */\nexport type PlTableFilterStringContains = {\n /** Predicate type */\n type: 'string_contains';\n /** Reference value */\n reference: string;\n};\n\n/** PlTableFilters string filter entry */\nexport type PlTableFilterStringDoesNotContain = {\n /** Predicate type */\n type: 'string_doesNotContain';\n /** Reference value */\n reference: string;\n};\n\n/** PlTableFilters string filter entry */\nexport type PlTableFilterStringMatches = {\n /** Predicate type */\n type: 'string_matches';\n /** Reference value */\n reference: string;\n};\n\n/** PlTableFilters string filter entry */\nexport type PlTableFilterStringDoesNotMatch = {\n /** Predicate type */\n type: 'string_doesNotMatch';\n /** Reference value */\n reference: string;\n};\n\n/** PlTableFilters string filter entry */\nexport type PlTableFilterStringContainsFuzzyMatch = {\n /** Predicate type */\n type: 'string_containsFuzzyMatch';\n /** Reference value */\n reference: string;\n /**\n * Maximum acceptable edit distance between reference value and matched substring\n * @see https://en.wikipedia.org/wiki/Edit_distance\n */\n maxEdits: number;\n /**\n * When {@link substitutionsOnly} is set to false\n * Levenshtein distance is used as edit distance (substitutions and indels)\n * @see https://en.wikipedia.org/wiki/Levenshtein_distance\n * When {@link substitutionsOnly} is set to true\n * Hamming distance is used as edit distance (substitutions only)\n * @see https://en.wikipedia.org/wiki/Hamming_distance\n */\n substitutionsOnly: boolean;\n /**\n * Single character in {@link reference} that will labelColumn any\n * single character in searched text.\n */\n wildcard?: string;\n};\n\n/** All PlTableFilters string filter entries */\nexport type PlTableFilterString =\n | PlTableFilterCommon\n | PlTableFilterStringEquals\n | PlTableFilterStringNotEquals\n | PlTableFilterStringContains\n | PlTableFilterStringDoesNotContain\n | PlTableFilterStringMatches\n | PlTableFilterStringDoesNotMatch\n | PlTableFilterStringContainsFuzzyMatch;\n/** All types of PlTableFilters string filter entries */\nexport type PlTableFilterStringType = PlTableFilterString['type'];\n\n/** All PlTableFilters filter entries */\nexport type PlTableFilter = PlTableFilterNumber | PlTableFilterString;\n/** All types of PlTableFilters filter entries */\nexport type PlTableFilterType = PlTableFilter['type'];\n\nexport type CreatePlDataTableOps = {\n /** Filters for columns and non-partitioned axes */\n filters?: PTableRecordFilter[];\n\n /** Sorting to columns hidden from user */\n sorting?: PTableSorting[];\n\n /**\n * Selects columns for which will be inner-joined to the table.\n *\n * Default behaviour: all columns are considered to be core\n */\n coreColumnPredicate?: (spec: PColumnIdAndSpec) => boolean;\n\n /**\n * Determines how core columns should be joined together:\n * inner - so user will only see records present in all core columns\n * full - so user will only see records present in any of the core columns\n *\n * All non-core columns will be left joined to the table produced by the core\n * columns, in other words records form the pool of non-core columns will only\n * make their way into the final table if core table contains corresponding key.\n *\n * Default: 'full'\n */\n coreJoinType?: 'inner' | 'full';\n};\n\n/** Get all label columns from the result pool */\nexport function getAllLabelColumns(\n resultPool: AxisLabelProvider & ColumnProvider,\n): PColumn<PColumnDataUniversal>[] | undefined {\n return new PColumnCollection()\n .addAxisLabelProvider(resultPool)\n .addColumnProvider(resultPool)\n .getColumns({\n name: PColumnName.Label,\n axes: [{}], // exactly one axis\n }, { dontWaitAllData: true, overrideLabelAnnotation: false });\n}\n\n/** Get label columns matching the provided columns from the result pool */\nexport function getMatchingLabelColumns(\n columns: PColumnIdAndSpec[],\n allLabelColumns: PColumn<PColumnDataUniversal>[],\n): PColumn<PColumnDataUniversal>[] {\n // split input columns into label and value columns\n const inputLabelColumns: typeof columns = [];\n const inputValueColumns: typeof columns = [];\n for (const column of columns) {\n if (isLabelColumn(column.spec)) {\n inputLabelColumns.push(column);\n } else {\n inputValueColumns.push(column);\n }\n }\n\n // collect distinct axes of value columns\n const unlabeledAxes: AxisId[] = [];\n for (const column of inputValueColumns) {\n for (const axis of column.spec.axesSpec) {\n const axisId = getAxisId(axis);\n if (!unlabeledAxes.some((id) => matchAxisId(id, axisId))) {\n unlabeledAxes.push(axisId);\n }\n }\n }\n\n // remove axes matched by input label columns\n for (const labelColumn of inputLabelColumns) {\n const labelAxisId = getAxisId(labelColumn.spec.axesSpec[0]);\n const labelMatch = unlabeledAxes.findIndex((axisId) => matchAxisId(axisId, labelAxisId));\n if (labelMatch !== -1) {\n unlabeledAxes.splice(labelMatch, 1);\n }\n }\n\n // warning: changing this id will break backward compatibility\n const colId = (id: PObjectId, domain?: Record<string, string>): PObjectId => {\n let wid = id.toString();\n if (domain) {\n for (const k in domain) {\n wid += k;\n wid += domain[k];\n }\n }\n return wid as PObjectId;\n };\n\n // search label columns for unmatched axes\n const labelColumns: typeof allLabelColumns = [];\n for (const labelColumn of allLabelColumns) {\n const labelAxis = labelColumn.spec.axesSpec[0];\n const labelAxisId = getAxisId(labelAxis);\n const labelMatch = unlabeledAxes.findIndex((axisId) => matchAxisId(axisId, labelAxisId));\n if (labelMatch !== -1) {\n const axisId = unlabeledAxes[labelMatch];\n const dataDomainLen = Object.keys(axisId.domain ?? {}).length;\n const labelDomainLen = Object.keys(labelAxis.domain ?? {}).length;\n if (dataDomainLen > labelDomainLen) {\n labelColumns.push({\n id: colId(labelColumn.id, axisId.domain),\n spec: {\n ...labelColumn.spec,\n axesSpec: [{ ...axisId, annotations: labelAxis.annotations }],\n },\n data: labelColumn.data,\n });\n } else {\n labelColumns.push(labelColumn);\n }\n unlabeledAxes.splice(labelMatch, 1);\n }\n }\n return labelColumns;\n}\n\nfunction createPTableDef(params: {\n columns: PColumn<PColumnDataUniversal>[];\n labelColumns: PColumn<PColumnDataUniversal>[];\n coreJoinType: 'inner' | 'full';\n partitionFilters: PTableRecordSingleValueFilterV2[];\n filters: PTableRecordSingleValueFilterV2[];\n sorting: PTableSorting[];\n coreColumnPredicate?: ((spec: PColumnIdAndSpec) => boolean);\n}): PTableDef<PColumn<TreeNodeAccessor | PColumnValues | DataInfo<TreeNodeAccessor>>> {\n let coreColumns = params.columns;\n const secondaryColumns: typeof params.columns = [];\n\n if (params.coreColumnPredicate) {\n coreColumns = [];\n for (const c of params.columns)\n if (params.coreColumnPredicate(getColumnIdAndSpec(c))) coreColumns.push(c);\n else secondaryColumns.push(c);\n }\n\n secondaryColumns.push(...params.labelColumns);\n\n return {\n src: {\n type: 'outer',\n primary: {\n type: params.coreJoinType,\n entries: coreColumns.map((c) => ({ type: 'column', column: c })),\n },\n secondary: secondaryColumns.map((c) => ({ type: 'column', column: c })),\n },\n partitionFilters: params.partitionFilters,\n filters: params.filters,\n sorting: params.sorting,\n };\n}\n\n/** PlAgDataTable model */\nexport type PlDataTableModel = {\n /** DataSource identifier for state management */\n sourceId: string | null;\n /** p-table including all columns, used to show the full specification of the table */\n fullTableHandle: PTableHandle;\n /** p-table including only visible columns, used to get the data */\n visibleTableHandle: PTableHandle;\n};\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/**\n * Create p-table spec and handle given ui table state\n *\n * @param ctx context\n * @param columns column list\n * @param tableState table ui state\n * @returns PlAgDataTableV2 table source\n */\nexport function createPlDataTableV2<A, U>(\n ctx: RenderCtx<A, U>,\n columns: PColumn<PColumnDataUniversal>[],\n tableState: PlDataTableStateV2 | undefined,\n ops?: CreatePlDataTableOps,\n): PlDataTableModel | undefined {\n if (columns.length === 0) return undefined;\n\n const tableStateNormalized = upgradePlDataTableStateV2(tableState);\n\n const allLabelColumns = getAllLabelColumns(ctx.resultPool);\n if (!allLabelColumns) return undefined;\n\n let fullLabelColumns = getMatchingLabelColumns(columns.map(getColumnIdAndSpec), allLabelColumns);\n fullLabelColumns = deriveLabels(fullLabelColumns, identity, { includeNativeLabel: true }).map((v) => {\n return {\n ...v.value,\n spec: {\n ...v.value.spec,\n annotations: {\n ...v.value.spec.annotations,\n [Annotation.Label]: v.label,\n },\n },\n };\n });\n\n const fullColumns = [...columns, ...fullLabelColumns];\n\n const fullColumnsAxes = uniqueBy(\n fullColumns.flatMap((c) => c.spec.axesSpec.map((a) => getAxisId(a))),\n (a) => canonicalizeJson<AxisId>(a),\n );\n const fullColumnsIds: PTableColumnId[] = [\n ...fullColumnsAxes.map((a) => ({ type: 'axis', id: a } satisfies PTableColumnIdAxis)),\n ...fullColumns.map((c) => ({ type: 'column', id: c.id } satisfies PTableColumnIdColumn)),\n ];\n const fullColumnsIdsSet = new Set(fullColumnsIds.map((c) => canonicalizeJson<PTableColumnId>(c)));\n const isValidColumnId = (id: PTableColumnId): boolean => fullColumnsIdsSet.has(canonicalizeJson<PTableColumnId>(id));\n\n const coreJoinType = ops?.coreJoinType ?? 'full';\n const partitionFilters: PTableRecordSingleValueFilterV2[]\n = tableStateNormalized.pTableParams.partitionFilters\n .filter((f) => {\n const valid = isValidColumnId(f.column);\n if (!valid) ctx.logWarn(`Partition filter ${JSON.stringify(f)} does not match provided columns, skipping`);\n return valid;\n });\n const filters: PTableRecordSingleValueFilterV2[]\n = uniqueBy(\n [...tableStateNormalized.pTableParams.filters, ...(ops?.filters ?? [])],\n (f) => canonicalizeJson<PTableColumnId>(f.column),\n ).filter((f) => {\n const valid = isValidColumnId(f.column);\n if (!valid) ctx.logWarn(`Filter ${JSON.stringify(f)} does not match provided columns, skipping`);\n return valid;\n });\n const sorting: PTableSorting[]\n = uniqueBy(\n [...tableStateNormalized.pTableParams.sorting, ...(ops?.sorting ?? [])],\n (s) => canonicalizeJson<PTableColumnId>(s.column),\n ).filter((s) => {\n const valid = isValidColumnId(s.column);\n if (!valid) ctx.logWarn(`Sorting ${JSON.stringify(s)} does not match provided columns, skipping`);\n return valid;\n });\n\n const fullDef = createPTableDef({\n columns,\n labelColumns: fullLabelColumns,\n coreJoinType,\n partitionFilters,\n filters,\n sorting,\n coreColumnPredicate: ops?.coreColumnPredicate,\n });\n const fullHandle = ctx.createPTable(fullDef);\n if (!fullHandle) return undefined;\n\n const hiddenColumns = new Set<PObjectId>(((): PObjectId[] => {\n // Inner join works as a filter - all columns must be present\n if (coreJoinType === 'inner') return [];\n\n const hiddenColIds = tableStateNormalized.pTableParams.hiddenColIds;\n if (hiddenColIds) return hiddenColIds;\n\n return columns\n .filter((c) => isColumnOptional(c.spec))\n .map((c) => c.id);\n })());\n\n // Preserve linker columns\n columns\n .filter((c) => isLinkerColumn(c.spec))\n .forEach((c) => hiddenColumns.delete(c.id));\n\n // Preserve core columns as they change the shape of join.\n const coreColumnPredicate = ops?.coreColumnPredicate;\n if (coreColumnPredicate) {\n const coreColumns = columns.flatMap((c) => coreColumnPredicate(getColumnIdAndSpec(c)) ? [c.id] : []);\n coreColumns.forEach((c) => hiddenColumns.delete(c));\n }\n\n // Filters decrease the number of result rows, sorting changes the order of result rows\n [...partitionFilters.map((f) => f.column), ...filters.map((f) => f.column), ...sorting.map((s) => s.column)]\n .filter((c): c is PTableColumnIdColumn => c.type === 'column')\n .forEach((c) => hiddenColumns.delete(c.id));\n\n const visibleColumns = columns.filter((c) => !hiddenColumns.has(c.id));\n const visibleLabelColumns = getMatchingLabelColumns(visibleColumns.map(getColumnIdAndSpec), allLabelColumns);\n\n // if at least one column is not yet computed, we can't show the table\n if (!allPColumnsReady([...visibleColumns, ...visibleLabelColumns])) return undefined;\n\n const visibleDef = createPTableDef({\n columns: visibleColumns,\n labelColumns: visibleLabelColumns,\n coreJoinType,\n partitionFilters,\n filters,\n sorting,\n coreColumnPredicate,\n });\n const visibleHandle = ctx.createPTable(visibleDef);\n if (!visibleHandle) return undefined;\n\n return {\n sourceId: tableStateNormalized.pTableParams.sourceId,\n fullTableHandle: fullHandle,\n visibleTableHandle: visibleHandle,\n } satisfies PlDataTableModel;\n}\n\n/** Create sheet entries for PlDataTable */\nexport function createPlDataTableSheet<A, U>(\n ctx: RenderCtx<A, U>,\n axis: AxisSpec,\n values: (string | number)[],\n): PlDataTableSheet {\n const labels = ctx.resultPool.findLabels(axis);\n return {\n axis,\n options: values.map((v) => ({\n value: v,\n label: labels?.[v] ?? v.toString(),\n })),\n defaultValue: values[0],\n };\n}\n"],"names":[],"mappings":";;;;;;;SAkNgB,uBAAuB,GAAA;IACrC,OAAO;AACL,QAAA,QAAQ,EAAE,IAAI;AACd,QAAA,YAAY,EAAE,IAAI;AAClB,QAAA,gBAAgB,EAAE,EAAE;AACpB,QAAA,OAAO,EAAE,EAAE;AACX,QAAA,OAAO,EAAE,EAAE;KACZ;AACH;AAEA;SACgB,wBAAwB,GAAA;IACtC,OAAO;AACL,QAAA,OAAO,EAAE,CAAC;AACV,QAAA,UAAU,EAAE,EAAE;QACd,YAAY,EAAE,uBAAuB,EAAE;KACxC;AACH;AAEA;AACM,SAAU,yBAAyB,CAAC,KAAqC,EAAA;;IAE7E,IAAI,CAAC,KAAK,EAAE;QACV,OAAO,wBAAwB,EAAE;IACnC;;AAEA,IAAA,IAAI,EAAE,SAAS,IAAI,KAAK,CAAC,EAAE;;QAEzB,KAAK,GAAG,wBAAwB,EAAE;IACpC;;AAEA,IAAA,IAAI,KAAK,CAAC,OAAO,KAAK,CAAC,EAAE;AACvB,QAAA,KAAK,GAAG;AACN,YAAA,OAAO,EAAE,CAAC;AACV,YAAA,UAAU,EAAE,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,KAAK,MAAM;AAC3C,gBAAA,GAAG,KAAK;AACR,gBAAA,YAAY,EAAE,EAAE;AACjB,aAAA,CAAC,CAAC;YACH,YAAY,EAAE,uBAAuB,EAAE;SACxC;IACH;;AAEA,IAAA,IAAI,KAAK,CAAC,OAAO,KAAK,CAAC,EAAE;;QAEvB,KAAK,GAAG,wBAAwB,EAAE;IACpC;AACA,IAAA,OAAO,KAAK;AACd;AA8NA;AACM,SAAU,kBAAkB,CAChC,UAA8C,EAAA;IAE9C,OAAO,IAAI,iBAAiB;SACzB,oBAAoB,CAAC,UAAU;SAC/B,iBAAiB,CAAC,UAAU;AAC5B,SAAA,UAAU,CAAC;QACV,IAAI,EAAE,WAAW,CAAC,KAAK;AACvB,QAAA,IAAI,EAAE,CAAC,EAAE,CAAC;KACX,EAAE,EAAE,eAAe,EAAE,IAAI,EAAE,uBAAuB,EAAE,KAAK,EAAE,CAAC;AACjE;AAEA;AACM,SAAU,uBAAuB,CACrC,OAA2B,EAC3B,eAAgD,EAAA;;IAGhD,MAAM,iBAAiB,GAAmB,EAAE;IAC5C,MAAM,iBAAiB,GAAmB,EAAE;AAC5C,IAAA,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE;AAC5B,QAAA,IAAI,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE;AAC9B,YAAA,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC;QAChC;aAAO;AACL,YAAA,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC;QAChC;IACF;;IAGA,MAAM,aAAa,GAAa,EAAE;AAClC,IAAA,KAAK,MAAM,MAAM,IAAI,iBAAiB,EAAE;QACtC,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE;AACvC,YAAA,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC;AAC9B,YAAA,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,WAAW,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC,EAAE;AACxD,gBAAA,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC;YAC5B;QACF;IACF;;AAGA,IAAA,KAAK,MAAM,WAAW,IAAI,iBAAiB,EAAE;AAC3C,QAAA,MAAM,WAAW,GAAG,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AAC3D,QAAA,MAAM,UAAU,GAAG,aAAa,CAAC,SAAS,CAAC,CAAC,MAAM,KAAK,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;AACxF,QAAA,IAAI,UAAU,KAAK,EAAE,EAAE;AACrB,YAAA,aAAa,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC;QACrC;IACF;;AAGA,IAAA,MAAM,KAAK,GAAG,CAAC,EAAa,EAAE,MAA+B,KAAe;AAC1E,QAAA,IAAI,GAAG,GAAG,EAAE,CAAC,QAAQ,EAAE;QACvB,IAAI,MAAM,EAAE;AACV,YAAA,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE;gBACtB,GAAG,IAAI,CAAC;AACR,gBAAA,GAAG,IAAI,MAAM,CAAC,CAAC,CAAC;YAClB;QACF;AACA,QAAA,OAAO,GAAgB;AACzB,IAAA,CAAC;;IAGD,MAAM,YAAY,GAA2B,EAAE;AAC/C,IAAA,KAAK,MAAM,WAAW,IAAI,eAAe,EAAE;QACzC,MAAM,SAAS,GAAG,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;AAC9C,QAAA,MAAM,WAAW,GAAG,SAAS,CAAC,SAAS,CAAC;AACxC,QAAA,MAAM,UAAU,GAAG,aAAa,CAAC,SAAS,CAAC,CAAC,MAAM,KAAK,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;AACxF,QAAA,IAAI,UAAU,KAAK,EAAE,EAAE;AACrB,YAAA,MAAM,MAAM,GAAG,aAAa,CAAC,UAAU,CAAC;AACxC,YAAA,MAAM,aAAa,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,MAAM;AAC7D,YAAA,MAAM,cAAc,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,MAAM;AACjE,YAAA,IAAI,aAAa,GAAG,cAAc,EAAE;gBAClC,YAAY,CAAC,IAAI,CAAC;oBAChB,EAAE,EAAE,KAAK,CAAC,WAAW,CAAC,EAAE,EAAE,MAAM,CAAC,MAAM,CAAC;AACxC,oBAAA,IAAI,EAAE;wBACJ,GAAG,WAAW,CAAC,IAAI;AACnB,wBAAA,QAAQ,EAAE,CAAC,EAAE,GAAG,MAAM,EAAE,WAAW,EAAE,SAAS,CAAC,WAAW,EAAE,CAAC;AAC9D,qBAAA;oBACD,IAAI,EAAE,WAAW,CAAC,IAAI;AACvB,iBAAA,CAAC;YACJ;iBAAO;AACL,gBAAA,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC;YAChC;AACA,YAAA,aAAa,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC;QACrC;IACF;AACA,IAAA,OAAO,YAAY;AACrB;AAEA,SAAS,eAAe,CAAC,MAQxB,EAAA;AACC,IAAA,IAAI,WAAW,GAAG,MAAM,CAAC,OAAO;IAChC,MAAM,gBAAgB,GAA0B,EAAE;AAElD,IAAA,IAAI,MAAM,CAAC,mBAAmB,EAAE;QAC9B,WAAW,GAAG,EAAE;AAChB,QAAA,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO;YAC5B,IAAI,MAAM,CAAC,mBAAmB,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC;AAAE,gBAAA,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC;;AACrE,gBAAA,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC;IACjC;IAEA,gBAAgB,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,YAAY,CAAC;IAE7C,OAAO;AACL,QAAA,GAAG,EAAE;AACH,YAAA,IAAI,EAAE,OAAO;AACb,YAAA,OAAO,EAAE;gBACP,IAAI,EAAE,MAAM,CAAC,YAAY;gBACzB,OAAO,EAAE,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;AACjE,aAAA;YACD,SAAS,EAAE,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;AACxE,SAAA;QACD,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;QACzC,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,OAAO,EAAE,MAAM,CAAC,OAAO;KACxB;AACH;AAYA;AACM,SAAU,cAAc,CAAC,IAAkC,EAAA;AAC/D,IAAA,OAAO,cAAc,CAAC,IAAI,EAAE,UAAU,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,QAAQ;AACvE;AAEA;AACM,SAAU,gBAAgB,CAAC,IAAkC,EAAA;AACjE,IAAA,OAAO,cAAc,CAAC,IAAI,EAAE,UAAU,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,UAAU;AACzE;AAEA;;;;;;;AAOG;AACG,SAAU,mBAAmB,CACjC,GAAoB,EACpB,OAAwC,EACxC,UAA0C,EAC1C,GAA0B,EAAA;AAE1B,IAAA,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;AAAE,QAAA,OAAO,SAAS;AAE1C,IAAA,MAAM,oBAAoB,GAAG,yBAAyB,CAAC,UAAU,CAAC;IAElE,MAAM,eAAe,GAAG,kBAAkB,CAAC,GAAG,CAAC,UAAU,CAAC;AAC1D,IAAA,IAAI,CAAC,eAAe;AAAE,QAAA,OAAO,SAAS;AAEtC,IAAA,IAAI,gBAAgB,GAAG,uBAAuB,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,EAAE,eAAe,CAAC;AAChG,IAAA,gBAAgB,GAAG,YAAY,CAAC,gBAAgB,EAAE,QAAQ,EAAE,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAI;QAClG,OAAO;YACL,GAAG,CAAC,CAAC,KAAK;AACV,YAAA,IAAI,EAAE;AACJ,gBAAA,GAAG,CAAC,CAAC,KAAK,CAAC,IAAI;AACf,gBAAA,WAAW,EAAE;AACX,oBAAA,GAAG,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW;AAC3B,oBAAA,CAAC,UAAU,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK;AAC5B,iBAAA;AACF,aAAA;SACF;AACH,IAAA,CAAC,CAAC;IAEF,MAAM,WAAW,GAAG,CAAC,GAAG,OAAO,EAAE,GAAG,gBAAgB,CAAC;AAErD,IAAA,MAAM,eAAe,GAAG,QAAQ,CAC9B,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,EACpE,CAAC,CAAC,KAAK,gBAAgB,CAAS,CAAC,CAAC,CACnC;AACD,IAAA,MAAM,cAAc,GAAqB;QACvC,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,EAAgC,CAAA,CAAC;QACrF,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAkC,CAAA,CAAC;KACzF;IACD,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,gBAAgB,CAAiB,CAAC,CAAC,CAAC,CAAC;AACjG,IAAA,MAAM,eAAe,GAAG,CAAC,EAAkB,KAAc,iBAAiB,CAAC,GAAG,CAAC,gBAAgB,CAAiB,EAAE,CAAC,CAAC;AAEpH,IAAA,MAAM,YAAY,GAAG,GAAG,EAAE,YAAY,IAAI,MAAM;AAChD,IAAA,MAAM,gBAAgB,GAClB,oBAAoB,CAAC,YAAY,CAAC;AACjC,SAAA,MAAM,CAAC,CAAC,CAAC,KAAI;QACZ,MAAM,KAAK,GAAG,eAAe,CAAC,CAAC,CAAC,MAAM,CAAC;AACvC,QAAA,IAAI,CAAC,KAAK;AAAE,YAAA,GAAG,CAAC,OAAO,CAAC,CAAA,iBAAA,EAAoB,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAA,0CAAA,CAA4C,CAAC;AAC1G,QAAA,OAAO,KAAK;AACd,IAAA,CAAC,CAAC;AACN,IAAA,MAAM,OAAO,GACT,QAAQ,CACR,CAAC,GAAG,oBAAoB,CAAC,YAAY,CAAC,OAAO,EAAE,IAAI,GAAG,EAAE,OAAO,IAAI,EAAE,CAAC,CAAC,EACvE,CAAC,CAAC,KAAK,gBAAgB,CAAiB,CAAC,CAAC,MAAM,CAAC,CAClD,CAAC,MAAM,CAAC,CAAC,CAAC,KAAI;QACb,MAAM,KAAK,GAAG,eAAe,CAAC,CAAC,CAAC,MAAM,CAAC;AACvC,QAAA,IAAI,CAAC,KAAK;AAAE,YAAA,GAAG,CAAC,OAAO,CAAC,CAAA,OAAA,EAAU,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAA,0CAAA,CAA4C,CAAC;AAChG,QAAA,OAAO,KAAK;AACd,IAAA,CAAC,CAAC;AACJ,IAAA,MAAM,OAAO,GACT,QAAQ,CACR,CAAC,GAAG,oBAAoB,CAAC,YAAY,CAAC,OAAO,EAAE,IAAI,GAAG,EAAE,OAAO,IAAI,EAAE,CAAC,CAAC,EACvE,CAAC,CAAC,KAAK,gBAAgB,CAAiB,CAAC,CAAC,MAAM,CAAC,CAClD,CAAC,MAAM,CAAC,CAAC,CAAC,KAAI;QACb,MAAM,KAAK,GAAG,eAAe,CAAC,CAAC,CAAC,MAAM,CAAC;AACvC,QAAA,IAAI,CAAC,KAAK;AAAE,YAAA,GAAG,CAAC,OAAO,CAAC,CAAA,QAAA,EAAW,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAA,0CAAA,CAA4C,CAAC;AACjG,QAAA,OAAO,KAAK;AACd,IAAA,CAAC,CAAC;IAEJ,MAAM,OAAO,GAAG,eAAe,CAAC;QAC9B,OAAO;AACP,QAAA,YAAY,EAAE,gBAAgB;QAC9B,YAAY;QACZ,gBAAgB;QAChB,OAAO;QACP,OAAO;QACP,mBAAmB,EAAE,GAAG,EAAE,mBAAmB;AAC9C,KAAA,CAAC;IACF,MAAM,UAAU,GAAG,GAAG,CAAC,YAAY,CAAC,OAAO,CAAC;AAC5C,IAAA,IAAI,CAAC,UAAU;AAAE,QAAA,OAAO,SAAS;AAEjC,IAAA,MAAM,aAAa,GAAG,IAAI,GAAG,CAAY,CAAC,MAAkB;;QAE1D,IAAI,YAAY,KAAK,OAAO;AAAE,YAAA,OAAO,EAAE;AAEvC,QAAA,MAAM,YAAY,GAAG,oBAAoB,CAAC,YAAY,CAAC,YAAY;AACnE,QAAA,IAAI,YAAY;AAAE,YAAA,OAAO,YAAY;AAErC,QAAA,OAAO;AACJ,aAAA,MAAM,CAAC,CAAC,CAAC,KAAK,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC;aACtC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;IACrB,CAAC,GAAG,CAAC;;IAGL;AACG,SAAA,MAAM,CAAC,CAAC,CAAC,KAAK,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC;AACpC,SAAA,OAAO,CAAC,CAAC,CAAC,KAAK,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;;AAG7C,IAAA,MAAM,mBAAmB,GAAG,GAAG,EAAE,mBAAmB;IACpD,IAAI,mBAAmB,EAAE;AACvB,QAAA,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,mBAAmB,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC;AACpG,QAAA,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IACrD;;IAGA,CAAC,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC;SACxG,MAAM,CAAC,CAAC,CAAC,KAAgC,CAAC,CAAC,IAAI,KAAK,QAAQ;AAC5D,SAAA,OAAO,CAAC,CAAC,CAAC,KAAK,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAE7C,MAAM,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AACtE,IAAA,MAAM,mBAAmB,GAAG,uBAAuB,CAAC,cAAc,CAAC,GAAG,CAAC,kBAAkB,CAAC,EAAE,eAAe,CAAC;;IAG5G,IAAI,CAAC,gBAAgB,CAAC,CAAC,GAAG,cAAc,EAAE,GAAG,mBAAmB,CAAC,CAAC;AAAE,QAAA,OAAO,SAAS;IAEpF,MAAM,UAAU,GAAG,eAAe,CAAC;AACjC,QAAA,OAAO,EAAE,cAAc;AACvB,QAAA,YAAY,EAAE,mBAAmB;QACjC,YAAY;QACZ,gBAAgB;QAChB,OAAO;QACP,OAAO;QACP,mBAAmB;AACpB,KAAA,CAAC;IACF,MAAM,aAAa,GAAG,GAAG,CAAC,YAAY,CAAC,UAAU,CAAC;AAClD,IAAA,IAAI,CAAC,aAAa;AAAE,QAAA,OAAO,SAAS;IAEpC,OAAO;AACL,QAAA,QAAQ,EAAE,oBAAoB,CAAC,YAAY,CAAC,QAAQ;AACpD,QAAA,eAAe,EAAE,UAAU;AAC3B,QAAA,kBAAkB,EAAE,aAAa;KACP;AAC9B;AAEA;SACgB,sBAAsB,CACpC,GAAoB,EACpB,IAAc,EACd,MAA2B,EAAA;IAE3B,MAAM,MAAM,GAAG,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC;IAC9C,OAAO;QACL,IAAI;QACJ,OAAO,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM;AAC1B,YAAA,KAAK,EAAE,CAAC;YACR,KAAK,EAAE,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE;AACnC,SAAA,CAAC,CAAC;AACH,QAAA,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC;KACxB;AACH;;;;"}
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var version = "1.51.2";
3
+ var version = "1.51.6";
4
4
 
5
5
  exports.version = version;
6
6
  //# sourceMappingURL=package.json.cjs.map
@@ -1,4 +1,4 @@
1
- var version = "1.51.2";
1
+ var version = "1.51.6";
2
2
 
3
3
  export { version };
4
4
  //# sourceMappingURL=package.json.js.map
@@ -110,6 +110,25 @@ function deriveLabels(values, specExtractor, ops = {}) {
110
110
  }
111
111
  return result;
112
112
  };
113
+ // Checks if a result has all unique labels
114
+ const hasUniqueLabels = (result) => result !== undefined && new Set(result.map((c) => c.label)).size === values.length;
115
+ // Post-processing: try removing types one by one (lowest importance first) to minimize the label set
116
+ const minimizeTypeSet = (typeSet) => {
117
+ // Get types sorted by importance ascending (lowest first), excluding forced elements
118
+ const removableSorted = [...typeSet]
119
+ .filter((t) => !forceTraceElements?.has(t.split('@')[0])
120
+ && !(ops.includeNativeLabel && t === LabelTypeFull))
121
+ .sort((a, b) => (importances.get(a) ?? 0) - (importances.get(b) ?? 0));
122
+ for (const typeToRemove of removableSorted) {
123
+ const reducedSet = new Set(typeSet);
124
+ reducedSet.delete(typeToRemove);
125
+ const candidateResult = calculate(reducedSet);
126
+ if (hasUniqueLabels(candidateResult)) {
127
+ typeSet.delete(typeToRemove);
128
+ }
129
+ }
130
+ return typeSet;
131
+ };
113
132
  if (mainTypes.length === 0) {
114
133
  if (secondaryTypes.length !== 0)
115
134
  throw new Error('Non-empty secondary types list while main types list is empty.');
@@ -135,16 +154,20 @@ function deriveLabels(values, specExtractor, ops = {}) {
135
154
  if (additionalType >= 0)
136
155
  currentSet.add(mainTypes[additionalType]);
137
156
  const candidateResult = calculate(currentSet);
138
- // checking if labels uniquely separate our records
139
- if (candidateResult !== undefined && new Set(candidateResult.map((c) => c.label)).size === values.length)
140
- return candidateResult;
157
+ if (hasUniqueLabels(candidateResult)) {
158
+ minimizeTypeSet(currentSet);
159
+ return calculate(currentSet);
160
+ }
141
161
  additionalType++;
142
162
  if (additionalType >= mainTypes.length) {
143
163
  includedTypes++;
144
164
  additionalType = includedTypes;
145
165
  }
146
166
  }
147
- return calculate(new Set([...mainTypes, ...secondaryTypes]), true);
167
+ // Fallback: include all types, then try to minimize
168
+ const fallbackSet = new Set([...mainTypes, ...secondaryTypes]);
169
+ minimizeTypeSet(fallbackSet);
170
+ return calculate(fallbackSet, true);
148
171
  }
149
172
 
150
173
  exports.Trace = Trace;
@@ -1 +1 @@
1
- {"version":3,"file":"label.cjs","sources":["../../../src/render/util/label.ts"],"sourcesContent":["import { Annotation, parseJson, readAnnotation, type PObjectSpec } from '@milaboratories/pl-model-common';\nimport { z } from 'zod';\n\nexport type RecordsWithLabel<T> = {\n value: T;\n label: string;\n};\n\nexport type LabelDerivationOps = {\n /** Force inclusion of native column label */\n includeNativeLabel?: boolean;\n /** Separator to use between label parts (\" / \" by default) */\n separator?: string;\n /** If true, label will be added as suffix (at the end of the generated label). By default label added as a prefix. */\n addLabelAsSuffix?: boolean;\n /** Trace elements list that will be forced to be included in the label. */\n forceTraceElements?: string[];\n};\n\nexport const TraceEntry = z.object({\n type: z.string(),\n importance: z.number().optional(),\n id: z.string().optional(),\n label: z.string(),\n});\nexport type TraceEntry = z.infer<typeof TraceEntry>;\ntype FullTraceEntry = TraceEntry & { fullType: string; occurrenceIndex: number };\n\nexport const Trace = z.array(TraceEntry);\nexport type Trace = z.infer<typeof Trace>;\ntype FullTrace = FullTraceEntry[];\n\n// Define the possible return types for the specExtractor function\ntype SpecExtractorResult = PObjectSpec | {\n spec: PObjectSpec;\n prefixTrace?: TraceEntry[];\n suffixTrace?: TraceEntry[];\n};\n\nconst DistancePenalty = 0.001;\n\nconst LabelType = '__LABEL__';\nconst LabelTypeFull = '__LABEL__@1';\n\nexport function deriveLabels<T>(\n values: T[],\n specExtractor: (obj: T) => SpecExtractorResult,\n ops: LabelDerivationOps = {},\n): RecordsWithLabel<T>[] {\n const importances = new Map<string, number>();\n\n const forceTraceElements = (ops.forceTraceElements !== undefined && ops.forceTraceElements.length > 0)\n ? new Set(ops.forceTraceElements)\n : undefined;\n\n // number of times certain type occurred among all of the\n const numberOfRecordsWithType = new Map<string, number>();\n\n const enrichedRecords = values.map((value) => {\n const extractorResult = specExtractor(value);\n let spec: PObjectSpec;\n let prefixTrace: TraceEntry[] | undefined;\n let suffixTrace: TraceEntry[] | undefined;\n\n // Check if the result is the new structure or just PObjectSpec\n if ('spec' in extractorResult && typeof extractorResult.spec === 'object') {\n // It's the new structure { spec, prefixTrace?, suffixTrace? }\n spec = extractorResult.spec;\n prefixTrace = extractorResult.prefixTrace;\n suffixTrace = extractorResult.suffixTrace;\n } else {\n // It's just PObjectSpec\n spec = extractorResult as PObjectSpec;\n }\n\n const label = readAnnotation(spec, Annotation.Label);\n const traceStr = readAnnotation(spec, Annotation.Trace);\n const baseTrace = (traceStr ? Trace.safeParse(parseJson(traceStr)).data : undefined) ?? [];\n\n const trace = [\n ...(prefixTrace ?? []),\n ...baseTrace,\n ...(suffixTrace ?? []),\n ];\n\n if (label !== undefined) {\n const labelEntry = { label, type: LabelType, importance: -2 };\n if (ops.addLabelAsSuffix) trace.push(labelEntry);\n else trace.splice(0, 0, labelEntry);\n }\n\n const fullTrace: FullTrace = [];\n\n const occurrences = new Map<string, number>();\n for (let i = trace.length - 1; i >= 0; --i) {\n const { type: typeName } = trace[i];\n const importance = trace[i].importance ?? 0;\n const occurrenceIndex = (occurrences.get(typeName) ?? 0) + 1;\n occurrences.set(typeName, occurrenceIndex);\n const fullType = `${typeName}@${occurrenceIndex}`;\n numberOfRecordsWithType.set(fullType, (numberOfRecordsWithType.get(fullType) ?? 0) + 1);\n importances.set(\n fullType,\n Math.max(\n importances.get(fullType) ?? Number.NEGATIVE_INFINITY,\n importance - (trace.length - i) * DistancePenalty,\n ),\n );\n fullTrace.push({ ...trace[i], fullType, occurrenceIndex: occurrenceIndex });\n }\n fullTrace.reverse();\n return {\n value,\n spec,\n label,\n fullTrace,\n };\n });\n\n // excluding repeated types (i.e. ..@2, ..@3, etc.) not found in some records\n const mainTypes: string[] = [];\n // repeated types (i.e. ..@2, ..@3, etc.) not found in some records\n const secondaryTypes: string[] = [];\n\n const allTypeRecords = [...importances];\n // sorting: most important types go first\n allTypeRecords.sort(([, i1], [, i2]) => i2 - i1);\n\n for (const [typeName] of allTypeRecords) {\n if (typeName.endsWith('@1') || numberOfRecordsWithType.get(typeName) === values.length)\n mainTypes.push(typeName);\n else secondaryTypes.push(typeName);\n }\n\n const calculate = (includedTypes: Set<string>, force: boolean = false) => {\n const result: RecordsWithLabel<T>[] = [];\n for (let i = 0; i < enrichedRecords.length; i++) {\n const r = enrichedRecords[i];\n const includedTrace = r.fullTrace\n .filter((fm) => includedTypes.has(fm.fullType)\n || (forceTraceElements && forceTraceElements.has(fm.type)));\n if (includedTrace.length === 0) {\n if (force)\n result.push({\n label: 'Unlabeled',\n value: r.value,\n } satisfies RecordsWithLabel<T>);\n else return undefined;\n }\n const labelSet = includedTrace\n .map((fm) => fm.label);\n const sep = ops.separator ?? ' / ';\n result.push({\n label: labelSet.join(sep),\n value: r.value,\n } satisfies RecordsWithLabel<T>);\n }\n return result;\n };\n\n if (mainTypes.length === 0) {\n if (secondaryTypes.length !== 0) throw new Error('Non-empty secondary types list while main types list is empty.');\n return calculate(new Set(LabelTypeFull), true)!;\n }\n\n //\n // includedTypes = 2\n // * *\n // T0 T1 T2 T3 T4 T5\n // *\n // additionalType = 3\n //\n // Resulting set: T0, T1, T3\n //\n let includedTypes = 0;\n let additionalType = -1;\n while (includedTypes < mainTypes.length) {\n const currentSet = new Set<string>();\n if (ops.includeNativeLabel) currentSet.add(LabelTypeFull);\n for (let i = 0; i < includedTypes; ++i) currentSet.add(mainTypes[i]);\n if (additionalType >= 0)\n currentSet.add(mainTypes[additionalType]);\n\n const candidateResult = calculate(currentSet);\n\n // checking if labels uniquely separate our records\n if (candidateResult !== undefined && new Set(candidateResult.map((c) => c.label)).size === values.length) return candidateResult;\n\n additionalType++;\n if (additionalType >= mainTypes.length) {\n includedTypes++;\n additionalType = includedTypes;\n }\n }\n\n return calculate(new Set([...mainTypes, ...secondaryTypes]), true)!;\n}\n"],"names":["z","readAnnotation","Annotation","parseJson"],"mappings":"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"}
1
+ {"version":3,"file":"label.cjs","sources":["../../../src/render/util/label.ts"],"sourcesContent":["import { Annotation, parseJson, readAnnotation, type PObjectSpec } from '@milaboratories/pl-model-common';\nimport { z } from 'zod';\n\nexport type RecordsWithLabel<T> = {\n value: T;\n label: string;\n};\n\nexport type LabelDerivationOps = {\n /** Force inclusion of native column label */\n includeNativeLabel?: boolean;\n /** Separator to use between label parts (\" / \" by default) */\n separator?: string;\n /** If true, label will be added as suffix (at the end of the generated label). By default label added as a prefix. */\n addLabelAsSuffix?: boolean;\n /** Trace elements list that will be forced to be included in the label. */\n forceTraceElements?: string[];\n};\n\nexport const TraceEntry = z.object({\n type: z.string(),\n importance: z.number().optional(),\n id: z.string().optional(),\n label: z.string(),\n});\nexport type TraceEntry = z.infer<typeof TraceEntry>;\ntype FullTraceEntry = TraceEntry & { fullType: string; occurrenceIndex: number };\n\nexport const Trace = z.array(TraceEntry);\nexport type Trace = z.infer<typeof Trace>;\ntype FullTrace = FullTraceEntry[];\n\n// Define the possible return types for the specExtractor function\ntype SpecExtractorResult = PObjectSpec | {\n spec: PObjectSpec;\n prefixTrace?: TraceEntry[];\n suffixTrace?: TraceEntry[];\n};\n\nconst DistancePenalty = 0.001;\n\nconst LabelType = '__LABEL__';\nconst LabelTypeFull = '__LABEL__@1';\n\nexport function deriveLabels<T>(\n values: T[],\n specExtractor: (obj: T) => SpecExtractorResult,\n ops: LabelDerivationOps = {},\n): RecordsWithLabel<T>[] {\n const importances = new Map<string, number>();\n\n const forceTraceElements = (ops.forceTraceElements !== undefined && ops.forceTraceElements.length > 0)\n ? new Set(ops.forceTraceElements)\n : undefined;\n\n // number of times certain type occurred among all of the\n const numberOfRecordsWithType = new Map<string, number>();\n\n const enrichedRecords = values.map((value) => {\n const extractorResult = specExtractor(value);\n let spec: PObjectSpec;\n let prefixTrace: TraceEntry[] | undefined;\n let suffixTrace: TraceEntry[] | undefined;\n\n // Check if the result is the new structure or just PObjectSpec\n if ('spec' in extractorResult && typeof extractorResult.spec === 'object') {\n // It's the new structure { spec, prefixTrace?, suffixTrace? }\n spec = extractorResult.spec;\n prefixTrace = extractorResult.prefixTrace;\n suffixTrace = extractorResult.suffixTrace;\n } else {\n // It's just PObjectSpec\n spec = extractorResult as PObjectSpec;\n }\n\n const label = readAnnotation(spec, Annotation.Label);\n const traceStr = readAnnotation(spec, Annotation.Trace);\n const baseTrace = (traceStr ? Trace.safeParse(parseJson(traceStr)).data : undefined) ?? [];\n\n const trace = [\n ...(prefixTrace ?? []),\n ...baseTrace,\n ...(suffixTrace ?? []),\n ];\n\n if (label !== undefined) {\n const labelEntry = { label, type: LabelType, importance: -2 };\n if (ops.addLabelAsSuffix) trace.push(labelEntry);\n else trace.splice(0, 0, labelEntry);\n }\n\n const fullTrace: FullTrace = [];\n\n const occurrences = new Map<string, number>();\n for (let i = trace.length - 1; i >= 0; --i) {\n const { type: typeName } = trace[i];\n const importance = trace[i].importance ?? 0;\n const occurrenceIndex = (occurrences.get(typeName) ?? 0) + 1;\n occurrences.set(typeName, occurrenceIndex);\n const fullType = `${typeName}@${occurrenceIndex}`;\n numberOfRecordsWithType.set(fullType, (numberOfRecordsWithType.get(fullType) ?? 0) + 1);\n importances.set(\n fullType,\n Math.max(\n importances.get(fullType) ?? Number.NEGATIVE_INFINITY,\n importance - (trace.length - i) * DistancePenalty,\n ),\n );\n fullTrace.push({ ...trace[i], fullType, occurrenceIndex: occurrenceIndex });\n }\n fullTrace.reverse();\n return {\n value,\n spec,\n label,\n fullTrace,\n };\n });\n\n // excluding repeated types (i.e. ..@2, ..@3, etc.) not found in some records\n const mainTypes: string[] = [];\n // repeated types (i.e. ..@2, ..@3, etc.) not found in some records\n const secondaryTypes: string[] = [];\n\n const allTypeRecords = [...importances];\n // sorting: most important types go first\n allTypeRecords.sort(([, i1], [, i2]) => i2 - i1);\n\n for (const [typeName] of allTypeRecords) {\n if (typeName.endsWith('@1') || numberOfRecordsWithType.get(typeName) === values.length)\n mainTypes.push(typeName);\n else secondaryTypes.push(typeName);\n }\n\n const calculate = (includedTypes: Set<string>, force: boolean = false) => {\n const result: RecordsWithLabel<T>[] = [];\n for (let i = 0; i < enrichedRecords.length; i++) {\n const r = enrichedRecords[i];\n const includedTrace = r.fullTrace\n .filter((fm) => includedTypes.has(fm.fullType)\n || (forceTraceElements && forceTraceElements.has(fm.type)));\n if (includedTrace.length === 0) {\n if (force)\n result.push({\n label: 'Unlabeled',\n value: r.value,\n } satisfies RecordsWithLabel<T>);\n else return undefined;\n }\n const labelSet = includedTrace\n .map((fm) => fm.label);\n const sep = ops.separator ?? ' / ';\n result.push({\n label: labelSet.join(sep),\n value: r.value,\n } satisfies RecordsWithLabel<T>);\n }\n return result;\n };\n\n // Checks if a result has all unique labels\n const hasUniqueLabels = (result: RecordsWithLabel<T>[] | undefined): boolean =>\n result !== undefined && new Set(result.map((c) => c.label)).size === values.length;\n\n // Post-processing: try removing types one by one (lowest importance first) to minimize the label set\n const minimizeTypeSet = (typeSet: Set<string>): Set<string> => {\n // Get types sorted by importance ascending (lowest first), excluding forced elements\n const removableSorted = [...typeSet]\n .filter((t) =>\n !forceTraceElements?.has(t.split('@')[0])\n && !(ops.includeNativeLabel && t === LabelTypeFull))\n .sort((a, b) => (importances.get(a) ?? 0) - (importances.get(b) ?? 0));\n\n for (const typeToRemove of removableSorted) {\n const reducedSet = new Set(typeSet);\n reducedSet.delete(typeToRemove);\n const candidateResult = calculate(reducedSet);\n if (hasUniqueLabels(candidateResult)) {\n typeSet.delete(typeToRemove);\n }\n }\n return typeSet;\n };\n\n if (mainTypes.length === 0) {\n if (secondaryTypes.length !== 0) throw new Error('Non-empty secondary types list while main types list is empty.');\n return calculate(new Set(LabelTypeFull), true)!;\n }\n\n //\n // includedTypes = 2\n // * *\n // T0 T1 T2 T3 T4 T5\n // *\n // additionalType = 3\n //\n // Resulting set: T0, T1, T3\n //\n let includedTypes = 0;\n let additionalType = -1;\n while (includedTypes < mainTypes.length) {\n const currentSet = new Set<string>();\n if (ops.includeNativeLabel) currentSet.add(LabelTypeFull);\n for (let i = 0; i < includedTypes; ++i) currentSet.add(mainTypes[i]);\n if (additionalType >= 0)\n currentSet.add(mainTypes[additionalType]);\n\n const candidateResult = calculate(currentSet);\n\n if (hasUniqueLabels(candidateResult)) {\n minimizeTypeSet(currentSet);\n return calculate(currentSet)!;\n }\n\n additionalType++;\n if (additionalType >= mainTypes.length) {\n includedTypes++;\n additionalType = includedTypes;\n }\n }\n\n // Fallback: include all types, then try to minimize\n const fallbackSet = new Set([...mainTypes, ...secondaryTypes]);\n minimizeTypeSet(fallbackSet);\n return calculate(fallbackSet, true)!;\n}\n"],"names":["z","readAnnotation","Annotation","parseJson"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"label.d.ts","sourceRoot":"","sources":["../../../src/render/util/label.ts"],"names":[],"mappings":"AAAA,OAAO,EAAyC,KAAK,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAC1G,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,MAAM,gBAAgB,CAAC,CAAC,IAAI;IAChC,KAAK,EAAE,CAAC,CAAC;IACT,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,6CAA6C;IAC7C,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,8DAA8D;IAC9D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sHAAsH;IACtH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,2EAA2E;IAC3E,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC/B,CAAC;AAEF,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;EAKrB,CAAC;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC;AAGpD,eAAO,MAAM,KAAK;;;;;;;;;;;;;;;WAAsB,CAAC;AACzC,MAAM,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,KAAK,CAAC,CAAC;AAI1C,KAAK,mBAAmB,GAAG,WAAW,GAAG;IACvC,IAAI,EAAE,WAAW,CAAC;IAClB,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC;IAC3B,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC;CAC5B,CAAC;AAOF,wBAAgB,YAAY,CAAC,CAAC,EAC5B,MAAM,EAAE,CAAC,EAAE,EACX,aAAa,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,mBAAmB,EAC9C,GAAG,GAAE,kBAAuB,GAC3B,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAoJvB"}
1
+ {"version":3,"file":"label.d.ts","sourceRoot":"","sources":["../../../src/render/util/label.ts"],"names":[],"mappings":"AAAA,OAAO,EAAyC,KAAK,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAC1G,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,MAAM,gBAAgB,CAAC,CAAC,IAAI;IAChC,KAAK,EAAE,CAAC,CAAC;IACT,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,6CAA6C;IAC7C,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,8DAA8D;IAC9D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sHAAsH;IACtH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,2EAA2E;IAC3E,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC/B,CAAC;AAEF,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;EAKrB,CAAC;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC;AAGpD,eAAO,MAAM,KAAK;;;;;;;;;;;;;;;WAAsB,CAAC;AACzC,MAAM,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,KAAK,CAAC,CAAC;AAI1C,KAAK,mBAAmB,GAAG,WAAW,GAAG;IACvC,IAAI,EAAE,WAAW,CAAC;IAClB,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC;IAC3B,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC;CAC5B,CAAC;AAOF,wBAAgB,YAAY,CAAC,CAAC,EAC5B,MAAM,EAAE,CAAC,EAAE,EACX,aAAa,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,mBAAmB,EAC9C,GAAG,GAAE,kBAAuB,GAC3B,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAiLvB"}
@@ -108,6 +108,25 @@ function deriveLabels(values, specExtractor, ops = {}) {
108
108
  }
109
109
  return result;
110
110
  };
111
+ // Checks if a result has all unique labels
112
+ const hasUniqueLabels = (result) => result !== undefined && new Set(result.map((c) => c.label)).size === values.length;
113
+ // Post-processing: try removing types one by one (lowest importance first) to minimize the label set
114
+ const minimizeTypeSet = (typeSet) => {
115
+ // Get types sorted by importance ascending (lowest first), excluding forced elements
116
+ const removableSorted = [...typeSet]
117
+ .filter((t) => !forceTraceElements?.has(t.split('@')[0])
118
+ && !(ops.includeNativeLabel && t === LabelTypeFull))
119
+ .sort((a, b) => (importances.get(a) ?? 0) - (importances.get(b) ?? 0));
120
+ for (const typeToRemove of removableSorted) {
121
+ const reducedSet = new Set(typeSet);
122
+ reducedSet.delete(typeToRemove);
123
+ const candidateResult = calculate(reducedSet);
124
+ if (hasUniqueLabels(candidateResult)) {
125
+ typeSet.delete(typeToRemove);
126
+ }
127
+ }
128
+ return typeSet;
129
+ };
111
130
  if (mainTypes.length === 0) {
112
131
  if (secondaryTypes.length !== 0)
113
132
  throw new Error('Non-empty secondary types list while main types list is empty.');
@@ -133,16 +152,20 @@ function deriveLabels(values, specExtractor, ops = {}) {
133
152
  if (additionalType >= 0)
134
153
  currentSet.add(mainTypes[additionalType]);
135
154
  const candidateResult = calculate(currentSet);
136
- // checking if labels uniquely separate our records
137
- if (candidateResult !== undefined && new Set(candidateResult.map((c) => c.label)).size === values.length)
138
- return candidateResult;
155
+ if (hasUniqueLabels(candidateResult)) {
156
+ minimizeTypeSet(currentSet);
157
+ return calculate(currentSet);
158
+ }
139
159
  additionalType++;
140
160
  if (additionalType >= mainTypes.length) {
141
161
  includedTypes++;
142
162
  additionalType = includedTypes;
143
163
  }
144
164
  }
145
- return calculate(new Set([...mainTypes, ...secondaryTypes]), true);
165
+ // Fallback: include all types, then try to minimize
166
+ const fallbackSet = new Set([...mainTypes, ...secondaryTypes]);
167
+ minimizeTypeSet(fallbackSet);
168
+ return calculate(fallbackSet, true);
146
169
  }
147
170
 
148
171
  export { Trace, TraceEntry, deriveLabels };
@@ -1 +1 @@
1
- {"version":3,"file":"label.js","sources":["../../../src/render/util/label.ts"],"sourcesContent":["import { Annotation, parseJson, readAnnotation, type PObjectSpec } from '@milaboratories/pl-model-common';\nimport { z } from 'zod';\n\nexport type RecordsWithLabel<T> = {\n value: T;\n label: string;\n};\n\nexport type LabelDerivationOps = {\n /** Force inclusion of native column label */\n includeNativeLabel?: boolean;\n /** Separator to use between label parts (\" / \" by default) */\n separator?: string;\n /** If true, label will be added as suffix (at the end of the generated label). By default label added as a prefix. */\n addLabelAsSuffix?: boolean;\n /** Trace elements list that will be forced to be included in the label. */\n forceTraceElements?: string[];\n};\n\nexport const TraceEntry = z.object({\n type: z.string(),\n importance: z.number().optional(),\n id: z.string().optional(),\n label: z.string(),\n});\nexport type TraceEntry = z.infer<typeof TraceEntry>;\ntype FullTraceEntry = TraceEntry & { fullType: string; occurrenceIndex: number };\n\nexport const Trace = z.array(TraceEntry);\nexport type Trace = z.infer<typeof Trace>;\ntype FullTrace = FullTraceEntry[];\n\n// Define the possible return types for the specExtractor function\ntype SpecExtractorResult = PObjectSpec | {\n spec: PObjectSpec;\n prefixTrace?: TraceEntry[];\n suffixTrace?: TraceEntry[];\n};\n\nconst DistancePenalty = 0.001;\n\nconst LabelType = '__LABEL__';\nconst LabelTypeFull = '__LABEL__@1';\n\nexport function deriveLabels<T>(\n values: T[],\n specExtractor: (obj: T) => SpecExtractorResult,\n ops: LabelDerivationOps = {},\n): RecordsWithLabel<T>[] {\n const importances = new Map<string, number>();\n\n const forceTraceElements = (ops.forceTraceElements !== undefined && ops.forceTraceElements.length > 0)\n ? new Set(ops.forceTraceElements)\n : undefined;\n\n // number of times certain type occurred among all of the\n const numberOfRecordsWithType = new Map<string, number>();\n\n const enrichedRecords = values.map((value) => {\n const extractorResult = specExtractor(value);\n let spec: PObjectSpec;\n let prefixTrace: TraceEntry[] | undefined;\n let suffixTrace: TraceEntry[] | undefined;\n\n // Check if the result is the new structure or just PObjectSpec\n if ('spec' in extractorResult && typeof extractorResult.spec === 'object') {\n // It's the new structure { spec, prefixTrace?, suffixTrace? }\n spec = extractorResult.spec;\n prefixTrace = extractorResult.prefixTrace;\n suffixTrace = extractorResult.suffixTrace;\n } else {\n // It's just PObjectSpec\n spec = extractorResult as PObjectSpec;\n }\n\n const label = readAnnotation(spec, Annotation.Label);\n const traceStr = readAnnotation(spec, Annotation.Trace);\n const baseTrace = (traceStr ? Trace.safeParse(parseJson(traceStr)).data : undefined) ?? [];\n\n const trace = [\n ...(prefixTrace ?? []),\n ...baseTrace,\n ...(suffixTrace ?? []),\n ];\n\n if (label !== undefined) {\n const labelEntry = { label, type: LabelType, importance: -2 };\n if (ops.addLabelAsSuffix) trace.push(labelEntry);\n else trace.splice(0, 0, labelEntry);\n }\n\n const fullTrace: FullTrace = [];\n\n const occurrences = new Map<string, number>();\n for (let i = trace.length - 1; i >= 0; --i) {\n const { type: typeName } = trace[i];\n const importance = trace[i].importance ?? 0;\n const occurrenceIndex = (occurrences.get(typeName) ?? 0) + 1;\n occurrences.set(typeName, occurrenceIndex);\n const fullType = `${typeName}@${occurrenceIndex}`;\n numberOfRecordsWithType.set(fullType, (numberOfRecordsWithType.get(fullType) ?? 0) + 1);\n importances.set(\n fullType,\n Math.max(\n importances.get(fullType) ?? Number.NEGATIVE_INFINITY,\n importance - (trace.length - i) * DistancePenalty,\n ),\n );\n fullTrace.push({ ...trace[i], fullType, occurrenceIndex: occurrenceIndex });\n }\n fullTrace.reverse();\n return {\n value,\n spec,\n label,\n fullTrace,\n };\n });\n\n // excluding repeated types (i.e. ..@2, ..@3, etc.) not found in some records\n const mainTypes: string[] = [];\n // repeated types (i.e. ..@2, ..@3, etc.) not found in some records\n const secondaryTypes: string[] = [];\n\n const allTypeRecords = [...importances];\n // sorting: most important types go first\n allTypeRecords.sort(([, i1], [, i2]) => i2 - i1);\n\n for (const [typeName] of allTypeRecords) {\n if (typeName.endsWith('@1') || numberOfRecordsWithType.get(typeName) === values.length)\n mainTypes.push(typeName);\n else secondaryTypes.push(typeName);\n }\n\n const calculate = (includedTypes: Set<string>, force: boolean = false) => {\n const result: RecordsWithLabel<T>[] = [];\n for (let i = 0; i < enrichedRecords.length; i++) {\n const r = enrichedRecords[i];\n const includedTrace = r.fullTrace\n .filter((fm) => includedTypes.has(fm.fullType)\n || (forceTraceElements && forceTraceElements.has(fm.type)));\n if (includedTrace.length === 0) {\n if (force)\n result.push({\n label: 'Unlabeled',\n value: r.value,\n } satisfies RecordsWithLabel<T>);\n else return undefined;\n }\n const labelSet = includedTrace\n .map((fm) => fm.label);\n const sep = ops.separator ?? ' / ';\n result.push({\n label: labelSet.join(sep),\n value: r.value,\n } satisfies RecordsWithLabel<T>);\n }\n return result;\n };\n\n if (mainTypes.length === 0) {\n if (secondaryTypes.length !== 0) throw new Error('Non-empty secondary types list while main types list is empty.');\n return calculate(new Set(LabelTypeFull), true)!;\n }\n\n //\n // includedTypes = 2\n // * *\n // T0 T1 T2 T3 T4 T5\n // *\n // additionalType = 3\n //\n // Resulting set: T0, T1, T3\n //\n let includedTypes = 0;\n let additionalType = -1;\n while (includedTypes < mainTypes.length) {\n const currentSet = new Set<string>();\n if (ops.includeNativeLabel) currentSet.add(LabelTypeFull);\n for (let i = 0; i < includedTypes; ++i) currentSet.add(mainTypes[i]);\n if (additionalType >= 0)\n currentSet.add(mainTypes[additionalType]);\n\n const candidateResult = calculate(currentSet);\n\n // checking if labels uniquely separate our records\n if (candidateResult !== undefined && new Set(candidateResult.map((c) => c.label)).size === values.length) return candidateResult;\n\n additionalType++;\n if (additionalType >= mainTypes.length) {\n includedTypes++;\n additionalType = includedTypes;\n }\n }\n\n return calculate(new Set([...mainTypes, ...secondaryTypes]), true)!;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"label.js","sources":["../../../src/render/util/label.ts"],"sourcesContent":["import { Annotation, parseJson, readAnnotation, type PObjectSpec } from '@milaboratories/pl-model-common';\nimport { z } from 'zod';\n\nexport type RecordsWithLabel<T> = {\n value: T;\n label: string;\n};\n\nexport type LabelDerivationOps = {\n /** Force inclusion of native column label */\n includeNativeLabel?: boolean;\n /** Separator to use between label parts (\" / \" by default) */\n separator?: string;\n /** If true, label will be added as suffix (at the end of the generated label). By default label added as a prefix. */\n addLabelAsSuffix?: boolean;\n /** Trace elements list that will be forced to be included in the label. */\n forceTraceElements?: string[];\n};\n\nexport const TraceEntry = z.object({\n type: z.string(),\n importance: z.number().optional(),\n id: z.string().optional(),\n label: z.string(),\n});\nexport type TraceEntry = z.infer<typeof TraceEntry>;\ntype FullTraceEntry = TraceEntry & { fullType: string; occurrenceIndex: number };\n\nexport const Trace = z.array(TraceEntry);\nexport type Trace = z.infer<typeof Trace>;\ntype FullTrace = FullTraceEntry[];\n\n// Define the possible return types for the specExtractor function\ntype SpecExtractorResult = PObjectSpec | {\n spec: PObjectSpec;\n prefixTrace?: TraceEntry[];\n suffixTrace?: TraceEntry[];\n};\n\nconst DistancePenalty = 0.001;\n\nconst LabelType = '__LABEL__';\nconst LabelTypeFull = '__LABEL__@1';\n\nexport function deriveLabels<T>(\n values: T[],\n specExtractor: (obj: T) => SpecExtractorResult,\n ops: LabelDerivationOps = {},\n): RecordsWithLabel<T>[] {\n const importances = new Map<string, number>();\n\n const forceTraceElements = (ops.forceTraceElements !== undefined && ops.forceTraceElements.length > 0)\n ? new Set(ops.forceTraceElements)\n : undefined;\n\n // number of times certain type occurred among all of the\n const numberOfRecordsWithType = new Map<string, number>();\n\n const enrichedRecords = values.map((value) => {\n const extractorResult = specExtractor(value);\n let spec: PObjectSpec;\n let prefixTrace: TraceEntry[] | undefined;\n let suffixTrace: TraceEntry[] | undefined;\n\n // Check if the result is the new structure or just PObjectSpec\n if ('spec' in extractorResult && typeof extractorResult.spec === 'object') {\n // It's the new structure { spec, prefixTrace?, suffixTrace? }\n spec = extractorResult.spec;\n prefixTrace = extractorResult.prefixTrace;\n suffixTrace = extractorResult.suffixTrace;\n } else {\n // It's just PObjectSpec\n spec = extractorResult as PObjectSpec;\n }\n\n const label = readAnnotation(spec, Annotation.Label);\n const traceStr = readAnnotation(spec, Annotation.Trace);\n const baseTrace = (traceStr ? Trace.safeParse(parseJson(traceStr)).data : undefined) ?? [];\n\n const trace = [\n ...(prefixTrace ?? []),\n ...baseTrace,\n ...(suffixTrace ?? []),\n ];\n\n if (label !== undefined) {\n const labelEntry = { label, type: LabelType, importance: -2 };\n if (ops.addLabelAsSuffix) trace.push(labelEntry);\n else trace.splice(0, 0, labelEntry);\n }\n\n const fullTrace: FullTrace = [];\n\n const occurrences = new Map<string, number>();\n for (let i = trace.length - 1; i >= 0; --i) {\n const { type: typeName } = trace[i];\n const importance = trace[i].importance ?? 0;\n const occurrenceIndex = (occurrences.get(typeName) ?? 0) + 1;\n occurrences.set(typeName, occurrenceIndex);\n const fullType = `${typeName}@${occurrenceIndex}`;\n numberOfRecordsWithType.set(fullType, (numberOfRecordsWithType.get(fullType) ?? 0) + 1);\n importances.set(\n fullType,\n Math.max(\n importances.get(fullType) ?? Number.NEGATIVE_INFINITY,\n importance - (trace.length - i) * DistancePenalty,\n ),\n );\n fullTrace.push({ ...trace[i], fullType, occurrenceIndex: occurrenceIndex });\n }\n fullTrace.reverse();\n return {\n value,\n spec,\n label,\n fullTrace,\n };\n });\n\n // excluding repeated types (i.e. ..@2, ..@3, etc.) not found in some records\n const mainTypes: string[] = [];\n // repeated types (i.e. ..@2, ..@3, etc.) not found in some records\n const secondaryTypes: string[] = [];\n\n const allTypeRecords = [...importances];\n // sorting: most important types go first\n allTypeRecords.sort(([, i1], [, i2]) => i2 - i1);\n\n for (const [typeName] of allTypeRecords) {\n if (typeName.endsWith('@1') || numberOfRecordsWithType.get(typeName) === values.length)\n mainTypes.push(typeName);\n else secondaryTypes.push(typeName);\n }\n\n const calculate = (includedTypes: Set<string>, force: boolean = false) => {\n const result: RecordsWithLabel<T>[] = [];\n for (let i = 0; i < enrichedRecords.length; i++) {\n const r = enrichedRecords[i];\n const includedTrace = r.fullTrace\n .filter((fm) => includedTypes.has(fm.fullType)\n || (forceTraceElements && forceTraceElements.has(fm.type)));\n if (includedTrace.length === 0) {\n if (force)\n result.push({\n label: 'Unlabeled',\n value: r.value,\n } satisfies RecordsWithLabel<T>);\n else return undefined;\n }\n const labelSet = includedTrace\n .map((fm) => fm.label);\n const sep = ops.separator ?? ' / ';\n result.push({\n label: labelSet.join(sep),\n value: r.value,\n } satisfies RecordsWithLabel<T>);\n }\n return result;\n };\n\n // Checks if a result has all unique labels\n const hasUniqueLabels = (result: RecordsWithLabel<T>[] | undefined): boolean =>\n result !== undefined && new Set(result.map((c) => c.label)).size === values.length;\n\n // Post-processing: try removing types one by one (lowest importance first) to minimize the label set\n const minimizeTypeSet = (typeSet: Set<string>): Set<string> => {\n // Get types sorted by importance ascending (lowest first), excluding forced elements\n const removableSorted = [...typeSet]\n .filter((t) =>\n !forceTraceElements?.has(t.split('@')[0])\n && !(ops.includeNativeLabel && t === LabelTypeFull))\n .sort((a, b) => (importances.get(a) ?? 0) - (importances.get(b) ?? 0));\n\n for (const typeToRemove of removableSorted) {\n const reducedSet = new Set(typeSet);\n reducedSet.delete(typeToRemove);\n const candidateResult = calculate(reducedSet);\n if (hasUniqueLabels(candidateResult)) {\n typeSet.delete(typeToRemove);\n }\n }\n return typeSet;\n };\n\n if (mainTypes.length === 0) {\n if (secondaryTypes.length !== 0) throw new Error('Non-empty secondary types list while main types list is empty.');\n return calculate(new Set(LabelTypeFull), true)!;\n }\n\n //\n // includedTypes = 2\n // * *\n // T0 T1 T2 T3 T4 T5\n // *\n // additionalType = 3\n //\n // Resulting set: T0, T1, T3\n //\n let includedTypes = 0;\n let additionalType = -1;\n while (includedTypes < mainTypes.length) {\n const currentSet = new Set<string>();\n if (ops.includeNativeLabel) currentSet.add(LabelTypeFull);\n for (let i = 0; i < includedTypes; ++i) currentSet.add(mainTypes[i]);\n if (additionalType >= 0)\n currentSet.add(mainTypes[additionalType]);\n\n const candidateResult = calculate(currentSet);\n\n if (hasUniqueLabels(candidateResult)) {\n minimizeTypeSet(currentSet);\n return calculate(currentSet)!;\n }\n\n additionalType++;\n if (additionalType >= mainTypes.length) {\n includedTypes++;\n additionalType = includedTypes;\n }\n }\n\n // Fallback: include all types, then try to minimize\n const fallbackSet = new Set([...mainTypes, ...secondaryTypes]);\n minimizeTypeSet(fallbackSet);\n return calculate(fallbackSet, true)!;\n}\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@platforma-sdk/model",
3
- "version": "1.51.2",
3
+ "version": "1.51.6",
4
4
  "description": "Platforma.bio SDK / Block Model",
5
5
  "type": "module",
6
6
  "types": "./dist/index.d.ts",
@@ -24,19 +24,19 @@
24
24
  "es-toolkit": "^1.39.10",
25
25
  "zod": "~3.23.8",
26
26
  "@milaboratories/ptabler-expression-js": "1.1.9",
27
- "@milaboratories/pl-error-like": "1.12.5",
28
- "@milaboratories/pl-model-common": "1.23.0"
27
+ "@milaboratories/pl-model-common": "1.23.0",
28
+ "@milaboratories/pl-error-like": "1.12.5"
29
29
  },
30
30
  "devDependencies": {
31
31
  "typescript": "~5.6.3",
32
32
  "vitest": "^4.0.16",
33
33
  "@vitest/coverage-istanbul": "^4.0.16",
34
34
  "fast-json-patch": "^3.1.1",
35
- "@milaboratories/build-configs": "1.2.1",
36
- "@milaboratories/helpers": "1.13.0",
37
35
  "@milaboratories/eslint-config": "1.0.5",
36
+ "@milaboratories/build-configs": "1.2.2",
37
+ "@milaboratories/ts-builder": "1.2.2",
38
38
  "@milaboratories/ts-configs": "1.2.0",
39
- "@milaboratories/ts-builder": "1.2.1"
39
+ "@milaboratories/helpers": "1.13.0"
40
40
  },
41
41
  "scripts": {
42
42
  "type-check": "ts-builder types --target node",
@@ -680,7 +680,7 @@ export function createPlDataTableV2<A, U>(
680
680
  });
681
681
  const filters: PTableRecordSingleValueFilterV2[]
682
682
  = uniqueBy(
683
- [...(ops?.filters ?? []), ...tableStateNormalized.pTableParams.filters],
683
+ [...tableStateNormalized.pTableParams.filters, ...(ops?.filters ?? [])],
684
684
  (f) => canonicalizeJson<PTableColumnId>(f.column),
685
685
  ).filter((f) => {
686
686
  const valid = isValidColumnId(f.column);
@@ -689,7 +689,7 @@ export function createPlDataTableV2<A, U>(
689
689
  });
690
690
  const sorting: PTableSorting[]
691
691
  = uniqueBy(
692
- [...(ops?.sorting ?? []), ...tableStateNormalized.pTableParams.sorting],
692
+ [...tableStateNormalized.pTableParams.sorting, ...(ops?.sorting ?? [])],
693
693
  (s) => canonicalizeJson<PTableColumnId>(s.column),
694
694
  ).filter((s) => {
695
695
  const valid = isValidColumnId(s.column);
@@ -119,6 +119,62 @@ test('test fallback to native labels in label derivation', () => {
119
119
  ]);
120
120
  });
121
121
 
122
+ test.each<{ name: string; traces: Trace[]; labels: string[] }>([
123
+ {
124
+ name: 'removes redundant low-importance type when high-importance alone suffices',
125
+ traces: [
126
+ [
127
+ { type: 't1', importance: 10, label: 'High1' },
128
+ { type: 't2', importance: 1, label: 'Low1' }
129
+ ],
130
+ [
131
+ { type: 't1', importance: 10, label: 'High2' },
132
+ { type: 't2', importance: 1, label: 'Low2' }
133
+ ]
134
+ ],
135
+ // Both t1 and t2 distinguish, but t2 (low importance) should be removed since t1 alone suffices
136
+ labels: ['High1', 'High2']
137
+ },
138
+ {
139
+ name: 'keeps both types when both are needed for uniqueness',
140
+ traces: [
141
+ [
142
+ { type: 't1', importance: 10, label: 'A' },
143
+ { type: 't2', importance: 1, label: 'X' }
144
+ ],
145
+ [
146
+ { type: 't1', importance: 10, label: 'A' },
147
+ { type: 't2', importance: 1, label: 'Y' }
148
+ ],
149
+ [
150
+ { type: 't1', importance: 10, label: 'B' },
151
+ { type: 't2', importance: 1, label: 'Y' }
152
+ ]
153
+ ],
154
+ // Neither t1 nor t2 alone can distinguish all three, need both
155
+ labels: ['A / X', 'A / Y', 'B / Y']
156
+ },
157
+ {
158
+ name: 'removes multiple redundant types greedily',
159
+ traces: [
160
+ [
161
+ { type: 't1', importance: 100, label: 'Unique1' },
162
+ { type: 't2', importance: 10, label: 'Same' },
163
+ { type: 't3', importance: 1, label: 'Same' }
164
+ ],
165
+ [
166
+ { type: 't1', importance: 100, label: 'Unique2' },
167
+ { type: 't2', importance: 10, label: 'Same' },
168
+ { type: 't3', importance: 1, label: 'Same' }
169
+ ]
170
+ ],
171
+ // t1 alone distinguishes; t2 and t3 are redundant and should be removed
172
+ labels: ['Unique1', 'Unique2']
173
+ }
174
+ ])('test label minimization: $name', ({ traces, labels }) => {
175
+ expect(deriveLabels(tracesToSpecs(traces), (s) => s).map((r) => r.label)).toEqual(labels);
176
+ });
177
+
122
178
  test.each<{ name: string; traces: Trace[]; labels: string[]; forceTraceElements: string[] }>([
123
179
  {
124
180
  name: 'force one element',
@@ -158,6 +158,30 @@ export function deriveLabels<T>(
158
158
  return result;
159
159
  };
160
160
 
161
+ // Checks if a result has all unique labels
162
+ const hasUniqueLabels = (result: RecordsWithLabel<T>[] | undefined): boolean =>
163
+ result !== undefined && new Set(result.map((c) => c.label)).size === values.length;
164
+
165
+ // Post-processing: try removing types one by one (lowest importance first) to minimize the label set
166
+ const minimizeTypeSet = (typeSet: Set<string>): Set<string> => {
167
+ // Get types sorted by importance ascending (lowest first), excluding forced elements
168
+ const removableSorted = [...typeSet]
169
+ .filter((t) =>
170
+ !forceTraceElements?.has(t.split('@')[0])
171
+ && !(ops.includeNativeLabel && t === LabelTypeFull))
172
+ .sort((a, b) => (importances.get(a) ?? 0) - (importances.get(b) ?? 0));
173
+
174
+ for (const typeToRemove of removableSorted) {
175
+ const reducedSet = new Set(typeSet);
176
+ reducedSet.delete(typeToRemove);
177
+ const candidateResult = calculate(reducedSet);
178
+ if (hasUniqueLabels(candidateResult)) {
179
+ typeSet.delete(typeToRemove);
180
+ }
181
+ }
182
+ return typeSet;
183
+ };
184
+
161
185
  if (mainTypes.length === 0) {
162
186
  if (secondaryTypes.length !== 0) throw new Error('Non-empty secondary types list while main types list is empty.');
163
187
  return calculate(new Set(LabelTypeFull), true)!;
@@ -183,8 +207,10 @@ export function deriveLabels<T>(
183
207
 
184
208
  const candidateResult = calculate(currentSet);
185
209
 
186
- // checking if labels uniquely separate our records
187
- if (candidateResult !== undefined && new Set(candidateResult.map((c) => c.label)).size === values.length) return candidateResult;
210
+ if (hasUniqueLabels(candidateResult)) {
211
+ minimizeTypeSet(currentSet);
212
+ return calculate(currentSet)!;
213
+ }
188
214
 
189
215
  additionalType++;
190
216
  if (additionalType >= mainTypes.length) {
@@ -193,5 +219,8 @@ export function deriveLabels<T>(
193
219
  }
194
220
  }
195
221
 
196
- return calculate(new Set([...mainTypes, ...secondaryTypes]), true)!;
222
+ // Fallback: include all types, then try to minimize
223
+ const fallbackSet = new Set([...mainTypes, ...secondaryTypes]);
224
+ minimizeTypeSet(fallbackSet);
225
+ return calculate(fallbackSet, true)!;
197
226
  }