@oscarpalmer/atoms 0.152.1 → 0.153.0
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/atoms.full.js +77 -1
- package/dist/function/retry.js +79 -0
- package/dist/index.js +2 -1
- package/package.json +5 -1
- package/src/function/retry.ts +162 -0
- package/src/index.ts +1 -0
- package/types/function/retry.d.ts +35 -0
- package/types/index.d.ts +1 -0
package/dist/atoms.full.js
CHANGED
|
@@ -937,6 +937,82 @@ function debounce(callback, time) {
|
|
|
937
937
|
function throttle(callback, time) {
|
|
938
938
|
return getTimer(TIMER_THROTTLE, callback, time);
|
|
939
939
|
}
|
|
940
|
+
var RetryError = class extends Error {
|
|
941
|
+
constructor(message, original) {
|
|
942
|
+
super(message);
|
|
943
|
+
this.original = original;
|
|
944
|
+
this.name = ERROR_NAME$1;
|
|
945
|
+
}
|
|
946
|
+
};
|
|
947
|
+
/**
|
|
948
|
+
* Retry a callback a specified number of times, with a delay between attempts
|
|
949
|
+
* @param callback Callback to retry
|
|
950
|
+
* @param options Retry options
|
|
951
|
+
* @returns Callback result
|
|
952
|
+
*/
|
|
953
|
+
async function asyncRetry(callback, options) {
|
|
954
|
+
if (typeof callback !== "function") throw new TypeError(MESSAGE_EXPECTATION);
|
|
955
|
+
async function handle() {
|
|
956
|
+
try {
|
|
957
|
+
const result = await callback();
|
|
958
|
+
resolver(result);
|
|
959
|
+
} catch (error) {
|
|
960
|
+
if (attempts >= times || !when(error)) rejector(new RetryError(MESSAGE_FAILED, error));
|
|
961
|
+
else {
|
|
962
|
+
attempts += 1;
|
|
963
|
+
timer();
|
|
964
|
+
}
|
|
965
|
+
}
|
|
966
|
+
}
|
|
967
|
+
const { delay, times, when } = getRetryOptions(options);
|
|
968
|
+
const timer = getTimer(TIMER_WAIT, handle, delay);
|
|
969
|
+
let attempts = 0;
|
|
970
|
+
let rejector;
|
|
971
|
+
let resolver;
|
|
972
|
+
return new Promise((resolve, reject) => {
|
|
973
|
+
rejector = reject;
|
|
974
|
+
resolver = resolve;
|
|
975
|
+
handle();
|
|
976
|
+
});
|
|
977
|
+
}
|
|
978
|
+
function getRetryNumber(value) {
|
|
979
|
+
return typeof value === "number" && value > 0 ? value : 0;
|
|
980
|
+
}
|
|
981
|
+
function getRetryOptions(input) {
|
|
982
|
+
const options = isPlainObject(input) ? input : {};
|
|
983
|
+
return {
|
|
984
|
+
delay: getRetryNumber(options.delay),
|
|
985
|
+
times: getRetryNumber(options.times),
|
|
986
|
+
when: typeof options.when === "function" ? options.when : shouldRetry
|
|
987
|
+
};
|
|
988
|
+
}
|
|
989
|
+
/**
|
|
990
|
+
* Retry a callback a specified number of times
|
|
991
|
+
* @param callback Callback to retry
|
|
992
|
+
* @param options Retry options
|
|
993
|
+
* @returns Callback result
|
|
994
|
+
*/
|
|
995
|
+
function retry(callback, options) {
|
|
996
|
+
if (typeof callback !== "function") throw new TypeError(MESSAGE_EXPECTATION);
|
|
997
|
+
const { times, when } = getRetryOptions(options);
|
|
998
|
+
let last;
|
|
999
|
+
for (let index = 0; index <= times; index += 1) try {
|
|
1000
|
+
return callback();
|
|
1001
|
+
} catch (error) {
|
|
1002
|
+
if (index >= times || !when(error)) {
|
|
1003
|
+
last = error;
|
|
1004
|
+
break;
|
|
1005
|
+
}
|
|
1006
|
+
}
|
|
1007
|
+
throw new RetryError(MESSAGE_FAILED, last);
|
|
1008
|
+
}
|
|
1009
|
+
retry.async = asyncRetry;
|
|
1010
|
+
function shouldRetry() {
|
|
1011
|
+
return true;
|
|
1012
|
+
}
|
|
1013
|
+
const ERROR_NAME$1 = "RetryError";
|
|
1014
|
+
const MESSAGE_EXPECTATION = "Retry expected a function";
|
|
1015
|
+
const MESSAGE_FAILED = "Retry failed";
|
|
940
1016
|
function _isResult(value, okValue) {
|
|
941
1017
|
if (!isPlainObject(value)) return false;
|
|
942
1018
|
return value.ok === okValue && (okValue ? "value" : "error") in value;
|
|
@@ -3696,4 +3772,4 @@ var SizedSet = class extends Set {
|
|
|
3696
3772
|
}
|
|
3697
3773
|
}
|
|
3698
3774
|
};
|
|
3699
|
-
export { CancelablePromise, PromiseTimeoutError, QueueError, SizedMap, SizedSet, attempt, attemptPromise, average, beacon, between, camelCase, cancelable, capitalize, ceil, chunk, clamp, clone, compact, compare, count, debounce, delay, diff, endsWith, equal, error, exists, filter, find, flatten, floor, flow, toResult as fromPromise, toResult, fromQuery, toPromise as fromResult, toPromise, getArray, getColor, getForegroundColor, getHexColor, getHexaColor, getHslColor, getHslaColor, getNormalizedHex, getNumber, getRandomBoolean, getRandomCharacters, getRandomColor, getRandomFloat, getRandomHex, getRandomInteger, getRandomItem, getRandomItems, getRgbColor, getRgbaColor, getString, getUuid, getValue, groupBy, hexToHsl, hexToHsla, hexToRgb, hexToRgba, hslToHex, hslToRgb, hslToRgba, ignoreKey, includes, indexOf, insert, isArrayOrPlainObject, isColor, isConstructor, isEmpty, isError, isFulfilled, isHexColor, isHslColor, isHslLike, isHslaColor, isInstanceOf, isKey, isNonNullable, isNullable, isNullableOrEmpty, isNullableOrWhitespace, isNumber, isNumerical, isObject, isOk, isPlainObject, isPrimitive, isRejected, isResult, isRgbColor, isRgbLike, isRgbaColor, isTypedArray, join, kebabCase, logger, lowerCase, max, median, memoize, merge, min, noop, ok, omit, parse, partition, pascalCase, pick, pipe, promises, push, queue, range, rgbToHex, rgbToHsl, rgbToHsla, round, select, setValue, shuffle, smush, snakeCase, sort, splice, startsWith, sum, template, throttle, timed, times, titleCase, toMap, toQuery, toRecord, toSet, toggle, trim, truncate, tryDecode, tryEncode, unique, unsmush, unwrap, update, upperCase, words };
|
|
3775
|
+
export { CancelablePromise, PromiseTimeoutError, QueueError, RetryError, SizedMap, SizedSet, attempt, attemptPromise, average, beacon, between, camelCase, cancelable, capitalize, ceil, chunk, clamp, clone, compact, compare, count, debounce, delay, diff, endsWith, equal, error, exists, filter, find, flatten, floor, flow, toResult as fromPromise, toResult, fromQuery, toPromise as fromResult, toPromise, getArray, getColor, getForegroundColor, getHexColor, getHexaColor, getHslColor, getHslaColor, getNormalizedHex, getNumber, getRandomBoolean, getRandomCharacters, getRandomColor, getRandomFloat, getRandomHex, getRandomInteger, getRandomItem, getRandomItems, getRgbColor, getRgbaColor, getString, getUuid, getValue, groupBy, hexToHsl, hexToHsla, hexToRgb, hexToRgba, hslToHex, hslToRgb, hslToRgba, ignoreKey, includes, indexOf, insert, isArrayOrPlainObject, isColor, isConstructor, isEmpty, isError, isFulfilled, isHexColor, isHslColor, isHslLike, isHslaColor, isInstanceOf, isKey, isNonNullable, isNullable, isNullableOrEmpty, isNullableOrWhitespace, isNumber, isNumerical, isObject, isOk, isPlainObject, isPrimitive, isRejected, isResult, isRgbColor, isRgbLike, isRgbaColor, isTypedArray, join, kebabCase, logger, lowerCase, max, median, memoize, merge, min, noop, ok, omit, parse, partition, pascalCase, pick, pipe, promises, push, queue, range, retry, rgbToHex, rgbToHsl, rgbToHsla, round, select, setValue, shuffle, smush, snakeCase, sort, splice, startsWith, sum, template, throttle, timed, times, titleCase, toMap, toQuery, toRecord, toSet, toggle, trim, truncate, tryDecode, tryEncode, unique, unsmush, unwrap, update, upperCase, words };
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { isPlainObject } from "../internal/is.js";
|
|
2
|
+
import { TIMER_WAIT, getTimer } from "../internal/function/timer.js";
|
|
3
|
+
var RetryError = class extends Error {
|
|
4
|
+
constructor(message, original) {
|
|
5
|
+
super(message);
|
|
6
|
+
this.original = original;
|
|
7
|
+
this.name = ERROR_NAME;
|
|
8
|
+
}
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Retry a callback a specified number of times, with a delay between attempts
|
|
12
|
+
* @param callback Callback to retry
|
|
13
|
+
* @param options Retry options
|
|
14
|
+
* @returns Callback result
|
|
15
|
+
*/
|
|
16
|
+
async function asyncRetry(callback, options) {
|
|
17
|
+
if (typeof callback !== "function") throw new TypeError(MESSAGE_EXPECTATION);
|
|
18
|
+
async function handle() {
|
|
19
|
+
try {
|
|
20
|
+
const result = await callback();
|
|
21
|
+
resolver(result);
|
|
22
|
+
} catch (error) {
|
|
23
|
+
if (attempts >= times || !when(error)) rejector(new RetryError(MESSAGE_FAILED, error));
|
|
24
|
+
else {
|
|
25
|
+
attempts += 1;
|
|
26
|
+
timer();
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
const { delay, times, when } = getRetryOptions(options);
|
|
31
|
+
const timer = getTimer(TIMER_WAIT, handle, delay);
|
|
32
|
+
let attempts = 0;
|
|
33
|
+
let rejector;
|
|
34
|
+
let resolver;
|
|
35
|
+
return new Promise((resolve, reject) => {
|
|
36
|
+
rejector = reject;
|
|
37
|
+
resolver = resolve;
|
|
38
|
+
handle();
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
function getRetryNumber(value) {
|
|
42
|
+
return typeof value === "number" && value > 0 ? value : 0;
|
|
43
|
+
}
|
|
44
|
+
function getRetryOptions(input) {
|
|
45
|
+
const options = isPlainObject(input) ? input : {};
|
|
46
|
+
return {
|
|
47
|
+
delay: getRetryNumber(options.delay),
|
|
48
|
+
times: getRetryNumber(options.times),
|
|
49
|
+
when: typeof options.when === "function" ? options.when : shouldRetry
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Retry a callback a specified number of times
|
|
54
|
+
* @param callback Callback to retry
|
|
55
|
+
* @param options Retry options
|
|
56
|
+
* @returns Callback result
|
|
57
|
+
*/
|
|
58
|
+
function retry(callback, options) {
|
|
59
|
+
if (typeof callback !== "function") throw new TypeError(MESSAGE_EXPECTATION);
|
|
60
|
+
const { times, when } = getRetryOptions(options);
|
|
61
|
+
let last;
|
|
62
|
+
for (let index = 0; index <= times; index += 1) try {
|
|
63
|
+
return callback();
|
|
64
|
+
} catch (error) {
|
|
65
|
+
if (index >= times || !when(error)) {
|
|
66
|
+
last = error;
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
throw new RetryError(MESSAGE_FAILED, last);
|
|
71
|
+
}
|
|
72
|
+
retry.async = asyncRetry;
|
|
73
|
+
function shouldRetry() {
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
76
|
+
var ERROR_NAME = "RetryError";
|
|
77
|
+
var MESSAGE_EXPECTATION = "Retry expected a function";
|
|
78
|
+
var MESSAGE_FAILED = "Retry failed";
|
|
79
|
+
export { RetryError, retry };
|
package/dist/index.js
CHANGED
|
@@ -39,6 +39,7 @@ import { getColor } from "./color/index.js";
|
|
|
39
39
|
import { SizedMap } from "./sized/map.js";
|
|
40
40
|
import { memoize } from "./function/memoize.js";
|
|
41
41
|
import { debounce, throttle } from "./function/index.js";
|
|
42
|
+
import { RetryError, retry } from "./function/retry.js";
|
|
42
43
|
import { isError, isOk, isResult } from "./internal/result.js";
|
|
43
44
|
import { flow, pipe } from "./function/work.js";
|
|
44
45
|
import { equal } from "./internal/value/equal.js";
|
|
@@ -70,4 +71,4 @@ import { QueueError, queue } from "./queue.js";
|
|
|
70
71
|
import { getRandomBoolean, getRandomCharacters, getRandomColor, getRandomHex, getRandomItem, getRandomItems } from "./random.js";
|
|
71
72
|
import { attempt } from "./result/index.js";
|
|
72
73
|
import { SizedSet } from "./sized/set.js";
|
|
73
|
-
export { CancelablePromise, PromiseTimeoutError, QueueError, SizedMap, SizedSet, attempt, attemptPromise, average, beacon, between, camelCase, cancelable, capitalize, ceil, chunk, clamp, clone, compact, compare, count, debounce, delay, diff, endsWith, equal, error, exists, filter, find, flatten, floor, flow, toResult as fromPromise, fromQuery, toPromise as fromResult, getArray, getColor, getForegroundColor, getHexColor, getHexaColor, getHslColor, getHslaColor, getNormalizedHex, getNumber, getRandomBoolean, getRandomCharacters, getRandomColor, getRandomFloat, getRandomHex, getRandomInteger, getRandomItem, getRandomItems, getRgbColor, getRgbaColor, getString, getUuid, getValue, groupBy, hexToHsl, hexToHsla, hexToRgb, hexToRgba, hslToHex, hslToRgb, hslToRgba, ignoreKey, includes, indexOf, insert, isArrayOrPlainObject, isColor, isConstructor, isEmpty, isError, isFulfilled, isHexColor, isHslColor, isHslLike, isHslaColor, isInstanceOf, isKey, isNonNullable, isNullable, isNullableOrEmpty, isNullableOrWhitespace, isNumber, isNumerical, isObject, isOk, isPlainObject, isPrimitive, isRejected, isResult, isRgbColor, isRgbLike, isRgbaColor, isTypedArray, join, kebabCase, logger, lowerCase, max, median, memoize, merge, min, noop, ok, omit, parse, partition, pascalCase, pick, pipe, promises, push, queue, range, rgbToHex, rgbToHsl, rgbToHsla, round, select, setValue, shuffle, smush, snakeCase, sort, splice, startsWith, sum, template, throttle, timed, times, titleCase, toMap, toPromise, toQuery, toRecord, toResult, toSet, toggle, trim, truncate, tryDecode, tryEncode, unique, unsmush, unwrap, update, upperCase, words };
|
|
74
|
+
export { CancelablePromise, PromiseTimeoutError, QueueError, RetryError, SizedMap, SizedSet, attempt, attemptPromise, average, beacon, between, camelCase, cancelable, capitalize, ceil, chunk, clamp, clone, compact, compare, count, debounce, delay, diff, endsWith, equal, error, exists, filter, find, flatten, floor, flow, toResult as fromPromise, fromQuery, toPromise as fromResult, getArray, getColor, getForegroundColor, getHexColor, getHexaColor, getHslColor, getHslaColor, getNormalizedHex, getNumber, getRandomBoolean, getRandomCharacters, getRandomColor, getRandomFloat, getRandomHex, getRandomInteger, getRandomItem, getRandomItems, getRgbColor, getRgbaColor, getString, getUuid, getValue, groupBy, hexToHsl, hexToHsla, hexToRgb, hexToRgba, hslToHex, hslToRgb, hslToRgba, ignoreKey, includes, indexOf, insert, isArrayOrPlainObject, isColor, isConstructor, isEmpty, isError, isFulfilled, isHexColor, isHslColor, isHslLike, isHslaColor, isInstanceOf, isKey, isNonNullable, isNullable, isNullableOrEmpty, isNullableOrWhitespace, isNumber, isNumerical, isObject, isOk, isPlainObject, isPrimitive, isRejected, isResult, isRgbColor, isRgbLike, isRgbaColor, isTypedArray, join, kebabCase, logger, lowerCase, max, median, memoize, merge, min, noop, ok, omit, parse, partition, pascalCase, pick, pipe, promises, push, queue, range, retry, rgbToHex, rgbToHsl, rgbToHsla, round, select, setValue, shuffle, smush, snakeCase, sort, splice, startsWith, sum, template, throttle, timed, times, titleCase, toMap, toPromise, toQuery, toRecord, toResult, toSet, toggle, trim, truncate, tryDecode, tryEncode, unique, unsmush, unwrap, update, upperCase, words };
|
package/package.json
CHANGED
|
@@ -54,6 +54,10 @@
|
|
|
54
54
|
"types": "./types/function/index.d.ts",
|
|
55
55
|
"default": "./dist/function/index.js"
|
|
56
56
|
},
|
|
57
|
+
"./function/retry": {
|
|
58
|
+
"types": "./types/function/retry.d.ts",
|
|
59
|
+
"default": "./dist/function/retry.js"
|
|
60
|
+
},
|
|
57
61
|
"./function/work": {
|
|
58
62
|
"types": "./types/function/work.d.ts",
|
|
59
63
|
"default": "./dist/function/work.js"
|
|
@@ -176,5 +180,5 @@
|
|
|
176
180
|
},
|
|
177
181
|
"type": "module",
|
|
178
182
|
"types": "./types/index.d.ts",
|
|
179
|
-
"version": "0.
|
|
183
|
+
"version": "0.153.0"
|
|
180
184
|
}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import {getTimer, TIMER_WAIT} from '../internal/function/timer';
|
|
2
|
+
import {isPlainObject} from '../internal/is';
|
|
3
|
+
import type {GenericAsyncCallback, GenericCallback} from '../models';
|
|
4
|
+
|
|
5
|
+
// #region Types
|
|
6
|
+
|
|
7
|
+
export class RetryError extends Error {
|
|
8
|
+
constructor(
|
|
9
|
+
message: string,
|
|
10
|
+
readonly original: unknown,
|
|
11
|
+
) {
|
|
12
|
+
super(message);
|
|
13
|
+
|
|
14
|
+
this.name = ERROR_NAME;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export type RetryOptions = {
|
|
19
|
+
delay?: number;
|
|
20
|
+
times?: number;
|
|
21
|
+
when?: (error: unknown) => boolean;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
// #endregion
|
|
25
|
+
|
|
26
|
+
// #region Functions
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Retry a callback a specified number of times, with a delay between attempts
|
|
30
|
+
* @param callback Callback to retry
|
|
31
|
+
* @param options Retry options
|
|
32
|
+
* @returns Callback result
|
|
33
|
+
*/
|
|
34
|
+
async function asyncRetry<Callback extends GenericAsyncCallback>(
|
|
35
|
+
callback: Callback,
|
|
36
|
+
options?: RetryOptions,
|
|
37
|
+
): Promise<Awaited<ReturnType<Callback>>>;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Retry a callback a specified number of times, with a delay between attempts
|
|
41
|
+
* @param callback Callback to retry
|
|
42
|
+
* @param options Retry options
|
|
43
|
+
* @returns Callback result
|
|
44
|
+
*/
|
|
45
|
+
async function asyncRetry<Callback extends GenericCallback>(
|
|
46
|
+
callback: Callback,
|
|
47
|
+
options?: RetryOptions,
|
|
48
|
+
): Promise<ReturnType<Callback>>;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Retry a callback a specified number of times, with a delay between attempts
|
|
52
|
+
* @param callback Callback to retry
|
|
53
|
+
* @param options Retry options
|
|
54
|
+
* @returns Callback result
|
|
55
|
+
*/
|
|
56
|
+
async function asyncRetry<Callback extends GenericCallback>(
|
|
57
|
+
callback: Callback,
|
|
58
|
+
options?: RetryOptions,
|
|
59
|
+
): Promise<ReturnType<Callback>> {
|
|
60
|
+
if (typeof callback !== 'function') {
|
|
61
|
+
throw new TypeError(MESSAGE_EXPECTATION);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
async function handle(): Promise<void> {
|
|
65
|
+
try {
|
|
66
|
+
const result = await callback();
|
|
67
|
+
|
|
68
|
+
resolver(result);
|
|
69
|
+
} catch (error) {
|
|
70
|
+
if (attempts >= times || !when(error)) {
|
|
71
|
+
rejector(new RetryError(MESSAGE_FAILED, error));
|
|
72
|
+
} else {
|
|
73
|
+
attempts += 1;
|
|
74
|
+
|
|
75
|
+
timer();
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const {delay, times, when} = getRetryOptions(options);
|
|
81
|
+
|
|
82
|
+
const timer = getTimer(TIMER_WAIT, handle, delay);
|
|
83
|
+
|
|
84
|
+
let attempts = 0;
|
|
85
|
+
|
|
86
|
+
let rejector: (reason?: unknown) => void;
|
|
87
|
+
let resolver: (value: Awaited<ReturnType<Callback>>) => void;
|
|
88
|
+
|
|
89
|
+
return new Promise<Awaited<ReturnType<Callback>>>((resolve, reject) => {
|
|
90
|
+
rejector = reject;
|
|
91
|
+
resolver = resolve;
|
|
92
|
+
|
|
93
|
+
handle();
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function getRetryNumber(value?: unknown): number {
|
|
98
|
+
return typeof value === 'number' && value > 0 ? value : 0;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function getRetryOptions(input?: RetryOptions): Required<RetryOptions> {
|
|
102
|
+
const options = isPlainObject(input) ? input : {};
|
|
103
|
+
|
|
104
|
+
return {
|
|
105
|
+
delay: getRetryNumber(options.delay),
|
|
106
|
+
times: getRetryNumber(options.times),
|
|
107
|
+
when: typeof options.when === 'function' ? options.when : shouldRetry,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Retry a callback a specified number of times
|
|
113
|
+
* @param callback Callback to retry
|
|
114
|
+
* @param options Retry options
|
|
115
|
+
* @returns Callback result
|
|
116
|
+
*/
|
|
117
|
+
export function retry<Callback extends GenericCallback>(
|
|
118
|
+
callback: Callback,
|
|
119
|
+
options?: Omit<RetryOptions, 'delay'>,
|
|
120
|
+
): ReturnType<Callback> {
|
|
121
|
+
if (typeof callback !== 'function') {
|
|
122
|
+
throw new TypeError(MESSAGE_EXPECTATION);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const {times, when} = getRetryOptions(options);
|
|
126
|
+
|
|
127
|
+
let last: unknown;
|
|
128
|
+
|
|
129
|
+
for (let index = 0; index <= times; index += 1) {
|
|
130
|
+
try {
|
|
131
|
+
const result = callback();
|
|
132
|
+
|
|
133
|
+
return result;
|
|
134
|
+
} catch (error) {
|
|
135
|
+
if (index >= times || !when(error)) {
|
|
136
|
+
last = error;
|
|
137
|
+
|
|
138
|
+
break;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
throw new RetryError(MESSAGE_FAILED, last);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
retry.async = asyncRetry;
|
|
147
|
+
|
|
148
|
+
function shouldRetry(): boolean {
|
|
149
|
+
return true;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// #endregion
|
|
153
|
+
|
|
154
|
+
// #region Variables
|
|
155
|
+
|
|
156
|
+
const ERROR_NAME = 'RetryError';
|
|
157
|
+
|
|
158
|
+
const MESSAGE_EXPECTATION = 'Retry expected a function';
|
|
159
|
+
|
|
160
|
+
const MESSAGE_FAILED = 'Retry failed';
|
|
161
|
+
|
|
162
|
+
// #endregion
|
package/src/index.ts
CHANGED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { GenericAsyncCallback, GenericCallback } from '../models';
|
|
2
|
+
export declare class RetryError extends Error {
|
|
3
|
+
readonly original: unknown;
|
|
4
|
+
constructor(message: string, original: unknown);
|
|
5
|
+
}
|
|
6
|
+
export type RetryOptions = {
|
|
7
|
+
delay?: number;
|
|
8
|
+
times?: number;
|
|
9
|
+
when?: (error: unknown) => boolean;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Retry a callback a specified number of times, with a delay between attempts
|
|
13
|
+
* @param callback Callback to retry
|
|
14
|
+
* @param options Retry options
|
|
15
|
+
* @returns Callback result
|
|
16
|
+
*/
|
|
17
|
+
declare function asyncRetry<Callback extends GenericAsyncCallback>(callback: Callback, options?: RetryOptions): Promise<Awaited<ReturnType<Callback>>>;
|
|
18
|
+
/**
|
|
19
|
+
* Retry a callback a specified number of times, with a delay between attempts
|
|
20
|
+
* @param callback Callback to retry
|
|
21
|
+
* @param options Retry options
|
|
22
|
+
* @returns Callback result
|
|
23
|
+
*/
|
|
24
|
+
declare function asyncRetry<Callback extends GenericCallback>(callback: Callback, options?: RetryOptions): Promise<ReturnType<Callback>>;
|
|
25
|
+
/**
|
|
26
|
+
* Retry a callback a specified number of times
|
|
27
|
+
* @param callback Callback to retry
|
|
28
|
+
* @param options Retry options
|
|
29
|
+
* @returns Callback result
|
|
30
|
+
*/
|
|
31
|
+
export declare function retry<Callback extends GenericCallback>(callback: Callback, options?: Omit<RetryOptions, 'delay'>): ReturnType<Callback>;
|
|
32
|
+
export declare namespace retry {
|
|
33
|
+
var async: typeof asyncRetry;
|
|
34
|
+
}
|
|
35
|
+
export {};
|
package/types/index.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ export * from './array/to-map';
|
|
|
4
4
|
export * from './array/to-record';
|
|
5
5
|
export * from './array/unique';
|
|
6
6
|
export * from './function/index';
|
|
7
|
+
export * from './function/retry';
|
|
7
8
|
export * from './function/work';
|
|
8
9
|
export * from './internal/function/misc';
|
|
9
10
|
export * from './internal/string';
|