@zap-studio/retry 0.3.1 → 1.0.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/CHANGELOG.md +55 -14
- package/README.md +87 -141
- package/dist/base-policy.d.ts +67 -0
- package/dist/base-policy.d.ts.map +1 -0
- package/dist/base-policy.js +306 -0
- package/dist/base-policy.js.map +1 -0
- package/dist/{errors-BVZjP1Q5.d.mts → errors-CS5UPJWs.d.ts} +25 -1
- package/dist/errors-CS5UPJWs.d.ts.map +1 -0
- package/dist/{errors.d.mts → errors.d.ts} +1 -1
- package/dist/{errors.mjs → errors.js} +19 -1
- package/dist/errors.js.map +1 -0
- package/dist/exponential-backoff.d.ts +40 -0
- package/dist/exponential-backoff.d.ts.map +1 -0
- package/dist/exponential-backoff.js +35 -0
- package/dist/exponential-backoff.js.map +1 -0
- package/dist/fixed-delay.d.ts +31 -0
- package/dist/fixed-delay.d.ts.map +1 -0
- package/dist/fixed-delay.js +33 -0
- package/dist/fixed-delay.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +6 -0
- package/dist/linear-backoff.d.ts +46 -0
- package/dist/linear-backoff.d.ts.map +1 -0
- package/dist/linear-backoff.js +35 -0
- package/dist/linear-backoff.js.map +1 -0
- package/dist/{types.d.mts → types.d.ts} +52 -8
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +0 -0
- package/package.json +12 -22
- package/dist/abort.d.mts +0 -29
- package/dist/abort.d.mts.map +0 -1
- package/dist/abort.mjs +0 -61
- package/dist/abort.mjs.map +0 -1
- package/dist/errors-BVZjP1Q5.d.mts.map +0 -1
- package/dist/errors.mjs.map +0 -1
- package/dist/exponential-backoff.d.mts +0 -55
- package/dist/exponential-backoff.d.mts.map +0 -1
- package/dist/exponential-backoff.mjs +0 -60
- package/dist/exponential-backoff.mjs.map +0 -1
- package/dist/fixed-delay.d.mts +0 -46
- package/dist/fixed-delay.d.mts.map +0 -1
- package/dist/fixed-delay.mjs +0 -53
- package/dist/fixed-delay.mjs.map +0 -1
- package/dist/index.d.mts +0 -59
- package/dist/index.d.mts.map +0 -1
- package/dist/index.mjs +0 -63
- package/dist/index.mjs.map +0 -1
- package/dist/result-mode.d.mts +0 -19
- package/dist/result-mode.d.mts.map +0 -1
- package/dist/result-mode.mjs +0 -145
- package/dist/result-mode.mjs.map +0 -1
- package/dist/sleep.d.mts +0 -17
- package/dist/sleep.d.mts.map +0 -1
- package/dist/sleep.mjs +0 -23
- package/dist/sleep.mjs.map +0 -1
- package/dist/throw-mode.d.mts +0 -21
- package/dist/throw-mode.d.mts.map +0 -1
- package/dist/throw-mode.mjs +0 -49
- package/dist/throw-mode.mjs.map +0 -1
- package/dist/types.d.mts.map +0 -1
- package/dist/types.mjs +0 -1
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { RetryPolicy } from "./types.js";
|
|
2
|
+
//#region src/linear-backoff.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* Configuration for `linearBackoff(...)`.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* const options: LinearBackoffOptions = {
|
|
8
|
+
* maxAttempts: 5,
|
|
9
|
+
* baseDelayMs: 100,
|
|
10
|
+
* incrementMs: 100,
|
|
11
|
+
* maxDelayMs: 2_000,
|
|
12
|
+
* };
|
|
13
|
+
*/
|
|
14
|
+
interface LinearBackoffOptions {
|
|
15
|
+
/**
|
|
16
|
+
* Maximum number of attempts (including the first) before giving up.
|
|
17
|
+
*/
|
|
18
|
+
maxAttempts: number;
|
|
19
|
+
/**
|
|
20
|
+
* Delay in milliseconds after the first failed attempt.
|
|
21
|
+
*/
|
|
22
|
+
baseDelayMs: number;
|
|
23
|
+
/**
|
|
24
|
+
* Amount added to the delay for each subsequent retry.
|
|
25
|
+
*/
|
|
26
|
+
incrementMs: number;
|
|
27
|
+
/**
|
|
28
|
+
* Hard upper bound in milliseconds for computed linear delay.
|
|
29
|
+
*/
|
|
30
|
+
maxDelayMs: number;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Creates a retry policy with linear delay growth up to a max cap.
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* const policy = linearBackoff({
|
|
37
|
+
* maxAttempts: 5,
|
|
38
|
+
* baseDelayMs: 100,
|
|
39
|
+
* incrementMs: 100,
|
|
40
|
+
* maxDelayMs: 2_000,
|
|
41
|
+
* });
|
|
42
|
+
*/
|
|
43
|
+
declare const linearBackoff: (options: LinearBackoffOptions) => RetryPolicy;
|
|
44
|
+
//#endregion
|
|
45
|
+
export { LinearBackoffOptions, linearBackoff };
|
|
46
|
+
//# sourceMappingURL=linear-backoff.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"linear-backoff.d.ts","names":[],"sources":["../src/linear-backoff.ts"],"mappings":";;;;;;;;;;;;;UAuBiB;;;;EAIf;;;;EAIA;;;;EAIA;;;;EAIA;;;;;;;;;;;;;cAcW,gBAAiB,SAAS,yBAAuB"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
//#region src/linear-backoff.ts
|
|
2
|
+
/**
|
|
3
|
+
* Creates a retry policy with linear delay growth up to a max cap.
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* const policy = linearBackoff({
|
|
7
|
+
* maxAttempts: 5,
|
|
8
|
+
* baseDelayMs: 100,
|
|
9
|
+
* incrementMs: 100,
|
|
10
|
+
* maxDelayMs: 2_000,
|
|
11
|
+
* });
|
|
12
|
+
*/
|
|
13
|
+
const linearBackoff = (options) => {
|
|
14
|
+
const { maxAttempts, baseDelayMs, incrementMs, maxDelayMs } = options;
|
|
15
|
+
return {
|
|
16
|
+
/**
|
|
17
|
+
* Computes retry decision for the current attempt.
|
|
18
|
+
*/
|
|
19
|
+
next(input) {
|
|
20
|
+
if (input.attempt >= maxAttempts) return {
|
|
21
|
+
delayMs: 0,
|
|
22
|
+
reason: "max-attempts-reached",
|
|
23
|
+
shouldRetry: false
|
|
24
|
+
};
|
|
25
|
+
return {
|
|
26
|
+
delayMs: Math.min(maxDelayMs, baseDelayMs + incrementMs * (input.attempt - 1)),
|
|
27
|
+
reason: "retry",
|
|
28
|
+
shouldRetry: true
|
|
29
|
+
};
|
|
30
|
+
} };
|
|
31
|
+
};
|
|
32
|
+
//#endregion
|
|
33
|
+
export { linearBackoff };
|
|
34
|
+
|
|
35
|
+
//# sourceMappingURL=linear-backoff.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"linear-backoff.js","names":[],"sources":["../src/linear-backoff.ts"],"sourcesContent":["/**\n * Linear backoff retry strategy.\n *\n * @module @zap-studio/retry/linear-backoff\n */\n\nimport type {\n RetryDecision,\n RetryDecisionInput,\n RetryPolicy,\n} from \"./types.js\";\n\n/**\n * Configuration for `linearBackoff(...)`.\n *\n * @example\n * const options: LinearBackoffOptions = {\n * maxAttempts: 5,\n * baseDelayMs: 100,\n * incrementMs: 100,\n * maxDelayMs: 2_000,\n * };\n */\nexport interface LinearBackoffOptions {\n /**\n * Maximum number of attempts (including the first) before giving up.\n */\n maxAttempts: number;\n /**\n * Delay in milliseconds after the first failed attempt.\n */\n baseDelayMs: number;\n /**\n * Amount added to the delay for each subsequent retry.\n */\n incrementMs: number;\n /**\n * Hard upper bound in milliseconds for computed linear delay.\n */\n maxDelayMs: number;\n}\n\n/**\n * Creates a retry policy with linear delay growth up to a max cap.\n *\n * @example\n * const policy = linearBackoff({\n * maxAttempts: 5,\n * baseDelayMs: 100,\n * incrementMs: 100,\n * maxDelayMs: 2_000,\n * });\n */\nexport const linearBackoff = (options: LinearBackoffOptions): RetryPolicy => {\n const { maxAttempts, baseDelayMs, incrementMs, maxDelayMs } = options;\n\n return {\n /**\n * Computes retry decision for the current attempt.\n */\n next(input: RetryDecisionInput): RetryDecision {\n if (input.attempt >= maxAttempts) {\n return {\n delayMs: 0,\n reason: \"max-attempts-reached\",\n shouldRetry: false,\n };\n }\n\n const delayMs = Math.min(\n maxDelayMs,\n baseDelayMs + incrementMs * (input.attempt - 1)\n );\n\n return { delayMs, reason: \"retry\", shouldRetry: true };\n },\n };\n};\n"],"mappings":";;;;;;;;;;;;AAqDA,MAAa,iBAAiB,YAA+C;CAC3E,MAAM,EAAE,aAAa,aAAa,aAAa,eAAe;CAE9D,OAAO;;;;AAIL,KAAK,OAA0C;EAC7C,IAAI,MAAM,WAAW,aACnB,OAAO;GACL,SAAS;GACT,QAAQ;GACR,aAAa;EACf;EAQF,OAAO;GAAE,SALO,KAAK,IACnB,YACA,cAAc,eAAe,MAAM,UAAU,EAGhC;GAAG,QAAQ;GAAS,aAAa;EAAK;CACvD,EACF;AACF"}
|
|
@@ -1,7 +1,11 @@
|
|
|
1
|
-
import { r as RetryError, t as AbortError } from "./errors-
|
|
1
|
+
import { r as RetryError, t as AbortError } from "./errors-CS5UPJWs.js";
|
|
2
2
|
//#region src/types.d.ts
|
|
3
3
|
/**
|
|
4
|
-
* Retry policy contract
|
|
4
|
+
* Retry policy contract consumed by `runRetryPolicy(...)`.
|
|
5
|
+
*
|
|
6
|
+
* Only `next` is required. `onExhausted` and `isKnownError` fall back to
|
|
7
|
+
* `runRetryPolicy`'s defaults when omitted, so a policy can be a plain
|
|
8
|
+
* object literal.
|
|
5
9
|
*
|
|
6
10
|
* @example
|
|
7
11
|
* const policy: RetryPolicy = {
|
|
@@ -9,7 +13,7 @@ import { r as RetryError, t as AbortError } from "./errors-BVZjP1Q5.mjs";
|
|
|
9
13
|
* onExhausted: ({ attempts }) => new RetryError("done", { attempts }),
|
|
10
14
|
* };
|
|
11
15
|
*/
|
|
12
|
-
interface RetryPolicy<TError =
|
|
16
|
+
interface RetryPolicy<TError extends Error = Error, TData = unknown> {
|
|
13
17
|
/**
|
|
14
18
|
* Returns the retry decision for a failed attempt.
|
|
15
19
|
*
|
|
@@ -19,12 +23,39 @@ interface RetryPolicy<TError = unknown, TData = unknown> {
|
|
|
19
23
|
/**
|
|
20
24
|
* Builds the terminal error used when retries are exhausted.
|
|
21
25
|
*
|
|
26
|
+
* Defaults to a `RetryError` built by `runRetryPolicy` when omitted.
|
|
27
|
+
*
|
|
22
28
|
* @throws {Error} Any error thrown by the policy implementation.
|
|
23
29
|
*/
|
|
30
|
+
onExhausted?: (input: RetryExhaustedInput<TError, TData>) => RetryError;
|
|
31
|
+
/**
|
|
32
|
+
* Narrows a caught `unknown` value into `TError`.
|
|
33
|
+
*
|
|
34
|
+
* The runner calls this before handing an error to `next`/`onExhausted`.
|
|
35
|
+
* When it returns `false`, the value is treated as outside this policy's
|
|
36
|
+
* error domain instead of a retryable failure — `runRetryPolicy(...)`
|
|
37
|
+
* rethrows it immediately in throw mode, or wraps it in a `RetryError` on
|
|
38
|
+
* `result.error` in non-throw mode. The default (used when omitted) checks
|
|
39
|
+
* `error instanceof Error`; supply your own when `TError` is a narrower
|
|
40
|
+
* subclass (e.g. a specific HTTP or domain error) to get real narrowing
|
|
41
|
+
* instead of an assumption.
|
|
42
|
+
*/
|
|
43
|
+
isKnownError?: (error: unknown) => error is TError;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* `RetryPolicy` with `onExhausted` and `isKnownError` resolved to concrete
|
|
47
|
+
* functions, used internally once `runRetryPolicy` has applied defaults.
|
|
48
|
+
*/
|
|
49
|
+
interface ResolvedRetryPolicy<TError extends Error, TData> {
|
|
50
|
+
next: RetryPolicy<TError, TData>["next"];
|
|
24
51
|
onExhausted: (input: RetryExhaustedInput<TError, TData>) => RetryError;
|
|
52
|
+
isKnownError: (error: unknown) => error is TError;
|
|
25
53
|
}
|
|
26
54
|
/**
|
|
27
55
|
* Decision returned by a retry policy for a specific attempt.
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* const decision: RetryDecision = { shouldRetry: true, delayMs: 200, reason: "retry" };
|
|
28
59
|
*/
|
|
29
60
|
interface RetryDecision {
|
|
30
61
|
/**
|
|
@@ -43,8 +74,11 @@ interface RetryDecision {
|
|
|
43
74
|
}
|
|
44
75
|
/**
|
|
45
76
|
* Input passed to `RetryPolicy.next(...)` for each failed attempt.
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* const input: RetryDecisionInput = { attempt: 2, error: new Error("timeout") };
|
|
46
80
|
*/
|
|
47
|
-
interface RetryDecisionInput<TError =
|
|
81
|
+
interface RetryDecisionInput<TError extends Error = Error, TData = unknown> {
|
|
48
82
|
/**
|
|
49
83
|
* One-based attempt number for the current failure.
|
|
50
84
|
*/
|
|
@@ -67,8 +101,11 @@ interface RetryDecisionInput<TError = unknown, TData = unknown> {
|
|
|
67
101
|
}
|
|
68
102
|
/**
|
|
69
103
|
* Input passed to `RetryPolicy.onExhausted(...)` when retries stop.
|
|
104
|
+
*
|
|
105
|
+
* @example
|
|
106
|
+
* const input: RetryExhaustedInput = { attempts: 5, error: new Error("timeout") };
|
|
70
107
|
*/
|
|
71
|
-
interface RetryExhaustedInput<TError =
|
|
108
|
+
interface RetryExhaustedInput<TError extends Error = Error, TData = unknown> {
|
|
72
109
|
/**
|
|
73
110
|
* Count of completed attempts that led to stopping retries.
|
|
74
111
|
*/
|
|
@@ -83,7 +120,10 @@ interface RetryExhaustedInput<TError = unknown, TData = unknown> {
|
|
|
83
120
|
readonly data?: TData;
|
|
84
121
|
}
|
|
85
122
|
/**
|
|
86
|
-
* Options for `
|
|
123
|
+
* Options for `runRetryPolicy(...)`.
|
|
124
|
+
*
|
|
125
|
+
* @example
|
|
126
|
+
* const options: RetryRunOptions = { throwOnExhausted: false, signal: controller.signal };
|
|
87
127
|
*/
|
|
88
128
|
interface RetryRunOptions {
|
|
89
129
|
/**
|
|
@@ -113,6 +153,10 @@ interface RetryRunOptions {
|
|
|
113
153
|
* - Success: `ok: true` with the resolved `value`.
|
|
114
154
|
* - Failure: `ok: false` with terminal `error` and completed `attempts` count
|
|
115
155
|
* (exhaustion or abort).
|
|
156
|
+
*
|
|
157
|
+
* @example
|
|
158
|
+
* const result: RetryRunResult<string> = await runRetryPolicy(policy, doWork, { throwOnExhausted: false });
|
|
159
|
+
* if (!result.ok) console.error(result.error);
|
|
116
160
|
*/
|
|
117
161
|
type RetryRunResult<T> = {
|
|
118
162
|
/**
|
|
@@ -139,5 +183,5 @@ type RetryRunResult<T> = {
|
|
|
139
183
|
attempts: number;
|
|
140
184
|
};
|
|
141
185
|
//#endregion
|
|
142
|
-
export { RetryDecision, RetryDecisionInput, RetryExhaustedInput, RetryPolicy, RetryRunOptions, RetryRunResult };
|
|
143
|
-
//# sourceMappingURL=types.d.
|
|
186
|
+
export { ResolvedRetryPolicy, RetryDecision, RetryDecisionInput, RetryExhaustedInput, RetryPolicy, RetryRunOptions, RetryRunResult };
|
|
187
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","names":[],"sources":["../src/types.ts"],"mappings":";;;;;;;;;;;;;;;UAqBiB,YAAY,eAAe,QAAQ,OAAO;;;;;;EAMzD,OAAO,OAAO,mBAAmB,QAAQ,WAAW;;;;;;;;EAQpD,eAAe,OAAO,oBAAoB,QAAQ,WAAW;;;;;;;;;;;;;EAa7D,gBAAgB,mBAAmB,SAAS;;;;;;UAO7B,oBAAoB,eAAe,OAAO;EACzD,MAAM,YAAY,QAAQ;EAC1B,cAAc,OAAO,oBAAoB,QAAQ,WAAW;EAC5D,eAAe,mBAAmB,SAAS;;;;;;;;UAS5B;;;;;WAKN;;;;WAIA;;;;WAIA;;;;;;;;UASM,mBACf,eAAe,QAAQ,OACvB;;;;WAKS;;;;;WAKA;;;;;WAKA,QAAQ;;;;;WAKR,OAAO;;;;;;;;UASD,oBACf,eAAe,QAAQ,OACvB;;;;WAKS;;;;WAIA,QAAQ;;;;WAIR,OAAO;;;;;;;;UASD;;;;;;WAMN,SAAS,oBAAoB;;;;;;WAM7B,SAAS;;;;;;;;WAQT;;;;;;;;;;;;;KAcC,eAAe;;;;EAKrB;;;;EAIA,OAAO;;;;;EAMP;;;;;EAKA,OAAO,aAAa;;;;EAIpB"}
|
package/dist/types.js
ADDED
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zap-studio/retry",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"private": false,
|
|
5
|
-
"description": "Composable retry policies for resilient async operations.",
|
|
5
|
+
"description": "Composable, tree-shakeable retry policies for resilient async operations.",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"backoff",
|
|
8
8
|
"exponential backoff",
|
|
9
9
|
"fetch",
|
|
10
10
|
"http",
|
|
11
|
+
"linear backoff",
|
|
11
12
|
"resilience",
|
|
12
13
|
"retry",
|
|
13
14
|
"typescript"
|
|
@@ -27,38 +28,27 @@
|
|
|
27
28
|
],
|
|
28
29
|
"type": "module",
|
|
29
30
|
"sideEffects": false,
|
|
30
|
-
"types": "./dist/index.d.
|
|
31
|
+
"types": "./dist/index.d.ts",
|
|
31
32
|
"exports": {
|
|
32
|
-
".": "./dist/index.
|
|
33
|
-
"./
|
|
34
|
-
"./errors": "./dist/errors.
|
|
35
|
-
"./exponential-backoff": "./dist/exponential-backoff.
|
|
36
|
-
"./fixed-delay": "./dist/fixed-delay.
|
|
37
|
-
"./
|
|
38
|
-
"./
|
|
39
|
-
"./throw-mode": "./dist/throw-mode.mjs",
|
|
40
|
-
"./types": "./dist/types.mjs",
|
|
33
|
+
".": "./dist/index.js",
|
|
34
|
+
"./base-policy": "./dist/base-policy.js",
|
|
35
|
+
"./errors": "./dist/errors.js",
|
|
36
|
+
"./exponential-backoff": "./dist/exponential-backoff.js",
|
|
37
|
+
"./fixed-delay": "./dist/fixed-delay.js",
|
|
38
|
+
"./linear-backoff": "./dist/linear-backoff.js",
|
|
39
|
+
"./types": "./dist/types.js",
|
|
41
40
|
"./package.json": "./package.json"
|
|
42
41
|
},
|
|
43
42
|
"publishConfig": {
|
|
44
43
|
"access": "public"
|
|
45
44
|
},
|
|
46
45
|
"devDependencies": {
|
|
47
|
-
"
|
|
48
|
-
"@types/promise-retry": "^1.1.6",
|
|
49
|
-
"async-retry": "^1.3.3",
|
|
50
|
-
"exponential-backoff": "^3.1.3",
|
|
51
|
-
"p-retry": "^8.0.0",
|
|
52
|
-
"promise-retry": "^2.0.1",
|
|
53
|
-
"tsdown": "^0.22.4",
|
|
46
|
+
"tsdown": "^0.22.14",
|
|
54
47
|
"typescript": "^7.0.2",
|
|
55
48
|
"vitest": "^4.1.10",
|
|
56
49
|
"@zap-studio/typescript": "0.0.0"
|
|
57
50
|
},
|
|
58
51
|
"engines": {
|
|
59
52
|
"node": ">=18.0.0"
|
|
60
|
-
},
|
|
61
|
-
"scripts": {
|
|
62
|
-
"build": "tsdown --config ./tsdown.config.ts"
|
|
63
53
|
}
|
|
64
54
|
}
|
package/dist/abort.d.mts
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { t as AbortError } from "./errors-BVZjP1Q5.mjs";
|
|
2
|
-
//#region src/abort.d.ts
|
|
3
|
-
/**
|
|
4
|
-
* Throws when the provided abort signal is already aborted.
|
|
5
|
-
*
|
|
6
|
-
* @param signal - Optional abort signal to inspect.
|
|
7
|
-
* @throws {AbortError} When the signal is aborted.
|
|
8
|
-
*/
|
|
9
|
-
declare const toAbortError: (reason: unknown) => AbortError;
|
|
10
|
-
/**
|
|
11
|
-
* Throws when the provided abort signal is already aborted.
|
|
12
|
-
*
|
|
13
|
-
* @param signal - Optional abort signal to inspect.
|
|
14
|
-
* @throws {AbortError} When the signal is aborted.
|
|
15
|
-
*/
|
|
16
|
-
declare const throwIfAborted: (signal?: AbortSignal) => void;
|
|
17
|
-
/**
|
|
18
|
-
* Waits for delay sleep while observing cancellation through an abort signal.
|
|
19
|
-
*
|
|
20
|
-
* @param sleep - Sleep function used to await `delayMs`.
|
|
21
|
-
* @param delayMs - Delay duration in milliseconds.
|
|
22
|
-
* @param signal - Abort signal to observe while waiting.
|
|
23
|
-
* @returns Promise that resolves when delay finishes.
|
|
24
|
-
* @throws {AbortError} When the signal aborts before or during wait.
|
|
25
|
-
*/
|
|
26
|
-
declare const sleepWithAbortSignal: (sleep: (delayMs: number) => Promise<void>, delayMs: number, signal: AbortSignal) => Promise<void>;
|
|
27
|
-
//#endregion
|
|
28
|
-
export { sleepWithAbortSignal, throwIfAborted, toAbortError };
|
|
29
|
-
//# sourceMappingURL=abort.d.mts.map
|
package/dist/abort.d.mts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"abort.d.mts","names":[],"sources":["../src/abort.ts"],"mappings":";;;;;;;;cAca,eAAgB,oBAAkB;;;;;;;cA8BlC,iBAAkB,SAAS;;;;;;;;;;cAiB3B,uBACX,QAAQ,oBAAoB,eAC5B,iBACA,QAAQ,gBACP"}
|
package/dist/abort.mjs
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import { AbortError } from "./errors.mjs";
|
|
2
|
-
//#region src/abort.ts
|
|
3
|
-
/**
|
|
4
|
-
* Abort-signal helpers for retry orchestration internals.
|
|
5
|
-
*
|
|
6
|
-
* @module @zap-studio/retry/abort
|
|
7
|
-
*/
|
|
8
|
-
/**
|
|
9
|
-
* Throws when the provided abort signal is already aborted.
|
|
10
|
-
*
|
|
11
|
-
* @param signal - Optional abort signal to inspect.
|
|
12
|
-
* @throws {AbortError} When the signal is aborted.
|
|
13
|
-
*/
|
|
14
|
-
const toAbortError = (reason) => {
|
|
15
|
-
if (reason instanceof AbortError) return reason;
|
|
16
|
-
if (reason instanceof Error) return new AbortError(reason.message, { cause: reason });
|
|
17
|
-
if (typeof reason === "string" && reason.length > 0) return new AbortError(reason);
|
|
18
|
-
if (reason === void 0) return new AbortError("Retry aborted.");
|
|
19
|
-
try {
|
|
20
|
-
return new AbortError(`Retry aborted: ${JSON.stringify(reason)}`);
|
|
21
|
-
} catch {
|
|
22
|
-
return new AbortError("Retry aborted.");
|
|
23
|
-
}
|
|
24
|
-
};
|
|
25
|
-
/**
|
|
26
|
-
* Throws when the provided abort signal is already aborted.
|
|
27
|
-
*
|
|
28
|
-
* @param signal - Optional abort signal to inspect.
|
|
29
|
-
* @throws {AbortError} When the signal is aborted.
|
|
30
|
-
*/
|
|
31
|
-
const throwIfAborted = (signal) => {
|
|
32
|
-
if (signal?.aborted !== true) return;
|
|
33
|
-
throw toAbortError(signal.reason);
|
|
34
|
-
};
|
|
35
|
-
/**
|
|
36
|
-
* Waits for delay sleep while observing cancellation through an abort signal.
|
|
37
|
-
*
|
|
38
|
-
* @param sleep - Sleep function used to await `delayMs`.
|
|
39
|
-
* @param delayMs - Delay duration in milliseconds.
|
|
40
|
-
* @param signal - Abort signal to observe while waiting.
|
|
41
|
-
* @returns Promise that resolves when delay finishes.
|
|
42
|
-
* @throws {AbortError} When the signal aborts before or during wait.
|
|
43
|
-
*/
|
|
44
|
-
const sleepWithAbortSignal = async (sleep, delayMs, signal) => {
|
|
45
|
-
if (signal.aborted) throw toAbortError(signal.reason);
|
|
46
|
-
let onAbort;
|
|
47
|
-
try {
|
|
48
|
-
await Promise.race([sleep(delayMs), new Promise((_resolve, reject) => {
|
|
49
|
-
onAbort = () => {
|
|
50
|
-
reject(toAbortError(signal.reason));
|
|
51
|
-
};
|
|
52
|
-
signal.addEventListener("abort", onAbort, { once: true });
|
|
53
|
-
})]);
|
|
54
|
-
} finally {
|
|
55
|
-
if (onAbort) signal.removeEventListener("abort", onAbort);
|
|
56
|
-
}
|
|
57
|
-
};
|
|
58
|
-
//#endregion
|
|
59
|
-
export { sleepWithAbortSignal, throwIfAborted, toAbortError };
|
|
60
|
-
|
|
61
|
-
//# sourceMappingURL=abort.mjs.map
|
package/dist/abort.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"abort.mjs","names":[],"sources":["../src/abort.ts"],"sourcesContent":["/**\n * Abort-signal helpers for retry orchestration internals.\n *\n * @module @zap-studio/retry/abort\n */\n\nimport { AbortError } from \"./errors.js\";\n\n/**\n * Throws when the provided abort signal is already aborted.\n *\n * @param signal - Optional abort signal to inspect.\n * @throws {AbortError} When the signal is aborted.\n */\nexport const toAbortError = (reason: unknown): AbortError => {\n if (reason instanceof AbortError) {\n return reason;\n }\n\n if (reason instanceof Error) {\n return new AbortError(reason.message, { cause: reason });\n }\n\n if (typeof reason === \"string\" && reason.length > 0) {\n return new AbortError(reason);\n }\n\n if (reason === undefined) {\n return new AbortError(\"Retry aborted.\");\n }\n\n try {\n return new AbortError(`Retry aborted: ${JSON.stringify(reason)}`);\n } catch {\n return new AbortError(\"Retry aborted.\");\n }\n};\n\n/**\n * Throws when the provided abort signal is already aborted.\n *\n * @param signal - Optional abort signal to inspect.\n * @throws {AbortError} When the signal is aborted.\n */\nexport const throwIfAborted = (signal?: AbortSignal): void => {\n if (signal?.aborted !== true) {\n return;\n }\n\n throw toAbortError(signal.reason);\n};\n\n/**\n * Waits for delay sleep while observing cancellation through an abort signal.\n *\n * @param sleep - Sleep function used to await `delayMs`.\n * @param delayMs - Delay duration in milliseconds.\n * @param signal - Abort signal to observe while waiting.\n * @returns Promise that resolves when delay finishes.\n * @throws {AbortError} When the signal aborts before or during wait.\n */\nexport const sleepWithAbortSignal = async (\n sleep: (delayMs: number) => Promise<void>,\n delayMs: number,\n signal: AbortSignal\n): Promise<void> => {\n if (signal.aborted) {\n throw toAbortError(signal.reason);\n }\n\n let onAbort: (() => void) | undefined;\n\n try {\n await Promise.race([\n sleep(delayMs),\n // oxlint-disable-next-line promise/avoid-new -- AbortSignal callback is adapted into the race promise.\n new Promise<never>((_resolve, reject) => {\n onAbort = (): void => {\n reject(toAbortError(signal.reason));\n };\n\n signal.addEventListener(\"abort\", onAbort, { once: true });\n }),\n ]);\n } finally {\n if (onAbort) {\n signal.removeEventListener(\"abort\", onAbort);\n }\n }\n};\n"],"mappings":";;;;;;;;;;;;;AAcA,MAAa,gBAAgB,WAAgC;CAC3D,IAAI,kBAAkB,YACpB,OAAO;CAGT,IAAI,kBAAkB,OACpB,OAAO,IAAI,WAAW,OAAO,SAAS,EAAE,OAAO,OAAO,CAAC;CAGzD,IAAI,OAAO,WAAW,YAAY,OAAO,SAAS,GAChD,OAAO,IAAI,WAAW,MAAM;CAG9B,IAAI,WAAW,KAAA,GACb,OAAO,IAAI,WAAW,gBAAgB;CAGxC,IAAI;EACF,OAAO,IAAI,WAAW,kBAAkB,KAAK,UAAU,MAAM,GAAG;CAClE,QAAQ;EACN,OAAO,IAAI,WAAW,gBAAgB;CACxC;AACF;;;;;;;AAQA,MAAa,kBAAkB,WAA+B;CAC5D,IAAI,QAAQ,YAAY,MACtB;CAGF,MAAM,aAAa,OAAO,MAAM;AAClC;;;;;;;;;;AAWA,MAAa,uBAAuB,OAClC,OACA,SACA,WACkB;CAClB,IAAI,OAAO,SACT,MAAM,aAAa,OAAO,MAAM;CAGlC,IAAI;CAEJ,IAAI;EACF,MAAM,QAAQ,KAAK,CACjB,MAAM,OAAO,GAEb,IAAI,SAAgB,UAAU,WAAW;GACvC,gBAAsB;IACpB,OAAO,aAAa,OAAO,MAAM,CAAC;GACpC;GAEA,OAAO,iBAAiB,SAAS,SAAS,EAAE,MAAM,KAAK,CAAC;EAC1D,CAAC,CACH,CAAC;CACH,UAAU;EACR,IAAI,SACF,OAAO,oBAAoB,SAAS,OAAO;CAE/C;AACF"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"errors-BVZjP1Q5.d.mts","names":[],"sources":["../src/errors.ts"],"mappings":";;;;;;;;;UAWiB;;;;WAIN;;;;WAIA;;;;WAIA;;;;;UAMM;;;;WAIN;;;;;;;;;;;cAYE,mBAAmB;;;;WAId;;;;WAIA;;;;WAIA;;;;EAKhB,YAAY,iBAAiB,SAAS;;;;;cAY3B,mBAAmB;;;;oBAIL;;;;;EAMzB,YAAY,iBAAiB,UAAS"}
|
package/dist/errors.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"errors.mjs","names":[],"sources":["../src/errors.ts"],"sourcesContent":["// oxlint-disable max-classes-per-file -- Public retry error types are intentionally colocated.\n\n/**\n * Terminal error types used by retry policies and runners.\n *\n * @module @zap-studio/retry/errors\n */\n\n/**\n * Context payload attached to `RetryError`.\n */\nexport interface RetryErrorContext {\n /**\n * Count of completed attempts at exhaustion.\n */\n readonly attempts: number;\n /**\n * The last error object raised by a failed `execute` attempt.\n */\n readonly lastError?: unknown;\n /**\n * Optional data captured from the last attempt when provided by a policy.\n */\n readonly lastData?: unknown;\n}\n\n/**\n * Context payload attached to `AbortError`.\n */\nexport interface AbortErrorContext {\n /**\n * When the abort `reason` was an `Error`, the optional wrapped cause.\n */\n readonly cause?: unknown;\n}\n\n/**\n * Error thrown when retries are exhausted.\n *\n * @example\n * throw new RetryError(\"Retry exhausted\", {\n * attempts: 3,\n * lastError: new Error(\"network\"),\n * });\n */\nexport class RetryError extends Error {\n /**\n * Total attempts performed before exhaustion.\n */\n public readonly attempts: number;\n /**\n * Last captured error from execution.\n */\n public readonly lastError?: unknown;\n /**\n * Last captured data value, when available.\n */\n public readonly lastData?: unknown;\n\n /**\n * Creates a RetryError with structured terminal context.\n */\n constructor(message: string, context: RetryErrorContext) {\n super(message);\n this.name = \"RetryError\";\n this.attempts = context.attempts;\n this.lastError = context.lastError;\n this.lastData = context.lastData;\n }\n}\n\n/**\n * Error thrown when retry orchestration is canceled through `AbortSignal`.\n */\nexport class AbortError extends Error {\n /**\n * Optional wrapped cause when the native abort `reason` was an `Error`.\n */\n public override readonly cause?: unknown;\n\n /**\n * @param message - Human-readable abort description.\n * @param context - Optional `cause` link for diagnostic chaining.\n */\n constructor(message: string, context: AbortErrorContext = {}) {\n super(message);\n this.name = \"AbortError\";\n this.cause = context.cause;\n }\n}\n"],"mappings":";;;;;;;;;;AA6CA,IAAa,aAAb,cAAgC,MAAM;;;;CAIpC;;;;CAIA;;;;CAIA;;;;CAKA,YAAY,SAAiB,SAA4B;EACvD,MAAM,OAAO;EACb,KAAK,OAAO;EACZ,KAAK,WAAW,QAAQ;EACxB,KAAK,YAAY,QAAQ;EACzB,KAAK,WAAW,QAAQ;CAC1B;AACF;;;;AAKA,IAAa,aAAb,cAAgC,MAAM;;;;CAIpC;;;;;CAMA,YAAY,SAAiB,UAA6B,CAAC,GAAG;EAC5D,MAAM,OAAO;EACb,KAAK,OAAO;EACZ,KAAK,QAAQ,QAAQ;CACvB;AACF"}
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import { RetryDecision, RetryDecisionInput } from "./types.mjs";
|
|
2
|
-
import { BaseRetryPolicy } from "./index.mjs";
|
|
3
|
-
//#region src/exponential-backoff.d.ts
|
|
4
|
-
/**
|
|
5
|
-
* Configuration for `ExponentialBackoff`.
|
|
6
|
-
*/
|
|
7
|
-
interface ExponentialBackoffOptions {
|
|
8
|
-
/**
|
|
9
|
-
* Maximum number of attempts (including the first) before giving up.
|
|
10
|
-
*/
|
|
11
|
-
maxAttempts: number;
|
|
12
|
-
/**
|
|
13
|
-
* Initial delay in milliseconds, doubled each retry until capped.
|
|
14
|
-
*/
|
|
15
|
-
baseDelayMs: number;
|
|
16
|
-
/**
|
|
17
|
-
* Hard upper bound in milliseconds for computed exponential delay.
|
|
18
|
-
*/
|
|
19
|
-
maxDelayMs: number;
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Retries with exponential delay growth up to a max cap.
|
|
23
|
-
*
|
|
24
|
-
* @example
|
|
25
|
-
* const policy = new ExponentialBackoff({
|
|
26
|
-
* maxAttempts: 5,
|
|
27
|
-
* baseDelayMs: 100,
|
|
28
|
-
* maxDelayMs: 2_000,
|
|
29
|
-
* });
|
|
30
|
-
*/
|
|
31
|
-
declare class ExponentialBackoff extends BaseRetryPolicy {
|
|
32
|
-
/**
|
|
33
|
-
* Maximum number of attempts before the policy returns `max-attempts-reached`.
|
|
34
|
-
*/
|
|
35
|
-
private readonly maxAttempts;
|
|
36
|
-
/**
|
|
37
|
-
* Base delay in milliseconds used in `baseDelayMs * 2 ** (attempt - 1)`.
|
|
38
|
-
*/
|
|
39
|
-
private readonly baseDelayMs;
|
|
40
|
-
/**
|
|
41
|
-
* Upper cap for computed delay, applied with `Math.min`.
|
|
42
|
-
*/
|
|
43
|
-
private readonly maxDelayMs;
|
|
44
|
-
/**
|
|
45
|
-
* Creates an exponential backoff retry policy.
|
|
46
|
-
*/
|
|
47
|
-
constructor(options: ExponentialBackoffOptions);
|
|
48
|
-
/**
|
|
49
|
-
* Computes retry decision for the current attempt.
|
|
50
|
-
*/
|
|
51
|
-
next(input: RetryDecisionInput): RetryDecision;
|
|
52
|
-
}
|
|
53
|
-
//#endregion
|
|
54
|
-
export { ExponentialBackoff, ExponentialBackoffOptions };
|
|
55
|
-
//# sourceMappingURL=exponential-backoff.d.mts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"exponential-backoff.d.mts","names":[],"sources":["../src/exponential-backoff.ts"],"mappings":";;;;;;UAYiB;;;;EAIf;;;;EAIA;;;;EAIA;;;;;;;;;;;;cAaW,2BAA2B;;;;mBAIrB;;;;mBAIA;;;;mBAIA;;;;EAKjB,YAAY,SAAS;;;;EAUrB,KAAY,OAAO,qBAAqB"}
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { BaseRetryPolicy } from "./index.mjs";
|
|
2
|
-
//#region src/exponential-backoff.ts
|
|
3
|
-
/**
|
|
4
|
-
* Exponential backoff retry strategy.
|
|
5
|
-
*
|
|
6
|
-
* @module @zap-studio/retry/exponential-backoff
|
|
7
|
-
*/
|
|
8
|
-
/**
|
|
9
|
-
* Retries with exponential delay growth up to a max cap.
|
|
10
|
-
*
|
|
11
|
-
* @example
|
|
12
|
-
* const policy = new ExponentialBackoff({
|
|
13
|
-
* maxAttempts: 5,
|
|
14
|
-
* baseDelayMs: 100,
|
|
15
|
-
* maxDelayMs: 2_000,
|
|
16
|
-
* });
|
|
17
|
-
*/
|
|
18
|
-
var ExponentialBackoff = class extends BaseRetryPolicy {
|
|
19
|
-
/**
|
|
20
|
-
* Maximum number of attempts before the policy returns `max-attempts-reached`.
|
|
21
|
-
*/
|
|
22
|
-
maxAttempts;
|
|
23
|
-
/**
|
|
24
|
-
* Base delay in milliseconds used in `baseDelayMs * 2 ** (attempt - 1)`.
|
|
25
|
-
*/
|
|
26
|
-
baseDelayMs;
|
|
27
|
-
/**
|
|
28
|
-
* Upper cap for computed delay, applied with `Math.min`.
|
|
29
|
-
*/
|
|
30
|
-
maxDelayMs;
|
|
31
|
-
/**
|
|
32
|
-
* Creates an exponential backoff retry policy.
|
|
33
|
-
*/
|
|
34
|
-
constructor(options) {
|
|
35
|
-
super();
|
|
36
|
-
this.maxAttempts = options.maxAttempts;
|
|
37
|
-
this.baseDelayMs = options.baseDelayMs;
|
|
38
|
-
this.maxDelayMs = options.maxDelayMs;
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Computes retry decision for the current attempt.
|
|
42
|
-
*/
|
|
43
|
-
next(input) {
|
|
44
|
-
if (input.attempt >= this.maxAttempts) return {
|
|
45
|
-
delayMs: 0,
|
|
46
|
-
reason: "max-attempts-reached",
|
|
47
|
-
shouldRetry: false
|
|
48
|
-
};
|
|
49
|
-
const exponent = Math.max(0, input.attempt - 1);
|
|
50
|
-
return {
|
|
51
|
-
delayMs: Math.min(this.maxDelayMs, this.baseDelayMs * 2 ** exponent),
|
|
52
|
-
reason: "retry",
|
|
53
|
-
shouldRetry: true
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
|
-
};
|
|
57
|
-
//#endregion
|
|
58
|
-
export { ExponentialBackoff };
|
|
59
|
-
|
|
60
|
-
//# sourceMappingURL=exponential-backoff.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"exponential-backoff.mjs","names":[],"sources":["../src/exponential-backoff.ts"],"sourcesContent":["/**\n * Exponential backoff retry strategy.\n *\n * @module @zap-studio/retry/exponential-backoff\n */\n\nimport { BaseRetryPolicy } from \"./index.js\";\nimport type { RetryDecision, RetryDecisionInput } from \"./types.js\";\n\n/**\n * Configuration for `ExponentialBackoff`.\n */\nexport interface ExponentialBackoffOptions {\n /**\n * Maximum number of attempts (including the first) before giving up.\n */\n maxAttempts: number;\n /**\n * Initial delay in milliseconds, doubled each retry until capped.\n */\n baseDelayMs: number;\n /**\n * Hard upper bound in milliseconds for computed exponential delay.\n */\n maxDelayMs: number;\n}\n\n/**\n * Retries with exponential delay growth up to a max cap.\n *\n * @example\n * const policy = new ExponentialBackoff({\n * maxAttempts: 5,\n * baseDelayMs: 100,\n * maxDelayMs: 2_000,\n * });\n */\nexport class ExponentialBackoff extends BaseRetryPolicy {\n /**\n * Maximum number of attempts before the policy returns `max-attempts-reached`.\n */\n private readonly maxAttempts: number;\n /**\n * Base delay in milliseconds used in `baseDelayMs * 2 ** (attempt - 1)`.\n */\n private readonly baseDelayMs: number;\n /**\n * Upper cap for computed delay, applied with `Math.min`.\n */\n private readonly maxDelayMs: number;\n\n /**\n * Creates an exponential backoff retry policy.\n */\n constructor(options: ExponentialBackoffOptions) {\n super();\n this.maxAttempts = options.maxAttempts;\n this.baseDelayMs = options.baseDelayMs;\n this.maxDelayMs = options.maxDelayMs;\n }\n\n /**\n * Computes retry decision for the current attempt.\n */\n public next(input: RetryDecisionInput): RetryDecision {\n if (input.attempt >= this.maxAttempts) {\n return { delayMs: 0, reason: \"max-attempts-reached\", shouldRetry: false };\n }\n\n const exponent = Math.max(0, input.attempt - 1);\n const delayMs = Math.min(this.maxDelayMs, this.baseDelayMs * 2 ** exponent);\n\n return { delayMs, reason: \"retry\", shouldRetry: true };\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAqCA,IAAa,qBAAb,cAAwC,gBAAgB;;;;CAItD;;;;CAIA;;;;CAIA;;;;CAKA,YAAY,SAAoC;EAC9C,MAAM;EACN,KAAK,cAAc,QAAQ;EAC3B,KAAK,cAAc,QAAQ;EAC3B,KAAK,aAAa,QAAQ;CAC5B;;;;CAKA,KAAY,OAA0C;EACpD,IAAI,MAAM,WAAW,KAAK,aACxB,OAAO;GAAE,SAAS;GAAG,QAAQ;GAAwB,aAAa;EAAM;EAG1E,MAAM,WAAW,KAAK,IAAI,GAAG,MAAM,UAAU,CAAC;EAG9C,OAAO;GAAE,SAFO,KAAK,IAAI,KAAK,YAAY,KAAK,cAAc,KAAK,QAEnD;GAAG,QAAQ;GAAS,aAAa;EAAK;CACvD;AACF"}
|
package/dist/fixed-delay.d.mts
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { RetryDecision, RetryDecisionInput } from "./types.mjs";
|
|
2
|
-
import { BaseRetryPolicy } from "./index.mjs";
|
|
3
|
-
//#region src/fixed-delay.d.ts
|
|
4
|
-
/**
|
|
5
|
-
* Configuration for `FixedDelay`.
|
|
6
|
-
*/
|
|
7
|
-
interface FixedDelayOptions {
|
|
8
|
-
/**
|
|
9
|
-
* Maximum number of attempts (including the first) before giving up.
|
|
10
|
-
*/
|
|
11
|
-
maxAttempts: number;
|
|
12
|
-
/**
|
|
13
|
-
* Constant delay in milliseconds before each retry after a failure.
|
|
14
|
-
*/
|
|
15
|
-
delayMs: number;
|
|
16
|
-
}
|
|
17
|
-
/**
|
|
18
|
-
* Retries with a constant delay between attempts.
|
|
19
|
-
*
|
|
20
|
-
* @example
|
|
21
|
-
* const policy = new FixedDelay({
|
|
22
|
-
* maxAttempts: 3,
|
|
23
|
-
* delayMs: 250,
|
|
24
|
-
* });
|
|
25
|
-
*/
|
|
26
|
-
declare class FixedDelay extends BaseRetryPolicy {
|
|
27
|
-
/**
|
|
28
|
-
* Maximum number of attempts before the policy returns `max-attempts-reached`.
|
|
29
|
-
*/
|
|
30
|
-
private readonly maxAttempts;
|
|
31
|
-
/**
|
|
32
|
-
* Constant delay in milliseconds before each subsequent attempt.
|
|
33
|
-
*/
|
|
34
|
-
private readonly delayMs;
|
|
35
|
-
/**
|
|
36
|
-
* Creates a fixed-delay retry policy.
|
|
37
|
-
*/
|
|
38
|
-
constructor(options: FixedDelayOptions);
|
|
39
|
-
/**
|
|
40
|
-
* Computes retry decision for the current attempt.
|
|
41
|
-
*/
|
|
42
|
-
next(input: RetryDecisionInput): RetryDecision;
|
|
43
|
-
}
|
|
44
|
-
//#endregion
|
|
45
|
-
export { FixedDelay, FixedDelayOptions };
|
|
46
|
-
//# sourceMappingURL=fixed-delay.d.mts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"fixed-delay.d.mts","names":[],"sources":["../src/fixed-delay.ts"],"mappings":";;;;;;UAYiB;;;;EAIf;;;;EAIA;;;;;;;;;;;cAYW,mBAAmB;;;;mBAIb;;;;mBAIA;;;;EAKjB,YAAY,SAAS;;;;EASrB,KAAY,OAAO,qBAAqB"}
|
package/dist/fixed-delay.mjs
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import { BaseRetryPolicy } from "./index.mjs";
|
|
2
|
-
//#region src/fixed-delay.ts
|
|
3
|
-
/**
|
|
4
|
-
* Fixed-delay retry strategy.
|
|
5
|
-
*
|
|
6
|
-
* @module @zap-studio/retry/fixed-delay
|
|
7
|
-
*/
|
|
8
|
-
/**
|
|
9
|
-
* Retries with a constant delay between attempts.
|
|
10
|
-
*
|
|
11
|
-
* @example
|
|
12
|
-
* const policy = new FixedDelay({
|
|
13
|
-
* maxAttempts: 3,
|
|
14
|
-
* delayMs: 250,
|
|
15
|
-
* });
|
|
16
|
-
*/
|
|
17
|
-
var FixedDelay = class extends BaseRetryPolicy {
|
|
18
|
-
/**
|
|
19
|
-
* Maximum number of attempts before the policy returns `max-attempts-reached`.
|
|
20
|
-
*/
|
|
21
|
-
maxAttempts;
|
|
22
|
-
/**
|
|
23
|
-
* Constant delay in milliseconds before each subsequent attempt.
|
|
24
|
-
*/
|
|
25
|
-
delayMs;
|
|
26
|
-
/**
|
|
27
|
-
* Creates a fixed-delay retry policy.
|
|
28
|
-
*/
|
|
29
|
-
constructor(options) {
|
|
30
|
-
super();
|
|
31
|
-
this.maxAttempts = options.maxAttempts;
|
|
32
|
-
this.delayMs = options.delayMs;
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* Computes retry decision for the current attempt.
|
|
36
|
-
*/
|
|
37
|
-
next(input) {
|
|
38
|
-
if (input.attempt >= this.maxAttempts) return {
|
|
39
|
-
delayMs: 0,
|
|
40
|
-
reason: "max-attempts-reached",
|
|
41
|
-
shouldRetry: false
|
|
42
|
-
};
|
|
43
|
-
return {
|
|
44
|
-
delayMs: this.delayMs,
|
|
45
|
-
reason: "retry",
|
|
46
|
-
shouldRetry: true
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
};
|
|
50
|
-
//#endregion
|
|
51
|
-
export { FixedDelay };
|
|
52
|
-
|
|
53
|
-
//# sourceMappingURL=fixed-delay.mjs.map
|
package/dist/fixed-delay.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"fixed-delay.mjs","names":[],"sources":["../src/fixed-delay.ts"],"sourcesContent":["/**\n * Fixed-delay retry strategy.\n *\n * @module @zap-studio/retry/fixed-delay\n */\n\nimport { BaseRetryPolicy } from \"./index.js\";\nimport type { RetryDecision, RetryDecisionInput } from \"./types.js\";\n\n/**\n * Configuration for `FixedDelay`.\n */\nexport interface FixedDelayOptions {\n /**\n * Maximum number of attempts (including the first) before giving up.\n */\n maxAttempts: number;\n /**\n * Constant delay in milliseconds before each retry after a failure.\n */\n delayMs: number;\n}\n\n/**\n * Retries with a constant delay between attempts.\n *\n * @example\n * const policy = new FixedDelay({\n * maxAttempts: 3,\n * delayMs: 250,\n * });\n */\nexport class FixedDelay extends BaseRetryPolicy {\n /**\n * Maximum number of attempts before the policy returns `max-attempts-reached`.\n */\n private readonly maxAttempts: number;\n /**\n * Constant delay in milliseconds before each subsequent attempt.\n */\n private readonly delayMs: number;\n\n /**\n * Creates a fixed-delay retry policy.\n */\n constructor(options: FixedDelayOptions) {\n super();\n this.maxAttempts = options.maxAttempts;\n this.delayMs = options.delayMs;\n }\n\n /**\n * Computes retry decision for the current attempt.\n */\n public next(input: RetryDecisionInput): RetryDecision {\n if (input.attempt >= this.maxAttempts) {\n return { delayMs: 0, reason: \"max-attempts-reached\", shouldRetry: false };\n }\n\n return { delayMs: this.delayMs, reason: \"retry\", shouldRetry: true };\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAgCA,IAAa,aAAb,cAAgC,gBAAgB;;;;CAI9C;;;;CAIA;;;;CAKA,YAAY,SAA4B;EACtC,MAAM;EACN,KAAK,cAAc,QAAQ;EAC3B,KAAK,UAAU,QAAQ;CACzB;;;;CAKA,KAAY,OAA0C;EACpD,IAAI,MAAM,WAAW,KAAK,aACxB,OAAO;GAAE,SAAS;GAAG,QAAQ;GAAwB,aAAa;EAAM;EAG1E,OAAO;GAAE,SAAS,KAAK;GAAS,QAAQ;GAAS,aAAa;EAAK;CACrE;AACF"}
|