@tanstack/table-core 8.0.0-alpha.67 → 8.0.0-alpha.70

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 (140) hide show
  1. package/build/cjs/aggregationFns.js +25 -37
  2. package/build/cjs/aggregationFns.js.map +1 -1
  3. package/build/cjs/core.js +167 -46
  4. package/build/cjs/core.js.map +1 -1
  5. package/build/cjs/createTable.js +24 -40
  6. package/build/cjs/createTable.js.map +1 -1
  7. package/build/cjs/features/Cells.js +28 -34
  8. package/build/cjs/features/Cells.js.map +1 -1
  9. package/build/cjs/features/ColumnSizing.js +102 -116
  10. package/build/cjs/features/ColumnSizing.js.map +1 -1
  11. package/build/cjs/features/Columns.js +52 -79
  12. package/build/cjs/features/Columns.js.map +1 -1
  13. package/build/cjs/features/Expanding.js +49 -58
  14. package/build/cjs/features/Expanding.js.map +1 -1
  15. package/build/cjs/features/Filters.js +98 -193
  16. package/build/cjs/features/Filters.js.map +1 -1
  17. package/build/cjs/features/Grouping.js +53 -71
  18. package/build/cjs/features/Grouping.js.map +1 -1
  19. package/build/cjs/features/Headers.js +109 -165
  20. package/build/cjs/features/Headers.js.map +1 -1
  21. package/build/cjs/features/Ordering.js +31 -43
  22. package/build/cjs/features/Ordering.js.map +1 -1
  23. package/build/cjs/features/Pagination.js +79 -82
  24. package/build/cjs/features/Pagination.js.map +1 -1
  25. package/build/cjs/features/Pinning.js +71 -125
  26. package/build/cjs/features/Pinning.js.map +1 -1
  27. package/build/cjs/features/RowSelection.js +93 -112
  28. package/build/cjs/features/RowSelection.js.map +1 -1
  29. package/build/cjs/features/Rows.js +32 -22
  30. package/build/cjs/features/Rows.js.map +1 -1
  31. package/build/cjs/features/Sorting.js +54 -73
  32. package/build/cjs/features/Sorting.js.map +1 -1
  33. package/build/cjs/features/Visibility.js +47 -86
  34. package/build/cjs/features/Visibility.js.map +1 -1
  35. package/build/cjs/filterFns.js +48 -72
  36. package/build/cjs/filterFns.js.map +1 -1
  37. package/build/cjs/index.js +13 -13
  38. package/build/cjs/sortingFns.js +21 -21
  39. package/build/cjs/sortingFns.js.map +1 -1
  40. package/build/cjs/utils/filterRowsUtils.js +49 -55
  41. package/build/cjs/utils/filterRowsUtils.js.map +1 -1
  42. package/build/cjs/utils/getCoreRowModel.js +98 -0
  43. package/build/cjs/utils/getCoreRowModel.js.map +1 -0
  44. package/build/cjs/utils/getExpandedRowModel.js +17 -21
  45. package/build/cjs/utils/getExpandedRowModel.js.map +1 -1
  46. package/build/cjs/utils/getFacetedMinMaxValues.js +48 -0
  47. package/build/cjs/utils/getFacetedMinMaxValues.js.map +1 -0
  48. package/build/cjs/utils/getFacetedRowModel.js +50 -0
  49. package/build/cjs/utils/getFacetedRowModel.js.map +1 -0
  50. package/build/cjs/utils/getFacetedUniqueValues.js +48 -0
  51. package/build/cjs/utils/getFacetedUniqueValues.js.map +1 -0
  52. package/build/cjs/utils/getFilteredRowModel.js +130 -0
  53. package/build/cjs/utils/getFilteredRowModel.js.map +1 -0
  54. package/build/cjs/utils/getGroupedRowModel.js +126 -136
  55. package/build/cjs/utils/getGroupedRowModel.js.map +1 -1
  56. package/build/cjs/utils/getPaginationRowModel.js +39 -39
  57. package/build/cjs/utils/getPaginationRowModel.js.map +1 -1
  58. package/build/cjs/utils/getSortedRowModel.js +112 -0
  59. package/build/cjs/utils/getSortedRowModel.js.map +1 -0
  60. package/build/cjs/utils.js +36 -207
  61. package/build/cjs/utils.js.map +1 -1
  62. package/build/esm/index.js +1778 -2347
  63. package/build/esm/index.js.map +1 -1
  64. package/build/stats-html.html +1 -1
  65. package/build/stats-react.json +421 -481
  66. package/build/types/core.d.ts +3 -5
  67. package/build/types/features/Cells.d.ts +1 -1
  68. package/build/types/features/ColumnSizing.d.ts +2 -2
  69. package/build/types/features/Columns.d.ts +1 -1
  70. package/build/types/features/Expanding.d.ts +1 -1
  71. package/build/types/features/Filters.d.ts +12 -7
  72. package/build/types/features/Grouping.d.ts +5 -4
  73. package/build/types/features/Ordering.d.ts +1 -1
  74. package/build/types/features/Pagination.d.ts +4 -4
  75. package/build/types/features/Pinning.d.ts +1 -1
  76. package/build/types/features/RowSelection.d.ts +1 -1
  77. package/build/types/features/Rows.d.ts +4 -3
  78. package/build/types/features/Sorting.d.ts +2 -1
  79. package/build/types/features/Visibility.d.ts +1 -0
  80. package/build/types/index.d.ts +6 -4
  81. package/build/types/types.d.ts +3 -13
  82. package/build/types/utils/filterRowsUtils.d.ts +3 -3
  83. package/build/types/utils/getCoreRowModel.d.ts +2 -0
  84. package/build/types/utils/getFacetedMinMaxValues.d.ts +2 -0
  85. package/build/types/utils/getFacetedRowModel.d.ts +2 -0
  86. package/build/types/utils/getFacetedUniqueValues.d.ts +2 -0
  87. package/build/types/utils/{getCoreRowModelSync.d.ts → getFilteredRowModel.d.ts} +1 -1
  88. package/build/types/utils/getGroupedRowModel.d.ts +1 -1
  89. package/build/types/utils/getSortedRowModel.d.ts +2 -0
  90. package/build/types/utils.d.ts +1 -17
  91. package/build/umd/index.development.js +1779 -2350
  92. package/build/umd/index.development.js.map +1 -1
  93. package/build/umd/index.production.js +1 -1
  94. package/build/umd/index.production.js.map +1 -1
  95. package/package.json +1 -1
  96. package/src/core.ts +197 -45
  97. package/src/features/Cells.ts +7 -11
  98. package/src/features/ColumnSizing.ts +27 -19
  99. package/src/features/Columns.ts +4 -8
  100. package/src/features/Expanding.ts +5 -3
  101. package/src/features/Filters.ts +105 -162
  102. package/src/features/Grouping.ts +21 -23
  103. package/src/features/Ordering.ts +5 -3
  104. package/src/features/Pagination.ts +32 -19
  105. package/src/features/Pinning.ts +13 -7
  106. package/src/features/RowSelection.ts +5 -3
  107. package/src/features/Rows.ts +21 -6
  108. package/src/features/Sorting.ts +14 -12
  109. package/src/features/Visibility.ts +7 -0
  110. package/src/filterFns.ts +9 -9
  111. package/src/index.ts +12 -4
  112. package/src/sortingFns.ts +11 -11
  113. package/src/types.ts +3 -16
  114. package/src/utils/filterRowsUtils.ts +47 -68
  115. package/src/utils/{getCoreRowModelSync.ts → getCoreRowModel.ts} +2 -8
  116. package/src/utils/getFacetedMinMaxValues.ts +37 -0
  117. package/src/utils/getFacetedRowModel.ts +50 -0
  118. package/src/utils/getFacetedUniqueValues.ts +37 -0
  119. package/src/utils/{getFilteredRowModelSync.ts → getFilteredRowModel.ts} +29 -20
  120. package/src/utils/getGroupedRowModel.ts +52 -61
  121. package/src/utils/{getSortedRowModelSync.ts → getSortedRowModel.ts} +3 -3
  122. package/src/utils.ts +28 -236
  123. package/build/cjs/_virtual/_rollupPluginBabelHelpers.js +0 -112
  124. package/build/cjs/_virtual/_rollupPluginBabelHelpers.js.map +0 -1
  125. package/build/cjs/utils/getCoreRowModelAsync.js +0 -125
  126. package/build/cjs/utils/getCoreRowModelAsync.js.map +0 -1
  127. package/build/cjs/utils/getCoreRowModelSync.js +0 -102
  128. package/build/cjs/utils/getCoreRowModelSync.js.map +0 -1
  129. package/build/cjs/utils/getFilteredRowModelSync.js +0 -125
  130. package/build/cjs/utils/getFilteredRowModelSync.js.map +0 -1
  131. package/build/cjs/utils/getSortedRowModelSync.js +0 -118
  132. package/build/cjs/utils/getSortedRowModelSync.js.map +0 -1
  133. package/build/types/utils/getCoreRowModelAsync.d.ts +0 -4
  134. package/build/types/utils/getFilteredRowModelAsync.d.ts +0 -4
  135. package/build/types/utils/getFilteredRowModelSync.d.ts +0 -2
  136. package/build/types/utils/getSortedRowModelAsync.d.ts +0 -13
  137. package/build/types/utils/getSortedRowModelSync.d.ts +0 -2
  138. package/src/utils/getCoreRowModelAsync.ts +0 -104
  139. package/src/utils/getFilteredRowModelAsync.ts +0 -157
  140. package/src/utils/getSortedRowModelAsync.ts +0 -200
@@ -1,4 +0,0 @@
1
- import { TableInstance, RowModel, TableGenerics } from '../types';
2
- export declare function getCoreRowModelAsync<TGenerics extends TableGenerics>(opts?: {
3
- initialSync: boolean;
4
- }): (instance: TableInstance<TGenerics>) => () => RowModel<TGenerics>;
@@ -1,4 +0,0 @@
1
- import { TableInstance, RowModel, TableGenerics } from '../types';
2
- export declare function getFilteredRowModelAsync<TGenerics extends TableGenerics>(opts?: {
3
- initialSync?: boolean;
4
- }): (instance: TableInstance<TGenerics>) => () => RowModel<TGenerics>;
@@ -1,2 +0,0 @@
1
- import { TableInstance, RowModel, TableGenerics } from '../types';
2
- export declare function getFilteredRowModelSync<TGenerics extends TableGenerics>(): (instance: TableInstance<TGenerics>) => () => RowModel<TGenerics>;
@@ -1,13 +0,0 @@
1
- import { TableInstance, Row, RowModel, TableGenerics } from '../types';
2
- export declare function getSortedRowModelSync<TGenerics extends TableGenerics>(opts?: {
3
- initialSync?: boolean;
4
- }): (instance: TableInstance<TGenerics>) => () => RowModel<TGenerics>;
5
- declare type Sorter<TGenerics extends TableGenerics> = {
6
- id: string;
7
- compare: (a: Row<TGenerics>, b: Row<TGenerics>) => number;
8
- desc?: boolean;
9
- sortUndefined?: false | -1 | 1;
10
- invertSorting?: boolean;
11
- };
12
- export declare function quicksort<TGenerics extends TableGenerics>(rows: Row<TGenerics>[], sorters: Sorter<TGenerics>[]): Row<TGenerics>[];
13
- export {};
@@ -1,2 +0,0 @@
1
- import { TableInstance, RowModel, TableGenerics } from '../types';
2
- export declare function getSortedRowModelSync<TGenerics extends TableGenerics>(): (instance: TableInstance<TGenerics>) => () => RowModel<TGenerics>;
@@ -1,104 +0,0 @@
1
- import { TableInstance, Row, RowModel, TableGenerics } from '../types'
2
- import { getBatchGroups, incrementalMemo } from '../utils'
3
-
4
- export function getCoreRowModelAsync<TGenerics extends TableGenerics>(opts?: {
5
- initialSync: boolean
6
- }): (instance: TableInstance<TGenerics>) => () => RowModel<TGenerics> {
7
- return instance =>
8
- incrementalMemo(
9
- () => [instance.options.data, instance.getAllLeafColumns()],
10
- () => {
11
- const rows: Row<TGenerics>[] = []
12
- const flatRows: Row<TGenerics>[] = []
13
- const rowsById: Record<string, Row<TGenerics>> = {}
14
-
15
- return { rows, flatRows, rowsById }
16
- },
17
- (data, leafColumns) => rowModelRef => scheduleTask => {
18
- const accessRows = (
19
- originalRows: TGenerics['Row'][],
20
- depth = 0,
21
- parent?: Row<TGenerics>
22
- ) => {
23
- const batchGroups = getBatchGroups(originalRows, 2000)
24
-
25
- for (let i = 0; i < batchGroups.length; i++) {
26
- const batchGroup = batchGroups[i]
27
- scheduleTask(() => {
28
- for (let i = 0; i < batchGroup.items.length; i++) {
29
- const originalRow = batchGroup.items[i]
30
- const rowIndex = batchGroup.start + i
31
- const id = instance.getRowId(originalRow, rowIndex, parent)
32
-
33
- if (!id) {
34
- if (process.env.NODE_ENV !== 'production') {
35
- throw new Error(`getRowId expected an ID, but got ${id}`)
36
- }
37
- }
38
-
39
- const values: Record<string, any> = {}
40
-
41
- for (let i = 0; i < leafColumns.length; i++) {
42
- const column = leafColumns[i]
43
- if (column && column.accessorFn) {
44
- values[column.id] = column.accessorFn(originalRow, rowIndex)
45
- }
46
- }
47
-
48
- // Make the row
49
- const row = instance.createRow(
50
- id,
51
- originalRow,
52
- rowIndex,
53
- depth,
54
- values
55
- )
56
-
57
- // Push instance row into the parentRows array
58
- if (parent) {
59
- parent.subRows.push(row)
60
- } else {
61
- rowModelRef.current.rows.push(row)
62
- }
63
- // Keep track of every row in a flat array
64
- rowModelRef.current.flatRows.push(row)
65
- // Also keep track of every row by its ID
66
- rowModelRef.current.rowsById[id] = row
67
-
68
- // Get the original subrows
69
- if (instance.options.getSubRows) {
70
- const originalSubRows = instance.options.getSubRows(
71
- originalRow,
72
- rowIndex
73
- )
74
-
75
- // Then recursively access them
76
- if (originalSubRows?.length) {
77
- row.originalSubRows = originalSubRows
78
- row.subRows = []
79
-
80
- accessRows(row.originalSubRows, depth + 1, row)
81
- }
82
- }
83
- }
84
- })
85
- }
86
- }
87
-
88
- accessRows(data)
89
- },
90
- {
91
- key: process.env.NODE_ENV === 'development' && 'getRowModel',
92
- initialSync: opts?.initialSync,
93
- onProgress: progress => {
94
- instance.setState(old => ({ ...old, coreProgress: progress }))
95
- },
96
- debug: () => instance.options.debugAll ?? instance.options.debugTable,
97
- onChange: () => {
98
- instance.queue(() => {
99
- instance._autoResetPageIndex()
100
- })
101
- },
102
- }
103
- )
104
- }
@@ -1,157 +0,0 @@
1
- import { ResolvedColumnFilter } from '../features/Filters'
2
- import { TableInstance, RowModel, TableGenerics, Row } from '../types'
3
- import { incrementalMemo } from '../utils'
4
- import { filterRows } from './filterRowsUtils'
5
-
6
- export function getFilteredRowModelAsync<
7
- TGenerics extends TableGenerics
8
- >(opts?: {
9
- initialSync?: boolean
10
- }): (instance: TableInstance<TGenerics>) => () => RowModel<TGenerics> {
11
- return instance =>
12
- incrementalMemo(
13
- () => [
14
- instance.getPreFilteredRowModel(),
15
- instance.getState().columnFilters,
16
- instance.getState().globalFilter,
17
- ],
18
- (rowModel): RowModel<TGenerics> => {
19
- return {
20
- rows: rowModel.rows.slice(),
21
- flatRows: [],
22
- rowsById: rowModel.rowsById,
23
- }
24
- },
25
- (rowModel, columnFilters, globalFilter) => rowModelRef => scheduleTask => {
26
- if (
27
- !rowModel.rows.length ||
28
- (!columnFilters?.length && !globalFilter)
29
- ) {
30
- rowModelRef.current = rowModel
31
- return
32
- }
33
-
34
- const resolvedColumnFilters: ResolvedColumnFilter<TGenerics>[] = []
35
- const resolvedGlobalFilters: ResolvedColumnFilter<TGenerics>[] = []
36
-
37
- ;(columnFilters ?? []).forEach(d => {
38
- const column = instance.getColumn(d.id)
39
-
40
- if (!column) {
41
- if (process.env.NODE_ENV !== 'production') {
42
- console.warn(
43
- `Table: Could not find a column to filter with columnId: ${d.id}`
44
- )
45
- }
46
- }
47
-
48
- const filterFn = column.getFilterFn()!
49
-
50
- if (!filterFn) {
51
- if (process.env.NODE_ENV !== 'production') {
52
- console.warn(
53
- `Could not find a valid 'column.filterFn' for column with the ID: ${column.id}.`
54
- )
55
- }
56
- return
57
- }
58
-
59
- resolvedColumnFilters.push({
60
- id: d.id,
61
- filterFn,
62
- resolvedValue: filterFn.resolveFilterValue?.(d.value) ?? d.value,
63
- })
64
- })
65
-
66
- const filterableIds = columnFilters.map(d => d.id)
67
-
68
- const globalFilterFn = instance.getGlobalFilterFn()
69
-
70
- const globallyFilterableColumns = instance
71
- .getAllLeafColumns()
72
- .filter(column => column.getCanGlobalFilter())
73
-
74
- if (
75
- globalFilter &&
76
- globalFilterFn &&
77
- globallyFilterableColumns.length
78
- ) {
79
- filterableIds.push('__global__')
80
-
81
- globallyFilterableColumns.forEach(column => {
82
- resolvedGlobalFilters.push({
83
- id: column.id,
84
- filterFn: globalFilterFn,
85
- resolvedValue:
86
- globalFilterFn.resolveFilterValue?.(globalFilter) ??
87
- globalFilter,
88
- })
89
- })
90
- }
91
-
92
- // Flag the prefiltered row model with each filter state
93
- for (let j = 0; j < rowModel.flatRows.length; j++) {
94
- const row = rowModel.flatRows[j]
95
-
96
- row.columnFilterMap = {}
97
-
98
- if (resolvedColumnFilters.length) {
99
- for (let i = 0; i < resolvedColumnFilters.length; i++) {
100
- const columnFilter = resolvedColumnFilters[i]
101
-
102
- // Tag the row with the column filter state
103
- row.columnFilterMap[columnFilter.id] = columnFilter.filterFn(
104
- row,
105
- columnFilter.id,
106
- columnFilter.resolvedValue
107
- )
108
- }
109
- }
110
-
111
- if (resolvedGlobalFilters.length) {
112
- let hit = false
113
-
114
- for (let i = 0; i < resolvedGlobalFilters.length; i++) {
115
- const globalFilter = resolvedGlobalFilters[i]
116
- // Tag the row with the first truthy global filter state
117
- if (
118
- globalFilter.filterFn(
119
- row,
120
- globalFilter.id,
121
- globalFilter.resolvedValue
122
- )
123
- ) {
124
- hit = true
125
- row.columnFilterMap.__global__ = true
126
- break
127
- }
128
- }
129
-
130
- if (row.columnFilterMap.__global__ !== true) {
131
- row.columnFilterMap.__global__ = false
132
- }
133
- }
134
- }
135
-
136
- // Filter final rows using all of the active filters
137
- return filterRows(rowModel.rows, filterableIds, instance)
138
- },
139
- {
140
- key:
141
- process.env.NODE_ENV === 'production' && 'getFilteredRowModelAsync',
142
- initialSync: opts?.initialSync,
143
- onProgress: progress => {
144
- instance.setState(old => ({
145
- ...old,
146
- columnFiltersProgress: progress,
147
- }))
148
- },
149
- debug: () => instance.options.debugAll ?? instance.options.debugTable,
150
- onChange: () => {
151
- instance.queue(() => {
152
- instance._autoResetPageIndex()
153
- })
154
- },
155
- }
156
- )
157
- }
@@ -1,200 +0,0 @@
1
- import { TableInstance, Row, RowModel, TableGenerics } from '../types'
2
- import { incrementalMemo, memo } from '../utils'
3
-
4
- export function getSortedRowModelSync<TGenerics extends TableGenerics>(opts?: {
5
- initialSync?: boolean
6
- }): (instance: TableInstance<TGenerics>) => () => RowModel<TGenerics> {
7
- return instance =>
8
- incrementalMemo(
9
- () => [instance.getState().sorting, instance.getPreSortedRowModel()],
10
- (_sorting, rowModel): RowModel<TGenerics> => {
11
- return {
12
- rows: rowModel.rows.slice(),
13
- flatRows: [],
14
- rowsById: rowModel.rowsById,
15
- }
16
- },
17
- (sorting, rowModel) => rowModelRef => scheduleTask => {
18
- // TODO: Figure out how to do async sorting
19
- // We probably need to use a sorting algo that is "divide and
20
- // conquer", since that will probably distribute the easiest into
21
- // separate tasks. The trick will be batching those tasks in a way
22
- // that makes them fast. JS work loops don't tend to do well with
23
- // a high number of tasks that do one thing. Instead, shoot for each
24
- // task to have a few thousand opts (or whatever amount is generally
25
- // fast for most devices).
26
-
27
- throw new Error()
28
-
29
- // if (!rowModel.rows.length || !sorting?.length) {
30
- // rowModelRef.current = rowModel
31
- // return
32
- // }
33
-
34
- // const sortingState = instance.getState().sorting
35
-
36
- // const sortedFlatRows: Row<TGenerics>[] = []
37
-
38
- // // Filter out sortings that correspond to non existing columns
39
- // const availableSorting = sortingState.filter(sort =>
40
- // instance.getColumnCanSort(sort.id)
41
- // )
42
-
43
- // const sorters = availableSorting.map(columnSorting => {
44
- // const column = instance.getColumn(columnSorting.id)!
45
- // const sortingFn = instance.getColumnSortingFn(columnSorting.id)!
46
-
47
- // return {
48
- // id: columnSorting.id,
49
- // compare: (rowA: Row<TGenerics>, rowB: Row<TGenerics>) =>
50
- // sortingFn(rowA, rowB, columnSorting.id),
51
- // desc: columnSorting.desc,
52
- // invertSorting: column.invertSorting,
53
- // sortUndefined: column.sortUndefined,
54
- // }
55
- // })
56
-
57
- // const sortData = (rows: Row<TGenerics>[]) => {
58
- // // This will also perform a stable sorting using the row index
59
- // // if needed.
60
-
61
- // const sortedData = quicksort(rows, sorters)
62
-
63
- // // If there are sub-rows, sort them
64
- // sortedData.forEach(row => {
65
- // rowModelRef.current.flatRows.push(row)
66
- // if (!row.subRows || row.subRows.length <= 1) {
67
- // return
68
- // }
69
- // row.subRows = sortData(row.subRows)
70
- // })
71
-
72
- // return sortedData
73
- // }
74
-
75
- // sortData(rowModelRef.current.rows)
76
- },
77
- {
78
- key: process.env.NODE_ENV === 'development' && 'getSortedRowModel',
79
- initialSync: opts?.initialSync,
80
- onProgress: progress => {
81
- instance.setState(old => ({ ...old, sortingProgress: progress }))
82
- },
83
- debug: () => instance.options.debugAll ?? instance.options.debugTable,
84
- onChange: () => {
85
- instance.queue(() => {
86
- instance._autoResetPageIndex()
87
- })
88
- },
89
- }
90
- )
91
- }
92
-
93
- type Sorter<TGenerics extends TableGenerics> = {
94
- id: string
95
- compare: (a: Row<TGenerics>, b: Row<TGenerics>) => number
96
- desc?: boolean
97
- sortUndefined?: false | -1 | 1
98
- invertSorting?: boolean
99
- }
100
-
101
- export function quicksort<TGenerics extends TableGenerics>(
102
- rows: Row<TGenerics>[],
103
- sorters: Sorter<TGenerics>[]
104
- ): Row<TGenerics>[] {
105
- if (!rows.length) {
106
- return rows
107
- }
108
-
109
- // Copy the rows so we can mutate the order
110
- rows = rows.slice()
111
-
112
- // Start the quicksort recursion
113
- recurse(0, rows.length - 1)
114
-
115
- // Return the rows
116
- return rows
117
-
118
- function recurse(start: number, end: number) {
119
- const pivotIndex = pivot(start, end)
120
-
121
- if (start < pivotIndex - 1) {
122
- recurse(start, pivotIndex - 1)
123
- }
124
-
125
- if (pivotIndex < end) {
126
- recurse(pivotIndex + 1, end)
127
- }
128
- }
129
-
130
- function pivot(start: number, end: number) {
131
- const pivotIndex = Math.floor((start + end) / 2)
132
- let i = start
133
- let j = end
134
-
135
- const compare = (a: number, b: number) => {
136
- const rowA = rows[a]
137
- const rowB = rows[b]
138
-
139
- for (let i = 0; i < sorters.length; i += 1) {
140
- const sorter = sorters[i]!
141
- const isDesc = sorter?.desc ?? false
142
-
143
- if (sorter.sortUndefined) {
144
- const aValue = rowA.values[sorter.id]
145
- const bValue = rowB.values[sorter.id]
146
-
147
- const aUndefined = typeof aValue === 'undefined'
148
- const bUndefined = typeof bValue === 'undefined'
149
-
150
- if (aUndefined || bUndefined) {
151
- if (aUndefined !== bUndefined) {
152
- return aUndefined ? sorter.sortUndefined : -sorter.sortUndefined
153
- }
154
- }
155
- }
156
-
157
- // This function should always return in ascending order
158
- let sortInt = sorter.compare(rowA, rowB)
159
-
160
- if (sortInt !== 0) {
161
- if (isDesc) {
162
- sortInt *= -1
163
- }
164
-
165
- if (sorter.invertSorting) {
166
- sortInt *= -1
167
- }
168
-
169
- return sortInt
170
- }
171
- }
172
-
173
- return rowA.index < rowB.index ? -1 : 1
174
- }
175
-
176
- while (i <= j) {
177
- while (compare(i, pivotIndex) < 0) {
178
- i++
179
- }
180
-
181
- while (compare(pivotIndex, j) < 0) {
182
- j--
183
- }
184
-
185
- if (i <= j) {
186
- swap(rows, i, j)
187
- i++
188
- j--
189
- }
190
- }
191
-
192
- return i
193
- }
194
-
195
- function swap<T>(arr: T[], a: number, b: number) {
196
- const t = arr[a]
197
- arr[a] = arr[b]
198
- arr[b] = t
199
- }
200
- }