@tanstack/table-core 9.0.0-beta.49 → 9.0.0-beta.50

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/dist/core/rows/coreRowsFeature.cjs +5 -1
  2. package/dist/core/rows/coreRowsFeature.cjs.map +1 -1
  3. package/dist/core/rows/coreRowsFeature.js +6 -2
  4. package/dist/core/rows/coreRowsFeature.js.map +1 -1
  5. package/dist/core/rows/coreRowsFeature.types.d.cts +8 -0
  6. package/dist/core/rows/coreRowsFeature.types.d.ts +8 -0
  7. package/dist/core/rows/coreRowsFeature.utils.cjs +11 -0
  8. package/dist/core/rows/coreRowsFeature.utils.cjs.map +1 -1
  9. package/dist/core/rows/coreRowsFeature.utils.d.cts +6 -1
  10. package/dist/core/rows/coreRowsFeature.utils.d.ts +6 -1
  11. package/dist/core/rows/coreRowsFeature.utils.js +11 -1
  12. package/dist/core/rows/coreRowsFeature.utils.js.map +1 -1
  13. package/dist/features/aggregation/aggregationFeature.cjs +3 -2
  14. package/dist/features/aggregation/aggregationFeature.cjs.map +1 -1
  15. package/dist/features/aggregation/aggregationFeature.js +3 -2
  16. package/dist/features/aggregation/aggregationFeature.js.map +1 -1
  17. package/dist/features/aggregation/aggregationFeature.types.cjs.map +1 -1
  18. package/dist/features/aggregation/aggregationFeature.types.d.cts +36 -13
  19. package/dist/features/aggregation/aggregationFeature.types.d.ts +36 -13
  20. package/dist/features/aggregation/aggregationFeature.types.js.map +1 -1
  21. package/dist/features/aggregation/aggregationFeature.utils.cjs +36 -22
  22. package/dist/features/aggregation/aggregationFeature.utils.cjs.map +1 -1
  23. package/dist/features/aggregation/aggregationFeature.utils.d.cts +9 -8
  24. package/dist/features/aggregation/aggregationFeature.utils.d.ts +9 -8
  25. package/dist/features/aggregation/aggregationFeature.utils.js +36 -22
  26. package/dist/features/aggregation/aggregationFeature.utils.js.map +1 -1
  27. package/dist/features/aggregation/aggregationFns.cjs +35 -29
  28. package/dist/features/aggregation/aggregationFns.cjs.map +1 -1
  29. package/dist/features/aggregation/aggregationFns.d.cts +8 -7
  30. package/dist/features/aggregation/aggregationFns.d.ts +8 -7
  31. package/dist/features/aggregation/aggregationFns.js +35 -29
  32. package/dist/features/aggregation/aggregationFns.js.map +1 -1
  33. package/dist/features/column-grouping/createGroupedRowModel.cjs +3 -3
  34. package/dist/features/column-grouping/createGroupedRowModel.cjs.map +1 -1
  35. package/dist/features/column-grouping/createGroupedRowModel.js +3 -3
  36. package/dist/features/column-grouping/createGroupedRowModel.js.map +1 -1
  37. package/dist/index.d.cts +2 -2
  38. package/dist/index.d.ts +2 -2
  39. package/dist/static-functions.cjs +1 -0
  40. package/dist/static-functions.d.cts +2 -2
  41. package/dist/static-functions.d.ts +2 -2
  42. package/dist/static-functions.js +2 -2
  43. package/package.json +1 -1
  44. package/skills/aggregation/SKILL.md +25 -15
  45. package/skills/api-not-found/SKILL.md +1 -1
  46. package/skills/client-vs-server/SKILL.md +1 -1
  47. package/skills/column-faceting/SKILL.md +1 -1
  48. package/skills/column-filtering/SKILL.md +1 -1
  49. package/skills/column-ordering/SKILL.md +1 -1
  50. package/skills/column-pinning/SKILL.md +1 -1
  51. package/skills/column-resizing/SKILL.md +1 -1
  52. package/skills/column-sizing/SKILL.md +1 -1
  53. package/skills/column-visibility/SKILL.md +1 -1
  54. package/skills/core/SKILL.md +1 -1
  55. package/skills/custom-features/SKILL.md +1 -1
  56. package/skills/expanding/SKILL.md +1 -1
  57. package/skills/global-filtering/SKILL.md +1 -1
  58. package/skills/grouping/SKILL.md +1 -1
  59. package/skills/migrate-v8-to-v9/SKILL.md +11 -3
  60. package/skills/pagination/SKILL.md +1 -1
  61. package/skills/row-pinning/SKILL.md +1 -1
  62. package/skills/row-selection/SKILL.md +1 -1
  63. package/skills/sorting/SKILL.md +1 -1
  64. package/skills/table-features/SKILL.md +1 -1
  65. package/skills/typescript/SKILL.md +1 -1
  66. package/src/core/rows/coreRowsFeature.ts +5 -0
  67. package/src/core/rows/coreRowsFeature.types.ts +8 -0
  68. package/src/core/rows/coreRowsFeature.utils.ts +18 -0
  69. package/src/features/aggregation/aggregationFeature.ts +2 -1
  70. package/src/features/aggregation/aggregationFeature.types.ts +39 -12
  71. package/src/features/aggregation/aggregationFeature.utils.ts +56 -27
  72. package/src/features/aggregation/aggregationFns.ts +42 -33
  73. package/src/features/column-grouping/createGroupedRowModel.ts +3 -3
@@ -1 +1 @@
1
- {"version":3,"file":"aggregationFeature.utils.js","names":[],"sources":["../../../src/features/aggregation/aggregationFeature.utils.ts"],"sourcesContent":["import { hasOwn, makeObjectMap } from '../../utils'\nimport type { Cell } from '../../types/Cell'\nimport type { Column, Column_Internal } from '../../types/Column'\nimport type { Row } from '../../types/Row'\nimport type { TableFeatures } from '../../types/TableFeatures'\nimport type { CellData, RowData } from '../../types/type-utils'\nimport type {\n AggregationFnDef,\n AggregationFnDescriptor,\n AggregationFnRef,\n ColumnAggregationValue,\n ResolvedAggregationFn,\n} from './aggregationFeature.types'\n\ninterface AggregationCacheEntry {\n aggregationFnOption: unknown\n dependency: unknown\n registry: unknown\n value: unknown\n}\n\ninterface ResolvedAggregationFnsCacheEntry<\n TFeatures extends TableFeatures,\n TData extends RowData,\n> {\n coreRowModel: unknown\n option: unknown\n registry: unknown\n value: ReadonlyArray<ResolvedAggregationFn<TFeatures, TData>>\n}\n\nfunction isAggregationFnDef(value: unknown): value is AggregationFnDef {\n return !!value && typeof value === 'object' && 'aggregate' in value\n}\n\nfunction isAggregationFnDescriptor(\n value: unknown,\n): value is AggregationFnDescriptor<any, any> {\n return (\n !!value &&\n typeof value === 'object' &&\n 'id' in value &&\n 'aggregationFn' in value\n )\n}\n\nfunction warn(message: string) {\n if (process.env.NODE_ENV === 'development') {\n console.warn(message)\n }\n}\n\n/**\n * Flattens hierarchical row inputs to unique terminal leaves in encounter\n * order. This is the normalization used by public aggregation-value calls.\n */\nexport function normalizeAggregationRows<\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(rows: ReadonlyArray<Row<TFeatures, TData>>): Array<Row<TFeatures, TData>> {\n const result: Array<Row<TFeatures, TData>> = []\n const seen = new Set<string>()\n\n const visit = (row: Row<TFeatures, TData>) => {\n if (row.subRows.length) {\n for (let i = 0; i < row.subRows.length; i++) {\n visit(row.subRows[i]!)\n }\n return\n }\n\n if (!seen.has(row.id)) {\n seen.add(row.id)\n result.push(row)\n }\n }\n\n for (let i = 0; i < rows.length; i++) {\n visit(rows[i]!)\n }\n\n return result\n}\n\nfunction getAutoAggregationFnName(\n value: unknown,\n): 'extent' | 'sum' | undefined {\n if (typeof value === 'number') {\n return 'sum'\n }\n\n if (value instanceof Date && !Number.isNaN(value.getTime())) {\n return 'extent'\n }\n\n return undefined\n}\n\n/** Resolves the `sum` or `extent` definition inferred from the first core row. */\nexport function column_getAutoAggregationFn<\n TFeatures extends TableFeatures,\n TData extends RowData,\n TValue extends CellData = CellData,\n>(column: Column_Internal<TFeatures, TData, TValue>) {\n const value = column.table.getCoreRowModel().flatRows[0]?.getValue(column.id)\n\n const name = getAutoAggregationFnName(value)\n if (!name) return undefined\n\n const aggregationFn = column.table._rowModelFns.aggregationFns?.[name]\n\n if (!aggregationFn) {\n warn(\n `aggregationFn '${name}' (auto) for column '${column.id}' is not registered`,\n )\n }\n\n return aggregationFn\n}\n\nfunction resolveAggregationFn<\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(\n column: Column_Internal<TFeatures, TData, any>,\n ref: AggregationFnRef<TFeatures, TData, any, any>,\n): AggregationFnDef<TFeatures, TData, any, any> | undefined {\n if (isAggregationFnDef(ref)) return ref as any\n if (ref === 'auto') return column_getAutoAggregationFn(column)\n\n const aggregationFn =\n column.table._rowModelFns.aggregationFns?.[ref as string]\n if (!aggregationFn) {\n warn(\n `aggregationFn '${String(ref)}' for column '${column.id}' is not registered`,\n )\n }\n return aggregationFn\n}\n\n/** Resolves and validates a column's scalar or multiple aggregation option. */\nexport function column_getAggregationFns<\n TFeatures extends TableFeatures,\n TData extends RowData,\n TValue extends CellData = CellData,\n>(\n column: Column_Internal<TFeatures, TData, TValue>,\n): ReadonlyArray<ResolvedAggregationFn<TFeatures, TData>> {\n const option = column.columnDef.aggregationFn\n const registry = column.table._rowModelFns.aggregationFns\n const coreRowModel = column.table.getCoreRowModel()\n const previous = (column as any)._resolvedAggregationFnsCache as\n | ResolvedAggregationFnsCacheEntry<TFeatures, TData>\n | undefined\n\n if (\n previous &&\n previous.option === option &&\n previous.registry === registry &&\n previous.coreRowModel === coreRowModel\n ) {\n return previous.value\n }\n\n const finish = (\n value: ReadonlyArray<ResolvedAggregationFn<TFeatures, TData>>,\n ) => {\n ;(column as any)._resolvedAggregationFnsCache = {\n coreRowModel,\n option,\n registry,\n value,\n } satisfies ResolvedAggregationFnsCacheEntry<TFeatures, TData>\n return value\n }\n\n if (option == null) return finish([])\n\n if (!Array.isArray(option)) {\n return finish([\n {\n aggregationFn: resolveAggregationFn(column, option as any),\n id: typeof option === 'string' ? option : undefined,\n },\n ])\n }\n\n const ids = makeObjectMap<number>()\n for (let i = 0; i < option.length; i++) {\n const item = option[i]\n const id =\n typeof item === 'string'\n ? item\n : isAggregationFnDescriptor(item)\n ? item.id\n : undefined\n if (id !== undefined) ids[id] = (ids[id] ?? 0) + 1\n }\n\n const resolved: Array<ResolvedAggregationFn<TFeatures, TData>> = []\n\n for (let i = 0; i < option.length; i++) {\n const item = option[i]\n const id =\n typeof item === 'string'\n ? item\n : isAggregationFnDescriptor(item)\n ? item.id\n : undefined\n\n if (id === undefined) {\n warn(\n `aggregationFn at index ${i} for column '${column.id}' needs a stable id`,\n )\n resolved.push({ aggregationFn: undefined, id: undefined })\n continue\n }\n\n if (ids[id]! > 1) {\n warn(`aggregationFn id '${id}' for column '${column.id}' is duplicated`)\n resolved.push({ aggregationFn: undefined, id })\n continue\n }\n\n const ref = isAggregationFnDescriptor(item) ? item.aggregationFn : item\n resolved.push({\n aggregationFn: resolveAggregationFn(column, ref),\n id,\n })\n }\n\n return finish(resolved)\n}\n\nfunction getChildResult(\n childValue: unknown,\n isMultiple: boolean,\n id: string | undefined,\n) {\n if (!isMultiple) return childValue\n if (!id || !childValue || typeof childValue !== 'object') return undefined\n return hasOwn(childValue, id)\n ? (childValue as Record<string, unknown>)[id]\n : undefined\n}\n\n/** Executes every configured aggregation for a column over normalized rows. */\nexport function aggregateColumnValue<\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(args: {\n childRows?: ReadonlyArray<Row<TFeatures, TData>>\n column: Column<TFeatures, TData, unknown>\n groupingRow?: Row<TFeatures, TData>\n rows: ReadonlyArray<Row<TFeatures, TData>>\n}): unknown {\n const { childRows, column, groupingRow, rows } = args\n const internalColumn = column as Column_Internal<TFeatures, TData, unknown>\n const entries = column_getAggregationFns(internalColumn)\n const isMultiple = Array.isArray(internalColumn.columnDef.aggregationFn)\n const canMerge =\n !!childRows?.length &&\n childRows.every(\n (row) =>\n !!(row as any).groupingColumnId &&\n (row as any).groupingColumnId !== column.id,\n )\n\n const execute = (entry: ResolvedAggregationFn<TFeatures, TData>) => {\n const definition = entry.aggregationFn\n if (!definition) return undefined\n\n const context = {\n column,\n columnId: column.id,\n getValue: (row: Row<TFeatures, TData>) => row.getValue(column.id),\n ...(groupingRow ? { groupingRow } : {}),\n rows,\n table: column.table as any,\n }\n\n if (canMerge && definition.merge) {\n return definition.merge({\n ...context,\n childResults: childRows.map((row) =>\n getChildResult(row.getValue(column.id), isMultiple, entry.id),\n ),\n childRows: childRows,\n })\n }\n\n return definition.aggregate(context)\n }\n\n if (!isMultiple) {\n return entries[0] ? execute(entries[0]) : undefined\n }\n\n const result = makeObjectMap<unknown>()\n for (let i = 0; i < entries.length; i++) {\n const entry = entries[i]!\n if (entry.id !== undefined) {\n result[entry.id] = execute(entry)\n }\n }\n return result\n}\n\n/** Implements `column.getAggregationValue(rows?)` and its default-value cache. */\nexport function column_getAggregationValue<\n TFeatures extends TableFeatures,\n TData extends RowData,\n TValue extends CellData = CellData,\n>(\n column: Column_Internal<TFeatures, TData, TValue>,\n rows?: ReadonlyArray<Row<TFeatures, TData>>,\n): ColumnAggregationValue<TFeatures> {\n const providedResult = column.columnDef.getAggregationValue?.({\n column: column as any,\n rows,\n table: column.table as any,\n })\n\n if (providedResult) return providedResult.value as any\n if (column.table.options.manualAggregation) return undefined\n\n if (rows !== undefined) {\n return aggregateColumnValue({\n column: column as any,\n rows: normalizeAggregationRows(rows),\n }) as any\n }\n\n const model = column.table.getPreGroupedRowModel()\n const previous = (column as any)._aggregationValueCache as\n | AggregationCacheEntry\n | undefined\n const registry = column.table._rowModelFns.aggregationFns\n const aggregationFnOption = column.columnDef.aggregationFn\n\n if (\n previous &&\n previous.dependency === model &&\n previous.registry === registry &&\n previous.aggregationFnOption === aggregationFnOption\n ) {\n return previous.value as any\n }\n\n const value = aggregateColumnValue({\n column: column as any,\n rows: normalizeAggregationRows(model.rows),\n })\n ;(column as any)._aggregationValueCache = {\n aggregationFnOption,\n dependency: model,\n registry,\n value,\n } satisfies AggregationCacheEntry\n return value as any\n}\n\n/** Implements `cell.getIsAggregated()` for synthetic grouped rows. */\nexport function cell_getIsAggregated<\n TFeatures extends TableFeatures,\n TData extends RowData,\n TValue extends CellData = CellData,\n>(cell: Cell<TFeatures, TData, TValue>) {\n const groupingColumnId = (cell.row as any).groupingColumnId as\n | string\n | undefined\n if (!groupingColumnId || groupingColumnId === cell.column.id) return false\n\n const grouping = (cell.column.table as any).atoms.grouping?.get?.() as\n | Array<string>\n | undefined\n if (grouping?.includes(cell.column.id)) return false\n\n return column_getAggregationFns(cell.column as any).some(\n (entry) => !!entry.aggregationFn,\n )\n}\n\n/** Formats the default scalar or keyed aggregated-cell representation. */\nexport function formatAggregatedCellValue(\n value: unknown,\n option: unknown,\n): string | null {\n if (value == null) return null\n\n if (Array.isArray(option) && typeof value === 'object') {\n const entries = Object.keys(value)\n return entries\n .map(\n (key) => `${key}: ${String((value as Record<string, unknown>)[key])}`,\n )\n .join(', ')\n }\n\n return String(value)\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"aggregationFeature.utils.js","names":[],"sources":["../../../src/features/aggregation/aggregationFeature.utils.ts"],"sourcesContent":["import { hasOwn, makeObjectMap } from '../../utils'\nimport type { Cell } from '../../types/Cell'\nimport type { Column, Column_Internal } from '../../types/Column'\nimport type { Row } from '../../types/Row'\nimport type { TableFeatures } from '../../types/TableFeatures'\nimport type { CellData, RowData } from '../../types/type-utils'\nimport type {\n AggregationContext,\n AggregationFnDef,\n AggregationFnDescriptor,\n AggregationFnRef,\n AggregationValueOptions,\n ColumnAggregationValue,\n ResolvedAggregationFn,\n} from './aggregationFeature.types'\n\ninterface AggregationCacheEntry {\n aggregationFnOption: unknown\n dependency: unknown\n maxDepth: number\n registry: unknown\n value: unknown\n}\n\ninterface ResolvedAggregationFnsCacheEntry<\n TFeatures extends TableFeatures,\n TData extends RowData,\n> {\n coreRowModel: unknown\n option: unknown\n registry: unknown\n value: ReadonlyArray<ResolvedAggregationFn<TFeatures, TData>>\n}\n\nfunction isAggregationFnDef(value: unknown): value is AggregationFnDef {\n return !!value && typeof value === 'object' && 'aggregate' in value\n}\n\nfunction isAggregationFnDescriptor(\n value: unknown,\n): value is AggregationFnDescriptor<any, any> {\n return (\n !!value &&\n typeof value === 'object' &&\n 'id' in value &&\n 'aggregationFn' in value\n )\n}\n\nfunction warn(message: string) {\n if (process.env.NODE_ENV === 'development') {\n console.warn(message)\n }\n}\n\nfunction resolveMaxAggregationDepth(maxDepth: number | undefined) {\n return maxDepth === undefined || Number.isNaN(maxDepth)\n ? 0\n : Math.max(0, Math.floor(maxDepth))\n}\n\n/**\n * Selects unique rows at a maximum relative depth in encounter order.\n * Branches that end before the requested depth contribute their deepest row.\n */\nexport function normalizeAggregationRows<\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(\n rows: ReadonlyArray<Row<TFeatures, TData>>,\n maxDepth = 0,\n): Array<Row<TFeatures, TData>> {\n const result: Array<Row<TFeatures, TData>> = []\n const seen = new Set<string>()\n const normalizedMaxDepth = resolveMaxAggregationDepth(maxDepth)\n\n const visit = (row: Row<TFeatures, TData>, depth: number) => {\n if (row.subRows.length && depth < normalizedMaxDepth) {\n for (let i = 0; i < row.subRows.length; i++) {\n visit(row.subRows[i]!, depth + 1)\n }\n return\n }\n\n if (!seen.has(row.id)) {\n seen.add(row.id)\n result.push(row)\n }\n }\n\n for (let i = 0; i < rows.length; i++) {\n visit(rows[i]!, 0)\n }\n\n return result\n}\n\nfunction getAutoAggregationFnName(\n value: unknown,\n): 'extent' | 'sum' | undefined {\n if (typeof value === 'number') {\n return 'sum'\n }\n\n if (value instanceof Date && !Number.isNaN(value.getTime())) {\n return 'extent'\n }\n\n return undefined\n}\n\n/** Resolves the `sum` or `extent` definition inferred from the first core row. */\nexport function column_getAutoAggregationFn<\n TFeatures extends TableFeatures,\n TData extends RowData,\n TValue extends CellData = CellData,\n>(column: Column_Internal<TFeatures, TData, TValue>) {\n const value = column.table.getCoreRowModel().flatRows[0]?.getValue(column.id)\n\n const name = getAutoAggregationFnName(value)\n if (!name) return undefined\n\n const aggregationFn = column.table._rowModelFns.aggregationFns?.[name]\n\n if (!aggregationFn) {\n warn(\n `aggregationFn '${name}' (auto) for column '${column.id}' is not registered`,\n )\n }\n\n return aggregationFn\n}\n\nfunction resolveAggregationFn<\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(\n column: Column_Internal<TFeatures, TData, any>,\n ref: AggregationFnRef<TFeatures, TData, any, any>,\n): AggregationFnDef<TFeatures, TData, any, any> | undefined {\n if (isAggregationFnDef(ref)) return ref as any\n if (ref === 'auto') return column_getAutoAggregationFn(column)\n\n const aggregationFn =\n column.table._rowModelFns.aggregationFns?.[ref as string]\n if (!aggregationFn) {\n warn(\n `aggregationFn '${String(ref)}' for column '${column.id}' is not registered`,\n )\n }\n return aggregationFn\n}\n\n/** Resolves and validates a column's scalar or multiple aggregation option. */\nexport function column_getAggregationFns<\n TFeatures extends TableFeatures,\n TData extends RowData,\n TValue extends CellData = CellData,\n>(\n column: Column_Internal<TFeatures, TData, TValue>,\n): ReadonlyArray<ResolvedAggregationFn<TFeatures, TData>> {\n const option = column.columnDef.aggregationFn\n const registry = column.table._rowModelFns.aggregationFns\n const coreRowModel = column.table.getCoreRowModel()\n const previous = (column as any)._resolvedAggregationFnsCache as\n | ResolvedAggregationFnsCacheEntry<TFeatures, TData>\n | undefined\n\n if (\n previous &&\n previous.option === option &&\n previous.registry === registry &&\n previous.coreRowModel === coreRowModel\n ) {\n return previous.value\n }\n\n const finish = (\n value: ReadonlyArray<ResolvedAggregationFn<TFeatures, TData>>,\n ) => {\n ;(column as any)._resolvedAggregationFnsCache = {\n coreRowModel,\n option,\n registry,\n value,\n } satisfies ResolvedAggregationFnsCacheEntry<TFeatures, TData>\n return value\n }\n\n if (option == null) return finish([])\n\n if (!Array.isArray(option)) {\n return finish([\n {\n aggregationFn: resolveAggregationFn(column, option as any),\n id: typeof option === 'string' ? option : undefined,\n },\n ])\n }\n\n const ids = makeObjectMap<number>()\n for (let i = 0; i < option.length; i++) {\n const item = option[i]\n const id =\n typeof item === 'string'\n ? item\n : isAggregationFnDescriptor(item)\n ? item.id\n : undefined\n if (id !== undefined) ids[id] = (ids[id] ?? 0) + 1\n }\n\n const resolved: Array<ResolvedAggregationFn<TFeatures, TData>> = []\n\n for (let i = 0; i < option.length; i++) {\n const item = option[i]\n const id =\n typeof item === 'string'\n ? item\n : isAggregationFnDescriptor(item)\n ? item.id\n : undefined\n\n if (id === undefined) {\n warn(\n `aggregationFn at index ${i} for column '${column.id}' needs a stable id`,\n )\n resolved.push({ aggregationFn: undefined, id: undefined })\n continue\n }\n\n if (ids[id]! > 1) {\n warn(`aggregationFn id '${id}' for column '${column.id}' is duplicated`)\n resolved.push({ aggregationFn: undefined, id })\n continue\n }\n\n const ref = isAggregationFnDescriptor(item) ? item.aggregationFn : item\n resolved.push({\n aggregationFn: resolveAggregationFn(column, ref),\n id,\n })\n }\n\n return finish(resolved)\n}\n\nfunction getSubRowResult(\n subRowValue: unknown,\n isMultiple: boolean,\n id: string | undefined,\n) {\n if (!isMultiple) return subRowValue\n if (!id || !subRowValue || typeof subRowValue !== 'object') return undefined\n return hasOwn(subRowValue, id)\n ? (subRowValue as Record<string, unknown>)[id]\n : undefined\n}\n\n/** Executes every configured aggregation over a depth-selected row frontier. */\nexport function aggregateColumnValue<\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(args: {\n maxDepth?: number\n subRows?: ReadonlyArray<Row<TFeatures, TData>>\n column: Column<TFeatures, TData, unknown>\n groupingRow?: Row<TFeatures, TData>\n rows: ReadonlyArray<Row<TFeatures, TData>>\n}): unknown {\n const { subRows, column, groupingRow, rows } = args\n const internalColumn = column as Column_Internal<TFeatures, TData, unknown>\n const maxDepth = resolveMaxAggregationDepth(\n args.maxDepth ?? internalColumn.columnDef.maxAggregationDepth,\n )\n const aggregationRows = normalizeAggregationRows(rows, maxDepth)\n const entries = column_getAggregationFns(internalColumn)\n const isMultiple = Array.isArray(internalColumn.columnDef.aggregationFn)\n const canMerge =\n !!subRows?.length &&\n subRows.every(\n (row) =>\n !!(row as any).groupingColumnId &&\n (row as any).groupingColumnId !== column.id,\n )\n\n const execute = (entry: ResolvedAggregationFn<TFeatures, TData>) => {\n const definition = entry.aggregationFn\n if (!definition) return undefined\n\n const context: AggregationContext<TFeatures, TData, unknown> = {\n ...(subRows ? { subRows } : {}),\n column,\n columnId: column.id,\n getValue: (row: Row<TFeatures, TData>) => row.getValue(column.id),\n ...(groupingRow ? { groupingRow } : {}),\n maxDepth,\n rows: aggregationRows,\n table: column.table as any,\n }\n\n if (canMerge && definition.merge) {\n return definition.merge({\n ...context,\n subRowResults: subRows.map((row) =>\n getSubRowResult(row.getValue(column.id), isMultiple, entry.id),\n ),\n subRows,\n })\n }\n\n return definition.aggregate(context)\n }\n\n if (!isMultiple) {\n return entries[0] ? execute(entries[0]) : undefined\n }\n\n const result = makeObjectMap<unknown>()\n for (let i = 0; i < entries.length; i++) {\n const entry = entries[i]!\n if (entry.id !== undefined) {\n result[entry.id] = execute(entry)\n }\n }\n return result\n}\n\n/** Implements `column.getAggregationValue(options?)` and its default cache. */\nexport function column_getAggregationValue<\n TFeatures extends TableFeatures,\n TData extends RowData,\n TValue extends CellData = CellData,\n>(\n column: Column_Internal<TFeatures, TData, TValue>,\n options?: AggregationValueOptions<TFeatures, TData>,\n): ColumnAggregationValue<TFeatures> {\n const rows = options?.rows\n const resolvedMaxDepth = resolveMaxAggregationDepth(\n options?.maxDepth ?? column.columnDef.maxAggregationDepth,\n )\n const providedResult = column.columnDef.getAggregationValue?.({\n column: column as any,\n maxDepth: resolvedMaxDepth,\n rows,\n table: column.table as any,\n })\n\n if (providedResult) return providedResult.value as any\n if (column.table.options.manualAggregation) return undefined\n\n if (rows !== undefined) {\n return aggregateColumnValue({\n column: column as any,\n maxDepth: resolvedMaxDepth,\n rows,\n }) as any\n }\n\n const model = column.table.getPreGroupedRowModel()\n const previous = (column as any)._aggregationValueCache as\n | AggregationCacheEntry\n | undefined\n const registry = column.table._rowModelFns.aggregationFns\n const aggregationFnOption = column.columnDef.aggregationFn\n\n if (\n previous &&\n previous.dependency === model &&\n previous.maxDepth === resolvedMaxDepth &&\n previous.registry === registry &&\n previous.aggregationFnOption === aggregationFnOption\n ) {\n return previous.value as any\n }\n\n const value = aggregateColumnValue({\n column: column as any,\n maxDepth: resolvedMaxDepth,\n rows: model.rows,\n })\n ;(column as any)._aggregationValueCache = {\n aggregationFnOption,\n dependency: model,\n maxDepth: resolvedMaxDepth,\n registry,\n value,\n } satisfies AggregationCacheEntry\n return value as any\n}\n\n/** Implements `cell.getIsAggregated()` for synthetic grouped rows. */\nexport function cell_getIsAggregated<\n TFeatures extends TableFeatures,\n TData extends RowData,\n TValue extends CellData = CellData,\n>(cell: Cell<TFeatures, TData, TValue>) {\n const groupingColumnId = (cell.row as any).groupingColumnId as\n | string\n | undefined\n if (!groupingColumnId || groupingColumnId === cell.column.id) return false\n\n const grouping = (cell.column.table as any).atoms.grouping?.get?.() as\n | Array<string>\n | undefined\n if (grouping?.includes(cell.column.id)) return false\n\n return column_getAggregationFns(cell.column as any).some(\n (entry) => !!entry.aggregationFn,\n )\n}\n\n/** Formats the default scalar or keyed aggregated-cell representation. */\nexport function formatAggregatedCellValue(\n value: unknown,\n option: unknown,\n): string | null {\n if (value == null) return null\n\n if (Array.isArray(option) && typeof value === 'object') {\n const entries = Object.keys(value)\n return entries\n .map(\n (key) => `${key}: ${String((value as Record<string, unknown>)[key])}`,\n )\n .join(', ')\n }\n\n return String(value)\n}\n"],"mappings":";;;AAkCA,SAAS,mBAAmB,OAA2C;CACrE,OAAO,CAAC,CAAC,SAAS,OAAO,UAAU,YAAY,eAAe;AAChE;AAEA,SAAS,0BACP,OAC4C;CAC5C,OACE,CAAC,CAAC,SACF,OAAO,UAAU,YACjB,QAAQ,SACR,mBAAmB;AAEvB;AAEA,SAAS,KAAK,SAAiB;CAC7B,IAAI,QAAQ,IAAI,aAAa,eAC3B,QAAQ,KAAK,OAAO;AAExB;AAEA,SAAS,2BAA2B,UAA8B;CAChE,OAAO,aAAa,UAAa,OAAO,MAAM,QAAQ,IAClD,IACA,KAAK,IAAI,GAAG,KAAK,MAAM,QAAQ,CAAC;AACtC;;;;;AAMA,SAAgB,yBAId,MACA,WAAW,GACmB;CAC9B,MAAM,SAAuC,CAAC;CAC9C,MAAM,uBAAO,IAAI,IAAY;CAC7B,MAAM,qBAAqB,2BAA2B,QAAQ;CAE9D,MAAM,SAAS,KAA4B,UAAkB;EAC3D,IAAI,IAAI,QAAQ,UAAU,QAAQ,oBAAoB;GACpD,KAAK,IAAI,IAAI,GAAG,IAAI,IAAI,QAAQ,QAAQ,KACtC,MAAM,IAAI,QAAQ,IAAK,QAAQ,CAAC;GAElC;EACF;EAEA,IAAI,CAAC,KAAK,IAAI,IAAI,EAAE,GAAG;GACrB,KAAK,IAAI,IAAI,EAAE;GACf,OAAO,KAAK,GAAG;EACjB;CACF;CAEA,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,KAC/B,MAAM,KAAK,IAAK,CAAC;CAGnB,OAAO;AACT;AAEA,SAAS,yBACP,OAC8B;CAC9B,IAAI,OAAO,UAAU,UACnB,OAAO;CAGT,IAAI,iBAAiB,QAAQ,CAAC,OAAO,MAAM,MAAM,QAAQ,CAAC,GACxD,OAAO;AAIX;;AAGA,SAAgB,4BAId,QAAmD;CACnD,MAAM,QAAQ,OAAO,MAAM,gBAAgB,CAAC,CAAC,SAAS,EAAE,EAAE,SAAS,OAAO,EAAE;CAE5E,MAAM,OAAO,yBAAyB,KAAK;CAC3C,IAAI,CAAC,MAAM,OAAO;CAElB,MAAM,gBAAgB,OAAO,MAAM,aAAa,iBAAiB;CAEjE,IAAI,CAAC,eACH,KACE,kBAAkB,KAAK,uBAAuB,OAAO,GAAG,oBAC1D;CAGF,OAAO;AACT;AAEA,SAAS,qBAIP,QACA,KAC0D;CAC1D,IAAI,mBAAmB,GAAG,GAAG,OAAO;CACpC,IAAI,QAAQ,QAAQ,OAAO,4BAA4B,MAAM;CAE7D,MAAM,gBACJ,OAAO,MAAM,aAAa,iBAAiB;CAC7C,IAAI,CAAC,eACH,KACE,kBAAkB,OAAO,GAAG,EAAE,gBAAgB,OAAO,GAAG,oBAC1D;CAEF,OAAO;AACT;;AAGA,SAAgB,yBAKd,QACwD;CACxD,MAAM,SAAS,OAAO,UAAU;CAChC,MAAM,WAAW,OAAO,MAAM,aAAa;CAC3C,MAAM,eAAe,OAAO,MAAM,gBAAgB;CAClD,MAAM,WAAY,OAAe;CAIjC,IACE,YACA,SAAS,WAAW,UACpB,SAAS,aAAa,YACtB,SAAS,iBAAiB,cAE1B,OAAO,SAAS;CAGlB,MAAM,UACJ,UACG;EACF,AAAC,OAAe,+BAA+B;GAC9C;GACA;GACA;GACA;EACF;EACA,OAAO;CACT;CAEA,IAAI,UAAU,MAAM,OAAO,OAAO,CAAC,CAAC;CAEpC,IAAI,CAAC,MAAM,QAAQ,MAAM,GACvB,OAAO,OAAO,CACZ;EACE,eAAe,qBAAqB,QAAQ,MAAa;EACzD,IAAI,OAAO,WAAW,WAAW,SAAS;CAC5C,CACF,CAAC;CAGH,MAAM,MAAM,cAAsB;CAClC,KAAK,IAAI,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;EACtC,MAAM,OAAO,OAAO;EACpB,MAAM,KACJ,OAAO,SAAS,WACZ,OACA,0BAA0B,IAAI,IAC5B,KAAK,KACL;EACR,IAAI,OAAO,QAAW,IAAI,OAAO,IAAI,OAAO,KAAK;CACnD;CAEA,MAAM,WAA2D,CAAC;CAElE,KAAK,IAAI,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;EACtC,MAAM,OAAO,OAAO;EACpB,MAAM,KACJ,OAAO,SAAS,WACZ,OACA,0BAA0B,IAAI,IAC5B,KAAK,KACL;EAER,IAAI,OAAO,QAAW;GACpB,KACE,0BAA0B,EAAE,eAAe,OAAO,GAAG,oBACvD;GACA,SAAS,KAAK;IAAE,eAAe;IAAW,IAAI;GAAU,CAAC;GACzD;EACF;EAEA,IAAI,IAAI,MAAO,GAAG;GAChB,KAAK,qBAAqB,GAAG,gBAAgB,OAAO,GAAG,gBAAgB;GACvE,SAAS,KAAK;IAAE,eAAe;IAAW;GAAG,CAAC;GAC9C;EACF;EAEA,MAAM,MAAM,0BAA0B,IAAI,IAAI,KAAK,gBAAgB;EACnE,SAAS,KAAK;GACZ,eAAe,qBAAqB,QAAQ,GAAG;GAC/C;EACF,CAAC;CACH;CAEA,OAAO,OAAO,QAAQ;AACxB;AAEA,SAAS,gBACP,aACA,YACA,IACA;CACA,IAAI,CAAC,YAAY,OAAO;CACxB,IAAI,CAAC,MAAM,CAAC,eAAe,OAAO,gBAAgB,UAAU,OAAO;CACnE,OAAO,OAAO,aAAa,EAAE,IACxB,YAAwC,MACzC;AACN;;AAGA,SAAgB,qBAGd,MAMU;CACV,MAAM,EAAE,SAAS,QAAQ,aAAa,SAAS;CAC/C,MAAM,iBAAiB;CACvB,MAAM,WAAW,2BACf,KAAK,YAAY,eAAe,UAAU,mBAC5C;CACA,MAAM,kBAAkB,yBAAyB,MAAM,QAAQ;CAC/D,MAAM,UAAU,yBAAyB,cAAc;CACvD,MAAM,aAAa,MAAM,QAAQ,eAAe,UAAU,aAAa;CACvE,MAAM,WACJ,CAAC,CAAC,SAAS,UACX,QAAQ,OACL,QACC,CAAC,CAAE,IAAY,oBACd,IAAY,qBAAqB,OAAO,EAC7C;CAEF,MAAM,WAAW,UAAmD;EAClE,MAAM,aAAa,MAAM;EACzB,IAAI,CAAC,YAAY,OAAO;EAExB,MAAM,UAAyD;GAC7D,GAAI,UAAU,EAAE,QAAQ,IAAI,CAAC;GAC7B;GACA,UAAU,OAAO;GACjB,WAAW,QAA+B,IAAI,SAAS,OAAO,EAAE;GAChE,GAAI,cAAc,EAAE,YAAY,IAAI,CAAC;GACrC;GACA,MAAM;GACN,OAAO,OAAO;EAChB;EAEA,IAAI,YAAY,WAAW,OACzB,OAAO,WAAW,MAAM;GACtB,GAAG;GACH,eAAe,QAAQ,KAAK,QAC1B,gBAAgB,IAAI,SAAS,OAAO,EAAE,GAAG,YAAY,MAAM,EAAE,CAC/D;GACA;EACF,CAAC;EAGH,OAAO,WAAW,UAAU,OAAO;CACrC;CAEA,IAAI,CAAC,YACH,OAAO,QAAQ,KAAK,QAAQ,QAAQ,EAAE,IAAI;CAG5C,MAAM,SAAS,cAAuB;CACtC,KAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;EACvC,MAAM,QAAQ,QAAQ;EACtB,IAAI,MAAM,OAAO,QACf,OAAO,MAAM,MAAM,QAAQ,KAAK;CAEpC;CACA,OAAO;AACT;;AAGA,SAAgB,2BAKd,QACA,SACmC;CACnC,MAAM,OAAO,SAAS;CACtB,MAAM,mBAAmB,2BACvB,SAAS,YAAY,OAAO,UAAU,mBACxC;CACA,MAAM,iBAAiB,OAAO,UAAU,sBAAsB;EACpD;EACR,UAAU;EACV;EACA,OAAO,OAAO;CAChB,CAAC;CAED,IAAI,gBAAgB,OAAO,eAAe;CAC1C,IAAI,OAAO,MAAM,QAAQ,mBAAmB,OAAO;CAEnD,IAAI,SAAS,QACX,OAAO,qBAAqB;EAClB;EACR,UAAU;EACV;CACF,CAAC;CAGH,MAAM,QAAQ,OAAO,MAAM,sBAAsB;CACjD,MAAM,WAAY,OAAe;CAGjC,MAAM,WAAW,OAAO,MAAM,aAAa;CAC3C,MAAM,sBAAsB,OAAO,UAAU;CAE7C,IACE,YACA,SAAS,eAAe,SACxB,SAAS,aAAa,oBACtB,SAAS,aAAa,YACtB,SAAS,wBAAwB,qBAEjC,OAAO,SAAS;CAGlB,MAAM,QAAQ,qBAAqB;EACzB;EACR,UAAU;EACV,MAAM,MAAM;CACd,CAAC;CACA,AAAC,OAAe,yBAAyB;EACxC;EACA,YAAY;EACZ,UAAU;EACV;EACA;CACF;CACA,OAAO;AACT;;AAGA,SAAgB,qBAId,MAAsC;CACtC,MAAM,mBAAoB,KAAK,IAAY;CAG3C,IAAI,CAAC,oBAAoB,qBAAqB,KAAK,OAAO,IAAI,OAAO;CAKrE,KAHkB,KAAK,OAAO,MAAc,MAAM,UAAU,MAAM,EAGtD,EAAE,SAAS,KAAK,OAAO,EAAE,GAAG,OAAO;CAE/C,OAAO,yBAAyB,KAAK,MAAa,CAAC,CAAC,MACjD,UAAU,CAAC,CAAC,MAAM,aACrB;AACF;;AAGA,SAAgB,0BACd,OACA,QACe;CACf,IAAI,SAAS,MAAM,OAAO;CAE1B,IAAI,MAAM,QAAQ,MAAM,KAAK,OAAO,UAAU,UAE5C,OADgB,OAAO,KAAK,KACf,CAAC,CACX,KACE,QAAQ,GAAG,IAAI,IAAI,OAAQ,MAAkC,IAAI,GACpE,CAAC,CACA,KAAK,IAAI;CAGd,OAAO,OAAO,KAAK;AACrB"}
@@ -27,8 +27,8 @@ function collectRangeValues(context) {
27
27
  return values;
28
28
  }
29
29
  /**
30
- * Sums numeric row values. Non-number values contribute zero. As in the
31
- * previous API, `NaN` is a number and therefore propagates through the sum.
30
+ * Sums numeric selected-row values. Non-number values contribute zero. As in
31
+ * the previous API, `NaN` is a number and therefore propagates through the sum.
32
32
  */
33
33
  const aggregationFn_sum = require_aggregationFeature_types.constructAggregationFn({
34
34
  aggregate: (context) => {
@@ -39,18 +39,18 @@ const aggregationFn_sum = require_aggregationFeature_types.constructAggregationF
39
39
  }
40
40
  return sum;
41
41
  },
42
- merge: ({ childResults }) => {
42
+ merge: ({ subRowResults }) => {
43
43
  let sum = 0;
44
- for (let i = 0; i < childResults.length; i++) {
45
- const value = childResults[i];
44
+ for (let i = 0; i < subRowResults.length; i++) {
45
+ const value = subRowResults[i];
46
46
  if (isNumber(value)) sum += value;
47
47
  }
48
48
  return sum;
49
49
  }
50
50
  });
51
51
  /**
52
- * Finds the minimum numeric or Date value. Invalid value types are ignored;
53
- * `NaN` preserves the legacy numeric seeding behavior.
52
+ * Finds the minimum numeric or Date value from the selected rows. Invalid value
53
+ * types are ignored; `NaN` preserves the legacy numeric seeding behavior.
54
54
  */
55
55
  const aggregationFn_min = require_aggregationFeature_types.constructAggregationFn({
56
56
  aggregate: (context) => {
@@ -59,13 +59,14 @@ const aggregationFn_min = require_aggregationFeature_types.constructAggregationF
59
59
  for (let i = 1; i < values.length; i++) if (compareRangeValues(values[i], result) < 0) result = values[i];
60
60
  return result;
61
61
  },
62
- merge: ({ childResults }) => {
62
+ merge: ({ subRowResults }) => {
63
63
  let result;
64
64
  let kind;
65
- for (let i = 0; i < childResults.length; i++) {
66
- const value = childResults[i];
65
+ for (let i = 0; i < subRowResults.length; i++) {
66
+ const value = subRowResults[i];
67
67
  const valueKind = getRangeKind(value);
68
68
  if (!valueKind) continue;
69
+ if (value === void 0) continue;
69
70
  kind ??= valueKind;
70
71
  if (kind !== valueKind) continue;
71
72
  if (result === void 0 || compareRangeValues(value, result) < 0) result = value;
@@ -74,8 +75,8 @@ const aggregationFn_min = require_aggregationFeature_types.constructAggregationF
74
75
  }
75
76
  });
76
77
  /**
77
- * Finds the maximum numeric or Date value. Invalid value types are ignored;
78
- * `NaN` preserves the legacy numeric seeding behavior.
78
+ * Finds the maximum numeric or Date value from the selected rows. Invalid value
79
+ * types are ignored; `NaN` preserves the legacy numeric seeding behavior.
79
80
  */
80
81
  const aggregationFn_max = require_aggregationFeature_types.constructAggregationFn({
81
82
  aggregate: (context) => {
@@ -84,13 +85,14 @@ const aggregationFn_max = require_aggregationFeature_types.constructAggregationF
84
85
  for (let i = 1; i < values.length; i++) if (compareRangeValues(values[i], result) > 0) result = values[i];
85
86
  return result;
86
87
  },
87
- merge: ({ childResults }) => {
88
+ merge: ({ subRowResults }) => {
88
89
  let result;
89
90
  let kind;
90
- for (let i = 0; i < childResults.length; i++) {
91
- const value = childResults[i];
91
+ for (let i = 0; i < subRowResults.length; i++) {
92
+ const value = subRowResults[i];
92
93
  const valueKind = getRangeKind(value);
93
94
  if (!valueKind) continue;
95
+ if (value === void 0) continue;
94
96
  kind ??= valueKind;
95
97
  if (kind !== valueKind) continue;
96
98
  if (result === void 0 || compareRangeValues(value, result) > 0) result = value;
@@ -99,7 +101,8 @@ const aggregationFn_max = require_aggregationFeature_types.constructAggregationF
99
101
  }
100
102
  });
101
103
  /**
102
- * Finds the minimum and maximum numeric or Date values. Empty inputs return
104
+ * Finds the minimum and maximum numeric or Date values from the selected rows.
105
+ * Empty inputs return
103
106
  * `[undefined, undefined]`, preserving the previous built-in result shape.
104
107
  */
105
108
  const aggregationFn_extent = require_aggregationFeature_types.constructAggregationFn({
@@ -115,19 +118,22 @@ const aggregationFn_extent = require_aggregationFeature_types.constructAggregati
115
118
  }
116
119
  return [min, max];
117
120
  },
118
- merge: ({ childResults }) => {
121
+ merge: ({ subRowResults }) => {
119
122
  let result = [void 0, void 0];
120
123
  let kind;
121
- for (let i = 0; i < childResults.length; i++) {
122
- const extent = childResults[i];
123
- const valueKind = getRangeKind(extent[0]);
124
- if (!valueKind) continue;
124
+ for (let i = 0; i < subRowResults.length; i++) {
125
+ const extent = subRowResults[i];
126
+ const min = extent[0];
127
+ const max = extent[1];
128
+ const valueKind = getRangeKind(min);
129
+ if (!valueKind || min === void 0 || max === void 0) continue;
125
130
  kind ??= valueKind;
126
131
  if (kind !== valueKind) continue;
127
- if (result[0] === void 0) result = [extent[0], extent[1]];
132
+ if (result[0] === void 0) result = [min, max];
128
133
  else {
129
- if (compareRangeValues(extent[0], result[0]) < 0) result[0] = extent[0];
130
- if (compareRangeValues(extent[1], result[1]) > 0) result[1] = extent[1];
134
+ if (compareRangeValues(min, result[0]) < 0) result[0] = min;
135
+ const currentMax = result[1];
136
+ if (currentMax === void 0 || compareRangeValues(max, currentMax) > 0) result[1] = max;
131
137
  }
132
138
  }
133
139
  return result;
@@ -182,10 +188,10 @@ const aggregationFn_uniqueCount = require_aggregationFeature_types.constructAggr
182
188
  /** Counts rows, independently of the column's values. */
183
189
  const aggregationFn_count = require_aggregationFeature_types.constructAggregationFn({
184
190
  aggregate: ({ rows }) => rows.length,
185
- merge: ({ childResults }) => {
191
+ merge: ({ subRowResults }) => {
186
192
  let count = 0;
187
- for (let i = 0; i < childResults.length; i++) {
188
- const value = childResults[i];
193
+ for (let i = 0; i < subRowResults.length; i++) {
194
+ const value = subRowResults[i];
189
195
  if (isNumber(value)) count += value;
190
196
  }
191
197
  return count;
@@ -194,7 +200,7 @@ const aggregationFn_count = require_aggregationFeature_types.constructAggregatio
194
200
  /** Returns the first row's value, including a nullish value. */
195
201
  const aggregationFn_first = require_aggregationFeature_types.constructAggregationFn({
196
202
  aggregate: (context) => context.rows[0] ? context.getValue(context.rows[0]) : void 0,
197
- merge: ({ childResults }) => childResults[0]
203
+ merge: ({ subRowResults }) => subRowResults[0]
198
204
  });
199
205
  /** Returns the last row's value, including a nullish value. */
200
206
  const aggregationFn_last = require_aggregationFeature_types.constructAggregationFn({
@@ -202,7 +208,7 @@ const aggregationFn_last = require_aggregationFeature_types.constructAggregation
202
208
  const row = context.rows[context.rows.length - 1];
203
209
  return row ? context.getValue(row) : void 0;
204
210
  },
205
- merge: ({ childResults }) => childResults[childResults.length - 1]
211
+ merge: ({ subRowResults }) => subRowResults[subRowResults.length - 1]
206
212
  });
207
213
  /**
208
214
  * Full built-in registry. Register individual definitions for tree-shaking.
@@ -1 +1 @@
1
- {"version":3,"file":"aggregationFns.cjs","names":["constructAggregationFn"],"sources":["../../../src/features/aggregation/aggregationFns.ts"],"sourcesContent":["import { constructAggregationFn } from './aggregationFeature.types'\nimport type { AggregationContext } from './aggregationFeature.types'\n\ntype RangeValue = Date | number\n\nfunction isNumber(value: unknown): value is number {\n return typeof value === 'number'\n}\n\nfunction isValidDate(value: unknown): value is Date {\n return value instanceof Date && !Number.isNaN(value.getTime())\n}\n\nfunction getRangeKind(value: unknown): 'date' | 'number' | undefined {\n if (isNumber(value)) return 'number'\n if (isValidDate(value)) return 'date'\n return undefined\n}\n\nfunction compareRangeValues(left: RangeValue, right: RangeValue) {\n const leftValue = left instanceof Date ? left.getTime() : left\n const rightValue = right instanceof Date ? right.getTime() : right\n return leftValue - rightValue\n}\n\nfunction collectRangeValues(context: AggregationContext<any, any, unknown>) {\n const values: Array<RangeValue> = []\n let kind: 'date' | 'number' | undefined\n\n for (let i = 0; i < context.rows.length; i++) {\n const value = context.getValue(context.rows[i]!)\n const valueKind = getRangeKind(value)\n if (!valueKind) continue\n kind ??= valueKind\n if (valueKind === kind) values.push(value as RangeValue)\n }\n\n return values\n}\n\n/**\n * Sums numeric row values. Non-number values contribute zero. As in the\n * previous API, `NaN` is a number and therefore propagates through the sum.\n */\nexport const aggregationFn_sum = constructAggregationFn<\n any,\n any,\n unknown,\n number\n>({\n aggregate: (context) => {\n let sum = 0\n for (let i = 0; i < context.rows.length; i++) {\n const value = context.getValue(context.rows[i]!)\n sum += typeof value === 'number' ? value : 0\n }\n return sum\n },\n merge: ({ childResults }) => {\n let sum = 0\n for (let i = 0; i < childResults.length; i++) {\n const value = childResults[i]\n if (isNumber(value)) sum += value\n }\n return sum\n },\n})\n\n/**\n * Finds the minimum numeric or Date value. Invalid value types are ignored;\n * `NaN` preserves the legacy numeric seeding behavior.\n */\nexport const aggregationFn_min = constructAggregationFn<\n any,\n any,\n unknown,\n RangeValue | undefined\n>({\n aggregate: (context) => {\n const values = collectRangeValues(context)\n let result = values[0]\n for (let i = 1; i < values.length; i++) {\n if (compareRangeValues(values[i]!, result!) < 0) result = values[i]\n }\n return result\n },\n merge: ({ childResults }) => {\n let result: RangeValue | undefined\n let kind: 'date' | 'number' | undefined\n for (let i = 0; i < childResults.length; i++) {\n const value = childResults[i]\n const valueKind = getRangeKind(value)\n if (!valueKind) continue\n kind ??= valueKind\n if (kind !== valueKind) continue\n if (result === undefined || compareRangeValues(value!, result) < 0) {\n result = value\n }\n }\n return result\n },\n})\n\n/**\n * Finds the maximum numeric or Date value. Invalid value types are ignored;\n * `NaN` preserves the legacy numeric seeding behavior.\n */\nexport const aggregationFn_max = constructAggregationFn<\n any,\n any,\n unknown,\n RangeValue | undefined\n>({\n aggregate: (context) => {\n const values = collectRangeValues(context)\n let result = values[0]\n for (let i = 1; i < values.length; i++) {\n if (compareRangeValues(values[i]!, result!) > 0) result = values[i]\n }\n return result\n },\n merge: ({ childResults }) => {\n let result: RangeValue | undefined\n let kind: 'date' | 'number' | undefined\n for (let i = 0; i < childResults.length; i++) {\n const value = childResults[i]\n const valueKind = getRangeKind(value)\n if (!valueKind) continue\n kind ??= valueKind\n if (kind !== valueKind) continue\n if (result === undefined || compareRangeValues(value!, result) > 0) {\n result = value\n }\n }\n return result\n },\n})\n\n/**\n * Finds the minimum and maximum numeric or Date values. Empty inputs return\n * `[undefined, undefined]`, preserving the previous built-in result shape.\n */\nexport const aggregationFn_extent = constructAggregationFn<\n any,\n any,\n unknown,\n [RangeValue | undefined, RangeValue | undefined]\n>({\n aggregate: (context) => {\n const values = collectRangeValues(context)\n if (!values.length) return [undefined, undefined]\n let min = values[0]!\n let max = values[0]!\n for (let i = 1; i < values.length; i++) {\n const value = values[i]!\n if (compareRangeValues(value, min) < 0) min = value\n if (compareRangeValues(value, max) > 0) max = value\n }\n return [min, max]\n },\n merge: ({ childResults }) => {\n let result: [RangeValue | undefined, RangeValue | undefined] = [\n undefined,\n undefined,\n ]\n let kind: 'date' | 'number' | undefined\n for (let i = 0; i < childResults.length; i++) {\n const extent = childResults[i]!\n const valueKind = getRangeKind(extent[0])\n if (!valueKind) continue\n kind ??= valueKind\n if (kind !== valueKind) continue\n if (result[0] === undefined) {\n result = [extent[0], extent[1]]\n } else {\n if (compareRangeValues(extent[0]!, result[0]) < 0) {\n result[0] = extent[0]\n }\n if (compareRangeValues(extent[1]!, result[1]!) > 0) {\n result[1] = extent[1]\n }\n }\n }\n return result\n },\n})\n\n/**\n * Averages number and number-like row values. Nullish and non-numeric values\n * are ignored; other values retain the legacy unary-plus coercion behavior.\n */\nexport const aggregationFn_mean = constructAggregationFn<\n any,\n any,\n unknown,\n number | undefined\n>({\n aggregate: (context) => {\n let count = 0\n let sum = 0\n for (let i = 0; i < context.rows.length; i++) {\n const value = context.getValue(context.rows[i]!)\n if (value == null) continue\n const numberValue = typeof value === 'number' ? value : +value\n if (!Number.isNaN(numberValue)) {\n count++\n sum += numberValue\n }\n }\n return count ? sum / count : undefined\n },\n})\n\n/**\n * Computes the median when every row value is a number. Returns `undefined`\n * for empty inputs or when any value is non-numeric.\n */\nexport const aggregationFn_median = constructAggregationFn<\n any,\n any,\n unknown,\n number | undefined\n>({\n aggregate: (context) => {\n if (!context.rows.length) return undefined\n const values = new Array<number>(context.rows.length)\n for (let i = 0; i < context.rows.length; i++) {\n const value = context.getValue(context.rows[i]!)\n if (typeof value !== 'number') return undefined\n values[i] = value\n }\n values.sort((a, b) => a - b)\n const mid = Math.floor(values.length / 2)\n return values.length % 2\n ? values[mid]\n : (values[mid - 1]! + values[mid]!) / 2\n },\n})\n\n/** Collects distinct row values using JavaScript `Set` semantics. */\nexport const aggregationFn_unique = constructAggregationFn<\n any,\n any,\n unknown,\n Array<unknown>\n>({\n aggregate: (context) => {\n const values = new Set<unknown>()\n for (let i = 0; i < context.rows.length; i++) {\n values.add(context.getValue(context.rows[i]!))\n }\n return Array.from(values)\n },\n})\n\n/** Counts distinct row values using JavaScript `Set` semantics. */\nexport const aggregationFn_uniqueCount = constructAggregationFn<\n any,\n any,\n unknown,\n number\n>({\n aggregate: (context) => {\n const values = new Set<unknown>()\n for (let i = 0; i < context.rows.length; i++) {\n values.add(context.getValue(context.rows[i]!))\n }\n return values.size\n },\n})\n\n/** Counts rows, independently of the column's values. */\nexport const aggregationFn_count = constructAggregationFn<\n any,\n any,\n unknown,\n number\n>({\n aggregate: ({ rows }) => rows.length,\n merge: ({ childResults }) => {\n let count = 0\n for (let i = 0; i < childResults.length; i++) {\n const value = childResults[i]\n if (isNumber(value)) count += value\n }\n return count\n },\n})\n\n/** Returns the first row's value, including a nullish value. */\nexport const aggregationFn_first = constructAggregationFn<\n any,\n any,\n unknown,\n unknown\n>({\n aggregate: (context) =>\n context.rows[0] ? context.getValue(context.rows[0]) : undefined,\n merge: ({ childResults }) => childResults[0],\n})\n\n/** Returns the last row's value, including a nullish value. */\nexport const aggregationFn_last = constructAggregationFn<\n any,\n any,\n unknown,\n unknown\n>({\n aggregate: (context) => {\n const row = context.rows[context.rows.length - 1]\n return row ? context.getValue(row) : undefined\n },\n merge: ({ childResults }) => childResults[childResults.length - 1],\n})\n\n/**\n * Full built-in registry. Register individual definitions for tree-shaking.\n *\n * @deprecated Import individual `aggregationFn_*` definitions instead for a\n * smaller bundle. This registry remains available for compatibility.\n */\nexport const aggregationFns = {\n sum: aggregationFn_sum,\n min: aggregationFn_min,\n max: aggregationFn_max,\n extent: aggregationFn_extent,\n mean: aggregationFn_mean,\n median: aggregationFn_median,\n unique: aggregationFn_unique,\n uniqueCount: aggregationFn_uniqueCount,\n count: aggregationFn_count,\n first: aggregationFn_first,\n last: aggregationFn_last,\n}\n\nexport type BuiltInAggregationFn = keyof typeof aggregationFns\n"],"mappings":"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"}
1
+ {"version":3,"file":"aggregationFns.cjs","names":["constructAggregationFn"],"sources":["../../../src/features/aggregation/aggregationFns.ts"],"sourcesContent":["import { constructAggregationFn } from './aggregationFeature.types'\nimport type { AggregationContext } from './aggregationFeature.types'\n\ntype RangeValue = Date | number\n\nfunction isNumber(value: unknown): value is number {\n return typeof value === 'number'\n}\n\nfunction isValidDate(value: unknown): value is Date {\n return value instanceof Date && !Number.isNaN(value.getTime())\n}\n\nfunction getRangeKind(value: unknown): 'date' | 'number' | undefined {\n if (isNumber(value)) return 'number'\n if (isValidDate(value)) return 'date'\n return undefined\n}\n\nfunction compareRangeValues(left: RangeValue, right: RangeValue) {\n const leftValue = left instanceof Date ? left.getTime() : left\n const rightValue = right instanceof Date ? right.getTime() : right\n return leftValue - rightValue\n}\n\nfunction collectRangeValues(context: AggregationContext<any, any, unknown>) {\n const values: Array<RangeValue> = []\n let kind: 'date' | 'number' | undefined\n\n for (let i = 0; i < context.rows.length; i++) {\n const value = context.getValue(context.rows[i]!)\n const valueKind = getRangeKind(value)\n if (!valueKind) continue\n kind ??= valueKind\n if (valueKind === kind) values.push(value as RangeValue)\n }\n\n return values\n}\n\n/**\n * Sums numeric selected-row values. Non-number values contribute zero. As in\n * the previous API, `NaN` is a number and therefore propagates through the sum.\n */\nexport const aggregationFn_sum = constructAggregationFn<\n any,\n any,\n unknown,\n number\n>({\n aggregate: (context) => {\n let sum = 0\n for (let i = 0; i < context.rows.length; i++) {\n const value = context.getValue(context.rows[i]!)\n sum += typeof value === 'number' ? value : 0\n }\n return sum\n },\n merge: ({ subRowResults }) => {\n let sum = 0\n for (let i = 0; i < subRowResults.length; i++) {\n const value = subRowResults[i]\n if (isNumber(value)) sum += value\n }\n return sum\n },\n})\n\n/**\n * Finds the minimum numeric or Date value from the selected rows. Invalid value\n * types are ignored; `NaN` preserves the legacy numeric seeding behavior.\n */\nexport const aggregationFn_min = constructAggregationFn<\n any,\n any,\n unknown,\n RangeValue | undefined\n>({\n aggregate: (context) => {\n const values = collectRangeValues(context)\n let result = values[0]\n for (let i = 1; i < values.length; i++) {\n if (compareRangeValues(values[i]!, result!) < 0) result = values[i]\n }\n return result\n },\n merge: ({ subRowResults }) => {\n let result: RangeValue | undefined\n let kind: 'date' | 'number' | undefined\n for (let i = 0; i < subRowResults.length; i++) {\n const value = subRowResults[i]\n const valueKind = getRangeKind(value)\n if (!valueKind) continue\n if (value === undefined) continue\n kind ??= valueKind\n if (kind !== valueKind) continue\n if (result === undefined || compareRangeValues(value, result) < 0) {\n result = value\n }\n }\n return result\n },\n})\n\n/**\n * Finds the maximum numeric or Date value from the selected rows. Invalid value\n * types are ignored; `NaN` preserves the legacy numeric seeding behavior.\n */\nexport const aggregationFn_max = constructAggregationFn<\n any,\n any,\n unknown,\n RangeValue | undefined\n>({\n aggregate: (context) => {\n const values = collectRangeValues(context)\n let result = values[0]\n for (let i = 1; i < values.length; i++) {\n if (compareRangeValues(values[i]!, result!) > 0) result = values[i]\n }\n return result\n },\n merge: ({ subRowResults }) => {\n let result: RangeValue | undefined\n let kind: 'date' | 'number' | undefined\n for (let i = 0; i < subRowResults.length; i++) {\n const value = subRowResults[i]\n const valueKind = getRangeKind(value)\n if (!valueKind) continue\n if (value === undefined) continue\n kind ??= valueKind\n if (kind !== valueKind) continue\n if (result === undefined || compareRangeValues(value, result) > 0) {\n result = value\n }\n }\n return result\n },\n})\n\n/**\n * Finds the minimum and maximum numeric or Date values from the selected rows.\n * Empty inputs return\n * `[undefined, undefined]`, preserving the previous built-in result shape.\n */\nexport const aggregationFn_extent = constructAggregationFn<\n any,\n any,\n unknown,\n [RangeValue | undefined, RangeValue | undefined]\n>({\n aggregate: (context) => {\n const values = collectRangeValues(context)\n if (!values.length) return [undefined, undefined]\n let min = values[0]!\n let max = values[0]!\n for (let i = 1; i < values.length; i++) {\n const value = values[i]!\n if (compareRangeValues(value, min) < 0) min = value\n if (compareRangeValues(value, max) > 0) max = value\n }\n return [min, max]\n },\n merge: ({ subRowResults }) => {\n let result: [RangeValue | undefined, RangeValue | undefined] = [\n undefined,\n undefined,\n ]\n let kind: 'date' | 'number' | undefined\n for (let i = 0; i < subRowResults.length; i++) {\n const extent = subRowResults[i]!\n const min = extent[0]\n const max = extent[1]\n const valueKind = getRangeKind(min)\n if (!valueKind || min === undefined || max === undefined) continue\n kind ??= valueKind\n if (kind !== valueKind) continue\n if (result[0] === undefined) {\n result = [min, max]\n } else {\n if (compareRangeValues(min, result[0]) < 0) {\n result[0] = min\n }\n const currentMax = result[1]\n if (\n currentMax === undefined ||\n compareRangeValues(max, currentMax) > 0\n ) {\n result[1] = max\n }\n }\n }\n return result\n },\n})\n\n/**\n * Averages number and number-like row values. Nullish and non-numeric values\n * are ignored; other values retain the legacy unary-plus coercion behavior.\n */\nexport const aggregationFn_mean = constructAggregationFn<\n any,\n any,\n unknown,\n number | undefined\n>({\n aggregate: (context) => {\n let count = 0\n let sum = 0\n for (let i = 0; i < context.rows.length; i++) {\n const value = context.getValue(context.rows[i]!)\n if (value == null) continue\n const numberValue = typeof value === 'number' ? value : +value\n if (!Number.isNaN(numberValue)) {\n count++\n sum += numberValue\n }\n }\n return count ? sum / count : undefined\n },\n})\n\n/**\n * Computes the median when every row value is a number. Returns `undefined`\n * for empty inputs or when any value is non-numeric.\n */\nexport const aggregationFn_median = constructAggregationFn<\n any,\n any,\n unknown,\n number | undefined\n>({\n aggregate: (context) => {\n if (!context.rows.length) return undefined\n const values = new Array<number>(context.rows.length)\n for (let i = 0; i < context.rows.length; i++) {\n const value = context.getValue(context.rows[i]!)\n if (typeof value !== 'number') return undefined\n values[i] = value\n }\n values.sort((a, b) => a - b)\n const mid = Math.floor(values.length / 2)\n return values.length % 2\n ? values[mid]\n : (values[mid - 1]! + values[mid]!) / 2\n },\n})\n\n/** Collects distinct row values using JavaScript `Set` semantics. */\nexport const aggregationFn_unique = constructAggregationFn<\n any,\n any,\n unknown,\n Array<unknown>\n>({\n aggregate: (context) => {\n const values = new Set<unknown>()\n for (let i = 0; i < context.rows.length; i++) {\n values.add(context.getValue(context.rows[i]!))\n }\n return Array.from(values)\n },\n})\n\n/** Counts distinct row values using JavaScript `Set` semantics. */\nexport const aggregationFn_uniqueCount = constructAggregationFn<\n any,\n any,\n unknown,\n number\n>({\n aggregate: (context) => {\n const values = new Set<unknown>()\n for (let i = 0; i < context.rows.length; i++) {\n values.add(context.getValue(context.rows[i]!))\n }\n return values.size\n },\n})\n\n/** Counts rows, independently of the column's values. */\nexport const aggregationFn_count = constructAggregationFn<\n any,\n any,\n unknown,\n number\n>({\n aggregate: ({ rows }) => rows.length,\n merge: ({ subRowResults }) => {\n let count = 0\n for (let i = 0; i < subRowResults.length; i++) {\n const value = subRowResults[i]\n if (isNumber(value)) count += value\n }\n return count\n },\n})\n\n/** Returns the first row's value, including a nullish value. */\nexport const aggregationFn_first = constructAggregationFn<\n any,\n any,\n unknown,\n unknown\n>({\n aggregate: (context) =>\n context.rows[0] ? context.getValue(context.rows[0]) : undefined,\n merge: ({ subRowResults }) => subRowResults[0],\n})\n\n/** Returns the last row's value, including a nullish value. */\nexport const aggregationFn_last = constructAggregationFn<\n any,\n any,\n unknown,\n unknown\n>({\n aggregate: (context) => {\n const row = context.rows[context.rows.length - 1]\n return row ? context.getValue(row) : undefined\n },\n merge: ({ subRowResults }) => subRowResults[subRowResults.length - 1],\n})\n\n/**\n * Full built-in registry. Register individual definitions for tree-shaking.\n *\n * @deprecated Import individual `aggregationFn_*` definitions instead for a\n * smaller bundle. This registry remains available for compatibility.\n */\nexport const aggregationFns = {\n sum: aggregationFn_sum,\n min: aggregationFn_min,\n max: aggregationFn_max,\n extent: aggregationFn_extent,\n mean: aggregationFn_mean,\n median: aggregationFn_median,\n unique: aggregationFn_unique,\n uniqueCount: aggregationFn_uniqueCount,\n count: aggregationFn_count,\n first: aggregationFn_first,\n last: aggregationFn_last,\n}\n\nexport type BuiltInAggregationFn = keyof typeof aggregationFns\n"],"mappings":"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"}
@@ -3,22 +3,23 @@ import { AggregationFnDef } from "./aggregationFeature.types.cjs";
3
3
  //#region src/features/aggregation/aggregationFns.d.ts
4
4
  type RangeValue = Date | number;
5
5
  /**
6
- * Sums numeric row values. Non-number values contribute zero. As in the
7
- * previous API, `NaN` is a number and therefore propagates through the sum.
6
+ * Sums numeric selected-row values. Non-number values contribute zero. As in
7
+ * the previous API, `NaN` is a number and therefore propagates through the sum.
8
8
  */
9
9
  declare const aggregationFn_sum: AggregationFnDef<any, any, unknown, number>;
10
10
  /**
11
- * Finds the minimum numeric or Date value. Invalid value types are ignored;
12
- * `NaN` preserves the legacy numeric seeding behavior.
11
+ * Finds the minimum numeric or Date value from the selected rows. Invalid value
12
+ * types are ignored; `NaN` preserves the legacy numeric seeding behavior.
13
13
  */
14
14
  declare const aggregationFn_min: AggregationFnDef<any, any, unknown, RangeValue | undefined>;
15
15
  /**
16
- * Finds the maximum numeric or Date value. Invalid value types are ignored;
17
- * `NaN` preserves the legacy numeric seeding behavior.
16
+ * Finds the maximum numeric or Date value from the selected rows. Invalid value
17
+ * types are ignored; `NaN` preserves the legacy numeric seeding behavior.
18
18
  */
19
19
  declare const aggregationFn_max: AggregationFnDef<any, any, unknown, RangeValue | undefined>;
20
20
  /**
21
- * Finds the minimum and maximum numeric or Date values. Empty inputs return
21
+ * Finds the minimum and maximum numeric or Date values from the selected rows.
22
+ * Empty inputs return
22
23
  * `[undefined, undefined]`, preserving the previous built-in result shape.
23
24
  */
24
25
  declare const aggregationFn_extent: AggregationFnDef<any, any, unknown, [RangeValue | undefined, RangeValue | undefined]>;
@@ -3,22 +3,23 @@ import { AggregationFnDef } from "./aggregationFeature.types.js";
3
3
  //#region src/features/aggregation/aggregationFns.d.ts
4
4
  type RangeValue = Date | number;
5
5
  /**
6
- * Sums numeric row values. Non-number values contribute zero. As in the
7
- * previous API, `NaN` is a number and therefore propagates through the sum.
6
+ * Sums numeric selected-row values. Non-number values contribute zero. As in
7
+ * the previous API, `NaN` is a number and therefore propagates through the sum.
8
8
  */
9
9
  declare const aggregationFn_sum: AggregationFnDef<any, any, unknown, number>;
10
10
  /**
11
- * Finds the minimum numeric or Date value. Invalid value types are ignored;
12
- * `NaN` preserves the legacy numeric seeding behavior.
11
+ * Finds the minimum numeric or Date value from the selected rows. Invalid value
12
+ * types are ignored; `NaN` preserves the legacy numeric seeding behavior.
13
13
  */
14
14
  declare const aggregationFn_min: AggregationFnDef<any, any, unknown, RangeValue | undefined>;
15
15
  /**
16
- * Finds the maximum numeric or Date value. Invalid value types are ignored;
17
- * `NaN` preserves the legacy numeric seeding behavior.
16
+ * Finds the maximum numeric or Date value from the selected rows. Invalid value
17
+ * types are ignored; `NaN` preserves the legacy numeric seeding behavior.
18
18
  */
19
19
  declare const aggregationFn_max: AggregationFnDef<any, any, unknown, RangeValue | undefined>;
20
20
  /**
21
- * Finds the minimum and maximum numeric or Date values. Empty inputs return
21
+ * Finds the minimum and maximum numeric or Date values from the selected rows.
22
+ * Empty inputs return
22
23
  * `[undefined, undefined]`, preserving the previous built-in result shape.
23
24
  */
24
25
  declare const aggregationFn_extent: AggregationFnDef<any, any, unknown, [RangeValue | undefined, RangeValue | undefined]>;
@@ -27,8 +27,8 @@ function collectRangeValues(context) {
27
27
  return values;
28
28
  }
29
29
  /**
30
- * Sums numeric row values. Non-number values contribute zero. As in the
31
- * previous API, `NaN` is a number and therefore propagates through the sum.
30
+ * Sums numeric selected-row values. Non-number values contribute zero. As in
31
+ * the previous API, `NaN` is a number and therefore propagates through the sum.
32
32
  */
33
33
  const aggregationFn_sum = constructAggregationFn({
34
34
  aggregate: (context) => {
@@ -39,18 +39,18 @@ const aggregationFn_sum = constructAggregationFn({
39
39
  }
40
40
  return sum;
41
41
  },
42
- merge: ({ childResults }) => {
42
+ merge: ({ subRowResults }) => {
43
43
  let sum = 0;
44
- for (let i = 0; i < childResults.length; i++) {
45
- const value = childResults[i];
44
+ for (let i = 0; i < subRowResults.length; i++) {
45
+ const value = subRowResults[i];
46
46
  if (isNumber(value)) sum += value;
47
47
  }
48
48
  return sum;
49
49
  }
50
50
  });
51
51
  /**
52
- * Finds the minimum numeric or Date value. Invalid value types are ignored;
53
- * `NaN` preserves the legacy numeric seeding behavior.
52
+ * Finds the minimum numeric or Date value from the selected rows. Invalid value
53
+ * types are ignored; `NaN` preserves the legacy numeric seeding behavior.
54
54
  */
55
55
  const aggregationFn_min = constructAggregationFn({
56
56
  aggregate: (context) => {
@@ -59,13 +59,14 @@ const aggregationFn_min = constructAggregationFn({
59
59
  for (let i = 1; i < values.length; i++) if (compareRangeValues(values[i], result) < 0) result = values[i];
60
60
  return result;
61
61
  },
62
- merge: ({ childResults }) => {
62
+ merge: ({ subRowResults }) => {
63
63
  let result;
64
64
  let kind;
65
- for (let i = 0; i < childResults.length; i++) {
66
- const value = childResults[i];
65
+ for (let i = 0; i < subRowResults.length; i++) {
66
+ const value = subRowResults[i];
67
67
  const valueKind = getRangeKind(value);
68
68
  if (!valueKind) continue;
69
+ if (value === void 0) continue;
69
70
  kind ??= valueKind;
70
71
  if (kind !== valueKind) continue;
71
72
  if (result === void 0 || compareRangeValues(value, result) < 0) result = value;
@@ -74,8 +75,8 @@ const aggregationFn_min = constructAggregationFn({
74
75
  }
75
76
  });
76
77
  /**
77
- * Finds the maximum numeric or Date value. Invalid value types are ignored;
78
- * `NaN` preserves the legacy numeric seeding behavior.
78
+ * Finds the maximum numeric or Date value from the selected rows. Invalid value
79
+ * types are ignored; `NaN` preserves the legacy numeric seeding behavior.
79
80
  */
80
81
  const aggregationFn_max = constructAggregationFn({
81
82
  aggregate: (context) => {
@@ -84,13 +85,14 @@ const aggregationFn_max = constructAggregationFn({
84
85
  for (let i = 1; i < values.length; i++) if (compareRangeValues(values[i], result) > 0) result = values[i];
85
86
  return result;
86
87
  },
87
- merge: ({ childResults }) => {
88
+ merge: ({ subRowResults }) => {
88
89
  let result;
89
90
  let kind;
90
- for (let i = 0; i < childResults.length; i++) {
91
- const value = childResults[i];
91
+ for (let i = 0; i < subRowResults.length; i++) {
92
+ const value = subRowResults[i];
92
93
  const valueKind = getRangeKind(value);
93
94
  if (!valueKind) continue;
95
+ if (value === void 0) continue;
94
96
  kind ??= valueKind;
95
97
  if (kind !== valueKind) continue;
96
98
  if (result === void 0 || compareRangeValues(value, result) > 0) result = value;
@@ -99,7 +101,8 @@ const aggregationFn_max = constructAggregationFn({
99
101
  }
100
102
  });
101
103
  /**
102
- * Finds the minimum and maximum numeric or Date values. Empty inputs return
104
+ * Finds the minimum and maximum numeric or Date values from the selected rows.
105
+ * Empty inputs return
103
106
  * `[undefined, undefined]`, preserving the previous built-in result shape.
104
107
  */
105
108
  const aggregationFn_extent = constructAggregationFn({
@@ -115,19 +118,22 @@ const aggregationFn_extent = constructAggregationFn({
115
118
  }
116
119
  return [min, max];
117
120
  },
118
- merge: ({ childResults }) => {
121
+ merge: ({ subRowResults }) => {
119
122
  let result = [void 0, void 0];
120
123
  let kind;
121
- for (let i = 0; i < childResults.length; i++) {
122
- const extent = childResults[i];
123
- const valueKind = getRangeKind(extent[0]);
124
- if (!valueKind) continue;
124
+ for (let i = 0; i < subRowResults.length; i++) {
125
+ const extent = subRowResults[i];
126
+ const min = extent[0];
127
+ const max = extent[1];
128
+ const valueKind = getRangeKind(min);
129
+ if (!valueKind || min === void 0 || max === void 0) continue;
125
130
  kind ??= valueKind;
126
131
  if (kind !== valueKind) continue;
127
- if (result[0] === void 0) result = [extent[0], extent[1]];
132
+ if (result[0] === void 0) result = [min, max];
128
133
  else {
129
- if (compareRangeValues(extent[0], result[0]) < 0) result[0] = extent[0];
130
- if (compareRangeValues(extent[1], result[1]) > 0) result[1] = extent[1];
134
+ if (compareRangeValues(min, result[0]) < 0) result[0] = min;
135
+ const currentMax = result[1];
136
+ if (currentMax === void 0 || compareRangeValues(max, currentMax) > 0) result[1] = max;
131
137
  }
132
138
  }
133
139
  return result;
@@ -182,10 +188,10 @@ const aggregationFn_uniqueCount = constructAggregationFn({ aggregate: (context)
182
188
  /** Counts rows, independently of the column's values. */
183
189
  const aggregationFn_count = constructAggregationFn({
184
190
  aggregate: ({ rows }) => rows.length,
185
- merge: ({ childResults }) => {
191
+ merge: ({ subRowResults }) => {
186
192
  let count = 0;
187
- for (let i = 0; i < childResults.length; i++) {
188
- const value = childResults[i];
193
+ for (let i = 0; i < subRowResults.length; i++) {
194
+ const value = subRowResults[i];
189
195
  if (isNumber(value)) count += value;
190
196
  }
191
197
  return count;
@@ -194,7 +200,7 @@ const aggregationFn_count = constructAggregationFn({
194
200
  /** Returns the first row's value, including a nullish value. */
195
201
  const aggregationFn_first = constructAggregationFn({
196
202
  aggregate: (context) => context.rows[0] ? context.getValue(context.rows[0]) : void 0,
197
- merge: ({ childResults }) => childResults[0]
203
+ merge: ({ subRowResults }) => subRowResults[0]
198
204
  });
199
205
  /** Returns the last row's value, including a nullish value. */
200
206
  const aggregationFn_last = constructAggregationFn({
@@ -202,7 +208,7 @@ const aggregationFn_last = constructAggregationFn({
202
208
  const row = context.rows[context.rows.length - 1];
203
209
  return row ? context.getValue(row) : void 0;
204
210
  },
205
- merge: ({ childResults }) => childResults[childResults.length - 1]
211
+ merge: ({ subRowResults }) => subRowResults[subRowResults.length - 1]
206
212
  });
207
213
  /**
208
214
  * Full built-in registry. Register individual definitions for tree-shaking.
@@ -1 +1 @@
1
- {"version":3,"file":"aggregationFns.js","names":[],"sources":["../../../src/features/aggregation/aggregationFns.ts"],"sourcesContent":["import { constructAggregationFn } from './aggregationFeature.types'\nimport type { AggregationContext } from './aggregationFeature.types'\n\ntype RangeValue = Date | number\n\nfunction isNumber(value: unknown): value is number {\n return typeof value === 'number'\n}\n\nfunction isValidDate(value: unknown): value is Date {\n return value instanceof Date && !Number.isNaN(value.getTime())\n}\n\nfunction getRangeKind(value: unknown): 'date' | 'number' | undefined {\n if (isNumber(value)) return 'number'\n if (isValidDate(value)) return 'date'\n return undefined\n}\n\nfunction compareRangeValues(left: RangeValue, right: RangeValue) {\n const leftValue = left instanceof Date ? left.getTime() : left\n const rightValue = right instanceof Date ? right.getTime() : right\n return leftValue - rightValue\n}\n\nfunction collectRangeValues(context: AggregationContext<any, any, unknown>) {\n const values: Array<RangeValue> = []\n let kind: 'date' | 'number' | undefined\n\n for (let i = 0; i < context.rows.length; i++) {\n const value = context.getValue(context.rows[i]!)\n const valueKind = getRangeKind(value)\n if (!valueKind) continue\n kind ??= valueKind\n if (valueKind === kind) values.push(value as RangeValue)\n }\n\n return values\n}\n\n/**\n * Sums numeric row values. Non-number values contribute zero. As in the\n * previous API, `NaN` is a number and therefore propagates through the sum.\n */\nexport const aggregationFn_sum = constructAggregationFn<\n any,\n any,\n unknown,\n number\n>({\n aggregate: (context) => {\n let sum = 0\n for (let i = 0; i < context.rows.length; i++) {\n const value = context.getValue(context.rows[i]!)\n sum += typeof value === 'number' ? value : 0\n }\n return sum\n },\n merge: ({ childResults }) => {\n let sum = 0\n for (let i = 0; i < childResults.length; i++) {\n const value = childResults[i]\n if (isNumber(value)) sum += value\n }\n return sum\n },\n})\n\n/**\n * Finds the minimum numeric or Date value. Invalid value types are ignored;\n * `NaN` preserves the legacy numeric seeding behavior.\n */\nexport const aggregationFn_min = constructAggregationFn<\n any,\n any,\n unknown,\n RangeValue | undefined\n>({\n aggregate: (context) => {\n const values = collectRangeValues(context)\n let result = values[0]\n for (let i = 1; i < values.length; i++) {\n if (compareRangeValues(values[i]!, result!) < 0) result = values[i]\n }\n return result\n },\n merge: ({ childResults }) => {\n let result: RangeValue | undefined\n let kind: 'date' | 'number' | undefined\n for (let i = 0; i < childResults.length; i++) {\n const value = childResults[i]\n const valueKind = getRangeKind(value)\n if (!valueKind) continue\n kind ??= valueKind\n if (kind !== valueKind) continue\n if (result === undefined || compareRangeValues(value!, result) < 0) {\n result = value\n }\n }\n return result\n },\n})\n\n/**\n * Finds the maximum numeric or Date value. Invalid value types are ignored;\n * `NaN` preserves the legacy numeric seeding behavior.\n */\nexport const aggregationFn_max = constructAggregationFn<\n any,\n any,\n unknown,\n RangeValue | undefined\n>({\n aggregate: (context) => {\n const values = collectRangeValues(context)\n let result = values[0]\n for (let i = 1; i < values.length; i++) {\n if (compareRangeValues(values[i]!, result!) > 0) result = values[i]\n }\n return result\n },\n merge: ({ childResults }) => {\n let result: RangeValue | undefined\n let kind: 'date' | 'number' | undefined\n for (let i = 0; i < childResults.length; i++) {\n const value = childResults[i]\n const valueKind = getRangeKind(value)\n if (!valueKind) continue\n kind ??= valueKind\n if (kind !== valueKind) continue\n if (result === undefined || compareRangeValues(value!, result) > 0) {\n result = value\n }\n }\n return result\n },\n})\n\n/**\n * Finds the minimum and maximum numeric or Date values. Empty inputs return\n * `[undefined, undefined]`, preserving the previous built-in result shape.\n */\nexport const aggregationFn_extent = constructAggregationFn<\n any,\n any,\n unknown,\n [RangeValue | undefined, RangeValue | undefined]\n>({\n aggregate: (context) => {\n const values = collectRangeValues(context)\n if (!values.length) return [undefined, undefined]\n let min = values[0]!\n let max = values[0]!\n for (let i = 1; i < values.length; i++) {\n const value = values[i]!\n if (compareRangeValues(value, min) < 0) min = value\n if (compareRangeValues(value, max) > 0) max = value\n }\n return [min, max]\n },\n merge: ({ childResults }) => {\n let result: [RangeValue | undefined, RangeValue | undefined] = [\n undefined,\n undefined,\n ]\n let kind: 'date' | 'number' | undefined\n for (let i = 0; i < childResults.length; i++) {\n const extent = childResults[i]!\n const valueKind = getRangeKind(extent[0])\n if (!valueKind) continue\n kind ??= valueKind\n if (kind !== valueKind) continue\n if (result[0] === undefined) {\n result = [extent[0], extent[1]]\n } else {\n if (compareRangeValues(extent[0]!, result[0]) < 0) {\n result[0] = extent[0]\n }\n if (compareRangeValues(extent[1]!, result[1]!) > 0) {\n result[1] = extent[1]\n }\n }\n }\n return result\n },\n})\n\n/**\n * Averages number and number-like row values. Nullish and non-numeric values\n * are ignored; other values retain the legacy unary-plus coercion behavior.\n */\nexport const aggregationFn_mean = constructAggregationFn<\n any,\n any,\n unknown,\n number | undefined\n>({\n aggregate: (context) => {\n let count = 0\n let sum = 0\n for (let i = 0; i < context.rows.length; i++) {\n const value = context.getValue(context.rows[i]!)\n if (value == null) continue\n const numberValue = typeof value === 'number' ? value : +value\n if (!Number.isNaN(numberValue)) {\n count++\n sum += numberValue\n }\n }\n return count ? sum / count : undefined\n },\n})\n\n/**\n * Computes the median when every row value is a number. Returns `undefined`\n * for empty inputs or when any value is non-numeric.\n */\nexport const aggregationFn_median = constructAggregationFn<\n any,\n any,\n unknown,\n number | undefined\n>({\n aggregate: (context) => {\n if (!context.rows.length) return undefined\n const values = new Array<number>(context.rows.length)\n for (let i = 0; i < context.rows.length; i++) {\n const value = context.getValue(context.rows[i]!)\n if (typeof value !== 'number') return undefined\n values[i] = value\n }\n values.sort((a, b) => a - b)\n const mid = Math.floor(values.length / 2)\n return values.length % 2\n ? values[mid]\n : (values[mid - 1]! + values[mid]!) / 2\n },\n})\n\n/** Collects distinct row values using JavaScript `Set` semantics. */\nexport const aggregationFn_unique = constructAggregationFn<\n any,\n any,\n unknown,\n Array<unknown>\n>({\n aggregate: (context) => {\n const values = new Set<unknown>()\n for (let i = 0; i < context.rows.length; i++) {\n values.add(context.getValue(context.rows[i]!))\n }\n return Array.from(values)\n },\n})\n\n/** Counts distinct row values using JavaScript `Set` semantics. */\nexport const aggregationFn_uniqueCount = constructAggregationFn<\n any,\n any,\n unknown,\n number\n>({\n aggregate: (context) => {\n const values = new Set<unknown>()\n for (let i = 0; i < context.rows.length; i++) {\n values.add(context.getValue(context.rows[i]!))\n }\n return values.size\n },\n})\n\n/** Counts rows, independently of the column's values. */\nexport const aggregationFn_count = constructAggregationFn<\n any,\n any,\n unknown,\n number\n>({\n aggregate: ({ rows }) => rows.length,\n merge: ({ childResults }) => {\n let count = 0\n for (let i = 0; i < childResults.length; i++) {\n const value = childResults[i]\n if (isNumber(value)) count += value\n }\n return count\n },\n})\n\n/** Returns the first row's value, including a nullish value. */\nexport const aggregationFn_first = constructAggregationFn<\n any,\n any,\n unknown,\n unknown\n>({\n aggregate: (context) =>\n context.rows[0] ? context.getValue(context.rows[0]) : undefined,\n merge: ({ childResults }) => childResults[0],\n})\n\n/** Returns the last row's value, including a nullish value. */\nexport const aggregationFn_last = constructAggregationFn<\n any,\n any,\n unknown,\n unknown\n>({\n aggregate: (context) => {\n const row = context.rows[context.rows.length - 1]\n return row ? context.getValue(row) : undefined\n },\n merge: ({ childResults }) => childResults[childResults.length - 1],\n})\n\n/**\n * Full built-in registry. Register individual definitions for tree-shaking.\n *\n * @deprecated Import individual `aggregationFn_*` definitions instead for a\n * smaller bundle. This registry remains available for compatibility.\n */\nexport const aggregationFns = {\n sum: aggregationFn_sum,\n min: aggregationFn_min,\n max: aggregationFn_max,\n extent: aggregationFn_extent,\n mean: aggregationFn_mean,\n median: aggregationFn_median,\n unique: aggregationFn_unique,\n uniqueCount: aggregationFn_uniqueCount,\n count: aggregationFn_count,\n first: aggregationFn_first,\n last: aggregationFn_last,\n}\n\nexport type BuiltInAggregationFn = keyof typeof aggregationFns\n"],"mappings":";;;AAKA,SAAS,SAAS,OAAiC;CACjD,OAAO,OAAO,UAAU;AAC1B;AAEA,SAAS,YAAY,OAA+B;CAClD,OAAO,iBAAiB,QAAQ,CAAC,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC/D;AAEA,SAAS,aAAa,OAA+C;CACnE,IAAI,SAAS,KAAK,GAAG,OAAO;CAC5B,IAAI,YAAY,KAAK,GAAG,OAAO;AAEjC;AAEA,SAAS,mBAAmB,MAAkB,OAAmB;CAG/D,QAFkB,gBAAgB,OAAO,KAAK,QAAQ,IAAI,SACvC,iBAAiB,OAAO,MAAM,QAAQ,IAAI;AAE/D;AAEA,SAAS,mBAAmB,SAAgD;CAC1E,MAAM,SAA4B,CAAC;CACnC,IAAI;CAEJ,KAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,KAAK,QAAQ,KAAK;EAC5C,MAAM,QAAQ,QAAQ,SAAS,QAAQ,KAAK,EAAG;EAC/C,MAAM,YAAY,aAAa,KAAK;EACpC,IAAI,CAAC,WAAW;EAChB,SAAS;EACT,IAAI,cAAc,MAAM,OAAO,KAAK,KAAmB;CACzD;CAEA,OAAO;AACT;;;;;AAMA,MAAa,oBAAoB,uBAK/B;CACA,YAAY,YAAY;EACtB,IAAI,MAAM;EACV,KAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,KAAK,QAAQ,KAAK;GAC5C,MAAM,QAAQ,QAAQ,SAAS,QAAQ,KAAK,EAAG;GAC/C,OAAO,OAAO,UAAU,WAAW,QAAQ;EAC7C;EACA,OAAO;CACT;CACA,QAAQ,EAAE,mBAAmB;EAC3B,IAAI,MAAM;EACV,KAAK,IAAI,IAAI,GAAG,IAAI,aAAa,QAAQ,KAAK;GAC5C,MAAM,QAAQ,aAAa;GAC3B,IAAI,SAAS,KAAK,GAAG,OAAO;EAC9B;EACA,OAAO;CACT;AACF,CAAC;;;;;AAMD,MAAa,oBAAoB,uBAK/B;CACA,YAAY,YAAY;EACtB,MAAM,SAAS,mBAAmB,OAAO;EACzC,IAAI,SAAS,OAAO;EACpB,KAAK,IAAI,IAAI,GAAG,IAAI,OAAO,QAAQ,KACjC,IAAI,mBAAmB,OAAO,IAAK,MAAO,IAAI,GAAG,SAAS,OAAO;EAEnE,OAAO;CACT;CACA,QAAQ,EAAE,mBAAmB;EAC3B,IAAI;EACJ,IAAI;EACJ,KAAK,IAAI,IAAI,GAAG,IAAI,aAAa,QAAQ,KAAK;GAC5C,MAAM,QAAQ,aAAa;GAC3B,MAAM,YAAY,aAAa,KAAK;GACpC,IAAI,CAAC,WAAW;GAChB,SAAS;GACT,IAAI,SAAS,WAAW;GACxB,IAAI,WAAW,UAAa,mBAAmB,OAAQ,MAAM,IAAI,GAC/D,SAAS;EAEb;EACA,OAAO;CACT;AACF,CAAC;;;;;AAMD,MAAa,oBAAoB,uBAK/B;CACA,YAAY,YAAY;EACtB,MAAM,SAAS,mBAAmB,OAAO;EACzC,IAAI,SAAS,OAAO;EACpB,KAAK,IAAI,IAAI,GAAG,IAAI,OAAO,QAAQ,KACjC,IAAI,mBAAmB,OAAO,IAAK,MAAO,IAAI,GAAG,SAAS,OAAO;EAEnE,OAAO;CACT;CACA,QAAQ,EAAE,mBAAmB;EAC3B,IAAI;EACJ,IAAI;EACJ,KAAK,IAAI,IAAI,GAAG,IAAI,aAAa,QAAQ,KAAK;GAC5C,MAAM,QAAQ,aAAa;GAC3B,MAAM,YAAY,aAAa,KAAK;GACpC,IAAI,CAAC,WAAW;GAChB,SAAS;GACT,IAAI,SAAS,WAAW;GACxB,IAAI,WAAW,UAAa,mBAAmB,OAAQ,MAAM,IAAI,GAC/D,SAAS;EAEb;EACA,OAAO;CACT;AACF,CAAC;;;;;AAMD,MAAa,uBAAuB,uBAKlC;CACA,YAAY,YAAY;EACtB,MAAM,SAAS,mBAAmB,OAAO;EACzC,IAAI,CAAC,OAAO,QAAQ,OAAO,CAAC,QAAW,MAAS;EAChD,IAAI,MAAM,OAAO;EACjB,IAAI,MAAM,OAAO;EACjB,KAAK,IAAI,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;GACtC,MAAM,QAAQ,OAAO;GACrB,IAAI,mBAAmB,OAAO,GAAG,IAAI,GAAG,MAAM;GAC9C,IAAI,mBAAmB,OAAO,GAAG,IAAI,GAAG,MAAM;EAChD;EACA,OAAO,CAAC,KAAK,GAAG;CAClB;CACA,QAAQ,EAAE,mBAAmB;EAC3B,IAAI,SAA2D,CAC7D,QACA,MACF;EACA,IAAI;EACJ,KAAK,IAAI,IAAI,GAAG,IAAI,aAAa,QAAQ,KAAK;GAC5C,MAAM,SAAS,aAAa;GAC5B,MAAM,YAAY,aAAa,OAAO,EAAE;GACxC,IAAI,CAAC,WAAW;GAChB,SAAS;GACT,IAAI,SAAS,WAAW;GACxB,IAAI,OAAO,OAAO,QAChB,SAAS,CAAC,OAAO,IAAI,OAAO,EAAE;QACzB;IACL,IAAI,mBAAmB,OAAO,IAAK,OAAO,EAAE,IAAI,GAC9C,OAAO,KAAK,OAAO;IAErB,IAAI,mBAAmB,OAAO,IAAK,OAAO,EAAG,IAAI,GAC/C,OAAO,KAAK,OAAO;GAEvB;EACF;EACA,OAAO;CACT;AACF,CAAC;;;;;AAMD,MAAa,qBAAqB,uBAKhC,EACA,YAAY,YAAY;CACtB,IAAI,QAAQ;CACZ,IAAI,MAAM;CACV,KAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,KAAK,QAAQ,KAAK;EAC5C,MAAM,QAAQ,QAAQ,SAAS,QAAQ,KAAK,EAAG;EAC/C,IAAI,SAAS,MAAM;EACnB,MAAM,cAAc,OAAO,UAAU,WAAW,QAAQ,CAAC;EACzD,IAAI,CAAC,OAAO,MAAM,WAAW,GAAG;GAC9B;GACA,OAAO;EACT;CACF;CACA,OAAO,QAAQ,MAAM,QAAQ;AAC/B,EACF,CAAC;;;;;AAMD,MAAa,uBAAuB,uBAKlC,EACA,YAAY,YAAY;CACtB,IAAI,CAAC,QAAQ,KAAK,QAAQ,OAAO;CACjC,MAAM,SAAS,IAAI,MAAc,QAAQ,KAAK,MAAM;CACpD,KAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,KAAK,QAAQ,KAAK;EAC5C,MAAM,QAAQ,QAAQ,SAAS,QAAQ,KAAK,EAAG;EAC/C,IAAI,OAAO,UAAU,UAAU,OAAO;EACtC,OAAO,KAAK;CACd;CACA,OAAO,MAAM,GAAG,MAAM,IAAI,CAAC;CAC3B,MAAM,MAAM,KAAK,MAAM,OAAO,SAAS,CAAC;CACxC,OAAO,OAAO,SAAS,IACnB,OAAO,QACN,OAAO,MAAM,KAAM,OAAO,QAAS;AAC1C,EACF,CAAC;;AAGD,MAAa,uBAAuB,uBAKlC,EACA,YAAY,YAAY;CACtB,MAAM,yBAAS,IAAI,IAAa;CAChC,KAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,KAAK,QAAQ,KACvC,OAAO,IAAI,QAAQ,SAAS,QAAQ,KAAK,EAAG,CAAC;CAE/C,OAAO,MAAM,KAAK,MAAM;AAC1B,EACF,CAAC;;AAGD,MAAa,4BAA4B,uBAKvC,EACA,YAAY,YAAY;CACtB,MAAM,yBAAS,IAAI,IAAa;CAChC,KAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,KAAK,QAAQ,KACvC,OAAO,IAAI,QAAQ,SAAS,QAAQ,KAAK,EAAG,CAAC;CAE/C,OAAO,OAAO;AAChB,EACF,CAAC;;AAGD,MAAa,sBAAsB,uBAKjC;CACA,YAAY,EAAE,WAAW,KAAK;CAC9B,QAAQ,EAAE,mBAAmB;EAC3B,IAAI,QAAQ;EACZ,KAAK,IAAI,IAAI,GAAG,IAAI,aAAa,QAAQ,KAAK;GAC5C,MAAM,QAAQ,aAAa;GAC3B,IAAI,SAAS,KAAK,GAAG,SAAS;EAChC;EACA,OAAO;CACT;AACF,CAAC;;AAGD,MAAa,sBAAsB,uBAKjC;CACA,YAAY,YACV,QAAQ,KAAK,KAAK,QAAQ,SAAS,QAAQ,KAAK,EAAE,IAAI;CACxD,QAAQ,EAAE,mBAAmB,aAAa;AAC5C,CAAC;;AAGD,MAAa,qBAAqB,uBAKhC;CACA,YAAY,YAAY;EACtB,MAAM,MAAM,QAAQ,KAAK,QAAQ,KAAK,SAAS;EAC/C,OAAO,MAAM,QAAQ,SAAS,GAAG,IAAI;CACvC;CACA,QAAQ,EAAE,mBAAmB,aAAa,aAAa,SAAS;AAClE,CAAC;;;;;;;AAQD,MAAa,iBAAiB;CAC5B,KAAK;CACL,KAAK;CACL,KAAK;CACL,QAAQ;CACR,MAAM;CACN,QAAQ;CACR,QAAQ;CACR,aAAa;CACb,OAAO;CACP,OAAO;CACP,MAAM;AACR"}
1
+ {"version":3,"file":"aggregationFns.js","names":[],"sources":["../../../src/features/aggregation/aggregationFns.ts"],"sourcesContent":["import { constructAggregationFn } from './aggregationFeature.types'\nimport type { AggregationContext } from './aggregationFeature.types'\n\ntype RangeValue = Date | number\n\nfunction isNumber(value: unknown): value is number {\n return typeof value === 'number'\n}\n\nfunction isValidDate(value: unknown): value is Date {\n return value instanceof Date && !Number.isNaN(value.getTime())\n}\n\nfunction getRangeKind(value: unknown): 'date' | 'number' | undefined {\n if (isNumber(value)) return 'number'\n if (isValidDate(value)) return 'date'\n return undefined\n}\n\nfunction compareRangeValues(left: RangeValue, right: RangeValue) {\n const leftValue = left instanceof Date ? left.getTime() : left\n const rightValue = right instanceof Date ? right.getTime() : right\n return leftValue - rightValue\n}\n\nfunction collectRangeValues(context: AggregationContext<any, any, unknown>) {\n const values: Array<RangeValue> = []\n let kind: 'date' | 'number' | undefined\n\n for (let i = 0; i < context.rows.length; i++) {\n const value = context.getValue(context.rows[i]!)\n const valueKind = getRangeKind(value)\n if (!valueKind) continue\n kind ??= valueKind\n if (valueKind === kind) values.push(value as RangeValue)\n }\n\n return values\n}\n\n/**\n * Sums numeric selected-row values. Non-number values contribute zero. As in\n * the previous API, `NaN` is a number and therefore propagates through the sum.\n */\nexport const aggregationFn_sum = constructAggregationFn<\n any,\n any,\n unknown,\n number\n>({\n aggregate: (context) => {\n let sum = 0\n for (let i = 0; i < context.rows.length; i++) {\n const value = context.getValue(context.rows[i]!)\n sum += typeof value === 'number' ? value : 0\n }\n return sum\n },\n merge: ({ subRowResults }) => {\n let sum = 0\n for (let i = 0; i < subRowResults.length; i++) {\n const value = subRowResults[i]\n if (isNumber(value)) sum += value\n }\n return sum\n },\n})\n\n/**\n * Finds the minimum numeric or Date value from the selected rows. Invalid value\n * types are ignored; `NaN` preserves the legacy numeric seeding behavior.\n */\nexport const aggregationFn_min = constructAggregationFn<\n any,\n any,\n unknown,\n RangeValue | undefined\n>({\n aggregate: (context) => {\n const values = collectRangeValues(context)\n let result = values[0]\n for (let i = 1; i < values.length; i++) {\n if (compareRangeValues(values[i]!, result!) < 0) result = values[i]\n }\n return result\n },\n merge: ({ subRowResults }) => {\n let result: RangeValue | undefined\n let kind: 'date' | 'number' | undefined\n for (let i = 0; i < subRowResults.length; i++) {\n const value = subRowResults[i]\n const valueKind = getRangeKind(value)\n if (!valueKind) continue\n if (value === undefined) continue\n kind ??= valueKind\n if (kind !== valueKind) continue\n if (result === undefined || compareRangeValues(value, result) < 0) {\n result = value\n }\n }\n return result\n },\n})\n\n/**\n * Finds the maximum numeric or Date value from the selected rows. Invalid value\n * types are ignored; `NaN` preserves the legacy numeric seeding behavior.\n */\nexport const aggregationFn_max = constructAggregationFn<\n any,\n any,\n unknown,\n RangeValue | undefined\n>({\n aggregate: (context) => {\n const values = collectRangeValues(context)\n let result = values[0]\n for (let i = 1; i < values.length; i++) {\n if (compareRangeValues(values[i]!, result!) > 0) result = values[i]\n }\n return result\n },\n merge: ({ subRowResults }) => {\n let result: RangeValue | undefined\n let kind: 'date' | 'number' | undefined\n for (let i = 0; i < subRowResults.length; i++) {\n const value = subRowResults[i]\n const valueKind = getRangeKind(value)\n if (!valueKind) continue\n if (value === undefined) continue\n kind ??= valueKind\n if (kind !== valueKind) continue\n if (result === undefined || compareRangeValues(value, result) > 0) {\n result = value\n }\n }\n return result\n },\n})\n\n/**\n * Finds the minimum and maximum numeric or Date values from the selected rows.\n * Empty inputs return\n * `[undefined, undefined]`, preserving the previous built-in result shape.\n */\nexport const aggregationFn_extent = constructAggregationFn<\n any,\n any,\n unknown,\n [RangeValue | undefined, RangeValue | undefined]\n>({\n aggregate: (context) => {\n const values = collectRangeValues(context)\n if (!values.length) return [undefined, undefined]\n let min = values[0]!\n let max = values[0]!\n for (let i = 1; i < values.length; i++) {\n const value = values[i]!\n if (compareRangeValues(value, min) < 0) min = value\n if (compareRangeValues(value, max) > 0) max = value\n }\n return [min, max]\n },\n merge: ({ subRowResults }) => {\n let result: [RangeValue | undefined, RangeValue | undefined] = [\n undefined,\n undefined,\n ]\n let kind: 'date' | 'number' | undefined\n for (let i = 0; i < subRowResults.length; i++) {\n const extent = subRowResults[i]!\n const min = extent[0]\n const max = extent[1]\n const valueKind = getRangeKind(min)\n if (!valueKind || min === undefined || max === undefined) continue\n kind ??= valueKind\n if (kind !== valueKind) continue\n if (result[0] === undefined) {\n result = [min, max]\n } else {\n if (compareRangeValues(min, result[0]) < 0) {\n result[0] = min\n }\n const currentMax = result[1]\n if (\n currentMax === undefined ||\n compareRangeValues(max, currentMax) > 0\n ) {\n result[1] = max\n }\n }\n }\n return result\n },\n})\n\n/**\n * Averages number and number-like row values. Nullish and non-numeric values\n * are ignored; other values retain the legacy unary-plus coercion behavior.\n */\nexport const aggregationFn_mean = constructAggregationFn<\n any,\n any,\n unknown,\n number | undefined\n>({\n aggregate: (context) => {\n let count = 0\n let sum = 0\n for (let i = 0; i < context.rows.length; i++) {\n const value = context.getValue(context.rows[i]!)\n if (value == null) continue\n const numberValue = typeof value === 'number' ? value : +value\n if (!Number.isNaN(numberValue)) {\n count++\n sum += numberValue\n }\n }\n return count ? sum / count : undefined\n },\n})\n\n/**\n * Computes the median when every row value is a number. Returns `undefined`\n * for empty inputs or when any value is non-numeric.\n */\nexport const aggregationFn_median = constructAggregationFn<\n any,\n any,\n unknown,\n number | undefined\n>({\n aggregate: (context) => {\n if (!context.rows.length) return undefined\n const values = new Array<number>(context.rows.length)\n for (let i = 0; i < context.rows.length; i++) {\n const value = context.getValue(context.rows[i]!)\n if (typeof value !== 'number') return undefined\n values[i] = value\n }\n values.sort((a, b) => a - b)\n const mid = Math.floor(values.length / 2)\n return values.length % 2\n ? values[mid]\n : (values[mid - 1]! + values[mid]!) / 2\n },\n})\n\n/** Collects distinct row values using JavaScript `Set` semantics. */\nexport const aggregationFn_unique = constructAggregationFn<\n any,\n any,\n unknown,\n Array<unknown>\n>({\n aggregate: (context) => {\n const values = new Set<unknown>()\n for (let i = 0; i < context.rows.length; i++) {\n values.add(context.getValue(context.rows[i]!))\n }\n return Array.from(values)\n },\n})\n\n/** Counts distinct row values using JavaScript `Set` semantics. */\nexport const aggregationFn_uniqueCount = constructAggregationFn<\n any,\n any,\n unknown,\n number\n>({\n aggregate: (context) => {\n const values = new Set<unknown>()\n for (let i = 0; i < context.rows.length; i++) {\n values.add(context.getValue(context.rows[i]!))\n }\n return values.size\n },\n})\n\n/** Counts rows, independently of the column's values. */\nexport const aggregationFn_count = constructAggregationFn<\n any,\n any,\n unknown,\n number\n>({\n aggregate: ({ rows }) => rows.length,\n merge: ({ subRowResults }) => {\n let count = 0\n for (let i = 0; i < subRowResults.length; i++) {\n const value = subRowResults[i]\n if (isNumber(value)) count += value\n }\n return count\n },\n})\n\n/** Returns the first row's value, including a nullish value. */\nexport const aggregationFn_first = constructAggregationFn<\n any,\n any,\n unknown,\n unknown\n>({\n aggregate: (context) =>\n context.rows[0] ? context.getValue(context.rows[0]) : undefined,\n merge: ({ subRowResults }) => subRowResults[0],\n})\n\n/** Returns the last row's value, including a nullish value. */\nexport const aggregationFn_last = constructAggregationFn<\n any,\n any,\n unknown,\n unknown\n>({\n aggregate: (context) => {\n const row = context.rows[context.rows.length - 1]\n return row ? context.getValue(row) : undefined\n },\n merge: ({ subRowResults }) => subRowResults[subRowResults.length - 1],\n})\n\n/**\n * Full built-in registry. Register individual definitions for tree-shaking.\n *\n * @deprecated Import individual `aggregationFn_*` definitions instead for a\n * smaller bundle. This registry remains available for compatibility.\n */\nexport const aggregationFns = {\n sum: aggregationFn_sum,\n min: aggregationFn_min,\n max: aggregationFn_max,\n extent: aggregationFn_extent,\n mean: aggregationFn_mean,\n median: aggregationFn_median,\n unique: aggregationFn_unique,\n uniqueCount: aggregationFn_uniqueCount,\n count: aggregationFn_count,\n first: aggregationFn_first,\n last: aggregationFn_last,\n}\n\nexport type BuiltInAggregationFn = keyof typeof aggregationFns\n"],"mappings":"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"}
@@ -70,7 +70,7 @@ function _createGroupedRowModel(table) {
70
70
  subRows.forEach((subRow) => {
71
71
  subRow.parentId = id;
72
72
  });
73
- const leafRows = require_aggregationFeature_utils.normalizeAggregationRows(groupedRows);
73
+ const leafRows = require_aggregationFeature_utils.normalizeAggregationRows(groupedRows, Infinity);
74
74
  const row = require_constructRow.constructRow(table, id, leafRows[0].original, index, depth, void 0, parentId);
75
75
  Object.assign(row, {
76
76
  groupingColumnId: columnId,
@@ -90,10 +90,10 @@ function _createGroupedRowModel(table) {
90
90
  if (typeof column.getAggregationFns !== "function") return void 0;
91
91
  const cache = row._aggregationValuesCache ??= require_utils.makeObjectMap();
92
92
  cache[colId] = require_aggregationFeature_utils.aggregateColumnValue({
93
- childRows: subRows,
93
+ subRows,
94
94
  column,
95
95
  groupingRow: row,
96
- rows: leafRows
96
+ rows: groupedRows
97
97
  });
98
98
  return cache[colId];
99
99
  }