@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.
- package/dist/cjs/index-dev.cjs +200 -36
- package/dist/cjs/index-dev.cjs.map +1 -1
- package/dist/cjs/index-min.cjs +1 -1
- package/dist/cjs/index-min.cjs.map +1 -1
- package/dist/esm/index-dev.js +200 -37
- package/dist/esm/index-dev.js.map +1 -1
- package/dist/esm/index-min.js +1 -1
- package/dist/esm/index-min.js.map +1 -1
- package/dist/umd/index.dev.js +200 -36
- package/dist/umd/index.dev.js.map +1 -1
- package/dist/umd/index.min.js +1 -1
- package/dist/umd/index.min.js.map +1 -1
- package/package.json +1 -1
- package/types/array-utils.d.ts +39 -0
- package/types/index.d.ts +3 -1
- package/types/promise-utils.d.ts +22 -16
- package/types/time-utils.d.ts +36 -0
package/dist/cjs/index-dev.cjs
CHANGED
|
@@ -12,7 +12,7 @@ var LangUtils = {
|
|
|
12
12
|
defaults,
|
|
13
13
|
extend,
|
|
14
14
|
extends: extend,
|
|
15
|
-
equals: equals$
|
|
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$
|
|
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
|
-
//
|
|
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 {
|
|
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 = (
|
|
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(
|
|
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 {
|
|
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
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
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[]}
|
|
1601
|
-
* @returns {Promise<
|
|
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<
|
|
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<
|
|
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
|
-
|
|
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
|
-
|
|
2109
|
-
|
|
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()
|
|
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;
|