@creejs/commons-lang 2.1.18 → 2.1.20
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/cjs/index-dev.cjs +285 -58
- package/dist/cjs/index-dev.cjs.map +1 -1
- package/dist/cjs/index-min.cjs +1 -1
- package/dist/cjs/index-min.cjs.map +1 -1
- package/dist/esm/index-dev.js +285 -58
- package/dist/esm/index-dev.js.map +1 -1
- package/dist/esm/index-min.js +1 -1
- package/dist/esm/index-min.js.map +1 -1
- package/dist/umd/index.dev.js +285 -58
- package/dist/umd/index.dev.js.map +1 -1
- package/dist/umd/index.min.js +1 -1
- package/dist/umd/index.min.js.map +1 -1
- package/package.json +1 -1
- package/types/array-utils.d.ts +8 -0
- package/types/lang-utils.d.ts +2 -0
- package/types/promise-utils.d.ts +49 -11
- package/types/string-utils.d.ts +8 -0
package/dist/cjs/index-dev.cjs
CHANGED
|
@@ -14,7 +14,9 @@ var LangUtils = {
|
|
|
14
14
|
extends: extend,
|
|
15
15
|
equals: equals$2,
|
|
16
16
|
isBrowser,
|
|
17
|
-
isNode
|
|
17
|
+
isNode,
|
|
18
|
+
cloneToPlainObject,
|
|
19
|
+
deepCloneToPlainObject
|
|
18
20
|
};
|
|
19
21
|
|
|
20
22
|
/**
|
|
@@ -72,6 +74,41 @@ function extend (target, ...sources) {
|
|
|
72
74
|
return target
|
|
73
75
|
}
|
|
74
76
|
|
|
77
|
+
/**
|
|
78
|
+
* Creates a shallow clone of an object by copying its enumerable properties to a new plain object.
|
|
79
|
+
* 1. This returns a PlainObject
|
|
80
|
+
* 2. It lose the type information of the original object
|
|
81
|
+
* 3. Shallow clone, copy only the first level properties
|
|
82
|
+
* @param {{[key:string]: any}} obj - The object to clone.
|
|
83
|
+
* @returns {{[key:string]: any}} A new plain object with the same enumerable properties as the input object.
|
|
84
|
+
*/
|
|
85
|
+
function cloneToPlainObject (obj) {
|
|
86
|
+
if (obj == null) {
|
|
87
|
+
return obj
|
|
88
|
+
}
|
|
89
|
+
if (typeof obj !== 'object') {
|
|
90
|
+
throw new Error('Only Object allowed to clone')
|
|
91
|
+
}
|
|
92
|
+
return { ...obj }
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Deep clones an object by converting it to JSON and back to a plain object.
|
|
97
|
+
* 1. This will lose any non-JSON-serializable properties (e.g. functions, Symbols).
|
|
98
|
+
* 2. Only Use this to clone PlainObject
|
|
99
|
+
* @param {{[key:string]: any}} obj - The object to clone
|
|
100
|
+
* @returns {{[key:string]: any}} A new plain object with the cloned properties
|
|
101
|
+
*/
|
|
102
|
+
function deepCloneToPlainObject (obj) {
|
|
103
|
+
if (obj == null) {
|
|
104
|
+
return obj
|
|
105
|
+
}
|
|
106
|
+
if (typeof obj !== 'object') {
|
|
107
|
+
throw new Error('Only Object allowed to clone')
|
|
108
|
+
}
|
|
109
|
+
return JSON.parse(JSON.stringify(obj))
|
|
110
|
+
}
|
|
111
|
+
|
|
75
112
|
/**
|
|
76
113
|
* Compares two values for equality
|
|
77
114
|
* 1. First checks strict equality (===),
|
|
@@ -579,7 +616,7 @@ var TypeAssert = {
|
|
|
579
616
|
*/
|
|
580
617
|
function assertArray (value, paramName) {
|
|
581
618
|
if (!Array.isArray(value)) {
|
|
582
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
619
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not Array: type=${typeof value} value=${safeToString(value)}`)
|
|
583
620
|
}
|
|
584
621
|
}
|
|
585
622
|
/**
|
|
@@ -591,7 +628,7 @@ function assertArray (value, paramName) {
|
|
|
591
628
|
*/
|
|
592
629
|
function assertString (value, paramName) {
|
|
593
630
|
if (!isString(value)) {
|
|
594
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
631
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not String: type=${typeof value} value=${safeToString(value)}`)
|
|
595
632
|
}
|
|
596
633
|
}
|
|
597
634
|
/**
|
|
@@ -603,7 +640,7 @@ function assertString (value, paramName) {
|
|
|
603
640
|
*/
|
|
604
641
|
function assertNumber (value, paramName) {
|
|
605
642
|
if (!isNumber(value)) {
|
|
606
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
643
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not Number: type=${typeof value} value=${safeToString(value)}`)
|
|
607
644
|
}
|
|
608
645
|
}
|
|
609
646
|
|
|
@@ -615,7 +652,7 @@ function assertNumber (value, paramName) {
|
|
|
615
652
|
*/
|
|
616
653
|
function assertPositive (value, paramName) {
|
|
617
654
|
if (!isPositive(value)) {
|
|
618
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
655
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not Positive: ${value}`)
|
|
619
656
|
}
|
|
620
657
|
}
|
|
621
658
|
|
|
@@ -627,7 +664,7 @@ function assertPositive (value, paramName) {
|
|
|
627
664
|
*/
|
|
628
665
|
function assertNegative (value, paramName) {
|
|
629
666
|
if (!isNegative(value)) {
|
|
630
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
667
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not Negative: ${value}`)
|
|
631
668
|
}
|
|
632
669
|
}
|
|
633
670
|
|
|
@@ -639,7 +676,7 @@ function assertNegative (value, paramName) {
|
|
|
639
676
|
*/
|
|
640
677
|
function assertNotNegative (value, paramName) {
|
|
641
678
|
if (!isNotNegative(value)) {
|
|
642
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
679
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not "0 or Positive": ${value}`)
|
|
643
680
|
}
|
|
644
681
|
}
|
|
645
682
|
|
|
@@ -652,7 +689,7 @@ function assertNotNegative (value, paramName) {
|
|
|
652
689
|
*/
|
|
653
690
|
function assertBoolean (value, paramName) {
|
|
654
691
|
if (!isBoolean(value)) {
|
|
655
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
692
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not Boolean: type=${typeof value} value=${safeToString(value)}`)
|
|
656
693
|
}
|
|
657
694
|
}
|
|
658
695
|
/**
|
|
@@ -664,7 +701,7 @@ function assertBoolean (value, paramName) {
|
|
|
664
701
|
*/
|
|
665
702
|
function assertObject (value, paramName) {
|
|
666
703
|
if (!isObject(value)) {
|
|
667
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
704
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not Object: type=${typeof value} value=${safeToString(value)}`)
|
|
668
705
|
}
|
|
669
706
|
}
|
|
670
707
|
/**
|
|
@@ -676,7 +713,7 @@ function assertObject (value, paramName) {
|
|
|
676
713
|
*/
|
|
677
714
|
function assertPlainObject (value, paramName) {
|
|
678
715
|
if (!isPlainObject$1(value)) {
|
|
679
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
716
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not PlainObject: type=${typeof value} value=${safeToString(value)}`)
|
|
680
717
|
}
|
|
681
718
|
}
|
|
682
719
|
/**
|
|
@@ -688,7 +725,7 @@ function assertPlainObject (value, paramName) {
|
|
|
688
725
|
*/
|
|
689
726
|
function assertSymbol (value, paramName) {
|
|
690
727
|
if (!isSymbol(value)) {
|
|
691
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
728
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not Symbol: type=${typeof value} value=${safeToString(value)}`)
|
|
692
729
|
}
|
|
693
730
|
}
|
|
694
731
|
/**
|
|
@@ -700,7 +737,7 @@ function assertSymbol (value, paramName) {
|
|
|
700
737
|
*/
|
|
701
738
|
function assertFunction (value, paramName) {
|
|
702
739
|
if (!isFunction(value)) {
|
|
703
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
740
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not Function: type=${typeof value} value=${safeToString(value)}`)
|
|
704
741
|
}
|
|
705
742
|
}
|
|
706
743
|
/**
|
|
@@ -712,7 +749,7 @@ function assertFunction (value, paramName) {
|
|
|
712
749
|
*/
|
|
713
750
|
function assertInstance (value, paramName) {
|
|
714
751
|
if (!isInstance(value)) {
|
|
715
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
752
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not Class Instance: type=${typeof value} value=${safeToString(value)}`)
|
|
716
753
|
}
|
|
717
754
|
}
|
|
718
755
|
/**
|
|
@@ -724,7 +761,7 @@ function assertInstance (value, paramName) {
|
|
|
724
761
|
*/
|
|
725
762
|
function assertPromise (value, paramName) {
|
|
726
763
|
if (!isPromise(value)) {
|
|
727
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
764
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not Promise: type=${typeof value} value=${safeToString(value)}`)
|
|
728
765
|
}
|
|
729
766
|
}
|
|
730
767
|
/**
|
|
@@ -736,7 +773,7 @@ function assertPromise (value, paramName) {
|
|
|
736
773
|
*/
|
|
737
774
|
function assertNil (value, paramName) {
|
|
738
775
|
if (!isNil(value)) {
|
|
739
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
776
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Neither Null nor Undefined: type=${typeof value} value=${safeToString(value)}`)
|
|
740
777
|
}
|
|
741
778
|
}
|
|
742
779
|
|
|
@@ -748,7 +785,7 @@ function assertNil (value, paramName) {
|
|
|
748
785
|
*/
|
|
749
786
|
function assertNotNil (value, paramName) {
|
|
750
787
|
if (isNil(value)) {
|
|
751
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
788
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Should Not Nil`)
|
|
752
789
|
}
|
|
753
790
|
}
|
|
754
791
|
|
|
@@ -761,7 +798,7 @@ function assertNotNil (value, paramName) {
|
|
|
761
798
|
*/
|
|
762
799
|
function assertNull (value, paramName) {
|
|
763
800
|
if (!isNull(value)) {
|
|
764
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
801
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not Null: type=${typeof value} value=${safeToString(value)}`)
|
|
765
802
|
}
|
|
766
803
|
}
|
|
767
804
|
|
|
@@ -773,7 +810,7 @@ function assertNull (value, paramName) {
|
|
|
773
810
|
*/
|
|
774
811
|
function assertNotNull (value, paramName) {
|
|
775
812
|
if (isNull(value)) {
|
|
776
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
813
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Should Not Null`)
|
|
777
814
|
}
|
|
778
815
|
}
|
|
779
816
|
/**
|
|
@@ -785,7 +822,7 @@ function assertNotNull (value, paramName) {
|
|
|
785
822
|
*/
|
|
786
823
|
function assertUndefined (value, paramName) {
|
|
787
824
|
if (!isUndefined(value)) {
|
|
788
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
825
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not Undefined: type=${typeof value} value=${safeToString(value)}`)
|
|
789
826
|
}
|
|
790
827
|
}
|
|
791
828
|
|
|
@@ -797,7 +834,7 @@ function assertUndefined (value, paramName) {
|
|
|
797
834
|
*/
|
|
798
835
|
function assertStringOrSymbol (value, paramName) {
|
|
799
836
|
if (!isString(value) && !isSymbol(value)) {
|
|
800
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
837
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not String or Symbol: type=${typeof value} value=${safeToString(value)}`)
|
|
801
838
|
}
|
|
802
839
|
}
|
|
803
840
|
|
|
@@ -808,7 +845,7 @@ function assertStringOrSymbol (value, paramName) {
|
|
|
808
845
|
*/
|
|
809
846
|
function assertTypedArray (value, paramName) {
|
|
810
847
|
if (isTypedArray(value)) {
|
|
811
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
848
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not TypedArray`)
|
|
812
849
|
}
|
|
813
850
|
}
|
|
814
851
|
/**
|
|
@@ -818,7 +855,7 @@ function assertTypedArray (value, paramName) {
|
|
|
818
855
|
*/
|
|
819
856
|
function assertInt8Array (value, paramName) {
|
|
820
857
|
if (isInt8Array(value)) {
|
|
821
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
858
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not Int8Array`)
|
|
822
859
|
}
|
|
823
860
|
}
|
|
824
861
|
/**
|
|
@@ -828,7 +865,7 @@ function assertInt8Array (value, paramName) {
|
|
|
828
865
|
*/
|
|
829
866
|
function assertUint8Array (value, paramName) {
|
|
830
867
|
if (isUint8Array(value)) {
|
|
831
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
868
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not Uint8Array`)
|
|
832
869
|
}
|
|
833
870
|
}
|
|
834
871
|
/**
|
|
@@ -838,7 +875,7 @@ function assertUint8Array (value, paramName) {
|
|
|
838
875
|
*/
|
|
839
876
|
function assertUint8ClampedArray (value, paramName) {
|
|
840
877
|
if (isUint8ClampedArray(value)) {
|
|
841
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
878
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not Uint8ClampedArray`)
|
|
842
879
|
}
|
|
843
880
|
}
|
|
844
881
|
/**
|
|
@@ -848,7 +885,7 @@ function assertUint8ClampedArray (value, paramName) {
|
|
|
848
885
|
*/
|
|
849
886
|
function assertInt16Array (value, paramName) {
|
|
850
887
|
if (isInt16Array(value)) {
|
|
851
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
888
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not Int16Array`)
|
|
852
889
|
}
|
|
853
890
|
}
|
|
854
891
|
/**
|
|
@@ -858,7 +895,7 @@ function assertInt16Array (value, paramName) {
|
|
|
858
895
|
*/
|
|
859
896
|
function assertUint16Array (value, paramName) {
|
|
860
897
|
if (isUint16Array(value)) {
|
|
861
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
898
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not Uint16Array`)
|
|
862
899
|
}
|
|
863
900
|
}
|
|
864
901
|
/**
|
|
@@ -868,7 +905,7 @@ function assertUint16Array (value, paramName) {
|
|
|
868
905
|
*/
|
|
869
906
|
function assertInt32Array (value, paramName) {
|
|
870
907
|
if (isInt32Array(value)) {
|
|
871
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
908
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not Int32Array`)
|
|
872
909
|
}
|
|
873
910
|
}
|
|
874
911
|
/**
|
|
@@ -878,7 +915,7 @@ function assertInt32Array (value, paramName) {
|
|
|
878
915
|
*/
|
|
879
916
|
function assertUint32Array (value, paramName) {
|
|
880
917
|
if (isUint32Array(value)) {
|
|
881
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
918
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not Uint32Array`)
|
|
882
919
|
}
|
|
883
920
|
}
|
|
884
921
|
/**
|
|
@@ -888,7 +925,7 @@ function assertUint32Array (value, paramName) {
|
|
|
888
925
|
*/
|
|
889
926
|
function assertFloat32Array (value, paramName) {
|
|
890
927
|
if (isFloat32Array(value)) {
|
|
891
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
928
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not Float32Array`)
|
|
892
929
|
}
|
|
893
930
|
}
|
|
894
931
|
/**
|
|
@@ -898,7 +935,7 @@ function assertFloat32Array (value, paramName) {
|
|
|
898
935
|
*/
|
|
899
936
|
function assertFloat64Array (value, paramName) {
|
|
900
937
|
if (isFloat64Array(value)) {
|
|
901
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
938
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not Float64Array`)
|
|
902
939
|
}
|
|
903
940
|
}
|
|
904
941
|
/**
|
|
@@ -908,7 +945,7 @@ function assertFloat64Array (value, paramName) {
|
|
|
908
945
|
*/
|
|
909
946
|
function assertBigInt64Array (value, paramName) {
|
|
910
947
|
if (isBigInt64Array(value)) {
|
|
911
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
948
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not BigInt64Array`)
|
|
912
949
|
}
|
|
913
950
|
}
|
|
914
951
|
/**
|
|
@@ -918,7 +955,7 @@ function assertBigInt64Array (value, paramName) {
|
|
|
918
955
|
*/
|
|
919
956
|
function assertBigUint64Array (value, paramName) {
|
|
920
957
|
if (isBigUint64Array(value)) {
|
|
921
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
958
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not BigUint64Array`)
|
|
922
959
|
}
|
|
923
960
|
}
|
|
924
961
|
|
|
@@ -930,7 +967,7 @@ function assertBigUint64Array (value, paramName) {
|
|
|
930
967
|
*/
|
|
931
968
|
function assertArrayBuffer (value, paramName) {
|
|
932
969
|
if (!isArrayBuffer(value)) {
|
|
933
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
970
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not ArrayBuffer`)
|
|
934
971
|
}
|
|
935
972
|
}
|
|
936
973
|
|
|
@@ -959,7 +996,8 @@ var StringUtils = {
|
|
|
959
996
|
substringAfterLast,
|
|
960
997
|
substringBetween,
|
|
961
998
|
substringBetweenGreedy,
|
|
962
|
-
substringsBetween
|
|
999
|
+
substringsBetween,
|
|
1000
|
+
safeToString
|
|
963
1001
|
};
|
|
964
1002
|
|
|
965
1003
|
/**
|
|
@@ -1356,6 +1394,22 @@ function substringsBetween (str, startMarker, endMarker) {
|
|
|
1356
1394
|
return substrings
|
|
1357
1395
|
}
|
|
1358
1396
|
|
|
1397
|
+
/**
|
|
1398
|
+
* Safely converts a value to its string representation.
|
|
1399
|
+
* Attempts to use JSON.stringify first, falls back to toString() if stringify fails.
|
|
1400
|
+
* @param {*} value - The value to convert to string
|
|
1401
|
+
* @returns {string} The string representation of the value
|
|
1402
|
+
*/
|
|
1403
|
+
function safeToString (value) {
|
|
1404
|
+
let valueStr;
|
|
1405
|
+
try {
|
|
1406
|
+
valueStr = JSON.stringify(value);
|
|
1407
|
+
} catch (e) {
|
|
1408
|
+
valueStr = value.toString();
|
|
1409
|
+
}
|
|
1410
|
+
return valueStr
|
|
1411
|
+
}
|
|
1412
|
+
|
|
1359
1413
|
/**
|
|
1360
1414
|
* @module ExecUtils
|
|
1361
1415
|
* @description Utils about how to execute task functions.
|
|
@@ -1433,6 +1487,7 @@ var ExecUtils = {
|
|
|
1433
1487
|
* promise: Promise<*>,
|
|
1434
1488
|
* timerHandler: NodeJS.Timeout,
|
|
1435
1489
|
* timerCleared: boolean,
|
|
1490
|
+
* pending: boolean,
|
|
1436
1491
|
* resolved: boolean,
|
|
1437
1492
|
* rejected: boolean,
|
|
1438
1493
|
* canceled: boolean,
|
|
@@ -1445,7 +1500,8 @@ var ExecUtils = {
|
|
|
1445
1500
|
* @typedef {{
|
|
1446
1501
|
* promise: Promise<*>,
|
|
1447
1502
|
* timerHandler: NodeJS.Timeout,
|
|
1448
|
-
*
|
|
1503
|
+
* _resolve: (...args:any[])=> void,
|
|
1504
|
+
* wakeup: ()=> void
|
|
1449
1505
|
* }} Waiter
|
|
1450
1506
|
*/
|
|
1451
1507
|
|
|
@@ -1454,6 +1510,7 @@ var ExecUtils = {
|
|
|
1454
1510
|
* @description Promise utility functions for enhanced promise handling, including timeout, delay, parallel execution, and series execution.
|
|
1455
1511
|
*/
|
|
1456
1512
|
var PromiseUtils = {
|
|
1513
|
+
any,
|
|
1457
1514
|
defer,
|
|
1458
1515
|
delay,
|
|
1459
1516
|
timeout,
|
|
@@ -1462,6 +1519,7 @@ var PromiseUtils = {
|
|
|
1462
1519
|
series,
|
|
1463
1520
|
seriesAllSettled,
|
|
1464
1521
|
parallel,
|
|
1522
|
+
parallelAny,
|
|
1465
1523
|
parallelAllSettled,
|
|
1466
1524
|
wait
|
|
1467
1525
|
};
|
|
@@ -1477,48 +1535,66 @@ function defer (timeout = -1, timeoutMessage) {
|
|
|
1477
1535
|
assertNumber(timeout);
|
|
1478
1536
|
/** @type {Deferred} */
|
|
1479
1537
|
const rtnVal = {};
|
|
1480
|
-
|
|
1538
|
+
rtnVal.pending = true;
|
|
1539
|
+
rtnVal.canceled = false;
|
|
1540
|
+
rtnVal.rejected = false;
|
|
1541
|
+
rtnVal.resolved = false;
|
|
1481
1542
|
/**
|
|
1482
1543
|
* @type {NodeJS.Timeout}
|
|
1483
1544
|
*/
|
|
1484
1545
|
let timerHandler;
|
|
1485
1546
|
if (timeout >= 0) {
|
|
1547
|
+
rtnVal.timerCleared = false;
|
|
1486
1548
|
rtnVal.timerHandler = timerHandler = setTimeout(() => {
|
|
1487
1549
|
clearTimeout(timerHandler); // must clear it
|
|
1488
|
-
rtnVal.timerCleared = true;
|
|
1550
|
+
rtnVal.timerCleared = true;
|
|
1489
1551
|
rtnVal.reject(new Error(timeoutMessage ?? `Promise Timeout: ${timeout}ms`));
|
|
1490
1552
|
}, timeout);
|
|
1491
1553
|
}
|
|
1492
1554
|
|
|
1493
1555
|
rtnVal.promise = new Promise((resolve, reject) => {
|
|
1494
1556
|
rtnVal.resolve = (arg) => {
|
|
1557
|
+
if (rtnVal.resolved || rtnVal.rejected || rtnVal.canceled) {
|
|
1558
|
+
return // already done, Can Not operate again
|
|
1559
|
+
}
|
|
1495
1560
|
if (timerHandler != null) {
|
|
1496
1561
|
clearTimeout(timerHandler); // must clear it
|
|
1497
|
-
rtnVal.timerCleared = true;
|
|
1562
|
+
rtnVal.timerCleared = true;
|
|
1498
1563
|
}
|
|
1564
|
+
rtnVal.pending = false;
|
|
1565
|
+
rtnVal.canceled = false;
|
|
1566
|
+
rtnVal.rejected = false;
|
|
1499
1567
|
rtnVal.resolved = true;
|
|
1500
1568
|
resolve(arg);
|
|
1501
1569
|
};
|
|
1502
1570
|
|
|
1503
1571
|
rtnVal.reject = (err) => {
|
|
1572
|
+
if (rtnVal.resolved || rtnVal.rejected || rtnVal.canceled) {
|
|
1573
|
+
return // already done, Can Not operate again
|
|
1574
|
+
}
|
|
1504
1575
|
if (timerHandler != null) {
|
|
1505
1576
|
clearTimeout(timerHandler); // must clear it
|
|
1506
|
-
rtnVal.timerCleared = true;
|
|
1577
|
+
rtnVal.timerCleared = true;
|
|
1507
1578
|
}
|
|
1579
|
+
rtnVal.pending = false;
|
|
1580
|
+
rtnVal.canceled = false;
|
|
1581
|
+
rtnVal.resolved = false;
|
|
1508
1582
|
rtnVal.rejected = true;
|
|
1509
1583
|
reject(err);
|
|
1510
1584
|
};
|
|
1511
1585
|
});
|
|
1512
1586
|
// @ts-ignore
|
|
1513
|
-
rtnVal.promise.cancel = () => {
|
|
1587
|
+
rtnVal.cancel = rtnVal.promise.cancel = (reason) => {
|
|
1588
|
+
if (rtnVal.resolved || rtnVal.rejected || rtnVal.canceled) {
|
|
1589
|
+
return // already done, Can Not operate again
|
|
1590
|
+
}
|
|
1514
1591
|
if (timerHandler != null) {
|
|
1515
1592
|
clearTimeout(timerHandler); // must clear it
|
|
1516
|
-
rtnVal.timerCleared = true;
|
|
1593
|
+
rtnVal.timerCleared = true;
|
|
1517
1594
|
}
|
|
1518
|
-
rtnVal.
|
|
1595
|
+
rtnVal.reject(reason ?? new Error('Cancelled'));
|
|
1519
1596
|
// @ts-ignore
|
|
1520
|
-
rtnVal.canceled = rtnVal.promise.canceled = true;
|
|
1521
|
-
rtnVal.reject(new Error('Cancelled'));
|
|
1597
|
+
rtnVal.canceled = rtnVal.promise.canceled = true;
|
|
1522
1598
|
};
|
|
1523
1599
|
return rtnVal
|
|
1524
1600
|
}
|
|
@@ -1589,7 +1665,7 @@ async function allSettled (promises) {
|
|
|
1589
1665
|
function returnValuePromised (task) {
|
|
1590
1666
|
try {
|
|
1591
1667
|
const taskRtnVal = task();
|
|
1592
|
-
if (isPromise(taskRtnVal)) {
|
|
1668
|
+
if (TypeUtils.isPromise(taskRtnVal)) {
|
|
1593
1669
|
return taskRtnVal
|
|
1594
1670
|
}
|
|
1595
1671
|
return Promise.resolve(taskRtnVal)
|
|
@@ -1610,7 +1686,7 @@ function returnValuePromised (task) {
|
|
|
1610
1686
|
* @returns {Promise<*>} A new promise that settles after the delay period
|
|
1611
1687
|
*/
|
|
1612
1688
|
function delay (promise, ms) {
|
|
1613
|
-
if (isNumber(promise)) { // defer(ms)
|
|
1689
|
+
if (TypeUtils.isNumber(promise)) { // defer(ms)
|
|
1614
1690
|
// @ts-ignore
|
|
1615
1691
|
ms = promise;
|
|
1616
1692
|
promise = Promise.resolve();
|
|
@@ -1642,21 +1718,78 @@ function delay (promise, ms) {
|
|
|
1642
1718
|
});
|
|
1643
1719
|
return deferred.promise
|
|
1644
1720
|
}
|
|
1721
|
+
/**
|
|
1722
|
+
* 1. run all tasks
|
|
1723
|
+
* 2. any Task succeed, return its result
|
|
1724
|
+
* * resolve with the result.
|
|
1725
|
+
* * the others tasks will run to its end, and results will be dropped.
|
|
1726
|
+
* 3. If all tasks fail, rejects with an array of errors. the array length is same as the input tasks
|
|
1727
|
+
* @param {Array<Promise<any>|Function>} tasks - Array of promises or async functions to execute
|
|
1728
|
+
* @returns {Promise<any>} A promise that resolves with the result of the first successful task
|
|
1729
|
+
*/
|
|
1730
|
+
function any (tasks) {
|
|
1731
|
+
assertArray(tasks);
|
|
1732
|
+
if (tasks.length === 0) {
|
|
1733
|
+
throw new Error('Empty Tasks')
|
|
1734
|
+
}
|
|
1735
|
+
const deferred = defer();
|
|
1736
|
+
/** @type {any[]} */
|
|
1737
|
+
const errors = [];
|
|
1738
|
+
for (let i = 0; i < tasks.length; i++) {
|
|
1739
|
+
const task = tasks[i];
|
|
1740
|
+
/** @type {Promise<any>} */
|
|
1741
|
+
let taskPromise;
|
|
1742
|
+
if (TypeUtils.isPromise(task)) {
|
|
1743
|
+
// @ts-ignore
|
|
1744
|
+
taskPromise = task;
|
|
1745
|
+
} else if (TypeUtils.isFunction(task)) {
|
|
1746
|
+
// @ts-ignore
|
|
1747
|
+
taskPromise = returnValuePromised(task);
|
|
1748
|
+
} else {
|
|
1749
|
+
errors.push(new Error(`Invalid Task at index ${i}/${tasks.length - 1}: ${task}`));
|
|
1750
|
+
continue
|
|
1751
|
+
}
|
|
1752
|
+
taskPromise.then(/** @type {any} */ rtnVal => {
|
|
1753
|
+
deferred.resolve(rtnVal);
|
|
1754
|
+
}).catch(e => {
|
|
1755
|
+
errors.push(e);
|
|
1756
|
+
// all tasks failed
|
|
1757
|
+
if (errors.length >= tasks.length) {
|
|
1758
|
+
deferred.reject(errors);
|
|
1759
|
+
}
|
|
1760
|
+
});
|
|
1761
|
+
}
|
|
1762
|
+
if (errors.length === tasks.length) {
|
|
1763
|
+
deferred.reject(errors);
|
|
1764
|
+
}
|
|
1765
|
+
return deferred.promise
|
|
1766
|
+
}
|
|
1645
1767
|
|
|
1646
1768
|
/**
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1769
|
+
* Execute Tasks(functions) in series (one after another) and returns their results in order.
|
|
1770
|
+
* 1. Tasks are executed one by one
|
|
1771
|
+
* * if task is a function, execute it.
|
|
1772
|
+
* * if task is a promise, wait for it to settle.
|
|
1773
|
+
* 2. Fast Fail: if any tasks fail, the whole chain is rejected with the first error
|
|
1774
|
+
* 3. if an element is not function, rejects the whole chain with Error(Not Function)
|
|
1775
|
+
* 4. All Tasks run successfully, Return Results Array, it's length is same as the input tasks
|
|
1776
|
+
* @param {Array<Promise<any>|Function>} tasks
|
|
1777
|
+
* @returns {Promise<any[]>} Promise that resolves with an array of results in the same order as input tasks
|
|
1778
|
+
*/
|
|
1654
1779
|
async function series (tasks) {
|
|
1655
1780
|
assertArray(tasks);
|
|
1656
1781
|
const results = [];
|
|
1657
1782
|
for (const task of tasks) {
|
|
1658
1783
|
assertFunction(task);
|
|
1659
|
-
|
|
1784
|
+
if (TypeUtils.isFunction(task)) {
|
|
1785
|
+
// @ts-ignore
|
|
1786
|
+
results.push(await returnValuePromised(task));
|
|
1787
|
+
} else if (TypeUtils.isPromise(task)) {
|
|
1788
|
+
// @ts-ignore
|
|
1789
|
+
results.push(await task);
|
|
1790
|
+
} else {
|
|
1791
|
+
throw new Error(`Invalid Task: ${task}`)
|
|
1792
|
+
}
|
|
1660
1793
|
}
|
|
1661
1794
|
return results
|
|
1662
1795
|
}
|
|
@@ -1731,7 +1864,7 @@ async function parallel (tasks, maxParallel = 5) {
|
|
|
1731
1864
|
* 2. all tasks will be executed, even some of them failed.
|
|
1732
1865
|
* @param {Function[]} tasks
|
|
1733
1866
|
* @param {number} [maxParallel=5] - Maximum number of tasks to run in parallel
|
|
1734
|
-
* @returns {Promise<any[]>}
|
|
1867
|
+
* @returns {Promise<{ok: boolean, result: any}[]>}
|
|
1735
1868
|
* @throws {TypeError} If input is not an array of export function or maxParallel is not a number
|
|
1736
1869
|
*/
|
|
1737
1870
|
async function parallelAllSettled (tasks, maxParallel = 5) {
|
|
@@ -1751,7 +1884,6 @@ async function parallelAllSettled (tasks, maxParallel = 5) {
|
|
|
1751
1884
|
// run group by MaxParallel
|
|
1752
1885
|
const tasksToRun = [];
|
|
1753
1886
|
for (const task of tasks) {
|
|
1754
|
-
assertFunction(task);
|
|
1755
1887
|
tasksToRun.push(task);
|
|
1756
1888
|
if (tasksToRun.length >= maxParallel) {
|
|
1757
1889
|
const resultsForBatch = await allSettled(tasksToRun.map(task => returnValuePromised(task)));
|
|
@@ -1767,6 +1899,76 @@ async function parallelAllSettled (tasks, maxParallel = 5) {
|
|
|
1767
1899
|
return rtnVal
|
|
1768
1900
|
}
|
|
1769
1901
|
|
|
1902
|
+
/**
|
|
1903
|
+
* Executes multiple async tasks in parallel with limited concurrency,
|
|
1904
|
+
* 1. resolving when any task completes successfully.
|
|
1905
|
+
* 2. Maybe multiple tasks are executed as a bulk block, and all of them resolved.
|
|
1906
|
+
* * only the first fulfilled value is returned
|
|
1907
|
+
* * other results are dropped
|
|
1908
|
+
* @param {Array<Function|Promise<any>>} tasks - Array of async functions to execute
|
|
1909
|
+
* @param {number} [maxParallel=5] - Maximum number of tasks to run in parallel
|
|
1910
|
+
* @returns {Promise<any>} Resolves with the result of the first successfully completed task
|
|
1911
|
+
*/
|
|
1912
|
+
async function parallelAny (tasks, maxParallel = 5) {
|
|
1913
|
+
assertArray(tasks, 'tasks');
|
|
1914
|
+
assertNumber(maxParallel);
|
|
1915
|
+
if (tasks.length === 0) {
|
|
1916
|
+
throw new Error('Empty Tasks')
|
|
1917
|
+
}
|
|
1918
|
+
if (maxParallel <= 0) {
|
|
1919
|
+
throw new Error(`Invalid maxParallel: ${maxParallel}, should > 0`)
|
|
1920
|
+
}
|
|
1921
|
+
/** @type {any[]} */
|
|
1922
|
+
const errors = [];
|
|
1923
|
+
let taskIndex = 0;
|
|
1924
|
+
let runningTasksCount = 0;
|
|
1925
|
+
const deferred = defer();
|
|
1926
|
+
function takeTaskAndRun () {
|
|
1927
|
+
if (taskIndex >= tasks.length) {
|
|
1928
|
+
return // no more task
|
|
1929
|
+
}
|
|
1930
|
+
// reach max parallel, wait for one task to finish
|
|
1931
|
+
if (runningTasksCount > maxParallel) {
|
|
1932
|
+
return
|
|
1933
|
+
}
|
|
1934
|
+
const task = tasks[taskIndex++];
|
|
1935
|
+
runningTasksCount++;
|
|
1936
|
+
/** @type {Promise<any>} */
|
|
1937
|
+
let taskPromise;
|
|
1938
|
+
if (TypeUtils.isPromise(task)) {
|
|
1939
|
+
// @ts-ignore
|
|
1940
|
+
taskPromise = task;
|
|
1941
|
+
} else if (TypeUtils.isFunction(task)) {
|
|
1942
|
+
// @ts-ignore
|
|
1943
|
+
taskPromise = returnValuePromised(task);
|
|
1944
|
+
} else {
|
|
1945
|
+
errors.push(new TypeError(`Invalid task: ${task}`));
|
|
1946
|
+
takeTaskAndRun();
|
|
1947
|
+
return
|
|
1948
|
+
}
|
|
1949
|
+
taskPromise.then(/** @type {any} */ rtnVal => {
|
|
1950
|
+
deferred.resolve(rtnVal);
|
|
1951
|
+
}).catch(e => {
|
|
1952
|
+
errors.push(e);
|
|
1953
|
+
// No task left, and No successful execution, reject with errors
|
|
1954
|
+
if (errors.length >= tasks.length) {
|
|
1955
|
+
if (deferred.pending) {
|
|
1956
|
+
deferred.reject(errors);
|
|
1957
|
+
return
|
|
1958
|
+
}
|
|
1959
|
+
}
|
|
1960
|
+
takeTaskAndRun();
|
|
1961
|
+
}).finally(() => {
|
|
1962
|
+
runningTasksCount--;
|
|
1963
|
+
});
|
|
1964
|
+
}
|
|
1965
|
+
// start tasks until maxParallel
|
|
1966
|
+
while (runningTasksCount < maxParallel) {
|
|
1967
|
+
takeTaskAndRun();
|
|
1968
|
+
}
|
|
1969
|
+
return deferred.promise
|
|
1970
|
+
}
|
|
1971
|
+
|
|
1770
1972
|
/**
|
|
1771
1973
|
* Creates a "Waiter" Object
|
|
1772
1974
|
* 1. wait the specified time
|
|
@@ -1785,17 +1987,20 @@ function wait (waitTime) {
|
|
|
1785
1987
|
let timerHandler;
|
|
1786
1988
|
rtnVal.timerHandler = timerHandler = setTimeout(() => {
|
|
1787
1989
|
clearTimeout(timerHandler); // must clear it
|
|
1788
|
-
rtnVal.
|
|
1990
|
+
rtnVal._resolve();
|
|
1789
1991
|
}, waitTime);
|
|
1790
1992
|
|
|
1791
1993
|
rtnVal.promise = new Promise((resolve, reject) => {
|
|
1792
|
-
rtnVal.
|
|
1994
|
+
rtnVal._resolve = (arg) => {
|
|
1793
1995
|
if (timerHandler != null) {
|
|
1794
1996
|
clearTimeout(timerHandler); // must clear it
|
|
1795
1997
|
}
|
|
1796
1998
|
resolve(arg);
|
|
1797
1999
|
};
|
|
1798
2000
|
});
|
|
2001
|
+
rtnVal.wakeup = () => {
|
|
2002
|
+
rtnVal._resolve();
|
|
2003
|
+
};
|
|
1799
2004
|
return rtnVal
|
|
1800
2005
|
}
|
|
1801
2006
|
|
|
@@ -2256,6 +2461,7 @@ function timeoutMillis (nanoTimestamp64, millisTimeout) {
|
|
|
2256
2461
|
|
|
2257
2462
|
var ArrayUtils = {
|
|
2258
2463
|
first,
|
|
2464
|
+
chunk,
|
|
2259
2465
|
last,
|
|
2260
2466
|
equals,
|
|
2261
2467
|
equalsIgnoreOrder
|
|
@@ -2339,6 +2545,27 @@ function equals (arr1, arr2, compareFn) {
|
|
|
2339
2545
|
return true
|
|
2340
2546
|
}
|
|
2341
2547
|
|
|
2548
|
+
/**
|
|
2549
|
+
* Splits an array into chunks of the specified size.
|
|
2550
|
+
* @param {any[]} array - The array to be chunked.
|
|
2551
|
+
* @param {number} size - The size of each chunk.
|
|
2552
|
+
* @returns {any[]} An array of arrays containing the chunks.
|
|
2553
|
+
*/
|
|
2554
|
+
function chunk (array, size) {
|
|
2555
|
+
assertArray(array, 'array');
|
|
2556
|
+
assertPositive(size, 'size');
|
|
2557
|
+
if (array.length <= size) {
|
|
2558
|
+
return array
|
|
2559
|
+
}
|
|
2560
|
+
const chunked = [];
|
|
2561
|
+
let index = 0;
|
|
2562
|
+
while (index < array.length) {
|
|
2563
|
+
chunked.push(array.slice(index, size + index));
|
|
2564
|
+
index += size;
|
|
2565
|
+
}
|
|
2566
|
+
return chunked
|
|
2567
|
+
}
|
|
2568
|
+
|
|
2342
2569
|
/**
|
|
2343
2570
|
* @module Lang
|
|
2344
2571
|
* @description Core language utilities for type checking, string manipulation, and common operations.
|