@oscarpalmer/atoms 0.194.0 → 0.195.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/array/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/once.mjs +1 -1
- package/dist/herald.d.mts +2 -71
- package/dist/herald.mjs +1 -109
- package/dist/index.d.mts +3270 -3271
- package/dist/index.mjs +1500 -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 +1 -1
- package/dist/result/index.mjs +1 -1
- package/dist/result/match.d.mts +1 -1
- package/dist/result/match.mjs +1 -1
- package/dist/result/misc.d.mts +3 -42
- package/dist/result/misc.mjs +2 -28
- package/dist/result/work/flow.d.mts +1 -1
- package/dist/result/work/flow.mjs +2 -2
- package/dist/result/work/pipe.d.mts +1 -1
- package/dist/result/work/pipe.mjs +2 -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,204 @@ 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
|
+
Object.defineProperty(debounce, "async", { value: asyncDebounce });
|
|
1532
|
+
Object.defineProperty(throttle, "async", { value: asyncThrottle });
|
|
1533
|
+
//#endregion
|
|
1534
|
+
//#region src/internal/result/misc.ts
|
|
1535
|
+
function error(value, original) {
|
|
1536
|
+
return getError(value, original);
|
|
1537
|
+
}
|
|
1538
|
+
function getError(value, original) {
|
|
1539
|
+
const errorResult = {
|
|
1540
|
+
error: value,
|
|
1541
|
+
ok: false
|
|
1542
|
+
};
|
|
1543
|
+
if (original instanceof Error) errorResult.original = original;
|
|
1544
|
+
return errorResult;
|
|
1545
|
+
}
|
|
1546
|
+
function isError(value, extended) {
|
|
1547
|
+
return isResultValue(value, false) && (extended === true ? value.original instanceof Error : true);
|
|
1548
|
+
}
|
|
1549
|
+
function isOk(value) {
|
|
1550
|
+
return isResultValue(value, true);
|
|
1551
|
+
}
|
|
1552
|
+
/**
|
|
1553
|
+
* Is the value a _Result_?
|
|
1554
|
+
*
|
|
1555
|
+
* @param value Value to check
|
|
1556
|
+
* @returns `true` if the value is a _Result_, otherwise `false`
|
|
1557
|
+
*/
|
|
1558
|
+
function isResult(value) {
|
|
1559
|
+
return isResultValue(value, true) || isResultValue(value, false);
|
|
1560
|
+
}
|
|
1561
|
+
function isResultValue(value, okValue) {
|
|
1562
|
+
if (isNonPlainObject(value)) return false;
|
|
1563
|
+
return value.ok === okValue && (okValue ? RESULT_PROPERTY_VALUE : RESULT_PROPERTY_ERROR) in value;
|
|
1564
|
+
}
|
|
1565
|
+
/**
|
|
1566
|
+
* Creates an ok result
|
|
1567
|
+
*
|
|
1568
|
+
* @param value Value
|
|
1569
|
+
* @returns Ok result
|
|
1570
|
+
*/
|
|
1571
|
+
function ok(value) {
|
|
1572
|
+
return {
|
|
1573
|
+
ok: true,
|
|
1574
|
+
value
|
|
1575
|
+
};
|
|
1443
1576
|
}
|
|
1444
1577
|
function unwrap(value, defaultValue) {
|
|
1445
1578
|
return isOk(value) ? value.value : defaultValue;
|
|
1446
1579
|
}
|
|
1447
|
-
const
|
|
1580
|
+
const RESULT_PROPERTY_ERROR = "error";
|
|
1581
|
+
const RESULT_PROPERTY_VALUE = "value";
|
|
1448
1582
|
//#endregion
|
|
1449
1583
|
//#region src/internal/value/misc.ts
|
|
1450
1584
|
function findKey(needle, haystack) {
|
|
@@ -1499,7 +1633,7 @@ function hasValueResult(data, path, ignoreCase) {
|
|
|
1499
1633
|
return getNestedValue(data, path, ignoreCase === true);
|
|
1500
1634
|
}
|
|
1501
1635
|
//#endregion
|
|
1502
|
-
//#region src/function/assert.ts
|
|
1636
|
+
//#region src/internal/function/assert.ts
|
|
1503
1637
|
/**
|
|
1504
1638
|
* Asserts that a condition is true, throwing an error if it is not
|
|
1505
1639
|
*
|
|
@@ -1593,51 +1727,309 @@ function assertProperty(path, condition, message, error) {
|
|
|
1593
1727
|
}
|
|
1594
1728
|
const ASSERT_MESSAGE_VALUE_DEFINED = "Expected value to be defined";
|
|
1595
1729
|
//#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
|
|
1730
|
+
//#region src/function/once.ts
|
|
1603
1731
|
/**
|
|
1604
|
-
*
|
|
1732
|
+
* Create an asynchronous function that can only be called once, rejecting or resolving the same result on subsequent calls
|
|
1605
1733
|
*
|
|
1606
|
-
*
|
|
1607
|
-
*
|
|
1608
|
-
* @param
|
|
1609
|
-
* @returns
|
|
1734
|
+
* _Available as `asyncOnce` and `once.async`_
|
|
1735
|
+
*
|
|
1736
|
+
* @param callback Callback to use once
|
|
1737
|
+
* @returns _Once_ callback
|
|
1610
1738
|
*/
|
|
1611
|
-
function
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1739
|
+
function asyncOnce(callback) {
|
|
1740
|
+
assert(() => typeof callback === "function", ONCE_MESSAGE_EXPECTATION);
|
|
1741
|
+
const state = {
|
|
1742
|
+
called: false,
|
|
1743
|
+
cleared: false,
|
|
1744
|
+
error: false,
|
|
1745
|
+
finished: false,
|
|
1746
|
+
items: [],
|
|
1747
|
+
value: void 0
|
|
1748
|
+
};
|
|
1749
|
+
const fn = (...parameters) => {
|
|
1750
|
+
if (state.cleared) return Promise.reject(new Error(ONCE_MESSAGE_CLEARED));
|
|
1751
|
+
if (state.finished) return state.error ? Promise.reject(state.value) : Promise.resolve(state.value);
|
|
1752
|
+
if (state.called) return new Promise((resolve, reject) => {
|
|
1753
|
+
state.items.push({
|
|
1754
|
+
reject,
|
|
1755
|
+
resolve
|
|
1756
|
+
});
|
|
1757
|
+
});
|
|
1758
|
+
state.called = true;
|
|
1759
|
+
return new Promise((resolve, reject) => {
|
|
1760
|
+
state.items.push({
|
|
1761
|
+
reject,
|
|
1762
|
+
resolve
|
|
1763
|
+
});
|
|
1764
|
+
callback(...parameters).then((value) => {
|
|
1765
|
+
handleOnceResult(state, value, false);
|
|
1766
|
+
}).catch((error) => {
|
|
1767
|
+
handleOnceResult(state, error, true);
|
|
1768
|
+
});
|
|
1769
|
+
});
|
|
1770
|
+
};
|
|
1771
|
+
Object.defineProperties(fn, {
|
|
1772
|
+
called: {
|
|
1773
|
+
enumerable: true,
|
|
1774
|
+
get: () => state.called
|
|
1775
|
+
},
|
|
1776
|
+
clear: { value: () => clearState(state) },
|
|
1777
|
+
cleared: {
|
|
1778
|
+
enumerable: true,
|
|
1779
|
+
get: () => state.cleared
|
|
1780
|
+
},
|
|
1781
|
+
error: {
|
|
1782
|
+
enumerable: true,
|
|
1783
|
+
get: () => state.error
|
|
1784
|
+
},
|
|
1785
|
+
finished: {
|
|
1786
|
+
enumerable: true,
|
|
1787
|
+
get: () => state.finished
|
|
1788
|
+
}
|
|
1789
|
+
});
|
|
1790
|
+
return fn;
|
|
1791
|
+
}
|
|
1792
|
+
function clearState(state) {
|
|
1793
|
+
if (!state.called || state.cleared) return;
|
|
1794
|
+
state.cleared = true;
|
|
1795
|
+
state.value = void 0;
|
|
1796
|
+
}
|
|
1797
|
+
function handleOnceResult(state, value, error) {
|
|
1798
|
+
state.error = error;
|
|
1799
|
+
state.finished = true;
|
|
1800
|
+
state.value = value;
|
|
1801
|
+
const items = state.items.splice(0);
|
|
1802
|
+
const { length } = items;
|
|
1803
|
+
for (let index = 0; index < length; index += 1) {
|
|
1804
|
+
const { reject, resolve } = items[index];
|
|
1805
|
+
if (error) reject(value);
|
|
1806
|
+
else resolve(value);
|
|
1807
|
+
}
|
|
1619
1808
|
}
|
|
1620
1809
|
/**
|
|
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
|
|
1810
|
+
* Create a function that can only be called once, returning the same value on subsequent calls
|
|
1628
1811
|
*
|
|
1629
|
-
* @
|
|
1630
|
-
*
|
|
1631
|
-
* clamp(10, 0, 5); // => 5
|
|
1632
|
-
* clamp(10, 0, 5, true); // => 0
|
|
1633
|
-
* ```
|
|
1812
|
+
* @param callback Callback to use once
|
|
1813
|
+
* @returns _Once_ callback
|
|
1634
1814
|
*/
|
|
1635
|
-
function
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1815
|
+
function once(callback) {
|
|
1816
|
+
assert(() => typeof callback === "function", ONCE_MESSAGE_EXPECTATION);
|
|
1817
|
+
const state = {
|
|
1818
|
+
called: false,
|
|
1819
|
+
cleared: false,
|
|
1820
|
+
value: void 0
|
|
1821
|
+
};
|
|
1822
|
+
const fn = (...parameters) => {
|
|
1823
|
+
if (state.cleared) throw new Error(ONCE_MESSAGE_CLEARED);
|
|
1824
|
+
if (state.called) return state.value;
|
|
1825
|
+
state.called = true;
|
|
1826
|
+
state.value = callback(...parameters);
|
|
1827
|
+
return state.value;
|
|
1828
|
+
};
|
|
1829
|
+
Object.defineProperties(fn, {
|
|
1830
|
+
called: {
|
|
1831
|
+
enumerable: true,
|
|
1832
|
+
get: () => state.called
|
|
1833
|
+
},
|
|
1834
|
+
clear: { value: () => clearState(state) },
|
|
1835
|
+
cleared: {
|
|
1836
|
+
enumerable: true,
|
|
1837
|
+
get: () => state.cleared
|
|
1838
|
+
}
|
|
1839
|
+
});
|
|
1840
|
+
return fn;
|
|
1841
|
+
}
|
|
1842
|
+
const ONCE_MESSAGE_CLEARED = "Once has been cleared";
|
|
1843
|
+
const ONCE_MESSAGE_EXPECTATION = "Once expected a function";
|
|
1844
|
+
Object.defineProperty(once, "async", { value: asyncOnce });
|
|
1845
|
+
//#endregion
|
|
1846
|
+
//#region src/function/retry.ts
|
|
1847
|
+
/**
|
|
1848
|
+
* An error thrown when a retry fails
|
|
1849
|
+
*/
|
|
1850
|
+
var RetryError = class extends Error {
|
|
1851
|
+
original;
|
|
1852
|
+
constructor(message, original) {
|
|
1853
|
+
super(message);
|
|
1854
|
+
this.original = original;
|
|
1855
|
+
this.name = RETRY_ERROR_NAME;
|
|
1856
|
+
}
|
|
1857
|
+
};
|
|
1858
|
+
/**
|
|
1859
|
+
* Retry a callback a specified number of times, with a delay between attempts
|
|
1860
|
+
*
|
|
1861
|
+
* _Available as `asyncRetry` and `retry.async`_
|
|
1862
|
+
*
|
|
1863
|
+
* @param callback Callback to retry
|
|
1864
|
+
* @param options Retry options
|
|
1865
|
+
* @returns Callback result
|
|
1866
|
+
*/
|
|
1867
|
+
async function asyncRetry(callback, options) {
|
|
1868
|
+
if (typeof callback !== "function") throw new TypeError(RETRY_MESSAGE_EXPECTATION);
|
|
1869
|
+
async function handle() {
|
|
1870
|
+
try {
|
|
1871
|
+
const result = await callback();
|
|
1872
|
+
resolver(result);
|
|
1873
|
+
} catch (error) {
|
|
1874
|
+
if (attempts >= times || !when(error)) rejector(new RetryError(RETRY_MESSAGE_FAILED, error));
|
|
1875
|
+
else {
|
|
1876
|
+
attempts += 1;
|
|
1877
|
+
timer();
|
|
1878
|
+
}
|
|
1879
|
+
}
|
|
1880
|
+
}
|
|
1881
|
+
const { delay, times, when } = getRetryOptions(options);
|
|
1882
|
+
const timer = getTimer(TIMER_WAIT, handle, delay);
|
|
1883
|
+
let attempts = 0;
|
|
1884
|
+
let rejector;
|
|
1885
|
+
let resolver;
|
|
1886
|
+
return new Promise((resolve, reject) => {
|
|
1887
|
+
rejector = reject;
|
|
1888
|
+
resolver = resolve;
|
|
1889
|
+
handle();
|
|
1890
|
+
});
|
|
1891
|
+
}
|
|
1892
|
+
function getRetryNumber(value) {
|
|
1893
|
+
return typeof value === "number" && value > 0 ? value : 0;
|
|
1894
|
+
}
|
|
1895
|
+
function getRetryOptions(input) {
|
|
1896
|
+
const options = isPlainObject(input) ? input : {};
|
|
1897
|
+
return {
|
|
1898
|
+
delay: getRetryNumber(options.delay),
|
|
1899
|
+
times: getRetryNumber(options.times),
|
|
1900
|
+
when: typeof options.when === "function" ? options.when : shouldRetry
|
|
1901
|
+
};
|
|
1902
|
+
}
|
|
1903
|
+
/**
|
|
1904
|
+
* Retry a callback a specified number of times
|
|
1905
|
+
*
|
|
1906
|
+
* @param callback Callback to retry
|
|
1907
|
+
* @param options Retry options
|
|
1908
|
+
* @returns Callback result
|
|
1909
|
+
*/
|
|
1910
|
+
function retry(callback, options) {
|
|
1911
|
+
if (typeof callback !== "function") throw new TypeError(RETRY_MESSAGE_EXPECTATION);
|
|
1912
|
+
const { times, when } = getRetryOptions(options);
|
|
1913
|
+
let last;
|
|
1914
|
+
for (let index = 0; index <= times; index += 1) try {
|
|
1915
|
+
return callback();
|
|
1916
|
+
} catch (error) {
|
|
1917
|
+
if (index >= times || !when(error)) {
|
|
1918
|
+
last = error;
|
|
1919
|
+
break;
|
|
1920
|
+
}
|
|
1921
|
+
}
|
|
1922
|
+
throw new RetryError(RETRY_MESSAGE_FAILED, last);
|
|
1923
|
+
}
|
|
1924
|
+
function shouldRetry() {
|
|
1925
|
+
return true;
|
|
1926
|
+
}
|
|
1927
|
+
const RETRY_ERROR_NAME = "RetryError";
|
|
1928
|
+
const RETRY_MESSAGE_EXPECTATION = "Retry expected a function";
|
|
1929
|
+
const RETRY_MESSAGE_FAILED = "Retry failed";
|
|
1930
|
+
Object.defineProperty(retry, "async", { value: asyncRetry });
|
|
1931
|
+
//#endregion
|
|
1932
|
+
//#region src/internal/function/work.ts
|
|
1933
|
+
function asyncFlow(...fns) {
|
|
1934
|
+
assertFlowFunctions(fns);
|
|
1935
|
+
return (...args) => asyncWork(args.map((value) => {
|
|
1936
|
+
if (isError(value)) throw value.error;
|
|
1937
|
+
return isOk(value) ? value.value : value;
|
|
1938
|
+
}), fns, true);
|
|
1939
|
+
}
|
|
1940
|
+
function flow(...fns) {
|
|
1941
|
+
assertFlowFunctions(fns);
|
|
1942
|
+
return (...args) => work(args.map((value) => {
|
|
1943
|
+
if (isError(value)) throw value.error;
|
|
1944
|
+
return isOk(value) ? value.value : value;
|
|
1945
|
+
}), fns, true);
|
|
1946
|
+
}
|
|
1947
|
+
async function asyncPipe(value, ...pipes) {
|
|
1948
|
+
assertPipeFunctions(pipes);
|
|
1949
|
+
return asyncWork(value, pipes, false);
|
|
1950
|
+
}
|
|
1951
|
+
function pipe(value, ...pipes) {
|
|
1952
|
+
assertPipeFunctions(pipes);
|
|
1953
|
+
return work(value, pipes, false);
|
|
1954
|
+
}
|
|
1955
|
+
async function asyncWork(initial, functions, flow) {
|
|
1956
|
+
const { length } = functions;
|
|
1957
|
+
let transformed = unwrapValue(initial);
|
|
1958
|
+
for (let index = 0; index < length; index += 1) {
|
|
1959
|
+
const fn = functions[index];
|
|
1960
|
+
transformed = unwrapValue(flow && index === 0 && Array.isArray(initial) ? await fn(...initial) : await fn(transformed));
|
|
1961
|
+
}
|
|
1962
|
+
return transformed;
|
|
1963
|
+
}
|
|
1964
|
+
function unwrapValue(value, flow, nested) {
|
|
1965
|
+
if (typeof value === "function") {
|
|
1966
|
+
if (nested != null) throw new TypeError(WORK_MESSAGE_NESTING);
|
|
1967
|
+
return unwrapValue(value(), flow, true);
|
|
1968
|
+
}
|
|
1969
|
+
if (flow != null && value instanceof Promise) throw new TypeError(flow ? WORK_MESSAGE_FLOW_PROMISE : WORK_MESSAGE_PIPE_PROMISE);
|
|
1970
|
+
if (isError(value)) throw value.error;
|
|
1971
|
+
return isOk(value) ? value.value : value;
|
|
1972
|
+
}
|
|
1973
|
+
function work(initial, functions, flow) {
|
|
1974
|
+
const { length } = functions;
|
|
1975
|
+
let transformed = unwrapValue(initial, flow);
|
|
1976
|
+
for (let index = 0; index < length; index += 1) {
|
|
1977
|
+
const fn = functions[index];
|
|
1978
|
+
transformed = unwrapValue(flow && index === 0 && Array.isArray(initial) ? fn(...initial) : fn(transformed), flow);
|
|
1979
|
+
}
|
|
1980
|
+
return transformed;
|
|
1981
|
+
}
|
|
1982
|
+
const WORK_MESSAGE_FLOW_ARRAY = "Flow expected to receive an array of functions";
|
|
1983
|
+
const WORK_MESSAGE_FLOW_PROMISE = "Synchronous Flow received a promise. Use `flow.async` instead.";
|
|
1984
|
+
const WORK_MESSAGE_NESTING = "Return values are too deeply nested.";
|
|
1985
|
+
const WORK_MESSAGE_PIPE_ARRAY = "Pipe expected to receive an array of functions";
|
|
1986
|
+
const WORK_MESSAGE_PIPE_PROMISE = "Synchronous Pipe received a promise. Use `pipe.async` instead.";
|
|
1987
|
+
const assertFlowFunctions = assert.condition((value) => Array.isArray(value) && value.every((item) => typeof item === "function"), WORK_MESSAGE_FLOW_ARRAY, TypeError);
|
|
1988
|
+
const assertPipeFunctions = assert.condition((value) => Array.isArray(value) && value.every((item) => typeof item === "function"), WORK_MESSAGE_PIPE_ARRAY, TypeError);
|
|
1989
|
+
flow.async = asyncFlow;
|
|
1990
|
+
pipe.async = asyncPipe;
|
|
1991
|
+
Object.defineProperty(flow, "async", { value: asyncFlow });
|
|
1992
|
+
Object.defineProperty(pipe, "async", { value: asyncPipe });
|
|
1993
|
+
//#endregion
|
|
1994
|
+
//#region src/internal/number.ts
|
|
1995
|
+
/**
|
|
1996
|
+
* Is the number between a minimum and maximum value?
|
|
1997
|
+
*
|
|
1998
|
+
* @param value Value to check
|
|
1999
|
+
* @param minimum Minimum value
|
|
2000
|
+
* @param maximum Maximum value
|
|
2001
|
+
* @returns `true` if the value is between the minimum and maximum, otherwise `false`
|
|
2002
|
+
*/
|
|
2003
|
+
function between(value, minimum, maximum) {
|
|
2004
|
+
if (![
|
|
2005
|
+
value,
|
|
2006
|
+
minimum,
|
|
2007
|
+
maximum
|
|
2008
|
+
].every(isNumber)) return false;
|
|
2009
|
+
if (Object.is(minimum, maximum)) return Object.is(value, minimum);
|
|
2010
|
+
return value >= (maximum > minimum ? minimum : maximum) && value <= (maximum > minimum ? maximum : minimum);
|
|
2011
|
+
}
|
|
2012
|
+
/**
|
|
2013
|
+
* Clamp a number between a minimum and maximum value
|
|
2014
|
+
*
|
|
2015
|
+
* @param value Value to clamp
|
|
2016
|
+
* @param minimum Minimum value
|
|
2017
|
+
* @param maximum Maximum value
|
|
2018
|
+
* @param loop If `true`, the value will loop around when smaller than the minimum or larger than the maximum _(defaults to `false`)_
|
|
2019
|
+
* @returns Clamped value
|
|
2020
|
+
*
|
|
2021
|
+
* @example
|
|
2022
|
+
* ```typescript
|
|
2023
|
+
* clamp(10, 0, 5); // => 5
|
|
2024
|
+
* clamp(10, 0, 5, true); // => 0
|
|
2025
|
+
* ```
|
|
2026
|
+
*/
|
|
2027
|
+
function clamp(value, minimum, maximum, loop) {
|
|
2028
|
+
if (![
|
|
2029
|
+
value,
|
|
2030
|
+
minimum,
|
|
2031
|
+
maximum
|
|
2032
|
+
].every(isNumber)) return NaN;
|
|
1641
2033
|
if (value < minimum) return loop === true ? maximum : minimum;
|
|
1642
2034
|
return value > maximum ? loop === true ? minimum : maximum : value;
|
|
1643
2035
|
}
|
|
@@ -1664,15 +2056,12 @@ function getNumber(value) {
|
|
|
1664
2056
|
if (isBinary || NUMBER_EXPRESSION_OCTAL.test(trimmed)) return Number.parseInt(trimmed.slice(2), isBinary ? 2 : NUMBER_OCTAL_VALUE);
|
|
1665
2057
|
return Number(trimmed);
|
|
1666
2058
|
}
|
|
1667
|
-
function getNumberOrDefault(value, defaultValue, minimum) {
|
|
1668
|
-
return typeof value === "number" && !Number.isNaN(value) && value >= (minimum ?? 0) ? Math.floor(value) : defaultValue;
|
|
1669
|
-
}
|
|
1670
2059
|
const NUMBER_EXPRESSION_BINARY = /^0b[01]+$/i;
|
|
1671
2060
|
const NUMBER_EXPRESSION_OCTAL = /^0o[0-7]+$/i;
|
|
1672
2061
|
const NUMBER_EXPRESSION_ZEROISH = /^\s*0+\s*$/;
|
|
1673
2062
|
const NUMBER_OCTAL_VALUE = 8;
|
|
1674
2063
|
//#endregion
|
|
1675
|
-
//#region src/internal/sized.ts
|
|
2064
|
+
//#region src/internal/sized/misc.ts
|
|
1676
2065
|
function getSizedMaximum(first, second) {
|
|
1677
2066
|
let actual;
|
|
1678
2067
|
if (typeof first === "number") actual = first;
|
|
@@ -1682,7 +2071,7 @@ function getSizedMaximum(first, second) {
|
|
|
1682
2071
|
const SIZED_MAXIMUM_ABSOLUTE = 16777216;
|
|
1683
2072
|
const SIZED_MAXIMUM_DEFAULT = 1048576;
|
|
1684
2073
|
//#endregion
|
|
1685
|
-
//#region src/sized/map.ts
|
|
2074
|
+
//#region src/internal/sized/map.ts
|
|
1686
2075
|
/**
|
|
1687
2076
|
* A _Map_ with a maximum size
|
|
1688
2077
|
*
|
|
@@ -1736,7 +2125,7 @@ var SizedMap = class extends Map {
|
|
|
1736
2125
|
}
|
|
1737
2126
|
};
|
|
1738
2127
|
//#endregion
|
|
1739
|
-
//#region src/function/memoize.ts
|
|
2128
|
+
//#region src/internal/function/memoize.ts
|
|
1740
2129
|
function getMemoizationOptions(input) {
|
|
1741
2130
|
const { cacheKey, cacheSize } = isPlainObject(input) ? input : {};
|
|
1742
2131
|
return {
|
|
@@ -1789,1012 +2178,718 @@ const MEMOIZED_CACHE_SIZE_DEFAULT = 1024;
|
|
|
1789
2178
|
const MEMOIZED_CALLBACK = "Memoized requires a callback function";
|
|
1790
2179
|
const MEMOIZED_KEY_SEPARATOR = "_";
|
|
1791
2180
|
//#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
|
|
2181
|
+
//#region src/internal/string/case.ts
|
|
1881
2182
|
/**
|
|
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`_
|
|
2183
|
+
* Convert a string to camel case _(thisIsCamelCase)_
|
|
1888
2184
|
*
|
|
1889
|
-
* @param
|
|
1890
|
-
* @
|
|
1891
|
-
* @returns Debounced callback handler with a `cancel` method
|
|
2185
|
+
* @param value String to convert
|
|
2186
|
+
* @returns Camel-cased string
|
|
1892
2187
|
*/
|
|
1893
|
-
function
|
|
1894
|
-
return
|
|
2188
|
+
function camelCase(value) {
|
|
2189
|
+
return toCase(STRING_CASE_CAMEL, value, true, false);
|
|
1895
2190
|
}
|
|
1896
2191
|
/**
|
|
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`_
|
|
2192
|
+
* Capitalize the first letter of a string _(and lowercase the rest)_
|
|
1903
2193
|
*
|
|
1904
|
-
* @param
|
|
1905
|
-
* @
|
|
1906
|
-
* @returns Throttled callback handler with a `cancel` method
|
|
2194
|
+
* @param value String to capitalize
|
|
2195
|
+
* @returns Capitalized string
|
|
1907
2196
|
*/
|
|
1908
|
-
function
|
|
1909
|
-
|
|
2197
|
+
function capitalize(value) {
|
|
2198
|
+
if (typeof value !== "string" || value.length === 0) return "";
|
|
2199
|
+
memoizedCapitalize ??= memoize((v) => v.length === 1 ? v.toLocaleUpperCase() : `${v.charAt(0).toLocaleUpperCase()}${v.slice(1).toLocaleLowerCase()}`);
|
|
2200
|
+
return memoizedCapitalize.run(value);
|
|
1910
2201
|
}
|
|
1911
2202
|
/**
|
|
1912
|
-
*
|
|
2203
|
+
* Convert a string to kebab case _(this-is-kebab-case)_
|
|
1913
2204
|
*
|
|
1914
|
-
*
|
|
2205
|
+
* @param value String to convert
|
|
2206
|
+
* @returns Kebab-cased string
|
|
2207
|
+
*/
|
|
2208
|
+
function kebabCase(value) {
|
|
2209
|
+
return toCase(STRING_CASE_KEBAB, value, false, false);
|
|
2210
|
+
}
|
|
2211
|
+
/**
|
|
2212
|
+
* Convert a string to lower case
|
|
1915
2213
|
*
|
|
1916
|
-
* @param
|
|
1917
|
-
* @
|
|
1918
|
-
* @returns Debounced callback handler with a `cancel` method
|
|
2214
|
+
* @param value String to convert
|
|
2215
|
+
* @returns Lower-cased string
|
|
1919
2216
|
*/
|
|
1920
|
-
function
|
|
1921
|
-
|
|
2217
|
+
function lowerCase(value) {
|
|
2218
|
+
if (typeof value !== "string") return "";
|
|
2219
|
+
memoizedLowerCase ??= memoize((v) => v.toLocaleLowerCase());
|
|
2220
|
+
return memoizedLowerCase.run(value);
|
|
1922
2221
|
}
|
|
1923
2222
|
/**
|
|
1924
|
-
*
|
|
2223
|
+
* Convert a string to pascal case _(ThisIsPascalCase)_
|
|
1925
2224
|
*
|
|
1926
|
-
* @param
|
|
1927
|
-
* @
|
|
1928
|
-
* @returns Throttled callback handler with a `cancel` method
|
|
2225
|
+
* @param value String to convert
|
|
2226
|
+
* @returns Pascal-cased string
|
|
1929
2227
|
*/
|
|
1930
|
-
function
|
|
1931
|
-
return
|
|
2228
|
+
function pascalCase(value) {
|
|
2229
|
+
return toCase(STRING_CASE_PASCAL, value, true, true);
|
|
1932
2230
|
}
|
|
1933
|
-
Object.defineProperty(debounce, "async", { value: asyncDebounce });
|
|
1934
|
-
Object.defineProperty(throttle, "async", { value: asyncThrottle });
|
|
1935
|
-
//#endregion
|
|
1936
|
-
//#region src/function/once.ts
|
|
1937
2231
|
/**
|
|
1938
|
-
*
|
|
2232
|
+
* Convert a string to snake case _(this_is_snake_case)_
|
|
1939
2233
|
*
|
|
1940
|
-
*
|
|
2234
|
+
* @param value String to convert
|
|
2235
|
+
* @returns Snake-cased string
|
|
2236
|
+
*/
|
|
2237
|
+
function snakeCase(value) {
|
|
2238
|
+
return toCase(STRING_CASE_SNAKE, value, false, false);
|
|
2239
|
+
}
|
|
2240
|
+
/**
|
|
2241
|
+
* Convert a string to title case _(Capitalizing Every Word)_
|
|
1941
2242
|
*
|
|
1942
|
-
* @param
|
|
1943
|
-
* @returns
|
|
2243
|
+
* @param value String to convert
|
|
2244
|
+
* @returns Title-cased string
|
|
1944
2245
|
*/
|
|
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;
|
|
2246
|
+
function titleCase(value) {
|
|
2247
|
+
if (typeof value !== "string" || value.length === 0) return "";
|
|
2248
|
+
memoizedTitleCase ??= memoize((v) => v.length < 2 ? capitalize(v) : join(words(v).map(capitalize), " "));
|
|
2249
|
+
return memoizedTitleCase.run(value);
|
|
1997
2250
|
}
|
|
1998
|
-
function
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2251
|
+
function toCase(type, value, capitalizeAny, capitalizeFirst) {
|
|
2252
|
+
caseMemoizers[type] ??= memoize(toCaseCallback.bind({
|
|
2253
|
+
type,
|
|
2254
|
+
capitalizeAny,
|
|
2255
|
+
capitalizeFirst
|
|
2256
|
+
}));
|
|
2257
|
+
return caseMemoizers[type].run(value);
|
|
2002
2258
|
}
|
|
2003
|
-
function
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
const
|
|
2008
|
-
const
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2259
|
+
function toCaseCallback(value) {
|
|
2260
|
+
if (typeof value !== "string") return "";
|
|
2261
|
+
if (value.length < 1) return value;
|
|
2262
|
+
const { capitalizeAny, capitalizeFirst, type } = this;
|
|
2263
|
+
const parts = words(value);
|
|
2264
|
+
const partsLength = parts.length;
|
|
2265
|
+
const cased = [];
|
|
2266
|
+
for (let partIndex = 0; partIndex < partsLength; partIndex += 1) {
|
|
2267
|
+
const items = parts[partIndex].replace(STRING_EXPRESSION_ACRONYM, (full, one, two, three) => three === STRING_S ? full : `${one}-${two}${three}`).replace(STRING_EXPRESSION_CAMEL_CASE, STRING_REPLACEMENT_CAMEL_CASE).split("-");
|
|
2268
|
+
const itemsLength = items.length;
|
|
2269
|
+
const partResult = [];
|
|
2270
|
+
let itemCount = 0;
|
|
2271
|
+
for (let itemIndex = 0; itemIndex < itemsLength; itemIndex += 1) {
|
|
2272
|
+
const item = items[itemIndex];
|
|
2273
|
+
if (item.length === 0) continue;
|
|
2274
|
+
if (!capitalizeAny || itemCount === 0 && partIndex === 0 && !capitalizeFirst) partResult.push(item.toLocaleLowerCase());
|
|
2275
|
+
else partResult.push(capitalize(item));
|
|
2276
|
+
itemCount += 1;
|
|
2277
|
+
}
|
|
2278
|
+
cased.push(join(partResult, delimiters[type]));
|
|
2013
2279
|
}
|
|
2280
|
+
return join(cased, delimiters[type]);
|
|
2014
2281
|
}
|
|
2015
2282
|
/**
|
|
2016
|
-
*
|
|
2283
|
+
* Convert a string to upper case
|
|
2017
2284
|
*
|
|
2018
|
-
* @param
|
|
2019
|
-
* @returns
|
|
2285
|
+
* @param value String to convert
|
|
2286
|
+
* @returns Upper-cased string
|
|
2020
2287
|
*/
|
|
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;
|
|
2288
|
+
function upperCase(value) {
|
|
2289
|
+
if (typeof value !== "string" || value.length === 0) return "";
|
|
2290
|
+
memoizedUpperCase ??= memoize((v) => v.toLocaleUpperCase());
|
|
2291
|
+
return memoizedUpperCase.run(value);
|
|
2047
2292
|
}
|
|
2048
|
-
const
|
|
2049
|
-
const
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2293
|
+
const STRING_CASE_CAMEL = "camel";
|
|
2294
|
+
const STRING_CASE_KEBAB = "kebab";
|
|
2295
|
+
const STRING_CASE_PASCAL = "pascal";
|
|
2296
|
+
const STRING_CASE_SNAKE = "snake";
|
|
2297
|
+
const STRING_DELIMTER_EMPTY = "";
|
|
2298
|
+
const STRING_DELIMITER_HYPHEN = "-";
|
|
2299
|
+
const STRING_DELIMITER_UNDERSCORE = "_";
|
|
2300
|
+
const STRING_EXPRESSION_CAMEL_CASE = /(\p{Ll})(\p{Lu})/gu;
|
|
2301
|
+
const STRING_EXPRESSION_ACRONYM = /(\p{Lu}*)(\p{Lu})(\p{Ll}+)/gu;
|
|
2302
|
+
const STRING_REPLACEMENT_CAMEL_CASE = "$1-$2";
|
|
2303
|
+
const STRING_S = "s";
|
|
2304
|
+
const caseMemoizers = {};
|
|
2305
|
+
const delimiters = {
|
|
2306
|
+
[STRING_CASE_CAMEL]: STRING_DELIMTER_EMPTY,
|
|
2307
|
+
[STRING_CASE_KEBAB]: STRING_DELIMITER_HYPHEN,
|
|
2308
|
+
[STRING_CASE_PASCAL]: STRING_DELIMTER_EMPTY,
|
|
2309
|
+
[STRING_CASE_SNAKE]: STRING_DELIMITER_UNDERSCORE
|
|
2063
2310
|
};
|
|
2311
|
+
let memoizedCapitalize;
|
|
2312
|
+
let memoizedLowerCase;
|
|
2313
|
+
let memoizedTitleCase;
|
|
2314
|
+
let memoizedUpperCase;
|
|
2315
|
+
//#endregion
|
|
2316
|
+
//#region src/internal/value/equal.ts
|
|
2064
2317
|
/**
|
|
2065
|
-
*
|
|
2318
|
+
* Deregister a equality comparison handler for a specific class
|
|
2066
2319
|
*
|
|
2067
|
-
* _Available as `
|
|
2320
|
+
* _Available as `deregisterEqualizer` and `equal.deregister`_
|
|
2068
2321
|
*
|
|
2069
|
-
* @param
|
|
2070
|
-
* @param options Retry options
|
|
2071
|
-
* @returns Callback result
|
|
2322
|
+
* @param constructor Class constructor
|
|
2072
2323
|
*/
|
|
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
|
-
});
|
|
2324
|
+
function deregisterEqualizer(constructor) {
|
|
2325
|
+
equal.handlers.deregister(constructor);
|
|
2097
2326
|
}
|
|
2098
|
-
function
|
|
2099
|
-
|
|
2327
|
+
function filterKey(key, options) {
|
|
2328
|
+
if (typeof key !== "string") return true;
|
|
2329
|
+
if (options.ignoreExpressions.enabled && options.ignoreExpressions.values.some((expression) => expression.test(key))) return false;
|
|
2330
|
+
if (options.ignoreKeys.enabled && options.ignoreKeys.values.has(key)) return false;
|
|
2331
|
+
return true;
|
|
2100
2332
|
}
|
|
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
|
-
};
|
|
2333
|
+
function equal(first, second, options) {
|
|
2334
|
+
return equalValue(first, second, getEqualOptions(options));
|
|
2108
2335
|
}
|
|
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
|
-
}
|
|
2336
|
+
equal.handlers = getCompareHandlers(equal, { callback: Object.is });
|
|
2337
|
+
equal.deregister = deregisterEqualizer;
|
|
2338
|
+
equal.initialize = initializeEqualizer;
|
|
2339
|
+
equal.register = registerEqualizer;
|
|
2340
|
+
function equalArray(first, second, options) {
|
|
2341
|
+
const { length } = first;
|
|
2342
|
+
if (length !== second.length) return false;
|
|
2343
|
+
let offset = 0;
|
|
2344
|
+
if (length >= EQUAL_ARRAY_THRESHOLD) {
|
|
2345
|
+
offset = Math.round(length / EQUAL_ARRAY_PEEK_PERCENTAGE);
|
|
2346
|
+
offset = offset > EQUAL_ARRAY_THRESHOLD ? EQUAL_ARRAY_THRESHOLD : offset;
|
|
2347
|
+
for (let index = 0; index < offset; index += 1) if (!(equalValue(first[index], second[index], options) && equalValue(first[length - index - 1], second[length - index - 1], options))) return false;
|
|
2127
2348
|
}
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
function shouldRetry() {
|
|
2349
|
+
const end = length - offset;
|
|
2350
|
+
for (let index = offset; index < end; index += 1) if (!equalValue(first[index], second[index], options)) return false;
|
|
2131
2351
|
return true;
|
|
2132
2352
|
}
|
|
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);
|
|
2353
|
+
function equalArrayBuffer(first, second, options) {
|
|
2354
|
+
return first.byteLength === second.byteLength ? equalArray(new Uint8Array(first), new Uint8Array(second), options) : false;
|
|
2152
2355
|
}
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
return asyncWork(value, pipes, false);
|
|
2356
|
+
function equalDataView(first, second, options) {
|
|
2357
|
+
return first.byteOffset === second.byteOffset ? equalArrayBuffer(first.buffer, second.buffer, options) : false;
|
|
2156
2358
|
}
|
|
2157
|
-
function
|
|
2158
|
-
|
|
2159
|
-
|
|
2359
|
+
function equalMap(first, second, options) {
|
|
2360
|
+
const { size } = first;
|
|
2361
|
+
if (size !== second.size) return false;
|
|
2362
|
+
const firstKeys = [...first.keys()];
|
|
2363
|
+
for (let index = 0; index < size; index += 1) {
|
|
2364
|
+
const key = firstKeys[index];
|
|
2365
|
+
if (!second.has(key) || !equalValue(first.get(key), second.get(key), options)) return false;
|
|
2366
|
+
}
|
|
2367
|
+
return true;
|
|
2160
2368
|
}
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
let
|
|
2369
|
+
function equalPlainObject(first, second, options) {
|
|
2370
|
+
let firstKeys = [...Object.keys(first), ...Object.getOwnPropertySymbols(first)];
|
|
2371
|
+
let secondKeys = [...Object.keys(second), ...Object.getOwnPropertySymbols(second)];
|
|
2372
|
+
if (options.ignoreKeys.enabled || options.ignoreExpressions.enabled) {
|
|
2373
|
+
firstKeys = firstKeys.filter((key) => filterKey(key, options));
|
|
2374
|
+
secondKeys = secondKeys.filter((key) => filterKey(key, options));
|
|
2375
|
+
}
|
|
2376
|
+
const secondSet = secondKeys.length >= EQUAL_MINIMUM_LENGTH_FOR_SET ? new Set(secondKeys) : void 0;
|
|
2377
|
+
const { length } = firstKeys;
|
|
2378
|
+
if (length !== secondKeys.length) return false;
|
|
2164
2379
|
for (let index = 0; index < length; index += 1) {
|
|
2165
|
-
const
|
|
2166
|
-
|
|
2380
|
+
const key = firstKeys[index];
|
|
2381
|
+
if (!(secondSet?.has(key) ?? secondKeys.includes(key)) || !equalValue(first[key], second[key], options)) return false;
|
|
2167
2382
|
}
|
|
2168
|
-
return
|
|
2383
|
+
return true;
|
|
2169
2384
|
}
|
|
2170
|
-
function
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2385
|
+
function equalProperties(first, second, properties, options) {
|
|
2386
|
+
const { length } = properties;
|
|
2387
|
+
for (let index = 0; index < length; index += 1) {
|
|
2388
|
+
const property = properties[index];
|
|
2389
|
+
if (!equalValue(first[property], second[property], options)) return false;
|
|
2174
2390
|
}
|
|
2175
|
-
|
|
2176
|
-
if (isError(value)) throw value.error;
|
|
2177
|
-
return isOk(value) ? value.value : value;
|
|
2391
|
+
return true;
|
|
2178
2392
|
}
|
|
2179
|
-
function
|
|
2180
|
-
const {
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2393
|
+
function equalSet(first, second, options) {
|
|
2394
|
+
const { size } = first;
|
|
2395
|
+
if (size !== second.size) return false;
|
|
2396
|
+
const firstValues = [...first];
|
|
2397
|
+
const secondValues = [...second];
|
|
2398
|
+
for (let index = 0; index < size; index += 1) {
|
|
2399
|
+
const firstValue = firstValues[index];
|
|
2400
|
+
if (isPrimitive(firstValue) ? !second.has(firstValue) : !secondValues.some((secondValue) => equalValue(firstValue, secondValue, options))) return false;
|
|
2185
2401
|
}
|
|
2186
|
-
return
|
|
2402
|
+
return true;
|
|
2187
2403
|
}
|
|
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
|
-
};
|
|
2404
|
+
function equalTypedArray(first, second) {
|
|
2405
|
+
if (first.constructor !== second.constructor) return false;
|
|
2406
|
+
if (first.byteLength !== second.byteLength) return false;
|
|
2407
|
+
const { length } = first;
|
|
2408
|
+
for (let index = 0; index < length; index += 1) if (first[index] !== second[index]) return false;
|
|
2409
|
+
return true;
|
|
2209
2410
|
}
|
|
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);
|
|
2411
|
+
function equalValue(first, second, options) {
|
|
2412
|
+
if (options.relaxedNullish && first == null && second == null) return true;
|
|
2413
|
+
switch (true) {
|
|
2414
|
+
case Object.is(first, second): return true;
|
|
2415
|
+
case first == null || second == null: return first === second;
|
|
2416
|
+
case typeof first !== typeof second: return false;
|
|
2417
|
+
case typeof first === "string" && options.ignoreCase === true: return Object.is(first.toLocaleLowerCase(), second.toLocaleLowerCase());
|
|
2418
|
+
case first instanceof ArrayBuffer && second instanceof ArrayBuffer: return equalArrayBuffer(first, second, options);
|
|
2419
|
+
case first instanceof Date && second instanceof Date: return Object.is(first.getTime(), second.getTime());
|
|
2420
|
+
case first instanceof DataView && second instanceof DataView: return equalDataView(first, second, options);
|
|
2421
|
+
case first instanceof Error && second instanceof Error: return equalProperties(first, second, EQUAL_ERROR_PROPERTIES, options);
|
|
2422
|
+
case first instanceof Map && second instanceof Map: return equalMap(first, second, options);
|
|
2423
|
+
case first instanceof RegExp && second instanceof RegExp: return equalProperties(first, second, EQUAL_EXPRESSION_PROPERTIES, options);
|
|
2424
|
+
case first instanceof Set && second instanceof Set: return equalSet(first, second, options);
|
|
2425
|
+
case Array.isArray(first) && Array.isArray(second): return equalArray(first, second, options);
|
|
2426
|
+
case isPlainObject(first) && isPlainObject(second): return equalPlainObject(first, second, options);
|
|
2427
|
+
case isTypedArray(first) && isTypedArray(second): return equalTypedArray(first, second);
|
|
2428
|
+
default: return equal.handlers.handle(first, second, options);
|
|
2243
2429
|
}
|
|
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
2430
|
}
|
|
2272
|
-
function
|
|
2273
|
-
const
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
keyed: keys == null ? void 0 : /* @__PURE__ */ new Map()
|
|
2431
|
+
function getEqualOptions(input) {
|
|
2432
|
+
const options = {
|
|
2433
|
+
ignoreCase: false,
|
|
2434
|
+
ignoreExpressions: {
|
|
2435
|
+
enabled: false,
|
|
2436
|
+
values: []
|
|
2279
2437
|
},
|
|
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)
|
|
2438
|
+
ignoreKeys: {
|
|
2439
|
+
enabled: false,
|
|
2440
|
+
values: /* @__PURE__ */ new Set()
|
|
2441
|
+
},
|
|
2442
|
+
relaxedNullish: false
|
|
2295
2443
|
};
|
|
2296
|
-
|
|
2444
|
+
if (typeof input === "boolean") {
|
|
2445
|
+
options.ignoreCase = input;
|
|
2446
|
+
return options;
|
|
2447
|
+
}
|
|
2448
|
+
if (isNonPlainObject(input)) return options;
|
|
2449
|
+
options.ignoreCase = typeof input.ignoreCase === "boolean" ? input.ignoreCase : false;
|
|
2450
|
+
options.ignoreExpressions.values = (Array.isArray(input.ignoreKeys) ? input.ignoreKeys : [input.ignoreKeys]).filter((key) => key instanceof RegExp);
|
|
2451
|
+
options.ignoreKeys.values = new Set((Array.isArray(input.ignoreKeys) ? input.ignoreKeys : [input.ignoreKeys]).filter((key) => typeof key === "string"));
|
|
2452
|
+
options.ignoreExpressions.enabled = options.ignoreExpressions.values.length > 0;
|
|
2453
|
+
options.ignoreKeys.enabled = options.ignoreKeys.values.size > 0;
|
|
2454
|
+
options.relaxedNullish = input.relaxedNullish === true;
|
|
2455
|
+
return options;
|
|
2297
2456
|
}
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2457
|
+
/**
|
|
2458
|
+
* Create an equalizer with predefined options
|
|
2459
|
+
*
|
|
2460
|
+
* _Available as `initializeEqualizer` and `equal.initialize`_
|
|
2461
|
+
*
|
|
2462
|
+
* @param options Comparison options
|
|
2463
|
+
* @returns Equalizer function
|
|
2464
|
+
*/
|
|
2465
|
+
function initializeEqualizer(options) {
|
|
2466
|
+
const actual = getEqualOptions(options);
|
|
2467
|
+
const equalizer = (first, second) => equalValue(first, second, actual);
|
|
2468
|
+
equalizer.deregister = deregisterEqualizer;
|
|
2469
|
+
equalizer.register = registerEqualizer;
|
|
2470
|
+
return equalizer;
|
|
2302
2471
|
}
|
|
2303
2472
|
/**
|
|
2304
|
-
*
|
|
2473
|
+
* Register a equality comparison function for a specific class
|
|
2305
2474
|
*
|
|
2306
|
-
*
|
|
2307
|
-
*
|
|
2475
|
+
* _Available as `registerEqualizer` and `equal.register`_
|
|
2476
|
+
*
|
|
2477
|
+
* @param constructor Class constructor
|
|
2478
|
+
* @param handler Comparison function
|
|
2308
2479
|
*/
|
|
2309
|
-
function
|
|
2310
|
-
|
|
2480
|
+
function registerEqualizer(constructor, handler) {
|
|
2481
|
+
equal.handlers.register(constructor, handler);
|
|
2311
2482
|
}
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2483
|
+
const EQUAL_ARRAY_PEEK_PERCENTAGE = 10;
|
|
2484
|
+
const EQUAL_ARRAY_THRESHOLD = 100;
|
|
2485
|
+
const EQUAL_ERROR_PROPERTIES = ["name", "message"];
|
|
2486
|
+
const EQUAL_EXPRESSION_PROPERTIES = ["source", "flags"];
|
|
2487
|
+
const EQUAL_MINIMUM_LENGTH_FOR_SET = 16;
|
|
2488
|
+
//#endregion
|
|
2489
|
+
//#region src/internal/value/get.ts
|
|
2490
|
+
function getValue(data, path, ignoreCase) {
|
|
2491
|
+
return getNestedValue(data, path, ignoreCase === true).value;
|
|
2321
2492
|
}
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
removeFromStore(items.any, values, subscription, value);
|
|
2332
|
-
return;
|
|
2493
|
+
//#endregion
|
|
2494
|
+
//#region src/internal/value/set.ts
|
|
2495
|
+
function setValue(data, path, value, ignoreCase) {
|
|
2496
|
+
if (typeof data !== "object" || data === null || typeof path !== "string" || path.trim().length === 0) return data;
|
|
2497
|
+
const shouldIgnoreCase = ignoreCase === true;
|
|
2498
|
+
const paths = getPaths(path, shouldIgnoreCase);
|
|
2499
|
+
if (typeof paths === "string") {
|
|
2500
|
+
handleValue(data, paths, value, false, shouldIgnoreCase);
|
|
2501
|
+
return data;
|
|
2333
2502
|
}
|
|
2334
|
-
const
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2503
|
+
const { length } = paths;
|
|
2504
|
+
const lastIndex = length - 1;
|
|
2505
|
+
let target = data;
|
|
2506
|
+
for (let index = 0; index < length; index += 1) {
|
|
2507
|
+
const currentPath = paths[index];
|
|
2508
|
+
if (index === lastIndex) {
|
|
2509
|
+
handleValue(target, currentPath, value, false, shouldIgnoreCase);
|
|
2510
|
+
break;
|
|
2511
|
+
}
|
|
2512
|
+
let next = handleValue(target, currentPath, null, true, shouldIgnoreCase).value;
|
|
2513
|
+
if (typeof next !== "object" || next === null) {
|
|
2514
|
+
const nextPath = paths[index + 1];
|
|
2515
|
+
if (SET_EXPRESSION_INDEX.test(nextPath)) next = Array.from({ length: Number(nextPath) + 1 }, () => void 0);
|
|
2516
|
+
else next = {};
|
|
2517
|
+
target[currentPath] = next;
|
|
2518
|
+
}
|
|
2519
|
+
target = next;
|
|
2520
|
+
}
|
|
2521
|
+
return data;
|
|
2345
2522
|
}
|
|
2346
|
-
const
|
|
2347
|
-
const SUBSCRIPTION_PROPERTY = "$subscription";
|
|
2523
|
+
const SET_EXPRESSION_INDEX = /^\d+$/;
|
|
2348
2524
|
//#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);
|
|
2525
|
+
//#region src/internal/abort.ts
|
|
2526
|
+
function createAborter(value, onAbort) {
|
|
2527
|
+
if (!(value instanceof AbortSignal)) return;
|
|
2528
|
+
value.addEventListener(ABORT_EVENT, onAbort, ABORT_OPTIONS);
|
|
2365
2529
|
return {
|
|
2366
|
-
|
|
2367
|
-
|
|
2530
|
+
callback: onAbort,
|
|
2531
|
+
signal: value,
|
|
2532
|
+
cancel: () => value.removeEventListener(ABORT_EVENT, onAbort)
|
|
2368
2533
|
};
|
|
2369
2534
|
}
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
return
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
property: getHeraldSubscriptionProperty(options.property)
|
|
2380
|
-
}),
|
|
2381
|
-
onCreate: options.onCreate
|
|
2382
|
-
};
|
|
2535
|
+
const ABORT_EVENT = "abort";
|
|
2536
|
+
const ABORT_OPTIONS = { once: true };
|
|
2537
|
+
//#endregion
|
|
2538
|
+
//#region src/internal/defaults.ts
|
|
2539
|
+
function getBooleanOrDefault(value, defaultValue) {
|
|
2540
|
+
return typeof value === "boolean" ? value : defaultValue;
|
|
2541
|
+
}
|
|
2542
|
+
function getNumberOrDefault(value, defaultValue, minimum) {
|
|
2543
|
+
return typeof value === "number" && !Number.isNaN(value) && value >= (minimum ?? 0) ? value : defaultValue;
|
|
2383
2544
|
}
|
|
2545
|
+
//#endregion
|
|
2546
|
+
//#region src/promise/constants.ts
|
|
2547
|
+
const PROMISE_ERROR_NAME = "PromiseTimeoutError";
|
|
2548
|
+
const PROMISE_MESSAGE_EXPECTATION_ATTEMPT = "Attempt expected a function or a promise";
|
|
2549
|
+
const PROMISE_MESSAGE_EXPECTATION_RESULT = "toResult expected a Promise";
|
|
2550
|
+
const PROMISE_MESSAGE_EXPECTATION_TIMED = "Timed function expected a Promise";
|
|
2551
|
+
const PROMISE_MESSAGE_TIMEOUT = "Promise timed out";
|
|
2552
|
+
const PROMISE_STRATEGY_ALL = /* @__PURE__ */ new Set(["complete", "first"]);
|
|
2553
|
+
const PROMISE_STRATEGY_DEFAULT = "complete";
|
|
2554
|
+
const PROMISE_TYPE_FULFILLED = "fulfilled";
|
|
2555
|
+
const PROMISE_TYPE_REJECTED = "rejected";
|
|
2556
|
+
//#endregion
|
|
2557
|
+
//#region src/promise/models.ts
|
|
2384
2558
|
/**
|
|
2385
|
-
*
|
|
2386
|
-
*
|
|
2387
|
-
* @param names Event names
|
|
2388
|
-
* @param property Optional property for subscription identification _(defaults to `$herald`)_
|
|
2389
|
-
* @returns _Herald_ instance
|
|
2559
|
+
* A _Promise_ that can be canceled
|
|
2390
2560
|
*/
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2561
|
+
var CancelablePromise = class extends Promise {
|
|
2562
|
+
#rejector;
|
|
2563
|
+
constructor(executor) {
|
|
2564
|
+
let rejector;
|
|
2565
|
+
super((resolve, reject) => {
|
|
2566
|
+
rejector = reject;
|
|
2567
|
+
executor(resolve, reject);
|
|
2568
|
+
});
|
|
2569
|
+
this.#rejector = rejector;
|
|
2570
|
+
}
|
|
2571
|
+
/**
|
|
2572
|
+
* Cancel the _Promise_, rejecting it with an optional reason
|
|
2573
|
+
*
|
|
2574
|
+
* @param reason Optional reason for canceling the _Promise_
|
|
2575
|
+
*/
|
|
2576
|
+
cancel(reason) {
|
|
2577
|
+
this.#rejector?.(reason);
|
|
2578
|
+
this.#rejector = void 0;
|
|
2579
|
+
}
|
|
2580
|
+
};
|
|
2581
|
+
/**
|
|
2582
|
+
* An error thrown when a promise times out
|
|
2583
|
+
*/
|
|
2584
|
+
var PromiseTimeoutError = class extends Error {
|
|
2585
|
+
constructor() {
|
|
2586
|
+
super(PROMISE_MESSAGE_TIMEOUT);
|
|
2587
|
+
this.name = PROMISE_ERROR_NAME;
|
|
2588
|
+
}
|
|
2589
|
+
};
|
|
2590
|
+
//#endregion
|
|
2591
|
+
//#region src/promise/helpers.ts
|
|
2592
|
+
function getPromiseOptions(input) {
|
|
2593
|
+
if (typeof input === "number") return { time: getNumberOrDefault(input, 0) };
|
|
2594
|
+
if (input instanceof AbortSignal) return {
|
|
2595
|
+
signal: input,
|
|
2596
|
+
time: 0
|
|
2398
2597
|
};
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
return
|
|
2598
|
+
const options = typeof input === "object" && input !== null ? input : {};
|
|
2599
|
+
return {
|
|
2600
|
+
signal: options.signal instanceof AbortSignal ? options.signal : void 0,
|
|
2601
|
+
time: getNumberOrDefault(options.time, 0)
|
|
2602
|
+
};
|
|
2603
|
+
}
|
|
2604
|
+
function getPromisesOptions(input) {
|
|
2605
|
+
if (typeof input === "string") return { strategy: getStrategyOrDefault(input) };
|
|
2606
|
+
if (input instanceof AbortSignal) return {
|
|
2607
|
+
signal: input,
|
|
2608
|
+
strategy: PROMISE_STRATEGY_DEFAULT
|
|
2609
|
+
};
|
|
2610
|
+
const options = typeof input === "object" && input !== null ? input : {};
|
|
2611
|
+
return {
|
|
2612
|
+
signal: options.signal instanceof AbortSignal ? options.signal : void 0,
|
|
2613
|
+
strategy: getStrategyOrDefault(options.strategy)
|
|
2614
|
+
};
|
|
2615
|
+
}
|
|
2616
|
+
function getResultsFromPromises(promised) {
|
|
2617
|
+
return promised.map((result) => isFulfilled(result) ? ok(result.value) : error(result.reason));
|
|
2618
|
+
}
|
|
2619
|
+
function getStrategyOrDefault(value) {
|
|
2620
|
+
return PROMISE_STRATEGY_ALL.has(value) ? value : PROMISE_STRATEGY_DEFAULT;
|
|
2407
2621
|
}
|
|
2408
2622
|
/**
|
|
2409
|
-
* Is the value
|
|
2623
|
+
* Is the value a fulfilled _Promise_ result?
|
|
2410
2624
|
*
|
|
2411
2625
|
* @param value Value to check
|
|
2412
|
-
* @returns `true` if the value is
|
|
2626
|
+
* @returns `true` if the value is a fulfilled _Promise_ result, otherwise `false`
|
|
2413
2627
|
*/
|
|
2414
|
-
function
|
|
2415
|
-
return
|
|
2628
|
+
function isFulfilled(value) {
|
|
2629
|
+
return isType(value, PROMISE_TYPE_FULFILLED);
|
|
2416
2630
|
}
|
|
2417
2631
|
/**
|
|
2418
|
-
* Is the value a
|
|
2632
|
+
* Is the value a rejected _Promise_ result?
|
|
2419
2633
|
*
|
|
2420
2634
|
* @param value Value to check
|
|
2421
|
-
* @returns `true` if the value is a
|
|
2635
|
+
* @returns `true` if the value is a rejected _Promise_ result, otherwise `false`
|
|
2422
2636
|
*/
|
|
2423
|
-
function
|
|
2424
|
-
return
|
|
2637
|
+
function isRejected(value) {
|
|
2638
|
+
return isType(value, PROMISE_TYPE_REJECTED);
|
|
2425
2639
|
}
|
|
2426
|
-
function
|
|
2427
|
-
return
|
|
2640
|
+
function isType(value, type) {
|
|
2641
|
+
return typeof value === "object" && value !== null && value.status === type;
|
|
2428
2642
|
}
|
|
2643
|
+
//#endregion
|
|
2644
|
+
//#region src/result/misc.ts
|
|
2429
2645
|
/**
|
|
2430
|
-
*
|
|
2646
|
+
* Converts a _Result_ to a _Promise_
|
|
2431
2647
|
*
|
|
2432
|
-
*
|
|
2433
|
-
*
|
|
2648
|
+
* Resolves if ok, rejects for error
|
|
2649
|
+
*
|
|
2650
|
+
* @param result _Result_ to convert
|
|
2651
|
+
* @returns Promised result
|
|
2434
2652
|
*/
|
|
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;
|
|
2653
|
+
async function toPromise(result) {
|
|
2654
|
+
const actual = typeof result === "function" ? result() : result;
|
|
2655
|
+
if (!isResult(actual)) return Promise.reject(new Error(RESULT_MESSAGE_PROMISE));
|
|
2656
|
+
return isOk(actual) ? Promise.resolve(actual.value) : Promise.reject(actual.error);
|
|
2446
2657
|
}
|
|
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 };
|
|
2658
|
+
const RESULT_MESSAGE_PROMISE = "toPromise expected to receive a Result";
|
|
2454
2659
|
//#endregion
|
|
2455
|
-
//#region src/
|
|
2660
|
+
//#region src/promise/misc.ts
|
|
2456
2661
|
/**
|
|
2457
|
-
*
|
|
2458
|
-
*
|
|
2459
|
-
* _Available as `deregisterEqualizer` and `equal.deregister`_
|
|
2662
|
+
* Create a cancelable _Promise_
|
|
2460
2663
|
*
|
|
2461
|
-
* @param
|
|
2664
|
+
* @param executor Executor function for the _Promise_
|
|
2665
|
+
* @returns Cancelable _Promise_
|
|
2462
2666
|
*/
|
|
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));
|
|
2667
|
+
function cancelable(executor) {
|
|
2668
|
+
return new CancelablePromise(executor);
|
|
2474
2669
|
}
|
|
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;
|
|
2670
|
+
function handleResult(status, parameters) {
|
|
2671
|
+
const { aborter, complete, data, handlers, index, value } = parameters;
|
|
2672
|
+
if (aborter?.signal.aborted ?? false) return;
|
|
2673
|
+
if (!complete && status === "rejected") {
|
|
2674
|
+
settlePromise(handlers.reject, value, aborter);
|
|
2675
|
+
return;
|
|
2487
2676
|
}
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2677
|
+
data.result[index] = !complete ? value : status === "fulfilled" ? {
|
|
2678
|
+
status,
|
|
2679
|
+
value
|
|
2680
|
+
} : {
|
|
2681
|
+
status,
|
|
2682
|
+
reason: value
|
|
2683
|
+
};
|
|
2684
|
+
if (index === data.last) settlePromise(handlers.resolve, data.result, aborter);
|
|
2491
2685
|
}
|
|
2492
|
-
function
|
|
2493
|
-
|
|
2686
|
+
function settlePromise(settler, value, aborter) {
|
|
2687
|
+
aborter?.cancel();
|
|
2688
|
+
settler(value);
|
|
2494
2689
|
}
|
|
2495
|
-
function
|
|
2496
|
-
|
|
2690
|
+
async function toResult(value) {
|
|
2691
|
+
const actual = typeof value === "function" ? value() : value;
|
|
2692
|
+
if (!(actual instanceof Promise)) return Promise.reject(/* @__PURE__ */ new TypeError(PROMISE_MESSAGE_EXPECTATION_RESULT));
|
|
2693
|
+
return actual.then((result) => ok(result)).catch((reason) => error(reason));
|
|
2497
2694
|
}
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
const
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2695
|
+
//#endregion
|
|
2696
|
+
//#region src/promise/delay.ts
|
|
2697
|
+
function delay(options) {
|
|
2698
|
+
const { signal, time } = getPromiseOptions(options);
|
|
2699
|
+
if (signal?.aborted ?? false) return Promise.reject(signal?.reason);
|
|
2700
|
+
const aborter = createAborter(signal, () => {
|
|
2701
|
+
timer.cancel();
|
|
2702
|
+
rejector(signal?.reason);
|
|
2703
|
+
});
|
|
2704
|
+
const timer = getTimer(TIMER_WAIT, () => settlePromise(resolver, void 0, aborter), time);
|
|
2705
|
+
let rejector;
|
|
2706
|
+
let resolver;
|
|
2707
|
+
return new Promise((resolve, reject) => {
|
|
2708
|
+
rejector = reject;
|
|
2709
|
+
resolver = resolve;
|
|
2710
|
+
if (time === 0) settlePromise(resolver, void 0, aborter);
|
|
2711
|
+
else timer();
|
|
2712
|
+
});
|
|
2507
2713
|
}
|
|
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;
|
|
2714
|
+
//#endregion
|
|
2715
|
+
//#region src/promise/timed.ts
|
|
2716
|
+
async function getTimedPromise(promise, time, signal) {
|
|
2717
|
+
const aborter = createAborter(signal, () => {
|
|
2718
|
+
timer.cancel();
|
|
2719
|
+
rejector(signal?.reason);
|
|
2720
|
+
});
|
|
2721
|
+
const timer = getTimer(TIMER_WAIT, () => settlePromise(rejector, new PromiseTimeoutError(), aborter), time);
|
|
2722
|
+
let rejector;
|
|
2723
|
+
return Promise.race([promise, new Promise((_, reject) => {
|
|
2724
|
+
rejector = reject;
|
|
2725
|
+
timer();
|
|
2726
|
+
})]).then((value) => {
|
|
2727
|
+
aborter?.cancel();
|
|
2728
|
+
timer.cancel();
|
|
2729
|
+
rejector(void 0);
|
|
2730
|
+
return value;
|
|
2731
|
+
});
|
|
2542
2732
|
}
|
|
2543
|
-
function
|
|
2544
|
-
if (
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
return true;
|
|
2733
|
+
async function timed(promise, options) {
|
|
2734
|
+
if (!(promise instanceof Promise)) return Promise.reject(/* @__PURE__ */ new TypeError(PROMISE_MESSAGE_EXPECTATION_TIMED));
|
|
2735
|
+
const { signal, time } = getPromiseOptions(options);
|
|
2736
|
+
if (signal?.aborted ?? false) return Promise.reject(signal?.reason);
|
|
2737
|
+
return time > 0 ? getTimedPromise(promise, time, signal) : promise;
|
|
2549
2738
|
}
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2739
|
+
//#endregion
|
|
2740
|
+
//#region src/promise/index.ts
|
|
2741
|
+
async function attemptPromise(value, options) {
|
|
2742
|
+
const isFunction = typeof value === "function";
|
|
2743
|
+
if (!isFunction && !(value instanceof Promise)) return Promise.reject(/* @__PURE__ */ new TypeError(PROMISE_MESSAGE_EXPECTATION_ATTEMPT));
|
|
2744
|
+
const { signal, time } = getPromiseOptions(options);
|
|
2745
|
+
if (signal?.aborted ?? false) return Promise.reject(signal?.reason);
|
|
2746
|
+
const aborter = createAborter(signal, () => {
|
|
2747
|
+
rejector(signal?.reason);
|
|
2748
|
+
});
|
|
2749
|
+
async function handler(resolve, reject) {
|
|
2750
|
+
try {
|
|
2751
|
+
let result = isFunction ? value() : await value;
|
|
2752
|
+
if (result instanceof Promise) result = await result;
|
|
2753
|
+
settlePromise(resolve, result, aborter);
|
|
2754
|
+
} catch (error) {
|
|
2755
|
+
settlePromise(reject, error, aborter);
|
|
2756
|
+
}
|
|
2568
2757
|
}
|
|
2758
|
+
let rejector;
|
|
2759
|
+
const promise = new Promise((resolve, reject) => {
|
|
2760
|
+
rejector = reject;
|
|
2761
|
+
handler(resolve, reject);
|
|
2762
|
+
});
|
|
2763
|
+
return time > 0 ? getTimedPromise(promise, time, signal) : promise;
|
|
2569
2764
|
}
|
|
2570
|
-
function
|
|
2571
|
-
const
|
|
2572
|
-
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
|
|
2765
|
+
async function promises(items, options) {
|
|
2766
|
+
const { signal, strategy } = getPromisesOptions(options);
|
|
2767
|
+
if (signal?.aborted ?? false) return Promise.reject(signal?.reason);
|
|
2768
|
+
if (!Array.isArray(items)) return Promise.resolve([]);
|
|
2769
|
+
const actual = items.map((item) => typeof item === "function" ? item() : item).filter((item) => item instanceof Promise);
|
|
2770
|
+
const { length } = actual;
|
|
2771
|
+
if (length === 0) return Promise.resolve([]);
|
|
2772
|
+
const complete = strategy === PROMISE_STRATEGY_DEFAULT;
|
|
2773
|
+
const aborter = createAborter(signal, () => {
|
|
2774
|
+
handlers.reject(signal?.reason);
|
|
2775
|
+
});
|
|
2776
|
+
const data = {
|
|
2777
|
+
last: length - 1,
|
|
2778
|
+
result: []
|
|
2582
2779
|
};
|
|
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);
|
|
2780
|
+
let handlers;
|
|
2781
|
+
return new Promise((resolve, reject) => {
|
|
2782
|
+
handlers = {
|
|
2783
|
+
reject,
|
|
2784
|
+
resolve
|
|
2785
|
+
};
|
|
2786
|
+
for (let index = 0; index < length; index += 1) actual[index].then((value) => handleResult(PROMISE_TYPE_FULFILLED, {
|
|
2787
|
+
aborter,
|
|
2788
|
+
complete,
|
|
2789
|
+
data,
|
|
2790
|
+
handlers,
|
|
2791
|
+
index,
|
|
2792
|
+
value
|
|
2793
|
+
})).catch((reason) => handleResult(PROMISE_TYPE_REJECTED, {
|
|
2794
|
+
aborter,
|
|
2795
|
+
complete,
|
|
2796
|
+
data,
|
|
2797
|
+
handlers,
|
|
2798
|
+
index,
|
|
2799
|
+
value: reason
|
|
2800
|
+
}));
|
|
2801
|
+
});
|
|
2621
2802
|
}
|
|
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;
|
|
2803
|
+
promises.result = resultPromises;
|
|
2804
|
+
async function resultPromises(items, signal) {
|
|
2805
|
+
return promises(items, signal).then(getResultsFromPromises);
|
|
2631
2806
|
}
|
|
2632
2807
|
//#endregion
|
|
2633
|
-
//#region src/
|
|
2634
|
-
function
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
return
|
|
2808
|
+
//#region src/result/index.ts
|
|
2809
|
+
async function asyncAttempt(value, err) {
|
|
2810
|
+
try {
|
|
2811
|
+
let result = typeof value === "function" ? value() : await value;
|
|
2812
|
+
if (result instanceof Promise) result = await result;
|
|
2813
|
+
return ok(result);
|
|
2814
|
+
} catch (thrown) {
|
|
2815
|
+
return getError(err ?? thrown, err == null ? void 0 : thrown);
|
|
2641
2816
|
}
|
|
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;
|
|
2817
|
+
}
|
|
2818
|
+
function attempt(callback, err) {
|
|
2819
|
+
try {
|
|
2820
|
+
return ok(callback());
|
|
2821
|
+
} catch (thrown) {
|
|
2822
|
+
return getError(err ?? thrown, err == null ? void 0 : thrown);
|
|
2659
2823
|
}
|
|
2660
|
-
return data;
|
|
2661
2824
|
}
|
|
2662
|
-
|
|
2825
|
+
Object.defineProperty(attempt, "async", { value: asyncAttempt });
|
|
2663
2826
|
//#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);
|
|
2827
|
+
//#region src/result/match.ts
|
|
2828
|
+
async function asyncMatchResult(result, first, error) {
|
|
2829
|
+
let value;
|
|
2830
|
+
if (typeof result === "function") value = await result();
|
|
2831
|
+
else if (result instanceof Promise) value = await result;
|
|
2832
|
+
else value = result;
|
|
2833
|
+
if (!isResult(value)) throw new Error(MATCH_MESSAGE);
|
|
2834
|
+
const hasObj = typeof first === "object" && first !== null;
|
|
2835
|
+
const okHandler = hasObj ? first.ok : first;
|
|
2836
|
+
const errorHandler = hasObj ? first.error : error;
|
|
2837
|
+
if (isOk(value)) return okHandler(value.value);
|
|
2838
|
+
return errorHandler(value.error, value.original);
|
|
2733
2839
|
}
|
|
2734
|
-
function
|
|
2735
|
-
|
|
2736
|
-
|
|
2737
|
-
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
return
|
|
2840
|
+
function matchResult(result, first, error) {
|
|
2841
|
+
const value = typeof result === "function" ? result() : result;
|
|
2842
|
+
if (!isResult(value)) throw new Error(MATCH_MESSAGE);
|
|
2843
|
+
const hasObj = typeof first === "object" && first !== null;
|
|
2844
|
+
const okHandler = hasObj ? first.ok : first;
|
|
2845
|
+
const errorHandler = hasObj ? first.error : error;
|
|
2846
|
+
if (isOk(value)) return okHandler(value.value);
|
|
2847
|
+
return errorHandler(value.error, value.original);
|
|
2741
2848
|
}
|
|
2742
|
-
function
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
const item = items[itemIndex];
|
|
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]);
|
|
2849
|
+
const MATCH_MESSAGE = "`result.match` expected a Result or a function that returns a Result";
|
|
2850
|
+
Object.defineProperty(matchResult, "async", { value: asyncMatchResult });
|
|
2851
|
+
//#endregion
|
|
2852
|
+
//#region src/result/work/flow.ts
|
|
2853
|
+
function attemptAsyncFlow(...fns) {
|
|
2854
|
+
let Flow;
|
|
2855
|
+
return (...args) => asyncAttempt(() => {
|
|
2856
|
+
Flow ??= asyncFlow(...fns);
|
|
2857
|
+
return Flow(...args.map((value) => {
|
|
2858
|
+
if (isError(value)) throw value.error;
|
|
2859
|
+
return isOk(value) ? value.value : value;
|
|
2860
|
+
}));
|
|
2861
|
+
});
|
|
2764
2862
|
}
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
return memoizedUpperCase.run(value);
|
|
2863
|
+
function attemptFlow(...fns) {
|
|
2864
|
+
let Flow;
|
|
2865
|
+
return (...args) => attempt(() => {
|
|
2866
|
+
Flow ??= flow(...fns);
|
|
2867
|
+
return Flow(...args.map((value) => {
|
|
2868
|
+
if (isError(value)) throw value.error;
|
|
2869
|
+
return isOk(value) ? value.value : value;
|
|
2870
|
+
}));
|
|
2871
|
+
});
|
|
2775
2872
|
}
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
const
|
|
2783
|
-
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
};
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
let memoizedTitleCase;
|
|
2797
|
-
let memoizedUpperCase;
|
|
2873
|
+
Object.defineProperty(attemptFlow, "async", { value: attemptAsyncFlow });
|
|
2874
|
+
//#endregion
|
|
2875
|
+
//#region src/result/work/pipe.ts
|
|
2876
|
+
async function attemptAsyncPipe(initial, first, ...seconds) {
|
|
2877
|
+
return asyncAttempt(() => {
|
|
2878
|
+
if (isError(initial)) throw initial.error;
|
|
2879
|
+
const value = typeof initial === "function" ? initial() : isOk(initial) ? initial.value : initial;
|
|
2880
|
+
if (first == null) return value;
|
|
2881
|
+
return asyncPipe(value, ...[first, ...seconds]);
|
|
2882
|
+
});
|
|
2883
|
+
}
|
|
2884
|
+
function attemptPipe(initial, first, ...seconds) {
|
|
2885
|
+
return attempt(() => {
|
|
2886
|
+
if (isError(initial)) throw initial.error;
|
|
2887
|
+
const value = typeof initial === "function" ? initial() : isOk(initial) ? initial.value : initial;
|
|
2888
|
+
if (first == null) return value;
|
|
2889
|
+
return pipe(value, ...[first, ...seconds]);
|
|
2890
|
+
});
|
|
2891
|
+
}
|
|
2892
|
+
Object.defineProperty(attemptPipe, "async", { value: attemptAsyncPipe });
|
|
2798
2893
|
//#endregion
|
|
2799
2894
|
//#region src/string/match.ts
|
|
2800
2895
|
/**
|
|
@@ -3856,6 +3951,142 @@ function transformValue(value, transformer) {
|
|
|
3856
3951
|
return value;
|
|
3857
3952
|
}
|
|
3858
3953
|
//#endregion
|
|
3954
|
+
//#region src/internal/subscription.ts
|
|
3955
|
+
function addSubscription(subscriptions, subscription, state) {
|
|
3956
|
+
const { key, value } = state.parameters;
|
|
3957
|
+
const { items, values } = subscriptions.state;
|
|
3958
|
+
if (!isKey(key)) {
|
|
3959
|
+
items.any.add(subscription);
|
|
3960
|
+
values.from.any.set(value, subscription);
|
|
3961
|
+
values.to.any.set(subscription, value);
|
|
3962
|
+
return;
|
|
3963
|
+
}
|
|
3964
|
+
/* istanbul ignore if */
|
|
3965
|
+
if (items.keyed == null || values.from.keyed == null || values.to.keyed == null)
|
|
3966
|
+
// istanbul ignore next
|
|
3967
|
+
return;
|
|
3968
|
+
let keyedItems = items.keyed.get(key);
|
|
3969
|
+
if (keyedItems == null) {
|
|
3970
|
+
keyedItems = /* @__PURE__ */ new Set();
|
|
3971
|
+
items.keyed.set(key, keyedItems);
|
|
3972
|
+
}
|
|
3973
|
+
keyedItems.add(subscription);
|
|
3974
|
+
let keyedFrom = values.from.keyed.get(key);
|
|
3975
|
+
if (keyedFrom == null) {
|
|
3976
|
+
keyedFrom = /* @__PURE__ */ new Map();
|
|
3977
|
+
values.from.keyed.set(key, keyedFrom);
|
|
3978
|
+
}
|
|
3979
|
+
keyedFrom.set(value, subscription);
|
|
3980
|
+
let keyedTo = values.to.keyed.get(key);
|
|
3981
|
+
if (keyedTo == null) {
|
|
3982
|
+
keyedTo = /* @__PURE__ */ new Map();
|
|
3983
|
+
values.to.keyed.set(key, keyedTo);
|
|
3984
|
+
}
|
|
3985
|
+
keyedTo.set(subscription, value);
|
|
3986
|
+
}
|
|
3987
|
+
function clearSubscriptions(store) {
|
|
3988
|
+
for (const susbcription of store.values.to.any.keys()) susbcription.unsubscribe();
|
|
3989
|
+
if (store.values.to.keyed != null) for (const values of store.values.to.keyed.values()) for (const susbcription of values.keys()) susbcription.unsubscribe();
|
|
3990
|
+
}
|
|
3991
|
+
function createSubscription(subscriptions, property, parameters) {
|
|
3992
|
+
if (parameters.signal?.aborted ?? false) throw new Error(parameters.signal?.reason);
|
|
3993
|
+
const state = {
|
|
3994
|
+
parameters,
|
|
3995
|
+
active: true
|
|
3996
|
+
};
|
|
3997
|
+
const existing = getExistingSubscription(subscriptions, state);
|
|
3998
|
+
if (existing != null) return [existing, true];
|
|
3999
|
+
if (subscriptions.state.keys != null && isKey(parameters.key) && !subscriptions.state.keys.has(parameters.key)) throw new Error(SUBSCRIPTION_INVALID_KEY);
|
|
4000
|
+
state.aborter = createAborter(parameters.signal, () => unsubscribe(subscriptions, instance, state));
|
|
4001
|
+
const instance = { unsubscribe: () => unsubscribe(subscriptions, instance, state) };
|
|
4002
|
+
Object.defineProperties(instance, {
|
|
4003
|
+
[SUBSCRIPTION_PROPERTY]: { value: true },
|
|
4004
|
+
[property.key]: { value: property.value ?? "subscription" },
|
|
4005
|
+
active: {
|
|
4006
|
+
enumerable: true,
|
|
4007
|
+
get: () => (parameters.isActive?.() ?? true) && state.active
|
|
4008
|
+
}
|
|
4009
|
+
});
|
|
4010
|
+
addSubscription(subscriptions, instance, state);
|
|
4011
|
+
return [Object.freeze(instance), false];
|
|
4012
|
+
}
|
|
4013
|
+
function createSubscriptions(parameters) {
|
|
4014
|
+
const { keys, property } = parameters;
|
|
4015
|
+
const state = {
|
|
4016
|
+
keys,
|
|
4017
|
+
items: {
|
|
4018
|
+
any: /* @__PURE__ */ new Set(),
|
|
4019
|
+
keyed: keys == null ? void 0 : /* @__PURE__ */ new Map()
|
|
4020
|
+
},
|
|
4021
|
+
values: {
|
|
4022
|
+
from: {
|
|
4023
|
+
any: /* @__PURE__ */ new Map(),
|
|
4024
|
+
keyed: keys == null ? void 0 : /* @__PURE__ */ new Map()
|
|
4025
|
+
},
|
|
4026
|
+
to: {
|
|
4027
|
+
any: /* @__PURE__ */ new Map(),
|
|
4028
|
+
keyed: keys == null ? void 0 : /* @__PURE__ */ new Map()
|
|
4029
|
+
}
|
|
4030
|
+
}
|
|
4031
|
+
};
|
|
4032
|
+
const instance = {
|
|
4033
|
+
state,
|
|
4034
|
+
clear: () => clearSubscriptions(state),
|
|
4035
|
+
create: (parameters) => createSubscription(instance, property, parameters)
|
|
4036
|
+
};
|
|
4037
|
+
return instance;
|
|
4038
|
+
}
|
|
4039
|
+
function getExistingSubscription(subscriptions, state) {
|
|
4040
|
+
const { parameters } = state;
|
|
4041
|
+
const { values } = subscriptions.state;
|
|
4042
|
+
return isKey(parameters.key) ? values.from.keyed?.get(parameters.key)?.get(parameters.value) : values.from.any.get(parameters.value);
|
|
4043
|
+
}
|
|
4044
|
+
/**
|
|
4045
|
+
* Is the value a subscription?
|
|
4046
|
+
*
|
|
4047
|
+
* @param value Value to check
|
|
4048
|
+
* @returns `true` if the value is a subscription, otherwise `false`
|
|
4049
|
+
*/
|
|
4050
|
+
function isSubscription(value) {
|
|
4051
|
+
return isPlainObject(value) && SUBSCRIPTION_PROPERTY in value && value[SUBSCRIPTION_PROPERTY] === true;
|
|
4052
|
+
}
|
|
4053
|
+
function removeFromStore(items, values, subscription, value, key) {
|
|
4054
|
+
items.delete(subscription);
|
|
4055
|
+
if (key == null) {
|
|
4056
|
+
values.from.any.delete(value);
|
|
4057
|
+
values.to.any.delete(subscription);
|
|
4058
|
+
} else {
|
|
4059
|
+
values.from.keyed?.get(key)?.delete(value);
|
|
4060
|
+
values.to.keyed?.get(key)?.delete(subscription);
|
|
4061
|
+
}
|
|
4062
|
+
}
|
|
4063
|
+
function removeSubscription(subscriptions, subscription, state) {
|
|
4064
|
+
if (!state.active) return;
|
|
4065
|
+
state.aborter = void 0;
|
|
4066
|
+
state.active = false;
|
|
4067
|
+
state.parameters.isActive = void 0;
|
|
4068
|
+
state.parameters.signal = void 0;
|
|
4069
|
+
const { key, value } = state.parameters;
|
|
4070
|
+
const { items, values } = subscriptions.state;
|
|
4071
|
+
if (!isKey(key)) {
|
|
4072
|
+
removeFromStore(items.any, values, subscription, value);
|
|
4073
|
+
return;
|
|
4074
|
+
}
|
|
4075
|
+
const keyed = items.keyed?.get(key);
|
|
4076
|
+
/* istanbul ignore if */
|
|
4077
|
+
if (items.keyed == null || keyed == null)
|
|
4078
|
+
// istanbul ignore next
|
|
4079
|
+
return;
|
|
4080
|
+
removeFromStore(keyed, values, subscription, value, key);
|
|
4081
|
+
if (keyed.size === 0) items.keyed.delete(key);
|
|
4082
|
+
}
|
|
4083
|
+
function unsubscribe(subscriptions, subscription, state) {
|
|
4084
|
+
state.aborter?.cancel();
|
|
4085
|
+
removeSubscription(subscriptions, subscription, state);
|
|
4086
|
+
}
|
|
4087
|
+
const SUBSCRIPTION_INVALID_KEY = "Invalid key for subscription";
|
|
4088
|
+
const SUBSCRIPTION_PROPERTY = "$subscription";
|
|
4089
|
+
//#endregion
|
|
3859
4090
|
//#region src/beacon.ts
|
|
3860
4091
|
/**
|
|
3861
4092
|
* Create a new beacon
|
|
@@ -3987,26 +4218,132 @@ function subscribeToObservable(state, first, second, third) {
|
|
|
3987
4218
|
isActive: () => state.beacon.active && state.active,
|
|
3988
4219
|
value: observer
|
|
3989
4220
|
});
|
|
3990
|
-
observer.next?.(state.beacon.value);
|
|
4221
|
+
observer.next?.(state.beacon.value);
|
|
4222
|
+
return subscription;
|
|
4223
|
+
}
|
|
4224
|
+
function updateBeacon(type, state, value, finish) {
|
|
4225
|
+
if (!state.active) return;
|
|
4226
|
+
if (type === BEACON_TYPE_NEXT) {
|
|
4227
|
+
if (state.options.equal(state.value, value)) return;
|
|
4228
|
+
state.value = value;
|
|
4229
|
+
}
|
|
4230
|
+
for (const [, observer] of state.subscriptions.state.values.to.any) observer[type]?.(value);
|
|
4231
|
+
if (finish === true) finishBeacon(state, true);
|
|
4232
|
+
}
|
|
4233
|
+
const BEACON_MESSAGE_RETRIEVE = "Cannot retrieve observable from a closed beacon";
|
|
4234
|
+
const BEACON_MESSAGE_SUBSCRIBE = "Cannot subscribe to a closed observable";
|
|
4235
|
+
const BEACON_PROPERTY = "$beacon";
|
|
4236
|
+
const BEACON_NAME = "beacon";
|
|
4237
|
+
const BEACON_OBSERVABLE = "observable";
|
|
4238
|
+
const BEACON_TYPE_ERROR = "error";
|
|
4239
|
+
const BEACON_TYPE_NEXT = "next";
|
|
4240
|
+
const beaconSubscription = { key: BEACON_PROPERTY };
|
|
4241
|
+
//#endregion
|
|
4242
|
+
//#region src/internal/herald.ts
|
|
4243
|
+
function createEvents(herald, state) {
|
|
4244
|
+
const events = {};
|
|
4245
|
+
Object.defineProperty(events, HERALD_PROPERTY, { value: HERALD_NAME_EVENTS });
|
|
4246
|
+
for (const key of state.keys) events[key] = (callback, signal) => herald.subscribe(key, callback, signal);
|
|
4247
|
+
return Object.freeze(events);
|
|
4248
|
+
}
|
|
4249
|
+
function emitForHerald(state, event, ...parameters) {
|
|
4250
|
+
const items = state.subscriptions.state.values.from.keyed?.get(event);
|
|
4251
|
+
if (items == null || items.size === 0) return;
|
|
4252
|
+
for (const [callback] of items) callback(...parameters);
|
|
4253
|
+
}
|
|
4254
|
+
function getHeraldSubscriptionProperty(input) {
|
|
4255
|
+
if (input == null) return heraldSubscription;
|
|
4256
|
+
const property = isPlainObject(input) ? input : {};
|
|
4257
|
+
if (typeof property.key !== "string" || property.value != null && typeof property.value !== "string") throw new Error(HERALD_MESSAGE_PROPERTY);
|
|
4258
|
+
return {
|
|
4259
|
+
key: property.key,
|
|
4260
|
+
value: property.value
|
|
4261
|
+
};
|
|
4262
|
+
}
|
|
4263
|
+
function getHeraldState(input) {
|
|
4264
|
+
const options = isPlainObject(input) ? input : {};
|
|
4265
|
+
if (!Array.isArray(options.names) || options.names.length === 0 || !options.names.every((name) => typeof name === "string")) throw new Error(HERALD_MESSAGE_ARRAY);
|
|
4266
|
+
if (options.onCreate != null && typeof options.onCreate !== "function") throw new Error(HERALD_MESSAGE_ONCREATE);
|
|
4267
|
+
const keys = new Set(options.names);
|
|
4268
|
+
return {
|
|
4269
|
+
keys,
|
|
4270
|
+
subscriptions: createSubscriptions({
|
|
4271
|
+
keys,
|
|
4272
|
+
property: getHeraldSubscriptionProperty(options.property)
|
|
4273
|
+
}),
|
|
4274
|
+
onCreate: options.onCreate
|
|
4275
|
+
};
|
|
4276
|
+
}
|
|
4277
|
+
/**
|
|
4278
|
+
* Create a _Herald_ for announcing named events
|
|
4279
|
+
*
|
|
4280
|
+
* @param names Event names
|
|
4281
|
+
* @param property Optional property for subscription identification _(defaults to `$herald`)_
|
|
4282
|
+
* @returns _Herald_ instance
|
|
4283
|
+
*/
|
|
4284
|
+
function herald(options) {
|
|
4285
|
+
const state = getHeraldState(options);
|
|
4286
|
+
const instance = {
|
|
4287
|
+
clear: () => state.subscriptions.clear(),
|
|
4288
|
+
emit: (event, ...parameters) => emitForHerald(state, event, ...parameters),
|
|
4289
|
+
observed: (event) => (state.subscriptions.state.items.keyed?.get(event)?.size ?? 0) > 0,
|
|
4290
|
+
subscribe: (key, callback, signal) => subscribeToHerald(state, key, callback, signal)
|
|
4291
|
+
};
|
|
4292
|
+
Object.defineProperties(instance, {
|
|
4293
|
+
[HERALD_PROPERTY]: { value: HERALD_NAME_HERALD },
|
|
4294
|
+
events: {
|
|
4295
|
+
enumerable: true,
|
|
4296
|
+
value: createEvents(instance, state)
|
|
4297
|
+
}
|
|
4298
|
+
});
|
|
4299
|
+
return Object.freeze(instance);
|
|
4300
|
+
}
|
|
4301
|
+
/**
|
|
4302
|
+
* Is the value a herald?
|
|
4303
|
+
*
|
|
4304
|
+
* @param value Value to check
|
|
4305
|
+
* @returns `true` if the value is a herald, otherwise `false`
|
|
4306
|
+
*/
|
|
4307
|
+
function isHerald(value) {
|
|
4308
|
+
return isHeraldInstance(HERALD_NAME_HERALD, value);
|
|
4309
|
+
}
|
|
4310
|
+
/**
|
|
4311
|
+
* Is the value events for a herald?
|
|
4312
|
+
*
|
|
4313
|
+
* @param value Value to check
|
|
4314
|
+
* @returns `true` if the value is events for a herald, otherwise `false`
|
|
4315
|
+
*/
|
|
4316
|
+
function isHeraldEvents(value) {
|
|
4317
|
+
return isHeraldInstance(HERALD_NAME_EVENTS, value);
|
|
4318
|
+
}
|
|
4319
|
+
function isHeraldInstance(name, value) {
|
|
4320
|
+
return isPlainObject(value) && HERALD_PROPERTY in value && value[HERALD_PROPERTY] === name;
|
|
4321
|
+
}
|
|
4322
|
+
/**
|
|
4323
|
+
* Is the value a herald subscription?
|
|
4324
|
+
*
|
|
4325
|
+
* @param value Value to check
|
|
4326
|
+
* @returns `true` if the value is a herald subscription, otherwise `false`
|
|
4327
|
+
*/
|
|
4328
|
+
function isHeraldSubscription(value) {
|
|
4329
|
+
return isSubscription(value) && value[HERALD_PROPERTY] === "subscription";
|
|
4330
|
+
}
|
|
4331
|
+
function subscribeToHerald(state, key, callback, signal) {
|
|
4332
|
+
const [subscription, existing] = state.subscriptions.create({
|
|
4333
|
+
key,
|
|
4334
|
+
signal,
|
|
4335
|
+
value: callback
|
|
4336
|
+
});
|
|
4337
|
+
if (!existing) state.onCreate?.(key, callback, subscription);
|
|
3991
4338
|
return subscription;
|
|
3992
4339
|
}
|
|
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 };
|
|
4340
|
+
const HERALD_PROPERTY = "$herald";
|
|
4341
|
+
const HERALD_MESSAGE_ARRAY = "Herald requires an array of event names.";
|
|
4342
|
+
const HERALD_MESSAGE_ONCREATE = `Herald requires a valid onCreate callback for subscription creation`;
|
|
4343
|
+
const HERALD_MESSAGE_PROPERTY = `Herald requires valid property information for subscription identification`;
|
|
4344
|
+
const HERALD_NAME_EVENTS = "events";
|
|
4345
|
+
const HERALD_NAME_HERALD = "herald";
|
|
4346
|
+
const heraldSubscription = { key: HERALD_PROPERTY };
|
|
4010
4347
|
//#endregion
|
|
4011
4348
|
//#region src/color/constants.ts
|
|
4012
4349
|
const COLOR_ALPHA = {
|
|
@@ -5333,332 +5670,86 @@ const methods = [
|
|
|
5333
5670
|
* _(Logging can be enabled or disabled by setting the `enabled` property)_
|
|
5334
5671
|
*/
|
|
5335
5672
|
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);
|
|
5673
|
+
const instance = {};
|
|
5674
|
+
Object.defineProperties(instance, {
|
|
5675
|
+
[LOGGER_PROPERTY]: { value: LOGGER_NAME },
|
|
5676
|
+
enabled: {
|
|
5677
|
+
enumerable: true,
|
|
5678
|
+
get: () => enabled,
|
|
5679
|
+
set: (value) => {
|
|
5680
|
+
enabled = typeof value === "boolean" ? value : enabled;
|
|
5681
|
+
}
|
|
5682
|
+
},
|
|
5683
|
+
time: { value: (label) => timedLogger(getString(label)) }
|
|
5559
5684
|
});
|
|
5560
|
-
const
|
|
5561
|
-
|
|
5562
|
-
|
|
5563
|
-
|
|
5564
|
-
|
|
5565
|
-
resolver = resolve;
|
|
5566
|
-
if (time === 0) settlePromise(resolver, void 0, aborter);
|
|
5567
|
-
else timer();
|
|
5685
|
+
for (const method of methods) Object.defineProperty(instance, method, {
|
|
5686
|
+
enumerable: true,
|
|
5687
|
+
get() {
|
|
5688
|
+
return enabled ? console[method].bind(console) : noop;
|
|
5689
|
+
}
|
|
5568
5690
|
});
|
|
5569
|
-
|
|
5691
|
+
return Object.freeze(instance);
|
|
5692
|
+
})();
|
|
5693
|
+
let enabled = true;
|
|
5570
5694
|
//#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
|
-
});
|
|
5695
|
+
//#region src/math.ts
|
|
5696
|
+
function average(array, key) {
|
|
5697
|
+
const aggregated = aggregate(AGGREGATION_AVERAGE, array, key);
|
|
5698
|
+
return aggregated.count > 0 ? aggregated.value / aggregated.count : NaN;
|
|
5588
5699
|
}
|
|
5589
|
-
|
|
5590
|
-
|
|
5591
|
-
|
|
5592
|
-
|
|
5593
|
-
|
|
5700
|
+
/**
|
|
5701
|
+
* Round a number up
|
|
5702
|
+
*
|
|
5703
|
+
* @param value Number to round up
|
|
5704
|
+
* @param decimals Number of decimal places to round to _(defaults to `0`)_
|
|
5705
|
+
* @returns Rounded number, or `Number.NaN` if the value if unable to be rounded
|
|
5706
|
+
*/
|
|
5707
|
+
function ceil(value, decimals) {
|
|
5708
|
+
return roundNumber(Math.ceil, value, decimals);
|
|
5594
5709
|
}
|
|
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
|
-
}
|
|
5710
|
+
function count(array, key, value) {
|
|
5711
|
+
if (!Array.isArray(array)) return NaN;
|
|
5712
|
+
const { length } = array;
|
|
5713
|
+
const callback = getAggregateCallback(key);
|
|
5714
|
+
if (callback == null) return length;
|
|
5715
|
+
let counted = 0;
|
|
5716
|
+
for (let index = 0; index < length; index += 1) {
|
|
5717
|
+
const item = array[index];
|
|
5718
|
+
if (Object.is(callback(item, index, array), value)) counted += 1;
|
|
5613
5719
|
}
|
|
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;
|
|
5720
|
+
return counted;
|
|
5620
5721
|
}
|
|
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
|
-
});
|
|
5722
|
+
/**
|
|
5723
|
+
* Round a number down
|
|
5724
|
+
*
|
|
5725
|
+
* @param value Number to round down
|
|
5726
|
+
* @param decimals Number of decimal places to round to _(defaults to `0`)_
|
|
5727
|
+
* @returns Rounded number, or `Number.NaN` if the value if unable to be rounded
|
|
5728
|
+
*/
|
|
5729
|
+
function floor(value, decimals) {
|
|
5730
|
+
return roundNumber(Math.floor, value, decimals);
|
|
5658
5731
|
}
|
|
5659
|
-
|
|
5660
|
-
|
|
5661
|
-
|
|
5732
|
+
function median(array, key) {
|
|
5733
|
+
let length = Array.isArray(array) ? array.length : 0;
|
|
5734
|
+
if (!Array.isArray(array) || length === 0) return NaN;
|
|
5735
|
+
let values = array;
|
|
5736
|
+
const callback = getAggregateCallback(key);
|
|
5737
|
+
if (callback != null) values = array.map((item, index) => callback(item, index, array));
|
|
5738
|
+
const numbers = values.filter(isNumber).sort((first, second) => first - second);
|
|
5739
|
+
length = numbers.length;
|
|
5740
|
+
if (length === 1) return numbers[0];
|
|
5741
|
+
if (length % 2 === 0) {
|
|
5742
|
+
const first = length / 2 - 1;
|
|
5743
|
+
const second = length / 2;
|
|
5744
|
+
return (numbers[first] + numbers[second]) / 2;
|
|
5745
|
+
}
|
|
5746
|
+
return numbers[Math.floor(length / 2)];
|
|
5747
|
+
}
|
|
5748
|
+
function min(array, key) {
|
|
5749
|
+
return getAggregated("min", array, key);
|
|
5750
|
+
}
|
|
5751
|
+
function sum(array, key) {
|
|
5752
|
+
return getAggregated("sum", array, key);
|
|
5662
5753
|
}
|
|
5663
5754
|
//#endregion
|
|
5664
5755
|
//#region src/query.ts
|
|
@@ -5847,9 +5938,6 @@ function createQueue(callback, options, key) {
|
|
|
5847
5938
|
});
|
|
5848
5939
|
return Object.freeze(instance);
|
|
5849
5940
|
}
|
|
5850
|
-
function getBooleanOrDefault(value, defaultValue) {
|
|
5851
|
-
return typeof value === "boolean" ? value : defaultValue;
|
|
5852
|
-
}
|
|
5853
5941
|
function getOptions(input) {
|
|
5854
5942
|
const options = typeof input === "object" && input != null ? input : {};
|
|
5855
5943
|
return {
|
|
@@ -6125,92 +6213,6 @@ const RANDOM_BOOLEAN_MODIFIER = .5;
|
|
|
6125
6213
|
const RANDOM_HEX_CHARACTERS = "0123456789ABCDEF";
|
|
6126
6214
|
const RANDOM_HEX_MAXIMUM = 15;
|
|
6127
6215
|
//#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
6216
|
//#region src/sized/set.ts
|
|
6215
6217
|
/**
|
|
6216
6218
|
* A _Set_ with a maximum size
|
|
@@ -6267,4 +6269,4 @@ var SizedSet = class extends Set {
|
|
|
6267
6269
|
}
|
|
6268
6270
|
};
|
|
6269
6271
|
//#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,
|
|
6272
|
+
export { CancelablePromise, Logger, PromiseTimeoutError, QueueError, RetryError, SORT_DIRECTION_ASCENDING, SORT_DIRECTION_DESCENDING, SizedMap, SizedSet, assert, assertCondition, assertDefined, assertInstanceOf, assertIs, assertProperty, assign, asyncAttempt, asyncDebounce, asyncFlow, asyncMatchResult, asyncOnce, asyncPipe, asyncThrottle, attempt, attemptAsyncFlow, attemptAsyncPipe, attemptFlow, attemptPipe, attemptPromise, average, beacon, between, camelCase, cancelable, capitalize, ceil, chunk, clamp, clone, compact, compare, copy, count, debounce, deburr, dedent, delay, deregisterCloner, deregisterComparator, deregisterEqualizer, diff, difference, drop, endsWith, endsWithArray, equal, error, exclude, exists, filter, find, findLast, first, firstOrDefault, flatFreeze, flatten, floor, flow, freeze, fromQuery, toPromise as fromResult, toPromise, fuzzy, fuzzyMatch, getArray, getArrayComparison, getColor, getForegroundColor, getHexColor, getHexaColor, getHslColor, getHslaColor, getHwbColor, getHwbaColor, getNormalizedHex, getNumber, getRandomBoolean, getRandomCharacters, getRandomColor, getRandomFloatingNumber as getRandomFloat, getRandomHex, getRandomInteger, getRandomItem, getRandomItems, getRgbColor, getRgbaColor, getSortedIndex, getString, getTimedPromise, getUuid, getValue, groupArraysBy, groupBy, handleResult, hasValue, hasValueResult, herald, hexToHsl, hexToHsla, hexToHwb, hexToHwba, hexToRgb, hexToRgba, hslToHex, hslToHwb, hslToHwba, hslToRgb, hslToRgba, hwbToHex, hwbToHsl, hwbToHsla, hwbToRgb, hwbToRgba, ignoreKey, inMap, inSet, includes, includesArray, indexOf, indexOfArray, initializeAssigner, initializeEqualizer, initializeMerger, initializeNormalizer, initializeSorter, initializeTemplater, initializeTransformer, insert, interpolate, intersection, isArrayOrPlainObject, isBeacon, isBeaconSubscription, isColor, isConstructor, isEmpty, isError, isFrozen, isFulfilled, isHerald, isHeraldEvents, isHeraldSubscription, isHexColor, isHslColor, isHslaColor, isHwbColor, isHwbaColor, isInstanceOf, isKey, isKeyedQueue, isLogger, isNonArrayOrPlainObject, isNonConstructor, isNonEmpty, isNonInstanceOf, isNonKey, isNonNullable, isNonNullableOrEmpty, isNonNullableOrWhitespace, isNonNumber, isNonNumerical, isNonObject, isNonPlainObject, isNonPrimitive, isNonTypedArray, isNullable, isNullableOrEmpty, isNullableOrWhitespace, isNumber, isNumerical, isObject, isObservable, isOk, isPlainObject, isPrimitive, isQueue, isQueueInstance, isRejected, isResult, isRgbColor, isRgbaColor, isSorted, isSubscription, isTimedLogger, isTypedArray, join, kebabCase, keyedQueue, last, lastIndexOf, lastOrDefault, lowerCase, matchResult, max, median, memoize, merge, min, move, moveIndices, moveToIndex, noop, normalize, ok, omit, once, parse, partition, pascalCase, pick, pipe, promises, push, queue, range, registerCloner, registerComparator, registerEqualizer, resultPromises, retry, reverse, rgbToHex, rgbToHsl, rgbToHsla, rgbToHwb, rgbToHwba, round, select, setValue, settlePromise, shake, shuffle, single, slice, smush, snakeCase, sort, splice, startsWith, startsWithArray, sum, swap, take, template, throttle, timed, times, titleCase, toMap, toMapArrays, toQuery, toRecord, toRecordArrays, toResult, toSet, toggle, transform, trim, truncate, tryDecode, tryEncode, union, unique, unsmush, unwrap, update, upperCase, words };
|