foreslash 0.2.3 → 0.2.4
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/CHANGELOG.md +12 -0
- package/lib/index.cmn.cjs +90 -17
- package/lib/index.d.ts +67 -3
- package/lib/index.mjs +89 -18
- package/lib/index.umd.js +90 -17
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
+
## Version 0.2.4 - 2025-0
|
|
4
|
+
|
|
5
|
+
Unstable version
|
|
6
|
+
|
|
7
|
+
- Feat 🥥 Functions added: `retry` `parallel`
|
|
8
|
+
- Other fixes and improvements
|
|
9
|
+
|
|
10
|
+
不稳定版本
|
|
11
|
+
|
|
12
|
+
- 功能 🥥 添加函数: `retry` `parallel`
|
|
13
|
+
- 其他修复与优化
|
|
14
|
+
|
|
3
15
|
## Version 0.2.3 - 2025-03-28
|
|
4
16
|
|
|
5
17
|
Unstable version
|
package/lib/index.cmn.cjs
CHANGED
|
@@ -351,12 +351,100 @@ function defer(asyncFunction, options) {
|
|
|
351
351
|
});
|
|
352
352
|
}
|
|
353
353
|
|
|
354
|
+
function clamp(num, min, max, options) {
|
|
355
|
+
var _a, _b;
|
|
356
|
+
if (isNaN(min))
|
|
357
|
+
throw new Error('Invalid min parameter');
|
|
358
|
+
if (isNaN(max))
|
|
359
|
+
throw new Error('Invalid max parameter');
|
|
360
|
+
if (max < min) {
|
|
361
|
+
[min, max] = [max, min];
|
|
362
|
+
}
|
|
363
|
+
const { default: def, defaultMin: _dMin, defaultMax: _dMax } = options || {};
|
|
364
|
+
const defaultMin = (_a = _dMin !== null && _dMin !== void 0 ? _dMin : def) !== null && _a !== void 0 ? _a : min;
|
|
365
|
+
const defaultMax = (_b = _dMax !== null && _dMax !== void 0 ? _dMax : def) !== null && _b !== void 0 ? _b : max;
|
|
366
|
+
if (isNaN(num))
|
|
367
|
+
return defaultMin;
|
|
368
|
+
return num < min ? defaultMin : num > max ? defaultMax : num;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
function parallel(args, fn, options) {
|
|
372
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
373
|
+
if (!args.length)
|
|
374
|
+
return [];
|
|
375
|
+
const { limit: _limit = 5 } = options || {};
|
|
376
|
+
const limit = clamp(Math.floor(_limit), 1, 100);
|
|
377
|
+
let current = 0;
|
|
378
|
+
const results = [];
|
|
379
|
+
const errors = [];
|
|
380
|
+
const asyncFn = tryit(fn);
|
|
381
|
+
const processor = () => __awaiter(this, void 0, void 0, function* () {
|
|
382
|
+
while (current < args.length) {
|
|
383
|
+
const index = current++;
|
|
384
|
+
const [err, result] = yield asyncFn(args[index]);
|
|
385
|
+
if (err)
|
|
386
|
+
errors.push({ index, error: err });
|
|
387
|
+
else
|
|
388
|
+
results[index] = result;
|
|
389
|
+
}
|
|
390
|
+
});
|
|
391
|
+
const tasks = [];
|
|
392
|
+
for (let i = 0; i < Math.min(args.length, limit); i++) {
|
|
393
|
+
tasks.push(processor());
|
|
394
|
+
}
|
|
395
|
+
yield Promise.all(tasks);
|
|
396
|
+
if (errors.length) {
|
|
397
|
+
throw new Error(`Parallel execution failed on index: ${errors.map((e) => e.index).join(', ')}`, { cause: errors });
|
|
398
|
+
}
|
|
399
|
+
return results;
|
|
400
|
+
});
|
|
401
|
+
}
|
|
402
|
+
|
|
354
403
|
function sleep(time = 1000) {
|
|
355
404
|
return new Promise((res) => {
|
|
356
405
|
setTimeout(res, time);
|
|
357
406
|
});
|
|
358
407
|
}
|
|
359
408
|
|
|
409
|
+
function retry(asyncFunction, option) {
|
|
410
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
411
|
+
let retryCounts = 0;
|
|
412
|
+
const times = isNumber(option === null || option === void 0 ? void 0 : option.times) ? option.times : 3;
|
|
413
|
+
const delay = isFunction(option === null || option === void 0 ? void 0 : option.delay)
|
|
414
|
+
? option.delay
|
|
415
|
+
: isNumber(option === null || option === void 0 ? void 0 : option.delay)
|
|
416
|
+
? () => option.delay
|
|
417
|
+
: null;
|
|
418
|
+
const gap = isFunction(option === null || option === void 0 ? void 0 : option.gap) ? option.gap : isNumber(option === null || option === void 0 ? void 0 : option.gap) ? () => option.gap : null;
|
|
419
|
+
let lastRunTime = 0;
|
|
420
|
+
const getDelayTime = !option || (!delay && !gap)
|
|
421
|
+
? () => 0
|
|
422
|
+
: gap
|
|
423
|
+
? (retryCounts) => {
|
|
424
|
+
const time = gap(retryCounts);
|
|
425
|
+
return time - Date.now() + lastRunTime;
|
|
426
|
+
}
|
|
427
|
+
: delay;
|
|
428
|
+
while (1) {
|
|
429
|
+
lastRunTime = Date.now();
|
|
430
|
+
const [err, res] = yield tryit(asyncFunction)((err) => {
|
|
431
|
+
throw { $$exit_retry: err };
|
|
432
|
+
});
|
|
433
|
+
if (!err)
|
|
434
|
+
return res;
|
|
435
|
+
retryCounts++;
|
|
436
|
+
if (err && err.$$exit_retry)
|
|
437
|
+
throw err.$$exit_retry;
|
|
438
|
+
if (retryCounts >= times)
|
|
439
|
+
throw err;
|
|
440
|
+
const delayTime = getDelayTime(retryCounts);
|
|
441
|
+
if (delayTime > 0)
|
|
442
|
+
yield sleep(delayTime);
|
|
443
|
+
}
|
|
444
|
+
throw new Error('retry failed');
|
|
445
|
+
});
|
|
446
|
+
}
|
|
447
|
+
|
|
360
448
|
const noop = function noop() { };
|
|
361
449
|
|
|
362
450
|
function withResolvers(PromiseLike = Promise) {
|
|
@@ -370,23 +458,6 @@ function withResolvers(PromiseLike = Promise) {
|
|
|
370
458
|
return { promise, resolve, reject };
|
|
371
459
|
}
|
|
372
460
|
|
|
373
|
-
function clamp(num, min, max, options) {
|
|
374
|
-
var _a, _b;
|
|
375
|
-
if (isNaN(min))
|
|
376
|
-
throw new Error('Invalid min parameter');
|
|
377
|
-
if (isNaN(max))
|
|
378
|
-
throw new Error('Invalid max parameter');
|
|
379
|
-
if (max < min) {
|
|
380
|
-
[min, max] = [max, min];
|
|
381
|
-
}
|
|
382
|
-
const { default: def, defaultMin: _dMin, defaultMax: _dMax } = options || {};
|
|
383
|
-
const defaultMin = (_a = _dMin !== null && _dMin !== void 0 ? _dMin : def) !== null && _a !== void 0 ? _a : min;
|
|
384
|
-
const defaultMax = (_b = _dMax !== null && _dMax !== void 0 ? _dMax : def) !== null && _b !== void 0 ? _b : max;
|
|
385
|
-
if (isNaN(num))
|
|
386
|
-
return defaultMin;
|
|
387
|
-
return num < min ? defaultMin : num > max ? defaultMax : num;
|
|
388
|
-
}
|
|
389
|
-
|
|
390
461
|
const mimeMap = {
|
|
391
462
|
application: {
|
|
392
463
|
acrobat: ['pdf'],
|
|
@@ -1775,6 +1846,7 @@ exports.kebabCase = kebabCase;
|
|
|
1775
1846
|
exports.memo = memo;
|
|
1776
1847
|
exports.noop = noop;
|
|
1777
1848
|
exports.not = not;
|
|
1849
|
+
exports.parallel = parallel;
|
|
1778
1850
|
exports.pascalCase = pascalCase;
|
|
1779
1851
|
exports.pass = pass;
|
|
1780
1852
|
exports.passWith = passWith;
|
|
@@ -1787,6 +1859,7 @@ exports.randomIntFloor = randomIntFloor;
|
|
|
1787
1859
|
exports.randomString = randomString;
|
|
1788
1860
|
exports.range = range;
|
|
1789
1861
|
exports.remove = remove;
|
|
1862
|
+
exports.retry = retry;
|
|
1790
1863
|
exports.shuffle = shuffle;
|
|
1791
1864
|
exports.sleep = sleep;
|
|
1792
1865
|
exports.snakeCase = snakeCase;
|
package/lib/index.d.ts
CHANGED
|
@@ -116,6 +116,70 @@ type DeferOption = {
|
|
|
116
116
|
*/
|
|
117
117
|
declare function defer<T>(asyncFunction: (cleanUp: (fn: DeferCallbackFunction) => number, cancelCleanUp: (fnOrIndex: DeferCallbackFunction | number) => void) => T | Promise<T>, options?: Partial<DeferOption>): Promise<T>;
|
|
118
118
|
|
|
119
|
+
/**
|
|
120
|
+
* 并发执行函数, 可以控制并发数
|
|
121
|
+
* @param args 要经由 `fn` 处理的数据
|
|
122
|
+
* @param fn 处理函数, 可以是异步函数
|
|
123
|
+
* @param options 配置项, 目前仅支持 `limit` 限制并发数, 默认为 `5`
|
|
124
|
+
* @returns 一个 `Promise`, 当所有数据都处理完成后, 会返回一个包含所有结果的数组\
|
|
125
|
+
* 如果有错误, 则会抛出一个 `Error` 对象, `Error.cause` 中包含所有错误信息(如果环境支持的话)
|
|
126
|
+
* @example
|
|
127
|
+
* ```js
|
|
128
|
+
* const fn = async (n) => { return n * 2 }
|
|
129
|
+
* parallel([1, 2, 3, 4, 5], fn, { limit: 2 }) // Promise<[2, 4, 6, 8, 10]>
|
|
130
|
+
* ```
|
|
131
|
+
* @since 0.2.4
|
|
132
|
+
*/
|
|
133
|
+
declare function parallel<Args, Res>(args: Args[], fn: (arg: Args) => Promise<Res>, options?: {
|
|
134
|
+
limit?: number;
|
|
135
|
+
}): Promise<Res[]>;
|
|
136
|
+
|
|
137
|
+
type RetryFunction<T> = (() => T | Promise<T>) | ((exitCallback: (err: any) => never) => T | Promise<T>);
|
|
138
|
+
type RetryOption = {
|
|
139
|
+
times?: number;
|
|
140
|
+
delay?: number | ((retryCounts: number) => number);
|
|
141
|
+
gap?: number | ((retryCounts: number) => number);
|
|
142
|
+
};
|
|
143
|
+
/**
|
|
144
|
+
* 在传入的函数发生异常后重试\
|
|
145
|
+
* 使用场景一般是重试网络请求等情况
|
|
146
|
+
* - 可以设置两次重试之间的延迟(delay), 默认为无延迟
|
|
147
|
+
* - 也可以设置为两次重试之间的时间间隔(gap), 与延迟模式的区别见下文
|
|
148
|
+
* - 传入的函数接受一个 `exit` 回调函数, 调用这个回调函数会立即退出重试逻辑
|
|
149
|
+
*
|
|
150
|
+
* 延迟模式(delay)
|
|
151
|
+
* ``` text
|
|
152
|
+
* delay = 1000:
|
|
153
|
+
* |0s |1s |2s |3s
|
|
154
|
+
* |[400ms-] | [800ms------|---] | [第 3 次调用]
|
|
155
|
+
* ^ 1000ms ++++|+++++++ ^ ^ 1000ms ++++++++|+++ ^
|
|
156
|
+
* ```
|
|
157
|
+
*
|
|
158
|
+
* 间隔模式(gap)
|
|
159
|
+
* ``` text
|
|
160
|
+
* gap = 1000:
|
|
161
|
+
* |0s |1s |2s
|
|
162
|
+
* |[400ms-] |[800ms---------] |[第 3 次调用]
|
|
163
|
+
* ^ 1000ms +++++++++++ ^ 1000ms +++++++++++ ^
|
|
164
|
+
* ```
|
|
165
|
+
*
|
|
166
|
+
* @param asyncFunction 需要处理的函数, 推荐是异步函数, 也可以是同步函数
|
|
167
|
+
* @param option 重试相关的配置, 具体配置见下
|
|
168
|
+
* @example
|
|
169
|
+
* ```js
|
|
170
|
+
* // 基本用法, 默认重试 3 次, 每次失败后会立即重新调用
|
|
171
|
+
* const res = await retry(() => fetch(url, params))
|
|
172
|
+
* // 重试 10 次
|
|
173
|
+
* const res = await retry(() => fetch(url, params), { times: 10 })
|
|
174
|
+
* // 延迟模式, 每次失败后会等待 1 秒再重新调用
|
|
175
|
+
* const res = await retry(() => fetch(url, params), { delay: 1000 })
|
|
176
|
+
* // 间隔模式, 每次失败后会在下 1 秒再重新调用
|
|
177
|
+
* const res = await retry(() => fetch(url, params), { gap: 1000 })
|
|
178
|
+
* ```
|
|
179
|
+
* @version 0.2.4
|
|
180
|
+
*/
|
|
181
|
+
declare function retry<T>(asyncFunction: RetryFunction<T>, option?: RetryOption): Promise<T>;
|
|
182
|
+
|
|
119
183
|
/**
|
|
120
184
|
* 延迟一定时间
|
|
121
185
|
* @param time 延迟时间, 单位为毫秒(ms), 默认为 `1000` (即 1 秒)
|
|
@@ -768,7 +832,7 @@ declare function isWrapperBigInt(value: unknown): value is BigInt;
|
|
|
768
832
|
* @param options 配置项, 可以配置默认值等
|
|
769
833
|
* - `default` 默认值, 如果初始值不在范围内, 则返回默认值
|
|
770
834
|
* - `defaultMin` 初始值小于最小值时返回该值, 覆盖 `default` 参数
|
|
771
|
-
* - `defaultMax`
|
|
835
|
+
* - `defaultMax` 初始值大于最大值时返回该值, 覆盖 `default` 参数
|
|
772
836
|
* @returns 返回一个在指定范围内的数字
|
|
773
837
|
* @example
|
|
774
838
|
* ```js
|
|
@@ -1428,7 +1492,7 @@ declare function deepClone<T>(obj: T, options?: Partial<CloneOptions>, map?: Map
|
|
|
1428
1492
|
|
|
1429
1493
|
/**
|
|
1430
1494
|
* 快速深拷贝
|
|
1431
|
-
* - 相对 `deepClone`
|
|
1495
|
+
* - 功能较为齐全, 相对 `deepClone` 而言运行更快
|
|
1432
1496
|
* - 支持处理的情况:循环引用、数组、`Date`、正则、`Set`、`Map`、`FormData`
|
|
1433
1497
|
* - 对象上以 `Symbol` 为键的属性无法拷贝
|
|
1434
1498
|
* - 无法拷贝的内容将视为原生数据类型, 直接复制(如函数、`Promise`、`WeakMap`、`WeakSet`)
|
|
@@ -1673,4 +1737,4 @@ declare function throttle<T extends any[]>(fn: (...args: T) => any, delay: numbe
|
|
|
1673
1737
|
reset: () => void;
|
|
1674
1738
|
};
|
|
1675
1739
|
|
|
1676
|
-
export { type CloneOptions, type CustomCloner, type RangeOptions, type TypedArray, _, acceptableFileName, acceptableFileType, camelCase, caseCamel, caseConvert, caseKebab, casePascal, caseSnake, clamp, compose, _curryMore as curry, debounce, deepClone, defer, fastClone, getAcceptableExtByMIME, getAcceptableMIMEByExt, getGlobalThis, getTag, isArray, isArrayBuffer, isArrayLike, isBigInt, isBigInt64Array, isBigUint64Array, isBoolean, isBuffer, isDataView, isDate, isEmpty, isFile, isFloat32Array, isFloat64Array, isFormData, isFunction, isInt16Array, isInt32Array, isInt8Array, isInteger, isIterable, isMap, isNil, isNull, isNumber, isObject, isPlaceholder, isPrimitive, isPromise, isPromiseLike, isRegExp, isSet, isString, isSymbol, isTypedArray, isUint16Array, isUint32Array, isUint8Array, isUint8ClampedArray, isUndefined, isWeakMap, isWeakSet, isWrapperBigInt, isWrapperBoolean, isWrapperNumber, isWrapperObject, isWrapperString, isWrapperSymbol, kebabCase, memo, noop, not, pascalCase, pass, passWith, pipe, randomBase32String, randomChoice, randomHexString, randomInt, randomIntFloor, randomString, range, remove, shuffle, sleep, snakeCase, splitWords, throttle, titleCase, tryit, ulid, uuidNil, uuidV4, withResolvers };
|
|
1740
|
+
export { type CloneOptions, type CustomCloner, type RangeOptions, type TypedArray, _, acceptableFileName, acceptableFileType, camelCase, caseCamel, caseConvert, caseKebab, casePascal, caseSnake, clamp, compose, _curryMore as curry, debounce, deepClone, defer, fastClone, getAcceptableExtByMIME, getAcceptableMIMEByExt, getGlobalThis, getTag, isArray, isArrayBuffer, isArrayLike, isBigInt, isBigInt64Array, isBigUint64Array, isBoolean, isBuffer, isDataView, isDate, isEmpty, isFile, isFloat32Array, isFloat64Array, isFormData, isFunction, isInt16Array, isInt32Array, isInt8Array, isInteger, isIterable, isMap, isNil, isNull, isNumber, isObject, isPlaceholder, isPrimitive, isPromise, isPromiseLike, isRegExp, isSet, isString, isSymbol, isTypedArray, isUint16Array, isUint32Array, isUint8Array, isUint8ClampedArray, isUndefined, isWeakMap, isWeakSet, isWrapperBigInt, isWrapperBoolean, isWrapperNumber, isWrapperObject, isWrapperString, isWrapperSymbol, kebabCase, memo, noop, not, parallel, pascalCase, pass, passWith, pipe, randomBase32String, randomChoice, randomHexString, randomInt, randomIntFloor, randomString, range, remove, retry, shuffle, sleep, snakeCase, splitWords, throttle, titleCase, tryit, ulid, uuidNil, uuidV4, withResolvers };
|
package/lib/index.mjs
CHANGED
|
@@ -349,12 +349,100 @@ function defer(asyncFunction, options) {
|
|
|
349
349
|
});
|
|
350
350
|
}
|
|
351
351
|
|
|
352
|
+
function clamp(num, min, max, options) {
|
|
353
|
+
var _a, _b;
|
|
354
|
+
if (isNaN(min))
|
|
355
|
+
throw new Error('Invalid min parameter');
|
|
356
|
+
if (isNaN(max))
|
|
357
|
+
throw new Error('Invalid max parameter');
|
|
358
|
+
if (max < min) {
|
|
359
|
+
[min, max] = [max, min];
|
|
360
|
+
}
|
|
361
|
+
const { default: def, defaultMin: _dMin, defaultMax: _dMax } = options || {};
|
|
362
|
+
const defaultMin = (_a = _dMin !== null && _dMin !== void 0 ? _dMin : def) !== null && _a !== void 0 ? _a : min;
|
|
363
|
+
const defaultMax = (_b = _dMax !== null && _dMax !== void 0 ? _dMax : def) !== null && _b !== void 0 ? _b : max;
|
|
364
|
+
if (isNaN(num))
|
|
365
|
+
return defaultMin;
|
|
366
|
+
return num < min ? defaultMin : num > max ? defaultMax : num;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
function parallel(args, fn, options) {
|
|
370
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
371
|
+
if (!args.length)
|
|
372
|
+
return [];
|
|
373
|
+
const { limit: _limit = 5 } = options || {};
|
|
374
|
+
const limit = clamp(Math.floor(_limit), 1, 100);
|
|
375
|
+
let current = 0;
|
|
376
|
+
const results = [];
|
|
377
|
+
const errors = [];
|
|
378
|
+
const asyncFn = tryit(fn);
|
|
379
|
+
const processor = () => __awaiter(this, void 0, void 0, function* () {
|
|
380
|
+
while (current < args.length) {
|
|
381
|
+
const index = current++;
|
|
382
|
+
const [err, result] = yield asyncFn(args[index]);
|
|
383
|
+
if (err)
|
|
384
|
+
errors.push({ index, error: err });
|
|
385
|
+
else
|
|
386
|
+
results[index] = result;
|
|
387
|
+
}
|
|
388
|
+
});
|
|
389
|
+
const tasks = [];
|
|
390
|
+
for (let i = 0; i < Math.min(args.length, limit); i++) {
|
|
391
|
+
tasks.push(processor());
|
|
392
|
+
}
|
|
393
|
+
yield Promise.all(tasks);
|
|
394
|
+
if (errors.length) {
|
|
395
|
+
throw new Error(`Parallel execution failed on index: ${errors.map((e) => e.index).join(', ')}`, { cause: errors });
|
|
396
|
+
}
|
|
397
|
+
return results;
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
|
|
352
401
|
function sleep(time = 1000) {
|
|
353
402
|
return new Promise((res) => {
|
|
354
403
|
setTimeout(res, time);
|
|
355
404
|
});
|
|
356
405
|
}
|
|
357
406
|
|
|
407
|
+
function retry(asyncFunction, option) {
|
|
408
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
409
|
+
let retryCounts = 0;
|
|
410
|
+
const times = isNumber(option === null || option === void 0 ? void 0 : option.times) ? option.times : 3;
|
|
411
|
+
const delay = isFunction(option === null || option === void 0 ? void 0 : option.delay)
|
|
412
|
+
? option.delay
|
|
413
|
+
: isNumber(option === null || option === void 0 ? void 0 : option.delay)
|
|
414
|
+
? () => option.delay
|
|
415
|
+
: null;
|
|
416
|
+
const gap = isFunction(option === null || option === void 0 ? void 0 : option.gap) ? option.gap : isNumber(option === null || option === void 0 ? void 0 : option.gap) ? () => option.gap : null;
|
|
417
|
+
let lastRunTime = 0;
|
|
418
|
+
const getDelayTime = !option || (!delay && !gap)
|
|
419
|
+
? () => 0
|
|
420
|
+
: gap
|
|
421
|
+
? (retryCounts) => {
|
|
422
|
+
const time = gap(retryCounts);
|
|
423
|
+
return time - Date.now() + lastRunTime;
|
|
424
|
+
}
|
|
425
|
+
: delay;
|
|
426
|
+
while (1) {
|
|
427
|
+
lastRunTime = Date.now();
|
|
428
|
+
const [err, res] = yield tryit(asyncFunction)((err) => {
|
|
429
|
+
throw { $$exit_retry: err };
|
|
430
|
+
});
|
|
431
|
+
if (!err)
|
|
432
|
+
return res;
|
|
433
|
+
retryCounts++;
|
|
434
|
+
if (err && err.$$exit_retry)
|
|
435
|
+
throw err.$$exit_retry;
|
|
436
|
+
if (retryCounts >= times)
|
|
437
|
+
throw err;
|
|
438
|
+
const delayTime = getDelayTime(retryCounts);
|
|
439
|
+
if (delayTime > 0)
|
|
440
|
+
yield sleep(delayTime);
|
|
441
|
+
}
|
|
442
|
+
throw new Error('retry failed');
|
|
443
|
+
});
|
|
444
|
+
}
|
|
445
|
+
|
|
358
446
|
const noop = function noop() { };
|
|
359
447
|
|
|
360
448
|
function withResolvers(PromiseLike = Promise) {
|
|
@@ -368,23 +456,6 @@ function withResolvers(PromiseLike = Promise) {
|
|
|
368
456
|
return { promise, resolve, reject };
|
|
369
457
|
}
|
|
370
458
|
|
|
371
|
-
function clamp(num, min, max, options) {
|
|
372
|
-
var _a, _b;
|
|
373
|
-
if (isNaN(min))
|
|
374
|
-
throw new Error('Invalid min parameter');
|
|
375
|
-
if (isNaN(max))
|
|
376
|
-
throw new Error('Invalid max parameter');
|
|
377
|
-
if (max < min) {
|
|
378
|
-
[min, max] = [max, min];
|
|
379
|
-
}
|
|
380
|
-
const { default: def, defaultMin: _dMin, defaultMax: _dMax } = options || {};
|
|
381
|
-
const defaultMin = (_a = _dMin !== null && _dMin !== void 0 ? _dMin : def) !== null && _a !== void 0 ? _a : min;
|
|
382
|
-
const defaultMax = (_b = _dMax !== null && _dMax !== void 0 ? _dMax : def) !== null && _b !== void 0 ? _b : max;
|
|
383
|
-
if (isNaN(num))
|
|
384
|
-
return defaultMin;
|
|
385
|
-
return num < min ? defaultMin : num > max ? defaultMax : num;
|
|
386
|
-
}
|
|
387
|
-
|
|
388
459
|
const mimeMap = {
|
|
389
460
|
application: {
|
|
390
461
|
acrobat: ['pdf'],
|
|
@@ -1701,4 +1772,4 @@ function throttle(fn, delay, options) {
|
|
|
1701
1772
|
return _throttle(fn, delay, Object.assign({ trailing: false, leading: true }, options));
|
|
1702
1773
|
}
|
|
1703
1774
|
|
|
1704
|
-
export { _, acceptableFileName, acceptableFileType, camelCase, caseCamel, caseConvert, caseKebab, casePascal, caseSnake, clamp, compose, _curryMore as curry, debounce, deepClone, defer, fastClone, getAcceptableExtByMIME, getAcceptableMIMEByExt, getGlobalThis, getTag, isArray, isArrayBuffer, isArrayLike, isBigInt, isBigInt64Array, isBigUint64Array, isBoolean, isBuffer, isDataView, isDate, isEmpty, isFile, isFloat32Array, isFloat64Array, isFormData, isFunction, isInt16Array, isInt32Array, isInt8Array, isInteger, isIterable, isMap, isNil, isNull, isNumber, isObject, isPlaceholder, isPrimitive, isPromise, isPromiseLike, isRegExp, isSet, isString, isSymbol, isTypedArray, isUint16Array, isUint32Array, isUint8Array, isUint8ClampedArray, isUndefined, isWeakMap, isWeakSet, isWrapperBigInt, isWrapperBoolean, isWrapperNumber, isWrapperObject, isWrapperString, isWrapperSymbol, kebabCase, memo, noop, not, pascalCase, pass, passWith, pipe, randomBase32String, randomChoice, randomHexString, randomInt, randomIntFloor, randomString, range, remove, shuffle, sleep, snakeCase, splitWords, throttle, titleCase, tryit, ulid, uuidNil, uuidV4, withResolvers };
|
|
1775
|
+
export { _, acceptableFileName, acceptableFileType, camelCase, caseCamel, caseConvert, caseKebab, casePascal, caseSnake, clamp, compose, _curryMore as curry, debounce, deepClone, defer, fastClone, getAcceptableExtByMIME, getAcceptableMIMEByExt, getGlobalThis, getTag, isArray, isArrayBuffer, isArrayLike, isBigInt, isBigInt64Array, isBigUint64Array, isBoolean, isBuffer, isDataView, isDate, isEmpty, isFile, isFloat32Array, isFloat64Array, isFormData, isFunction, isInt16Array, isInt32Array, isInt8Array, isInteger, isIterable, isMap, isNil, isNull, isNumber, isObject, isPlaceholder, isPrimitive, isPromise, isPromiseLike, isRegExp, isSet, isString, isSymbol, isTypedArray, isUint16Array, isUint32Array, isUint8Array, isUint8ClampedArray, isUndefined, isWeakMap, isWeakSet, isWrapperBigInt, isWrapperBoolean, isWrapperNumber, isWrapperObject, isWrapperString, isWrapperSymbol, kebabCase, memo, noop, not, parallel, pascalCase, pass, passWith, pipe, randomBase32String, randomChoice, randomHexString, randomInt, randomIntFloor, randomString, range, remove, retry, shuffle, sleep, snakeCase, splitWords, throttle, titleCase, tryit, ulid, uuidNil, uuidV4, withResolvers };
|
package/lib/index.umd.js
CHANGED
|
@@ -355,12 +355,100 @@ See the Mulan PSL v2 for more details.
|
|
|
355
355
|
});
|
|
356
356
|
}
|
|
357
357
|
|
|
358
|
+
function clamp(num, min, max, options) {
|
|
359
|
+
var _a, _b;
|
|
360
|
+
if (isNaN(min))
|
|
361
|
+
throw new Error('Invalid min parameter');
|
|
362
|
+
if (isNaN(max))
|
|
363
|
+
throw new Error('Invalid max parameter');
|
|
364
|
+
if (max < min) {
|
|
365
|
+
[min, max] = [max, min];
|
|
366
|
+
}
|
|
367
|
+
const { default: def, defaultMin: _dMin, defaultMax: _dMax } = options || {};
|
|
368
|
+
const defaultMin = (_a = _dMin !== null && _dMin !== void 0 ? _dMin : def) !== null && _a !== void 0 ? _a : min;
|
|
369
|
+
const defaultMax = (_b = _dMax !== null && _dMax !== void 0 ? _dMax : def) !== null && _b !== void 0 ? _b : max;
|
|
370
|
+
if (isNaN(num))
|
|
371
|
+
return defaultMin;
|
|
372
|
+
return num < min ? defaultMin : num > max ? defaultMax : num;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
function parallel(args, fn, options) {
|
|
376
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
377
|
+
if (!args.length)
|
|
378
|
+
return [];
|
|
379
|
+
const { limit: _limit = 5 } = options || {};
|
|
380
|
+
const limit = clamp(Math.floor(_limit), 1, 100);
|
|
381
|
+
let current = 0;
|
|
382
|
+
const results = [];
|
|
383
|
+
const errors = [];
|
|
384
|
+
const asyncFn = tryit(fn);
|
|
385
|
+
const processor = () => __awaiter(this, void 0, void 0, function* () {
|
|
386
|
+
while (current < args.length) {
|
|
387
|
+
const index = current++;
|
|
388
|
+
const [err, result] = yield asyncFn(args[index]);
|
|
389
|
+
if (err)
|
|
390
|
+
errors.push({ index, error: err });
|
|
391
|
+
else
|
|
392
|
+
results[index] = result;
|
|
393
|
+
}
|
|
394
|
+
});
|
|
395
|
+
const tasks = [];
|
|
396
|
+
for (let i = 0; i < Math.min(args.length, limit); i++) {
|
|
397
|
+
tasks.push(processor());
|
|
398
|
+
}
|
|
399
|
+
yield Promise.all(tasks);
|
|
400
|
+
if (errors.length) {
|
|
401
|
+
throw new Error(`Parallel execution failed on index: ${errors.map((e) => e.index).join(', ')}`, { cause: errors });
|
|
402
|
+
}
|
|
403
|
+
return results;
|
|
404
|
+
});
|
|
405
|
+
}
|
|
406
|
+
|
|
358
407
|
function sleep(time = 1000) {
|
|
359
408
|
return new Promise((res) => {
|
|
360
409
|
setTimeout(res, time);
|
|
361
410
|
});
|
|
362
411
|
}
|
|
363
412
|
|
|
413
|
+
function retry(asyncFunction, option) {
|
|
414
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
415
|
+
let retryCounts = 0;
|
|
416
|
+
const times = isNumber(option === null || option === void 0 ? void 0 : option.times) ? option.times : 3;
|
|
417
|
+
const delay = isFunction(option === null || option === void 0 ? void 0 : option.delay)
|
|
418
|
+
? option.delay
|
|
419
|
+
: isNumber(option === null || option === void 0 ? void 0 : option.delay)
|
|
420
|
+
? () => option.delay
|
|
421
|
+
: null;
|
|
422
|
+
const gap = isFunction(option === null || option === void 0 ? void 0 : option.gap) ? option.gap : isNumber(option === null || option === void 0 ? void 0 : option.gap) ? () => option.gap : null;
|
|
423
|
+
let lastRunTime = 0;
|
|
424
|
+
const getDelayTime = !option || (!delay && !gap)
|
|
425
|
+
? () => 0
|
|
426
|
+
: gap
|
|
427
|
+
? (retryCounts) => {
|
|
428
|
+
const time = gap(retryCounts);
|
|
429
|
+
return time - Date.now() + lastRunTime;
|
|
430
|
+
}
|
|
431
|
+
: delay;
|
|
432
|
+
while (1) {
|
|
433
|
+
lastRunTime = Date.now();
|
|
434
|
+
const [err, res] = yield tryit(asyncFunction)((err) => {
|
|
435
|
+
throw { $$exit_retry: err };
|
|
436
|
+
});
|
|
437
|
+
if (!err)
|
|
438
|
+
return res;
|
|
439
|
+
retryCounts++;
|
|
440
|
+
if (err && err.$$exit_retry)
|
|
441
|
+
throw err.$$exit_retry;
|
|
442
|
+
if (retryCounts >= times)
|
|
443
|
+
throw err;
|
|
444
|
+
const delayTime = getDelayTime(retryCounts);
|
|
445
|
+
if (delayTime > 0)
|
|
446
|
+
yield sleep(delayTime);
|
|
447
|
+
}
|
|
448
|
+
throw new Error('retry failed');
|
|
449
|
+
});
|
|
450
|
+
}
|
|
451
|
+
|
|
364
452
|
const noop = function noop() { };
|
|
365
453
|
|
|
366
454
|
function withResolvers(PromiseLike = Promise) {
|
|
@@ -374,23 +462,6 @@ See the Mulan PSL v2 for more details.
|
|
|
374
462
|
return { promise, resolve, reject };
|
|
375
463
|
}
|
|
376
464
|
|
|
377
|
-
function clamp(num, min, max, options) {
|
|
378
|
-
var _a, _b;
|
|
379
|
-
if (isNaN(min))
|
|
380
|
-
throw new Error('Invalid min parameter');
|
|
381
|
-
if (isNaN(max))
|
|
382
|
-
throw new Error('Invalid max parameter');
|
|
383
|
-
if (max < min) {
|
|
384
|
-
[min, max] = [max, min];
|
|
385
|
-
}
|
|
386
|
-
const { default: def, defaultMin: _dMin, defaultMax: _dMax } = options || {};
|
|
387
|
-
const defaultMin = (_a = _dMin !== null && _dMin !== void 0 ? _dMin : def) !== null && _a !== void 0 ? _a : min;
|
|
388
|
-
const defaultMax = (_b = _dMax !== null && _dMax !== void 0 ? _dMax : def) !== null && _b !== void 0 ? _b : max;
|
|
389
|
-
if (isNaN(num))
|
|
390
|
-
return defaultMin;
|
|
391
|
-
return num < min ? defaultMin : num > max ? defaultMax : num;
|
|
392
|
-
}
|
|
393
|
-
|
|
394
465
|
const mimeMap = {
|
|
395
466
|
application: {
|
|
396
467
|
acrobat: ['pdf'],
|
|
@@ -1779,6 +1850,7 @@ See the Mulan PSL v2 for more details.
|
|
|
1779
1850
|
exports.memo = memo;
|
|
1780
1851
|
exports.noop = noop;
|
|
1781
1852
|
exports.not = not;
|
|
1853
|
+
exports.parallel = parallel;
|
|
1782
1854
|
exports.pascalCase = pascalCase;
|
|
1783
1855
|
exports.pass = pass;
|
|
1784
1856
|
exports.passWith = passWith;
|
|
@@ -1791,6 +1863,7 @@ See the Mulan PSL v2 for more details.
|
|
|
1791
1863
|
exports.randomString = randomString;
|
|
1792
1864
|
exports.range = range;
|
|
1793
1865
|
exports.remove = remove;
|
|
1866
|
+
exports.retry = retry;
|
|
1794
1867
|
exports.shuffle = shuffle;
|
|
1795
1868
|
exports.sleep = sleep;
|
|
1796
1869
|
exports.snakeCase = snakeCase;
|