@superutils/promise 1.0.5 → 1.0.6
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/index.d.ts +95 -44
- package/dist/index.js +6 -5
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -184,7 +184,7 @@ type RetryOptions<T = unknown> = {
|
|
|
184
184
|
* Additional condition/function to be used to determine whether function should be retried.
|
|
185
185
|
* `retryIf` will only be executed when function execution is successful.
|
|
186
186
|
*/
|
|
187
|
-
retryIf?: null | ((prevResult: T | undefined, retryCount: number
|
|
187
|
+
retryIf?: null | ((prevResult: T | undefined, retryCount: number) => boolean | Promise<boolean>);
|
|
188
188
|
};
|
|
189
189
|
|
|
190
190
|
declare class PromisEBase<T = unknown> extends Promise<T> implements IPromisE<T> {
|
|
@@ -293,7 +293,38 @@ type TimeoutOptions<Func extends string = 'all'> = {
|
|
|
293
293
|
* @function PromisE.deferred
|
|
294
294
|
* The adaptation of the `deferred()` function tailored for Promises.
|
|
295
295
|
*
|
|
296
|
-
*
|
|
296
|
+
*
|
|
297
|
+
* # Notes
|
|
298
|
+
*
|
|
299
|
+
* - A "request" simply means invokation of the returned callback function
|
|
300
|
+
* - By "handled" it means a "request" will be resolved or rejected.
|
|
301
|
+
* - `PromisE.deferred` is to be used with promises/functions.
|
|
302
|
+
* `PromisE.deferredCallback` is for use with callback functions.
|
|
303
|
+
* - There is no specific time delay.
|
|
304
|
+
* - If a request takes longer than `delayMs`, the following request will be added to queue
|
|
305
|
+
* and either be ignored or exectued based on the debounce/throttle configuration.
|
|
306
|
+
* - If not throttled:
|
|
307
|
+
* 1. Once a request is handled, all previous requests will be ignored and pool starts anew.
|
|
308
|
+
* 2. If a function is provided in the returned callback, ALL of them will be invoked, regardless of pool size.
|
|
309
|
+
* 3. The last/only request in an on-going requests' pool will handled (resolve/reject).
|
|
310
|
+
* - If throttled:
|
|
311
|
+
* 1. Once a requst starts executing, subsequent requests will be added to a queue.
|
|
312
|
+
* 2. The last/only item in the queue will be handled. Rest will be ignored.
|
|
313
|
+
* 3. If a function is provided in the returned callback, it will be invoked only if the request is handled.
|
|
314
|
+
* Thus, improving performance by avoiding unnecessary invokations.
|
|
315
|
+
* 4. If every single request/function needs to be invoked, avoid using throttle.
|
|
316
|
+
* - If throttled and `strict` is truthy, all subsequent request while a request is being handled will be ignored.
|
|
317
|
+
*
|
|
318
|
+
* @param options (optional) Debounce/throttle configuration.
|
|
319
|
+
*
|
|
320
|
+
* The properties' default values can be overridden to be EFFECTIVE GLOBALLY:
|
|
321
|
+
* ```typescript
|
|
322
|
+
* deferred.defaults = {
|
|
323
|
+
* delayMs: 100,
|
|
324
|
+
* resolveError: ResolveError.REJECT,
|
|
325
|
+
* resolveIgnored: ResolveIgnored.WITH_LAST,
|
|
326
|
+
* }
|
|
327
|
+
* ```
|
|
297
328
|
* @property options.delayMs (optional) delay in milliseconds to be used with debounce & throttle modes. When `undefined` or `>= 0`, execution will be sequential.
|
|
298
329
|
* @property options.onError (optional)
|
|
299
330
|
* @property options.onIgnore (optional) invoked whenever callback invocation is ignored by a newer invocation
|
|
@@ -305,30 +336,11 @@ type TimeoutOptions<Func extends string = 'all'> = {
|
|
|
305
336
|
* Requires `defer`.
|
|
306
337
|
* Default: `false`
|
|
307
338
|
*
|
|
308
|
-
* @returns
|
|
309
|
-
* - sequential: when `delayMs <= 0`
|
|
339
|
+
* @returns Callback function that can be invoked in one of the followin 3 methods:
|
|
340
|
+
* - sequential: when `delayMs <= 0`
|
|
310
341
|
* - debounced: when `delayMs > 0` and `throttle = false`
|
|
311
342
|
* - throttled: when `delayMs > 0` and `throttle = true`
|
|
312
343
|
*
|
|
313
|
-
* The main difference is that:
|
|
314
|
-
* - Notes:
|
|
315
|
-
* 1. A "request" simply means invokation of the returned callback function
|
|
316
|
-
* 2. By "handled" it means a "request" will be resolved or rejected.
|
|
317
|
-
* - `PromisE.deferred` is to be used with promises/functions
|
|
318
|
-
* - There is no specific time delay.
|
|
319
|
-
* - The time when a request is completed is irrelevant.
|
|
320
|
-
* - If not throttled:
|
|
321
|
-
* 1. Once a request is handled, all previous requests will be ignored and pool starts anew.
|
|
322
|
-
* 2. If a function is provided in the returned callback, ALL of them will be invoked, regardless of pool size.
|
|
323
|
-
* 3. The last/only request in an on-going requests' pool will handled (resolve/reject).
|
|
324
|
-
* - If throttled:
|
|
325
|
-
* 1. Once a requst starts executing, subsequent requests will be added to a queue.
|
|
326
|
-
* 2. The last/only item in the queue will be handled. Rest will be ignored.
|
|
327
|
-
* 3. If a function is provided in the returned callback, it will be invoked only if the request is handled.
|
|
328
|
-
* Thus, improving performance by avoiding unnecessary invokations.
|
|
329
|
-
* 4. If every single request/function needs to be invoked, avoid using throttle.
|
|
330
|
-
*
|
|
331
|
-
* - If throttled and `strict` is truthy, all subsequent request while a request is being handled will be ignored.
|
|
332
344
|
*
|
|
333
345
|
* @example Explanation & example usage:
|
|
334
346
|
* ```typescript
|
|
@@ -400,15 +412,19 @@ declare namespace deferred {
|
|
|
400
412
|
declare function deferredCallback<TDefault, ThisArg, Delay extends number = number, CbArgs extends unknown[] = unknown[]>(callback: (...args: CbArgs) => TDefault | Promise<TDefault>, options?: DeferredAsyncOptions<ThisArg, Delay>): <TResult = TDefault>(...args: CbArgs) => IPromisE<TResult>;
|
|
401
413
|
|
|
402
414
|
/**
|
|
403
|
-
*
|
|
404
|
-
*
|
|
415
|
+
* Creates a promise that completes after given delay/duration.
|
|
416
|
+
*
|
|
417
|
+
* Also accessible from the `PromisE` class as `PromisE.delay()`.
|
|
418
|
+
*
|
|
419
|
+
* @param duration duration in milliseconds. Default: `100`
|
|
420
|
+
* @param result (optional) specify a value to resolve or error to reject with.
|
|
405
421
|
*
|
|
406
|
-
*
|
|
407
|
-
* @param {unknown} result (optional) specify a value to resolve or reject with.
|
|
408
|
-
* Default: `delayMs` when resolved or timed out error when rejected
|
|
409
|
-
* @param {boolean} asRejected (optional) if `true`, will reject the promise after the delay.
|
|
422
|
+
* Alternatively, a function (with no arguments) can be provided that returns the result.
|
|
410
423
|
*
|
|
411
|
-
*
|
|
424
|
+
* Default: `delayMs` when resolved or timed out error when rejected
|
|
425
|
+
* @param asRejected (optional) if `true`, will reject the promise after the delay.
|
|
426
|
+
*
|
|
427
|
+
* @returns a promise
|
|
412
428
|
*
|
|
413
429
|
* @example Delay before continuing execution
|
|
414
430
|
* ```typescript
|
|
@@ -433,7 +449,7 @@ declare namespace delay {
|
|
|
433
449
|
var defaults: {
|
|
434
450
|
/** Default delay duration in milliseconds */
|
|
435
451
|
duration: number;
|
|
436
|
-
/** Default timed out message */
|
|
452
|
+
/** Default timed out message (if `result` is not provided) */
|
|
437
453
|
delayTimeoutMsg: string;
|
|
438
454
|
};
|
|
439
455
|
}
|
|
@@ -630,7 +646,7 @@ declare class PromisE<T = unknown> extends PromisEBase<T> {
|
|
|
630
646
|
}
|
|
631
647
|
|
|
632
648
|
/**
|
|
633
|
-
* Executes a function and retries it on failure or until a specific condition is met.
|
|
649
|
+
* Executes a function asynchronously and retries it on failure or until a specific condition is met.
|
|
634
650
|
*
|
|
635
651
|
* The function will be re-executed if:
|
|
636
652
|
* 1. The `func` promise rejects or the function throws an error.
|
|
@@ -640,21 +656,56 @@ declare class PromisE<T = unknown> extends PromisEBase<T> {
|
|
|
640
656
|
* Retries will stop when the `retry` count is exhausted, or when `func` executes successfully
|
|
641
657
|
* (resolves without error) AND the `retryIf` (if provided) returns `false`.
|
|
642
658
|
*
|
|
643
|
-
* @template T The type of the value that the `func`
|
|
644
|
-
*
|
|
645
|
-
* @param
|
|
646
|
-
* @
|
|
647
|
-
*
|
|
648
|
-
*
|
|
649
|
-
*
|
|
650
|
-
*
|
|
651
|
-
*
|
|
652
|
-
*
|
|
653
|
-
*
|
|
654
|
-
*
|
|
659
|
+
* @template T The type of the value that the `func` resolves to.
|
|
660
|
+
*
|
|
661
|
+
* @param func The function to execute. It can be synchronous or asynchronous.
|
|
662
|
+
* @param options (optional) Configuration of the retry mechanism.
|
|
663
|
+
*
|
|
664
|
+
* The following options' default values can be configured to be EFFECTIVE GLOBALLY.
|
|
665
|
+
*
|
|
666
|
+
* ```typescript
|
|
667
|
+
* PromisE.retry.defaults = {
|
|
668
|
+
* retry: 1,
|
|
669
|
+
* retryBackOff: 'exponential',
|
|
670
|
+
* retryDelay: 300,
|
|
671
|
+
* retryDelayJitter: true,
|
|
672
|
+
* retryDelayJitterMax: 100,
|
|
673
|
+
* }
|
|
674
|
+
* ```
|
|
675
|
+
* @param options.retry (optional) The maximum number of retries. Default: `1`
|
|
676
|
+
* @param options.retryBackOff (optional) The backoff strategy.
|
|
677
|
+
* Accepted values:
|
|
678
|
+
* - `'exponential'` doubles the delay for each subsequent retry.
|
|
679
|
+
* - `'linear'` uses a constant delay.
|
|
680
|
+
*
|
|
681
|
+
* Default: `'exponential'`
|
|
682
|
+
* @param options.retryDelayMs (optional) The base delay in milliseconds between retries.
|
|
683
|
+
*
|
|
684
|
+
* Default: `300`
|
|
685
|
+
* @param options.retryDelayJitter (optional) If true, adds a random jitter to the delay to prevent
|
|
686
|
+
* the thundering herd problem.
|
|
687
|
+
*
|
|
688
|
+
* Default: `true`
|
|
689
|
+
* @param options.retryDelayJitterMax The maximum jitter in milliseconds to add to the delay.
|
|
690
|
+
*
|
|
691
|
+
* Default: `100`
|
|
692
|
+
* @param options.retryIf (optional) A function that is called after a successful execution of `func`.
|
|
693
|
+
* If it returns `true`, a retry is triggered.
|
|
694
|
+
*
|
|
695
|
+
* **Arguments:**
|
|
696
|
+
* - `result`: result received after the most recent `func` excution
|
|
697
|
+
* - `retryCount`: number of times the execution has been retried (`total_attemts - 1`)
|
|
698
|
+
*
|
|
699
|
+
* If `retryIf()` throws error, the are handled gracefully and it's return value defaults `false` (no further retry).
|
|
700
|
+
*
|
|
701
|
+
* @returns A promise that resolves with the result of the last successful execution of `func`.
|
|
702
|
+
* If all retries fail (either by throwing an error or when `retryIf()` returned true in every time),
|
|
703
|
+
* it resolves with the last return value of `func()`. Errors thrown by `func` are caught and handled internally,
|
|
704
|
+
* only re-thrown if no result is received after maximum retries.
|
|
655
705
|
*/
|
|
656
706
|
declare const retry: {
|
|
657
707
|
<T>(func: () => ValueOrPromise<T>, options: RetryOptions<T>): Promise<T>;
|
|
708
|
+
/** Global default values */
|
|
658
709
|
defaults: {
|
|
659
710
|
retry: number;
|
|
660
711
|
retryBackOff: "exponential";
|
package/dist/index.js
CHANGED
|
@@ -170,7 +170,6 @@ function deferred(options) {
|
|
|
170
170
|
options = objCopy(defaults, options, [], "empty");
|
|
171
171
|
let { onError, onIgnore, onResult } = options;
|
|
172
172
|
const {
|
|
173
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
174
173
|
delayMs,
|
|
175
174
|
resolveError,
|
|
176
175
|
// by default reject on error
|
|
@@ -259,7 +258,7 @@ function deferred(options) {
|
|
|
259
258
|
return deferredFunc;
|
|
260
259
|
}
|
|
261
260
|
deferred.defaults = {
|
|
262
|
-
delayMs:
|
|
261
|
+
delayMs: 100,
|
|
263
262
|
resolveError: "REJECT" /* REJECT */,
|
|
264
263
|
resolveIgnored: "WITH_LAST" /* WITH_LAST */
|
|
265
264
|
};
|
|
@@ -284,7 +283,9 @@ function delay(duration = delay.defaults.duration, result = duration, asRejected
|
|
|
284
283
|
result2 = (_a = fallbackIfFails3(result2, [], void 0)) != null ? _a : duration;
|
|
285
284
|
if (!asRejected) return promise.resolve(result2);
|
|
286
285
|
promise.reject(
|
|
287
|
-
result2
|
|
286
|
+
duration !== result2 && result2 !== void 0 ? result2 : new Error(
|
|
287
|
+
`${delay.defaults.delayTimeoutMsg} ${duration}ms`
|
|
288
|
+
)
|
|
288
289
|
);
|
|
289
290
|
};
|
|
290
291
|
promise.timeoutId = setTimeout(() => finalize(result), duration);
|
|
@@ -296,7 +297,7 @@ function delay(duration = delay.defaults.duration, result = duration, asRejected
|
|
|
296
297
|
delay.defaults = {
|
|
297
298
|
/** Default delay duration in milliseconds */
|
|
298
299
|
duration: 100,
|
|
299
|
-
/** Default timed out message */
|
|
300
|
+
/** Default timed out message (if `result` is not provided) */
|
|
300
301
|
delayTimeoutMsg: "Timed out after"
|
|
301
302
|
};
|
|
302
303
|
var delay_default = delay;
|
|
@@ -353,7 +354,7 @@ var retry = async (func, options) => {
|
|
|
353
354
|
}
|
|
354
355
|
shouldRetry = maxRetries > 0 && retryCount < maxRetries && (!!error || !!await fallbackIfFails4(
|
|
355
356
|
options.retryIf,
|
|
356
|
-
[result, retryCount
|
|
357
|
+
[result, retryCount],
|
|
357
358
|
false
|
|
358
359
|
));
|
|
359
360
|
} while (shouldRetry);
|
package/package.json
CHANGED