@oscarpalmer/atoms 0.193.0 → 0.194.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/difference.mjs +2 -2
- package/dist/array/intersection.mjs +2 -2
- package/dist/array/match.mjs +13 -13
- package/dist/array/slice.mjs +5 -5
- package/dist/array/sort.d.mts +5 -1
- package/dist/array/sort.mjs +4 -2
- package/dist/array/union.mjs +2 -2
- package/dist/beacon.d.mts +8 -1
- package/dist/beacon.mjs +52 -60
- package/dist/color/constants.d.mts +1 -1
- package/dist/color/constants.mjs +3 -5
- package/dist/color/instance.mjs +34 -41
- package/dist/color/misc/format.d.mts +3 -2
- package/dist/color/misc/format.mjs +4 -1
- package/dist/color/misc/is.d.mts +9 -1
- package/dist/color/misc/is.mjs +11 -1
- package/dist/color/misc/state.d.mts +6 -6
- package/dist/color/misc/state.mjs +11 -14
- package/dist/color/models.d.mts +23 -68
- package/dist/function/assert.mjs +2 -2
- package/dist/function/limit.d.mts +0 -6
- package/dist/function/limit.mjs +2 -2
- package/dist/function/memoize.mjs +19 -32
- package/dist/function/once.d.mts +0 -3
- package/dist/function/once.mjs +16 -13
- package/dist/function/retry.d.mts +1 -24
- package/dist/function/retry.mjs +1 -1
- package/dist/function/work.mjs +13 -11
- package/dist/herald.d.mts +30 -31
- package/dist/herald.mjs +74 -56
- package/dist/index.d.mts +100 -185
- package/dist/index.mjs +680 -702
- package/dist/internal/abort.d.mts +10 -0
- package/dist/internal/abort.mjs +14 -0
- package/dist/internal/array/chunk.mjs +2 -2
- package/dist/internal/array/find.mjs +2 -2
- package/dist/internal/array/sets.d.mts +4 -4
- package/dist/internal/array/sets.mjs +7 -7
- package/dist/internal/function/timer.mjs +19 -15
- package/dist/internal/number.mjs +7 -7
- package/dist/internal/result.mjs +3 -3
- package/dist/internal/sized.mjs +4 -4
- package/dist/internal/string.mjs +4 -4
- package/dist/internal/subscription.d.mts +24 -8
- package/dist/internal/subscription.mjs +49 -36
- package/dist/internal/value/equal.mjs +6 -6
- package/dist/internal/value/misc.mjs +14 -14
- package/dist/internal/value/set.mjs +2 -2
- package/dist/logger.mjs +15 -39
- package/dist/promise/constants.d.mts +17 -0
- package/dist/promise/constants.mjs +14 -0
- package/dist/promise/delay.mjs +7 -10
- package/dist/promise/helpers.mjs +1 -1
- package/dist/promise/index.mjs +14 -17
- package/dist/promise/misc.d.mts +2 -1
- package/dist/promise/misc.mjs +8 -7
- package/dist/promise/models.d.mts +4 -16
- package/dist/promise/models.mjs +4 -13
- package/dist/promise/timed.mjs +9 -10
- package/dist/query.mjs +15 -15
- package/dist/queue.mjs +103 -116
- package/dist/random.mjs +7 -7
- package/dist/result/index.d.mts +0 -3
- package/dist/result/index.mjs +1 -1
- package/dist/result/match.d.mts +0 -3
- package/dist/result/match.mjs +4 -4
- package/dist/result/misc.mjs +2 -2
- package/dist/result/work/flow.d.mts +0 -3
- package/dist/result/work/flow.mjs +5 -5
- package/dist/result/work/pipe.d.mts +0 -3
- package/dist/result/work/pipe.mjs +3 -3
- package/dist/string/case.mjs +20 -20
- package/dist/string/fuzzy.mjs +23 -18
- package/dist/string/index.mjs +7 -7
- package/dist/string/normalize.mjs +14 -14
- package/dist/string/template.mjs +2 -2
- package/dist/value/clone.mjs +10 -10
- package/dist/value/smush.mjs +2 -2
- package/package.json +13 -5
- package/src/array/difference.ts +0 -73
- package/src/array/exists.ts +0 -93
- package/src/array/filter.ts +0 -182
- package/src/array/find.ts +0 -183
- package/src/array/first.ts +0 -196
- package/src/array/flatten.ts +0 -20
- package/src/array/from.ts +0 -129
- package/src/array/get.ts +0 -131
- package/src/array/group-by.ts +0 -369
- package/src/array/index.ts +0 -26
- package/src/array/insert.ts +0 -52
- package/src/array/intersection.ts +0 -72
- package/src/array/last.ts +0 -194
- package/src/array/match.ts +0 -436
- package/src/array/move.ts +0 -315
- package/src/array/partition.ts +0 -91
- package/src/array/push.ts +0 -23
- package/src/array/reverse.ts +0 -33
- package/src/array/select.ts +0 -260
- package/src/array/single.ts +0 -93
- package/src/array/slice.ts +0 -335
- package/src/array/sort.ts +0 -607
- package/src/array/splice.ts +0 -106
- package/src/array/swap.ts +0 -322
- package/src/array/to-map.ts +0 -371
- package/src/array/to-record.ts +0 -351
- package/src/array/to-set.ts +0 -80
- package/src/array/toggle.ts +0 -79
- package/src/array/union.ts +0 -72
- package/src/array/unique.ts +0 -67
- package/src/array/update.ts +0 -75
- package/src/beacon.ts +0 -378
- package/src/color/constants.ts +0 -137
- package/src/color/index.ts +0 -83
- package/src/color/instance.ts +0 -162
- package/src/color/misc/alpha.ts +0 -56
- package/src/color/misc/format.ts +0 -29
- package/src/color/misc/get.ts +0 -210
- package/src/color/misc/is.ts +0 -221
- package/src/color/misc/state.ts +0 -243
- package/src/color/models.ts +0 -389
- package/src/color/space/hex.ts +0 -184
- package/src/color/space/hsl.ts +0 -174
- package/src/color/space/hwb.ts +0 -153
- package/src/color/space/rgb.ts +0 -240
- package/src/function/assert.ts +0 -174
- package/src/function/index.ts +0 -2
- package/src/function/limit.ts +0 -83
- package/src/function/memoize.ts +0 -202
- package/src/function/once.ts +0 -200
- package/src/function/retry.ts +0 -175
- package/src/function/work.ts +0 -1007
- package/src/herald.ts +0 -216
- package/src/index.ts +0 -68
- package/src/internal/array/callbacks.ts +0 -46
- package/src/internal/array/chunk.ts +0 -51
- package/src/internal/array/compact.ts +0 -56
- package/src/internal/array/find.ts +0 -200
- package/src/internal/array/group.ts +0 -42
- package/src/internal/array/index-of.ts +0 -182
- package/src/internal/array/insert.ts +0 -80
- package/src/internal/array/overlap.ts +0 -35
- package/src/internal/array/sets.ts +0 -74
- package/src/internal/array/shuffle.ts +0 -33
- package/src/internal/array/update.ts +0 -52
- package/src/internal/function/misc.ts +0 -8
- package/src/internal/function/timer.ts +0 -168
- package/src/internal/is.ts +0 -244
- package/src/internal/math/aggregate.ts +0 -164
- package/src/internal/math/misc.ts +0 -28
- package/src/internal/number.ts +0 -129
- package/src/internal/random.ts +0 -49
- package/src/internal/result.ts +0 -92
- package/src/internal/sized.ts +0 -25
- package/src/internal/string.ts +0 -128
- package/src/internal/subscription.ts +0 -264
- package/src/internal/value/compare.ts +0 -170
- package/src/internal/value/equal.ts +0 -465
- package/src/internal/value/get.ts +0 -57
- package/src/internal/value/handlers.ts +0 -95
- package/src/internal/value/has.ts +0 -118
- package/src/internal/value/misc.ts +0 -125
- package/src/internal/value/partial.ts +0 -46
- package/src/internal/value/set.ts +0 -132
- package/src/is.ts +0 -182
- package/src/logger.ts +0 -230
- package/src/math.ts +0 -281
- package/src/models.ts +0 -286
- package/src/number.ts +0 -1
- package/src/promise/delay.ts +0 -62
- package/src/promise/helpers.ts +0 -96
- package/src/promise/index.ts +0 -300
- package/src/promise/misc.ts +0 -96
- package/src/promise/models.ts +0 -195
- package/src/promise/timed.ts +0 -91
- package/src/query.ts +0 -147
- package/src/queue.ts +0 -814
- package/src/random.ts +0 -125
- package/src/result/index.ts +0 -105
- package/src/result/match.ts +0 -124
- package/src/result/misc.ts +0 -129
- package/src/result/models.ts +0 -83
- package/src/result/work/flow.ts +0 -488
- package/src/result/work/pipe.ts +0 -496
- package/src/sized/map.ts +0 -110
- package/src/sized/set.ts +0 -107
- package/src/string/case.ts +0 -236
- package/src/string/fuzzy.ts +0 -444
- package/src/string/index.ts +0 -199
- package/src/string/match.ts +0 -80
- package/src/string/normalize.ts +0 -205
- package/src/string/template.ts +0 -161
- package/src/value/clone.ts +0 -319
- package/src/value/collection.ts +0 -63
- package/src/value/diff.ts +0 -232
- package/src/value/freeze.ts +0 -322
- package/src/value/handle.ts +0 -3
- package/src/value/index.ts +0 -5
- package/src/value/merge.ts +0 -278
- package/src/value/omit.ts +0 -20
- package/src/value/pick.ts +0 -20
- package/src/value/shake.ts +0 -45
- package/src/value/smush.ts +0 -89
- package/src/value/transform.ts +0 -153
- package/src/value/unsmush.ts +0 -84
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { GenericCallback } from "../models.mjs";
|
|
2
|
+
//#region src/internal/abort.d.ts
|
|
3
|
+
type Aborter = {
|
|
4
|
+
callback: GenericCallback;
|
|
5
|
+
signal: AbortSignal;
|
|
6
|
+
cancel: () => void;
|
|
7
|
+
};
|
|
8
|
+
declare function createAborter(value: unknown, onAbort: () => void): Aborter | undefined;
|
|
9
|
+
//#endregion
|
|
10
|
+
export { Aborter, createAborter };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
//#region src/internal/abort.ts
|
|
2
|
+
function createAborter(value, onAbort) {
|
|
3
|
+
if (!(value instanceof AbortSignal)) return;
|
|
4
|
+
value.addEventListener(ABORT_EVENT, onAbort, ABORT_OPTIONS);
|
|
5
|
+
return {
|
|
6
|
+
callback: onAbort,
|
|
7
|
+
signal: value,
|
|
8
|
+
cancel: () => value.removeEventListener(ABORT_EVENT, onAbort)
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
const ABORT_EVENT = "abort";
|
|
12
|
+
const ABORT_OPTIONS = { once: true };
|
|
13
|
+
//#endregion
|
|
14
|
+
export { createAborter };
|
|
@@ -15,7 +15,7 @@ function chunk(array, size) {
|
|
|
15
15
|
if (!Array.isArray(array)) return [];
|
|
16
16
|
if (array.length === 0) return [];
|
|
17
17
|
const { length } = array;
|
|
18
|
-
const actualSize = typeof size === "number" && size > 0 && size <=
|
|
18
|
+
const actualSize = typeof size === "number" && size > 0 && size <= CHUNK_MAX_SIZE ? size : CHUNK_MAX_SIZE;
|
|
19
19
|
if (length <= actualSize) return [array];
|
|
20
20
|
const chunks = [];
|
|
21
21
|
let index = 0;
|
|
@@ -25,6 +25,6 @@ function chunk(array, size) {
|
|
|
25
25
|
}
|
|
26
26
|
return chunks;
|
|
27
27
|
}
|
|
28
|
-
const
|
|
28
|
+
const CHUNK_MAX_SIZE = 5e3;
|
|
29
29
|
//#endregion
|
|
30
30
|
export { chunk };
|
|
@@ -40,7 +40,7 @@ function findValues(type, array, parameters, mapper) {
|
|
|
40
40
|
const { length } = array;
|
|
41
41
|
const { bool, key, value } = getFindParameters(parameters);
|
|
42
42
|
const callbacks = getArrayCallbacks(bool, key);
|
|
43
|
-
if (type === "unique" && callbacks?.keyed == null && length >=
|
|
43
|
+
if (type === "unique" && callbacks?.keyed == null && length >= FIND_UNIQUE_THRESHOLD) {
|
|
44
44
|
result.matched = [...new Set(array)];
|
|
45
45
|
return result;
|
|
46
46
|
}
|
|
@@ -77,6 +77,6 @@ const FIND_VALUE_INDEX = "index";
|
|
|
77
77
|
const FIND_VALUE_ITEM = "item";
|
|
78
78
|
const FIND_VALUES_ALL = "all";
|
|
79
79
|
const FIND_VALUES_UNIQUE = "unique";
|
|
80
|
-
const
|
|
80
|
+
const FIND_UNIQUE_THRESHOLD = 100;
|
|
81
81
|
//#endregion
|
|
82
82
|
export { FIND_VALUES_ALL, FIND_VALUES_UNIQUE, FIND_VALUE_INDEX, FIND_VALUE_ITEM, findAbsoluteValueOrDefault, findValue, findValues, getFindParameters };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
//#region src/internal/array/sets.d.ts
|
|
2
2
|
type CompareSetsType = 'difference' | 'intersection' | 'union';
|
|
3
3
|
declare function compareSets(type: CompareSetsType, first: unknown[], second: unknown[], key?: unknown): unknown[];
|
|
4
|
-
declare const
|
|
5
|
-
declare const
|
|
6
|
-
declare const
|
|
4
|
+
declare const SETS_COMPARE_DIFFERENCE: CompareSetsType;
|
|
5
|
+
declare const SETS_COMPARE_INTERSECTION: CompareSetsType;
|
|
6
|
+
declare const SETS_COMPARE_UNION: CompareSetsType;
|
|
7
7
|
//#endregion
|
|
8
|
-
export {
|
|
8
|
+
export { SETS_COMPARE_DIFFERENCE, SETS_COMPARE_INTERSECTION, SETS_COMPARE_UNION, compareSets };
|
|
@@ -2,9 +2,9 @@ import { getArrayCallback } from "./callbacks.mjs";
|
|
|
2
2
|
//#region src/internal/array/sets.ts
|
|
3
3
|
function compareSets(type, first, second, key) {
|
|
4
4
|
if (!Array.isArray(first)) return [];
|
|
5
|
-
const isDifference = type ===
|
|
6
|
-
const isIntersection = type ===
|
|
7
|
-
const isUnion = type ===
|
|
5
|
+
const isDifference = type === SETS_COMPARE_DIFFERENCE;
|
|
6
|
+
const isIntersection = type === SETS_COMPARE_INTERSECTION;
|
|
7
|
+
const isUnion = type === SETS_COMPARE_UNION;
|
|
8
8
|
if (first.length === 0) return isDifference ? first.slice() : isIntersection ? [] : second.slice();
|
|
9
9
|
if (!Array.isArray(second) || second.length === 0) return isIntersection ? [] : first.slice();
|
|
10
10
|
const callback = getArrayCallback(key);
|
|
@@ -25,8 +25,8 @@ function compareSets(type, first, second, key) {
|
|
|
25
25
|
}
|
|
26
26
|
return result;
|
|
27
27
|
}
|
|
28
|
-
const
|
|
29
|
-
const
|
|
30
|
-
const
|
|
28
|
+
const SETS_COMPARE_DIFFERENCE = "difference";
|
|
29
|
+
const SETS_COMPARE_INTERSECTION = "intersection";
|
|
30
|
+
const SETS_COMPARE_UNION = "union";
|
|
31
31
|
//#endregion
|
|
32
|
-
export {
|
|
32
|
+
export { SETS_COMPARE_DIFFERENCE, SETS_COMPARE_INTERSECTION, SETS_COMPARE_UNION, compareSets };
|
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
//#region src/internal/function/timer.ts
|
|
2
2
|
function getAsyncTimer(type, callback, time) {
|
|
3
|
+
function cancel() {
|
|
4
|
+
clearTimer(id);
|
|
5
|
+
if (last != null && !last.running) {
|
|
6
|
+
last.reject();
|
|
7
|
+
last = void 0;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
3
10
|
async function run(item) {
|
|
4
11
|
const now = performance.now();
|
|
5
12
|
start ??= now;
|
|
6
|
-
if (interval === 0 || now - start >= interval -
|
|
13
|
+
if (interval === 0 || now - start >= interval - TIMER_OFFSET) {
|
|
7
14
|
start = throttle ? now : void 0;
|
|
8
15
|
item.running = true;
|
|
9
16
|
try {
|
|
@@ -23,7 +30,7 @@ function getAsyncTimer(type, callback, time) {
|
|
|
23
30
|
let last;
|
|
24
31
|
let start;
|
|
25
32
|
const timer = (...parameters) => {
|
|
26
|
-
|
|
33
|
+
cancel();
|
|
27
34
|
const next = {
|
|
28
35
|
parameters,
|
|
29
36
|
running: false
|
|
@@ -34,25 +41,23 @@ function getAsyncTimer(type, callback, time) {
|
|
|
34
41
|
});
|
|
35
42
|
last = next;
|
|
36
43
|
if (throttle) run(next);
|
|
37
|
-
else id = startTimer(() =>
|
|
38
|
-
run(next);
|
|
39
|
-
});
|
|
44
|
+
else id = startTimer(() => run(next));
|
|
40
45
|
return next.promise;
|
|
41
46
|
};
|
|
42
|
-
timer
|
|
43
|
-
clearTimer(id);
|
|
44
|
-
if (last != null && !last.running) last.reject();
|
|
45
|
-
};
|
|
47
|
+
Object.defineProperty(timer, TIMER_CANCEL, { value: () => cancel() });
|
|
46
48
|
return timer;
|
|
47
49
|
}
|
|
48
50
|
function getInterval(value) {
|
|
49
51
|
return typeof value === "number" && value > 0 ? value : 0;
|
|
50
52
|
}
|
|
51
53
|
function getTimer(type, callback, time) {
|
|
54
|
+
function cancel() {
|
|
55
|
+
clearTimer(id);
|
|
56
|
+
}
|
|
52
57
|
function run() {
|
|
53
58
|
const now = performance.now();
|
|
54
59
|
start ??= now;
|
|
55
|
-
if (interval === 0 || now - start >= interval -
|
|
60
|
+
if (interval === 0 || now - start >= interval - TIMER_OFFSET) {
|
|
56
61
|
start = throttle ? now : void 0;
|
|
57
62
|
callback(...args);
|
|
58
63
|
} else id = startTimer(run);
|
|
@@ -63,18 +68,17 @@ function getTimer(type, callback, time) {
|
|
|
63
68
|
let id;
|
|
64
69
|
let start;
|
|
65
70
|
const timer = (...parameters) => {
|
|
66
|
-
|
|
71
|
+
cancel();
|
|
67
72
|
args = parameters;
|
|
68
73
|
if (throttle) run();
|
|
69
74
|
else id = startTimer(run);
|
|
70
75
|
};
|
|
71
|
-
timer
|
|
72
|
-
clearTimer(id);
|
|
73
|
-
};
|
|
76
|
+
Object.defineProperty(timer, TIMER_CANCEL, { value: () => cancel() });
|
|
74
77
|
return timer;
|
|
75
78
|
}
|
|
76
|
-
const
|
|
79
|
+
const TIMER_CANCEL = "cancel";
|
|
77
80
|
const TIMER_DEBOUNCE = "debounce";
|
|
81
|
+
const TIMER_OFFSET = 5;
|
|
78
82
|
const TIMER_THROTTLE = "throttle";
|
|
79
83
|
const TIMER_WAIT = "wait";
|
|
80
84
|
// istanbul ignore next
|
package/dist/internal/number.mjs
CHANGED
|
@@ -59,17 +59,17 @@ function getNumber(value) {
|
|
|
59
59
|
if (typeof parsed !== "string") return getNumber(parsed);
|
|
60
60
|
const trimmed = parsed.trim();
|
|
61
61
|
if (trimmed.length === 0) return NaN;
|
|
62
|
-
if (
|
|
63
|
-
const isBinary =
|
|
64
|
-
if (isBinary ||
|
|
62
|
+
if (NUMBER_EXPRESSION_ZEROISH.test(parsed)) return 0;
|
|
63
|
+
const isBinary = NUMBER_EXPRESSION_BINARY.test(trimmed);
|
|
64
|
+
if (isBinary || NUMBER_EXPRESSION_OCTAL.test(trimmed)) return Number.parseInt(trimmed.slice(2), isBinary ? 2 : NUMBER_OCTAL_VALUE);
|
|
65
65
|
return Number(trimmed);
|
|
66
66
|
}
|
|
67
67
|
function getNumberOrDefault(value, defaultValue, minimum) {
|
|
68
68
|
return typeof value === "number" && !Number.isNaN(value) && value >= (minimum ?? 0) ? Math.floor(value) : defaultValue;
|
|
69
69
|
}
|
|
70
|
-
const
|
|
71
|
-
const
|
|
72
|
-
const
|
|
73
|
-
const
|
|
70
|
+
const NUMBER_EXPRESSION_BINARY = /^0b[01]+$/i;
|
|
71
|
+
const NUMBER_EXPRESSION_OCTAL = /^0o[0-7]+$/i;
|
|
72
|
+
const NUMBER_EXPRESSION_ZEROISH = /^\s*0+\s*$/;
|
|
73
|
+
const NUMBER_OCTAL_VALUE = 8;
|
|
74
74
|
//#endregion
|
|
75
75
|
export { between, clamp, getNumber, getNumberOrDefault };
|
package/dist/internal/result.mjs
CHANGED
|
@@ -17,9 +17,9 @@ function isResult(value) {
|
|
|
17
17
|
}
|
|
18
18
|
function isResultValue(value, okValue) {
|
|
19
19
|
if (isNonPlainObject(value)) return false;
|
|
20
|
-
return value.ok === okValue && (okValue ?
|
|
20
|
+
return value.ok === okValue && (okValue ? RESULT_PROPERTY_VALUE : RESULT_PROPERTY_ERROR) in value;
|
|
21
21
|
}
|
|
22
|
-
const
|
|
23
|
-
const
|
|
22
|
+
const RESULT_PROPERTY_ERROR = "error";
|
|
23
|
+
const RESULT_PROPERTY_VALUE = "value";
|
|
24
24
|
//#endregion
|
|
25
25
|
export { isError, isOk, isResult };
|
package/dist/internal/sized.mjs
CHANGED
|
@@ -3,10 +3,10 @@ import { clamp } from "./number.mjs";
|
|
|
3
3
|
function getSizedMaximum(first, second) {
|
|
4
4
|
let actual;
|
|
5
5
|
if (typeof first === "number") actual = first;
|
|
6
|
-
else actual = typeof second === "number" ? second :
|
|
7
|
-
return clamp(actual, 1,
|
|
6
|
+
else actual = typeof second === "number" ? second : SIZED_MAXIMUM_DEFAULT;
|
|
7
|
+
return clamp(actual, 1, SIZED_MAXIMUM_ABSOLUTE);
|
|
8
8
|
}
|
|
9
|
-
const
|
|
10
|
-
const
|
|
9
|
+
const SIZED_MAXIMUM_ABSOLUTE = 16777216;
|
|
10
|
+
const SIZED_MAXIMUM_DEFAULT = 1048576;
|
|
11
11
|
//#endregion
|
|
12
12
|
export { getSizedMaximum };
|
package/dist/internal/string.mjs
CHANGED
|
@@ -25,7 +25,7 @@ function getString(value) {
|
|
|
25
25
|
return asString.startsWith("[object ") ? JSON.stringify(value) : asString;
|
|
26
26
|
}
|
|
27
27
|
function ignoreKey(key) {
|
|
28
|
-
return
|
|
28
|
+
return STRING_EXPRESSION_IGNORED.test(key);
|
|
29
29
|
}
|
|
30
30
|
function interpolate(strings, values) {
|
|
31
31
|
const { length } = strings;
|
|
@@ -76,9 +76,9 @@ function tryEncode(value) {
|
|
|
76
76
|
* @returns Array of words found in the string
|
|
77
77
|
*/
|
|
78
78
|
function words(value) {
|
|
79
|
-
return typeof value === "string" ? value.match(
|
|
79
|
+
return typeof value === "string" ? value.match(STRING_EXPRESSION_WORDS) ?? [] : [];
|
|
80
80
|
}
|
|
81
|
-
const
|
|
82
|
-
const
|
|
81
|
+
const STRING_EXPRESSION_IGNORED = /(^|\.)(__proto__|constructor|prototype)(\.|$)/i;
|
|
82
|
+
const STRING_EXPRESSION_WORDS = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;
|
|
83
83
|
//#endregion
|
|
84
84
|
export { getString, ignoreKey, interpolate, join, tryDecode, tryEncode, words };
|
|
@@ -12,16 +12,33 @@ type Subscription = {
|
|
|
12
12
|
};
|
|
13
13
|
type SubscriptionParameters = {
|
|
14
14
|
isActive?: () => boolean;
|
|
15
|
-
key?:
|
|
16
|
-
|
|
17
|
-
subscriptions: Subscriptions;
|
|
15
|
+
key?: unknown;
|
|
16
|
+
signal?: AbortSignal;
|
|
18
17
|
value: unknown;
|
|
19
18
|
};
|
|
19
|
+
/**
|
|
20
|
+
* Property information for subscription identification
|
|
21
|
+
*/
|
|
20
22
|
type SubscriptionProperty = {
|
|
23
|
+
/**
|
|
24
|
+
* Name of the property used to identify a subscription
|
|
25
|
+
*/
|
|
21
26
|
key: string;
|
|
22
|
-
|
|
27
|
+
/**
|
|
28
|
+
* Value of the property used to identify a subscription _(defaults to `subscription`)_
|
|
29
|
+
*/
|
|
30
|
+
value?: unknown;
|
|
23
31
|
};
|
|
24
32
|
type Subscriptions<Value = unknown> = {
|
|
33
|
+
state: SubscriptionsState<Value>;
|
|
34
|
+
clear: () => void;
|
|
35
|
+
create: (parameters: SubscriptionParameters) => [Subscription, boolean];
|
|
36
|
+
};
|
|
37
|
+
type SubscriptionsParameters = {
|
|
38
|
+
keys?: Set<Key>;
|
|
39
|
+
property: SubscriptionProperty;
|
|
40
|
+
};
|
|
41
|
+
type SubscriptionsState<Value = unknown> = {
|
|
25
42
|
items: SubscriptionsItems;
|
|
26
43
|
keys?: Set<Key>;
|
|
27
44
|
values: SubscriptionsValues<Value>;
|
|
@@ -38,9 +55,7 @@ type SubscriptionsValuesItem<MapKey, MapValue> = {
|
|
|
38
55
|
any: Map<MapKey, MapValue>;
|
|
39
56
|
keyed?: Map<Key, Map<MapKey, MapValue>>;
|
|
40
57
|
};
|
|
41
|
-
declare function
|
|
42
|
-
declare function getSubscription(parameters: SubscriptionParameters): Subscription;
|
|
43
|
-
declare function getSubscriptions<Value = unknown>(keys?: Set<Key>): Subscriptions<Value>;
|
|
58
|
+
declare function createSubscriptions<Value = unknown>(parameters: SubscriptionsParameters): Subscriptions<Value>;
|
|
44
59
|
/**
|
|
45
60
|
* Is the value a subscription?
|
|
46
61
|
*
|
|
@@ -48,5 +63,6 @@ declare function getSubscriptions<Value = unknown>(keys?: Set<Key>): Subscriptio
|
|
|
48
63
|
* @returns `true` if the value is a subscription, otherwise `false`
|
|
49
64
|
*/
|
|
50
65
|
declare function isSubscription(value: unknown): value is Subscription;
|
|
66
|
+
declare const SUBSCRIPTION_NAME = "subscription";
|
|
51
67
|
//#endregion
|
|
52
|
-
export { Subscription, SubscriptionParameters, SubscriptionProperty, Subscriptions,
|
|
68
|
+
export { SUBSCRIPTION_NAME, Subscription, SubscriptionParameters, SubscriptionProperty, Subscriptions, createSubscriptions, isSubscription };
|
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
import { isPlainObject } from "./is.mjs";
|
|
1
|
+
import { isKey, isPlainObject } from "./is.mjs";
|
|
2
|
+
import { createAborter } from "./abort.mjs";
|
|
2
3
|
//#region src/internal/subscription.ts
|
|
3
|
-
function addSubscription(subscription, state) {
|
|
4
|
-
const { key,
|
|
5
|
-
const { items, values } = subscriptions;
|
|
6
|
-
if (key
|
|
4
|
+
function addSubscription(subscriptions, subscription, state) {
|
|
5
|
+
const { key, value } = state.parameters;
|
|
6
|
+
const { items, values } = subscriptions.state;
|
|
7
|
+
if (!isKey(key)) {
|
|
7
8
|
items.any.add(subscription);
|
|
8
9
|
values.from.any.set(value, subscription);
|
|
9
10
|
values.to.any.set(subscription, value);
|
|
10
11
|
return;
|
|
11
12
|
}
|
|
13
|
+
/* istanbul ignore if */
|
|
12
14
|
if (items.keyed == null || values.from.keyed == null || values.to.keyed == null)
|
|
13
15
|
// istanbul ignore next
|
|
14
16
|
return;
|
|
@@ -35,41 +37,31 @@ function clearSubscriptions(store) {
|
|
|
35
37
|
for (const susbcription of store.values.to.any.keys()) susbcription.unsubscribe();
|
|
36
38
|
if (store.values.to.keyed != null) for (const values of store.values.to.keyed.values()) for (const susbcription of values.keys()) susbcription.unsubscribe();
|
|
37
39
|
}
|
|
38
|
-
function
|
|
39
|
-
|
|
40
|
-
const { values } = parameters.subscriptions;
|
|
41
|
-
return parameters.key == null ? values.from.any.get(parameters.value) : values.from.keyed?.get(parameters.key)?.get(parameters.value);
|
|
42
|
-
}
|
|
43
|
-
function getSubscription(parameters) {
|
|
40
|
+
function createSubscription(subscriptions, property, parameters) {
|
|
41
|
+
if (parameters.signal?.aborted ?? false) throw new Error(parameters.signal?.reason);
|
|
44
42
|
const state = {
|
|
45
43
|
parameters,
|
|
46
44
|
active: true
|
|
47
45
|
};
|
|
48
|
-
const existing = getExistingSubscription(state);
|
|
49
|
-
if (existing != null) return existing;
|
|
50
|
-
if (
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
} };
|
|
46
|
+
const existing = getExistingSubscription(subscriptions, state);
|
|
47
|
+
if (existing != null) return [existing, true];
|
|
48
|
+
if (subscriptions.state.keys != null && isKey(parameters.key) && !subscriptions.state.keys.has(parameters.key)) throw new Error(SUBSCRIPTION_INVALID_KEY);
|
|
49
|
+
state.aborter = createAborter(parameters.signal, () => unsubscribe(subscriptions, instance, state));
|
|
50
|
+
const instance = { unsubscribe: () => unsubscribe(subscriptions, instance, state) };
|
|
54
51
|
Object.defineProperties(instance, {
|
|
55
|
-
[
|
|
56
|
-
|
|
57
|
-
value: true
|
|
58
|
-
},
|
|
59
|
-
[parameters.property.key]: {
|
|
60
|
-
enumerable: false,
|
|
61
|
-
value: parameters.property.value
|
|
62
|
-
},
|
|
52
|
+
[SUBSCRIPTION_PROPERTY]: { value: true },
|
|
53
|
+
[property.key]: { value: property.value ?? "subscription" },
|
|
63
54
|
active: {
|
|
64
55
|
enumerable: true,
|
|
65
56
|
get: () => (parameters.isActive?.() ?? true) && state.active
|
|
66
57
|
}
|
|
67
58
|
});
|
|
68
|
-
addSubscription(instance, state);
|
|
69
|
-
return Object.freeze(instance);
|
|
59
|
+
addSubscription(subscriptions, instance, state);
|
|
60
|
+
return [Object.freeze(instance), false];
|
|
70
61
|
}
|
|
71
|
-
function
|
|
72
|
-
|
|
62
|
+
function createSubscriptions(parameters) {
|
|
63
|
+
const { keys, property } = parameters;
|
|
64
|
+
const state = {
|
|
73
65
|
keys,
|
|
74
66
|
items: {
|
|
75
67
|
any: /* @__PURE__ */ new Set(),
|
|
@@ -86,6 +78,17 @@ function getSubscriptions(keys) {
|
|
|
86
78
|
}
|
|
87
79
|
}
|
|
88
80
|
};
|
|
81
|
+
const instance = {
|
|
82
|
+
state,
|
|
83
|
+
clear: () => clearSubscriptions(state),
|
|
84
|
+
create: (parameters) => createSubscription(instance, property, parameters)
|
|
85
|
+
};
|
|
86
|
+
return instance;
|
|
87
|
+
}
|
|
88
|
+
function getExistingSubscription(subscriptions, state) {
|
|
89
|
+
const { parameters } = state;
|
|
90
|
+
const { values } = subscriptions.state;
|
|
91
|
+
return isKey(parameters.key) ? values.from.keyed?.get(parameters.key)?.get(parameters.value) : values.from.any.get(parameters.value);
|
|
89
92
|
}
|
|
90
93
|
/**
|
|
91
94
|
* Is the value a subscription?
|
|
@@ -94,7 +97,7 @@ function getSubscriptions(keys) {
|
|
|
94
97
|
* @returns `true` if the value is a subscription, otherwise `false`
|
|
95
98
|
*/
|
|
96
99
|
function isSubscription(value) {
|
|
97
|
-
return isPlainObject(value) &&
|
|
100
|
+
return isPlainObject(value) && SUBSCRIPTION_PROPERTY in value && value[SUBSCRIPTION_PROPERTY] === true;
|
|
98
101
|
}
|
|
99
102
|
function removeFromStore(items, values, subscription, value, key) {
|
|
100
103
|
items.delete(subscription);
|
|
@@ -106,22 +109,32 @@ function removeFromStore(items, values, subscription, value, key) {
|
|
|
106
109
|
values.to.keyed?.get(key)?.delete(subscription);
|
|
107
110
|
}
|
|
108
111
|
}
|
|
109
|
-
function removeSubscription(subscription, state) {
|
|
112
|
+
function removeSubscription(subscriptions, subscription, state) {
|
|
110
113
|
if (!state.active) return;
|
|
114
|
+
state.aborter = void 0;
|
|
111
115
|
state.active = false;
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
116
|
+
state.parameters.isActive = void 0;
|
|
117
|
+
state.parameters.signal = void 0;
|
|
118
|
+
const { key, value } = state.parameters;
|
|
119
|
+
const { items, values } = subscriptions.state;
|
|
120
|
+
if (!isKey(key)) {
|
|
115
121
|
removeFromStore(items.any, values, subscription, value);
|
|
116
122
|
return;
|
|
117
123
|
}
|
|
118
124
|
const keyed = items.keyed?.get(key);
|
|
125
|
+
/* istanbul ignore if */
|
|
119
126
|
if (items.keyed == null || keyed == null)
|
|
120
127
|
// istanbul ignore next
|
|
121
128
|
return;
|
|
122
129
|
removeFromStore(keyed, values, subscription, value, key);
|
|
123
130
|
if (keyed.size === 0) items.keyed.delete(key);
|
|
124
131
|
}
|
|
125
|
-
|
|
132
|
+
function unsubscribe(subscriptions, subscription, state) {
|
|
133
|
+
state.aborter?.cancel();
|
|
134
|
+
removeSubscription(subscriptions, subscription, state);
|
|
135
|
+
}
|
|
136
|
+
const SUBSCRIPTION_INVALID_KEY = "Invalid key for subscription";
|
|
137
|
+
const SUBSCRIPTION_NAME = "subscription";
|
|
138
|
+
const SUBSCRIPTION_PROPERTY = "$subscription";
|
|
126
139
|
//#endregion
|
|
127
|
-
export {
|
|
140
|
+
export { SUBSCRIPTION_NAME, createSubscriptions, isSubscription };
|
|
@@ -60,7 +60,7 @@ function equalPlainObject(first, second, options) {
|
|
|
60
60
|
firstKeys = firstKeys.filter((key) => filterKey(key, options));
|
|
61
61
|
secondKeys = secondKeys.filter((key) => filterKey(key, options));
|
|
62
62
|
}
|
|
63
|
-
const secondSet = secondKeys.length >=
|
|
63
|
+
const secondSet = secondKeys.length >= EQUAL_MINIMUM_LENGTH_FOR_SET ? new Set(secondKeys) : void 0;
|
|
64
64
|
const { length } = firstKeys;
|
|
65
65
|
if (length !== secondKeys.length) return false;
|
|
66
66
|
for (let index = 0; index < length; index += 1) {
|
|
@@ -105,9 +105,9 @@ function equalValue(first, second, options) {
|
|
|
105
105
|
case first instanceof ArrayBuffer && second instanceof ArrayBuffer: return equalArrayBuffer(first, second, options);
|
|
106
106
|
case first instanceof Date && second instanceof Date: return Object.is(first.getTime(), second.getTime());
|
|
107
107
|
case first instanceof DataView && second instanceof DataView: return equalDataView(first, second, options);
|
|
108
|
-
case first instanceof Error && second instanceof Error: return equalProperties(first, second,
|
|
108
|
+
case first instanceof Error && second instanceof Error: return equalProperties(first, second, EQUAL_ERROR_PROPERTIES, options);
|
|
109
109
|
case first instanceof Map && second instanceof Map: return equalMap(first, second, options);
|
|
110
|
-
case first instanceof RegExp && second instanceof RegExp: return equalProperties(first, second,
|
|
110
|
+
case first instanceof RegExp && second instanceof RegExp: return equalProperties(first, second, EQUAL_EXPRESSION_PROPERTIES, options);
|
|
111
111
|
case first instanceof Set && second instanceof Set: return equalSet(first, second, options);
|
|
112
112
|
case Array.isArray(first) && Array.isArray(second): return equalArray(first, second, options);
|
|
113
113
|
case isPlainObject(first) && isPlainObject(second): return equalPlainObject(first, second, options);
|
|
@@ -169,8 +169,8 @@ function registerEqualizer(constructor, handler) {
|
|
|
169
169
|
}
|
|
170
170
|
const EQUAL_ARRAY_PEEK_PERCENTAGE = 10;
|
|
171
171
|
const EQUAL_ARRAY_THRESHOLD = 100;
|
|
172
|
-
const
|
|
173
|
-
const
|
|
174
|
-
const
|
|
172
|
+
const EQUAL_ERROR_PROPERTIES = ["name", "message"];
|
|
173
|
+
const EQUAL_EXPRESSION_PROPERTIES = ["source", "flags"];
|
|
174
|
+
const EQUAL_MINIMUM_LENGTH_FOR_SET = 16;
|
|
175
175
|
//#endregion
|
|
176
176
|
export { deregisterEqualizer, equal, initializeEqualizer, registerEqualizer };
|
|
@@ -7,8 +7,8 @@ function findKey(needle, haystack) {
|
|
|
7
7
|
return index > -1 ? keys[index] : needle;
|
|
8
8
|
}
|
|
9
9
|
function getNestedValue(data, path, ignoreCase) {
|
|
10
|
-
if (typeof data !== "object" || data === null) return error(
|
|
11
|
-
if (typeof path !== "string" || path.trim().length === 0) return error(
|
|
10
|
+
if (typeof data !== "object" || data === null) return error(MISC_NESTED_MESSAGE_INPUT);
|
|
11
|
+
if (typeof path !== "string" || path.trim().length === 0) return error(MISC_NESTED_MESSAGE_PATH);
|
|
12
12
|
const shouldIgnoreCase = ignoreCase === true;
|
|
13
13
|
const paths = getPaths(path, shouldIgnoreCase);
|
|
14
14
|
if (typeof paths === "string") return handleValue(data, paths, null, true, shouldIgnoreCase);
|
|
@@ -24,24 +24,24 @@ function getNestedValue(data, path, ignoreCase) {
|
|
|
24
24
|
}
|
|
25
25
|
function getPaths(path, lowercase) {
|
|
26
26
|
const normalized = lowercase ? path.toLowerCase() : path;
|
|
27
|
-
if (!
|
|
28
|
-
return normalized.replace(
|
|
27
|
+
if (!MISC_EXPRESSION_NESTED.test(normalized)) return normalized;
|
|
28
|
+
return normalized.replace(MISC_EXPRESSION_BRACKET, ".$1").replace(MISC_EXPRESSION_DOTS, "").split(".");
|
|
29
29
|
}
|
|
30
30
|
function handleValue(data, path, value, get, ignoreCase) {
|
|
31
31
|
if (typeof data === "object" && data !== null) {
|
|
32
|
-
if (ignoreKey(path)) return error(
|
|
32
|
+
if (ignoreKey(path)) return error(MISC_NESTED_MESSAGE_UNSAFE);
|
|
33
33
|
const key = ignoreCase ? findKey(path, data) : path;
|
|
34
|
-
if (get) return key in data ? ok(data[key]) : error(
|
|
34
|
+
if (get) return key in data ? ok(data[key]) : error(MISC_NESTED_MESSAGE_MISSING);
|
|
35
35
|
data[key] = typeof value === "function" ? value(data[key]) : value;
|
|
36
36
|
}
|
|
37
|
-
if (get) return error(
|
|
37
|
+
if (get) return error(MISC_NESTED_MESSAGE_MISSING);
|
|
38
38
|
}
|
|
39
|
-
const
|
|
40
|
-
const
|
|
41
|
-
const
|
|
42
|
-
const
|
|
43
|
-
const
|
|
44
|
-
const
|
|
45
|
-
const
|
|
39
|
+
const MISC_EXPRESSION_BRACKET = /\[(\w+)\]/g;
|
|
40
|
+
const MISC_EXPRESSION_DOTS = /^\.|\.$/g;
|
|
41
|
+
const MISC_EXPRESSION_NESTED = /\.|\[\w+\]/;
|
|
42
|
+
const MISC_NESTED_MESSAGE_INPUT = "Expected data to be an object";
|
|
43
|
+
const MISC_NESTED_MESSAGE_MISSING = "Expected property to exist in object";
|
|
44
|
+
const MISC_NESTED_MESSAGE_PATH = "Expected path to be a string";
|
|
45
|
+
const MISC_NESTED_MESSAGE_UNSAFE = "Access to this property is not allowed";
|
|
46
46
|
//#endregion
|
|
47
47
|
export { findKey, getNestedValue, getPaths, handleValue };
|
|
@@ -20,7 +20,7 @@ function setValue(data, path, value, ignoreCase) {
|
|
|
20
20
|
let next = handleValue(target, currentPath, null, true, shouldIgnoreCase).value;
|
|
21
21
|
if (typeof next !== "object" || next === null) {
|
|
22
22
|
const nextPath = paths[index + 1];
|
|
23
|
-
if (
|
|
23
|
+
if (SET_EXPRESSION_INDEX.test(nextPath)) next = Array.from({ length: Number(nextPath) + 1 }, () => void 0);
|
|
24
24
|
else next = {};
|
|
25
25
|
target[currentPath] = next;
|
|
26
26
|
}
|
|
@@ -28,6 +28,6 @@ function setValue(data, path, value, ignoreCase) {
|
|
|
28
28
|
}
|
|
29
29
|
return data;
|
|
30
30
|
}
|
|
31
|
-
const
|
|
31
|
+
const SET_EXPRESSION_INDEX = /^\d+$/;
|
|
32
32
|
//#endregion
|
|
33
33
|
export { setValue };
|
package/dist/logger.mjs
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { noop } from "./internal/function/misc.mjs";
|
|
2
|
+
import { getString } from "./internal/string.mjs";
|
|
2
3
|
//#region src/logger.ts
|
|
3
4
|
function isLogger(value) {
|
|
4
|
-
return isLoggerInstance(
|
|
5
|
+
return isLoggerInstance(LOGGER_NAME, value);
|
|
5
6
|
}
|
|
6
7
|
function isLoggerInstance(name, value) {
|
|
7
|
-
return typeof value === "object" && value !== null && value[
|
|
8
|
+
return typeof value === "object" && value !== null && value[LOGGER_PROPERTY] === name;
|
|
8
9
|
}
|
|
9
10
|
function isTimedLogger(value) {
|
|
10
|
-
return isLoggerInstance(
|
|
11
|
+
return isLoggerInstance(LOGGER_NAME_TIMED, value);
|
|
11
12
|
}
|
|
12
13
|
function timedLogger(label) {
|
|
13
14
|
function stop() {
|
|
@@ -26,35 +27,20 @@ function timedLogger(label) {
|
|
|
26
27
|
};
|
|
27
28
|
const instance = {};
|
|
28
29
|
Object.defineProperties(instance, {
|
|
29
|
-
[
|
|
30
|
-
enumerable: false,
|
|
31
|
-
value: NAME_TIMED
|
|
32
|
-
},
|
|
30
|
+
[LOGGER_PROPERTY]: { value: LOGGER_NAME_TIMED },
|
|
33
31
|
active: {
|
|
34
32
|
enumerable: true,
|
|
35
|
-
get()
|
|
36
|
-
return state.started && !state.stopped && enabled;
|
|
37
|
-
}
|
|
38
|
-
},
|
|
39
|
-
log: {
|
|
40
|
-
enumerable: true,
|
|
41
|
-
get() {
|
|
42
|
-
return this.active ? logger : noop;
|
|
43
|
-
}
|
|
33
|
+
get: () => state.started && !state.stopped && enabled
|
|
44
34
|
},
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
get() {
|
|
48
|
-
return instance.active ? stop() : noop;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
35
|
+
log: { get: () => instance.active ? logger : noop },
|
|
36
|
+
stop: { get: () => instance.active ? stop() : noop }
|
|
51
37
|
});
|
|
52
38
|
if (state.started) console.time(label);
|
|
53
39
|
return Object.freeze(instance);
|
|
54
40
|
}
|
|
55
|
-
const
|
|
56
|
-
const
|
|
57
|
-
const
|
|
41
|
+
const LOGGER_NAME = "Logger";
|
|
42
|
+
const LOGGER_NAME_TIMED = "TimedLogger";
|
|
43
|
+
const LOGGER_PROPERTY = "$logger";
|
|
58
44
|
const methods = [
|
|
59
45
|
"debug",
|
|
60
46
|
"dir",
|
|
@@ -73,25 +59,15 @@ const methods = [
|
|
|
73
59
|
const Logger = (() => {
|
|
74
60
|
const instance = {};
|
|
75
61
|
Object.defineProperties(instance, {
|
|
76
|
-
[
|
|
77
|
-
enumerable: false,
|
|
78
|
-
value: NAME_LOGGER
|
|
79
|
-
},
|
|
62
|
+
[LOGGER_PROPERTY]: { value: LOGGER_NAME },
|
|
80
63
|
enabled: {
|
|
81
64
|
enumerable: true,
|
|
82
|
-
get()
|
|
83
|
-
|
|
84
|
-
},
|
|
85
|
-
set(value) {
|
|
65
|
+
get: () => enabled,
|
|
66
|
+
set: (value) => {
|
|
86
67
|
enabled = typeof value === "boolean" ? value : enabled;
|
|
87
68
|
}
|
|
88
69
|
},
|
|
89
|
-
time: {
|
|
90
|
-
enumerable: true,
|
|
91
|
-
value(label) {
|
|
92
|
-
return timedLogger(label);
|
|
93
|
-
}
|
|
94
|
-
}
|
|
70
|
+
time: { value: (label) => timedLogger(getString(label)) }
|
|
95
71
|
});
|
|
96
72
|
for (const method of methods) Object.defineProperty(instance, method, {
|
|
97
73
|
enumerable: true,
|