@tanstack/table-core 9.0.0-beta.46 → 9.0.0-beta.47
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/features/column-filtering/columnFilteringFeature.types.d.cts +43 -3
- package/dist/features/column-filtering/columnFilteringFeature.types.d.ts +43 -3
- package/dist/features/column-filtering/columnFilteringFeature.utils.cjs +18 -9
- package/dist/features/column-filtering/columnFilteringFeature.utils.cjs.map +1 -1
- package/dist/features/column-filtering/columnFilteringFeature.utils.d.cts +6 -2
- package/dist/features/column-filtering/columnFilteringFeature.utils.d.ts +6 -2
- package/dist/features/column-filtering/columnFilteringFeature.utils.js +18 -9
- package/dist/features/column-filtering/columnFilteringFeature.utils.js.map +1 -1
- package/dist/features/column-filtering/createFilteredRowModel.cjs +7 -2
- package/dist/features/column-filtering/createFilteredRowModel.cjs.map +1 -1
- package/dist/features/column-filtering/createFilteredRowModel.d.cts +6 -2
- package/dist/features/column-filtering/createFilteredRowModel.d.ts +6 -2
- package/dist/features/column-filtering/createFilteredRowModel.js +7 -2
- package/dist/features/column-filtering/createFilteredRowModel.js.map +1 -1
- package/dist/features/column-grouping/columnGroupingFeature.types.d.cts +41 -3
- package/dist/features/column-grouping/columnGroupingFeature.types.d.ts +41 -3
- package/dist/features/column-grouping/columnGroupingFeature.utils.cjs +17 -3
- package/dist/features/column-grouping/columnGroupingFeature.utils.cjs.map +1 -1
- package/dist/features/column-grouping/columnGroupingFeature.utils.d.cts +5 -0
- package/dist/features/column-grouping/columnGroupingFeature.utils.d.ts +5 -0
- package/dist/features/column-grouping/columnGroupingFeature.utils.js +17 -3
- package/dist/features/column-grouping/columnGroupingFeature.utils.js.map +1 -1
- package/dist/features/column-grouping/createGroupedRowModel.cjs +6 -3
- package/dist/features/column-grouping/createGroupedRowModel.cjs.map +1 -1
- package/dist/features/column-grouping/createGroupedRowModel.d.cts +6 -3
- package/dist/features/column-grouping/createGroupedRowModel.d.ts +6 -3
- package/dist/features/column-grouping/createGroupedRowModel.js +6 -3
- package/dist/features/column-grouping/createGroupedRowModel.js.map +1 -1
- package/dist/features/global-filtering/globalFilteringFeature.utils.cjs +3 -1
- package/dist/features/global-filtering/globalFilteringFeature.utils.cjs.map +1 -1
- package/dist/features/global-filtering/globalFilteringFeature.utils.d.cts +2 -6
- package/dist/features/global-filtering/globalFilteringFeature.utils.d.ts +2 -6
- package/dist/features/global-filtering/globalFilteringFeature.utils.js +3 -1
- package/dist/features/global-filtering/globalFilteringFeature.utils.js.map +1 -1
- package/dist/features/row-sorting/createSortedRowModel.cjs +6 -2
- package/dist/features/row-sorting/createSortedRowModel.cjs.map +1 -1
- package/dist/features/row-sorting/createSortedRowModel.d.cts +6 -2
- package/dist/features/row-sorting/createSortedRowModel.d.ts +6 -2
- package/dist/features/row-sorting/createSortedRowModel.js +6 -2
- package/dist/features/row-sorting/createSortedRowModel.js.map +1 -1
- package/dist/features/row-sorting/rowSortingFeature.types.d.cts +31 -2
- package/dist/features/row-sorting/rowSortingFeature.types.d.ts +31 -2
- package/dist/features/row-sorting/rowSortingFeature.utils.cjs +19 -4
- package/dist/features/row-sorting/rowSortingFeature.utils.cjs.map +1 -1
- package/dist/features/row-sorting/rowSortingFeature.utils.js +19 -4
- package/dist/features/row-sorting/rowSortingFeature.utils.js.map +1 -1
- package/dist/fns/aggregationFns.cjs +128 -57
- package/dist/fns/aggregationFns.cjs.map +1 -1
- package/dist/fns/aggregationFns.d.cts +72 -18
- package/dist/fns/aggregationFns.d.ts +72 -18
- package/dist/fns/aggregationFns.js +126 -58
- package/dist/fns/aggregationFns.js.map +1 -1
- package/dist/fns/filterFns.cjs +253 -96
- package/dist/fns/filterFns.cjs.map +1 -1
- package/dist/fns/filterFns.d.cts +126 -94
- package/dist/fns/filterFns.d.ts +126 -94
- package/dist/fns/filterFns.js +246 -97
- package/dist/fns/filterFns.js.map +1 -1
- package/dist/fns/sortFns.cjs +68 -21
- package/dist/fns/sortFns.cjs.map +1 -1
- package/dist/fns/sortFns.d.cts +48 -15
- package/dist/fns/sortFns.d.ts +48 -15
- package/dist/fns/sortFns.js +68 -22
- package/dist/fns/sortFns.js.map +1 -1
- package/dist/helpers/tableFeatures.cjs +5 -4
- package/dist/helpers/tableFeatures.cjs.map +1 -1
- package/dist/helpers/tableFeatures.d.cts +5 -4
- package/dist/helpers/tableFeatures.d.ts +5 -4
- package/dist/helpers/tableFeatures.js +5 -4
- package/dist/helpers/tableFeatures.js.map +1 -1
- package/dist/index.cjs +12 -0
- package/dist/index.d.cts +8 -8
- package/dist/index.d.ts +8 -8
- package/dist/index.js +4 -4
- package/dist/types/TableFeatures.d.cts +15 -7
- package/dist/types/TableFeatures.d.ts +15 -7
- package/dist/types/type-utils.d.cts +8 -1
- package/dist/types/type-utils.d.ts +8 -1
- package/package.json +1 -1
- package/skills/api-not-found/SKILL.md +1 -1
- package/skills/client-vs-server/SKILL.md +1 -1
- package/skills/column-faceting/SKILL.md +11 -5
- package/skills/column-filtering/SKILL.md +8 -3
- 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 +3 -3
- package/skills/grouping/SKILL.md +8 -3
- package/skills/migrate-v8-to-v9/SKILL.md +7 -7
- 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 +9 -3
- package/skills/table-features/SKILL.md +16 -13
- package/skills/typescript/SKILL.md +1 -1
- package/src/features/column-filtering/columnFilteringFeature.types.ts +60 -0
- package/src/features/column-filtering/columnFilteringFeature.utils.ts +33 -19
- package/src/features/column-filtering/createFilteredRowModel.ts +13 -3
- package/src/features/column-grouping/columnGroupingFeature.types.ts +63 -8
- package/src/features/column-grouping/columnGroupingFeature.utils.ts +43 -9
- package/src/features/column-grouping/createGroupedRowModel.ts +6 -3
- package/src/features/global-filtering/globalFilteringFeature.utils.ts +8 -0
- package/src/features/row-sorting/createSortedRowModel.ts +6 -2
- package/src/features/row-sorting/rowSortingFeature.types.ts +53 -1
- package/src/features/row-sorting/rowSortingFeature.utils.ts +45 -13
- package/src/fns/aggregationFns.ts +204 -146
- package/src/fns/filterFns.ts +361 -283
- package/src/fns/sortFns.ts +95 -78
- package/src/helpers/tableFeatures.ts +5 -4
- package/src/types/TableFeatures.ts +15 -7
- package/src/types/type-utils.ts +8 -0
package/dist/fns/sortFns.cjs
CHANGED
|
@@ -8,55 +8,93 @@
|
|
|
8
8
|
*/
|
|
9
9
|
const reSplitAlphaNumeric = /([0-9]+)/gm;
|
|
10
10
|
/**
|
|
11
|
+
* Builds a `SortFn` from a value-level comparator plus an optional
|
|
12
|
+
* `resolveDataValue` normalizer.
|
|
13
|
+
*
|
|
14
|
+
* The `sort` comparator receives both rows' data values, each already passed
|
|
15
|
+
* through `resolveDataValue` when one is defined. Keeping normalization in the
|
|
16
|
+
* resolver means a variant of an existing sorting function only has to swap
|
|
17
|
+
* the resolver, not re-implement the comparison.
|
|
18
|
+
*
|
|
19
|
+
* The definition is attached to the returned function, so a variant can be
|
|
20
|
+
* created by spreading a built-in sorting function and overriding what
|
|
21
|
+
* differs:
|
|
22
|
+
*
|
|
23
|
+
* ```ts
|
|
24
|
+
* const stripDiacritics = (value: string) =>
|
|
25
|
+
* value.normalize('NFD').replace(/\p{Diacritic}/gu, '')
|
|
26
|
+
*
|
|
27
|
+
* const alphanumericIgnoreDiacritics = constructSortFn({
|
|
28
|
+
* ...sortFn_alphanumeric,
|
|
29
|
+
* resolveDataValue: (value) =>
|
|
30
|
+
* stripDiacritics(sortFn_alphanumeric.resolveDataValue!(value)),
|
|
31
|
+
* })
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
function constructSortFn(def) {
|
|
35
|
+
const sortFn = Object.assign((rowA, rowB, columnId) => {
|
|
36
|
+
let dataValueA = rowA.getValue(columnId);
|
|
37
|
+
let dataValueB = rowB.getValue(columnId);
|
|
38
|
+
const resolveDataValue = sortFn.resolveDataValue;
|
|
39
|
+
if (resolveDataValue) {
|
|
40
|
+
dataValueA = resolveDataValue(dataValueA);
|
|
41
|
+
dataValueB = resolveDataValue(dataValueB);
|
|
42
|
+
}
|
|
43
|
+
return sortFn.sort(dataValueA, dataValueB, rowA, rowB, columnId);
|
|
44
|
+
}, def);
|
|
45
|
+
return sortFn;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
11
48
|
* Sorts rows with the built-in alphanumeric strategy.
|
|
12
49
|
*
|
|
13
50
|
* This comparator returns ascending-order results; descending order is applied by the sorting row model.
|
|
14
51
|
*/
|
|
15
|
-
const sortFn_alphanumeric = (
|
|
16
|
-
|
|
17
|
-
|
|
52
|
+
const sortFn_alphanumeric = constructSortFn({
|
|
53
|
+
resolveDataValue: (dataValue) => toString(dataValue).toLowerCase(),
|
|
54
|
+
sort: (dataValueA, dataValueB) => compareAlphanumeric(dataValueA, dataValueB)
|
|
55
|
+
});
|
|
18
56
|
/**
|
|
19
57
|
* Sorts rows with the built-in alphanumeric case sensitive strategy.
|
|
20
58
|
*
|
|
21
59
|
* This comparator returns ascending-order results; descending order is applied by the sorting row model.
|
|
22
60
|
*/
|
|
23
|
-
const sortFn_alphanumericCaseSensitive = (
|
|
24
|
-
|
|
25
|
-
|
|
61
|
+
const sortFn_alphanumericCaseSensitive = constructSortFn({
|
|
62
|
+
resolveDataValue: (dataValue) => toString(dataValue),
|
|
63
|
+
sort: (dataValueA, dataValueB) => compareAlphanumeric(dataValueA, dataValueB)
|
|
64
|
+
});
|
|
26
65
|
/**
|
|
27
66
|
* Sorts rows with the built-in text strategy.
|
|
28
67
|
*
|
|
29
68
|
* This comparator returns ascending-order results; descending order is applied by the sorting row model.
|
|
30
69
|
*/
|
|
31
|
-
const sortFn_text = (
|
|
32
|
-
|
|
33
|
-
|
|
70
|
+
const sortFn_text = constructSortFn({
|
|
71
|
+
resolveDataValue: (dataValue) => toString(dataValue).toLowerCase(),
|
|
72
|
+
sort: (dataValueA, dataValueB) => compareBasic(dataValueA, dataValueB)
|
|
73
|
+
});
|
|
34
74
|
/**
|
|
35
75
|
* Sorts rows with the built-in text case sensitive strategy.
|
|
36
76
|
*
|
|
37
77
|
* This comparator returns ascending-order results; descending order is applied by the sorting row model.
|
|
38
78
|
*/
|
|
39
|
-
const sortFn_textCaseSensitive = (
|
|
40
|
-
|
|
41
|
-
|
|
79
|
+
const sortFn_textCaseSensitive = constructSortFn({
|
|
80
|
+
resolveDataValue: (dataValue) => toString(dataValue),
|
|
81
|
+
sort: (dataValueA, dataValueB) => compareBasic(dataValueA, dataValueB)
|
|
82
|
+
});
|
|
42
83
|
/**
|
|
43
84
|
* Sorts rows with the built-in datetime strategy.
|
|
44
85
|
*
|
|
45
86
|
* This comparator returns ascending-order results; descending order is applied by the sorting row model.
|
|
46
87
|
*/
|
|
47
|
-
const sortFn_datetime = (
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
};
|
|
88
|
+
const sortFn_datetime = constructSortFn({
|
|
89
|
+
resolveDataValue: (dataValue) => toDateSortValue(dataValue),
|
|
90
|
+
sort: (dataValueA, dataValueB) => dataValueA > dataValueB ? 1 : dataValueA < dataValueB ? -1 : 0
|
|
91
|
+
});
|
|
52
92
|
/**
|
|
53
93
|
* Sorts rows with the built-in basic strategy.
|
|
54
94
|
*
|
|
55
95
|
* This comparator returns ascending-order results; descending order is applied by the sorting row model.
|
|
56
96
|
*/
|
|
57
|
-
const sortFn_basic = (
|
|
58
|
-
return compareBasic(rowA.getValue(columnId), rowB.getValue(columnId));
|
|
59
|
-
};
|
|
97
|
+
const sortFn_basic = constructSortFn({ sort: (dataValueA, dataValueB) => compareBasic(dataValueA, dataValueB) });
|
|
60
98
|
function compareBasic(a, b) {
|
|
61
99
|
return a === b ? 0 : a > b ? 1 : -1;
|
|
62
100
|
}
|
|
@@ -156,7 +194,15 @@ function countRemainingChunks(str, start) {
|
|
|
156
194
|
/**
|
|
157
195
|
* The built-in sorting function registry.
|
|
158
196
|
*
|
|
159
|
-
*
|
|
197
|
+
* Registering this full object opts out of tree-shaking: every built-in
|
|
198
|
+
* sorting function ends up in your bundle. Prefer importing the `sortFn_*`
|
|
199
|
+
* functions you actually use and registering just those in the `sortFns`
|
|
200
|
+
* slot, or passing them directly to the `sortFn` column option.
|
|
201
|
+
*
|
|
202
|
+
* @deprecated Import individual `sortFn_*` functions instead for a smaller
|
|
203
|
+
* bundle. This export still works and is not going away in v9, but built-in
|
|
204
|
+
* name resolution (including `sortFn: 'auto'`) only finds functions you
|
|
205
|
+
* register yourself.
|
|
160
206
|
*/
|
|
161
207
|
const sortFns = {
|
|
162
208
|
alphanumeric: sortFn_alphanumeric,
|
|
@@ -168,6 +214,7 @@ const sortFns = {
|
|
|
168
214
|
};
|
|
169
215
|
|
|
170
216
|
//#endregion
|
|
217
|
+
exports.constructSortFn = constructSortFn;
|
|
171
218
|
exports.reSplitAlphaNumeric = reSplitAlphaNumeric;
|
|
172
219
|
exports.sortFn_alphanumeric = sortFn_alphanumeric;
|
|
173
220
|
exports.sortFn_alphanumericCaseSensitive = sortFn_alphanumericCaseSensitive;
|
package/dist/fns/sortFns.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sortFns.cjs","names":[],"sources":["../../src/fns/sortFns.ts"],"sourcesContent":["import type { RowData } from '../types/type-utils'\nimport type { TableFeatures } from '../types/TableFeatures'\nimport type { Row } from '../types/Row'\n\n/**\n * Regular expression used to split mixed text and numeric chunks.\n *\n * The alphanumeric sort functions use these chunks for natural sorting of\n * strings like `item2` before `item10`.\n */\nexport const reSplitAlphaNumeric = /([0-9]+)/gm\n\n/**\n * Sorts rows with the built-in alphanumeric strategy.\n *\n * This comparator returns ascending-order results; descending order is applied by the sorting row model.\n */\nexport const sortFn_alphanumeric = <\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(\n rowA: Row<TFeatures, TData>,\n rowB: Row<TFeatures, TData>,\n columnId: string,\n) => {\n return compareAlphanumeric(\n toString(rowA.getValue(columnId)).toLowerCase(),\n toString(rowB.getValue(columnId)).toLowerCase(),\n )\n}\n\n/**\n * Sorts rows with the built-in alphanumeric case sensitive strategy.\n *\n * This comparator returns ascending-order results; descending order is applied by the sorting row model.\n */\nexport const sortFn_alphanumericCaseSensitive = <\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(\n rowA: Row<TFeatures, TData>,\n rowB: Row<TFeatures, TData>,\n columnId: string,\n) => {\n return compareAlphanumeric(\n toString(rowA.getValue(columnId)),\n toString(rowB.getValue(columnId)),\n )\n}\n\n// The text filter is more basic (less numeric support)\n// but is much faster\n/**\n * Sorts rows with the built-in text strategy.\n *\n * This comparator returns ascending-order results; descending order is applied by the sorting row model.\n */\nexport const sortFn_text = <\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(\n rowA: Row<TFeatures, TData>,\n rowB: Row<TFeatures, TData>,\n columnId: string,\n) => {\n return compareBasic(\n toString(rowA.getValue(columnId)).toLowerCase(),\n toString(rowB.getValue(columnId)).toLowerCase(),\n )\n}\n\n// The text filter is more basic (less numeric support)\n// but is much faster\n/**\n * Sorts rows with the built-in text case sensitive strategy.\n *\n * This comparator returns ascending-order results; descending order is applied by the sorting row model.\n */\nexport const sortFn_textCaseSensitive = <\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(\n rowA: Row<TFeatures, TData>,\n rowB: Row<TFeatures, TData>,\n columnId: string,\n) => {\n return compareBasic(\n toString(rowA.getValue(columnId)),\n toString(rowB.getValue(columnId)),\n )\n}\n\n/**\n * Sorts rows with the built-in datetime strategy.\n *\n * This comparator returns ascending-order results; descending order is applied by the sorting row model.\n */\nexport const sortFn_datetime = <\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(\n rowA: Row<TFeatures, TData>,\n rowB: Row<TFeatures, TData>,\n columnId: string,\n) => {\n const a = toDateSortValue(rowA.getValue(columnId))\n const b = toDateSortValue(rowB.getValue(columnId))\n\n // Can handle nullish values\n // Use > and < because == (and ===) doesn't work with\n // Date objects (would require calling getTime()).\n return a > b ? 1 : a < b ? -1 : 0\n}\n\n/**\n * Sorts rows with the built-in basic strategy.\n *\n * This comparator returns ascending-order results; descending order is applied by the sorting row model.\n */\nexport const sortFn_basic = <\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(\n rowA: Row<TFeatures, TData>,\n rowB: Row<TFeatures, TData>,\n columnId: string,\n) => {\n return compareBasic(rowA.getValue(columnId), rowB.getValue(columnId))\n}\n\n// Utils\n\nfunction compareBasic(a: any, b: any) {\n return a === b ? 0 : a > b ? 1 : -1\n}\n\nfunction toDateSortValue(value: any) {\n return value instanceof Date ? value.getTime() : value\n}\n\nfunction toString(a: any) {\n if (typeof a === 'number') {\n if (isNaN(a) || a === Infinity || a === -Infinity) {\n return ''\n }\n return String(a)\n }\n if (typeof a === 'string') {\n return a\n }\n return ''\n}\n\n// Mixed sorting is slow, but very inclusive of many edge cases.\n// It handles numbers, mixed alphanumeric combinations, and even\n// null, undefined, and Infinity\nfunction compareAlphanumeric(aStr: string, bStr: string) {\n let ai = 0\n let bi = 0\n const aLen = aStr.length\n const bLen = bStr.length\n\n while (ai < aLen && bi < bLen) {\n const aIsNumeric = isDigit(aStr.charCodeAt(ai))\n const bIsNumeric = isDigit(bStr.charCodeAt(bi))\n\n const aEnd = findChunkEnd(aStr, ai, aIsNumeric)\n const bEnd = findChunkEnd(bStr, bi, bIsNumeric)\n\n // Both are string chunks\n if (!aIsNumeric && !bIsNumeric) {\n const stringComparison = compareStringChunks(\n aStr,\n ai,\n aEnd,\n bStr,\n bi,\n bEnd,\n )\n if (stringComparison) {\n return stringComparison\n }\n ai = aEnd\n bi = bEnd\n continue\n }\n\n // One is a string chunk, one is a number chunk — the string sorts first\n if (aIsNumeric !== bIsNumeric) {\n return aIsNumeric ? 1 : -1\n }\n\n // Both are numeric chunks\n const numericComparison = compareNumericChunks(\n aStr,\n ai,\n aEnd,\n bStr,\n bi,\n bEnd,\n )\n if (numericComparison) {\n return numericComparison\n }\n\n ai = aEnd\n bi = bEnd\n }\n\n // One side is exhausted — compare the counts of remaining non-empty chunks\n return countRemainingChunks(aStr, ai) - countRemainingChunks(bStr, bi)\n}\n\nfunction isDigit(charCode: number) {\n return charCode >= 48 && charCode <= 57\n}\n\nfunction findChunkEnd(str: string, start: number, isNumeric: boolean) {\n let end = start + 1\n while (end < str.length && isDigit(str.charCodeAt(end)) === isNumeric) {\n end++\n }\n return end\n}\n\nfunction compareStringChunks(\n aStr: string,\n aStart: number,\n aEnd: number,\n bStr: string,\n bStart: number,\n bEnd: number,\n) {\n const aLength = aEnd - aStart\n const bLength = bEnd - bStart\n const minLength = aLength < bLength ? aLength : bLength\n\n for (let i = 0; i < minLength; i++) {\n const aCode = aStr.charCodeAt(aStart + i)\n const bCode = bStr.charCodeAt(bStart + i)\n\n if (aCode > bCode) {\n return 1\n }\n if (bCode > aCode) {\n return -1\n }\n }\n\n if (aLength > bLength) {\n return 1\n }\n if (bLength > aLength) {\n return -1\n }\n return 0\n}\n\nfunction compareNumericChunks(\n aStr: string,\n aStart: number,\n aEnd: number,\n bStr: string,\n bStart: number,\n bEnd: number,\n) {\n let aSignificantStart = aStart\n while (\n aSignificantStart < aEnd &&\n aStr.charCodeAt(aSignificantStart) === 48\n ) {\n aSignificantStart++\n }\n\n let bSignificantStart = bStart\n while (\n bSignificantStart < bEnd &&\n bStr.charCodeAt(bSignificantStart) === 48\n ) {\n bSignificantStart++\n }\n\n const aSignificantLength = aEnd - aSignificantStart\n const bSignificantLength = bEnd - bSignificantStart\n\n if (aSignificantLength === 0 && bSignificantLength === 0) {\n return 0\n }\n\n if (aSignificantLength <= 15 && bSignificantLength <= 15) {\n const an = parseSmallInt(aStr, aSignificantStart, aEnd)\n const bn = parseSmallInt(bStr, bSignificantStart, bEnd)\n\n if (an > bn) {\n return 1\n }\n if (bn > an) {\n return -1\n }\n return 0\n }\n\n // Preserve parseInt precision-collapse behavior for unusually large chunks.\n const an = parseInt(aStr.slice(aStart, aEnd), 10)\n const bn = parseInt(bStr.slice(bStart, bEnd), 10)\n\n if (an > bn) {\n return 1\n }\n if (bn > an) {\n return -1\n }\n return 0\n}\n\nfunction parseSmallInt(str: string, start: number, end: number) {\n let result = 0\n for (let i = start; i < end; i++) {\n result = result * 10 + str.charCodeAt(i) - 48\n }\n return result\n}\n\nfunction countRemainingChunks(str: string, start: number) {\n let count = 0\n let index = start\n\n while (index < str.length) {\n count++\n index = findChunkEnd(str, index, isDigit(str.charCodeAt(index)))\n }\n\n return count\n}\n\n// Exports\n\n/**\n * The built-in sorting function registry.\n *\n * Pass this object to sorted row model creation or extend it with custom sorting functions.\n */\nexport const sortFns = {\n alphanumeric: sortFn_alphanumeric,\n alphanumericCaseSensitive: sortFn_alphanumericCaseSensitive,\n basic: sortFn_basic,\n datetime: sortFn_datetime,\n text: sortFn_text,\n textCaseSensitive: sortFn_textCaseSensitive,\n}\n\nexport type BuiltInSortFn = keyof typeof sortFns\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"sortFns.cjs","names":[],"sources":["../../src/fns/sortFns.ts"],"sourcesContent":["import type {\n CreatedSortFn,\n SortFnDef,\n} from '../features/row-sorting/rowSortingFeature.types'\nimport type { RowData } from '../types/type-utils'\nimport type { TableFeatures } from '../types/TableFeatures'\nimport type { Row } from '../types/Row'\n\n/**\n * Regular expression used to split mixed text and numeric chunks.\n *\n * The alphanumeric sort functions use these chunks for natural sorting of\n * strings like `item2` before `item10`.\n */\nexport const reSplitAlphaNumeric = /([0-9]+)/gm\n\n/**\n * Builds a `SortFn` from a value-level comparator plus an optional\n * `resolveDataValue` normalizer.\n *\n * The `sort` comparator receives both rows' data values, each already passed\n * through `resolveDataValue` when one is defined. Keeping normalization in the\n * resolver means a variant of an existing sorting function only has to swap\n * the resolver, not re-implement the comparison.\n *\n * The definition is attached to the returned function, so a variant can be\n * created by spreading a built-in sorting function and overriding what\n * differs:\n *\n * ```ts\n * const stripDiacritics = (value: string) =>\n * value.normalize('NFD').replace(/\\p{Diacritic}/gu, '')\n *\n * const alphanumericIgnoreDiacritics = constructSortFn({\n * ...sortFn_alphanumeric,\n * resolveDataValue: (value) =>\n * stripDiacritics(sortFn_alphanumeric.resolveDataValue!(value)),\n * })\n * ```\n */\nexport function constructSortFn<\n TFeatures extends TableFeatures = any,\n TData extends RowData = any,\n>(def: SortFnDef<TFeatures, TData>): CreatedSortFn<TFeatures, TData> {\n const sortFn: CreatedSortFn<TFeatures, TData> = Object.assign(\n <TRowFeatures extends TableFeatures, TRowData extends RowData>(\n rowA: Row<TRowFeatures, TRowData>,\n rowB: Row<TRowFeatures, TRowData>,\n columnId: string,\n ): number => {\n let dataValueA = rowA.getValue(columnId)\n let dataValueB = rowB.getValue(columnId)\n const resolveDataValue = sortFn.resolveDataValue\n if (resolveDataValue) {\n dataValueA = resolveDataValue(dataValueA)\n dataValueB = resolveDataValue(dataValueB)\n }\n // The def's comparator is typed against the factory's TFeatures/TData;\n // the caller's row generics are erased at this boundary.\n return sortFn.sort(\n dataValueA,\n dataValueB,\n rowA as any,\n rowB as any,\n columnId,\n )\n },\n def,\n )\n return sortFn\n}\n\n/**\n * Sorts rows with the built-in alphanumeric strategy.\n *\n * This comparator returns ascending-order results; descending order is applied by the sorting row model.\n */\nexport const sortFn_alphanumeric = constructSortFn({\n resolveDataValue: (dataValue) => toString(dataValue).toLowerCase(),\n sort: (dataValueA, dataValueB) => compareAlphanumeric(dataValueA, dataValueB),\n})\n\n/**\n * Sorts rows with the built-in alphanumeric case sensitive strategy.\n *\n * This comparator returns ascending-order results; descending order is applied by the sorting row model.\n */\nexport const sortFn_alphanumericCaseSensitive = constructSortFn({\n resolveDataValue: (dataValue) => toString(dataValue),\n sort: (dataValueA, dataValueB) => compareAlphanumeric(dataValueA, dataValueB),\n})\n\n// The text sort is more basic (less numeric support)\n// but is much faster\n/**\n * Sorts rows with the built-in text strategy.\n *\n * This comparator returns ascending-order results; descending order is applied by the sorting row model.\n */\nexport const sortFn_text = constructSortFn({\n resolveDataValue: (dataValue) => toString(dataValue).toLowerCase(),\n sort: (dataValueA, dataValueB) => compareBasic(dataValueA, dataValueB),\n})\n\n// The text sort is more basic (less numeric support)\n// but is much faster\n/**\n * Sorts rows with the built-in text case sensitive strategy.\n *\n * This comparator returns ascending-order results; descending order is applied by the sorting row model.\n */\nexport const sortFn_textCaseSensitive = constructSortFn({\n resolveDataValue: (dataValue) => toString(dataValue),\n sort: (dataValueA, dataValueB) => compareBasic(dataValueA, dataValueB),\n})\n\n/**\n * Sorts rows with the built-in datetime strategy.\n *\n * This comparator returns ascending-order results; descending order is applied by the sorting row model.\n */\nexport const sortFn_datetime = constructSortFn({\n resolveDataValue: (dataValue) => toDateSortValue(dataValue),\n // Can handle nullish values\n // Use > and < because == (and ===) doesn't work with\n // Date objects (would require calling getTime()).\n sort: (dataValueA, dataValueB) =>\n dataValueA > dataValueB ? 1 : dataValueA < dataValueB ? -1 : 0,\n})\n\n/**\n * Sorts rows with the built-in basic strategy.\n *\n * This comparator returns ascending-order results; descending order is applied by the sorting row model.\n */\nexport const sortFn_basic = constructSortFn({\n sort: (dataValueA, dataValueB) => compareBasic(dataValueA, dataValueB),\n})\n\n// Utils\n\nfunction compareBasic(a: any, b: any) {\n return a === b ? 0 : a > b ? 1 : -1\n}\n\nfunction toDateSortValue(value: any) {\n return value instanceof Date ? value.getTime() : value\n}\n\nfunction toString(a: any) {\n if (typeof a === 'number') {\n if (isNaN(a) || a === Infinity || a === -Infinity) {\n return ''\n }\n return String(a)\n }\n if (typeof a === 'string') {\n return a\n }\n return ''\n}\n\n// Mixed sorting is slow, but very inclusive of many edge cases.\n// It handles numbers, mixed alphanumeric combinations, and even\n// null, undefined, and Infinity\nfunction compareAlphanumeric(aStr: string, bStr: string) {\n let ai = 0\n let bi = 0\n const aLen = aStr.length\n const bLen = bStr.length\n\n while (ai < aLen && bi < bLen) {\n const aIsNumeric = isDigit(aStr.charCodeAt(ai))\n const bIsNumeric = isDigit(bStr.charCodeAt(bi))\n\n const aEnd = findChunkEnd(aStr, ai, aIsNumeric)\n const bEnd = findChunkEnd(bStr, bi, bIsNumeric)\n\n // Both are string chunks\n if (!aIsNumeric && !bIsNumeric) {\n const stringComparison = compareStringChunks(\n aStr,\n ai,\n aEnd,\n bStr,\n bi,\n bEnd,\n )\n if (stringComparison) {\n return stringComparison\n }\n ai = aEnd\n bi = bEnd\n continue\n }\n\n // One is a string chunk, one is a number chunk — the string sorts first\n if (aIsNumeric !== bIsNumeric) {\n return aIsNumeric ? 1 : -1\n }\n\n // Both are numeric chunks\n const numericComparison = compareNumericChunks(\n aStr,\n ai,\n aEnd,\n bStr,\n bi,\n bEnd,\n )\n if (numericComparison) {\n return numericComparison\n }\n\n ai = aEnd\n bi = bEnd\n }\n\n // One side is exhausted — compare the counts of remaining non-empty chunks\n return countRemainingChunks(aStr, ai) - countRemainingChunks(bStr, bi)\n}\n\nfunction isDigit(charCode: number) {\n return charCode >= 48 && charCode <= 57\n}\n\nfunction findChunkEnd(str: string, start: number, isNumeric: boolean) {\n let end = start + 1\n while (end < str.length && isDigit(str.charCodeAt(end)) === isNumeric) {\n end++\n }\n return end\n}\n\nfunction compareStringChunks(\n aStr: string,\n aStart: number,\n aEnd: number,\n bStr: string,\n bStart: number,\n bEnd: number,\n) {\n const aLength = aEnd - aStart\n const bLength = bEnd - bStart\n const minLength = aLength < bLength ? aLength : bLength\n\n for (let i = 0; i < minLength; i++) {\n const aCode = aStr.charCodeAt(aStart + i)\n const bCode = bStr.charCodeAt(bStart + i)\n\n if (aCode > bCode) {\n return 1\n }\n if (bCode > aCode) {\n return -1\n }\n }\n\n if (aLength > bLength) {\n return 1\n }\n if (bLength > aLength) {\n return -1\n }\n return 0\n}\n\nfunction compareNumericChunks(\n aStr: string,\n aStart: number,\n aEnd: number,\n bStr: string,\n bStart: number,\n bEnd: number,\n) {\n let aSignificantStart = aStart\n while (\n aSignificantStart < aEnd &&\n aStr.charCodeAt(aSignificantStart) === 48\n ) {\n aSignificantStart++\n }\n\n let bSignificantStart = bStart\n while (\n bSignificantStart < bEnd &&\n bStr.charCodeAt(bSignificantStart) === 48\n ) {\n bSignificantStart++\n }\n\n const aSignificantLength = aEnd - aSignificantStart\n const bSignificantLength = bEnd - bSignificantStart\n\n if (aSignificantLength === 0 && bSignificantLength === 0) {\n return 0\n }\n\n if (aSignificantLength <= 15 && bSignificantLength <= 15) {\n const an = parseSmallInt(aStr, aSignificantStart, aEnd)\n const bn = parseSmallInt(bStr, bSignificantStart, bEnd)\n\n if (an > bn) {\n return 1\n }\n if (bn > an) {\n return -1\n }\n return 0\n }\n\n // Preserve parseInt precision-collapse behavior for unusually large chunks.\n const an = parseInt(aStr.slice(aStart, aEnd), 10)\n const bn = parseInt(bStr.slice(bStart, bEnd), 10)\n\n if (an > bn) {\n return 1\n }\n if (bn > an) {\n return -1\n }\n return 0\n}\n\nfunction parseSmallInt(str: string, start: number, end: number) {\n let result = 0\n for (let i = start; i < end; i++) {\n result = result * 10 + str.charCodeAt(i) - 48\n }\n return result\n}\n\nfunction countRemainingChunks(str: string, start: number) {\n let count = 0\n let index = start\n\n while (index < str.length) {\n count++\n index = findChunkEnd(str, index, isDigit(str.charCodeAt(index)))\n }\n\n return count\n}\n\n// Exports\n\n/**\n * The built-in sorting function registry.\n *\n * Registering this full object opts out of tree-shaking: every built-in\n * sorting function ends up in your bundle. Prefer importing the `sortFn_*`\n * functions you actually use and registering just those in the `sortFns`\n * slot, or passing them directly to the `sortFn` column option.\n *\n * @deprecated Import individual `sortFn_*` functions instead for a smaller\n * bundle. This export still works and is not going away in v9, but built-in\n * name resolution (including `sortFn: 'auto'`) only finds functions you\n * register yourself.\n */\nexport const sortFns = {\n alphanumeric: sortFn_alphanumeric,\n alphanumericCaseSensitive: sortFn_alphanumericCaseSensitive,\n basic: sortFn_basic,\n datetime: sortFn_datetime,\n text: sortFn_text,\n textCaseSensitive: sortFn_textCaseSensitive,\n}\n\nexport type BuiltInSortFn = keyof typeof sortFns\n"],"mappings":"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"}
|
package/dist/fns/sortFns.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { RowData } from "../types/type-utils.cjs";
|
|
2
|
-
import {
|
|
2
|
+
import { CreatedSortFn, SortFnDef } from "../features/row-sorting/rowSortingFeature.types.cjs";
|
|
3
3
|
import { TableFeatures } from "../types/TableFeatures.cjs";
|
|
4
4
|
|
|
5
5
|
//#region src/fns/sortFns.d.ts
|
|
@@ -10,56 +10,89 @@ import { TableFeatures } from "../types/TableFeatures.cjs";
|
|
|
10
10
|
* strings like `item2` before `item10`.
|
|
11
11
|
*/
|
|
12
12
|
declare const reSplitAlphaNumeric: RegExp;
|
|
13
|
+
/**
|
|
14
|
+
* Builds a `SortFn` from a value-level comparator plus an optional
|
|
15
|
+
* `resolveDataValue` normalizer.
|
|
16
|
+
*
|
|
17
|
+
* The `sort` comparator receives both rows' data values, each already passed
|
|
18
|
+
* through `resolveDataValue` when one is defined. Keeping normalization in the
|
|
19
|
+
* resolver means a variant of an existing sorting function only has to swap
|
|
20
|
+
* the resolver, not re-implement the comparison.
|
|
21
|
+
*
|
|
22
|
+
* The definition is attached to the returned function, so a variant can be
|
|
23
|
+
* created by spreading a built-in sorting function and overriding what
|
|
24
|
+
* differs:
|
|
25
|
+
*
|
|
26
|
+
* ```ts
|
|
27
|
+
* const stripDiacritics = (value: string) =>
|
|
28
|
+
* value.normalize('NFD').replace(/\p{Diacritic}/gu, '')
|
|
29
|
+
*
|
|
30
|
+
* const alphanumericIgnoreDiacritics = constructSortFn({
|
|
31
|
+
* ...sortFn_alphanumeric,
|
|
32
|
+
* resolveDataValue: (value) =>
|
|
33
|
+
* stripDiacritics(sortFn_alphanumeric.resolveDataValue!(value)),
|
|
34
|
+
* })
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
declare function constructSortFn<TFeatures extends TableFeatures = any, TData extends RowData = any>(def: SortFnDef<TFeatures, TData>): CreatedSortFn<TFeatures, TData>;
|
|
13
38
|
/**
|
|
14
39
|
* Sorts rows with the built-in alphanumeric strategy.
|
|
15
40
|
*
|
|
16
41
|
* This comparator returns ascending-order results; descending order is applied by the sorting row model.
|
|
17
42
|
*/
|
|
18
|
-
declare const sortFn_alphanumeric: <
|
|
43
|
+
declare const sortFn_alphanumeric: CreatedSortFn<any, any>;
|
|
19
44
|
/**
|
|
20
45
|
* Sorts rows with the built-in alphanumeric case sensitive strategy.
|
|
21
46
|
*
|
|
22
47
|
* This comparator returns ascending-order results; descending order is applied by the sorting row model.
|
|
23
48
|
*/
|
|
24
|
-
declare const sortFn_alphanumericCaseSensitive: <
|
|
49
|
+
declare const sortFn_alphanumericCaseSensitive: CreatedSortFn<any, any>;
|
|
25
50
|
/**
|
|
26
51
|
* Sorts rows with the built-in text strategy.
|
|
27
52
|
*
|
|
28
53
|
* This comparator returns ascending-order results; descending order is applied by the sorting row model.
|
|
29
54
|
*/
|
|
30
|
-
declare const sortFn_text: <
|
|
55
|
+
declare const sortFn_text: CreatedSortFn<any, any>;
|
|
31
56
|
/**
|
|
32
57
|
* Sorts rows with the built-in text case sensitive strategy.
|
|
33
58
|
*
|
|
34
59
|
* This comparator returns ascending-order results; descending order is applied by the sorting row model.
|
|
35
60
|
*/
|
|
36
|
-
declare const sortFn_textCaseSensitive: <
|
|
61
|
+
declare const sortFn_textCaseSensitive: CreatedSortFn<any, any>;
|
|
37
62
|
/**
|
|
38
63
|
* Sorts rows with the built-in datetime strategy.
|
|
39
64
|
*
|
|
40
65
|
* This comparator returns ascending-order results; descending order is applied by the sorting row model.
|
|
41
66
|
*/
|
|
42
|
-
declare const sortFn_datetime: <
|
|
67
|
+
declare const sortFn_datetime: CreatedSortFn<any, any>;
|
|
43
68
|
/**
|
|
44
69
|
* Sorts rows with the built-in basic strategy.
|
|
45
70
|
*
|
|
46
71
|
* This comparator returns ascending-order results; descending order is applied by the sorting row model.
|
|
47
72
|
*/
|
|
48
|
-
declare const sortFn_basic: <
|
|
73
|
+
declare const sortFn_basic: CreatedSortFn<any, any>;
|
|
49
74
|
/**
|
|
50
75
|
* The built-in sorting function registry.
|
|
51
76
|
*
|
|
52
|
-
*
|
|
77
|
+
* Registering this full object opts out of tree-shaking: every built-in
|
|
78
|
+
* sorting function ends up in your bundle. Prefer importing the `sortFn_*`
|
|
79
|
+
* functions you actually use and registering just those in the `sortFns`
|
|
80
|
+
* slot, or passing them directly to the `sortFn` column option.
|
|
81
|
+
*
|
|
82
|
+
* @deprecated Import individual `sortFn_*` functions instead for a smaller
|
|
83
|
+
* bundle. This export still works and is not going away in v9, but built-in
|
|
84
|
+
* name resolution (including `sortFn: 'auto'`) only finds functions you
|
|
85
|
+
* register yourself.
|
|
53
86
|
*/
|
|
54
87
|
declare const sortFns: {
|
|
55
|
-
alphanumeric: <
|
|
56
|
-
alphanumericCaseSensitive: <
|
|
57
|
-
basic: <
|
|
58
|
-
datetime: <
|
|
59
|
-
text: <
|
|
60
|
-
textCaseSensitive: <
|
|
88
|
+
alphanumeric: CreatedSortFn<any, any>;
|
|
89
|
+
alphanumericCaseSensitive: CreatedSortFn<any, any>;
|
|
90
|
+
basic: CreatedSortFn<any, any>;
|
|
91
|
+
datetime: CreatedSortFn<any, any>;
|
|
92
|
+
text: CreatedSortFn<any, any>;
|
|
93
|
+
textCaseSensitive: CreatedSortFn<any, any>;
|
|
61
94
|
};
|
|
62
95
|
type BuiltInSortFn = keyof typeof sortFns;
|
|
63
96
|
//#endregion
|
|
64
|
-
export { BuiltInSortFn, reSplitAlphaNumeric, sortFn_alphanumeric, sortFn_alphanumericCaseSensitive, sortFn_basic, sortFn_datetime, sortFn_text, sortFn_textCaseSensitive, sortFns };
|
|
97
|
+
export { BuiltInSortFn, constructSortFn, reSplitAlphaNumeric, sortFn_alphanumeric, sortFn_alphanumericCaseSensitive, sortFn_basic, sortFn_datetime, sortFn_text, sortFn_textCaseSensitive, sortFns };
|
|
65
98
|
//# sourceMappingURL=sortFns.d.cts.map
|
package/dist/fns/sortFns.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { RowData } from "../types/type-utils.js";
|
|
2
|
-
import {
|
|
2
|
+
import { CreatedSortFn, SortFnDef } from "../features/row-sorting/rowSortingFeature.types.js";
|
|
3
3
|
import { TableFeatures } from "../types/TableFeatures.js";
|
|
4
4
|
|
|
5
5
|
//#region src/fns/sortFns.d.ts
|
|
@@ -10,56 +10,89 @@ import { TableFeatures } from "../types/TableFeatures.js";
|
|
|
10
10
|
* strings like `item2` before `item10`.
|
|
11
11
|
*/
|
|
12
12
|
declare const reSplitAlphaNumeric: RegExp;
|
|
13
|
+
/**
|
|
14
|
+
* Builds a `SortFn` from a value-level comparator plus an optional
|
|
15
|
+
* `resolveDataValue` normalizer.
|
|
16
|
+
*
|
|
17
|
+
* The `sort` comparator receives both rows' data values, each already passed
|
|
18
|
+
* through `resolveDataValue` when one is defined. Keeping normalization in the
|
|
19
|
+
* resolver means a variant of an existing sorting function only has to swap
|
|
20
|
+
* the resolver, not re-implement the comparison.
|
|
21
|
+
*
|
|
22
|
+
* The definition is attached to the returned function, so a variant can be
|
|
23
|
+
* created by spreading a built-in sorting function and overriding what
|
|
24
|
+
* differs:
|
|
25
|
+
*
|
|
26
|
+
* ```ts
|
|
27
|
+
* const stripDiacritics = (value: string) =>
|
|
28
|
+
* value.normalize('NFD').replace(/\p{Diacritic}/gu, '')
|
|
29
|
+
*
|
|
30
|
+
* const alphanumericIgnoreDiacritics = constructSortFn({
|
|
31
|
+
* ...sortFn_alphanumeric,
|
|
32
|
+
* resolveDataValue: (value) =>
|
|
33
|
+
* stripDiacritics(sortFn_alphanumeric.resolveDataValue!(value)),
|
|
34
|
+
* })
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
declare function constructSortFn<TFeatures extends TableFeatures = any, TData extends RowData = any>(def: SortFnDef<TFeatures, TData>): CreatedSortFn<TFeatures, TData>;
|
|
13
38
|
/**
|
|
14
39
|
* Sorts rows with the built-in alphanumeric strategy.
|
|
15
40
|
*
|
|
16
41
|
* This comparator returns ascending-order results; descending order is applied by the sorting row model.
|
|
17
42
|
*/
|
|
18
|
-
declare const sortFn_alphanumeric: <
|
|
43
|
+
declare const sortFn_alphanumeric: CreatedSortFn<any, any>;
|
|
19
44
|
/**
|
|
20
45
|
* Sorts rows with the built-in alphanumeric case sensitive strategy.
|
|
21
46
|
*
|
|
22
47
|
* This comparator returns ascending-order results; descending order is applied by the sorting row model.
|
|
23
48
|
*/
|
|
24
|
-
declare const sortFn_alphanumericCaseSensitive: <
|
|
49
|
+
declare const sortFn_alphanumericCaseSensitive: CreatedSortFn<any, any>;
|
|
25
50
|
/**
|
|
26
51
|
* Sorts rows with the built-in text strategy.
|
|
27
52
|
*
|
|
28
53
|
* This comparator returns ascending-order results; descending order is applied by the sorting row model.
|
|
29
54
|
*/
|
|
30
|
-
declare const sortFn_text: <
|
|
55
|
+
declare const sortFn_text: CreatedSortFn<any, any>;
|
|
31
56
|
/**
|
|
32
57
|
* Sorts rows with the built-in text case sensitive strategy.
|
|
33
58
|
*
|
|
34
59
|
* This comparator returns ascending-order results; descending order is applied by the sorting row model.
|
|
35
60
|
*/
|
|
36
|
-
declare const sortFn_textCaseSensitive: <
|
|
61
|
+
declare const sortFn_textCaseSensitive: CreatedSortFn<any, any>;
|
|
37
62
|
/**
|
|
38
63
|
* Sorts rows with the built-in datetime strategy.
|
|
39
64
|
*
|
|
40
65
|
* This comparator returns ascending-order results; descending order is applied by the sorting row model.
|
|
41
66
|
*/
|
|
42
|
-
declare const sortFn_datetime: <
|
|
67
|
+
declare const sortFn_datetime: CreatedSortFn<any, any>;
|
|
43
68
|
/**
|
|
44
69
|
* Sorts rows with the built-in basic strategy.
|
|
45
70
|
*
|
|
46
71
|
* This comparator returns ascending-order results; descending order is applied by the sorting row model.
|
|
47
72
|
*/
|
|
48
|
-
declare const sortFn_basic: <
|
|
73
|
+
declare const sortFn_basic: CreatedSortFn<any, any>;
|
|
49
74
|
/**
|
|
50
75
|
* The built-in sorting function registry.
|
|
51
76
|
*
|
|
52
|
-
*
|
|
77
|
+
* Registering this full object opts out of tree-shaking: every built-in
|
|
78
|
+
* sorting function ends up in your bundle. Prefer importing the `sortFn_*`
|
|
79
|
+
* functions you actually use and registering just those in the `sortFns`
|
|
80
|
+
* slot, or passing them directly to the `sortFn` column option.
|
|
81
|
+
*
|
|
82
|
+
* @deprecated Import individual `sortFn_*` functions instead for a smaller
|
|
83
|
+
* bundle. This export still works and is not going away in v9, but built-in
|
|
84
|
+
* name resolution (including `sortFn: 'auto'`) only finds functions you
|
|
85
|
+
* register yourself.
|
|
53
86
|
*/
|
|
54
87
|
declare const sortFns: {
|
|
55
|
-
alphanumeric: <
|
|
56
|
-
alphanumericCaseSensitive: <
|
|
57
|
-
basic: <
|
|
58
|
-
datetime: <
|
|
59
|
-
text: <
|
|
60
|
-
textCaseSensitive: <
|
|
88
|
+
alphanumeric: CreatedSortFn<any, any>;
|
|
89
|
+
alphanumericCaseSensitive: CreatedSortFn<any, any>;
|
|
90
|
+
basic: CreatedSortFn<any, any>;
|
|
91
|
+
datetime: CreatedSortFn<any, any>;
|
|
92
|
+
text: CreatedSortFn<any, any>;
|
|
93
|
+
textCaseSensitive: CreatedSortFn<any, any>;
|
|
61
94
|
};
|
|
62
95
|
type BuiltInSortFn = keyof typeof sortFns;
|
|
63
96
|
//#endregion
|
|
64
|
-
export { BuiltInSortFn, reSplitAlphaNumeric, sortFn_alphanumeric, sortFn_alphanumericCaseSensitive, sortFn_basic, sortFn_datetime, sortFn_text, sortFn_textCaseSensitive, sortFns };
|
|
97
|
+
export { BuiltInSortFn, constructSortFn, reSplitAlphaNumeric, sortFn_alphanumeric, sortFn_alphanumericCaseSensitive, sortFn_basic, sortFn_datetime, sortFn_text, sortFn_textCaseSensitive, sortFns };
|
|
65
98
|
//# sourceMappingURL=sortFns.d.ts.map
|
package/dist/fns/sortFns.js
CHANGED
|
@@ -7,55 +7,93 @@
|
|
|
7
7
|
*/
|
|
8
8
|
const reSplitAlphaNumeric = /([0-9]+)/gm;
|
|
9
9
|
/**
|
|
10
|
+
* Builds a `SortFn` from a value-level comparator plus an optional
|
|
11
|
+
* `resolveDataValue` normalizer.
|
|
12
|
+
*
|
|
13
|
+
* The `sort` comparator receives both rows' data values, each already passed
|
|
14
|
+
* through `resolveDataValue` when one is defined. Keeping normalization in the
|
|
15
|
+
* resolver means a variant of an existing sorting function only has to swap
|
|
16
|
+
* the resolver, not re-implement the comparison.
|
|
17
|
+
*
|
|
18
|
+
* The definition is attached to the returned function, so a variant can be
|
|
19
|
+
* created by spreading a built-in sorting function and overriding what
|
|
20
|
+
* differs:
|
|
21
|
+
*
|
|
22
|
+
* ```ts
|
|
23
|
+
* const stripDiacritics = (value: string) =>
|
|
24
|
+
* value.normalize('NFD').replace(/\p{Diacritic}/gu, '')
|
|
25
|
+
*
|
|
26
|
+
* const alphanumericIgnoreDiacritics = constructSortFn({
|
|
27
|
+
* ...sortFn_alphanumeric,
|
|
28
|
+
* resolveDataValue: (value) =>
|
|
29
|
+
* stripDiacritics(sortFn_alphanumeric.resolveDataValue!(value)),
|
|
30
|
+
* })
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
function constructSortFn(def) {
|
|
34
|
+
const sortFn = Object.assign((rowA, rowB, columnId) => {
|
|
35
|
+
let dataValueA = rowA.getValue(columnId);
|
|
36
|
+
let dataValueB = rowB.getValue(columnId);
|
|
37
|
+
const resolveDataValue = sortFn.resolveDataValue;
|
|
38
|
+
if (resolveDataValue) {
|
|
39
|
+
dataValueA = resolveDataValue(dataValueA);
|
|
40
|
+
dataValueB = resolveDataValue(dataValueB);
|
|
41
|
+
}
|
|
42
|
+
return sortFn.sort(dataValueA, dataValueB, rowA, rowB, columnId);
|
|
43
|
+
}, def);
|
|
44
|
+
return sortFn;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
10
47
|
* Sorts rows with the built-in alphanumeric strategy.
|
|
11
48
|
*
|
|
12
49
|
* This comparator returns ascending-order results; descending order is applied by the sorting row model.
|
|
13
50
|
*/
|
|
14
|
-
const sortFn_alphanumeric = (
|
|
15
|
-
|
|
16
|
-
|
|
51
|
+
const sortFn_alphanumeric = constructSortFn({
|
|
52
|
+
resolveDataValue: (dataValue) => toString(dataValue).toLowerCase(),
|
|
53
|
+
sort: (dataValueA, dataValueB) => compareAlphanumeric(dataValueA, dataValueB)
|
|
54
|
+
});
|
|
17
55
|
/**
|
|
18
56
|
* Sorts rows with the built-in alphanumeric case sensitive strategy.
|
|
19
57
|
*
|
|
20
58
|
* This comparator returns ascending-order results; descending order is applied by the sorting row model.
|
|
21
59
|
*/
|
|
22
|
-
const sortFn_alphanumericCaseSensitive = (
|
|
23
|
-
|
|
24
|
-
|
|
60
|
+
const sortFn_alphanumericCaseSensitive = constructSortFn({
|
|
61
|
+
resolveDataValue: (dataValue) => toString(dataValue),
|
|
62
|
+
sort: (dataValueA, dataValueB) => compareAlphanumeric(dataValueA, dataValueB)
|
|
63
|
+
});
|
|
25
64
|
/**
|
|
26
65
|
* Sorts rows with the built-in text strategy.
|
|
27
66
|
*
|
|
28
67
|
* This comparator returns ascending-order results; descending order is applied by the sorting row model.
|
|
29
68
|
*/
|
|
30
|
-
const sortFn_text = (
|
|
31
|
-
|
|
32
|
-
|
|
69
|
+
const sortFn_text = constructSortFn({
|
|
70
|
+
resolveDataValue: (dataValue) => toString(dataValue).toLowerCase(),
|
|
71
|
+
sort: (dataValueA, dataValueB) => compareBasic(dataValueA, dataValueB)
|
|
72
|
+
});
|
|
33
73
|
/**
|
|
34
74
|
* Sorts rows with the built-in text case sensitive strategy.
|
|
35
75
|
*
|
|
36
76
|
* This comparator returns ascending-order results; descending order is applied by the sorting row model.
|
|
37
77
|
*/
|
|
38
|
-
const sortFn_textCaseSensitive = (
|
|
39
|
-
|
|
40
|
-
|
|
78
|
+
const sortFn_textCaseSensitive = constructSortFn({
|
|
79
|
+
resolveDataValue: (dataValue) => toString(dataValue),
|
|
80
|
+
sort: (dataValueA, dataValueB) => compareBasic(dataValueA, dataValueB)
|
|
81
|
+
});
|
|
41
82
|
/**
|
|
42
83
|
* Sorts rows with the built-in datetime strategy.
|
|
43
84
|
*
|
|
44
85
|
* This comparator returns ascending-order results; descending order is applied by the sorting row model.
|
|
45
86
|
*/
|
|
46
|
-
const sortFn_datetime = (
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
};
|
|
87
|
+
const sortFn_datetime = constructSortFn({
|
|
88
|
+
resolveDataValue: (dataValue) => toDateSortValue(dataValue),
|
|
89
|
+
sort: (dataValueA, dataValueB) => dataValueA > dataValueB ? 1 : dataValueA < dataValueB ? -1 : 0
|
|
90
|
+
});
|
|
51
91
|
/**
|
|
52
92
|
* Sorts rows with the built-in basic strategy.
|
|
53
93
|
*
|
|
54
94
|
* This comparator returns ascending-order results; descending order is applied by the sorting row model.
|
|
55
95
|
*/
|
|
56
|
-
const sortFn_basic = (
|
|
57
|
-
return compareBasic(rowA.getValue(columnId), rowB.getValue(columnId));
|
|
58
|
-
};
|
|
96
|
+
const sortFn_basic = constructSortFn({ sort: (dataValueA, dataValueB) => compareBasic(dataValueA, dataValueB) });
|
|
59
97
|
function compareBasic(a, b) {
|
|
60
98
|
return a === b ? 0 : a > b ? 1 : -1;
|
|
61
99
|
}
|
|
@@ -155,7 +193,15 @@ function countRemainingChunks(str, start) {
|
|
|
155
193
|
/**
|
|
156
194
|
* The built-in sorting function registry.
|
|
157
195
|
*
|
|
158
|
-
*
|
|
196
|
+
* Registering this full object opts out of tree-shaking: every built-in
|
|
197
|
+
* sorting function ends up in your bundle. Prefer importing the `sortFn_*`
|
|
198
|
+
* functions you actually use and registering just those in the `sortFns`
|
|
199
|
+
* slot, or passing them directly to the `sortFn` column option.
|
|
200
|
+
*
|
|
201
|
+
* @deprecated Import individual `sortFn_*` functions instead for a smaller
|
|
202
|
+
* bundle. This export still works and is not going away in v9, but built-in
|
|
203
|
+
* name resolution (including `sortFn: 'auto'`) only finds functions you
|
|
204
|
+
* register yourself.
|
|
159
205
|
*/
|
|
160
206
|
const sortFns = {
|
|
161
207
|
alphanumeric: sortFn_alphanumeric,
|
|
@@ -167,5 +213,5 @@ const sortFns = {
|
|
|
167
213
|
};
|
|
168
214
|
|
|
169
215
|
//#endregion
|
|
170
|
-
export { reSplitAlphaNumeric, sortFn_alphanumeric, sortFn_alphanumericCaseSensitive, sortFn_basic, sortFn_datetime, sortFn_text, sortFn_textCaseSensitive, sortFns };
|
|
216
|
+
export { constructSortFn, reSplitAlphaNumeric, sortFn_alphanumeric, sortFn_alphanumericCaseSensitive, sortFn_basic, sortFn_datetime, sortFn_text, sortFn_textCaseSensitive, sortFns };
|
|
171
217
|
//# sourceMappingURL=sortFns.js.map
|
package/dist/fns/sortFns.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sortFns.js","names":[],"sources":["../../src/fns/sortFns.ts"],"sourcesContent":["import type { RowData } from '../types/type-utils'\nimport type { TableFeatures } from '../types/TableFeatures'\nimport type { Row } from '../types/Row'\n\n/**\n * Regular expression used to split mixed text and numeric chunks.\n *\n * The alphanumeric sort functions use these chunks for natural sorting of\n * strings like `item2` before `item10`.\n */\nexport const reSplitAlphaNumeric = /([0-9]+)/gm\n\n/**\n * Sorts rows with the built-in alphanumeric strategy.\n *\n * This comparator returns ascending-order results; descending order is applied by the sorting row model.\n */\nexport const sortFn_alphanumeric = <\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(\n rowA: Row<TFeatures, TData>,\n rowB: Row<TFeatures, TData>,\n columnId: string,\n) => {\n return compareAlphanumeric(\n toString(rowA.getValue(columnId)).toLowerCase(),\n toString(rowB.getValue(columnId)).toLowerCase(),\n )\n}\n\n/**\n * Sorts rows with the built-in alphanumeric case sensitive strategy.\n *\n * This comparator returns ascending-order results; descending order is applied by the sorting row model.\n */\nexport const sortFn_alphanumericCaseSensitive = <\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(\n rowA: Row<TFeatures, TData>,\n rowB: Row<TFeatures, TData>,\n columnId: string,\n) => {\n return compareAlphanumeric(\n toString(rowA.getValue(columnId)),\n toString(rowB.getValue(columnId)),\n )\n}\n\n// The text filter is more basic (less numeric support)\n// but is much faster\n/**\n * Sorts rows with the built-in text strategy.\n *\n * This comparator returns ascending-order results; descending order is applied by the sorting row model.\n */\nexport const sortFn_text = <\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(\n rowA: Row<TFeatures, TData>,\n rowB: Row<TFeatures, TData>,\n columnId: string,\n) => {\n return compareBasic(\n toString(rowA.getValue(columnId)).toLowerCase(),\n toString(rowB.getValue(columnId)).toLowerCase(),\n )\n}\n\n// The text filter is more basic (less numeric support)\n// but is much faster\n/**\n * Sorts rows with the built-in text case sensitive strategy.\n *\n * This comparator returns ascending-order results; descending order is applied by the sorting row model.\n */\nexport const sortFn_textCaseSensitive = <\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(\n rowA: Row<TFeatures, TData>,\n rowB: Row<TFeatures, TData>,\n columnId: string,\n) => {\n return compareBasic(\n toString(rowA.getValue(columnId)),\n toString(rowB.getValue(columnId)),\n )\n}\n\n/**\n * Sorts rows with the built-in datetime strategy.\n *\n * This comparator returns ascending-order results; descending order is applied by the sorting row model.\n */\nexport const sortFn_datetime = <\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(\n rowA: Row<TFeatures, TData>,\n rowB: Row<TFeatures, TData>,\n columnId: string,\n) => {\n const a = toDateSortValue(rowA.getValue(columnId))\n const b = toDateSortValue(rowB.getValue(columnId))\n\n // Can handle nullish values\n // Use > and < because == (and ===) doesn't work with\n // Date objects (would require calling getTime()).\n return a > b ? 1 : a < b ? -1 : 0\n}\n\n/**\n * Sorts rows with the built-in basic strategy.\n *\n * This comparator returns ascending-order results; descending order is applied by the sorting row model.\n */\nexport const sortFn_basic = <\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(\n rowA: Row<TFeatures, TData>,\n rowB: Row<TFeatures, TData>,\n columnId: string,\n) => {\n return compareBasic(rowA.getValue(columnId), rowB.getValue(columnId))\n}\n\n// Utils\n\nfunction compareBasic(a: any, b: any) {\n return a === b ? 0 : a > b ? 1 : -1\n}\n\nfunction toDateSortValue(value: any) {\n return value instanceof Date ? value.getTime() : value\n}\n\nfunction toString(a: any) {\n if (typeof a === 'number') {\n if (isNaN(a) || a === Infinity || a === -Infinity) {\n return ''\n }\n return String(a)\n }\n if (typeof a === 'string') {\n return a\n }\n return ''\n}\n\n// Mixed sorting is slow, but very inclusive of many edge cases.\n// It handles numbers, mixed alphanumeric combinations, and even\n// null, undefined, and Infinity\nfunction compareAlphanumeric(aStr: string, bStr: string) {\n let ai = 0\n let bi = 0\n const aLen = aStr.length\n const bLen = bStr.length\n\n while (ai < aLen && bi < bLen) {\n const aIsNumeric = isDigit(aStr.charCodeAt(ai))\n const bIsNumeric = isDigit(bStr.charCodeAt(bi))\n\n const aEnd = findChunkEnd(aStr, ai, aIsNumeric)\n const bEnd = findChunkEnd(bStr, bi, bIsNumeric)\n\n // Both are string chunks\n if (!aIsNumeric && !bIsNumeric) {\n const stringComparison = compareStringChunks(\n aStr,\n ai,\n aEnd,\n bStr,\n bi,\n bEnd,\n )\n if (stringComparison) {\n return stringComparison\n }\n ai = aEnd\n bi = bEnd\n continue\n }\n\n // One is a string chunk, one is a number chunk — the string sorts first\n if (aIsNumeric !== bIsNumeric) {\n return aIsNumeric ? 1 : -1\n }\n\n // Both are numeric chunks\n const numericComparison = compareNumericChunks(\n aStr,\n ai,\n aEnd,\n bStr,\n bi,\n bEnd,\n )\n if (numericComparison) {\n return numericComparison\n }\n\n ai = aEnd\n bi = bEnd\n }\n\n // One side is exhausted — compare the counts of remaining non-empty chunks\n return countRemainingChunks(aStr, ai) - countRemainingChunks(bStr, bi)\n}\n\nfunction isDigit(charCode: number) {\n return charCode >= 48 && charCode <= 57\n}\n\nfunction findChunkEnd(str: string, start: number, isNumeric: boolean) {\n let end = start + 1\n while (end < str.length && isDigit(str.charCodeAt(end)) === isNumeric) {\n end++\n }\n return end\n}\n\nfunction compareStringChunks(\n aStr: string,\n aStart: number,\n aEnd: number,\n bStr: string,\n bStart: number,\n bEnd: number,\n) {\n const aLength = aEnd - aStart\n const bLength = bEnd - bStart\n const minLength = aLength < bLength ? aLength : bLength\n\n for (let i = 0; i < minLength; i++) {\n const aCode = aStr.charCodeAt(aStart + i)\n const bCode = bStr.charCodeAt(bStart + i)\n\n if (aCode > bCode) {\n return 1\n }\n if (bCode > aCode) {\n return -1\n }\n }\n\n if (aLength > bLength) {\n return 1\n }\n if (bLength > aLength) {\n return -1\n }\n return 0\n}\n\nfunction compareNumericChunks(\n aStr: string,\n aStart: number,\n aEnd: number,\n bStr: string,\n bStart: number,\n bEnd: number,\n) {\n let aSignificantStart = aStart\n while (\n aSignificantStart < aEnd &&\n aStr.charCodeAt(aSignificantStart) === 48\n ) {\n aSignificantStart++\n }\n\n let bSignificantStart = bStart\n while (\n bSignificantStart < bEnd &&\n bStr.charCodeAt(bSignificantStart) === 48\n ) {\n bSignificantStart++\n }\n\n const aSignificantLength = aEnd - aSignificantStart\n const bSignificantLength = bEnd - bSignificantStart\n\n if (aSignificantLength === 0 && bSignificantLength === 0) {\n return 0\n }\n\n if (aSignificantLength <= 15 && bSignificantLength <= 15) {\n const an = parseSmallInt(aStr, aSignificantStart, aEnd)\n const bn = parseSmallInt(bStr, bSignificantStart, bEnd)\n\n if (an > bn) {\n return 1\n }\n if (bn > an) {\n return -1\n }\n return 0\n }\n\n // Preserve parseInt precision-collapse behavior for unusually large chunks.\n const an = parseInt(aStr.slice(aStart, aEnd), 10)\n const bn = parseInt(bStr.slice(bStart, bEnd), 10)\n\n if (an > bn) {\n return 1\n }\n if (bn > an) {\n return -1\n }\n return 0\n}\n\nfunction parseSmallInt(str: string, start: number, end: number) {\n let result = 0\n for (let i = start; i < end; i++) {\n result = result * 10 + str.charCodeAt(i) - 48\n }\n return result\n}\n\nfunction countRemainingChunks(str: string, start: number) {\n let count = 0\n let index = start\n\n while (index < str.length) {\n count++\n index = findChunkEnd(str, index, isDigit(str.charCodeAt(index)))\n }\n\n return count\n}\n\n// Exports\n\n/**\n * The built-in sorting function registry.\n *\n * Pass this object to sorted row model creation or extend it with custom sorting functions.\n */\nexport const sortFns = {\n alphanumeric: sortFn_alphanumeric,\n alphanumericCaseSensitive: sortFn_alphanumericCaseSensitive,\n basic: sortFn_basic,\n datetime: sortFn_datetime,\n text: sortFn_text,\n textCaseSensitive: sortFn_textCaseSensitive,\n}\n\nexport type BuiltInSortFn = keyof typeof sortFns\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"sortFns.js","names":[],"sources":["../../src/fns/sortFns.ts"],"sourcesContent":["import type {\n CreatedSortFn,\n SortFnDef,\n} from '../features/row-sorting/rowSortingFeature.types'\nimport type { RowData } from '../types/type-utils'\nimport type { TableFeatures } from '../types/TableFeatures'\nimport type { Row } from '../types/Row'\n\n/**\n * Regular expression used to split mixed text and numeric chunks.\n *\n * The alphanumeric sort functions use these chunks for natural sorting of\n * strings like `item2` before `item10`.\n */\nexport const reSplitAlphaNumeric = /([0-9]+)/gm\n\n/**\n * Builds a `SortFn` from a value-level comparator plus an optional\n * `resolveDataValue` normalizer.\n *\n * The `sort` comparator receives both rows' data values, each already passed\n * through `resolveDataValue` when one is defined. Keeping normalization in the\n * resolver means a variant of an existing sorting function only has to swap\n * the resolver, not re-implement the comparison.\n *\n * The definition is attached to the returned function, so a variant can be\n * created by spreading a built-in sorting function and overriding what\n * differs:\n *\n * ```ts\n * const stripDiacritics = (value: string) =>\n * value.normalize('NFD').replace(/\\p{Diacritic}/gu, '')\n *\n * const alphanumericIgnoreDiacritics = constructSortFn({\n * ...sortFn_alphanumeric,\n * resolveDataValue: (value) =>\n * stripDiacritics(sortFn_alphanumeric.resolveDataValue!(value)),\n * })\n * ```\n */\nexport function constructSortFn<\n TFeatures extends TableFeatures = any,\n TData extends RowData = any,\n>(def: SortFnDef<TFeatures, TData>): CreatedSortFn<TFeatures, TData> {\n const sortFn: CreatedSortFn<TFeatures, TData> = Object.assign(\n <TRowFeatures extends TableFeatures, TRowData extends RowData>(\n rowA: Row<TRowFeatures, TRowData>,\n rowB: Row<TRowFeatures, TRowData>,\n columnId: string,\n ): number => {\n let dataValueA = rowA.getValue(columnId)\n let dataValueB = rowB.getValue(columnId)\n const resolveDataValue = sortFn.resolveDataValue\n if (resolveDataValue) {\n dataValueA = resolveDataValue(dataValueA)\n dataValueB = resolveDataValue(dataValueB)\n }\n // The def's comparator is typed against the factory's TFeatures/TData;\n // the caller's row generics are erased at this boundary.\n return sortFn.sort(\n dataValueA,\n dataValueB,\n rowA as any,\n rowB as any,\n columnId,\n )\n },\n def,\n )\n return sortFn\n}\n\n/**\n * Sorts rows with the built-in alphanumeric strategy.\n *\n * This comparator returns ascending-order results; descending order is applied by the sorting row model.\n */\nexport const sortFn_alphanumeric = constructSortFn({\n resolveDataValue: (dataValue) => toString(dataValue).toLowerCase(),\n sort: (dataValueA, dataValueB) => compareAlphanumeric(dataValueA, dataValueB),\n})\n\n/**\n * Sorts rows with the built-in alphanumeric case sensitive strategy.\n *\n * This comparator returns ascending-order results; descending order is applied by the sorting row model.\n */\nexport const sortFn_alphanumericCaseSensitive = constructSortFn({\n resolveDataValue: (dataValue) => toString(dataValue),\n sort: (dataValueA, dataValueB) => compareAlphanumeric(dataValueA, dataValueB),\n})\n\n// The text sort is more basic (less numeric support)\n// but is much faster\n/**\n * Sorts rows with the built-in text strategy.\n *\n * This comparator returns ascending-order results; descending order is applied by the sorting row model.\n */\nexport const sortFn_text = constructSortFn({\n resolveDataValue: (dataValue) => toString(dataValue).toLowerCase(),\n sort: (dataValueA, dataValueB) => compareBasic(dataValueA, dataValueB),\n})\n\n// The text sort is more basic (less numeric support)\n// but is much faster\n/**\n * Sorts rows with the built-in text case sensitive strategy.\n *\n * This comparator returns ascending-order results; descending order is applied by the sorting row model.\n */\nexport const sortFn_textCaseSensitive = constructSortFn({\n resolveDataValue: (dataValue) => toString(dataValue),\n sort: (dataValueA, dataValueB) => compareBasic(dataValueA, dataValueB),\n})\n\n/**\n * Sorts rows with the built-in datetime strategy.\n *\n * This comparator returns ascending-order results; descending order is applied by the sorting row model.\n */\nexport const sortFn_datetime = constructSortFn({\n resolveDataValue: (dataValue) => toDateSortValue(dataValue),\n // Can handle nullish values\n // Use > and < because == (and ===) doesn't work with\n // Date objects (would require calling getTime()).\n sort: (dataValueA, dataValueB) =>\n dataValueA > dataValueB ? 1 : dataValueA < dataValueB ? -1 : 0,\n})\n\n/**\n * Sorts rows with the built-in basic strategy.\n *\n * This comparator returns ascending-order results; descending order is applied by the sorting row model.\n */\nexport const sortFn_basic = constructSortFn({\n sort: (dataValueA, dataValueB) => compareBasic(dataValueA, dataValueB),\n})\n\n// Utils\n\nfunction compareBasic(a: any, b: any) {\n return a === b ? 0 : a > b ? 1 : -1\n}\n\nfunction toDateSortValue(value: any) {\n return value instanceof Date ? value.getTime() : value\n}\n\nfunction toString(a: any) {\n if (typeof a === 'number') {\n if (isNaN(a) || a === Infinity || a === -Infinity) {\n return ''\n }\n return String(a)\n }\n if (typeof a === 'string') {\n return a\n }\n return ''\n}\n\n// Mixed sorting is slow, but very inclusive of many edge cases.\n// It handles numbers, mixed alphanumeric combinations, and even\n// null, undefined, and Infinity\nfunction compareAlphanumeric(aStr: string, bStr: string) {\n let ai = 0\n let bi = 0\n const aLen = aStr.length\n const bLen = bStr.length\n\n while (ai < aLen && bi < bLen) {\n const aIsNumeric = isDigit(aStr.charCodeAt(ai))\n const bIsNumeric = isDigit(bStr.charCodeAt(bi))\n\n const aEnd = findChunkEnd(aStr, ai, aIsNumeric)\n const bEnd = findChunkEnd(bStr, bi, bIsNumeric)\n\n // Both are string chunks\n if (!aIsNumeric && !bIsNumeric) {\n const stringComparison = compareStringChunks(\n aStr,\n ai,\n aEnd,\n bStr,\n bi,\n bEnd,\n )\n if (stringComparison) {\n return stringComparison\n }\n ai = aEnd\n bi = bEnd\n continue\n }\n\n // One is a string chunk, one is a number chunk — the string sorts first\n if (aIsNumeric !== bIsNumeric) {\n return aIsNumeric ? 1 : -1\n }\n\n // Both are numeric chunks\n const numericComparison = compareNumericChunks(\n aStr,\n ai,\n aEnd,\n bStr,\n bi,\n bEnd,\n )\n if (numericComparison) {\n return numericComparison\n }\n\n ai = aEnd\n bi = bEnd\n }\n\n // One side is exhausted — compare the counts of remaining non-empty chunks\n return countRemainingChunks(aStr, ai) - countRemainingChunks(bStr, bi)\n}\n\nfunction isDigit(charCode: number) {\n return charCode >= 48 && charCode <= 57\n}\n\nfunction findChunkEnd(str: string, start: number, isNumeric: boolean) {\n let end = start + 1\n while (end < str.length && isDigit(str.charCodeAt(end)) === isNumeric) {\n end++\n }\n return end\n}\n\nfunction compareStringChunks(\n aStr: string,\n aStart: number,\n aEnd: number,\n bStr: string,\n bStart: number,\n bEnd: number,\n) {\n const aLength = aEnd - aStart\n const bLength = bEnd - bStart\n const minLength = aLength < bLength ? aLength : bLength\n\n for (let i = 0; i < minLength; i++) {\n const aCode = aStr.charCodeAt(aStart + i)\n const bCode = bStr.charCodeAt(bStart + i)\n\n if (aCode > bCode) {\n return 1\n }\n if (bCode > aCode) {\n return -1\n }\n }\n\n if (aLength > bLength) {\n return 1\n }\n if (bLength > aLength) {\n return -1\n }\n return 0\n}\n\nfunction compareNumericChunks(\n aStr: string,\n aStart: number,\n aEnd: number,\n bStr: string,\n bStart: number,\n bEnd: number,\n) {\n let aSignificantStart = aStart\n while (\n aSignificantStart < aEnd &&\n aStr.charCodeAt(aSignificantStart) === 48\n ) {\n aSignificantStart++\n }\n\n let bSignificantStart = bStart\n while (\n bSignificantStart < bEnd &&\n bStr.charCodeAt(bSignificantStart) === 48\n ) {\n bSignificantStart++\n }\n\n const aSignificantLength = aEnd - aSignificantStart\n const bSignificantLength = bEnd - bSignificantStart\n\n if (aSignificantLength === 0 && bSignificantLength === 0) {\n return 0\n }\n\n if (aSignificantLength <= 15 && bSignificantLength <= 15) {\n const an = parseSmallInt(aStr, aSignificantStart, aEnd)\n const bn = parseSmallInt(bStr, bSignificantStart, bEnd)\n\n if (an > bn) {\n return 1\n }\n if (bn > an) {\n return -1\n }\n return 0\n }\n\n // Preserve parseInt precision-collapse behavior for unusually large chunks.\n const an = parseInt(aStr.slice(aStart, aEnd), 10)\n const bn = parseInt(bStr.slice(bStart, bEnd), 10)\n\n if (an > bn) {\n return 1\n }\n if (bn > an) {\n return -1\n }\n return 0\n}\n\nfunction parseSmallInt(str: string, start: number, end: number) {\n let result = 0\n for (let i = start; i < end; i++) {\n result = result * 10 + str.charCodeAt(i) - 48\n }\n return result\n}\n\nfunction countRemainingChunks(str: string, start: number) {\n let count = 0\n let index = start\n\n while (index < str.length) {\n count++\n index = findChunkEnd(str, index, isDigit(str.charCodeAt(index)))\n }\n\n return count\n}\n\n// Exports\n\n/**\n * The built-in sorting function registry.\n *\n * Registering this full object opts out of tree-shaking: every built-in\n * sorting function ends up in your bundle. Prefer importing the `sortFn_*`\n * functions you actually use and registering just those in the `sortFns`\n * slot, or passing them directly to the `sortFn` column option.\n *\n * @deprecated Import individual `sortFn_*` functions instead for a smaller\n * bundle. This export still works and is not going away in v9, but built-in\n * name resolution (including `sortFn: 'auto'`) only finds functions you\n * register yourself.\n */\nexport const sortFns = {\n alphanumeric: sortFn_alphanumeric,\n alphanumericCaseSensitive: sortFn_alphanumericCaseSensitive,\n basic: sortFn_basic,\n datetime: sortFn_datetime,\n text: sortFn_text,\n textCaseSensitive: sortFn_textCaseSensitive,\n}\n\nexport type BuiltInSortFn = keyof typeof sortFns\n"],"mappings":"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"}
|