@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.
- package/dist/core/row-models/coreRowModelsFeature.types.d.cts +1 -1
- package/dist/core/row-models/coreRowModelsFeature.types.d.ts +1 -1
- package/dist/core/row-models/coreRowModelsFeature.utils.cjs +1 -1
- package/dist/core/row-models/coreRowModelsFeature.utils.cjs.map +1 -1
- package/dist/core/row-models/coreRowModelsFeature.utils.d.cts +1 -1
- package/dist/core/row-models/coreRowModelsFeature.utils.d.ts +1 -1
- package/dist/core/row-models/coreRowModelsFeature.utils.js +1 -1
- package/dist/core/row-models/coreRowModelsFeature.utils.js.map +1 -1
- package/dist/features/aggregation/aggregationFeature.cjs +38 -0
- package/dist/features/aggregation/aggregationFeature.cjs.map +1 -0
- package/dist/features/aggregation/aggregationFeature.d.cts +10 -0
- package/dist/features/aggregation/aggregationFeature.d.ts +10 -0
- package/dist/features/aggregation/aggregationFeature.js +38 -0
- package/dist/features/aggregation/aggregationFeature.js.map +1 -0
- package/dist/features/aggregation/aggregationFeature.types.cjs +13 -0
- package/dist/features/aggregation/aggregationFeature.types.cjs.map +1 -0
- package/dist/features/aggregation/aggregationFeature.types.d.cts +172 -0
- package/dist/features/aggregation/aggregationFeature.types.d.ts +172 -0
- package/dist/features/aggregation/aggregationFeature.types.js +12 -0
- package/dist/features/aggregation/aggregationFeature.types.js.map +1 -0
- package/dist/features/aggregation/aggregationFeature.utils.cjs +198 -0
- package/dist/features/aggregation/aggregationFeature.utils.cjs.map +1 -0
- package/dist/features/aggregation/aggregationFeature.utils.d.cts +33 -0
- package/dist/features/aggregation/aggregationFeature.utils.d.ts +33 -0
- package/dist/features/aggregation/aggregationFeature.utils.js +192 -0
- package/dist/features/aggregation/aggregationFeature.utils.js.map +1 -0
- package/dist/features/aggregation/aggregationFns.cjs +240 -0
- package/dist/features/aggregation/aggregationFns.cjs.map +1 -0
- package/dist/features/aggregation/aggregationFns.d.cts +67 -0
- package/dist/features/aggregation/aggregationFns.d.ts +67 -0
- package/dist/features/aggregation/aggregationFns.js +229 -0
- package/dist/features/aggregation/aggregationFns.js.map +1 -0
- package/dist/features/column-filtering/columnFilteringFeature.types.d.cts +1 -1
- package/dist/features/column-filtering/columnFilteringFeature.types.d.ts +1 -1
- package/dist/{fns → features/column-filtering}/filterFns.cjs +1 -1
- package/dist/features/column-filtering/filterFns.cjs.map +1 -0
- package/dist/{fns → features/column-filtering}/filterFns.d.cts +4 -4
- package/dist/{fns → features/column-filtering}/filterFns.d.ts +4 -4
- package/dist/{fns → features/column-filtering}/filterFns.js +1 -1
- package/dist/features/column-filtering/filterFns.js.map +1 -0
- package/dist/features/column-grouping/columnGroupingFeature.cjs +3 -12
- package/dist/features/column-grouping/columnGroupingFeature.cjs.map +1 -1
- package/dist/features/column-grouping/columnGroupingFeature.d.cts +1 -1
- package/dist/features/column-grouping/columnGroupingFeature.d.ts +1 -1
- package/dist/features/column-grouping/columnGroupingFeature.js +4 -13
- package/dist/features/column-grouping/columnGroupingFeature.js.map +1 -1
- package/dist/features/column-grouping/columnGroupingFeature.types.d.cts +6 -87
- package/dist/features/column-grouping/columnGroupingFeature.types.d.ts +6 -87
- package/dist/features/column-grouping/columnGroupingFeature.utils.cjs +0 -64
- package/dist/features/column-grouping/columnGroupingFeature.utils.cjs.map +1 -1
- package/dist/features/column-grouping/columnGroupingFeature.utils.d.cts +2 -44
- package/dist/features/column-grouping/columnGroupingFeature.utils.d.ts +2 -44
- package/dist/features/column-grouping/columnGroupingFeature.utils.js +2 -63
- package/dist/features/column-grouping/columnGroupingFeature.utils.js.map +1 -1
- package/dist/features/column-grouping/createGroupedRowModel.cjs +23 -16
- package/dist/features/column-grouping/createGroupedRowModel.cjs.map +1 -1
- package/dist/features/column-grouping/createGroupedRowModel.d.cts +2 -6
- package/dist/features/column-grouping/createGroupedRowModel.d.ts +2 -6
- package/dist/features/column-grouping/createGroupedRowModel.js +25 -18
- package/dist/features/column-grouping/createGroupedRowModel.js.map +1 -1
- package/dist/features/global-filtering/globalFilteringFeature.utils.cjs +1 -1
- package/dist/features/global-filtering/globalFilteringFeature.utils.cjs.map +1 -1
- package/dist/features/global-filtering/globalFilteringFeature.utils.js +1 -1
- package/dist/features/global-filtering/globalFilteringFeature.utils.js.map +1 -1
- package/dist/features/row-sorting/rowSortingFeature.types.d.cts +1 -1
- package/dist/features/row-sorting/rowSortingFeature.types.d.ts +1 -1
- package/dist/features/row-sorting/rowSortingFeature.utils.cjs +1 -1
- package/dist/features/row-sorting/rowSortingFeature.utils.cjs.map +1 -1
- package/dist/features/row-sorting/rowSortingFeature.utils.js +1 -1
- package/dist/features/row-sorting/rowSortingFeature.utils.js.map +1 -1
- package/dist/{fns → features/row-sorting}/sortFns.cjs +1 -1
- package/dist/{fns/sortFns.js.map → features/row-sorting/sortFns.cjs.map} +1 -1
- package/dist/{fns → features/row-sorting}/sortFns.d.cts +4 -4
- package/dist/{fns → features/row-sorting}/sortFns.d.ts +4 -4
- package/dist/{fns → features/row-sorting}/sortFns.js +1 -1
- package/dist/features/row-sorting/sortFns.js.map +1 -0
- package/dist/features/stockFeatures.cjs +2 -0
- package/dist/features/stockFeatures.cjs.map +1 -1
- package/dist/features/stockFeatures.d.cts +2 -0
- package/dist/features/stockFeatures.d.ts +2 -0
- package/dist/features/stockFeatures.js +2 -0
- package/dist/features/stockFeatures.js.map +1 -1
- package/dist/index.cjs +7 -4
- package/dist/index.d.cts +7 -5
- package/dist/index.d.ts +7 -5
- package/dist/index.js +6 -4
- package/dist/static-functions.cjs +8 -3
- package/dist/static-functions.d.cts +3 -2
- package/dist/static-functions.d.ts +3 -2
- package/dist/static-functions.js +3 -2
- package/dist/types/Cell.d.cts +3 -1
- package/dist/types/Cell.d.ts +3 -1
- package/dist/types/Column.d.cts +4 -2
- package/dist/types/Column.d.ts +4 -2
- package/dist/types/ColumnDef.d.cts +5 -3
- package/dist/types/ColumnDef.d.ts +5 -3
- package/dist/types/Row.d.cts +3 -1
- package/dist/types/Row.d.ts +3 -1
- package/dist/types/RowModel.d.cts +1 -1
- package/dist/types/RowModel.d.ts +1 -1
- package/dist/types/RowModelFns.d.cts +3 -3
- package/dist/types/RowModelFns.d.ts +3 -3
- package/dist/types/Table.d.cts +1 -1
- package/dist/types/Table.d.ts +1 -1
- package/dist/types/TableFeatures.d.cts +4 -4
- package/dist/types/TableFeatures.d.ts +4 -4
- package/dist/types/TableOptions.d.cts +5 -3
- package/dist/types/TableOptions.d.ts +5 -3
- package/dist/types/TableState.d.cts +1 -1
- package/dist/types/TableState.d.ts +1 -1
- package/dist/worker/initTableWorker.cjs.map +1 -1
- package/dist/worker/initTableWorker.js.map +1 -1
- package/package.json +1 -1
- package/skills/aggregation/SKILL.md +131 -0
- package/skills/api-not-found/SKILL.md +1 -1
- package/skills/client-vs-server/SKILL.md +1 -1
- package/skills/column-faceting/SKILL.md +1 -1
- package/skills/column-filtering/SKILL.md +1 -1
- package/skills/column-ordering/SKILL.md +1 -1
- package/skills/column-pinning/SKILL.md +1 -1
- package/skills/column-resizing/SKILL.md +1 -1
- package/skills/column-sizing/SKILL.md +1 -1
- package/skills/column-visibility/SKILL.md +1 -1
- package/skills/core/SKILL.md +1 -1
- package/skills/custom-features/SKILL.md +1 -1
- package/skills/expanding/SKILL.md +1 -1
- package/skills/global-filtering/SKILL.md +1 -1
- package/skills/grouping/SKILL.md +12 -18
- package/skills/migrate-v8-to-v9/SKILL.md +15 -2
- package/skills/pagination/SKILL.md +1 -1
- package/skills/row-pinning/SKILL.md +1 -1
- package/skills/row-selection/SKILL.md +1 -1
- package/skills/sorting/SKILL.md +1 -1
- package/skills/table-features/SKILL.md +5 -2
- package/skills/typescript/SKILL.md +1 -1
- package/src/core/row-models/coreRowModelsFeature.utils.ts +1 -1
- package/src/features/aggregation/aggregationFeature.ts +59 -0
- package/src/features/aggregation/aggregationFeature.types.ts +312 -0
- package/src/features/aggregation/aggregationFeature.utils.ts +401 -0
- package/src/features/aggregation/aggregationFns.ts +336 -0
- package/src/features/column-filtering/columnFilteringFeature.types.ts +1 -1
- package/src/{fns → features/column-filtering}/filterFns.ts +4 -4
- package/src/features/column-grouping/columnGroupingFeature.ts +1 -20
- package/src/features/column-grouping/columnGroupingFeature.types.ts +4 -141
- package/src/features/column-grouping/columnGroupingFeature.utils.ts +1 -122
- package/src/features/column-grouping/createGroupedRowModel.ts +32 -41
- package/src/features/global-filtering/globalFilteringFeature.utils.ts +1 -1
- package/src/features/row-sorting/rowSortingFeature.types.ts +1 -1
- package/src/features/row-sorting/rowSortingFeature.utils.ts +1 -1
- package/src/{fns → features/row-sorting}/sortFns.ts +4 -7
- package/src/features/stockFeatures.ts +3 -0
- package/src/index.ts +7 -8
- package/src/static-functions.ts +1 -0
- package/src/types/Cell.ts +2 -0
- package/src/types/Column.ts +3 -1
- package/src/types/ColumnDef.ts +6 -3
- package/src/types/Row.ts +2 -0
- package/src/types/RowModelFns.ts +3 -3
- package/src/types/TableFeatures.ts +4 -4
- package/src/types/TableOptions.ts +5 -1
- package/src/worker/initTableWorker.ts +1 -1
- package/dist/fns/aggregationFns.cjs +0 -234
- package/dist/fns/aggregationFns.cjs.map +0 -1
- package/dist/fns/aggregationFns.d.cts +0 -139
- package/dist/fns/aggregationFns.d.ts +0 -139
- package/dist/fns/aggregationFns.js +0 -221
- package/dist/fns/aggregationFns.js.map +0 -1
- package/dist/fns/filterFns.cjs.map +0 -1
- package/dist/fns/filterFns.js.map +0 -1
- package/dist/fns/sortFns.cjs.map +0 -1
- 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
|
+
}
|