@oscarpalmer/atoms 0.194.0 → 0.195.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/array/index.d.mts +2 -2
- package/dist/array/index.mjs +2 -2
- package/dist/array/move.mjs +1 -1
- package/dist/array/swap.mjs +1 -1
- package/dist/color/instance.mjs +1 -1
- package/dist/color/misc/state.d.mts +1 -1
- package/dist/color/models.d.mts +1 -1
- 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 +6 -0
- package/dist/function/limit.mjs +2 -0
- package/dist/function/once.d.mts +3 -0
- package/dist/function/once.mjs +2 -1
- package/dist/function/retry.d.mts +24 -1
- package/dist/function/retry.mjs +1 -0
- package/dist/herald.d.mts +2 -71
- package/dist/herald.mjs +1 -109
- package/dist/index.d.mts +3325 -3282
- package/dist/index.mjs +1508 -1498
- 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 +2 -2
- 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 +2 -2
- package/dist/{function → internal/function}/memoize.d.mts +2 -2
- package/dist/{function → internal/function}/memoize.mjs +3 -3
- package/dist/{function → internal/function}/work.d.mts +2 -2
- package/dist/{function → internal/function}/work.mjs +2 -2
- 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 +1 -4
- package/dist/internal/{result.d.mts → result/misc.d.mts} +42 -3
- package/dist/internal/{result.mjs → result/misc.mjs} +29 -3
- 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.mjs → sized/misc.mjs} +2 -2
- package/dist/{string → internal/string}/case.d.mts +1 -1
- package/dist/{string → internal/string}/case.mjs +2 -2
- package/dist/internal/{string.d.mts → string/misc.d.mts} +1 -1
- package/dist/internal/{string.mjs → string/misc.mjs} +1 -1
- package/dist/internal/value/compare.mjs +1 -1
- package/dist/internal/value/has.d.mts +1 -1
- package/dist/internal/value/misc.d.mts +1 -1
- package/dist/internal/value/misc.mjs +2 -2
- package/dist/is.mjs +2 -2
- package/dist/logger.mjs +1 -1
- package/dist/promise/helpers.d.mts +1 -1
- package/dist/promise/helpers.mjs +2 -2
- package/dist/promise/index.d.mts +1 -1
- package/dist/promise/misc.d.mts +1 -1
- package/dist/promise/misc.mjs +2 -1
- package/dist/promise/models.d.mts +1 -1
- package/dist/query.mjs +1 -1
- package/dist/queue.mjs +1 -4
- package/dist/random.mjs +1 -1
- package/dist/result/index.d.mts +4 -1
- package/dist/result/index.mjs +2 -1
- package/dist/result/match.d.mts +4 -1
- package/dist/result/match.mjs +2 -1
- package/dist/result/misc.d.mts +3 -42
- package/dist/result/misc.mjs +2 -28
- package/dist/result/work/flow.d.mts +4 -1
- package/dist/result/work/flow.mjs +3 -2
- package/dist/result/work/pipe.d.mts +4 -1
- package/dist/result/work/pipe.mjs +3 -2
- package/dist/sized/set.mjs +1 -1
- package/dist/string/fuzzy.mjs +2 -2
- package/dist/string/index.d.mts +1 -1
- package/dist/string/index.mjs +1 -1
- package/dist/string/match.mjs +1 -1
- package/dist/string/normalize.mjs +2 -2
- package/dist/string/template.mjs +1 -1
- package/dist/subscription.d.mts +2 -0
- package/dist/subscription.mjs +2 -0
- package/dist/value/diff.mjs +1 -1
- package/dist/value/smush.mjs +1 -1
- package/package.json +23 -11
- /package/dist/{result → internal/result}/models.mjs +0 -0
package/dist/index.mjs
CHANGED
|
@@ -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;
|
|
@@ -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;
|
|
@@ -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 ? MATCH_COMPARISON_SAME : MATCH_COMPARISON_START;
|
|
570
|
-
return start + needle === haystack ? MATCH_COMPARISON_END : MATCH_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 MATCH_COMPARISON_END = "end";
|
|
606
|
-
const MATCH_COMPARISON_INSIDE = "inside";
|
|
607
|
-
const MATCH_COMPARISON_INVALID = "invalid";
|
|
608
|
-
const MATCH_COMPARISON_OUTSIDE = "outside";
|
|
609
|
-
const MATCH_COMPARISON_SAME = "same";
|
|
610
|
-
const MATCH_COMPARISON_START = "start";
|
|
611
|
-
const endings = /* @__PURE__ */ new Set([MATCH_COMPARISON_END, MATCH_COMPARISON_SAME]);
|
|
612
|
-
const invalid = [-1, MATCH_COMPARISON_INVALID];
|
|
613
|
-
const outside = [-1, MATCH_COMPARISON_OUTSIDE];
|
|
614
|
-
const outsides = /* @__PURE__ */ new Set([MATCH_COMPARISON_INVALID, MATCH_COMPARISON_OUTSIDE]);
|
|
615
|
-
const starts = /* @__PURE__ */ new Set([MATCH_COMPARISON_START, MATCH_COMPARISON_SAME]);
|
|
616
|
-
//#endregion
|
|
617
617
|
//#region src/array/push.ts
|
|
618
618
|
/**
|
|
619
619
|
* Push items into an array _(at the end)_
|
|
@@ -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
|
*
|
|
@@ -1381,70 +1381,206 @@ function toRecordArrays(array, first, second) {
|
|
|
1381
1381
|
return groupValues(array, first, second, true);
|
|
1382
1382
|
}
|
|
1383
1383
|
//#endregion
|
|
1384
|
-
//#region src/internal/
|
|
1385
|
-
function isError(value, extended) {
|
|
1386
|
-
return isResultValue(value, false) && (extended === true ? value.original instanceof Error : true);
|
|
1387
|
-
}
|
|
1388
|
-
function isOk(value) {
|
|
1389
|
-
return isResultValue(value, true);
|
|
1390
|
-
}
|
|
1384
|
+
//#region src/internal/function/misc.ts
|
|
1391
1385
|
/**
|
|
1392
|
-
*
|
|
1393
|
-
*
|
|
1394
|
-
* @param value Value to check
|
|
1395
|
-
* @returns `true` if the value is a _Result_, otherwise `false`
|
|
1386
|
+
* A function that does nothing, which can be useful, I guess…
|
|
1396
1387
|
*/
|
|
1397
|
-
function
|
|
1398
|
-
return isResultValue(value, true) || isResultValue(value, false);
|
|
1399
|
-
}
|
|
1400
|
-
function isResultValue(value, okValue) {
|
|
1401
|
-
if (isNonPlainObject(value)) return false;
|
|
1402
|
-
return value.ok === okValue && (okValue ? RESULT_PROPERTY_VALUE : RESULT_PROPERTY_ERROR) in value;
|
|
1403
|
-
}
|
|
1404
|
-
const RESULT_PROPERTY_ERROR = "error";
|
|
1405
|
-
const RESULT_PROPERTY_VALUE = "value";
|
|
1388
|
+
function noop() {}
|
|
1406
1389
|
//#endregion
|
|
1407
|
-
//#region src/
|
|
1408
|
-
function
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
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;
|
|
1415
1435
|
};
|
|
1416
|
-
|
|
1417
|
-
return
|
|
1436
|
+
Object.defineProperty(timer, TIMER_CANCEL, { value: () => cancel() });
|
|
1437
|
+
return timer;
|
|
1418
1438
|
}
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
*
|
|
1422
|
-
* @param value Value
|
|
1423
|
-
* @returns Ok result
|
|
1424
|
-
*/
|
|
1425
|
-
function ok(value) {
|
|
1426
|
-
return {
|
|
1427
|
-
ok: true,
|
|
1428
|
-
value
|
|
1429
|
-
};
|
|
1439
|
+
function getInterval(value) {
|
|
1440
|
+
return typeof value === "number" && value > 0 ? value : 0;
|
|
1430
1441
|
}
|
|
1431
|
-
|
|
1432
|
-
|
|
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);
|
|
1464
|
+
};
|
|
1465
|
+
Object.defineProperty(timer, TIMER_CANCEL, { value: () => cancel() });
|
|
1466
|
+
return timer;
|
|
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
|
|
1479
|
+
/**
|
|
1480
|
+
* Debounce a function, ensuring it is only called after `time` milliseconds have passed
|
|
1433
1481
|
*
|
|
1434
|
-
*
|
|
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...)_
|
|
1435
1484
|
*
|
|
1436
|
-
*
|
|
1437
|
-
*
|
|
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
|
|
1438
1490
|
*/
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1491
|
+
function asyncDebounce(callback, time) {
|
|
1492
|
+
return getAsyncTimer(TIMER_DEBOUNCE, callback, time);
|
|
1493
|
+
}
|
|
1494
|
+
/**
|
|
1495
|
+
* Throttle a function, ensuring it is only called once every `time` milliseconds
|
|
1496
|
+
*
|
|
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...)_
|
|
1499
|
+
*
|
|
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
|
|
1505
|
+
*/
|
|
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
|
+
debounce.async = asyncDebounce;
|
|
1532
|
+
throttle.async = asyncThrottle;
|
|
1533
|
+
Object.defineProperty(debounce, "async", { value: asyncDebounce });
|
|
1534
|
+
Object.defineProperty(throttle, "async", { value: asyncThrottle });
|
|
1535
|
+
//#endregion
|
|
1536
|
+
//#region src/internal/result/misc.ts
|
|
1537
|
+
function error(value, original) {
|
|
1538
|
+
return getError(value, original);
|
|
1539
|
+
}
|
|
1540
|
+
function getError(value, original) {
|
|
1541
|
+
const errorResult = {
|
|
1542
|
+
error: value,
|
|
1543
|
+
ok: false
|
|
1544
|
+
};
|
|
1545
|
+
if (original instanceof Error) errorResult.original = original;
|
|
1546
|
+
return errorResult;
|
|
1547
|
+
}
|
|
1548
|
+
function isError(value, extended) {
|
|
1549
|
+
return isResultValue(value, false) && (extended === true ? value.original instanceof Error : true);
|
|
1550
|
+
}
|
|
1551
|
+
function isOk(value) {
|
|
1552
|
+
return isResultValue(value, true);
|
|
1553
|
+
}
|
|
1554
|
+
/**
|
|
1555
|
+
* Is the value a _Result_?
|
|
1556
|
+
*
|
|
1557
|
+
* @param value Value to check
|
|
1558
|
+
* @returns `true` if the value is a _Result_, otherwise `false`
|
|
1559
|
+
*/
|
|
1560
|
+
function isResult(value) {
|
|
1561
|
+
return isResultValue(value, true) || isResultValue(value, false);
|
|
1562
|
+
}
|
|
1563
|
+
function isResultValue(value, okValue) {
|
|
1564
|
+
if (isNonPlainObject(value)) return false;
|
|
1565
|
+
return value.ok === okValue && (okValue ? RESULT_PROPERTY_VALUE : RESULT_PROPERTY_ERROR) in value;
|
|
1566
|
+
}
|
|
1567
|
+
/**
|
|
1568
|
+
* Creates an ok result
|
|
1569
|
+
*
|
|
1570
|
+
* @param value Value
|
|
1571
|
+
* @returns Ok result
|
|
1572
|
+
*/
|
|
1573
|
+
function ok(value) {
|
|
1574
|
+
return {
|
|
1575
|
+
ok: true,
|
|
1576
|
+
value
|
|
1577
|
+
};
|
|
1443
1578
|
}
|
|
1444
1579
|
function unwrap(value, defaultValue) {
|
|
1445
1580
|
return isOk(value) ? value.value : defaultValue;
|
|
1446
1581
|
}
|
|
1447
|
-
const
|
|
1582
|
+
const RESULT_PROPERTY_ERROR = "error";
|
|
1583
|
+
const RESULT_PROPERTY_VALUE = "value";
|
|
1448
1584
|
//#endregion
|
|
1449
1585
|
//#region src/internal/value/misc.ts
|
|
1450
1586
|
function findKey(needle, haystack) {
|
|
@@ -1499,7 +1635,7 @@ function hasValueResult(data, path, ignoreCase) {
|
|
|
1499
1635
|
return getNestedValue(data, path, ignoreCase === true);
|
|
1500
1636
|
}
|
|
1501
1637
|
//#endregion
|
|
1502
|
-
//#region src/function/assert.ts
|
|
1638
|
+
//#region src/internal/function/assert.ts
|
|
1503
1639
|
/**
|
|
1504
1640
|
* Asserts that a condition is true, throwing an error if it is not
|
|
1505
1641
|
*
|
|
@@ -1593,51 +1729,311 @@ function assertProperty(path, condition, message, error) {
|
|
|
1593
1729
|
}
|
|
1594
1730
|
const ASSERT_MESSAGE_VALUE_DEFINED = "Expected value to be defined";
|
|
1595
1731
|
//#endregion
|
|
1596
|
-
//#region src/
|
|
1597
|
-
/**
|
|
1598
|
-
* A function that does nothing, which can be useful, I guess…
|
|
1599
|
-
*/
|
|
1600
|
-
function noop() {}
|
|
1601
|
-
//#endregion
|
|
1602
|
-
//#region src/internal/number.ts
|
|
1732
|
+
//#region src/function/once.ts
|
|
1603
1733
|
/**
|
|
1604
|
-
*
|
|
1734
|
+
* Create an asynchronous function that can only be called once, rejecting or resolving the same result on subsequent calls
|
|
1605
1735
|
*
|
|
1606
|
-
*
|
|
1607
|
-
*
|
|
1608
|
-
* @param
|
|
1609
|
-
* @returns
|
|
1736
|
+
* _Available as `asyncOnce` and `once.async`_
|
|
1737
|
+
*
|
|
1738
|
+
* @param callback Callback to use once
|
|
1739
|
+
* @returns _Once_ callback
|
|
1610
1740
|
*/
|
|
1611
|
-
function
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1741
|
+
function asyncOnce(callback) {
|
|
1742
|
+
assert(() => typeof callback === "function", ONCE_MESSAGE_EXPECTATION);
|
|
1743
|
+
const state = {
|
|
1744
|
+
called: false,
|
|
1745
|
+
cleared: false,
|
|
1746
|
+
error: false,
|
|
1747
|
+
finished: false,
|
|
1748
|
+
items: [],
|
|
1749
|
+
value: void 0
|
|
1750
|
+
};
|
|
1751
|
+
const fn = (...parameters) => {
|
|
1752
|
+
if (state.cleared) return Promise.reject(new Error(ONCE_MESSAGE_CLEARED));
|
|
1753
|
+
if (state.finished) return state.error ? Promise.reject(state.value) : Promise.resolve(state.value);
|
|
1754
|
+
if (state.called) return new Promise((resolve, reject) => {
|
|
1755
|
+
state.items.push({
|
|
1756
|
+
reject,
|
|
1757
|
+
resolve
|
|
1758
|
+
});
|
|
1759
|
+
});
|
|
1760
|
+
state.called = true;
|
|
1761
|
+
return new Promise((resolve, reject) => {
|
|
1762
|
+
state.items.push({
|
|
1763
|
+
reject,
|
|
1764
|
+
resolve
|
|
1765
|
+
});
|
|
1766
|
+
callback(...parameters).then((value) => {
|
|
1767
|
+
handleOnceResult(state, value, false);
|
|
1768
|
+
}).catch((error) => {
|
|
1769
|
+
handleOnceResult(state, error, true);
|
|
1770
|
+
});
|
|
1771
|
+
});
|
|
1772
|
+
};
|
|
1773
|
+
Object.defineProperties(fn, {
|
|
1774
|
+
called: {
|
|
1775
|
+
enumerable: true,
|
|
1776
|
+
get: () => state.called
|
|
1777
|
+
},
|
|
1778
|
+
clear: { value: () => clearState(state) },
|
|
1779
|
+
cleared: {
|
|
1780
|
+
enumerable: true,
|
|
1781
|
+
get: () => state.cleared
|
|
1782
|
+
},
|
|
1783
|
+
error: {
|
|
1784
|
+
enumerable: true,
|
|
1785
|
+
get: () => state.error
|
|
1786
|
+
},
|
|
1787
|
+
finished: {
|
|
1788
|
+
enumerable: true,
|
|
1789
|
+
get: () => state.finished
|
|
1790
|
+
}
|
|
1791
|
+
});
|
|
1792
|
+
return fn;
|
|
1793
|
+
}
|
|
1794
|
+
function clearState(state) {
|
|
1795
|
+
if (!state.called || state.cleared) return;
|
|
1796
|
+
state.cleared = true;
|
|
1797
|
+
state.value = void 0;
|
|
1798
|
+
}
|
|
1799
|
+
function handleOnceResult(state, value, error) {
|
|
1800
|
+
state.error = error;
|
|
1801
|
+
state.finished = true;
|
|
1802
|
+
state.value = value;
|
|
1803
|
+
const items = state.items.splice(0);
|
|
1804
|
+
const { length } = items;
|
|
1805
|
+
for (let index = 0; index < length; index += 1) {
|
|
1806
|
+
const { reject, resolve } = items[index];
|
|
1807
|
+
if (error) reject(value);
|
|
1808
|
+
else resolve(value);
|
|
1809
|
+
}
|
|
1619
1810
|
}
|
|
1620
1811
|
/**
|
|
1621
|
-
*
|
|
1622
|
-
*
|
|
1623
|
-
* @param value Value to clamp
|
|
1624
|
-
* @param minimum Minimum value
|
|
1625
|
-
* @param maximum Maximum value
|
|
1626
|
-
* @param loop If `true`, the value will loop around when smaller than the minimum or larger than the maximum _(defaults to `false`)_
|
|
1627
|
-
* @returns Clamped value
|
|
1812
|
+
* Create a function that can only be called once, returning the same value on subsequent calls
|
|
1628
1813
|
*
|
|
1629
|
-
* @
|
|
1630
|
-
*
|
|
1631
|
-
* clamp(10, 0, 5); // => 5
|
|
1632
|
-
* clamp(10, 0, 5, true); // => 0
|
|
1633
|
-
* ```
|
|
1814
|
+
* @param callback Callback to use once
|
|
1815
|
+
* @returns _Once_ callback
|
|
1634
1816
|
*/
|
|
1635
|
-
function
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1817
|
+
function once(callback) {
|
|
1818
|
+
assert(() => typeof callback === "function", ONCE_MESSAGE_EXPECTATION);
|
|
1819
|
+
const state = {
|
|
1820
|
+
called: false,
|
|
1821
|
+
cleared: false,
|
|
1822
|
+
value: void 0
|
|
1823
|
+
};
|
|
1824
|
+
const fn = (...parameters) => {
|
|
1825
|
+
if (state.cleared) throw new Error(ONCE_MESSAGE_CLEARED);
|
|
1826
|
+
if (state.called) return state.value;
|
|
1827
|
+
state.called = true;
|
|
1828
|
+
state.value = callback(...parameters);
|
|
1829
|
+
return state.value;
|
|
1830
|
+
};
|
|
1831
|
+
Object.defineProperties(fn, {
|
|
1832
|
+
called: {
|
|
1833
|
+
enumerable: true,
|
|
1834
|
+
get: () => state.called
|
|
1835
|
+
},
|
|
1836
|
+
clear: { value: () => clearState(state) },
|
|
1837
|
+
cleared: {
|
|
1838
|
+
enumerable: true,
|
|
1839
|
+
get: () => state.cleared
|
|
1840
|
+
}
|
|
1841
|
+
});
|
|
1842
|
+
return fn;
|
|
1843
|
+
}
|
|
1844
|
+
const ONCE_MESSAGE_CLEARED = "Once has been cleared";
|
|
1845
|
+
const ONCE_MESSAGE_EXPECTATION = "Once expected a function";
|
|
1846
|
+
once.async = asyncOnce;
|
|
1847
|
+
Object.defineProperty(once, "async", { value: asyncOnce });
|
|
1848
|
+
//#endregion
|
|
1849
|
+
//#region src/function/retry.ts
|
|
1850
|
+
/**
|
|
1851
|
+
* An error thrown when a retry fails
|
|
1852
|
+
*/
|
|
1853
|
+
var RetryError = class extends Error {
|
|
1854
|
+
original;
|
|
1855
|
+
constructor(message, original) {
|
|
1856
|
+
super(message);
|
|
1857
|
+
this.original = original;
|
|
1858
|
+
this.name = RETRY_ERROR_NAME;
|
|
1859
|
+
}
|
|
1860
|
+
};
|
|
1861
|
+
/**
|
|
1862
|
+
* Retry a callback a specified number of times, with a delay between attempts
|
|
1863
|
+
*
|
|
1864
|
+
* _Available as `asyncRetry` and `retry.async`_
|
|
1865
|
+
*
|
|
1866
|
+
* @param callback Callback to retry
|
|
1867
|
+
* @param options Retry options
|
|
1868
|
+
* @returns Callback result
|
|
1869
|
+
*/
|
|
1870
|
+
async function asyncRetry(callback, options) {
|
|
1871
|
+
if (typeof callback !== "function") throw new TypeError(RETRY_MESSAGE_EXPECTATION);
|
|
1872
|
+
async function handle() {
|
|
1873
|
+
try {
|
|
1874
|
+
const result = await callback();
|
|
1875
|
+
resolver(result);
|
|
1876
|
+
} catch (error) {
|
|
1877
|
+
if (attempts >= times || !when(error)) rejector(new RetryError(RETRY_MESSAGE_FAILED, error));
|
|
1878
|
+
else {
|
|
1879
|
+
attempts += 1;
|
|
1880
|
+
timer();
|
|
1881
|
+
}
|
|
1882
|
+
}
|
|
1883
|
+
}
|
|
1884
|
+
const { delay, times, when } = getRetryOptions(options);
|
|
1885
|
+
const timer = getTimer(TIMER_WAIT, handle, delay);
|
|
1886
|
+
let attempts = 0;
|
|
1887
|
+
let rejector;
|
|
1888
|
+
let resolver;
|
|
1889
|
+
return new Promise((resolve, reject) => {
|
|
1890
|
+
rejector = reject;
|
|
1891
|
+
resolver = resolve;
|
|
1892
|
+
handle();
|
|
1893
|
+
});
|
|
1894
|
+
}
|
|
1895
|
+
function getRetryNumber(value) {
|
|
1896
|
+
return typeof value === "number" && value > 0 ? value : 0;
|
|
1897
|
+
}
|
|
1898
|
+
function getRetryOptions(input) {
|
|
1899
|
+
const options = isPlainObject(input) ? input : {};
|
|
1900
|
+
return {
|
|
1901
|
+
delay: getRetryNumber(options.delay),
|
|
1902
|
+
times: getRetryNumber(options.times),
|
|
1903
|
+
when: typeof options.when === "function" ? options.when : shouldRetry
|
|
1904
|
+
};
|
|
1905
|
+
}
|
|
1906
|
+
/**
|
|
1907
|
+
* Retry a callback a specified number of times
|
|
1908
|
+
*
|
|
1909
|
+
* @param callback Callback to retry
|
|
1910
|
+
* @param options Retry options
|
|
1911
|
+
* @returns Callback result
|
|
1912
|
+
*/
|
|
1913
|
+
function retry(callback, options) {
|
|
1914
|
+
if (typeof callback !== "function") throw new TypeError(RETRY_MESSAGE_EXPECTATION);
|
|
1915
|
+
const { times, when } = getRetryOptions(options);
|
|
1916
|
+
let last;
|
|
1917
|
+
for (let index = 0; index <= times; index += 1) try {
|
|
1918
|
+
return callback();
|
|
1919
|
+
} catch (error) {
|
|
1920
|
+
if (index >= times || !when(error)) {
|
|
1921
|
+
last = error;
|
|
1922
|
+
break;
|
|
1923
|
+
}
|
|
1924
|
+
}
|
|
1925
|
+
throw new RetryError(RETRY_MESSAGE_FAILED, last);
|
|
1926
|
+
}
|
|
1927
|
+
function shouldRetry() {
|
|
1928
|
+
return true;
|
|
1929
|
+
}
|
|
1930
|
+
const RETRY_ERROR_NAME = "RetryError";
|
|
1931
|
+
const RETRY_MESSAGE_EXPECTATION = "Retry expected a function";
|
|
1932
|
+
const RETRY_MESSAGE_FAILED = "Retry failed";
|
|
1933
|
+
retry.async = asyncRetry;
|
|
1934
|
+
Object.defineProperty(retry, "async", { value: asyncRetry });
|
|
1935
|
+
//#endregion
|
|
1936
|
+
//#region src/internal/function/work.ts
|
|
1937
|
+
function asyncFlow(...fns) {
|
|
1938
|
+
assertFlowFunctions(fns);
|
|
1939
|
+
return (...args) => asyncWork(args.map((value) => {
|
|
1940
|
+
if (isError(value)) throw value.error;
|
|
1941
|
+
return isOk(value) ? value.value : value;
|
|
1942
|
+
}), fns, true);
|
|
1943
|
+
}
|
|
1944
|
+
function flow(...fns) {
|
|
1945
|
+
assertFlowFunctions(fns);
|
|
1946
|
+
return (...args) => work(args.map((value) => {
|
|
1947
|
+
if (isError(value)) throw value.error;
|
|
1948
|
+
return isOk(value) ? value.value : value;
|
|
1949
|
+
}), fns, true);
|
|
1950
|
+
}
|
|
1951
|
+
async function asyncPipe(value, ...pipes) {
|
|
1952
|
+
assertPipeFunctions(pipes);
|
|
1953
|
+
return asyncWork(value, pipes, false);
|
|
1954
|
+
}
|
|
1955
|
+
function pipe(value, ...pipes) {
|
|
1956
|
+
assertPipeFunctions(pipes);
|
|
1957
|
+
return work(value, pipes, false);
|
|
1958
|
+
}
|
|
1959
|
+
async function asyncWork(initial, functions, flow) {
|
|
1960
|
+
const { length } = functions;
|
|
1961
|
+
let transformed = unwrapValue(initial);
|
|
1962
|
+
for (let index = 0; index < length; index += 1) {
|
|
1963
|
+
const fn = functions[index];
|
|
1964
|
+
transformed = unwrapValue(flow && index === 0 && Array.isArray(initial) ? await fn(...initial) : await fn(transformed));
|
|
1965
|
+
}
|
|
1966
|
+
return transformed;
|
|
1967
|
+
}
|
|
1968
|
+
function unwrapValue(value, flow, nested) {
|
|
1969
|
+
if (typeof value === "function") {
|
|
1970
|
+
if (nested != null) throw new TypeError(WORK_MESSAGE_NESTING);
|
|
1971
|
+
return unwrapValue(value(), flow, true);
|
|
1972
|
+
}
|
|
1973
|
+
if (flow != null && value instanceof Promise) throw new TypeError(flow ? WORK_MESSAGE_FLOW_PROMISE : WORK_MESSAGE_PIPE_PROMISE);
|
|
1974
|
+
if (isError(value)) throw value.error;
|
|
1975
|
+
return isOk(value) ? value.value : value;
|
|
1976
|
+
}
|
|
1977
|
+
function work(initial, functions, flow) {
|
|
1978
|
+
const { length } = functions;
|
|
1979
|
+
let transformed = unwrapValue(initial, flow);
|
|
1980
|
+
for (let index = 0; index < length; index += 1) {
|
|
1981
|
+
const fn = functions[index];
|
|
1982
|
+
transformed = unwrapValue(flow && index === 0 && Array.isArray(initial) ? fn(...initial) : fn(transformed), flow);
|
|
1983
|
+
}
|
|
1984
|
+
return transformed;
|
|
1985
|
+
}
|
|
1986
|
+
const WORK_MESSAGE_FLOW_ARRAY = "Flow expected to receive an array of functions";
|
|
1987
|
+
const WORK_MESSAGE_FLOW_PROMISE = "Synchronous Flow received a promise. Use `flow.async` instead.";
|
|
1988
|
+
const WORK_MESSAGE_NESTING = "Return values are too deeply nested.";
|
|
1989
|
+
const WORK_MESSAGE_PIPE_ARRAY = "Pipe expected to receive an array of functions";
|
|
1990
|
+
const WORK_MESSAGE_PIPE_PROMISE = "Synchronous Pipe received a promise. Use `pipe.async` instead.";
|
|
1991
|
+
const assertFlowFunctions = assert.condition((value) => Array.isArray(value) && value.every((item) => typeof item === "function"), WORK_MESSAGE_FLOW_ARRAY, TypeError);
|
|
1992
|
+
const assertPipeFunctions = assert.condition((value) => Array.isArray(value) && value.every((item) => typeof item === "function"), WORK_MESSAGE_PIPE_ARRAY, TypeError);
|
|
1993
|
+
flow.async = asyncFlow;
|
|
1994
|
+
pipe.async = asyncPipe;
|
|
1995
|
+
Object.defineProperty(flow, "async", { value: asyncFlow });
|
|
1996
|
+
Object.defineProperty(pipe, "async", { value: asyncPipe });
|
|
1997
|
+
//#endregion
|
|
1998
|
+
//#region src/internal/number.ts
|
|
1999
|
+
/**
|
|
2000
|
+
* Is the number between a minimum and maximum value?
|
|
2001
|
+
*
|
|
2002
|
+
* @param value Value to check
|
|
2003
|
+
* @param minimum Minimum value
|
|
2004
|
+
* @param maximum Maximum value
|
|
2005
|
+
* @returns `true` if the value is between the minimum and maximum, otherwise `false`
|
|
2006
|
+
*/
|
|
2007
|
+
function between(value, minimum, maximum) {
|
|
2008
|
+
if (![
|
|
2009
|
+
value,
|
|
2010
|
+
minimum,
|
|
2011
|
+
maximum
|
|
2012
|
+
].every(isNumber)) return false;
|
|
2013
|
+
if (Object.is(minimum, maximum)) return Object.is(value, minimum);
|
|
2014
|
+
return value >= (maximum > minimum ? minimum : maximum) && value <= (maximum > minimum ? maximum : minimum);
|
|
2015
|
+
}
|
|
2016
|
+
/**
|
|
2017
|
+
* Clamp a number between a minimum and maximum value
|
|
2018
|
+
*
|
|
2019
|
+
* @param value Value to clamp
|
|
2020
|
+
* @param minimum Minimum value
|
|
2021
|
+
* @param maximum Maximum value
|
|
2022
|
+
* @param loop If `true`, the value will loop around when smaller than the minimum or larger than the maximum _(defaults to `false`)_
|
|
2023
|
+
* @returns Clamped value
|
|
2024
|
+
*
|
|
2025
|
+
* @example
|
|
2026
|
+
* ```typescript
|
|
2027
|
+
* clamp(10, 0, 5); // => 5
|
|
2028
|
+
* clamp(10, 0, 5, true); // => 0
|
|
2029
|
+
* ```
|
|
2030
|
+
*/
|
|
2031
|
+
function clamp(value, minimum, maximum, loop) {
|
|
2032
|
+
if (![
|
|
2033
|
+
value,
|
|
2034
|
+
minimum,
|
|
2035
|
+
maximum
|
|
2036
|
+
].every(isNumber)) return NaN;
|
|
1641
2037
|
if (value < minimum) return loop === true ? maximum : minimum;
|
|
1642
2038
|
return value > maximum ? loop === true ? minimum : maximum : value;
|
|
1643
2039
|
}
|
|
@@ -1664,15 +2060,12 @@ function getNumber(value) {
|
|
|
1664
2060
|
if (isBinary || NUMBER_EXPRESSION_OCTAL.test(trimmed)) return Number.parseInt(trimmed.slice(2), isBinary ? 2 : NUMBER_OCTAL_VALUE);
|
|
1665
2061
|
return Number(trimmed);
|
|
1666
2062
|
}
|
|
1667
|
-
function getNumberOrDefault(value, defaultValue, minimum) {
|
|
1668
|
-
return typeof value === "number" && !Number.isNaN(value) && value >= (minimum ?? 0) ? Math.floor(value) : defaultValue;
|
|
1669
|
-
}
|
|
1670
2063
|
const NUMBER_EXPRESSION_BINARY = /^0b[01]+$/i;
|
|
1671
2064
|
const NUMBER_EXPRESSION_OCTAL = /^0o[0-7]+$/i;
|
|
1672
2065
|
const NUMBER_EXPRESSION_ZEROISH = /^\s*0+\s*$/;
|
|
1673
2066
|
const NUMBER_OCTAL_VALUE = 8;
|
|
1674
2067
|
//#endregion
|
|
1675
|
-
//#region src/internal/sized.ts
|
|
2068
|
+
//#region src/internal/sized/misc.ts
|
|
1676
2069
|
function getSizedMaximum(first, second) {
|
|
1677
2070
|
let actual;
|
|
1678
2071
|
if (typeof first === "number") actual = first;
|
|
@@ -1682,7 +2075,7 @@ function getSizedMaximum(first, second) {
|
|
|
1682
2075
|
const SIZED_MAXIMUM_ABSOLUTE = 16777216;
|
|
1683
2076
|
const SIZED_MAXIMUM_DEFAULT = 1048576;
|
|
1684
2077
|
//#endregion
|
|
1685
|
-
//#region src/sized/map.ts
|
|
2078
|
+
//#region src/internal/sized/map.ts
|
|
1686
2079
|
/**
|
|
1687
2080
|
* A _Map_ with a maximum size
|
|
1688
2081
|
*
|
|
@@ -1736,7 +2129,7 @@ var SizedMap = class extends Map {
|
|
|
1736
2129
|
}
|
|
1737
2130
|
};
|
|
1738
2131
|
//#endregion
|
|
1739
|
-
//#region src/function/memoize.ts
|
|
2132
|
+
//#region src/internal/function/memoize.ts
|
|
1740
2133
|
function getMemoizationOptions(input) {
|
|
1741
2134
|
const { cacheKey, cacheSize } = isPlainObject(input) ? input : {};
|
|
1742
2135
|
return {
|
|
@@ -1789,1012 +2182,722 @@ const MEMOIZED_CACHE_SIZE_DEFAULT = 1024;
|
|
|
1789
2182
|
const MEMOIZED_CALLBACK = "Memoized requires a callback function";
|
|
1790
2183
|
const MEMOIZED_KEY_SEPARATOR = "_";
|
|
1791
2184
|
//#endregion
|
|
1792
|
-
//#region src/internal/
|
|
1793
|
-
function getAsyncTimer(type, callback, time) {
|
|
1794
|
-
function cancel() {
|
|
1795
|
-
clearTimer(id);
|
|
1796
|
-
if (last != null && !last.running) {
|
|
1797
|
-
last.reject();
|
|
1798
|
-
last = void 0;
|
|
1799
|
-
}
|
|
1800
|
-
}
|
|
1801
|
-
async function run(item) {
|
|
1802
|
-
const now = performance.now();
|
|
1803
|
-
start ??= now;
|
|
1804
|
-
if (interval === 0 || now - start >= interval - TIMER_OFFSET) {
|
|
1805
|
-
start = throttle ? now : void 0;
|
|
1806
|
-
item.running = true;
|
|
1807
|
-
try {
|
|
1808
|
-
let result = callback(...item.parameters);
|
|
1809
|
-
if (result instanceof Promise) result = await result;
|
|
1810
|
-
item.resolve(result);
|
|
1811
|
-
} catch (error) {
|
|
1812
|
-
item.reject(error);
|
|
1813
|
-
} finally {
|
|
1814
|
-
item.running = false;
|
|
1815
|
-
}
|
|
1816
|
-
} else id = startTimer(() => run(item));
|
|
1817
|
-
}
|
|
1818
|
-
const interval = getInterval(time);
|
|
1819
|
-
const throttle = type === TIMER_THROTTLE;
|
|
1820
|
-
let id;
|
|
1821
|
-
let last;
|
|
1822
|
-
let start;
|
|
1823
|
-
const timer = (...parameters) => {
|
|
1824
|
-
cancel();
|
|
1825
|
-
const next = {
|
|
1826
|
-
parameters,
|
|
1827
|
-
running: false
|
|
1828
|
-
};
|
|
1829
|
-
next.promise = new Promise((resolve, reject) => {
|
|
1830
|
-
next.reject = reject;
|
|
1831
|
-
next.resolve = resolve;
|
|
1832
|
-
});
|
|
1833
|
-
last = next;
|
|
1834
|
-
if (throttle) run(next);
|
|
1835
|
-
else id = startTimer(() => run(next));
|
|
1836
|
-
return next.promise;
|
|
1837
|
-
};
|
|
1838
|
-
Object.defineProperty(timer, TIMER_CANCEL, { value: () => cancel() });
|
|
1839
|
-
return timer;
|
|
1840
|
-
}
|
|
1841
|
-
function getInterval(value) {
|
|
1842
|
-
return typeof value === "number" && value > 0 ? value : 0;
|
|
1843
|
-
}
|
|
1844
|
-
function getTimer(type, callback, time) {
|
|
1845
|
-
function cancel() {
|
|
1846
|
-
clearTimer(id);
|
|
1847
|
-
}
|
|
1848
|
-
function run() {
|
|
1849
|
-
const now = performance.now();
|
|
1850
|
-
start ??= now;
|
|
1851
|
-
if (interval === 0 || now - start >= interval - TIMER_OFFSET) {
|
|
1852
|
-
start = throttle ? now : void 0;
|
|
1853
|
-
callback(...args);
|
|
1854
|
-
} else id = startTimer(run);
|
|
1855
|
-
}
|
|
1856
|
-
const interval = getInterval(time);
|
|
1857
|
-
const throttle = type === TIMER_THROTTLE;
|
|
1858
|
-
let args;
|
|
1859
|
-
let id;
|
|
1860
|
-
let start;
|
|
1861
|
-
const timer = (...parameters) => {
|
|
1862
|
-
cancel();
|
|
1863
|
-
args = parameters;
|
|
1864
|
-
if (throttle) run();
|
|
1865
|
-
else id = startTimer(run);
|
|
1866
|
-
};
|
|
1867
|
-
Object.defineProperty(timer, TIMER_CANCEL, { value: () => cancel() });
|
|
1868
|
-
return timer;
|
|
1869
|
-
}
|
|
1870
|
-
const TIMER_CANCEL = "cancel";
|
|
1871
|
-
const TIMER_DEBOUNCE = "debounce";
|
|
1872
|
-
const TIMER_OFFSET = 5;
|
|
1873
|
-
const TIMER_THROTTLE = "throttle";
|
|
1874
|
-
const TIMER_WAIT = "wait";
|
|
1875
|
-
// istanbul ignore next
|
|
1876
|
-
const clearTimer = typeof cancelAnimationFrame === "function" ? cancelAnimationFrame : clearTimeout;
|
|
1877
|
-
// istanbul ignore next
|
|
1878
|
-
const startTimer = typeof requestAnimationFrame === "function" ? requestAnimationFrame : setTimeout;
|
|
1879
|
-
//#endregion
|
|
1880
|
-
//#region src/function/limit.ts
|
|
2185
|
+
//#region src/internal/string/case.ts
|
|
1881
2186
|
/**
|
|
1882
|
-
*
|
|
1883
|
-
*
|
|
1884
|
-
* - When called, successful _(finished)_ results will resolve and errors will reject
|
|
1885
|
-
* - 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...)_
|
|
1886
|
-
*
|
|
1887
|
-
* _Available as `asyncDebounce` and `debounce.async`_
|
|
2187
|
+
* Convert a string to camel case _(thisIsCamelCase)_
|
|
1888
2188
|
*
|
|
1889
|
-
* @param
|
|
1890
|
-
* @
|
|
1891
|
-
* @returns Debounced callback handler with a `cancel` method
|
|
2189
|
+
* @param value String to convert
|
|
2190
|
+
* @returns Camel-cased string
|
|
1892
2191
|
*/
|
|
1893
|
-
function
|
|
1894
|
-
return
|
|
2192
|
+
function camelCase(value) {
|
|
2193
|
+
return toCase(STRING_CASE_CAMEL, value, true, false);
|
|
1895
2194
|
}
|
|
1896
2195
|
/**
|
|
1897
|
-
*
|
|
1898
|
-
*
|
|
1899
|
-
* - When called, successful _(finished)_ results will resolve and errors will reject
|
|
1900
|
-
* - 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...)_
|
|
1901
|
-
*
|
|
1902
|
-
* _Available as `asyncThrottle` and `throttle.async`_
|
|
2196
|
+
* Capitalize the first letter of a string _(and lowercase the rest)_
|
|
1903
2197
|
*
|
|
1904
|
-
* @param
|
|
1905
|
-
* @
|
|
1906
|
-
* @returns Throttled callback handler with a `cancel` method
|
|
2198
|
+
* @param value String to capitalize
|
|
2199
|
+
* @returns Capitalized string
|
|
1907
2200
|
*/
|
|
1908
|
-
function
|
|
1909
|
-
|
|
2201
|
+
function capitalize(value) {
|
|
2202
|
+
if (typeof value !== "string" || value.length === 0) return "";
|
|
2203
|
+
memoizedCapitalize ??= memoize((v) => v.length === 1 ? v.toLocaleUpperCase() : `${v.charAt(0).toLocaleUpperCase()}${v.slice(1).toLocaleLowerCase()}`);
|
|
2204
|
+
return memoizedCapitalize.run(value);
|
|
1910
2205
|
}
|
|
1911
2206
|
/**
|
|
1912
|
-
*
|
|
2207
|
+
* Convert a string to kebab case _(this-is-kebab-case)_
|
|
1913
2208
|
*
|
|
1914
|
-
*
|
|
2209
|
+
* @param value String to convert
|
|
2210
|
+
* @returns Kebab-cased string
|
|
2211
|
+
*/
|
|
2212
|
+
function kebabCase(value) {
|
|
2213
|
+
return toCase(STRING_CASE_KEBAB, value, false, false);
|
|
2214
|
+
}
|
|
2215
|
+
/**
|
|
2216
|
+
* Convert a string to lower case
|
|
1915
2217
|
*
|
|
1916
|
-
* @param
|
|
1917
|
-
* @
|
|
1918
|
-
* @returns Debounced callback handler with a `cancel` method
|
|
2218
|
+
* @param value String to convert
|
|
2219
|
+
* @returns Lower-cased string
|
|
1919
2220
|
*/
|
|
1920
|
-
function
|
|
1921
|
-
|
|
2221
|
+
function lowerCase(value) {
|
|
2222
|
+
if (typeof value !== "string") return "";
|
|
2223
|
+
memoizedLowerCase ??= memoize((v) => v.toLocaleLowerCase());
|
|
2224
|
+
return memoizedLowerCase.run(value);
|
|
1922
2225
|
}
|
|
1923
2226
|
/**
|
|
1924
|
-
*
|
|
2227
|
+
* Convert a string to pascal case _(ThisIsPascalCase)_
|
|
1925
2228
|
*
|
|
1926
|
-
* @param
|
|
1927
|
-
* @
|
|
1928
|
-
* @returns Throttled callback handler with a `cancel` method
|
|
2229
|
+
* @param value String to convert
|
|
2230
|
+
* @returns Pascal-cased string
|
|
1929
2231
|
*/
|
|
1930
|
-
function
|
|
1931
|
-
return
|
|
2232
|
+
function pascalCase(value) {
|
|
2233
|
+
return toCase(STRING_CASE_PASCAL, value, true, true);
|
|
1932
2234
|
}
|
|
1933
|
-
Object.defineProperty(debounce, "async", { value: asyncDebounce });
|
|
1934
|
-
Object.defineProperty(throttle, "async", { value: asyncThrottle });
|
|
1935
|
-
//#endregion
|
|
1936
|
-
//#region src/function/once.ts
|
|
1937
2235
|
/**
|
|
1938
|
-
*
|
|
2236
|
+
* Convert a string to snake case _(this_is_snake_case)_
|
|
1939
2237
|
*
|
|
1940
|
-
*
|
|
2238
|
+
* @param value String to convert
|
|
2239
|
+
* @returns Snake-cased string
|
|
2240
|
+
*/
|
|
2241
|
+
function snakeCase(value) {
|
|
2242
|
+
return toCase(STRING_CASE_SNAKE, value, false, false);
|
|
2243
|
+
}
|
|
2244
|
+
/**
|
|
2245
|
+
* Convert a string to title case _(Capitalizing Every Word)_
|
|
1941
2246
|
*
|
|
1942
|
-
* @param
|
|
1943
|
-
* @returns
|
|
2247
|
+
* @param value String to convert
|
|
2248
|
+
* @returns Title-cased string
|
|
1944
2249
|
*/
|
|
1945
|
-
function
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
cleared: false,
|
|
1950
|
-
error: false,
|
|
1951
|
-
finished: false,
|
|
1952
|
-
items: [],
|
|
1953
|
-
value: void 0
|
|
1954
|
-
};
|
|
1955
|
-
const fn = (...parameters) => {
|
|
1956
|
-
if (state.cleared) return Promise.reject(new Error(ONCE_MESSAGE_CLEARED));
|
|
1957
|
-
if (state.finished) return state.error ? Promise.reject(state.value) : Promise.resolve(state.value);
|
|
1958
|
-
if (state.called) return new Promise((resolve, reject) => {
|
|
1959
|
-
state.items.push({
|
|
1960
|
-
reject,
|
|
1961
|
-
resolve
|
|
1962
|
-
});
|
|
1963
|
-
});
|
|
1964
|
-
state.called = true;
|
|
1965
|
-
return new Promise((resolve, reject) => {
|
|
1966
|
-
state.items.push({
|
|
1967
|
-
reject,
|
|
1968
|
-
resolve
|
|
1969
|
-
});
|
|
1970
|
-
callback(...parameters).then((value) => {
|
|
1971
|
-
handleOnceResult(state, value, false);
|
|
1972
|
-
}).catch((error) => {
|
|
1973
|
-
handleOnceResult(state, error, true);
|
|
1974
|
-
});
|
|
1975
|
-
});
|
|
1976
|
-
};
|
|
1977
|
-
Object.defineProperties(fn, {
|
|
1978
|
-
called: {
|
|
1979
|
-
enumerable: true,
|
|
1980
|
-
get: () => state.called
|
|
1981
|
-
},
|
|
1982
|
-
clear: { value: () => clearState(state) },
|
|
1983
|
-
cleared: {
|
|
1984
|
-
enumerable: true,
|
|
1985
|
-
get: () => state.cleared
|
|
1986
|
-
},
|
|
1987
|
-
error: {
|
|
1988
|
-
enumerable: true,
|
|
1989
|
-
get: () => state.error
|
|
1990
|
-
},
|
|
1991
|
-
finished: {
|
|
1992
|
-
enumerable: true,
|
|
1993
|
-
get: () => state.finished
|
|
1994
|
-
}
|
|
1995
|
-
});
|
|
1996
|
-
return fn;
|
|
2250
|
+
function titleCase(value) {
|
|
2251
|
+
if (typeof value !== "string" || value.length === 0) return "";
|
|
2252
|
+
memoizedTitleCase ??= memoize((v) => v.length < 2 ? capitalize(v) : join(words(v).map(capitalize), " "));
|
|
2253
|
+
return memoizedTitleCase.run(value);
|
|
1997
2254
|
}
|
|
1998
|
-
function
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2255
|
+
function toCase(type, value, capitalizeAny, capitalizeFirst) {
|
|
2256
|
+
caseMemoizers[type] ??= memoize(toCaseCallback.bind({
|
|
2257
|
+
type,
|
|
2258
|
+
capitalizeAny,
|
|
2259
|
+
capitalizeFirst
|
|
2260
|
+
}));
|
|
2261
|
+
return caseMemoizers[type].run(value);
|
|
2002
2262
|
}
|
|
2003
|
-
function
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
const
|
|
2008
|
-
const
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2263
|
+
function toCaseCallback(value) {
|
|
2264
|
+
if (typeof value !== "string") return "";
|
|
2265
|
+
if (value.length < 1) return value;
|
|
2266
|
+
const { capitalizeAny, capitalizeFirst, type } = this;
|
|
2267
|
+
const parts = words(value);
|
|
2268
|
+
const partsLength = parts.length;
|
|
2269
|
+
const cased = [];
|
|
2270
|
+
for (let partIndex = 0; partIndex < partsLength; partIndex += 1) {
|
|
2271
|
+
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("-");
|
|
2272
|
+
const itemsLength = items.length;
|
|
2273
|
+
const partResult = [];
|
|
2274
|
+
let itemCount = 0;
|
|
2275
|
+
for (let itemIndex = 0; itemIndex < itemsLength; itemIndex += 1) {
|
|
2276
|
+
const item = items[itemIndex];
|
|
2277
|
+
if (item.length === 0) continue;
|
|
2278
|
+
if (!capitalizeAny || itemCount === 0 && partIndex === 0 && !capitalizeFirst) partResult.push(item.toLocaleLowerCase());
|
|
2279
|
+
else partResult.push(capitalize(item));
|
|
2280
|
+
itemCount += 1;
|
|
2281
|
+
}
|
|
2282
|
+
cased.push(join(partResult, delimiters[type]));
|
|
2013
2283
|
}
|
|
2284
|
+
return join(cased, delimiters[type]);
|
|
2014
2285
|
}
|
|
2015
2286
|
/**
|
|
2016
|
-
*
|
|
2287
|
+
* Convert a string to upper case
|
|
2017
2288
|
*
|
|
2018
|
-
* @param
|
|
2019
|
-
* @returns
|
|
2289
|
+
* @param value String to convert
|
|
2290
|
+
* @returns Upper-cased string
|
|
2020
2291
|
*/
|
|
2021
|
-
function
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
cleared: false,
|
|
2026
|
-
value: void 0
|
|
2027
|
-
};
|
|
2028
|
-
const fn = (...parameters) => {
|
|
2029
|
-
if (state.cleared) throw new Error(ONCE_MESSAGE_CLEARED);
|
|
2030
|
-
if (state.called) return state.value;
|
|
2031
|
-
state.called = true;
|
|
2032
|
-
state.value = callback(...parameters);
|
|
2033
|
-
return state.value;
|
|
2034
|
-
};
|
|
2035
|
-
Object.defineProperties(fn, {
|
|
2036
|
-
called: {
|
|
2037
|
-
enumerable: true,
|
|
2038
|
-
get: () => state.called
|
|
2039
|
-
},
|
|
2040
|
-
clear: { value: () => clearState(state) },
|
|
2041
|
-
cleared: {
|
|
2042
|
-
enumerable: true,
|
|
2043
|
-
get: () => state.cleared
|
|
2044
|
-
}
|
|
2045
|
-
});
|
|
2046
|
-
return fn;
|
|
2292
|
+
function upperCase(value) {
|
|
2293
|
+
if (typeof value !== "string" || value.length === 0) return "";
|
|
2294
|
+
memoizedUpperCase ??= memoize((v) => v.toLocaleUpperCase());
|
|
2295
|
+
return memoizedUpperCase.run(value);
|
|
2047
2296
|
}
|
|
2048
|
-
const
|
|
2049
|
-
const
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2297
|
+
const STRING_CASE_CAMEL = "camel";
|
|
2298
|
+
const STRING_CASE_KEBAB = "kebab";
|
|
2299
|
+
const STRING_CASE_PASCAL = "pascal";
|
|
2300
|
+
const STRING_CASE_SNAKE = "snake";
|
|
2301
|
+
const STRING_DELIMTER_EMPTY = "";
|
|
2302
|
+
const STRING_DELIMITER_HYPHEN = "-";
|
|
2303
|
+
const STRING_DELIMITER_UNDERSCORE = "_";
|
|
2304
|
+
const STRING_EXPRESSION_CAMEL_CASE = /(\p{Ll})(\p{Lu})/gu;
|
|
2305
|
+
const STRING_EXPRESSION_ACRONYM = /(\p{Lu}*)(\p{Lu})(\p{Ll}+)/gu;
|
|
2306
|
+
const STRING_REPLACEMENT_CAMEL_CASE = "$1-$2";
|
|
2307
|
+
const STRING_S = "s";
|
|
2308
|
+
const caseMemoizers = {};
|
|
2309
|
+
const delimiters = {
|
|
2310
|
+
[STRING_CASE_CAMEL]: STRING_DELIMTER_EMPTY,
|
|
2311
|
+
[STRING_CASE_KEBAB]: STRING_DELIMITER_HYPHEN,
|
|
2312
|
+
[STRING_CASE_PASCAL]: STRING_DELIMTER_EMPTY,
|
|
2313
|
+
[STRING_CASE_SNAKE]: STRING_DELIMITER_UNDERSCORE
|
|
2063
2314
|
};
|
|
2315
|
+
let memoizedCapitalize;
|
|
2316
|
+
let memoizedLowerCase;
|
|
2317
|
+
let memoizedTitleCase;
|
|
2318
|
+
let memoizedUpperCase;
|
|
2319
|
+
//#endregion
|
|
2320
|
+
//#region src/internal/value/equal.ts
|
|
2064
2321
|
/**
|
|
2065
|
-
*
|
|
2322
|
+
* Deregister a equality comparison handler for a specific class
|
|
2066
2323
|
*
|
|
2067
|
-
* _Available as `
|
|
2324
|
+
* _Available as `deregisterEqualizer` and `equal.deregister`_
|
|
2068
2325
|
*
|
|
2069
|
-
* @param
|
|
2070
|
-
* @param options Retry options
|
|
2071
|
-
* @returns Callback result
|
|
2326
|
+
* @param constructor Class constructor
|
|
2072
2327
|
*/
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
async function handle() {
|
|
2076
|
-
try {
|
|
2077
|
-
const result = await callback();
|
|
2078
|
-
resolver(result);
|
|
2079
|
-
} catch (error) {
|
|
2080
|
-
if (attempts >= times || !when(error)) rejector(new RetryError(RETRY_MESSAGE_FAILED, error));
|
|
2081
|
-
else {
|
|
2082
|
-
attempts += 1;
|
|
2083
|
-
timer();
|
|
2084
|
-
}
|
|
2085
|
-
}
|
|
2086
|
-
}
|
|
2087
|
-
const { delay, times, when } = getRetryOptions(options);
|
|
2088
|
-
const timer = getTimer(TIMER_WAIT, handle, delay);
|
|
2089
|
-
let attempts = 0;
|
|
2090
|
-
let rejector;
|
|
2091
|
-
let resolver;
|
|
2092
|
-
return new Promise((resolve, reject) => {
|
|
2093
|
-
rejector = reject;
|
|
2094
|
-
resolver = resolve;
|
|
2095
|
-
handle();
|
|
2096
|
-
});
|
|
2328
|
+
function deregisterEqualizer(constructor) {
|
|
2329
|
+
equal.handlers.deregister(constructor);
|
|
2097
2330
|
}
|
|
2098
|
-
function
|
|
2099
|
-
|
|
2331
|
+
function filterKey(key, options) {
|
|
2332
|
+
if (typeof key !== "string") return true;
|
|
2333
|
+
if (options.ignoreExpressions.enabled && options.ignoreExpressions.values.some((expression) => expression.test(key))) return false;
|
|
2334
|
+
if (options.ignoreKeys.enabled && options.ignoreKeys.values.has(key)) return false;
|
|
2335
|
+
return true;
|
|
2100
2336
|
}
|
|
2101
|
-
function
|
|
2102
|
-
|
|
2103
|
-
return {
|
|
2104
|
-
delay: getRetryNumber(options.delay),
|
|
2105
|
-
times: getRetryNumber(options.times),
|
|
2106
|
-
when: typeof options.when === "function" ? options.when : shouldRetry
|
|
2107
|
-
};
|
|
2337
|
+
function equal(first, second, options) {
|
|
2338
|
+
return equalValue(first, second, getEqualOptions(options));
|
|
2108
2339
|
}
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
if (
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
return callback();
|
|
2122
|
-
} catch (error) {
|
|
2123
|
-
if (index >= times || !when(error)) {
|
|
2124
|
-
last = error;
|
|
2125
|
-
break;
|
|
2126
|
-
}
|
|
2340
|
+
equal.handlers = getCompareHandlers(equal, { callback: Object.is });
|
|
2341
|
+
equal.deregister = deregisterEqualizer;
|
|
2342
|
+
equal.initialize = initializeEqualizer;
|
|
2343
|
+
equal.register = registerEqualizer;
|
|
2344
|
+
function equalArray(first, second, options) {
|
|
2345
|
+
const { length } = first;
|
|
2346
|
+
if (length !== second.length) return false;
|
|
2347
|
+
let offset = 0;
|
|
2348
|
+
if (length >= EQUAL_ARRAY_THRESHOLD) {
|
|
2349
|
+
offset = Math.round(length / EQUAL_ARRAY_PEEK_PERCENTAGE);
|
|
2350
|
+
offset = offset > EQUAL_ARRAY_THRESHOLD ? EQUAL_ARRAY_THRESHOLD : offset;
|
|
2351
|
+
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;
|
|
2127
2352
|
}
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
function shouldRetry() {
|
|
2353
|
+
const end = length - offset;
|
|
2354
|
+
for (let index = offset; index < end; index += 1) if (!equalValue(first[index], second[index], options)) return false;
|
|
2131
2355
|
return true;
|
|
2132
2356
|
}
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
const RETRY_MESSAGE_FAILED = "Retry failed";
|
|
2136
|
-
Object.defineProperty(retry, "async", { value: asyncRetry });
|
|
2137
|
-
//#endregion
|
|
2138
|
-
//#region src/function/work.ts
|
|
2139
|
-
function asyncFlow(...fns) {
|
|
2140
|
-
assertFlowFunctions(fns);
|
|
2141
|
-
return (...args) => asyncWork(args.map((value) => {
|
|
2142
|
-
if (isError(value)) throw value.error;
|
|
2143
|
-
return isOk(value) ? value.value : value;
|
|
2144
|
-
}), fns, true);
|
|
2145
|
-
}
|
|
2146
|
-
function flow(...fns) {
|
|
2147
|
-
assertFlowFunctions(fns);
|
|
2148
|
-
return (...args) => work(args.map((value) => {
|
|
2149
|
-
if (isError(value)) throw value.error;
|
|
2150
|
-
return isOk(value) ? value.value : value;
|
|
2151
|
-
}), fns, true);
|
|
2357
|
+
function equalArrayBuffer(first, second, options) {
|
|
2358
|
+
return first.byteLength === second.byteLength ? equalArray(new Uint8Array(first), new Uint8Array(second), options) : false;
|
|
2152
2359
|
}
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
return asyncWork(value, pipes, false);
|
|
2360
|
+
function equalDataView(first, second, options) {
|
|
2361
|
+
return first.byteOffset === second.byteOffset ? equalArrayBuffer(first.buffer, second.buffer, options) : false;
|
|
2156
2362
|
}
|
|
2157
|
-
function
|
|
2158
|
-
|
|
2159
|
-
|
|
2363
|
+
function equalMap(first, second, options) {
|
|
2364
|
+
const { size } = first;
|
|
2365
|
+
if (size !== second.size) return false;
|
|
2366
|
+
const firstKeys = [...first.keys()];
|
|
2367
|
+
for (let index = 0; index < size; index += 1) {
|
|
2368
|
+
const key = firstKeys[index];
|
|
2369
|
+
if (!second.has(key) || !equalValue(first.get(key), second.get(key), options)) return false;
|
|
2370
|
+
}
|
|
2371
|
+
return true;
|
|
2160
2372
|
}
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
let
|
|
2373
|
+
function equalPlainObject(first, second, options) {
|
|
2374
|
+
let firstKeys = [...Object.keys(first), ...Object.getOwnPropertySymbols(first)];
|
|
2375
|
+
let secondKeys = [...Object.keys(second), ...Object.getOwnPropertySymbols(second)];
|
|
2376
|
+
if (options.ignoreKeys.enabled || options.ignoreExpressions.enabled) {
|
|
2377
|
+
firstKeys = firstKeys.filter((key) => filterKey(key, options));
|
|
2378
|
+
secondKeys = secondKeys.filter((key) => filterKey(key, options));
|
|
2379
|
+
}
|
|
2380
|
+
const secondSet = secondKeys.length >= EQUAL_MINIMUM_LENGTH_FOR_SET ? new Set(secondKeys) : void 0;
|
|
2381
|
+
const { length } = firstKeys;
|
|
2382
|
+
if (length !== secondKeys.length) return false;
|
|
2164
2383
|
for (let index = 0; index < length; index += 1) {
|
|
2165
|
-
const
|
|
2166
|
-
|
|
2384
|
+
const key = firstKeys[index];
|
|
2385
|
+
if (!(secondSet?.has(key) ?? secondKeys.includes(key)) || !equalValue(first[key], second[key], options)) return false;
|
|
2167
2386
|
}
|
|
2168
|
-
return
|
|
2387
|
+
return true;
|
|
2169
2388
|
}
|
|
2170
|
-
function
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2389
|
+
function equalProperties(first, second, properties, options) {
|
|
2390
|
+
const { length } = properties;
|
|
2391
|
+
for (let index = 0; index < length; index += 1) {
|
|
2392
|
+
const property = properties[index];
|
|
2393
|
+
if (!equalValue(first[property], second[property], options)) return false;
|
|
2174
2394
|
}
|
|
2175
|
-
|
|
2176
|
-
if (isError(value)) throw value.error;
|
|
2177
|
-
return isOk(value) ? value.value : value;
|
|
2395
|
+
return true;
|
|
2178
2396
|
}
|
|
2179
|
-
function
|
|
2180
|
-
const {
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2397
|
+
function equalSet(first, second, options) {
|
|
2398
|
+
const { size } = first;
|
|
2399
|
+
if (size !== second.size) return false;
|
|
2400
|
+
const firstValues = [...first];
|
|
2401
|
+
const secondValues = [...second];
|
|
2402
|
+
for (let index = 0; index < size; index += 1) {
|
|
2403
|
+
const firstValue = firstValues[index];
|
|
2404
|
+
if (isPrimitive(firstValue) ? !second.has(firstValue) : !secondValues.some((secondValue) => equalValue(firstValue, secondValue, options))) return false;
|
|
2185
2405
|
}
|
|
2186
|
-
return
|
|
2406
|
+
return true;
|
|
2187
2407
|
}
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
const
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
const assertPipeFunctions = assert.condition((value) => Array.isArray(value) && value.every((item) => typeof item === "function"), WORK_MESSAGE_PIPE_ARRAY, TypeError);
|
|
2195
|
-
flow.async = asyncFlow;
|
|
2196
|
-
pipe.async = asyncPipe;
|
|
2197
|
-
Object.defineProperty(flow, "async", { value: asyncFlow });
|
|
2198
|
-
Object.defineProperty(pipe, "async", { value: asyncPipe });
|
|
2199
|
-
//#endregion
|
|
2200
|
-
//#region src/internal/abort.ts
|
|
2201
|
-
function createAborter(value, onAbort) {
|
|
2202
|
-
if (!(value instanceof AbortSignal)) return;
|
|
2203
|
-
value.addEventListener(ABORT_EVENT, onAbort, ABORT_OPTIONS);
|
|
2204
|
-
return {
|
|
2205
|
-
callback: onAbort,
|
|
2206
|
-
signal: value,
|
|
2207
|
-
cancel: () => value.removeEventListener(ABORT_EVENT, onAbort)
|
|
2208
|
-
};
|
|
2408
|
+
function equalTypedArray(first, second) {
|
|
2409
|
+
if (first.constructor !== second.constructor) return false;
|
|
2410
|
+
if (first.byteLength !== second.byteLength) return false;
|
|
2411
|
+
const { length } = first;
|
|
2412
|
+
for (let index = 0; index < length; index += 1) if (first[index] !== second[index]) return false;
|
|
2413
|
+
return true;
|
|
2209
2414
|
}
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
return;
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
if (keyedItems == null) {
|
|
2229
|
-
keyedItems = /* @__PURE__ */ new Set();
|
|
2230
|
-
items.keyed.set(key, keyedItems);
|
|
2231
|
-
}
|
|
2232
|
-
keyedItems.add(subscription);
|
|
2233
|
-
let keyedFrom = values.from.keyed.get(key);
|
|
2234
|
-
if (keyedFrom == null) {
|
|
2235
|
-
keyedFrom = /* @__PURE__ */ new Map();
|
|
2236
|
-
values.from.keyed.set(key, keyedFrom);
|
|
2237
|
-
}
|
|
2238
|
-
keyedFrom.set(value, subscription);
|
|
2239
|
-
let keyedTo = values.to.keyed.get(key);
|
|
2240
|
-
if (keyedTo == null) {
|
|
2241
|
-
keyedTo = /* @__PURE__ */ new Map();
|
|
2242
|
-
values.to.keyed.set(key, keyedTo);
|
|
2415
|
+
function equalValue(first, second, options) {
|
|
2416
|
+
if (options.relaxedNullish && first == null && second == null) return true;
|
|
2417
|
+
switch (true) {
|
|
2418
|
+
case Object.is(first, second): return true;
|
|
2419
|
+
case first == null || second == null: return first === second;
|
|
2420
|
+
case typeof first !== typeof second: return false;
|
|
2421
|
+
case typeof first === "string" && options.ignoreCase === true: return Object.is(first.toLocaleLowerCase(), second.toLocaleLowerCase());
|
|
2422
|
+
case first instanceof ArrayBuffer && second instanceof ArrayBuffer: return equalArrayBuffer(first, second, options);
|
|
2423
|
+
case first instanceof Date && second instanceof Date: return Object.is(first.getTime(), second.getTime());
|
|
2424
|
+
case first instanceof DataView && second instanceof DataView: return equalDataView(first, second, options);
|
|
2425
|
+
case first instanceof Error && second instanceof Error: return equalProperties(first, second, EQUAL_ERROR_PROPERTIES, options);
|
|
2426
|
+
case first instanceof Map && second instanceof Map: return equalMap(first, second, options);
|
|
2427
|
+
case first instanceof RegExp && second instanceof RegExp: return equalProperties(first, second, EQUAL_EXPRESSION_PROPERTIES, options);
|
|
2428
|
+
case first instanceof Set && second instanceof Set: return equalSet(first, second, options);
|
|
2429
|
+
case Array.isArray(first) && Array.isArray(second): return equalArray(first, second, options);
|
|
2430
|
+
case isPlainObject(first) && isPlainObject(second): return equalPlainObject(first, second, options);
|
|
2431
|
+
case isTypedArray(first) && isTypedArray(second): return equalTypedArray(first, second);
|
|
2432
|
+
default: return equal.handlers.handle(first, second, options);
|
|
2243
2433
|
}
|
|
2244
|
-
keyedTo.set(subscription, value);
|
|
2245
|
-
}
|
|
2246
|
-
function clearSubscriptions(store) {
|
|
2247
|
-
for (const susbcription of store.values.to.any.keys()) susbcription.unsubscribe();
|
|
2248
|
-
if (store.values.to.keyed != null) for (const values of store.values.to.keyed.values()) for (const susbcription of values.keys()) susbcription.unsubscribe();
|
|
2249
|
-
}
|
|
2250
|
-
function createSubscription(subscriptions, property, parameters) {
|
|
2251
|
-
if (parameters.signal?.aborted ?? false) throw new Error(parameters.signal?.reason);
|
|
2252
|
-
const state = {
|
|
2253
|
-
parameters,
|
|
2254
|
-
active: true
|
|
2255
|
-
};
|
|
2256
|
-
const existing = getExistingSubscription(subscriptions, state);
|
|
2257
|
-
if (existing != null) return [existing, true];
|
|
2258
|
-
if (subscriptions.state.keys != null && isKey(parameters.key) && !subscriptions.state.keys.has(parameters.key)) throw new Error(SUBSCRIPTION_INVALID_KEY);
|
|
2259
|
-
state.aborter = createAborter(parameters.signal, () => unsubscribe(subscriptions, instance, state));
|
|
2260
|
-
const instance = { unsubscribe: () => unsubscribe(subscriptions, instance, state) };
|
|
2261
|
-
Object.defineProperties(instance, {
|
|
2262
|
-
[SUBSCRIPTION_PROPERTY]: { value: true },
|
|
2263
|
-
[property.key]: { value: property.value ?? "subscription" },
|
|
2264
|
-
active: {
|
|
2265
|
-
enumerable: true,
|
|
2266
|
-
get: () => (parameters.isActive?.() ?? true) && state.active
|
|
2267
|
-
}
|
|
2268
|
-
});
|
|
2269
|
-
addSubscription(subscriptions, instance, state);
|
|
2270
|
-
return [Object.freeze(instance), false];
|
|
2271
2434
|
}
|
|
2272
|
-
function
|
|
2273
|
-
const
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
keyed: keys == null ? void 0 : /* @__PURE__ */ new Map()
|
|
2435
|
+
function getEqualOptions(input) {
|
|
2436
|
+
const options = {
|
|
2437
|
+
ignoreCase: false,
|
|
2438
|
+
ignoreExpressions: {
|
|
2439
|
+
enabled: false,
|
|
2440
|
+
values: []
|
|
2279
2441
|
},
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
to: {
|
|
2286
|
-
any: /* @__PURE__ */ new Map(),
|
|
2287
|
-
keyed: keys == null ? void 0 : /* @__PURE__ */ new Map()
|
|
2288
|
-
}
|
|
2289
|
-
}
|
|
2290
|
-
};
|
|
2291
|
-
const instance = {
|
|
2292
|
-
state,
|
|
2293
|
-
clear: () => clearSubscriptions(state),
|
|
2294
|
-
create: (parameters) => createSubscription(instance, property, parameters)
|
|
2442
|
+
ignoreKeys: {
|
|
2443
|
+
enabled: false,
|
|
2444
|
+
values: /* @__PURE__ */ new Set()
|
|
2445
|
+
},
|
|
2446
|
+
relaxedNullish: false
|
|
2295
2447
|
};
|
|
2296
|
-
|
|
2448
|
+
if (typeof input === "boolean") {
|
|
2449
|
+
options.ignoreCase = input;
|
|
2450
|
+
return options;
|
|
2451
|
+
}
|
|
2452
|
+
if (isNonPlainObject(input)) return options;
|
|
2453
|
+
options.ignoreCase = typeof input.ignoreCase === "boolean" ? input.ignoreCase : false;
|
|
2454
|
+
options.ignoreExpressions.values = (Array.isArray(input.ignoreKeys) ? input.ignoreKeys : [input.ignoreKeys]).filter((key) => key instanceof RegExp);
|
|
2455
|
+
options.ignoreKeys.values = new Set((Array.isArray(input.ignoreKeys) ? input.ignoreKeys : [input.ignoreKeys]).filter((key) => typeof key === "string"));
|
|
2456
|
+
options.ignoreExpressions.enabled = options.ignoreExpressions.values.length > 0;
|
|
2457
|
+
options.ignoreKeys.enabled = options.ignoreKeys.values.size > 0;
|
|
2458
|
+
options.relaxedNullish = input.relaxedNullish === true;
|
|
2459
|
+
return options;
|
|
2297
2460
|
}
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2461
|
+
/**
|
|
2462
|
+
* Create an equalizer with predefined options
|
|
2463
|
+
*
|
|
2464
|
+
* _Available as `initializeEqualizer` and `equal.initialize`_
|
|
2465
|
+
*
|
|
2466
|
+
* @param options Comparison options
|
|
2467
|
+
* @returns Equalizer function
|
|
2468
|
+
*/
|
|
2469
|
+
function initializeEqualizer(options) {
|
|
2470
|
+
const actual = getEqualOptions(options);
|
|
2471
|
+
const equalizer = (first, second) => equalValue(first, second, actual);
|
|
2472
|
+
equalizer.deregister = deregisterEqualizer;
|
|
2473
|
+
equalizer.register = registerEqualizer;
|
|
2474
|
+
return equalizer;
|
|
2302
2475
|
}
|
|
2303
2476
|
/**
|
|
2304
|
-
*
|
|
2477
|
+
* Register a equality comparison function for a specific class
|
|
2305
2478
|
*
|
|
2306
|
-
*
|
|
2307
|
-
*
|
|
2479
|
+
* _Available as `registerEqualizer` and `equal.register`_
|
|
2480
|
+
*
|
|
2481
|
+
* @param constructor Class constructor
|
|
2482
|
+
* @param handler Comparison function
|
|
2308
2483
|
*/
|
|
2309
|
-
function
|
|
2310
|
-
|
|
2484
|
+
function registerEqualizer(constructor, handler) {
|
|
2485
|
+
equal.handlers.register(constructor, handler);
|
|
2311
2486
|
}
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2487
|
+
const EQUAL_ARRAY_PEEK_PERCENTAGE = 10;
|
|
2488
|
+
const EQUAL_ARRAY_THRESHOLD = 100;
|
|
2489
|
+
const EQUAL_ERROR_PROPERTIES = ["name", "message"];
|
|
2490
|
+
const EQUAL_EXPRESSION_PROPERTIES = ["source", "flags"];
|
|
2491
|
+
const EQUAL_MINIMUM_LENGTH_FOR_SET = 16;
|
|
2492
|
+
//#endregion
|
|
2493
|
+
//#region src/internal/value/get.ts
|
|
2494
|
+
function getValue(data, path, ignoreCase) {
|
|
2495
|
+
return getNestedValue(data, path, ignoreCase === true).value;
|
|
2321
2496
|
}
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
removeFromStore(items.any, values, subscription, value);
|
|
2332
|
-
return;
|
|
2497
|
+
//#endregion
|
|
2498
|
+
//#region src/internal/value/set.ts
|
|
2499
|
+
function setValue(data, path, value, ignoreCase) {
|
|
2500
|
+
if (typeof data !== "object" || data === null || typeof path !== "string" || path.trim().length === 0) return data;
|
|
2501
|
+
const shouldIgnoreCase = ignoreCase === true;
|
|
2502
|
+
const paths = getPaths(path, shouldIgnoreCase);
|
|
2503
|
+
if (typeof paths === "string") {
|
|
2504
|
+
handleValue(data, paths, value, false, shouldIgnoreCase);
|
|
2505
|
+
return data;
|
|
2333
2506
|
}
|
|
2334
|
-
const
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2507
|
+
const { length } = paths;
|
|
2508
|
+
const lastIndex = length - 1;
|
|
2509
|
+
let target = data;
|
|
2510
|
+
for (let index = 0; index < length; index += 1) {
|
|
2511
|
+
const currentPath = paths[index];
|
|
2512
|
+
if (index === lastIndex) {
|
|
2513
|
+
handleValue(target, currentPath, value, false, shouldIgnoreCase);
|
|
2514
|
+
break;
|
|
2515
|
+
}
|
|
2516
|
+
let next = handleValue(target, currentPath, null, true, shouldIgnoreCase).value;
|
|
2517
|
+
if (typeof next !== "object" || next === null) {
|
|
2518
|
+
const nextPath = paths[index + 1];
|
|
2519
|
+
if (SET_EXPRESSION_INDEX.test(nextPath)) next = Array.from({ length: Number(nextPath) + 1 }, () => void 0);
|
|
2520
|
+
else next = {};
|
|
2521
|
+
target[currentPath] = next;
|
|
2522
|
+
}
|
|
2523
|
+
target = next;
|
|
2524
|
+
}
|
|
2525
|
+
return data;
|
|
2345
2526
|
}
|
|
2346
|
-
const
|
|
2347
|
-
const SUBSCRIPTION_PROPERTY = "$subscription";
|
|
2527
|
+
const SET_EXPRESSION_INDEX = /^\d+$/;
|
|
2348
2528
|
//#endregion
|
|
2349
|
-
//#region src/
|
|
2350
|
-
function
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
for (const key of state.keys) events[key] = (callback, signal) => herald.subscribe(key, callback, signal);
|
|
2354
|
-
return Object.freeze(events);
|
|
2355
|
-
}
|
|
2356
|
-
function emitForHerald(state, event, ...parameters) {
|
|
2357
|
-
const items = state.subscriptions.state.values.from.keyed?.get(event);
|
|
2358
|
-
if (items == null || items.size === 0) return;
|
|
2359
|
-
for (const [callback] of items) callback(...parameters);
|
|
2360
|
-
}
|
|
2361
|
-
function getHeraldSubscriptionProperty(input) {
|
|
2362
|
-
if (input == null) return heraldSubscription;
|
|
2363
|
-
const property = isPlainObject(input) ? input : {};
|
|
2364
|
-
if (typeof property.key !== "string" || property.value != null && typeof property.value !== "string") throw new Error(HERALD_MESSAGE_PROPERTY);
|
|
2529
|
+
//#region src/internal/abort.ts
|
|
2530
|
+
function createAborter(value, onAbort) {
|
|
2531
|
+
if (!(value instanceof AbortSignal)) return;
|
|
2532
|
+
value.addEventListener(ABORT_EVENT, onAbort, ABORT_OPTIONS);
|
|
2365
2533
|
return {
|
|
2366
|
-
|
|
2367
|
-
|
|
2534
|
+
callback: onAbort,
|
|
2535
|
+
signal: value,
|
|
2536
|
+
cancel: () => value.removeEventListener(ABORT_EVENT, onAbort)
|
|
2368
2537
|
};
|
|
2369
2538
|
}
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
return
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
property: getHeraldSubscriptionProperty(options.property)
|
|
2380
|
-
}),
|
|
2381
|
-
onCreate: options.onCreate
|
|
2382
|
-
};
|
|
2539
|
+
const ABORT_EVENT = "abort";
|
|
2540
|
+
const ABORT_OPTIONS = { once: true };
|
|
2541
|
+
//#endregion
|
|
2542
|
+
//#region src/internal/defaults.ts
|
|
2543
|
+
function getBooleanOrDefault(value, defaultValue) {
|
|
2544
|
+
return typeof value === "boolean" ? value : defaultValue;
|
|
2545
|
+
}
|
|
2546
|
+
function getNumberOrDefault(value, defaultValue, minimum) {
|
|
2547
|
+
return typeof value === "number" && !Number.isNaN(value) && value >= (minimum ?? 0) ? value : defaultValue;
|
|
2383
2548
|
}
|
|
2549
|
+
//#endregion
|
|
2550
|
+
//#region src/promise/constants.ts
|
|
2551
|
+
const PROMISE_ERROR_NAME = "PromiseTimeoutError";
|
|
2552
|
+
const PROMISE_MESSAGE_EXPECTATION_ATTEMPT = "Attempt expected a function or a promise";
|
|
2553
|
+
const PROMISE_MESSAGE_EXPECTATION_RESULT = "toResult expected a Promise";
|
|
2554
|
+
const PROMISE_MESSAGE_EXPECTATION_TIMED = "Timed function expected a Promise";
|
|
2555
|
+
const PROMISE_MESSAGE_TIMEOUT = "Promise timed out";
|
|
2556
|
+
const PROMISE_STRATEGY_ALL = /* @__PURE__ */ new Set(["complete", "first"]);
|
|
2557
|
+
const PROMISE_STRATEGY_DEFAULT = "complete";
|
|
2558
|
+
const PROMISE_TYPE_FULFILLED = "fulfilled";
|
|
2559
|
+
const PROMISE_TYPE_REJECTED = "rejected";
|
|
2560
|
+
//#endregion
|
|
2561
|
+
//#region src/promise/models.ts
|
|
2384
2562
|
/**
|
|
2385
|
-
*
|
|
2386
|
-
*
|
|
2387
|
-
* @param names Event names
|
|
2388
|
-
* @param property Optional property for subscription identification _(defaults to `$herald`)_
|
|
2389
|
-
* @returns _Herald_ instance
|
|
2563
|
+
* A _Promise_ that can be canceled
|
|
2390
2564
|
*/
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2565
|
+
var CancelablePromise = class extends Promise {
|
|
2566
|
+
#rejector;
|
|
2567
|
+
constructor(executor) {
|
|
2568
|
+
let rejector;
|
|
2569
|
+
super((resolve, reject) => {
|
|
2570
|
+
rejector = reject;
|
|
2571
|
+
executor(resolve, reject);
|
|
2572
|
+
});
|
|
2573
|
+
this.#rejector = rejector;
|
|
2574
|
+
}
|
|
2575
|
+
/**
|
|
2576
|
+
* Cancel the _Promise_, rejecting it with an optional reason
|
|
2577
|
+
*
|
|
2578
|
+
* @param reason Optional reason for canceling the _Promise_
|
|
2579
|
+
*/
|
|
2580
|
+
cancel(reason) {
|
|
2581
|
+
this.#rejector?.(reason);
|
|
2582
|
+
this.#rejector = void 0;
|
|
2583
|
+
}
|
|
2584
|
+
};
|
|
2585
|
+
/**
|
|
2586
|
+
* An error thrown when a promise times out
|
|
2587
|
+
*/
|
|
2588
|
+
var PromiseTimeoutError = class extends Error {
|
|
2589
|
+
constructor() {
|
|
2590
|
+
super(PROMISE_MESSAGE_TIMEOUT);
|
|
2591
|
+
this.name = PROMISE_ERROR_NAME;
|
|
2592
|
+
}
|
|
2593
|
+
};
|
|
2594
|
+
//#endregion
|
|
2595
|
+
//#region src/promise/helpers.ts
|
|
2596
|
+
function getPromiseOptions(input) {
|
|
2597
|
+
if (typeof input === "number") return { time: getNumberOrDefault(input, 0) };
|
|
2598
|
+
if (input instanceof AbortSignal) return {
|
|
2599
|
+
signal: input,
|
|
2600
|
+
time: 0
|
|
2398
2601
|
};
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
return
|
|
2602
|
+
const options = typeof input === "object" && input !== null ? input : {};
|
|
2603
|
+
return {
|
|
2604
|
+
signal: options.signal instanceof AbortSignal ? options.signal : void 0,
|
|
2605
|
+
time: getNumberOrDefault(options.time, 0)
|
|
2606
|
+
};
|
|
2607
|
+
}
|
|
2608
|
+
function getPromisesOptions(input) {
|
|
2609
|
+
if (typeof input === "string") return { strategy: getStrategyOrDefault(input) };
|
|
2610
|
+
if (input instanceof AbortSignal) return {
|
|
2611
|
+
signal: input,
|
|
2612
|
+
strategy: PROMISE_STRATEGY_DEFAULT
|
|
2613
|
+
};
|
|
2614
|
+
const options = typeof input === "object" && input !== null ? input : {};
|
|
2615
|
+
return {
|
|
2616
|
+
signal: options.signal instanceof AbortSignal ? options.signal : void 0,
|
|
2617
|
+
strategy: getStrategyOrDefault(options.strategy)
|
|
2618
|
+
};
|
|
2619
|
+
}
|
|
2620
|
+
function getResultsFromPromises(promised) {
|
|
2621
|
+
return promised.map((result) => isFulfilled(result) ? ok(result.value) : error(result.reason));
|
|
2622
|
+
}
|
|
2623
|
+
function getStrategyOrDefault(value) {
|
|
2624
|
+
return PROMISE_STRATEGY_ALL.has(value) ? value : PROMISE_STRATEGY_DEFAULT;
|
|
2407
2625
|
}
|
|
2408
2626
|
/**
|
|
2409
|
-
* Is the value
|
|
2627
|
+
* Is the value a fulfilled _Promise_ result?
|
|
2410
2628
|
*
|
|
2411
2629
|
* @param value Value to check
|
|
2412
|
-
* @returns `true` if the value is
|
|
2630
|
+
* @returns `true` if the value is a fulfilled _Promise_ result, otherwise `false`
|
|
2413
2631
|
*/
|
|
2414
|
-
function
|
|
2415
|
-
return
|
|
2632
|
+
function isFulfilled(value) {
|
|
2633
|
+
return isType(value, PROMISE_TYPE_FULFILLED);
|
|
2416
2634
|
}
|
|
2417
2635
|
/**
|
|
2418
|
-
* Is the value a
|
|
2636
|
+
* Is the value a rejected _Promise_ result?
|
|
2419
2637
|
*
|
|
2420
2638
|
* @param value Value to check
|
|
2421
|
-
* @returns `true` if the value is a
|
|
2639
|
+
* @returns `true` if the value is a rejected _Promise_ result, otherwise `false`
|
|
2422
2640
|
*/
|
|
2423
|
-
function
|
|
2424
|
-
return
|
|
2641
|
+
function isRejected(value) {
|
|
2642
|
+
return isType(value, PROMISE_TYPE_REJECTED);
|
|
2425
2643
|
}
|
|
2426
|
-
function
|
|
2427
|
-
return
|
|
2644
|
+
function isType(value, type) {
|
|
2645
|
+
return typeof value === "object" && value !== null && value.status === type;
|
|
2428
2646
|
}
|
|
2647
|
+
//#endregion
|
|
2648
|
+
//#region src/result/misc.ts
|
|
2429
2649
|
/**
|
|
2430
|
-
*
|
|
2650
|
+
* Converts a _Result_ to a _Promise_
|
|
2431
2651
|
*
|
|
2432
|
-
*
|
|
2433
|
-
*
|
|
2652
|
+
* Resolves if ok, rejects for error
|
|
2653
|
+
*
|
|
2654
|
+
* @param result _Result_ to convert
|
|
2655
|
+
* @returns Promised result
|
|
2434
2656
|
*/
|
|
2435
|
-
function
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
const [subscription, existing] = state.subscriptions.create({
|
|
2440
|
-
key,
|
|
2441
|
-
signal,
|
|
2442
|
-
value: callback
|
|
2443
|
-
});
|
|
2444
|
-
if (!existing) state.onCreate?.(key, callback, subscription);
|
|
2445
|
-
return subscription;
|
|
2657
|
+
async function toPromise(result) {
|
|
2658
|
+
const actual = typeof result === "function" ? result() : result;
|
|
2659
|
+
if (!isResult(actual)) return Promise.reject(new Error(RESULT_MESSAGE_PROMISE));
|
|
2660
|
+
return isOk(actual) ? Promise.resolve(actual.value) : Promise.reject(actual.error);
|
|
2446
2661
|
}
|
|
2447
|
-
const
|
|
2448
|
-
const HERALD_MESSAGE_ARRAY = "Herald requires an array of event names.";
|
|
2449
|
-
const HERALD_MESSAGE_ONCREATE = `Herald requires a valid onCreate callback for subscription creation`;
|
|
2450
|
-
const HERALD_MESSAGE_PROPERTY = `Herald requires valid property information for subscription identification`;
|
|
2451
|
-
const HERALD_NAME_EVENTS = "events";
|
|
2452
|
-
const HERALD_NAME_HERALD = "herald";
|
|
2453
|
-
const heraldSubscription = { key: HERALD_PROPERTY };
|
|
2662
|
+
const RESULT_MESSAGE_PROMISE = "toPromise expected to receive a Result";
|
|
2454
2663
|
//#endregion
|
|
2455
|
-
//#region src/
|
|
2664
|
+
//#region src/promise/misc.ts
|
|
2456
2665
|
/**
|
|
2457
|
-
*
|
|
2458
|
-
*
|
|
2459
|
-
* _Available as `deregisterEqualizer` and `equal.deregister`_
|
|
2666
|
+
* Create a cancelable _Promise_
|
|
2460
2667
|
*
|
|
2461
|
-
* @param
|
|
2668
|
+
* @param executor Executor function for the _Promise_
|
|
2669
|
+
* @returns Cancelable _Promise_
|
|
2462
2670
|
*/
|
|
2463
|
-
function
|
|
2464
|
-
|
|
2465
|
-
}
|
|
2466
|
-
function filterKey(key, options) {
|
|
2467
|
-
if (typeof key !== "string") return true;
|
|
2468
|
-
if (options.ignoreExpressions.enabled && options.ignoreExpressions.values.some((expression) => expression.test(key))) return false;
|
|
2469
|
-
if (options.ignoreKeys.enabled && options.ignoreKeys.values.has(key)) return false;
|
|
2470
|
-
return true;
|
|
2471
|
-
}
|
|
2472
|
-
function equal(first, second, options) {
|
|
2473
|
-
return equalValue(first, second, getEqualOptions(options));
|
|
2671
|
+
function cancelable(executor) {
|
|
2672
|
+
return new CancelablePromise(executor);
|
|
2474
2673
|
}
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
if (length !== second.length) return false;
|
|
2482
|
-
let offset = 0;
|
|
2483
|
-
if (length >= EQUAL_ARRAY_THRESHOLD) {
|
|
2484
|
-
offset = Math.round(length / EQUAL_ARRAY_PEEK_PERCENTAGE);
|
|
2485
|
-
offset = offset > EQUAL_ARRAY_THRESHOLD ? EQUAL_ARRAY_THRESHOLD : offset;
|
|
2486
|
-
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;
|
|
2674
|
+
function handleResult(status, parameters) {
|
|
2675
|
+
const { aborter, complete, data, handlers, index, value } = parameters;
|
|
2676
|
+
if (aborter?.signal.aborted ?? false) return;
|
|
2677
|
+
if (!complete && status === "rejected") {
|
|
2678
|
+
settlePromise(handlers.reject, value, aborter);
|
|
2679
|
+
return;
|
|
2487
2680
|
}
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2681
|
+
data.result[index] = !complete ? value : status === "fulfilled" ? {
|
|
2682
|
+
status,
|
|
2683
|
+
value
|
|
2684
|
+
} : {
|
|
2685
|
+
status,
|
|
2686
|
+
reason: value
|
|
2687
|
+
};
|
|
2688
|
+
if (index === data.last) settlePromise(handlers.resolve, data.result, aborter);
|
|
2491
2689
|
}
|
|
2492
|
-
function
|
|
2493
|
-
|
|
2690
|
+
function settlePromise(settler, value, aborter) {
|
|
2691
|
+
aborter?.cancel();
|
|
2692
|
+
settler(value);
|
|
2494
2693
|
}
|
|
2495
|
-
function
|
|
2496
|
-
|
|
2694
|
+
async function toResult(value) {
|
|
2695
|
+
const actual = typeof value === "function" ? value() : value;
|
|
2696
|
+
if (!(actual instanceof Promise)) return Promise.reject(/* @__PURE__ */ new TypeError(PROMISE_MESSAGE_EXPECTATION_RESULT));
|
|
2697
|
+
return actual.then((result) => ok(result)).catch((reason) => error(reason));
|
|
2497
2698
|
}
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
const
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2699
|
+
//#endregion
|
|
2700
|
+
//#region src/promise/delay.ts
|
|
2701
|
+
function delay(options) {
|
|
2702
|
+
const { signal, time } = getPromiseOptions(options);
|
|
2703
|
+
if (signal?.aborted ?? false) return Promise.reject(signal?.reason);
|
|
2704
|
+
const aborter = createAborter(signal, () => {
|
|
2705
|
+
timer.cancel();
|
|
2706
|
+
rejector(signal?.reason);
|
|
2707
|
+
});
|
|
2708
|
+
const timer = getTimer(TIMER_WAIT, () => settlePromise(resolver, void 0, aborter), time);
|
|
2709
|
+
let rejector;
|
|
2710
|
+
let resolver;
|
|
2711
|
+
return new Promise((resolve, reject) => {
|
|
2712
|
+
rejector = reject;
|
|
2713
|
+
resolver = resolve;
|
|
2714
|
+
if (time === 0) settlePromise(resolver, void 0, aborter);
|
|
2715
|
+
else timer();
|
|
2716
|
+
});
|
|
2507
2717
|
}
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
}
|
|
2515
|
-
const
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
for (let index = 0; index < length; index += 1) {
|
|
2527
|
-
const property = properties[index];
|
|
2528
|
-
if (!equalValue(first[property], second[property], options)) return false;
|
|
2529
|
-
}
|
|
2530
|
-
return true;
|
|
2531
|
-
}
|
|
2532
|
-
function equalSet(first, second, options) {
|
|
2533
|
-
const { size } = first;
|
|
2534
|
-
if (size !== second.size) return false;
|
|
2535
|
-
const firstValues = [...first];
|
|
2536
|
-
const secondValues = [...second];
|
|
2537
|
-
for (let index = 0; index < size; index += 1) {
|
|
2538
|
-
const firstValue = firstValues[index];
|
|
2539
|
-
if (isPrimitive(firstValue) ? !second.has(firstValue) : !secondValues.some((secondValue) => equalValue(firstValue, secondValue, options))) return false;
|
|
2540
|
-
}
|
|
2541
|
-
return true;
|
|
2718
|
+
//#endregion
|
|
2719
|
+
//#region src/promise/timed.ts
|
|
2720
|
+
async function getTimedPromise(promise, time, signal) {
|
|
2721
|
+
const aborter = createAborter(signal, () => {
|
|
2722
|
+
timer.cancel();
|
|
2723
|
+
rejector(signal?.reason);
|
|
2724
|
+
});
|
|
2725
|
+
const timer = getTimer(TIMER_WAIT, () => settlePromise(rejector, new PromiseTimeoutError(), aborter), time);
|
|
2726
|
+
let rejector;
|
|
2727
|
+
return Promise.race([promise, new Promise((_, reject) => {
|
|
2728
|
+
rejector = reject;
|
|
2729
|
+
timer();
|
|
2730
|
+
})]).then((value) => {
|
|
2731
|
+
aborter?.cancel();
|
|
2732
|
+
timer.cancel();
|
|
2733
|
+
rejector(void 0);
|
|
2734
|
+
return value;
|
|
2735
|
+
});
|
|
2542
2736
|
}
|
|
2543
|
-
function
|
|
2544
|
-
if (
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
return true;
|
|
2737
|
+
async function timed(promise, options) {
|
|
2738
|
+
if (!(promise instanceof Promise)) return Promise.reject(/* @__PURE__ */ new TypeError(PROMISE_MESSAGE_EXPECTATION_TIMED));
|
|
2739
|
+
const { signal, time } = getPromiseOptions(options);
|
|
2740
|
+
if (signal?.aborted ?? false) return Promise.reject(signal?.reason);
|
|
2741
|
+
return time > 0 ? getTimedPromise(promise, time, signal) : promise;
|
|
2549
2742
|
}
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2743
|
+
//#endregion
|
|
2744
|
+
//#region src/promise/index.ts
|
|
2745
|
+
async function attemptPromise(value, options) {
|
|
2746
|
+
const isFunction = typeof value === "function";
|
|
2747
|
+
if (!isFunction && !(value instanceof Promise)) return Promise.reject(/* @__PURE__ */ new TypeError(PROMISE_MESSAGE_EXPECTATION_ATTEMPT));
|
|
2748
|
+
const { signal, time } = getPromiseOptions(options);
|
|
2749
|
+
if (signal?.aborted ?? false) return Promise.reject(signal?.reason);
|
|
2750
|
+
const aborter = createAborter(signal, () => {
|
|
2751
|
+
rejector(signal?.reason);
|
|
2752
|
+
});
|
|
2753
|
+
async function handler(resolve, reject) {
|
|
2754
|
+
try {
|
|
2755
|
+
let result = isFunction ? value() : await value;
|
|
2756
|
+
if (result instanceof Promise) result = await result;
|
|
2757
|
+
settlePromise(resolve, result, aborter);
|
|
2758
|
+
} catch (error) {
|
|
2759
|
+
settlePromise(reject, error, aborter);
|
|
2760
|
+
}
|
|
2568
2761
|
}
|
|
2762
|
+
let rejector;
|
|
2763
|
+
const promise = new Promise((resolve, reject) => {
|
|
2764
|
+
rejector = reject;
|
|
2765
|
+
handler(resolve, reject);
|
|
2766
|
+
});
|
|
2767
|
+
return time > 0 ? getTimedPromise(promise, time, signal) : promise;
|
|
2569
2768
|
}
|
|
2570
|
-
function
|
|
2571
|
-
const
|
|
2572
|
-
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
|
|
2769
|
+
async function promises(items, options) {
|
|
2770
|
+
const { signal, strategy } = getPromisesOptions(options);
|
|
2771
|
+
if (signal?.aborted ?? false) return Promise.reject(signal?.reason);
|
|
2772
|
+
if (!Array.isArray(items)) return Promise.resolve([]);
|
|
2773
|
+
const actual = items.map((item) => typeof item === "function" ? item() : item).filter((item) => item instanceof Promise);
|
|
2774
|
+
const { length } = actual;
|
|
2775
|
+
if (length === 0) return Promise.resolve([]);
|
|
2776
|
+
const complete = strategy === PROMISE_STRATEGY_DEFAULT;
|
|
2777
|
+
const aborter = createAborter(signal, () => {
|
|
2778
|
+
handlers.reject(signal?.reason);
|
|
2779
|
+
});
|
|
2780
|
+
const data = {
|
|
2781
|
+
last: length - 1,
|
|
2782
|
+
result: []
|
|
2582
2783
|
};
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
const actual = getEqualOptions(options);
|
|
2606
|
-
const equalizer = (first, second) => equalValue(first, second, actual);
|
|
2607
|
-
equalizer.deregister = deregisterEqualizer;
|
|
2608
|
-
equalizer.register = registerEqualizer;
|
|
2609
|
-
return equalizer;
|
|
2610
|
-
}
|
|
2611
|
-
/**
|
|
2612
|
-
* Register a equality comparison function for a specific class
|
|
2613
|
-
*
|
|
2614
|
-
* _Available as `registerEqualizer` and `equal.register`_
|
|
2615
|
-
*
|
|
2616
|
-
* @param constructor Class constructor
|
|
2617
|
-
* @param handler Comparison function
|
|
2618
|
-
*/
|
|
2619
|
-
function registerEqualizer(constructor, handler) {
|
|
2620
|
-
equal.handlers.register(constructor, handler);
|
|
2784
|
+
let handlers;
|
|
2785
|
+
return new Promise((resolve, reject) => {
|
|
2786
|
+
handlers = {
|
|
2787
|
+
reject,
|
|
2788
|
+
resolve
|
|
2789
|
+
};
|
|
2790
|
+
for (let index = 0; index < length; index += 1) actual[index].then((value) => handleResult(PROMISE_TYPE_FULFILLED, {
|
|
2791
|
+
aborter,
|
|
2792
|
+
complete,
|
|
2793
|
+
data,
|
|
2794
|
+
handlers,
|
|
2795
|
+
index,
|
|
2796
|
+
value
|
|
2797
|
+
})).catch((reason) => handleResult(PROMISE_TYPE_REJECTED, {
|
|
2798
|
+
aborter,
|
|
2799
|
+
complete,
|
|
2800
|
+
data,
|
|
2801
|
+
handlers,
|
|
2802
|
+
index,
|
|
2803
|
+
value: reason
|
|
2804
|
+
}));
|
|
2805
|
+
});
|
|
2621
2806
|
}
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
const EQUAL_EXPRESSION_PROPERTIES = ["source", "flags"];
|
|
2626
|
-
const EQUAL_MINIMUM_LENGTH_FOR_SET = 16;
|
|
2627
|
-
//#endregion
|
|
2628
|
-
//#region src/internal/value/get.ts
|
|
2629
|
-
function getValue(data, path, ignoreCase) {
|
|
2630
|
-
return getNestedValue(data, path, ignoreCase === true).value;
|
|
2807
|
+
promises.result = resultPromises;
|
|
2808
|
+
async function resultPromises(items, signal) {
|
|
2809
|
+
return promises(items, signal).then(getResultsFromPromises);
|
|
2631
2810
|
}
|
|
2632
2811
|
//#endregion
|
|
2633
|
-
//#region src/
|
|
2634
|
-
function
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
return
|
|
2812
|
+
//#region src/result/index.ts
|
|
2813
|
+
async function asyncAttempt(value, err) {
|
|
2814
|
+
try {
|
|
2815
|
+
let result = typeof value === "function" ? value() : await value;
|
|
2816
|
+
if (result instanceof Promise) result = await result;
|
|
2817
|
+
return ok(result);
|
|
2818
|
+
} catch (thrown) {
|
|
2819
|
+
return getError(err ?? thrown, err == null ? void 0 : thrown);
|
|
2641
2820
|
}
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
handleValue(target, currentPath, value, false, shouldIgnoreCase);
|
|
2649
|
-
break;
|
|
2650
|
-
}
|
|
2651
|
-
let next = handleValue(target, currentPath, null, true, shouldIgnoreCase).value;
|
|
2652
|
-
if (typeof next !== "object" || next === null) {
|
|
2653
|
-
const nextPath = paths[index + 1];
|
|
2654
|
-
if (SET_EXPRESSION_INDEX.test(nextPath)) next = Array.from({ length: Number(nextPath) + 1 }, () => void 0);
|
|
2655
|
-
else next = {};
|
|
2656
|
-
target[currentPath] = next;
|
|
2657
|
-
}
|
|
2658
|
-
target = next;
|
|
2821
|
+
}
|
|
2822
|
+
function attempt(callback, err) {
|
|
2823
|
+
try {
|
|
2824
|
+
return ok(callback());
|
|
2825
|
+
} catch (thrown) {
|
|
2826
|
+
return getError(err ?? thrown, err == null ? void 0 : thrown);
|
|
2659
2827
|
}
|
|
2660
|
-
return data;
|
|
2661
2828
|
}
|
|
2662
|
-
|
|
2829
|
+
attempt.async = asyncAttempt;
|
|
2830
|
+
Object.defineProperty(attempt, "async", { value: asyncAttempt });
|
|
2663
2831
|
//#endregion
|
|
2664
|
-
//#region src/
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
|
|
2672
|
-
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
*
|
|
2677
|
-
* @param value String to capitalize
|
|
2678
|
-
* @returns Capitalized string
|
|
2679
|
-
*/
|
|
2680
|
-
function capitalize(value) {
|
|
2681
|
-
if (typeof value !== "string" || value.length === 0) return "";
|
|
2682
|
-
memoizedCapitalize ??= memoize((v) => v.length === 1 ? v.toLocaleUpperCase() : `${v.charAt(0).toLocaleUpperCase()}${v.slice(1).toLocaleLowerCase()}`);
|
|
2683
|
-
return memoizedCapitalize.run(value);
|
|
2684
|
-
}
|
|
2685
|
-
/**
|
|
2686
|
-
* Convert a string to kebab case _(this-is-kebab-case)_
|
|
2687
|
-
*
|
|
2688
|
-
* @param value String to convert
|
|
2689
|
-
* @returns Kebab-cased string
|
|
2690
|
-
*/
|
|
2691
|
-
function kebabCase(value) {
|
|
2692
|
-
return toCase(STRING_CASE_KEBAB, value, false, false);
|
|
2693
|
-
}
|
|
2694
|
-
/**
|
|
2695
|
-
* Convert a string to lower case
|
|
2696
|
-
*
|
|
2697
|
-
* @param value String to convert
|
|
2698
|
-
* @returns Lower-cased string
|
|
2699
|
-
*/
|
|
2700
|
-
function lowerCase(value) {
|
|
2701
|
-
if (typeof value !== "string") return "";
|
|
2702
|
-
memoizedLowerCase ??= memoize((v) => v.toLocaleLowerCase());
|
|
2703
|
-
return memoizedLowerCase.run(value);
|
|
2704
|
-
}
|
|
2705
|
-
/**
|
|
2706
|
-
* Convert a string to pascal case _(ThisIsPascalCase)_
|
|
2707
|
-
*
|
|
2708
|
-
* @param value String to convert
|
|
2709
|
-
* @returns Pascal-cased string
|
|
2710
|
-
*/
|
|
2711
|
-
function pascalCase(value) {
|
|
2712
|
-
return toCase(STRING_CASE_PASCAL, value, true, true);
|
|
2713
|
-
}
|
|
2714
|
-
/**
|
|
2715
|
-
* Convert a string to snake case _(this_is_snake_case)_
|
|
2716
|
-
*
|
|
2717
|
-
* @param value String to convert
|
|
2718
|
-
* @returns Snake-cased string
|
|
2719
|
-
*/
|
|
2720
|
-
function snakeCase(value) {
|
|
2721
|
-
return toCase(STRING_CASE_SNAKE, value, false, false);
|
|
2722
|
-
}
|
|
2723
|
-
/**
|
|
2724
|
-
* Convert a string to title case _(Capitalizing Every Word)_
|
|
2725
|
-
*
|
|
2726
|
-
* @param value String to convert
|
|
2727
|
-
* @returns Title-cased string
|
|
2728
|
-
*/
|
|
2729
|
-
function titleCase(value) {
|
|
2730
|
-
if (typeof value !== "string" || value.length === 0) return "";
|
|
2731
|
-
memoizedTitleCase ??= memoize((v) => v.length < 2 ? capitalize(v) : join(words(v).map(capitalize), " "));
|
|
2732
|
-
return memoizedTitleCase.run(value);
|
|
2832
|
+
//#region src/result/match.ts
|
|
2833
|
+
async function asyncMatchResult(result, first, error) {
|
|
2834
|
+
let value;
|
|
2835
|
+
if (typeof result === "function") value = await result();
|
|
2836
|
+
else if (result instanceof Promise) value = await result;
|
|
2837
|
+
else value = result;
|
|
2838
|
+
if (!isResult(value)) throw new Error(MATCH_MESSAGE);
|
|
2839
|
+
const hasObj = typeof first === "object" && first !== null;
|
|
2840
|
+
const okHandler = hasObj ? first.ok : first;
|
|
2841
|
+
const errorHandler = hasObj ? first.error : error;
|
|
2842
|
+
if (isOk(value)) return okHandler(value.value);
|
|
2843
|
+
return errorHandler(value.error, value.original);
|
|
2733
2844
|
}
|
|
2734
|
-
function
|
|
2735
|
-
|
|
2736
|
-
|
|
2737
|
-
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
return
|
|
2845
|
+
function matchResult(result, first, error) {
|
|
2846
|
+
const value = typeof result === "function" ? result() : result;
|
|
2847
|
+
if (!isResult(value)) throw new Error(MATCH_MESSAGE);
|
|
2848
|
+
const hasObj = typeof first === "object" && first !== null;
|
|
2849
|
+
const okHandler = hasObj ? first.ok : first;
|
|
2850
|
+
const errorHandler = hasObj ? first.error : error;
|
|
2851
|
+
if (isOk(value)) return okHandler(value.value);
|
|
2852
|
+
return errorHandler(value.error, value.original);
|
|
2741
2853
|
}
|
|
2742
|
-
function
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
if (item.length === 0) continue;
|
|
2757
|
-
if (!capitalizeAny || itemCount === 0 && partIndex === 0 && !capitalizeFirst) partResult.push(item.toLocaleLowerCase());
|
|
2758
|
-
else partResult.push(capitalize(item));
|
|
2759
|
-
itemCount += 1;
|
|
2760
|
-
}
|
|
2761
|
-
cased.push(join(partResult, delimiters[type]));
|
|
2762
|
-
}
|
|
2763
|
-
return join(cased, delimiters[type]);
|
|
2854
|
+
const MATCH_MESSAGE = "`result.match` expected a Result or a function that returns a Result";
|
|
2855
|
+
matchResult.async = asyncMatchResult;
|
|
2856
|
+
Object.defineProperty(matchResult, "async", { value: asyncMatchResult });
|
|
2857
|
+
//#endregion
|
|
2858
|
+
//#region src/result/work/flow.ts
|
|
2859
|
+
function attemptAsyncFlow(...fns) {
|
|
2860
|
+
let Flow;
|
|
2861
|
+
return (...args) => asyncAttempt(() => {
|
|
2862
|
+
Flow ??= asyncFlow(...fns);
|
|
2863
|
+
return Flow(...args.map((value) => {
|
|
2864
|
+
if (isError(value)) throw value.error;
|
|
2865
|
+
return isOk(value) ? value.value : value;
|
|
2866
|
+
}));
|
|
2867
|
+
});
|
|
2764
2868
|
}
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
return memoizedUpperCase.run(value);
|
|
2869
|
+
function attemptFlow(...fns) {
|
|
2870
|
+
let Flow;
|
|
2871
|
+
return (...args) => attempt(() => {
|
|
2872
|
+
Flow ??= flow(...fns);
|
|
2873
|
+
return Flow(...args.map((value) => {
|
|
2874
|
+
if (isError(value)) throw value.error;
|
|
2875
|
+
return isOk(value) ? value.value : value;
|
|
2876
|
+
}));
|
|
2877
|
+
});
|
|
2775
2878
|
}
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
const
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
|
|
2879
|
+
attemptFlow.async = attemptAsyncFlow;
|
|
2880
|
+
Object.defineProperty(attemptFlow, "async", { value: attemptAsyncFlow });
|
|
2881
|
+
//#endregion
|
|
2882
|
+
//#region src/result/work/pipe.ts
|
|
2883
|
+
async function attemptAsyncPipe(initial, first, ...seconds) {
|
|
2884
|
+
return asyncAttempt(() => {
|
|
2885
|
+
if (isError(initial)) throw initial.error;
|
|
2886
|
+
const value = typeof initial === "function" ? initial() : isOk(initial) ? initial.value : initial;
|
|
2887
|
+
if (first == null) return value;
|
|
2888
|
+
return asyncPipe(value, ...[first, ...seconds]);
|
|
2889
|
+
});
|
|
2890
|
+
}
|
|
2891
|
+
function attemptPipe(initial, first, ...seconds) {
|
|
2892
|
+
return attempt(() => {
|
|
2893
|
+
if (isError(initial)) throw initial.error;
|
|
2894
|
+
const value = typeof initial === "function" ? initial() : isOk(initial) ? initial.value : initial;
|
|
2895
|
+
if (first == null) return value;
|
|
2896
|
+
return pipe(value, ...[first, ...seconds]);
|
|
2897
|
+
});
|
|
2898
|
+
}
|
|
2899
|
+
attemptPipe.async = attemptAsyncPipe;
|
|
2900
|
+
Object.defineProperty(attemptPipe, "async", { value: attemptAsyncPipe });
|
|
2798
2901
|
//#endregion
|
|
2799
2902
|
//#region src/string/match.ts
|
|
2800
2903
|
/**
|
|
@@ -3856,6 +3959,142 @@ function transformValue(value, transformer) {
|
|
|
3856
3959
|
return value;
|
|
3857
3960
|
}
|
|
3858
3961
|
//#endregion
|
|
3962
|
+
//#region src/internal/subscription.ts
|
|
3963
|
+
function addSubscription(subscriptions, subscription, state) {
|
|
3964
|
+
const { key, value } = state.parameters;
|
|
3965
|
+
const { items, values } = subscriptions.state;
|
|
3966
|
+
if (!isKey(key)) {
|
|
3967
|
+
items.any.add(subscription);
|
|
3968
|
+
values.from.any.set(value, subscription);
|
|
3969
|
+
values.to.any.set(subscription, value);
|
|
3970
|
+
return;
|
|
3971
|
+
}
|
|
3972
|
+
/* istanbul ignore if */
|
|
3973
|
+
if (items.keyed == null || values.from.keyed == null || values.to.keyed == null)
|
|
3974
|
+
// istanbul ignore next
|
|
3975
|
+
return;
|
|
3976
|
+
let keyedItems = items.keyed.get(key);
|
|
3977
|
+
if (keyedItems == null) {
|
|
3978
|
+
keyedItems = /* @__PURE__ */ new Set();
|
|
3979
|
+
items.keyed.set(key, keyedItems);
|
|
3980
|
+
}
|
|
3981
|
+
keyedItems.add(subscription);
|
|
3982
|
+
let keyedFrom = values.from.keyed.get(key);
|
|
3983
|
+
if (keyedFrom == null) {
|
|
3984
|
+
keyedFrom = /* @__PURE__ */ new Map();
|
|
3985
|
+
values.from.keyed.set(key, keyedFrom);
|
|
3986
|
+
}
|
|
3987
|
+
keyedFrom.set(value, subscription);
|
|
3988
|
+
let keyedTo = values.to.keyed.get(key);
|
|
3989
|
+
if (keyedTo == null) {
|
|
3990
|
+
keyedTo = /* @__PURE__ */ new Map();
|
|
3991
|
+
values.to.keyed.set(key, keyedTo);
|
|
3992
|
+
}
|
|
3993
|
+
keyedTo.set(subscription, value);
|
|
3994
|
+
}
|
|
3995
|
+
function clearSubscriptions(store) {
|
|
3996
|
+
for (const susbcription of store.values.to.any.keys()) susbcription.unsubscribe();
|
|
3997
|
+
if (store.values.to.keyed != null) for (const values of store.values.to.keyed.values()) for (const susbcription of values.keys()) susbcription.unsubscribe();
|
|
3998
|
+
}
|
|
3999
|
+
function createSubscription(subscriptions, property, parameters) {
|
|
4000
|
+
if (parameters.signal?.aborted ?? false) throw new Error(parameters.signal?.reason);
|
|
4001
|
+
const state = {
|
|
4002
|
+
parameters,
|
|
4003
|
+
active: true
|
|
4004
|
+
};
|
|
4005
|
+
const existing = getExistingSubscription(subscriptions, state);
|
|
4006
|
+
if (existing != null) return [existing, true];
|
|
4007
|
+
if (subscriptions.state.keys != null && isKey(parameters.key) && !subscriptions.state.keys.has(parameters.key)) throw new Error(SUBSCRIPTION_INVALID_KEY);
|
|
4008
|
+
state.aborter = createAborter(parameters.signal, () => unsubscribe(subscriptions, instance, state));
|
|
4009
|
+
const instance = { unsubscribe: () => unsubscribe(subscriptions, instance, state) };
|
|
4010
|
+
Object.defineProperties(instance, {
|
|
4011
|
+
[SUBSCRIPTION_PROPERTY]: { value: true },
|
|
4012
|
+
[property.key]: { value: property.value ?? "subscription" },
|
|
4013
|
+
active: {
|
|
4014
|
+
enumerable: true,
|
|
4015
|
+
get: () => (parameters.isActive?.() ?? true) && state.active
|
|
4016
|
+
}
|
|
4017
|
+
});
|
|
4018
|
+
addSubscription(subscriptions, instance, state);
|
|
4019
|
+
return [Object.freeze(instance), false];
|
|
4020
|
+
}
|
|
4021
|
+
function createSubscriptions(parameters) {
|
|
4022
|
+
const { keys, property } = parameters;
|
|
4023
|
+
const state = {
|
|
4024
|
+
keys,
|
|
4025
|
+
items: {
|
|
4026
|
+
any: /* @__PURE__ */ new Set(),
|
|
4027
|
+
keyed: keys == null ? void 0 : /* @__PURE__ */ new Map()
|
|
4028
|
+
},
|
|
4029
|
+
values: {
|
|
4030
|
+
from: {
|
|
4031
|
+
any: /* @__PURE__ */ new Map(),
|
|
4032
|
+
keyed: keys == null ? void 0 : /* @__PURE__ */ new Map()
|
|
4033
|
+
},
|
|
4034
|
+
to: {
|
|
4035
|
+
any: /* @__PURE__ */ new Map(),
|
|
4036
|
+
keyed: keys == null ? void 0 : /* @__PURE__ */ new Map()
|
|
4037
|
+
}
|
|
4038
|
+
}
|
|
4039
|
+
};
|
|
4040
|
+
const instance = {
|
|
4041
|
+
state,
|
|
4042
|
+
clear: () => clearSubscriptions(state),
|
|
4043
|
+
create: (parameters) => createSubscription(instance, property, parameters)
|
|
4044
|
+
};
|
|
4045
|
+
return instance;
|
|
4046
|
+
}
|
|
4047
|
+
function getExistingSubscription(subscriptions, state) {
|
|
4048
|
+
const { parameters } = state;
|
|
4049
|
+
const { values } = subscriptions.state;
|
|
4050
|
+
return isKey(parameters.key) ? values.from.keyed?.get(parameters.key)?.get(parameters.value) : values.from.any.get(parameters.value);
|
|
4051
|
+
}
|
|
4052
|
+
/**
|
|
4053
|
+
* Is the value a subscription?
|
|
4054
|
+
*
|
|
4055
|
+
* @param value Value to check
|
|
4056
|
+
* @returns `true` if the value is a subscription, otherwise `false`
|
|
4057
|
+
*/
|
|
4058
|
+
function isSubscription(value) {
|
|
4059
|
+
return isPlainObject(value) && SUBSCRIPTION_PROPERTY in value && value[SUBSCRIPTION_PROPERTY] === true;
|
|
4060
|
+
}
|
|
4061
|
+
function removeFromStore(items, values, subscription, value, key) {
|
|
4062
|
+
items.delete(subscription);
|
|
4063
|
+
if (key == null) {
|
|
4064
|
+
values.from.any.delete(value);
|
|
4065
|
+
values.to.any.delete(subscription);
|
|
4066
|
+
} else {
|
|
4067
|
+
values.from.keyed?.get(key)?.delete(value);
|
|
4068
|
+
values.to.keyed?.get(key)?.delete(subscription);
|
|
4069
|
+
}
|
|
4070
|
+
}
|
|
4071
|
+
function removeSubscription(subscriptions, subscription, state) {
|
|
4072
|
+
if (!state.active) return;
|
|
4073
|
+
state.aborter = void 0;
|
|
4074
|
+
state.active = false;
|
|
4075
|
+
state.parameters.isActive = void 0;
|
|
4076
|
+
state.parameters.signal = void 0;
|
|
4077
|
+
const { key, value } = state.parameters;
|
|
4078
|
+
const { items, values } = subscriptions.state;
|
|
4079
|
+
if (!isKey(key)) {
|
|
4080
|
+
removeFromStore(items.any, values, subscription, value);
|
|
4081
|
+
return;
|
|
4082
|
+
}
|
|
4083
|
+
const keyed = items.keyed?.get(key);
|
|
4084
|
+
/* istanbul ignore if */
|
|
4085
|
+
if (items.keyed == null || keyed == null)
|
|
4086
|
+
// istanbul ignore next
|
|
4087
|
+
return;
|
|
4088
|
+
removeFromStore(keyed, values, subscription, value, key);
|
|
4089
|
+
if (keyed.size === 0) items.keyed.delete(key);
|
|
4090
|
+
}
|
|
4091
|
+
function unsubscribe(subscriptions, subscription, state) {
|
|
4092
|
+
state.aborter?.cancel();
|
|
4093
|
+
removeSubscription(subscriptions, subscription, state);
|
|
4094
|
+
}
|
|
4095
|
+
const SUBSCRIPTION_INVALID_KEY = "Invalid key for subscription";
|
|
4096
|
+
const SUBSCRIPTION_PROPERTY = "$subscription";
|
|
4097
|
+
//#endregion
|
|
3859
4098
|
//#region src/beacon.ts
|
|
3860
4099
|
/**
|
|
3861
4100
|
* Create a new beacon
|
|
@@ -3987,26 +4226,132 @@ function subscribeToObservable(state, first, second, third) {
|
|
|
3987
4226
|
isActive: () => state.beacon.active && state.active,
|
|
3988
4227
|
value: observer
|
|
3989
4228
|
});
|
|
3990
|
-
observer.next?.(state.beacon.value);
|
|
4229
|
+
observer.next?.(state.beacon.value);
|
|
4230
|
+
return subscription;
|
|
4231
|
+
}
|
|
4232
|
+
function updateBeacon(type, state, value, finish) {
|
|
4233
|
+
if (!state.active) return;
|
|
4234
|
+
if (type === BEACON_TYPE_NEXT) {
|
|
4235
|
+
if (state.options.equal(state.value, value)) return;
|
|
4236
|
+
state.value = value;
|
|
4237
|
+
}
|
|
4238
|
+
for (const [, observer] of state.subscriptions.state.values.to.any) observer[type]?.(value);
|
|
4239
|
+
if (finish === true) finishBeacon(state, true);
|
|
4240
|
+
}
|
|
4241
|
+
const BEACON_MESSAGE_RETRIEVE = "Cannot retrieve observable from a closed beacon";
|
|
4242
|
+
const BEACON_MESSAGE_SUBSCRIBE = "Cannot subscribe to a closed observable";
|
|
4243
|
+
const BEACON_PROPERTY = "$beacon";
|
|
4244
|
+
const BEACON_NAME = "beacon";
|
|
4245
|
+
const BEACON_OBSERVABLE = "observable";
|
|
4246
|
+
const BEACON_TYPE_ERROR = "error";
|
|
4247
|
+
const BEACON_TYPE_NEXT = "next";
|
|
4248
|
+
const beaconSubscription = { key: BEACON_PROPERTY };
|
|
4249
|
+
//#endregion
|
|
4250
|
+
//#region src/internal/herald.ts
|
|
4251
|
+
function createEvents(herald, state) {
|
|
4252
|
+
const events = {};
|
|
4253
|
+
Object.defineProperty(events, HERALD_PROPERTY, { value: HERALD_NAME_EVENTS });
|
|
4254
|
+
for (const key of state.keys) events[key] = (callback, signal) => herald.subscribe(key, callback, signal);
|
|
4255
|
+
return Object.freeze(events);
|
|
4256
|
+
}
|
|
4257
|
+
function emitForHerald(state, event, ...parameters) {
|
|
4258
|
+
const items = state.subscriptions.state.values.from.keyed?.get(event);
|
|
4259
|
+
if (items == null || items.size === 0) return;
|
|
4260
|
+
for (const [callback] of items) callback(...parameters);
|
|
4261
|
+
}
|
|
4262
|
+
function getHeraldSubscriptionProperty(input) {
|
|
4263
|
+
if (input == null) return heraldSubscription;
|
|
4264
|
+
const property = isPlainObject(input) ? input : {};
|
|
4265
|
+
if (typeof property.key !== "string" || property.value != null && typeof property.value !== "string") throw new Error(HERALD_MESSAGE_PROPERTY);
|
|
4266
|
+
return {
|
|
4267
|
+
key: property.key,
|
|
4268
|
+
value: property.value
|
|
4269
|
+
};
|
|
4270
|
+
}
|
|
4271
|
+
function getHeraldState(input) {
|
|
4272
|
+
const options = isPlainObject(input) ? input : {};
|
|
4273
|
+
if (!Array.isArray(options.names) || options.names.length === 0 || !options.names.every((name) => typeof name === "string")) throw new Error(HERALD_MESSAGE_ARRAY);
|
|
4274
|
+
if (options.onCreate != null && typeof options.onCreate !== "function") throw new Error(HERALD_MESSAGE_ONCREATE);
|
|
4275
|
+
const keys = new Set(options.names);
|
|
4276
|
+
return {
|
|
4277
|
+
keys,
|
|
4278
|
+
subscriptions: createSubscriptions({
|
|
4279
|
+
keys,
|
|
4280
|
+
property: getHeraldSubscriptionProperty(options.property)
|
|
4281
|
+
}),
|
|
4282
|
+
onCreate: options.onCreate
|
|
4283
|
+
};
|
|
4284
|
+
}
|
|
4285
|
+
/**
|
|
4286
|
+
* Create a _Herald_ for announcing named events
|
|
4287
|
+
*
|
|
4288
|
+
* @param names Event names
|
|
4289
|
+
* @param property Optional property for subscription identification _(defaults to `$herald`)_
|
|
4290
|
+
* @returns _Herald_ instance
|
|
4291
|
+
*/
|
|
4292
|
+
function herald(options) {
|
|
4293
|
+
const state = getHeraldState(options);
|
|
4294
|
+
const instance = {
|
|
4295
|
+
clear: () => state.subscriptions.clear(),
|
|
4296
|
+
emit: (event, ...parameters) => emitForHerald(state, event, ...parameters),
|
|
4297
|
+
observed: (event) => (state.subscriptions.state.items.keyed?.get(event)?.size ?? 0) > 0,
|
|
4298
|
+
subscribe: (key, callback, signal) => subscribeToHerald(state, key, callback, signal)
|
|
4299
|
+
};
|
|
4300
|
+
Object.defineProperties(instance, {
|
|
4301
|
+
[HERALD_PROPERTY]: { value: HERALD_NAME_HERALD },
|
|
4302
|
+
events: {
|
|
4303
|
+
enumerable: true,
|
|
4304
|
+
value: createEvents(instance, state)
|
|
4305
|
+
}
|
|
4306
|
+
});
|
|
4307
|
+
return Object.freeze(instance);
|
|
4308
|
+
}
|
|
4309
|
+
/**
|
|
4310
|
+
* Is the value a herald?
|
|
4311
|
+
*
|
|
4312
|
+
* @param value Value to check
|
|
4313
|
+
* @returns `true` if the value is a herald, otherwise `false`
|
|
4314
|
+
*/
|
|
4315
|
+
function isHerald(value) {
|
|
4316
|
+
return isHeraldInstance(HERALD_NAME_HERALD, value);
|
|
4317
|
+
}
|
|
4318
|
+
/**
|
|
4319
|
+
* Is the value events for a herald?
|
|
4320
|
+
*
|
|
4321
|
+
* @param value Value to check
|
|
4322
|
+
* @returns `true` if the value is events for a herald, otherwise `false`
|
|
4323
|
+
*/
|
|
4324
|
+
function isHeraldEvents(value) {
|
|
4325
|
+
return isHeraldInstance(HERALD_NAME_EVENTS, value);
|
|
4326
|
+
}
|
|
4327
|
+
function isHeraldInstance(name, value) {
|
|
4328
|
+
return isPlainObject(value) && HERALD_PROPERTY in value && value[HERALD_PROPERTY] === name;
|
|
4329
|
+
}
|
|
4330
|
+
/**
|
|
4331
|
+
* Is the value a herald subscription?
|
|
4332
|
+
*
|
|
4333
|
+
* @param value Value to check
|
|
4334
|
+
* @returns `true` if the value is a herald subscription, otherwise `false`
|
|
4335
|
+
*/
|
|
4336
|
+
function isHeraldSubscription(value) {
|
|
4337
|
+
return isSubscription(value) && value[HERALD_PROPERTY] === "subscription";
|
|
4338
|
+
}
|
|
4339
|
+
function subscribeToHerald(state, key, callback, signal) {
|
|
4340
|
+
const [subscription, existing] = state.subscriptions.create({
|
|
4341
|
+
key,
|
|
4342
|
+
signal,
|
|
4343
|
+
value: callback
|
|
4344
|
+
});
|
|
4345
|
+
if (!existing) state.onCreate?.(key, callback, subscription);
|
|
3991
4346
|
return subscription;
|
|
3992
4347
|
}
|
|
3993
|
-
|
|
3994
|
-
|
|
3995
|
-
|
|
3996
|
-
|
|
3997
|
-
|
|
3998
|
-
|
|
3999
|
-
|
|
4000
|
-
if (finish === true) finishBeacon(state, true);
|
|
4001
|
-
}
|
|
4002
|
-
const BEACON_MESSAGE_RETRIEVE = "Cannot retrieve observable from a closed beacon";
|
|
4003
|
-
const BEACON_MESSAGE_SUBSCRIBE = "Cannot subscribe to a closed observable";
|
|
4004
|
-
const BEACON_PROPERTY = "$beacon";
|
|
4005
|
-
const BEACON_NAME = "beacon";
|
|
4006
|
-
const BEACON_OBSERVABLE = "observable";
|
|
4007
|
-
const BEACON_TYPE_ERROR = "error";
|
|
4008
|
-
const BEACON_TYPE_NEXT = "next";
|
|
4009
|
-
const beaconSubscription = { key: BEACON_PROPERTY };
|
|
4348
|
+
const HERALD_PROPERTY = "$herald";
|
|
4349
|
+
const HERALD_MESSAGE_ARRAY = "Herald requires an array of event names.";
|
|
4350
|
+
const HERALD_MESSAGE_ONCREATE = `Herald requires a valid onCreate callback for subscription creation`;
|
|
4351
|
+
const HERALD_MESSAGE_PROPERTY = `Herald requires valid property information for subscription identification`;
|
|
4352
|
+
const HERALD_NAME_EVENTS = "events";
|
|
4353
|
+
const HERALD_NAME_HERALD = "herald";
|
|
4354
|
+
const heraldSubscription = { key: HERALD_PROPERTY };
|
|
4010
4355
|
//#endregion
|
|
4011
4356
|
//#region src/color/constants.ts
|
|
4012
4357
|
const COLOR_ALPHA = {
|
|
@@ -5333,332 +5678,86 @@ const methods = [
|
|
|
5333
5678
|
* _(Logging can be enabled or disabled by setting the `enabled` property)_
|
|
5334
5679
|
*/
|
|
5335
5680
|
const Logger = (() => {
|
|
5336
|
-
const instance = {};
|
|
5337
|
-
Object.defineProperties(instance, {
|
|
5338
|
-
[LOGGER_PROPERTY]: { value: LOGGER_NAME },
|
|
5339
|
-
enabled: {
|
|
5340
|
-
enumerable: true,
|
|
5341
|
-
get: () => enabled,
|
|
5342
|
-
set: (value) => {
|
|
5343
|
-
enabled = typeof value === "boolean" ? value : enabled;
|
|
5344
|
-
}
|
|
5345
|
-
},
|
|
5346
|
-
time: { value: (label) => timedLogger(getString(label)) }
|
|
5347
|
-
});
|
|
5348
|
-
for (const method of methods) Object.defineProperty(instance, method, {
|
|
5349
|
-
enumerable: true,
|
|
5350
|
-
get() {
|
|
5351
|
-
return enabled ? console[method].bind(console) : noop;
|
|
5352
|
-
}
|
|
5353
|
-
});
|
|
5354
|
-
return Object.freeze(instance);
|
|
5355
|
-
})();
|
|
5356
|
-
let enabled = true;
|
|
5357
|
-
//#endregion
|
|
5358
|
-
//#region src/math.ts
|
|
5359
|
-
function average(array, key) {
|
|
5360
|
-
const aggregated = aggregate(AGGREGATION_AVERAGE, array, key);
|
|
5361
|
-
return aggregated.count > 0 ? aggregated.value / aggregated.count : NaN;
|
|
5362
|
-
}
|
|
5363
|
-
/**
|
|
5364
|
-
* Round a number up
|
|
5365
|
-
*
|
|
5366
|
-
* @param value Number to round up
|
|
5367
|
-
* @param decimals Number of decimal places to round to _(defaults to `0`)_
|
|
5368
|
-
* @returns Rounded number, or `Number.NaN` if the value if unable to be rounded
|
|
5369
|
-
*/
|
|
5370
|
-
function ceil(value, decimals) {
|
|
5371
|
-
return roundNumber(Math.ceil, value, decimals);
|
|
5372
|
-
}
|
|
5373
|
-
function count(array, key, value) {
|
|
5374
|
-
if (!Array.isArray(array)) return NaN;
|
|
5375
|
-
const { length } = array;
|
|
5376
|
-
const callback = getAggregateCallback(key);
|
|
5377
|
-
if (callback == null) return length;
|
|
5378
|
-
let counted = 0;
|
|
5379
|
-
for (let index = 0; index < length; index += 1) {
|
|
5380
|
-
const item = array[index];
|
|
5381
|
-
if (Object.is(callback(item, index, array), value)) counted += 1;
|
|
5382
|
-
}
|
|
5383
|
-
return counted;
|
|
5384
|
-
}
|
|
5385
|
-
/**
|
|
5386
|
-
* Round a number down
|
|
5387
|
-
*
|
|
5388
|
-
* @param value Number to round down
|
|
5389
|
-
* @param decimals Number of decimal places to round to _(defaults to `0`)_
|
|
5390
|
-
* @returns Rounded number, or `Number.NaN` if the value if unable to be rounded
|
|
5391
|
-
*/
|
|
5392
|
-
function floor(value, decimals) {
|
|
5393
|
-
return roundNumber(Math.floor, value, decimals);
|
|
5394
|
-
}
|
|
5395
|
-
function median(array, key) {
|
|
5396
|
-
let length = Array.isArray(array) ? array.length : 0;
|
|
5397
|
-
if (!Array.isArray(array) || length === 0) return NaN;
|
|
5398
|
-
let values = array;
|
|
5399
|
-
const callback = getAggregateCallback(key);
|
|
5400
|
-
if (callback != null) values = array.map((item, index) => callback(item, index, array));
|
|
5401
|
-
const numbers = values.filter(isNumber).sort((first, second) => first - second);
|
|
5402
|
-
length = numbers.length;
|
|
5403
|
-
if (length === 1) return numbers[0];
|
|
5404
|
-
if (length % 2 === 0) {
|
|
5405
|
-
const first = length / 2 - 1;
|
|
5406
|
-
const second = length / 2;
|
|
5407
|
-
return (numbers[first] + numbers[second]) / 2;
|
|
5408
|
-
}
|
|
5409
|
-
return numbers[Math.floor(length / 2)];
|
|
5410
|
-
}
|
|
5411
|
-
function min(array, key) {
|
|
5412
|
-
return getAggregated("min", array, key);
|
|
5413
|
-
}
|
|
5414
|
-
function sum(array, key) {
|
|
5415
|
-
return getAggregated("sum", array, key);
|
|
5416
|
-
}
|
|
5417
|
-
//#endregion
|
|
5418
|
-
//#region src/promise/constants.ts
|
|
5419
|
-
const PROMISE_ERROR_NAME = "PromiseTimeoutError";
|
|
5420
|
-
const PROMISE_MESSAGE_EXPECTATION_ATTEMPT = "Attempt expected a function or a promise";
|
|
5421
|
-
const PROMISE_MESSAGE_EXPECTATION_RESULT = "toResult expected a Promise";
|
|
5422
|
-
const PROMISE_MESSAGE_EXPECTATION_TIMED = "Timed function expected a Promise";
|
|
5423
|
-
const PROMISE_MESSAGE_TIMEOUT = "Promise timed out";
|
|
5424
|
-
const PROMISE_STRATEGY_ALL = /* @__PURE__ */ new Set(["complete", "first"]);
|
|
5425
|
-
const PROMISE_STRATEGY_DEFAULT = "complete";
|
|
5426
|
-
const PROMISE_TYPE_FULFILLED = "fulfilled";
|
|
5427
|
-
const PROMISE_TYPE_REJECTED = "rejected";
|
|
5428
|
-
//#endregion
|
|
5429
|
-
//#region src/promise/models.ts
|
|
5430
|
-
/**
|
|
5431
|
-
* A _Promise_ that can be canceled
|
|
5432
|
-
*/
|
|
5433
|
-
var CancelablePromise = class extends Promise {
|
|
5434
|
-
#rejector;
|
|
5435
|
-
constructor(executor) {
|
|
5436
|
-
let rejector;
|
|
5437
|
-
super((resolve, reject) => {
|
|
5438
|
-
rejector = reject;
|
|
5439
|
-
executor(resolve, reject);
|
|
5440
|
-
});
|
|
5441
|
-
this.#rejector = rejector;
|
|
5442
|
-
}
|
|
5443
|
-
/**
|
|
5444
|
-
* Cancel the _Promise_, rejecting it with an optional reason
|
|
5445
|
-
*
|
|
5446
|
-
* @param reason Optional reason for canceling the _Promise_
|
|
5447
|
-
*/
|
|
5448
|
-
cancel(reason) {
|
|
5449
|
-
this.#rejector?.(reason);
|
|
5450
|
-
this.#rejector = void 0;
|
|
5451
|
-
}
|
|
5452
|
-
};
|
|
5453
|
-
/**
|
|
5454
|
-
* An error thrown when a promise times out
|
|
5455
|
-
*/
|
|
5456
|
-
var PromiseTimeoutError = class extends Error {
|
|
5457
|
-
constructor() {
|
|
5458
|
-
super(PROMISE_MESSAGE_TIMEOUT);
|
|
5459
|
-
this.name = PROMISE_ERROR_NAME;
|
|
5460
|
-
}
|
|
5461
|
-
};
|
|
5462
|
-
//#endregion
|
|
5463
|
-
//#region src/promise/helpers.ts
|
|
5464
|
-
function getPromiseOptions(input) {
|
|
5465
|
-
if (typeof input === "number") return { time: getNumberOrDefault(input, 0) };
|
|
5466
|
-
if (input instanceof AbortSignal) return {
|
|
5467
|
-
signal: input,
|
|
5468
|
-
time: 0
|
|
5469
|
-
};
|
|
5470
|
-
const options = typeof input === "object" && input !== null ? input : {};
|
|
5471
|
-
return {
|
|
5472
|
-
signal: options.signal instanceof AbortSignal ? options.signal : void 0,
|
|
5473
|
-
time: getNumberOrDefault(options.time, 0)
|
|
5474
|
-
};
|
|
5475
|
-
}
|
|
5476
|
-
function getPromisesOptions(input) {
|
|
5477
|
-
if (typeof input === "string") return { strategy: getStrategyOrDefault(input) };
|
|
5478
|
-
if (input instanceof AbortSignal) return {
|
|
5479
|
-
signal: input,
|
|
5480
|
-
strategy: PROMISE_STRATEGY_DEFAULT
|
|
5481
|
-
};
|
|
5482
|
-
const options = typeof input === "object" && input !== null ? input : {};
|
|
5483
|
-
return {
|
|
5484
|
-
signal: options.signal instanceof AbortSignal ? options.signal : void 0,
|
|
5485
|
-
strategy: getStrategyOrDefault(options.strategy)
|
|
5486
|
-
};
|
|
5487
|
-
}
|
|
5488
|
-
function getResultsFromPromises(promised) {
|
|
5489
|
-
return promised.map((result) => isFulfilled(result) ? ok(result.value) : error(result.reason));
|
|
5490
|
-
}
|
|
5491
|
-
function getStrategyOrDefault(value) {
|
|
5492
|
-
return PROMISE_STRATEGY_ALL.has(value) ? value : PROMISE_STRATEGY_DEFAULT;
|
|
5493
|
-
}
|
|
5494
|
-
/**
|
|
5495
|
-
* Is the value a fulfilled _Promise_ result?
|
|
5496
|
-
*
|
|
5497
|
-
* @param value Value to check
|
|
5498
|
-
* @returns `true` if the value is a fulfilled _Promise_ result, otherwise `false`
|
|
5499
|
-
*/
|
|
5500
|
-
function isFulfilled(value) {
|
|
5501
|
-
return isType(value, PROMISE_TYPE_FULFILLED);
|
|
5502
|
-
}
|
|
5503
|
-
/**
|
|
5504
|
-
* Is the value a rejected _Promise_ result?
|
|
5505
|
-
*
|
|
5506
|
-
* @param value Value to check
|
|
5507
|
-
* @returns `true` if the value is a rejected _Promise_ result, otherwise `false`
|
|
5508
|
-
*/
|
|
5509
|
-
function isRejected(value) {
|
|
5510
|
-
return isType(value, PROMISE_TYPE_REJECTED);
|
|
5511
|
-
}
|
|
5512
|
-
function isType(value, type) {
|
|
5513
|
-
return typeof value === "object" && value !== null && value.status === type;
|
|
5514
|
-
}
|
|
5515
|
-
//#endregion
|
|
5516
|
-
//#region src/promise/misc.ts
|
|
5517
|
-
/**
|
|
5518
|
-
* Create a cancelable _Promise_
|
|
5519
|
-
*
|
|
5520
|
-
* @param executor Executor function for the _Promise_
|
|
5521
|
-
* @returns Cancelable _Promise_
|
|
5522
|
-
*/
|
|
5523
|
-
function cancelable(executor) {
|
|
5524
|
-
return new CancelablePromise(executor);
|
|
5525
|
-
}
|
|
5526
|
-
function handleResult(status, parameters) {
|
|
5527
|
-
const { aborter, complete, data, handlers, index, value } = parameters;
|
|
5528
|
-
if (aborter?.signal.aborted ?? false) return;
|
|
5529
|
-
if (!complete && status === "rejected") {
|
|
5530
|
-
settlePromise(handlers.reject, value, aborter);
|
|
5531
|
-
return;
|
|
5532
|
-
}
|
|
5533
|
-
data.result[index] = !complete ? value : status === "fulfilled" ? {
|
|
5534
|
-
status,
|
|
5535
|
-
value
|
|
5536
|
-
} : {
|
|
5537
|
-
status,
|
|
5538
|
-
reason: value
|
|
5539
|
-
};
|
|
5540
|
-
if (index === data.last) settlePromise(handlers.resolve, data.result, aborter);
|
|
5541
|
-
}
|
|
5542
|
-
function settlePromise(settler, value, aborter) {
|
|
5543
|
-
aborter?.cancel();
|
|
5544
|
-
settler(value);
|
|
5545
|
-
}
|
|
5546
|
-
async function toResult(value) {
|
|
5547
|
-
const actual = typeof value === "function" ? value() : value;
|
|
5548
|
-
if (!(actual instanceof Promise)) return Promise.reject(/* @__PURE__ */ new TypeError(PROMISE_MESSAGE_EXPECTATION_RESULT));
|
|
5549
|
-
return actual.then((result) => ok(result)).catch((reason) => error(reason));
|
|
5550
|
-
}
|
|
5551
|
-
//#endregion
|
|
5552
|
-
//#region src/promise/delay.ts
|
|
5553
|
-
function delay(options) {
|
|
5554
|
-
const { signal, time } = getPromiseOptions(options);
|
|
5555
|
-
if (signal?.aborted ?? false) return Promise.reject(signal?.reason);
|
|
5556
|
-
const aborter = createAborter(signal, () => {
|
|
5557
|
-
timer.cancel();
|
|
5558
|
-
rejector(signal?.reason);
|
|
5681
|
+
const instance = {};
|
|
5682
|
+
Object.defineProperties(instance, {
|
|
5683
|
+
[LOGGER_PROPERTY]: { value: LOGGER_NAME },
|
|
5684
|
+
enabled: {
|
|
5685
|
+
enumerable: true,
|
|
5686
|
+
get: () => enabled,
|
|
5687
|
+
set: (value) => {
|
|
5688
|
+
enabled = typeof value === "boolean" ? value : enabled;
|
|
5689
|
+
}
|
|
5690
|
+
},
|
|
5691
|
+
time: { value: (label) => timedLogger(getString(label)) }
|
|
5559
5692
|
});
|
|
5560
|
-
const
|
|
5561
|
-
|
|
5562
|
-
|
|
5563
|
-
|
|
5564
|
-
|
|
5565
|
-
resolver = resolve;
|
|
5566
|
-
if (time === 0) settlePromise(resolver, void 0, aborter);
|
|
5567
|
-
else timer();
|
|
5693
|
+
for (const method of methods) Object.defineProperty(instance, method, {
|
|
5694
|
+
enumerable: true,
|
|
5695
|
+
get() {
|
|
5696
|
+
return enabled ? console[method].bind(console) : noop;
|
|
5697
|
+
}
|
|
5568
5698
|
});
|
|
5569
|
-
|
|
5699
|
+
return Object.freeze(instance);
|
|
5700
|
+
})();
|
|
5701
|
+
let enabled = true;
|
|
5570
5702
|
//#endregion
|
|
5571
|
-
//#region src/
|
|
5572
|
-
|
|
5573
|
-
const
|
|
5574
|
-
|
|
5575
|
-
rejector(signal?.reason);
|
|
5576
|
-
});
|
|
5577
|
-
const timer = getTimer(TIMER_WAIT, () => settlePromise(rejector, new PromiseTimeoutError(), aborter), time);
|
|
5578
|
-
let rejector;
|
|
5579
|
-
return Promise.race([promise, new Promise((_, reject) => {
|
|
5580
|
-
rejector = reject;
|
|
5581
|
-
timer();
|
|
5582
|
-
})]).then((value) => {
|
|
5583
|
-
aborter?.cancel();
|
|
5584
|
-
timer.cancel();
|
|
5585
|
-
rejector(void 0);
|
|
5586
|
-
return value;
|
|
5587
|
-
});
|
|
5703
|
+
//#region src/math.ts
|
|
5704
|
+
function average(array, key) {
|
|
5705
|
+
const aggregated = aggregate(AGGREGATION_AVERAGE, array, key);
|
|
5706
|
+
return aggregated.count > 0 ? aggregated.value / aggregated.count : NaN;
|
|
5588
5707
|
}
|
|
5589
|
-
|
|
5590
|
-
|
|
5591
|
-
|
|
5592
|
-
|
|
5593
|
-
|
|
5708
|
+
/**
|
|
5709
|
+
* Round a number up
|
|
5710
|
+
*
|
|
5711
|
+
* @param value Number to round up
|
|
5712
|
+
* @param decimals Number of decimal places to round to _(defaults to `0`)_
|
|
5713
|
+
* @returns Rounded number, or `Number.NaN` if the value if unable to be rounded
|
|
5714
|
+
*/
|
|
5715
|
+
function ceil(value, decimals) {
|
|
5716
|
+
return roundNumber(Math.ceil, value, decimals);
|
|
5594
5717
|
}
|
|
5595
|
-
|
|
5596
|
-
|
|
5597
|
-
|
|
5598
|
-
const
|
|
5599
|
-
if (
|
|
5600
|
-
|
|
5601
|
-
|
|
5602
|
-
|
|
5603
|
-
|
|
5604
|
-
});
|
|
5605
|
-
async function handler(resolve, reject) {
|
|
5606
|
-
try {
|
|
5607
|
-
let result = isFunction ? value() : await value;
|
|
5608
|
-
if (result instanceof Promise) result = await result;
|
|
5609
|
-
settlePromise(resolve, result, aborter);
|
|
5610
|
-
} catch (error) {
|
|
5611
|
-
settlePromise(reject, error, aborter);
|
|
5612
|
-
}
|
|
5718
|
+
function count(array, key, value) {
|
|
5719
|
+
if (!Array.isArray(array)) return NaN;
|
|
5720
|
+
const { length } = array;
|
|
5721
|
+
const callback = getAggregateCallback(key);
|
|
5722
|
+
if (callback == null) return length;
|
|
5723
|
+
let counted = 0;
|
|
5724
|
+
for (let index = 0; index < length; index += 1) {
|
|
5725
|
+
const item = array[index];
|
|
5726
|
+
if (Object.is(callback(item, index, array), value)) counted += 1;
|
|
5613
5727
|
}
|
|
5614
|
-
|
|
5615
|
-
const promise = new Promise((resolve, reject) => {
|
|
5616
|
-
rejector = reject;
|
|
5617
|
-
handler(resolve, reject);
|
|
5618
|
-
});
|
|
5619
|
-
return time > 0 ? getTimedPromise(promise, time, signal) : promise;
|
|
5728
|
+
return counted;
|
|
5620
5729
|
}
|
|
5621
|
-
|
|
5622
|
-
|
|
5623
|
-
|
|
5624
|
-
|
|
5625
|
-
|
|
5626
|
-
|
|
5627
|
-
|
|
5628
|
-
|
|
5629
|
-
|
|
5630
|
-
handlers.reject(signal?.reason);
|
|
5631
|
-
});
|
|
5632
|
-
const data = {
|
|
5633
|
-
last: length - 1,
|
|
5634
|
-
result: []
|
|
5635
|
-
};
|
|
5636
|
-
let handlers;
|
|
5637
|
-
return new Promise((resolve, reject) => {
|
|
5638
|
-
handlers = {
|
|
5639
|
-
reject,
|
|
5640
|
-
resolve
|
|
5641
|
-
};
|
|
5642
|
-
for (let index = 0; index < length; index += 1) actual[index].then((value) => handleResult(PROMISE_TYPE_FULFILLED, {
|
|
5643
|
-
aborter,
|
|
5644
|
-
complete,
|
|
5645
|
-
data,
|
|
5646
|
-
handlers,
|
|
5647
|
-
index,
|
|
5648
|
-
value
|
|
5649
|
-
})).catch((reason) => handleResult(PROMISE_TYPE_REJECTED, {
|
|
5650
|
-
aborter,
|
|
5651
|
-
complete,
|
|
5652
|
-
data,
|
|
5653
|
-
handlers,
|
|
5654
|
-
index,
|
|
5655
|
-
value: reason
|
|
5656
|
-
}));
|
|
5657
|
-
});
|
|
5730
|
+
/**
|
|
5731
|
+
* Round a number down
|
|
5732
|
+
*
|
|
5733
|
+
* @param value Number to round down
|
|
5734
|
+
* @param decimals Number of decimal places to round to _(defaults to `0`)_
|
|
5735
|
+
* @returns Rounded number, or `Number.NaN` if the value if unable to be rounded
|
|
5736
|
+
*/
|
|
5737
|
+
function floor(value, decimals) {
|
|
5738
|
+
return roundNumber(Math.floor, value, decimals);
|
|
5658
5739
|
}
|
|
5659
|
-
|
|
5660
|
-
|
|
5661
|
-
|
|
5740
|
+
function median(array, key) {
|
|
5741
|
+
let length = Array.isArray(array) ? array.length : 0;
|
|
5742
|
+
if (!Array.isArray(array) || length === 0) return NaN;
|
|
5743
|
+
let values = array;
|
|
5744
|
+
const callback = getAggregateCallback(key);
|
|
5745
|
+
if (callback != null) values = array.map((item, index) => callback(item, index, array));
|
|
5746
|
+
const numbers = values.filter(isNumber).sort((first, second) => first - second);
|
|
5747
|
+
length = numbers.length;
|
|
5748
|
+
if (length === 1) return numbers[0];
|
|
5749
|
+
if (length % 2 === 0) {
|
|
5750
|
+
const first = length / 2 - 1;
|
|
5751
|
+
const second = length / 2;
|
|
5752
|
+
return (numbers[first] + numbers[second]) / 2;
|
|
5753
|
+
}
|
|
5754
|
+
return numbers[Math.floor(length / 2)];
|
|
5755
|
+
}
|
|
5756
|
+
function min(array, key) {
|
|
5757
|
+
return getAggregated("min", array, key);
|
|
5758
|
+
}
|
|
5759
|
+
function sum(array, key) {
|
|
5760
|
+
return getAggregated("sum", array, key);
|
|
5662
5761
|
}
|
|
5663
5762
|
//#endregion
|
|
5664
5763
|
//#region src/query.ts
|
|
@@ -5847,9 +5946,6 @@ function createQueue(callback, options, key) {
|
|
|
5847
5946
|
});
|
|
5848
5947
|
return Object.freeze(instance);
|
|
5849
5948
|
}
|
|
5850
|
-
function getBooleanOrDefault(value, defaultValue) {
|
|
5851
|
-
return typeof value === "boolean" ? value : defaultValue;
|
|
5852
|
-
}
|
|
5853
5949
|
function getOptions(input) {
|
|
5854
5950
|
const options = typeof input === "object" && input != null ? input : {};
|
|
5855
5951
|
return {
|
|
@@ -6125,92 +6221,6 @@ const RANDOM_BOOLEAN_MODIFIER = .5;
|
|
|
6125
6221
|
const RANDOM_HEX_CHARACTERS = "0123456789ABCDEF";
|
|
6126
6222
|
const RANDOM_HEX_MAXIMUM = 15;
|
|
6127
6223
|
//#endregion
|
|
6128
|
-
//#region src/result/index.ts
|
|
6129
|
-
async function asyncAttempt(value, err) {
|
|
6130
|
-
try {
|
|
6131
|
-
let result = typeof value === "function" ? value() : await value;
|
|
6132
|
-
if (result instanceof Promise) result = await result;
|
|
6133
|
-
return ok(result);
|
|
6134
|
-
} catch (thrown) {
|
|
6135
|
-
return getError(err ?? thrown, err == null ? void 0 : thrown);
|
|
6136
|
-
}
|
|
6137
|
-
}
|
|
6138
|
-
function attempt(callback, err) {
|
|
6139
|
-
try {
|
|
6140
|
-
return ok(callback());
|
|
6141
|
-
} catch (thrown) {
|
|
6142
|
-
return getError(err ?? thrown, err == null ? void 0 : thrown);
|
|
6143
|
-
}
|
|
6144
|
-
}
|
|
6145
|
-
Object.defineProperty(attempt, "async", { value: asyncAttempt });
|
|
6146
|
-
//#endregion
|
|
6147
|
-
//#region src/result/match.ts
|
|
6148
|
-
async function asyncMatchResult(result, first, error) {
|
|
6149
|
-
let value;
|
|
6150
|
-
if (typeof result === "function") value = await result();
|
|
6151
|
-
else if (result instanceof Promise) value = await result;
|
|
6152
|
-
else value = result;
|
|
6153
|
-
if (!isResult(value)) throw new Error(MATCH_MESSAGE);
|
|
6154
|
-
const hasObj = typeof first === "object" && first !== null;
|
|
6155
|
-
const okHandler = hasObj ? first.ok : first;
|
|
6156
|
-
const errorHandler = hasObj ? first.error : error;
|
|
6157
|
-
if (isOk(value)) return okHandler(value.value);
|
|
6158
|
-
return errorHandler(value.error, value.original);
|
|
6159
|
-
}
|
|
6160
|
-
function matchResult(result, first, error) {
|
|
6161
|
-
const value = typeof result === "function" ? result() : result;
|
|
6162
|
-
if (!isResult(value)) throw new Error(MATCH_MESSAGE);
|
|
6163
|
-
const hasObj = typeof first === "object" && first !== null;
|
|
6164
|
-
const okHandler = hasObj ? first.ok : first;
|
|
6165
|
-
const errorHandler = hasObj ? first.error : error;
|
|
6166
|
-
if (isOk(value)) return okHandler(value.value);
|
|
6167
|
-
return errorHandler(value.error, value.original);
|
|
6168
|
-
}
|
|
6169
|
-
const MATCH_MESSAGE = "`result.match` expected a Result or a function that returns a Result";
|
|
6170
|
-
Object.defineProperty(matchResult, "async", { value: asyncMatchResult });
|
|
6171
|
-
//#endregion
|
|
6172
|
-
//#region src/result/work/flow.ts
|
|
6173
|
-
function attemptAsyncFlow(...fns) {
|
|
6174
|
-
let Flow;
|
|
6175
|
-
return (...args) => asyncAttempt(() => {
|
|
6176
|
-
Flow ??= asyncFlow(...fns);
|
|
6177
|
-
return Flow(...args.map((value) => {
|
|
6178
|
-
if (isError(value)) throw value.error;
|
|
6179
|
-
return isOk(value) ? value.value : value;
|
|
6180
|
-
}));
|
|
6181
|
-
});
|
|
6182
|
-
}
|
|
6183
|
-
function attemptFlow(...fns) {
|
|
6184
|
-
let Flow;
|
|
6185
|
-
return (...args) => attempt(() => {
|
|
6186
|
-
Flow ??= flow(...fns);
|
|
6187
|
-
return Flow(...args.map((value) => {
|
|
6188
|
-
if (isError(value)) throw value.error;
|
|
6189
|
-
return isOk(value) ? value.value : value;
|
|
6190
|
-
}));
|
|
6191
|
-
});
|
|
6192
|
-
}
|
|
6193
|
-
Object.defineProperty(attemptFlow, "async", { value: attemptAsyncFlow });
|
|
6194
|
-
//#endregion
|
|
6195
|
-
//#region src/result/work/pipe.ts
|
|
6196
|
-
async function attemptAsyncPipe(initial, first, ...seconds) {
|
|
6197
|
-
return asyncAttempt(() => {
|
|
6198
|
-
if (isError(initial)) throw initial.error;
|
|
6199
|
-
const value = typeof initial === "function" ? initial() : isOk(initial) ? initial.value : initial;
|
|
6200
|
-
if (first == null) return value;
|
|
6201
|
-
return asyncPipe(value, ...[first, ...seconds]);
|
|
6202
|
-
});
|
|
6203
|
-
}
|
|
6204
|
-
function attemptPipe(initial, first, ...seconds) {
|
|
6205
|
-
return attempt(() => {
|
|
6206
|
-
if (isError(initial)) throw initial.error;
|
|
6207
|
-
const value = typeof initial === "function" ? initial() : isOk(initial) ? initial.value : initial;
|
|
6208
|
-
if (first == null) return value;
|
|
6209
|
-
return pipe(value, ...[first, ...seconds]);
|
|
6210
|
-
});
|
|
6211
|
-
}
|
|
6212
|
-
Object.defineProperty(attemptPipe, "async", { value: attemptAsyncPipe });
|
|
6213
|
-
//#endregion
|
|
6214
6224
|
//#region src/sized/set.ts
|
|
6215
6225
|
/**
|
|
6216
6226
|
* A _Set_ with a maximum size
|
|
@@ -6267,4 +6277,4 @@ var SizedSet = class extends Set {
|
|
|
6267
6277
|
}
|
|
6268
6278
|
};
|
|
6269
6279
|
//#endregion
|
|
6270
|
-
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,
|
|
6280
|
+
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 };
|