@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/esm/index-dev.js
CHANGED
|
@@ -10,7 +10,9 @@ var LangUtils = {
|
|
|
10
10
|
extends: extend,
|
|
11
11
|
equals: equals$2,
|
|
12
12
|
isBrowser,
|
|
13
|
-
isNode
|
|
13
|
+
isNode,
|
|
14
|
+
cloneToPlainObject,
|
|
15
|
+
deepCloneToPlainObject
|
|
14
16
|
};
|
|
15
17
|
|
|
16
18
|
/**
|
|
@@ -68,6 +70,41 @@ function extend (target, ...sources) {
|
|
|
68
70
|
return target
|
|
69
71
|
}
|
|
70
72
|
|
|
73
|
+
/**
|
|
74
|
+
* Creates a shallow clone of an object by copying its enumerable properties to a new plain object.
|
|
75
|
+
* 1. This returns a PlainObject
|
|
76
|
+
* 2. It lose the type information of the original object
|
|
77
|
+
* 3. Shallow clone, copy only the first level properties
|
|
78
|
+
* @param {{[key:string]: any}} obj - The object to clone.
|
|
79
|
+
* @returns {{[key:string]: any}} A new plain object with the same enumerable properties as the input object.
|
|
80
|
+
*/
|
|
81
|
+
function cloneToPlainObject (obj) {
|
|
82
|
+
if (obj == null) {
|
|
83
|
+
return obj
|
|
84
|
+
}
|
|
85
|
+
if (typeof obj !== 'object') {
|
|
86
|
+
throw new Error('Only Object allowed to clone')
|
|
87
|
+
}
|
|
88
|
+
return { ...obj }
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Deep clones an object by converting it to JSON and back to a plain object.
|
|
93
|
+
* 1. This will lose any non-JSON-serializable properties (e.g. functions, Symbols).
|
|
94
|
+
* 2. Only Use this to clone PlainObject
|
|
95
|
+
* @param {{[key:string]: any}} obj - The object to clone
|
|
96
|
+
* @returns {{[key:string]: any}} A new plain object with the cloned properties
|
|
97
|
+
*/
|
|
98
|
+
function deepCloneToPlainObject (obj) {
|
|
99
|
+
if (obj == null) {
|
|
100
|
+
return obj
|
|
101
|
+
}
|
|
102
|
+
if (typeof obj !== 'object') {
|
|
103
|
+
throw new Error('Only Object allowed to clone')
|
|
104
|
+
}
|
|
105
|
+
return JSON.parse(JSON.stringify(obj))
|
|
106
|
+
}
|
|
107
|
+
|
|
71
108
|
/**
|
|
72
109
|
* Compares two values for equality
|
|
73
110
|
* 1. First checks strict equality (===),
|
|
@@ -575,7 +612,7 @@ var TypeAssert = {
|
|
|
575
612
|
*/
|
|
576
613
|
function assertArray (value, paramName) {
|
|
577
614
|
if (!Array.isArray(value)) {
|
|
578
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
615
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not Array: type=${typeof value} value=${safeToString(value)}`)
|
|
579
616
|
}
|
|
580
617
|
}
|
|
581
618
|
/**
|
|
@@ -587,7 +624,7 @@ function assertArray (value, paramName) {
|
|
|
587
624
|
*/
|
|
588
625
|
function assertString (value, paramName) {
|
|
589
626
|
if (!isString(value)) {
|
|
590
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
627
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not String: type=${typeof value} value=${safeToString(value)}`)
|
|
591
628
|
}
|
|
592
629
|
}
|
|
593
630
|
/**
|
|
@@ -599,7 +636,7 @@ function assertString (value, paramName) {
|
|
|
599
636
|
*/
|
|
600
637
|
function assertNumber (value, paramName) {
|
|
601
638
|
if (!isNumber(value)) {
|
|
602
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
639
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not Number: type=${typeof value} value=${safeToString(value)}`)
|
|
603
640
|
}
|
|
604
641
|
}
|
|
605
642
|
|
|
@@ -611,7 +648,7 @@ function assertNumber (value, paramName) {
|
|
|
611
648
|
*/
|
|
612
649
|
function assertPositive (value, paramName) {
|
|
613
650
|
if (!isPositive(value)) {
|
|
614
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
651
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not Positive: ${value}`)
|
|
615
652
|
}
|
|
616
653
|
}
|
|
617
654
|
|
|
@@ -623,7 +660,7 @@ function assertPositive (value, paramName) {
|
|
|
623
660
|
*/
|
|
624
661
|
function assertNegative (value, paramName) {
|
|
625
662
|
if (!isNegative(value)) {
|
|
626
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
663
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not Negative: ${value}`)
|
|
627
664
|
}
|
|
628
665
|
}
|
|
629
666
|
|
|
@@ -635,7 +672,7 @@ function assertNegative (value, paramName) {
|
|
|
635
672
|
*/
|
|
636
673
|
function assertNotNegative (value, paramName) {
|
|
637
674
|
if (!isNotNegative(value)) {
|
|
638
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
675
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not "0 or Positive": ${value}`)
|
|
639
676
|
}
|
|
640
677
|
}
|
|
641
678
|
|
|
@@ -648,7 +685,7 @@ function assertNotNegative (value, paramName) {
|
|
|
648
685
|
*/
|
|
649
686
|
function assertBoolean (value, paramName) {
|
|
650
687
|
if (!isBoolean(value)) {
|
|
651
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
688
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not Boolean: type=${typeof value} value=${safeToString(value)}`)
|
|
652
689
|
}
|
|
653
690
|
}
|
|
654
691
|
/**
|
|
@@ -660,7 +697,7 @@ function assertBoolean (value, paramName) {
|
|
|
660
697
|
*/
|
|
661
698
|
function assertObject (value, paramName) {
|
|
662
699
|
if (!isObject(value)) {
|
|
663
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
700
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not Object: type=${typeof value} value=${safeToString(value)}`)
|
|
664
701
|
}
|
|
665
702
|
}
|
|
666
703
|
/**
|
|
@@ -672,7 +709,7 @@ function assertObject (value, paramName) {
|
|
|
672
709
|
*/
|
|
673
710
|
function assertPlainObject (value, paramName) {
|
|
674
711
|
if (!isPlainObject$1(value)) {
|
|
675
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
712
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not PlainObject: type=${typeof value} value=${safeToString(value)}`)
|
|
676
713
|
}
|
|
677
714
|
}
|
|
678
715
|
/**
|
|
@@ -684,7 +721,7 @@ function assertPlainObject (value, paramName) {
|
|
|
684
721
|
*/
|
|
685
722
|
function assertSymbol (value, paramName) {
|
|
686
723
|
if (!isSymbol(value)) {
|
|
687
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
724
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not Symbol: type=${typeof value} value=${safeToString(value)}`)
|
|
688
725
|
}
|
|
689
726
|
}
|
|
690
727
|
/**
|
|
@@ -696,7 +733,7 @@ function assertSymbol (value, paramName) {
|
|
|
696
733
|
*/
|
|
697
734
|
function assertFunction (value, paramName) {
|
|
698
735
|
if (!isFunction(value)) {
|
|
699
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
736
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not Function: type=${typeof value} value=${safeToString(value)}`)
|
|
700
737
|
}
|
|
701
738
|
}
|
|
702
739
|
/**
|
|
@@ -708,7 +745,7 @@ function assertFunction (value, paramName) {
|
|
|
708
745
|
*/
|
|
709
746
|
function assertInstance (value, paramName) {
|
|
710
747
|
if (!isInstance(value)) {
|
|
711
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
748
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not Class Instance: type=${typeof value} value=${safeToString(value)}`)
|
|
712
749
|
}
|
|
713
750
|
}
|
|
714
751
|
/**
|
|
@@ -720,7 +757,7 @@ function assertInstance (value, paramName) {
|
|
|
720
757
|
*/
|
|
721
758
|
function assertPromise (value, paramName) {
|
|
722
759
|
if (!isPromise(value)) {
|
|
723
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
760
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not Promise: type=${typeof value} value=${safeToString(value)}`)
|
|
724
761
|
}
|
|
725
762
|
}
|
|
726
763
|
/**
|
|
@@ -732,7 +769,7 @@ function assertPromise (value, paramName) {
|
|
|
732
769
|
*/
|
|
733
770
|
function assertNil (value, paramName) {
|
|
734
771
|
if (!isNil(value)) {
|
|
735
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
772
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Neither Null nor Undefined: type=${typeof value} value=${safeToString(value)}`)
|
|
736
773
|
}
|
|
737
774
|
}
|
|
738
775
|
|
|
@@ -744,7 +781,7 @@ function assertNil (value, paramName) {
|
|
|
744
781
|
*/
|
|
745
782
|
function assertNotNil (value, paramName) {
|
|
746
783
|
if (isNil(value)) {
|
|
747
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
784
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Should Not Nil`)
|
|
748
785
|
}
|
|
749
786
|
}
|
|
750
787
|
|
|
@@ -757,7 +794,7 @@ function assertNotNil (value, paramName) {
|
|
|
757
794
|
*/
|
|
758
795
|
function assertNull (value, paramName) {
|
|
759
796
|
if (!isNull(value)) {
|
|
760
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
797
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not Null: type=${typeof value} value=${safeToString(value)}`)
|
|
761
798
|
}
|
|
762
799
|
}
|
|
763
800
|
|
|
@@ -769,7 +806,7 @@ function assertNull (value, paramName) {
|
|
|
769
806
|
*/
|
|
770
807
|
function assertNotNull (value, paramName) {
|
|
771
808
|
if (isNull(value)) {
|
|
772
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
809
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Should Not Null`)
|
|
773
810
|
}
|
|
774
811
|
}
|
|
775
812
|
/**
|
|
@@ -781,7 +818,7 @@ function assertNotNull (value, paramName) {
|
|
|
781
818
|
*/
|
|
782
819
|
function assertUndefined (value, paramName) {
|
|
783
820
|
if (!isUndefined(value)) {
|
|
784
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
821
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not Undefined: type=${typeof value} value=${safeToString(value)}`)
|
|
785
822
|
}
|
|
786
823
|
}
|
|
787
824
|
|
|
@@ -793,7 +830,7 @@ function assertUndefined (value, paramName) {
|
|
|
793
830
|
*/
|
|
794
831
|
function assertStringOrSymbol (value, paramName) {
|
|
795
832
|
if (!isString(value) && !isSymbol(value)) {
|
|
796
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
833
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not String or Symbol: type=${typeof value} value=${safeToString(value)}`)
|
|
797
834
|
}
|
|
798
835
|
}
|
|
799
836
|
|
|
@@ -804,7 +841,7 @@ function assertStringOrSymbol (value, paramName) {
|
|
|
804
841
|
*/
|
|
805
842
|
function assertTypedArray (value, paramName) {
|
|
806
843
|
if (isTypedArray(value)) {
|
|
807
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
844
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not TypedArray`)
|
|
808
845
|
}
|
|
809
846
|
}
|
|
810
847
|
/**
|
|
@@ -814,7 +851,7 @@ function assertTypedArray (value, paramName) {
|
|
|
814
851
|
*/
|
|
815
852
|
function assertInt8Array (value, paramName) {
|
|
816
853
|
if (isInt8Array(value)) {
|
|
817
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
854
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not Int8Array`)
|
|
818
855
|
}
|
|
819
856
|
}
|
|
820
857
|
/**
|
|
@@ -824,7 +861,7 @@ function assertInt8Array (value, paramName) {
|
|
|
824
861
|
*/
|
|
825
862
|
function assertUint8Array (value, paramName) {
|
|
826
863
|
if (isUint8Array(value)) {
|
|
827
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
864
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not Uint8Array`)
|
|
828
865
|
}
|
|
829
866
|
}
|
|
830
867
|
/**
|
|
@@ -834,7 +871,7 @@ function assertUint8Array (value, paramName) {
|
|
|
834
871
|
*/
|
|
835
872
|
function assertUint8ClampedArray (value, paramName) {
|
|
836
873
|
if (isUint8ClampedArray(value)) {
|
|
837
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
874
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not Uint8ClampedArray`)
|
|
838
875
|
}
|
|
839
876
|
}
|
|
840
877
|
/**
|
|
@@ -844,7 +881,7 @@ function assertUint8ClampedArray (value, paramName) {
|
|
|
844
881
|
*/
|
|
845
882
|
function assertInt16Array (value, paramName) {
|
|
846
883
|
if (isInt16Array(value)) {
|
|
847
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
884
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not Int16Array`)
|
|
848
885
|
}
|
|
849
886
|
}
|
|
850
887
|
/**
|
|
@@ -854,7 +891,7 @@ function assertInt16Array (value, paramName) {
|
|
|
854
891
|
*/
|
|
855
892
|
function assertUint16Array (value, paramName) {
|
|
856
893
|
if (isUint16Array(value)) {
|
|
857
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
894
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not Uint16Array`)
|
|
858
895
|
}
|
|
859
896
|
}
|
|
860
897
|
/**
|
|
@@ -864,7 +901,7 @@ function assertUint16Array (value, paramName) {
|
|
|
864
901
|
*/
|
|
865
902
|
function assertInt32Array (value, paramName) {
|
|
866
903
|
if (isInt32Array(value)) {
|
|
867
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
904
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not Int32Array`)
|
|
868
905
|
}
|
|
869
906
|
}
|
|
870
907
|
/**
|
|
@@ -874,7 +911,7 @@ function assertInt32Array (value, paramName) {
|
|
|
874
911
|
*/
|
|
875
912
|
function assertUint32Array (value, paramName) {
|
|
876
913
|
if (isUint32Array(value)) {
|
|
877
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
914
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not Uint32Array`)
|
|
878
915
|
}
|
|
879
916
|
}
|
|
880
917
|
/**
|
|
@@ -884,7 +921,7 @@ function assertUint32Array (value, paramName) {
|
|
|
884
921
|
*/
|
|
885
922
|
function assertFloat32Array (value, paramName) {
|
|
886
923
|
if (isFloat32Array(value)) {
|
|
887
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
924
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not Float32Array`)
|
|
888
925
|
}
|
|
889
926
|
}
|
|
890
927
|
/**
|
|
@@ -894,7 +931,7 @@ function assertFloat32Array (value, paramName) {
|
|
|
894
931
|
*/
|
|
895
932
|
function assertFloat64Array (value, paramName) {
|
|
896
933
|
if (isFloat64Array(value)) {
|
|
897
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
934
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not Float64Array`)
|
|
898
935
|
}
|
|
899
936
|
}
|
|
900
937
|
/**
|
|
@@ -904,7 +941,7 @@ function assertFloat64Array (value, paramName) {
|
|
|
904
941
|
*/
|
|
905
942
|
function assertBigInt64Array (value, paramName) {
|
|
906
943
|
if (isBigInt64Array(value)) {
|
|
907
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
944
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not BigInt64Array`)
|
|
908
945
|
}
|
|
909
946
|
}
|
|
910
947
|
/**
|
|
@@ -914,7 +951,7 @@ function assertBigInt64Array (value, paramName) {
|
|
|
914
951
|
*/
|
|
915
952
|
function assertBigUint64Array (value, paramName) {
|
|
916
953
|
if (isBigUint64Array(value)) {
|
|
917
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
954
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not BigUint64Array`)
|
|
918
955
|
}
|
|
919
956
|
}
|
|
920
957
|
|
|
@@ -926,7 +963,7 @@ function assertBigUint64Array (value, paramName) {
|
|
|
926
963
|
*/
|
|
927
964
|
function assertArrayBuffer (value, paramName) {
|
|
928
965
|
if (!isArrayBuffer(value)) {
|
|
929
|
-
throw new Error(`${paramName ? '"' + paramName + '" ' : '
|
|
966
|
+
throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not ArrayBuffer`)
|
|
930
967
|
}
|
|
931
968
|
}
|
|
932
969
|
|
|
@@ -955,7 +992,8 @@ var StringUtils = {
|
|
|
955
992
|
substringAfterLast,
|
|
956
993
|
substringBetween,
|
|
957
994
|
substringBetweenGreedy,
|
|
958
|
-
substringsBetween
|
|
995
|
+
substringsBetween,
|
|
996
|
+
safeToString
|
|
959
997
|
};
|
|
960
998
|
|
|
961
999
|
/**
|
|
@@ -1352,6 +1390,22 @@ function substringsBetween (str, startMarker, endMarker) {
|
|
|
1352
1390
|
return substrings
|
|
1353
1391
|
}
|
|
1354
1392
|
|
|
1393
|
+
/**
|
|
1394
|
+
* Safely converts a value to its string representation.
|
|
1395
|
+
* Attempts to use JSON.stringify first, falls back to toString() if stringify fails.
|
|
1396
|
+
* @param {*} value - The value to convert to string
|
|
1397
|
+
* @returns {string} The string representation of the value
|
|
1398
|
+
*/
|
|
1399
|
+
function safeToString (value) {
|
|
1400
|
+
let valueStr;
|
|
1401
|
+
try {
|
|
1402
|
+
valueStr = JSON.stringify(value);
|
|
1403
|
+
} catch (e) {
|
|
1404
|
+
valueStr = value.toString();
|
|
1405
|
+
}
|
|
1406
|
+
return valueStr
|
|
1407
|
+
}
|
|
1408
|
+
|
|
1355
1409
|
/**
|
|
1356
1410
|
* @module ExecUtils
|
|
1357
1411
|
* @description Utils about how to execute task functions.
|
|
@@ -1429,6 +1483,7 @@ var ExecUtils = {
|
|
|
1429
1483
|
* promise: Promise<*>,
|
|
1430
1484
|
* timerHandler: NodeJS.Timeout,
|
|
1431
1485
|
* timerCleared: boolean,
|
|
1486
|
+
* pending: boolean,
|
|
1432
1487
|
* resolved: boolean,
|
|
1433
1488
|
* rejected: boolean,
|
|
1434
1489
|
* canceled: boolean,
|
|
@@ -1441,7 +1496,8 @@ var ExecUtils = {
|
|
|
1441
1496
|
* @typedef {{
|
|
1442
1497
|
* promise: Promise<*>,
|
|
1443
1498
|
* timerHandler: NodeJS.Timeout,
|
|
1444
|
-
*
|
|
1499
|
+
* _resolve: (...args:any[])=> void,
|
|
1500
|
+
* wakeup: ()=> void
|
|
1445
1501
|
* }} Waiter
|
|
1446
1502
|
*/
|
|
1447
1503
|
|
|
@@ -1450,6 +1506,7 @@ var ExecUtils = {
|
|
|
1450
1506
|
* @description Promise utility functions for enhanced promise handling, including timeout, delay, parallel execution, and series execution.
|
|
1451
1507
|
*/
|
|
1452
1508
|
var PromiseUtils = {
|
|
1509
|
+
any,
|
|
1453
1510
|
defer,
|
|
1454
1511
|
delay,
|
|
1455
1512
|
timeout,
|
|
@@ -1458,6 +1515,7 @@ var PromiseUtils = {
|
|
|
1458
1515
|
series,
|
|
1459
1516
|
seriesAllSettled,
|
|
1460
1517
|
parallel,
|
|
1518
|
+
parallelAny,
|
|
1461
1519
|
parallelAllSettled,
|
|
1462
1520
|
wait
|
|
1463
1521
|
};
|
|
@@ -1473,48 +1531,66 @@ function defer (timeout = -1, timeoutMessage) {
|
|
|
1473
1531
|
assertNumber(timeout);
|
|
1474
1532
|
/** @type {Deferred} */
|
|
1475
1533
|
const rtnVal = {};
|
|
1476
|
-
|
|
1534
|
+
rtnVal.pending = true;
|
|
1535
|
+
rtnVal.canceled = false;
|
|
1536
|
+
rtnVal.rejected = false;
|
|
1537
|
+
rtnVal.resolved = false;
|
|
1477
1538
|
/**
|
|
1478
1539
|
* @type {NodeJS.Timeout}
|
|
1479
1540
|
*/
|
|
1480
1541
|
let timerHandler;
|
|
1481
1542
|
if (timeout >= 0) {
|
|
1543
|
+
rtnVal.timerCleared = false;
|
|
1482
1544
|
rtnVal.timerHandler = timerHandler = setTimeout(() => {
|
|
1483
1545
|
clearTimeout(timerHandler); // must clear it
|
|
1484
|
-
rtnVal.timerCleared = true;
|
|
1546
|
+
rtnVal.timerCleared = true;
|
|
1485
1547
|
rtnVal.reject(new Error(timeoutMessage ?? `Promise Timeout: ${timeout}ms`));
|
|
1486
1548
|
}, timeout);
|
|
1487
1549
|
}
|
|
1488
1550
|
|
|
1489
1551
|
rtnVal.promise = new Promise((resolve, reject) => {
|
|
1490
1552
|
rtnVal.resolve = (arg) => {
|
|
1553
|
+
if (rtnVal.resolved || rtnVal.rejected || rtnVal.canceled) {
|
|
1554
|
+
return // already done, Can Not operate again
|
|
1555
|
+
}
|
|
1491
1556
|
if (timerHandler != null) {
|
|
1492
1557
|
clearTimeout(timerHandler); // must clear it
|
|
1493
|
-
rtnVal.timerCleared = true;
|
|
1558
|
+
rtnVal.timerCleared = true;
|
|
1494
1559
|
}
|
|
1560
|
+
rtnVal.pending = false;
|
|
1561
|
+
rtnVal.canceled = false;
|
|
1562
|
+
rtnVal.rejected = false;
|
|
1495
1563
|
rtnVal.resolved = true;
|
|
1496
1564
|
resolve(arg);
|
|
1497
1565
|
};
|
|
1498
1566
|
|
|
1499
1567
|
rtnVal.reject = (err) => {
|
|
1568
|
+
if (rtnVal.resolved || rtnVal.rejected || rtnVal.canceled) {
|
|
1569
|
+
return // already done, Can Not operate again
|
|
1570
|
+
}
|
|
1500
1571
|
if (timerHandler != null) {
|
|
1501
1572
|
clearTimeout(timerHandler); // must clear it
|
|
1502
|
-
rtnVal.timerCleared = true;
|
|
1573
|
+
rtnVal.timerCleared = true;
|
|
1503
1574
|
}
|
|
1575
|
+
rtnVal.pending = false;
|
|
1576
|
+
rtnVal.canceled = false;
|
|
1577
|
+
rtnVal.resolved = false;
|
|
1504
1578
|
rtnVal.rejected = true;
|
|
1505
1579
|
reject(err);
|
|
1506
1580
|
};
|
|
1507
1581
|
});
|
|
1508
1582
|
// @ts-ignore
|
|
1509
|
-
rtnVal.promise.cancel = () => {
|
|
1583
|
+
rtnVal.cancel = rtnVal.promise.cancel = (reason) => {
|
|
1584
|
+
if (rtnVal.resolved || rtnVal.rejected || rtnVal.canceled) {
|
|
1585
|
+
return // already done, Can Not operate again
|
|
1586
|
+
}
|
|
1510
1587
|
if (timerHandler != null) {
|
|
1511
1588
|
clearTimeout(timerHandler); // must clear it
|
|
1512
|
-
rtnVal.timerCleared = true;
|
|
1589
|
+
rtnVal.timerCleared = true;
|
|
1513
1590
|
}
|
|
1514
|
-
rtnVal.
|
|
1591
|
+
rtnVal.reject(reason ?? new Error('Cancelled'));
|
|
1515
1592
|
// @ts-ignore
|
|
1516
|
-
rtnVal.canceled = rtnVal.promise.canceled = true;
|
|
1517
|
-
rtnVal.reject(new Error('Cancelled'));
|
|
1593
|
+
rtnVal.canceled = rtnVal.promise.canceled = true;
|
|
1518
1594
|
};
|
|
1519
1595
|
return rtnVal
|
|
1520
1596
|
}
|
|
@@ -1585,7 +1661,7 @@ async function allSettled (promises) {
|
|
|
1585
1661
|
function returnValuePromised (task) {
|
|
1586
1662
|
try {
|
|
1587
1663
|
const taskRtnVal = task();
|
|
1588
|
-
if (isPromise(taskRtnVal)) {
|
|
1664
|
+
if (TypeUtils.isPromise(taskRtnVal)) {
|
|
1589
1665
|
return taskRtnVal
|
|
1590
1666
|
}
|
|
1591
1667
|
return Promise.resolve(taskRtnVal)
|
|
@@ -1606,7 +1682,7 @@ function returnValuePromised (task) {
|
|
|
1606
1682
|
* @returns {Promise<*>} A new promise that settles after the delay period
|
|
1607
1683
|
*/
|
|
1608
1684
|
function delay (promise, ms) {
|
|
1609
|
-
if (isNumber(promise)) { // defer(ms)
|
|
1685
|
+
if (TypeUtils.isNumber(promise)) { // defer(ms)
|
|
1610
1686
|
// @ts-ignore
|
|
1611
1687
|
ms = promise;
|
|
1612
1688
|
promise = Promise.resolve();
|
|
@@ -1638,21 +1714,78 @@ function delay (promise, ms) {
|
|
|
1638
1714
|
});
|
|
1639
1715
|
return deferred.promise
|
|
1640
1716
|
}
|
|
1717
|
+
/**
|
|
1718
|
+
* 1. run all tasks
|
|
1719
|
+
* 2. any Task succeed, return its result
|
|
1720
|
+
* * resolve with the result.
|
|
1721
|
+
* * the others tasks will run to its end, and results will be dropped.
|
|
1722
|
+
* 3. If all tasks fail, rejects with an array of errors. the array length is same as the input tasks
|
|
1723
|
+
* @param {Array<Promise<any>|Function>} tasks - Array of promises or async functions to execute
|
|
1724
|
+
* @returns {Promise<any>} A promise that resolves with the result of the first successful task
|
|
1725
|
+
*/
|
|
1726
|
+
function any (tasks) {
|
|
1727
|
+
assertArray(tasks);
|
|
1728
|
+
if (tasks.length === 0) {
|
|
1729
|
+
throw new Error('Empty Tasks')
|
|
1730
|
+
}
|
|
1731
|
+
const deferred = defer();
|
|
1732
|
+
/** @type {any[]} */
|
|
1733
|
+
const errors = [];
|
|
1734
|
+
for (let i = 0; i < tasks.length; i++) {
|
|
1735
|
+
const task = tasks[i];
|
|
1736
|
+
/** @type {Promise<any>} */
|
|
1737
|
+
let taskPromise;
|
|
1738
|
+
if (TypeUtils.isPromise(task)) {
|
|
1739
|
+
// @ts-ignore
|
|
1740
|
+
taskPromise = task;
|
|
1741
|
+
} else if (TypeUtils.isFunction(task)) {
|
|
1742
|
+
// @ts-ignore
|
|
1743
|
+
taskPromise = returnValuePromised(task);
|
|
1744
|
+
} else {
|
|
1745
|
+
errors.push(new Error(`Invalid Task at index ${i}/${tasks.length - 1}: ${task}`));
|
|
1746
|
+
continue
|
|
1747
|
+
}
|
|
1748
|
+
taskPromise.then(/** @type {any} */ rtnVal => {
|
|
1749
|
+
deferred.resolve(rtnVal);
|
|
1750
|
+
}).catch(e => {
|
|
1751
|
+
errors.push(e);
|
|
1752
|
+
// all tasks failed
|
|
1753
|
+
if (errors.length >= tasks.length) {
|
|
1754
|
+
deferred.reject(errors);
|
|
1755
|
+
}
|
|
1756
|
+
});
|
|
1757
|
+
}
|
|
1758
|
+
if (errors.length === tasks.length) {
|
|
1759
|
+
deferred.reject(errors);
|
|
1760
|
+
}
|
|
1761
|
+
return deferred.promise
|
|
1762
|
+
}
|
|
1641
1763
|
|
|
1642
1764
|
/**
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1765
|
+
* Execute Tasks(functions) in series (one after another) and returns their results in order.
|
|
1766
|
+
* 1. Tasks are executed one by one
|
|
1767
|
+
* * if task is a function, execute it.
|
|
1768
|
+
* * if task is a promise, wait for it to settle.
|
|
1769
|
+
* 2. Fast Fail: if any tasks fail, the whole chain is rejected with the first error
|
|
1770
|
+
* 3. if an element is not function, rejects the whole chain with Error(Not Function)
|
|
1771
|
+
* 4. All Tasks run successfully, Return Results Array, it's length is same as the input tasks
|
|
1772
|
+
* @param {Array<Promise<any>|Function>} tasks
|
|
1773
|
+
* @returns {Promise<any[]>} Promise that resolves with an array of results in the same order as input tasks
|
|
1774
|
+
*/
|
|
1650
1775
|
async function series (tasks) {
|
|
1651
1776
|
assertArray(tasks);
|
|
1652
1777
|
const results = [];
|
|
1653
1778
|
for (const task of tasks) {
|
|
1654
1779
|
assertFunction(task);
|
|
1655
|
-
|
|
1780
|
+
if (TypeUtils.isFunction(task)) {
|
|
1781
|
+
// @ts-ignore
|
|
1782
|
+
results.push(await returnValuePromised(task));
|
|
1783
|
+
} else if (TypeUtils.isPromise(task)) {
|
|
1784
|
+
// @ts-ignore
|
|
1785
|
+
results.push(await task);
|
|
1786
|
+
} else {
|
|
1787
|
+
throw new Error(`Invalid Task: ${task}`)
|
|
1788
|
+
}
|
|
1656
1789
|
}
|
|
1657
1790
|
return results
|
|
1658
1791
|
}
|
|
@@ -1727,7 +1860,7 @@ async function parallel (tasks, maxParallel = 5) {
|
|
|
1727
1860
|
* 2. all tasks will be executed, even some of them failed.
|
|
1728
1861
|
* @param {Function[]} tasks
|
|
1729
1862
|
* @param {number} [maxParallel=5] - Maximum number of tasks to run in parallel
|
|
1730
|
-
* @returns {Promise<any[]>}
|
|
1863
|
+
* @returns {Promise<{ok: boolean, result: any}[]>}
|
|
1731
1864
|
* @throws {TypeError} If input is not an array of export function or maxParallel is not a number
|
|
1732
1865
|
*/
|
|
1733
1866
|
async function parallelAllSettled (tasks, maxParallel = 5) {
|
|
@@ -1747,7 +1880,6 @@ async function parallelAllSettled (tasks, maxParallel = 5) {
|
|
|
1747
1880
|
// run group by MaxParallel
|
|
1748
1881
|
const tasksToRun = [];
|
|
1749
1882
|
for (const task of tasks) {
|
|
1750
|
-
assertFunction(task);
|
|
1751
1883
|
tasksToRun.push(task);
|
|
1752
1884
|
if (tasksToRun.length >= maxParallel) {
|
|
1753
1885
|
const resultsForBatch = await allSettled(tasksToRun.map(task => returnValuePromised(task)));
|
|
@@ -1763,6 +1895,76 @@ async function parallelAllSettled (tasks, maxParallel = 5) {
|
|
|
1763
1895
|
return rtnVal
|
|
1764
1896
|
}
|
|
1765
1897
|
|
|
1898
|
+
/**
|
|
1899
|
+
* Executes multiple async tasks in parallel with limited concurrency,
|
|
1900
|
+
* 1. resolving when any task completes successfully.
|
|
1901
|
+
* 2. Maybe multiple tasks are executed as a bulk block, and all of them resolved.
|
|
1902
|
+
* * only the first fulfilled value is returned
|
|
1903
|
+
* * other results are dropped
|
|
1904
|
+
* @param {Array<Function|Promise<any>>} tasks - Array of async functions to execute
|
|
1905
|
+
* @param {number} [maxParallel=5] - Maximum number of tasks to run in parallel
|
|
1906
|
+
* @returns {Promise<any>} Resolves with the result of the first successfully completed task
|
|
1907
|
+
*/
|
|
1908
|
+
async function parallelAny (tasks, maxParallel = 5) {
|
|
1909
|
+
assertArray(tasks, 'tasks');
|
|
1910
|
+
assertNumber(maxParallel);
|
|
1911
|
+
if (tasks.length === 0) {
|
|
1912
|
+
throw new Error('Empty Tasks')
|
|
1913
|
+
}
|
|
1914
|
+
if (maxParallel <= 0) {
|
|
1915
|
+
throw new Error(`Invalid maxParallel: ${maxParallel}, should > 0`)
|
|
1916
|
+
}
|
|
1917
|
+
/** @type {any[]} */
|
|
1918
|
+
const errors = [];
|
|
1919
|
+
let taskIndex = 0;
|
|
1920
|
+
let runningTasksCount = 0;
|
|
1921
|
+
const deferred = defer();
|
|
1922
|
+
function takeTaskAndRun () {
|
|
1923
|
+
if (taskIndex >= tasks.length) {
|
|
1924
|
+
return // no more task
|
|
1925
|
+
}
|
|
1926
|
+
// reach max parallel, wait for one task to finish
|
|
1927
|
+
if (runningTasksCount > maxParallel) {
|
|
1928
|
+
return
|
|
1929
|
+
}
|
|
1930
|
+
const task = tasks[taskIndex++];
|
|
1931
|
+
runningTasksCount++;
|
|
1932
|
+
/** @type {Promise<any>} */
|
|
1933
|
+
let taskPromise;
|
|
1934
|
+
if (TypeUtils.isPromise(task)) {
|
|
1935
|
+
// @ts-ignore
|
|
1936
|
+
taskPromise = task;
|
|
1937
|
+
} else if (TypeUtils.isFunction(task)) {
|
|
1938
|
+
// @ts-ignore
|
|
1939
|
+
taskPromise = returnValuePromised(task);
|
|
1940
|
+
} else {
|
|
1941
|
+
errors.push(new TypeError(`Invalid task: ${task}`));
|
|
1942
|
+
takeTaskAndRun();
|
|
1943
|
+
return
|
|
1944
|
+
}
|
|
1945
|
+
taskPromise.then(/** @type {any} */ rtnVal => {
|
|
1946
|
+
deferred.resolve(rtnVal);
|
|
1947
|
+
}).catch(e => {
|
|
1948
|
+
errors.push(e);
|
|
1949
|
+
// No task left, and No successful execution, reject with errors
|
|
1950
|
+
if (errors.length >= tasks.length) {
|
|
1951
|
+
if (deferred.pending) {
|
|
1952
|
+
deferred.reject(errors);
|
|
1953
|
+
return
|
|
1954
|
+
}
|
|
1955
|
+
}
|
|
1956
|
+
takeTaskAndRun();
|
|
1957
|
+
}).finally(() => {
|
|
1958
|
+
runningTasksCount--;
|
|
1959
|
+
});
|
|
1960
|
+
}
|
|
1961
|
+
// start tasks until maxParallel
|
|
1962
|
+
while (runningTasksCount < maxParallel) {
|
|
1963
|
+
takeTaskAndRun();
|
|
1964
|
+
}
|
|
1965
|
+
return deferred.promise
|
|
1966
|
+
}
|
|
1967
|
+
|
|
1766
1968
|
/**
|
|
1767
1969
|
* Creates a "Waiter" Object
|
|
1768
1970
|
* 1. wait the specified time
|
|
@@ -1781,17 +1983,20 @@ function wait (waitTime) {
|
|
|
1781
1983
|
let timerHandler;
|
|
1782
1984
|
rtnVal.timerHandler = timerHandler = setTimeout(() => {
|
|
1783
1985
|
clearTimeout(timerHandler); // must clear it
|
|
1784
|
-
rtnVal.
|
|
1986
|
+
rtnVal._resolve();
|
|
1785
1987
|
}, waitTime);
|
|
1786
1988
|
|
|
1787
1989
|
rtnVal.promise = new Promise((resolve, reject) => {
|
|
1788
|
-
rtnVal.
|
|
1990
|
+
rtnVal._resolve = (arg) => {
|
|
1789
1991
|
if (timerHandler != null) {
|
|
1790
1992
|
clearTimeout(timerHandler); // must clear it
|
|
1791
1993
|
}
|
|
1792
1994
|
resolve(arg);
|
|
1793
1995
|
};
|
|
1794
1996
|
});
|
|
1997
|
+
rtnVal.wakeup = () => {
|
|
1998
|
+
rtnVal._resolve();
|
|
1999
|
+
};
|
|
1795
2000
|
return rtnVal
|
|
1796
2001
|
}
|
|
1797
2002
|
|
|
@@ -2252,6 +2457,7 @@ function timeoutMillis (nanoTimestamp64, millisTimeout) {
|
|
|
2252
2457
|
|
|
2253
2458
|
var ArrayUtils = {
|
|
2254
2459
|
first,
|
|
2460
|
+
chunk,
|
|
2255
2461
|
last,
|
|
2256
2462
|
equals,
|
|
2257
2463
|
equalsIgnoreOrder
|
|
@@ -2335,6 +2541,27 @@ function equals (arr1, arr2, compareFn) {
|
|
|
2335
2541
|
return true
|
|
2336
2542
|
}
|
|
2337
2543
|
|
|
2544
|
+
/**
|
|
2545
|
+
* Splits an array into chunks of the specified size.
|
|
2546
|
+
* @param {any[]} array - The array to be chunked.
|
|
2547
|
+
* @param {number} size - The size of each chunk.
|
|
2548
|
+
* @returns {any[]} An array of arrays containing the chunks.
|
|
2549
|
+
*/
|
|
2550
|
+
function chunk (array, size) {
|
|
2551
|
+
assertArray(array, 'array');
|
|
2552
|
+
assertPositive(size, 'size');
|
|
2553
|
+
if (array.length <= size) {
|
|
2554
|
+
return array
|
|
2555
|
+
}
|
|
2556
|
+
const chunked = [];
|
|
2557
|
+
let index = 0;
|
|
2558
|
+
while (index < array.length) {
|
|
2559
|
+
chunked.push(array.slice(index, size + index));
|
|
2560
|
+
index += size;
|
|
2561
|
+
}
|
|
2562
|
+
return chunked
|
|
2563
|
+
}
|
|
2564
|
+
|
|
2338
2565
|
/**
|
|
2339
2566
|
* @module Lang
|
|
2340
2567
|
* @description Core language utilities for type checking, string manipulation, and common operations.
|