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

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 (110) hide show
  1. package/dist/features/column-grouping/createGroupedRowModel.cjs +22 -14
  2. package/dist/features/column-grouping/createGroupedRowModel.cjs.map +1 -1
  3. package/dist/features/column-grouping/createGroupedRowModel.d.cts +1 -1
  4. package/dist/features/column-grouping/createGroupedRowModel.d.ts +1 -1
  5. package/dist/features/column-grouping/createGroupedRowModel.js +21 -13
  6. package/dist/features/column-grouping/createGroupedRowModel.js.map +1 -1
  7. package/dist/features/{aggregation → row-aggregation}/aggregationFns.cjs +93 -48
  8. package/dist/features/row-aggregation/aggregationFns.cjs.map +1 -0
  9. package/dist/features/{aggregation → row-aggregation}/aggregationFns.d.cts +2 -2
  10. package/dist/features/{aggregation → row-aggregation}/aggregationFns.d.ts +2 -2
  11. package/dist/features/{aggregation → row-aggregation}/aggregationFns.js +82 -37
  12. package/dist/features/row-aggregation/aggregationFns.js.map +1 -0
  13. package/dist/features/row-aggregation/rowAggregationFeature.cjs +36 -0
  14. package/dist/features/row-aggregation/rowAggregationFeature.cjs.map +1 -0
  15. package/dist/features/row-aggregation/rowAggregationFeature.d.cts +10 -0
  16. package/dist/features/row-aggregation/rowAggregationFeature.d.ts +10 -0
  17. package/dist/features/{aggregation/aggregationFeature.js → row-aggregation/rowAggregationFeature.js} +8 -11
  18. package/dist/features/row-aggregation/rowAggregationFeature.js.map +1 -0
  19. package/dist/features/{aggregation/aggregationFeature.types.cjs → row-aggregation/rowAggregationFeature.types.cjs} +2 -2
  20. package/dist/features/row-aggregation/rowAggregationFeature.types.cjs.map +1 -0
  21. package/dist/features/{aggregation/aggregationFeature.types.d.cts → row-aggregation/rowAggregationFeature.types.d.cts} +8 -8
  22. package/dist/features/{aggregation/aggregationFeature.types.d.ts → row-aggregation/rowAggregationFeature.types.d.ts} +8 -8
  23. package/dist/features/{aggregation/aggregationFeature.types.js → row-aggregation/rowAggregationFeature.types.js} +2 -2
  24. package/dist/features/row-aggregation/rowAggregationFeature.types.js.map +1 -0
  25. package/dist/features/{aggregation/aggregationFeature.utils.cjs → row-aggregation/rowAggregationFeature.utils.cjs} +37 -6
  26. package/dist/features/row-aggregation/rowAggregationFeature.utils.cjs.map +1 -0
  27. package/dist/features/{aggregation/aggregationFeature.utils.d.cts → row-aggregation/rowAggregationFeature.utils.d.cts} +18 -4
  28. package/dist/features/{aggregation/aggregationFeature.utils.d.ts → row-aggregation/rowAggregationFeature.utils.d.ts} +18 -4
  29. package/dist/features/{aggregation/aggregationFeature.utils.js → row-aggregation/rowAggregationFeature.utils.js} +37 -7
  30. package/dist/features/row-aggregation/rowAggregationFeature.utils.js.map +1 -0
  31. package/dist/features/stockFeatures.cjs +2 -2
  32. package/dist/features/stockFeatures.cjs.map +1 -1
  33. package/dist/features/stockFeatures.d.cts +2 -2
  34. package/dist/features/stockFeatures.d.ts +2 -2
  35. package/dist/features/stockFeatures.js +2 -2
  36. package/dist/features/stockFeatures.js.map +1 -1
  37. package/dist/index.cjs +5 -5
  38. package/dist/index.d.cts +4 -4
  39. package/dist/index.d.ts +4 -4
  40. package/dist/index.js +4 -4
  41. package/dist/static-functions.cjs +9 -8
  42. package/dist/static-functions.d.cts +2 -2
  43. package/dist/static-functions.d.ts +2 -2
  44. package/dist/static-functions.js +2 -2
  45. package/dist/types/Cell.d.cts +2 -2
  46. package/dist/types/Cell.d.ts +2 -2
  47. package/dist/types/Column.d.cts +2 -2
  48. package/dist/types/Column.d.ts +2 -2
  49. package/dist/types/ColumnDef.d.cts +2 -2
  50. package/dist/types/ColumnDef.d.ts +2 -2
  51. package/dist/types/Row.d.cts +2 -2
  52. package/dist/types/Row.d.ts +2 -2
  53. package/dist/types/RowModelFns.d.cts +2 -2
  54. package/dist/types/RowModelFns.d.ts +2 -2
  55. package/dist/types/TableFeatures.d.cts +2 -2
  56. package/dist/types/TableFeatures.d.ts +2 -2
  57. package/dist/types/TableOptions.d.cts +3 -3
  58. package/dist/types/TableOptions.d.ts +3 -3
  59. package/dist/worker/initTableWorker.cjs.map +1 -1
  60. package/dist/worker/initTableWorker.js.map +1 -1
  61. package/package.json +1 -1
  62. package/skills/aggregation/SKILL.md +6 -6
  63. package/skills/api-not-found/SKILL.md +1 -1
  64. package/skills/client-vs-server/SKILL.md +1 -1
  65. package/skills/column-faceting/SKILL.md +1 -1
  66. package/skills/column-filtering/SKILL.md +1 -1
  67. package/skills/column-ordering/SKILL.md +1 -1
  68. package/skills/column-pinning/SKILL.md +1 -1
  69. package/skills/column-resizing/SKILL.md +1 -1
  70. package/skills/column-sizing/SKILL.md +1 -1
  71. package/skills/column-visibility/SKILL.md +1 -1
  72. package/skills/core/SKILL.md +1 -1
  73. package/skills/custom-features/SKILL.md +1 -1
  74. package/skills/expanding/SKILL.md +1 -1
  75. package/skills/global-filtering/SKILL.md +1 -1
  76. package/skills/grouping/SKILL.md +1 -1
  77. package/skills/migrate-v8-to-v9/SKILL.md +8 -8
  78. package/skills/pagination/SKILL.md +1 -1
  79. package/skills/row-pinning/SKILL.md +1 -1
  80. package/skills/row-selection/SKILL.md +1 -1
  81. package/skills/sorting/SKILL.md +1 -1
  82. package/skills/table-features/SKILL.md +5 -5
  83. package/skills/typescript/SKILL.md +1 -1
  84. package/src/features/column-grouping/createGroupedRowModel.ts +49 -12
  85. package/src/features/{aggregation → row-aggregation}/aggregationFns.ts +81 -43
  86. package/src/features/{aggregation/aggregationFeature.ts → row-aggregation/rowAggregationFeature.ts} +5 -9
  87. package/src/features/{aggregation/aggregationFeature.types.ts → row-aggregation/rowAggregationFeature.types.ts} +6 -6
  88. package/src/features/{aggregation/aggregationFeature.utils.ts → row-aggregation/rowAggregationFeature.utils.ts} +61 -4
  89. package/src/features/stockFeatures.ts +3 -3
  90. package/src/index.ts +4 -4
  91. package/src/static-functions.ts +1 -1
  92. package/src/types/Cell.ts +2 -2
  93. package/src/types/Column.ts +2 -2
  94. package/src/types/ColumnDef.ts +2 -2
  95. package/src/types/Row.ts +2 -2
  96. package/src/types/RowModelFns.ts +2 -2
  97. package/src/types/TableFeatures.ts +2 -2
  98. package/src/types/TableOptions.ts +3 -3
  99. package/src/worker/initTableWorker.ts +1 -1
  100. package/dist/features/aggregation/aggregationFeature.cjs +0 -39
  101. package/dist/features/aggregation/aggregationFeature.cjs.map +0 -1
  102. package/dist/features/aggregation/aggregationFeature.d.cts +0 -10
  103. package/dist/features/aggregation/aggregationFeature.d.ts +0 -10
  104. package/dist/features/aggregation/aggregationFeature.js.map +0 -1
  105. package/dist/features/aggregation/aggregationFeature.types.cjs.map +0 -1
  106. package/dist/features/aggregation/aggregationFeature.types.js.map +0 -1
  107. package/dist/features/aggregation/aggregationFeature.utils.cjs.map +0 -1
  108. package/dist/features/aggregation/aggregationFeature.utils.js.map +0 -1
  109. package/dist/features/aggregation/aggregationFns.cjs.map +0 -1
  110. package/dist/features/aggregation/aggregationFns.js.map +0 -1
@@ -2,8 +2,7 @@ const require_utils = require('../../utils.cjs');
2
2
  const require_coreColumnsFeature_utils = require('../../core/columns/coreColumnsFeature.utils.cjs');
3
3
  const require_constructRow = require('../../core/rows/constructRow.cjs');
4
4
  const require_rowPaginationFeature_utils = require('../row-pagination/rowPaginationFeature.utils.cjs');
5
- const require_aggregationFeature_utils = require('../aggregation/aggregationFeature.utils.cjs');
6
- const require_columnGroupingFeature_utils = require('./columnGroupingFeature.utils.cjs');
5
+ const require_rowAggregationFeature_utils = require('../row-aggregation/rowAggregationFeature.utils.cjs');
7
6
  const require_rowExpandingFeature_utils = require('../row-expanding/rowExpandingFeature.utils.cjs');
8
7
 
9
8
  //#region src/features/column-grouping/createGroupedRowModel.ts
@@ -12,7 +11,7 @@ const require_rowExpandingFeature_utils = require('../row-expanding/rowExpanding
12
11
  *
13
12
  * The factory reads the relevant table state atoms and options, then returns a row model function used by the table row-model pipeline.
14
13
  *
15
- * When aggregationFeature is also registered, grouped rows use its shared
14
+ * When rowAggregationFeature is also registered, grouped rows use its shared
16
15
  * executor for non-group values. Grouping remains useful without aggregation.
17
16
  */
18
17
  function createGroupedRowModel() {
@@ -62,7 +61,7 @@ function _createGroupedRowModel(table) {
62
61
  return row;
63
62
  });
64
63
  const columnId = existingGrouping[depth];
65
- const rowGroupsMap = groupBy(rows, columnId);
64
+ const rowGroupsMap = groupBy(table, rows, columnId);
66
65
  return Array.from(rowGroupsMap.entries()).map(([groupingValue, groupedRows], index) => {
67
66
  let id = `${columnId}:${groupingValue}`;
68
67
  id = parentId ? `${parentId}>${id}` : id;
@@ -70,7 +69,7 @@ function _createGroupedRowModel(table) {
70
69
  subRows.forEach((subRow) => {
71
70
  subRow.parentId = id;
72
71
  });
73
- const leafRows = require_aggregationFeature_utils.normalizeAggregationRows(groupedRows, Infinity);
72
+ const leafRows = require_rowAggregationFeature_utils.normalizeUniqueAggregationRows(groupedRows, Infinity);
74
73
  const row = require_constructRow.constructRow(table, id, leafRows[0].original, index, depth, void 0, parentId);
75
74
  Object.assign(row, {
76
75
  groupingColumnId: columnId,
@@ -89,11 +88,12 @@ function _createGroupedRowModel(table) {
89
88
  const column = table.getColumn(colId);
90
89
  if (typeof column.getAggregationFns !== "function") return void 0;
91
90
  const cache = row._aggregationValuesCache ??= require_utils.makeObjectMap();
92
- cache[colId] = require_aggregationFeature_utils.aggregateColumnValue({
91
+ cache[colId] = require_rowAggregationFeature_utils.aggregateColumnValue({
93
92
  subRows,
94
93
  column,
95
94
  groupingRow: row,
96
- rows: groupedRows
95
+ rows: groupedRows,
96
+ uniqueRows: true
97
97
  });
98
98
  return cache[colId];
99
99
  }
@@ -116,15 +116,23 @@ function _createGroupedRowModel(table) {
116
116
  rowsById: groupedRowsById
117
117
  };
118
118
  }
119
- function groupBy(rows, columnId) {
119
+ function groupBy(table, rows, columnId) {
120
120
  const groupMap = /* @__PURE__ */ new Map();
121
- return rows.reduce((map, row) => {
122
- const resKey = `${require_columnGroupingFeature_utils.row_getGroupingValue(row, columnId)}`;
123
- const previous = map.get(resKey);
124
- if (!previous) map.set(resKey, [row]);
121
+ const getGroupingValue = require_coreColumnsFeature_utils.table_getColumn(table, columnId)?.columnDef.getGroupingValue;
122
+ for (let i = 0; i < rows.length; i++) {
123
+ const row = rows[i];
124
+ let groupingValue;
125
+ if (getGroupingValue) {
126
+ const cache = row._groupingValuesCache;
127
+ if (cache && require_utils.hasOwn(cache, columnId)) groupingValue = cache[columnId];
128
+ else if (cache) groupingValue = cache[columnId] = getGroupingValue(row.original, row.index, row);
129
+ } else groupingValue = row.getValue(columnId);
130
+ const resKey = `${groupingValue}`;
131
+ const previous = groupMap.get(resKey);
132
+ if (!previous) groupMap.set(resKey, [row]);
125
133
  else previous.push(row);
126
- return map;
127
- }, groupMap);
134
+ }
135
+ return groupMap;
128
136
  }
129
137
 
130
138
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"createGroupedRowModel.cjs","names":["tableMemo","table_getColumn","makeObjectMap","normalizeAggregationRows","constructRow","hasOwn","aggregateColumnValue","row_getGroupingValue"],"sources":["../../../src/features/column-grouping/createGroupedRowModel.ts"],"sourcesContent":["import { hasOwn, makeObjectMap, tableMemo } from '../../utils'\nimport { constructRow } from '../../core/rows/constructRow'\nimport { table_getColumn } from '../../core/columns/coreColumnsFeature.utils'\nimport { table_autoResetExpanded } from '../row-expanding/rowExpandingFeature.utils'\nimport { table_autoResetPageIndex } from '../row-pagination/rowPaginationFeature.utils'\nimport {\n aggregateColumnValue,\n normalizeAggregationRows,\n} from '../aggregation/aggregationFeature.utils'\nimport { row_getGroupingValue } from './columnGroupingFeature.utils'\nimport type { Row_ColumnGrouping } from './columnGroupingFeature.types'\nimport type { TableFeatures } from '../../types/TableFeatures'\nimport type { RowModel } from '../../core/row-models/coreRowModelsFeature.types'\nimport type { Table, Table_Internal } from '../../types/Table'\nimport type { Row } from '../../types/Row'\nimport type { RowData } from '../../types/type-utils'\n\n/**\n * Creates a memoized grouped row model factory.\n *\n * The factory reads the relevant table state atoms and options, then returns a row model function used by the table row-model pipeline.\n *\n * When aggregationFeature is also registered, grouped rows use its shared\n * executor for non-group values. Grouping remains useful without aggregation.\n */\nexport function createGroupedRowModel<\n TFeatures extends TableFeatures,\n TData extends RowData = any,\n>(): (table: Table<TFeatures, TData>) => () => RowModel<TFeatures, TData> {\n return (_table) => {\n const table = _table as unknown as Table_Internal<TFeatures, TData>\n return tableMemo({\n feature: 'columnGroupingFeature',\n table,\n fnName: 'table.getGroupedRowModel',\n memoDeps: () => [\n table.atoms.grouping?.get(),\n table.getPreGroupedRowModel(),\n table.options.columns,\n ],\n fn: () => _createGroupedRowModel(table),\n onAfterUpdate: () => {\n table_autoResetExpanded(table)\n table_autoResetPageIndex(table)\n },\n })\n }\n}\n\nfunction _createGroupedRowModel<\n TFeatures extends TableFeatures,\n TData extends RowData = any,\n>(table: Table_Internal<TFeatures, TData>): RowModel<TFeatures, TData> {\n const rowModel = table.getPreGroupedRowModel()\n const grouping = table.atoms.grouping?.get()\n\n if (!rowModel.rows.length || !grouping?.length) {\n rowModel.rows.forEach((row) => {\n row.depth = 0\n row.parentId = undefined\n })\n return rowModel\n }\n\n // Filter the grouping list down to columns that exist\n const existingGrouping = grouping.filter((columnId) =>\n table_getColumn(table, columnId),\n )\n\n const groupedFlatRows: Array<Row<TFeatures, TData>> &\n Partial<Row_ColumnGrouping> = []\n const groupedRowsById = makeObjectMap<Row<TFeatures, TData>>()\n\n // Recursively group the data\n const groupUpRecursively = (\n rows: Array<Row<TFeatures, TData>>,\n depth = 0,\n parentId?: string,\n ) => {\n // Grouping depth has been been met\n // Stop grouping and simply rewrite thd depth and row relationships\n if (depth >= existingGrouping.length) {\n return rows.map((row) => {\n row.depth = depth\n\n // Every row is pushed into flatRows/rowsById exactly once, by its\n // parent frame: rows returned here are pushed by the caller (the\n // parent group's loop or the root loop), so only descendants below\n // the terminal depth are pushed here.\n if (row.subRows.length) {\n row.subRows = groupUpRecursively(row.subRows, depth + 1, row.id)\n for (let i = 0; i < row.subRows.length; i++) {\n const subRow = row.subRows[i]!\n groupedFlatRows.push(subRow)\n groupedRowsById[subRow.id] = subRow\n }\n }\n\n return row\n })\n }\n\n const columnId = existingGrouping[depth] as string\n\n // Group the rows together for this level\n const rowGroupsMap = groupBy(rows, columnId)\n\n // Perform aggregations for each group\n const aggregatedGroupedRows = Array.from(rowGroupsMap.entries()).map(\n ([groupingValue, groupedRows], index) => {\n let id = `${columnId}:${groupingValue}`\n id = parentId ? `${parentId}>${id}` : id\n\n // First, Recurse to group sub rows before aggregation\n const subRows = groupUpRecursively(groupedRows, depth + 1, id)\n\n subRows.forEach((subRow) => {\n subRow.parentId = id\n })\n\n const leafRows = normalizeAggregationRows(groupedRows, Infinity)\n\n const row = constructRow(\n table,\n id,\n leafRows[0]!.original,\n index,\n depth,\n undefined,\n parentId,\n ) as Row<TFeatures, TData> & Partial<Row_ColumnGrouping>\n\n Object.assign(row, {\n groupingColumnId: columnId,\n groupingValue,\n subRows,\n leafRows,\n getValue: (colId: string) => {\n const groupingIndex = existingGrouping.indexOf(colId)\n\n // The active grouping column and ancestor grouping columns expose\n // their inherited grouping values. Columns grouped at deeper\n // levels are still eligible for aggregation here.\n if (groupingIndex !== -1 && groupingIndex <= depth) {\n if (hasOwn(row._valuesCache, colId)) {\n return row._valuesCache[colId]\n }\n\n if (groupedRows[0]) {\n row._valuesCache[colId] =\n groupedRows[0].getValue(colId) ?? undefined\n }\n\n return row._valuesCache[colId]\n }\n\n const aggregationCache = (row as any)._aggregationValuesCache as\n | Record<string, unknown>\n | undefined\n if (aggregationCache && hasOwn(aggregationCache, colId)) {\n return aggregationCache[colId]\n }\n\n const column = table.getColumn(colId) as any\n if (typeof column.getAggregationFns !== 'function') return undefined\n\n const cache = ((row as any)._aggregationValuesCache ??=\n makeObjectMap())\n cache[colId] = aggregateColumnValue({\n subRows,\n column,\n groupingRow: row,\n rows: groupedRows,\n })\n return cache[colId]\n },\n })\n\n subRows.forEach((subRow) => {\n groupedFlatRows.push(subRow)\n groupedRowsById[subRow.id] = subRow\n })\n\n return row\n },\n )\n\n return aggregatedGroupedRows\n }\n\n const groupedRows = groupUpRecursively(rowModel.rows, 0)\n\n groupedRows.forEach((subRow) => {\n groupedFlatRows.push(subRow)\n groupedRowsById[subRow.id] = subRow\n })\n\n return {\n rows: groupedRows,\n flatRows: groupedFlatRows,\n rowsById: groupedRowsById,\n }\n}\n\nfunction groupBy<TFeatures extends TableFeatures, TData extends RowData = any>(\n rows: Array<Row<TFeatures, TData>>,\n columnId: string,\n) {\n const groupMap = new Map<any, Array<Row<TFeatures, TData>>>()\n\n return rows.reduce((map, row) => {\n const resKey = `${row_getGroupingValue(row, columnId)}`\n const previous = map.get(resKey)\n if (!previous) {\n map.set(resKey, [row])\n } else {\n previous.push(row)\n }\n return map\n }, groupMap)\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"createGroupedRowModel.cjs","names":["tableMemo","table_getColumn","makeObjectMap","normalizeUniqueAggregationRows","constructRow","hasOwn","aggregateColumnValue"],"sources":["../../../src/features/column-grouping/createGroupedRowModel.ts"],"sourcesContent":["import { hasOwn, makeObjectMap, tableMemo } from '../../utils'\nimport { constructRow } from '../../core/rows/constructRow'\nimport { table_getColumn } from '../../core/columns/coreColumnsFeature.utils'\nimport { table_autoResetExpanded } from '../row-expanding/rowExpandingFeature.utils'\nimport { table_autoResetPageIndex } from '../row-pagination/rowPaginationFeature.utils'\nimport {\n aggregateColumnValue,\n normalizeUniqueAggregationRows,\n} from '../row-aggregation/rowAggregationFeature.utils'\nimport type { Row_ColumnGrouping } from './columnGroupingFeature.types'\nimport type { Column_Internal } from '../../types/Column'\nimport type { TableFeatures } from '../../types/TableFeatures'\nimport type { RowModel } from '../../core/row-models/coreRowModelsFeature.types'\nimport type { Table, Table_Internal } from '../../types/Table'\nimport type { Row } from '../../types/Row'\nimport type { RowData } from '../../types/type-utils'\n\n/**\n * Creates a memoized grouped row model factory.\n *\n * The factory reads the relevant table state atoms and options, then returns a row model function used by the table row-model pipeline.\n *\n * When rowAggregationFeature is also registered, grouped rows use its shared\n * executor for non-group values. Grouping remains useful without aggregation.\n */\nexport function createGroupedRowModel<\n TFeatures extends TableFeatures,\n TData extends RowData = any,\n>(): (table: Table<TFeatures, TData>) => () => RowModel<TFeatures, TData> {\n return (_table) => {\n const table = _table as unknown as Table_Internal<TFeatures, TData>\n return tableMemo({\n feature: 'columnGroupingFeature',\n table,\n fnName: 'table.getGroupedRowModel',\n memoDeps: () => [\n table.atoms.grouping?.get(),\n table.getPreGroupedRowModel(),\n table.options.columns,\n ],\n fn: () => _createGroupedRowModel(table),\n onAfterUpdate: () => {\n table_autoResetExpanded(table)\n table_autoResetPageIndex(table)\n },\n })\n }\n}\n\nfunction _createGroupedRowModel<\n TFeatures extends TableFeatures,\n TData extends RowData = any,\n>(table: Table_Internal<TFeatures, TData>): RowModel<TFeatures, TData> {\n const rowModel = table.getPreGroupedRowModel()\n const grouping = table.atoms.grouping?.get()\n\n if (!rowModel.rows.length || !grouping?.length) {\n rowModel.rows.forEach((row) => {\n row.depth = 0\n row.parentId = undefined\n })\n return rowModel\n }\n\n // Filter the grouping list down to columns that exist\n const existingGrouping = grouping.filter((columnId) =>\n table_getColumn(table, columnId),\n )\n\n const groupedFlatRows: Array<Row<TFeatures, TData>> &\n Partial<Row_ColumnGrouping> = []\n const groupedRowsById = makeObjectMap<Row<TFeatures, TData>>()\n\n // Recursively group the data\n const groupUpRecursively = (\n rows: Array<Row<TFeatures, TData>>,\n depth = 0,\n parentId?: string,\n ) => {\n // Grouping depth has been been met\n // Stop grouping and simply rewrite thd depth and row relationships\n if (depth >= existingGrouping.length) {\n return rows.map((row) => {\n row.depth = depth\n\n // Every row is pushed into flatRows/rowsById exactly once, by its\n // parent frame: rows returned here are pushed by the caller (the\n // parent group's loop or the root loop), so only descendants below\n // the terminal depth are pushed here.\n if (row.subRows.length) {\n row.subRows = groupUpRecursively(row.subRows, depth + 1, row.id)\n for (let i = 0; i < row.subRows.length; i++) {\n const subRow = row.subRows[i]!\n groupedFlatRows.push(subRow)\n groupedRowsById[subRow.id] = subRow\n }\n }\n\n return row\n })\n }\n\n const columnId = existingGrouping[depth] as string\n\n // Group the rows together for this level\n const rowGroupsMap = groupBy(table, rows, columnId)\n\n // Perform aggregations for each group\n const aggregatedGroupedRows = Array.from(rowGroupsMap.entries()).map(\n ([groupingValue, groupedRows], index) => {\n let id = `${columnId}:${groupingValue}`\n id = parentId ? `${parentId}>${id}` : id\n\n // First, Recurse to group sub rows before aggregation\n const subRows = groupUpRecursively(groupedRows, depth + 1, id)\n\n subRows.forEach((subRow) => {\n subRow.parentId = id\n })\n\n // Rows produced by groupBy are disjoint members of the pre-grouped\n // row tree, so the duplicate-id guard is unnecessary; flat groups\n // reuse the partition array as-is.\n const leafRows = normalizeUniqueAggregationRows(\n groupedRows,\n Infinity,\n ) as Array<Row<TFeatures, TData>>\n\n const row = constructRow(\n table,\n id,\n leafRows[0]!.original,\n index,\n depth,\n undefined,\n parentId,\n ) as Row<TFeatures, TData> & Partial<Row_ColumnGrouping>\n\n Object.assign(row, {\n groupingColumnId: columnId,\n groupingValue,\n subRows,\n leafRows,\n getValue: (colId: string) => {\n const groupingIndex = existingGrouping.indexOf(colId)\n\n // The active grouping column and ancestor grouping columns expose\n // their inherited grouping values. Columns grouped at deeper\n // levels are still eligible for aggregation here.\n if (groupingIndex !== -1 && groupingIndex <= depth) {\n if (hasOwn(row._valuesCache, colId)) {\n return row._valuesCache[colId]\n }\n\n if (groupedRows[0]) {\n row._valuesCache[colId] =\n groupedRows[0].getValue(colId) ?? undefined\n }\n\n return row._valuesCache[colId]\n }\n\n const aggregationCache = (row as any)._aggregationValuesCache as\n | Record<string, unknown>\n | undefined\n if (aggregationCache && hasOwn(aggregationCache, colId)) {\n return aggregationCache[colId]\n }\n\n const column = table.getColumn(colId) as any\n if (typeof column.getAggregationFns !== 'function') return undefined\n\n const cache = ((row as any)._aggregationValuesCache ??=\n makeObjectMap())\n cache[colId] = aggregateColumnValue({\n subRows,\n column,\n groupingRow: row,\n rows: groupedRows,\n uniqueRows: true,\n })\n return cache[colId]\n },\n })\n\n subRows.forEach((subRow) => {\n groupedFlatRows.push(subRow)\n groupedRowsById[subRow.id] = subRow\n })\n\n return row\n },\n )\n\n return aggregatedGroupedRows\n }\n\n const groupedRows = groupUpRecursively(rowModel.rows, 0)\n\n groupedRows.forEach((subRow) => {\n groupedFlatRows.push(subRow)\n groupedRowsById[subRow.id] = subRow\n })\n\n return {\n rows: groupedRows,\n flatRows: groupedFlatRows,\n rowsById: groupedRowsById,\n }\n}\n\nfunction groupBy<TFeatures extends TableFeatures, TData extends RowData = any>(\n table: Table_Internal<TFeatures, TData>,\n rows: Array<Row<TFeatures, TData>>,\n columnId: string,\n) {\n const groupMap = new Map<any, Array<Row<TFeatures, TData>>>()\n\n // Resolve the column once instead of per row: `table.getColumn` goes\n // through the memoized-API dispatcher, which is far too expensive to sit\n // inside this per-row loop. The branches below mirror\n // `row_getGroupingValue`'s caching contract exactly.\n const column = table_getColumn(table, columnId) as\n | Column_Internal<TFeatures, TData, unknown>\n | undefined\n const getGroupingValue = column?.columnDef.getGroupingValue\n\n for (let i = 0; i < rows.length; i++) {\n const row = rows[i]!\n let groupingValue\n if (getGroupingValue) {\n const cache = (row as any)._groupingValuesCache as\n | Record<string, unknown>\n | undefined\n if (cache && hasOwn(cache, columnId)) {\n groupingValue = cache[columnId]\n } else if (cache) {\n groupingValue = cache[columnId] = getGroupingValue(\n row.original,\n row.index,\n row,\n )\n }\n } else {\n groupingValue = row.getValue(columnId)\n }\n\n const resKey = `${groupingValue}`\n const previous = groupMap.get(resKey)\n if (!previous) {\n groupMap.set(resKey, [row])\n } else {\n previous.push(row)\n }\n }\n\n return groupMap\n}\n"],"mappings":"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"}
@@ -9,7 +9,7 @@ import { TableFeatures } from "../../types/TableFeatures.cjs";
9
9
  *
10
10
  * The factory reads the relevant table state atoms and options, then returns a row model function used by the table row-model pipeline.
11
11
  *
12
- * When aggregationFeature is also registered, grouped rows use its shared
12
+ * When rowAggregationFeature is also registered, grouped rows use its shared
13
13
  * executor for non-group values. Grouping remains useful without aggregation.
14
14
  */
15
15
  declare function createGroupedRowModel<TFeatures extends TableFeatures, TData extends RowData = any>(): (table: Table<TFeatures, TData>) => () => RowModel<TFeatures, TData>;
@@ -9,7 +9,7 @@ import { TableFeatures } from "../../types/TableFeatures.js";
9
9
  *
10
10
  * The factory reads the relevant table state atoms and options, then returns a row model function used by the table row-model pipeline.
11
11
  *
12
- * When aggregationFeature is also registered, grouped rows use its shared
12
+ * When rowAggregationFeature is also registered, grouped rows use its shared
13
13
  * executor for non-group values. Grouping remains useful without aggregation.
14
14
  */
15
15
  declare function createGroupedRowModel<TFeatures extends TableFeatures, TData extends RowData = any>(): (table: Table<TFeatures, TData>) => () => RowModel<TFeatures, TData>;
@@ -2,8 +2,7 @@ import { hasOwn, makeObjectMap, tableMemo } from "../../utils.js";
2
2
  import { table_getColumn } from "../../core/columns/coreColumnsFeature.utils.js";
3
3
  import { constructRow } from "../../core/rows/constructRow.js";
4
4
  import { table_autoResetPageIndex } from "../row-pagination/rowPaginationFeature.utils.js";
5
- import { aggregateColumnValue, normalizeAggregationRows } from "../aggregation/aggregationFeature.utils.js";
6
- import { row_getGroupingValue } from "./columnGroupingFeature.utils.js";
5
+ import { aggregateColumnValue, normalizeUniqueAggregationRows } from "../row-aggregation/rowAggregationFeature.utils.js";
7
6
  import { table_autoResetExpanded } from "../row-expanding/rowExpandingFeature.utils.js";
8
7
 
9
8
  //#region src/features/column-grouping/createGroupedRowModel.ts
@@ -12,7 +11,7 @@ import { table_autoResetExpanded } from "../row-expanding/rowExpandingFeature.ut
12
11
  *
13
12
  * The factory reads the relevant table state atoms and options, then returns a row model function used by the table row-model pipeline.
14
13
  *
15
- * When aggregationFeature is also registered, grouped rows use its shared
14
+ * When rowAggregationFeature is also registered, grouped rows use its shared
16
15
  * executor for non-group values. Grouping remains useful without aggregation.
17
16
  */
18
17
  function createGroupedRowModel() {
@@ -62,7 +61,7 @@ function _createGroupedRowModel(table) {
62
61
  return row;
63
62
  });
64
63
  const columnId = existingGrouping[depth];
65
- const rowGroupsMap = groupBy(rows, columnId);
64
+ const rowGroupsMap = groupBy(table, rows, columnId);
66
65
  return Array.from(rowGroupsMap.entries()).map(([groupingValue, groupedRows], index) => {
67
66
  let id = `${columnId}:${groupingValue}`;
68
67
  id = parentId ? `${parentId}>${id}` : id;
@@ -70,7 +69,7 @@ function _createGroupedRowModel(table) {
70
69
  subRows.forEach((subRow) => {
71
70
  subRow.parentId = id;
72
71
  });
73
- const leafRows = normalizeAggregationRows(groupedRows, Infinity);
72
+ const leafRows = normalizeUniqueAggregationRows(groupedRows, Infinity);
74
73
  const row = constructRow(table, id, leafRows[0].original, index, depth, void 0, parentId);
75
74
  Object.assign(row, {
76
75
  groupingColumnId: columnId,
@@ -93,7 +92,8 @@ function _createGroupedRowModel(table) {
93
92
  subRows,
94
93
  column,
95
94
  groupingRow: row,
96
- rows: groupedRows
95
+ rows: groupedRows,
96
+ uniqueRows: true
97
97
  });
98
98
  return cache[colId];
99
99
  }
@@ -116,15 +116,23 @@ function _createGroupedRowModel(table) {
116
116
  rowsById: groupedRowsById
117
117
  };
118
118
  }
119
- function groupBy(rows, columnId) {
119
+ function groupBy(table, rows, columnId) {
120
120
  const groupMap = /* @__PURE__ */ new Map();
121
- return rows.reduce((map, row) => {
122
- const resKey = `${row_getGroupingValue(row, columnId)}`;
123
- const previous = map.get(resKey);
124
- if (!previous) map.set(resKey, [row]);
121
+ const getGroupingValue = table_getColumn(table, columnId)?.columnDef.getGroupingValue;
122
+ for (let i = 0; i < rows.length; i++) {
123
+ const row = rows[i];
124
+ let groupingValue;
125
+ if (getGroupingValue) {
126
+ const cache = row._groupingValuesCache;
127
+ if (cache && hasOwn(cache, columnId)) groupingValue = cache[columnId];
128
+ else if (cache) groupingValue = cache[columnId] = getGroupingValue(row.original, row.index, row);
129
+ } else groupingValue = row.getValue(columnId);
130
+ const resKey = `${groupingValue}`;
131
+ const previous = groupMap.get(resKey);
132
+ if (!previous) groupMap.set(resKey, [row]);
125
133
  else previous.push(row);
126
- return map;
127
- }, groupMap);
134
+ }
135
+ return groupMap;
128
136
  }
129
137
 
130
138
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"createGroupedRowModel.js","names":[],"sources":["../../../src/features/column-grouping/createGroupedRowModel.ts"],"sourcesContent":["import { hasOwn, makeObjectMap, tableMemo } from '../../utils'\nimport { constructRow } from '../../core/rows/constructRow'\nimport { table_getColumn } from '../../core/columns/coreColumnsFeature.utils'\nimport { table_autoResetExpanded } from '../row-expanding/rowExpandingFeature.utils'\nimport { table_autoResetPageIndex } from '../row-pagination/rowPaginationFeature.utils'\nimport {\n aggregateColumnValue,\n normalizeAggregationRows,\n} from '../aggregation/aggregationFeature.utils'\nimport { row_getGroupingValue } from './columnGroupingFeature.utils'\nimport type { Row_ColumnGrouping } from './columnGroupingFeature.types'\nimport type { TableFeatures } from '../../types/TableFeatures'\nimport type { RowModel } from '../../core/row-models/coreRowModelsFeature.types'\nimport type { Table, Table_Internal } from '../../types/Table'\nimport type { Row } from '../../types/Row'\nimport type { RowData } from '../../types/type-utils'\n\n/**\n * Creates a memoized grouped row model factory.\n *\n * The factory reads the relevant table state atoms and options, then returns a row model function used by the table row-model pipeline.\n *\n * When aggregationFeature is also registered, grouped rows use its shared\n * executor for non-group values. Grouping remains useful without aggregation.\n */\nexport function createGroupedRowModel<\n TFeatures extends TableFeatures,\n TData extends RowData = any,\n>(): (table: Table<TFeatures, TData>) => () => RowModel<TFeatures, TData> {\n return (_table) => {\n const table = _table as unknown as Table_Internal<TFeatures, TData>\n return tableMemo({\n feature: 'columnGroupingFeature',\n table,\n fnName: 'table.getGroupedRowModel',\n memoDeps: () => [\n table.atoms.grouping?.get(),\n table.getPreGroupedRowModel(),\n table.options.columns,\n ],\n fn: () => _createGroupedRowModel(table),\n onAfterUpdate: () => {\n table_autoResetExpanded(table)\n table_autoResetPageIndex(table)\n },\n })\n }\n}\n\nfunction _createGroupedRowModel<\n TFeatures extends TableFeatures,\n TData extends RowData = any,\n>(table: Table_Internal<TFeatures, TData>): RowModel<TFeatures, TData> {\n const rowModel = table.getPreGroupedRowModel()\n const grouping = table.atoms.grouping?.get()\n\n if (!rowModel.rows.length || !grouping?.length) {\n rowModel.rows.forEach((row) => {\n row.depth = 0\n row.parentId = undefined\n })\n return rowModel\n }\n\n // Filter the grouping list down to columns that exist\n const existingGrouping = grouping.filter((columnId) =>\n table_getColumn(table, columnId),\n )\n\n const groupedFlatRows: Array<Row<TFeatures, TData>> &\n Partial<Row_ColumnGrouping> = []\n const groupedRowsById = makeObjectMap<Row<TFeatures, TData>>()\n\n // Recursively group the data\n const groupUpRecursively = (\n rows: Array<Row<TFeatures, TData>>,\n depth = 0,\n parentId?: string,\n ) => {\n // Grouping depth has been been met\n // Stop grouping and simply rewrite thd depth and row relationships\n if (depth >= existingGrouping.length) {\n return rows.map((row) => {\n row.depth = depth\n\n // Every row is pushed into flatRows/rowsById exactly once, by its\n // parent frame: rows returned here are pushed by the caller (the\n // parent group's loop or the root loop), so only descendants below\n // the terminal depth are pushed here.\n if (row.subRows.length) {\n row.subRows = groupUpRecursively(row.subRows, depth + 1, row.id)\n for (let i = 0; i < row.subRows.length; i++) {\n const subRow = row.subRows[i]!\n groupedFlatRows.push(subRow)\n groupedRowsById[subRow.id] = subRow\n }\n }\n\n return row\n })\n }\n\n const columnId = existingGrouping[depth] as string\n\n // Group the rows together for this level\n const rowGroupsMap = groupBy(rows, columnId)\n\n // Perform aggregations for each group\n const aggregatedGroupedRows = Array.from(rowGroupsMap.entries()).map(\n ([groupingValue, groupedRows], index) => {\n let id = `${columnId}:${groupingValue}`\n id = parentId ? `${parentId}>${id}` : id\n\n // First, Recurse to group sub rows before aggregation\n const subRows = groupUpRecursively(groupedRows, depth + 1, id)\n\n subRows.forEach((subRow) => {\n subRow.parentId = id\n })\n\n const leafRows = normalizeAggregationRows(groupedRows, Infinity)\n\n const row = constructRow(\n table,\n id,\n leafRows[0]!.original,\n index,\n depth,\n undefined,\n parentId,\n ) as Row<TFeatures, TData> & Partial<Row_ColumnGrouping>\n\n Object.assign(row, {\n groupingColumnId: columnId,\n groupingValue,\n subRows,\n leafRows,\n getValue: (colId: string) => {\n const groupingIndex = existingGrouping.indexOf(colId)\n\n // The active grouping column and ancestor grouping columns expose\n // their inherited grouping values. Columns grouped at deeper\n // levels are still eligible for aggregation here.\n if (groupingIndex !== -1 && groupingIndex <= depth) {\n if (hasOwn(row._valuesCache, colId)) {\n return row._valuesCache[colId]\n }\n\n if (groupedRows[0]) {\n row._valuesCache[colId] =\n groupedRows[0].getValue(colId) ?? undefined\n }\n\n return row._valuesCache[colId]\n }\n\n const aggregationCache = (row as any)._aggregationValuesCache as\n | Record<string, unknown>\n | undefined\n if (aggregationCache && hasOwn(aggregationCache, colId)) {\n return aggregationCache[colId]\n }\n\n const column = table.getColumn(colId) as any\n if (typeof column.getAggregationFns !== 'function') return undefined\n\n const cache = ((row as any)._aggregationValuesCache ??=\n makeObjectMap())\n cache[colId] = aggregateColumnValue({\n subRows,\n column,\n groupingRow: row,\n rows: groupedRows,\n })\n return cache[colId]\n },\n })\n\n subRows.forEach((subRow) => {\n groupedFlatRows.push(subRow)\n groupedRowsById[subRow.id] = subRow\n })\n\n return row\n },\n )\n\n return aggregatedGroupedRows\n }\n\n const groupedRows = groupUpRecursively(rowModel.rows, 0)\n\n groupedRows.forEach((subRow) => {\n groupedFlatRows.push(subRow)\n groupedRowsById[subRow.id] = subRow\n })\n\n return {\n rows: groupedRows,\n flatRows: groupedFlatRows,\n rowsById: groupedRowsById,\n }\n}\n\nfunction groupBy<TFeatures extends TableFeatures, TData extends RowData = any>(\n rows: Array<Row<TFeatures, TData>>,\n columnId: string,\n) {\n const groupMap = new Map<any, Array<Row<TFeatures, TData>>>()\n\n return rows.reduce((map, row) => {\n const resKey = `${row_getGroupingValue(row, columnId)}`\n const previous = map.get(resKey)\n if (!previous) {\n map.set(resKey, [row])\n } else {\n previous.push(row)\n }\n return map\n }, groupMap)\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"createGroupedRowModel.js","names":[],"sources":["../../../src/features/column-grouping/createGroupedRowModel.ts"],"sourcesContent":["import { hasOwn, makeObjectMap, tableMemo } from '../../utils'\nimport { constructRow } from '../../core/rows/constructRow'\nimport { table_getColumn } from '../../core/columns/coreColumnsFeature.utils'\nimport { table_autoResetExpanded } from '../row-expanding/rowExpandingFeature.utils'\nimport { table_autoResetPageIndex } from '../row-pagination/rowPaginationFeature.utils'\nimport {\n aggregateColumnValue,\n normalizeUniqueAggregationRows,\n} from '../row-aggregation/rowAggregationFeature.utils'\nimport type { Row_ColumnGrouping } from './columnGroupingFeature.types'\nimport type { Column_Internal } from '../../types/Column'\nimport type { TableFeatures } from '../../types/TableFeatures'\nimport type { RowModel } from '../../core/row-models/coreRowModelsFeature.types'\nimport type { Table, Table_Internal } from '../../types/Table'\nimport type { Row } from '../../types/Row'\nimport type { RowData } from '../../types/type-utils'\n\n/**\n * Creates a memoized grouped row model factory.\n *\n * The factory reads the relevant table state atoms and options, then returns a row model function used by the table row-model pipeline.\n *\n * When rowAggregationFeature is also registered, grouped rows use its shared\n * executor for non-group values. Grouping remains useful without aggregation.\n */\nexport function createGroupedRowModel<\n TFeatures extends TableFeatures,\n TData extends RowData = any,\n>(): (table: Table<TFeatures, TData>) => () => RowModel<TFeatures, TData> {\n return (_table) => {\n const table = _table as unknown as Table_Internal<TFeatures, TData>\n return tableMemo({\n feature: 'columnGroupingFeature',\n table,\n fnName: 'table.getGroupedRowModel',\n memoDeps: () => [\n table.atoms.grouping?.get(),\n table.getPreGroupedRowModel(),\n table.options.columns,\n ],\n fn: () => _createGroupedRowModel(table),\n onAfterUpdate: () => {\n table_autoResetExpanded(table)\n table_autoResetPageIndex(table)\n },\n })\n }\n}\n\nfunction _createGroupedRowModel<\n TFeatures extends TableFeatures,\n TData extends RowData = any,\n>(table: Table_Internal<TFeatures, TData>): RowModel<TFeatures, TData> {\n const rowModel = table.getPreGroupedRowModel()\n const grouping = table.atoms.grouping?.get()\n\n if (!rowModel.rows.length || !grouping?.length) {\n rowModel.rows.forEach((row) => {\n row.depth = 0\n row.parentId = undefined\n })\n return rowModel\n }\n\n // Filter the grouping list down to columns that exist\n const existingGrouping = grouping.filter((columnId) =>\n table_getColumn(table, columnId),\n )\n\n const groupedFlatRows: Array<Row<TFeatures, TData>> &\n Partial<Row_ColumnGrouping> = []\n const groupedRowsById = makeObjectMap<Row<TFeatures, TData>>()\n\n // Recursively group the data\n const groupUpRecursively = (\n rows: Array<Row<TFeatures, TData>>,\n depth = 0,\n parentId?: string,\n ) => {\n // Grouping depth has been been met\n // Stop grouping and simply rewrite thd depth and row relationships\n if (depth >= existingGrouping.length) {\n return rows.map((row) => {\n row.depth = depth\n\n // Every row is pushed into flatRows/rowsById exactly once, by its\n // parent frame: rows returned here are pushed by the caller (the\n // parent group's loop or the root loop), so only descendants below\n // the terminal depth are pushed here.\n if (row.subRows.length) {\n row.subRows = groupUpRecursively(row.subRows, depth + 1, row.id)\n for (let i = 0; i < row.subRows.length; i++) {\n const subRow = row.subRows[i]!\n groupedFlatRows.push(subRow)\n groupedRowsById[subRow.id] = subRow\n }\n }\n\n return row\n })\n }\n\n const columnId = existingGrouping[depth] as string\n\n // Group the rows together for this level\n const rowGroupsMap = groupBy(table, rows, columnId)\n\n // Perform aggregations for each group\n const aggregatedGroupedRows = Array.from(rowGroupsMap.entries()).map(\n ([groupingValue, groupedRows], index) => {\n let id = `${columnId}:${groupingValue}`\n id = parentId ? `${parentId}>${id}` : id\n\n // First, Recurse to group sub rows before aggregation\n const subRows = groupUpRecursively(groupedRows, depth + 1, id)\n\n subRows.forEach((subRow) => {\n subRow.parentId = id\n })\n\n // Rows produced by groupBy are disjoint members of the pre-grouped\n // row tree, so the duplicate-id guard is unnecessary; flat groups\n // reuse the partition array as-is.\n const leafRows = normalizeUniqueAggregationRows(\n groupedRows,\n Infinity,\n ) as Array<Row<TFeatures, TData>>\n\n const row = constructRow(\n table,\n id,\n leafRows[0]!.original,\n index,\n depth,\n undefined,\n parentId,\n ) as Row<TFeatures, TData> & Partial<Row_ColumnGrouping>\n\n Object.assign(row, {\n groupingColumnId: columnId,\n groupingValue,\n subRows,\n leafRows,\n getValue: (colId: string) => {\n const groupingIndex = existingGrouping.indexOf(colId)\n\n // The active grouping column and ancestor grouping columns expose\n // their inherited grouping values. Columns grouped at deeper\n // levels are still eligible for aggregation here.\n if (groupingIndex !== -1 && groupingIndex <= depth) {\n if (hasOwn(row._valuesCache, colId)) {\n return row._valuesCache[colId]\n }\n\n if (groupedRows[0]) {\n row._valuesCache[colId] =\n groupedRows[0].getValue(colId) ?? undefined\n }\n\n return row._valuesCache[colId]\n }\n\n const aggregationCache = (row as any)._aggregationValuesCache as\n | Record<string, unknown>\n | undefined\n if (aggregationCache && hasOwn(aggregationCache, colId)) {\n return aggregationCache[colId]\n }\n\n const column = table.getColumn(colId) as any\n if (typeof column.getAggregationFns !== 'function') return undefined\n\n const cache = ((row as any)._aggregationValuesCache ??=\n makeObjectMap())\n cache[colId] = aggregateColumnValue({\n subRows,\n column,\n groupingRow: row,\n rows: groupedRows,\n uniqueRows: true,\n })\n return cache[colId]\n },\n })\n\n subRows.forEach((subRow) => {\n groupedFlatRows.push(subRow)\n groupedRowsById[subRow.id] = subRow\n })\n\n return row\n },\n )\n\n return aggregatedGroupedRows\n }\n\n const groupedRows = groupUpRecursively(rowModel.rows, 0)\n\n groupedRows.forEach((subRow) => {\n groupedFlatRows.push(subRow)\n groupedRowsById[subRow.id] = subRow\n })\n\n return {\n rows: groupedRows,\n flatRows: groupedFlatRows,\n rowsById: groupedRowsById,\n }\n}\n\nfunction groupBy<TFeatures extends TableFeatures, TData extends RowData = any>(\n table: Table_Internal<TFeatures, TData>,\n rows: Array<Row<TFeatures, TData>>,\n columnId: string,\n) {\n const groupMap = new Map<any, Array<Row<TFeatures, TData>>>()\n\n // Resolve the column once instead of per row: `table.getColumn` goes\n // through the memoized-API dispatcher, which is far too expensive to sit\n // inside this per-row loop. The branches below mirror\n // `row_getGroupingValue`'s caching contract exactly.\n const column = table_getColumn(table, columnId) as\n | Column_Internal<TFeatures, TData, unknown>\n | undefined\n const getGroupingValue = column?.columnDef.getGroupingValue\n\n for (let i = 0; i < rows.length; i++) {\n const row = rows[i]!\n let groupingValue\n if (getGroupingValue) {\n const cache = (row as any)._groupingValuesCache as\n | Record<string, unknown>\n | undefined\n if (cache && hasOwn(cache, columnId)) {\n groupingValue = cache[columnId]\n } else if (cache) {\n groupingValue = cache[columnId] = getGroupingValue(\n row.original,\n row.index,\n row,\n )\n }\n } else {\n groupingValue = row.getValue(columnId)\n }\n\n const resKey = `${groupingValue}`\n const previous = groupMap.get(resKey)\n if (!previous) {\n groupMap.set(resKey, [row])\n } else {\n previous.push(row)\n }\n }\n\n return groupMap\n}\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
- const require_aggregationFeature_types = require('./aggregationFeature.types.cjs');
1
+ const require_rowAggregationFeature_types = require('./rowAggregationFeature.types.cjs');
2
2
 
3
- //#region src/features/aggregation/aggregationFns.ts
3
+ //#region src/features/row-aggregation/aggregationFns.ts
4
4
  function isNumber(value) {
5
5
  return typeof value === "number";
6
6
  }
@@ -14,27 +14,20 @@ function getRangeKind(value) {
14
14
  function compareRangeValues(left, right) {
15
15
  return (left instanceof Date ? left.getTime() : left) - (right instanceof Date ? right.getTime() : right);
16
16
  }
17
- function collectRangeValues(context) {
18
- const values = [];
19
- let kind;
20
- for (let i = 0; i < context.rows.length; i++) {
21
- const value = context.getValue(context.rows[i]);
22
- const valueKind = getRangeKind(value);
23
- if (!valueKind) continue;
24
- kind ??= valueKind;
25
- if (valueKind === kind) values.push(value);
26
- }
27
- return values;
17
+ /** Comparable representation of a range value; `Date`s compare by time. */
18
+ function toRangeNumber(value) {
19
+ return value instanceof Date ? value.getTime() : value;
28
20
  }
29
21
  /**
30
22
  * Sums numeric selected-row values. Non-number values contribute zero. As in
31
23
  * the previous API, `NaN` is a number and therefore propagates through the sum.
32
24
  */
33
- const aggregationFn_sum = require_aggregationFeature_types.constructAggregationFn({
25
+ const aggregationFn_sum = require_rowAggregationFeature_types.constructAggregationFn({
34
26
  aggregate: (context) => {
27
+ const rows = context.rows;
35
28
  let sum = 0;
36
- for (let i = 0; i < context.rows.length; i++) {
37
- const value = context.getValue(context.rows[i]);
29
+ for (let i = 0; i < rows.length; i++) {
30
+ const value = context.getValue(rows[i]);
38
31
  sum += typeof value === "number" ? value : 0;
39
32
  }
40
33
  return sum;
@@ -52,11 +45,26 @@ const aggregationFn_sum = require_aggregationFeature_types.constructAggregationF
52
45
  * Finds the minimum numeric or Date value from the selected rows. Invalid value
53
46
  * types are ignored; `NaN` preserves the legacy numeric seeding behavior.
54
47
  */
55
- const aggregationFn_min = require_aggregationFeature_types.constructAggregationFn({
48
+ const aggregationFn_min = require_rowAggregationFeature_types.constructAggregationFn({
56
49
  aggregate: (context) => {
57
- const values = collectRangeValues(context);
58
- let result = values[0];
59
- for (let i = 1; i < values.length; i++) if (compareRangeValues(values[i], result) < 0) result = values[i];
50
+ const rows = context.rows;
51
+ let kind;
52
+ let result;
53
+ let resultNumber = 0;
54
+ for (let i = 0; i < rows.length; i++) {
55
+ const value = context.getValue(rows[i]);
56
+ const valueKind = getRangeKind(value);
57
+ if (!valueKind || kind !== void 0 && valueKind !== kind) continue;
58
+ const valueNumber = toRangeNumber(value);
59
+ if (kind === void 0) {
60
+ kind = valueKind;
61
+ result = value;
62
+ resultNumber = valueNumber;
63
+ } else if (valueNumber - resultNumber < 0) {
64
+ result = value;
65
+ resultNumber = valueNumber;
66
+ }
67
+ }
60
68
  return result;
61
69
  },
62
70
  merge: ({ subRowResults }) => {
@@ -78,11 +86,26 @@ const aggregationFn_min = require_aggregationFeature_types.constructAggregationF
78
86
  * Finds the maximum numeric or Date value from the selected rows. Invalid value
79
87
  * types are ignored; `NaN` preserves the legacy numeric seeding behavior.
80
88
  */
81
- const aggregationFn_max = require_aggregationFeature_types.constructAggregationFn({
89
+ const aggregationFn_max = require_rowAggregationFeature_types.constructAggregationFn({
82
90
  aggregate: (context) => {
83
- const values = collectRangeValues(context);
84
- let result = values[0];
85
- for (let i = 1; i < values.length; i++) if (compareRangeValues(values[i], result) > 0) result = values[i];
91
+ const rows = context.rows;
92
+ let kind;
93
+ let result;
94
+ let resultNumber = 0;
95
+ for (let i = 0; i < rows.length; i++) {
96
+ const value = context.getValue(rows[i]);
97
+ const valueKind = getRangeKind(value);
98
+ if (!valueKind || kind !== void 0 && valueKind !== kind) continue;
99
+ const valueNumber = toRangeNumber(value);
100
+ if (kind === void 0) {
101
+ kind = valueKind;
102
+ result = value;
103
+ resultNumber = valueNumber;
104
+ } else if (valueNumber - resultNumber > 0) {
105
+ result = value;
106
+ resultNumber = valueNumber;
107
+ }
108
+ }
86
109
  return result;
87
110
  },
88
111
  merge: ({ subRowResults }) => {
@@ -105,17 +128,35 @@ const aggregationFn_max = require_aggregationFeature_types.constructAggregationF
105
128
  * Empty inputs return
106
129
  * `[undefined, undefined]`, preserving the previous built-in result shape.
107
130
  */
108
- const aggregationFn_extent = require_aggregationFeature_types.constructAggregationFn({
131
+ const aggregationFn_extent = require_rowAggregationFeature_types.constructAggregationFn({
109
132
  aggregate: (context) => {
110
- const values = collectRangeValues(context);
111
- if (!values.length) return [void 0, void 0];
112
- let min = values[0];
113
- let max = values[0];
114
- for (let i = 1; i < values.length; i++) {
115
- const value = values[i];
116
- if (compareRangeValues(value, min) < 0) min = value;
117
- if (compareRangeValues(value, max) > 0) max = value;
133
+ const rows = context.rows;
134
+ let kind;
135
+ let min;
136
+ let max;
137
+ let minNumber = 0;
138
+ let maxNumber = 0;
139
+ for (let i = 0; i < rows.length; i++) {
140
+ const value = context.getValue(rows[i]);
141
+ const valueKind = getRangeKind(value);
142
+ if (!valueKind || kind !== void 0 && valueKind !== kind) continue;
143
+ const valueNumber = toRangeNumber(value);
144
+ if (kind === void 0) {
145
+ kind = valueKind;
146
+ min = max = value;
147
+ minNumber = maxNumber = valueNumber;
148
+ } else {
149
+ if (valueNumber - minNumber < 0) {
150
+ min = value;
151
+ minNumber = valueNumber;
152
+ }
153
+ if (valueNumber - maxNumber > 0) {
154
+ max = value;
155
+ maxNumber = valueNumber;
156
+ }
157
+ }
118
158
  }
159
+ if (kind === void 0) return [void 0, void 0];
119
160
  return [min, max];
120
161
  },
121
162
  merge: ({ subRowResults }) => {
@@ -143,11 +184,12 @@ const aggregationFn_extent = require_aggregationFeature_types.constructAggregati
143
184
  * Averages number and number-like row values. Nullish and non-numeric values
144
185
  * are ignored; other values retain the legacy unary-plus coercion behavior.
145
186
  */
146
- const aggregationFn_mean = require_aggregationFeature_types.constructAggregationFn({ aggregate: (context) => {
187
+ const aggregationFn_mean = require_rowAggregationFeature_types.constructAggregationFn({ aggregate: (context) => {
188
+ const rows = context.rows;
147
189
  let count = 0;
148
190
  let sum = 0;
149
- for (let i = 0; i < context.rows.length; i++) {
150
- const value = context.getValue(context.rows[i]);
191
+ for (let i = 0; i < rows.length; i++) {
192
+ const value = context.getValue(rows[i]);
151
193
  if (value == null) continue;
152
194
  const numberValue = typeof value === "number" ? value : +value;
153
195
  if (!Number.isNaN(numberValue)) {
@@ -161,11 +203,12 @@ const aggregationFn_mean = require_aggregationFeature_types.constructAggregation
161
203
  * Computes the median when every row value is a number. Returns `undefined`
162
204
  * for empty inputs or when any value is non-numeric.
163
205
  */
164
- const aggregationFn_median = require_aggregationFeature_types.constructAggregationFn({ aggregate: (context) => {
165
- if (!context.rows.length) return void 0;
166
- const values = new Array(context.rows.length);
167
- for (let i = 0; i < context.rows.length; i++) {
168
- const value = context.getValue(context.rows[i]);
206
+ const aggregationFn_median = require_rowAggregationFeature_types.constructAggregationFn({ aggregate: (context) => {
207
+ const rows = context.rows;
208
+ if (!rows.length) return void 0;
209
+ const values = new Array(rows.length);
210
+ for (let i = 0; i < rows.length; i++) {
211
+ const value = context.getValue(rows[i]);
169
212
  if (typeof value !== "number") return void 0;
170
213
  values[i] = value;
171
214
  }
@@ -174,19 +217,21 @@ const aggregationFn_median = require_aggregationFeature_types.constructAggregati
174
217
  return values.length % 2 ? values[mid] : (values[mid - 1] + values[mid]) / 2;
175
218
  } });
176
219
  /** Collects distinct row values using JavaScript `Set` semantics. */
177
- const aggregationFn_unique = require_aggregationFeature_types.constructAggregationFn({ aggregate: (context) => {
220
+ const aggregationFn_unique = require_rowAggregationFeature_types.constructAggregationFn({ aggregate: (context) => {
221
+ const rows = context.rows;
178
222
  const values = /* @__PURE__ */ new Set();
179
- for (let i = 0; i < context.rows.length; i++) values.add(context.getValue(context.rows[i]));
223
+ for (let i = 0; i < rows.length; i++) values.add(context.getValue(rows[i]));
180
224
  return Array.from(values);
181
225
  } });
182
226
  /** Counts distinct row values using JavaScript `Set` semantics. */
183
- const aggregationFn_uniqueCount = require_aggregationFeature_types.constructAggregationFn({ aggregate: (context) => {
227
+ const aggregationFn_uniqueCount = require_rowAggregationFeature_types.constructAggregationFn({ aggregate: (context) => {
228
+ const rows = context.rows;
184
229
  const values = /* @__PURE__ */ new Set();
185
- for (let i = 0; i < context.rows.length; i++) values.add(context.getValue(context.rows[i]));
230
+ for (let i = 0; i < rows.length; i++) values.add(context.getValue(rows[i]));
186
231
  return values.size;
187
232
  } });
188
233
  /** Counts rows, independently of the column's values. */
189
- const aggregationFn_count = require_aggregationFeature_types.constructAggregationFn({
234
+ const aggregationFn_count = require_rowAggregationFeature_types.constructAggregationFn({
190
235
  aggregate: ({ rows }) => rows.length,
191
236
  merge: ({ subRowResults }) => {
192
237
  let count = 0;
@@ -198,12 +243,12 @@ const aggregationFn_count = require_aggregationFeature_types.constructAggregatio
198
243
  }
199
244
  });
200
245
  /** Returns the first row's value, including a nullish value. */
201
- const aggregationFn_first = require_aggregationFeature_types.constructAggregationFn({
246
+ const aggregationFn_first = require_rowAggregationFeature_types.constructAggregationFn({
202
247
  aggregate: (context) => context.rows[0] ? context.getValue(context.rows[0]) : void 0,
203
248
  merge: ({ subRowResults }) => subRowResults[0]
204
249
  });
205
250
  /** Returns the last row's value, including a nullish value. */
206
- const aggregationFn_last = require_aggregationFeature_types.constructAggregationFn({
251
+ const aggregationFn_last = require_rowAggregationFeature_types.constructAggregationFn({
207
252
  aggregate: (context) => {
208
253
  const row = context.rows[context.rows.length - 1];
209
254
  return row ? context.getValue(row) : void 0;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aggregationFns.cjs","names":["constructAggregationFn"],"sources":["../../../src/features/row-aggregation/aggregationFns.ts"],"sourcesContent":["import { constructAggregationFn } from './rowAggregationFeature.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\n/** Comparable representation of a range value; `Date`s compare by time. */\nfunction toRangeNumber(value: RangeValue): number {\n return value instanceof Date ? value.getTime() : value\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 const rows = context.rows\n let sum = 0\n for (let i = 0; i < rows.length; i++) {\n const value = context.getValue(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 rows = context.rows\n let kind: 'date' | 'number' | undefined\n let result: RangeValue | undefined\n let resultNumber = 0\n for (let i = 0; i < rows.length; i++) {\n const value = context.getValue(rows[i]!)\n const valueKind = getRangeKind(value)\n if (!valueKind || (kind !== undefined && valueKind !== kind)) continue\n const valueNumber = toRangeNumber(value as RangeValue)\n if (kind === undefined) {\n kind = valueKind\n result = value as RangeValue\n resultNumber = valueNumber\n } else if (valueNumber - resultNumber < 0) {\n result = value as RangeValue\n resultNumber = valueNumber\n }\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 rows = context.rows\n let kind: 'date' | 'number' | undefined\n let result: RangeValue | undefined\n let resultNumber = 0\n for (let i = 0; i < rows.length; i++) {\n const value = context.getValue(rows[i]!)\n const valueKind = getRangeKind(value)\n if (!valueKind || (kind !== undefined && valueKind !== kind)) continue\n const valueNumber = toRangeNumber(value as RangeValue)\n if (kind === undefined) {\n kind = valueKind\n result = value as RangeValue\n resultNumber = valueNumber\n } else if (valueNumber - resultNumber > 0) {\n result = value as RangeValue\n resultNumber = valueNumber\n }\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 rows = context.rows\n let kind: 'date' | 'number' | undefined\n let min: RangeValue | undefined\n let max: RangeValue | undefined\n let minNumber = 0\n let maxNumber = 0\n for (let i = 0; i < rows.length; i++) {\n const value = context.getValue(rows[i]!)\n const valueKind = getRangeKind(value)\n if (!valueKind || (kind !== undefined && valueKind !== kind)) continue\n const valueNumber = toRangeNumber(value as RangeValue)\n if (kind === undefined) {\n kind = valueKind\n min = max = value as RangeValue\n minNumber = maxNumber = valueNumber\n } else {\n if (valueNumber - minNumber < 0) {\n min = value as RangeValue\n minNumber = valueNumber\n }\n if (valueNumber - maxNumber > 0) {\n max = value as RangeValue\n maxNumber = valueNumber\n }\n }\n }\n if (kind === undefined) return [undefined, undefined]\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 const rows = context.rows\n let count = 0\n let sum = 0\n for (let i = 0; i < rows.length; i++) {\n const value = context.getValue(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 const rows = context.rows\n if (!rows.length) return undefined\n const values = new Array<number>(rows.length)\n for (let i = 0; i < rows.length; i++) {\n const value = context.getValue(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 rows = context.rows\n const values = new Set<unknown>()\n for (let i = 0; i < rows.length; i++) {\n values.add(context.getValue(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 rows = context.rows\n const values = new Set<unknown>()\n for (let i = 0; i < rows.length; i++) {\n values.add(context.getValue(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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"}
@@ -1,6 +1,6 @@
1
- import { AggregationFnDef } from "./aggregationFeature.types.cjs";
1
+ import { AggregationFnDef } from "./rowAggregationFeature.types.cjs";
2
2
 
3
- //#region src/features/aggregation/aggregationFns.d.ts
3
+ //#region src/features/row-aggregation/aggregationFns.d.ts
4
4
  type RangeValue = Date | number;
5
5
  /**
6
6
  * Sums numeric selected-row values. Non-number values contribute zero. As in
@@ -1,6 +1,6 @@
1
- import { AggregationFnDef } from "./aggregationFeature.types.js";
1
+ import { AggregationFnDef } from "./rowAggregationFeature.types.js";
2
2
 
3
- //#region src/features/aggregation/aggregationFns.d.ts
3
+ //#region src/features/row-aggregation/aggregationFns.d.ts
4
4
  type RangeValue = Date | number;
5
5
  /**
6
6
  * Sums numeric selected-row values. Non-number values contribute zero. As in