@oscarpalmer/atoms 0.193.1 → 0.195.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/index.d.mts +2 -2
- package/dist/array/index.mjs +2 -2
- package/dist/array/intersection.mjs +2 -2
- package/dist/array/move.mjs +1 -1
- 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/swap.mjs +1 -1
- 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/color/space/hex.mjs +1 -1
- package/dist/color/space/rgb.mjs +1 -1
- package/dist/function/index.d.mts +1 -2
- package/dist/function/index.mjs +1 -2
- package/dist/function/limit.d.mts +0 -6
- package/dist/function/limit.mjs +2 -2
- package/dist/function/once.d.mts +0 -3
- package/dist/function/once.mjs +17 -14
- package/dist/function/retry.d.mts +1 -24
- package/dist/function/retry.mjs +1 -1
- package/dist/herald.d.mts +2 -72
- package/dist/herald.mjs +2 -92
- package/dist/index.d.mts +3332 -3418
- package/dist/index.mjs +1850 -1870
- 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/{array → internal/array}/get.d.mts +2 -2
- package/dist/{array → internal/array}/get.mjs +2 -2
- package/dist/{array → internal/array}/match.d.mts +2 -2
- package/dist/{array → internal/array}/match.mjs +15 -15
- package/dist/internal/array/sets.d.mts +4 -4
- package/dist/internal/array/sets.mjs +7 -7
- package/dist/internal/defaults.d.mts +5 -0
- package/dist/internal/defaults.mjs +9 -0
- package/dist/{function → internal/function}/assert.d.mts +2 -2
- package/dist/{function → internal/function}/assert.mjs +4 -4
- package/dist/{function → internal/function}/memoize.d.mts +2 -2
- package/dist/{function → internal/function}/memoize.mjs +22 -35
- package/dist/internal/function/timer.mjs +19 -15
- package/dist/{function → internal/function}/work.d.mts +2 -2
- package/dist/{function → internal/function}/work.mjs +15 -13
- package/dist/internal/herald.d.mts +71 -0
- package/dist/internal/herald.mjs +110 -0
- package/dist/internal/number.d.mts +1 -2
- package/dist/internal/number.mjs +8 -11
- package/dist/internal/{result.d.mts → result/misc.d.mts} +42 -3
- package/dist/internal/result/misc.mjs +51 -0
- package/dist/{result → internal/result}/models.d.mts +2 -2
- package/dist/{sized → internal/sized}/map.d.mts +1 -1
- package/dist/{sized → internal/sized}/map.mjs +2 -2
- package/dist/internal/{sized.d.mts → sized/misc.d.mts} +1 -1
- package/dist/internal/sized/misc.mjs +12 -0
- package/dist/{string → internal/string}/case.d.mts +1 -1
- package/dist/{string → internal/string}/case.mjs +22 -22
- package/dist/internal/{string.d.mts → string/misc.d.mts} +1 -1
- package/dist/internal/{string.mjs → string/misc.mjs} +5 -5
- package/dist/internal/subscription.d.mts +24 -8
- package/dist/internal/subscription.mjs +49 -36
- package/dist/internal/value/compare.mjs +1 -1
- package/dist/internal/value/equal.mjs +6 -6
- package/dist/internal/value/has.d.mts +1 -1
- package/dist/internal/value/misc.d.mts +1 -1
- package/dist/internal/value/misc.mjs +16 -16
- package/dist/internal/value/set.mjs +2 -2
- package/dist/is.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.d.mts +1 -1
- package/dist/promise/helpers.mjs +3 -3
- package/dist/promise/index.d.mts +1 -1
- package/dist/promise/index.mjs +14 -17
- package/dist/promise/misc.d.mts +3 -2
- package/dist/promise/misc.mjs +10 -8
- package/dist/promise/models.d.mts +5 -17
- package/dist/promise/models.mjs +4 -13
- package/dist/promise/timed.mjs +9 -10
- package/dist/query.mjs +16 -16
- package/dist/queue.mjs +104 -120
- package/dist/random.mjs +8 -8
- package/dist/result/index.d.mts +1 -4
- package/dist/result/index.mjs +2 -2
- package/dist/result/match.d.mts +1 -4
- package/dist/result/match.mjs +5 -5
- package/dist/result/misc.d.mts +3 -42
- package/dist/result/misc.mjs +4 -30
- package/dist/result/work/flow.d.mts +1 -4
- package/dist/result/work/flow.mjs +6 -6
- package/dist/result/work/pipe.d.mts +1 -4
- package/dist/result/work/pipe.mjs +5 -5
- package/dist/sized/set.mjs +1 -1
- package/dist/string/fuzzy.mjs +25 -20
- package/dist/string/index.d.mts +1 -1
- package/dist/string/index.mjs +8 -8
- package/dist/string/match.mjs +1 -1
- package/dist/string/normalize.mjs +16 -16
- package/dist/string/template.mjs +3 -3
- package/dist/subscription.d.mts +2 -0
- package/dist/subscription.mjs +2 -0
- package/dist/value/clone.mjs +10 -10
- package/dist/value/diff.mjs +1 -1
- package/dist/value/smush.mjs +3 -3
- package/package.json +35 -14
- package/dist/internal/result.mjs +0 -25
- package/dist/internal/sized.mjs +0 -12
- /package/dist/{result → internal/result}/models.mjs +0 -0
package/dist/index.mjs
CHANGED
|
@@ -55,7 +55,7 @@ function findValues(type, array, parameters, mapper) {
|
|
|
55
55
|
const { length } = array;
|
|
56
56
|
const { bool, key, value } = getFindParameters(parameters);
|
|
57
57
|
const callbacks = getArrayCallbacks(bool, key);
|
|
58
|
-
if (type === "unique" && callbacks?.keyed == null && length >=
|
|
58
|
+
if (type === "unique" && callbacks?.keyed == null && length >= FIND_UNIQUE_THRESHOLD) {
|
|
59
59
|
result.matched = [...new Set(array)];
|
|
60
60
|
return result;
|
|
61
61
|
}
|
|
@@ -91,7 +91,7 @@ function getFindParameters(original) {
|
|
|
91
91
|
const FIND_VALUE_INDEX = "index";
|
|
92
92
|
const FIND_VALUE_ITEM = "item";
|
|
93
93
|
const FIND_VALUES_UNIQUE = "unique";
|
|
94
|
-
const
|
|
94
|
+
const FIND_UNIQUE_THRESHOLD = 100;
|
|
95
95
|
//#endregion
|
|
96
96
|
//#region src/array/filter.ts
|
|
97
97
|
function exclude(array, ...parameters) {
|
|
@@ -156,7 +156,7 @@ function chunk(array, size) {
|
|
|
156
156
|
if (!Array.isArray(array)) return [];
|
|
157
157
|
if (array.length === 0) return [];
|
|
158
158
|
const { length } = array;
|
|
159
|
-
const actualSize = typeof size === "number" && size > 0 && size <=
|
|
159
|
+
const actualSize = typeof size === "number" && size > 0 && size <= CHUNK_MAX_SIZE ? size : CHUNK_MAX_SIZE;
|
|
160
160
|
if (length <= actualSize) return [array];
|
|
161
161
|
const chunks = [];
|
|
162
162
|
let index = 0;
|
|
@@ -166,7 +166,7 @@ function chunk(array, size) {
|
|
|
166
166
|
}
|
|
167
167
|
return chunks;
|
|
168
168
|
}
|
|
169
|
-
const
|
|
169
|
+
const CHUNK_MAX_SIZE = 5e3;
|
|
170
170
|
//#endregion
|
|
171
171
|
//#region src/internal/array/compact.ts
|
|
172
172
|
function compact(array, strict) {
|
|
@@ -181,15 +181,6 @@ function compact(array, strict) {
|
|
|
181
181
|
return compacted;
|
|
182
182
|
}
|
|
183
183
|
//#endregion
|
|
184
|
-
//#region src/internal/array/index-of.ts
|
|
185
|
-
function indexOf(array, ...parameters) {
|
|
186
|
-
return findValue(FIND_VALUE_INDEX, array, parameters, false);
|
|
187
|
-
}
|
|
188
|
-
indexOf.last = lastIndexOf;
|
|
189
|
-
function lastIndexOf(array, ...parameters) {
|
|
190
|
-
return findValue(FIND_VALUE_INDEX, array, parameters, true);
|
|
191
|
-
}
|
|
192
|
-
//#endregion
|
|
193
184
|
//#region src/internal/is.ts
|
|
194
185
|
/**
|
|
195
186
|
* Is the value an array or a plain object?
|
|
@@ -365,6 +356,89 @@ function isTypedArray(value) {
|
|
|
365
356
|
return isTypedArray.types.has(value?.constructor);
|
|
366
357
|
}
|
|
367
358
|
//#endregion
|
|
359
|
+
//#region src/internal/array/get.ts
|
|
360
|
+
function getArray(value, indiced) {
|
|
361
|
+
if (Array.isArray(value)) return value;
|
|
362
|
+
if (value instanceof Map) return [...value.entries()];
|
|
363
|
+
if (value instanceof Set) return [...value.values()];
|
|
364
|
+
if (isNonPlainObject(value)) return [value];
|
|
365
|
+
if (indiced !== true) return Object.entries(value);
|
|
366
|
+
const keys = Object.keys(value);
|
|
367
|
+
const { length } = keys;
|
|
368
|
+
const array = [];
|
|
369
|
+
for (let index = 0; index < length; index += 1) {
|
|
370
|
+
const key = keys[index];
|
|
371
|
+
const asNumber = Number.parseInt(key, 10);
|
|
372
|
+
if (!Number.isNaN(asNumber)) array[asNumber] = value[key];
|
|
373
|
+
}
|
|
374
|
+
return array;
|
|
375
|
+
}
|
|
376
|
+
//#endregion
|
|
377
|
+
//#region src/internal/array/index-of.ts
|
|
378
|
+
function indexOf(array, ...parameters) {
|
|
379
|
+
return findValue(FIND_VALUE_INDEX, array, parameters, false);
|
|
380
|
+
}
|
|
381
|
+
indexOf.last = lastIndexOf;
|
|
382
|
+
function lastIndexOf(array, ...parameters) {
|
|
383
|
+
return findValue(FIND_VALUE_INDEX, array, parameters, true);
|
|
384
|
+
}
|
|
385
|
+
//#endregion
|
|
386
|
+
//#region src/internal/array/match.ts
|
|
387
|
+
function endsWithArray(haystack, needle, key) {
|
|
388
|
+
return endings.has(getPosition(haystack, needle, key)[1]);
|
|
389
|
+
}
|
|
390
|
+
function getArrayComparison(haystack, needle, key) {
|
|
391
|
+
return getPosition(haystack, needle, key)[1];
|
|
392
|
+
}
|
|
393
|
+
function getName(start, haystack, needle) {
|
|
394
|
+
if (start === 0) return haystack === needle ? MATCH_COMPARISON_SAME : MATCH_COMPARISON_START;
|
|
395
|
+
return start + needle === haystack ? MATCH_COMPARISON_END : MATCH_COMPARISON_INSIDE;
|
|
396
|
+
}
|
|
397
|
+
function getPosition(haystack, needle, key) {
|
|
398
|
+
if (!Array.isArray(haystack) || !Array.isArray(needle)) return invalid;
|
|
399
|
+
const haystackLength = haystack.length;
|
|
400
|
+
const needleLength = needle.length;
|
|
401
|
+
if (haystackLength === 0 || needleLength === 0) return outside;
|
|
402
|
+
if (needleLength > haystackLength) return outside;
|
|
403
|
+
const callback = getArrayCallback(key);
|
|
404
|
+
const limit = haystackLength - needleLength + 1;
|
|
405
|
+
let needleValues = callback == null ? needle : needle.slice();
|
|
406
|
+
if (callback != null) for (let needleIndex = 0; needleIndex < needleLength; needleIndex += 1) needleValues[needleIndex] = callback(needle[needleIndex], needleIndex, needle);
|
|
407
|
+
for (let haystackIndex = 0; haystackIndex < limit; haystackIndex += 1) {
|
|
408
|
+
let haystackItem = haystack[haystackIndex];
|
|
409
|
+
let haystackValue = callback?.(haystackItem, haystackIndex, haystack) ?? haystackItem;
|
|
410
|
+
if (!Object.is(haystackValue, needleValues[0])) continue;
|
|
411
|
+
if (needleLength === 1) return [haystackIndex, getName(haystackIndex, haystackLength, needleLength)];
|
|
412
|
+
for (let needleIndex = 1; needleIndex < needleLength; needleIndex += 1) {
|
|
413
|
+
haystackItem = haystack[haystackIndex + needleIndex];
|
|
414
|
+
haystackValue = callback?.(haystackItem, haystackIndex + needleIndex, haystack) ?? haystackItem;
|
|
415
|
+
if (!Object.is(haystackValue, needleValues[needleIndex])) break;
|
|
416
|
+
if (needleIndex === needleLength - 1) return [haystackIndex, getName(haystackIndex, haystackLength, needleLength)];
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
return outside;
|
|
420
|
+
}
|
|
421
|
+
function includesArray(haystack, needle, key) {
|
|
422
|
+
return !outsides.has(getPosition(haystack, needle, key)[1]);
|
|
423
|
+
}
|
|
424
|
+
function indexOfArray(haystack, needle, key) {
|
|
425
|
+
return getPosition(haystack, needle, key)[0];
|
|
426
|
+
}
|
|
427
|
+
function startsWithArray(haystack, needle, key) {
|
|
428
|
+
return starts.has(getPosition(haystack, needle, key)[1]);
|
|
429
|
+
}
|
|
430
|
+
const MATCH_COMPARISON_END = "end";
|
|
431
|
+
const MATCH_COMPARISON_INSIDE = "inside";
|
|
432
|
+
const MATCH_COMPARISON_INVALID = "invalid";
|
|
433
|
+
const MATCH_COMPARISON_OUTSIDE = "outside";
|
|
434
|
+
const MATCH_COMPARISON_SAME = "same";
|
|
435
|
+
const MATCH_COMPARISON_START = "start";
|
|
436
|
+
const endings = /* @__PURE__ */ new Set([MATCH_COMPARISON_END, MATCH_COMPARISON_SAME]);
|
|
437
|
+
const invalid = [-1, MATCH_COMPARISON_INVALID];
|
|
438
|
+
const outside = [-1, MATCH_COMPARISON_OUTSIDE];
|
|
439
|
+
const outsides = /* @__PURE__ */ new Set([MATCH_COMPARISON_INVALID, MATCH_COMPARISON_OUTSIDE]);
|
|
440
|
+
const starts = /* @__PURE__ */ new Set([MATCH_COMPARISON_START, MATCH_COMPARISON_SAME]);
|
|
441
|
+
//#endregion
|
|
368
442
|
//#region src/internal/random.ts
|
|
369
443
|
function getRandomFloatingNumberValue(inclusive, minimum, maximum) {
|
|
370
444
|
let maxFloat = isNumber(maximum) && maximum <= Number.MAX_SAFE_INTEGER ? maximum : Number.MAX_SAFE_INTEGER;
|
|
@@ -416,9 +490,9 @@ function shuffle(array) {
|
|
|
416
490
|
//#region src/internal/array/sets.ts
|
|
417
491
|
function compareSets(type, first, second, key) {
|
|
418
492
|
if (!Array.isArray(first)) return [];
|
|
419
|
-
const isDifference = type ===
|
|
420
|
-
const isIntersection = type ===
|
|
421
|
-
const isUnion = type ===
|
|
493
|
+
const isDifference = type === SETS_COMPARE_DIFFERENCE;
|
|
494
|
+
const isIntersection = type === SETS_COMPARE_INTERSECTION;
|
|
495
|
+
const isUnion = type === SETS_COMPARE_UNION;
|
|
422
496
|
if (first.length === 0) return isDifference ? first.slice() : isIntersection ? [] : second.slice();
|
|
423
497
|
if (!Array.isArray(second) || second.length === 0) return isIntersection ? [] : first.slice();
|
|
424
498
|
const callback = getArrayCallback(key);
|
|
@@ -439,13 +513,13 @@ function compareSets(type, first, second, key) {
|
|
|
439
513
|
}
|
|
440
514
|
return result;
|
|
441
515
|
}
|
|
442
|
-
const
|
|
443
|
-
const
|
|
444
|
-
const
|
|
516
|
+
const SETS_COMPARE_DIFFERENCE = "difference";
|
|
517
|
+
const SETS_COMPARE_INTERSECTION = "intersection";
|
|
518
|
+
const SETS_COMPARE_UNION = "union";
|
|
445
519
|
//#endregion
|
|
446
520
|
//#region src/array/difference.ts
|
|
447
521
|
function difference(first, second, key) {
|
|
448
|
-
return compareSets(
|
|
522
|
+
return compareSets(SETS_COMPARE_DIFFERENCE, first, second, key);
|
|
449
523
|
}
|
|
450
524
|
//#endregion
|
|
451
525
|
//#region src/array/exists.ts
|
|
@@ -498,24 +572,6 @@ function times(length, value) {
|
|
|
498
572
|
return values;
|
|
499
573
|
}
|
|
500
574
|
//#endregion
|
|
501
|
-
//#region src/array/get.ts
|
|
502
|
-
function getArray(value, indiced) {
|
|
503
|
-
if (Array.isArray(value)) return value;
|
|
504
|
-
if (value instanceof Map) return [...value.entries()];
|
|
505
|
-
if (value instanceof Set) return [...value.values()];
|
|
506
|
-
if (isNonPlainObject(value)) return [value];
|
|
507
|
-
if (indiced !== true) return Object.entries(value);
|
|
508
|
-
const keys = Object.keys(value);
|
|
509
|
-
const { length } = keys;
|
|
510
|
-
const array = [];
|
|
511
|
-
for (let index = 0; index < length; index += 1) {
|
|
512
|
-
const key = keys[index];
|
|
513
|
-
const asNumber = Number.parseInt(key, 10);
|
|
514
|
-
if (!Number.isNaN(asNumber)) array[asNumber] = value[key];
|
|
515
|
-
}
|
|
516
|
-
return array;
|
|
517
|
-
}
|
|
518
|
-
//#endregion
|
|
519
575
|
//#region src/internal/array/insert.ts
|
|
520
576
|
function insertChunkedValues(type, array, items, start, deleteCount) {
|
|
521
577
|
const actualDeleteCount = deleteCount < 0 ? 0 : deleteCount;
|
|
@@ -549,7 +605,7 @@ function insert(array, indexOrItems, items) {
|
|
|
549
605
|
//#endregion
|
|
550
606
|
//#region src/array/intersection.ts
|
|
551
607
|
function intersection(first, second, key) {
|
|
552
|
-
return compareSets(
|
|
608
|
+
return compareSets(SETS_COMPARE_INTERSECTION, first, second, key);
|
|
553
609
|
}
|
|
554
610
|
//#endregion
|
|
555
611
|
//#region src/array/partition.ts
|
|
@@ -558,62 +614,6 @@ function partition(array, ...parameters) {
|
|
|
558
614
|
return [matched, notMatched];
|
|
559
615
|
}
|
|
560
616
|
//#endregion
|
|
561
|
-
//#region src/array/match.ts
|
|
562
|
-
function endsWithArray(haystack, needle, key) {
|
|
563
|
-
return endings.has(getPosition(haystack, needle, key)[1]);
|
|
564
|
-
}
|
|
565
|
-
function getArrayComparison(haystack, needle, key) {
|
|
566
|
-
return getPosition(haystack, needle, key)[1];
|
|
567
|
-
}
|
|
568
|
-
function getName(start, haystack, needle) {
|
|
569
|
-
if (start === 0) return haystack === needle ? COMPARISON_SAME : COMPARISON_START;
|
|
570
|
-
return start + needle === haystack ? COMPARISON_END : COMPARISON_INSIDE;
|
|
571
|
-
}
|
|
572
|
-
function getPosition(haystack, needle, key) {
|
|
573
|
-
if (!Array.isArray(haystack) || !Array.isArray(needle)) return invalid;
|
|
574
|
-
const haystackLength = haystack.length;
|
|
575
|
-
const needleLength = needle.length;
|
|
576
|
-
if (haystackLength === 0 || needleLength === 0) return outside;
|
|
577
|
-
if (needleLength > haystackLength) return outside;
|
|
578
|
-
const callback = getArrayCallback(key);
|
|
579
|
-
const limit = haystackLength - needleLength + 1;
|
|
580
|
-
let needleValues = callback == null ? needle : needle.slice();
|
|
581
|
-
if (callback != null) for (let needleIndex = 0; needleIndex < needleLength; needleIndex += 1) needleValues[needleIndex] = callback(needle[needleIndex], needleIndex, needle);
|
|
582
|
-
for (let haystackIndex = 0; haystackIndex < limit; haystackIndex += 1) {
|
|
583
|
-
let haystackItem = haystack[haystackIndex];
|
|
584
|
-
let haystackValue = callback?.(haystackItem, haystackIndex, haystack) ?? haystackItem;
|
|
585
|
-
if (!Object.is(haystackValue, needleValues[0])) continue;
|
|
586
|
-
if (needleLength === 1) return [haystackIndex, getName(haystackIndex, haystackLength, needleLength)];
|
|
587
|
-
for (let needleIndex = 1; needleIndex < needleLength; needleIndex += 1) {
|
|
588
|
-
haystackItem = haystack[haystackIndex + needleIndex];
|
|
589
|
-
haystackValue = callback?.(haystackItem, haystackIndex + needleIndex, haystack) ?? haystackItem;
|
|
590
|
-
if (!Object.is(haystackValue, needleValues[needleIndex])) break;
|
|
591
|
-
if (needleIndex === needleLength - 1) return [haystackIndex, getName(haystackIndex, haystackLength, needleLength)];
|
|
592
|
-
}
|
|
593
|
-
}
|
|
594
|
-
return outside;
|
|
595
|
-
}
|
|
596
|
-
function includesArray(haystack, needle, key) {
|
|
597
|
-
return !outsides.has(getPosition(haystack, needle, key)[1]);
|
|
598
|
-
}
|
|
599
|
-
function indexOfArray(haystack, needle, key) {
|
|
600
|
-
return getPosition(haystack, needle, key)[0];
|
|
601
|
-
}
|
|
602
|
-
function startsWithArray(haystack, needle, key) {
|
|
603
|
-
return starts.has(getPosition(haystack, needle, key)[1]);
|
|
604
|
-
}
|
|
605
|
-
const COMPARISON_END = "end";
|
|
606
|
-
const COMPARISON_INSIDE = "inside";
|
|
607
|
-
const COMPARISON_INVALID = "invalid";
|
|
608
|
-
const COMPARISON_OUTSIDE = "outside";
|
|
609
|
-
const COMPARISON_SAME = "same";
|
|
610
|
-
const COMPARISON_START = "start";
|
|
611
|
-
const endings = /* @__PURE__ */ new Set([COMPARISON_END, COMPARISON_SAME]);
|
|
612
|
-
const invalid = [-1, COMPARISON_INVALID];
|
|
613
|
-
const outside = [-1, COMPARISON_OUTSIDE];
|
|
614
|
-
const outsides = /* @__PURE__ */ new Set([COMPARISON_INVALID, COMPARISON_OUTSIDE]);
|
|
615
|
-
const starts = /* @__PURE__ */ new Set([COMPARISON_START, COMPARISON_SAME]);
|
|
616
|
-
//#endregion
|
|
617
617
|
//#region src/array/push.ts
|
|
618
618
|
/**
|
|
619
619
|
* Push items into an array _(at the end)_
|
|
@@ -669,13 +669,13 @@ const SINGLE_MESSAGE = "Multiple items were found";
|
|
|
669
669
|
//#endregion
|
|
670
670
|
//#region src/array/slice.ts
|
|
671
671
|
function drop(array, first, second) {
|
|
672
|
-
return extract(
|
|
672
|
+
return extract(SLICE_DROP, array, first, second);
|
|
673
673
|
}
|
|
674
674
|
function extract(type, array, first, second) {
|
|
675
675
|
if (!Array.isArray(array)) return [];
|
|
676
676
|
const { length } = array;
|
|
677
677
|
if (length === 0) return [];
|
|
678
|
-
const isTake = type ===
|
|
678
|
+
const isTake = type === SLICE_TAKE;
|
|
679
679
|
if (typeof first === "number") {
|
|
680
680
|
if (Math.abs(first) >= length) return isTake ? array.slice() : [];
|
|
681
681
|
if (first === 0) return isTake ? [] : array.slice();
|
|
@@ -713,10 +713,10 @@ function slice(array, first, second) {
|
|
|
713
713
|
return first >= 0 ? array.slice(first, second) : array.slice(array.length + first, array.length + second);
|
|
714
714
|
}
|
|
715
715
|
function take(array, first, second) {
|
|
716
|
-
return extract(
|
|
716
|
+
return extract(SLICE_TAKE, array, first, second);
|
|
717
717
|
}
|
|
718
|
-
const
|
|
719
|
-
const
|
|
718
|
+
const SLICE_DROP = "drop";
|
|
719
|
+
const SLICE_TAKE = "take";
|
|
720
720
|
//#endregion
|
|
721
721
|
//#region src/array/splice.ts
|
|
722
722
|
function splice(array, start, deleteCountOrItems, items) {
|
|
@@ -764,7 +764,7 @@ function toggle(array, values, key) {
|
|
|
764
764
|
//#endregion
|
|
765
765
|
//#region src/array/union.ts
|
|
766
766
|
function union(first, second, key) {
|
|
767
|
-
return compareSets(
|
|
767
|
+
return compareSets(SETS_COMPARE_UNION, first, second, key);
|
|
768
768
|
}
|
|
769
769
|
//#endregion
|
|
770
770
|
//#region src/array/unique.ts
|
|
@@ -927,7 +927,7 @@ const aggregators = {
|
|
|
927
927
|
sum: calculateSum
|
|
928
928
|
};
|
|
929
929
|
//#endregion
|
|
930
|
-
//#region src/internal/string.ts
|
|
930
|
+
//#region src/internal/string/misc.ts
|
|
931
931
|
/**
|
|
932
932
|
* Get the string value from any value
|
|
933
933
|
*
|
|
@@ -954,7 +954,7 @@ function getString(value) {
|
|
|
954
954
|
return asString.startsWith("[object ") ? JSON.stringify(value) : asString;
|
|
955
955
|
}
|
|
956
956
|
function ignoreKey(key) {
|
|
957
|
-
return
|
|
957
|
+
return STRING_EXPRESSION_IGNORED.test(key);
|
|
958
958
|
}
|
|
959
959
|
function interpolate(strings, values) {
|
|
960
960
|
const { length } = strings;
|
|
@@ -1005,10 +1005,10 @@ function tryEncode(value) {
|
|
|
1005
1005
|
* @returns Array of words found in the string
|
|
1006
1006
|
*/
|
|
1007
1007
|
function words(value) {
|
|
1008
|
-
return typeof value === "string" ? value.match(
|
|
1008
|
+
return typeof value === "string" ? value.match(STRING_EXPRESSION_WORDS) ?? [] : [];
|
|
1009
1009
|
}
|
|
1010
|
-
const
|
|
1011
|
-
const
|
|
1010
|
+
const STRING_EXPRESSION_IGNORED = /(^|\.)(__proto__|constructor|prototype)(\.|$)/i;
|
|
1011
|
+
const STRING_EXPRESSION_WORDS = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;
|
|
1012
1012
|
//#endregion
|
|
1013
1013
|
//#region src/internal/value/handlers.ts
|
|
1014
1014
|
function getCompareHandlers(owner, options) {
|
|
@@ -1236,8 +1236,10 @@ function getValueSorter(value, modifier) {
|
|
|
1236
1236
|
function initializeSorter(first, second) {
|
|
1237
1237
|
const sorters = getSorters(first, getModifier(first, second));
|
|
1238
1238
|
const sorter = (array) => sortArray(array, sorters);
|
|
1239
|
-
|
|
1240
|
-
|
|
1239
|
+
Object.defineProperties(sorter, {
|
|
1240
|
+
index: { value: (array, item) => getIndex(array, item, sorters) },
|
|
1241
|
+
is: { value: (array) => isSortedArray(array, sorters) }
|
|
1242
|
+
});
|
|
1241
1243
|
return sorter;
|
|
1242
1244
|
}
|
|
1243
1245
|
function isSorted(array, first, second) {
|
|
@@ -1379,70 +1381,204 @@ function toRecordArrays(array, first, second) {
|
|
|
1379
1381
|
return groupValues(array, first, second, true);
|
|
1380
1382
|
}
|
|
1381
1383
|
//#endregion
|
|
1382
|
-
//#region src/internal/
|
|
1383
|
-
function isError(value, extended) {
|
|
1384
|
-
return isResultValue(value, false) && (extended === true ? value.original instanceof Error : true);
|
|
1385
|
-
}
|
|
1386
|
-
function isOk(value) {
|
|
1387
|
-
return isResultValue(value, true);
|
|
1388
|
-
}
|
|
1384
|
+
//#region src/internal/function/misc.ts
|
|
1389
1385
|
/**
|
|
1390
|
-
*
|
|
1391
|
-
*
|
|
1392
|
-
* @param value Value to check
|
|
1393
|
-
* @returns `true` if the value is a _Result_, otherwise `false`
|
|
1386
|
+
* A function that does nothing, which can be useful, I guess…
|
|
1394
1387
|
*/
|
|
1395
|
-
function
|
|
1396
|
-
return isResultValue(value, true) || isResultValue(value, false);
|
|
1397
|
-
}
|
|
1398
|
-
function isResultValue(value, okValue) {
|
|
1399
|
-
if (isNonPlainObject(value)) return false;
|
|
1400
|
-
return value.ok === okValue && (okValue ? PROPERTY_VALUE : PROPERTY_ERROR) in value;
|
|
1401
|
-
}
|
|
1402
|
-
const PROPERTY_ERROR = "error";
|
|
1403
|
-
const PROPERTY_VALUE = "value";
|
|
1388
|
+
function noop() {}
|
|
1404
1389
|
//#endregion
|
|
1405
|
-
//#region src/
|
|
1406
|
-
function
|
|
1407
|
-
|
|
1390
|
+
//#region src/internal/function/timer.ts
|
|
1391
|
+
function getAsyncTimer(type, callback, time) {
|
|
1392
|
+
function cancel() {
|
|
1393
|
+
clearTimer(id);
|
|
1394
|
+
if (last != null && !last.running) {
|
|
1395
|
+
last.reject();
|
|
1396
|
+
last = void 0;
|
|
1397
|
+
}
|
|
1398
|
+
}
|
|
1399
|
+
async function run(item) {
|
|
1400
|
+
const now = performance.now();
|
|
1401
|
+
start ??= now;
|
|
1402
|
+
if (interval === 0 || now - start >= interval - TIMER_OFFSET) {
|
|
1403
|
+
start = throttle ? now : void 0;
|
|
1404
|
+
item.running = true;
|
|
1405
|
+
try {
|
|
1406
|
+
let result = callback(...item.parameters);
|
|
1407
|
+
if (result instanceof Promise) result = await result;
|
|
1408
|
+
item.resolve(result);
|
|
1409
|
+
} catch (error) {
|
|
1410
|
+
item.reject(error);
|
|
1411
|
+
} finally {
|
|
1412
|
+
item.running = false;
|
|
1413
|
+
}
|
|
1414
|
+
} else id = startTimer(() => run(item));
|
|
1415
|
+
}
|
|
1416
|
+
const interval = getInterval(time);
|
|
1417
|
+
const throttle = type === TIMER_THROTTLE;
|
|
1418
|
+
let id;
|
|
1419
|
+
let last;
|
|
1420
|
+
let start;
|
|
1421
|
+
const timer = (...parameters) => {
|
|
1422
|
+
cancel();
|
|
1423
|
+
const next = {
|
|
1424
|
+
parameters,
|
|
1425
|
+
running: false
|
|
1426
|
+
};
|
|
1427
|
+
next.promise = new Promise((resolve, reject) => {
|
|
1428
|
+
next.reject = reject;
|
|
1429
|
+
next.resolve = resolve;
|
|
1430
|
+
});
|
|
1431
|
+
last = next;
|
|
1432
|
+
if (throttle) run(next);
|
|
1433
|
+
else id = startTimer(() => run(next));
|
|
1434
|
+
return next.promise;
|
|
1435
|
+
};
|
|
1436
|
+
Object.defineProperty(timer, TIMER_CANCEL, { value: () => cancel() });
|
|
1437
|
+
return timer;
|
|
1408
1438
|
}
|
|
1409
|
-
function
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1439
|
+
function getInterval(value) {
|
|
1440
|
+
return typeof value === "number" && value > 0 ? value : 0;
|
|
1441
|
+
}
|
|
1442
|
+
function getTimer(type, callback, time) {
|
|
1443
|
+
function cancel() {
|
|
1444
|
+
clearTimer(id);
|
|
1445
|
+
}
|
|
1446
|
+
function run() {
|
|
1447
|
+
const now = performance.now();
|
|
1448
|
+
start ??= now;
|
|
1449
|
+
if (interval === 0 || now - start >= interval - TIMER_OFFSET) {
|
|
1450
|
+
start = throttle ? now : void 0;
|
|
1451
|
+
callback(...args);
|
|
1452
|
+
} else id = startTimer(run);
|
|
1453
|
+
}
|
|
1454
|
+
const interval = getInterval(time);
|
|
1455
|
+
const throttle = type === TIMER_THROTTLE;
|
|
1456
|
+
let args;
|
|
1457
|
+
let id;
|
|
1458
|
+
let start;
|
|
1459
|
+
const timer = (...parameters) => {
|
|
1460
|
+
cancel();
|
|
1461
|
+
args = parameters;
|
|
1462
|
+
if (throttle) run();
|
|
1463
|
+
else id = startTimer(run);
|
|
1413
1464
|
};
|
|
1414
|
-
|
|
1415
|
-
return
|
|
1465
|
+
Object.defineProperty(timer, TIMER_CANCEL, { value: () => cancel() });
|
|
1466
|
+
return timer;
|
|
1416
1467
|
}
|
|
1468
|
+
const TIMER_CANCEL = "cancel";
|
|
1469
|
+
const TIMER_DEBOUNCE = "debounce";
|
|
1470
|
+
const TIMER_OFFSET = 5;
|
|
1471
|
+
const TIMER_THROTTLE = "throttle";
|
|
1472
|
+
const TIMER_WAIT = "wait";
|
|
1473
|
+
// istanbul ignore next
|
|
1474
|
+
const clearTimer = typeof cancelAnimationFrame === "function" ? cancelAnimationFrame : clearTimeout;
|
|
1475
|
+
// istanbul ignore next
|
|
1476
|
+
const startTimer = typeof requestAnimationFrame === "function" ? requestAnimationFrame : setTimeout;
|
|
1477
|
+
//#endregion
|
|
1478
|
+
//#region src/function/limit.ts
|
|
1417
1479
|
/**
|
|
1418
|
-
*
|
|
1480
|
+
* Debounce a function, ensuring it is only called after `time` milliseconds have passed
|
|
1419
1481
|
*
|
|
1420
|
-
*
|
|
1421
|
-
*
|
|
1482
|
+
* - When called, successful _(finished)_ results will resolve and errors will reject
|
|
1483
|
+
* - On subsequent calls, existing calls will be canceled _(rejected)_, the timer reset, and will wait another `time` milliseconds before the new call is made _(and so on...)_
|
|
1484
|
+
*
|
|
1485
|
+
* _Available as `asyncDebounce` and `debounce.async`_
|
|
1486
|
+
*
|
|
1487
|
+
* @param callback Callback to debounce
|
|
1488
|
+
* @param time Time in milliseconds to wait before calling the callback _(defaults to `0`; e.g., as soon as possible)_
|
|
1489
|
+
* @returns Debounced callback handler with a `cancel` method
|
|
1422
1490
|
*/
|
|
1423
|
-
function
|
|
1424
|
-
return
|
|
1425
|
-
ok: true,
|
|
1426
|
-
value
|
|
1427
|
-
};
|
|
1491
|
+
function asyncDebounce(callback, time) {
|
|
1492
|
+
return getAsyncTimer(TIMER_DEBOUNCE, callback, time);
|
|
1428
1493
|
}
|
|
1429
1494
|
/**
|
|
1430
|
-
*
|
|
1495
|
+
* Throttle a function, ensuring it is only called once every `time` milliseconds
|
|
1431
1496
|
*
|
|
1432
|
-
*
|
|
1497
|
+
* - When called, successful _(finished)_ results will resolve and errors will reject
|
|
1498
|
+
* - On subsequent calls, existing calls will be canceled _(rejected)_ and will wait until the next valid time to call the callback again _(and so on...)_
|
|
1433
1499
|
*
|
|
1434
|
-
*
|
|
1435
|
-
*
|
|
1500
|
+
* _Available as `asyncThrottle` and `throttle.async`_
|
|
1501
|
+
*
|
|
1502
|
+
* @param callback Callback to throttle
|
|
1503
|
+
* @param time Time in milliseconds to wait before calling the callback again _(defaults to `0`; e.g., as soon as possible)_
|
|
1504
|
+
* @returns Throttled callback handler with a `cancel` method
|
|
1436
1505
|
*/
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1506
|
+
function asyncThrottle(callback, time) {
|
|
1507
|
+
return getAsyncTimer(TIMER_THROTTLE, callback, time);
|
|
1508
|
+
}
|
|
1509
|
+
/**
|
|
1510
|
+
* Debounce a function, ensuring it is only called after `time` milliseconds have passed
|
|
1511
|
+
*
|
|
1512
|
+
* On subsequent calls, the timer is reset and will wait another `time` milliseconds _(and so on...)_
|
|
1513
|
+
*
|
|
1514
|
+
* @param callback Callback to debounce
|
|
1515
|
+
* @param time Time in milliseconds to wait before calling the callback _(defaults to `0`; e.g., as soon as possible)_
|
|
1516
|
+
* @returns Debounced callback handler with a `cancel` method
|
|
1517
|
+
*/
|
|
1518
|
+
function debounce(callback, time) {
|
|
1519
|
+
return getTimer(TIMER_DEBOUNCE, callback, time);
|
|
1520
|
+
}
|
|
1521
|
+
/**
|
|
1522
|
+
* Throttle a function, ensuring it is only called once every `time` milliseconds
|
|
1523
|
+
*
|
|
1524
|
+
* @param callback Callback to throttle
|
|
1525
|
+
* @param time Time in milliseconds to wait before calling the callback again _(defaults to `0`; e.g., as soon as possible)_
|
|
1526
|
+
* @returns Throttled callback handler with a `cancel` method
|
|
1527
|
+
*/
|
|
1528
|
+
function throttle(callback, time) {
|
|
1529
|
+
return getTimer(TIMER_THROTTLE, callback, time);
|
|
1530
|
+
}
|
|
1531
|
+
Object.defineProperty(debounce, "async", { value: asyncDebounce });
|
|
1532
|
+
Object.defineProperty(throttle, "async", { value: asyncThrottle });
|
|
1533
|
+
//#endregion
|
|
1534
|
+
//#region src/internal/result/misc.ts
|
|
1535
|
+
function error(value, original) {
|
|
1536
|
+
return getError(value, original);
|
|
1537
|
+
}
|
|
1538
|
+
function getError(value, original) {
|
|
1539
|
+
const errorResult = {
|
|
1540
|
+
error: value,
|
|
1541
|
+
ok: false
|
|
1542
|
+
};
|
|
1543
|
+
if (original instanceof Error) errorResult.original = original;
|
|
1544
|
+
return errorResult;
|
|
1545
|
+
}
|
|
1546
|
+
function isError(value, extended) {
|
|
1547
|
+
return isResultValue(value, false) && (extended === true ? value.original instanceof Error : true);
|
|
1548
|
+
}
|
|
1549
|
+
function isOk(value) {
|
|
1550
|
+
return isResultValue(value, true);
|
|
1551
|
+
}
|
|
1552
|
+
/**
|
|
1553
|
+
* Is the value a _Result_?
|
|
1554
|
+
*
|
|
1555
|
+
* @param value Value to check
|
|
1556
|
+
* @returns `true` if the value is a _Result_, otherwise `false`
|
|
1557
|
+
*/
|
|
1558
|
+
function isResult(value) {
|
|
1559
|
+
return isResultValue(value, true) || isResultValue(value, false);
|
|
1560
|
+
}
|
|
1561
|
+
function isResultValue(value, okValue) {
|
|
1562
|
+
if (isNonPlainObject(value)) return false;
|
|
1563
|
+
return value.ok === okValue && (okValue ? RESULT_PROPERTY_VALUE : RESULT_PROPERTY_ERROR) in value;
|
|
1564
|
+
}
|
|
1565
|
+
/**
|
|
1566
|
+
* Creates an ok result
|
|
1567
|
+
*
|
|
1568
|
+
* @param value Value
|
|
1569
|
+
* @returns Ok result
|
|
1570
|
+
*/
|
|
1571
|
+
function ok(value) {
|
|
1572
|
+
return {
|
|
1573
|
+
ok: true,
|
|
1574
|
+
value
|
|
1575
|
+
};
|
|
1441
1576
|
}
|
|
1442
1577
|
function unwrap(value, defaultValue) {
|
|
1443
1578
|
return isOk(value) ? value.value : defaultValue;
|
|
1444
1579
|
}
|
|
1445
|
-
const
|
|
1580
|
+
const RESULT_PROPERTY_ERROR = "error";
|
|
1581
|
+
const RESULT_PROPERTY_VALUE = "value";
|
|
1446
1582
|
//#endregion
|
|
1447
1583
|
//#region src/internal/value/misc.ts
|
|
1448
1584
|
function findKey(needle, haystack) {
|
|
@@ -1451,8 +1587,8 @@ function findKey(needle, haystack) {
|
|
|
1451
1587
|
return index > -1 ? keys[index] : needle;
|
|
1452
1588
|
}
|
|
1453
1589
|
function getNestedValue(data, path, ignoreCase) {
|
|
1454
|
-
if (typeof data !== "object" || data === null) return error(
|
|
1455
|
-
if (typeof path !== "string" || path.trim().length === 0) return error(
|
|
1590
|
+
if (typeof data !== "object" || data === null) return error(MISC_NESTED_MESSAGE_INPUT);
|
|
1591
|
+
if (typeof path !== "string" || path.trim().length === 0) return error(MISC_NESTED_MESSAGE_PATH);
|
|
1456
1592
|
const shouldIgnoreCase = ignoreCase === true;
|
|
1457
1593
|
const paths = getPaths(path, shouldIgnoreCase);
|
|
1458
1594
|
if (typeof paths === "string") return handleValue(data, paths, null, true, shouldIgnoreCase);
|
|
@@ -1468,25 +1604,25 @@ function getNestedValue(data, path, ignoreCase) {
|
|
|
1468
1604
|
}
|
|
1469
1605
|
function getPaths(path, lowercase) {
|
|
1470
1606
|
const normalized = lowercase ? path.toLowerCase() : path;
|
|
1471
|
-
if (!
|
|
1472
|
-
return normalized.replace(
|
|
1607
|
+
if (!MISC_EXPRESSION_NESTED.test(normalized)) return normalized;
|
|
1608
|
+
return normalized.replace(MISC_EXPRESSION_BRACKET, ".$1").replace(MISC_EXPRESSION_DOTS, "").split(".");
|
|
1473
1609
|
}
|
|
1474
1610
|
function handleValue(data, path, value, get, ignoreCase) {
|
|
1475
1611
|
if (typeof data === "object" && data !== null) {
|
|
1476
|
-
if (ignoreKey(path)) return error(
|
|
1612
|
+
if (ignoreKey(path)) return error(MISC_NESTED_MESSAGE_UNSAFE);
|
|
1477
1613
|
const key = ignoreCase ? findKey(path, data) : path;
|
|
1478
|
-
if (get) return key in data ? ok(data[key]) : error(
|
|
1614
|
+
if (get) return key in data ? ok(data[key]) : error(MISC_NESTED_MESSAGE_MISSING);
|
|
1479
1615
|
data[key] = typeof value === "function" ? value(data[key]) : value;
|
|
1480
1616
|
}
|
|
1481
|
-
if (get) return error(
|
|
1617
|
+
if (get) return error(MISC_NESTED_MESSAGE_MISSING);
|
|
1482
1618
|
}
|
|
1483
|
-
const
|
|
1484
|
-
const
|
|
1485
|
-
const
|
|
1486
|
-
const
|
|
1487
|
-
const
|
|
1488
|
-
const
|
|
1489
|
-
const
|
|
1619
|
+
const MISC_EXPRESSION_BRACKET = /\[(\w+)\]/g;
|
|
1620
|
+
const MISC_EXPRESSION_DOTS = /^\.|\.$/g;
|
|
1621
|
+
const MISC_EXPRESSION_NESTED = /\.|\[\w+\]/;
|
|
1622
|
+
const MISC_NESTED_MESSAGE_INPUT = "Expected data to be an object";
|
|
1623
|
+
const MISC_NESTED_MESSAGE_MISSING = "Expected property to exist in object";
|
|
1624
|
+
const MISC_NESTED_MESSAGE_PATH = "Expected path to be a string";
|
|
1625
|
+
const MISC_NESTED_MESSAGE_UNSAFE = "Access to this property is not allowed";
|
|
1490
1626
|
//#endregion
|
|
1491
1627
|
//#region src/internal/value/has.ts
|
|
1492
1628
|
function hasValue(data, path, ignoreCase) {
|
|
@@ -1497,7 +1633,7 @@ function hasValueResult(data, path, ignoreCase) {
|
|
|
1497
1633
|
return getNestedValue(data, path, ignoreCase === true);
|
|
1498
1634
|
}
|
|
1499
1635
|
//#endregion
|
|
1500
|
-
//#region src/function/assert.ts
|
|
1636
|
+
//#region src/internal/function/assert.ts
|
|
1501
1637
|
/**
|
|
1502
1638
|
* Asserts that a condition is true, throwing an error if it is not
|
|
1503
1639
|
*
|
|
@@ -1538,7 +1674,7 @@ function assertCondition(condition, message, error) {
|
|
|
1538
1674
|
* @param error Error constructor _(defaults to `Error`)_
|
|
1539
1675
|
*/
|
|
1540
1676
|
function assertDefined(value, message, error) {
|
|
1541
|
-
assert(() => value != null, message ??
|
|
1677
|
+
assert(() => value != null, message ?? ASSERT_MESSAGE_VALUE_DEFINED, error);
|
|
1542
1678
|
}
|
|
1543
1679
|
/**
|
|
1544
1680
|
* Creates an _Asserter_ that asserts a value is an instance of a constructor, throwing an error if it is not
|
|
@@ -1589,108 +1725,363 @@ function assertProperty(path, condition, message, error) {
|
|
|
1589
1725
|
}, message, error);
|
|
1590
1726
|
};
|
|
1591
1727
|
}
|
|
1592
|
-
const
|
|
1593
|
-
//#endregion
|
|
1594
|
-
//#region src/internal/function/misc.ts
|
|
1595
|
-
/**
|
|
1596
|
-
* A function that does nothing, which can be useful, I guess…
|
|
1597
|
-
*/
|
|
1598
|
-
function noop() {}
|
|
1728
|
+
const ASSERT_MESSAGE_VALUE_DEFINED = "Expected value to be defined";
|
|
1599
1729
|
//#endregion
|
|
1600
|
-
//#region src/
|
|
1601
|
-
/**
|
|
1602
|
-
* Is the number between a minimum and maximum value?
|
|
1603
|
-
*
|
|
1604
|
-
* @param value Value to check
|
|
1605
|
-
* @param minimum Minimum value
|
|
1606
|
-
* @param maximum Maximum value
|
|
1607
|
-
* @returns `true` if the value is between the minimum and maximum, otherwise `false`
|
|
1608
|
-
*/
|
|
1609
|
-
function between(value, minimum, maximum) {
|
|
1610
|
-
if (![
|
|
1611
|
-
value,
|
|
1612
|
-
minimum,
|
|
1613
|
-
maximum
|
|
1614
|
-
].every(isNumber)) return false;
|
|
1615
|
-
if (Object.is(minimum, maximum)) return Object.is(value, minimum);
|
|
1616
|
-
return value >= (maximum > minimum ? minimum : maximum) && value <= (maximum > minimum ? maximum : minimum);
|
|
1617
|
-
}
|
|
1730
|
+
//#region src/function/once.ts
|
|
1618
1731
|
/**
|
|
1619
|
-
*
|
|
1732
|
+
* Create an asynchronous function that can only be called once, rejecting or resolving the same result on subsequent calls
|
|
1620
1733
|
*
|
|
1621
|
-
*
|
|
1622
|
-
* @param minimum Minimum value
|
|
1623
|
-
* @param maximum Maximum value
|
|
1624
|
-
* @param loop If `true`, the value will loop around when smaller than the minimum or larger than the maximum _(defaults to `false`)_
|
|
1625
|
-
* @returns Clamped value
|
|
1734
|
+
* _Available as `asyncOnce` and `once.async`_
|
|
1626
1735
|
*
|
|
1627
|
-
* @
|
|
1628
|
-
*
|
|
1629
|
-
* clamp(10, 0, 5); // => 5
|
|
1630
|
-
* clamp(10, 0, 5, true); // => 0
|
|
1631
|
-
* ```
|
|
1736
|
+
* @param callback Callback to use once
|
|
1737
|
+
* @returns _Once_ callback
|
|
1632
1738
|
*/
|
|
1633
|
-
function
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1739
|
+
function asyncOnce(callback) {
|
|
1740
|
+
assert(() => typeof callback === "function", ONCE_MESSAGE_EXPECTATION);
|
|
1741
|
+
const state = {
|
|
1742
|
+
called: false,
|
|
1743
|
+
cleared: false,
|
|
1744
|
+
error: false,
|
|
1745
|
+
finished: false,
|
|
1746
|
+
items: [],
|
|
1747
|
+
value: void 0
|
|
1748
|
+
};
|
|
1749
|
+
const fn = (...parameters) => {
|
|
1750
|
+
if (state.cleared) return Promise.reject(new Error(ONCE_MESSAGE_CLEARED));
|
|
1751
|
+
if (state.finished) return state.error ? Promise.reject(state.value) : Promise.resolve(state.value);
|
|
1752
|
+
if (state.called) return new Promise((resolve, reject) => {
|
|
1753
|
+
state.items.push({
|
|
1754
|
+
reject,
|
|
1755
|
+
resolve
|
|
1756
|
+
});
|
|
1757
|
+
});
|
|
1758
|
+
state.called = true;
|
|
1759
|
+
return new Promise((resolve, reject) => {
|
|
1760
|
+
state.items.push({
|
|
1761
|
+
reject,
|
|
1762
|
+
resolve
|
|
1763
|
+
});
|
|
1764
|
+
callback(...parameters).then((value) => {
|
|
1765
|
+
handleOnceResult(state, value, false);
|
|
1766
|
+
}).catch((error) => {
|
|
1767
|
+
handleOnceResult(state, error, true);
|
|
1768
|
+
});
|
|
1769
|
+
});
|
|
1770
|
+
};
|
|
1771
|
+
Object.defineProperties(fn, {
|
|
1772
|
+
called: {
|
|
1773
|
+
enumerable: true,
|
|
1774
|
+
get: () => state.called
|
|
1775
|
+
},
|
|
1776
|
+
clear: { value: () => clearState(state) },
|
|
1777
|
+
cleared: {
|
|
1778
|
+
enumerable: true,
|
|
1779
|
+
get: () => state.cleared
|
|
1780
|
+
},
|
|
1781
|
+
error: {
|
|
1782
|
+
enumerable: true,
|
|
1783
|
+
get: () => state.error
|
|
1784
|
+
},
|
|
1785
|
+
finished: {
|
|
1786
|
+
enumerable: true,
|
|
1787
|
+
get: () => state.finished
|
|
1788
|
+
}
|
|
1789
|
+
});
|
|
1790
|
+
return fn;
|
|
1791
|
+
}
|
|
1792
|
+
function clearState(state) {
|
|
1793
|
+
if (!state.called || state.cleared) return;
|
|
1794
|
+
state.cleared = true;
|
|
1795
|
+
state.value = void 0;
|
|
1796
|
+
}
|
|
1797
|
+
function handleOnceResult(state, value, error) {
|
|
1798
|
+
state.error = error;
|
|
1799
|
+
state.finished = true;
|
|
1800
|
+
state.value = value;
|
|
1801
|
+
const items = state.items.splice(0);
|
|
1802
|
+
const { length } = items;
|
|
1803
|
+
for (let index = 0; index < length; index += 1) {
|
|
1804
|
+
const { reject, resolve } = items[index];
|
|
1805
|
+
if (error) reject(value);
|
|
1806
|
+
else resolve(value);
|
|
1807
|
+
}
|
|
1641
1808
|
}
|
|
1642
1809
|
/**
|
|
1643
|
-
*
|
|
1644
|
-
*
|
|
1645
|
-
* _(Based on Lodash)_
|
|
1810
|
+
* Create a function that can only be called once, returning the same value on subsequent calls
|
|
1646
1811
|
*
|
|
1647
|
-
* @param
|
|
1648
|
-
* @returns
|
|
1812
|
+
* @param callback Callback to use once
|
|
1813
|
+
* @returns _Once_ callback
|
|
1649
1814
|
*/
|
|
1650
|
-
function
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
if (typeof first === "number") actual = first;
|
|
1677
|
-
else actual = typeof second === "number" ? second : MAXIMUM_DEFAULT;
|
|
1678
|
-
return clamp(actual, 1, MAXIMUM_ABSOLUTE);
|
|
1815
|
+
function once(callback) {
|
|
1816
|
+
assert(() => typeof callback === "function", ONCE_MESSAGE_EXPECTATION);
|
|
1817
|
+
const state = {
|
|
1818
|
+
called: false,
|
|
1819
|
+
cleared: false,
|
|
1820
|
+
value: void 0
|
|
1821
|
+
};
|
|
1822
|
+
const fn = (...parameters) => {
|
|
1823
|
+
if (state.cleared) throw new Error(ONCE_MESSAGE_CLEARED);
|
|
1824
|
+
if (state.called) return state.value;
|
|
1825
|
+
state.called = true;
|
|
1826
|
+
state.value = callback(...parameters);
|
|
1827
|
+
return state.value;
|
|
1828
|
+
};
|
|
1829
|
+
Object.defineProperties(fn, {
|
|
1830
|
+
called: {
|
|
1831
|
+
enumerable: true,
|
|
1832
|
+
get: () => state.called
|
|
1833
|
+
},
|
|
1834
|
+
clear: { value: () => clearState(state) },
|
|
1835
|
+
cleared: {
|
|
1836
|
+
enumerable: true,
|
|
1837
|
+
get: () => state.cleared
|
|
1838
|
+
}
|
|
1839
|
+
});
|
|
1840
|
+
return fn;
|
|
1679
1841
|
}
|
|
1680
|
-
const
|
|
1681
|
-
const
|
|
1842
|
+
const ONCE_MESSAGE_CLEARED = "Once has been cleared";
|
|
1843
|
+
const ONCE_MESSAGE_EXPECTATION = "Once expected a function";
|
|
1844
|
+
Object.defineProperty(once, "async", { value: asyncOnce });
|
|
1682
1845
|
//#endregion
|
|
1683
|
-
//#region src/
|
|
1846
|
+
//#region src/function/retry.ts
|
|
1684
1847
|
/**
|
|
1685
|
-
*
|
|
1686
|
-
*
|
|
1687
|
-
* Behavior is similar to a _LRU_ cache, where the least recently used entries are removed
|
|
1848
|
+
* An error thrown when a retry fails
|
|
1688
1849
|
*/
|
|
1689
|
-
var
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1850
|
+
var RetryError = class extends Error {
|
|
1851
|
+
original;
|
|
1852
|
+
constructor(message, original) {
|
|
1853
|
+
super(message);
|
|
1854
|
+
this.original = original;
|
|
1855
|
+
this.name = RETRY_ERROR_NAME;
|
|
1856
|
+
}
|
|
1857
|
+
};
|
|
1858
|
+
/**
|
|
1859
|
+
* Retry a callback a specified number of times, with a delay between attempts
|
|
1860
|
+
*
|
|
1861
|
+
* _Available as `asyncRetry` and `retry.async`_
|
|
1862
|
+
*
|
|
1863
|
+
* @param callback Callback to retry
|
|
1864
|
+
* @param options Retry options
|
|
1865
|
+
* @returns Callback result
|
|
1866
|
+
*/
|
|
1867
|
+
async function asyncRetry(callback, options) {
|
|
1868
|
+
if (typeof callback !== "function") throw new TypeError(RETRY_MESSAGE_EXPECTATION);
|
|
1869
|
+
async function handle() {
|
|
1870
|
+
try {
|
|
1871
|
+
const result = await callback();
|
|
1872
|
+
resolver(result);
|
|
1873
|
+
} catch (error) {
|
|
1874
|
+
if (attempts >= times || !when(error)) rejector(new RetryError(RETRY_MESSAGE_FAILED, error));
|
|
1875
|
+
else {
|
|
1876
|
+
attempts += 1;
|
|
1877
|
+
timer();
|
|
1878
|
+
}
|
|
1879
|
+
}
|
|
1880
|
+
}
|
|
1881
|
+
const { delay, times, when } = getRetryOptions(options);
|
|
1882
|
+
const timer = getTimer(TIMER_WAIT, handle, delay);
|
|
1883
|
+
let attempts = 0;
|
|
1884
|
+
let rejector;
|
|
1885
|
+
let resolver;
|
|
1886
|
+
return new Promise((resolve, reject) => {
|
|
1887
|
+
rejector = reject;
|
|
1888
|
+
resolver = resolve;
|
|
1889
|
+
handle();
|
|
1890
|
+
});
|
|
1891
|
+
}
|
|
1892
|
+
function getRetryNumber(value) {
|
|
1893
|
+
return typeof value === "number" && value > 0 ? value : 0;
|
|
1894
|
+
}
|
|
1895
|
+
function getRetryOptions(input) {
|
|
1896
|
+
const options = isPlainObject(input) ? input : {};
|
|
1897
|
+
return {
|
|
1898
|
+
delay: getRetryNumber(options.delay),
|
|
1899
|
+
times: getRetryNumber(options.times),
|
|
1900
|
+
when: typeof options.when === "function" ? options.when : shouldRetry
|
|
1901
|
+
};
|
|
1902
|
+
}
|
|
1903
|
+
/**
|
|
1904
|
+
* Retry a callback a specified number of times
|
|
1905
|
+
*
|
|
1906
|
+
* @param callback Callback to retry
|
|
1907
|
+
* @param options Retry options
|
|
1908
|
+
* @returns Callback result
|
|
1909
|
+
*/
|
|
1910
|
+
function retry(callback, options) {
|
|
1911
|
+
if (typeof callback !== "function") throw new TypeError(RETRY_MESSAGE_EXPECTATION);
|
|
1912
|
+
const { times, when } = getRetryOptions(options);
|
|
1913
|
+
let last;
|
|
1914
|
+
for (let index = 0; index <= times; index += 1) try {
|
|
1915
|
+
return callback();
|
|
1916
|
+
} catch (error) {
|
|
1917
|
+
if (index >= times || !when(error)) {
|
|
1918
|
+
last = error;
|
|
1919
|
+
break;
|
|
1920
|
+
}
|
|
1921
|
+
}
|
|
1922
|
+
throw new RetryError(RETRY_MESSAGE_FAILED, last);
|
|
1923
|
+
}
|
|
1924
|
+
function shouldRetry() {
|
|
1925
|
+
return true;
|
|
1926
|
+
}
|
|
1927
|
+
const RETRY_ERROR_NAME = "RetryError";
|
|
1928
|
+
const RETRY_MESSAGE_EXPECTATION = "Retry expected a function";
|
|
1929
|
+
const RETRY_MESSAGE_FAILED = "Retry failed";
|
|
1930
|
+
Object.defineProperty(retry, "async", { value: asyncRetry });
|
|
1931
|
+
//#endregion
|
|
1932
|
+
//#region src/internal/function/work.ts
|
|
1933
|
+
function asyncFlow(...fns) {
|
|
1934
|
+
assertFlowFunctions(fns);
|
|
1935
|
+
return (...args) => asyncWork(args.map((value) => {
|
|
1936
|
+
if (isError(value)) throw value.error;
|
|
1937
|
+
return isOk(value) ? value.value : value;
|
|
1938
|
+
}), fns, true);
|
|
1939
|
+
}
|
|
1940
|
+
function flow(...fns) {
|
|
1941
|
+
assertFlowFunctions(fns);
|
|
1942
|
+
return (...args) => work(args.map((value) => {
|
|
1943
|
+
if (isError(value)) throw value.error;
|
|
1944
|
+
return isOk(value) ? value.value : value;
|
|
1945
|
+
}), fns, true);
|
|
1946
|
+
}
|
|
1947
|
+
async function asyncPipe(value, ...pipes) {
|
|
1948
|
+
assertPipeFunctions(pipes);
|
|
1949
|
+
return asyncWork(value, pipes, false);
|
|
1950
|
+
}
|
|
1951
|
+
function pipe(value, ...pipes) {
|
|
1952
|
+
assertPipeFunctions(pipes);
|
|
1953
|
+
return work(value, pipes, false);
|
|
1954
|
+
}
|
|
1955
|
+
async function asyncWork(initial, functions, flow) {
|
|
1956
|
+
const { length } = functions;
|
|
1957
|
+
let transformed = unwrapValue(initial);
|
|
1958
|
+
for (let index = 0; index < length; index += 1) {
|
|
1959
|
+
const fn = functions[index];
|
|
1960
|
+
transformed = unwrapValue(flow && index === 0 && Array.isArray(initial) ? await fn(...initial) : await fn(transformed));
|
|
1961
|
+
}
|
|
1962
|
+
return transformed;
|
|
1963
|
+
}
|
|
1964
|
+
function unwrapValue(value, flow, nested) {
|
|
1965
|
+
if (typeof value === "function") {
|
|
1966
|
+
if (nested != null) throw new TypeError(WORK_MESSAGE_NESTING);
|
|
1967
|
+
return unwrapValue(value(), flow, true);
|
|
1968
|
+
}
|
|
1969
|
+
if (flow != null && value instanceof Promise) throw new TypeError(flow ? WORK_MESSAGE_FLOW_PROMISE : WORK_MESSAGE_PIPE_PROMISE);
|
|
1970
|
+
if (isError(value)) throw value.error;
|
|
1971
|
+
return isOk(value) ? value.value : value;
|
|
1972
|
+
}
|
|
1973
|
+
function work(initial, functions, flow) {
|
|
1974
|
+
const { length } = functions;
|
|
1975
|
+
let transformed = unwrapValue(initial, flow);
|
|
1976
|
+
for (let index = 0; index < length; index += 1) {
|
|
1977
|
+
const fn = functions[index];
|
|
1978
|
+
transformed = unwrapValue(flow && index === 0 && Array.isArray(initial) ? fn(...initial) : fn(transformed), flow);
|
|
1979
|
+
}
|
|
1980
|
+
return transformed;
|
|
1981
|
+
}
|
|
1982
|
+
const WORK_MESSAGE_FLOW_ARRAY = "Flow expected to receive an array of functions";
|
|
1983
|
+
const WORK_MESSAGE_FLOW_PROMISE = "Synchronous Flow received a promise. Use `flow.async` instead.";
|
|
1984
|
+
const WORK_MESSAGE_NESTING = "Return values are too deeply nested.";
|
|
1985
|
+
const WORK_MESSAGE_PIPE_ARRAY = "Pipe expected to receive an array of functions";
|
|
1986
|
+
const WORK_MESSAGE_PIPE_PROMISE = "Synchronous Pipe received a promise. Use `pipe.async` instead.";
|
|
1987
|
+
const assertFlowFunctions = assert.condition((value) => Array.isArray(value) && value.every((item) => typeof item === "function"), WORK_MESSAGE_FLOW_ARRAY, TypeError);
|
|
1988
|
+
const assertPipeFunctions = assert.condition((value) => Array.isArray(value) && value.every((item) => typeof item === "function"), WORK_MESSAGE_PIPE_ARRAY, TypeError);
|
|
1989
|
+
flow.async = asyncFlow;
|
|
1990
|
+
pipe.async = asyncPipe;
|
|
1991
|
+
Object.defineProperty(flow, "async", { value: asyncFlow });
|
|
1992
|
+
Object.defineProperty(pipe, "async", { value: asyncPipe });
|
|
1993
|
+
//#endregion
|
|
1994
|
+
//#region src/internal/number.ts
|
|
1995
|
+
/**
|
|
1996
|
+
* Is the number between a minimum and maximum value?
|
|
1997
|
+
*
|
|
1998
|
+
* @param value Value to check
|
|
1999
|
+
* @param minimum Minimum value
|
|
2000
|
+
* @param maximum Maximum value
|
|
2001
|
+
* @returns `true` if the value is between the minimum and maximum, otherwise `false`
|
|
2002
|
+
*/
|
|
2003
|
+
function between(value, minimum, maximum) {
|
|
2004
|
+
if (![
|
|
2005
|
+
value,
|
|
2006
|
+
minimum,
|
|
2007
|
+
maximum
|
|
2008
|
+
].every(isNumber)) return false;
|
|
2009
|
+
if (Object.is(minimum, maximum)) return Object.is(value, minimum);
|
|
2010
|
+
return value >= (maximum > minimum ? minimum : maximum) && value <= (maximum > minimum ? maximum : minimum);
|
|
2011
|
+
}
|
|
2012
|
+
/**
|
|
2013
|
+
* Clamp a number between a minimum and maximum value
|
|
2014
|
+
*
|
|
2015
|
+
* @param value Value to clamp
|
|
2016
|
+
* @param minimum Minimum value
|
|
2017
|
+
* @param maximum Maximum value
|
|
2018
|
+
* @param loop If `true`, the value will loop around when smaller than the minimum or larger than the maximum _(defaults to `false`)_
|
|
2019
|
+
* @returns Clamped value
|
|
2020
|
+
*
|
|
2021
|
+
* @example
|
|
2022
|
+
* ```typescript
|
|
2023
|
+
* clamp(10, 0, 5); // => 5
|
|
2024
|
+
* clamp(10, 0, 5, true); // => 0
|
|
2025
|
+
* ```
|
|
2026
|
+
*/
|
|
2027
|
+
function clamp(value, minimum, maximum, loop) {
|
|
2028
|
+
if (![
|
|
2029
|
+
value,
|
|
2030
|
+
minimum,
|
|
2031
|
+
maximum
|
|
2032
|
+
].every(isNumber)) return NaN;
|
|
2033
|
+
if (value < minimum) return loop === true ? maximum : minimum;
|
|
2034
|
+
return value > maximum ? loop === true ? minimum : maximum : value;
|
|
2035
|
+
}
|
|
2036
|
+
/**
|
|
2037
|
+
* Get the number value from an unknown value
|
|
2038
|
+
*
|
|
2039
|
+
* _(Based on Lodash)_
|
|
2040
|
+
*
|
|
2041
|
+
* @param value Original value
|
|
2042
|
+
* @returns Original value as a number, or `Number.NaN` if the value is unable to be parsed
|
|
2043
|
+
*/
|
|
2044
|
+
function getNumber(value) {
|
|
2045
|
+
if (typeof value === "number") return value;
|
|
2046
|
+
if (typeof value === "bigint" || typeof value === "boolean") return Number(value);
|
|
2047
|
+
if (value == null || typeof value === "symbol") return NaN;
|
|
2048
|
+
if (typeof value === "function") return getNumber(value());
|
|
2049
|
+
let parsed = value.valueOf();
|
|
2050
|
+
if (typeof parsed === "object") parsed = parsed.toString();
|
|
2051
|
+
if (typeof parsed !== "string") return getNumber(parsed);
|
|
2052
|
+
const trimmed = parsed.trim();
|
|
2053
|
+
if (trimmed.length === 0) return NaN;
|
|
2054
|
+
if (NUMBER_EXPRESSION_ZEROISH.test(parsed)) return 0;
|
|
2055
|
+
const isBinary = NUMBER_EXPRESSION_BINARY.test(trimmed);
|
|
2056
|
+
if (isBinary || NUMBER_EXPRESSION_OCTAL.test(trimmed)) return Number.parseInt(trimmed.slice(2), isBinary ? 2 : NUMBER_OCTAL_VALUE);
|
|
2057
|
+
return Number(trimmed);
|
|
2058
|
+
}
|
|
2059
|
+
const NUMBER_EXPRESSION_BINARY = /^0b[01]+$/i;
|
|
2060
|
+
const NUMBER_EXPRESSION_OCTAL = /^0o[0-7]+$/i;
|
|
2061
|
+
const NUMBER_EXPRESSION_ZEROISH = /^\s*0+\s*$/;
|
|
2062
|
+
const NUMBER_OCTAL_VALUE = 8;
|
|
2063
|
+
//#endregion
|
|
2064
|
+
//#region src/internal/sized/misc.ts
|
|
2065
|
+
function getSizedMaximum(first, second) {
|
|
2066
|
+
let actual;
|
|
2067
|
+
if (typeof first === "number") actual = first;
|
|
2068
|
+
else actual = typeof second === "number" ? second : SIZED_MAXIMUM_DEFAULT;
|
|
2069
|
+
return clamp(actual, 1, SIZED_MAXIMUM_ABSOLUTE);
|
|
2070
|
+
}
|
|
2071
|
+
const SIZED_MAXIMUM_ABSOLUTE = 16777216;
|
|
2072
|
+
const SIZED_MAXIMUM_DEFAULT = 1048576;
|
|
2073
|
+
//#endregion
|
|
2074
|
+
//#region src/internal/sized/map.ts
|
|
2075
|
+
/**
|
|
2076
|
+
* A _Map_ with a maximum size
|
|
2077
|
+
*
|
|
2078
|
+
* Behavior is similar to a _LRU_ cache, where the least recently used entries are removed
|
|
2079
|
+
*/
|
|
2080
|
+
var SizedMap = class extends Map {
|
|
2081
|
+
/**
|
|
2082
|
+
* The maximum size of the _Map_
|
|
2083
|
+
*/
|
|
2084
|
+
#maximumSize;
|
|
1694
2085
|
/**
|
|
1695
2086
|
* Is the _Map_ full?
|
|
1696
2087
|
*/
|
|
@@ -1734,12 +2125,12 @@ var SizedMap = class extends Map {
|
|
|
1734
2125
|
}
|
|
1735
2126
|
};
|
|
1736
2127
|
//#endregion
|
|
1737
|
-
//#region src/function/memoize.ts
|
|
2128
|
+
//#region src/internal/function/memoize.ts
|
|
1738
2129
|
function getMemoizationOptions(input) {
|
|
1739
2130
|
const { cacheKey, cacheSize } = isPlainObject(input) ? input : {};
|
|
1740
2131
|
return {
|
|
1741
2132
|
cacheKey: typeof cacheKey === "function" ? cacheKey : void 0,
|
|
1742
|
-
cacheSize: typeof cacheSize === "number" && cacheSize > 0 ? cacheSize :
|
|
2133
|
+
cacheSize: typeof cacheSize === "number" && cacheSize > 0 ? cacheSize : MEMOIZED_CACHE_SIZE_DEFAULT
|
|
1743
2134
|
};
|
|
1744
2135
|
}
|
|
1745
2136
|
/**
|
|
@@ -1750,818 +2141,326 @@ function getMemoizationOptions(input) {
|
|
|
1750
2141
|
* @returns _Memoized_ instance
|
|
1751
2142
|
*/
|
|
1752
2143
|
function memoize(callback, options) {
|
|
1753
|
-
if (typeof callback !== "function") throw new TypeError(
|
|
1754
|
-
const state = {
|
|
2144
|
+
if (typeof callback !== "function") throw new TypeError(MEMOIZED_CALLBACK);
|
|
2145
|
+
const state = {
|
|
2146
|
+
cache: void 0,
|
|
2147
|
+
getter: void 0,
|
|
2148
|
+
options: getMemoizationOptions(options)
|
|
2149
|
+
};
|
|
1755
2150
|
state.cache = new SizedMap(state.options.cacheSize);
|
|
1756
2151
|
state.getter = (...parameters) => {
|
|
1757
|
-
const key = state.options.cacheKey?.(...parameters) ?? (parameters.length === 1 ? parameters[0] : join(parameters.map(getString),
|
|
2152
|
+
const key = state.options.cacheKey?.(...parameters) ?? (parameters.length === 1 ? parameters[0] : join(parameters.map(getString), MEMOIZED_KEY_SEPARATOR));
|
|
1758
2153
|
if (state.cache.has(key)) return state.cache.get(key);
|
|
1759
2154
|
const value = callback(...parameters);
|
|
1760
|
-
state.cache
|
|
2155
|
+
state.cache.set(key, value);
|
|
1761
2156
|
return value;
|
|
1762
2157
|
};
|
|
1763
2158
|
const instance = {
|
|
1764
|
-
clear: () =>
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
},
|
|
1770
|
-
destroy: () => {
|
|
1771
|
-
state.cache?.clear();
|
|
1772
|
-
state.cache = void 0;
|
|
1773
|
-
state.getter = void 0;
|
|
1774
|
-
},
|
|
1775
|
-
get: (key) => {
|
|
1776
|
-
return state.cache?.get(key);
|
|
1777
|
-
},
|
|
1778
|
-
has: (key) => {
|
|
1779
|
-
return state.cache?.has(key) ?? false;
|
|
1780
|
-
},
|
|
1781
|
-
run: (...parameters) => {
|
|
1782
|
-
if (state.cache == null || state.getter == null) throw new Error(MEMOIZED_ERROR_DESTROYED);
|
|
1783
|
-
return state.getter(...parameters);
|
|
1784
|
-
}
|
|
2159
|
+
clear: () => state.cache.clear(),
|
|
2160
|
+
delete: (key) => state.cache.delete(key),
|
|
2161
|
+
get: (key) => state.cache.get(key),
|
|
2162
|
+
has: (key) => state.cache.has(key),
|
|
2163
|
+
run: (...parameters) => state.getter(...parameters)
|
|
1785
2164
|
};
|
|
1786
2165
|
Object.defineProperties(instance, {
|
|
1787
2166
|
maximum: {
|
|
1788
2167
|
enumerable: true,
|
|
1789
|
-
get: () => state.cache
|
|
2168
|
+
get: () => state.cache.maximum
|
|
1790
2169
|
},
|
|
1791
2170
|
size: {
|
|
1792
2171
|
enumerable: true,
|
|
1793
|
-
get: () => state.cache
|
|
2172
|
+
get: () => state.cache.size
|
|
1794
2173
|
}
|
|
1795
2174
|
});
|
|
1796
2175
|
return Object.freeze(instance);
|
|
1797
2176
|
}
|
|
1798
|
-
const
|
|
1799
|
-
const
|
|
1800
|
-
const
|
|
1801
|
-
const SEPARATOR = "_";
|
|
2177
|
+
const MEMOIZED_CACHE_SIZE_DEFAULT = 1024;
|
|
2178
|
+
const MEMOIZED_CALLBACK = "Memoized requires a callback function";
|
|
2179
|
+
const MEMOIZED_KEY_SEPARATOR = "_";
|
|
1802
2180
|
//#endregion
|
|
1803
|
-
//#region src/internal/
|
|
1804
|
-
function getAsyncTimer(type, callback, time) {
|
|
1805
|
-
async function run(item) {
|
|
1806
|
-
const now = performance.now();
|
|
1807
|
-
start ??= now;
|
|
1808
|
-
if (interval === 0 || now - start >= interval - OFFSET) {
|
|
1809
|
-
start = throttle ? now : void 0;
|
|
1810
|
-
item.running = true;
|
|
1811
|
-
try {
|
|
1812
|
-
let result = callback(...item.parameters);
|
|
1813
|
-
if (result instanceof Promise) result = await result;
|
|
1814
|
-
item.resolve(result);
|
|
1815
|
-
} catch (error) {
|
|
1816
|
-
item.reject(error);
|
|
1817
|
-
} finally {
|
|
1818
|
-
item.running = false;
|
|
1819
|
-
}
|
|
1820
|
-
} else id = startTimer(() => run(item));
|
|
1821
|
-
}
|
|
1822
|
-
const interval = getInterval(time);
|
|
1823
|
-
const throttle = type === TIMER_THROTTLE;
|
|
1824
|
-
let id;
|
|
1825
|
-
let last;
|
|
1826
|
-
let start;
|
|
1827
|
-
const timer = (...parameters) => {
|
|
1828
|
-
timer.cancel();
|
|
1829
|
-
const next = {
|
|
1830
|
-
parameters,
|
|
1831
|
-
running: false
|
|
1832
|
-
};
|
|
1833
|
-
next.promise = new Promise((resolve, reject) => {
|
|
1834
|
-
next.reject = reject;
|
|
1835
|
-
next.resolve = resolve;
|
|
1836
|
-
});
|
|
1837
|
-
last = next;
|
|
1838
|
-
if (throttle) run(next);
|
|
1839
|
-
else id = startTimer(() => {
|
|
1840
|
-
run(next);
|
|
1841
|
-
});
|
|
1842
|
-
return next.promise;
|
|
1843
|
-
};
|
|
1844
|
-
timer.cancel = () => {
|
|
1845
|
-
clearTimer(id);
|
|
1846
|
-
if (last != null && !last.running) last.reject();
|
|
1847
|
-
};
|
|
1848
|
-
return timer;
|
|
1849
|
-
}
|
|
1850
|
-
function getInterval(value) {
|
|
1851
|
-
return typeof value === "number" && value > 0 ? value : 0;
|
|
1852
|
-
}
|
|
1853
|
-
function getTimer(type, callback, time) {
|
|
1854
|
-
function run() {
|
|
1855
|
-
const now = performance.now();
|
|
1856
|
-
start ??= now;
|
|
1857
|
-
if (interval === 0 || now - start >= interval - OFFSET) {
|
|
1858
|
-
start = throttle ? now : void 0;
|
|
1859
|
-
callback(...args);
|
|
1860
|
-
} else id = startTimer(run);
|
|
1861
|
-
}
|
|
1862
|
-
const interval = getInterval(time);
|
|
1863
|
-
const throttle = type === TIMER_THROTTLE;
|
|
1864
|
-
let args;
|
|
1865
|
-
let id;
|
|
1866
|
-
let start;
|
|
1867
|
-
const timer = (...parameters) => {
|
|
1868
|
-
timer.cancel();
|
|
1869
|
-
args = parameters;
|
|
1870
|
-
if (throttle) run();
|
|
1871
|
-
else id = startTimer(run);
|
|
1872
|
-
};
|
|
1873
|
-
timer.cancel = () => {
|
|
1874
|
-
clearTimer(id);
|
|
1875
|
-
};
|
|
1876
|
-
return timer;
|
|
1877
|
-
}
|
|
1878
|
-
const OFFSET = 5;
|
|
1879
|
-
const TIMER_DEBOUNCE = "debounce";
|
|
1880
|
-
const TIMER_THROTTLE = "throttle";
|
|
1881
|
-
const TIMER_WAIT = "wait";
|
|
1882
|
-
// istanbul ignore next
|
|
1883
|
-
const clearTimer = typeof cancelAnimationFrame === "function" ? cancelAnimationFrame : clearTimeout;
|
|
1884
|
-
// istanbul ignore next
|
|
1885
|
-
const startTimer = typeof requestAnimationFrame === "function" ? requestAnimationFrame : setTimeout;
|
|
1886
|
-
//#endregion
|
|
1887
|
-
//#region src/function/limit.ts
|
|
2181
|
+
//#region src/internal/string/case.ts
|
|
1888
2182
|
/**
|
|
1889
|
-
*
|
|
1890
|
-
*
|
|
1891
|
-
* - When called, successful _(finished)_ results will resolve and errors will reject
|
|
1892
|
-
* - On subsequent calls, existing calls will be canceled _(rejected)_, the timer reset, and will wait another `time` milliseconds before the new call is made _(and so on...)_
|
|
1893
|
-
*
|
|
1894
|
-
* _Available as `asyncDebounce` and `debounce.async`_
|
|
2183
|
+
* Convert a string to camel case _(thisIsCamelCase)_
|
|
1895
2184
|
*
|
|
1896
|
-
* @param
|
|
1897
|
-
* @
|
|
1898
|
-
* @returns Debounced callback handler with a `cancel` method
|
|
2185
|
+
* @param value String to convert
|
|
2186
|
+
* @returns Camel-cased string
|
|
1899
2187
|
*/
|
|
1900
|
-
function
|
|
1901
|
-
return
|
|
2188
|
+
function camelCase(value) {
|
|
2189
|
+
return toCase(STRING_CASE_CAMEL, value, true, false);
|
|
1902
2190
|
}
|
|
1903
2191
|
/**
|
|
1904
|
-
*
|
|
1905
|
-
*
|
|
1906
|
-
* - When called, successful _(finished)_ results will resolve and errors will reject
|
|
1907
|
-
* - On subsequent calls, existing calls will be canceled _(rejected)_ and will wait until the next valid time to call the callback again _(and so on...)_
|
|
1908
|
-
*
|
|
1909
|
-
* _Available as `asyncThrottle` and `throttle.async`_
|
|
2192
|
+
* Capitalize the first letter of a string _(and lowercase the rest)_
|
|
1910
2193
|
*
|
|
1911
|
-
* @param
|
|
1912
|
-
* @
|
|
1913
|
-
* @returns Throttled callback handler with a `cancel` method
|
|
2194
|
+
* @param value String to capitalize
|
|
2195
|
+
* @returns Capitalized string
|
|
1914
2196
|
*/
|
|
1915
|
-
function
|
|
1916
|
-
|
|
2197
|
+
function capitalize(value) {
|
|
2198
|
+
if (typeof value !== "string" || value.length === 0) return "";
|
|
2199
|
+
memoizedCapitalize ??= memoize((v) => v.length === 1 ? v.toLocaleUpperCase() : `${v.charAt(0).toLocaleUpperCase()}${v.slice(1).toLocaleLowerCase()}`);
|
|
2200
|
+
return memoizedCapitalize.run(value);
|
|
1917
2201
|
}
|
|
1918
2202
|
/**
|
|
1919
|
-
*
|
|
1920
|
-
*
|
|
1921
|
-
* On subsequent calls, the timer is reset and will wait another `time` milliseconds _(and so on...)_
|
|
2203
|
+
* Convert a string to kebab case _(this-is-kebab-case)_
|
|
1922
2204
|
*
|
|
1923
|
-
* @param
|
|
1924
|
-
* @
|
|
1925
|
-
* @returns Debounced callback handler with a `cancel` method
|
|
2205
|
+
* @param value String to convert
|
|
2206
|
+
* @returns Kebab-cased string
|
|
1926
2207
|
*/
|
|
1927
|
-
function
|
|
1928
|
-
return
|
|
2208
|
+
function kebabCase(value) {
|
|
2209
|
+
return toCase(STRING_CASE_KEBAB, value, false, false);
|
|
1929
2210
|
}
|
|
1930
|
-
debounce.async = asyncDebounce;
|
|
1931
2211
|
/**
|
|
1932
|
-
*
|
|
2212
|
+
* Convert a string to lower case
|
|
1933
2213
|
*
|
|
1934
|
-
* @param
|
|
1935
|
-
* @
|
|
1936
|
-
* @returns Throttled callback handler with a `cancel` method
|
|
2214
|
+
* @param value String to convert
|
|
2215
|
+
* @returns Lower-cased string
|
|
1937
2216
|
*/
|
|
1938
|
-
function
|
|
1939
|
-
|
|
2217
|
+
function lowerCase(value) {
|
|
2218
|
+
if (typeof value !== "string") return "";
|
|
2219
|
+
memoizedLowerCase ??= memoize((v) => v.toLocaleLowerCase());
|
|
2220
|
+
return memoizedLowerCase.run(value);
|
|
1940
2221
|
}
|
|
1941
|
-
throttle.async = asyncThrottle;
|
|
1942
|
-
//#endregion
|
|
1943
|
-
//#region src/function/once.ts
|
|
1944
2222
|
/**
|
|
1945
|
-
*
|
|
1946
|
-
*
|
|
1947
|
-
* _Available as `asyncOnce` and `once.async`_
|
|
2223
|
+
* Convert a string to pascal case _(ThisIsPascalCase)_
|
|
1948
2224
|
*
|
|
1949
|
-
* @param
|
|
1950
|
-
* @returns
|
|
2225
|
+
* @param value String to convert
|
|
2226
|
+
* @returns Pascal-cased string
|
|
1951
2227
|
*/
|
|
1952
|
-
function
|
|
1953
|
-
|
|
1954
|
-
const state = {
|
|
1955
|
-
called: false,
|
|
1956
|
-
cleared: false,
|
|
1957
|
-
error: false,
|
|
1958
|
-
finished: false,
|
|
1959
|
-
items: [],
|
|
1960
|
-
value: void 0
|
|
1961
|
-
};
|
|
1962
|
-
const fn = (...parameters) => {
|
|
1963
|
-
if (state.cleared) return Promise.reject(new Error(ONCE_MESSAGE_CLEARED));
|
|
1964
|
-
if (state.finished) return state.error ? Promise.reject(state.value) : Promise.resolve(state.value);
|
|
1965
|
-
if (state.called) return new Promise((resolve, reject) => {
|
|
1966
|
-
state.items.push({
|
|
1967
|
-
reject,
|
|
1968
|
-
resolve
|
|
1969
|
-
});
|
|
1970
|
-
});
|
|
1971
|
-
state.called = true;
|
|
1972
|
-
return new Promise((resolve, reject) => {
|
|
1973
|
-
state.items.push({
|
|
1974
|
-
reject,
|
|
1975
|
-
resolve
|
|
1976
|
-
});
|
|
1977
|
-
callback(...parameters).then((value) => {
|
|
1978
|
-
handleOnceResult(state, value, false);
|
|
1979
|
-
}).catch((error) => {
|
|
1980
|
-
handleOnceResult(state, error, true);
|
|
1981
|
-
});
|
|
1982
|
-
});
|
|
1983
|
-
};
|
|
1984
|
-
Object.defineProperties(fn, {
|
|
1985
|
-
called: {
|
|
1986
|
-
enumerable: true,
|
|
1987
|
-
get: () => state.called
|
|
1988
|
-
},
|
|
1989
|
-
cleared: {
|
|
1990
|
-
enumerable: true,
|
|
1991
|
-
get: () => state.cleared
|
|
1992
|
-
},
|
|
1993
|
-
error: {
|
|
1994
|
-
enumerable: true,
|
|
1995
|
-
get: () => state.error
|
|
1996
|
-
},
|
|
1997
|
-
finished: {
|
|
1998
|
-
enumerable: true,
|
|
1999
|
-
get: () => state.finished
|
|
2000
|
-
}
|
|
2001
|
-
});
|
|
2002
|
-
fn.clear = () => {
|
|
2003
|
-
if (!state.called || !state.finished || state.cleared) return;
|
|
2004
|
-
state.cleared = true;
|
|
2005
|
-
state.value = void 0;
|
|
2006
|
-
};
|
|
2007
|
-
return fn;
|
|
2008
|
-
}
|
|
2009
|
-
function handleOnceResult(state, value, error) {
|
|
2010
|
-
state.error = error;
|
|
2011
|
-
state.finished = true;
|
|
2012
|
-
state.value = value;
|
|
2013
|
-
const items = state.items.splice(0);
|
|
2014
|
-
const { length } = items;
|
|
2015
|
-
for (let index = 0; index < length; index += 1) {
|
|
2016
|
-
const { reject, resolve } = items[index];
|
|
2017
|
-
if (error) reject(value);
|
|
2018
|
-
else resolve(value);
|
|
2019
|
-
}
|
|
2228
|
+
function pascalCase(value) {
|
|
2229
|
+
return toCase(STRING_CASE_PASCAL, value, true, true);
|
|
2020
2230
|
}
|
|
2021
2231
|
/**
|
|
2022
|
-
*
|
|
2232
|
+
* Convert a string to snake case _(this_is_snake_case)_
|
|
2023
2233
|
*
|
|
2024
|
-
* @param
|
|
2025
|
-
* @returns
|
|
2234
|
+
* @param value String to convert
|
|
2235
|
+
* @returns Snake-cased string
|
|
2026
2236
|
*/
|
|
2027
|
-
function
|
|
2028
|
-
|
|
2029
|
-
const state = {
|
|
2030
|
-
called: false,
|
|
2031
|
-
cleared: false,
|
|
2032
|
-
value: void 0
|
|
2033
|
-
};
|
|
2034
|
-
const fn = (...parameters) => {
|
|
2035
|
-
if (state.cleared) throw new Error(ONCE_MESSAGE_CLEARED);
|
|
2036
|
-
if (state.called) return state.value;
|
|
2037
|
-
state.called = true;
|
|
2038
|
-
state.value = callback(...parameters);
|
|
2039
|
-
return state.value;
|
|
2040
|
-
};
|
|
2041
|
-
Object.defineProperties(fn, {
|
|
2042
|
-
called: { get: () => state.called },
|
|
2043
|
-
cleared: { get: () => state.cleared }
|
|
2044
|
-
});
|
|
2045
|
-
fn.clear = () => {
|
|
2046
|
-
if (!state.called || state.cleared) return;
|
|
2047
|
-
state.cleared = true;
|
|
2048
|
-
state.value = void 0;
|
|
2049
|
-
};
|
|
2050
|
-
return fn;
|
|
2237
|
+
function snakeCase(value) {
|
|
2238
|
+
return toCase(STRING_CASE_SNAKE, value, false, false);
|
|
2051
2239
|
}
|
|
2052
|
-
once.async = asyncOnce;
|
|
2053
|
-
const ONCE_MESSAGE_CLEARED = "Once has been cleared";
|
|
2054
|
-
const ONCE_MESSAGE_EXPECTATION = "Once expected a function";
|
|
2055
|
-
//#endregion
|
|
2056
|
-
//#region src/function/retry.ts
|
|
2057
2240
|
/**
|
|
2058
|
-
*
|
|
2241
|
+
* Convert a string to title case _(Capitalizing Every Word)_
|
|
2242
|
+
*
|
|
2243
|
+
* @param value String to convert
|
|
2244
|
+
* @returns Title-cased string
|
|
2059
2245
|
*/
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2246
|
+
function titleCase(value) {
|
|
2247
|
+
if (typeof value !== "string" || value.length === 0) return "";
|
|
2248
|
+
memoizedTitleCase ??= memoize((v) => v.length < 2 ? capitalize(v) : join(words(v).map(capitalize), " "));
|
|
2249
|
+
return memoizedTitleCase.run(value);
|
|
2250
|
+
}
|
|
2251
|
+
function toCase(type, value, capitalizeAny, capitalizeFirst) {
|
|
2252
|
+
caseMemoizers[type] ??= memoize(toCaseCallback.bind({
|
|
2253
|
+
type,
|
|
2254
|
+
capitalizeAny,
|
|
2255
|
+
capitalizeFirst
|
|
2256
|
+
}));
|
|
2257
|
+
return caseMemoizers[type].run(value);
|
|
2258
|
+
}
|
|
2259
|
+
function toCaseCallback(value) {
|
|
2260
|
+
if (typeof value !== "string") return "";
|
|
2261
|
+
if (value.length < 1) return value;
|
|
2262
|
+
const { capitalizeAny, capitalizeFirst, type } = this;
|
|
2263
|
+
const parts = words(value);
|
|
2264
|
+
const partsLength = parts.length;
|
|
2265
|
+
const cased = [];
|
|
2266
|
+
for (let partIndex = 0; partIndex < partsLength; partIndex += 1) {
|
|
2267
|
+
const items = parts[partIndex].replace(STRING_EXPRESSION_ACRONYM, (full, one, two, three) => three === STRING_S ? full : `${one}-${two}${three}`).replace(STRING_EXPRESSION_CAMEL_CASE, STRING_REPLACEMENT_CAMEL_CASE).split("-");
|
|
2268
|
+
const itemsLength = items.length;
|
|
2269
|
+
const partResult = [];
|
|
2270
|
+
let itemCount = 0;
|
|
2271
|
+
for (let itemIndex = 0; itemIndex < itemsLength; itemIndex += 1) {
|
|
2272
|
+
const item = items[itemIndex];
|
|
2273
|
+
if (item.length === 0) continue;
|
|
2274
|
+
if (!capitalizeAny || itemCount === 0 && partIndex === 0 && !capitalizeFirst) partResult.push(item.toLocaleLowerCase());
|
|
2275
|
+
else partResult.push(capitalize(item));
|
|
2276
|
+
itemCount += 1;
|
|
2277
|
+
}
|
|
2278
|
+
cased.push(join(partResult, delimiters[type]));
|
|
2066
2279
|
}
|
|
2067
|
-
|
|
2280
|
+
return join(cased, delimiters[type]);
|
|
2281
|
+
}
|
|
2068
2282
|
/**
|
|
2069
|
-
*
|
|
2070
|
-
*
|
|
2071
|
-
* _Available as `asyncRetry` and `retry.async`_
|
|
2283
|
+
* Convert a string to upper case
|
|
2072
2284
|
*
|
|
2073
|
-
* @param
|
|
2074
|
-
* @
|
|
2075
|
-
* @returns Callback result
|
|
2285
|
+
* @param value String to convert
|
|
2286
|
+
* @returns Upper-cased string
|
|
2076
2287
|
*/
|
|
2077
|
-
|
|
2078
|
-
if (typeof
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
const result = await callback();
|
|
2082
|
-
resolver(result);
|
|
2083
|
-
} catch (error) {
|
|
2084
|
-
if (attempts >= times || !when(error)) rejector(new RetryError(RETRY_MESSAGE_FAILED, error));
|
|
2085
|
-
else {
|
|
2086
|
-
attempts += 1;
|
|
2087
|
-
timer();
|
|
2088
|
-
}
|
|
2089
|
-
}
|
|
2090
|
-
}
|
|
2091
|
-
const { delay, times, when } = getRetryOptions(options);
|
|
2092
|
-
const timer = getTimer(TIMER_WAIT, handle, delay);
|
|
2093
|
-
let attempts = 0;
|
|
2094
|
-
let rejector;
|
|
2095
|
-
let resolver;
|
|
2096
|
-
return new Promise((resolve, reject) => {
|
|
2097
|
-
rejector = reject;
|
|
2098
|
-
resolver = resolve;
|
|
2099
|
-
handle();
|
|
2100
|
-
});
|
|
2101
|
-
}
|
|
2102
|
-
function getRetryNumber(value) {
|
|
2103
|
-
return typeof value === "number" && value > 0 ? value : 0;
|
|
2104
|
-
}
|
|
2105
|
-
function getRetryOptions(input) {
|
|
2106
|
-
const options = isPlainObject(input) ? input : {};
|
|
2107
|
-
return {
|
|
2108
|
-
delay: getRetryNumber(options.delay),
|
|
2109
|
-
times: getRetryNumber(options.times),
|
|
2110
|
-
when: typeof options.when === "function" ? options.when : shouldRetry
|
|
2111
|
-
};
|
|
2288
|
+
function upperCase(value) {
|
|
2289
|
+
if (typeof value !== "string" || value.length === 0) return "";
|
|
2290
|
+
memoizedUpperCase ??= memoize((v) => v.toLocaleUpperCase());
|
|
2291
|
+
return memoizedUpperCase.run(value);
|
|
2112
2292
|
}
|
|
2293
|
+
const STRING_CASE_CAMEL = "camel";
|
|
2294
|
+
const STRING_CASE_KEBAB = "kebab";
|
|
2295
|
+
const STRING_CASE_PASCAL = "pascal";
|
|
2296
|
+
const STRING_CASE_SNAKE = "snake";
|
|
2297
|
+
const STRING_DELIMTER_EMPTY = "";
|
|
2298
|
+
const STRING_DELIMITER_HYPHEN = "-";
|
|
2299
|
+
const STRING_DELIMITER_UNDERSCORE = "_";
|
|
2300
|
+
const STRING_EXPRESSION_CAMEL_CASE = /(\p{Ll})(\p{Lu})/gu;
|
|
2301
|
+
const STRING_EXPRESSION_ACRONYM = /(\p{Lu}*)(\p{Lu})(\p{Ll}+)/gu;
|
|
2302
|
+
const STRING_REPLACEMENT_CAMEL_CASE = "$1-$2";
|
|
2303
|
+
const STRING_S = "s";
|
|
2304
|
+
const caseMemoizers = {};
|
|
2305
|
+
const delimiters = {
|
|
2306
|
+
[STRING_CASE_CAMEL]: STRING_DELIMTER_EMPTY,
|
|
2307
|
+
[STRING_CASE_KEBAB]: STRING_DELIMITER_HYPHEN,
|
|
2308
|
+
[STRING_CASE_PASCAL]: STRING_DELIMTER_EMPTY,
|
|
2309
|
+
[STRING_CASE_SNAKE]: STRING_DELIMITER_UNDERSCORE
|
|
2310
|
+
};
|
|
2311
|
+
let memoizedCapitalize;
|
|
2312
|
+
let memoizedLowerCase;
|
|
2313
|
+
let memoizedTitleCase;
|
|
2314
|
+
let memoizedUpperCase;
|
|
2315
|
+
//#endregion
|
|
2316
|
+
//#region src/internal/value/equal.ts
|
|
2113
2317
|
/**
|
|
2114
|
-
*
|
|
2318
|
+
* Deregister a equality comparison handler for a specific class
|
|
2115
2319
|
*
|
|
2116
|
-
*
|
|
2117
|
-
*
|
|
2118
|
-
* @
|
|
2320
|
+
* _Available as `deregisterEqualizer` and `equal.deregister`_
|
|
2321
|
+
*
|
|
2322
|
+
* @param constructor Class constructor
|
|
2119
2323
|
*/
|
|
2120
|
-
function
|
|
2121
|
-
|
|
2122
|
-
const { times, when } = getRetryOptions(options);
|
|
2123
|
-
let last;
|
|
2124
|
-
for (let index = 0; index <= times; index += 1) try {
|
|
2125
|
-
return callback();
|
|
2126
|
-
} catch (error) {
|
|
2127
|
-
if (index >= times || !when(error)) {
|
|
2128
|
-
last = error;
|
|
2129
|
-
break;
|
|
2130
|
-
}
|
|
2131
|
-
}
|
|
2132
|
-
throw new RetryError(RETRY_MESSAGE_FAILED, last);
|
|
2324
|
+
function deregisterEqualizer(constructor) {
|
|
2325
|
+
equal.handlers.deregister(constructor);
|
|
2133
2326
|
}
|
|
2134
|
-
|
|
2135
|
-
|
|
2327
|
+
function filterKey(key, options) {
|
|
2328
|
+
if (typeof key !== "string") return true;
|
|
2329
|
+
if (options.ignoreExpressions.enabled && options.ignoreExpressions.values.some((expression) => expression.test(key))) return false;
|
|
2330
|
+
if (options.ignoreKeys.enabled && options.ignoreKeys.values.has(key)) return false;
|
|
2136
2331
|
return true;
|
|
2137
2332
|
}
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
const RETRY_MESSAGE_FAILED = "Retry failed";
|
|
2141
|
-
//#endregion
|
|
2142
|
-
//#region src/function/work.ts
|
|
2143
|
-
function asyncFlow(...fns) {
|
|
2144
|
-
assertFlowFunctions(fns);
|
|
2145
|
-
return (...args) => asyncWork(args.map((value) => {
|
|
2146
|
-
if (isError(value)) throw value.error;
|
|
2147
|
-
return isOk(value) ? value.value : value;
|
|
2148
|
-
}), fns, true);
|
|
2333
|
+
function equal(first, second, options) {
|
|
2334
|
+
return equalValue(first, second, getEqualOptions(options));
|
|
2149
2335
|
}
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
}
|
|
2336
|
+
equal.handlers = getCompareHandlers(equal, { callback: Object.is });
|
|
2337
|
+
equal.deregister = deregisterEqualizer;
|
|
2338
|
+
equal.initialize = initializeEqualizer;
|
|
2339
|
+
equal.register = registerEqualizer;
|
|
2340
|
+
function equalArray(first, second, options) {
|
|
2341
|
+
const { length } = first;
|
|
2342
|
+
if (length !== second.length) return false;
|
|
2343
|
+
let offset = 0;
|
|
2344
|
+
if (length >= EQUAL_ARRAY_THRESHOLD) {
|
|
2345
|
+
offset = Math.round(length / EQUAL_ARRAY_PEEK_PERCENTAGE);
|
|
2346
|
+
offset = offset > EQUAL_ARRAY_THRESHOLD ? EQUAL_ARRAY_THRESHOLD : offset;
|
|
2347
|
+
for (let index = 0; index < offset; index += 1) if (!(equalValue(first[index], second[index], options) && equalValue(first[length - index - 1], second[length - index - 1], options))) return false;
|
|
2348
|
+
}
|
|
2349
|
+
const end = length - offset;
|
|
2350
|
+
for (let index = offset; index < end; index += 1) if (!equalValue(first[index], second[index], options)) return false;
|
|
2351
|
+
return true;
|
|
2156
2352
|
}
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
assertPipeFunctions(pipes);
|
|
2160
|
-
return asyncWork(value, pipes, false);
|
|
2353
|
+
function equalArrayBuffer(first, second, options) {
|
|
2354
|
+
return first.byteLength === second.byteLength ? equalArray(new Uint8Array(first), new Uint8Array(second), options) : false;
|
|
2161
2355
|
}
|
|
2162
|
-
function
|
|
2163
|
-
|
|
2164
|
-
return work(value, pipes, false);
|
|
2356
|
+
function equalDataView(first, second, options) {
|
|
2357
|
+
return first.byteOffset === second.byteOffset ? equalArrayBuffer(first.buffer, second.buffer, options) : false;
|
|
2165
2358
|
}
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
for (let index = 0; index <
|
|
2171
|
-
const
|
|
2172
|
-
|
|
2359
|
+
function equalMap(first, second, options) {
|
|
2360
|
+
const { size } = first;
|
|
2361
|
+
if (size !== second.size) return false;
|
|
2362
|
+
const firstKeys = [...first.keys()];
|
|
2363
|
+
for (let index = 0; index < size; index += 1) {
|
|
2364
|
+
const key = firstKeys[index];
|
|
2365
|
+
if (!second.has(key) || !equalValue(first.get(key), second.get(key), options)) return false;
|
|
2173
2366
|
}
|
|
2174
|
-
return
|
|
2367
|
+
return true;
|
|
2175
2368
|
}
|
|
2176
|
-
function
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2369
|
+
function equalPlainObject(first, second, options) {
|
|
2370
|
+
let firstKeys = [...Object.keys(first), ...Object.getOwnPropertySymbols(first)];
|
|
2371
|
+
let secondKeys = [...Object.keys(second), ...Object.getOwnPropertySymbols(second)];
|
|
2372
|
+
if (options.ignoreKeys.enabled || options.ignoreExpressions.enabled) {
|
|
2373
|
+
firstKeys = firstKeys.filter((key) => filterKey(key, options));
|
|
2374
|
+
secondKeys = secondKeys.filter((key) => filterKey(key, options));
|
|
2180
2375
|
}
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2376
|
+
const secondSet = secondKeys.length >= EQUAL_MINIMUM_LENGTH_FOR_SET ? new Set(secondKeys) : void 0;
|
|
2377
|
+
const { length } = firstKeys;
|
|
2378
|
+
if (length !== secondKeys.length) return false;
|
|
2379
|
+
for (let index = 0; index < length; index += 1) {
|
|
2380
|
+
const key = firstKeys[index];
|
|
2381
|
+
if (!(secondSet?.has(key) ?? secondKeys.includes(key)) || !equalValue(first[key], second[key], options)) return false;
|
|
2382
|
+
}
|
|
2383
|
+
return true;
|
|
2184
2384
|
}
|
|
2185
|
-
function
|
|
2186
|
-
const { length } =
|
|
2187
|
-
let transformed = unwrapValue(initial, flow);
|
|
2385
|
+
function equalProperties(first, second, properties, options) {
|
|
2386
|
+
const { length } = properties;
|
|
2188
2387
|
for (let index = 0; index < length; index += 1) {
|
|
2189
|
-
const
|
|
2190
|
-
|
|
2388
|
+
const property = properties[index];
|
|
2389
|
+
if (!equalValue(first[property], second[property], options)) return false;
|
|
2191
2390
|
}
|
|
2192
|
-
return
|
|
2391
|
+
return true;
|
|
2193
2392
|
}
|
|
2194
|
-
|
|
2195
|
-
const
|
|
2196
|
-
|
|
2197
|
-
const
|
|
2198
|
-
const
|
|
2199
|
-
|
|
2200
|
-
const
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
const events = {
|
|
2205
|
-
subscribe: (event, callback) => herald.subscribe(event, callback),
|
|
2206
|
-
unsubscribe: (event, callback) => herald.unsubscribe(event, callback)
|
|
2207
|
-
};
|
|
2208
|
-
Object.defineProperty(events, KEY_HERALD, {
|
|
2209
|
-
enumerable: false,
|
|
2210
|
-
value: NAME_EVENTS
|
|
2211
|
-
});
|
|
2212
|
-
return Object.freeze(events);
|
|
2393
|
+
function equalSet(first, second, options) {
|
|
2394
|
+
const { size } = first;
|
|
2395
|
+
if (size !== second.size) return false;
|
|
2396
|
+
const firstValues = [...first];
|
|
2397
|
+
const secondValues = [...second];
|
|
2398
|
+
for (let index = 0; index < size; index += 1) {
|
|
2399
|
+
const firstValue = firstValues[index];
|
|
2400
|
+
if (isPrimitive(firstValue) ? !second.has(firstValue) : !secondValues.some((secondValue) => equalValue(firstValue, secondValue, options))) return false;
|
|
2401
|
+
}
|
|
2402
|
+
return true;
|
|
2213
2403
|
}
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2404
|
+
function equalTypedArray(first, second) {
|
|
2405
|
+
if (first.constructor !== second.constructor) return false;
|
|
2406
|
+
if (first.byteLength !== second.byteLength) return false;
|
|
2407
|
+
const { length } = first;
|
|
2408
|
+
for (let index = 0; index < length; index += 1) if (first[index] !== second[index]) return false;
|
|
2409
|
+
return true;
|
|
2410
|
+
}
|
|
2411
|
+
function equalValue(first, second, options) {
|
|
2412
|
+
if (options.relaxedNullish && first == null && second == null) return true;
|
|
2413
|
+
switch (true) {
|
|
2414
|
+
case Object.is(first, second): return true;
|
|
2415
|
+
case first == null || second == null: return first === second;
|
|
2416
|
+
case typeof first !== typeof second: return false;
|
|
2417
|
+
case typeof first === "string" && options.ignoreCase === true: return Object.is(first.toLocaleLowerCase(), second.toLocaleLowerCase());
|
|
2418
|
+
case first instanceof ArrayBuffer && second instanceof ArrayBuffer: return equalArrayBuffer(first, second, options);
|
|
2419
|
+
case first instanceof Date && second instanceof Date: return Object.is(first.getTime(), second.getTime());
|
|
2420
|
+
case first instanceof DataView && second instanceof DataView: return equalDataView(first, second, options);
|
|
2421
|
+
case first instanceof Error && second instanceof Error: return equalProperties(first, second, EQUAL_ERROR_PROPERTIES, options);
|
|
2422
|
+
case first instanceof Map && second instanceof Map: return equalMap(first, second, options);
|
|
2423
|
+
case first instanceof RegExp && second instanceof RegExp: return equalProperties(first, second, EQUAL_EXPRESSION_PROPERTIES, options);
|
|
2424
|
+
case first instanceof Set && second instanceof Set: return equalSet(first, second, options);
|
|
2425
|
+
case Array.isArray(first) && Array.isArray(second): return equalArray(first, second, options);
|
|
2426
|
+
case isPlainObject(first) && isPlainObject(second): return equalPlainObject(first, second, options);
|
|
2427
|
+
case isTypedArray(first) && isTypedArray(second): return equalTypedArray(first, second);
|
|
2428
|
+
default: return equal.handlers.handle(first, second, options);
|
|
2429
|
+
}
|
|
2430
|
+
}
|
|
2431
|
+
function getEqualOptions(input) {
|
|
2432
|
+
const options = {
|
|
2433
|
+
ignoreCase: false,
|
|
2434
|
+
ignoreExpressions: {
|
|
2435
|
+
enabled: false,
|
|
2436
|
+
values: []
|
|
2232
2437
|
},
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
if (eventSubscribers == null) {
|
|
2237
|
-
eventSubscribers = /* @__PURE__ */ new Set();
|
|
2238
|
-
subscribers.set(event, eventSubscribers);
|
|
2239
|
-
}
|
|
2240
|
-
eventSubscribers.add(callback);
|
|
2241
|
-
return () => {
|
|
2242
|
-
eventSubscribers?.delete(callback);
|
|
2243
|
-
};
|
|
2438
|
+
ignoreKeys: {
|
|
2439
|
+
enabled: false,
|
|
2440
|
+
values: /* @__PURE__ */ new Set()
|
|
2244
2441
|
},
|
|
2245
|
-
|
|
2246
|
-
if (!set.has(event) || (callback != null ? typeof callback !== "function" : false)) return;
|
|
2247
|
-
const eventSubscribers = subscribers.get(event);
|
|
2248
|
-
if (eventSubscribers == null) return;
|
|
2249
|
-
if (callback == null) eventSubscribers.clear();
|
|
2250
|
-
else eventSubscribers.delete(callback);
|
|
2251
|
-
if (callback == null || eventSubscribers.size === 0) subscribers.delete(event);
|
|
2252
|
-
}
|
|
2442
|
+
relaxedNullish: false
|
|
2253
2443
|
};
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2444
|
+
if (typeof input === "boolean") {
|
|
2445
|
+
options.ignoreCase = input;
|
|
2446
|
+
return options;
|
|
2447
|
+
}
|
|
2448
|
+
if (isNonPlainObject(input)) return options;
|
|
2449
|
+
options.ignoreCase = typeof input.ignoreCase === "boolean" ? input.ignoreCase : false;
|
|
2450
|
+
options.ignoreExpressions.values = (Array.isArray(input.ignoreKeys) ? input.ignoreKeys : [input.ignoreKeys]).filter((key) => key instanceof RegExp);
|
|
2451
|
+
options.ignoreKeys.values = new Set((Array.isArray(input.ignoreKeys) ? input.ignoreKeys : [input.ignoreKeys]).filter((key) => typeof key === "string"));
|
|
2452
|
+
options.ignoreExpressions.enabled = options.ignoreExpressions.values.length > 0;
|
|
2453
|
+
options.ignoreKeys.enabled = options.ignoreKeys.values.size > 0;
|
|
2454
|
+
options.relaxedNullish = input.relaxedNullish === true;
|
|
2455
|
+
return options;
|
|
2265
2456
|
}
|
|
2266
2457
|
/**
|
|
2267
|
-
*
|
|
2458
|
+
* Create an equalizer with predefined options
|
|
2268
2459
|
*
|
|
2269
|
-
*
|
|
2270
|
-
* @returns `true` if the value is events for a herald, otherwise `false`
|
|
2271
|
-
*/
|
|
2272
|
-
function isEvents(value) {
|
|
2273
|
-
return isHeraldInstance(NAME_EVENTS, value);
|
|
2274
|
-
}
|
|
2275
|
-
/**
|
|
2276
|
-
* Is the value a herald?
|
|
2460
|
+
* _Available as `initializeEqualizer` and `equal.initialize`_
|
|
2277
2461
|
*
|
|
2278
|
-
* @param
|
|
2279
|
-
* @returns
|
|
2280
|
-
*/
|
|
2281
|
-
function isHerald(value) {
|
|
2282
|
-
return isHeraldInstance(NAME_HERALD, value);
|
|
2283
|
-
}
|
|
2284
|
-
function isHeraldInstance(name, value) {
|
|
2285
|
-
return typeof value === "object" && value != null && KEY_HERALD in value && value[KEY_HERALD] === name;
|
|
2286
|
-
}
|
|
2287
|
-
const KEY_HERALD = "$herald";
|
|
2288
|
-
const MESSAGE = "Herald requires an array of event names.";
|
|
2289
|
-
const NAME_EVENTS = "events";
|
|
2290
|
-
const NAME_HERALD = "herald";
|
|
2291
|
-
//#endregion
|
|
2292
|
-
//#region src/internal/subscription.ts
|
|
2293
|
-
function addSubscription(subscription, state) {
|
|
2294
|
-
const { key, subscriptions, value } = state.parameters;
|
|
2295
|
-
const { items, values } = subscriptions;
|
|
2296
|
-
if (key == null) {
|
|
2297
|
-
items.any.add(subscription);
|
|
2298
|
-
values.from.any.set(value, subscription);
|
|
2299
|
-
values.to.any.set(subscription, value);
|
|
2300
|
-
return;
|
|
2301
|
-
}
|
|
2302
|
-
if (items.keyed == null || values.from.keyed == null || values.to.keyed == null)
|
|
2303
|
-
// istanbul ignore next
|
|
2304
|
-
return;
|
|
2305
|
-
let keyedItems = items.keyed.get(key);
|
|
2306
|
-
if (keyedItems == null) {
|
|
2307
|
-
keyedItems = /* @__PURE__ */ new Set();
|
|
2308
|
-
items.keyed.set(key, keyedItems);
|
|
2309
|
-
}
|
|
2310
|
-
keyedItems.add(subscription);
|
|
2311
|
-
let keyedFrom = values.from.keyed.get(key);
|
|
2312
|
-
if (keyedFrom == null) {
|
|
2313
|
-
keyedFrom = /* @__PURE__ */ new Map();
|
|
2314
|
-
values.from.keyed.set(key, keyedFrom);
|
|
2315
|
-
}
|
|
2316
|
-
keyedFrom.set(value, subscription);
|
|
2317
|
-
let keyedTo = values.to.keyed.get(key);
|
|
2318
|
-
if (keyedTo == null) {
|
|
2319
|
-
keyedTo = /* @__PURE__ */ new Map();
|
|
2320
|
-
values.to.keyed.set(key, keyedTo);
|
|
2321
|
-
}
|
|
2322
|
-
keyedTo.set(subscription, value);
|
|
2323
|
-
}
|
|
2324
|
-
function clearSubscriptions(store) {
|
|
2325
|
-
for (const susbcription of store.values.to.any.keys()) susbcription.unsubscribe();
|
|
2326
|
-
if (store.values.to.keyed != null) for (const values of store.values.to.keyed.values()) for (const susbcription of values.keys()) susbcription.unsubscribe();
|
|
2327
|
-
}
|
|
2328
|
-
function getExistingSubscription(state) {
|
|
2329
|
-
const { parameters } = state;
|
|
2330
|
-
const { values } = parameters.subscriptions;
|
|
2331
|
-
return parameters.key == null ? values.from.any.get(parameters.value) : values.from.keyed?.get(parameters.key)?.get(parameters.value);
|
|
2332
|
-
}
|
|
2333
|
-
function getSubscription(parameters) {
|
|
2334
|
-
const state = {
|
|
2335
|
-
parameters,
|
|
2336
|
-
active: true
|
|
2337
|
-
};
|
|
2338
|
-
const existing = getExistingSubscription(state);
|
|
2339
|
-
if (existing != null) return existing;
|
|
2340
|
-
if (parameters.subscriptions.keys != null && parameters.key != null && !parameters.subscriptions.keys.has(parameters.key)) throw new Error();
|
|
2341
|
-
const instance = { unsubscribe: () => {
|
|
2342
|
-
removeSubscription(instance, state);
|
|
2343
|
-
} };
|
|
2344
|
-
Object.defineProperties(instance, {
|
|
2345
|
-
[PROPERTY]: {
|
|
2346
|
-
enumerable: false,
|
|
2347
|
-
value: true
|
|
2348
|
-
},
|
|
2349
|
-
[parameters.property.key]: {
|
|
2350
|
-
enumerable: false,
|
|
2351
|
-
value: parameters.property.value
|
|
2352
|
-
},
|
|
2353
|
-
active: {
|
|
2354
|
-
enumerable: true,
|
|
2355
|
-
get: () => (parameters.isActive?.() ?? true) && state.active
|
|
2356
|
-
}
|
|
2357
|
-
});
|
|
2358
|
-
addSubscription(instance, state);
|
|
2359
|
-
return Object.freeze(instance);
|
|
2360
|
-
}
|
|
2361
|
-
function getSubscriptions(keys) {
|
|
2362
|
-
return {
|
|
2363
|
-
keys,
|
|
2364
|
-
items: {
|
|
2365
|
-
any: /* @__PURE__ */ new Set(),
|
|
2366
|
-
keyed: keys == null ? void 0 : /* @__PURE__ */ new Map()
|
|
2367
|
-
},
|
|
2368
|
-
values: {
|
|
2369
|
-
from: {
|
|
2370
|
-
any: /* @__PURE__ */ new Map(),
|
|
2371
|
-
keyed: keys == null ? void 0 : /* @__PURE__ */ new Map()
|
|
2372
|
-
},
|
|
2373
|
-
to: {
|
|
2374
|
-
any: /* @__PURE__ */ new Map(),
|
|
2375
|
-
keyed: keys == null ? void 0 : /* @__PURE__ */ new Map()
|
|
2376
|
-
}
|
|
2377
|
-
}
|
|
2378
|
-
};
|
|
2379
|
-
}
|
|
2380
|
-
/**
|
|
2381
|
-
* Is the value a subscription?
|
|
2382
|
-
*
|
|
2383
|
-
* @param value Value to check
|
|
2384
|
-
* @returns `true` if the value is a subscription, otherwise `false`
|
|
2385
|
-
*/
|
|
2386
|
-
function isSubscription(value) {
|
|
2387
|
-
return isPlainObject(value) && PROPERTY in value && value[PROPERTY] === true;
|
|
2388
|
-
}
|
|
2389
|
-
function removeFromStore(items, values, subscription, value, key) {
|
|
2390
|
-
items.delete(subscription);
|
|
2391
|
-
if (key == null) {
|
|
2392
|
-
values.from.any.delete(value);
|
|
2393
|
-
values.to.any.delete(subscription);
|
|
2394
|
-
} else {
|
|
2395
|
-
values.from.keyed?.get(key)?.delete(value);
|
|
2396
|
-
values.to.keyed?.get(key)?.delete(subscription);
|
|
2397
|
-
}
|
|
2398
|
-
}
|
|
2399
|
-
function removeSubscription(subscription, state) {
|
|
2400
|
-
if (!state.active) return;
|
|
2401
|
-
state.active = false;
|
|
2402
|
-
const { key, subscriptions, value } = state.parameters;
|
|
2403
|
-
const { items, values } = subscriptions;
|
|
2404
|
-
if (key == null) {
|
|
2405
|
-
removeFromStore(items.any, values, subscription, value);
|
|
2406
|
-
return;
|
|
2407
|
-
}
|
|
2408
|
-
const keyed = items.keyed?.get(key);
|
|
2409
|
-
if (items.keyed == null || keyed == null)
|
|
2410
|
-
// istanbul ignore next
|
|
2411
|
-
return;
|
|
2412
|
-
removeFromStore(keyed, values, subscription, value, key);
|
|
2413
|
-
if (keyed.size === 0) items.keyed.delete(key);
|
|
2414
|
-
}
|
|
2415
|
-
const PROPERTY = "$subscription";
|
|
2416
|
-
//#endregion
|
|
2417
|
-
//#region src/internal/value/equal.ts
|
|
2418
|
-
/**
|
|
2419
|
-
* Deregister a equality comparison handler for a specific class
|
|
2420
|
-
*
|
|
2421
|
-
* _Available as `deregisterEqualizer` and `equal.deregister`_
|
|
2422
|
-
*
|
|
2423
|
-
* @param constructor Class constructor
|
|
2424
|
-
*/
|
|
2425
|
-
function deregisterEqualizer(constructor) {
|
|
2426
|
-
equal.handlers.deregister(constructor);
|
|
2427
|
-
}
|
|
2428
|
-
function filterKey(key, options) {
|
|
2429
|
-
if (typeof key !== "string") return true;
|
|
2430
|
-
if (options.ignoreExpressions.enabled && options.ignoreExpressions.values.some((expression) => expression.test(key))) return false;
|
|
2431
|
-
if (options.ignoreKeys.enabled && options.ignoreKeys.values.has(key)) return false;
|
|
2432
|
-
return true;
|
|
2433
|
-
}
|
|
2434
|
-
function equal(first, second, options) {
|
|
2435
|
-
return equalValue(first, second, getEqualOptions(options));
|
|
2436
|
-
}
|
|
2437
|
-
equal.handlers = getCompareHandlers(equal, { callback: Object.is });
|
|
2438
|
-
equal.deregister = deregisterEqualizer;
|
|
2439
|
-
equal.initialize = initializeEqualizer;
|
|
2440
|
-
equal.register = registerEqualizer;
|
|
2441
|
-
function equalArray(first, second, options) {
|
|
2442
|
-
const { length } = first;
|
|
2443
|
-
if (length !== second.length) return false;
|
|
2444
|
-
let offset = 0;
|
|
2445
|
-
if (length >= EQUAL_ARRAY_THRESHOLD) {
|
|
2446
|
-
offset = Math.round(length / EQUAL_ARRAY_PEEK_PERCENTAGE);
|
|
2447
|
-
offset = offset > EQUAL_ARRAY_THRESHOLD ? EQUAL_ARRAY_THRESHOLD : offset;
|
|
2448
|
-
for (let index = 0; index < offset; index += 1) if (!(equalValue(first[index], second[index], options) && equalValue(first[length - index - 1], second[length - index - 1], options))) return false;
|
|
2449
|
-
}
|
|
2450
|
-
const end = length - offset;
|
|
2451
|
-
for (let index = offset; index < end; index += 1) if (!equalValue(first[index], second[index], options)) return false;
|
|
2452
|
-
return true;
|
|
2453
|
-
}
|
|
2454
|
-
function equalArrayBuffer(first, second, options) {
|
|
2455
|
-
return first.byteLength === second.byteLength ? equalArray(new Uint8Array(first), new Uint8Array(second), options) : false;
|
|
2456
|
-
}
|
|
2457
|
-
function equalDataView(first, second, options) {
|
|
2458
|
-
return first.byteOffset === second.byteOffset ? equalArrayBuffer(first.buffer, second.buffer, options) : false;
|
|
2459
|
-
}
|
|
2460
|
-
function equalMap(first, second, options) {
|
|
2461
|
-
const { size } = first;
|
|
2462
|
-
if (size !== second.size) return false;
|
|
2463
|
-
const firstKeys = [...first.keys()];
|
|
2464
|
-
for (let index = 0; index < size; index += 1) {
|
|
2465
|
-
const key = firstKeys[index];
|
|
2466
|
-
if (!second.has(key) || !equalValue(first.get(key), second.get(key), options)) return false;
|
|
2467
|
-
}
|
|
2468
|
-
return true;
|
|
2469
|
-
}
|
|
2470
|
-
function equalPlainObject(first, second, options) {
|
|
2471
|
-
let firstKeys = [...Object.keys(first), ...Object.getOwnPropertySymbols(first)];
|
|
2472
|
-
let secondKeys = [...Object.keys(second), ...Object.getOwnPropertySymbols(second)];
|
|
2473
|
-
if (options.ignoreKeys.enabled || options.ignoreExpressions.enabled) {
|
|
2474
|
-
firstKeys = firstKeys.filter((key) => filterKey(key, options));
|
|
2475
|
-
secondKeys = secondKeys.filter((key) => filterKey(key, options));
|
|
2476
|
-
}
|
|
2477
|
-
const secondSet = secondKeys.length >= MINIMUM_LENGTH_FOR_SET ? new Set(secondKeys) : void 0;
|
|
2478
|
-
const { length } = firstKeys;
|
|
2479
|
-
if (length !== secondKeys.length) return false;
|
|
2480
|
-
for (let index = 0; index < length; index += 1) {
|
|
2481
|
-
const key = firstKeys[index];
|
|
2482
|
-
if (!(secondSet?.has(key) ?? secondKeys.includes(key)) || !equalValue(first[key], second[key], options)) return false;
|
|
2483
|
-
}
|
|
2484
|
-
return true;
|
|
2485
|
-
}
|
|
2486
|
-
function equalProperties(first, second, properties, options) {
|
|
2487
|
-
const { length } = properties;
|
|
2488
|
-
for (let index = 0; index < length; index += 1) {
|
|
2489
|
-
const property = properties[index];
|
|
2490
|
-
if (!equalValue(first[property], second[property], options)) return false;
|
|
2491
|
-
}
|
|
2492
|
-
return true;
|
|
2493
|
-
}
|
|
2494
|
-
function equalSet(first, second, options) {
|
|
2495
|
-
const { size } = first;
|
|
2496
|
-
if (size !== second.size) return false;
|
|
2497
|
-
const firstValues = [...first];
|
|
2498
|
-
const secondValues = [...second];
|
|
2499
|
-
for (let index = 0; index < size; index += 1) {
|
|
2500
|
-
const firstValue = firstValues[index];
|
|
2501
|
-
if (isPrimitive(firstValue) ? !second.has(firstValue) : !secondValues.some((secondValue) => equalValue(firstValue, secondValue, options))) return false;
|
|
2502
|
-
}
|
|
2503
|
-
return true;
|
|
2504
|
-
}
|
|
2505
|
-
function equalTypedArray(first, second) {
|
|
2506
|
-
if (first.constructor !== second.constructor) return false;
|
|
2507
|
-
if (first.byteLength !== second.byteLength) return false;
|
|
2508
|
-
const { length } = first;
|
|
2509
|
-
for (let index = 0; index < length; index += 1) if (first[index] !== second[index]) return false;
|
|
2510
|
-
return true;
|
|
2511
|
-
}
|
|
2512
|
-
function equalValue(first, second, options) {
|
|
2513
|
-
if (options.relaxedNullish && first == null && second == null) return true;
|
|
2514
|
-
switch (true) {
|
|
2515
|
-
case Object.is(first, second): return true;
|
|
2516
|
-
case first == null || second == null: return first === second;
|
|
2517
|
-
case typeof first !== typeof second: return false;
|
|
2518
|
-
case typeof first === "string" && options.ignoreCase === true: return Object.is(first.toLocaleLowerCase(), second.toLocaleLowerCase());
|
|
2519
|
-
case first instanceof ArrayBuffer && second instanceof ArrayBuffer: return equalArrayBuffer(first, second, options);
|
|
2520
|
-
case first instanceof Date && second instanceof Date: return Object.is(first.getTime(), second.getTime());
|
|
2521
|
-
case first instanceof DataView && second instanceof DataView: return equalDataView(first, second, options);
|
|
2522
|
-
case first instanceof Error && second instanceof Error: return equalProperties(first, second, ERROR_PROPERTIES, options);
|
|
2523
|
-
case first instanceof Map && second instanceof Map: return equalMap(first, second, options);
|
|
2524
|
-
case first instanceof RegExp && second instanceof RegExp: return equalProperties(first, second, EXPRESSION_PROPERTIES, options);
|
|
2525
|
-
case first instanceof Set && second instanceof Set: return equalSet(first, second, options);
|
|
2526
|
-
case Array.isArray(first) && Array.isArray(second): return equalArray(first, second, options);
|
|
2527
|
-
case isPlainObject(first) && isPlainObject(second): return equalPlainObject(first, second, options);
|
|
2528
|
-
case isTypedArray(first) && isTypedArray(second): return equalTypedArray(first, second);
|
|
2529
|
-
default: return equal.handlers.handle(first, second, options);
|
|
2530
|
-
}
|
|
2531
|
-
}
|
|
2532
|
-
function getEqualOptions(input) {
|
|
2533
|
-
const options = {
|
|
2534
|
-
ignoreCase: false,
|
|
2535
|
-
ignoreExpressions: {
|
|
2536
|
-
enabled: false,
|
|
2537
|
-
values: []
|
|
2538
|
-
},
|
|
2539
|
-
ignoreKeys: {
|
|
2540
|
-
enabled: false,
|
|
2541
|
-
values: /* @__PURE__ */ new Set()
|
|
2542
|
-
},
|
|
2543
|
-
relaxedNullish: false
|
|
2544
|
-
};
|
|
2545
|
-
if (typeof input === "boolean") {
|
|
2546
|
-
options.ignoreCase = input;
|
|
2547
|
-
return options;
|
|
2548
|
-
}
|
|
2549
|
-
if (isNonPlainObject(input)) return options;
|
|
2550
|
-
options.ignoreCase = typeof input.ignoreCase === "boolean" ? input.ignoreCase : false;
|
|
2551
|
-
options.ignoreExpressions.values = (Array.isArray(input.ignoreKeys) ? input.ignoreKeys : [input.ignoreKeys]).filter((key) => key instanceof RegExp);
|
|
2552
|
-
options.ignoreKeys.values = new Set((Array.isArray(input.ignoreKeys) ? input.ignoreKeys : [input.ignoreKeys]).filter((key) => typeof key === "string"));
|
|
2553
|
-
options.ignoreExpressions.enabled = options.ignoreExpressions.values.length > 0;
|
|
2554
|
-
options.ignoreKeys.enabled = options.ignoreKeys.values.size > 0;
|
|
2555
|
-
options.relaxedNullish = input.relaxedNullish === true;
|
|
2556
|
-
return options;
|
|
2557
|
-
}
|
|
2558
|
-
/**
|
|
2559
|
-
* Create an equalizer with predefined options
|
|
2560
|
-
*
|
|
2561
|
-
* _Available as `initializeEqualizer` and `equal.initialize`_
|
|
2562
|
-
*
|
|
2563
|
-
* @param options Comparison options
|
|
2564
|
-
* @returns Equalizer function
|
|
2462
|
+
* @param options Comparison options
|
|
2463
|
+
* @returns Equalizer function
|
|
2565
2464
|
*/
|
|
2566
2465
|
function initializeEqualizer(options) {
|
|
2567
2466
|
const actual = getEqualOptions(options);
|
|
@@ -2583,9 +2482,9 @@ function registerEqualizer(constructor, handler) {
|
|
|
2583
2482
|
}
|
|
2584
2483
|
const EQUAL_ARRAY_PEEK_PERCENTAGE = 10;
|
|
2585
2484
|
const EQUAL_ARRAY_THRESHOLD = 100;
|
|
2586
|
-
const
|
|
2587
|
-
const
|
|
2588
|
-
const
|
|
2485
|
+
const EQUAL_ERROR_PROPERTIES = ["name", "message"];
|
|
2486
|
+
const EQUAL_EXPRESSION_PROPERTIES = ["source", "flags"];
|
|
2487
|
+
const EQUAL_MINIMUM_LENGTH_FOR_SET = 16;
|
|
2589
2488
|
//#endregion
|
|
2590
2489
|
//#region src/internal/value/get.ts
|
|
2591
2490
|
function getValue(data, path, ignoreCase) {
|
|
@@ -2613,7 +2512,7 @@ function setValue(data, path, value, ignoreCase) {
|
|
|
2613
2512
|
let next = handleValue(target, currentPath, null, true, shouldIgnoreCase).value;
|
|
2614
2513
|
if (typeof next !== "object" || next === null) {
|
|
2615
2514
|
const nextPath = paths[index + 1];
|
|
2616
|
-
if (
|
|
2515
|
+
if (SET_EXPRESSION_INDEX.test(nextPath)) next = Array.from({ length: Number(nextPath) + 1 }, () => void 0);
|
|
2617
2516
|
else next = {};
|
|
2618
2517
|
target[currentPath] = next;
|
|
2619
2518
|
}
|
|
@@ -2621,142 +2520,376 @@ function setValue(data, path, value, ignoreCase) {
|
|
|
2621
2520
|
}
|
|
2622
2521
|
return data;
|
|
2623
2522
|
}
|
|
2624
|
-
const
|
|
2523
|
+
const SET_EXPRESSION_INDEX = /^\d+$/;
|
|
2625
2524
|
//#endregion
|
|
2626
|
-
//#region src/
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2525
|
+
//#region src/internal/abort.ts
|
|
2526
|
+
function createAborter(value, onAbort) {
|
|
2527
|
+
if (!(value instanceof AbortSignal)) return;
|
|
2528
|
+
value.addEventListener(ABORT_EVENT, onAbort, ABORT_OPTIONS);
|
|
2529
|
+
return {
|
|
2530
|
+
callback: onAbort,
|
|
2531
|
+
signal: value,
|
|
2532
|
+
cancel: () => value.removeEventListener(ABORT_EVENT, onAbort)
|
|
2533
|
+
};
|
|
2534
|
+
}
|
|
2535
|
+
const ABORT_EVENT = "abort";
|
|
2536
|
+
const ABORT_OPTIONS = { once: true };
|
|
2537
|
+
//#endregion
|
|
2538
|
+
//#region src/internal/defaults.ts
|
|
2539
|
+
function getBooleanOrDefault(value, defaultValue) {
|
|
2540
|
+
return typeof value === "boolean" ? value : defaultValue;
|
|
2541
|
+
}
|
|
2542
|
+
function getNumberOrDefault(value, defaultValue, minimum) {
|
|
2543
|
+
return typeof value === "number" && !Number.isNaN(value) && value >= (minimum ?? 0) ? value : defaultValue;
|
|
2635
2544
|
}
|
|
2545
|
+
//#endregion
|
|
2546
|
+
//#region src/promise/constants.ts
|
|
2547
|
+
const PROMISE_ERROR_NAME = "PromiseTimeoutError";
|
|
2548
|
+
const PROMISE_MESSAGE_EXPECTATION_ATTEMPT = "Attempt expected a function or a promise";
|
|
2549
|
+
const PROMISE_MESSAGE_EXPECTATION_RESULT = "toResult expected a Promise";
|
|
2550
|
+
const PROMISE_MESSAGE_EXPECTATION_TIMED = "Timed function expected a Promise";
|
|
2551
|
+
const PROMISE_MESSAGE_TIMEOUT = "Promise timed out";
|
|
2552
|
+
const PROMISE_STRATEGY_ALL = /* @__PURE__ */ new Set(["complete", "first"]);
|
|
2553
|
+
const PROMISE_STRATEGY_DEFAULT = "complete";
|
|
2554
|
+
const PROMISE_TYPE_FULFILLED = "fulfilled";
|
|
2555
|
+
const PROMISE_TYPE_REJECTED = "rejected";
|
|
2556
|
+
//#endregion
|
|
2557
|
+
//#region src/promise/models.ts
|
|
2636
2558
|
/**
|
|
2637
|
-
*
|
|
2638
|
-
*
|
|
2639
|
-
* @param value String to capitalize
|
|
2640
|
-
* @returns Capitalized string
|
|
2559
|
+
* A _Promise_ that can be canceled
|
|
2641
2560
|
*/
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2561
|
+
var CancelablePromise = class extends Promise {
|
|
2562
|
+
#rejector;
|
|
2563
|
+
constructor(executor) {
|
|
2564
|
+
let rejector;
|
|
2565
|
+
super((resolve, reject) => {
|
|
2566
|
+
rejector = reject;
|
|
2567
|
+
executor(resolve, reject);
|
|
2568
|
+
});
|
|
2569
|
+
this.#rejector = rejector;
|
|
2570
|
+
}
|
|
2571
|
+
/**
|
|
2572
|
+
* Cancel the _Promise_, rejecting it with an optional reason
|
|
2573
|
+
*
|
|
2574
|
+
* @param reason Optional reason for canceling the _Promise_
|
|
2575
|
+
*/
|
|
2576
|
+
cancel(reason) {
|
|
2577
|
+
this.#rejector?.(reason);
|
|
2578
|
+
this.#rejector = void 0;
|
|
2579
|
+
}
|
|
2580
|
+
};
|
|
2581
|
+
/**
|
|
2582
|
+
* An error thrown when a promise times out
|
|
2583
|
+
*/
|
|
2584
|
+
var PromiseTimeoutError = class extends Error {
|
|
2585
|
+
constructor() {
|
|
2586
|
+
super(PROMISE_MESSAGE_TIMEOUT);
|
|
2587
|
+
this.name = PROMISE_ERROR_NAME;
|
|
2588
|
+
}
|
|
2589
|
+
};
|
|
2590
|
+
//#endregion
|
|
2591
|
+
//#region src/promise/helpers.ts
|
|
2592
|
+
function getPromiseOptions(input) {
|
|
2593
|
+
if (typeof input === "number") return { time: getNumberOrDefault(input, 0) };
|
|
2594
|
+
if (input instanceof AbortSignal) return {
|
|
2595
|
+
signal: input,
|
|
2596
|
+
time: 0
|
|
2597
|
+
};
|
|
2598
|
+
const options = typeof input === "object" && input !== null ? input : {};
|
|
2599
|
+
return {
|
|
2600
|
+
signal: options.signal instanceof AbortSignal ? options.signal : void 0,
|
|
2601
|
+
time: getNumberOrDefault(options.time, 0)
|
|
2602
|
+
};
|
|
2603
|
+
}
|
|
2604
|
+
function getPromisesOptions(input) {
|
|
2605
|
+
if (typeof input === "string") return { strategy: getStrategyOrDefault(input) };
|
|
2606
|
+
if (input instanceof AbortSignal) return {
|
|
2607
|
+
signal: input,
|
|
2608
|
+
strategy: PROMISE_STRATEGY_DEFAULT
|
|
2609
|
+
};
|
|
2610
|
+
const options = typeof input === "object" && input !== null ? input : {};
|
|
2611
|
+
return {
|
|
2612
|
+
signal: options.signal instanceof AbortSignal ? options.signal : void 0,
|
|
2613
|
+
strategy: getStrategyOrDefault(options.strategy)
|
|
2614
|
+
};
|
|
2615
|
+
}
|
|
2616
|
+
function getResultsFromPromises(promised) {
|
|
2617
|
+
return promised.map((result) => isFulfilled(result) ? ok(result.value) : error(result.reason));
|
|
2618
|
+
}
|
|
2619
|
+
function getStrategyOrDefault(value) {
|
|
2620
|
+
return PROMISE_STRATEGY_ALL.has(value) ? value : PROMISE_STRATEGY_DEFAULT;
|
|
2646
2621
|
}
|
|
2647
2622
|
/**
|
|
2648
|
-
*
|
|
2623
|
+
* Is the value a fulfilled _Promise_ result?
|
|
2649
2624
|
*
|
|
2650
|
-
* @param value
|
|
2651
|
-
* @returns
|
|
2625
|
+
* @param value Value to check
|
|
2626
|
+
* @returns `true` if the value is a fulfilled _Promise_ result, otherwise `false`
|
|
2652
2627
|
*/
|
|
2653
|
-
function
|
|
2654
|
-
return
|
|
2628
|
+
function isFulfilled(value) {
|
|
2629
|
+
return isType(value, PROMISE_TYPE_FULFILLED);
|
|
2655
2630
|
}
|
|
2656
2631
|
/**
|
|
2657
|
-
*
|
|
2632
|
+
* Is the value a rejected _Promise_ result?
|
|
2658
2633
|
*
|
|
2659
|
-
* @param value
|
|
2660
|
-
* @returns
|
|
2634
|
+
* @param value Value to check
|
|
2635
|
+
* @returns `true` if the value is a rejected _Promise_ result, otherwise `false`
|
|
2661
2636
|
*/
|
|
2662
|
-
function
|
|
2663
|
-
|
|
2664
|
-
memoizedLowerCase ??= memoize((v) => v.toLocaleLowerCase());
|
|
2665
|
-
return memoizedLowerCase.run(value);
|
|
2637
|
+
function isRejected(value) {
|
|
2638
|
+
return isType(value, PROMISE_TYPE_REJECTED);
|
|
2666
2639
|
}
|
|
2640
|
+
function isType(value, type) {
|
|
2641
|
+
return typeof value === "object" && value !== null && value.status === type;
|
|
2642
|
+
}
|
|
2643
|
+
//#endregion
|
|
2644
|
+
//#region src/result/misc.ts
|
|
2667
2645
|
/**
|
|
2668
|
-
*
|
|
2646
|
+
* Converts a _Result_ to a _Promise_
|
|
2669
2647
|
*
|
|
2670
|
-
*
|
|
2671
|
-
*
|
|
2648
|
+
* Resolves if ok, rejects for error
|
|
2649
|
+
*
|
|
2650
|
+
* @param result _Result_ to convert
|
|
2651
|
+
* @returns Promised result
|
|
2672
2652
|
*/
|
|
2673
|
-
function
|
|
2674
|
-
|
|
2653
|
+
async function toPromise(result) {
|
|
2654
|
+
const actual = typeof result === "function" ? result() : result;
|
|
2655
|
+
if (!isResult(actual)) return Promise.reject(new Error(RESULT_MESSAGE_PROMISE));
|
|
2656
|
+
return isOk(actual) ? Promise.resolve(actual.value) : Promise.reject(actual.error);
|
|
2675
2657
|
}
|
|
2658
|
+
const RESULT_MESSAGE_PROMISE = "toPromise expected to receive a Result";
|
|
2659
|
+
//#endregion
|
|
2660
|
+
//#region src/promise/misc.ts
|
|
2676
2661
|
/**
|
|
2677
|
-
*
|
|
2662
|
+
* Create a cancelable _Promise_
|
|
2678
2663
|
*
|
|
2679
|
-
* @param
|
|
2680
|
-
* @returns
|
|
2664
|
+
* @param executor Executor function for the _Promise_
|
|
2665
|
+
* @returns Cancelable _Promise_
|
|
2681
2666
|
*/
|
|
2682
|
-
function
|
|
2683
|
-
return
|
|
2667
|
+
function cancelable(executor) {
|
|
2668
|
+
return new CancelablePromise(executor);
|
|
2669
|
+
}
|
|
2670
|
+
function handleResult(status, parameters) {
|
|
2671
|
+
const { aborter, complete, data, handlers, index, value } = parameters;
|
|
2672
|
+
if (aborter?.signal.aborted ?? false) return;
|
|
2673
|
+
if (!complete && status === "rejected") {
|
|
2674
|
+
settlePromise(handlers.reject, value, aborter);
|
|
2675
|
+
return;
|
|
2676
|
+
}
|
|
2677
|
+
data.result[index] = !complete ? value : status === "fulfilled" ? {
|
|
2678
|
+
status,
|
|
2679
|
+
value
|
|
2680
|
+
} : {
|
|
2681
|
+
status,
|
|
2682
|
+
reason: value
|
|
2683
|
+
};
|
|
2684
|
+
if (index === data.last) settlePromise(handlers.resolve, data.result, aborter);
|
|
2685
|
+
}
|
|
2686
|
+
function settlePromise(settler, value, aborter) {
|
|
2687
|
+
aborter?.cancel();
|
|
2688
|
+
settler(value);
|
|
2689
|
+
}
|
|
2690
|
+
async function toResult(value) {
|
|
2691
|
+
const actual = typeof value === "function" ? value() : value;
|
|
2692
|
+
if (!(actual instanceof Promise)) return Promise.reject(/* @__PURE__ */ new TypeError(PROMISE_MESSAGE_EXPECTATION_RESULT));
|
|
2693
|
+
return actual.then((result) => ok(result)).catch((reason) => error(reason));
|
|
2694
|
+
}
|
|
2695
|
+
//#endregion
|
|
2696
|
+
//#region src/promise/delay.ts
|
|
2697
|
+
function delay(options) {
|
|
2698
|
+
const { signal, time } = getPromiseOptions(options);
|
|
2699
|
+
if (signal?.aborted ?? false) return Promise.reject(signal?.reason);
|
|
2700
|
+
const aborter = createAborter(signal, () => {
|
|
2701
|
+
timer.cancel();
|
|
2702
|
+
rejector(signal?.reason);
|
|
2703
|
+
});
|
|
2704
|
+
const timer = getTimer(TIMER_WAIT, () => settlePromise(resolver, void 0, aborter), time);
|
|
2705
|
+
let rejector;
|
|
2706
|
+
let resolver;
|
|
2707
|
+
return new Promise((resolve, reject) => {
|
|
2708
|
+
rejector = reject;
|
|
2709
|
+
resolver = resolve;
|
|
2710
|
+
if (time === 0) settlePromise(resolver, void 0, aborter);
|
|
2711
|
+
else timer();
|
|
2712
|
+
});
|
|
2713
|
+
}
|
|
2714
|
+
//#endregion
|
|
2715
|
+
//#region src/promise/timed.ts
|
|
2716
|
+
async function getTimedPromise(promise, time, signal) {
|
|
2717
|
+
const aborter = createAborter(signal, () => {
|
|
2718
|
+
timer.cancel();
|
|
2719
|
+
rejector(signal?.reason);
|
|
2720
|
+
});
|
|
2721
|
+
const timer = getTimer(TIMER_WAIT, () => settlePromise(rejector, new PromiseTimeoutError(), aborter), time);
|
|
2722
|
+
let rejector;
|
|
2723
|
+
return Promise.race([promise, new Promise((_, reject) => {
|
|
2724
|
+
rejector = reject;
|
|
2725
|
+
timer();
|
|
2726
|
+
})]).then((value) => {
|
|
2727
|
+
aborter?.cancel();
|
|
2728
|
+
timer.cancel();
|
|
2729
|
+
rejector(void 0);
|
|
2730
|
+
return value;
|
|
2731
|
+
});
|
|
2732
|
+
}
|
|
2733
|
+
async function timed(promise, options) {
|
|
2734
|
+
if (!(promise instanceof Promise)) return Promise.reject(/* @__PURE__ */ new TypeError(PROMISE_MESSAGE_EXPECTATION_TIMED));
|
|
2735
|
+
const { signal, time } = getPromiseOptions(options);
|
|
2736
|
+
if (signal?.aborted ?? false) return Promise.reject(signal?.reason);
|
|
2737
|
+
return time > 0 ? getTimedPromise(promise, time, signal) : promise;
|
|
2738
|
+
}
|
|
2739
|
+
//#endregion
|
|
2740
|
+
//#region src/promise/index.ts
|
|
2741
|
+
async function attemptPromise(value, options) {
|
|
2742
|
+
const isFunction = typeof value === "function";
|
|
2743
|
+
if (!isFunction && !(value instanceof Promise)) return Promise.reject(/* @__PURE__ */ new TypeError(PROMISE_MESSAGE_EXPECTATION_ATTEMPT));
|
|
2744
|
+
const { signal, time } = getPromiseOptions(options);
|
|
2745
|
+
if (signal?.aborted ?? false) return Promise.reject(signal?.reason);
|
|
2746
|
+
const aborter = createAborter(signal, () => {
|
|
2747
|
+
rejector(signal?.reason);
|
|
2748
|
+
});
|
|
2749
|
+
async function handler(resolve, reject) {
|
|
2750
|
+
try {
|
|
2751
|
+
let result = isFunction ? value() : await value;
|
|
2752
|
+
if (result instanceof Promise) result = await result;
|
|
2753
|
+
settlePromise(resolve, result, aborter);
|
|
2754
|
+
} catch (error) {
|
|
2755
|
+
settlePromise(reject, error, aborter);
|
|
2756
|
+
}
|
|
2757
|
+
}
|
|
2758
|
+
let rejector;
|
|
2759
|
+
const promise = new Promise((resolve, reject) => {
|
|
2760
|
+
rejector = reject;
|
|
2761
|
+
handler(resolve, reject);
|
|
2762
|
+
});
|
|
2763
|
+
return time > 0 ? getTimedPromise(promise, time, signal) : promise;
|
|
2764
|
+
}
|
|
2765
|
+
async function promises(items, options) {
|
|
2766
|
+
const { signal, strategy } = getPromisesOptions(options);
|
|
2767
|
+
if (signal?.aborted ?? false) return Promise.reject(signal?.reason);
|
|
2768
|
+
if (!Array.isArray(items)) return Promise.resolve([]);
|
|
2769
|
+
const actual = items.map((item) => typeof item === "function" ? item() : item).filter((item) => item instanceof Promise);
|
|
2770
|
+
const { length } = actual;
|
|
2771
|
+
if (length === 0) return Promise.resolve([]);
|
|
2772
|
+
const complete = strategy === PROMISE_STRATEGY_DEFAULT;
|
|
2773
|
+
const aborter = createAborter(signal, () => {
|
|
2774
|
+
handlers.reject(signal?.reason);
|
|
2775
|
+
});
|
|
2776
|
+
const data = {
|
|
2777
|
+
last: length - 1,
|
|
2778
|
+
result: []
|
|
2779
|
+
};
|
|
2780
|
+
let handlers;
|
|
2781
|
+
return new Promise((resolve, reject) => {
|
|
2782
|
+
handlers = {
|
|
2783
|
+
reject,
|
|
2784
|
+
resolve
|
|
2785
|
+
};
|
|
2786
|
+
for (let index = 0; index < length; index += 1) actual[index].then((value) => handleResult(PROMISE_TYPE_FULFILLED, {
|
|
2787
|
+
aborter,
|
|
2788
|
+
complete,
|
|
2789
|
+
data,
|
|
2790
|
+
handlers,
|
|
2791
|
+
index,
|
|
2792
|
+
value
|
|
2793
|
+
})).catch((reason) => handleResult(PROMISE_TYPE_REJECTED, {
|
|
2794
|
+
aborter,
|
|
2795
|
+
complete,
|
|
2796
|
+
data,
|
|
2797
|
+
handlers,
|
|
2798
|
+
index,
|
|
2799
|
+
value: reason
|
|
2800
|
+
}));
|
|
2801
|
+
});
|
|
2802
|
+
}
|
|
2803
|
+
promises.result = resultPromises;
|
|
2804
|
+
async function resultPromises(items, signal) {
|
|
2805
|
+
return promises(items, signal).then(getResultsFromPromises);
|
|
2806
|
+
}
|
|
2807
|
+
//#endregion
|
|
2808
|
+
//#region src/result/index.ts
|
|
2809
|
+
async function asyncAttempt(value, err) {
|
|
2810
|
+
try {
|
|
2811
|
+
let result = typeof value === "function" ? value() : await value;
|
|
2812
|
+
if (result instanceof Promise) result = await result;
|
|
2813
|
+
return ok(result);
|
|
2814
|
+
} catch (thrown) {
|
|
2815
|
+
return getError(err ?? thrown, err == null ? void 0 : thrown);
|
|
2816
|
+
}
|
|
2817
|
+
}
|
|
2818
|
+
function attempt(callback, err) {
|
|
2819
|
+
try {
|
|
2820
|
+
return ok(callback());
|
|
2821
|
+
} catch (thrown) {
|
|
2822
|
+
return getError(err ?? thrown, err == null ? void 0 : thrown);
|
|
2823
|
+
}
|
|
2824
|
+
}
|
|
2825
|
+
Object.defineProperty(attempt, "async", { value: asyncAttempt });
|
|
2826
|
+
//#endregion
|
|
2827
|
+
//#region src/result/match.ts
|
|
2828
|
+
async function asyncMatchResult(result, first, error) {
|
|
2829
|
+
let value;
|
|
2830
|
+
if (typeof result === "function") value = await result();
|
|
2831
|
+
else if (result instanceof Promise) value = await result;
|
|
2832
|
+
else value = result;
|
|
2833
|
+
if (!isResult(value)) throw new Error(MATCH_MESSAGE);
|
|
2834
|
+
const hasObj = typeof first === "object" && first !== null;
|
|
2835
|
+
const okHandler = hasObj ? first.ok : first;
|
|
2836
|
+
const errorHandler = hasObj ? first.error : error;
|
|
2837
|
+
if (isOk(value)) return okHandler(value.value);
|
|
2838
|
+
return errorHandler(value.error, value.original);
|
|
2684
2839
|
}
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
memoizedTitleCase ??= memoize((v) => v.length < 2 ? capitalize(v) : join(words(v).map(capitalize), " "));
|
|
2694
|
-
return memoizedTitleCase.run(value);
|
|
2840
|
+
function matchResult(result, first, error) {
|
|
2841
|
+
const value = typeof result === "function" ? result() : result;
|
|
2842
|
+
if (!isResult(value)) throw new Error(MATCH_MESSAGE);
|
|
2843
|
+
const hasObj = typeof first === "object" && first !== null;
|
|
2844
|
+
const okHandler = hasObj ? first.ok : first;
|
|
2845
|
+
const errorHandler = hasObj ? first.error : error;
|
|
2846
|
+
if (isOk(value)) return okHandler(value.value);
|
|
2847
|
+
return errorHandler(value.error, value.original);
|
|
2695
2848
|
}
|
|
2696
|
-
function
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
return
|
|
2849
|
+
const MATCH_MESSAGE = "`result.match` expected a Result or a function that returns a Result";
|
|
2850
|
+
Object.defineProperty(matchResult, "async", { value: asyncMatchResult });
|
|
2851
|
+
//#endregion
|
|
2852
|
+
//#region src/result/work/flow.ts
|
|
2853
|
+
function attemptAsyncFlow(...fns) {
|
|
2854
|
+
let Flow;
|
|
2855
|
+
return (...args) => asyncAttempt(() => {
|
|
2856
|
+
Flow ??= asyncFlow(...fns);
|
|
2857
|
+
return Flow(...args.map((value) => {
|
|
2858
|
+
if (isError(value)) throw value.error;
|
|
2859
|
+
return isOk(value) ? value.value : value;
|
|
2860
|
+
}));
|
|
2861
|
+
});
|
|
2703
2862
|
}
|
|
2704
|
-
function
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
const itemsLength = items.length;
|
|
2714
|
-
const partResult = [];
|
|
2715
|
-
let itemCount = 0;
|
|
2716
|
-
for (let itemIndex = 0; itemIndex < itemsLength; itemIndex += 1) {
|
|
2717
|
-
const item = items[itemIndex];
|
|
2718
|
-
if (item.length === 0) continue;
|
|
2719
|
-
if (!capitalizeAny || itemCount === 0 && partIndex === 0 && !capitalizeFirst) partResult.push(item.toLocaleLowerCase());
|
|
2720
|
-
else partResult.push(capitalize(item));
|
|
2721
|
-
itemCount += 1;
|
|
2722
|
-
}
|
|
2723
|
-
cased.push(join(partResult, delimiters[type]));
|
|
2724
|
-
}
|
|
2725
|
-
return join(cased, delimiters[type]);
|
|
2863
|
+
function attemptFlow(...fns) {
|
|
2864
|
+
let Flow;
|
|
2865
|
+
return (...args) => attempt(() => {
|
|
2866
|
+
Flow ??= flow(...fns);
|
|
2867
|
+
return Flow(...args.map((value) => {
|
|
2868
|
+
if (isError(value)) throw value.error;
|
|
2869
|
+
return isOk(value) ? value.value : value;
|
|
2870
|
+
}));
|
|
2871
|
+
});
|
|
2726
2872
|
}
|
|
2727
|
-
|
|
2728
|
-
|
|
2729
|
-
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
|
|
2733
|
-
function
|
|
2734
|
-
|
|
2735
|
-
|
|
2736
|
-
|
|
2873
|
+
Object.defineProperty(attemptFlow, "async", { value: attemptAsyncFlow });
|
|
2874
|
+
//#endregion
|
|
2875
|
+
//#region src/result/work/pipe.ts
|
|
2876
|
+
async function attemptAsyncPipe(initial, first, ...seconds) {
|
|
2877
|
+
return asyncAttempt(() => {
|
|
2878
|
+
if (isError(initial)) throw initial.error;
|
|
2879
|
+
const value = typeof initial === "function" ? initial() : isOk(initial) ? initial.value : initial;
|
|
2880
|
+
if (first == null) return value;
|
|
2881
|
+
return asyncPipe(value, ...[first, ...seconds]);
|
|
2882
|
+
});
|
|
2737
2883
|
}
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
|
|
2741
|
-
const
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
const REPLACEMENT_CAMEL_CASE = "$1-$2";
|
|
2748
|
-
const S = "s";
|
|
2749
|
-
const caseMemoizers = {};
|
|
2750
|
-
const delimiters = {
|
|
2751
|
-
[CASE_CAMEL]: DELIMTER_EMPTY,
|
|
2752
|
-
[CASE_KEBAB]: DELIMITER_HYPHEN,
|
|
2753
|
-
[CASE_PASCAL]: DELIMTER_EMPTY,
|
|
2754
|
-
[CASE_SNAKE]: DELIMITER_UNDERSCORE
|
|
2755
|
-
};
|
|
2756
|
-
let memoizedCapitalize;
|
|
2757
|
-
let memoizedLowerCase;
|
|
2758
|
-
let memoizedTitleCase;
|
|
2759
|
-
let memoizedUpperCase;
|
|
2884
|
+
function attemptPipe(initial, first, ...seconds) {
|
|
2885
|
+
return attempt(() => {
|
|
2886
|
+
if (isError(initial)) throw initial.error;
|
|
2887
|
+
const value = typeof initial === "function" ? initial() : isOk(initial) ? initial.value : initial;
|
|
2888
|
+
if (first == null) return value;
|
|
2889
|
+
return pipe(value, ...[first, ...seconds]);
|
|
2890
|
+
});
|
|
2891
|
+
}
|
|
2892
|
+
Object.defineProperty(attemptPipe, "async", { value: attemptAsyncPipe });
|
|
2760
2893
|
//#endregion
|
|
2761
2894
|
//#region src/string/match.ts
|
|
2762
2895
|
/**
|
|
@@ -2813,10 +2946,10 @@ function getHandler(input) {
|
|
|
2813
2946
|
case "string": return (item) => item[input];
|
|
2814
2947
|
default:
|
|
2815
2948
|
if (isPlainObject(input)) return getHandler(input.key ?? input.handler);
|
|
2816
|
-
throw new TypeError(
|
|
2949
|
+
throw new TypeError(FUZZY_MESSAGE_HANDLER);
|
|
2817
2950
|
}
|
|
2818
2951
|
}
|
|
2819
|
-
function
|
|
2952
|
+
function getFuzzyItems(items) {
|
|
2820
2953
|
return items.sort((first, second) => first.haystack.localeCompare(second.haystack)).map(({ item }) => item);
|
|
2821
2954
|
}
|
|
2822
2955
|
function getFuzzyOptions(input, state) {
|
|
@@ -2840,22 +2973,22 @@ function getFuzzyState(items, input) {
|
|
|
2840
2973
|
}
|
|
2841
2974
|
function getTolerance(input, state) {
|
|
2842
2975
|
if (typeof input === "number" && !Number.isNaN(input)) return input < 0 ? 0 : Math.floor(input);
|
|
2843
|
-
return state?.tolerance ??
|
|
2976
|
+
return state?.tolerance ?? FUZZY_PROXIMITY_THRESHOLD;
|
|
2844
2977
|
}
|
|
2845
2978
|
function fuzzy(items, configuration) {
|
|
2846
|
-
if (!Array.isArray(items)) throw new TypeError(
|
|
2979
|
+
if (!Array.isArray(items)) throw new TypeError(FUZZY_MESSAGE_ARRAY);
|
|
2847
2980
|
const state = getFuzzyState(items, configuration);
|
|
2848
2981
|
const instance = { search: (value, options) => search(state.items, state.strings, value, options == null ? state : getFuzzyOptions(options, state)) };
|
|
2849
2982
|
Object.defineProperties(instance, {
|
|
2850
2983
|
items: {
|
|
2984
|
+
enumerable: true,
|
|
2851
2985
|
get: () => state.items.slice(),
|
|
2852
|
-
set: (
|
|
2853
|
-
if (!Array.isArray(items)) throw new TypeError(MESSAGE_ARRAY);
|
|
2854
|
-
state.items = items.slice();
|
|
2855
|
-
state.strings = items.map(state.handler);
|
|
2856
|
-
}
|
|
2986
|
+
set: (value) => setItems(state, value)
|
|
2857
2987
|
},
|
|
2858
|
-
strings: {
|
|
2988
|
+
strings: {
|
|
2989
|
+
enumerable: true,
|
|
2990
|
+
get: () => state.strings.slice()
|
|
2991
|
+
}
|
|
2859
2992
|
});
|
|
2860
2993
|
return Object.freeze(instance);
|
|
2861
2994
|
}
|
|
@@ -2899,14 +3032,14 @@ function getScore(haystack, needle) {
|
|
|
2899
3032
|
if (haystackIndex === 0) score += 1;
|
|
2900
3033
|
if (previousMatchIndex !== -1) {
|
|
2901
3034
|
const gap = haystackIndex - previousMatchIndex - 1;
|
|
2902
|
-
score += Math.max(0,
|
|
3035
|
+
score += Math.max(0, FUZZY_PROXIMITY_THRESHOLD - gap);
|
|
2903
3036
|
}
|
|
2904
3037
|
previousMatchIndex = haystackIndex;
|
|
2905
3038
|
needleIndex += 1;
|
|
2906
3039
|
}
|
|
2907
3040
|
if (needleIndex === needleLength) break;
|
|
2908
3041
|
}
|
|
2909
|
-
score -= Math.floor(lowerCaseHaystack.length /
|
|
3042
|
+
score -= Math.floor(lowerCaseHaystack.length / FUZZY_LENGTH_DIVISOR);
|
|
2910
3043
|
return Math.max(0, score);
|
|
2911
3044
|
}
|
|
2912
3045
|
function search(items, strings, input, options) {
|
|
@@ -2949,18 +3082,23 @@ function search(items, strings, input, options) {
|
|
|
2949
3082
|
for (let index = 0; index < length; index += 1) {
|
|
2950
3083
|
const key = keys[index];
|
|
2951
3084
|
if (maxScore - key > options.tolerance) break;
|
|
2952
|
-
similar.push(...
|
|
3085
|
+
similar.push(...getFuzzyItems(scored[key]));
|
|
2953
3086
|
}
|
|
2954
3087
|
}
|
|
2955
|
-
result.exact =
|
|
3088
|
+
result.exact = getFuzzyItems(options.limit == null ? exact : exact.slice(0, options.limit));
|
|
2956
3089
|
if (options.limit == null) result.similar = similar;
|
|
2957
3090
|
else result.similar = similar.slice(0, options.limit - result.exact.length);
|
|
2958
3091
|
return result;
|
|
2959
3092
|
}
|
|
2960
|
-
|
|
2961
|
-
|
|
2962
|
-
|
|
2963
|
-
|
|
3093
|
+
function setItems(state, value) {
|
|
3094
|
+
if (!Array.isArray(value)) throw new TypeError(FUZZY_MESSAGE_ARRAY);
|
|
3095
|
+
state.items = value.slice();
|
|
3096
|
+
state.strings = value.map(state.handler);
|
|
3097
|
+
}
|
|
3098
|
+
const FUZZY_LENGTH_DIVISOR = 3;
|
|
3099
|
+
const FUZZY_MESSAGE_ARRAY = "Fuzzy requires an array of items";
|
|
3100
|
+
const FUZZY_MESSAGE_HANDLER = "Fuzzy requires a key or function to stringify items";
|
|
3101
|
+
const FUZZY_PROXIMITY_THRESHOLD = 5;
|
|
2964
3102
|
//#endregion
|
|
2965
3103
|
//#region src/string/index.ts
|
|
2966
3104
|
function dedent(value, ...values) {
|
|
@@ -2999,16 +3137,16 @@ function getUuid(html) {
|
|
|
2999
3137
|
crypto.getRandomValues(bytes);
|
|
3000
3138
|
bytes[6] = bytes[6] & 15 | 64;
|
|
3001
3139
|
bytes[8] = bytes[8] & 63 | 128;
|
|
3002
|
-
const hex = Array.from(bytes, (byte) => byte.toString(16).padStart(2,
|
|
3140
|
+
const hex = Array.from(bytes, (byte) => byte.toString(16).padStart(2, STRING_ZERO)).join("");
|
|
3003
3141
|
const first = hex.substring(0, 8);
|
|
3004
|
-
if (forHTML &&
|
|
3142
|
+
if (forHTML && STRING_NUMERICAL_PREFIX_PATTERN.test(first)) continue;
|
|
3005
3143
|
return [
|
|
3006
3144
|
first,
|
|
3007
3145
|
hex.substring(8, 12),
|
|
3008
3146
|
hex.substring(12, 16),
|
|
3009
3147
|
hex.substring(16, 20),
|
|
3010
3148
|
hex.substring(20, 32)
|
|
3011
|
-
].join(forHTML ?
|
|
3149
|
+
].join(forHTML ? STRING_DELIMITER_UUID_HTML : STRING_DELIMITER_UUID_DEFAULT);
|
|
3012
3150
|
}
|
|
3013
3151
|
}
|
|
3014
3152
|
/**
|
|
@@ -3051,10 +3189,10 @@ function truncate(value, length, suffix) {
|
|
|
3051
3189
|
const truncatedLength = length - actualSuffixLength;
|
|
3052
3190
|
return `${value.slice(0, truncatedLength)}${actualSuffix}`;
|
|
3053
3191
|
}
|
|
3054
|
-
const
|
|
3055
|
-
const
|
|
3056
|
-
const
|
|
3057
|
-
const
|
|
3192
|
+
const STRING_DELIMITER_UUID_DEFAULT = "-";
|
|
3193
|
+
const STRING_DELIMITER_UUID_HTML = "_";
|
|
3194
|
+
const STRING_NUMERICAL_PREFIX_PATTERN = /^\d/;
|
|
3195
|
+
const STRING_ZERO = "0";
|
|
3058
3196
|
//#endregion
|
|
3059
3197
|
//#region src/string/normalize.ts
|
|
3060
3198
|
/**
|
|
@@ -3066,8 +3204,8 @@ const ZERO = "0";
|
|
|
3066
3204
|
function deburr(value) {
|
|
3067
3205
|
if (typeof value !== "string") return "";
|
|
3068
3206
|
deburrMemoizer ??= memoize((value) => {
|
|
3069
|
-
let deburred = value.normalize(
|
|
3070
|
-
deburred = deburred.replace(
|
|
3207
|
+
let deburred = value.normalize(NORMALIZE_DEBURR_NORMALIZATION).replace(NORMALIZE_DEBURR_PATTERN_SIMPLE, "");
|
|
3208
|
+
deburred = deburred.replace(NORMALIZE_DEBURR_PATTERN_CHARACTERS, (_, character) => NORMALIZE_DEBURR_CHARACTERS[character]);
|
|
3071
3209
|
return deburred;
|
|
3072
3210
|
});
|
|
3073
3211
|
return deburrMemoizer.run(value);
|
|
@@ -3111,13 +3249,13 @@ function normalizeString(value, options) {
|
|
|
3111
3249
|
if (typeof value !== "string") return "";
|
|
3112
3250
|
let result = value;
|
|
3113
3251
|
if (options.trim) result = result.trim();
|
|
3114
|
-
if (options.whitespace) result = result.replace(
|
|
3252
|
+
if (options.whitespace) result = result.replace(NORMALIZE_WHITESPACE_PATTERN, NORMALIZE_WHITESPACE_REPLACEMENT);
|
|
3115
3253
|
if (options.deburr) result = deburr(result);
|
|
3116
3254
|
if (options.lowerCase) result = lowerCase(result);
|
|
3117
|
-
if (options.special) result = result.replace(
|
|
3118
|
-
return result.normalize(
|
|
3255
|
+
if (options.special) result = result.replace(NORMALIZE_SPECIAL_PATTERN, NORMALIZE_SPECIAL_REPLACEMENT);
|
|
3256
|
+
return result.normalize(NORMALIZE_NORMALIZATION_NORMALIZATION);
|
|
3119
3257
|
}
|
|
3120
|
-
const
|
|
3258
|
+
const NORMALIZE_DEBURR_CHARACTERS = {
|
|
3121
3259
|
Æ: "AE",
|
|
3122
3260
|
æ: "ae",
|
|
3123
3261
|
Ð: "D",
|
|
@@ -3149,14 +3287,14 @@ const DEBURR_CHARACTERS = {
|
|
|
3149
3287
|
Ŧ: "T",
|
|
3150
3288
|
ŧ: "t"
|
|
3151
3289
|
};
|
|
3152
|
-
const
|
|
3153
|
-
const
|
|
3154
|
-
const
|
|
3155
|
-
const
|
|
3156
|
-
const
|
|
3157
|
-
const
|
|
3158
|
-
const
|
|
3159
|
-
const
|
|
3290
|
+
const NORMALIZE_DEBURR_NORMALIZATION = "NFD";
|
|
3291
|
+
const NORMALIZE_DEBURR_PATTERN_CHARACTERS = new RegExp(`(${Object.keys(NORMALIZE_DEBURR_CHARACTERS).join("|")})`, "g");
|
|
3292
|
+
const NORMALIZE_DEBURR_PATTERN_SIMPLE = /[\u0300-\u036f]/g;
|
|
3293
|
+
const NORMALIZE_NORMALIZATION_NORMALIZATION = "NFC";
|
|
3294
|
+
const NORMALIZE_SPECIAL_PATTERN = /[\p{P}\p{S}]/gu;
|
|
3295
|
+
const NORMALIZE_SPECIAL_REPLACEMENT = "";
|
|
3296
|
+
const NORMALIZE_WHITESPACE_PATTERN = /\s+/g;
|
|
3297
|
+
const NORMALIZE_WHITESPACE_REPLACEMENT = " ";
|
|
3160
3298
|
let deburrMemoizer;
|
|
3161
3299
|
//#endregion
|
|
3162
3300
|
//#region src/string/template.ts
|
|
@@ -3169,7 +3307,7 @@ function getTemplateOptions(input) {
|
|
|
3169
3307
|
const options = isPlainObject(input) ? input : {};
|
|
3170
3308
|
return {
|
|
3171
3309
|
ignoreCase: options.ignoreCase === true,
|
|
3172
|
-
pattern: options.pattern instanceof RegExp ? options.pattern :
|
|
3310
|
+
pattern: options.pattern instanceof RegExp ? options.pattern : TEMPLATE_EXPRESSION_VARIABLE
|
|
3173
3311
|
};
|
|
3174
3312
|
}
|
|
3175
3313
|
function handleTemplate(value, pattern, ignoreCase, variables) {
|
|
@@ -3204,7 +3342,7 @@ function template(value, ...parameters) {
|
|
|
3204
3342
|
return handleTemplate(value, pattern, ignoreCase, parameters[0]);
|
|
3205
3343
|
}
|
|
3206
3344
|
template.initialize = initializeTemplater;
|
|
3207
|
-
const
|
|
3345
|
+
const TEMPLATE_EXPRESSION_VARIABLE = /{{([\s\S]+?)}}/g;
|
|
3208
3346
|
//#endregion
|
|
3209
3347
|
//#region src/value/clone.ts
|
|
3210
3348
|
const CLONE_NAME = "clone";
|
|
@@ -3218,21 +3356,21 @@ clone.handlers = getSelfHandlers(clone, {
|
|
|
3218
3356
|
clone.deregister = deregisterCloner;
|
|
3219
3357
|
clone.register = registerCloner;
|
|
3220
3358
|
function cloneArrayBuffer(value, depth, references) {
|
|
3221
|
-
if (typeof depth === "number" && depth >=
|
|
3359
|
+
if (typeof depth === "number" && depth >= CLONE_MAX_DEPTH) return value;
|
|
3222
3360
|
const cloned = new ArrayBuffer(value.byteLength);
|
|
3223
3361
|
new Uint8Array(cloned).set(new Uint8Array(value));
|
|
3224
3362
|
references?.set(value, cloned);
|
|
3225
3363
|
return cloned;
|
|
3226
3364
|
}
|
|
3227
3365
|
function cloneDataView(value, depth, references) {
|
|
3228
|
-
if (depth >=
|
|
3366
|
+
if (depth >= CLONE_MAX_DEPTH) return value;
|
|
3229
3367
|
const buffer = cloneArrayBuffer(value.buffer);
|
|
3230
3368
|
const cloned = new DataView(buffer, value.byteOffset, value.byteLength);
|
|
3231
3369
|
references.set(value, cloned);
|
|
3232
3370
|
return cloned;
|
|
3233
3371
|
}
|
|
3234
3372
|
function cloneMap(map, depth, references, flat) {
|
|
3235
|
-
if (depth >=
|
|
3373
|
+
if (depth >= CLONE_MAX_DEPTH) return map;
|
|
3236
3374
|
const cloned = /* @__PURE__ */ new Map();
|
|
3237
3375
|
const entries = map.entries();
|
|
3238
3376
|
for (const entry of entries) cloned.set(flat ? entry[0] : cloneValue(entry[0], depth + 1, references, false), flat ? entry[1] : cloneValue(entry[1], depth + 1, references, false));
|
|
@@ -3240,13 +3378,13 @@ function cloneMap(map, depth, references, flat) {
|
|
|
3240
3378
|
return cloned;
|
|
3241
3379
|
}
|
|
3242
3380
|
function cloneNode(node, depth, references) {
|
|
3243
|
-
if (depth >=
|
|
3381
|
+
if (depth >= CLONE_MAX_DEPTH) return node;
|
|
3244
3382
|
const cloned = node.cloneNode(true);
|
|
3245
3383
|
references.set(node, cloned);
|
|
3246
3384
|
return cloned;
|
|
3247
3385
|
}
|
|
3248
3386
|
function cloneObject(value, depth, references, flat) {
|
|
3249
|
-
if (flat || depth >=
|
|
3387
|
+
if (flat || depth >= CLONE_MAX_DEPTH) return Array.isArray(value) ? value.slice() : { ...value };
|
|
3250
3388
|
const cloned = Array.isArray(value) ? [] : {};
|
|
3251
3389
|
const keys = [...Object.keys(value), ...Object.getOwnPropertySymbols(value)];
|
|
3252
3390
|
const { length } = keys;
|
|
@@ -3258,14 +3396,14 @@ function cloneObject(value, depth, references, flat) {
|
|
|
3258
3396
|
return cloned;
|
|
3259
3397
|
}
|
|
3260
3398
|
function cloneRegularExpression(value, depth, references) {
|
|
3261
|
-
if (depth >=
|
|
3399
|
+
if (depth >= CLONE_MAX_DEPTH) return value;
|
|
3262
3400
|
const cloned = new RegExp(value.source, value.flags);
|
|
3263
3401
|
cloned.lastIndex = value.lastIndex;
|
|
3264
3402
|
references.set(value, cloned);
|
|
3265
3403
|
return cloned;
|
|
3266
3404
|
}
|
|
3267
3405
|
function cloneSet(set, depth, references, flat) {
|
|
3268
|
-
if (depth >=
|
|
3406
|
+
if (depth >= CLONE_MAX_DEPTH) return set;
|
|
3269
3407
|
const cloned = /* @__PURE__ */ new Set();
|
|
3270
3408
|
const values = [...set.values()];
|
|
3271
3409
|
const { length } = values;
|
|
@@ -3274,7 +3412,7 @@ function cloneSet(set, depth, references, flat) {
|
|
|
3274
3412
|
return cloned;
|
|
3275
3413
|
}
|
|
3276
3414
|
function cloneTypedArray(value, depth, references) {
|
|
3277
|
-
if (depth >=
|
|
3415
|
+
if (depth >= CLONE_MAX_DEPTH) return value;
|
|
3278
3416
|
const cloned = new value.constructor(value);
|
|
3279
3417
|
references.set(value, cloned);
|
|
3280
3418
|
return cloned;
|
|
@@ -3335,7 +3473,7 @@ function registerCloner(constructor, handler) {
|
|
|
3335
3473
|
clone.handlers.register(constructor, handler);
|
|
3336
3474
|
}
|
|
3337
3475
|
function tryStructuredClone(value, depth, references) {
|
|
3338
|
-
if (depth >=
|
|
3476
|
+
if (depth >= CLONE_MAX_DEPTH) return value;
|
|
3339
3477
|
try {
|
|
3340
3478
|
const cloned = structuredClone(value);
|
|
3341
3479
|
references.set(value, cloned);
|
|
@@ -3345,7 +3483,7 @@ function tryStructuredClone(value, depth, references) {
|
|
|
3345
3483
|
return value;
|
|
3346
3484
|
}
|
|
3347
3485
|
}
|
|
3348
|
-
const
|
|
3486
|
+
const CLONE_MAX_DEPTH = 100;
|
|
3349
3487
|
//#endregion
|
|
3350
3488
|
//#region src/value/collection.ts
|
|
3351
3489
|
function inMap(map, value, key) {
|
|
@@ -3609,7 +3747,7 @@ function shake(value) {
|
|
|
3609
3747
|
//#endregion
|
|
3610
3748
|
//#region src/value/smush.ts
|
|
3611
3749
|
function flattenObject(value, depth, smushed, prefix) {
|
|
3612
|
-
if (depth >=
|
|
3750
|
+
if (depth >= SMUSH_MAX_DEPTH) return {};
|
|
3613
3751
|
if (smushed.has(value)) return smushed.get(value);
|
|
3614
3752
|
const keys = Object.keys(value);
|
|
3615
3753
|
const { length } = keys;
|
|
@@ -3641,7 +3779,7 @@ function flattenObject(value, depth, smushed, prefix) {
|
|
|
3641
3779
|
function smush(value) {
|
|
3642
3780
|
return typeof value === "object" && value !== null ? flattenObject(value, 0, /* @__PURE__ */ new WeakMap()) : {};
|
|
3643
3781
|
}
|
|
3644
|
-
const
|
|
3782
|
+
const SMUSH_MAX_DEPTH = 100;
|
|
3645
3783
|
//#endregion
|
|
3646
3784
|
//#region src/value/unsmush.ts
|
|
3647
3785
|
function getKeys(value) {
|
|
@@ -3813,6 +3951,142 @@ function transformValue(value, transformer) {
|
|
|
3813
3951
|
return value;
|
|
3814
3952
|
}
|
|
3815
3953
|
//#endregion
|
|
3954
|
+
//#region src/internal/subscription.ts
|
|
3955
|
+
function addSubscription(subscriptions, subscription, state) {
|
|
3956
|
+
const { key, value } = state.parameters;
|
|
3957
|
+
const { items, values } = subscriptions.state;
|
|
3958
|
+
if (!isKey(key)) {
|
|
3959
|
+
items.any.add(subscription);
|
|
3960
|
+
values.from.any.set(value, subscription);
|
|
3961
|
+
values.to.any.set(subscription, value);
|
|
3962
|
+
return;
|
|
3963
|
+
}
|
|
3964
|
+
/* istanbul ignore if */
|
|
3965
|
+
if (items.keyed == null || values.from.keyed == null || values.to.keyed == null)
|
|
3966
|
+
// istanbul ignore next
|
|
3967
|
+
return;
|
|
3968
|
+
let keyedItems = items.keyed.get(key);
|
|
3969
|
+
if (keyedItems == null) {
|
|
3970
|
+
keyedItems = /* @__PURE__ */ new Set();
|
|
3971
|
+
items.keyed.set(key, keyedItems);
|
|
3972
|
+
}
|
|
3973
|
+
keyedItems.add(subscription);
|
|
3974
|
+
let keyedFrom = values.from.keyed.get(key);
|
|
3975
|
+
if (keyedFrom == null) {
|
|
3976
|
+
keyedFrom = /* @__PURE__ */ new Map();
|
|
3977
|
+
values.from.keyed.set(key, keyedFrom);
|
|
3978
|
+
}
|
|
3979
|
+
keyedFrom.set(value, subscription);
|
|
3980
|
+
let keyedTo = values.to.keyed.get(key);
|
|
3981
|
+
if (keyedTo == null) {
|
|
3982
|
+
keyedTo = /* @__PURE__ */ new Map();
|
|
3983
|
+
values.to.keyed.set(key, keyedTo);
|
|
3984
|
+
}
|
|
3985
|
+
keyedTo.set(subscription, value);
|
|
3986
|
+
}
|
|
3987
|
+
function clearSubscriptions(store) {
|
|
3988
|
+
for (const susbcription of store.values.to.any.keys()) susbcription.unsubscribe();
|
|
3989
|
+
if (store.values.to.keyed != null) for (const values of store.values.to.keyed.values()) for (const susbcription of values.keys()) susbcription.unsubscribe();
|
|
3990
|
+
}
|
|
3991
|
+
function createSubscription(subscriptions, property, parameters) {
|
|
3992
|
+
if (parameters.signal?.aborted ?? false) throw new Error(parameters.signal?.reason);
|
|
3993
|
+
const state = {
|
|
3994
|
+
parameters,
|
|
3995
|
+
active: true
|
|
3996
|
+
};
|
|
3997
|
+
const existing = getExistingSubscription(subscriptions, state);
|
|
3998
|
+
if (existing != null) return [existing, true];
|
|
3999
|
+
if (subscriptions.state.keys != null && isKey(parameters.key) && !subscriptions.state.keys.has(parameters.key)) throw new Error(SUBSCRIPTION_INVALID_KEY);
|
|
4000
|
+
state.aborter = createAborter(parameters.signal, () => unsubscribe(subscriptions, instance, state));
|
|
4001
|
+
const instance = { unsubscribe: () => unsubscribe(subscriptions, instance, state) };
|
|
4002
|
+
Object.defineProperties(instance, {
|
|
4003
|
+
[SUBSCRIPTION_PROPERTY]: { value: true },
|
|
4004
|
+
[property.key]: { value: property.value ?? "subscription" },
|
|
4005
|
+
active: {
|
|
4006
|
+
enumerable: true,
|
|
4007
|
+
get: () => (parameters.isActive?.() ?? true) && state.active
|
|
4008
|
+
}
|
|
4009
|
+
});
|
|
4010
|
+
addSubscription(subscriptions, instance, state);
|
|
4011
|
+
return [Object.freeze(instance), false];
|
|
4012
|
+
}
|
|
4013
|
+
function createSubscriptions(parameters) {
|
|
4014
|
+
const { keys, property } = parameters;
|
|
4015
|
+
const state = {
|
|
4016
|
+
keys,
|
|
4017
|
+
items: {
|
|
4018
|
+
any: /* @__PURE__ */ new Set(),
|
|
4019
|
+
keyed: keys == null ? void 0 : /* @__PURE__ */ new Map()
|
|
4020
|
+
},
|
|
4021
|
+
values: {
|
|
4022
|
+
from: {
|
|
4023
|
+
any: /* @__PURE__ */ new Map(),
|
|
4024
|
+
keyed: keys == null ? void 0 : /* @__PURE__ */ new Map()
|
|
4025
|
+
},
|
|
4026
|
+
to: {
|
|
4027
|
+
any: /* @__PURE__ */ new Map(),
|
|
4028
|
+
keyed: keys == null ? void 0 : /* @__PURE__ */ new Map()
|
|
4029
|
+
}
|
|
4030
|
+
}
|
|
4031
|
+
};
|
|
4032
|
+
const instance = {
|
|
4033
|
+
state,
|
|
4034
|
+
clear: () => clearSubscriptions(state),
|
|
4035
|
+
create: (parameters) => createSubscription(instance, property, parameters)
|
|
4036
|
+
};
|
|
4037
|
+
return instance;
|
|
4038
|
+
}
|
|
4039
|
+
function getExistingSubscription(subscriptions, state) {
|
|
4040
|
+
const { parameters } = state;
|
|
4041
|
+
const { values } = subscriptions.state;
|
|
4042
|
+
return isKey(parameters.key) ? values.from.keyed?.get(parameters.key)?.get(parameters.value) : values.from.any.get(parameters.value);
|
|
4043
|
+
}
|
|
4044
|
+
/**
|
|
4045
|
+
* Is the value a subscription?
|
|
4046
|
+
*
|
|
4047
|
+
* @param value Value to check
|
|
4048
|
+
* @returns `true` if the value is a subscription, otherwise `false`
|
|
4049
|
+
*/
|
|
4050
|
+
function isSubscription(value) {
|
|
4051
|
+
return isPlainObject(value) && SUBSCRIPTION_PROPERTY in value && value[SUBSCRIPTION_PROPERTY] === true;
|
|
4052
|
+
}
|
|
4053
|
+
function removeFromStore(items, values, subscription, value, key) {
|
|
4054
|
+
items.delete(subscription);
|
|
4055
|
+
if (key == null) {
|
|
4056
|
+
values.from.any.delete(value);
|
|
4057
|
+
values.to.any.delete(subscription);
|
|
4058
|
+
} else {
|
|
4059
|
+
values.from.keyed?.get(key)?.delete(value);
|
|
4060
|
+
values.to.keyed?.get(key)?.delete(subscription);
|
|
4061
|
+
}
|
|
4062
|
+
}
|
|
4063
|
+
function removeSubscription(subscriptions, subscription, state) {
|
|
4064
|
+
if (!state.active) return;
|
|
4065
|
+
state.aborter = void 0;
|
|
4066
|
+
state.active = false;
|
|
4067
|
+
state.parameters.isActive = void 0;
|
|
4068
|
+
state.parameters.signal = void 0;
|
|
4069
|
+
const { key, value } = state.parameters;
|
|
4070
|
+
const { items, values } = subscriptions.state;
|
|
4071
|
+
if (!isKey(key)) {
|
|
4072
|
+
removeFromStore(items.any, values, subscription, value);
|
|
4073
|
+
return;
|
|
4074
|
+
}
|
|
4075
|
+
const keyed = items.keyed?.get(key);
|
|
4076
|
+
/* istanbul ignore if */
|
|
4077
|
+
if (items.keyed == null || keyed == null)
|
|
4078
|
+
// istanbul ignore next
|
|
4079
|
+
return;
|
|
4080
|
+
removeFromStore(keyed, values, subscription, value, key);
|
|
4081
|
+
if (keyed.size === 0) items.keyed.delete(key);
|
|
4082
|
+
}
|
|
4083
|
+
function unsubscribe(subscriptions, subscription, state) {
|
|
4084
|
+
state.aborter?.cancel();
|
|
4085
|
+
removeSubscription(subscriptions, subscription, state);
|
|
4086
|
+
}
|
|
4087
|
+
const SUBSCRIPTION_INVALID_KEY = "Invalid key for subscription";
|
|
4088
|
+
const SUBSCRIPTION_PROPERTY = "$subscription";
|
|
4089
|
+
//#endregion
|
|
3816
4090
|
//#region src/beacon.ts
|
|
3817
4091
|
/**
|
|
3818
4092
|
* Create a new beacon
|
|
@@ -3827,38 +4101,23 @@ function beacon(value, options) {
|
|
|
3827
4101
|
active: true,
|
|
3828
4102
|
observable: void 0,
|
|
3829
4103
|
options: getBeaconOptions(options),
|
|
3830
|
-
subscriptions:
|
|
4104
|
+
subscriptions: createSubscriptions({ property: beaconSubscription })
|
|
3831
4105
|
};
|
|
3832
4106
|
const instance = {
|
|
3833
|
-
deactivate: () =>
|
|
3834
|
-
|
|
3835
|
-
|
|
3836
|
-
|
|
3837
|
-
update$1(TYPE_NEXT, state, value, finish);
|
|
3838
|
-
},
|
|
3839
|
-
error: (value, finish) => {
|
|
3840
|
-
update$1(TYPE_ERROR, state, value, finish);
|
|
3841
|
-
},
|
|
3842
|
-
finish: () => {
|
|
3843
|
-
finishBeacon(state, true);
|
|
3844
|
-
}
|
|
4107
|
+
deactivate: () => finishBeacon(state, false),
|
|
4108
|
+
emit: (value, finish) => updateBeacon(BEACON_TYPE_NEXT, state, value, finish),
|
|
4109
|
+
error: (value, finish) => updateBeacon(BEACON_TYPE_ERROR, state, value, finish),
|
|
4110
|
+
finish: () => finishBeacon(state, true)
|
|
3845
4111
|
};
|
|
3846
4112
|
Object.defineProperties(instance, {
|
|
3847
|
-
[
|
|
3848
|
-
enumerable: false,
|
|
3849
|
-
value: NAME_BEACON
|
|
3850
|
-
},
|
|
4113
|
+
[BEACON_PROPERTY]: { value: BEACON_NAME },
|
|
3851
4114
|
active: {
|
|
3852
4115
|
enumerable: true,
|
|
3853
4116
|
get: () => state.active
|
|
3854
4117
|
},
|
|
3855
4118
|
observable: {
|
|
3856
4119
|
enumerable: true,
|
|
3857
|
-
get: () =>
|
|
3858
|
-
if (!state.active) throw new Error(MESSAGE_BEACON);
|
|
3859
|
-
state.observable ??= observe(state);
|
|
3860
|
-
return state.observable;
|
|
3861
|
-
}
|
|
4120
|
+
get: () => getObservable(state)
|
|
3862
4121
|
},
|
|
3863
4122
|
value: {
|
|
3864
4123
|
enumerable: true,
|
|
@@ -3870,8 +4129,8 @@ function beacon(value, options) {
|
|
|
3870
4129
|
function finishBeacon(state, emit) {
|
|
3871
4130
|
if (!state.active) return;
|
|
3872
4131
|
state.active = false;
|
|
3873
|
-
for (const [, observer] of state.subscriptions.values.to.any) if (emit) observer.complete?.();
|
|
3874
|
-
|
|
4132
|
+
for (const [, observer] of state.subscriptions.state.values.to.any) if (emit) observer.complete?.();
|
|
4133
|
+
state.subscriptions.clear();
|
|
3875
4134
|
state.observable?.deactivate();
|
|
3876
4135
|
state.observable = void 0;
|
|
3877
4136
|
}
|
|
@@ -3880,6 +4139,11 @@ function getBeaconOptions(input) {
|
|
|
3880
4139
|
options.equal = typeof options.equal === "function" ? options.equal : Object.is;
|
|
3881
4140
|
return options;
|
|
3882
4141
|
}
|
|
4142
|
+
function getObservable(state) {
|
|
4143
|
+
if (!state.active) throw new Error(BEACON_MESSAGE_RETRIEVE);
|
|
4144
|
+
state.observable ??= observeBeacon(state);
|
|
4145
|
+
return state.observable;
|
|
4146
|
+
}
|
|
3883
4147
|
function getObservableCallback(value) {
|
|
3884
4148
|
return typeof value === "function" ? value : noop;
|
|
3885
4149
|
}
|
|
@@ -3904,10 +4168,19 @@ function getObserver(first, second, third) {
|
|
|
3904
4168
|
* @returns `true` if the value is a beacon, otherwise `false`
|
|
3905
4169
|
*/
|
|
3906
4170
|
function isBeacon(value) {
|
|
3907
|
-
return isBeaconInstance(
|
|
4171
|
+
return isBeaconInstance(BEACON_NAME, value);
|
|
3908
4172
|
}
|
|
3909
4173
|
function isBeaconInstance(name, value) {
|
|
3910
|
-
return isPlainObject(value) && value[
|
|
4174
|
+
return isPlainObject(value) && value[BEACON_PROPERTY] === name;
|
|
4175
|
+
}
|
|
4176
|
+
/**
|
|
4177
|
+
* Is the value a beacon subscription?
|
|
4178
|
+
*
|
|
4179
|
+
* @param value Value to check
|
|
4180
|
+
* @returns `true` if the value is a beacon subscription, otherwise `false`
|
|
4181
|
+
*/
|
|
4182
|
+
function isBeaconSubscription(value) {
|
|
4183
|
+
return isSubscription(value) && value[BEACON_PROPERTY] === "subscription";
|
|
3911
4184
|
}
|
|
3912
4185
|
/**
|
|
3913
4186
|
* Is the value an observable?
|
|
@@ -3916,9 +4189,9 @@ function isBeaconInstance(name, value) {
|
|
|
3916
4189
|
* @returns `true` if the value is an observable, otherwise `false`
|
|
3917
4190
|
*/
|
|
3918
4191
|
function isObservable(value) {
|
|
3919
|
-
return isBeaconInstance(
|
|
4192
|
+
return isBeaconInstance(BEACON_OBSERVABLE, value);
|
|
3920
4193
|
}
|
|
3921
|
-
function
|
|
4194
|
+
function observeBeacon(beacon) {
|
|
3922
4195
|
const state = {
|
|
3923
4196
|
beacon,
|
|
3924
4197
|
active: beacon.active
|
|
@@ -3927,24 +4200,10 @@ function observe(beacon) {
|
|
|
3927
4200
|
deactivate: () => {
|
|
3928
4201
|
state.active = false;
|
|
3929
4202
|
},
|
|
3930
|
-
subscribe(first, second, third)
|
|
3931
|
-
if (!beacon.active || !state.active) throw new Error(MESSAGE_OBSERVABLE);
|
|
3932
|
-
const observer = getObserver(first, second, third);
|
|
3933
|
-
const subscription = getSubscription({
|
|
3934
|
-
isActive: () => beacon.active && state.active,
|
|
3935
|
-
property: beaconSubscription,
|
|
3936
|
-
subscriptions: beacon.subscriptions,
|
|
3937
|
-
value: observer
|
|
3938
|
-
});
|
|
3939
|
-
observer.next?.(beacon.value);
|
|
3940
|
-
return subscription;
|
|
3941
|
-
}
|
|
4203
|
+
subscribe: (first, second, third) => subscribeToObservable(state, first, second, third)
|
|
3942
4204
|
};
|
|
3943
4205
|
Object.defineProperties(instance, {
|
|
3944
|
-
[
|
|
3945
|
-
enumerable: false,
|
|
3946
|
-
value: NAME_OBSERVABLE
|
|
3947
|
-
},
|
|
4206
|
+
[BEACON_PROPERTY]: { value: BEACON_OBSERVABLE },
|
|
3948
4207
|
active: {
|
|
3949
4208
|
enumerable: true,
|
|
3950
4209
|
get: () => beacon.active && state.active
|
|
@@ -3952,26 +4211,139 @@ function observe(beacon) {
|
|
|
3952
4211
|
});
|
|
3953
4212
|
return Object.freeze(instance);
|
|
3954
4213
|
}
|
|
3955
|
-
function
|
|
3956
|
-
if (!state.active)
|
|
3957
|
-
|
|
3958
|
-
|
|
3959
|
-
state.
|
|
3960
|
-
|
|
3961
|
-
|
|
3962
|
-
|
|
4214
|
+
function subscribeToObservable(state, first, second, third) {
|
|
4215
|
+
if (!state.beacon.active || !state.active) throw new Error(BEACON_MESSAGE_SUBSCRIBE);
|
|
4216
|
+
const observer = getObserver(first, second, third);
|
|
4217
|
+
const [subscription] = state.beacon.subscriptions.create({
|
|
4218
|
+
isActive: () => state.beacon.active && state.active,
|
|
4219
|
+
value: observer
|
|
4220
|
+
});
|
|
4221
|
+
observer.next?.(state.beacon.value);
|
|
4222
|
+
return subscription;
|
|
4223
|
+
}
|
|
4224
|
+
function updateBeacon(type, state, value, finish) {
|
|
4225
|
+
if (!state.active) return;
|
|
4226
|
+
if (type === BEACON_TYPE_NEXT) {
|
|
4227
|
+
if (state.options.equal(state.value, value)) return;
|
|
4228
|
+
state.value = value;
|
|
4229
|
+
}
|
|
4230
|
+
for (const [, observer] of state.subscriptions.state.values.to.any) observer[type]?.(value);
|
|
4231
|
+
if (finish === true) finishBeacon(state, true);
|
|
4232
|
+
}
|
|
4233
|
+
const BEACON_MESSAGE_RETRIEVE = "Cannot retrieve observable from a closed beacon";
|
|
4234
|
+
const BEACON_MESSAGE_SUBSCRIBE = "Cannot subscribe to a closed observable";
|
|
4235
|
+
const BEACON_PROPERTY = "$beacon";
|
|
4236
|
+
const BEACON_NAME = "beacon";
|
|
4237
|
+
const BEACON_OBSERVABLE = "observable";
|
|
4238
|
+
const BEACON_TYPE_ERROR = "error";
|
|
4239
|
+
const BEACON_TYPE_NEXT = "next";
|
|
4240
|
+
const beaconSubscription = { key: BEACON_PROPERTY };
|
|
4241
|
+
//#endregion
|
|
4242
|
+
//#region src/internal/herald.ts
|
|
4243
|
+
function createEvents(herald, state) {
|
|
4244
|
+
const events = {};
|
|
4245
|
+
Object.defineProperty(events, HERALD_PROPERTY, { value: HERALD_NAME_EVENTS });
|
|
4246
|
+
for (const key of state.keys) events[key] = (callback, signal) => herald.subscribe(key, callback, signal);
|
|
4247
|
+
return Object.freeze(events);
|
|
4248
|
+
}
|
|
4249
|
+
function emitForHerald(state, event, ...parameters) {
|
|
4250
|
+
const items = state.subscriptions.state.values.from.keyed?.get(event);
|
|
4251
|
+
if (items == null || items.size === 0) return;
|
|
4252
|
+
for (const [callback] of items) callback(...parameters);
|
|
4253
|
+
}
|
|
4254
|
+
function getHeraldSubscriptionProperty(input) {
|
|
4255
|
+
if (input == null) return heraldSubscription;
|
|
4256
|
+
const property = isPlainObject(input) ? input : {};
|
|
4257
|
+
if (typeof property.key !== "string" || property.value != null && typeof property.value !== "string") throw new Error(HERALD_MESSAGE_PROPERTY);
|
|
4258
|
+
return {
|
|
4259
|
+
key: property.key,
|
|
4260
|
+
value: property.value
|
|
4261
|
+
};
|
|
4262
|
+
}
|
|
4263
|
+
function getHeraldState(input) {
|
|
4264
|
+
const options = isPlainObject(input) ? input : {};
|
|
4265
|
+
if (!Array.isArray(options.names) || options.names.length === 0 || !options.names.every((name) => typeof name === "string")) throw new Error(HERALD_MESSAGE_ARRAY);
|
|
4266
|
+
if (options.onCreate != null && typeof options.onCreate !== "function") throw new Error(HERALD_MESSAGE_ONCREATE);
|
|
4267
|
+
const keys = new Set(options.names);
|
|
4268
|
+
return {
|
|
4269
|
+
keys,
|
|
4270
|
+
subscriptions: createSubscriptions({
|
|
4271
|
+
keys,
|
|
4272
|
+
property: getHeraldSubscriptionProperty(options.property)
|
|
4273
|
+
}),
|
|
4274
|
+
onCreate: options.onCreate
|
|
4275
|
+
};
|
|
4276
|
+
}
|
|
4277
|
+
/**
|
|
4278
|
+
* Create a _Herald_ for announcing named events
|
|
4279
|
+
*
|
|
4280
|
+
* @param names Event names
|
|
4281
|
+
* @param property Optional property for subscription identification _(defaults to `$herald`)_
|
|
4282
|
+
* @returns _Herald_ instance
|
|
4283
|
+
*/
|
|
4284
|
+
function herald(options) {
|
|
4285
|
+
const state = getHeraldState(options);
|
|
4286
|
+
const instance = {
|
|
4287
|
+
clear: () => state.subscriptions.clear(),
|
|
4288
|
+
emit: (event, ...parameters) => emitForHerald(state, event, ...parameters),
|
|
4289
|
+
observed: (event) => (state.subscriptions.state.items.keyed?.get(event)?.size ?? 0) > 0,
|
|
4290
|
+
subscribe: (key, callback, signal) => subscribeToHerald(state, key, callback, signal)
|
|
4291
|
+
};
|
|
4292
|
+
Object.defineProperties(instance, {
|
|
4293
|
+
[HERALD_PROPERTY]: { value: HERALD_NAME_HERALD },
|
|
4294
|
+
events: {
|
|
4295
|
+
enumerable: true,
|
|
4296
|
+
value: createEvents(instance, state)
|
|
4297
|
+
}
|
|
4298
|
+
});
|
|
4299
|
+
return Object.freeze(instance);
|
|
4300
|
+
}
|
|
4301
|
+
/**
|
|
4302
|
+
* Is the value a herald?
|
|
4303
|
+
*
|
|
4304
|
+
* @param value Value to check
|
|
4305
|
+
* @returns `true` if the value is a herald, otherwise `false`
|
|
4306
|
+
*/
|
|
4307
|
+
function isHerald(value) {
|
|
4308
|
+
return isHeraldInstance(HERALD_NAME_HERALD, value);
|
|
4309
|
+
}
|
|
4310
|
+
/**
|
|
4311
|
+
* Is the value events for a herald?
|
|
4312
|
+
*
|
|
4313
|
+
* @param value Value to check
|
|
4314
|
+
* @returns `true` if the value is events for a herald, otherwise `false`
|
|
4315
|
+
*/
|
|
4316
|
+
function isHeraldEvents(value) {
|
|
4317
|
+
return isHeraldInstance(HERALD_NAME_EVENTS, value);
|
|
3963
4318
|
}
|
|
3964
|
-
|
|
3965
|
-
|
|
3966
|
-
|
|
3967
|
-
|
|
3968
|
-
|
|
3969
|
-
|
|
3970
|
-
|
|
3971
|
-
|
|
3972
|
-
|
|
3973
|
-
|
|
3974
|
-
|
|
4319
|
+
function isHeraldInstance(name, value) {
|
|
4320
|
+
return isPlainObject(value) && HERALD_PROPERTY in value && value[HERALD_PROPERTY] === name;
|
|
4321
|
+
}
|
|
4322
|
+
/**
|
|
4323
|
+
* Is the value a herald subscription?
|
|
4324
|
+
*
|
|
4325
|
+
* @param value Value to check
|
|
4326
|
+
* @returns `true` if the value is a herald subscription, otherwise `false`
|
|
4327
|
+
*/
|
|
4328
|
+
function isHeraldSubscription(value) {
|
|
4329
|
+
return isSubscription(value) && value[HERALD_PROPERTY] === "subscription";
|
|
4330
|
+
}
|
|
4331
|
+
function subscribeToHerald(state, key, callback, signal) {
|
|
4332
|
+
const [subscription, existing] = state.subscriptions.create({
|
|
4333
|
+
key,
|
|
4334
|
+
signal,
|
|
4335
|
+
value: callback
|
|
4336
|
+
});
|
|
4337
|
+
if (!existing) state.onCreate?.(key, callback, subscription);
|
|
4338
|
+
return subscription;
|
|
4339
|
+
}
|
|
4340
|
+
const HERALD_PROPERTY = "$herald";
|
|
4341
|
+
const HERALD_MESSAGE_ARRAY = "Herald requires an array of event names.";
|
|
4342
|
+
const HERALD_MESSAGE_ONCREATE = `Herald requires a valid onCreate callback for subscription creation`;
|
|
4343
|
+
const HERALD_MESSAGE_PROPERTY = `Herald requires valid property information for subscription identification`;
|
|
4344
|
+
const HERALD_NAME_EVENTS = "events";
|
|
4345
|
+
const HERALD_NAME_HERALD = "herald";
|
|
4346
|
+
const heraldSubscription = { key: HERALD_PROPERTY };
|
|
3975
4347
|
//#endregion
|
|
3976
4348
|
//#region src/color/constants.ts
|
|
3977
4349
|
const COLOR_ALPHA = {
|
|
@@ -4042,10 +4414,7 @@ const COLOR_MAX = {
|
|
|
4042
4414
|
hex: 255,
|
|
4043
4415
|
percent: 100
|
|
4044
4416
|
};
|
|
4045
|
-
const COLOR_PROPERTY = {
|
|
4046
|
-
name: "$color",
|
|
4047
|
-
subscription: "subscription"
|
|
4048
|
-
};
|
|
4417
|
+
const COLOR_PROPERTY = { name: "$color" };
|
|
4049
4418
|
const COLOR_TYPE = {
|
|
4050
4419
|
all: void 0,
|
|
4051
4420
|
hex: "hex",
|
|
@@ -4055,7 +4424,8 @@ const COLOR_TYPE = {
|
|
|
4055
4424
|
hwb: "hwb",
|
|
4056
4425
|
hwba: "hwba",
|
|
4057
4426
|
rgb: "rgb",
|
|
4058
|
-
rgba: "rgba"
|
|
4427
|
+
rgba: "rgba",
|
|
4428
|
+
wildcard: "*"
|
|
4059
4429
|
};
|
|
4060
4430
|
COLOR_TYPE.all = /* @__PURE__ */ new Set([
|
|
4061
4431
|
COLOR_ALPHA.name,
|
|
@@ -4967,7 +5337,7 @@ function getDefaultColorState() {
|
|
|
4967
5337
|
origin: COLOR_TYPE.hex
|
|
4968
5338
|
};
|
|
4969
5339
|
}
|
|
4970
|
-
function setColorValue(color, state,
|
|
5340
|
+
function setColorValue(color, state, changes, type, value, alpha) {
|
|
4971
5341
|
state.hex = void 0;
|
|
4972
5342
|
state.hsl = void 0;
|
|
4973
5343
|
state.hwb = void 0;
|
|
@@ -4975,36 +5345,33 @@ function setColorValue(color, state, subscriptions, type, value, alpha) {
|
|
|
4975
5345
|
state.origin = type;
|
|
4976
5346
|
state[type] = value;
|
|
4977
5347
|
if (alpha != null) state.alpha = getAlpha(alpha, type === COLOR_TYPE.hex);
|
|
4978
|
-
for (const type of COLOR_TYPE.all)
|
|
4979
|
-
|
|
4980
|
-
if (callbacks != null) for (const callback of callbacks.values()) callback(color[type]);
|
|
4981
|
-
}
|
|
4982
|
-
for (const callback of subscriptions.values.to.any.values()) callback(color);
|
|
5348
|
+
for (const type of COLOR_TYPE.all) if (changes.observed(type)) changes.emit(type, color[type]);
|
|
5349
|
+
changes.emit(COLOR_TYPE.wildcard, color);
|
|
4983
5350
|
}
|
|
4984
|
-
function setHexColor(color, state,
|
|
5351
|
+
function setHexColor(color, state, changes, value, alpha) {
|
|
4985
5352
|
if (!isHexColor(value) || !alpha && value === state.hex) return;
|
|
4986
5353
|
const normalized = getNormalizedHex(value, true);
|
|
4987
|
-
setColorValue(color, state,
|
|
5354
|
+
setColorValue(color, state, changes, COLOR_TYPE.hex, normalized.slice(0, COLOR_LENGTHS.hexLong), alpha ? normalized.slice(COLOR_LENGTHS.hexLong) : void 0);
|
|
4988
5355
|
}
|
|
4989
|
-
function setHSLColor(color, state,
|
|
5356
|
+
function setHSLColor(color, state, changes, value, alpha) {
|
|
4990
5357
|
if (!isHslLike(value)) return;
|
|
4991
|
-
setColorValue(color, state,
|
|
5358
|
+
setColorValue(color, state, changes, COLOR_TYPE.hsl, {
|
|
4992
5359
|
hue: getDegrees(value.hue),
|
|
4993
5360
|
saturation: getPercentage(value.saturation),
|
|
4994
5361
|
lightness: getPercentage(value.lightness)
|
|
4995
5362
|
}, alpha ? value.alpha : void 0);
|
|
4996
5363
|
}
|
|
4997
|
-
function setHWBColor(color, state,
|
|
5364
|
+
function setHWBColor(color, state, changes, value, alpha) {
|
|
4998
5365
|
if (!isHwbLike(value)) return;
|
|
4999
|
-
setColorValue(color, state,
|
|
5366
|
+
setColorValue(color, state, changes, COLOR_TYPE.hwb, {
|
|
5000
5367
|
hue: getDegrees(value.hue),
|
|
5001
5368
|
whiteness: getPercentage(value.whiteness),
|
|
5002
5369
|
blackness: getPercentage(value.blackness)
|
|
5003
5370
|
}, alpha ? value.alpha : void 0);
|
|
5004
5371
|
}
|
|
5005
|
-
function setRGBColor(color, state,
|
|
5372
|
+
function setRGBColor(color, state, changes, value, alpha) {
|
|
5006
5373
|
if (!isRgbLike(value)) return;
|
|
5007
|
-
setColorValue(color, state,
|
|
5374
|
+
setColorValue(color, state, changes, COLOR_TYPE.rgb, {
|
|
5008
5375
|
red: getHexValue(value.red),
|
|
5009
5376
|
green: getHexValue(value.green),
|
|
5010
5377
|
blue: getHexValue(value.blue)
|
|
@@ -5018,6 +5385,9 @@ const getters = {
|
|
|
5018
5385
|
};
|
|
5019
5386
|
//#endregion
|
|
5020
5387
|
//#region src/color/misc/format.ts
|
|
5388
|
+
function formatHexColor(color, alpha) {
|
|
5389
|
+
return `#${alpha === true ? color.hexa : color.hex}`;
|
|
5390
|
+
}
|
|
5021
5391
|
function formatHslColor(state, alpha) {
|
|
5022
5392
|
const { hue, lightness, saturation } = getColorFromState(state, COLOR_TYPE.hsl);
|
|
5023
5393
|
return `hsl(${hue}deg ${saturation}% ${lightness}%${getSuffix(state, alpha)})`;
|
|
@@ -5036,51 +5406,56 @@ function getSuffix(state, alpha) {
|
|
|
5036
5406
|
//#endregion
|
|
5037
5407
|
//#region src/color/instance.ts
|
|
5038
5408
|
function color(value) {
|
|
5409
|
+
const changes = herald({
|
|
5410
|
+
names: [COLOR_TYPE.wildcard, ...COLOR_TYPE.all],
|
|
5411
|
+
property: colorSubscription,
|
|
5412
|
+
onCreate: (event, callback) => onCreateSubscription(instance, event, callback)
|
|
5413
|
+
});
|
|
5039
5414
|
const state = getColorState(value);
|
|
5040
|
-
const subscriptions = getSubscriptions(COLOR_TYPE.all);
|
|
5041
5415
|
const instance = {
|
|
5042
|
-
subscribe: (
|
|
5043
|
-
toHexString: (alpha) =>
|
|
5416
|
+
subscribe: (callback, signal) => changes.subscribe(COLOR_TYPE.wildcard, callback, signal),
|
|
5417
|
+
toHexString: (alpha) => formatHexColor(instance, alpha),
|
|
5044
5418
|
toHslString: (alpha) => formatHslColor(state, alpha),
|
|
5045
5419
|
toHwbString: (alpha) => formatHwbColor(state, alpha),
|
|
5046
5420
|
toRgbString: (alpha) => formatRgbColor(state, alpha),
|
|
5047
5421
|
toString: () => instance.toHexString(),
|
|
5048
|
-
unsubscribe: () =>
|
|
5422
|
+
unsubscribe: () => changes.clear()
|
|
5049
5423
|
};
|
|
5050
5424
|
Object.defineProperties(instance, {
|
|
5051
|
-
[COLOR_PROPERTY.name]: {
|
|
5052
|
-
enumerable: false,
|
|
5053
|
-
value: true
|
|
5054
|
-
},
|
|
5425
|
+
[COLOR_PROPERTY.name]: { value: true },
|
|
5055
5426
|
alpha: {
|
|
5056
5427
|
enumerable: true,
|
|
5057
5428
|
get: () => state.alpha.value,
|
|
5058
5429
|
set: (value) => setAlphaValue(state, value)
|
|
5059
5430
|
},
|
|
5060
|
-
|
|
5061
|
-
|
|
5062
|
-
|
|
5063
|
-
|
|
5064
|
-
|
|
5065
|
-
|
|
5431
|
+
changes: {
|
|
5432
|
+
enumerable: true,
|
|
5433
|
+
value: changes.events
|
|
5434
|
+
},
|
|
5435
|
+
hex: getColorProperty(COLOR_TYPE.hex, instance, state, changes, false),
|
|
5436
|
+
hexa: getColorProperty(COLOR_TYPE.hex, instance, state, changes, true),
|
|
5437
|
+
hsl: getColorProperty(COLOR_TYPE.hsl, instance, state, changes, false),
|
|
5438
|
+
hsla: getColorProperty(COLOR_TYPE.hsl, instance, state, changes, true),
|
|
5439
|
+
hwb: getColorProperty(COLOR_TYPE.hwb, instance, state, changes, false),
|
|
5440
|
+
hwba: getColorProperty(COLOR_TYPE.hwb, instance, state, changes, true),
|
|
5066
5441
|
origin: {
|
|
5067
5442
|
enumerable: true,
|
|
5068
5443
|
get: () => state.origin
|
|
5069
5444
|
},
|
|
5070
|
-
rgb:
|
|
5071
|
-
rgba:
|
|
5445
|
+
rgb: getColorProperty(COLOR_TYPE.rgb, instance, state, changes, false),
|
|
5446
|
+
rgba: getColorProperty(COLOR_TYPE.rgb, instance, state, changes, true)
|
|
5072
5447
|
});
|
|
5073
5448
|
return Object.freeze(instance);
|
|
5074
5449
|
}
|
|
5075
|
-
function
|
|
5450
|
+
function getColorProperty(space, color, state, changes, alpha) {
|
|
5076
5451
|
const setValue = setters[space];
|
|
5077
5452
|
return {
|
|
5078
5453
|
enumerable: true,
|
|
5079
|
-
get: () =>
|
|
5080
|
-
set: (value) => setValue(color, state,
|
|
5454
|
+
get: () => getColorValue(space, state, alpha),
|
|
5455
|
+
set: (value) => setValue(color, state, changes, value, alpha)
|
|
5081
5456
|
};
|
|
5082
5457
|
}
|
|
5083
|
-
function
|
|
5458
|
+
function getColorValue(space, state, alpha) {
|
|
5084
5459
|
const value = getColorFromState(state, space);
|
|
5085
5460
|
if (typeof value === "string") return alpha ? `${value}${state.alpha.hex}` : value;
|
|
5086
5461
|
return alpha ? {
|
|
@@ -5088,28 +5463,16 @@ function getValue$1(space, state, alpha) {
|
|
|
5088
5463
|
alpha: state.alpha.value
|
|
5089
5464
|
} : { ...value };
|
|
5090
5465
|
}
|
|
5466
|
+
function onCreateSubscription(instance, event, callback) {
|
|
5467
|
+
let value;
|
|
5468
|
+
if (event === COLOR_TYPE.wildcard) value = instance;
|
|
5469
|
+
else value = instance[event];
|
|
5470
|
+
callback(value);
|
|
5471
|
+
}
|
|
5091
5472
|
function setAlphaValue(state, value) {
|
|
5092
5473
|
if (typeof value === "number" && !Number.isNaN(value)) state.alpha = getAlpha(value, false);
|
|
5093
5474
|
}
|
|
5094
|
-
|
|
5095
|
-
let key;
|
|
5096
|
-
let value;
|
|
5097
|
-
if (typeof first === "string") {
|
|
5098
|
-
key = first;
|
|
5099
|
-
value = second;
|
|
5100
|
-
} else if (typeof first === "function") value = first;
|
|
5101
|
-
if (typeof value !== "function") throw new Error();
|
|
5102
|
-
return getSubscription({
|
|
5103
|
-
key,
|
|
5104
|
-
subscriptions,
|
|
5105
|
-
value,
|
|
5106
|
-
property: colorSubscription
|
|
5107
|
-
});
|
|
5108
|
-
}
|
|
5109
|
-
const colorSubscription = {
|
|
5110
|
-
key: COLOR_PROPERTY.name,
|
|
5111
|
-
value: COLOR_PROPERTY.subscription
|
|
5112
|
-
};
|
|
5475
|
+
const colorSubscription = { key: COLOR_PROPERTY.name };
|
|
5113
5476
|
const setters = {
|
|
5114
5477
|
hex: setHexColor,
|
|
5115
5478
|
hsl: setHSLColor,
|
|
@@ -5252,13 +5615,13 @@ const EXPRESSION_WHITESPACE = /^\s*$/;
|
|
|
5252
5615
|
//#endregion
|
|
5253
5616
|
//#region src/logger.ts
|
|
5254
5617
|
function isLogger(value) {
|
|
5255
|
-
return isLoggerInstance(
|
|
5618
|
+
return isLoggerInstance(LOGGER_NAME, value);
|
|
5256
5619
|
}
|
|
5257
5620
|
function isLoggerInstance(name, value) {
|
|
5258
|
-
return typeof value === "object" && value !== null && value[
|
|
5621
|
+
return typeof value === "object" && value !== null && value[LOGGER_PROPERTY] === name;
|
|
5259
5622
|
}
|
|
5260
5623
|
function isTimedLogger(value) {
|
|
5261
|
-
return isLoggerInstance(
|
|
5624
|
+
return isLoggerInstance(LOGGER_NAME_TIMED, value);
|
|
5262
5625
|
}
|
|
5263
5626
|
function timedLogger(label) {
|
|
5264
5627
|
function stop() {
|
|
@@ -5277,35 +5640,20 @@ function timedLogger(label) {
|
|
|
5277
5640
|
};
|
|
5278
5641
|
const instance = {};
|
|
5279
5642
|
Object.defineProperties(instance, {
|
|
5280
|
-
[
|
|
5281
|
-
enumerable: false,
|
|
5282
|
-
value: NAME_TIMED
|
|
5283
|
-
},
|
|
5643
|
+
[LOGGER_PROPERTY]: { value: LOGGER_NAME_TIMED },
|
|
5284
5644
|
active: {
|
|
5285
5645
|
enumerable: true,
|
|
5286
|
-
get()
|
|
5287
|
-
return state.started && !state.stopped && enabled;
|
|
5288
|
-
}
|
|
5289
|
-
},
|
|
5290
|
-
log: {
|
|
5291
|
-
enumerable: true,
|
|
5292
|
-
get() {
|
|
5293
|
-
return this.active ? logger : noop;
|
|
5294
|
-
}
|
|
5646
|
+
get: () => state.started && !state.stopped && enabled
|
|
5295
5647
|
},
|
|
5296
|
-
|
|
5297
|
-
|
|
5298
|
-
get() {
|
|
5299
|
-
return instance.active ? stop() : noop;
|
|
5300
|
-
}
|
|
5301
|
-
}
|
|
5648
|
+
log: { get: () => instance.active ? logger : noop },
|
|
5649
|
+
stop: { get: () => instance.active ? stop() : noop }
|
|
5302
5650
|
});
|
|
5303
5651
|
if (state.started) console.time(label);
|
|
5304
5652
|
return Object.freeze(instance);
|
|
5305
5653
|
}
|
|
5306
|
-
const
|
|
5307
|
-
const
|
|
5308
|
-
const
|
|
5654
|
+
const LOGGER_NAME = "Logger";
|
|
5655
|
+
const LOGGER_NAME_TIMED = "TimedLogger";
|
|
5656
|
+
const LOGGER_PROPERTY = "$logger";
|
|
5309
5657
|
const methods = [
|
|
5310
5658
|
"debug",
|
|
5311
5659
|
"dir",
|
|
@@ -5324,349 +5672,84 @@ const methods = [
|
|
|
5324
5672
|
const Logger = (() => {
|
|
5325
5673
|
const instance = {};
|
|
5326
5674
|
Object.defineProperties(instance, {
|
|
5327
|
-
[
|
|
5328
|
-
enumerable: false,
|
|
5329
|
-
value: NAME_LOGGER
|
|
5330
|
-
},
|
|
5675
|
+
[LOGGER_PROPERTY]: { value: LOGGER_NAME },
|
|
5331
5676
|
enabled: {
|
|
5332
5677
|
enumerable: true,
|
|
5333
|
-
get()
|
|
5334
|
-
|
|
5335
|
-
},
|
|
5336
|
-
set(value) {
|
|
5678
|
+
get: () => enabled,
|
|
5679
|
+
set: (value) => {
|
|
5337
5680
|
enabled = typeof value === "boolean" ? value : enabled;
|
|
5338
5681
|
}
|
|
5339
5682
|
},
|
|
5340
|
-
time: {
|
|
5341
|
-
enumerable: true,
|
|
5342
|
-
value(label) {
|
|
5343
|
-
return timedLogger(label);
|
|
5344
|
-
}
|
|
5345
|
-
}
|
|
5346
|
-
});
|
|
5347
|
-
for (const method of methods) Object.defineProperty(instance, method, {
|
|
5348
|
-
enumerable: true,
|
|
5349
|
-
get() {
|
|
5350
|
-
return enabled ? console[method].bind(console) : noop;
|
|
5351
|
-
}
|
|
5683
|
+
time: { value: (label) => timedLogger(getString(label)) }
|
|
5352
5684
|
});
|
|
5353
|
-
|
|
5354
|
-
|
|
5355
|
-
|
|
5356
|
-
|
|
5357
|
-
|
|
5358
|
-
function average(array, key) {
|
|
5359
|
-
const aggregated = aggregate(AGGREGATION_AVERAGE, array, key);
|
|
5360
|
-
return aggregated.count > 0 ? aggregated.value / aggregated.count : NaN;
|
|
5361
|
-
}
|
|
5362
|
-
/**
|
|
5363
|
-
* Round a number up
|
|
5364
|
-
*
|
|
5365
|
-
* @param value Number to round up
|
|
5366
|
-
* @param decimals Number of decimal places to round to _(defaults to `0`)_
|
|
5367
|
-
* @returns Rounded number, or `Number.NaN` if the value if unable to be rounded
|
|
5368
|
-
*/
|
|
5369
|
-
function ceil(value, decimals) {
|
|
5370
|
-
return roundNumber(Math.ceil, value, decimals);
|
|
5371
|
-
}
|
|
5372
|
-
function count(array, key, value) {
|
|
5373
|
-
if (!Array.isArray(array)) return NaN;
|
|
5374
|
-
const { length } = array;
|
|
5375
|
-
const callback = getAggregateCallback(key);
|
|
5376
|
-
if (callback == null) return length;
|
|
5377
|
-
let counted = 0;
|
|
5378
|
-
for (let index = 0; index < length; index += 1) {
|
|
5379
|
-
const item = array[index];
|
|
5380
|
-
if (Object.is(callback(item, index, array), value)) counted += 1;
|
|
5381
|
-
}
|
|
5382
|
-
return counted;
|
|
5383
|
-
}
|
|
5384
|
-
/**
|
|
5385
|
-
* Round a number down
|
|
5386
|
-
*
|
|
5387
|
-
* @param value Number to round down
|
|
5388
|
-
* @param decimals Number of decimal places to round to _(defaults to `0`)_
|
|
5389
|
-
* @returns Rounded number, or `Number.NaN` if the value if unable to be rounded
|
|
5390
|
-
*/
|
|
5391
|
-
function floor(value, decimals) {
|
|
5392
|
-
return roundNumber(Math.floor, value, decimals);
|
|
5393
|
-
}
|
|
5394
|
-
function median(array, key) {
|
|
5395
|
-
let length = Array.isArray(array) ? array.length : 0;
|
|
5396
|
-
if (!Array.isArray(array) || length === 0) return NaN;
|
|
5397
|
-
let values = array;
|
|
5398
|
-
const callback = getAggregateCallback(key);
|
|
5399
|
-
if (callback != null) values = array.map((item, index) => callback(item, index, array));
|
|
5400
|
-
const numbers = values.filter(isNumber).sort((first, second) => first - second);
|
|
5401
|
-
length = numbers.length;
|
|
5402
|
-
if (length === 1) return numbers[0];
|
|
5403
|
-
if (length % 2 === 0) {
|
|
5404
|
-
const first = length / 2 - 1;
|
|
5405
|
-
const second = length / 2;
|
|
5406
|
-
return (numbers[first] + numbers[second]) / 2;
|
|
5407
|
-
}
|
|
5408
|
-
return numbers[Math.floor(length / 2)];
|
|
5409
|
-
}
|
|
5410
|
-
function min(array, key) {
|
|
5411
|
-
return getAggregated("min", array, key);
|
|
5412
|
-
}
|
|
5413
|
-
function sum(array, key) {
|
|
5414
|
-
return getAggregated("sum", array, key);
|
|
5415
|
-
}
|
|
5416
|
-
//#endregion
|
|
5417
|
-
//#region src/promise/models.ts
|
|
5418
|
-
/**
|
|
5419
|
-
* A _Promise_ that can be canceled
|
|
5420
|
-
*/
|
|
5421
|
-
var CancelablePromise = class extends Promise {
|
|
5422
|
-
#rejector;
|
|
5423
|
-
constructor(executor) {
|
|
5424
|
-
let rejector;
|
|
5425
|
-
super((resolve, reject) => {
|
|
5426
|
-
rejector = reject;
|
|
5427
|
-
executor(resolve, reject);
|
|
5428
|
-
});
|
|
5429
|
-
this.#rejector = rejector;
|
|
5430
|
-
}
|
|
5431
|
-
/**
|
|
5432
|
-
* Cancel the _Promise_, rejecting it with an optional reason
|
|
5433
|
-
*
|
|
5434
|
-
* @param reason Optional reason for canceling the _Promise_
|
|
5435
|
-
*/
|
|
5436
|
-
cancel(reason) {
|
|
5437
|
-
this.#rejector(reason);
|
|
5438
|
-
}
|
|
5439
|
-
};
|
|
5440
|
-
/**
|
|
5441
|
-
* An error thrown when a promise times out
|
|
5442
|
-
*/
|
|
5443
|
-
var PromiseTimeoutError = class extends Error {
|
|
5444
|
-
constructor() {
|
|
5445
|
-
super(PROMISE_MESSAGE_TIMEOUT);
|
|
5446
|
-
this.name = PROMISE_ERROR_NAME;
|
|
5447
|
-
}
|
|
5448
|
-
};
|
|
5449
|
-
const PROMISE_ABORT_EVENT = "abort";
|
|
5450
|
-
const PROMISE_ABORT_OPTIONS = { once: true };
|
|
5451
|
-
const PROMISE_ERROR_NAME = "PromiseTimeoutError";
|
|
5452
|
-
const PROMISE_MESSAGE_EXPECTATION_ATTEMPT = "Attempt expected a function or a promise";
|
|
5453
|
-
const PROMISE_MESSAGE_EXPECTATION_RESULT = "toResult expected a Promise";
|
|
5454
|
-
const PROMISE_MESSAGE_EXPECTATION_TIMED = "Timed function expected a Promise";
|
|
5455
|
-
const PROMISE_MESSAGE_TIMEOUT = "Promise timed out";
|
|
5456
|
-
const PROMISE_STRATEGY_ALL = /* @__PURE__ */ new Set(["complete", "first"]);
|
|
5457
|
-
const PROMISE_STRATEGY_DEFAULT = "complete";
|
|
5458
|
-
const PROMISE_TYPE_FULFILLED = "fulfilled";
|
|
5459
|
-
const PROMISE_TYPE_REJECTED = "rejected";
|
|
5460
|
-
//#endregion
|
|
5461
|
-
//#region src/promise/helpers.ts
|
|
5462
|
-
function getPromiseOptions(input) {
|
|
5463
|
-
if (typeof input === "number") return { time: getNumberOrDefault(input, 0) };
|
|
5464
|
-
if (input instanceof AbortSignal) return {
|
|
5465
|
-
signal: input,
|
|
5466
|
-
time: 0
|
|
5467
|
-
};
|
|
5468
|
-
const options = typeof input === "object" && input !== null ? input : {};
|
|
5469
|
-
return {
|
|
5470
|
-
signal: options.signal instanceof AbortSignal ? options.signal : void 0,
|
|
5471
|
-
time: getNumberOrDefault(options.time, 0)
|
|
5472
|
-
};
|
|
5473
|
-
}
|
|
5474
|
-
function getPromisesOptions(input) {
|
|
5475
|
-
if (typeof input === "string") return { strategy: getStrategyOrDefault(input) };
|
|
5476
|
-
if (input instanceof AbortSignal) return {
|
|
5477
|
-
signal: input,
|
|
5478
|
-
strategy: PROMISE_STRATEGY_DEFAULT
|
|
5479
|
-
};
|
|
5480
|
-
const options = typeof input === "object" && input !== null ? input : {};
|
|
5481
|
-
return {
|
|
5482
|
-
signal: options.signal instanceof AbortSignal ? options.signal : void 0,
|
|
5483
|
-
strategy: getStrategyOrDefault(options.strategy)
|
|
5484
|
-
};
|
|
5485
|
-
}
|
|
5486
|
-
function getResultsFromPromises(promised) {
|
|
5487
|
-
return promised.map((result) => isFulfilled(result) ? ok(result.value) : error(result.reason));
|
|
5488
|
-
}
|
|
5489
|
-
function getStrategyOrDefault(value) {
|
|
5490
|
-
return PROMISE_STRATEGY_ALL.has(value) ? value : PROMISE_STRATEGY_DEFAULT;
|
|
5491
|
-
}
|
|
5492
|
-
/**
|
|
5493
|
-
* Is the value a fulfilled _Promise_ result?
|
|
5494
|
-
*
|
|
5495
|
-
* @param value Value to check
|
|
5496
|
-
* @returns `true` if the value is a fulfilled _Promise_ result, otherwise `false`
|
|
5497
|
-
*/
|
|
5498
|
-
function isFulfilled(value) {
|
|
5499
|
-
return isType(value, PROMISE_TYPE_FULFILLED);
|
|
5500
|
-
}
|
|
5501
|
-
/**
|
|
5502
|
-
* Is the value a rejected _Promise_ result?
|
|
5503
|
-
*
|
|
5504
|
-
* @param value Value to check
|
|
5505
|
-
* @returns `true` if the value is a rejected _Promise_ result, otherwise `false`
|
|
5506
|
-
*/
|
|
5507
|
-
function isRejected(value) {
|
|
5508
|
-
return isType(value, PROMISE_TYPE_REJECTED);
|
|
5509
|
-
}
|
|
5510
|
-
function isType(value, type) {
|
|
5511
|
-
return typeof value === "object" && value !== null && value.status === type;
|
|
5512
|
-
}
|
|
5513
|
-
//#endregion
|
|
5514
|
-
//#region src/promise/misc.ts
|
|
5515
|
-
/**
|
|
5516
|
-
* Create a cancelable _Promise_
|
|
5517
|
-
*
|
|
5518
|
-
* @param executor Executor function for the _Promise_
|
|
5519
|
-
* @returns Cancelable _Promise_
|
|
5520
|
-
*/
|
|
5521
|
-
function cancelable(executor) {
|
|
5522
|
-
return new CancelablePromise(executor);
|
|
5523
|
-
}
|
|
5524
|
-
function handleResult(status, parameters) {
|
|
5525
|
-
const { abort, complete, data, handlers, index, signal, value } = parameters;
|
|
5526
|
-
if (signal?.aborted ?? false) return;
|
|
5527
|
-
if (!complete && status === "rejected") {
|
|
5528
|
-
settlePromise(abort, handlers.reject, value, signal);
|
|
5529
|
-
return;
|
|
5530
|
-
}
|
|
5531
|
-
data.result[index] = !complete ? value : status === "fulfilled" ? {
|
|
5532
|
-
status,
|
|
5533
|
-
value
|
|
5534
|
-
} : {
|
|
5535
|
-
status,
|
|
5536
|
-
reason: value
|
|
5537
|
-
};
|
|
5538
|
-
if (index === data.last) settlePromise(abort, handlers.resolve, data.result, signal);
|
|
5539
|
-
}
|
|
5540
|
-
function settlePromise(aborter, settler, value, signal) {
|
|
5541
|
-
signal?.removeEventListener(PROMISE_ABORT_EVENT, aborter);
|
|
5542
|
-
settler(value);
|
|
5543
|
-
}
|
|
5544
|
-
async function toResult(value) {
|
|
5545
|
-
const actual = typeof value === "function" ? value() : value;
|
|
5546
|
-
if (!(actual instanceof Promise)) return Promise.reject(/* @__PURE__ */ new TypeError(PROMISE_MESSAGE_EXPECTATION_RESULT));
|
|
5547
|
-
return actual.then((result) => ok(result)).catch((reason) => error(reason));
|
|
5548
|
-
}
|
|
5549
|
-
//#endregion
|
|
5550
|
-
//#region src/promise/delay.ts
|
|
5551
|
-
function delay(options) {
|
|
5552
|
-
const { signal, time } = getPromiseOptions(options);
|
|
5553
|
-
if (signal?.aborted ?? false) return Promise.reject(signal.reason);
|
|
5554
|
-
function abort() {
|
|
5555
|
-
timer.cancel();
|
|
5556
|
-
rejector(signal.reason);
|
|
5557
|
-
}
|
|
5558
|
-
const timer = getTimer(TIMER_WAIT, () => {
|
|
5559
|
-
settlePromise(abort, resolver, void 0, signal);
|
|
5560
|
-
}, time);
|
|
5561
|
-
signal?.addEventListener(PROMISE_ABORT_EVENT, abort, PROMISE_ABORT_OPTIONS);
|
|
5562
|
-
let rejector;
|
|
5563
|
-
let resolver;
|
|
5564
|
-
return new Promise((resolve, reject) => {
|
|
5565
|
-
rejector = reject;
|
|
5566
|
-
resolver = resolve;
|
|
5567
|
-
if (time === 0) settlePromise(abort, resolve, void 0, signal);
|
|
5568
|
-
else timer();
|
|
5685
|
+
for (const method of methods) Object.defineProperty(instance, method, {
|
|
5686
|
+
enumerable: true,
|
|
5687
|
+
get() {
|
|
5688
|
+
return enabled ? console[method].bind(console) : noop;
|
|
5689
|
+
}
|
|
5569
5690
|
});
|
|
5570
|
-
|
|
5691
|
+
return Object.freeze(instance);
|
|
5692
|
+
})();
|
|
5693
|
+
let enabled = true;
|
|
5571
5694
|
//#endregion
|
|
5572
|
-
//#region src/
|
|
5573
|
-
|
|
5574
|
-
|
|
5575
|
-
|
|
5576
|
-
rejector(signal.reason);
|
|
5577
|
-
}
|
|
5578
|
-
signal?.addEventListener(PROMISE_ABORT_EVENT, abort, PROMISE_ABORT_OPTIONS);
|
|
5579
|
-
const timer = getTimer(TIMER_WAIT, () => {
|
|
5580
|
-
settlePromise(abort, rejector, new PromiseTimeoutError(), signal);
|
|
5581
|
-
}, time);
|
|
5582
|
-
let rejector;
|
|
5583
|
-
return Promise.race([promise, new Promise((_, reject) => {
|
|
5584
|
-
rejector = reject;
|
|
5585
|
-
timer();
|
|
5586
|
-
})]).then((value) => {
|
|
5587
|
-
timer.cancel();
|
|
5588
|
-
rejector(void 0);
|
|
5589
|
-
signal?.removeEventListener(PROMISE_ABORT_EVENT, abort);
|
|
5590
|
-
return value;
|
|
5591
|
-
});
|
|
5695
|
+
//#region src/math.ts
|
|
5696
|
+
function average(array, key) {
|
|
5697
|
+
const aggregated = aggregate(AGGREGATION_AVERAGE, array, key);
|
|
5698
|
+
return aggregated.count > 0 ? aggregated.value / aggregated.count : NaN;
|
|
5592
5699
|
}
|
|
5593
|
-
|
|
5594
|
-
|
|
5595
|
-
|
|
5596
|
-
|
|
5597
|
-
|
|
5700
|
+
/**
|
|
5701
|
+
* Round a number up
|
|
5702
|
+
*
|
|
5703
|
+
* @param value Number to round up
|
|
5704
|
+
* @param decimals Number of decimal places to round to _(defaults to `0`)_
|
|
5705
|
+
* @returns Rounded number, or `Number.NaN` if the value if unable to be rounded
|
|
5706
|
+
*/
|
|
5707
|
+
function ceil(value, decimals) {
|
|
5708
|
+
return roundNumber(Math.ceil, value, decimals);
|
|
5598
5709
|
}
|
|
5599
|
-
|
|
5600
|
-
|
|
5601
|
-
|
|
5602
|
-
const
|
|
5603
|
-
if (
|
|
5604
|
-
|
|
5605
|
-
|
|
5606
|
-
|
|
5607
|
-
|
|
5608
|
-
}
|
|
5609
|
-
async function handler(resolve, reject) {
|
|
5610
|
-
try {
|
|
5611
|
-
let result = isFunction ? value() : await value;
|
|
5612
|
-
if (result instanceof Promise) result = await result;
|
|
5613
|
-
settlePromise(abort, resolve, result, signal);
|
|
5614
|
-
} catch (error) {
|
|
5615
|
-
settlePromise(abort, reject, error, signal);
|
|
5616
|
-
}
|
|
5710
|
+
function count(array, key, value) {
|
|
5711
|
+
if (!Array.isArray(array)) return NaN;
|
|
5712
|
+
const { length } = array;
|
|
5713
|
+
const callback = getAggregateCallback(key);
|
|
5714
|
+
if (callback == null) return length;
|
|
5715
|
+
let counted = 0;
|
|
5716
|
+
for (let index = 0; index < length; index += 1) {
|
|
5717
|
+
const item = array[index];
|
|
5718
|
+
if (Object.is(callback(item, index, array), value)) counted += 1;
|
|
5617
5719
|
}
|
|
5618
|
-
|
|
5619
|
-
signal?.addEventListener(PROMISE_ABORT_EVENT, abort, PROMISE_ABORT_OPTIONS);
|
|
5620
|
-
const promise = new Promise((resolve, reject) => {
|
|
5621
|
-
rejector = reject;
|
|
5622
|
-
handler(resolve, reject);
|
|
5623
|
-
});
|
|
5624
|
-
return time > 0 ? getTimedPromise(promise, time, signal) : promise;
|
|
5720
|
+
return counted;
|
|
5625
5721
|
}
|
|
5626
|
-
|
|
5627
|
-
|
|
5628
|
-
|
|
5629
|
-
|
|
5630
|
-
|
|
5631
|
-
|
|
5632
|
-
|
|
5633
|
-
|
|
5634
|
-
|
|
5635
|
-
|
|
5722
|
+
/**
|
|
5723
|
+
* Round a number down
|
|
5724
|
+
*
|
|
5725
|
+
* @param value Number to round down
|
|
5726
|
+
* @param decimals Number of decimal places to round to _(defaults to `0`)_
|
|
5727
|
+
* @returns Rounded number, or `Number.NaN` if the value if unable to be rounded
|
|
5728
|
+
*/
|
|
5729
|
+
function floor(value, decimals) {
|
|
5730
|
+
return roundNumber(Math.floor, value, decimals);
|
|
5731
|
+
}
|
|
5732
|
+
function median(array, key) {
|
|
5733
|
+
let length = Array.isArray(array) ? array.length : 0;
|
|
5734
|
+
if (!Array.isArray(array) || length === 0) return NaN;
|
|
5735
|
+
let values = array;
|
|
5736
|
+
const callback = getAggregateCallback(key);
|
|
5737
|
+
if (callback != null) values = array.map((item, index) => callback(item, index, array));
|
|
5738
|
+
const numbers = values.filter(isNumber).sort((first, second) => first - second);
|
|
5739
|
+
length = numbers.length;
|
|
5740
|
+
if (length === 1) return numbers[0];
|
|
5741
|
+
if (length % 2 === 0) {
|
|
5742
|
+
const first = length / 2 - 1;
|
|
5743
|
+
const second = length / 2;
|
|
5744
|
+
return (numbers[first] + numbers[second]) / 2;
|
|
5636
5745
|
}
|
|
5637
|
-
|
|
5638
|
-
const data = {
|
|
5639
|
-
last: length - 1,
|
|
5640
|
-
result: []
|
|
5641
|
-
};
|
|
5642
|
-
let handlers;
|
|
5643
|
-
return new Promise((resolve, reject) => {
|
|
5644
|
-
handlers = {
|
|
5645
|
-
reject,
|
|
5646
|
-
resolve
|
|
5647
|
-
};
|
|
5648
|
-
for (let index = 0; index < length; index += 1) actual[index].then((value) => handleResult(PROMISE_TYPE_FULFILLED, {
|
|
5649
|
-
abort,
|
|
5650
|
-
complete,
|
|
5651
|
-
data,
|
|
5652
|
-
handlers,
|
|
5653
|
-
index,
|
|
5654
|
-
signal,
|
|
5655
|
-
value
|
|
5656
|
-
})).catch((reason) => handleResult(PROMISE_TYPE_REJECTED, {
|
|
5657
|
-
abort,
|
|
5658
|
-
complete,
|
|
5659
|
-
data,
|
|
5660
|
-
handlers,
|
|
5661
|
-
index,
|
|
5662
|
-
signal,
|
|
5663
|
-
value: reason
|
|
5664
|
-
}));
|
|
5665
|
-
});
|
|
5746
|
+
return numbers[Math.floor(length / 2)];
|
|
5666
5747
|
}
|
|
5667
|
-
|
|
5668
|
-
|
|
5669
|
-
|
|
5748
|
+
function min(array, key) {
|
|
5749
|
+
return getAggregated("min", array, key);
|
|
5750
|
+
}
|
|
5751
|
+
function sum(array, key) {
|
|
5752
|
+
return getAggregated("sum", array, key);
|
|
5670
5753
|
}
|
|
5671
5754
|
//#endregion
|
|
5672
5755
|
//#region src/query.ts
|
|
@@ -5678,15 +5761,15 @@ async function resultPromises(items, signal) {
|
|
|
5678
5761
|
*/
|
|
5679
5762
|
function fromQuery(query) {
|
|
5680
5763
|
if (typeof query !== "string" || query.trim().length === 0) return {};
|
|
5681
|
-
const parts = query.split(
|
|
5764
|
+
const parts = query.split(QUERY_AMPERSAND).map((part) => part.split(QUERY_EQUAL).map(tryDecode)).sort(([first], [second]) => first.localeCompare(second));
|
|
5682
5765
|
const { length } = parts;
|
|
5683
5766
|
const parameters = {};
|
|
5684
5767
|
let position = 0;
|
|
5685
5768
|
let array;
|
|
5686
5769
|
for (let index = 0; index < length; index += 1) {
|
|
5687
5770
|
const [key, value] = parts[index];
|
|
5688
|
-
if (
|
|
5689
|
-
const named = key.replace(
|
|
5771
|
+
if (QUERY_EXPRESSION_ARRAY_SUFFIX.test(key)) {
|
|
5772
|
+
const named = key.replace(QUERY_EXPRESSION_ARRAY_SUFFIX, "");
|
|
5690
5773
|
if (named !== array) {
|
|
5691
5774
|
array = named;
|
|
5692
5775
|
position = 0;
|
|
@@ -5708,9 +5791,9 @@ function getParts(value, fromArray, prefix) {
|
|
|
5708
5791
|
for (let index = 0; index < length; index += 1) {
|
|
5709
5792
|
const key = keys[index];
|
|
5710
5793
|
const val = value[key];
|
|
5711
|
-
const fullKey = join([prefix, fromArray ? void 0 : key],
|
|
5794
|
+
const fullKey = join([prefix, fromArray ? void 0 : key], QUERY_DOT);
|
|
5712
5795
|
const encodedKey = getString(tryEncode(fullKey));
|
|
5713
|
-
const prefixedKey = fromArray ? join([encodedKey, index],
|
|
5796
|
+
const prefixedKey = fromArray ? join([encodedKey, index], QUERY_DOT) : encodedKey;
|
|
5714
5797
|
if (Array.isArray(val)) parts.push(...getParts(val, true, fullKey));
|
|
5715
5798
|
else if (isPlainObject(val)) parts.push(...getParts(val, false, fullKey));
|
|
5716
5799
|
else if (isDecodable(val)) parts.push(`${prefixedKey}=${getString(tryEncode(val))}`);
|
|
@@ -5719,7 +5802,7 @@ function getParts(value, fromArray, prefix) {
|
|
|
5719
5802
|
return parts;
|
|
5720
5803
|
}
|
|
5721
5804
|
function getQueryValue(value) {
|
|
5722
|
-
if (
|
|
5805
|
+
if (QUERY_EXPRESSION_BOOLEAN.test(value)) return value === QUERY_TRUE;
|
|
5723
5806
|
const asNumber = getNumber(value);
|
|
5724
5807
|
if (!Number.isNaN(asNumber)) return asNumber;
|
|
5725
5808
|
const parsed = Date.parse(value);
|
|
@@ -5728,7 +5811,7 @@ function getQueryValue(value) {
|
|
|
5728
5811
|
return date.toJSON() === value ? date : value;
|
|
5729
5812
|
}
|
|
5730
5813
|
function isDecodable(value) {
|
|
5731
|
-
return
|
|
5814
|
+
return QUERY_TYPES.has(typeof value);
|
|
5732
5815
|
}
|
|
5733
5816
|
/**
|
|
5734
5817
|
* Convert a plain _(nested)_ object to a query string
|
|
@@ -5737,15 +5820,15 @@ function isDecodable(value) {
|
|
|
5737
5820
|
* @returns Query string representation of the object
|
|
5738
5821
|
*/
|
|
5739
5822
|
function toQuery(parameters) {
|
|
5740
|
-
return isPlainObject(parameters) ? join(getParts(parameters, false).filter((part) => part.length > 0),
|
|
5741
|
-
}
|
|
5742
|
-
const
|
|
5743
|
-
const
|
|
5744
|
-
const
|
|
5745
|
-
const
|
|
5746
|
-
const
|
|
5747
|
-
const
|
|
5748
|
-
const
|
|
5823
|
+
return isPlainObject(parameters) ? join(getParts(parameters, false).filter((part) => part.length > 0), QUERY_AMPERSAND) : "";
|
|
5824
|
+
}
|
|
5825
|
+
const QUERY_AMPERSAND = "&";
|
|
5826
|
+
const QUERY_DOT = ".";
|
|
5827
|
+
const QUERY_EQUAL = "=";
|
|
5828
|
+
const QUERY_EXPRESSION_ARRAY_SUFFIX = /\[\]$/;
|
|
5829
|
+
const QUERY_EXPRESSION_BOOLEAN = /^(false|true)$/;
|
|
5830
|
+
const QUERY_TRUE = "true";
|
|
5831
|
+
const QUERY_TYPES = /* @__PURE__ */ new Set([
|
|
5749
5832
|
"boolean",
|
|
5750
5833
|
"number",
|
|
5751
5834
|
"string"
|
|
@@ -5758,11 +5841,47 @@ const TYPES = /* @__PURE__ */ new Set([
|
|
|
5758
5841
|
var QueueError = class extends Error {
|
|
5759
5842
|
constructor(message) {
|
|
5760
5843
|
super(message);
|
|
5761
|
-
this.name =
|
|
5844
|
+
this.name = QUEUE_ERROR_NAME;
|
|
5762
5845
|
}
|
|
5763
5846
|
};
|
|
5847
|
+
function addToQueue(instance, state, parameters, signal) {
|
|
5848
|
+
if (instance.full) throw new QueueError(QUEUE_MESSAGE_MAXIMUM);
|
|
5849
|
+
const abortSignal = signal instanceof AbortSignal ? signal : void 0;
|
|
5850
|
+
if (abortSignal?.aborted ?? false) throw new Error(abortSignal?.reason);
|
|
5851
|
+
const id = identify(state);
|
|
5852
|
+
let rejector;
|
|
5853
|
+
let resolver;
|
|
5854
|
+
const promise = new Promise((resolve, reject) => {
|
|
5855
|
+
rejector = reject;
|
|
5856
|
+
resolver = resolve;
|
|
5857
|
+
});
|
|
5858
|
+
const aborter = createAborter(abortSignal, () => rejector(abortSignal?.reason));
|
|
5859
|
+
state.items.push({
|
|
5860
|
+
aborter,
|
|
5861
|
+
id,
|
|
5862
|
+
parameters,
|
|
5863
|
+
promise,
|
|
5864
|
+
key: state.key,
|
|
5865
|
+
reject: rejector,
|
|
5866
|
+
resolve: resolver
|
|
5867
|
+
});
|
|
5868
|
+
if (state.options.autostart) run(state);
|
|
5869
|
+
return {
|
|
5870
|
+
id,
|
|
5871
|
+
promise
|
|
5872
|
+
};
|
|
5873
|
+
}
|
|
5874
|
+
function clearQueue(state) {
|
|
5875
|
+
const items = state.items.splice(0);
|
|
5876
|
+
const { length } = items;
|
|
5877
|
+
for (let index = 0; index < length; index += 1) {
|
|
5878
|
+
const { aborter, reject } = items[index];
|
|
5879
|
+
aborter?.cancel();
|
|
5880
|
+
reject(new QueueError(QUEUE_MESSAGE_CLEAR));
|
|
5881
|
+
}
|
|
5882
|
+
}
|
|
5764
5883
|
function createQueue(callback, options, key) {
|
|
5765
|
-
if (typeof callback !== "function") throw new TypeError(
|
|
5884
|
+
if (typeof callback !== "function") throw new TypeError(QUEUE_MESSAGE_CALLBACK);
|
|
5766
5885
|
const state = {
|
|
5767
5886
|
callback,
|
|
5768
5887
|
key,
|
|
@@ -5774,71 +5893,16 @@ function createQueue(callback, options, key) {
|
|
|
5774
5893
|
runners: 0
|
|
5775
5894
|
};
|
|
5776
5895
|
const instance = {
|
|
5777
|
-
add: (parameters, signal) =>
|
|
5778
|
-
|
|
5779
|
-
const abortSignal = signal instanceof AbortSignal ? signal : void 0;
|
|
5780
|
-
if (abortSignal?.aborted ?? false) throw new Error(abortSignal.reason);
|
|
5781
|
-
const id = identify(state);
|
|
5782
|
-
let rejector;
|
|
5783
|
-
let resolver;
|
|
5784
|
-
const promise = new Promise((resolve, reject) => {
|
|
5785
|
-
rejector = reject;
|
|
5786
|
-
resolver = resolve;
|
|
5787
|
-
});
|
|
5788
|
-
const aborter = abortSignal == null ? void 0 : () => rejector(abortSignal.reason);
|
|
5789
|
-
signal?.addEventListener(EVENT_NAME, aborter, EVENT_OPTIONS);
|
|
5790
|
-
state.items.push({
|
|
5791
|
-
id,
|
|
5792
|
-
parameters,
|
|
5793
|
-
promise,
|
|
5794
|
-
abort: aborter,
|
|
5795
|
-
key: state.key,
|
|
5796
|
-
reject: rejector,
|
|
5797
|
-
resolve: resolver,
|
|
5798
|
-
signal: abortSignal
|
|
5799
|
-
});
|
|
5800
|
-
if (state.options.autostart) run(state);
|
|
5801
|
-
return {
|
|
5802
|
-
id,
|
|
5803
|
-
promise
|
|
5804
|
-
};
|
|
5805
|
-
},
|
|
5806
|
-
clear: () => {
|
|
5807
|
-
const items = state.items.splice(0);
|
|
5808
|
-
const { length } = items;
|
|
5809
|
-
for (let index = 0; index < length; index += 1) {
|
|
5810
|
-
const { abort, reject, signal } = items[index];
|
|
5811
|
-
reject(new QueueError(MESSAGE_CLEAR));
|
|
5812
|
-
signal?.removeEventListener(EVENT_NAME, abort);
|
|
5813
|
-
}
|
|
5814
|
-
},
|
|
5896
|
+
add: (parameters, signal) => addToQueue(instance, state, parameters, signal),
|
|
5897
|
+
clear: () => clearQueue(state),
|
|
5815
5898
|
pause: () => {
|
|
5816
5899
|
state.paused = true;
|
|
5817
5900
|
},
|
|
5818
|
-
remove: (id) =>
|
|
5819
|
-
|
|
5820
|
-
if (index > -1) {
|
|
5821
|
-
const { abort, reject, signal } = state.items.splice(index, 1)[0];
|
|
5822
|
-
reject(new QueueError(MESSAGE_REMOVE));
|
|
5823
|
-
signal?.removeEventListener(EVENT_NAME, abort);
|
|
5824
|
-
}
|
|
5825
|
-
},
|
|
5826
|
-
resume: () => {
|
|
5827
|
-
if (state.paused) {
|
|
5828
|
-
const handled = state.handled.splice(0);
|
|
5829
|
-
const { length } = handled;
|
|
5830
|
-
for (let index = 0; index < length; index += 1) handled[index]();
|
|
5831
|
-
}
|
|
5832
|
-
state.paused = false;
|
|
5833
|
-
const length = Math.min(state.options.concurrency, state.items.length);
|
|
5834
|
-
for (let index = 0; index < length; index += 1) run(state);
|
|
5835
|
-
}
|
|
5901
|
+
remove: (id) => removeQueued(state, id),
|
|
5902
|
+
resume: () => resumeQueue(state)
|
|
5836
5903
|
};
|
|
5837
5904
|
Object.defineProperties(instance, {
|
|
5838
|
-
[
|
|
5839
|
-
enumerable: false,
|
|
5840
|
-
value: NAME_QUEUE
|
|
5841
|
-
},
|
|
5905
|
+
[QUEUE_PROPERTY]: { value: QUEUE_NAME_QUEUE },
|
|
5842
5906
|
active: {
|
|
5843
5907
|
enumerable: true,
|
|
5844
5908
|
get: () => state.runners > 0
|
|
@@ -5874,15 +5938,6 @@ function createQueue(callback, options, key) {
|
|
|
5874
5938
|
});
|
|
5875
5939
|
return Object.freeze(instance);
|
|
5876
5940
|
}
|
|
5877
|
-
function getBooleanOrDefault(value, defaultValue) {
|
|
5878
|
-
return typeof value === "boolean" ? value : defaultValue;
|
|
5879
|
-
}
|
|
5880
|
-
function getItems(state) {
|
|
5881
|
-
const size = {};
|
|
5882
|
-
const queues = state.queues.entries();
|
|
5883
|
-
for (const [key, queue] of queues) size[key] = queue.size;
|
|
5884
|
-
return size;
|
|
5885
|
-
}
|
|
5886
5941
|
function getOptions(input) {
|
|
5887
5942
|
const options = typeof input === "object" && input != null ? input : {};
|
|
5888
5943
|
return {
|
|
@@ -5892,7 +5947,7 @@ function getOptions(input) {
|
|
|
5892
5947
|
};
|
|
5893
5948
|
}
|
|
5894
5949
|
function getQueue(state, key, add) {
|
|
5895
|
-
if (typeof key !== "string" || key.trim().length === 0) throw new TypeError(
|
|
5950
|
+
if (typeof key !== "string" || key.trim().length === 0) throw new TypeError(QUEUE_MESSAGE_KEY);
|
|
5896
5951
|
let queue = state.queues.get(key);
|
|
5897
5952
|
if (queue == null && add === true) {
|
|
5898
5953
|
queue = createQueue(state.callback, state.options, key);
|
|
@@ -5900,6 +5955,12 @@ function getQueue(state, key, add) {
|
|
|
5900
5955
|
}
|
|
5901
5956
|
return queue;
|
|
5902
5957
|
}
|
|
5958
|
+
function getQueueItems(state) {
|
|
5959
|
+
const size = {};
|
|
5960
|
+
const queues = state.queues.entries();
|
|
5961
|
+
for (const [key, queue] of queues) size[key] = queue.size;
|
|
5962
|
+
return size;
|
|
5963
|
+
}
|
|
5903
5964
|
function getStatus(state, status) {
|
|
5904
5965
|
const queues = state.queues.entries();
|
|
5905
5966
|
const result = [];
|
|
@@ -5907,8 +5968,8 @@ function getStatus(state, status) {
|
|
|
5907
5968
|
return result;
|
|
5908
5969
|
}
|
|
5909
5970
|
function handleQueuedResult(item, error, result) {
|
|
5910
|
-
item.
|
|
5911
|
-
if (item.signal?.aborted ?? false) {
|
|
5971
|
+
item.aborter?.cancel();
|
|
5972
|
+
if (item.aborter?.signal?.aborted ?? false) {
|
|
5912
5973
|
item.reject();
|
|
5913
5974
|
return;
|
|
5914
5975
|
}
|
|
@@ -5937,7 +5998,7 @@ function identify(state) {
|
|
|
5937
5998
|
* @returns `true` if the value is a keyed queue, otherwise `false`
|
|
5938
5999
|
*/
|
|
5939
6000
|
function isKeyedQueue(value) {
|
|
5940
|
-
return isQueueInstance(
|
|
6001
|
+
return isQueueInstance(QUEUE_NAME_KEYED, value);
|
|
5941
6002
|
}
|
|
5942
6003
|
/**
|
|
5943
6004
|
* Is the value a queue?
|
|
@@ -5946,13 +6007,13 @@ function isKeyedQueue(value) {
|
|
|
5946
6007
|
* @returns `true` if the value is a queue, otherwise `false`
|
|
5947
6008
|
*/
|
|
5948
6009
|
function isQueue(value) {
|
|
5949
|
-
return isQueueInstance(
|
|
6010
|
+
return isQueueInstance(QUEUE_NAME_QUEUE, value);
|
|
5950
6011
|
}
|
|
5951
6012
|
function isQueueInstance(name, value) {
|
|
5952
|
-
return typeof value === "object" && value != null && value[
|
|
6013
|
+
return typeof value === "object" && value != null && value[QUEUE_PROPERTY] === name;
|
|
5953
6014
|
}
|
|
5954
6015
|
function keyedQueue(callback, options) {
|
|
5955
|
-
if (typeof callback !== "function") throw new TypeError(
|
|
6016
|
+
if (typeof callback !== "function") throw new TypeError(QUEUE_MESSAGE_CALLBACK);
|
|
5956
6017
|
const state = {
|
|
5957
6018
|
callback,
|
|
5958
6019
|
options: getOptions(options),
|
|
@@ -5960,26 +6021,17 @@ function keyedQueue(callback, options) {
|
|
|
5960
6021
|
};
|
|
5961
6022
|
const instance = {
|
|
5962
6023
|
add: (key, parameters, signal) => getQueue(state, key, true).add(parameters, signal),
|
|
5963
|
-
clear: (key) =>
|
|
5964
|
-
handleQueues(state, HANDLE_CLEAR, key);
|
|
5965
|
-
},
|
|
6024
|
+
clear: (key) => handleQueues(state, QUEUE_HANDLE_CLEAR, key),
|
|
5966
6025
|
get: (key) => getQueue(state, key),
|
|
5967
|
-
pause: (key) =>
|
|
5968
|
-
handleQueues(state, HANDLE_PAUSE, key);
|
|
5969
|
-
},
|
|
6026
|
+
pause: (key) => handleQueues(state, QUEUE_HANDLE_PAUSE, key),
|
|
5970
6027
|
remove: (key, id) => removeQueue(state, key, id),
|
|
5971
|
-
resume: (key) =>
|
|
5972
|
-
handleQueues(state, HANDLE_RESUME, key);
|
|
5973
|
-
}
|
|
6028
|
+
resume: (key) => handleQueues(state, QUEUE_HANDLE_RESUME, key)
|
|
5974
6029
|
};
|
|
5975
6030
|
Object.defineProperties(instance, {
|
|
5976
|
-
[
|
|
5977
|
-
enumerable: false,
|
|
5978
|
-
value: NAME_KEYED
|
|
5979
|
-
},
|
|
6031
|
+
[QUEUE_PROPERTY]: { value: QUEUE_NAME_KEYED },
|
|
5980
6032
|
active: {
|
|
5981
6033
|
enumerable: true,
|
|
5982
|
-
get: () => getStatus(state,
|
|
6034
|
+
get: () => getStatus(state, QUEUE_STATUS_ACTIVE)
|
|
5983
6035
|
},
|
|
5984
6036
|
autostart: {
|
|
5985
6037
|
enumerable: true,
|
|
@@ -5991,15 +6043,15 @@ function keyedQueue(callback, options) {
|
|
|
5991
6043
|
},
|
|
5992
6044
|
empty: {
|
|
5993
6045
|
enumerable: true,
|
|
5994
|
-
get: () => getStatus(state,
|
|
6046
|
+
get: () => getStatus(state, QUEUE_STATUS_EMPTY)
|
|
5995
6047
|
},
|
|
5996
6048
|
full: {
|
|
5997
6049
|
enumerable: true,
|
|
5998
|
-
get: () => getStatus(state,
|
|
6050
|
+
get: () => getStatus(state, QUEUE_STATUS_FULL)
|
|
5999
6051
|
},
|
|
6000
6052
|
items: {
|
|
6001
6053
|
enumerable: true,
|
|
6002
|
-
get: () =>
|
|
6054
|
+
get: () => getQueueItems(state)
|
|
6003
6055
|
},
|
|
6004
6056
|
keys: {
|
|
6005
6057
|
enumerable: true,
|
|
@@ -6011,7 +6063,7 @@ function keyedQueue(callback, options) {
|
|
|
6011
6063
|
},
|
|
6012
6064
|
paused: {
|
|
6013
6065
|
enumerable: true,
|
|
6014
|
-
get: () => getStatus(state,
|
|
6066
|
+
get: () => getStatus(state, QUEUE_STATUS_PAUSED)
|
|
6015
6067
|
},
|
|
6016
6068
|
queues: {
|
|
6017
6069
|
enumerable: true,
|
|
@@ -6026,7 +6078,7 @@ function queue(callback, options) {
|
|
|
6026
6078
|
queue.keyed = keyedQueue;
|
|
6027
6079
|
function removeQueue(state, key, id) {
|
|
6028
6080
|
if (key == null) {
|
|
6029
|
-
handleQueues(state,
|
|
6081
|
+
handleQueues(state, QUEUE_HANDLE_CLEAR);
|
|
6030
6082
|
state.queues.clear();
|
|
6031
6083
|
return;
|
|
6032
6084
|
}
|
|
@@ -6039,6 +6091,24 @@ function removeQueue(state, key, id) {
|
|
|
6039
6091
|
queue.clear();
|
|
6040
6092
|
state.queues.delete(key);
|
|
6041
6093
|
}
|
|
6094
|
+
function removeQueued(state, id) {
|
|
6095
|
+
const index = state.items.findIndex((item) => item.id === id);
|
|
6096
|
+
if (index > -1) {
|
|
6097
|
+
const { aborter, reject } = state.items.splice(index, 1)[0];
|
|
6098
|
+
aborter?.cancel();
|
|
6099
|
+
reject(new QueueError(QUEUE_MESSAGE_REMOVE));
|
|
6100
|
+
}
|
|
6101
|
+
}
|
|
6102
|
+
function resumeQueue(state) {
|
|
6103
|
+
if (state.paused) {
|
|
6104
|
+
const handled = state.handled.splice(0);
|
|
6105
|
+
const { length } = handled;
|
|
6106
|
+
for (let index = 0; index < length; index += 1) handled[index]();
|
|
6107
|
+
}
|
|
6108
|
+
state.paused = false;
|
|
6109
|
+
const length = Math.min(state.options.concurrency, state.items.length);
|
|
6110
|
+
for (let index = 0; index < length; index += 1) run(state);
|
|
6111
|
+
}
|
|
6042
6112
|
async function run(state) {
|
|
6043
6113
|
if (state.paused || state.runners >= state.options.concurrency) return;
|
|
6044
6114
|
state.runners += 1;
|
|
@@ -6047,7 +6117,7 @@ async function run(state) {
|
|
|
6047
6117
|
let error = false;
|
|
6048
6118
|
let result;
|
|
6049
6119
|
try {
|
|
6050
|
-
if (!(item.signal?.aborted ?? false)) {
|
|
6120
|
+
if (!(item.aborter?.signal?.aborted ?? false)) {
|
|
6051
6121
|
const parameters = item.key == null ? item.parameters : [item.key, ...item.parameters];
|
|
6052
6122
|
result = await state.callback(...parameters);
|
|
6053
6123
|
}
|
|
@@ -6057,9 +6127,7 @@ async function run(state) {
|
|
|
6057
6127
|
}
|
|
6058
6128
|
if (state.paused) {
|
|
6059
6129
|
const paused = item;
|
|
6060
|
-
state.handled.push(() =>
|
|
6061
|
-
handleQueuedResult(paused, error, result);
|
|
6062
|
-
});
|
|
6130
|
+
state.handled.push(() => handleQueuedResult(paused, error, result));
|
|
6063
6131
|
break;
|
|
6064
6132
|
}
|
|
6065
6133
|
handleQueuedResult(item, error, result);
|
|
@@ -6067,24 +6135,22 @@ async function run(state) {
|
|
|
6067
6135
|
}
|
|
6068
6136
|
state.runners -= 1;
|
|
6069
6137
|
}
|
|
6070
|
-
const
|
|
6071
|
-
const
|
|
6072
|
-
const
|
|
6073
|
-
const
|
|
6074
|
-
const
|
|
6075
|
-
const
|
|
6076
|
-
const
|
|
6077
|
-
const
|
|
6078
|
-
const
|
|
6079
|
-
const
|
|
6080
|
-
const
|
|
6081
|
-
const
|
|
6082
|
-
const
|
|
6083
|
-
const
|
|
6084
|
-
const
|
|
6085
|
-
const
|
|
6086
|
-
const STATUS_FULL = "full";
|
|
6087
|
-
const STATUS_PAUSED = "paused";
|
|
6138
|
+
const QUEUE_ERROR_NAME = "QueueError";
|
|
6139
|
+
const QUEUE_PROPERTY = "$queue";
|
|
6140
|
+
const QUEUE_HANDLE_CLEAR = "clear";
|
|
6141
|
+
const QUEUE_HANDLE_PAUSE = "pause";
|
|
6142
|
+
const QUEUE_HANDLE_RESUME = "resume";
|
|
6143
|
+
const QUEUE_MESSAGE_CALLBACK = "A Queue requires a callback function";
|
|
6144
|
+
const QUEUE_MESSAGE_CLEAR = "Queue was cleared";
|
|
6145
|
+
const QUEUE_MESSAGE_KEY = "Key must be a non-empty string";
|
|
6146
|
+
const QUEUE_MESSAGE_MAXIMUM = "Queue has reached its maximum size";
|
|
6147
|
+
const QUEUE_MESSAGE_REMOVE = "Item removed from queue";
|
|
6148
|
+
const QUEUE_NAME_KEYED = "keyedQueue";
|
|
6149
|
+
const QUEUE_NAME_QUEUE = "queue";
|
|
6150
|
+
const QUEUE_STATUS_ACTIVE = "active";
|
|
6151
|
+
const QUEUE_STATUS_EMPTY = "empty";
|
|
6152
|
+
const QUEUE_STATUS_FULL = "full";
|
|
6153
|
+
const QUEUE_STATUS_PAUSED = "paused";
|
|
6088
6154
|
//#endregion
|
|
6089
6155
|
//#region src/random.ts
|
|
6090
6156
|
/**
|
|
@@ -6093,7 +6159,7 @@ const STATUS_PAUSED = "paused";
|
|
|
6093
6159
|
* @returns Random boolean
|
|
6094
6160
|
*/
|
|
6095
6161
|
function getRandomBoolean() {
|
|
6096
|
-
return Math.random() >
|
|
6162
|
+
return Math.random() > RANDOM_BOOLEAN_MODIFIER;
|
|
6097
6163
|
}
|
|
6098
6164
|
/**
|
|
6099
6165
|
* Get a random string of characters with a specified length
|
|
@@ -6104,7 +6170,7 @@ function getRandomBoolean() {
|
|
|
6104
6170
|
*/
|
|
6105
6171
|
function getRandomCharacters(length, selection) {
|
|
6106
6172
|
if (typeof length !== "number" || length <= 0) return "";
|
|
6107
|
-
const actual = typeof selection === "string" && selection.length > 0 ? selection :
|
|
6173
|
+
const actual = typeof selection === "string" && selection.length > 0 ? selection : RANDOM_ALPHABET;
|
|
6108
6174
|
let characters = "";
|
|
6109
6175
|
for (let index = 0; index < length; index += 1) characters += actual.charAt(getRandomInteger(0, actual.length - 1));
|
|
6110
6176
|
return characters;
|
|
@@ -6124,7 +6190,7 @@ function getRandomColor(prefix) {
|
|
|
6124
6190
|
* @returns Random hexadecimal character from `0-9` and `A-F`
|
|
6125
6191
|
*/
|
|
6126
6192
|
function getRandomHex() {
|
|
6127
|
-
return
|
|
6193
|
+
return RANDOM_HEX_CHARACTERS[getRandomInteger(0, RANDOM_HEX_MAXIMUM)];
|
|
6128
6194
|
}
|
|
6129
6195
|
/**
|
|
6130
6196
|
* Get a random item from an array
|
|
@@ -6142,96 +6208,10 @@ function getRandomItems(array, amount) {
|
|
|
6142
6208
|
if (amount === 1) return [array[getRandomInteger(0, array.length - 1)]];
|
|
6143
6209
|
return typeof amount !== "number" || amount <= 0 || amount >= array.length ? shuffle(array) : shuffle(array).slice(0, amount);
|
|
6144
6210
|
}
|
|
6145
|
-
const
|
|
6146
|
-
const
|
|
6147
|
-
const
|
|
6148
|
-
const
|
|
6149
|
-
//#endregion
|
|
6150
|
-
//#region src/result/index.ts
|
|
6151
|
-
async function asyncAttempt(value, err) {
|
|
6152
|
-
try {
|
|
6153
|
-
let result = typeof value === "function" ? value() : await value;
|
|
6154
|
-
if (result instanceof Promise) result = await result;
|
|
6155
|
-
return ok(result);
|
|
6156
|
-
} catch (thrown) {
|
|
6157
|
-
return getError(err ?? thrown, err == null ? void 0 : thrown);
|
|
6158
|
-
}
|
|
6159
|
-
}
|
|
6160
|
-
function attempt(callback, err) {
|
|
6161
|
-
try {
|
|
6162
|
-
return ok(callback());
|
|
6163
|
-
} catch (thrown) {
|
|
6164
|
-
return getError(err ?? thrown, err == null ? void 0 : thrown);
|
|
6165
|
-
}
|
|
6166
|
-
}
|
|
6167
|
-
attempt.async = asyncAttempt;
|
|
6168
|
-
//#endregion
|
|
6169
|
-
//#region src/result/match.ts
|
|
6170
|
-
async function asyncMatchResult(result, first, error) {
|
|
6171
|
-
let value;
|
|
6172
|
-
if (typeof result === "function") value = await result();
|
|
6173
|
-
else if (result instanceof Promise) value = await result;
|
|
6174
|
-
else value = result;
|
|
6175
|
-
if (!isResult(value)) throw new Error(MESSAGE_RESULT);
|
|
6176
|
-
const hasObj = typeof first === "object" && first !== null;
|
|
6177
|
-
const okHandler = hasObj ? first.ok : first;
|
|
6178
|
-
const errorHandler = hasObj ? first.error : error;
|
|
6179
|
-
if (isOk(value)) return okHandler(value.value);
|
|
6180
|
-
return errorHandler(value.error, value.original);
|
|
6181
|
-
}
|
|
6182
|
-
function matchResult(result, first, error) {
|
|
6183
|
-
const value = typeof result === "function" ? result() : result;
|
|
6184
|
-
if (!isResult(value)) throw new Error(MESSAGE_RESULT);
|
|
6185
|
-
const hasObj = typeof first === "object" && first !== null;
|
|
6186
|
-
const okHandler = hasObj ? first.ok : first;
|
|
6187
|
-
const errorHandler = hasObj ? first.error : error;
|
|
6188
|
-
if (isOk(value)) return okHandler(value.value);
|
|
6189
|
-
return errorHandler(value.error, value.original);
|
|
6190
|
-
}
|
|
6191
|
-
matchResult.async = asyncMatchResult;
|
|
6192
|
-
const MESSAGE_RESULT = "`result.match` expected a Result or a function that returns a Result";
|
|
6193
|
-
//#endregion
|
|
6194
|
-
//#region src/result/work/flow.ts
|
|
6195
|
-
function attemptAsyncFlow(...fns) {
|
|
6196
|
-
let Flow;
|
|
6197
|
-
return (...args) => attempt.async(() => {
|
|
6198
|
-
Flow ??= flow.async(...fns);
|
|
6199
|
-
return Flow(...args.map((value) => {
|
|
6200
|
-
if (isError(value)) throw value.error;
|
|
6201
|
-
return isOk(value) ? value.value : value;
|
|
6202
|
-
}));
|
|
6203
|
-
});
|
|
6204
|
-
}
|
|
6205
|
-
function attemptFlow(...fns) {
|
|
6206
|
-
let Flow;
|
|
6207
|
-
return (...args) => attempt(() => {
|
|
6208
|
-
Flow ??= flow(...fns);
|
|
6209
|
-
return Flow(...args.map((value) => {
|
|
6210
|
-
if (isError(value)) throw value.error;
|
|
6211
|
-
return isOk(value) ? value.value : value;
|
|
6212
|
-
}));
|
|
6213
|
-
});
|
|
6214
|
-
}
|
|
6215
|
-
attemptFlow.async = attemptAsyncFlow;
|
|
6216
|
-
//#endregion
|
|
6217
|
-
//#region src/result/work/pipe.ts
|
|
6218
|
-
async function attemptAsyncPipe(initial, first, ...seconds) {
|
|
6219
|
-
return attempt.async(() => {
|
|
6220
|
-
if (isError(initial)) throw initial.error;
|
|
6221
|
-
const value = typeof initial === "function" ? initial() : isOk(initial) ? initial.value : initial;
|
|
6222
|
-
if (first == null) return value;
|
|
6223
|
-
return asyncPipe(value, ...[first, ...seconds]);
|
|
6224
|
-
});
|
|
6225
|
-
}
|
|
6226
|
-
function attemptPipe(initial, first, ...seconds) {
|
|
6227
|
-
return attempt(() => {
|
|
6228
|
-
if (isError(initial)) throw initial.error;
|
|
6229
|
-
const value = typeof initial === "function" ? initial() : isOk(initial) ? initial.value : initial;
|
|
6230
|
-
if (first == null) return value;
|
|
6231
|
-
return pipe(value, ...[first, ...seconds]);
|
|
6232
|
-
});
|
|
6233
|
-
}
|
|
6234
|
-
attemptPipe.async = attemptAsyncPipe;
|
|
6211
|
+
const RANDOM_ALPHABET = "abcdefghijklmnopqrstuvwxyz";
|
|
6212
|
+
const RANDOM_BOOLEAN_MODIFIER = .5;
|
|
6213
|
+
const RANDOM_HEX_CHARACTERS = "0123456789ABCDEF";
|
|
6214
|
+
const RANDOM_HEX_MAXIMUM = 15;
|
|
6235
6215
|
//#endregion
|
|
6236
6216
|
//#region src/sized/set.ts
|
|
6237
6217
|
/**
|
|
@@ -6289,4 +6269,4 @@ var SizedSet = class extends Set {
|
|
|
6289
6269
|
}
|
|
6290
6270
|
};
|
|
6291
6271
|
//#endregion
|
|
6292
|
-
export { CancelablePromise, Logger,
|
|
6272
|
+
export { CancelablePromise, Logger, PromiseTimeoutError, QueueError, RetryError, SORT_DIRECTION_ASCENDING, SORT_DIRECTION_DESCENDING, SizedMap, SizedSet, assert, assertCondition, assertDefined, assertInstanceOf, assertIs, assertProperty, assign, asyncAttempt, asyncDebounce, asyncFlow, asyncMatchResult, asyncOnce, asyncPipe, asyncThrottle, attempt, attemptAsyncFlow, attemptAsyncPipe, attemptFlow, attemptPipe, attemptPromise, average, beacon, between, camelCase, cancelable, capitalize, ceil, chunk, clamp, clone, compact, compare, copy, count, debounce, deburr, dedent, delay, deregisterCloner, deregisterComparator, deregisterEqualizer, diff, difference, drop, endsWith, endsWithArray, equal, error, exclude, exists, filter, find, findLast, first, firstOrDefault, flatFreeze, flatten, floor, flow, freeze, fromQuery, toPromise as fromResult, toPromise, fuzzy, fuzzyMatch, getArray, getArrayComparison, getColor, getForegroundColor, getHexColor, getHexaColor, getHslColor, getHslaColor, getHwbColor, getHwbaColor, getNormalizedHex, getNumber, getRandomBoolean, getRandomCharacters, getRandomColor, getRandomFloatingNumber as getRandomFloat, getRandomHex, getRandomInteger, getRandomItem, getRandomItems, getRgbColor, getRgbaColor, getSortedIndex, getString, getTimedPromise, getUuid, getValue, groupArraysBy, groupBy, handleResult, hasValue, hasValueResult, herald, hexToHsl, hexToHsla, hexToHwb, hexToHwba, hexToRgb, hexToRgba, hslToHex, hslToHwb, hslToHwba, hslToRgb, hslToRgba, hwbToHex, hwbToHsl, hwbToHsla, hwbToRgb, hwbToRgba, ignoreKey, inMap, inSet, includes, includesArray, indexOf, indexOfArray, initializeAssigner, initializeEqualizer, initializeMerger, initializeNormalizer, initializeSorter, initializeTemplater, initializeTransformer, insert, interpolate, intersection, isArrayOrPlainObject, isBeacon, isBeaconSubscription, isColor, isConstructor, isEmpty, isError, isFrozen, isFulfilled, isHerald, isHeraldEvents, isHeraldSubscription, isHexColor, isHslColor, isHslaColor, isHwbColor, isHwbaColor, isInstanceOf, isKey, isKeyedQueue, isLogger, isNonArrayOrPlainObject, isNonConstructor, isNonEmpty, isNonInstanceOf, isNonKey, isNonNullable, isNonNullableOrEmpty, isNonNullableOrWhitespace, isNonNumber, isNonNumerical, isNonObject, isNonPlainObject, isNonPrimitive, isNonTypedArray, isNullable, isNullableOrEmpty, isNullableOrWhitespace, isNumber, isNumerical, isObject, isObservable, isOk, isPlainObject, isPrimitive, isQueue, isQueueInstance, isRejected, isResult, isRgbColor, isRgbaColor, isSorted, isSubscription, isTimedLogger, isTypedArray, join, kebabCase, keyedQueue, last, lastIndexOf, lastOrDefault, lowerCase, matchResult, max, median, memoize, merge, min, move, moveIndices, moveToIndex, noop, normalize, ok, omit, once, parse, partition, pascalCase, pick, pipe, promises, push, queue, range, registerCloner, registerComparator, registerEqualizer, resultPromises, retry, reverse, rgbToHex, rgbToHsl, rgbToHsla, rgbToHwb, rgbToHwba, round, select, setValue, settlePromise, shake, shuffle, single, slice, smush, snakeCase, sort, splice, startsWith, startsWithArray, sum, swap, take, template, throttle, timed, times, titleCase, toMap, toMapArrays, toQuery, toRecord, toRecordArrays, toResult, toSet, toggle, transform, trim, truncate, tryDecode, tryEncode, union, unique, unsmush, unwrap, update, upperCase, words };
|