@creejs/commons-lang 2.1.11 → 2.1.13

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.
@@ -12,7 +12,7 @@ var LangUtils = {
12
12
  defaults,
13
13
  extend,
14
14
  extends: extend,
15
- equals: equals$1,
15
+ equals: equals$2,
16
16
  isBrowser,
17
17
  isNode
18
18
  };
@@ -80,7 +80,7 @@ function extend (target, ...sources) {
80
80
  * @param {*} value2 - Second value to compare
81
81
  * @returns {boolean} True if values are equal, false otherwise
82
82
  */
83
- function equals$1 (value1, value2) {
83
+ function equals$2 (value1, value2) {
84
84
  if (value1 === value2) {
85
85
  return true
86
86
  }
@@ -579,7 +579,7 @@ var TypeAssert = {
579
579
  */
580
580
  function assertArray (value, paramName) {
581
581
  if (!Array.isArray(value)) {
582
- throw new Error(`${paramName ? paramName + '' : ' '}Not Array: type=${typeof value} value=${JSON.stringify(value)}`)
582
+ throw new Error(`${paramName ? '"' + paramName + '" ' : ' '}Not Array: type=${typeof value} value=${JSON.stringify(value)}`)
583
583
  }
584
584
  }
585
585
  /**
@@ -1403,7 +1403,20 @@ var ExecUtils = {
1403
1403
  quietKeepError
1404
1404
  };
1405
1405
 
1406
- // @ts-nocheck
1406
+ // owned
1407
+
1408
+ /**
1409
+ * @typedef {{
1410
+ * promise: Promise<*>,
1411
+ * timerHandler: NodeJS.Timeout,
1412
+ * timerCleared: boolean,
1413
+ * resolved: boolean,
1414
+ * rejected: boolean,
1415
+ * canceled: boolean,
1416
+ * reject: (reason: Error)=> void,
1417
+ * resolve: (...args:any[])=> void
1418
+ * }} Deferred
1419
+ */
1407
1420
 
1408
1421
  /**
1409
1422
  * @module PromiseUtils
@@ -1426,12 +1439,16 @@ var PromiseUtils = {
1426
1439
  * 1. timeout=-1, it means no timeout check
1427
1440
  * @param {number} [timeout=-1] - Timeout duration in milliseconds
1428
1441
  * @param {string} [timeoutMessage]
1429
- * @returns {{promise: Promise<*>, reject: function, resolve: function}}
1442
+ * @returns {Deferred}
1430
1443
  */
1431
1444
  function defer (timeout = -1, timeoutMessage) {
1432
1445
  assertNumber(timeout);
1446
+ /** @type {Deferred} */
1433
1447
  const rtnVal = {};
1434
1448
 
1449
+ /**
1450
+ * @type {NodeJS.Timeout}
1451
+ */
1435
1452
  let timerHandler;
1436
1453
  if (timeout >= 0) {
1437
1454
  rtnVal.timerHandler = timerHandler = setTimeout(() => {
@@ -1439,17 +1456,16 @@ function defer (timeout = -1, timeoutMessage) {
1439
1456
  rtnVal.timerCleared = true; // easy to check in test case
1440
1457
  rtnVal.reject(new Error(timeoutMessage ?? `Promise Timeout: ${timeout}ms`));
1441
1458
  }, timeout);
1442
- rtnVal.timerHandler = timerHandler;
1443
1459
  }
1444
1460
 
1445
1461
  rtnVal.promise = new Promise((resolve, reject) => {
1446
- rtnVal.resolve = (...args) => {
1462
+ rtnVal.resolve = (arg) => {
1447
1463
  if (timerHandler != null) {
1448
1464
  clearTimeout(timerHandler); // must clear it
1449
1465
  rtnVal.timerCleared = true; // easy to check in test case
1450
1466
  }
1451
1467
  rtnVal.resolved = true;
1452
- resolve(...args);
1468
+ resolve(arg);
1453
1469
  };
1454
1470
 
1455
1471
  rtnVal.reject = (err) => {
@@ -1461,12 +1477,14 @@ function defer (timeout = -1, timeoutMessage) {
1461
1477
  reject(err);
1462
1478
  };
1463
1479
  });
1480
+ // @ts-ignore
1464
1481
  rtnVal.promise.cancel = () => {
1465
1482
  if (timerHandler != null) {
1466
1483
  clearTimeout(timerHandler); // must clear it
1467
1484
  rtnVal.timerCleared = true; // easy to check in test case
1468
1485
  }
1469
1486
  rtnVal.rejected = true; // easy to check in test case
1487
+ // @ts-ignore
1470
1488
  rtnVal.canceled = rtnVal.promise.canceled = true; // easy to check in test case
1471
1489
  rtnVal.reject(new Error('Cancelled'));
1472
1490
  };
@@ -1513,8 +1531,8 @@ function timeout (promise, time, message) {
1513
1531
  * 2. It's NOT convenient to use Promise.allSettled() to get the results of all promises.
1514
1532
  * * the data structure is not consistent when fullfilled or rejected
1515
1533
  * * have to check "string" type of status to know sucess or failure
1516
- * @param {Promise} promises
1517
- * @returns {Array<{ok: boolean, result: any}>}
1534
+ * @param {Promise<*>[]} promises
1535
+ * @returns {Promise<{ok: boolean, result: any}[]>}
1518
1536
  */
1519
1537
  async function allSettled (promises) {
1520
1538
  assertArray(promises);
@@ -1557,13 +1575,14 @@ function returnValuePromised (task) {
1557
1575
  *
1558
1576
  * @param {Promise<*>|number|undefined} [promise] - The input promise to delay
1559
1577
  * @param {number|undefined} [ms] - Minimum delay in milliseconds (default: 1)
1560
- * @returns {Promise} A new promise that settles after the delay period
1578
+ * @returns {Promise<*>} A new promise that settles after the delay period
1561
1579
  */
1562
1580
  function delay (promise, ms) {
1563
- if (isNumber(promise)) {
1581
+ if (isNumber(promise)) { // defer(ms)
1582
+ // @ts-ignore
1564
1583
  ms = promise;
1565
1584
  promise = Promise.resolve();
1566
- } else if (promise == null && ms == null) {
1585
+ } else if (promise == null && ms == null) { // defer(promise, ms)
1567
1586
  ms = 1;
1568
1587
  promise = Promise.resolve();
1569
1588
  }
@@ -1572,16 +1591,16 @@ function delay (promise, ms) {
1572
1591
  assertNumber(ms);
1573
1592
  const deferred = defer();
1574
1593
  const startTs = Date.now();
1575
- promise
1576
- .then((...args) => {
1577
- const escaped = Date.now() - startTs;
1578
- if (escaped < ms) {
1579
- setTimeout(() => deferred.resolve(...args), ms - escaped);
1580
- } else {
1581
- deferred.resolve(...args);
1582
- }
1583
- })
1584
- .catch((err) => {
1594
+ // @ts-ignore
1595
+ promise.then((...args) => {
1596
+ const escaped = Date.now() - startTs;
1597
+ if (escaped < ms) {
1598
+ setTimeout(() => deferred.resolve(...args), ms - escaped);
1599
+ } else {
1600
+ deferred.resolve(...args);
1601
+ }
1602
+ })
1603
+ .catch((/** @type {Error} */ err) => {
1585
1604
  const escaped = Date.now() - startTs;
1586
1605
  if (escaped < ms) {
1587
1606
  setTimeout(() => deferred.reject(err), ms - escaped);
@@ -1597,8 +1616,8 @@ function delay (promise, ms) {
1597
1616
  * 1. export function are executed one by one
1598
1617
  * 2. Fast Fail: if any tasks fail, the whole chain is rejected with the first error
1599
1618
  * 3. if an element is not function, rejects the whole chain with Error(Not Function)
1600
- * @param {Function[]} promises
1601
- * @returns {Promise<Array>} Promise that resolves with an array of results in the same order as input tasks
1619
+ * @param {Function[]} tasks
1620
+ * @returns {Promise<any[]>} Promise that resolves with an array of results in the same order as input tasks
1602
1621
  */
1603
1622
  async function series (tasks) {
1604
1623
  assertArray(tasks);
@@ -1638,7 +1657,7 @@ async function seriesAllSettled (tasks) {
1638
1657
  * 2. rejects whole chain with the first error, when first task fails
1639
1658
  * @param {Function[]} tasks
1640
1659
  * @param {number} [maxParallel=5]
1641
- * @returns {Promise<Array>} Array of resolved values from all promises
1660
+ * @returns {Promise<any[]>} Array of resolved values from all promises
1642
1661
  * @throws {TypeError} If input is not an array of export function or maxParallel is not a number
1643
1662
  */
1644
1663
  async function parallel (tasks, maxParallel = 5) {
@@ -1680,7 +1699,7 @@ async function parallel (tasks, maxParallel = 5) {
1680
1699
  * 2. all tasks will be executed, even some of them failed.
1681
1700
  * @param {Function[]} tasks
1682
1701
  * @param {number} [maxParallel=5] - Maximum number of tasks to run in parallel
1683
- * @returns {Promise<Array>} Array of resolved values from all promises
1702
+ * @returns {Promise<any[]>} Array of resolved values from all promises
1684
1703
  * @throws {TypeError} If input is not an array of export function or maxParallel is not a number
1685
1704
  */
1686
1705
  async function parallelAllSettled (tasks, maxParallel = 5) {
@@ -1908,7 +1927,7 @@ var ReflectUtils = {
1908
1927
  var TypedArrayUtils = {
1909
1928
  startsWith,
1910
1929
  isSameType,
1911
- equals
1930
+ equals: equals$1
1912
1931
  };
1913
1932
 
1914
1933
  /**
@@ -1923,7 +1942,7 @@ function startsWith (src, searching) {
1923
1942
  assertNotNil(searching, 'searching');
1924
1943
 
1925
1944
  const header = src.subarray(0, searching.length);
1926
- return equals(header, searching)
1945
+ return equals$1(header, searching)
1927
1946
  }
1928
1947
 
1929
1948
  /**
@@ -1949,7 +1968,7 @@ function isSameType (src, target) {
1949
1968
  * @returns {boolean} True if the typed arrays are equal, false otherwise.
1950
1969
  * @throws {Error} If either `src` or `target` is null or undefined.
1951
1970
  */
1952
- function equals (src, target) {
1971
+ function equals$1 (src, target) {
1953
1972
  assertNotNil(src, 'src');
1954
1973
  assertNotNil(target, 'target');
1955
1974
  if (!isSameType(src, target)) {
@@ -2094,21 +2113,164 @@ function writeArrayBuffer (target, dataArrayBuffer, targetOffset = 0, dataOffset
2094
2113
  targetView.set(dataView, targetOffset);
2095
2114
  }
2096
2115
 
2116
+ // module vars
2117
+ const ms2ns = 1_000_000;
2118
+ const s2ns = 1_000_000_000;
2119
+
2097
2120
  var TimeUtils = {
2098
- timestamp64
2121
+ s2ns,
2122
+ ms2ns,
2123
+ timestamp64,
2124
+ lapseNano,
2125
+ lapseMillis,
2126
+ timeoutNano,
2127
+ timeoutMillis
2099
2128
  };
2100
2129
 
2101
- const ms2ns = BigInt(1_000_000);
2102
2130
  /**
2103
2131
  * Gets the current timestamp in nanoseconds (if running in Node.js) or milliseconds (in browser).
2104
2132
  * Uses `process.hrtime.bigint()` for high-resolution timestamps in Node.js, falls back to `Date.now()` in browsers.
2105
2133
  * @returns {bigint} Current timestamp as a BigInt
2106
2134
  */
2107
2135
  function timestamp64 () {
2108
- if (typeof performance !== 'undefined') {
2109
- return BigInt(Math.floor(performance.timeOrigin + performance.now())) * ms2ns
2136
+ // sinon can not fake performance.timeOrigin, so we have to check it
2137
+ if (typeof performance !== 'undefined' && typeof performance.timeOrigin === 'number') {
2138
+ // timeOrigin specifies the high resolution millisecond timestamp, eg. 1756350801931.159
2139
+ const base = performance.timeOrigin;
2140
+ // the current high resolution millisecond timestamp, eg.31767926.416357
2141
+ const now = performance.now();
2142
+ return BigInt((base + now) * ms2ns)
2110
2143
  }
2111
- return BigInt(Date.now()) * ms2ns
2144
+ return BigInt(Date.now() * ms2ns)
2145
+ }
2146
+
2147
+ /**
2148
+ * Calculates the time elapsed in nanoseconds between the given timestamp and now.
2149
+ * @param {bigint} start - start timestamp64, in nanoseconds.
2150
+ * @param {bigint} [end] - end timestamp64, in nanoseconds. If not provided, uses current timestamp64.
2151
+ * @returns {bigint} The elapsed time in nanoseconds (current timestamp64 - ts64).
2152
+ */
2153
+ function lapseNano (start, end) {
2154
+ return (end ?? timestamp64()) - start
2155
+ }
2156
+
2157
+ /**
2158
+ * Calculates the time elapsed in milliseconds between the given timestamp and now.
2159
+ * @param {bigint} start - start The timestamp in 64-bit format.
2160
+ * @param {bigint} [end] - end timestamp64, in nanoseconds. If not provided, uses current timestamp64.
2161
+ * @returns {bigint} The elapsed time in milliseconds.
2162
+ */
2163
+ function lapseMillis (start, end) {
2164
+ end = end ?? timestamp64();
2165
+ const lapseNano = end - start;
2166
+ return BigInt(lapseNano) / BigInt(ms2ns)
2167
+ }
2168
+
2169
+ /**
2170
+ * compare current timestamp64 against the given ts64, and check if the elapsed time exceeds the specified timeout.
2171
+ * @param {bigint} nanoTimestamp64 - The timestamp to compare against (in nanoseconds).
2172
+ * @param {bigint|number} nanoTimeout - The timeout threshold (in nanoseconds).
2173
+ * @returns {boolean} True if elapsed time exceeds timeout, false otherwise.
2174
+ */
2175
+ function timeoutNano (nanoTimestamp64, nanoTimeout) {
2176
+ return lapseNano(nanoTimestamp64) > nanoTimeout
2177
+ }
2178
+
2179
+ /**
2180
+ * compare current timestamp64 against the given ts64, and check if the elapsed time exceeds the specified timeout.
2181
+ * @param {bigint} nanoTimestamp64 - The timestamp to compare against (in nanoseconds).
2182
+ * @param {bigint|number} millisTimeout - The timeout threshold (in milliseconds).
2183
+ * @returns {boolean} True if elapsed time exceeds timeout, false otherwise.
2184
+ */
2185
+ function timeoutMillis (nanoTimestamp64, millisTimeout) {
2186
+ return lapseMillis(nanoTimestamp64) > millisTimeout
2187
+ }
2188
+
2189
+ // owned
2190
+
2191
+ var ArrayUtils = {
2192
+ first,
2193
+ last,
2194
+ equals,
2195
+ equalsIgnoreOrder
2196
+ };
2197
+
2198
+ /**
2199
+ * Gets the first element of an array
2200
+ * @param {any[]} arr - The input array
2201
+ * @param {any} [defaultValue] - The value to return if the array is empty or first element is undefined/null.
2202
+ * @returns {any} The first element of the array, or the defaultValue if the array is empty or not an array.
2203
+ * @throws {Error} if arr is not an array
2204
+ */
2205
+ function first (arr, defaultValue) {
2206
+ assertArray(arr, 'arr');
2207
+ return arr[0] ?? defaultValue
2208
+ }
2209
+
2210
+ /**
2211
+ * Gets the last element of an array
2212
+ * @param {any[]} arr - The input array
2213
+ * @param {any} [defaultValue] - The value to return if the array is empty or last element is undefined/null
2214
+ * @returns {any} The last element of the array or the defaultValue
2215
+ * @throws {Error} if arr is not an array
2216
+ */
2217
+ function last (arr, defaultValue) {
2218
+ assertArray(arr, 'arr');
2219
+ return arr[arr.length - 1] ?? defaultValue
2220
+ }
2221
+
2222
+ /**
2223
+ * Checks if two arrays are equal ignoring element order
2224
+ * @param {any[]} arr1 - first array to compare
2225
+ * @param {any[]} arr2 - Second array to compare
2226
+ * @param {(a:any, b:any) => 0|1|-1} [compareFn]
2227
+ * @returns {boolean} True if arrays have same elements (order-independent), false otherwise
2228
+ */
2229
+ function equalsIgnoreOrder (arr1, arr2, compareFn) {
2230
+ if (!Array.isArray(arr1) || !Array.isArray(arr2)) {
2231
+ return false
2232
+ }
2233
+ if (arr1.length !== arr2.length) {
2234
+ return false
2235
+ }
2236
+ arr1.sort(compareFn);
2237
+ arr2.sort(compareFn);
2238
+ for (let i = 0; i < arr1.length; i++) {
2239
+ if (compareFn) {
2240
+ if (compareFn(arr1[i], arr2[i]) !== 0) {
2241
+ return false
2242
+ }
2243
+ } else if (arr1[i] !== arr2[i]) {
2244
+ return false
2245
+ }
2246
+ }
2247
+ return true
2248
+ }
2249
+
2250
+ /**
2251
+ * Checks if two arrays are equal by order
2252
+ * @param {any[]} arr1 - first array to compare
2253
+ * @param {any[]} arr2 - Second array to compare
2254
+ * @param {(a:any, b:any) => 0|1|-1} [compareFn]
2255
+ * @returns {boolean} True if arrays have same elements (order-independent), false otherwise
2256
+ */
2257
+ function equals (arr1, arr2, compareFn) {
2258
+ if (!Array.isArray(arr1) || !Array.isArray(arr2)) {
2259
+ return false
2260
+ }
2261
+ if (arr1.length !== arr2.length) {
2262
+ return false
2263
+ }
2264
+ for (let i = 0; i < arr1.length; i++) {
2265
+ if (compareFn) {
2266
+ if (compareFn(arr1[i], arr2[i]) !== 0) {
2267
+ return false
2268
+ }
2269
+ } else if (arr1[i] !== arr2[i]) {
2270
+ return false
2271
+ }
2272
+ }
2273
+ return true
2112
2274
  }
2113
2275
 
2114
2276
  /**
@@ -2132,10 +2294,12 @@ var index = {
2132
2294
  ReflectUtils,
2133
2295
  TypedArrayUtils,
2134
2296
  ArrayBufferUtils,
2135
- TimeUtils
2297
+ TimeUtils,
2298
+ ArrayUtils
2136
2299
  };
2137
2300
 
2138
2301
  exports.ArrayBufferUtils = ArrayBufferUtils;
2302
+ exports.ArrayUtils = ArrayUtils;
2139
2303
  exports.ClassProxyUtils = ClassProxyUtils;
2140
2304
  exports.Exec = ExecUtils;
2141
2305
  exports.ExecUtils = ExecUtils;