@oscarpalmer/atoms 0.184.1 → 0.185.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/{position.d.mts → match.d.mts} +9 -6
- package/dist/array/{position.mjs → match.mjs} +16 -16
- package/dist/array/move.mjs +1 -1
- package/dist/array/single.mjs +2 -2
- package/dist/array/sort.d.mts +9 -4
- package/dist/array/sort.mjs +6 -6
- package/dist/array/swap.mjs +1 -1
- package/dist/beacon.d.mts +12 -0
- package/dist/beacon.mjs +9 -0
- package/dist/color/instance.d.mts +8 -0
- package/dist/color/instance.mjs +5 -2
- package/dist/color/misc/get.mjs +8 -8
- package/dist/color/misc/state.d.mts +2 -2
- package/dist/color/misc/state.mjs +2 -2
- package/dist/color/models.d.mts +30 -0
- package/dist/function/assert.d.mts +29 -8
- package/dist/function/assert.mjs +29 -8
- package/dist/function/memoize.d.mts +3 -0
- package/dist/function/memoize.mjs +3 -0
- package/dist/function/once.mjs +9 -9
- package/dist/function/retry.d.mts +3 -0
- package/dist/function/retry.mjs +11 -8
- package/dist/function/work.mjs +1 -1
- package/dist/index.d.mts +272 -160
- package/dist/index.mjs +279 -216
- package/dist/internal/number.d.mts +2 -1
- package/dist/internal/number.mjs +4 -1
- package/dist/internal/value/compare.d.mts +2 -1
- package/dist/internal/value/equal.d.mts +5 -0
- package/dist/internal/value/equal.mjs +5 -5
- package/dist/internal/value/get.d.mts +2 -2
- package/dist/internal/value/has.d.mts +3 -3
- package/dist/internal/value/has.mjs +1 -1
- package/dist/internal/value/misc.d.mts +2 -2
- package/dist/internal/value/misc.mjs +10 -4
- package/dist/logger.d.mts +11 -0
- package/dist/logger.mjs +11 -0
- package/dist/models.d.mts +1 -1
- package/dist/promise/helpers.mjs +3 -5
- package/dist/promise/index.d.mts +0 -6
- package/dist/promise/models.d.mts +36 -0
- package/dist/promise/models.mjs +6 -0
- package/dist/queue.d.mts +13 -1
- package/dist/queue.mjs +14 -7
- package/dist/result/index.d.mts +0 -8
- package/dist/result/index.mjs +0 -8
- package/dist/result/match.d.mts +4 -4
- package/dist/result/work/flow.d.mts +12 -36
- package/dist/result/work/pipe.d.mts +11 -33
- package/dist/sized/set.d.mts +3 -2
- package/dist/sized/set.mjs +3 -2
- package/dist/string/fuzzy.mjs +2 -2
- package/dist/value/handle.mjs +1 -1
- package/dist/value/merge.d.mts +0 -1
- package/dist/value/merge.mjs +0 -1
- package/dist/value/shake.d.mts +3 -0
- package/dist/value/smush.d.mts +3 -0
- package/dist/value/transform.d.mts +9 -0
- package/dist/value/unsmush.d.mts +3 -0
- package/package.json +3 -3
- package/src/array/difference.ts +4 -0
- package/src/array/from.ts +4 -0
- package/src/array/index.ts +1 -1
- package/src/array/intersection.ts +4 -0
- package/src/array/{position.ts → match.ts} +28 -25
- package/src/array/move.ts +5 -1
- package/src/array/reverse.ts +4 -0
- package/src/array/select.ts +2 -0
- package/src/array/single.ts +2 -2
- package/src/array/sort.ts +14 -9
- package/src/array/swap.ts +5 -1
- package/src/array/toggle.ts +4 -0
- package/src/array/union.ts +4 -0
- package/src/beacon.ts +12 -0
- package/src/color/index.ts +0 -3
- package/src/color/instance.ts +11 -3
- package/src/color/misc/get.ts +8 -8
- package/src/color/misc/state.ts +1 -1
- package/src/color/models.ts +30 -0
- package/src/function/assert.ts +66 -7
- package/src/function/memoize.ts +3 -0
- package/src/function/once.ts +13 -9
- package/src/function/retry.ts +11 -8
- package/src/internal/number.ts +6 -0
- package/src/internal/value/compare.ts +2 -1
- package/src/internal/value/equal.ts +10 -5
- package/src/internal/value/get.ts +2 -2
- package/src/internal/value/has.ts +6 -6
- package/src/internal/value/misc.ts +24 -13
- package/src/logger.ts +11 -0
- package/src/models.ts +1 -1
- package/src/promise/helpers.ts +3 -6
- package/src/promise/index.ts +0 -6
- package/src/promise/models.ts +36 -0
- package/src/queue.ts +23 -11
- package/src/result/index.ts +0 -8
- package/src/result/match.ts +4 -4
- package/src/result/work/flow.ts +12 -36
- package/src/result/work/pipe.ts +11 -33
- package/src/sized/set.ts +4 -3
- package/src/string/fuzzy.ts +2 -2
- package/src/value/merge.ts +0 -1
- package/src/value/shake.ts +3 -0
- package/src/value/smush.ts +3 -0
- package/src/value/transform.ts +9 -0
- package/src/value/unsmush.ts +3 -0
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
// #region Types
|
|
2
|
-
|
|
3
1
|
import {getArrayCallback} from '../internal/array/callbacks';
|
|
4
2
|
import type {PlainObject} from '../models';
|
|
5
3
|
|
|
6
|
-
|
|
4
|
+
// #region Types
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Comparison of an array within another array
|
|
8
|
+
*/
|
|
9
|
+
export type ArrayComparison = 'end' | 'inside' | 'invalid' | 'outside' | 'same' | 'start';
|
|
7
10
|
|
|
8
11
|
// #endregion
|
|
9
12
|
|
|
@@ -54,11 +57,11 @@ export function endsWithArray(haystack: unknown[], needle: unknown[], key?: unkn
|
|
|
54
57
|
* @param key Key to get an item's value for matching
|
|
55
58
|
* @returns Position of the needle within the haystack
|
|
56
59
|
*/
|
|
57
|
-
export function
|
|
60
|
+
export function getArrayComparison<Item extends PlainObject>(
|
|
58
61
|
haystack: Item[],
|
|
59
62
|
needle: Item[],
|
|
60
63
|
key: keyof Item,
|
|
61
|
-
):
|
|
64
|
+
): ArrayComparison;
|
|
62
65
|
|
|
63
66
|
/**
|
|
64
67
|
* Get the position of an array within another array
|
|
@@ -67,11 +70,11 @@ export function getArrayPosition<Item extends PlainObject>(
|
|
|
67
70
|
* @param callback Callback to get an item's value for matching
|
|
68
71
|
* @returns Position of the needle within the haystack
|
|
69
72
|
*/
|
|
70
|
-
export function
|
|
73
|
+
export function getArrayComparison<Item>(
|
|
71
74
|
haystack: Item[],
|
|
72
75
|
needle: Item[],
|
|
73
76
|
callback: (item: Item, index: number, array: Item[]) => unknown,
|
|
74
|
-
):
|
|
77
|
+
): ArrayComparison;
|
|
75
78
|
|
|
76
79
|
/**
|
|
77
80
|
* Get the position of an array within another array
|
|
@@ -79,29 +82,29 @@ export function getArrayPosition<Item>(
|
|
|
79
82
|
* @param needle Needle array
|
|
80
83
|
* @returns Position of the needle within the haystack
|
|
81
84
|
*/
|
|
82
|
-
export function
|
|
85
|
+
export function getArrayComparison<Item>(haystack: Item[], needle: Item[]): ArrayComparison;
|
|
83
86
|
|
|
84
|
-
export function
|
|
87
|
+
export function getArrayComparison(
|
|
85
88
|
haystack: unknown[],
|
|
86
89
|
needle: unknown[],
|
|
87
90
|
key?: unknown,
|
|
88
|
-
):
|
|
91
|
+
): ArrayComparison {
|
|
89
92
|
return getPosition(haystack, needle, key)[1];
|
|
90
93
|
}
|
|
91
94
|
|
|
92
|
-
function getName(start: number, haystack: number, needle: number):
|
|
95
|
+
function getName(start: number, haystack: number, needle: number): ArrayComparison {
|
|
93
96
|
if (start === 0) {
|
|
94
|
-
return haystack === needle ?
|
|
97
|
+
return haystack === needle ? COMPARISON_SAME : COMPARISON_START;
|
|
95
98
|
}
|
|
96
99
|
|
|
97
|
-
return start + needle === haystack ?
|
|
100
|
+
return start + needle === haystack ? COMPARISON_END : COMPARISON_INSIDE;
|
|
98
101
|
}
|
|
99
102
|
|
|
100
103
|
function getPosition(
|
|
101
104
|
haystack: unknown[],
|
|
102
105
|
needle: unknown[],
|
|
103
106
|
key?: unknown,
|
|
104
|
-
): readonly [number,
|
|
107
|
+
): readonly [number, ArrayComparison] {
|
|
105
108
|
if (!Array.isArray(haystack) || !Array.isArray(needle)) {
|
|
106
109
|
return invalid;
|
|
107
110
|
}
|
|
@@ -278,26 +281,26 @@ export function startsWithArray(haystack: unknown[], needle: unknown[], key?: un
|
|
|
278
281
|
|
|
279
282
|
// #region Variables
|
|
280
283
|
|
|
281
|
-
const
|
|
284
|
+
const COMPARISON_END: ArrayComparison = 'end';
|
|
282
285
|
|
|
283
|
-
const
|
|
286
|
+
const COMPARISON_INSIDE: ArrayComparison = 'inside';
|
|
284
287
|
|
|
285
|
-
const
|
|
288
|
+
const COMPARISON_INVALID: ArrayComparison = 'invalid';
|
|
286
289
|
|
|
287
|
-
const
|
|
290
|
+
const COMPARISON_OUTSIDE: ArrayComparison = 'outside';
|
|
288
291
|
|
|
289
|
-
const
|
|
292
|
+
const COMPARISON_SAME: ArrayComparison = 'same';
|
|
290
293
|
|
|
291
|
-
const
|
|
294
|
+
const COMPARISON_START: ArrayComparison = 'start';
|
|
292
295
|
|
|
293
|
-
const endings = new Set<
|
|
296
|
+
const endings = new Set<ArrayComparison>([COMPARISON_END, COMPARISON_SAME]);
|
|
294
297
|
|
|
295
|
-
const invalid = [-1,
|
|
298
|
+
const invalid = [-1, COMPARISON_INVALID] as const;
|
|
296
299
|
|
|
297
|
-
const outside = [-1,
|
|
300
|
+
const outside = [-1, COMPARISON_OUTSIDE] as const;
|
|
298
301
|
|
|
299
|
-
const outsides = new Set<
|
|
302
|
+
const outsides = new Set<ArrayComparison>([COMPARISON_INVALID, COMPARISON_OUTSIDE]);
|
|
300
303
|
|
|
301
|
-
const starts = new Set<
|
|
304
|
+
const starts = new Set<ArrayComparison>([COMPARISON_START, COMPARISON_SAME]);
|
|
302
305
|
|
|
303
306
|
// #endregion
|
package/src/array/move.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import {arraysOverlap} from '../internal/array/overlap';
|
|
2
2
|
import type {PlainObject} from '../models';
|
|
3
|
-
import {indexOfArray} from './
|
|
3
|
+
import {indexOfArray} from './match';
|
|
4
|
+
|
|
5
|
+
// #region Functions
|
|
4
6
|
|
|
5
7
|
/**
|
|
6
8
|
* Move an item _(or array of items)_ to the position of another item _(or array of items)_ within an array
|
|
@@ -239,3 +241,5 @@ export function moveToIndex(
|
|
|
239
241
|
|
|
240
242
|
return array;
|
|
241
243
|
}
|
|
244
|
+
|
|
245
|
+
// #endregion
|
package/src/array/reverse.ts
CHANGED
package/src/array/select.ts
CHANGED
package/src/array/single.ts
CHANGED
|
@@ -49,7 +49,7 @@ export function single(array: unknown[], ...parameters: unknown[]): unknown {
|
|
|
49
49
|
const {matched} = findValues(FIND_VALUES_ALL, array, parameters);
|
|
50
50
|
|
|
51
51
|
if (matched.length > 1) {
|
|
52
|
-
throw new Error(
|
|
52
|
+
throw new Error(SINGLE_MESSAGE);
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
return matched[0];
|
|
@@ -59,6 +59,6 @@ export function single(array: unknown[], ...parameters: unknown[]): unknown {
|
|
|
59
59
|
|
|
60
60
|
// #region Variables
|
|
61
61
|
|
|
62
|
-
const
|
|
62
|
+
const SINGLE_MESSAGE = 'Multiple items were found';
|
|
63
63
|
|
|
64
64
|
// #endregion
|
package/src/array/sort.ts
CHANGED
|
@@ -104,6 +104,11 @@ type InternalSorterCompare = {
|
|
|
104
104
|
*/
|
|
105
105
|
export type SortDirection = 'ascending' | 'descending';
|
|
106
106
|
|
|
107
|
+
/**
|
|
108
|
+
* Sorter for an array with predefined sorters
|
|
109
|
+
*
|
|
110
|
+
* Can be used to sort an array, get the predicted index for an item, and check if an array is sorted
|
|
111
|
+
*/
|
|
107
112
|
export type Sorter<Item> = {
|
|
108
113
|
/**
|
|
109
114
|
* Sort an array of items
|
|
@@ -245,7 +250,7 @@ function getObjectSorter(obj: PlainObject, modifier: number): InternalSorter | u
|
|
|
245
250
|
*
|
|
246
251
|
* _(If the array is not sorted, it will be treated as sorted, and the result may be inaccurate)_
|
|
247
252
|
*
|
|
248
|
-
* Available as `getSortedIndex` and `sort.
|
|
253
|
+
* Available as `getSortedIndex` and `sort.getIndex`
|
|
249
254
|
* @param array Array to get the index from
|
|
250
255
|
* @param item Item to get the index for
|
|
251
256
|
* @param sorters Sorters to use to determine sorting
|
|
@@ -264,7 +269,7 @@ export function getSortedIndex<Item>(
|
|
|
264
269
|
*
|
|
265
270
|
* _(If the array is not sorted, it will be treated as sorted, and the result may be inaccurate)_
|
|
266
271
|
*
|
|
267
|
-
* Available as `getSortedIndex` and `sort.
|
|
272
|
+
* Available as `getSortedIndex` and `sort.getIndex`
|
|
268
273
|
* @param array Array to get the index from
|
|
269
274
|
* @param item Item to get the index for
|
|
270
275
|
* @param sorter Sorter to use to determine sorting
|
|
@@ -283,7 +288,7 @@ export function getSortedIndex<Item>(
|
|
|
283
288
|
*
|
|
284
289
|
* _(If the array is not sorted, it will be treated as sorted, and the result may be inaccurate)_
|
|
285
290
|
*
|
|
286
|
-
* Available as `getSortedIndex` and `sort.
|
|
291
|
+
* Available as `getSortedIndex` and `sort.getIndex`
|
|
287
292
|
* @param array Array to get the index from
|
|
288
293
|
* @param item Item to get the index for
|
|
289
294
|
* @param descending Sorted in descending order? _(defaults to `false`)_
|
|
@@ -458,9 +463,9 @@ function isSortedArray(array: unknown[], sorters: InternalSorter[]): boolean {
|
|
|
458
463
|
|
|
459
464
|
let offset = 0;
|
|
460
465
|
|
|
461
|
-
if (length >=
|
|
462
|
-
offset = Math.round(length /
|
|
463
|
-
offset = offset >
|
|
466
|
+
if (length >= SORT_THRESHOLD) {
|
|
467
|
+
offset = Math.round(length / SORT_PEEK_PERCENTAGE);
|
|
468
|
+
offset = offset > SORT_THRESHOLD ? SORT_THRESHOLD : offset;
|
|
464
469
|
|
|
465
470
|
for (let index = 0; index < offset; index += 1) {
|
|
466
471
|
const [firstItem, firstOffset] = [array[index], array[index + 1]];
|
|
@@ -552,7 +557,7 @@ function sortArray(array: unknown[], sorters: InternalSorter[]): unknown[] {
|
|
|
552
557
|
: array;
|
|
553
558
|
}
|
|
554
559
|
|
|
555
|
-
sort.
|
|
560
|
+
sort.getIndex = getSortedIndex;
|
|
556
561
|
sort.initialize = initializeSorter;
|
|
557
562
|
sort.is = isSorted;
|
|
558
563
|
|
|
@@ -560,9 +565,9 @@ sort.is = isSorted;
|
|
|
560
565
|
|
|
561
566
|
// #region Variables
|
|
562
567
|
|
|
563
|
-
const
|
|
568
|
+
const SORT_PEEK_PERCENTAGE = 10;
|
|
564
569
|
|
|
565
|
-
const
|
|
570
|
+
const SORT_THRESHOLD = 100;
|
|
566
571
|
|
|
567
572
|
export const SORT_DIRECTION_ASCENDING: SortDirection = 'ascending';
|
|
568
573
|
|
package/src/array/swap.ts
CHANGED
|
@@ -2,7 +2,9 @@ import {getArrayCallback} from '../internal/array/callbacks';
|
|
|
2
2
|
import {indexOf} from '../internal/array/index-of';
|
|
3
3
|
import {arraysOverlap} from '../internal/array/overlap';
|
|
4
4
|
import type {PlainObject} from '../models';
|
|
5
|
-
import {indexOfArray} from './
|
|
5
|
+
import {indexOfArray} from './match';
|
|
6
|
+
|
|
7
|
+
// #region Functions
|
|
6
8
|
|
|
7
9
|
/**
|
|
8
10
|
* Swap two smaller arrays within a larger array
|
|
@@ -211,3 +213,5 @@ function swapValues(array: unknown[], from: unknown, to: unknown, key?: unknown)
|
|
|
211
213
|
|
|
212
214
|
return swapIndices(array, first, second);
|
|
213
215
|
}
|
|
216
|
+
|
|
217
|
+
// #endregion
|
package/src/array/toggle.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import {updateInArray} from '../internal/array/update';
|
|
2
2
|
import type {PlainObject} from '../models';
|
|
3
3
|
|
|
4
|
+
// #region Functions
|
|
5
|
+
|
|
4
6
|
/**
|
|
5
7
|
* Toggle an item in an array: if the item exists, it will be removed; if it doesn't, it will be added
|
|
6
8
|
* @param destination Array to toggle within
|
|
@@ -38,3 +40,5 @@ export function toggle<Item>(destination: Item[], toggled: Item[]): Item[];
|
|
|
38
40
|
export function toggle(array: unknown[], values: unknown[], key?: unknown): unknown[] {
|
|
39
41
|
return updateInArray(array, values, key, false);
|
|
40
42
|
}
|
|
43
|
+
|
|
44
|
+
// #endregion
|
package/src/array/union.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import {COMPARE_SETS_UNION, compareSets} from '../internal/array/sets';
|
|
2
2
|
|
|
3
|
+
// #region Functions
|
|
4
|
+
|
|
3
5
|
/**
|
|
4
6
|
* Get the combined, unique values from two arrays
|
|
5
7
|
* @param first First array
|
|
@@ -37,3 +39,5 @@ export function union<First, Second>(first: First[], second: Second[]): (First |
|
|
|
37
39
|
export function union(first: unknown[], second: unknown[], key?: unknown): unknown[] {
|
|
38
40
|
return compareSets(COMPARE_SETS_UNION, first, second, key);
|
|
39
41
|
}
|
|
42
|
+
|
|
43
|
+
// #endregion
|
package/src/beacon.ts
CHANGED
|
@@ -4,6 +4,9 @@ import type {PlainObject} from './models';
|
|
|
4
4
|
|
|
5
5
|
// #region Types
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* A beacon is a lighthouse, holding an observable value that can be subscribed to and emitted from
|
|
9
|
+
*/
|
|
7
10
|
class Beacon<Value> {
|
|
8
11
|
readonly #options: Options;
|
|
9
12
|
readonly #state: BeaconState<Value>;
|
|
@@ -122,6 +125,9 @@ type BeaconState<Value> = {
|
|
|
122
125
|
value: Value;
|
|
123
126
|
};
|
|
124
127
|
|
|
128
|
+
/**
|
|
129
|
+
* An observable holds a value and allows observers to subscribe to changes in that value
|
|
130
|
+
*/
|
|
125
131
|
class Observable<Value> {
|
|
126
132
|
readonly #state: ObservableState<Value>;
|
|
127
133
|
|
|
@@ -186,6 +192,9 @@ type ObservableState<Value> = {
|
|
|
186
192
|
observers: Map<Subscription<Value>, Observer<Value>>;
|
|
187
193
|
};
|
|
188
194
|
|
|
195
|
+
/**
|
|
196
|
+
* An observer receives notifications from an observable
|
|
197
|
+
*/
|
|
189
198
|
type Observer<Value> = {
|
|
190
199
|
/**
|
|
191
200
|
* Callback for when the observable is completed
|
|
@@ -203,6 +212,9 @@ type Observer<Value> = {
|
|
|
203
212
|
|
|
204
213
|
type Options = Required<BeaconOptions<unknown>>;
|
|
205
214
|
|
|
215
|
+
/**
|
|
216
|
+
* A subscription represents an active subscription to an observable, holding its state and allowing it to be destroyed or unsubscribed from
|
|
217
|
+
*/
|
|
206
218
|
class Subscription<Value> {
|
|
207
219
|
readonly #state: SubscriptionState<Value>;
|
|
208
220
|
|
package/src/color/index.ts
CHANGED
|
@@ -39,11 +39,8 @@ export {
|
|
|
39
39
|
} from './misc/is';
|
|
40
40
|
|
|
41
41
|
export {getNormalizedHex, hexToHsl, hexToHsla, hexToRgb, hexToRgba} from './space/hex';
|
|
42
|
-
|
|
43
42
|
export {hslToHex, hslToRgb, hslToRgba} from './space/hsl';
|
|
44
|
-
|
|
45
43
|
export {rgbToHex, rgbToHsl, rgbToHsla} from './space/rgb';
|
|
46
|
-
|
|
47
44
|
export type {Color, HSLAColor, HSLColor, RGBAColor, RGBColor};
|
|
48
45
|
|
|
49
46
|
// #endregion
|
package/src/color/instance.ts
CHANGED
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
import {SPACE_HSL, SPACE_RGB} from './constants';
|
|
2
2
|
import {formatColor} from './misc';
|
|
3
3
|
import {getAlpha} from './misc/alpha';
|
|
4
|
-
import {
|
|
4
|
+
import {getColorState, setHexColor, setHSLColor, setRGBColor} from './misc/state';
|
|
5
5
|
import type {ColorState, HSLAColor, HSLColor, RGBAColor, RGBColor} from './models';
|
|
6
6
|
|
|
7
|
-
// #region
|
|
7
|
+
// #region Types
|
|
8
8
|
|
|
9
|
+
/**
|
|
10
|
+
* A color that is represented in multiple color formats
|
|
11
|
+
*/
|
|
9
12
|
export class Color {
|
|
13
|
+
/**
|
|
14
|
+
* A property to identify this as a Color instance, used for type checking
|
|
15
|
+
*
|
|
16
|
+
* @internal
|
|
17
|
+
*/
|
|
10
18
|
declare private readonly $color: boolean;
|
|
11
19
|
|
|
12
20
|
readonly #state: ColorState;
|
|
@@ -118,7 +126,7 @@ export class Color {
|
|
|
118
126
|
}
|
|
119
127
|
|
|
120
128
|
constructor(value: unknown) {
|
|
121
|
-
this.#state =
|
|
129
|
+
this.#state = getColorState(value);
|
|
122
130
|
|
|
123
131
|
Object.defineProperty(this, '$color', {
|
|
124
132
|
value: true,
|
package/src/color/misc/get.ts
CHANGED
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
} from '../constants';
|
|
18
18
|
import {Color} from '../instance';
|
|
19
19
|
import type {HSLAColor, HSLColor, RGBAColor, RGBColor} from '../models';
|
|
20
|
-
import {
|
|
20
|
+
import {getColorState} from './state';
|
|
21
21
|
|
|
22
22
|
// #region Functions
|
|
23
23
|
|
|
@@ -31,7 +31,7 @@ function getClampedValue(value: unknown, minimum: number, maximum: number): numb
|
|
|
31
31
|
* @returns Foreground color
|
|
32
32
|
*/
|
|
33
33
|
export function getForegroundColor(value: unknown): Color {
|
|
34
|
-
const state =
|
|
34
|
+
const state = getColorState(value);
|
|
35
35
|
const {blue, green, red} = state.rgb;
|
|
36
36
|
|
|
37
37
|
const values = [blue / MAX_HEX, green / MAX_HEX, red / MAX_HEX];
|
|
@@ -63,7 +63,7 @@ export function getForegroundColor(value: unknown): Color {
|
|
|
63
63
|
* @returns Hex color
|
|
64
64
|
*/
|
|
65
65
|
export function getHexaColor(value: unknown): string {
|
|
66
|
-
const {alpha, hex} =
|
|
66
|
+
const {alpha, hex} = getColorState(value);
|
|
67
67
|
|
|
68
68
|
return `${hex}${alpha.hex}`;
|
|
69
69
|
}
|
|
@@ -74,7 +74,7 @@ export function getHexaColor(value: unknown): string {
|
|
|
74
74
|
* @returns Hex color
|
|
75
75
|
*/
|
|
76
76
|
export function getHexColor(value: unknown): string {
|
|
77
|
-
return
|
|
77
|
+
return getColorState(value).hex;
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
export function getHexValue(value: unknown): number {
|
|
@@ -91,7 +91,7 @@ export function getDegrees(value: unknown): number {
|
|
|
91
91
|
* @returns HSLA color
|
|
92
92
|
*/
|
|
93
93
|
export function getHslaColor(value: unknown): HSLAColor {
|
|
94
|
-
const {alpha, hsl} =
|
|
94
|
+
const {alpha, hsl} = getColorState(value);
|
|
95
95
|
|
|
96
96
|
return {
|
|
97
97
|
...hsl,
|
|
@@ -105,7 +105,7 @@ export function getHslaColor(value: unknown): HSLAColor {
|
|
|
105
105
|
* @returns HSL color
|
|
106
106
|
*/
|
|
107
107
|
export function getHslColor(value: unknown): HSLColor {
|
|
108
|
-
return
|
|
108
|
+
return getColorState(value).hsl;
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
export function getPercentage(value: unknown): number {
|
|
@@ -118,7 +118,7 @@ export function getPercentage(value: unknown): number {
|
|
|
118
118
|
* @returns RGBA color
|
|
119
119
|
*/
|
|
120
120
|
export function getRgbaColor(value: unknown): RGBAColor {
|
|
121
|
-
const {alpha, rgb} =
|
|
121
|
+
const {alpha, rgb} = getColorState(value);
|
|
122
122
|
|
|
123
123
|
return {
|
|
124
124
|
...rgb,
|
|
@@ -132,7 +132,7 @@ export function getRgbaColor(value: unknown): RGBAColor {
|
|
|
132
132
|
* @returns RGB color
|
|
133
133
|
*/
|
|
134
134
|
export function getRgbColor(value: unknown): RGBColor {
|
|
135
|
-
return
|
|
135
|
+
return getColorState(value).rgb;
|
|
136
136
|
}
|
|
137
137
|
|
|
138
138
|
// #endregion
|
package/src/color/misc/state.ts
CHANGED
|
@@ -17,7 +17,7 @@ import {isColor, isHexColor, isHslLike, isRgbLike} from './is';
|
|
|
17
17
|
|
|
18
18
|
// #region Functions
|
|
19
19
|
|
|
20
|
-
export function
|
|
20
|
+
export function getColorState(value: unknown): ColorState {
|
|
21
21
|
if (typeof value === 'string') {
|
|
22
22
|
const normalized = getNormalizedHex(value, true);
|
|
23
23
|
const hex = normalized.slice(0, LENGTH_LONG);
|
package/src/color/models.ts
CHANGED
|
@@ -9,19 +9,49 @@ type ColorWithAlpha = {
|
|
|
9
9
|
alpha: number;
|
|
10
10
|
};
|
|
11
11
|
|
|
12
|
+
/**
|
|
13
|
+
* An _HSL_-color with an alpha channel
|
|
14
|
+
*/
|
|
12
15
|
export type HSLAColor = HSLColor & ColorWithAlpha;
|
|
13
16
|
|
|
17
|
+
/**
|
|
18
|
+
* An _HSL_-color
|
|
19
|
+
*/
|
|
14
20
|
export type HSLColor = {
|
|
21
|
+
/**
|
|
22
|
+
* Hue of the color _(in degrees; 0-360)_
|
|
23
|
+
*/
|
|
15
24
|
hue: number;
|
|
25
|
+
/**
|
|
26
|
+
* Lightness of the color _(in percentage; 0-100)_
|
|
27
|
+
*/
|
|
16
28
|
lightness: number;
|
|
29
|
+
/**
|
|
30
|
+
* Saturation of the color _(in percentage; 0-100)_
|
|
31
|
+
*/
|
|
17
32
|
saturation: number;
|
|
18
33
|
};
|
|
19
34
|
|
|
35
|
+
/**
|
|
36
|
+
* An _RGB_-color with an alpha channel
|
|
37
|
+
*/
|
|
20
38
|
export type RGBAColor = RGBColor & ColorWithAlpha;
|
|
21
39
|
|
|
40
|
+
/**
|
|
41
|
+
* An _RGB_-color
|
|
42
|
+
*/
|
|
22
43
|
export type RGBColor = {
|
|
44
|
+
/**
|
|
45
|
+
* Blue channel of the color _(in hexadecimal; 0-255)_
|
|
46
|
+
*/
|
|
23
47
|
blue: number;
|
|
48
|
+
/**
|
|
49
|
+
* Green channel of the color _(in hexadecimal; 0-255)_
|
|
50
|
+
*/
|
|
24
51
|
green: number;
|
|
52
|
+
/**
|
|
53
|
+
* Red channel of the color _(in hexadecimal; 0-255)_
|
|
54
|
+
*/
|
|
25
55
|
red: number;
|
|
26
56
|
};
|
|
27
57
|
|
package/src/function/assert.ts
CHANGED
|
@@ -1,9 +1,32 @@
|
|
|
1
|
-
import
|
|
1
|
+
import {hasValueResult} from '../internal/value/has';
|
|
2
|
+
import type {Constructor, NestedKeys, NestedValue, PlainObject} from '../models';
|
|
2
3
|
|
|
3
4
|
// #region Types
|
|
4
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Asserter for a nested property of a value
|
|
8
|
+
*/
|
|
9
|
+
export type AssertProperty<
|
|
10
|
+
Value extends PlainObject,
|
|
11
|
+
Path extends NestedKeys<Value>,
|
|
12
|
+
Asserted extends NestedPick<Value, Path> = NestedPick<Value, Path>,
|
|
13
|
+
> = Asserter<Asserted>;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* A function that asserts a value is of a specific type, throwing an error if it is not
|
|
17
|
+
*/
|
|
5
18
|
export type Asserter<Value> = (value: unknown) => asserts value is Value;
|
|
6
19
|
|
|
20
|
+
type NestedPick<Value, Path extends string> = Value extends PlainObject
|
|
21
|
+
? Path extends `${infer Head}.${infer Rest}`
|
|
22
|
+
? Head extends keyof Value
|
|
23
|
+
? {[Key in Head]: NestedPick<Value[Key], Rest>}
|
|
24
|
+
: never
|
|
25
|
+
: Path extends keyof Value
|
|
26
|
+
? {[Key in Path]: Value[Key]}
|
|
27
|
+
: never
|
|
28
|
+
: never;
|
|
29
|
+
|
|
7
30
|
// #endregion
|
|
8
31
|
|
|
9
32
|
// #region Functions
|
|
@@ -12,7 +35,7 @@ export type Asserter<Value> = (value: unknown) => asserts value is Value;
|
|
|
12
35
|
* Asserts that a condition is true, throwing an error if it is not
|
|
13
36
|
* @param condition Condition to assert
|
|
14
37
|
* @param message Error message
|
|
15
|
-
* @param error Error constructor
|
|
38
|
+
* @param error Error constructor _(defaults to `Error`)_
|
|
16
39
|
*/
|
|
17
40
|
export function assert<Condition extends () => boolean>(
|
|
18
41
|
condition: Condition,
|
|
@@ -28,6 +51,7 @@ assert.condition = assertCondition;
|
|
|
28
51
|
assert.defined = assertDefined;
|
|
29
52
|
assert.instanceOf = assertInstanceOf;
|
|
30
53
|
assert.is = assertIs;
|
|
54
|
+
assert.property = assertProperty;
|
|
31
55
|
|
|
32
56
|
/**
|
|
33
57
|
* Creates an asserter that asserts a condition is true, throwing an error if it is not
|
|
@@ -35,7 +59,7 @@ assert.is = assertIs;
|
|
|
35
59
|
* Available as `assertCondition` and `assert.condition`
|
|
36
60
|
* @param condition Condition to assert
|
|
37
61
|
* @param message Error message
|
|
38
|
-
* @param error Error constructor
|
|
62
|
+
* @param error Error constructor _(defaults to `Error`)_
|
|
39
63
|
* @returns Asserter
|
|
40
64
|
*/
|
|
41
65
|
export function assertCondition<Value>(
|
|
@@ -49,17 +73,19 @@ export function assertCondition<Value>(
|
|
|
49
73
|
}
|
|
50
74
|
|
|
51
75
|
/**
|
|
52
|
-
* Asserts that a value is defined throwing an error if it is not
|
|
76
|
+
* Asserts that a value is defined, throwing an error if it is not
|
|
53
77
|
*
|
|
54
78
|
* Available as `assertDefined` and `assert.defined`
|
|
55
79
|
* @param value Value to assert
|
|
56
80
|
* @param message Error message
|
|
81
|
+
* @param error Error constructor _(defaults to `Error`)_
|
|
57
82
|
*/
|
|
58
83
|
export function assertDefined<Value>(
|
|
59
84
|
value: unknown,
|
|
60
85
|
message?: string,
|
|
86
|
+
error?: ErrorConstructor,
|
|
61
87
|
): asserts value is Exclude<Value, null | undefined> {
|
|
62
|
-
assert(() => value != null, message ?? MESSAGE_VALUE_DEFINED);
|
|
88
|
+
assert(() => value != null, message ?? MESSAGE_VALUE_DEFINED, error);
|
|
63
89
|
}
|
|
64
90
|
|
|
65
91
|
/**
|
|
@@ -68,7 +94,7 @@ export function assertDefined<Value>(
|
|
|
68
94
|
* Available as `assertInstanceOf` and `assert.instanceOf`
|
|
69
95
|
* @param constructor Constructor to check against
|
|
70
96
|
* @param message Error message
|
|
71
|
-
* @param error Error constructor
|
|
97
|
+
* @param error Error constructor _(defaults to `Error`)_
|
|
72
98
|
* @returns Asserter
|
|
73
99
|
*/
|
|
74
100
|
export function assertInstanceOf<Value>(
|
|
@@ -87,7 +113,7 @@ export function assertInstanceOf<Value>(
|
|
|
87
113
|
* Available as `assertIs` and `assert.is`
|
|
88
114
|
* @param condition Type guard function to check the value
|
|
89
115
|
* @param message Error message
|
|
90
|
-
* @param error Error constructor
|
|
116
|
+
* @param error Error constructor _(defaults to `Error`)_
|
|
91
117
|
* @returns Asserter
|
|
92
118
|
*/
|
|
93
119
|
export function assertIs<Value>(
|
|
@@ -100,6 +126,39 @@ export function assertIs<Value>(
|
|
|
100
126
|
};
|
|
101
127
|
}
|
|
102
128
|
|
|
129
|
+
/**
|
|
130
|
+
* Creates an asserter that asserts a property of a value exists and satisfies a condition, throwing an error if it does not
|
|
131
|
+
*
|
|
132
|
+
* Available as `assertProperty` and `assert.property`
|
|
133
|
+
* @param path Path to the property to check, e.g., `foo.bar.baz` for a nested property
|
|
134
|
+
* @param condition Condition to assert for the property
|
|
135
|
+
* @param message Error message
|
|
136
|
+
* @param error Error constructor _(defaults to `Error`)_
|
|
137
|
+
* @returns Asserter
|
|
138
|
+
*/
|
|
139
|
+
export function assertProperty<
|
|
140
|
+
Value extends PlainObject,
|
|
141
|
+
Path extends NestedKeys<Value>,
|
|
142
|
+
Asserted = NestedPick<Value, Path>,
|
|
143
|
+
>(
|
|
144
|
+
path: Path,
|
|
145
|
+
condition: (value: NestedValue<Value, Path>) => boolean,
|
|
146
|
+
message: string,
|
|
147
|
+
error?: ErrorConstructor,
|
|
148
|
+
): Asserter<Asserted> {
|
|
149
|
+
return (value: unknown): asserts value is Asserted => {
|
|
150
|
+
assert(
|
|
151
|
+
() => {
|
|
152
|
+
const result = hasValueResult(value as never, path, false);
|
|
153
|
+
|
|
154
|
+
return result.ok && condition(result.value as never);
|
|
155
|
+
},
|
|
156
|
+
message,
|
|
157
|
+
error,
|
|
158
|
+
);
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
|
|
103
162
|
// #endregion
|
|
104
163
|
|
|
105
164
|
// #region Variables
|
package/src/function/memoize.ts
CHANGED
|
@@ -5,6 +5,9 @@ import {SizedMap} from '../sized/map';
|
|
|
5
5
|
|
|
6
6
|
// #region Types
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* A memoized function, caching and retrieving results based on the its parameters _(or a custom cache key)_
|
|
10
|
+
*/
|
|
8
11
|
class Memoized<Callback extends GenericCallback> {
|
|
9
12
|
readonly #state: MemoizedState<Callback>;
|
|
10
13
|
|