@oscarpalmer/atoms 0.165.1 → 0.166.0
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/array/index.d.mts +2 -2
- package/dist/array/index.mjs +2 -2
- package/dist/array/sort.d.mts +38 -41
- package/dist/array/sort.mjs +42 -35
- package/dist/index.d.mts +40 -41
- package/dist/index.mjs +170 -161
- package/dist/promise/delay.mjs +1 -1
- package/dist/promise/helpers.mjs +0 -1
- package/dist/promise/index.mjs +1 -1
- package/dist/promise/timed.mjs +1 -1
- package/dist/result/index.mjs +3 -3
- package/package.json +2 -2
- package/src/array/index.ts +1 -1
- package/src/array/sort.ts +144 -135
- package/src/promise/helpers.ts +1 -1
package/dist/array/index.d.mts
CHANGED
|
@@ -15,10 +15,10 @@ import { ArrayPosition, endsWithArray, getArrayPosition, includesArray, indexOfA
|
|
|
15
15
|
import { push } from "./push.mjs";
|
|
16
16
|
import { select } from "./select.mjs";
|
|
17
17
|
import { drop, slice, take } from "./slice.mjs";
|
|
18
|
-
import { sort } from "./sort.mjs";
|
|
18
|
+
import { ArrayComparisonSorter, ArrayKeySorter, ArrayValueSorter, SORT_DIRECTION_ASCENDING, SORT_DIRECTION_DESCENDING, SortDirection, sort } from "./sort.mjs";
|
|
19
19
|
import { splice } from "./splice.mjs";
|
|
20
20
|
import { toSet } from "./to-set.mjs";
|
|
21
21
|
import { toggle } from "./toggle.mjs";
|
|
22
22
|
import { union } from "./union.mjs";
|
|
23
23
|
import { update } from "./update.mjs";
|
|
24
|
-
export { ArrayPosition, chunk, compact, difference, drop, endsWithArray, exists, find, flatten, getArray, getArrayPosition, includesArray, indexOf, indexOfArray, insert, intersection, partition, push, range, select, shuffle, slice, sort, splice, startsWithArray, take, times, toSet, toggle, union, update };
|
|
24
|
+
export { ArrayComparisonSorter, ArrayKeySorter, ArrayPosition, ArrayValueSorter, SORT_DIRECTION_ASCENDING, SORT_DIRECTION_DESCENDING, SortDirection, chunk, compact, difference, drop, endsWithArray, exists, find, flatten, getArray, getArrayPosition, includesArray, indexOf, indexOfArray, insert, intersection, partition, push, range, select, shuffle, slice, sort, splice, startsWithArray, take, times, toSet, toggle, union, update };
|
package/dist/array/index.mjs
CHANGED
|
@@ -15,10 +15,10 @@ import { endsWithArray, getArrayPosition, includesArray, indexOfArray, startsWit
|
|
|
15
15
|
import { push } from "./push.mjs";
|
|
16
16
|
import { select } from "./select.mjs";
|
|
17
17
|
import { drop, slice, take } from "./slice.mjs";
|
|
18
|
-
import { sort } from "./sort.mjs";
|
|
18
|
+
import { SORT_DIRECTION_ASCENDING, SORT_DIRECTION_DESCENDING, sort } from "./sort.mjs";
|
|
19
19
|
import { splice } from "./splice.mjs";
|
|
20
20
|
import { toSet } from "./to-set.mjs";
|
|
21
21
|
import { toggle } from "./toggle.mjs";
|
|
22
22
|
import { union } from "./union.mjs";
|
|
23
23
|
import { update } from "./update.mjs";
|
|
24
|
-
export { chunk, compact, difference, drop, endsWithArray, exists, find, flatten, getArray, getArrayPosition, includesArray, indexOf, indexOfArray, insert, intersection, partition, push, range, select, shuffle, slice, sort, splice, startsWithArray, take, times, toSet, toggle, union, update };
|
|
24
|
+
export { SORT_DIRECTION_ASCENDING, SORT_DIRECTION_DESCENDING, chunk, compact, difference, drop, endsWithArray, exists, find, flatten, getArray, getArrayPosition, includesArray, indexOf, indexOfArray, insert, intersection, partition, push, range, select, shuffle, slice, sort, splice, startsWithArray, take, times, toSet, toggle, union, update };
|
package/dist/array/sort.d.mts
CHANGED
|
@@ -2,30 +2,26 @@ import { PlainObject, Primitive } from "../models.mjs";
|
|
|
2
2
|
|
|
3
3
|
//#region src/array/sort.d.ts
|
|
4
4
|
/**
|
|
5
|
-
* Sorting information for arrays _(using a callback)_
|
|
5
|
+
* Sorting information for arrays _(using a comparison callback)_
|
|
6
6
|
*/
|
|
7
|
-
type
|
|
7
|
+
type ArrayComparisonSorter<Item> = {
|
|
8
8
|
/**
|
|
9
|
-
*
|
|
9
|
+
* Callback to use when comparing items and values
|
|
10
10
|
*/
|
|
11
|
-
|
|
11
|
+
comparison: ComparisonSorter<Item>;
|
|
12
12
|
/**
|
|
13
13
|
* Direction to sort by
|
|
14
14
|
*/
|
|
15
15
|
direction?: SortDirection;
|
|
16
|
-
/**
|
|
17
|
-
* Value to sort by
|
|
18
|
-
*/
|
|
19
|
-
value: (item: Item) => unknown;
|
|
20
16
|
};
|
|
21
17
|
/**
|
|
22
18
|
* Sorting information for arrays _(using a key)_
|
|
23
19
|
*/
|
|
24
|
-
type ArrayKeySorter<Item> = {
|
|
20
|
+
type ArrayKeySorter<Item extends PlainObject, Key extends keyof Item> = {
|
|
25
21
|
/**
|
|
26
22
|
* Comparator to use when comparing items and values
|
|
27
23
|
*/
|
|
28
|
-
compare?:
|
|
24
|
+
compare?: CompareCallback<Item, Item[Key]>;
|
|
29
25
|
/**
|
|
30
26
|
* Direction to sort by
|
|
31
27
|
*/
|
|
@@ -33,41 +29,42 @@ type ArrayKeySorter<Item> = {
|
|
|
33
29
|
/**
|
|
34
30
|
* Key to sort by
|
|
35
31
|
*/
|
|
36
|
-
key:
|
|
32
|
+
key: Key;
|
|
37
33
|
};
|
|
38
|
-
type SortDirection = 'ascending' | 'descending';
|
|
39
34
|
/**
|
|
40
|
-
*
|
|
41
|
-
* @param array Array to sort
|
|
42
|
-
* @param sorters Sorters to use for sorting
|
|
43
|
-
* @param descending Sort in descending order? _(defaults to `false`; overridden by individual sorters)_
|
|
44
|
-
* @returns Sorted array
|
|
35
|
+
* Sorters based on keys in an object
|
|
45
36
|
*/
|
|
46
|
-
|
|
37
|
+
type ArrayKeySorters<Item extends PlainObject> = { [Key in keyof Item]: ArrayKeySorter<Item, Key> }[keyof Item];
|
|
47
38
|
/**
|
|
48
|
-
*
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
39
|
+
* Sorting information for arrays _(using a value callback and built-in comparison)_
|
|
40
|
+
*/
|
|
41
|
+
type ArrayValueSorter<Item> = {
|
|
42
|
+
/**
|
|
43
|
+
* Direction to sort by
|
|
44
|
+
*/
|
|
45
|
+
direction?: SortDirection;
|
|
46
|
+
/**
|
|
47
|
+
* Value to sort by
|
|
48
|
+
*/
|
|
49
|
+
value: (item: Item) => unknown;
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Comparator to use when comparing items and values
|
|
53
53
|
*/
|
|
54
|
-
|
|
54
|
+
type CompareCallback<Item, Value = CompareCallbackValue<Item>> = (first: Item, firstValue: Value, second: Item, secondValue: Value) => number;
|
|
55
|
+
type CompareCallbackValue<Item> = Item extends Primitive ? Item : unknown;
|
|
55
56
|
/**
|
|
56
|
-
*
|
|
57
|
-
* @param array Array to sort
|
|
58
|
-
* @param sorters Sorters to use for sorting
|
|
59
|
-
* @param descending Sort in descending order? _(defaults to `false`; overridden by individual sorters)_
|
|
60
|
-
* @returns Sorted array
|
|
57
|
+
* Callback to use when comparing items and values
|
|
61
58
|
*/
|
|
62
|
-
|
|
59
|
+
type ComparisonSorter<Item> = (first: Item, second: Item) => number;
|
|
63
60
|
/**
|
|
64
|
-
*
|
|
65
|
-
* @param array Array to sort
|
|
66
|
-
* @param sorter Sorter to use for sorting
|
|
67
|
-
* @param descending Sort in descending order? _(defaults to `false`; overridden by the sorter)_
|
|
68
|
-
* @returns Sorted array
|
|
61
|
+
* Direction to sort by
|
|
69
62
|
*/
|
|
70
|
-
|
|
63
|
+
type SortDirection = 'ascending' | 'descending';
|
|
64
|
+
/**
|
|
65
|
+
* Sorter to use for sorting
|
|
66
|
+
*/
|
|
67
|
+
type Sorter<Item> = Item extends PlainObject ? keyof Item | ArrayComparisonSorter<Item> | ArrayKeySorters<Item> | ArrayValueSorter<Item> | ComparisonSorter<Item> : ArrayComparisonSorter<Item> | ArrayValueSorter<Item> | ComparisonSorter<Item>;
|
|
71
68
|
/**
|
|
72
69
|
* Sort an array of items, using multiple sorters to sort by specific values
|
|
73
70
|
* @param array Array to sort
|
|
@@ -75,15 +72,15 @@ declare function sort<Item extends PlainObject>(array: Item[], sorter: keyof Ite
|
|
|
75
72
|
* @param descending Sort in descending order? _(defaults to `false`; overridden by individual sorters)_
|
|
76
73
|
* @returns Sorted array
|
|
77
74
|
*/
|
|
78
|
-
declare function sort<Item
|
|
75
|
+
declare function sort<Item>(array: Item[], sorters: Array<Sorter<Item>>, descending?: boolean): Item[];
|
|
79
76
|
/**
|
|
80
|
-
* Sort an array of items, using
|
|
77
|
+
* Sort an array of items, using multiple sorters to sort by specific values
|
|
81
78
|
* @param array Array to sort
|
|
82
79
|
* @param sorter Sorter to use for sorting
|
|
83
|
-
* @param descending Sort in descending order? _(defaults to `false`; overridden by
|
|
80
|
+
* @param descending Sort in descending order? _(defaults to `false`; overridden by individual sorters)_
|
|
84
81
|
* @returns Sorted array
|
|
85
82
|
*/
|
|
86
|
-
declare function sort<Item
|
|
83
|
+
declare function sort<Item>(array: Item[], sorter: Sorter<Item>, descending?: boolean): Item[];
|
|
87
84
|
/**
|
|
88
85
|
* Sort an array of items
|
|
89
86
|
* @param array Array to sort
|
|
@@ -94,4 +91,4 @@ declare function sort<Item>(array: Item[], descending?: boolean): Item[];
|
|
|
94
91
|
declare const SORT_DIRECTION_ASCENDING: SortDirection;
|
|
95
92
|
declare const SORT_DIRECTION_DESCENDING: SortDirection;
|
|
96
93
|
//#endregion
|
|
97
|
-
export {
|
|
94
|
+
export { ArrayComparisonSorter, ArrayKeySorter, ArrayValueSorter, SORT_DIRECTION_ASCENDING, SORT_DIRECTION_DESCENDING, SortDirection, sort };
|
package/dist/array/sort.mjs
CHANGED
|
@@ -1,64 +1,71 @@
|
|
|
1
1
|
import { isPlainObject } from "../internal/is.mjs";
|
|
2
2
|
import { compare } from "../internal/value/compare.mjs";
|
|
3
3
|
//#region src/array/sort.ts
|
|
4
|
-
function
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
return typeof value === "string" ? value : void 0;
|
|
4
|
+
function getComparisonSorter(callback, modifier) {
|
|
5
|
+
return {
|
|
6
|
+
modifier,
|
|
7
|
+
compare: { simple: callback },
|
|
8
|
+
get: false,
|
|
9
|
+
identifier: String(callback)
|
|
10
|
+
};
|
|
12
11
|
}
|
|
13
|
-
function
|
|
14
|
-
|
|
15
|
-
if (
|
|
16
|
-
|
|
12
|
+
function getObjectSorter(obj, modifier) {
|
|
13
|
+
let sorter;
|
|
14
|
+
if (typeof obj.comparison === "function") sorter = getComparisonSorter(obj.comparison, modifier);
|
|
15
|
+
else if (typeof obj.key === "string") {
|
|
16
|
+
sorter = getValueSorter(obj.key, modifier);
|
|
17
|
+
if (typeof obj.compare === "function") sorter.compare = { complex: obj.compare };
|
|
18
|
+
} else if (typeof obj.value === "function") sorter = getValueSorter(obj.value, modifier);
|
|
19
|
+
if (sorter != null && typeof obj.direction === "string") sorter.modifier = modifiers[obj.direction] ?? modifier;
|
|
20
|
+
return sorter;
|
|
17
21
|
}
|
|
18
22
|
function getSorter(value, modifier) {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
modifier
|
|
23
|
-
|
|
24
|
-
sorter.compare = forObject && typeof value.compare === "function" ? value.compare : void 0;
|
|
25
|
-
sorter.key = getKey(value, forObject);
|
|
26
|
-
sorter.modifier = getModifier(value, modifier, forObject);
|
|
27
|
-
sorter.callback = getCallback(value, sorter.key, forObject);
|
|
28
|
-
if (sorter.key != null || sorter.callback != null) {
|
|
29
|
-
sorter.identifier = `${sorter.key ?? sorter.callback}`;
|
|
30
|
-
return sorter;
|
|
23
|
+
switch (true) {
|
|
24
|
+
case typeof value === "function": return getComparisonSorter(value, modifier);
|
|
25
|
+
case typeof value === "string": return getValueSorter(value, modifier);
|
|
26
|
+
case isPlainObject(value): return getObjectSorter(value, modifier);
|
|
27
|
+
default: break;
|
|
31
28
|
}
|
|
32
29
|
}
|
|
30
|
+
function getValueSorter(value, modifier) {
|
|
31
|
+
return {
|
|
32
|
+
modifier,
|
|
33
|
+
get: true,
|
|
34
|
+
identifier: String(value),
|
|
35
|
+
value: typeof value === "function" ? value : (item) => item[value]
|
|
36
|
+
};
|
|
37
|
+
}
|
|
33
38
|
function sort(array, first, second) {
|
|
34
39
|
if (!Array.isArray(array)) return [];
|
|
35
40
|
if (array.length < 2) return array;
|
|
36
|
-
const modifier =
|
|
41
|
+
const modifier = modifiers[first === true || second === true ? SORT_DIRECTION_DESCENDING : SORT_DIRECTION_ASCENDING];
|
|
37
42
|
const sorters = (Array.isArray(first) ? first : [first]).map((item) => getSorter(item, modifier)).filter((sorter) => sorter != null).filter((current, index, filtered) => filtered.findIndex((next) => next.identifier === current.identifier) === index);
|
|
38
43
|
const { length } = sorters;
|
|
39
|
-
if (length === 0) return array.sort((
|
|
44
|
+
if (length === 0) return array.sort((first, second) => compare(first, second) * modifier);
|
|
40
45
|
if (length === 1) {
|
|
41
46
|
const sorter = sorters[0];
|
|
42
|
-
const { callback, key } = sorter;
|
|
43
47
|
return array.sort((firstItem, secondItem) => {
|
|
44
|
-
const firstValue =
|
|
45
|
-
const secondValue =
|
|
46
|
-
return (sorter.compare?.(firstItem, firstValue, secondItem, secondValue) ?? compare(firstValue, secondValue)) * sorter.modifier;
|
|
48
|
+
const firstValue = sorter.get ? sorter.value(firstItem) : firstItem;
|
|
49
|
+
const secondValue = sorter.get ? sorter.value(secondItem) : secondItem;
|
|
50
|
+
return (sorter.compare?.complex?.(firstItem, firstValue, secondItem, secondValue) ?? sorter.compare?.simple?.(firstItem, secondItem) ?? compare(firstValue, secondValue)) * sorter.modifier;
|
|
47
51
|
});
|
|
48
52
|
}
|
|
49
53
|
return array.sort((firstItem, secondItem) => {
|
|
50
54
|
for (let index = 0; index < length; index += 1) {
|
|
51
55
|
const sorter = sorters[index];
|
|
52
|
-
const
|
|
53
|
-
const
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
if (compared !== 0) return compared;
|
|
56
|
+
const firstValue = sorter.value?.(firstItem) ?? firstItem;
|
|
57
|
+
const secondValue = sorter.value?.(secondItem) ?? secondItem;
|
|
58
|
+
const comparison = (sorter.compare?.complex?.(firstItem, firstValue, secondItem, secondValue) ?? sorter.compare?.simple?.(firstItem, secondItem) ?? compare(firstValue, secondValue)) * sorter.modifier;
|
|
59
|
+
if (comparison !== 0) return comparison;
|
|
57
60
|
}
|
|
58
61
|
return 0;
|
|
59
62
|
});
|
|
60
63
|
}
|
|
61
64
|
const SORT_DIRECTION_ASCENDING = "ascending";
|
|
62
65
|
const SORT_DIRECTION_DESCENDING = "descending";
|
|
66
|
+
const modifiers = {
|
|
67
|
+
[SORT_DIRECTION_ASCENDING]: 1,
|
|
68
|
+
[SORT_DIRECTION_DESCENDING]: -1
|
|
69
|
+
};
|
|
63
70
|
//#endregion
|
|
64
71
|
export { SORT_DIRECTION_ASCENDING, SORT_DIRECTION_DESCENDING, sort };
|
package/dist/index.d.mts
CHANGED
|
@@ -855,30 +855,26 @@ declare function take(array: unknown[], count: number): unknown[];
|
|
|
855
855
|
//#endregion
|
|
856
856
|
//#region src/array/sort.d.ts
|
|
857
857
|
/**
|
|
858
|
-
* Sorting information for arrays _(using a callback)_
|
|
858
|
+
* Sorting information for arrays _(using a comparison callback)_
|
|
859
859
|
*/
|
|
860
|
-
type
|
|
860
|
+
type ArrayComparisonSorter<Item> = {
|
|
861
861
|
/**
|
|
862
|
-
*
|
|
862
|
+
* Callback to use when comparing items and values
|
|
863
863
|
*/
|
|
864
|
-
|
|
864
|
+
comparison: ComparisonSorter<Item>;
|
|
865
865
|
/**
|
|
866
866
|
* Direction to sort by
|
|
867
867
|
*/
|
|
868
868
|
direction?: SortDirection;
|
|
869
|
-
/**
|
|
870
|
-
* Value to sort by
|
|
871
|
-
*/
|
|
872
|
-
value: (item: Item) => unknown;
|
|
873
869
|
};
|
|
874
870
|
/**
|
|
875
871
|
* Sorting information for arrays _(using a key)_
|
|
876
872
|
*/
|
|
877
|
-
type ArrayKeySorter<Item> = {
|
|
873
|
+
type ArrayKeySorter<Item extends PlainObject, Key extends keyof Item> = {
|
|
878
874
|
/**
|
|
879
875
|
* Comparator to use when comparing items and values
|
|
880
876
|
*/
|
|
881
|
-
compare?:
|
|
877
|
+
compare?: CompareCallback<Item, Item[Key]>;
|
|
882
878
|
/**
|
|
883
879
|
* Direction to sort by
|
|
884
880
|
*/
|
|
@@ -886,41 +882,42 @@ type ArrayKeySorter<Item> = {
|
|
|
886
882
|
/**
|
|
887
883
|
* Key to sort by
|
|
888
884
|
*/
|
|
889
|
-
key:
|
|
885
|
+
key: Key;
|
|
890
886
|
};
|
|
891
|
-
type SortDirection = 'ascending' | 'descending';
|
|
892
887
|
/**
|
|
893
|
-
*
|
|
894
|
-
* @param array Array to sort
|
|
895
|
-
* @param sorters Sorters to use for sorting
|
|
896
|
-
* @param descending Sort in descending order? _(defaults to `false`; overridden by individual sorters)_
|
|
897
|
-
* @returns Sorted array
|
|
888
|
+
* Sorters based on keys in an object
|
|
898
889
|
*/
|
|
899
|
-
|
|
890
|
+
type ArrayKeySorters<Item extends PlainObject> = { [Key in keyof Item]: ArrayKeySorter<Item, Key> }[keyof Item];
|
|
900
891
|
/**
|
|
901
|
-
*
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
892
|
+
* Sorting information for arrays _(using a value callback and built-in comparison)_
|
|
893
|
+
*/
|
|
894
|
+
type ArrayValueSorter<Item> = {
|
|
895
|
+
/**
|
|
896
|
+
* Direction to sort by
|
|
897
|
+
*/
|
|
898
|
+
direction?: SortDirection;
|
|
899
|
+
/**
|
|
900
|
+
* Value to sort by
|
|
901
|
+
*/
|
|
902
|
+
value: (item: Item) => unknown;
|
|
903
|
+
};
|
|
904
|
+
/**
|
|
905
|
+
* Comparator to use when comparing items and values
|
|
906
906
|
*/
|
|
907
|
-
|
|
907
|
+
type CompareCallback<Item, Value = CompareCallbackValue<Item>> = (first: Item, firstValue: Value, second: Item, secondValue: Value) => number;
|
|
908
|
+
type CompareCallbackValue<Item> = Item extends Primitive ? Item : unknown;
|
|
908
909
|
/**
|
|
909
|
-
*
|
|
910
|
-
* @param array Array to sort
|
|
911
|
-
* @param sorters Sorters to use for sorting
|
|
912
|
-
* @param descending Sort in descending order? _(defaults to `false`; overridden by individual sorters)_
|
|
913
|
-
* @returns Sorted array
|
|
910
|
+
* Callback to use when comparing items and values
|
|
914
911
|
*/
|
|
915
|
-
|
|
912
|
+
type ComparisonSorter<Item> = (first: Item, second: Item) => number;
|
|
916
913
|
/**
|
|
917
|
-
*
|
|
918
|
-
* @param array Array to sort
|
|
919
|
-
* @param sorter Sorter to use for sorting
|
|
920
|
-
* @param descending Sort in descending order? _(defaults to `false`; overridden by the sorter)_
|
|
921
|
-
* @returns Sorted array
|
|
914
|
+
* Direction to sort by
|
|
922
915
|
*/
|
|
923
|
-
|
|
916
|
+
type SortDirection = 'ascending' | 'descending';
|
|
917
|
+
/**
|
|
918
|
+
* Sorter to use for sorting
|
|
919
|
+
*/
|
|
920
|
+
type Sorter<Item> = Item extends PlainObject ? keyof Item | ArrayComparisonSorter<Item> | ArrayKeySorters<Item> | ArrayValueSorter<Item> | ComparisonSorter<Item> : ArrayComparisonSorter<Item> | ArrayValueSorter<Item> | ComparisonSorter<Item>;
|
|
924
921
|
/**
|
|
925
922
|
* Sort an array of items, using multiple sorters to sort by specific values
|
|
926
923
|
* @param array Array to sort
|
|
@@ -928,15 +925,15 @@ declare function sort<Item extends PlainObject>(array: Item[], sorter: keyof Ite
|
|
|
928
925
|
* @param descending Sort in descending order? _(defaults to `false`; overridden by individual sorters)_
|
|
929
926
|
* @returns Sorted array
|
|
930
927
|
*/
|
|
931
|
-
declare function sort<Item
|
|
928
|
+
declare function sort<Item>(array: Item[], sorters: Array<Sorter<Item>>, descending?: boolean): Item[];
|
|
932
929
|
/**
|
|
933
|
-
* Sort an array of items, using
|
|
930
|
+
* Sort an array of items, using multiple sorters to sort by specific values
|
|
934
931
|
* @param array Array to sort
|
|
935
932
|
* @param sorter Sorter to use for sorting
|
|
936
|
-
* @param descending Sort in descending order? _(defaults to `false`; overridden by
|
|
933
|
+
* @param descending Sort in descending order? _(defaults to `false`; overridden by individual sorters)_
|
|
937
934
|
* @returns Sorted array
|
|
938
935
|
*/
|
|
939
|
-
declare function sort<Item
|
|
936
|
+
declare function sort<Item>(array: Item[], sorter: Sorter<Item>, descending?: boolean): Item[];
|
|
940
937
|
/**
|
|
941
938
|
* Sort an array of items
|
|
942
939
|
* @param array Array to sort
|
|
@@ -944,6 +941,8 @@ declare function sort<Item extends Primitive>(array: Item[], sorter: (item: Item
|
|
|
944
941
|
* @returns Sorted array
|
|
945
942
|
*/
|
|
946
943
|
declare function sort<Item>(array: Item[], descending?: boolean): Item[];
|
|
944
|
+
declare const SORT_DIRECTION_ASCENDING: SortDirection;
|
|
945
|
+
declare const SORT_DIRECTION_DESCENDING: SortDirection;
|
|
947
946
|
//#endregion
|
|
948
947
|
//#region src/array/splice.d.ts
|
|
949
948
|
/**
|
|
@@ -4296,4 +4295,4 @@ declare class SizedSet<Value = unknown> extends Set<Value> {
|
|
|
4296
4295
|
get(value: Value, update?: boolean): Value | undefined;
|
|
4297
4296
|
}
|
|
4298
4297
|
//#endregion
|
|
4299
|
-
export { ArrayOrPlainObject, ArrayPosition, Asserter, type Beacon, type BeaconOptions, BuiltIns, CancelableCallback, CancelablePromise, type Color, Constructor, DiffOptions, DiffResult, DiffValue, EqualOptions, type Err, EventPosition, type ExtendedErr, type ExtendedResult, Flow, FlowPromise, type FulfilledPromise, GenericAsyncCallback, GenericCallback, type HSLAColor, type HSLColor, HasValue, Key$1 as Key, KeyedValue, type Logger, type Memoized, type MemoizedOptions, MergeOptions, Merger, NestedArray, NestedKeys, NestedPartial, NestedValue, NestedValues, NumericalKeys, NumericalValues, type Observable, type Observer, type Ok, OnceAsyncCallback, OnceCallback, PlainObject, Primitive, type PromiseOptions, type PromiseStrategy, PromiseTimeoutError, type PromisesOptions, type PromisesResult, type PromisesValues as PromisesValue, type PromisesValue as PromisesValueItem, type Queue, QueueError, type QueueOptions, type Queued, type RGBAColor, type RGBColor, type RejectedPromise, RequiredKeys, type Result, RetryError, RetryOptions, Simplify, SizedMap, SizedSet, Smushed, type Subscription, TemplateOptions, type Time, ToString, TypedArray, Unsmushed, assert, attempt, attemptPromise, average, beacon, between, camelCase, cancelable, capitalize, ceil, chunk, clamp, clone, compact, compare, count, debounce, delay, diff, difference, drop, endsWith, endsWithArray, equal, error, exists, filter, find, flatten, floor, flow, toResult as fromPromise, toResult, fromQuery, toPromise as fromResult, toPromise, getArray, getArrayPosition, getColor, getForegroundColor, getHexColor, getHexaColor, getHslColor, getHslaColor, getNormalizedHex, getNumber, getRandomBoolean, getRandomCharacters, getRandomColor, getRandomFloat, getRandomHex, getRandomInteger, getRandomItem, getRandomItems, getRgbColor, getRgbaColor, getString, getUuid, getValue, groupBy, hasValue, hexToHsl, hexToHsla, hexToRgb, hexToRgba, hslToHex, hslToRgb, hslToRgba, ignoreKey, includes, includesArray, indexOf, indexOfArray, insert, intersection, isArrayOrPlainObject, isColor, isConstructor, isEmpty, isError, isFulfilled, isHexColor, isHslColor, isHslLike, isHslaColor, isInstanceOf, isKey, isNonNullable, isNullable, isNullableOrEmpty, isNullableOrWhitespace, isNumber, isNumerical, isObject, isOk, isPlainObject, isPrimitive, isRejected, isResult, isRgbColor, isRgbLike, isRgbaColor, isTypedArray, join, kebabCase, logger, lowerCase, max, median, memoize, merge, min, move, noop, ok, omit, once, parse, partition, pascalCase, pick, pipe, promises, push, queue, range, retry, rgbToHex, rgbToHsl, rgbToHsla, round, select, setValue, shuffle, slice, smush, snakeCase, sort, splice, startsWith, startsWithArray, sum, swap, take, template, throttle, timed, times, titleCase, toMap, toQuery, toRecord, toSet, toggle, trim, truncate, tryDecode, tryEncode, union, unique, unsmush, unwrap, update, upperCase, words };
|
|
4298
|
+
export { ArrayComparisonSorter, ArrayKeySorter, ArrayOrPlainObject, ArrayPosition, ArrayValueSorter, Asserter, type Beacon, type BeaconOptions, BuiltIns, CancelableCallback, CancelablePromise, type Color, Constructor, DiffOptions, DiffResult, DiffValue, EqualOptions, type Err, EventPosition, type ExtendedErr, type ExtendedResult, Flow, FlowPromise, type FulfilledPromise, GenericAsyncCallback, GenericCallback, type HSLAColor, type HSLColor, HasValue, Key$1 as Key, KeyedValue, type Logger, type Memoized, type MemoizedOptions, MergeOptions, Merger, NestedArray, NestedKeys, NestedPartial, NestedValue, NestedValues, NumericalKeys, NumericalValues, type Observable, type Observer, type Ok, OnceAsyncCallback, OnceCallback, PlainObject, Primitive, type PromiseOptions, type PromiseStrategy, PromiseTimeoutError, type PromisesOptions, type PromisesResult, type PromisesValues as PromisesValue, type PromisesValue as PromisesValueItem, type Queue, QueueError, type QueueOptions, type Queued, type RGBAColor, type RGBColor, type RejectedPromise, RequiredKeys, type Result, RetryError, RetryOptions, SORT_DIRECTION_ASCENDING, SORT_DIRECTION_DESCENDING, Simplify, SizedMap, SizedSet, Smushed, SortDirection, type Subscription, TemplateOptions, type Time, ToString, TypedArray, Unsmushed, assert, attempt, attemptPromise, average, beacon, between, camelCase, cancelable, capitalize, ceil, chunk, clamp, clone, compact, compare, count, debounce, delay, diff, difference, drop, endsWith, endsWithArray, equal, error, exists, filter, find, flatten, floor, flow, toResult as fromPromise, toResult, fromQuery, toPromise as fromResult, toPromise, getArray, getArrayPosition, getColor, getForegroundColor, getHexColor, getHexaColor, getHslColor, getHslaColor, getNormalizedHex, getNumber, getRandomBoolean, getRandomCharacters, getRandomColor, getRandomFloat, getRandomHex, getRandomInteger, getRandomItem, getRandomItems, getRgbColor, getRgbaColor, getString, getUuid, getValue, groupBy, hasValue, hexToHsl, hexToHsla, hexToRgb, hexToRgba, hslToHex, hslToRgb, hslToRgba, ignoreKey, includes, includesArray, indexOf, indexOfArray, insert, intersection, isArrayOrPlainObject, isColor, isConstructor, isEmpty, isError, isFulfilled, isHexColor, isHslColor, isHslLike, isHslaColor, isInstanceOf, isKey, isNonNullable, isNullable, isNullableOrEmpty, isNullableOrWhitespace, isNumber, isNumerical, isObject, isOk, isPlainObject, isPrimitive, isRejected, isResult, isRgbColor, isRgbLike, isRgbaColor, isTypedArray, join, kebabCase, logger, lowerCase, max, median, memoize, merge, min, move, noop, ok, omit, once, parse, partition, pascalCase, pick, pipe, promises, push, queue, range, retry, rgbToHex, rgbToHsl, rgbToHsla, round, select, setValue, shuffle, slice, smush, snakeCase, sort, splice, startsWith, startsWithArray, sum, swap, take, template, throttle, timed, times, titleCase, toMap, toQuery, toRecord, toSet, toggle, trim, truncate, tryDecode, tryEncode, union, unique, unsmush, unwrap, update, upperCase, words };
|
package/dist/index.mjs
CHANGED
|
@@ -762,63 +762,72 @@ const comparators = {
|
|
|
762
762
|
};
|
|
763
763
|
//#endregion
|
|
764
764
|
//#region src/array/sort.ts
|
|
765
|
-
function
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
return typeof value === "string" ? value : void 0;
|
|
765
|
+
function getComparisonSorter(callback, modifier) {
|
|
766
|
+
return {
|
|
767
|
+
modifier,
|
|
768
|
+
compare: { simple: callback },
|
|
769
|
+
get: false,
|
|
770
|
+
identifier: String(callback)
|
|
771
|
+
};
|
|
773
772
|
}
|
|
774
|
-
function
|
|
775
|
-
|
|
776
|
-
if (
|
|
777
|
-
|
|
773
|
+
function getObjectSorter(obj, modifier) {
|
|
774
|
+
let sorter;
|
|
775
|
+
if (typeof obj.comparison === "function") sorter = getComparisonSorter(obj.comparison, modifier);
|
|
776
|
+
else if (typeof obj.key === "string") {
|
|
777
|
+
sorter = getValueSorter(obj.key, modifier);
|
|
778
|
+
if (typeof obj.compare === "function") sorter.compare = { complex: obj.compare };
|
|
779
|
+
} else if (typeof obj.value === "function") sorter = getValueSorter(obj.value, modifier);
|
|
780
|
+
if (sorter != null && typeof obj.direction === "string") sorter.modifier = modifiers[obj.direction] ?? modifier;
|
|
781
|
+
return sorter;
|
|
778
782
|
}
|
|
779
783
|
function getSorter(value, modifier) {
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
modifier
|
|
784
|
-
|
|
785
|
-
sorter.compare = forObject && typeof value.compare === "function" ? value.compare : void 0;
|
|
786
|
-
sorter.key = getKey(value, forObject);
|
|
787
|
-
sorter.modifier = getModifier(value, modifier, forObject);
|
|
788
|
-
sorter.callback = getCallback(value, sorter.key, forObject);
|
|
789
|
-
if (sorter.key != null || sorter.callback != null) {
|
|
790
|
-
sorter.identifier = `${sorter.key ?? sorter.callback}`;
|
|
791
|
-
return sorter;
|
|
784
|
+
switch (true) {
|
|
785
|
+
case typeof value === "function": return getComparisonSorter(value, modifier);
|
|
786
|
+
case typeof value === "string": return getValueSorter(value, modifier);
|
|
787
|
+
case isPlainObject(value): return getObjectSorter(value, modifier);
|
|
788
|
+
default: break;
|
|
792
789
|
}
|
|
793
790
|
}
|
|
791
|
+
function getValueSorter(value, modifier) {
|
|
792
|
+
return {
|
|
793
|
+
modifier,
|
|
794
|
+
get: true,
|
|
795
|
+
identifier: String(value),
|
|
796
|
+
value: typeof value === "function" ? value : (item) => item[value]
|
|
797
|
+
};
|
|
798
|
+
}
|
|
794
799
|
function sort(array, first, second) {
|
|
795
800
|
if (!Array.isArray(array)) return [];
|
|
796
801
|
if (array.length < 2) return array;
|
|
797
|
-
const modifier =
|
|
802
|
+
const modifier = modifiers[first === true || second === true ? SORT_DIRECTION_DESCENDING : SORT_DIRECTION_ASCENDING];
|
|
798
803
|
const sorters = (Array.isArray(first) ? first : [first]).map((item) => getSorter(item, modifier)).filter((sorter) => sorter != null).filter((current, index, filtered) => filtered.findIndex((next) => next.identifier === current.identifier) === index);
|
|
799
804
|
const { length } = sorters;
|
|
800
|
-
if (length === 0) return array.sort((
|
|
805
|
+
if (length === 0) return array.sort((first, second) => compare(first, second) * modifier);
|
|
801
806
|
if (length === 1) {
|
|
802
807
|
const sorter = sorters[0];
|
|
803
|
-
const { callback, key } = sorter;
|
|
804
808
|
return array.sort((firstItem, secondItem) => {
|
|
805
|
-
const firstValue =
|
|
806
|
-
const secondValue =
|
|
807
|
-
return (sorter.compare?.(firstItem, firstValue, secondItem, secondValue) ?? compare(firstValue, secondValue)) * sorter.modifier;
|
|
809
|
+
const firstValue = sorter.get ? sorter.value(firstItem) : firstItem;
|
|
810
|
+
const secondValue = sorter.get ? sorter.value(secondItem) : secondItem;
|
|
811
|
+
return (sorter.compare?.complex?.(firstItem, firstValue, secondItem, secondValue) ?? sorter.compare?.simple?.(firstItem, secondItem) ?? compare(firstValue, secondValue)) * sorter.modifier;
|
|
808
812
|
});
|
|
809
813
|
}
|
|
810
814
|
return array.sort((firstItem, secondItem) => {
|
|
811
815
|
for (let index = 0; index < length; index += 1) {
|
|
812
816
|
const sorter = sorters[index];
|
|
813
|
-
const
|
|
814
|
-
const
|
|
815
|
-
const
|
|
816
|
-
|
|
817
|
-
if (compared !== 0) return compared;
|
|
817
|
+
const firstValue = sorter.value?.(firstItem) ?? firstItem;
|
|
818
|
+
const secondValue = sorter.value?.(secondItem) ?? secondItem;
|
|
819
|
+
const comparison = (sorter.compare?.complex?.(firstItem, firstValue, secondItem, secondValue) ?? sorter.compare?.simple?.(firstItem, secondItem) ?? compare(firstValue, secondValue)) * sorter.modifier;
|
|
820
|
+
if (comparison !== 0) return comparison;
|
|
818
821
|
}
|
|
819
822
|
return 0;
|
|
820
823
|
});
|
|
821
824
|
}
|
|
825
|
+
const SORT_DIRECTION_ASCENDING = "ascending";
|
|
826
|
+
const SORT_DIRECTION_DESCENDING = "descending";
|
|
827
|
+
const modifiers = {
|
|
828
|
+
[SORT_DIRECTION_ASCENDING]: 1,
|
|
829
|
+
[SORT_DIRECTION_DESCENDING]: -1
|
|
830
|
+
};
|
|
822
831
|
//#endregion
|
|
823
832
|
//#region src/array/splice.ts
|
|
824
833
|
function splice(array, start, deleteCountOrItems, items) {
|
|
@@ -3659,31 +3668,6 @@ function sum(array, key) {
|
|
|
3659
3668
|
return getAggregated("sum", array, key);
|
|
3660
3669
|
}
|
|
3661
3670
|
//#endregion
|
|
3662
|
-
//#region src/result/match.ts
|
|
3663
|
-
async function asyncMatchResult(result, first, error) {
|
|
3664
|
-
let value;
|
|
3665
|
-
if (typeof result === "function") value = await result();
|
|
3666
|
-
else if (result instanceof Promise) value = await result;
|
|
3667
|
-
else value = result;
|
|
3668
|
-
if (!isResult(value)) throw new Error(MESSAGE_RESULT);
|
|
3669
|
-
const hasObj = typeof first === "object" && first !== null;
|
|
3670
|
-
const okHandler = hasObj ? first.ok : first;
|
|
3671
|
-
const errorHandler = hasObj ? first.error : error;
|
|
3672
|
-
if (isOk(value)) return okHandler(value.value);
|
|
3673
|
-
return errorHandler(value.error, value.original);
|
|
3674
|
-
}
|
|
3675
|
-
function matchResult(result, first, error) {
|
|
3676
|
-
const value = typeof result === "function" ? result() : result;
|
|
3677
|
-
if (!isResult(value)) throw new Error(MESSAGE_RESULT);
|
|
3678
|
-
const hasObj = typeof first === "object" && first !== null;
|
|
3679
|
-
const okHandler = hasObj ? first.ok : first;
|
|
3680
|
-
const errorHandler = hasObj ? first.error : error;
|
|
3681
|
-
if (isOk(value)) return okHandler(value.value);
|
|
3682
|
-
return errorHandler(value.error, value.original);
|
|
3683
|
-
}
|
|
3684
|
-
matchResult.async = asyncMatchResult;
|
|
3685
|
-
const MESSAGE_RESULT = "`result.match` expected a Result or a function that returns a Result";
|
|
3686
|
-
//#endregion
|
|
3687
3671
|
//#region src/result/misc.ts
|
|
3688
3672
|
function error(value, original) {
|
|
3689
3673
|
return getError(value, original);
|
|
@@ -3724,48 +3708,6 @@ function unwrap(value, defaultValue) {
|
|
|
3724
3708
|
}
|
|
3725
3709
|
const MESSAGE_PROMISE_RESULT = "toPromise expected to receive a Result";
|
|
3726
3710
|
//#endregion
|
|
3727
|
-
//#region src/result/work/flow.ts
|
|
3728
|
-
function attemptAsyncFlow(...fns) {
|
|
3729
|
-
let Flow;
|
|
3730
|
-
return (...args) => attempt.async(() => {
|
|
3731
|
-
Flow ??= flow.async(...fns);
|
|
3732
|
-
return Flow(...args.map((value) => {
|
|
3733
|
-
if (isError(value)) throw value.error;
|
|
3734
|
-
return isOk(value) ? value.value : value;
|
|
3735
|
-
}));
|
|
3736
|
-
});
|
|
3737
|
-
}
|
|
3738
|
-
function attemptFlow(...fns) {
|
|
3739
|
-
let Flow;
|
|
3740
|
-
return (...args) => attempt(() => {
|
|
3741
|
-
Flow ??= flow(...fns);
|
|
3742
|
-
return Flow(...args.map((value) => {
|
|
3743
|
-
if (isError(value)) throw value.error;
|
|
3744
|
-
return isOk(value) ? value.value : value;
|
|
3745
|
-
}));
|
|
3746
|
-
});
|
|
3747
|
-
}
|
|
3748
|
-
attemptFlow.async = attemptAsyncFlow;
|
|
3749
|
-
//#endregion
|
|
3750
|
-
//#region src/result/work/pipe.ts
|
|
3751
|
-
async function attemptAsyncPipe(initial, first, ...seconds) {
|
|
3752
|
-
return attempt.async(() => {
|
|
3753
|
-
if (isError(initial)) throw initial.error;
|
|
3754
|
-
const value = typeof initial === "function" ? initial() : isOk(initial) ? initial.value : initial;
|
|
3755
|
-
if (first == null) return value;
|
|
3756
|
-
return pipe.async(value, ...[first, ...seconds]);
|
|
3757
|
-
});
|
|
3758
|
-
}
|
|
3759
|
-
function attemptPipe(initial, first, ...seconds) {
|
|
3760
|
-
return attempt(() => {
|
|
3761
|
-
if (isError(initial)) throw initial.error;
|
|
3762
|
-
const value = typeof initial === "function" ? initial() : isOk(initial) ? initial.value : initial;
|
|
3763
|
-
if (first == null) return value;
|
|
3764
|
-
return pipe(value, ...[first, ...seconds]);
|
|
3765
|
-
});
|
|
3766
|
-
}
|
|
3767
|
-
attemptPipe.async = attemptAsyncPipe;
|
|
3768
|
-
//#endregion
|
|
3769
3711
|
//#region src/promise/models.ts
|
|
3770
3712
|
var CancelablePromise = class extends Promise {
|
|
3771
3713
|
#rejector;
|
|
@@ -3803,64 +3745,6 @@ const PROMISE_STRATEGY_DEFAULT = "complete";
|
|
|
3803
3745
|
const PROMISE_TYPE_FULFILLED = "fulfilled";
|
|
3804
3746
|
const PROMISE_TYPE_REJECTED = "rejected";
|
|
3805
3747
|
//#endregion
|
|
3806
|
-
//#region src/promise/misc.ts
|
|
3807
|
-
/**
|
|
3808
|
-
* Create a cancelable promise
|
|
3809
|
-
* @param executor Executor function for the promise
|
|
3810
|
-
* @returns Cancelable promise
|
|
3811
|
-
*/
|
|
3812
|
-
function cancelable(executor) {
|
|
3813
|
-
return new CancelablePromise(executor);
|
|
3814
|
-
}
|
|
3815
|
-
function handleResult$1(status, parameters) {
|
|
3816
|
-
const { abort, complete, data, handlers, index, signal, value } = parameters;
|
|
3817
|
-
if (signal?.aborted ?? false) return;
|
|
3818
|
-
if (!complete && status === "rejected") {
|
|
3819
|
-
settlePromise(abort, handlers.reject, value, signal);
|
|
3820
|
-
return;
|
|
3821
|
-
}
|
|
3822
|
-
data.result[index] = !complete ? value : status === "fulfilled" ? {
|
|
3823
|
-
status,
|
|
3824
|
-
value
|
|
3825
|
-
} : {
|
|
3826
|
-
status,
|
|
3827
|
-
reason: value
|
|
3828
|
-
};
|
|
3829
|
-
if (index === data.last) settlePromise(abort, handlers.resolve, data.result, signal);
|
|
3830
|
-
}
|
|
3831
|
-
function settlePromise(aborter, settler, value, signal) {
|
|
3832
|
-
signal?.removeEventListener(PROMISE_ABORT_EVENT, aborter);
|
|
3833
|
-
settler(value);
|
|
3834
|
-
}
|
|
3835
|
-
async function toResult(value) {
|
|
3836
|
-
const actual = typeof value === "function" ? value() : value;
|
|
3837
|
-
if (!(actual instanceof Promise)) return Promise.reject(new TypeError(PROMISE_MESSAGE_EXPECTATION_RESULT));
|
|
3838
|
-
return actual.then((result) => ok(result)).catch((reason) => error(reason));
|
|
3839
|
-
}
|
|
3840
|
-
//#endregion
|
|
3841
|
-
//#region src/result/index.ts
|
|
3842
|
-
async function asyncAttempt(value, err) {
|
|
3843
|
-
try {
|
|
3844
|
-
let result = typeof value === "function" ? value() : await value;
|
|
3845
|
-
if (result instanceof Promise) result = await result;
|
|
3846
|
-
return ok(result);
|
|
3847
|
-
} catch (thrown) {
|
|
3848
|
-
return getError(err ?? thrown, err == null ? void 0 : thrown);
|
|
3849
|
-
}
|
|
3850
|
-
}
|
|
3851
|
-
function attempt(callback, err) {
|
|
3852
|
-
try {
|
|
3853
|
-
return ok(callback());
|
|
3854
|
-
} catch (thrown) {
|
|
3855
|
-
return getError(err ?? thrown, err == null ? void 0 : thrown);
|
|
3856
|
-
}
|
|
3857
|
-
}
|
|
3858
|
-
attempt.async = asyncAttempt;
|
|
3859
|
-
attempt.flow = attemptFlow;
|
|
3860
|
-
attempt.match = matchResult;
|
|
3861
|
-
attempt.pipe = attemptPipe;
|
|
3862
|
-
attempt.promise = attemptPromise;
|
|
3863
|
-
//#endregion
|
|
3864
3748
|
//#region src/promise/helpers.ts
|
|
3865
3749
|
function getNumberOrDefault$1(value) {
|
|
3866
3750
|
return typeof value === "number" && value > 0 ? value : 0;
|
|
@@ -3915,6 +3799,41 @@ function isType(value, type) {
|
|
|
3915
3799
|
return typeof value === "object" && value !== null && value.status === type;
|
|
3916
3800
|
}
|
|
3917
3801
|
//#endregion
|
|
3802
|
+
//#region src/promise/misc.ts
|
|
3803
|
+
/**
|
|
3804
|
+
* Create a cancelable promise
|
|
3805
|
+
* @param executor Executor function for the promise
|
|
3806
|
+
* @returns Cancelable promise
|
|
3807
|
+
*/
|
|
3808
|
+
function cancelable(executor) {
|
|
3809
|
+
return new CancelablePromise(executor);
|
|
3810
|
+
}
|
|
3811
|
+
function handleResult$1(status, parameters) {
|
|
3812
|
+
const { abort, complete, data, handlers, index, signal, value } = parameters;
|
|
3813
|
+
if (signal?.aborted ?? false) return;
|
|
3814
|
+
if (!complete && status === "rejected") {
|
|
3815
|
+
settlePromise(abort, handlers.reject, value, signal);
|
|
3816
|
+
return;
|
|
3817
|
+
}
|
|
3818
|
+
data.result[index] = !complete ? value : status === "fulfilled" ? {
|
|
3819
|
+
status,
|
|
3820
|
+
value
|
|
3821
|
+
} : {
|
|
3822
|
+
status,
|
|
3823
|
+
reason: value
|
|
3824
|
+
};
|
|
3825
|
+
if (index === data.last) settlePromise(abort, handlers.resolve, data.result, signal);
|
|
3826
|
+
}
|
|
3827
|
+
function settlePromise(aborter, settler, value, signal) {
|
|
3828
|
+
signal?.removeEventListener(PROMISE_ABORT_EVENT, aborter);
|
|
3829
|
+
settler(value);
|
|
3830
|
+
}
|
|
3831
|
+
async function toResult(value) {
|
|
3832
|
+
const actual = typeof value === "function" ? value() : value;
|
|
3833
|
+
if (!(actual instanceof Promise)) return Promise.reject(new TypeError(PROMISE_MESSAGE_EXPECTATION_RESULT));
|
|
3834
|
+
return actual.then((result) => ok(result)).catch((reason) => error(reason));
|
|
3835
|
+
}
|
|
3836
|
+
//#endregion
|
|
3918
3837
|
//#region src/promise/timed.ts
|
|
3919
3838
|
async function getTimedPromise(promise, time, signal) {
|
|
3920
3839
|
function abort() {
|
|
@@ -4372,6 +4291,96 @@ const BOOLEAN_MODIFIER = .5;
|
|
|
4372
4291
|
const HEX_CHARACTERS = "0123456789ABCDEF";
|
|
4373
4292
|
const HEX_MAXIMUM = 15;
|
|
4374
4293
|
//#endregion
|
|
4294
|
+
//#region src/result/match.ts
|
|
4295
|
+
async function asyncMatchResult(result, first, error) {
|
|
4296
|
+
let value;
|
|
4297
|
+
if (typeof result === "function") value = await result();
|
|
4298
|
+
else if (result instanceof Promise) value = await result;
|
|
4299
|
+
else value = result;
|
|
4300
|
+
if (!isResult(value)) throw new Error(MESSAGE_RESULT);
|
|
4301
|
+
const hasObj = typeof first === "object" && first !== null;
|
|
4302
|
+
const okHandler = hasObj ? first.ok : first;
|
|
4303
|
+
const errorHandler = hasObj ? first.error : error;
|
|
4304
|
+
if (isOk(value)) return okHandler(value.value);
|
|
4305
|
+
return errorHandler(value.error, value.original);
|
|
4306
|
+
}
|
|
4307
|
+
function matchResult(result, first, error) {
|
|
4308
|
+
const value = typeof result === "function" ? result() : result;
|
|
4309
|
+
if (!isResult(value)) throw new Error(MESSAGE_RESULT);
|
|
4310
|
+
const hasObj = typeof first === "object" && first !== null;
|
|
4311
|
+
const okHandler = hasObj ? first.ok : first;
|
|
4312
|
+
const errorHandler = hasObj ? first.error : error;
|
|
4313
|
+
if (isOk(value)) return okHandler(value.value);
|
|
4314
|
+
return errorHandler(value.error, value.original);
|
|
4315
|
+
}
|
|
4316
|
+
matchResult.async = asyncMatchResult;
|
|
4317
|
+
const MESSAGE_RESULT = "`result.match` expected a Result or a function that returns a Result";
|
|
4318
|
+
//#endregion
|
|
4319
|
+
//#region src/result/work/flow.ts
|
|
4320
|
+
function attemptAsyncFlow(...fns) {
|
|
4321
|
+
let Flow;
|
|
4322
|
+
return (...args) => attempt.async(() => {
|
|
4323
|
+
Flow ??= flow.async(...fns);
|
|
4324
|
+
return Flow(...args.map((value) => {
|
|
4325
|
+
if (isError(value)) throw value.error;
|
|
4326
|
+
return isOk(value) ? value.value : value;
|
|
4327
|
+
}));
|
|
4328
|
+
});
|
|
4329
|
+
}
|
|
4330
|
+
function attemptFlow(...fns) {
|
|
4331
|
+
let Flow;
|
|
4332
|
+
return (...args) => attempt(() => {
|
|
4333
|
+
Flow ??= flow(...fns);
|
|
4334
|
+
return Flow(...args.map((value) => {
|
|
4335
|
+
if (isError(value)) throw value.error;
|
|
4336
|
+
return isOk(value) ? value.value : value;
|
|
4337
|
+
}));
|
|
4338
|
+
});
|
|
4339
|
+
}
|
|
4340
|
+
attemptFlow.async = attemptAsyncFlow;
|
|
4341
|
+
//#endregion
|
|
4342
|
+
//#region src/result/work/pipe.ts
|
|
4343
|
+
async function attemptAsyncPipe(initial, first, ...seconds) {
|
|
4344
|
+
return attempt.async(() => {
|
|
4345
|
+
if (isError(initial)) throw initial.error;
|
|
4346
|
+
const value = typeof initial === "function" ? initial() : isOk(initial) ? initial.value : initial;
|
|
4347
|
+
if (first == null) return value;
|
|
4348
|
+
return pipe.async(value, ...[first, ...seconds]);
|
|
4349
|
+
});
|
|
4350
|
+
}
|
|
4351
|
+
function attemptPipe(initial, first, ...seconds) {
|
|
4352
|
+
return attempt(() => {
|
|
4353
|
+
if (isError(initial)) throw initial.error;
|
|
4354
|
+
const value = typeof initial === "function" ? initial() : isOk(initial) ? initial.value : initial;
|
|
4355
|
+
if (first == null) return value;
|
|
4356
|
+
return pipe(value, ...[first, ...seconds]);
|
|
4357
|
+
});
|
|
4358
|
+
}
|
|
4359
|
+
attemptPipe.async = attemptAsyncPipe;
|
|
4360
|
+
//#endregion
|
|
4361
|
+
//#region src/result/index.ts
|
|
4362
|
+
async function asyncAttempt(value, err) {
|
|
4363
|
+
try {
|
|
4364
|
+
let result = typeof value === "function" ? value() : await value;
|
|
4365
|
+
if (result instanceof Promise) result = await result;
|
|
4366
|
+
return ok(result);
|
|
4367
|
+
} catch (thrown) {
|
|
4368
|
+
return getError(err ?? thrown, err == null ? void 0 : thrown);
|
|
4369
|
+
}
|
|
4370
|
+
}
|
|
4371
|
+
function attempt(callback, err) {
|
|
4372
|
+
try {
|
|
4373
|
+
return ok(callback());
|
|
4374
|
+
} catch (thrown) {
|
|
4375
|
+
return getError(err ?? thrown, err == null ? void 0 : thrown);
|
|
4376
|
+
}
|
|
4377
|
+
}
|
|
4378
|
+
attempt.async = asyncAttempt;
|
|
4379
|
+
attempt.flow = attemptFlow;
|
|
4380
|
+
attempt.match = matchResult;
|
|
4381
|
+
attempt.pipe = attemptPipe;
|
|
4382
|
+
attempt.promise = attemptPromise;
|
|
4383
|
+
//#endregion
|
|
4375
4384
|
//#region src/sized/set.ts
|
|
4376
4385
|
/**
|
|
4377
4386
|
* - A Set with a maximum size
|
|
@@ -4426,4 +4435,4 @@ var SizedSet = class extends Set {
|
|
|
4426
4435
|
}
|
|
4427
4436
|
};
|
|
4428
4437
|
//#endregion
|
|
4429
|
-
export { CancelablePromise, PromiseTimeoutError, QueueError, RetryError, SizedMap, SizedSet, assert, attempt, attemptPromise, average, beacon, between, camelCase, cancelable, capitalize, ceil, chunk, clamp, clone, compact, compare, count, debounce, delay, diff, difference, drop, endsWith, endsWithArray, equal, error, exists, filter, find, flatten, floor, flow, toResult as fromPromise, toResult, fromQuery, toPromise as fromResult, toPromise, getArray, getArrayPosition, getColor, getForegroundColor, getHexColor, getHexaColor, getHslColor, getHslaColor, getNormalizedHex, getNumber, getRandomBoolean, getRandomCharacters, getRandomColor, getRandomFloat, getRandomHex, getRandomInteger, getRandomItem, getRandomItems, getRgbColor, getRgbaColor, getString, getUuid, getValue, groupBy, hasValue, hexToHsl, hexToHsla, hexToRgb, hexToRgba, hslToHex, hslToRgb, hslToRgba, ignoreKey, includes, includesArray, indexOf, indexOfArray, insert, intersection, isArrayOrPlainObject, isColor, isConstructor, isEmpty, isError, isFulfilled, isHexColor, isHslColor, isHslLike, isHslaColor, isInstanceOf, isKey, isNonNullable, isNullable, isNullableOrEmpty, isNullableOrWhitespace, isNumber, isNumerical, isObject, isOk, isPlainObject, isPrimitive, isRejected, isResult, isRgbColor, isRgbLike, isRgbaColor, isTypedArray, join, kebabCase, logger, lowerCase, max, median, memoize, merge, min, move, noop, ok, omit, once, parse, partition, pascalCase, pick, pipe, promises, push, queue, range, retry, rgbToHex, rgbToHsl, rgbToHsla, round, select, setValue, shuffle, slice, smush, snakeCase, sort, splice, startsWith, startsWithArray, sum, swap, take, template, throttle, timed, times, titleCase, toMap, toQuery, toRecord, toSet, toggle, trim, truncate, tryDecode, tryEncode, union, unique, unsmush, unwrap, update, upperCase, words };
|
|
4438
|
+
export { CancelablePromise, PromiseTimeoutError, QueueError, RetryError, SORT_DIRECTION_ASCENDING, SORT_DIRECTION_DESCENDING, SizedMap, SizedSet, assert, attempt, attemptPromise, average, beacon, between, camelCase, cancelable, capitalize, ceil, chunk, clamp, clone, compact, compare, count, debounce, delay, diff, difference, drop, endsWith, endsWithArray, equal, error, exists, filter, find, flatten, floor, flow, toResult as fromPromise, toResult, fromQuery, toPromise as fromResult, toPromise, getArray, getArrayPosition, getColor, getForegroundColor, getHexColor, getHexaColor, getHslColor, getHslaColor, getNormalizedHex, getNumber, getRandomBoolean, getRandomCharacters, getRandomColor, getRandomFloat, getRandomHex, getRandomInteger, getRandomItem, getRandomItems, getRgbColor, getRgbaColor, getString, getUuid, getValue, groupBy, hasValue, hexToHsl, hexToHsla, hexToRgb, hexToRgba, hslToHex, hslToRgb, hslToRgba, ignoreKey, includes, includesArray, indexOf, indexOfArray, insert, intersection, isArrayOrPlainObject, isColor, isConstructor, isEmpty, isError, isFulfilled, isHexColor, isHslColor, isHslLike, isHslaColor, isInstanceOf, isKey, isNonNullable, isNullable, isNullableOrEmpty, isNullableOrWhitespace, isNumber, isNumerical, isObject, isOk, isPlainObject, isPrimitive, isRejected, isResult, isRgbColor, isRgbLike, isRgbaColor, isTypedArray, join, kebabCase, logger, lowerCase, max, median, memoize, merge, min, move, noop, ok, omit, once, parse, partition, pascalCase, pick, pipe, promises, push, queue, range, retry, rgbToHex, rgbToHsl, rgbToHsla, round, select, setValue, shuffle, slice, smush, snakeCase, sort, splice, startsWith, startsWithArray, sum, swap, take, template, throttle, timed, times, titleCase, toMap, toQuery, toRecord, toSet, toggle, trim, truncate, tryDecode, tryEncode, union, unique, unsmush, unwrap, update, upperCase, words };
|
package/dist/promise/delay.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { TIMER_WAIT, getTimer } from "../internal/function/timer.mjs";
|
|
2
2
|
import { PROMISE_ABORT_EVENT, PROMISE_ABORT_OPTIONS } from "./models.mjs";
|
|
3
|
-
import { settlePromise } from "./misc.mjs";
|
|
4
3
|
import { getPromiseOptions } from "./helpers.mjs";
|
|
4
|
+
import { settlePromise } from "./misc.mjs";
|
|
5
5
|
//#region src/promise/delay.ts
|
|
6
6
|
function delay(options) {
|
|
7
7
|
const { signal, time } = getPromiseOptions(options);
|
package/dist/promise/helpers.mjs
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { error, ok } from "../result/misc.mjs";
|
|
2
2
|
import { PROMISE_STRATEGY_ALL, PROMISE_STRATEGY_DEFAULT, PROMISE_TYPE_FULFILLED, PROMISE_TYPE_REJECTED } from "./models.mjs";
|
|
3
|
-
import "../result/index.mjs";
|
|
4
3
|
//#region src/promise/helpers.ts
|
|
5
4
|
function getNumberOrDefault(value) {
|
|
6
5
|
return typeof value === "number" && value > 0 ? value : 0;
|
package/dist/promise/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { toPromise } from "../result/misc.mjs";
|
|
2
2
|
import { CancelablePromise, PROMISE_ABORT_EVENT, PROMISE_ABORT_OPTIONS, PROMISE_MESSAGE_EXPECTATION_ATTEMPT, PROMISE_STRATEGY_DEFAULT, PROMISE_TYPE_FULFILLED, PROMISE_TYPE_REJECTED, PromiseTimeoutError } from "./models.mjs";
|
|
3
|
-
import { cancelable, handleResult, settlePromise, toResult } from "./misc.mjs";
|
|
4
3
|
import { getPromiseOptions, getPromisesOptions, getResultsFromPromises, isFulfilled, isRejected } from "./helpers.mjs";
|
|
4
|
+
import { cancelable, handleResult, settlePromise, toResult } from "./misc.mjs";
|
|
5
5
|
import { getTimedPromise, timed } from "./timed.mjs";
|
|
6
6
|
import { delay } from "./delay.mjs";
|
|
7
7
|
//#region src/promise/index.ts
|
package/dist/promise/timed.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { TIMER_WAIT, getTimer } from "../internal/function/timer.mjs";
|
|
2
2
|
import { PROMISE_ABORT_EVENT, PROMISE_ABORT_OPTIONS, PROMISE_MESSAGE_EXPECTATION_TIMED, PromiseTimeoutError } from "./models.mjs";
|
|
3
|
-
import { settlePromise } from "./misc.mjs";
|
|
4
3
|
import { getPromiseOptions } from "./helpers.mjs";
|
|
4
|
+
import { settlePromise } from "./misc.mjs";
|
|
5
5
|
//#region src/promise/timed.ts
|
|
6
6
|
async function getTimedPromise(promise, time, signal) {
|
|
7
7
|
function abort() {
|
package/dist/result/index.mjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { isError, isOk, isResult } from "../internal/result.mjs";
|
|
2
|
-
import { matchResult } from "./match.mjs";
|
|
3
2
|
import { error, getError, ok, toPromise, unwrap } from "./misc.mjs";
|
|
4
|
-
import { attemptFlow } from "./work/flow.mjs";
|
|
5
|
-
import { attemptPipe } from "./work/pipe.mjs";
|
|
6
3
|
import { toResult } from "../promise/misc.mjs";
|
|
7
4
|
import { attemptPromise } from "../promise/index.mjs";
|
|
5
|
+
import { matchResult } from "./match.mjs";
|
|
6
|
+
import { attemptFlow } from "./work/flow.mjs";
|
|
7
|
+
import { attemptPipe } from "./work/pipe.mjs";
|
|
8
8
|
//#region src/result/index.ts
|
|
9
9
|
async function asyncAttempt(value, err) {
|
|
10
10
|
try {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oscarpalmer/atoms",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.166.0",
|
|
4
4
|
"description": "Atomic utilities for making your JavaScript better.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"helper",
|
|
@@ -195,7 +195,7 @@
|
|
|
195
195
|
"devDependencies": {
|
|
196
196
|
"@types/node": "^25.5",
|
|
197
197
|
"@vitest/coverage-istanbul": "^4.1",
|
|
198
|
-
"jsdom": "^
|
|
198
|
+
"jsdom": "^29.0",
|
|
199
199
|
"tsdown": "^0.21",
|
|
200
200
|
"typescript": "^5.9",
|
|
201
201
|
"vite": "npm:@voidzero-dev/vite-plus-core@latest",
|
package/src/array/index.ts
CHANGED
package/src/array/sort.ts
CHANGED
|
@@ -1,35 +1,31 @@
|
|
|
1
1
|
import {isPlainObject} from '../internal/is';
|
|
2
2
|
import {compare} from '../internal/value/compare';
|
|
3
|
-
import type {
|
|
3
|
+
import type {PlainObject, Primitive} from '../models';
|
|
4
4
|
|
|
5
5
|
// #region Types
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
* Sorting information for arrays _(using a callback)_
|
|
8
|
+
* Sorting information for arrays _(using a comparison callback)_
|
|
9
9
|
*/
|
|
10
|
-
export type
|
|
10
|
+
export type ArrayComparisonSorter<Item> = {
|
|
11
11
|
/**
|
|
12
|
-
*
|
|
12
|
+
* Callback to use when comparing items and values
|
|
13
13
|
*/
|
|
14
|
-
|
|
14
|
+
comparison: ComparisonSorter<Item>;
|
|
15
15
|
/**
|
|
16
16
|
* Direction to sort by
|
|
17
17
|
*/
|
|
18
18
|
direction?: SortDirection;
|
|
19
|
-
/**
|
|
20
|
-
* Value to sort by
|
|
21
|
-
*/
|
|
22
|
-
value: (item: Item) => unknown;
|
|
23
19
|
};
|
|
24
20
|
|
|
25
21
|
/**
|
|
26
22
|
* Sorting information for arrays _(using a key)_
|
|
27
23
|
*/
|
|
28
|
-
export type ArrayKeySorter<Item> = {
|
|
24
|
+
export type ArrayKeySorter<Item extends PlainObject, Key extends keyof Item> = {
|
|
29
25
|
/**
|
|
30
26
|
* Comparator to use when comparing items and values
|
|
31
27
|
*/
|
|
32
|
-
compare?:
|
|
28
|
+
compare?: CompareCallback<Item, Item[Key]>;
|
|
33
29
|
/**
|
|
34
30
|
* Direction to sort by
|
|
35
31
|
*/
|
|
@@ -37,82 +33,150 @@ export type ArrayKeySorter<Item> = {
|
|
|
37
33
|
/**
|
|
38
34
|
* Key to sort by
|
|
39
35
|
*/
|
|
40
|
-
key:
|
|
36
|
+
key: Key;
|
|
41
37
|
};
|
|
42
38
|
|
|
43
|
-
|
|
39
|
+
/**
|
|
40
|
+
* Sorters based on keys in an object
|
|
41
|
+
*/
|
|
42
|
+
type ArrayKeySorters<Item extends PlainObject> = {
|
|
43
|
+
[Key in keyof Item]: ArrayKeySorter<Item, Key>;
|
|
44
|
+
}[keyof Item];
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Sorting information for arrays _(using a value callback and built-in comparison)_
|
|
48
|
+
*/
|
|
49
|
+
export type ArrayValueSorter<Item> = {
|
|
50
|
+
/**
|
|
51
|
+
* Direction to sort by
|
|
52
|
+
*/
|
|
53
|
+
direction?: SortDirection;
|
|
54
|
+
/**
|
|
55
|
+
* Value to sort by
|
|
56
|
+
*/
|
|
57
|
+
value: (item: Item) => unknown;
|
|
58
|
+
};
|
|
44
59
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
60
|
+
/**
|
|
61
|
+
* Comparator to use when comparing items and values
|
|
62
|
+
*/
|
|
63
|
+
type CompareCallback<Item, Value = CompareCallbackValue<Item>> = (
|
|
64
|
+
first: Item,
|
|
65
|
+
firstValue: Value,
|
|
66
|
+
second: Item,
|
|
67
|
+
secondValue: Value,
|
|
68
|
+
) => number;
|
|
69
|
+
|
|
70
|
+
type CompareCallbackValue<Item> = Item extends Primitive ? Item : unknown;
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Callback to use when comparing items and values
|
|
74
|
+
*/
|
|
75
|
+
type ComparisonSorter<Item> = (first: Item, second: Item) => number;
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Internal sorter information
|
|
79
|
+
*/
|
|
80
|
+
type InternalSorter = {
|
|
81
|
+
compare?: SorterCompare;
|
|
82
|
+
get: boolean;
|
|
48
83
|
identifier: string;
|
|
49
|
-
key?: string;
|
|
50
84
|
modifier: number;
|
|
51
|
-
|
|
85
|
+
value?: (item: PlainObject) => unknown;
|
|
52
86
|
};
|
|
53
87
|
|
|
54
|
-
|
|
88
|
+
/**
|
|
89
|
+
* Direction to sort by
|
|
90
|
+
*/
|
|
91
|
+
export type SortDirection = 'ascending' | 'descending';
|
|
55
92
|
|
|
56
|
-
|
|
93
|
+
/**
|
|
94
|
+
* Comparison callbacks for sorter
|
|
95
|
+
*/
|
|
96
|
+
type SorterCompare = {
|
|
97
|
+
complex?: Function;
|
|
98
|
+
simple?: Function;
|
|
99
|
+
};
|
|
57
100
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
101
|
+
/**
|
|
102
|
+
* Sorter to use for sorting
|
|
103
|
+
*/
|
|
104
|
+
type Sorter<Item> = Item extends PlainObject
|
|
105
|
+
?
|
|
106
|
+
| keyof Item
|
|
107
|
+
| ArrayComparisonSorter<Item>
|
|
108
|
+
| ArrayKeySorters<Item>
|
|
109
|
+
| ArrayValueSorter<Item>
|
|
110
|
+
| ComparisonSorter<Item>
|
|
111
|
+
: ArrayComparisonSorter<Item> | ArrayValueSorter<Item> | ComparisonSorter<Item>;
|
|
66
112
|
|
|
67
|
-
|
|
68
|
-
return (value as PlainObject).value as never;
|
|
69
|
-
}
|
|
113
|
+
// #endregion
|
|
70
114
|
|
|
71
|
-
|
|
115
|
+
// #region Functions
|
|
116
|
+
|
|
117
|
+
function getComparisonSorter(callback: Function, modifier: number): InternalSorter {
|
|
118
|
+
return {
|
|
119
|
+
modifier,
|
|
120
|
+
compare: {
|
|
121
|
+
simple: callback,
|
|
122
|
+
},
|
|
123
|
+
get: false,
|
|
124
|
+
identifier: String(callback),
|
|
125
|
+
};
|
|
72
126
|
}
|
|
73
127
|
|
|
74
|
-
function
|
|
75
|
-
|
|
76
|
-
return (value as PlainObject).key as string;
|
|
77
|
-
}
|
|
128
|
+
function getObjectSorter(obj: PlainObject, modifier: number): InternalSorter | undefined {
|
|
129
|
+
let sorter: InternalSorter | undefined;
|
|
78
130
|
|
|
79
|
-
|
|
80
|
-
|
|
131
|
+
if (typeof obj.comparison === 'function') {
|
|
132
|
+
sorter = getComparisonSorter(obj.comparison, modifier);
|
|
133
|
+
} else if (typeof obj.key === 'string') {
|
|
134
|
+
sorter = getValueSorter(obj.key, modifier);
|
|
81
135
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
136
|
+
if (typeof obj.compare === 'function') {
|
|
137
|
+
sorter.compare = {
|
|
138
|
+
complex: obj.compare,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
} else if (typeof obj.value === 'function') {
|
|
142
|
+
sorter = getValueSorter(obj.value, modifier);
|
|
85
143
|
}
|
|
86
144
|
|
|
87
|
-
if (
|
|
88
|
-
|
|
145
|
+
if (sorter != null && typeof obj.direction === 'string') {
|
|
146
|
+
sorter.modifier = modifiers[obj.direction as SortDirection] ?? modifier;
|
|
89
147
|
}
|
|
90
148
|
|
|
91
|
-
return
|
|
149
|
+
return sorter;
|
|
92
150
|
}
|
|
93
151
|
|
|
94
|
-
function getSorter(value: unknown, modifier: number):
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
identifier: '',
|
|
99
|
-
modifier,
|
|
100
|
-
};
|
|
101
|
-
|
|
102
|
-
sorter.compare =
|
|
103
|
-
forObject && typeof value.compare === 'function' ? (value.compare as never) : undefined;
|
|
152
|
+
function getSorter(value: unknown, modifier: number): InternalSorter | undefined {
|
|
153
|
+
switch (true) {
|
|
154
|
+
case typeof value === 'function':
|
|
155
|
+
return getComparisonSorter(value, modifier);
|
|
104
156
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
sorter.callback = getCallback(value, sorter.key, forObject);
|
|
157
|
+
case typeof value === 'string':
|
|
158
|
+
return getValueSorter(value, modifier);
|
|
108
159
|
|
|
109
|
-
|
|
110
|
-
|
|
160
|
+
case isPlainObject(value):
|
|
161
|
+
return getObjectSorter(value, modifier);
|
|
111
162
|
|
|
112
|
-
|
|
163
|
+
default:
|
|
164
|
+
break;
|
|
113
165
|
}
|
|
114
166
|
}
|
|
115
167
|
|
|
168
|
+
function getValueSorter(value: string | Function, modifier: number): InternalSorter {
|
|
169
|
+
return {
|
|
170
|
+
modifier,
|
|
171
|
+
get: true,
|
|
172
|
+
identifier: String(value),
|
|
173
|
+
value:
|
|
174
|
+
typeof value === 'function'
|
|
175
|
+
? (value as (item: PlainObject) => unknown)
|
|
176
|
+
: item => (item as PlainObject)[value],
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
|
|
116
180
|
/**
|
|
117
181
|
* Sort an array of items, using multiple sorters to sort by specific values
|
|
118
182
|
* @param array Array to sort
|
|
@@ -122,76 +186,18 @@ function getSorter(value: unknown, modifier: number): Sorter | undefined {
|
|
|
122
186
|
*/
|
|
123
187
|
export function sort<Item>(
|
|
124
188
|
array: Item[],
|
|
125
|
-
sorters: Array<
|
|
126
|
-
descending?: boolean,
|
|
127
|
-
): Item[];
|
|
128
|
-
|
|
129
|
-
/**
|
|
130
|
-
* Sort an array of items, using a sorter to sort by a specific value
|
|
131
|
-
* @param array Array to sort
|
|
132
|
-
* @param sorter Sorter to use for sorting
|
|
133
|
-
* @param descending Sort in descending order? _(defaults to `false`; overridden by the sorter)_
|
|
134
|
-
* @returns Sorted array
|
|
135
|
-
*/
|
|
136
|
-
export function sort<Item>(
|
|
137
|
-
array: Item[],
|
|
138
|
-
sorter: ((item: Item) => unknown) | ArrayCallbackSorter<Item>,
|
|
189
|
+
sorters: Array<Sorter<Item>>,
|
|
139
190
|
descending?: boolean,
|
|
140
191
|
): Item[];
|
|
141
192
|
|
|
142
193
|
/**
|
|
143
194
|
* Sort an array of items, using multiple sorters to sort by specific values
|
|
144
195
|
* @param array Array to sort
|
|
145
|
-
* @param sorters Sorters to use for sorting
|
|
146
|
-
* @param descending Sort in descending order? _(defaults to `false`; overridden by individual sorters)_
|
|
147
|
-
* @returns Sorted array
|
|
148
|
-
*/
|
|
149
|
-
export function sort<Item extends PlainObject>(
|
|
150
|
-
array: Item[],
|
|
151
|
-
sorters: Array<
|
|
152
|
-
keyof Item | ((item: Item) => unknown) | ArrayCallbackSorter<Item> | ArrayKeySorter<Item>
|
|
153
|
-
>,
|
|
154
|
-
descending?: boolean,
|
|
155
|
-
): Item[];
|
|
156
|
-
|
|
157
|
-
/**
|
|
158
|
-
* Sort an array of items, using a sorter to sort by a specific value
|
|
159
|
-
* @param array Array to sort
|
|
160
196
|
* @param sorter Sorter to use for sorting
|
|
161
|
-
* @param descending Sort in descending order? _(defaults to `false`; overridden by the sorter)_
|
|
162
|
-
* @returns Sorted array
|
|
163
|
-
*/
|
|
164
|
-
export function sort<Item extends PlainObject>(
|
|
165
|
-
array: Item[],
|
|
166
|
-
sorter: keyof Item | ((item: Item) => unknown) | ArrayCallbackSorter<Item> | ArrayKeySorter<Item>,
|
|
167
|
-
descending?: boolean,
|
|
168
|
-
): Item[];
|
|
169
|
-
|
|
170
|
-
/**
|
|
171
|
-
* Sort an array of items, using multiple sorters to sort by specific values
|
|
172
|
-
* @param array Array to sort
|
|
173
|
-
* @param sorters Sorters to use for sorting
|
|
174
197
|
* @param descending Sort in descending order? _(defaults to `false`; overridden by individual sorters)_
|
|
175
198
|
* @returns Sorted array
|
|
176
199
|
*/
|
|
177
|
-
export function sort<Item
|
|
178
|
-
array: Item[],
|
|
179
|
-
sorters: ((item: Item) => unknown)[],
|
|
180
|
-
descending?: boolean,
|
|
181
|
-
): Item[];
|
|
182
|
-
|
|
183
|
-
/**
|
|
184
|
-
* Sort an array of items, using a sorter to sort by a specific value
|
|
185
|
-
* @param array Array to sort
|
|
186
|
-
* @param sorter Sorter to use for sorting
|
|
187
|
-
* @param descending Sort in descending order? _(defaults to `false`; overridden by the sorter)_
|
|
188
|
-
* @returns Sorted array
|
|
189
|
-
*/
|
|
190
|
-
export function sort<Item extends Primitive>(
|
|
191
|
-
array: Item[],
|
|
192
|
-
sorter: (item: Item) => unknown,
|
|
193
|
-
descending?: boolean,
|
|
194
|
-
): Item[];
|
|
200
|
+
export function sort<Item>(array: Item[], sorter: Sorter<Item>, descending?: boolean): Item[];
|
|
195
201
|
|
|
196
202
|
/**
|
|
197
203
|
* Sort an array of items
|
|
@@ -213,7 +219,7 @@ export function sort(array: unknown[], first?: unknown, second?: unknown): unkno
|
|
|
213
219
|
const direction =
|
|
214
220
|
first === true || second === true ? SORT_DIRECTION_DESCENDING : SORT_DIRECTION_ASCENDING;
|
|
215
221
|
|
|
216
|
-
const modifier = direction
|
|
222
|
+
const modifier = modifiers[direction];
|
|
217
223
|
|
|
218
224
|
const sorters = (Array.isArray(first) ? first : [first])
|
|
219
225
|
.map(item => getSorter(item, modifier))
|
|
@@ -226,21 +232,19 @@ export function sort(array: unknown[], first?: unknown, second?: unknown): unkno
|
|
|
226
232
|
const {length} = sorters;
|
|
227
233
|
|
|
228
234
|
if (length === 0) {
|
|
229
|
-
return array.sort(
|
|
230
|
-
(firstItem, secondItem) => compare(firstItem as never, secondItem as never) * modifier,
|
|
231
|
-
);
|
|
235
|
+
return array.sort((first, second) => compare(first, second) * modifier);
|
|
232
236
|
}
|
|
233
237
|
|
|
234
238
|
if (length === 1) {
|
|
235
239
|
const sorter = sorters[0];
|
|
236
|
-
const {callback, key} = sorter;
|
|
237
240
|
|
|
238
241
|
return array.sort((firstItem, secondItem) => {
|
|
239
|
-
const firstValue =
|
|
240
|
-
const secondValue =
|
|
242
|
+
const firstValue = sorter.get ? sorter.value!(firstItem as PlainObject) : firstItem;
|
|
243
|
+
const secondValue = sorter.get ? sorter.value!(secondItem as PlainObject) : secondItem;
|
|
241
244
|
|
|
242
245
|
return (
|
|
243
|
-
(sorter.compare?.(firstItem, firstValue, secondItem, secondValue) ??
|
|
246
|
+
(sorter.compare?.complex?.(firstItem, firstValue, secondItem, secondValue) ??
|
|
247
|
+
sorter.compare?.simple?.(firstItem, secondItem) ??
|
|
244
248
|
compare(firstValue, secondValue)) * sorter.modifier
|
|
245
249
|
);
|
|
246
250
|
});
|
|
@@ -249,17 +253,17 @@ export function sort(array: unknown[], first?: unknown, second?: unknown): unkno
|
|
|
249
253
|
return array.sort((firstItem, secondItem) => {
|
|
250
254
|
for (let index = 0; index < length; index += 1) {
|
|
251
255
|
const sorter = sorters[index];
|
|
252
|
-
const {callback, key} = sorter;
|
|
253
256
|
|
|
254
|
-
const firstValue =
|
|
255
|
-
const secondValue =
|
|
257
|
+
const firstValue = sorter.value?.(firstItem as PlainObject) ?? firstItem;
|
|
258
|
+
const secondValue = sorter.value?.(secondItem as PlainObject) ?? secondItem;
|
|
256
259
|
|
|
257
|
-
const
|
|
258
|
-
(sorter.compare?.(firstItem, firstValue, secondItem, secondValue) ??
|
|
260
|
+
const comparison =
|
|
261
|
+
(sorter.compare?.complex?.(firstItem, firstValue, secondItem, secondValue) ??
|
|
262
|
+
sorter.compare?.simple?.(firstItem, secondItem) ??
|
|
259
263
|
compare(firstValue, secondValue)) * sorter.modifier;
|
|
260
264
|
|
|
261
|
-
if (
|
|
262
|
-
return
|
|
265
|
+
if (comparison !== 0) {
|
|
266
|
+
return comparison;
|
|
263
267
|
}
|
|
264
268
|
}
|
|
265
269
|
|
|
@@ -275,4 +279,9 @@ export const SORT_DIRECTION_ASCENDING: SortDirection = 'ascending';
|
|
|
275
279
|
|
|
276
280
|
export const SORT_DIRECTION_DESCENDING: SortDirection = 'descending';
|
|
277
281
|
|
|
282
|
+
const modifiers: Record<SortDirection, number> = {
|
|
283
|
+
[SORT_DIRECTION_ASCENDING]: 1,
|
|
284
|
+
[SORT_DIRECTION_DESCENDING]: -1,
|
|
285
|
+
};
|
|
286
|
+
|
|
278
287
|
// #endregion
|
package/src/promise/helpers.ts
CHANGED