@creejs/commons-lang 2.1.19 → 2.1.21

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.
@@ -2,6 +2,104 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
+ class _Error extends Error {
6
+ /**
7
+ * Creates and returns a 404 Not Found error instance with the given message.
8
+ * @param {string} message - The error message to include.
9
+ * @returns {_Error} A new Error instance with status code 404.
10
+ */
11
+ static notFound (message) {
12
+ return new _Error(`Not Found: ${message}`, 404)
13
+ }
14
+
15
+ static notImpled () {
16
+ return new _Error('Not Impled Yet', 501)
17
+ }
18
+
19
+ /**
20
+ * Creates and returns a new Error instance for not supported operations.
21
+ * @param {string} message - The error message to include.
22
+ * @returns {_Error} A new Error instance with "Not Supported:" prefix and 505 status code.
23
+ */
24
+ static notSupported (message) {
25
+ return new _Error('Not Supported:' + message, 505)
26
+ }
27
+
28
+ /**
29
+ * Checks if the given error is a "Not Supported" error.
30
+ * @param {Error|_Error|{[key:string]:any}|unknown} err - The error to check
31
+ * @returns {boolean} True if the error is a Not Supported error (code 505), false otherwise
32
+ */
33
+ static isNotSupported (err) {
34
+ // @ts-ignore
35
+ return err?.code === 505
36
+ }
37
+
38
+ /**
39
+ * Error constructor with custom message and code.
40
+ * @param {string} message - Error message
41
+ * @param {number|string} code - Error code
42
+ */
43
+ constructor (message, code) {
44
+ super(message);
45
+ this.code = code;
46
+ }
47
+ }
48
+
49
+ class AggregatedError extends Error {
50
+ /**
51
+ * Checks if the given error is an AggregatedErrorLike
52
+ * 1. have "message:string" property
53
+ * 2. have "errors:Error[]" property
54
+ * @param {any} err - The error to check
55
+ * @returns {boolean} True if the error is an AggregatedError, false otherwise
56
+ */
57
+ static isAggregatedErrorLike (err) {
58
+ return err && Array.isArray(err.errors)
59
+ }
60
+
61
+ /**
62
+ * Checks if the given error is an instance of AggregatedError.
63
+ * @param {Error} err - The error to check.
64
+ * @returns {boolean} True if the error is an AggregatedError, false otherwise.
65
+ */
66
+ static isAggregatedError (err) {
67
+ return err instanceof AggregatedError
68
+ }
69
+
70
+ /**
71
+ * Error constructor with custom message and code.
72
+ * @param {string} message - Error message
73
+ * @param {any[]} [errors] - Errors
74
+ */
75
+ constructor (message, errors) {
76
+ super(message);
77
+ this.errors = errors ?? [];
78
+ }
79
+
80
+ /**
81
+ * Adds an error to the errors collection.
82
+ * @param {any} err - The error object to be added.
83
+ */
84
+ addError (err) {
85
+ this.errors.push(err);
86
+ }
87
+
88
+ /**
89
+ * Removes a specific error from the errors array.
90
+ * @param {Error} err - The error instance to remove.
91
+ * @returns {boolean} True if the error was found and removed, false otherwise.
92
+ */
93
+ removeError (err) {
94
+ const index = this.errors.indexOf(err);
95
+ if (index === -1) {
96
+ return false
97
+ }
98
+ this.errors.splice(index, 1);
99
+ return true
100
+ }
101
+ }
102
+
5
103
  /**
6
104
  * @module LangUtils
7
105
  * @description Language utility functions
@@ -616,7 +714,7 @@ var TypeAssert = {
616
714
  */
617
715
  function assertArray (value, paramName) {
618
716
  if (!Array.isArray(value)) {
619
- throw new Error(`${paramName ? '"' + paramName + '" ' : ' '}Not Array: type=${typeof value} value=${JSON.stringify(value)}`)
717
+ throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not Array: type=${typeof value} value=${safeToString(value)}`)
620
718
  }
621
719
  }
622
720
  /**
@@ -628,7 +726,7 @@ function assertArray (value, paramName) {
628
726
  */
629
727
  function assertString (value, paramName) {
630
728
  if (!isString(value)) {
631
- throw new Error(`${paramName ? '"' + paramName + '" ' : ' '}Not String: type=${typeof value} value=${JSON.stringify(value)}`)
729
+ throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not String: type=${typeof value} value=${safeToString(value)}`)
632
730
  }
633
731
  }
634
732
  /**
@@ -640,7 +738,7 @@ function assertString (value, paramName) {
640
738
  */
641
739
  function assertNumber (value, paramName) {
642
740
  if (!isNumber(value)) {
643
- throw new Error(`${paramName ? '"' + paramName + '" ' : ' '}Not Number: type=${typeof value} value=${JSON.stringify(value)}`)
741
+ throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not Number: type=${typeof value} value=${safeToString(value)}`)
644
742
  }
645
743
  }
646
744
 
@@ -652,7 +750,7 @@ function assertNumber (value, paramName) {
652
750
  */
653
751
  function assertPositive (value, paramName) {
654
752
  if (!isPositive(value)) {
655
- throw new Error(`${paramName ? '"' + paramName + '" ' : ' '}Not Positive: ${value}`)
753
+ throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not Positive: ${value}`)
656
754
  }
657
755
  }
658
756
 
@@ -664,7 +762,7 @@ function assertPositive (value, paramName) {
664
762
  */
665
763
  function assertNegative (value, paramName) {
666
764
  if (!isNegative(value)) {
667
- throw new Error(`${paramName ? '"' + paramName + '" ' : ' '}Not Negative: ${value}`)
765
+ throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not Negative: ${value}`)
668
766
  }
669
767
  }
670
768
 
@@ -676,7 +774,7 @@ function assertNegative (value, paramName) {
676
774
  */
677
775
  function assertNotNegative (value, paramName) {
678
776
  if (!isNotNegative(value)) {
679
- throw new Error(`${paramName ? '"' + paramName + '" ' : ' '}Not "0 or Positive": ${value}`)
777
+ throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not "0 or Positive": ${value}`)
680
778
  }
681
779
  }
682
780
 
@@ -689,7 +787,7 @@ function assertNotNegative (value, paramName) {
689
787
  */
690
788
  function assertBoolean (value, paramName) {
691
789
  if (!isBoolean(value)) {
692
- throw new Error(`${paramName ? '"' + paramName + '" ' : ' '}Not Boolean: type=${typeof value} value=${JSON.stringify(value)}`)
790
+ throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not Boolean: type=${typeof value} value=${safeToString(value)}`)
693
791
  }
694
792
  }
695
793
  /**
@@ -701,7 +799,7 @@ function assertBoolean (value, paramName) {
701
799
  */
702
800
  function assertObject (value, paramName) {
703
801
  if (!isObject(value)) {
704
- throw new Error(`${paramName ? '"' + paramName + '" ' : ' '}Not Object: type=${typeof value} value=${JSON.stringify(value)}`)
802
+ throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not Object: type=${typeof value} value=${safeToString(value)}`)
705
803
  }
706
804
  }
707
805
  /**
@@ -713,7 +811,7 @@ function assertObject (value, paramName) {
713
811
  */
714
812
  function assertPlainObject (value, paramName) {
715
813
  if (!isPlainObject$1(value)) {
716
- throw new Error(`${paramName ? '"' + paramName + '" ' : ' '}Not PlainObject: type=${typeof value} value=${JSON.stringify(value)}`)
814
+ throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not PlainObject: type=${typeof value} value=${safeToString(value)}`)
717
815
  }
718
816
  }
719
817
  /**
@@ -725,7 +823,7 @@ function assertPlainObject (value, paramName) {
725
823
  */
726
824
  function assertSymbol (value, paramName) {
727
825
  if (!isSymbol(value)) {
728
- throw new Error(`${paramName ? '"' + paramName + '" ' : ' '}Not Symbol: type=${typeof value} value=${JSON.stringify(value)}`)
826
+ throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not Symbol: type=${typeof value} value=${safeToString(value)}`)
729
827
  }
730
828
  }
731
829
  /**
@@ -737,7 +835,7 @@ function assertSymbol (value, paramName) {
737
835
  */
738
836
  function assertFunction (value, paramName) {
739
837
  if (!isFunction(value)) {
740
- throw new Error(`${paramName ? '"' + paramName + '" ' : ' '}Not Function: type=${typeof value} value=${JSON.stringify(value)}`)
838
+ throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not Function: type=${typeof value} value=${safeToString(value)}`)
741
839
  }
742
840
  }
743
841
  /**
@@ -749,7 +847,7 @@ function assertFunction (value, paramName) {
749
847
  */
750
848
  function assertInstance (value, paramName) {
751
849
  if (!isInstance(value)) {
752
- throw new Error(`${paramName ? '"' + paramName + '" ' : ' '}Not Class Instance: type=${typeof value} value=${JSON.stringify(value)}`)
850
+ throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not Class Instance: type=${typeof value} value=${safeToString(value)}`)
753
851
  }
754
852
  }
755
853
  /**
@@ -761,7 +859,7 @@ function assertInstance (value, paramName) {
761
859
  */
762
860
  function assertPromise (value, paramName) {
763
861
  if (!isPromise(value)) {
764
- throw new Error(`${paramName ? '"' + paramName + '" ' : ' '}Not Promise: type=${typeof value} value=${JSON.stringify(value)}`)
862
+ throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not Promise: type=${typeof value} value=${safeToString(value)}`)
765
863
  }
766
864
  }
767
865
  /**
@@ -773,7 +871,7 @@ function assertPromise (value, paramName) {
773
871
  */
774
872
  function assertNil (value, paramName) {
775
873
  if (!isNil(value)) {
776
- throw new Error(`${paramName ? '"' + paramName + '" ' : ' '}Neither Null nor Undefined: type=${typeof value} value=${JSON.stringify(value)}`)
874
+ throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Neither Null nor Undefined: type=${typeof value} value=${safeToString(value)}`)
777
875
  }
778
876
  }
779
877
 
@@ -785,7 +883,7 @@ function assertNil (value, paramName) {
785
883
  */
786
884
  function assertNotNil (value, paramName) {
787
885
  if (isNil(value)) {
788
- throw new Error(`${paramName ? '"' + paramName + '" ' : ' '}Should Not Nil`)
886
+ throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Should Not Nil`)
789
887
  }
790
888
  }
791
889
 
@@ -798,7 +896,7 @@ function assertNotNil (value, paramName) {
798
896
  */
799
897
  function assertNull (value, paramName) {
800
898
  if (!isNull(value)) {
801
- throw new Error(`${paramName ? '"' + paramName + '" ' : ' '}Not Null: type=${typeof value} value=${JSON.stringify(value)}`)
899
+ throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not Null: type=${typeof value} value=${safeToString(value)}`)
802
900
  }
803
901
  }
804
902
 
@@ -810,7 +908,7 @@ function assertNull (value, paramName) {
810
908
  */
811
909
  function assertNotNull (value, paramName) {
812
910
  if (isNull(value)) {
813
- throw new Error(`${paramName ? '"' + paramName + '" ' : ' '}Should Not Null`)
911
+ throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Should Not Null`)
814
912
  }
815
913
  }
816
914
  /**
@@ -822,7 +920,7 @@ function assertNotNull (value, paramName) {
822
920
  */
823
921
  function assertUndefined (value, paramName) {
824
922
  if (!isUndefined(value)) {
825
- throw new Error(`${paramName ? '"' + paramName + '" ' : ' '}Not Undefined: type=${typeof value} value=${JSON.stringify(value)}`)
923
+ throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not Undefined: type=${typeof value} value=${safeToString(value)}`)
826
924
  }
827
925
  }
828
926
 
@@ -834,7 +932,7 @@ function assertUndefined (value, paramName) {
834
932
  */
835
933
  function assertStringOrSymbol (value, paramName) {
836
934
  if (!isString(value) && !isSymbol(value)) {
837
- throw new Error(`${paramName ? '"' + paramName + '" ' : ' '}Not String or Symbol: type=${typeof value} value=${JSON.stringify(value)}`)
935
+ throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not String or Symbol: type=${typeof value} value=${safeToString(value)}`)
838
936
  }
839
937
  }
840
938
 
@@ -845,7 +943,7 @@ function assertStringOrSymbol (value, paramName) {
845
943
  */
846
944
  function assertTypedArray (value, paramName) {
847
945
  if (isTypedArray(value)) {
848
- throw new Error(`${paramName ? '"' + paramName + '" ' : ' '}Not TypedArray`)
946
+ throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not TypedArray`)
849
947
  }
850
948
  }
851
949
  /**
@@ -855,7 +953,7 @@ function assertTypedArray (value, paramName) {
855
953
  */
856
954
  function assertInt8Array (value, paramName) {
857
955
  if (isInt8Array(value)) {
858
- throw new Error(`${paramName ? '"' + paramName + '" ' : ' '}Not Int8Array`)
956
+ throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not Int8Array`)
859
957
  }
860
958
  }
861
959
  /**
@@ -865,7 +963,7 @@ function assertInt8Array (value, paramName) {
865
963
  */
866
964
  function assertUint8Array (value, paramName) {
867
965
  if (isUint8Array(value)) {
868
- throw new Error(`${paramName ? '"' + paramName + '" ' : ' '}Not Uint8Array`)
966
+ throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not Uint8Array`)
869
967
  }
870
968
  }
871
969
  /**
@@ -875,7 +973,7 @@ function assertUint8Array (value, paramName) {
875
973
  */
876
974
  function assertUint8ClampedArray (value, paramName) {
877
975
  if (isUint8ClampedArray(value)) {
878
- throw new Error(`${paramName ? '"' + paramName + '" ' : ' '}Not Uint8ClampedArray`)
976
+ throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not Uint8ClampedArray`)
879
977
  }
880
978
  }
881
979
  /**
@@ -885,7 +983,7 @@ function assertUint8ClampedArray (value, paramName) {
885
983
  */
886
984
  function assertInt16Array (value, paramName) {
887
985
  if (isInt16Array(value)) {
888
- throw new Error(`${paramName ? '"' + paramName + '" ' : ' '}Not Int16Array`)
986
+ throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not Int16Array`)
889
987
  }
890
988
  }
891
989
  /**
@@ -895,7 +993,7 @@ function assertInt16Array (value, paramName) {
895
993
  */
896
994
  function assertUint16Array (value, paramName) {
897
995
  if (isUint16Array(value)) {
898
- throw new Error(`${paramName ? '"' + paramName + '" ' : ' '}Not Uint16Array`)
996
+ throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not Uint16Array`)
899
997
  }
900
998
  }
901
999
  /**
@@ -905,7 +1003,7 @@ function assertUint16Array (value, paramName) {
905
1003
  */
906
1004
  function assertInt32Array (value, paramName) {
907
1005
  if (isInt32Array(value)) {
908
- throw new Error(`${paramName ? '"' + paramName + '" ' : ' '}Not Int32Array`)
1006
+ throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not Int32Array`)
909
1007
  }
910
1008
  }
911
1009
  /**
@@ -915,7 +1013,7 @@ function assertInt32Array (value, paramName) {
915
1013
  */
916
1014
  function assertUint32Array (value, paramName) {
917
1015
  if (isUint32Array(value)) {
918
- throw new Error(`${paramName ? '"' + paramName + '" ' : ' '}Not Uint32Array`)
1016
+ throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not Uint32Array`)
919
1017
  }
920
1018
  }
921
1019
  /**
@@ -925,7 +1023,7 @@ function assertUint32Array (value, paramName) {
925
1023
  */
926
1024
  function assertFloat32Array (value, paramName) {
927
1025
  if (isFloat32Array(value)) {
928
- throw new Error(`${paramName ? '"' + paramName + '" ' : ' '}Not Float32Array`)
1026
+ throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not Float32Array`)
929
1027
  }
930
1028
  }
931
1029
  /**
@@ -935,7 +1033,7 @@ function assertFloat32Array (value, paramName) {
935
1033
  */
936
1034
  function assertFloat64Array (value, paramName) {
937
1035
  if (isFloat64Array(value)) {
938
- throw new Error(`${paramName ? '"' + paramName + '" ' : ' '}Not Float64Array`)
1036
+ throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not Float64Array`)
939
1037
  }
940
1038
  }
941
1039
  /**
@@ -945,7 +1043,7 @@ function assertFloat64Array (value, paramName) {
945
1043
  */
946
1044
  function assertBigInt64Array (value, paramName) {
947
1045
  if (isBigInt64Array(value)) {
948
- throw new Error(`${paramName ? '"' + paramName + '" ' : ' '}Not BigInt64Array`)
1046
+ throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not BigInt64Array`)
949
1047
  }
950
1048
  }
951
1049
  /**
@@ -955,7 +1053,7 @@ function assertBigInt64Array (value, paramName) {
955
1053
  */
956
1054
  function assertBigUint64Array (value, paramName) {
957
1055
  if (isBigUint64Array(value)) {
958
- throw new Error(`${paramName ? '"' + paramName + '" ' : ' '}Not BigUint64Array`)
1056
+ throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not BigUint64Array`)
959
1057
  }
960
1058
  }
961
1059
 
@@ -967,7 +1065,7 @@ function assertBigUint64Array (value, paramName) {
967
1065
  */
968
1066
  function assertArrayBuffer (value, paramName) {
969
1067
  if (!isArrayBuffer(value)) {
970
- throw new Error(`${paramName ? '"' + paramName + '" ' : ' '}Not ArrayBuffer`)
1068
+ throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Not ArrayBuffer`)
971
1069
  }
972
1070
  }
973
1071
 
@@ -996,7 +1094,8 @@ var StringUtils = {
996
1094
  substringAfterLast,
997
1095
  substringBetween,
998
1096
  substringBetweenGreedy,
999
- substringsBetween
1097
+ substringsBetween,
1098
+ safeToString
1000
1099
  };
1001
1100
 
1002
1101
  /**
@@ -1393,6 +1492,22 @@ function substringsBetween (str, startMarker, endMarker) {
1393
1492
  return substrings
1394
1493
  }
1395
1494
 
1495
+ /**
1496
+ * Safely converts a value to its string representation.
1497
+ * Attempts to use JSON.stringify first, falls back to toString() if stringify fails.
1498
+ * @param {*} value - The value to convert to string
1499
+ * @returns {string} The string representation of the value
1500
+ */
1501
+ function safeToString (value) {
1502
+ let valueStr;
1503
+ try {
1504
+ valueStr = JSON.stringify(value);
1505
+ } catch (e) {
1506
+ valueStr = value.toString();
1507
+ }
1508
+ return valueStr
1509
+ }
1510
+
1396
1511
  /**
1397
1512
  * @module ExecUtils
1398
1513
  * @description Utils about how to execute task functions.
@@ -1470,6 +1585,7 @@ var ExecUtils = {
1470
1585
  * promise: Promise<*>,
1471
1586
  * timerHandler: NodeJS.Timeout,
1472
1587
  * timerCleared: boolean,
1588
+ * pending: boolean,
1473
1589
  * resolved: boolean,
1474
1590
  * rejected: boolean,
1475
1591
  * canceled: boolean,
@@ -1482,7 +1598,8 @@ var ExecUtils = {
1482
1598
  * @typedef {{
1483
1599
  * promise: Promise<*>,
1484
1600
  * timerHandler: NodeJS.Timeout,
1485
- * resolve: (...args:any[])=> void
1601
+ * _resolve: (...args:any[])=> void,
1602
+ * wakeup: ()=> void
1486
1603
  * }} Waiter
1487
1604
  */
1488
1605
 
@@ -1491,6 +1608,7 @@ var ExecUtils = {
1491
1608
  * @description Promise utility functions for enhanced promise handling, including timeout, delay, parallel execution, and series execution.
1492
1609
  */
1493
1610
  var PromiseUtils = {
1611
+ any,
1494
1612
  defer,
1495
1613
  delay,
1496
1614
  timeout,
@@ -1499,6 +1617,7 @@ var PromiseUtils = {
1499
1617
  series,
1500
1618
  seriesAllSettled,
1501
1619
  parallel,
1620
+ parallelAny,
1502
1621
  parallelAllSettled,
1503
1622
  wait
1504
1623
  };
@@ -1514,48 +1633,66 @@ function defer (timeout = -1, timeoutMessage) {
1514
1633
  assertNumber(timeout);
1515
1634
  /** @type {Deferred} */
1516
1635
  const rtnVal = {};
1517
-
1636
+ rtnVal.pending = true;
1637
+ rtnVal.canceled = false;
1638
+ rtnVal.rejected = false;
1639
+ rtnVal.resolved = false;
1518
1640
  /**
1519
1641
  * @type {NodeJS.Timeout}
1520
1642
  */
1521
1643
  let timerHandler;
1522
1644
  if (timeout >= 0) {
1645
+ rtnVal.timerCleared = false;
1523
1646
  rtnVal.timerHandler = timerHandler = setTimeout(() => {
1524
1647
  clearTimeout(timerHandler); // must clear it
1525
- rtnVal.timerCleared = true; // easy to check in test case
1648
+ rtnVal.timerCleared = true;
1526
1649
  rtnVal.reject(new Error(timeoutMessage ?? `Promise Timeout: ${timeout}ms`));
1527
1650
  }, timeout);
1528
1651
  }
1529
1652
 
1530
1653
  rtnVal.promise = new Promise((resolve, reject) => {
1531
1654
  rtnVal.resolve = (arg) => {
1655
+ if (rtnVal.resolved || rtnVal.rejected || rtnVal.canceled) {
1656
+ return // already done, Can Not operate again
1657
+ }
1532
1658
  if (timerHandler != null) {
1533
1659
  clearTimeout(timerHandler); // must clear it
1534
- rtnVal.timerCleared = true; // easy to check in test case
1660
+ rtnVal.timerCleared = true;
1535
1661
  }
1662
+ rtnVal.pending = false;
1663
+ rtnVal.canceled = false;
1664
+ rtnVal.rejected = false;
1536
1665
  rtnVal.resolved = true;
1537
1666
  resolve(arg);
1538
1667
  };
1539
1668
 
1540
1669
  rtnVal.reject = (err) => {
1670
+ if (rtnVal.resolved || rtnVal.rejected || rtnVal.canceled) {
1671
+ return // already done, Can Not operate again
1672
+ }
1541
1673
  if (timerHandler != null) {
1542
1674
  clearTimeout(timerHandler); // must clear it
1543
- rtnVal.timerCleared = true; // easy to check in test case
1675
+ rtnVal.timerCleared = true;
1544
1676
  }
1677
+ rtnVal.pending = false;
1678
+ rtnVal.canceled = false;
1679
+ rtnVal.resolved = false;
1545
1680
  rtnVal.rejected = true;
1546
1681
  reject(err);
1547
1682
  };
1548
1683
  });
1549
1684
  // @ts-ignore
1550
- rtnVal.promise.cancel = () => {
1685
+ rtnVal.cancel = rtnVal.promise.cancel = (reason) => {
1686
+ if (rtnVal.resolved || rtnVal.rejected || rtnVal.canceled) {
1687
+ return // already done, Can Not operate again
1688
+ }
1551
1689
  if (timerHandler != null) {
1552
1690
  clearTimeout(timerHandler); // must clear it
1553
- rtnVal.timerCleared = true; // easy to check in test case
1691
+ rtnVal.timerCleared = true;
1554
1692
  }
1555
- rtnVal.rejected = true; // easy to check in test case
1693
+ rtnVal.reject(reason ?? new Error('Cancelled'));
1556
1694
  // @ts-ignore
1557
- rtnVal.canceled = rtnVal.promise.canceled = true; // easy to check in test case
1558
- rtnVal.reject(new Error('Cancelled'));
1695
+ rtnVal.canceled = rtnVal.promise.canceled = true;
1559
1696
  };
1560
1697
  return rtnVal
1561
1698
  }
@@ -1626,7 +1763,7 @@ async function allSettled (promises) {
1626
1763
  function returnValuePromised (task) {
1627
1764
  try {
1628
1765
  const taskRtnVal = task();
1629
- if (isPromise(taskRtnVal)) {
1766
+ if (TypeUtils.isPromise(taskRtnVal)) {
1630
1767
  return taskRtnVal
1631
1768
  }
1632
1769
  return Promise.resolve(taskRtnVal)
@@ -1647,7 +1784,7 @@ function returnValuePromised (task) {
1647
1784
  * @returns {Promise<*>} A new promise that settles after the delay period
1648
1785
  */
1649
1786
  function delay (promise, ms) {
1650
- if (isNumber(promise)) { // defer(ms)
1787
+ if (TypeUtils.isNumber(promise)) { // defer(ms)
1651
1788
  // @ts-ignore
1652
1789
  ms = promise;
1653
1790
  promise = Promise.resolve();
@@ -1679,21 +1816,78 @@ function delay (promise, ms) {
1679
1816
  });
1680
1817
  return deferred.promise
1681
1818
  }
1819
+ /**
1820
+ * 1. run all tasks
1821
+ * 2. any Task succeed, return its result
1822
+ * * resolve with the result.
1823
+ * * the others tasks will run to its end, and results will be dropped.
1824
+ * 3. If all tasks fail, rejects with an array of errors. the array length is same as the input tasks
1825
+ * @param {Array<Promise<any>|Function>} tasks - Array of promises or async functions to execute
1826
+ * @returns {Promise<any>} A promise that resolves with the result of the first successful task
1827
+ */
1828
+ function any (tasks) {
1829
+ assertArray(tasks);
1830
+ if (tasks.length === 0) {
1831
+ throw new Error('Empty Tasks')
1832
+ }
1833
+ const deferred = defer();
1834
+ /** @type {any[]} */
1835
+ const errors = [];
1836
+ for (let i = 0; i < tasks.length; i++) {
1837
+ const task = tasks[i];
1838
+ /** @type {Promise<any>} */
1839
+ let taskPromise;
1840
+ if (TypeUtils.isPromise(task)) {
1841
+ // @ts-ignore
1842
+ taskPromise = task;
1843
+ } else if (TypeUtils.isFunction(task)) {
1844
+ // @ts-ignore
1845
+ taskPromise = returnValuePromised(task);
1846
+ } else {
1847
+ errors.push(new Error(`Invalid Task at index ${i}/${tasks.length - 1}: ${task}`));
1848
+ continue
1849
+ }
1850
+ taskPromise.then(/** @type {any} */ rtnVal => {
1851
+ deferred.resolve(rtnVal);
1852
+ }).catch(e => {
1853
+ errors.push(e);
1854
+ // all tasks failed
1855
+ if (errors.length >= tasks.length) {
1856
+ deferred.reject(errors);
1857
+ }
1858
+ });
1859
+ }
1860
+ if (errors.length === tasks.length) {
1861
+ deferred.reject(errors);
1862
+ }
1863
+ return deferred.promise
1864
+ }
1682
1865
 
1683
1866
  /**
1684
- * Fast-Fail mode to execute Tasks(functions) in series (one after another) and returns their results in order.
1685
- * 1. export function are executed one by one
1686
- * 2. Fast Fail: if any tasks fail, the whole chain is rejected with the first error
1687
- * 3. if an element is not function, rejects the whole chain with Error(Not Function)
1688
- * @param {Function[]} tasks
1689
- * @returns {Promise<any[]>} Promise that resolves with an array of results in the same order as input tasks
1690
- */
1867
+ * Execute Tasks(functions) in series (one after another) and returns their results in order.
1868
+ * 1. Tasks are executed one by one
1869
+ * * if task is a function, execute it.
1870
+ * * if task is a promise, wait for it to settle.
1871
+ * 2. Fast Fail: if any tasks fail, the whole chain is rejected with the first error
1872
+ * 3. if an element is not function, rejects the whole chain with Error(Not Function)
1873
+ * 4. All Tasks run successfully, Return Results Array, it's length is same as the input tasks
1874
+ * @param {Array<Promise<any>|Function>} tasks
1875
+ * @returns {Promise<any[]>} Promise that resolves with an array of results in the same order as input tasks
1876
+ */
1691
1877
  async function series (tasks) {
1692
1878
  assertArray(tasks);
1693
1879
  const results = [];
1694
1880
  for (const task of tasks) {
1695
1881
  assertFunction(task);
1696
- results.push(await task());
1882
+ if (TypeUtils.isFunction(task)) {
1883
+ // @ts-ignore
1884
+ results.push(await returnValuePromised(task));
1885
+ } else if (TypeUtils.isPromise(task)) {
1886
+ // @ts-ignore
1887
+ results.push(await task);
1888
+ } else {
1889
+ throw new Error(`Invalid Task: ${task}`)
1890
+ }
1697
1891
  }
1698
1892
  return results
1699
1893
  }
@@ -1768,7 +1962,7 @@ async function parallel (tasks, maxParallel = 5) {
1768
1962
  * 2. all tasks will be executed, even some of them failed.
1769
1963
  * @param {Function[]} tasks
1770
1964
  * @param {number} [maxParallel=5] - Maximum number of tasks to run in parallel
1771
- * @returns {Promise<any[]>} Array of resolved values from all promises
1965
+ * @returns {Promise<{ok: boolean, result: any}[]>}
1772
1966
  * @throws {TypeError} If input is not an array of export function or maxParallel is not a number
1773
1967
  */
1774
1968
  async function parallelAllSettled (tasks, maxParallel = 5) {
@@ -1788,7 +1982,6 @@ async function parallelAllSettled (tasks, maxParallel = 5) {
1788
1982
  // run group by MaxParallel
1789
1983
  const tasksToRun = [];
1790
1984
  for (const task of tasks) {
1791
- assertFunction(task);
1792
1985
  tasksToRun.push(task);
1793
1986
  if (tasksToRun.length >= maxParallel) {
1794
1987
  const resultsForBatch = await allSettled(tasksToRun.map(task => returnValuePromised(task)));
@@ -1804,6 +1997,76 @@ async function parallelAllSettled (tasks, maxParallel = 5) {
1804
1997
  return rtnVal
1805
1998
  }
1806
1999
 
2000
+ /**
2001
+ * Executes multiple async tasks in parallel with limited concurrency,
2002
+ * 1. resolving when any task completes successfully.
2003
+ * 2. Maybe multiple tasks are executed as a bulk block, and all of them resolved.
2004
+ * * only the first fulfilled value is returned
2005
+ * * other results are dropped
2006
+ * @param {Array<Function|Promise<any>>} tasks - Array of async functions to execute
2007
+ * @param {number} [maxParallel=5] - Maximum number of tasks to run in parallel
2008
+ * @returns {Promise<any>} Resolves with the result of the first successfully completed task
2009
+ */
2010
+ async function parallelAny (tasks, maxParallel = 5) {
2011
+ assertArray(tasks, 'tasks');
2012
+ assertNumber(maxParallel);
2013
+ if (tasks.length === 0) {
2014
+ throw new Error('Empty Tasks')
2015
+ }
2016
+ if (maxParallel <= 0) {
2017
+ throw new Error(`Invalid maxParallel: ${maxParallel}, should > 0`)
2018
+ }
2019
+ /** @type {any[]} */
2020
+ const errors = [];
2021
+ let taskIndex = 0;
2022
+ let runningTasksCount = 0;
2023
+ const deferred = defer();
2024
+ function takeTaskAndRun () {
2025
+ if (taskIndex >= tasks.length) {
2026
+ return // no more task
2027
+ }
2028
+ // reach max parallel, wait for one task to finish
2029
+ if (runningTasksCount > maxParallel) {
2030
+ return
2031
+ }
2032
+ const task = tasks[taskIndex++];
2033
+ runningTasksCount++;
2034
+ /** @type {Promise<any>} */
2035
+ let taskPromise;
2036
+ if (TypeUtils.isPromise(task)) {
2037
+ // @ts-ignore
2038
+ taskPromise = task;
2039
+ } else if (TypeUtils.isFunction(task)) {
2040
+ // @ts-ignore
2041
+ taskPromise = returnValuePromised(task);
2042
+ } else {
2043
+ errors.push(new TypeError(`Invalid task: ${task}`));
2044
+ takeTaskAndRun();
2045
+ return
2046
+ }
2047
+ taskPromise.then(/** @type {any} */ rtnVal => {
2048
+ deferred.resolve(rtnVal);
2049
+ }).catch(e => {
2050
+ errors.push(e);
2051
+ // No task left, and No successful execution, reject with errors
2052
+ if (errors.length >= tasks.length) {
2053
+ if (deferred.pending) {
2054
+ deferred.reject(errors);
2055
+ return
2056
+ }
2057
+ }
2058
+ takeTaskAndRun();
2059
+ }).finally(() => {
2060
+ runningTasksCount--;
2061
+ });
2062
+ }
2063
+ // start tasks until maxParallel
2064
+ while (runningTasksCount < maxParallel) {
2065
+ takeTaskAndRun();
2066
+ }
2067
+ return deferred.promise
2068
+ }
2069
+
1807
2070
  /**
1808
2071
  * Creates a "Waiter" Object
1809
2072
  * 1. wait the specified time
@@ -1822,17 +2085,20 @@ function wait (waitTime) {
1822
2085
  let timerHandler;
1823
2086
  rtnVal.timerHandler = timerHandler = setTimeout(() => {
1824
2087
  clearTimeout(timerHandler); // must clear it
1825
- rtnVal.resolve();
2088
+ rtnVal._resolve();
1826
2089
  }, waitTime);
1827
2090
 
1828
2091
  rtnVal.promise = new Promise((resolve, reject) => {
1829
- rtnVal.resolve = (arg) => {
2092
+ rtnVal._resolve = (arg) => {
1830
2093
  if (timerHandler != null) {
1831
2094
  clearTimeout(timerHandler); // must clear it
1832
2095
  }
1833
2096
  resolve(arg);
1834
2097
  };
1835
2098
  });
2099
+ rtnVal.wakeup = () => {
2100
+ rtnVal._resolve();
2101
+ };
1836
2102
  return rtnVal
1837
2103
  }
1838
2104
 
@@ -2293,6 +2559,7 @@ function timeoutMillis (nanoTimestamp64, millisTimeout) {
2293
2559
 
2294
2560
  var ArrayUtils = {
2295
2561
  first,
2562
+ chunk,
2296
2563
  last,
2297
2564
  equals,
2298
2565
  equalsIgnoreOrder
@@ -2376,13 +2643,35 @@ function equals (arr1, arr2, compareFn) {
2376
2643
  return true
2377
2644
  }
2378
2645
 
2646
+ /**
2647
+ * Splits an array into chunks of the specified size.
2648
+ * @param {any[]} array - The array to be chunked.
2649
+ * @param {number} size - The size of each chunk.
2650
+ * @returns {any[]} An array of arrays containing the chunks.
2651
+ */
2652
+ function chunk (array, size) {
2653
+ assertArray(array, 'array');
2654
+ assertPositive(size, 'size');
2655
+ if (array.length <= size) {
2656
+ return array
2657
+ }
2658
+ const chunked = [];
2659
+ let index = 0;
2660
+ while (index < array.length) {
2661
+ chunked.push(array.slice(index, size + index));
2662
+ index += size;
2663
+ }
2664
+ return chunked
2665
+ }
2666
+
2379
2667
  /**
2380
2668
  * @module Lang
2381
2669
  * @description Core language utilities for type checking, string manipulation, and common operations.
2382
2670
  */
2383
2671
 
2384
-
2385
2672
  var index = {
2673
+ _Error,
2674
+ AggregatedError,
2386
2675
  LangUtils,
2387
2676
  StringUtils,
2388
2677
  TypeUtils,
@@ -2401,6 +2690,7 @@ var index = {
2401
2690
  ArrayUtils
2402
2691
  };
2403
2692
 
2693
+ exports.AggregatedError = AggregatedError;
2404
2694
  exports.ArrayBufferUtils = ArrayBufferUtils;
2405
2695
  exports.ArrayUtils = ArrayUtils;
2406
2696
  exports.ClassProxyUtils = ClassProxyUtils;
@@ -2417,5 +2707,6 @@ exports.Type = TypeUtils;
2417
2707
  exports.TypeAssert = TypeAssert;
2418
2708
  exports.TypeUtils = TypeUtils;
2419
2709
  exports.TypedArrayUtils = TypedArrayUtils;
2710
+ exports._Error = _Error;
2420
2711
  exports.default = index;
2421
2712
  //# sourceMappingURL=index-dev.cjs.map