@lowentry/utils 1.13.5 → 1.15.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/LeTypes.d.ts +15 -0
- package/build/LeUtils.d.ts +217 -0
- package/build/index.d.ts +2 -0
- package/index.js +877 -469
- package/index.js.map +1 -1
- package/jest.config.js +9 -0
- package/package.json +6 -3
- package/src/LeUtils.js +584 -386
- package/tests/each.test.js +45 -0
- package/tsconfig.d.ts +3 -0
- package/tsconfig.json +49 -0
package/src/LeUtils.js
CHANGED
|
@@ -4,7 +4,7 @@ import {ISSET, IS_OBJECT, IS_ARRAY, STRING, INT_LAX, FLOAT_LAX, INT_LAX_ANY, FLO
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
* @param {
|
|
7
|
+
* @param {LeUtils_TransactionalValue} transactionalValue
|
|
8
8
|
*/
|
|
9
9
|
const checkTransactionalValue = (transactionalValue) =>
|
|
10
10
|
{
|
|
@@ -17,7 +17,7 @@ const checkTransactionalValue = (transactionalValue) =>
|
|
|
17
17
|
};
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
|
-
* @param {
|
|
20
|
+
* @param {LeUtils_TransactionalValue} transactionalValue
|
|
21
21
|
* @param {string} changeId
|
|
22
22
|
* @returns {{index:number, value:*}|null}
|
|
23
23
|
*/
|
|
@@ -75,7 +75,7 @@ export const LeUtils = {
|
|
|
75
75
|
|
|
76
76
|
if((document.readyState === 'interactive') || (document.readyState === 'complete'))
|
|
77
77
|
{
|
|
78
|
-
return LeUtils.setTimeout(callback, 0);
|
|
78
|
+
return LeUtils.setTimeout(() => callback(), 0);
|
|
79
79
|
}
|
|
80
80
|
else
|
|
81
81
|
{
|
|
@@ -435,17 +435,11 @@ export const LeUtils = {
|
|
|
435
435
|
return result;
|
|
436
436
|
},
|
|
437
437
|
|
|
438
|
-
/**
|
|
439
|
-
* @callback LeUtils~__findIndexValueCallback
|
|
440
|
-
* @param {*} value
|
|
441
|
-
* @param {*} index
|
|
442
|
-
* @returns {boolean|undefined}
|
|
443
|
-
*/
|
|
444
438
|
/**
|
|
445
439
|
* Finds the first element in the given array or object that returns true from the callback, and returns an object with the index and value.
|
|
446
440
|
*
|
|
447
441
|
* @param {*[]|object|Function} elements
|
|
448
|
-
* @param {
|
|
442
|
+
* @param {(value:*, index:*) => boolean|void} callback
|
|
449
443
|
* @param {boolean} [optionalSkipHasOwnPropertyCheck]
|
|
450
444
|
* @returns {{index:*, value:*}|null}
|
|
451
445
|
*/
|
|
@@ -460,7 +454,7 @@ export const LeUtils = {
|
|
|
460
454
|
result = {index, value};
|
|
461
455
|
return false;
|
|
462
456
|
}
|
|
463
|
-
});
|
|
457
|
+
}, optionalSkipHasOwnPropertyCheck);
|
|
464
458
|
return result;
|
|
465
459
|
},
|
|
466
460
|
|
|
@@ -468,7 +462,7 @@ export const LeUtils = {
|
|
|
468
462
|
* Finds the first element in the given array or object that returns true from the callback, and returns the index.
|
|
469
463
|
*
|
|
470
464
|
* @param {*[]|object|Function} elements
|
|
471
|
-
* @param {
|
|
465
|
+
* @param {(value:*, index:*) => boolean|void} callback
|
|
472
466
|
* @param {boolean} [optionalSkipHasOwnPropertyCheck]
|
|
473
467
|
* @returns {*|null}
|
|
474
468
|
*/
|
|
@@ -479,7 +473,7 @@ export const LeUtils = {
|
|
|
479
473
|
* Finds the first element in the given array or object that returns true from the callback, and returns the value.
|
|
480
474
|
*
|
|
481
475
|
* @param {*[]|object|Function} elements
|
|
482
|
-
* @param {
|
|
476
|
+
* @param {(value:*, index:*) => boolean|void} callback
|
|
483
477
|
* @param {boolean} [optionalSkipHasOwnPropertyCheck]
|
|
484
478
|
* @returns {*|null}
|
|
485
479
|
*/
|
|
@@ -487,50 +481,222 @@ export const LeUtils = {
|
|
|
487
481
|
(elements, callback, optionalSkipHasOwnPropertyCheck = false) => LeUtils.findIndexValue(elements, callback, optionalSkipHasOwnPropertyCheck)?.value ?? null,
|
|
488
482
|
|
|
489
483
|
/**
|
|
490
|
-
*
|
|
491
|
-
*
|
|
484
|
+
* Returns the value at the given index in the given elements.
|
|
485
|
+
*
|
|
486
|
+
* @param {*} elements
|
|
492
487
|
* @param {*} index
|
|
493
|
-
* @
|
|
488
|
+
* @param {boolean} [optionalSkipHasOwnPropertyCheck]
|
|
489
|
+
* @returns {*}
|
|
494
490
|
*/
|
|
491
|
+
getValueAtIndex:
|
|
492
|
+
(elements, index, optionalSkipHasOwnPropertyCheck = false) =>
|
|
493
|
+
{
|
|
494
|
+
if((elements === null) || (typeof elements === 'undefined'))
|
|
495
|
+
{
|
|
496
|
+
return undefined;
|
|
497
|
+
}
|
|
498
|
+
if(Array.isArray(elements))
|
|
499
|
+
{
|
|
500
|
+
return elements[index];
|
|
501
|
+
}
|
|
502
|
+
if((typeof elements === 'object') && (elements?.constructor === Object))
|
|
503
|
+
{
|
|
504
|
+
if((optionalSkipHasOwnPropertyCheck === true) || Object.prototype.hasOwnProperty.call(elements, index))
|
|
505
|
+
{
|
|
506
|
+
return elements[index];
|
|
507
|
+
}
|
|
508
|
+
return undefined;
|
|
509
|
+
}
|
|
510
|
+
if(elements instanceof Map)
|
|
511
|
+
{
|
|
512
|
+
return elements.get(index);
|
|
513
|
+
}
|
|
514
|
+
if(elements instanceof Set)
|
|
515
|
+
{
|
|
516
|
+
return index;
|
|
517
|
+
}
|
|
518
|
+
if(ArrayBuffer.isView(elements) && !(elements instanceof DataView))
|
|
519
|
+
{
|
|
520
|
+
return elements[index];
|
|
521
|
+
}
|
|
522
|
+
if(typeof elements === 'string')
|
|
523
|
+
{
|
|
524
|
+
return elements.charAt(index);
|
|
525
|
+
}
|
|
526
|
+
if(typeof elements?.[Symbol.iterator] === 'function')
|
|
527
|
+
{
|
|
528
|
+
let i = 0;
|
|
529
|
+
for(const value of elements)
|
|
530
|
+
{
|
|
531
|
+
if(i === index)
|
|
532
|
+
{
|
|
533
|
+
return value;
|
|
534
|
+
}
|
|
535
|
+
i++;
|
|
536
|
+
}
|
|
537
|
+
return undefined;
|
|
538
|
+
}
|
|
539
|
+
if(typeof elements?.forEach === 'function')
|
|
540
|
+
{
|
|
541
|
+
let result = undefined;
|
|
542
|
+
let shouldContinue = true;
|
|
543
|
+
elements.forEach((value, i) =>
|
|
544
|
+
{
|
|
545
|
+
if(shouldContinue)
|
|
546
|
+
{
|
|
547
|
+
if(i === index)
|
|
548
|
+
{
|
|
549
|
+
result = value;
|
|
550
|
+
shouldContinue = false;
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
});
|
|
554
|
+
return result;
|
|
555
|
+
}
|
|
556
|
+
if((typeof elements === 'object') || (typeof elements === 'function'))
|
|
557
|
+
{
|
|
558
|
+
if((optionalSkipHasOwnPropertyCheck === true) || Object.prototype.hasOwnProperty.call(elements, index))
|
|
559
|
+
{
|
|
560
|
+
return elements[index];
|
|
561
|
+
}
|
|
562
|
+
return undefined;
|
|
563
|
+
}
|
|
564
|
+
return undefined;
|
|
565
|
+
},
|
|
566
|
+
|
|
495
567
|
/**
|
|
496
|
-
*
|
|
568
|
+
* Checks if the given elements can be iterated over using LeUtils.each().
|
|
497
569
|
*
|
|
498
|
-
* @param {*
|
|
499
|
-
* @
|
|
570
|
+
* @param {*} elements
|
|
571
|
+
* @returns {boolean}
|
|
572
|
+
*/
|
|
573
|
+
supportsEach:
|
|
574
|
+
(elements) =>
|
|
575
|
+
{
|
|
576
|
+
if((elements === null) || (typeof elements === 'undefined'))
|
|
577
|
+
{
|
|
578
|
+
return false;
|
|
579
|
+
}
|
|
580
|
+
return !!(
|
|
581
|
+
(Array.isArray(elements))
|
|
582
|
+
|| ((typeof elements === 'object') && (elements?.constructor === Object))
|
|
583
|
+
|| (typeof elements === 'string')
|
|
584
|
+
|| (typeof elements?.[Symbol.iterator] === 'function')
|
|
585
|
+
|| (typeof elements?.forEach === 'function')
|
|
586
|
+
|| ((typeof elements === 'object') || (typeof elements === 'function'))
|
|
587
|
+
);
|
|
588
|
+
},
|
|
589
|
+
|
|
590
|
+
/**
|
|
591
|
+
* Returns an iterator that iterates over each element in the given array or object, yielding an array with the value and the index/key.
|
|
592
|
+
*
|
|
593
|
+
* @param {*} elements
|
|
500
594
|
* @param {boolean} [optionalSkipHasOwnPropertyCheck]
|
|
501
|
-
* @returns {
|
|
595
|
+
* @returns {Generator<*, void, *>}
|
|
502
596
|
*/
|
|
503
|
-
|
|
504
|
-
(elements,
|
|
597
|
+
eachIterator:
|
|
598
|
+
function* (elements, optionalSkipHasOwnPropertyCheck = false)
|
|
505
599
|
{
|
|
506
|
-
if((elements
|
|
600
|
+
if((elements === null) || (typeof elements === 'undefined'))
|
|
601
|
+
{
|
|
602
|
+
return;
|
|
603
|
+
}
|
|
604
|
+
if(Array.isArray(elements))
|
|
605
|
+
{
|
|
606
|
+
for(let i = 0; i < elements.length; i++)
|
|
607
|
+
{
|
|
608
|
+
yield [elements[i], i];
|
|
609
|
+
}
|
|
610
|
+
return;
|
|
611
|
+
}
|
|
612
|
+
if((typeof elements === 'object') && (elements?.constructor === Object))
|
|
507
613
|
{
|
|
508
|
-
|
|
614
|
+
for(const i in elements)
|
|
509
615
|
{
|
|
510
|
-
|
|
616
|
+
if((optionalSkipHasOwnPropertyCheck === true) || Object.prototype.hasOwnProperty.call(elements, i))
|
|
511
617
|
{
|
|
512
|
-
|
|
513
|
-
{
|
|
514
|
-
break;
|
|
515
|
-
}
|
|
618
|
+
yield [elements[i], i];
|
|
516
619
|
}
|
|
517
620
|
}
|
|
518
|
-
|
|
621
|
+
return;
|
|
622
|
+
}
|
|
623
|
+
if(elements instanceof Map)
|
|
624
|
+
{
|
|
625
|
+
for(const [i, value] of elements)
|
|
626
|
+
{
|
|
627
|
+
yield [value, i];
|
|
628
|
+
}
|
|
629
|
+
return;
|
|
630
|
+
}
|
|
631
|
+
if(elements instanceof Set)
|
|
632
|
+
{
|
|
633
|
+
for(const value of elements)
|
|
634
|
+
{
|
|
635
|
+
yield [value, value];
|
|
636
|
+
}
|
|
637
|
+
return;
|
|
638
|
+
}
|
|
639
|
+
if(typeof elements === 'string')
|
|
640
|
+
{
|
|
641
|
+
for(let i = 0; i < elements.length; i++)
|
|
642
|
+
{
|
|
643
|
+
yield [elements.charAt(i), i];
|
|
644
|
+
}
|
|
645
|
+
return;
|
|
646
|
+
}
|
|
647
|
+
if(typeof elements?.[Symbol.iterator] === 'function')
|
|
648
|
+
{
|
|
649
|
+
let i = 0;
|
|
650
|
+
for(const value of elements)
|
|
519
651
|
{
|
|
520
|
-
|
|
652
|
+
yield [value, i];
|
|
653
|
+
i++;
|
|
654
|
+
}
|
|
655
|
+
return;
|
|
656
|
+
}
|
|
657
|
+
if(typeof elements?.forEach === 'function')
|
|
658
|
+
{
|
|
659
|
+
const buffer = [];
|
|
660
|
+
elements.forEach((value, i) =>
|
|
661
|
+
{
|
|
662
|
+
buffer.push([value, i]);
|
|
663
|
+
});
|
|
664
|
+
for(const entry of buffer)
|
|
665
|
+
{
|
|
666
|
+
yield entry;
|
|
667
|
+
}
|
|
668
|
+
return;
|
|
669
|
+
}
|
|
670
|
+
if((typeof elements === 'object') || (typeof elements === 'function'))
|
|
671
|
+
{
|
|
672
|
+
for(const i in elements)
|
|
673
|
+
{
|
|
674
|
+
if((optionalSkipHasOwnPropertyCheck === true) || Object.prototype.hasOwnProperty.call(elements, i))
|
|
521
675
|
{
|
|
522
|
-
|
|
523
|
-
{
|
|
524
|
-
if(callback.call(elements[index], elements[index], index) === false)
|
|
525
|
-
{
|
|
526
|
-
break;
|
|
527
|
-
}
|
|
528
|
-
}
|
|
676
|
+
yield [elements[i], i];
|
|
529
677
|
}
|
|
530
678
|
}
|
|
531
|
-
|
|
679
|
+
return;
|
|
680
|
+
}
|
|
681
|
+
console.warn('Executed LeUtils.eachIterator() on an invalid type: [' + (typeof elements) + ']', elements);
|
|
682
|
+
},
|
|
683
|
+
|
|
684
|
+
/**
|
|
685
|
+
* Loops through each element in the given array or object, and calls the callback for each element.
|
|
686
|
+
*
|
|
687
|
+
* @param {*} elements
|
|
688
|
+
* @param {(value:*, index?:*) => boolean|void} callback
|
|
689
|
+
* @param {boolean} [optionalSkipHasOwnPropertyCheck]
|
|
690
|
+
* @returns {*}
|
|
691
|
+
*/
|
|
692
|
+
each:
|
|
693
|
+
(elements, callback, optionalSkipHasOwnPropertyCheck = false) =>
|
|
694
|
+
{
|
|
695
|
+
for(const [value, key] of LeUtils.eachIterator(elements, optionalSkipHasOwnPropertyCheck))
|
|
696
|
+
{
|
|
697
|
+
if(callback.call(value, value, key) === false)
|
|
532
698
|
{
|
|
533
|
-
|
|
699
|
+
break;
|
|
534
700
|
}
|
|
535
701
|
}
|
|
536
702
|
return elements;
|
|
@@ -539,54 +705,55 @@ export const LeUtils = {
|
|
|
539
705
|
/**
|
|
540
706
|
* Like LeUtils.each(), except that it expects an async callback.
|
|
541
707
|
*
|
|
542
|
-
* @param {*
|
|
543
|
-
* @param {
|
|
708
|
+
* @param {*} elements
|
|
709
|
+
* @param {(value:*, index?:*) => Promise<boolean|undefined>} asyncCallback
|
|
544
710
|
* @param {number} [optionalParallelCount]
|
|
545
711
|
* @param {boolean} [optionalSkipHasOwnPropertyCheck]
|
|
546
|
-
* @returns {
|
|
712
|
+
* @returns {Promise<*>}
|
|
547
713
|
*/
|
|
548
714
|
eachAsync:
|
|
549
715
|
(() =>
|
|
550
716
|
{
|
|
717
|
+
/**
|
|
718
|
+
* Instead of waiting for every promise individually, this function will queue up multiple promises at once, then wait for any of them to finish, before adding more, until it has looped through all elements.
|
|
719
|
+
* Then, at the end, it will wait for the remaining promises to finish.
|
|
720
|
+
*/
|
|
551
721
|
const eachAsyncParallel = async (elements, asyncCallback, optionalParallelCount, optionalSkipHasOwnPropertyCheck) =>
|
|
552
722
|
{
|
|
553
|
-
|
|
723
|
+
const runningPromises = new Set();
|
|
554
724
|
let doBreak = false;
|
|
555
|
-
await LeUtils.eachAsync(elements, async (
|
|
725
|
+
await LeUtils.eachAsync(elements, async (value, index) =>// loop through each element
|
|
556
726
|
{
|
|
557
|
-
|
|
727
|
+
if(doBreak)
|
|
558
728
|
{
|
|
559
|
-
|
|
560
|
-
LeUtils.each(promises, (promise) =>
|
|
561
|
-
{
|
|
562
|
-
if(!promise.__lowentry_utils__promise_is_done__)
|
|
563
|
-
{
|
|
564
|
-
newPromises.push(promise);
|
|
565
|
-
}
|
|
566
|
-
});
|
|
567
|
-
promises = newPromises;
|
|
568
|
-
if(promises.length > optionalParallelCount)
|
|
569
|
-
{
|
|
570
|
-
await Promise.any(promises);
|
|
571
|
-
}
|
|
729
|
+
return false;
|
|
572
730
|
}
|
|
573
731
|
|
|
574
|
-
if
|
|
732
|
+
// if no spot is available, wait for one to finish
|
|
733
|
+
while(runningPromises.size >= optionalParallelCount)
|
|
575
734
|
{
|
|
576
|
-
|
|
735
|
+
await Promise.race(runningPromises);
|
|
736
|
+
if(doBreak)
|
|
737
|
+
{
|
|
738
|
+
return false;
|
|
739
|
+
}
|
|
577
740
|
}
|
|
578
741
|
|
|
742
|
+
// process this element, by creating a promise, and adding it to the queue
|
|
579
743
|
const promise = (async () =>
|
|
580
744
|
{
|
|
581
|
-
if((await asyncCallback.call(
|
|
745
|
+
if((await asyncCallback.call(value, value, index)) === false)
|
|
582
746
|
{
|
|
583
747
|
doBreak = true;
|
|
584
748
|
}
|
|
585
|
-
promise.__lowentry_utils__promise_is_done__ = true;
|
|
586
749
|
})();
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
750
|
+
runningPromises.add(promise);
|
|
751
|
+
promise.finally(() =>
|
|
752
|
+
{
|
|
753
|
+
runningPromises.delete(promise);
|
|
754
|
+
});
|
|
755
|
+
}, 1, optionalSkipHasOwnPropertyCheck);
|
|
756
|
+
await Promise.all(runningPromises);
|
|
590
757
|
return elements;
|
|
591
758
|
};
|
|
592
759
|
|
|
@@ -600,166 +767,163 @@ export const LeUtils = {
|
|
|
600
767
|
return await eachAsyncParallel(elements, asyncCallback, parallelCount, optionalSkipHasOwnPropertyCheck);
|
|
601
768
|
}
|
|
602
769
|
|
|
603
|
-
|
|
604
|
-
{
|
|
605
|
-
for(let index = 0; index < elements.length; index++)
|
|
606
|
-
{
|
|
607
|
-
if((await asyncCallback.call(elements[index], elements[index], index)) === false)
|
|
608
|
-
{
|
|
609
|
-
break;
|
|
610
|
-
}
|
|
611
|
-
}
|
|
612
|
-
}
|
|
613
|
-
else if((typeof elements === 'object') || (typeof elements === 'function'))
|
|
770
|
+
for(const [value, key] of LeUtils.eachIterator(elements, optionalSkipHasOwnPropertyCheck))
|
|
614
771
|
{
|
|
615
|
-
|
|
772
|
+
if((await asyncCallback.call(value, value, key)) === false)
|
|
616
773
|
{
|
|
617
|
-
|
|
618
|
-
{
|
|
619
|
-
if((await asyncCallback.call(elements[index], elements[index], index)) === false)
|
|
620
|
-
{
|
|
621
|
-
break;
|
|
622
|
-
}
|
|
623
|
-
}
|
|
774
|
+
break;
|
|
624
775
|
}
|
|
625
776
|
}
|
|
626
|
-
else
|
|
627
|
-
{
|
|
628
|
-
console.warn('Executed LeUtils.eachAsync() on an invalid type: [' + (typeof elements) + ']', elements);
|
|
629
|
-
}
|
|
630
777
|
}
|
|
631
778
|
return elements;
|
|
632
779
|
};
|
|
633
780
|
})(),
|
|
634
781
|
|
|
635
782
|
/**
|
|
636
|
-
*
|
|
637
|
-
*
|
|
638
|
-
*
|
|
639
|
-
*
|
|
783
|
+
* Returns an empty simplified collection (array, object, or Map), based on the given elements.
|
|
784
|
+
*
|
|
785
|
+
* Usage:
|
|
786
|
+
*
|
|
787
|
+
* ```js
|
|
788
|
+
* const [success, collection, add] = LeUtils.getEmptySimplifiedCollection(elements);
|
|
789
|
+
* ```
|
|
790
|
+
*
|
|
791
|
+
* @param {*} elements
|
|
792
|
+
* @returns {[boolean, *[]|object|Map, (value:*,index:*)=>void]}
|
|
640
793
|
*/
|
|
794
|
+
getEmptySimplifiedCollection:
|
|
795
|
+
(elements) =>
|
|
796
|
+
{
|
|
797
|
+
if((elements === null) || (typeof elements === 'undefined'))
|
|
798
|
+
{
|
|
799
|
+
return [false, [], (value, index) =>
|
|
800
|
+
{
|
|
801
|
+
}];
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
let collection = null;
|
|
805
|
+
let add = null;
|
|
806
|
+
if(Array.isArray(elements))
|
|
807
|
+
{
|
|
808
|
+
collection = [];
|
|
809
|
+
add = (value, index) =>
|
|
810
|
+
{
|
|
811
|
+
collection.push(value);
|
|
812
|
+
};
|
|
813
|
+
}
|
|
814
|
+
else if((typeof elements === 'object') && (elements?.constructor === Object))
|
|
815
|
+
{
|
|
816
|
+
collection = {};
|
|
817
|
+
add = (value, index) =>
|
|
818
|
+
{
|
|
819
|
+
collection[index] = value;
|
|
820
|
+
};
|
|
821
|
+
}
|
|
822
|
+
else if(elements instanceof Map)
|
|
823
|
+
{
|
|
824
|
+
collection = new Map();
|
|
825
|
+
add = (value, index) =>
|
|
826
|
+
{
|
|
827
|
+
collection.set(index, value);
|
|
828
|
+
};
|
|
829
|
+
}
|
|
830
|
+
else if((typeof elements === 'string') || (typeof elements?.[Symbol.iterator] === 'function') || (typeof elements?.forEach === 'function'))
|
|
831
|
+
{
|
|
832
|
+
collection = [];
|
|
833
|
+
add = (value, index) =>
|
|
834
|
+
{
|
|
835
|
+
collection.push(value);
|
|
836
|
+
};
|
|
837
|
+
}
|
|
838
|
+
else if((typeof elements === 'object') || (typeof elements === 'function'))
|
|
839
|
+
{
|
|
840
|
+
collection = {};
|
|
841
|
+
add = (value, index) =>
|
|
842
|
+
{
|
|
843
|
+
collection[index] = value;
|
|
844
|
+
};
|
|
845
|
+
}
|
|
846
|
+
else
|
|
847
|
+
{
|
|
848
|
+
console.warn('Executed LeUtils.getEmptySimplifiedCollection() on an invalid type: [' + (typeof elements) + ']', elements);
|
|
849
|
+
return [false, [], (value, index) =>
|
|
850
|
+
{
|
|
851
|
+
}];
|
|
852
|
+
}
|
|
853
|
+
return [true, collection, add];
|
|
854
|
+
},
|
|
855
|
+
|
|
641
856
|
/**
|
|
642
|
-
* Loops through the given elements, and returns a new
|
|
857
|
+
* Loops through the given elements, and returns a new collection, with only the elements that returned true (or a value equals to true) from the callback.
|
|
643
858
|
* If no callback is given, it will return all elements that are of a true value (for example, values that are: not null, not undefined, not false, not 0, not an empty string, not an empty array, not an empty object).
|
|
644
859
|
*
|
|
645
|
-
* @param {*
|
|
646
|
-
* @param {
|
|
860
|
+
* @param {*} elements
|
|
861
|
+
* @param {(value:*, index:*) => boolean|undefined} [callback]
|
|
647
862
|
* @param {boolean} [optionalSkipHasOwnPropertyCheck]
|
|
648
|
-
* @returns {*
|
|
863
|
+
* @returns {*}
|
|
649
864
|
*/
|
|
650
865
|
filter:
|
|
651
866
|
(elements, callback, optionalSkipHasOwnPropertyCheck = false) =>
|
|
652
867
|
{
|
|
653
|
-
|
|
868
|
+
const [success, collection, add] = LeUtils.getEmptySimplifiedCollection(elements);
|
|
869
|
+
if(!success)
|
|
654
870
|
{
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
{
|
|
662
|
-
result.push(elements[index]);
|
|
663
|
-
}
|
|
664
|
-
}
|
|
665
|
-
return result;
|
|
666
|
-
}
|
|
667
|
-
else if((typeof elements === 'object') || (typeof elements === 'function'))
|
|
871
|
+
return elements;
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
LeUtils.each(elements, (value, index) =>
|
|
875
|
+
{
|
|
876
|
+
if(!callback)
|
|
668
877
|
{
|
|
669
|
-
|
|
670
|
-
for(let index in elements)
|
|
878
|
+
if(value)
|
|
671
879
|
{
|
|
672
|
-
|
|
673
|
-
{
|
|
674
|
-
if((!callback && elements[index]) || (callback && callback.call(elements[index], elements[index], index)))
|
|
675
|
-
{
|
|
676
|
-
result[index] = elements[index];
|
|
677
|
-
}
|
|
678
|
-
}
|
|
880
|
+
add(value, index);
|
|
679
881
|
}
|
|
680
|
-
return result;
|
|
681
882
|
}
|
|
682
|
-
else
|
|
883
|
+
else if(callback.call(value, value, index))
|
|
683
884
|
{
|
|
684
|
-
|
|
885
|
+
add(value, index);
|
|
685
886
|
}
|
|
686
|
-
}
|
|
687
|
-
return
|
|
887
|
+
}, optionalSkipHasOwnPropertyCheck);
|
|
888
|
+
return collection;
|
|
688
889
|
},
|
|
689
890
|
|
|
690
891
|
/**
|
|
691
|
-
*
|
|
692
|
-
* @param {*} value
|
|
693
|
-
* @param {*} index
|
|
694
|
-
* @returns {*}
|
|
695
|
-
*/
|
|
696
|
-
/**
|
|
697
|
-
* Loops through the given elements, and returns a new array or object, with the elements that were returned from the callback.
|
|
892
|
+
* Loops through the given elements, and returns a new collection, with the elements that were returned from the callback.
|
|
698
893
|
*
|
|
699
|
-
* @param {*
|
|
700
|
-
* @param {
|
|
894
|
+
* @param {*} elements
|
|
895
|
+
* @param {(value:*, index:*) => *} [callback]
|
|
701
896
|
* @param {boolean} [optionalSkipHasOwnPropertyCheck]
|
|
702
|
-
* @returns {*
|
|
897
|
+
* @returns {*}
|
|
703
898
|
*/
|
|
704
899
|
map:
|
|
705
900
|
(elements, callback, optionalSkipHasOwnPropertyCheck = false) =>
|
|
706
901
|
{
|
|
707
|
-
|
|
902
|
+
const [success, collection, add] = LeUtils.getEmptySimplifiedCollection(elements);
|
|
903
|
+
if(!success)
|
|
708
904
|
{
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
{
|
|
716
|
-
result[index] = elements[index];
|
|
717
|
-
}
|
|
718
|
-
else
|
|
719
|
-
{
|
|
720
|
-
result[index] = callback.call(elements[index], elements[index], index);
|
|
721
|
-
}
|
|
722
|
-
}
|
|
723
|
-
return result;
|
|
724
|
-
}
|
|
725
|
-
else if((typeof elements === 'object') || (typeof elements === 'function'))
|
|
905
|
+
return elements;
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
LeUtils.each(elements, (value, index) =>
|
|
909
|
+
{
|
|
910
|
+
if(!callback)
|
|
726
911
|
{
|
|
727
|
-
|
|
728
|
-
for(let index in elements)
|
|
729
|
-
{
|
|
730
|
-
if((optionalSkipHasOwnPropertyCheck === true) || Object.prototype.hasOwnProperty.call(elements, index))
|
|
731
|
-
{
|
|
732
|
-
if(!callback)
|
|
733
|
-
{
|
|
734
|
-
result[index] = elements[index];
|
|
735
|
-
}
|
|
736
|
-
else
|
|
737
|
-
{
|
|
738
|
-
result[index] = callback.call(elements[index], elements[index], index);
|
|
739
|
-
}
|
|
740
|
-
}
|
|
741
|
-
}
|
|
742
|
-
return result;
|
|
912
|
+
add(value, index);
|
|
743
913
|
}
|
|
744
914
|
else
|
|
745
915
|
{
|
|
746
|
-
|
|
916
|
+
add(callback.call(value, value, index), index);
|
|
747
917
|
}
|
|
748
|
-
}
|
|
749
|
-
return
|
|
918
|
+
}, optionalSkipHasOwnPropertyCheck);
|
|
919
|
+
return collection;
|
|
750
920
|
},
|
|
751
921
|
|
|
752
|
-
/**
|
|
753
|
-
* @callback LeUtils~__mapToArrayCallback
|
|
754
|
-
* @param {*} value
|
|
755
|
-
* @param {*} index
|
|
756
|
-
* @returns {*}
|
|
757
|
-
*/
|
|
758
922
|
/**
|
|
759
923
|
* Loops through the given elements, and returns a new array, with the elements that were returned from the callback. Always returns an array.
|
|
760
924
|
*
|
|
761
|
-
* @param {*
|
|
762
|
-
* @param {
|
|
925
|
+
* @param {*} elements
|
|
926
|
+
* @param {(value:*, index:*) => *} [callback]
|
|
763
927
|
* @param {boolean} [optionalSkipHasOwnPropertyCheck]
|
|
764
928
|
* @returns {*[]}
|
|
765
929
|
*/
|
|
@@ -767,59 +931,26 @@ export const LeUtils = {
|
|
|
767
931
|
(elements, callback, optionalSkipHasOwnPropertyCheck = false) =>
|
|
768
932
|
{
|
|
769
933
|
let result = [];
|
|
770
|
-
|
|
934
|
+
LeUtils.each(elements, (value, index) =>
|
|
771
935
|
{
|
|
772
|
-
if(
|
|
773
|
-
{
|
|
774
|
-
for(let index = 0; index < elements.length; index++)
|
|
775
|
-
{
|
|
776
|
-
if(!callback)
|
|
777
|
-
{
|
|
778
|
-
result.push(elements[index]);
|
|
779
|
-
}
|
|
780
|
-
else
|
|
781
|
-
{
|
|
782
|
-
result.push(callback.call(elements[index], elements[index], index));
|
|
783
|
-
}
|
|
784
|
-
}
|
|
785
|
-
}
|
|
786
|
-
else if((typeof elements === 'object') || (typeof elements === 'function'))
|
|
936
|
+
if(!callback)
|
|
787
937
|
{
|
|
788
|
-
|
|
789
|
-
{
|
|
790
|
-
if((optionalSkipHasOwnPropertyCheck === true) || Object.prototype.hasOwnProperty.call(elements, index))
|
|
791
|
-
{
|
|
792
|
-
if(!callback)
|
|
793
|
-
{
|
|
794
|
-
result.push(elements[index]);
|
|
795
|
-
}
|
|
796
|
-
else
|
|
797
|
-
{
|
|
798
|
-
result.push(callback.call(elements[index], elements[index], index));
|
|
799
|
-
}
|
|
800
|
-
}
|
|
801
|
-
}
|
|
938
|
+
result.push(value);
|
|
802
939
|
}
|
|
803
940
|
else
|
|
804
941
|
{
|
|
805
|
-
|
|
942
|
+
result.push(callback.call(value, value, index));
|
|
806
943
|
}
|
|
807
|
-
}
|
|
944
|
+
}, optionalSkipHasOwnPropertyCheck);
|
|
808
945
|
return result;
|
|
809
946
|
},
|
|
810
947
|
|
|
811
|
-
/**
|
|
812
|
-
* @callback LeUtils~__mapToArraySortedCallback
|
|
813
|
-
* @param {*} value
|
|
814
|
-
* @param {*} index
|
|
815
|
-
* @returns {*}
|
|
816
|
-
*/
|
|
817
948
|
/**
|
|
818
949
|
* Loops through the given elements, and returns a new array, with the elements that were returned from the callback. The elements will be sorted by the result from the given comparator. Always returns an array.
|
|
819
950
|
*
|
|
820
|
-
* @param {*
|
|
821
|
-
* @param {
|
|
822
|
-
* @param {
|
|
951
|
+
* @param {*} elements
|
|
952
|
+
* @param {(valueA:*, valueB:*) => number} comparator
|
|
953
|
+
* @param {(value:*, index:*) => *} [callback]
|
|
823
954
|
* @param {boolean} [optionalSkipHasOwnPropertyCheck]
|
|
824
955
|
* @returns {*[]}
|
|
825
956
|
*/
|
|
@@ -828,31 +959,26 @@ export const LeUtils = {
|
|
|
828
959
|
{
|
|
829
960
|
const keys = LeUtils.sortKeys(elements, comparator, optionalSkipHasOwnPropertyCheck);
|
|
830
961
|
let result = [];
|
|
831
|
-
for(
|
|
962
|
+
for(const key of keys)
|
|
832
963
|
{
|
|
964
|
+
const value = LeUtils.getValueAtIndex(elements, key, optionalSkipHasOwnPropertyCheck);
|
|
833
965
|
if(!callback)
|
|
834
966
|
{
|
|
835
|
-
result.push(
|
|
967
|
+
result.push(value);
|
|
836
968
|
}
|
|
837
969
|
else
|
|
838
970
|
{
|
|
839
|
-
result.push(callback.call(
|
|
971
|
+
result.push(callback.call(value, value, key));
|
|
840
972
|
}
|
|
841
973
|
}
|
|
842
974
|
return result;
|
|
843
975
|
},
|
|
844
976
|
|
|
845
|
-
/**
|
|
846
|
-
* @callback LeUtils~__sortKeysComparatorCallback
|
|
847
|
-
* @param {*} elementA
|
|
848
|
-
* @param {*} elementB
|
|
849
|
-
* @returns {number}
|
|
850
|
-
*/
|
|
851
977
|
/**
|
|
852
978
|
* Loops through the given elements, and returns a new array, with the keys from the given elements, sorted by the result from the given comparator. Always returns an array.
|
|
853
979
|
*
|
|
854
|
-
* @param {*
|
|
855
|
-
* @param {
|
|
980
|
+
* @param {*} elements
|
|
981
|
+
* @param {(valueA:*, valueB:*) => number} comparator
|
|
856
982
|
* @param {boolean} [optionalSkipHasOwnPropertyCheck]
|
|
857
983
|
* @returns {*[]}
|
|
858
984
|
*/
|
|
@@ -860,31 +986,12 @@ export const LeUtils = {
|
|
|
860
986
|
(elements, comparator, optionalSkipHasOwnPropertyCheck = false) =>
|
|
861
987
|
{
|
|
862
988
|
let keys = [];
|
|
863
|
-
|
|
989
|
+
LeUtils.each(elements, (value, index) =>
|
|
864
990
|
{
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
keys.push(index);
|
|
870
|
-
}
|
|
871
|
-
}
|
|
872
|
-
else if((typeof elements === 'object') || (typeof elements === 'function'))
|
|
873
|
-
{
|
|
874
|
-
for(let index in elements)
|
|
875
|
-
{
|
|
876
|
-
if((optionalSkipHasOwnPropertyCheck === true) || Object.prototype.hasOwnProperty.call(elements, index))
|
|
877
|
-
{
|
|
878
|
-
keys.push(index);
|
|
879
|
-
}
|
|
880
|
-
}
|
|
881
|
-
}
|
|
882
|
-
else
|
|
883
|
-
{
|
|
884
|
-
console.warn('Executed LeUtils.sortKeys() on an invalid type: [' + (typeof elements) + ']', elements);
|
|
885
|
-
}
|
|
886
|
-
}
|
|
887
|
-
keys.sort((a, b) => comparator(elements[a], elements[b]));
|
|
991
|
+
keys.push(index);
|
|
992
|
+
}, optionalSkipHasOwnPropertyCheck);
|
|
993
|
+
|
|
994
|
+
keys.sort((a, b) => comparator(LeUtils.getValueAtIndex(elements, a, optionalSkipHasOwnPropertyCheck), LeUtils.getValueAtIndex(elements, b, optionalSkipHasOwnPropertyCheck)));
|
|
888
995
|
return keys;
|
|
889
996
|
},
|
|
890
997
|
|
|
@@ -927,6 +1034,46 @@ export const LeUtils = {
|
|
|
927
1034
|
};
|
|
928
1035
|
})(),
|
|
929
1036
|
|
|
1037
|
+
/**
|
|
1038
|
+
* Turns the given value(s) into a 1 dimensional array.
|
|
1039
|
+
*
|
|
1040
|
+
* Compared to LeUtils.flattenArray(), this function also supports objects, Maps, Sets, and other iterable objects.
|
|
1041
|
+
*
|
|
1042
|
+
* @param {*} elements
|
|
1043
|
+
* @param {boolean} [optionalSkipHasOwnPropertyCheck]
|
|
1044
|
+
* @returns {*[]}
|
|
1045
|
+
*/
|
|
1046
|
+
flattenToArray:
|
|
1047
|
+
(() =>
|
|
1048
|
+
{
|
|
1049
|
+
const flattenToArrayRecursive = (result, elements, optionalSkipHasOwnPropertyCheck) =>
|
|
1050
|
+
{
|
|
1051
|
+
if(!LeUtils.supportsEach(elements))
|
|
1052
|
+
{
|
|
1053
|
+
result.push(elements);
|
|
1054
|
+
return;
|
|
1055
|
+
}
|
|
1056
|
+
LeUtils.each(elements, entry =>
|
|
1057
|
+
{
|
|
1058
|
+
flattenToArrayRecursive(result, entry, optionalSkipHasOwnPropertyCheck);
|
|
1059
|
+
}, optionalSkipHasOwnPropertyCheck);
|
|
1060
|
+
};
|
|
1061
|
+
|
|
1062
|
+
return (elements, optionalSkipHasOwnPropertyCheck = false) =>
|
|
1063
|
+
{
|
|
1064
|
+
if(!LeUtils.supportsEach(elements))
|
|
1065
|
+
{
|
|
1066
|
+
return [elements];
|
|
1067
|
+
}
|
|
1068
|
+
let result = [];
|
|
1069
|
+
LeUtils.each(elements, entry =>
|
|
1070
|
+
{
|
|
1071
|
+
flattenToArrayRecursive(result, entry, optionalSkipHasOwnPropertyCheck);
|
|
1072
|
+
}, optionalSkipHasOwnPropertyCheck);
|
|
1073
|
+
return result;
|
|
1074
|
+
};
|
|
1075
|
+
})(),
|
|
1076
|
+
|
|
930
1077
|
/**
|
|
931
1078
|
* Compares two values. Primarily used for sorting.
|
|
932
1079
|
*
|
|
@@ -957,13 +1104,26 @@ export const LeUtils = {
|
|
|
957
1104
|
compareNumericStrings:
|
|
958
1105
|
(a, b) =>
|
|
959
1106
|
{
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
1107
|
+
const aParts = STRING(a).split('.');
|
|
1108
|
+
const bParts = STRING(b).split('.');
|
|
1109
|
+
for(let i = 0; i < Math.min(aParts.length, bParts.length); i++)
|
|
1110
|
+
{
|
|
1111
|
+
a = aParts[i].trim();
|
|
1112
|
+
b = bParts[i].trim();
|
|
1113
|
+
if(a.length !== b.length)
|
|
1114
|
+
{
|
|
1115
|
+
return (a.length < b.length) ? -1 : 1;
|
|
1116
|
+
}
|
|
1117
|
+
if(a !== b)
|
|
1118
|
+
{
|
|
1119
|
+
return (a < b) ? -1 : 1;
|
|
1120
|
+
}
|
|
1121
|
+
}
|
|
1122
|
+
if(aParts.length !== bParts.length)
|
|
963
1123
|
{
|
|
964
|
-
return (
|
|
1124
|
+
return (aParts.length < bParts.length) ? -1 : 1;
|
|
965
1125
|
}
|
|
966
|
-
return
|
|
1126
|
+
return 0;
|
|
967
1127
|
},
|
|
968
1128
|
|
|
969
1129
|
/**
|
|
@@ -1043,9 +1203,9 @@ export const LeUtils = {
|
|
|
1043
1203
|
{
|
|
1044
1204
|
}.constructor;
|
|
1045
1205
|
|
|
1046
|
-
const PossibleGeneratorFunctionNames = Array.from(new Set(['GeneratorFunction', 'AsyncFunction', 'AsyncGeneratorFunction', GeneratorFunction.name,
|
|
1206
|
+
const PossibleGeneratorFunctionNames = Array.from(new Set(['GeneratorFunction', 'AsyncFunction', 'AsyncGeneratorFunction', GeneratorFunction.name, AsyncGeneratorFunction.name])).filter((element) =>
|
|
1047
1207
|
{
|
|
1048
|
-
return (element && (element !== RegularFunction.name)
|
|
1208
|
+
return (element && (element !== RegularFunction.name));
|
|
1049
1209
|
});
|
|
1050
1210
|
|
|
1051
1211
|
return (func) =>
|
|
@@ -1059,20 +1219,17 @@ export const LeUtils = {
|
|
|
1059
1219
|
{
|
|
1060
1220
|
return false;
|
|
1061
1221
|
}
|
|
1222
|
+
// noinspection JSUnresolvedVariable
|
|
1062
1223
|
return ((constructor.name && PossibleGeneratorFunctionNames.includes(constructor.name)) || (constructor.displayName && PossibleGeneratorFunctionNames.includes(constructor.displayName)));
|
|
1063
1224
|
};
|
|
1064
1225
|
})(),
|
|
1065
1226
|
|
|
1066
|
-
/**
|
|
1067
|
-
* @callback LeUtils~__setTimeoutCallback
|
|
1068
|
-
* @param {number} deltaTime
|
|
1069
|
-
*/
|
|
1070
1227
|
/**
|
|
1071
1228
|
* Executes the callback after the given number of milliseconds. Passes the elapsed time in seconds to the callback.
|
|
1072
1229
|
*
|
|
1073
1230
|
* To cancel the timeout, call remove() on the result of this function (example: "const timeoutHandler = LeUtils.setTimeout((deltaTime)=>{}, 1000); timeoutHandler.remove();")
|
|
1074
1231
|
*
|
|
1075
|
-
* @param {
|
|
1232
|
+
* @param {(deltaTime:number) => *} callback
|
|
1076
1233
|
* @param {number} ms
|
|
1077
1234
|
* @returns {{remove:Function}}
|
|
1078
1235
|
*/
|
|
@@ -1091,6 +1248,7 @@ export const LeUtils = {
|
|
|
1091
1248
|
ms = FLOAT_LAX(ms);
|
|
1092
1249
|
|
|
1093
1250
|
let lastTime = performance.now();
|
|
1251
|
+
/** @type {number|null} */
|
|
1094
1252
|
let handler = window.setTimeout(() =>
|
|
1095
1253
|
{
|
|
1096
1254
|
const currentTime = performance.now();
|
|
@@ -1118,16 +1276,12 @@ export const LeUtils = {
|
|
|
1118
1276
|
};
|
|
1119
1277
|
},
|
|
1120
1278
|
|
|
1121
|
-
/**
|
|
1122
|
-
* @callback LeUtils~__setIntervalCallback
|
|
1123
|
-
* @param {number} deltaTime
|
|
1124
|
-
*/
|
|
1125
1279
|
/**
|
|
1126
1280
|
* Executes the callback every given number of milliseconds. Passes the time difference in seconds between the last frame and now to it.
|
|
1127
1281
|
*
|
|
1128
1282
|
* To remove the interval, call remove() on the result of this function (example: "const intervalHandler = LeUtils.setInterval((deltaTime)=>{}, 1000); intervalHandler.remove();")
|
|
1129
1283
|
*
|
|
1130
|
-
* @param {
|
|
1284
|
+
* @param {(deltaTime:number) => *} callback
|
|
1131
1285
|
* @param {number} [intervalMs]
|
|
1132
1286
|
* @param {boolean} [fireImmediately]
|
|
1133
1287
|
* @returns {{remove:Function}}
|
|
@@ -1159,6 +1313,7 @@ export const LeUtils = {
|
|
|
1159
1313
|
}
|
|
1160
1314
|
|
|
1161
1315
|
let lastTime = performance.now();
|
|
1316
|
+
/** @type {number|null} */
|
|
1162
1317
|
let handler = window.setInterval(() =>
|
|
1163
1318
|
{
|
|
1164
1319
|
const currentTime = performance.now();
|
|
@@ -1186,16 +1341,12 @@ export const LeUtils = {
|
|
|
1186
1341
|
};
|
|
1187
1342
|
},
|
|
1188
1343
|
|
|
1189
|
-
/**
|
|
1190
|
-
* @callback LeUtils~__setAnimationFrameTimeoutCallback
|
|
1191
|
-
* @param {number} deltaTime
|
|
1192
|
-
*/
|
|
1193
1344
|
/**
|
|
1194
1345
|
* Executes the callback after the given number of frames. Passes the elapsed time in seconds to the callback.
|
|
1195
1346
|
*
|
|
1196
1347
|
* To cancel the timeout, call remove() on the result of this function (example: "const timeoutHandler = LeUtils.setAnimationFrameTimeout((deltaTime){}, 5); timeoutHandler.remove();")
|
|
1197
1348
|
*
|
|
1198
|
-
* @param {
|
|
1349
|
+
* @param {(deltaTime:number) => *} callback
|
|
1199
1350
|
* @param {number} [frames]
|
|
1200
1351
|
* @returns {{remove:Function}}
|
|
1201
1352
|
*/
|
|
@@ -1256,16 +1407,12 @@ export const LeUtils = {
|
|
|
1256
1407
|
};
|
|
1257
1408
|
},
|
|
1258
1409
|
|
|
1259
|
-
/**
|
|
1260
|
-
* @callback LeUtils~__setAnimationFrameIntervalCallback
|
|
1261
|
-
* @param {number} deltaTime
|
|
1262
|
-
*/
|
|
1263
1410
|
/**
|
|
1264
1411
|
* Executes the callback every given number of frames. Passes the time difference in seconds between the last frame and now to it.
|
|
1265
1412
|
*
|
|
1266
1413
|
* To remove the interval, call remove() on the result of this function (example: "const intervalHandler = LeUtils.setAnimationFrameInterval((deltaTime)=>{}, 5); intervalHandler.remove();")
|
|
1267
1414
|
*
|
|
1268
|
-
* @param {
|
|
1415
|
+
* @param {(deltaTime:number) => *} callback
|
|
1269
1416
|
* @param {number} [intervalFrames]
|
|
1270
1417
|
* @param {boolean} [fireImmediately]
|
|
1271
1418
|
* @returns {{remove:Function}}
|
|
@@ -1346,7 +1493,7 @@ export const LeUtils = {
|
|
|
1346
1493
|
* Returns a promise, which will be resolved after the given number of milliseconds.
|
|
1347
1494
|
*
|
|
1348
1495
|
* @param {number} ms
|
|
1349
|
-
* @returns {Promise}
|
|
1496
|
+
* @returns {Promise<number>}
|
|
1350
1497
|
*/
|
|
1351
1498
|
promiseTimeout:
|
|
1352
1499
|
(ms) =>
|
|
@@ -1354,7 +1501,7 @@ export const LeUtils = {
|
|
|
1354
1501
|
ms = FLOAT_LAX(ms);
|
|
1355
1502
|
if(ms <= 0)
|
|
1356
1503
|
{
|
|
1357
|
-
return new Promise(resolve => resolve(
|
|
1504
|
+
return new Promise(resolve => resolve(0));
|
|
1358
1505
|
}
|
|
1359
1506
|
return new Promise(resolve => LeUtils.setTimeout(resolve, ms));
|
|
1360
1507
|
},
|
|
@@ -1363,7 +1510,7 @@ export const LeUtils = {
|
|
|
1363
1510
|
* Returns a promise, which will be resolved after the given number of frames.
|
|
1364
1511
|
*
|
|
1365
1512
|
* @param {number} frames
|
|
1366
|
-
* @returns {Promise}
|
|
1513
|
+
* @returns {Promise<number>}
|
|
1367
1514
|
*/
|
|
1368
1515
|
promiseAnimationFrameTimeout:
|
|
1369
1516
|
(frames) =>
|
|
@@ -1371,7 +1518,7 @@ export const LeUtils = {
|
|
|
1371
1518
|
frames = INT_LAX(frames);
|
|
1372
1519
|
if(frames <= 0)
|
|
1373
1520
|
{
|
|
1374
|
-
return new Promise(resolve => resolve(
|
|
1521
|
+
return new Promise(resolve => resolve(0));
|
|
1375
1522
|
}
|
|
1376
1523
|
return new Promise(resolve => LeUtils.setAnimationFrameTimeout(resolve, frames));
|
|
1377
1524
|
},
|
|
@@ -1380,7 +1527,7 @@ export const LeUtils = {
|
|
|
1380
1527
|
* Allows you to do a fetch, with built-in retry and abort functionality.
|
|
1381
1528
|
*
|
|
1382
1529
|
* @param {string} url
|
|
1383
|
-
* @param {
|
|
1530
|
+
* @param {{retries?:number|null, delay?:number|((attempt:number)=>number)|null}|object|null} [options]
|
|
1384
1531
|
* @returns {{then:Function, catch:Function, finally:Function, remove:Function, isRemoved:Function}}
|
|
1385
1532
|
*/
|
|
1386
1533
|
fetch:
|
|
@@ -1466,6 +1613,68 @@ export const LeUtils = {
|
|
|
1466
1613
|
return result;
|
|
1467
1614
|
},
|
|
1468
1615
|
|
|
1616
|
+
/**
|
|
1617
|
+
* Allows you to do a fetch, with built-in retry functionality. Caches on the requested URL, so that the same URL will not be fetched multiple times.
|
|
1618
|
+
*
|
|
1619
|
+
* @param {string} url
|
|
1620
|
+
* @param {{retries?:number|null, delay?:number|((attempt:number)=>number)|null, [verify]:((data:*,response:*)=>void)|null}|null} [options]
|
|
1621
|
+
* @param {((response:*)=>*)|null} [responseFunction] A function that will be called with the response object, and should return the data to be cached.
|
|
1622
|
+
* @returns {Promise<*>}
|
|
1623
|
+
*/
|
|
1624
|
+
cachedFetch:
|
|
1625
|
+
(() =>
|
|
1626
|
+
{
|
|
1627
|
+
const cache = new Map();
|
|
1628
|
+
return async (url, options, responseFunction) =>
|
|
1629
|
+
{
|
|
1630
|
+
if(cache.has(url))
|
|
1631
|
+
{
|
|
1632
|
+
const result = cache.get(url);
|
|
1633
|
+
if(result.data)
|
|
1634
|
+
{
|
|
1635
|
+
return result.data;
|
|
1636
|
+
}
|
|
1637
|
+
if(result.promise)
|
|
1638
|
+
{
|
|
1639
|
+
return await result.promise;
|
|
1640
|
+
}
|
|
1641
|
+
if(result.error)
|
|
1642
|
+
{
|
|
1643
|
+
throw result.error;
|
|
1644
|
+
}
|
|
1645
|
+
console.warn('Failed to use the cachedFetch cache, for URL: ', url, ', it is in an unexpected state: ', result);
|
|
1646
|
+
return null;
|
|
1647
|
+
}
|
|
1648
|
+
|
|
1649
|
+
const promise = LeUtils.fetch(url, options)
|
|
1650
|
+
.then(async response =>
|
|
1651
|
+
{
|
|
1652
|
+
const data = responseFunction ? (await responseFunction(response)) : response;
|
|
1653
|
+
if(typeof options?.verify === 'function')
|
|
1654
|
+
{
|
|
1655
|
+
await options.verify(data, response);
|
|
1656
|
+
}
|
|
1657
|
+
return data;
|
|
1658
|
+
})
|
|
1659
|
+
.then(data =>
|
|
1660
|
+
{
|
|
1661
|
+
cache.set(url, {data});
|
|
1662
|
+
return data;
|
|
1663
|
+
})
|
|
1664
|
+
.catch(error =>
|
|
1665
|
+
{
|
|
1666
|
+
cache.set(url, {error});
|
|
1667
|
+
console.error('Failed to fetch: ', error);
|
|
1668
|
+
throw error;
|
|
1669
|
+
});
|
|
1670
|
+
if(!cache.has(url))
|
|
1671
|
+
{
|
|
1672
|
+
cache.set(url, {promise});
|
|
1673
|
+
}
|
|
1674
|
+
return await promise;
|
|
1675
|
+
};
|
|
1676
|
+
})(),
|
|
1677
|
+
|
|
1469
1678
|
/**
|
|
1470
1679
|
* Returns true if the user is on a smartphone device (mobile).
|
|
1471
1680
|
* Will return false if the user is on a tablet or on a desktop.
|
|
@@ -1732,7 +1941,7 @@ export const LeUtils = {
|
|
|
1732
1941
|
* - foo-bar
|
|
1733
1942
|
* - foo_bar
|
|
1734
1943
|
*
|
|
1735
|
-
* @param {string} names
|
|
1944
|
+
* @param {string[]} names
|
|
1736
1945
|
* @returns {string[]}
|
|
1737
1946
|
*/
|
|
1738
1947
|
generateNamePermutations:
|
|
@@ -1790,7 +1999,7 @@ export const LeUtils = {
|
|
|
1790
1999
|
}
|
|
1791
2000
|
if(c < '9')
|
|
1792
2001
|
{
|
|
1793
|
-
c
|
|
2002
|
+
c = String.fromCharCode(c.charCodeAt(0) + 1);
|
|
1794
2003
|
string = string.substring(0, i) + c + string.substring(i + 1);// string[i] = (char + 1);
|
|
1795
2004
|
break;
|
|
1796
2005
|
}
|
|
@@ -1812,7 +2021,7 @@ export const LeUtils = {
|
|
|
1812
2021
|
(() =>
|
|
1813
2022
|
{
|
|
1814
2023
|
let previousUniqueIdsTime = null;
|
|
1815
|
-
let previousUniqueIds =
|
|
2024
|
+
let previousUniqueIds = new Map();
|
|
1816
2025
|
|
|
1817
2026
|
const numberToBytes = (number) =>
|
|
1818
2027
|
{
|
|
@@ -1896,12 +2105,13 @@ export const LeUtils = {
|
|
|
1896
2105
|
if(previousUniqueIdsTime !== result.time)
|
|
1897
2106
|
{
|
|
1898
2107
|
previousUniqueIdsTime = result.time;
|
|
1899
|
-
previousUniqueIds
|
|
2108
|
+
previousUniqueIds.clear();
|
|
2109
|
+
previousUniqueIds.set(result.id, true);
|
|
1900
2110
|
return result.id;
|
|
1901
2111
|
}
|
|
1902
|
-
else if(previousUniqueIds
|
|
2112
|
+
else if(previousUniqueIds.get(result.id) !== true)
|
|
1903
2113
|
{
|
|
1904
|
-
previousUniqueIds
|
|
2114
|
+
previousUniqueIds.set(result.id, true);
|
|
1905
2115
|
return result.id;
|
|
1906
2116
|
}
|
|
1907
2117
|
}
|
|
@@ -1931,7 +2141,7 @@ export const LeUtils = {
|
|
|
1931
2141
|
return bytes;
|
|
1932
2142
|
};
|
|
1933
2143
|
|
|
1934
|
-
return (now = null) =>
|
|
2144
|
+
return (/** @type {number|null|undefined} */ now = null) =>
|
|
1935
2145
|
{
|
|
1936
2146
|
if(ISSET(now))
|
|
1937
2147
|
{
|
|
@@ -1988,7 +2198,7 @@ export const LeUtils = {
|
|
|
1988
2198
|
{
|
|
1989
2199
|
part = FLOAT_LAX(part);
|
|
1990
2200
|
total = FLOAT_LAX(total);
|
|
1991
|
-
if(total
|
|
2201
|
+
if(total === 0)
|
|
1992
2202
|
{
|
|
1993
2203
|
return 100;
|
|
1994
2204
|
}
|
|
@@ -2015,22 +2225,18 @@ export const LeUtils = {
|
|
|
2015
2225
|
const ctx = canvas.getContext('2d');
|
|
2016
2226
|
const width = Math.floor(image.width);
|
|
2017
2227
|
const height = Math.floor(image.height);
|
|
2018
|
-
if((width <= 0) || (height <= 0))
|
|
2019
|
-
{
|
|
2020
|
-
canvas.width = 1;
|
|
2021
|
-
canvas.height = 1;
|
|
2022
|
-
}
|
|
2023
|
-
else
|
|
2228
|
+
if(!ctx || (width <= 0) || (height <= 0))
|
|
2024
2229
|
{
|
|
2025
|
-
|
|
2026
|
-
canvas.height = height;
|
|
2027
|
-
ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
|
|
2230
|
+
return new Uint8ClampedArray();
|
|
2028
2231
|
}
|
|
2232
|
+
canvas.width = width;
|
|
2233
|
+
canvas.height = height;
|
|
2234
|
+
ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
|
|
2029
2235
|
return ctx.getImageData(0, 0, canvas.width, canvas.height).data;
|
|
2030
2236
|
}
|
|
2031
2237
|
finally
|
|
2032
2238
|
{
|
|
2033
|
-
canvas
|
|
2239
|
+
canvas?.parentNode?.removeChild(canvas);
|
|
2034
2240
|
}
|
|
2035
2241
|
},
|
|
2036
2242
|
|
|
@@ -2055,17 +2261,13 @@ export const LeUtils = {
|
|
|
2055
2261
|
const ctx = canvas.getContext('2d');
|
|
2056
2262
|
const width = Math.floor(image.width);
|
|
2057
2263
|
const height = Math.floor(image.height);
|
|
2058
|
-
if((width <= 0) || (height <= 0))
|
|
2264
|
+
if(!ctx || (width <= 0) || (height <= 0))
|
|
2059
2265
|
{
|
|
2060
|
-
|
|
2061
|
-
canvas.height = 1;
|
|
2062
|
-
}
|
|
2063
|
-
else
|
|
2064
|
-
{
|
|
2065
|
-
canvas.width = width;
|
|
2066
|
-
canvas.height = height;
|
|
2067
|
-
ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
|
|
2266
|
+
return LeUtils.getEmptyImageSrc();
|
|
2068
2267
|
}
|
|
2268
|
+
canvas.width = width;
|
|
2269
|
+
canvas.height = height;
|
|
2270
|
+
ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
|
|
2069
2271
|
ctx.globalCompositeOperation = 'source-in';
|
|
2070
2272
|
ctx.fillStyle = color;
|
|
2071
2273
|
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
|
@@ -2073,7 +2275,7 @@ export const LeUtils = {
|
|
|
2073
2275
|
}
|
|
2074
2276
|
finally
|
|
2075
2277
|
{
|
|
2076
|
-
canvas
|
|
2278
|
+
canvas?.parentNode?.removeChild(canvas);
|
|
2077
2279
|
}
|
|
2078
2280
|
},
|
|
2079
2281
|
|
|
@@ -2102,13 +2304,18 @@ export const LeUtils = {
|
|
|
2102
2304
|
hexToRgb:
|
|
2103
2305
|
(hexstring) =>
|
|
2104
2306
|
{
|
|
2307
|
+
const initialHexstring = hexstring;
|
|
2105
2308
|
hexstring = hexstring.replace(/[^0-9A-F]/gi, '');
|
|
2106
2309
|
const hasAlpha = ((hexstring.length === 4) || (hexstring.length === 8));
|
|
2107
2310
|
while(hexstring.length < 6)
|
|
2108
2311
|
{
|
|
2109
2312
|
hexstring = hexstring.replace(/(.)/g, '$1$1');
|
|
2110
2313
|
}
|
|
2111
|
-
const result = hexstring.match(/\w{2}/g)
|
|
2314
|
+
const result = hexstring.match(/\w{2}/g)?.map((a) => parseInt(a, 16));
|
|
2315
|
+
if(!result || (result.length < 3))
|
|
2316
|
+
{
|
|
2317
|
+
throw new Error('Invalid hex color: "' + hexstring + '" (was given "' + initialHexstring + '")');
|
|
2318
|
+
}
|
|
2112
2319
|
return [
|
|
2113
2320
|
result[0],
|
|
2114
2321
|
result[1],
|
|
@@ -2131,12 +2338,10 @@ export const LeUtils = {
|
|
|
2131
2338
|
const b = rgb[2] / 255;
|
|
2132
2339
|
const max = Math.max(r, g, b);
|
|
2133
2340
|
const min = Math.min(r, g, b);
|
|
2134
|
-
let h
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
}
|
|
2139
|
-
else
|
|
2341
|
+
let h = 0;
|
|
2342
|
+
let s = 0;
|
|
2343
|
+
let l = (max + min) / 2;
|
|
2344
|
+
if(max !== min)
|
|
2140
2345
|
{
|
|
2141
2346
|
const d = max - min;
|
|
2142
2347
|
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
|
|
@@ -2195,12 +2400,10 @@ export const LeUtils = {
|
|
|
2195
2400
|
const h = hsl[0];
|
|
2196
2401
|
const s = hsl[1];
|
|
2197
2402
|
const l = hsl[2];
|
|
2198
|
-
let r
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
}
|
|
2203
|
-
else
|
|
2403
|
+
let r = 1;
|
|
2404
|
+
let g = 1;
|
|
2405
|
+
let b = 1;
|
|
2406
|
+
if(s !== 0)
|
|
2204
2407
|
{
|
|
2205
2408
|
const q = (l < 0.5) ? (l * (1 + s)) : (l + s - (l * s));
|
|
2206
2409
|
const p = (2 * l) - q;
|
|
@@ -2241,13 +2444,13 @@ export const LeUtils = {
|
|
|
2241
2444
|
*
|
|
2242
2445
|
* Returns a number:
|
|
2243
2446
|
*
|
|
2244
|
-
*
|
|
2245
|
-
* < 1
|
|
2447
|
+
* ```js
|
|
2448
|
+
* < 1 is not perceptible by human eyes
|
|
2246
2449
|
* 1-2 is perceptible through close observation
|
|
2247
2450
|
* 2-10 is perceptible at a glance
|
|
2248
2451
|
* 11-49 is more similar than opposite
|
|
2249
2452
|
* 100 is exactly the opposite color
|
|
2250
|
-
*
|
|
2453
|
+
* ```
|
|
2251
2454
|
*
|
|
2252
2455
|
* @param {number[]} rgbA
|
|
2253
2456
|
* @param {number[]} rgbB
|
|
@@ -2266,13 +2469,13 @@ export const LeUtils = {
|
|
|
2266
2469
|
*
|
|
2267
2470
|
* Returns a number:
|
|
2268
2471
|
*
|
|
2269
|
-
*
|
|
2270
|
-
* < 1
|
|
2472
|
+
* ```js
|
|
2473
|
+
* < 1 is not perceptible by human eyes
|
|
2271
2474
|
* 1-2 is perceptible through close observation
|
|
2272
2475
|
* 2-10 is perceptible at a glance
|
|
2273
2476
|
* 11-49 is more similar than opposite
|
|
2274
2477
|
* 100 is exactly the opposite color
|
|
2275
|
-
*
|
|
2478
|
+
* ```
|
|
2276
2479
|
*
|
|
2277
2480
|
* @param {number[]} labA
|
|
2278
2481
|
* @param {number[]} labB
|
|
@@ -2304,16 +2507,16 @@ export const LeUtils = {
|
|
|
2304
2507
|
*
|
|
2305
2508
|
* Usage:
|
|
2306
2509
|
*
|
|
2307
|
-
*
|
|
2510
|
+
* ```js
|
|
2308
2511
|
* LeUtils.getRgbOfGradient({
|
|
2309
2512
|
* 0: [255, 0, 0],
|
|
2310
2513
|
* 33: [255, 255, 0],
|
|
2311
2514
|
* 66: [0, 255, 0],
|
|
2312
2515
|
* 100:[0, 255, 255],
|
|
2313
2516
|
* }, 45.1234);
|
|
2314
|
-
*
|
|
2517
|
+
* ```
|
|
2315
2518
|
*
|
|
2316
|
-
* @param {{
|
|
2519
|
+
* @param {{percentage?:number[]}} gradient
|
|
2317
2520
|
* @param {number} percentage
|
|
2318
2521
|
* @returns {number[]}
|
|
2319
2522
|
*/
|
|
@@ -2341,12 +2544,14 @@ export const LeUtils = {
|
|
|
2341
2544
|
});
|
|
2342
2545
|
if(closest === null)
|
|
2343
2546
|
{
|
|
2344
|
-
return
|
|
2547
|
+
return [0, 0, 0];
|
|
2345
2548
|
}
|
|
2346
2549
|
closest = closest[0];
|
|
2347
2550
|
|
|
2348
|
-
|
|
2349
|
-
|
|
2551
|
+
const HIGHER = 99999;
|
|
2552
|
+
const LOWER = -99999;
|
|
2553
|
+
let higher = HIGHER;
|
|
2554
|
+
let lower = LOWER;
|
|
2350
2555
|
LeUtils.each(gradient, (color, percent) =>
|
|
2351
2556
|
{
|
|
2352
2557
|
percent = INT_LAX(percent);
|
|
@@ -2365,20 +2570,12 @@ export const LeUtils = {
|
|
|
2365
2570
|
}
|
|
2366
2571
|
}
|
|
2367
2572
|
});
|
|
2368
|
-
if(higher === 99999)
|
|
2369
|
-
{
|
|
2370
|
-
higher = null;
|
|
2371
|
-
}
|
|
2372
|
-
if(lower === -99999)
|
|
2373
|
-
{
|
|
2374
|
-
lower = null;
|
|
2375
|
-
}
|
|
2376
2573
|
|
|
2377
|
-
if(((higher ===
|
|
2574
|
+
if(((higher === HIGHER) && (lower === LOWER)) || (higher === lower))
|
|
2378
2575
|
{
|
|
2379
2576
|
return gradient[closest];
|
|
2380
2577
|
}
|
|
2381
|
-
else if((higher !==
|
|
2578
|
+
else if((higher !== HIGHER) && (lower !== LOWER))
|
|
2382
2579
|
{
|
|
2383
2580
|
const higherDifference = Math.abs(higher - percentage);
|
|
2384
2581
|
const lowerDifference = Math.abs(percentage - lower);
|
|
@@ -2391,7 +2588,7 @@ export const LeUtils = {
|
|
|
2391
2588
|
lower = closest;
|
|
2392
2589
|
}
|
|
2393
2590
|
}
|
|
2394
|
-
else if(lower ===
|
|
2591
|
+
else if(lower === LOWER)
|
|
2395
2592
|
{
|
|
2396
2593
|
lower = closest;
|
|
2397
2594
|
}
|
|
@@ -2512,7 +2709,12 @@ export const LeUtils = {
|
|
|
2512
2709
|
hexToBase64:
|
|
2513
2710
|
(hexstring) =>
|
|
2514
2711
|
{
|
|
2515
|
-
|
|
2712
|
+
const hexResult = hexstring.replace(/[^0-9A-F]/gi, '').match(/\w{2}/g)?.map((a) => String.fromCharCode(parseInt(a, 16)))?.join('');
|
|
2713
|
+
if(!hexResult)
|
|
2714
|
+
{
|
|
2715
|
+
throw new Error('Invalid hex string: "' + hexstring + '"');
|
|
2716
|
+
}
|
|
2717
|
+
return LeUtils.btoa(hexResult);
|
|
2516
2718
|
},
|
|
2517
2719
|
|
|
2518
2720
|
/**
|
|
@@ -2537,7 +2739,7 @@ export const LeUtils = {
|
|
|
2537
2739
|
/**
|
|
2538
2740
|
* Converts bytes into a base64 string.
|
|
2539
2741
|
*
|
|
2540
|
-
* @param {ArrayLike<number>|
|
|
2742
|
+
* @param {ArrayLike<number>|ArrayBuffer} arraybuffer
|
|
2541
2743
|
* @returns {string}
|
|
2542
2744
|
*/
|
|
2543
2745
|
bytesToBase64:
|
|
@@ -2594,11 +2796,7 @@ export const LeUtils = {
|
|
|
2594
2796
|
}
|
|
2595
2797
|
try
|
|
2596
2798
|
{
|
|
2597
|
-
|
|
2598
|
-
if(typeof result['-'] !== 'undefined')
|
|
2599
|
-
{
|
|
2600
|
-
return result['-'];
|
|
2601
|
-
}
|
|
2799
|
+
return JSON.parse(result)?.['-'];
|
|
2602
2800
|
}
|
|
2603
2801
|
catch(e)
|
|
2604
2802
|
{
|
|
@@ -2707,8 +2905,8 @@ export const LeUtils = {
|
|
|
2707
2905
|
* This way, you can have values that aren't the same be treated as if they are. This can be used to deal with issues such as floating point errors for example.
|
|
2708
2906
|
*
|
|
2709
2907
|
* @param {*[]} elements
|
|
2710
|
-
* @param {
|
|
2711
|
-
* @returns {{getElements:
|
|
2908
|
+
* @param {(valueA:*, valueB:*) => number} comparator
|
|
2909
|
+
* @returns {{getElements:(()=>*[]), getComparator:(()=>((valueA:*,valueB:*)=>number)), size:(()=>number), isEmpty:(()=>boolean), contains:((value:*)=>boolean), first:(()=>*|undefined), last:(()=>*|undefined), pollFirst:(()=>*|undefined), pollLast:(()=>*|undefined), add:((value:*)=>void), addAll:((values:*)=>void), getEqualValue:((value:*)=>*), getEqualValueOrAdd:((value:*)=>*)}}
|
|
2712
2910
|
*/
|
|
2713
2911
|
createTreeSet:
|
|
2714
2912
|
(elements, comparator) =>
|
|
@@ -2760,7 +2958,7 @@ export const LeUtils = {
|
|
|
2760
2958
|
/**
|
|
2761
2959
|
* Returns the comparator of the set.
|
|
2762
2960
|
*
|
|
2763
|
-
* @returns {
|
|
2961
|
+
* @returns {(valueA:*, valueB:*) => number}
|
|
2764
2962
|
*/
|
|
2765
2963
|
getComparator:
|
|
2766
2964
|
() => comparator,
|
|
@@ -2841,7 +3039,7 @@ export const LeUtils = {
|
|
|
2841
3039
|
/**
|
|
2842
3040
|
* Adds all the given values to the set. Will only do so if no equal value already exists.
|
|
2843
3041
|
*
|
|
2844
|
-
* @param {*
|
|
3042
|
+
* @param {*} values
|
|
2845
3043
|
*/
|
|
2846
3044
|
addAll:
|
|
2847
3045
|
(values) =>
|
|
@@ -2888,7 +3086,7 @@ export const LeUtils = {
|
|
|
2888
3086
|
},
|
|
2889
3087
|
|
|
2890
3088
|
/**
|
|
2891
|
-
* @typedef {Object}
|
|
3089
|
+
* @typedef {Object} LeUtils_TransactionalValue
|
|
2892
3090
|
* @property {*} value
|
|
2893
3091
|
* @property {{id:string, value:*}[]} changes
|
|
2894
3092
|
*/
|
|
@@ -2901,7 +3099,7 @@ export const LeUtils = {
|
|
|
2901
3099
|
* This allows you to make multiple unconfirmed changes, and confirm or cancel each of them individually at any time.
|
|
2902
3100
|
*
|
|
2903
3101
|
* @param {*} [value]
|
|
2904
|
-
* @returns {
|
|
3102
|
+
* @returns {LeUtils_TransactionalValue}
|
|
2905
3103
|
*/
|
|
2906
3104
|
createTransactionalValue:
|
|
2907
3105
|
(value) =>
|
|
@@ -2916,7 +3114,7 @@ export const LeUtils = {
|
|
|
2916
3114
|
/**
|
|
2917
3115
|
* Returns true if the given value is a valid TransactionalValue, returns false if it isn't.
|
|
2918
3116
|
*
|
|
2919
|
-
* @param {
|
|
3117
|
+
* @param {LeUtils_TransactionalValue} transactionalValue
|
|
2920
3118
|
* @returns {boolean}
|
|
2921
3119
|
*/
|
|
2922
3120
|
isTransactionalValueValid:
|
|
@@ -2928,7 +3126,7 @@ export const LeUtils = {
|
|
|
2928
3126
|
/**
|
|
2929
3127
|
* Returns true if the given value is a TransactionalValue, false otherwise.
|
|
2930
3128
|
*
|
|
2931
|
-
* @param {
|
|
3129
|
+
* @param {LeUtils_TransactionalValue} transactionalValue
|
|
2932
3130
|
* @returns {string}
|
|
2933
3131
|
*/
|
|
2934
3132
|
transactionalValueToString:
|
|
@@ -2953,7 +3151,7 @@ export const LeUtils = {
|
|
|
2953
3151
|
/**
|
|
2954
3152
|
* Sets the committed value of the given TransactionalValue to the given value. Clears out the previously uncommitted changes.
|
|
2955
3153
|
*
|
|
2956
|
-
* @param {
|
|
3154
|
+
* @param {LeUtils_TransactionalValue} transactionalValue
|
|
2957
3155
|
* @param {*} value
|
|
2958
3156
|
*/
|
|
2959
3157
|
transactionSetAndCommit:
|
|
@@ -2972,7 +3170,7 @@ export const LeUtils = {
|
|
|
2972
3170
|
* Sets the value of the given TransactionalValue to the given value, without yet committing it, meaning it can be committed or cancelled later.
|
|
2973
3171
|
* It returns the ID of the change, which can be used to commit or cancel the change later.
|
|
2974
3172
|
*
|
|
2975
|
-
* @param {
|
|
3173
|
+
* @param {LeUtils_TransactionalValue} transactionalValue
|
|
2976
3174
|
* @param {*} value
|
|
2977
3175
|
* @returns {string}
|
|
2978
3176
|
*/
|
|
@@ -2993,7 +3191,7 @@ export const LeUtils = {
|
|
|
2993
3191
|
* Commits the change with the given ID, making it the new committed value.
|
|
2994
3192
|
* Returns true if the change was found and committed, returns false if it was already overwritten by a newer committed change.
|
|
2995
3193
|
*
|
|
2996
|
-
* @param {
|
|
3194
|
+
* @param {LeUtils_TransactionalValue} transactionalValue
|
|
2997
3195
|
* @param {string} changeId
|
|
2998
3196
|
* @returns {boolean}
|
|
2999
3197
|
*/
|
|
@@ -3015,7 +3213,7 @@ export const LeUtils = {
|
|
|
3015
3213
|
* Cancels the change with the given ID, removing it from the uncommitted changes.
|
|
3016
3214
|
* Returns true if the change was found and removed, returns false if it was already overwritten by a newer committed change.
|
|
3017
3215
|
*
|
|
3018
|
-
* @param {
|
|
3216
|
+
* @param {LeUtils_TransactionalValue} transactionalValue
|
|
3019
3217
|
* @param {string} changeId
|
|
3020
3218
|
* @returns {boolean}
|
|
3021
3219
|
*/
|
|
@@ -3036,7 +3234,7 @@ export const LeUtils = {
|
|
|
3036
3234
|
* Returns true if the change was found, meaning it can still make a difference to the final committed value of this TransactionalValue.
|
|
3037
3235
|
* Returns false if it was already overwritten by a newer committed change, meaning that this change can no longer make a difference to the final committed value of this TransactionalValue.
|
|
3038
3236
|
*
|
|
3039
|
-
* @param {
|
|
3237
|
+
* @param {LeUtils_TransactionalValue} transactionalValue
|
|
3040
3238
|
* @param {string} changeId
|
|
3041
3239
|
* @returns {boolean}
|
|
3042
3240
|
*/
|
|
@@ -3050,7 +3248,7 @@ export const LeUtils = {
|
|
|
3050
3248
|
/**
|
|
3051
3249
|
* Returns the committed value of the given TransactionalValue.
|
|
3052
3250
|
*
|
|
3053
|
-
* @param {
|
|
3251
|
+
* @param {LeUtils_TransactionalValue} transactionalValue
|
|
3054
3252
|
* @returns {*}
|
|
3055
3253
|
*/
|
|
3056
3254
|
transactionGetCommittedValue:
|
|
@@ -3063,7 +3261,7 @@ export const LeUtils = {
|
|
|
3063
3261
|
/**
|
|
3064
3262
|
* Returns the value (including any uncommitted changes made to it) of the given TransactionalValue.
|
|
3065
3263
|
*
|
|
3066
|
-
* @param {
|
|
3264
|
+
* @param {LeUtils_TransactionalValue} transactionalValue
|
|
3067
3265
|
* @returns {*}
|
|
3068
3266
|
*/
|
|
3069
3267
|
transactionGetValue:
|
|
@@ -3129,7 +3327,7 @@ export const LeUtils = {
|
|
|
3129
3327
|
* ```
|
|
3130
3328
|
*
|
|
3131
3329
|
* @param {string} name
|
|
3132
|
-
* @returns {{worker:
|
|
3330
|
+
* @returns {{worker:Worker|null, sendMessage:(data:Object,options:{timeout:number|undefined}|undefined)=>Promise<Object>}}
|
|
3133
3331
|
*/
|
|
3134
3332
|
createWorkerThread:
|
|
3135
3333
|
(name) =>
|
|
@@ -3138,7 +3336,7 @@ export const LeUtils = {
|
|
|
3138
3336
|
{
|
|
3139
3337
|
return {
|
|
3140
3338
|
worker: null,
|
|
3141
|
-
sendMessage:new Promise((resolve, reject) =>
|
|
3339
|
+
sendMessage:(data, options) => new Promise((resolve, reject) =>
|
|
3142
3340
|
{
|
|
3143
3341
|
reject('Workers are not supported in this environment');
|
|
3144
3342
|
}),
|
|
@@ -3146,16 +3344,16 @@ export const LeUtils = {
|
|
|
3146
3344
|
}
|
|
3147
3345
|
|
|
3148
3346
|
const worker = new Worker('/workers/' + name + '.worker.js');
|
|
3149
|
-
let listeners =
|
|
3347
|
+
let listeners = new Map();
|
|
3150
3348
|
|
|
3151
3349
|
const addListener = (id, callback) =>
|
|
3152
3350
|
{
|
|
3153
|
-
listeners
|
|
3351
|
+
listeners.set(id, callback);
|
|
3154
3352
|
};
|
|
3155
3353
|
|
|
3156
3354
|
const removeListener = (id) =>
|
|
3157
3355
|
{
|
|
3158
|
-
delete
|
|
3356
|
+
listeners.delete(id);
|
|
3159
3357
|
};
|
|
3160
3358
|
|
|
3161
3359
|
const sendMessage = (data, options) =>
|
|
@@ -3186,7 +3384,7 @@ export const LeUtils = {
|
|
|
3186
3384
|
const data = message.data;
|
|
3187
3385
|
if(data?.id)
|
|
3188
3386
|
{
|
|
3189
|
-
const callback = listeners
|
|
3387
|
+
const callback = listeners.get(data.id);
|
|
3190
3388
|
if(callback)
|
|
3191
3389
|
{
|
|
3192
3390
|
removeListener(data.id);
|
|
@@ -3205,20 +3403,20 @@ export const LeUtils = {
|
|
|
3205
3403
|
*
|
|
3206
3404
|
* @param {string} workerName
|
|
3207
3405
|
* @param {Object} data
|
|
3208
|
-
* @param {{timeout:
|
|
3406
|
+
* @param {{timeout:number|undefined}} [options]
|
|
3209
3407
|
* @returns {Promise<Object>}
|
|
3210
3408
|
*/
|
|
3211
3409
|
sendWorkerMessage:
|
|
3212
3410
|
(() =>
|
|
3213
3411
|
{
|
|
3214
|
-
const workers =
|
|
3412
|
+
const workers = new Map();
|
|
3215
3413
|
return (workerName, data, options) =>
|
|
3216
3414
|
{
|
|
3217
|
-
if(!workers
|
|
3415
|
+
if(!workers.has(workerName))
|
|
3218
3416
|
{
|
|
3219
|
-
workers
|
|
3417
|
+
workers.set(workerName, LeUtils.createWorkerThread(workerName));
|
|
3220
3418
|
}
|
|
3221
|
-
return workers
|
|
3419
|
+
return workers.get(workerName).sendMessage(data, options);
|
|
3222
3420
|
};
|
|
3223
3421
|
})(),
|
|
3224
3422
|
|
|
@@ -3251,7 +3449,7 @@ export const LeUtils = {
|
|
|
3251
3449
|
return () => true;
|
|
3252
3450
|
}
|
|
3253
3451
|
const inputTypes = ['text', 'search', 'email', 'number', 'password', 'tel', 'time', 'url', 'week', 'month', 'date', 'datetime-local'];
|
|
3254
|
-
return () => !((document?.activeElement?.tagName?.toLowerCase() === 'input') && inputTypes.includes(document?.activeElement?.type?.toLowerCase()));
|
|
3452
|
+
return () => !((document?.activeElement?.tagName?.toLowerCase() === 'input') && inputTypes.includes(document?.activeElement?.getAttribute('type')?.toLowerCase() ?? ''));
|
|
3255
3453
|
})(),
|
|
3256
3454
|
|
|
3257
3455
|
/**
|