@tanstack/table-core 9.0.0-beta.47 → 9.0.0-beta.48

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 (171) hide show
  1. package/dist/core/row-models/coreRowModelsFeature.types.d.cts +1 -1
  2. package/dist/core/row-models/coreRowModelsFeature.types.d.ts +1 -1
  3. package/dist/core/row-models/coreRowModelsFeature.utils.cjs +1 -1
  4. package/dist/core/row-models/coreRowModelsFeature.utils.cjs.map +1 -1
  5. package/dist/core/row-models/coreRowModelsFeature.utils.d.cts +1 -1
  6. package/dist/core/row-models/coreRowModelsFeature.utils.d.ts +1 -1
  7. package/dist/core/row-models/coreRowModelsFeature.utils.js +1 -1
  8. package/dist/core/row-models/coreRowModelsFeature.utils.js.map +1 -1
  9. package/dist/features/aggregation/aggregationFeature.cjs +38 -0
  10. package/dist/features/aggregation/aggregationFeature.cjs.map +1 -0
  11. package/dist/features/aggregation/aggregationFeature.d.cts +10 -0
  12. package/dist/features/aggregation/aggregationFeature.d.ts +10 -0
  13. package/dist/features/aggregation/aggregationFeature.js +38 -0
  14. package/dist/features/aggregation/aggregationFeature.js.map +1 -0
  15. package/dist/features/aggregation/aggregationFeature.types.cjs +13 -0
  16. package/dist/features/aggregation/aggregationFeature.types.cjs.map +1 -0
  17. package/dist/features/aggregation/aggregationFeature.types.d.cts +172 -0
  18. package/dist/features/aggregation/aggregationFeature.types.d.ts +172 -0
  19. package/dist/features/aggregation/aggregationFeature.types.js +12 -0
  20. package/dist/features/aggregation/aggregationFeature.types.js.map +1 -0
  21. package/dist/features/aggregation/aggregationFeature.utils.cjs +198 -0
  22. package/dist/features/aggregation/aggregationFeature.utils.cjs.map +1 -0
  23. package/dist/features/aggregation/aggregationFeature.utils.d.cts +33 -0
  24. package/dist/features/aggregation/aggregationFeature.utils.d.ts +33 -0
  25. package/dist/features/aggregation/aggregationFeature.utils.js +192 -0
  26. package/dist/features/aggregation/aggregationFeature.utils.js.map +1 -0
  27. package/dist/features/aggregation/aggregationFns.cjs +240 -0
  28. package/dist/features/aggregation/aggregationFns.cjs.map +1 -0
  29. package/dist/features/aggregation/aggregationFns.d.cts +67 -0
  30. package/dist/features/aggregation/aggregationFns.d.ts +67 -0
  31. package/dist/features/aggregation/aggregationFns.js +229 -0
  32. package/dist/features/aggregation/aggregationFns.js.map +1 -0
  33. package/dist/features/column-filtering/columnFilteringFeature.types.d.cts +1 -1
  34. package/dist/features/column-filtering/columnFilteringFeature.types.d.ts +1 -1
  35. package/dist/{fns → features/column-filtering}/filterFns.cjs +1 -1
  36. package/dist/features/column-filtering/filterFns.cjs.map +1 -0
  37. package/dist/{fns → features/column-filtering}/filterFns.d.cts +4 -4
  38. package/dist/{fns → features/column-filtering}/filterFns.d.ts +4 -4
  39. package/dist/{fns → features/column-filtering}/filterFns.js +1 -1
  40. package/dist/features/column-filtering/filterFns.js.map +1 -0
  41. package/dist/features/column-grouping/columnGroupingFeature.cjs +3 -12
  42. package/dist/features/column-grouping/columnGroupingFeature.cjs.map +1 -1
  43. package/dist/features/column-grouping/columnGroupingFeature.d.cts +1 -1
  44. package/dist/features/column-grouping/columnGroupingFeature.d.ts +1 -1
  45. package/dist/features/column-grouping/columnGroupingFeature.js +4 -13
  46. package/dist/features/column-grouping/columnGroupingFeature.js.map +1 -1
  47. package/dist/features/column-grouping/columnGroupingFeature.types.d.cts +6 -87
  48. package/dist/features/column-grouping/columnGroupingFeature.types.d.ts +6 -87
  49. package/dist/features/column-grouping/columnGroupingFeature.utils.cjs +0 -64
  50. package/dist/features/column-grouping/columnGroupingFeature.utils.cjs.map +1 -1
  51. package/dist/features/column-grouping/columnGroupingFeature.utils.d.cts +2 -44
  52. package/dist/features/column-grouping/columnGroupingFeature.utils.d.ts +2 -44
  53. package/dist/features/column-grouping/columnGroupingFeature.utils.js +2 -63
  54. package/dist/features/column-grouping/columnGroupingFeature.utils.js.map +1 -1
  55. package/dist/features/column-grouping/createGroupedRowModel.cjs +23 -16
  56. package/dist/features/column-grouping/createGroupedRowModel.cjs.map +1 -1
  57. package/dist/features/column-grouping/createGroupedRowModel.d.cts +2 -6
  58. package/dist/features/column-grouping/createGroupedRowModel.d.ts +2 -6
  59. package/dist/features/column-grouping/createGroupedRowModel.js +25 -18
  60. package/dist/features/column-grouping/createGroupedRowModel.js.map +1 -1
  61. package/dist/features/global-filtering/globalFilteringFeature.utils.cjs +1 -1
  62. package/dist/features/global-filtering/globalFilteringFeature.utils.cjs.map +1 -1
  63. package/dist/features/global-filtering/globalFilteringFeature.utils.js +1 -1
  64. package/dist/features/global-filtering/globalFilteringFeature.utils.js.map +1 -1
  65. package/dist/features/row-sorting/rowSortingFeature.types.d.cts +1 -1
  66. package/dist/features/row-sorting/rowSortingFeature.types.d.ts +1 -1
  67. package/dist/features/row-sorting/rowSortingFeature.utils.cjs +1 -1
  68. package/dist/features/row-sorting/rowSortingFeature.utils.cjs.map +1 -1
  69. package/dist/features/row-sorting/rowSortingFeature.utils.js +1 -1
  70. package/dist/features/row-sorting/rowSortingFeature.utils.js.map +1 -1
  71. package/dist/{fns → features/row-sorting}/sortFns.cjs +1 -1
  72. package/dist/{fns/sortFns.js.map → features/row-sorting/sortFns.cjs.map} +1 -1
  73. package/dist/{fns → features/row-sorting}/sortFns.d.cts +4 -4
  74. package/dist/{fns → features/row-sorting}/sortFns.d.ts +4 -4
  75. package/dist/{fns → features/row-sorting}/sortFns.js +1 -1
  76. package/dist/features/row-sorting/sortFns.js.map +1 -0
  77. package/dist/features/stockFeatures.cjs +2 -0
  78. package/dist/features/stockFeatures.cjs.map +1 -1
  79. package/dist/features/stockFeatures.d.cts +2 -0
  80. package/dist/features/stockFeatures.d.ts +2 -0
  81. package/dist/features/stockFeatures.js +2 -0
  82. package/dist/features/stockFeatures.js.map +1 -1
  83. package/dist/index.cjs +7 -4
  84. package/dist/index.d.cts +7 -5
  85. package/dist/index.d.ts +7 -5
  86. package/dist/index.js +6 -4
  87. package/dist/static-functions.cjs +8 -3
  88. package/dist/static-functions.d.cts +3 -2
  89. package/dist/static-functions.d.ts +3 -2
  90. package/dist/static-functions.js +3 -2
  91. package/dist/types/Cell.d.cts +3 -1
  92. package/dist/types/Cell.d.ts +3 -1
  93. package/dist/types/Column.d.cts +4 -2
  94. package/dist/types/Column.d.ts +4 -2
  95. package/dist/types/ColumnDef.d.cts +5 -3
  96. package/dist/types/ColumnDef.d.ts +5 -3
  97. package/dist/types/Row.d.cts +3 -1
  98. package/dist/types/Row.d.ts +3 -1
  99. package/dist/types/RowModel.d.cts +1 -1
  100. package/dist/types/RowModel.d.ts +1 -1
  101. package/dist/types/RowModelFns.d.cts +3 -3
  102. package/dist/types/RowModelFns.d.ts +3 -3
  103. package/dist/types/Table.d.cts +1 -1
  104. package/dist/types/Table.d.ts +1 -1
  105. package/dist/types/TableFeatures.d.cts +4 -4
  106. package/dist/types/TableFeatures.d.ts +4 -4
  107. package/dist/types/TableOptions.d.cts +5 -3
  108. package/dist/types/TableOptions.d.ts +5 -3
  109. package/dist/types/TableState.d.cts +1 -1
  110. package/dist/types/TableState.d.ts +1 -1
  111. package/dist/worker/initTableWorker.cjs.map +1 -1
  112. package/dist/worker/initTableWorker.js.map +1 -1
  113. package/package.json +1 -1
  114. package/skills/aggregation/SKILL.md +131 -0
  115. package/skills/api-not-found/SKILL.md +1 -1
  116. package/skills/client-vs-server/SKILL.md +1 -1
  117. package/skills/column-faceting/SKILL.md +1 -1
  118. package/skills/column-filtering/SKILL.md +1 -1
  119. package/skills/column-ordering/SKILL.md +1 -1
  120. package/skills/column-pinning/SKILL.md +1 -1
  121. package/skills/column-resizing/SKILL.md +1 -1
  122. package/skills/column-sizing/SKILL.md +1 -1
  123. package/skills/column-visibility/SKILL.md +1 -1
  124. package/skills/core/SKILL.md +1 -1
  125. package/skills/custom-features/SKILL.md +1 -1
  126. package/skills/expanding/SKILL.md +1 -1
  127. package/skills/global-filtering/SKILL.md +1 -1
  128. package/skills/grouping/SKILL.md +12 -18
  129. package/skills/migrate-v8-to-v9/SKILL.md +15 -2
  130. package/skills/pagination/SKILL.md +1 -1
  131. package/skills/row-pinning/SKILL.md +1 -1
  132. package/skills/row-selection/SKILL.md +1 -1
  133. package/skills/sorting/SKILL.md +1 -1
  134. package/skills/table-features/SKILL.md +5 -2
  135. package/skills/typescript/SKILL.md +1 -1
  136. package/src/core/row-models/coreRowModelsFeature.utils.ts +1 -1
  137. package/src/features/aggregation/aggregationFeature.ts +59 -0
  138. package/src/features/aggregation/aggregationFeature.types.ts +312 -0
  139. package/src/features/aggregation/aggregationFeature.utils.ts +401 -0
  140. package/src/features/aggregation/aggregationFns.ts +336 -0
  141. package/src/features/column-filtering/columnFilteringFeature.types.ts +1 -1
  142. package/src/{fns → features/column-filtering}/filterFns.ts +4 -4
  143. package/src/features/column-grouping/columnGroupingFeature.ts +1 -20
  144. package/src/features/column-grouping/columnGroupingFeature.types.ts +4 -141
  145. package/src/features/column-grouping/columnGroupingFeature.utils.ts +1 -122
  146. package/src/features/column-grouping/createGroupedRowModel.ts +32 -41
  147. package/src/features/global-filtering/globalFilteringFeature.utils.ts +1 -1
  148. package/src/features/row-sorting/rowSortingFeature.types.ts +1 -1
  149. package/src/features/row-sorting/rowSortingFeature.utils.ts +1 -1
  150. package/src/{fns → features/row-sorting}/sortFns.ts +4 -7
  151. package/src/features/stockFeatures.ts +3 -0
  152. package/src/index.ts +7 -8
  153. package/src/static-functions.ts +1 -0
  154. package/src/types/Cell.ts +2 -0
  155. package/src/types/Column.ts +3 -1
  156. package/src/types/ColumnDef.ts +6 -3
  157. package/src/types/Row.ts +2 -0
  158. package/src/types/RowModelFns.ts +3 -3
  159. package/src/types/TableFeatures.ts +4 -4
  160. package/src/types/TableOptions.ts +5 -1
  161. package/src/worker/initTableWorker.ts +1 -1
  162. package/dist/fns/aggregationFns.cjs +0 -234
  163. package/dist/fns/aggregationFns.cjs.map +0 -1
  164. package/dist/fns/aggregationFns.d.cts +0 -139
  165. package/dist/fns/aggregationFns.d.ts +0 -139
  166. package/dist/fns/aggregationFns.js +0 -221
  167. package/dist/fns/aggregationFns.js.map +0 -1
  168. package/dist/fns/filterFns.cjs.map +0 -1
  169. package/dist/fns/filterFns.js.map +0 -1
  170. package/dist/fns/sortFns.cjs.map +0 -1
  171. package/src/fns/aggregationFns.ts +0 -303
@@ -0,0 +1,401 @@
1
+ import { hasOwn, makeObjectMap } from '../../utils'
2
+ import type { Cell } from '../../types/Cell'
3
+ import type { Column, Column_Internal } from '../../types/Column'
4
+ import type { Row } from '../../types/Row'
5
+ import type { TableFeatures } from '../../types/TableFeatures'
6
+ import type { CellData, RowData } from '../../types/type-utils'
7
+ import type {
8
+ AggregationFnDef,
9
+ AggregationFnDescriptor,
10
+ AggregationFnRef,
11
+ ColumnAggregationValue,
12
+ ResolvedAggregationFn,
13
+ } from './aggregationFeature.types'
14
+
15
+ interface AggregationCacheEntry {
16
+ aggregationFnOption: unknown
17
+ dependency: unknown
18
+ registry: unknown
19
+ value: unknown
20
+ }
21
+
22
+ interface ResolvedAggregationFnsCacheEntry<
23
+ TFeatures extends TableFeatures,
24
+ TData extends RowData,
25
+ > {
26
+ coreRowModel: unknown
27
+ option: unknown
28
+ registry: unknown
29
+ value: ReadonlyArray<ResolvedAggregationFn<TFeatures, TData>>
30
+ }
31
+
32
+ function isAggregationFnDef(value: unknown): value is AggregationFnDef {
33
+ return !!value && typeof value === 'object' && 'aggregate' in value
34
+ }
35
+
36
+ function isAggregationFnDescriptor(
37
+ value: unknown,
38
+ ): value is AggregationFnDescriptor<any, any> {
39
+ return (
40
+ !!value &&
41
+ typeof value === 'object' &&
42
+ 'id' in value &&
43
+ 'aggregationFn' in value
44
+ )
45
+ }
46
+
47
+ function warn(message: string) {
48
+ if (process.env.NODE_ENV === 'development') {
49
+ console.warn(message)
50
+ }
51
+ }
52
+
53
+ /**
54
+ * Flattens hierarchical row inputs to unique terminal leaves in encounter
55
+ * order. This is the normalization used by public aggregation-value calls.
56
+ */
57
+ export function normalizeAggregationRows<
58
+ TFeatures extends TableFeatures,
59
+ TData extends RowData,
60
+ >(rows: ReadonlyArray<Row<TFeatures, TData>>): Array<Row<TFeatures, TData>> {
61
+ const result: Array<Row<TFeatures, TData>> = []
62
+ const seen = new Set<string>()
63
+
64
+ const visit = (row: Row<TFeatures, TData>) => {
65
+ if (row.subRows.length) {
66
+ for (let i = 0; i < row.subRows.length; i++) {
67
+ visit(row.subRows[i]!)
68
+ }
69
+ return
70
+ }
71
+
72
+ if (!seen.has(row.id)) {
73
+ seen.add(row.id)
74
+ result.push(row)
75
+ }
76
+ }
77
+
78
+ for (let i = 0; i < rows.length; i++) {
79
+ visit(rows[i]!)
80
+ }
81
+
82
+ return result
83
+ }
84
+
85
+ function getAutoAggregationFnName(
86
+ value: unknown,
87
+ ): 'extent' | 'sum' | undefined {
88
+ if (typeof value === 'number') {
89
+ return 'sum'
90
+ }
91
+
92
+ if (value instanceof Date && !Number.isNaN(value.getTime())) {
93
+ return 'extent'
94
+ }
95
+
96
+ return undefined
97
+ }
98
+
99
+ /** Resolves the `sum` or `extent` definition inferred from the first core row. */
100
+ export function column_getAutoAggregationFn<
101
+ TFeatures extends TableFeatures,
102
+ TData extends RowData,
103
+ TValue extends CellData = CellData,
104
+ >(column: Column_Internal<TFeatures, TData, TValue>) {
105
+ const value = column.table.getCoreRowModel().flatRows[0]?.getValue(column.id)
106
+
107
+ const name = getAutoAggregationFnName(value)
108
+ if (!name) return undefined
109
+
110
+ const aggregationFn = column.table._rowModelFns.aggregationFns?.[name]
111
+
112
+ if (!aggregationFn) {
113
+ warn(
114
+ `aggregationFn '${name}' (auto) for column '${column.id}' is not registered`,
115
+ )
116
+ }
117
+
118
+ return aggregationFn
119
+ }
120
+
121
+ function resolveAggregationFn<
122
+ TFeatures extends TableFeatures,
123
+ TData extends RowData,
124
+ >(
125
+ column: Column_Internal<TFeatures, TData, any>,
126
+ ref: AggregationFnRef<TFeatures, TData, any, any>,
127
+ ): AggregationFnDef<TFeatures, TData, any, any> | undefined {
128
+ if (isAggregationFnDef(ref)) return ref as any
129
+ if (ref === 'auto') return column_getAutoAggregationFn(column)
130
+
131
+ const aggregationFn =
132
+ column.table._rowModelFns.aggregationFns?.[ref as string]
133
+ if (!aggregationFn) {
134
+ warn(
135
+ `aggregationFn '${String(ref)}' for column '${column.id}' is not registered`,
136
+ )
137
+ }
138
+ return aggregationFn
139
+ }
140
+
141
+ /** Resolves and validates a column's scalar or multiple aggregation option. */
142
+ export function column_getAggregationFns<
143
+ TFeatures extends TableFeatures,
144
+ TData extends RowData,
145
+ TValue extends CellData = CellData,
146
+ >(
147
+ column: Column_Internal<TFeatures, TData, TValue>,
148
+ ): ReadonlyArray<ResolvedAggregationFn<TFeatures, TData>> {
149
+ const option = column.columnDef.aggregationFn
150
+ const registry = column.table._rowModelFns.aggregationFns
151
+ const coreRowModel = column.table.getCoreRowModel()
152
+ const previous = (column as any)._resolvedAggregationFnsCache as
153
+ | ResolvedAggregationFnsCacheEntry<TFeatures, TData>
154
+ | undefined
155
+
156
+ if (
157
+ previous &&
158
+ previous.option === option &&
159
+ previous.registry === registry &&
160
+ previous.coreRowModel === coreRowModel
161
+ ) {
162
+ return previous.value
163
+ }
164
+
165
+ const finish = (
166
+ value: ReadonlyArray<ResolvedAggregationFn<TFeatures, TData>>,
167
+ ) => {
168
+ ;(column as any)._resolvedAggregationFnsCache = {
169
+ coreRowModel,
170
+ option,
171
+ registry,
172
+ value,
173
+ } satisfies ResolvedAggregationFnsCacheEntry<TFeatures, TData>
174
+ return value
175
+ }
176
+
177
+ if (option == null) return finish([])
178
+
179
+ if (!Array.isArray(option)) {
180
+ return finish([
181
+ {
182
+ aggregationFn: resolveAggregationFn(column, option as any),
183
+ id: typeof option === 'string' ? option : undefined,
184
+ },
185
+ ])
186
+ }
187
+
188
+ const ids = makeObjectMap<number>()
189
+ for (let i = 0; i < option.length; i++) {
190
+ const item = option[i]
191
+ const id =
192
+ typeof item === 'string'
193
+ ? item
194
+ : isAggregationFnDescriptor(item)
195
+ ? item.id
196
+ : undefined
197
+ if (id !== undefined) ids[id] = (ids[id] ?? 0) + 1
198
+ }
199
+
200
+ const resolved: Array<ResolvedAggregationFn<TFeatures, TData>> = []
201
+
202
+ for (let i = 0; i < option.length; i++) {
203
+ const item = option[i]
204
+ const id =
205
+ typeof item === 'string'
206
+ ? item
207
+ : isAggregationFnDescriptor(item)
208
+ ? item.id
209
+ : undefined
210
+
211
+ if (id === undefined) {
212
+ warn(
213
+ `aggregationFn at index ${i} for column '${column.id}' needs a stable id`,
214
+ )
215
+ resolved.push({ aggregationFn: undefined, id: undefined })
216
+ continue
217
+ }
218
+
219
+ if (ids[id]! > 1) {
220
+ warn(`aggregationFn id '${id}' for column '${column.id}' is duplicated`)
221
+ resolved.push({ aggregationFn: undefined, id })
222
+ continue
223
+ }
224
+
225
+ const ref = isAggregationFnDescriptor(item) ? item.aggregationFn : item
226
+ resolved.push({
227
+ aggregationFn: resolveAggregationFn(column, ref),
228
+ id,
229
+ })
230
+ }
231
+
232
+ return finish(resolved)
233
+ }
234
+
235
+ function getChildResult(
236
+ childValue: unknown,
237
+ isMultiple: boolean,
238
+ id: string | undefined,
239
+ ) {
240
+ if (!isMultiple) return childValue
241
+ if (!id || !childValue || typeof childValue !== 'object') return undefined
242
+ return hasOwn(childValue, id)
243
+ ? (childValue as Record<string, unknown>)[id]
244
+ : undefined
245
+ }
246
+
247
+ /** Executes every configured aggregation for a column over normalized rows. */
248
+ export function aggregateColumnValue<
249
+ TFeatures extends TableFeatures,
250
+ TData extends RowData,
251
+ >(args: {
252
+ childRows?: ReadonlyArray<Row<TFeatures, TData>>
253
+ column: Column<TFeatures, TData, unknown>
254
+ groupingRow?: Row<TFeatures, TData>
255
+ rows: ReadonlyArray<Row<TFeatures, TData>>
256
+ }): unknown {
257
+ const { childRows, column, groupingRow, rows } = args
258
+ const internalColumn = column as Column_Internal<TFeatures, TData, unknown>
259
+ const entries = column_getAggregationFns(internalColumn)
260
+ const isMultiple = Array.isArray(internalColumn.columnDef.aggregationFn)
261
+ const canMerge =
262
+ !!childRows?.length &&
263
+ childRows.every(
264
+ (row) =>
265
+ !!(row as any).groupingColumnId &&
266
+ (row as any).groupingColumnId !== column.id,
267
+ )
268
+
269
+ const execute = (entry: ResolvedAggregationFn<TFeatures, TData>) => {
270
+ const definition = entry.aggregationFn
271
+ if (!definition) return undefined
272
+
273
+ const context = {
274
+ column,
275
+ columnId: column.id,
276
+ getValue: (row: Row<TFeatures, TData>) => row.getValue(column.id),
277
+ ...(groupingRow ? { groupingRow } : {}),
278
+ rows,
279
+ table: column.table as any,
280
+ }
281
+
282
+ if (canMerge && definition.merge) {
283
+ return definition.merge({
284
+ ...context,
285
+ childResults: childRows.map((row) =>
286
+ getChildResult(row.getValue(column.id), isMultiple, entry.id),
287
+ ),
288
+ childRows: childRows,
289
+ })
290
+ }
291
+
292
+ return definition.aggregate(context)
293
+ }
294
+
295
+ if (!isMultiple) {
296
+ return entries[0] ? execute(entries[0]) : undefined
297
+ }
298
+
299
+ const result = makeObjectMap<unknown>()
300
+ for (let i = 0; i < entries.length; i++) {
301
+ const entry = entries[i]!
302
+ if (entry.id !== undefined) {
303
+ result[entry.id] = execute(entry)
304
+ }
305
+ }
306
+ return result
307
+ }
308
+
309
+ /** Implements `column.getAggregationValue(rows?)` and its default-value cache. */
310
+ export function column_getAggregationValue<
311
+ TFeatures extends TableFeatures,
312
+ TData extends RowData,
313
+ TValue extends CellData = CellData,
314
+ >(
315
+ column: Column_Internal<TFeatures, TData, TValue>,
316
+ rows?: ReadonlyArray<Row<TFeatures, TData>>,
317
+ ): ColumnAggregationValue<TFeatures> {
318
+ const providedResult = column.columnDef.getAggregationValue?.({
319
+ column: column as any,
320
+ rows,
321
+ table: column.table as any,
322
+ })
323
+
324
+ if (providedResult) return providedResult.value as any
325
+ if (column.table.options.manualAggregation) return undefined
326
+
327
+ if (rows !== undefined) {
328
+ return aggregateColumnValue({
329
+ column: column as any,
330
+ rows: normalizeAggregationRows(rows),
331
+ }) as any
332
+ }
333
+
334
+ const model = column.table.getPreGroupedRowModel()
335
+ const previous = (column as any)._aggregationValueCache as
336
+ | AggregationCacheEntry
337
+ | undefined
338
+ const registry = column.table._rowModelFns.aggregationFns
339
+ const aggregationFnOption = column.columnDef.aggregationFn
340
+
341
+ if (
342
+ previous &&
343
+ previous.dependency === model &&
344
+ previous.registry === registry &&
345
+ previous.aggregationFnOption === aggregationFnOption
346
+ ) {
347
+ return previous.value as any
348
+ }
349
+
350
+ const value = aggregateColumnValue({
351
+ column: column as any,
352
+ rows: normalizeAggregationRows(model.rows),
353
+ })
354
+ ;(column as any)._aggregationValueCache = {
355
+ aggregationFnOption,
356
+ dependency: model,
357
+ registry,
358
+ value,
359
+ } satisfies AggregationCacheEntry
360
+ return value as any
361
+ }
362
+
363
+ /** Implements `cell.getIsAggregated()` for synthetic grouped rows. */
364
+ export function cell_getIsAggregated<
365
+ TFeatures extends TableFeatures,
366
+ TData extends RowData,
367
+ TValue extends CellData = CellData,
368
+ >(cell: Cell<TFeatures, TData, TValue>) {
369
+ const groupingColumnId = (cell.row as any).groupingColumnId as
370
+ | string
371
+ | undefined
372
+ if (!groupingColumnId || groupingColumnId === cell.column.id) return false
373
+
374
+ const grouping = (cell.column.table as any).atoms.grouping?.get?.() as
375
+ | Array<string>
376
+ | undefined
377
+ if (grouping?.includes(cell.column.id)) return false
378
+
379
+ return column_getAggregationFns(cell.column as any).some(
380
+ (entry) => !!entry.aggregationFn,
381
+ )
382
+ }
383
+
384
+ /** Formats the default scalar or keyed aggregated-cell representation. */
385
+ export function formatAggregatedCellValue(
386
+ value: unknown,
387
+ option: unknown,
388
+ ): string | null {
389
+ if (value == null) return null
390
+
391
+ if (Array.isArray(option) && typeof value === 'object') {
392
+ const entries = Object.keys(value)
393
+ return entries
394
+ .map(
395
+ (key) => `${key}: ${String((value as Record<string, unknown>)[key])}`,
396
+ )
397
+ .join(', ')
398
+ }
399
+
400
+ return String(value)
401
+ }