@creejs/commons-lang 2.1.25 → 2.1.27

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.
@@ -2041,11 +2041,15 @@ async function parallelAllSettled (tasks, maxParallel = 5) {
2041
2041
  * 2. Maybe multiple tasks are executed as a bulk block, and all of them resolved.
2042
2042
  * * only the first fulfilled value is returned
2043
2043
  * * other results are dropped
2044
+ * 3. Notice:
2045
+ * * In Beginning, we start bulk(maxParallel) of tasks
2046
+ * * One task failed, it will start next task immediately, Not Wait for the bulk(maxParallel) to complete
2044
2047
  * @param {Array<Function|Promise<any>>} tasks - Array of async functions to execute
2045
2048
  * @param {number} [maxParallel=5] - Maximum number of tasks to run in parallel
2049
+ * @param {string} [failureMessage] - Error message when all tasks failed
2046
2050
  * @returns {Promise<any>} Resolves with the result of the first successfully completed task
2047
2051
  */
2048
- async function parallelAny (tasks, maxParallel = 5) {
2052
+ async function parallelAny (tasks, maxParallel = 5, failureMessage) {
2049
2053
  assertArray(tasks, 'tasks');
2050
2054
  assertNumber(maxParallel);
2051
2055
  if (tasks.length === 0) {
@@ -2078,28 +2082,29 @@ async function parallelAny (tasks, maxParallel = 5) {
2078
2082
  // @ts-ignore
2079
2083
  taskPromise = returnValuePromised(task);
2080
2084
  } else {
2081
- errors.push(new TypeError(`Invalid task: ${task}`));
2082
- takeTaskAndRun();
2083
- return
2085
+ taskPromise = Promise.reject(new TypeError(`Invalid task: ${typeof task}, Only Promise or Function allowed`));
2084
2086
  }
2087
+
2085
2088
  taskPromise.then(/** @type {any} */ rtnVal => {
2086
- deferred.resolve(rtnVal);
2089
+ runningTasksCount--; // DO Not put in finally
2090
+ // any task resolved, whole parallelAny resolved
2091
+ deferred.resolve(rtnVal); // This may be called many times: In worst case, "maxParallel" times
2087
2092
  }).catch(e => {
2088
2093
  errors.push(e);
2089
2094
  // No task left, and No successful execution, reject with errors
2090
2095
  if (errors.length >= tasks.length) {
2091
2096
  if (deferred.pending) {
2092
- deferred.reject(new AggregatedError('All Tasks Failed', errors));
2097
+ deferred.reject(new AggregatedError(failureMessage ?? 'All Tasks Failed', errors));
2093
2098
  return
2094
2099
  }
2095
2100
  }
2096
- takeTaskAndRun();
2097
- }).finally(() => {
2098
- runningTasksCount--;
2101
+ runningTasksCount--; // DO Not put in finally, must reduce before takeTaskAndRun()
2102
+ takeTaskAndRun(); // start next task
2099
2103
  });
2100
2104
  }
2101
- // start tasks until maxParallel
2102
- while (runningTasksCount < maxParallel) {
2105
+ // start tasks until maxParallel or no more task
2106
+ const parallelCount = Math.min(tasks.length, maxParallel);
2107
+ for (let i = 0; i < parallelCount; i++) {
2103
2108
  takeTaskAndRun();
2104
2109
  }
2105
2110
  return deferred.promise
@@ -2527,6 +2532,7 @@ const s2ns = 1_000_000_000;
2527
2532
  var TimeUtils = {
2528
2533
  s2ns,
2529
2534
  ms2ns,
2535
+ timestamp,
2530
2536
  timestamp64,
2531
2537
  lapseNano,
2532
2538
  lapseMillis,
@@ -2535,8 +2541,9 @@ var TimeUtils = {
2535
2541
  };
2536
2542
 
2537
2543
  /**
2538
- * Gets the current timestamp in nanoseconds (if running in Node.js) or milliseconds (in browser).
2539
- * Uses `process.hrtime.bigint()` for high-resolution timestamps in Node.js, falls back to `Date.now()` in browsers.
2544
+ * Gets the current timestamp in nanoseconds
2545
+ * * If "performance" API is available, uses performance timeOrigin + now()
2546
+ * * Else fall back to `Date.now()` to get milliseconds and convert to nanoseconds
2540
2547
  * @returns {bigint} Current timestamp as a BigInt
2541
2548
  */
2542
2549
  function timestamp64 () {
@@ -2551,6 +2558,24 @@ function timestamp64 () {
2551
2558
  return BigInt(Date.now() * ms2ns)
2552
2559
  }
2553
2560
 
2561
+ /**
2562
+ * Gets the current timestamp in milliseconds
2563
+ * * If "performance" API is available, uses performance timeOrigin + now(), then convert to milliseconds
2564
+ * * Else fall back to `Date.now()`
2565
+ * @returns {number} Current timestamp in milliseconds
2566
+ */
2567
+ function timestamp () {
2568
+ // sinon can not fake performance.timeOrigin, so we have to check it
2569
+ if (typeof performance !== 'undefined' && typeof performance.timeOrigin === 'number') {
2570
+ // timeOrigin specifies the high resolution millisecond timestamp, eg. 1756350801931.159
2571
+ const base = performance.timeOrigin;
2572
+ // the current high resolution millisecond timestamp, eg.31767926.416357
2573
+ const now = performance.now();
2574
+ return Math.ceil((base + now) / ms2ns)
2575
+ }
2576
+ return Date.now()
2577
+ }
2578
+
2554
2579
  /**
2555
2580
  * Calculates the time elapsed in nanoseconds between the given timestamp and now.
2556
2581
  * @param {bigint} start - start timestamp64, in nanoseconds.