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