@creejs/commons-lang 2.1.24 → 2.1.26

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.
@@ -158,14 +158,14 @@ function constructorName (value) {
158
158
 
159
159
  /**
160
160
  * Assigns default values from source objects to target object for undefined properties.
161
- * @param {Object<string, any>} target - The target object to assign defaults to
162
- * @param {...Object<string, any>} sources - Source objects containing default values
163
- * @returns {Object<string, any>} The modified target object with defaults applied
164
- * @throws {TypeError} If target is null or undefined
161
+ * 1. No Deep-Copy, only first level properties are assigned.
162
+ * @param {{[key:string]:any}} target - The target object to assign defaults to
163
+ * @param {...{[key:string]:any}|undefined} sources - Source objects containing default values
164
+ * @returns {{[key:string]:any}} The modified target object with defaults applied
165
165
  */
166
166
  function defaults (target, ...sources) {
167
167
  if (target == null) {
168
- throw new TypeError('"target" must not be null or undefined')
168
+ throw new TypeError('"target" Should Not Nil')
169
169
  }
170
170
  for (const source of sources) {
171
171
  if (source == null) {
@@ -1145,11 +1145,13 @@ function isEmpty (str) {
1145
1145
  /**
1146
1146
  * Asserts that the given string is not empty.
1147
1147
  * @param {string} str - The string to check.
1148
+ * @param {string} [paramName]
1149
+ *
1148
1150
  * @throws {Error} Throws an error if the string is empty.
1149
1151
  */
1150
- function assertNotEmpty (str) {
1152
+ function assertNotEmpty (str, paramName) {
1151
1153
  if (isEmpty(str)) {
1152
- throw new Error(`Empty String: ${str}`)
1154
+ throw new Error(`${paramName ? '"' + paramName + '" ' : ''}IsEmpty String: ${str}`)
1153
1155
  }
1154
1156
  }
1155
1157
 
@@ -1170,11 +1172,12 @@ function isBlank (str) {
1170
1172
  /**
1171
1173
  * Asserts that the given string is not blank.
1172
1174
  * @param {string} str - The string to check.
1175
+ * @param {string} [paramName]
1173
1176
  * @throws {Error} Throws an error if the string is blank.
1174
1177
  */
1175
- function assertNotBlank (str) {
1178
+ function assertNotBlank (str, paramName) {
1176
1179
  if (isBlank(str)) {
1177
- throw new Error(`Blank String: ${str}`)
1180
+ throw new Error(`${paramName ? '"' + paramName + '" ' : ''}Is Blank: ${str}`)
1178
1181
  }
1179
1182
  }
1180
1183
 
@@ -2038,6 +2041,9 @@ async function parallelAllSettled (tasks, maxParallel = 5) {
2038
2041
  * 2. Maybe multiple tasks are executed as a bulk block, and all of them resolved.
2039
2042
  * * only the first fulfilled value is returned
2040
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
2041
2047
  * @param {Array<Function|Promise<any>>} tasks - Array of async functions to execute
2042
2048
  * @param {number} [maxParallel=5] - Maximum number of tasks to run in parallel
2043
2049
  * @returns {Promise<any>} Resolves with the result of the first successfully completed task
@@ -2075,12 +2081,13 @@ async function parallelAny (tasks, maxParallel = 5) {
2075
2081
  // @ts-ignore
2076
2082
  taskPromise = returnValuePromised(task);
2077
2083
  } else {
2078
- errors.push(new TypeError(`Invalid task: ${task}`));
2079
- takeTaskAndRun();
2080
- return
2084
+ taskPromise = Promise.reject(new TypeError(`Invalid task: ${typeof task}, Only Promise or Function allowed`));
2081
2085
  }
2086
+
2082
2087
  taskPromise.then(/** @type {any} */ rtnVal => {
2083
- deferred.resolve(rtnVal);
2088
+ runningTasksCount--; // DO Not put in finally
2089
+ // any task resolved, whole parallelAny resolved
2090
+ deferred.resolve(rtnVal); // This may be called many times: In worst case, "maxParallel" times
2084
2091
  }).catch(e => {
2085
2092
  errors.push(e);
2086
2093
  // No task left, and No successful execution, reject with errors
@@ -2090,13 +2097,13 @@ async function parallelAny (tasks, maxParallel = 5) {
2090
2097
  return
2091
2098
  }
2092
2099
  }
2093
- takeTaskAndRun();
2094
- }).finally(() => {
2095
- runningTasksCount--;
2100
+ runningTasksCount--; // DO Not put in finally, must reduce before takeTaskAndRun()
2101
+ takeTaskAndRun(); // start next task
2096
2102
  });
2097
2103
  }
2098
- // start tasks until maxParallel
2099
- while (runningTasksCount < maxParallel) {
2104
+ // start tasks until maxParallel or no more task
2105
+ const parallelCount = Math.min(tasks.length, maxParallel);
2106
+ for (let i = 0; i < parallelCount; i++) {
2100
2107
  takeTaskAndRun();
2101
2108
  }
2102
2109
  return deferred.promise
@@ -2524,6 +2531,7 @@ const s2ns = 1_000_000_000;
2524
2531
  var TimeUtils = {
2525
2532
  s2ns,
2526
2533
  ms2ns,
2534
+ timestamp,
2527
2535
  timestamp64,
2528
2536
  lapseNano,
2529
2537
  lapseMillis,
@@ -2532,8 +2540,9 @@ var TimeUtils = {
2532
2540
  };
2533
2541
 
2534
2542
  /**
2535
- * Gets the current timestamp in nanoseconds (if running in Node.js) or milliseconds (in browser).
2536
- * Uses `process.hrtime.bigint()` for high-resolution timestamps in Node.js, falls back to `Date.now()` in browsers.
2543
+ * Gets the current timestamp in nanoseconds
2544
+ * * If "performance" API is available, uses performance timeOrigin + now()
2545
+ * * Else fall back to `Date.now()` to get milliseconds and convert to nanoseconds
2537
2546
  * @returns {bigint} Current timestamp as a BigInt
2538
2547
  */
2539
2548
  function timestamp64 () {
@@ -2548,6 +2557,24 @@ function timestamp64 () {
2548
2557
  return BigInt(Date.now() * ms2ns)
2549
2558
  }
2550
2559
 
2560
+ /**
2561
+ * Gets the current timestamp in milliseconds
2562
+ * * If "performance" API is available, uses performance timeOrigin + now(), then convert to milliseconds
2563
+ * * Else fall back to `Date.now()`
2564
+ * @returns {number} Current timestamp in milliseconds
2565
+ */
2566
+ function timestamp () {
2567
+ // sinon can not fake performance.timeOrigin, so we have to check it
2568
+ if (typeof performance !== 'undefined' && typeof performance.timeOrigin === 'number') {
2569
+ // timeOrigin specifies the high resolution millisecond timestamp, eg. 1756350801931.159
2570
+ const base = performance.timeOrigin;
2571
+ // the current high resolution millisecond timestamp, eg.31767926.416357
2572
+ const now = performance.now();
2573
+ return Math.ceil((base + now) / ms2ns)
2574
+ }
2575
+ return Date.now()
2576
+ }
2577
+
2551
2578
  /**
2552
2579
  * Calculates the time elapsed in nanoseconds between the given timestamp and now.
2553
2580
  * @param {bigint} start - start timestamp64, in nanoseconds.