fetch-retrier 0.6.4 → 0.7.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/.editorconfig +12 -0
- package/README.md +13 -11
- package/lib/core/errors.d.ts +7 -6
- package/lib/core/errors.js +6 -5
- package/lib/core/http/timed-fetch.d.ts +2 -0
- package/lib/core/http/timed-fetch.js +3 -1
- package/lib/core/options.d.ts +5 -3
- package/lib/core/options.js +1 -1
- package/lib/core/time/wait.d.ts +7 -2
- package/lib/core/time/wait.js +22 -4
- package/lib/default-should-retry.d.ts +6 -0
- package/lib/default-should-retry.js +12 -0
- package/lib/{core/fetch-retrier.d.ts → fetch-retrier.d.ts} +8 -5
- package/lib/fetch-retrier.js +88 -0
- package/lib/index.d.ts +4 -4
- package/lib/index.js +7 -7
- package/lib/parse-retry-after.d.ts +6 -0
- package/lib/parse-retry-after.js +11 -0
- package/package.json +3 -2
- package/.devcontainer/devcontainer.json +0 -27
- package/lib/core/fetch-retrier.js +0 -86
package/.editorconfig
ADDED
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
[](https://www.npmjs.com/package/fetch-retrier)
|
|
4
4
|
[](https://www.npmjs.com/package/fetch-retrier)
|
|
5
5
|
[](https://www.npmjs.com/package/fetch-retrier)
|
|
6
|
-
[](https://github.com/gammarers-labs/fetch-retrier/actions/workflows/build.yml)
|
|
7
7
|
|
|
8
8
|
A lightweight wrapper around `fetch` that adds **retries**, **per-attempt timeout**, **Retry-After** support, **full jitter** backoff, and **option validation**. Pass standard `RequestInit` options (`method`, `body`, `credentials`, and more) for POST/PUT APIs and other HTTP calls that may be rate-limited or temporarily unavailable.
|
|
9
9
|
|
|
@@ -18,8 +18,8 @@ A lightweight wrapper around `fetch` that adds **retries**, **per-attempt timeou
|
|
|
18
18
|
- **Header shorthand** – Optional top-level `headers` override `init.headers` when both are set.
|
|
19
19
|
- **Default retry policy** – Retries transient HTTP statuses (408, 425, 429, 500, 502, 503, 504) via `defaultShouldRetry` and `DEFAULT_RETRYABLE_HTTP_STATUSES`.
|
|
20
20
|
- **Extensible retry predicate** – Compose `defaultShouldRetry` with custom `shouldRetry` logic (receives response body text).
|
|
21
|
-
- **External cancellation** – Pass an `AbortSignal` to cancel in-flight requests.
|
|
22
|
-
- **Typed errors** – All failures extend `FetchRetrierError`. Subclasses include `FetchRetrierHttpError` (with `status` and `body`), `FetchRetrierNetworkError`, `FetchRetrierAbortError`, and `FetchRetrierInvalidOptionsError`.
|
|
21
|
+
- **External cancellation** – Pass an `AbortSignal` to cancel in-flight requests and backoff waits.
|
|
22
|
+
- **Typed errors** – All failures extend abstract `FetchRetrierError`. Subclasses include `FetchRetrierHttpError` (with `status` and `body`), `FetchRetrierNetworkError`, `FetchRetrierAbortError`, `FetchRetrierAlreadyAbortedError`, and `FetchRetrierInvalidOptionsError`.
|
|
23
23
|
- **TypeScript** – Exported types including `RequestOptions` and `FetchInitOptions`.
|
|
24
24
|
|
|
25
25
|
## How it works
|
|
@@ -27,12 +27,13 @@ A lightweight wrapper around `fetch` that adds **retries**, **per-attempt timeou
|
|
|
27
27
|
Options are validated, then each attempt sends the same URL and `init`/`headers` with an internal timeout. If `response.ok` is true, that response is returned. Otherwise `shouldRetry` decides whether to wait and try again. HTTP retries prefer a valid `Retry-After` header; abort and network retries use full jitter. After the last attempt, a subclass of `FetchRetrierError` is thrown.
|
|
28
28
|
|
|
29
29
|
- **Success** – If `response.ok` is true, the response is returned immediately.
|
|
30
|
-
- **Package errors** – Failures from this package extend `FetchRetrierError`. Catch the base, or a subclass for a specific case.
|
|
30
|
+
- **Package errors** – Failures from this package extend abstract `FetchRetrierError`. Catch the base, or a subclass for a specific case. Construct a subclass.
|
|
31
31
|
- **Invalid options** – If `retries < 1`, `timeoutMs <= 0`, `baseBackoffMs < 0`, or `maxBackoffMs` is set and `< 0`, `FetchRetrierInvalidOptionsError` is thrown before any request is made. This is not a `TypeError`.
|
|
32
32
|
- **Retriable failure** – If the response is not OK and `shouldRetry(response, body)` returns true, the client waits and retries until `retries` is exhausted. Wait prefers a valid `Retry-After` header (delta-seconds or HTTP-date); otherwise uses full jitter. On the last attempt, `FetchRetrierHttpError` is thrown (includes `status` and `body`).
|
|
33
33
|
- **Non-retriable failure** – If `shouldRetry` returns false, `FetchRetrierHttpError` is thrown immediately with `status` and `body` (e.g. `Non-retriable HTTP error: 404`).
|
|
34
34
|
- **Timeout** – If a request exceeds `timeoutMs`, that attempt is aborted and retried with full jitter until `retries` is exhausted. Timeout is per-attempt and does not cancel later attempts. The final failure is `FetchRetrierAbortError`.
|
|
35
|
-
- **External abort (in-flight)** – If `signal` is aborted during an attempt, the in-flight request is aborted. On the last attempt, the failure is `FetchRetrierAbortError`. If retries remain, the next attempt sees the still-aborted signal and throws `FetchRetrierAlreadyAbortedError` (no further request is made).
|
|
35
|
+
- **External abort (in-flight)** – If `signal` is aborted during an attempt, the in-flight request is aborted. On the last attempt, the failure is `FetchRetrierAbortError`. If retries remain, backoff is skipped and the next attempt sees the still-aborted signal and throws `FetchRetrierAlreadyAbortedError` (no further request is made).
|
|
36
|
+
- **Abort during backoff** – If `signal` aborts while waiting on full jitter or `Retry-After`, the wait ends immediately and `FetchRetrierAlreadyAbortedError` is thrown (no further request is made).
|
|
36
37
|
- **Network / TypeError** – Network errors are retried with full jitter; after the last attempt, `FetchRetrierNetworkError` is thrown with the original error as `cause`.
|
|
37
38
|
- **Already aborted signal** – If `signal` is already aborted before an attempt starts, `FetchRetrierAlreadyAbortedError` is thrown (no attempt is made).
|
|
38
39
|
|
|
@@ -126,9 +127,9 @@ const response = await fetchRetrier('https://api.example.com/data', {
|
|
|
126
127
|
|
|
127
128
|
### Handling errors
|
|
128
129
|
|
|
129
|
-
All failures thrown by `fetchRetrier` extend `FetchRetrierError`.
|
|
130
|
-
failure, or a subclass for a specific case.
|
|
131
|
-
`TypeError`.
|
|
130
|
+
All failures thrown by `fetchRetrier` extend `FetchRetrierError`. The base class is abstract.
|
|
131
|
+
Catch it for any library failure, or a subclass for a specific case. Construct a subclass.
|
|
132
|
+
`FetchRetrierInvalidOptionsError` does not extend `TypeError`.
|
|
132
133
|
|
|
133
134
|
On a non-OK response that is not retried (or after retries are exhausted), `FetchRetrierHttpError`
|
|
134
135
|
includes both `status` and the already-read `body`:
|
|
@@ -162,7 +163,8 @@ try {
|
|
|
162
163
|
Timeout abort and external abort are different. Per-attempt timeout retries remaining attempts and
|
|
163
164
|
then throws `FetchRetrierAbortError`. An in-flight external abort cancels the current request;
|
|
164
165
|
the last attempt throws `FetchRetrierAbortError`, while remaining attempts throw
|
|
165
|
-
`FetchRetrierAlreadyAbortedError` because the signal stays aborted.
|
|
166
|
+
`FetchRetrierAlreadyAbortedError` because the signal stays aborted. Aborting during a full-jitter
|
|
167
|
+
or `Retry-After` wait also ends the wait immediately and throws `FetchRetrierAlreadyAbortedError`.
|
|
166
168
|
|
|
167
169
|
`FetchRetrierAlreadyAbortedError` extends `FetchRetrierAbortError`, so check the subclass first.
|
|
168
170
|
|
|
@@ -206,7 +208,7 @@ try {
|
|
|
206
208
|
| `maxBackoffMs` | `number` | No | Optional ceiling in milliseconds applied to the full-jitter result (`Math.min(jitter, maxBackoffMs)`). Does not clip a valid `Retry-After`. Must be `>= 0` when set (`0` skips jitter wait). Omitted means no extra clip. |
|
|
207
209
|
| `init` | `FetchInitOptions` | No | `fetch` options forwarded to every attempt: `method`, `body`, `credentials`, `redirect`, `mode`, `cache`, etc. `signal` is reserved for internal timeout and cancellation. |
|
|
208
210
|
| `headers` | `Record<string, string>` | No | Headers sent on every attempt. Overrides `init.headers` when both are set. |
|
|
209
|
-
| `signal` | `AbortSignal` | No | External abort signal. If already aborted before an attempt, `FetchRetrierAlreadyAbortedError` is thrown. If aborted during an attempt, the in-flight request is aborted: the last attempt fails with `FetchRetrierAbortError`; remaining attempts fail with `FetchRetrierAlreadyAbortedError
|
|
211
|
+
| `signal` | `AbortSignal` | No | External abort signal. If already aborted before an attempt, `FetchRetrierAlreadyAbortedError` is thrown. If aborted during an attempt, the in-flight request is aborted: the last attempt fails with `FetchRetrierAbortError`; remaining attempts fail with `FetchRetrierAlreadyAbortedError` without waiting out backoff. If aborted during a full-jitter or `Retry-After` wait, the wait ends immediately and `FetchRetrierAlreadyAbortedError` is thrown. Distinct from `timeoutMs`, which retries remaining attempts and then throws `FetchRetrierAbortError`. |
|
|
210
212
|
| `shouldRetry` | `(response: Response, body: string) => boolean` | No | Called after `response.text()` when `response.ok` is false. Return `true` to retry. Default: `defaultShouldRetry` (statuses in `DEFAULT_RETRYABLE_HTTP_STATUSES`: 408, 425, 429, 500, 502, 503, 504). |
|
|
211
213
|
|
|
212
214
|
### Exported helpers
|
|
@@ -220,7 +222,7 @@ try {
|
|
|
220
222
|
## Requirements
|
|
221
223
|
|
|
222
224
|
- **Node.js** >= 20.0.0
|
|
223
|
-
- Uses the global `fetch`
|
|
225
|
+
- Uses the global `fetch`
|
|
224
226
|
|
|
225
227
|
## License
|
|
226
228
|
|
package/lib/core/errors.d.ts
CHANGED
|
@@ -7,16 +7,16 @@
|
|
|
7
7
|
/**
|
|
8
8
|
* Base class for every error thrown by this package.
|
|
9
9
|
*
|
|
10
|
-
* Catch
|
|
11
|
-
* case. Distinct from native `fetch` `TypeError` and `AbortError`
|
|
12
|
-
* before they leave {@link fetchRetrier}.
|
|
10
|
+
* This class is abstract. Catch it to handle any library failure, or a subclass for a specific
|
|
11
|
+
* case. Callers construct a subclass. Distinct from native `fetch` `TypeError` and `AbortError`
|
|
12
|
+
* values, which are wrapped before they leave {@link fetchRetrier}.
|
|
13
13
|
*/
|
|
14
|
-
export declare class FetchRetrierError extends Error {
|
|
14
|
+
export declare abstract class FetchRetrierError extends Error {
|
|
15
15
|
readonly name: string;
|
|
16
16
|
/**
|
|
17
17
|
* @param message - Human-readable reason
|
|
18
18
|
*/
|
|
19
|
-
constructor(message: string);
|
|
19
|
+
protected constructor(message: string);
|
|
20
20
|
}
|
|
21
21
|
/**
|
|
22
22
|
* Error thrown when the last attempt is cancelled by per-attempt timeout or an in-flight
|
|
@@ -31,7 +31,8 @@ export declare class FetchRetrierAbortError extends FetchRetrierError {
|
|
|
31
31
|
constructor(message?: string);
|
|
32
32
|
}
|
|
33
33
|
/**
|
|
34
|
-
* Error thrown when {@link RequestOptions.signal} is already aborted before an attempt starts
|
|
34
|
+
* Error thrown when {@link RequestOptions.signal} is already aborted before an attempt starts,
|
|
35
|
+
* including when a full-jitter or `Retry-After` wait ends early because the signal aborted.
|
|
35
36
|
*/
|
|
36
37
|
export declare class FetchRetrierAlreadyAbortedError extends FetchRetrierAbortError {
|
|
37
38
|
readonly name: string;
|
package/lib/core/errors.js
CHANGED
|
@@ -10,9 +10,9 @@ exports.FetchRetrierUnreachableError = exports.FetchRetrierInvalidOptionsError =
|
|
|
10
10
|
/**
|
|
11
11
|
* Base class for every error thrown by this package.
|
|
12
12
|
*
|
|
13
|
-
* Catch
|
|
14
|
-
* case. Distinct from native `fetch` `TypeError` and `AbortError`
|
|
15
|
-
* before they leave {@link fetchRetrier}.
|
|
13
|
+
* This class is abstract. Catch it to handle any library failure, or a subclass for a specific
|
|
14
|
+
* case. Callers construct a subclass. Distinct from native `fetch` `TypeError` and `AbortError`
|
|
15
|
+
* values, which are wrapped before they leave {@link fetchRetrier}.
|
|
16
16
|
*/
|
|
17
17
|
class FetchRetrierError extends Error {
|
|
18
18
|
/**
|
|
@@ -42,7 +42,8 @@ class FetchRetrierAbortError extends FetchRetrierError {
|
|
|
42
42
|
}
|
|
43
43
|
exports.FetchRetrierAbortError = FetchRetrierAbortError;
|
|
44
44
|
/**
|
|
45
|
-
* Error thrown when {@link RequestOptions.signal} is already aborted before an attempt starts
|
|
45
|
+
* Error thrown when {@link RequestOptions.signal} is already aborted before an attempt starts,
|
|
46
|
+
* including when a full-jitter or `Retry-After` wait ends early because the signal aborted.
|
|
46
47
|
*/
|
|
47
48
|
class FetchRetrierAlreadyAbortedError extends FetchRetrierAbortError {
|
|
48
49
|
/**
|
|
@@ -129,4 +130,4 @@ class FetchRetrierUnreachableError extends FetchRetrierError {
|
|
|
129
130
|
}
|
|
130
131
|
}
|
|
131
132
|
exports.FetchRetrierUnreachableError = FetchRetrierUnreachableError;
|
|
132
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
133
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXJyb3JzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvcmUvZXJyb3JzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7Ozs7R0FLRzs7O0FBRUg7Ozs7OztHQU1HO0FBQ0gsTUFBc0IsaUJBQWtCLFNBQVEsS0FBSztJQUVuRDs7T0FFRztJQUNILFlBQXNCLE9BQWU7UUFDbkMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBTEMsU0FBSSxHQUFXLG1CQUFtQixDQUFDO1FBTW5ELE1BQU0sQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFFLGlCQUFpQixDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQzNELENBQUM7Q0FDRjtBQVRELDhDQVNDO0FBRUQ7Ozs7R0FJRztBQUNILE1BQWEsc0JBQXVCLFNBQVEsaUJBQWlCO0lBRTNEOztPQUVHO0lBQ0gsWUFBWSxPQUFPLEdBQUcsU0FBUztRQUM3QixLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7UUFMQyxTQUFJLEdBQVcsd0JBQXdCLENBQUM7UUFNeEQsTUFBTSxDQUFDLGNBQWMsQ0FBQyxJQUFJLEVBQUUsc0JBQXNCLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDaEUsQ0FBQztDQUNGO0FBVEQsd0RBU0M7QUFFRDs7O0dBR0c7QUFDSCxNQUFhLCtCQUFnQyxTQUFRLHNCQUFzQjtJQUV6RTs7T0FFRztJQUNILFlBQVksT0FBTyxHQUFHLDRCQUE0QjtRQUNoRCxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7UUFMQyxTQUFJLEdBQVcsaUNBQWlDLENBQUM7UUFNakUsTUFBTSxDQUFDLGNBQWMsQ0FBQyxJQUFJLEVBQUUsK0JBQStCLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDekUsQ0FBQztDQUNGO0FBVEQsMEVBU0M7QUFFRDs7Ozs7Ozs7R0FRRztBQUNILE1BQWEscUJBQXNCLFNBQVEsaUJBQWlCO0lBRTFEOzs7O09BSUc7SUFDSCxZQUNFLE9BQWUsRUFDQyxNQUFjLEVBQ2QsSUFBWTtRQUU1QixLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7UUFIQyxXQUFNLEdBQU4sTUFBTSxDQUFRO1FBQ2QsU0FBSSxHQUFKLElBQUksQ0FBUTtRQVRaLFNBQUksR0FBVyx1QkFBdUIsQ0FBQztRQVl2RCxNQUFNLENBQUMsY0FBYyxDQUFDLElBQUksRUFBRSxxQkFBcUIsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUMvRCxDQUFDO0NBQ0Y7QUFmRCxzREFlQztBQUVEOzs7O0dBSUc7QUFDSCxNQUFhLHdCQUF5QixTQUFRLGlCQUFpQjtJQUU3RDs7O09BR0c7SUFDSCxZQUFZLE9BQU8sR0FBRyxlQUFlLEVBQWtCLEtBQWU7UUFDcEUsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBRHNDLFVBQUssR0FBTCxLQUFLLENBQVU7UUFMcEQsU0FBSSxHQUFXLDBCQUEwQixDQUFDO1FBTzFELE1BQU0sQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFFLHdCQUF3QixDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ2xFLENBQUM7Q0FDRjtBQVZELDREQVVDO0FBRUQ7Ozs7OztHQU1HO0FBQ0gsTUFBYSwrQkFBZ0MsU0FBUSxpQkFBaUI7SUFFcEU7O09BRUc7SUFDSCxZQUFZLE9BQWU7UUFDekIsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBTEMsU0FBSSxHQUFXLGlDQUFpQyxDQUFDO1FBTWpFLE1BQU0sQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFFLCtCQUErQixDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ3pFLENBQUM7Q0FDRjtBQVRELDBFQVNDO0FBRUQ7O0dBRUc7QUFDSCxNQUFhLDRCQUE2QixTQUFRLGlCQUFpQjtJQUVqRTs7T0FFRztJQUNILFlBQVksT0FBTyxHQUFHLGFBQWE7UUFDakMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBTEMsU0FBSSxHQUFXLDhCQUE4QixDQUFDO1FBTTlELE1BQU0sQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFFLDRCQUE0QixDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ3RFLENBQUM7Q0FDRjtBQVRELG9FQVNDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBUeXBlZCBlcnJvcnMgdGhyb3duIGJ5IHtAbGluayBmZXRjaFJldHJpZXJ9LlxuICpcbiAqIEFsbCBwdWJsaWMgZXJyb3IgY2xhc3NlcyBleHRlbmQge0BsaW5rIEZldGNoUmV0cmllckVycm9yfSBzbyBjYWxsZXJzIGNhbiBjYXRjaCBhbnkgbGlicmFyeVxuICogZmFpbHVyZSB3aXRoIG9uZSBgaW5zdGFuY2VvZmAgY2hlY2suXG4gKi9cblxuLyoqXG4gKiBCYXNlIGNsYXNzIGZvciBldmVyeSBlcnJvciB0aHJvd24gYnkgdGhpcyBwYWNrYWdlLlxuICpcbiAqIFRoaXMgY2xhc3MgaXMgYWJzdHJhY3QuIENhdGNoIGl0IHRvIGhhbmRsZSBhbnkgbGlicmFyeSBmYWlsdXJlLCBvciBhIHN1YmNsYXNzIGZvciBhIHNwZWNpZmljXG4gKiBjYXNlLiBDYWxsZXJzIGNvbnN0cnVjdCBhIHN1YmNsYXNzLiBEaXN0aW5jdCBmcm9tIG5hdGl2ZSBgZmV0Y2hgIGBUeXBlRXJyb3JgIGFuZCBgQWJvcnRFcnJvcmBcbiAqIHZhbHVlcywgd2hpY2ggYXJlIHdyYXBwZWQgYmVmb3JlIHRoZXkgbGVhdmUge0BsaW5rIGZldGNoUmV0cmllcn0uXG4gKi9cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBGZXRjaFJldHJpZXJFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgb3ZlcnJpZGUgcmVhZG9ubHkgbmFtZTogc3RyaW5nID0gJ0ZldGNoUmV0cmllckVycm9yJztcbiAgLyoqXG4gICAqIEBwYXJhbSBtZXNzYWdlIC0gSHVtYW4tcmVhZGFibGUgcmVhc29uXG4gICAqL1xuICBwcm90ZWN0ZWQgY29uc3RydWN0b3IobWVzc2FnZTogc3RyaW5nKSB7XG4gICAgc3VwZXIobWVzc2FnZSk7XG4gICAgT2JqZWN0LnNldFByb3RvdHlwZU9mKHRoaXMsIEZldGNoUmV0cmllckVycm9yLnByb3RvdHlwZSk7XG4gIH1cbn1cblxuLyoqXG4gKiBFcnJvciB0aHJvd24gd2hlbiB0aGUgbGFzdCBhdHRlbXB0IGlzIGNhbmNlbGxlZCBieSBwZXItYXR0ZW1wdCB0aW1lb3V0IG9yIGFuIGluLWZsaWdodFxuICogZXh0ZXJuYWwge0BsaW5rIEFib3J0U2lnbmFsfS4gUmVtYWluaW5nIHJldHJpZXMgYWZ0ZXIgYW4gZXh0ZXJuYWwgYWJvcnQgdGhyb3dcbiAqIHtAbGluayBGZXRjaFJldHJpZXJBbHJlYWR5QWJvcnRlZEVycm9yfSBpbnN0ZWFkLCBiZWNhdXNlIHRoZSBzaWduYWwgc3RheXMgYWJvcnRlZC5cbiAqL1xuZXhwb3J0IGNsYXNzIEZldGNoUmV0cmllckFib3J0RXJyb3IgZXh0ZW5kcyBGZXRjaFJldHJpZXJFcnJvciB7XG4gIG92ZXJyaWRlIHJlYWRvbmx5IG5hbWU6IHN0cmluZyA9ICdGZXRjaFJldHJpZXJBYm9ydEVycm9yJztcbiAgLyoqXG4gICAqIEBwYXJhbSBtZXNzYWdlIC0gSHVtYW4tcmVhZGFibGUgcmVhc29uIChkZWZhdWx0OiBgJ0Fib3J0ZWQnYClcbiAgICovXG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2UgPSAnQWJvcnRlZCcpIHtcbiAgICBzdXBlcihtZXNzYWdlKTtcbiAgICBPYmplY3Quc2V0UHJvdG90eXBlT2YodGhpcywgRmV0Y2hSZXRyaWVyQWJvcnRFcnJvci5wcm90b3R5cGUpO1xuICB9XG59XG5cbi8qKlxuICogRXJyb3IgdGhyb3duIHdoZW4ge0BsaW5rIFJlcXVlc3RPcHRpb25zLnNpZ25hbH0gaXMgYWxyZWFkeSBhYm9ydGVkIGJlZm9yZSBhbiBhdHRlbXB0IHN0YXJ0cyxcbiAqIGluY2x1ZGluZyB3aGVuIGEgZnVsbC1qaXR0ZXIgb3IgYFJldHJ5LUFmdGVyYCB3YWl0IGVuZHMgZWFybHkgYmVjYXVzZSB0aGUgc2lnbmFsIGFib3J0ZWQuXG4gKi9cbmV4cG9ydCBjbGFzcyBGZXRjaFJldHJpZXJBbHJlYWR5QWJvcnRlZEVycm9yIGV4dGVuZHMgRmV0Y2hSZXRyaWVyQWJvcnRFcnJvciB7XG4gIG92ZXJyaWRlIHJlYWRvbmx5IG5hbWU6IHN0cmluZyA9ICdGZXRjaFJldHJpZXJBbHJlYWR5QWJvcnRlZEVycm9yJztcbiAgLyoqXG4gICAqIEBwYXJhbSBtZXNzYWdlIC0gSHVtYW4tcmVhZGFibGUgcmVhc29uIChkZWZhdWx0OiBgJ1NpZ25hbCB3YXMgYWxyZWFkeSBhYm9ydGVkJ2ApXG4gICAqL1xuICBjb25zdHJ1Y3RvcihtZXNzYWdlID0gJ1NpZ25hbCB3YXMgYWxyZWFkeSBhYm9ydGVkJykge1xuICAgIHN1cGVyKG1lc3NhZ2UpO1xuICAgIE9iamVjdC5zZXRQcm90b3R5cGVPZih0aGlzLCBGZXRjaFJldHJpZXJBbHJlYWR5QWJvcnRlZEVycm9yLnByb3RvdHlwZSk7XG4gIH1cbn1cblxuLyoqXG4gKiBFcnJvciB0aHJvd24gd2hlbiB0aGUgc2VydmVyIHJldHVybnMgYSBub24tT0sgSFRUUCBzdGF0dXMgYW5kIG5vIGZ1cnRoZXIgcmV0cnkgaXMgcGVyZm9ybWVkLlxuICpcbiAqIENhcnJpZXMgdGhlIGxhc3QgcmVzcG9uc2UgYHN0YXR1c2AgYW5kIHRoZSBib2R5IHRleHQgYWxyZWFkeSBjb25zdW1lZCB2aWEgYHJlc3BvbnNlLnRleHQoKWBcbiAqICh0aGUgc2FtZSB0ZXh0IHBhc3NlZCB0byB7QGxpbmsgUmVxdWVzdE9wdGlvbnMuc2hvdWxkUmV0cnl9KS5cbiAqXG4gKiBAcHJvcGVydHkgc3RhdHVzIC0gSFRUUCBzdGF0dXMgY29kZSBmcm9tIHRoZSBsYXN0IG5vbi1PSyByZXNwb25zZVxuICogQHByb3BlcnR5IGJvZHkgLSBSZXNwb25zZSBib2R5IHRleHQgYWxyZWFkeSByZWFkIHZpYSBgcmVzcG9uc2UudGV4dCgpYCBmb3IgdGhhdCBhdHRlbXB0XG4gKi9cbmV4cG9ydCBjbGFzcyBGZXRjaFJldHJpZXJIdHRwRXJyb3IgZXh0ZW5kcyBGZXRjaFJldHJpZXJFcnJvciB7XG4gIG92ZXJyaWRlIHJlYWRvbmx5IG5hbWU6IHN0cmluZyA9ICdGZXRjaFJldHJpZXJIdHRwRXJyb3InO1xuICAvKipcbiAgICogQHBhcmFtIG1lc3NhZ2UgLSBFcnJvciBkZXNjcmlwdGlvblxuICAgKiBAcGFyYW0gc3RhdHVzIC0gSFRUUCBzdGF0dXMgY29kZSBmcm9tIHRoZSBsYXN0IG5vbi1PSyByZXNwb25zZVxuICAgKiBAcGFyYW0gYm9keSAtIFJlc3BvbnNlIGJvZHkgdGV4dCBhbHJlYWR5IHJlYWQgdmlhIGByZXNwb25zZS50ZXh0KClgIGZvciB0aGF0IGF0dGVtcHRcbiAgICovXG4gIGNvbnN0cnVjdG9yKFxuICAgIG1lc3NhZ2U6IHN0cmluZyxcbiAgICBwdWJsaWMgcmVhZG9ubHkgc3RhdHVzOiBudW1iZXIsXG4gICAgcHVibGljIHJlYWRvbmx5IGJvZHk6IHN0cmluZyxcbiAgKSB7XG4gICAgc3VwZXIobWVzc2FnZSk7XG4gICAgT2JqZWN0LnNldFByb3RvdHlwZU9mKHRoaXMsIEZldGNoUmV0cmllckh0dHBFcnJvci5wcm90b3R5cGUpO1xuICB9XG59XG5cbi8qKlxuICogRXJyb3IgdGhyb3duIHdoZW4gYSBmZXRjaCBmYWlscyB3aXRoIGEgbmV0d29yay1sZXZlbCBlcnJvciAoZS5nLiBETlMgZmFpbHVyZSwgY29ubmVjdGlvbiByZWZ1c2VkKS5cbiAqXG4gKiBAcHJvcGVydHkgY2F1c2UgLSBPcmlnaW5hbCBlcnJvciBmcm9tIHRoZSB1bmRlcmx5aW5nIGBmZXRjaGAsIHdoZW4gYXZhaWxhYmxlXG4gKi9cbmV4cG9ydCBjbGFzcyBGZXRjaFJldHJpZXJOZXR3b3JrRXJyb3IgZXh0ZW5kcyBGZXRjaFJldHJpZXJFcnJvciB7XG4gIG92ZXJyaWRlIHJlYWRvbmx5IG5hbWU6IHN0cmluZyA9ICdGZXRjaFJldHJpZXJOZXR3b3JrRXJyb3InO1xuICAvKipcbiAgICogQHBhcmFtIG1lc3NhZ2UgLSBIdW1hbi1yZWFkYWJsZSByZWFzb24gKGRlZmF1bHQ6IGAnTmV0d29yayBlcnJvcidgKVxuICAgKiBAcGFyYW0gY2F1c2UgLSBPcmlnaW5hbCBlcnJvciBmcm9tIHRoZSB1bmRlcmx5aW5nIGBmZXRjaGAsIHdoZW4gYXZhaWxhYmxlXG4gICAqL1xuICBjb25zdHJ1Y3RvcihtZXNzYWdlID0gJ05ldHdvcmsgZXJyb3InLCBwdWJsaWMgcmVhZG9ubHkgY2F1c2U/OiB1bmtub3duKSB7XG4gICAgc3VwZXIobWVzc2FnZSk7XG4gICAgT2JqZWN0LnNldFByb3RvdHlwZU9mKHRoaXMsIEZldGNoUmV0cmllck5ldHdvcmtFcnJvci5wcm90b3R5cGUpO1xuICB9XG59XG5cbi8qKlxuICogRXJyb3IgdGhyb3duIHdoZW4ge0BsaW5rIFJlcXVlc3RPcHRpb25zfSBjb250YWlucyBpbnZhbGlkIG51bWVyaWMgdmFsdWVzLlxuICpcbiAqIEV4dGVuZHMge0BsaW5rIEZldGNoUmV0cmllckVycm9yfSwgbm90IHtAbGluayBUeXBlRXJyb3J9LCBzbyBpdCBpcyBub3QgdHJlYXRlZCBhcyBhIG5ldHdvcmtcbiAqIGZhaWx1cmUuIE5hdGl2ZSBgZmV0Y2hgIGBUeXBlRXJyb3JgIHZhbHVlcyBhcmUgcmV0cmllZCBhbmQgc3VyZmFjZWQgYXNcbiAqIHtAbGluayBGZXRjaFJldHJpZXJOZXR3b3JrRXJyb3J9IGFmdGVyIHRoZSBsYXN0IGF0dGVtcHQuXG4gKi9cbmV4cG9ydCBjbGFzcyBGZXRjaFJldHJpZXJJbnZhbGlkT3B0aW9uc0Vycm9yIGV4dGVuZHMgRmV0Y2hSZXRyaWVyRXJyb3Ige1xuICBvdmVycmlkZSByZWFkb25seSBuYW1lOiBzdHJpbmcgPSAnRmV0Y2hSZXRyaWVySW52YWxpZE9wdGlvbnNFcnJvcic7XG4gIC8qKlxuICAgKiBAcGFyYW0gbWVzc2FnZSAtIEh1bWFuLXJlYWRhYmxlIHJlYXNvbiBkZXNjcmliaW5nIHRoZSBpbnZhbGlkIG9wdGlvblxuICAgKi9cbiAgY29uc3RydWN0b3IobWVzc2FnZTogc3RyaW5nKSB7XG4gICAgc3VwZXIobWVzc2FnZSk7XG4gICAgT2JqZWN0LnNldFByb3RvdHlwZU9mKHRoaXMsIEZldGNoUmV0cmllckludmFsaWRPcHRpb25zRXJyb3IucHJvdG90eXBlKTtcbiAgfVxufVxuXG4vKipcbiAqIEVycm9yIHRocm93biB3aGVuIGFuIGludGVybmFsIGludmFyaWFudCBmYWlscyAoc2hvdWxkIG5vdCBoYXBwZW4gaW4gbm9ybWFsIHVzZSkuXG4gKi9cbmV4cG9ydCBjbGFzcyBGZXRjaFJldHJpZXJVbnJlYWNoYWJsZUVycm9yIGV4dGVuZHMgRmV0Y2hSZXRyaWVyRXJyb3Ige1xuICBvdmVycmlkZSByZWFkb25seSBuYW1lOiBzdHJpbmcgPSAnRmV0Y2hSZXRyaWVyVW5yZWFjaGFibGVFcnJvcic7XG4gIC8qKlxuICAgKiBAcGFyYW0gbWVzc2FnZSAtIEh1bWFuLXJlYWRhYmxlIHJlYXNvbiAoZGVmYXVsdDogYCdVbnJlYWNoYWJsZSdgKVxuICAgKi9cbiAgY29uc3RydWN0b3IobWVzc2FnZSA9ICdVbnJlYWNoYWJsZScpIHtcbiAgICBzdXBlcihtZXNzYWdlKTtcbiAgICBPYmplY3Quc2V0UHJvdG90eXBlT2YodGhpcywgRmV0Y2hSZXRyaWVyVW5yZWFjaGFibGVFcnJvci5wcm90b3R5cGUpO1xuICB9XG59XG4iXX0=
|
|
@@ -25,6 +25,8 @@ export interface TimedFetchOptions {
|
|
|
25
25
|
/**
|
|
26
26
|
* Calls `fetch` with an internal {@link AbortSignal} for `timeoutMs`.
|
|
27
27
|
*
|
|
28
|
+
* When `options.signal` aborts, that internal signal aborts as well.
|
|
29
|
+
*
|
|
28
30
|
* @param url - Request URL passed to `fetch`
|
|
29
31
|
* @param options - Timeout, init, headers, and optional external signal
|
|
30
32
|
* @returns The {@link Response} from this single attempt
|
|
@@ -10,6 +10,8 @@ exports.timedFetch = void 0;
|
|
|
10
10
|
/**
|
|
11
11
|
* Calls `fetch` with an internal {@link AbortSignal} for `timeoutMs`.
|
|
12
12
|
*
|
|
13
|
+
* When `options.signal` aborts, that internal signal aborts as well.
|
|
14
|
+
*
|
|
13
15
|
* @param url - Request URL passed to `fetch`
|
|
14
16
|
* @param options - Timeout, init, headers, and optional external signal
|
|
15
17
|
* @returns The {@link Response} from this single attempt
|
|
@@ -38,4 +40,4 @@ const timedFetch = async (url, options) => {
|
|
|
38
40
|
}
|
|
39
41
|
};
|
|
40
42
|
exports.timedFetch = timedFetch;
|
|
41
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
43
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGltZWQtZmV0Y2guanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY29yZS9odHRwL3RpbWVkLWZldGNoLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7Ozs7R0FLRzs7O0FBcUJIOzs7Ozs7OztHQVFHO0FBQ0ksTUFBTSxVQUFVLEdBQUcsS0FBSyxFQUFFLEdBQVcsRUFBRSxPQUEwQixFQUFxQixFQUFFO0lBQzdGLE1BQU0sRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsY0FBYyxFQUFFLEdBQUcsT0FBTyxDQUFDO0lBQ3JFLE1BQU0sVUFBVSxHQUFHLElBQUksZUFBZSxFQUFFLENBQUM7SUFDekMsTUFBTSxLQUFLLEdBQUcsVUFBVSxDQUFDLEdBQUcsRUFBRSxDQUFDLFVBQVUsQ0FBQyxLQUFLLEVBQUUsRUFBRSxTQUFTLENBQUMsQ0FBQztJQUU5RCxNQUFNLGVBQWUsR0FBRyxHQUFTLEVBQUU7UUFDakMsWUFBWSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3BCLFVBQVUsQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUNyQixDQUFDLENBQUM7SUFFRixJQUFJLGNBQWMsRUFBRSxDQUFDO1FBQ25CLGNBQWMsQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLEVBQUUsZUFBZSxDQUFDLENBQUM7SUFDNUQsQ0FBQztJQUVELElBQUksQ0FBQztRQUNILE9BQU8sTUFBTSxLQUFLLENBQUMsR0FBRyxFQUFFO1lBQ3RCLEdBQUcsSUFBSTtZQUNQLEdBQUcsQ0FBQyxPQUFPLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDN0MsTUFBTSxFQUFFLFVBQVUsQ0FBQyxNQUFNO1NBQzFCLENBQUMsQ0FBQztJQUNMLENBQUM7WUFBUyxDQUFDO1FBQ1QsWUFBWSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3BCLGNBQWMsRUFBRSxtQkFBbUIsQ0FBQyxPQUFPLEVBQUUsZUFBZSxDQUFDLENBQUM7SUFDaEUsQ0FBQztBQUNILENBQUMsQ0FBQztBQXhCVyxRQUFBLFVBQVUsY0F3QnJCIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBPbmUgSFRUUCBhdHRlbXB0OiBwZXItYXR0ZW1wdCB0aW1lb3V0IGFuZCBvcHRpb25hbCBleHRlcm5hbCBhYm9ydCwgdGhlbiBgZmV0Y2hgLlxuICpcbiAqIERvZXMgbm90IHJldHJ5IG9yIG1hcCBmYWlsdXJlcyB0byBwYWNrYWdlIGVycm9ycy4gTmF0aXZlIGBBYm9ydEVycm9yYCBhbmQgYFR5cGVFcnJvcmBcbiAqIHByb3BhZ2F0ZSB0byB0aGUgY2FsbGVyLlxuICovXG5cbmV4cG9ydCBpbnRlcmZhY2UgVGltZWRGZXRjaE9wdGlvbnMge1xuICAvKipcbiAgICogUGVyLWF0dGVtcHQgdGltZW91dCBpbiBtaWxsaXNlY29uZHMuXG4gICAqL1xuICB0aW1lb3V0TXM6IG51bWJlcjtcbiAgLyoqXG4gICAqIGBmZXRjaGAgb3B0aW9ucyBleGNsdWRpbmcgYHNpZ25hbGAuXG4gICAqL1xuICBpbml0PzogT21pdDxSZXF1ZXN0SW5pdCwgJ3NpZ25hbCc+O1xuICAvKipcbiAgICogSGVhZGVycyBzZW50IG9uIHRoaXMgYXR0ZW1wdC4gT3ZlcnJpZGUgYGluaXQuaGVhZGVyc2Agd2hlbiBib3RoIGFyZSBzZXQuXG4gICAqL1xuICBoZWFkZXJzPzogUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcbiAgLyoqXG4gICAqIE9wdGlvbmFsIGV4dGVybmFsIGFib3J0IHNpZ25hbDsgYWJvcnRzIHRoZSBpbi1mbGlnaHQgcmVxdWVzdCB3aGVuIGZpcmVkLlxuICAgKi9cbiAgc2lnbmFsPzogQWJvcnRTaWduYWw7XG59XG5cbi8qKlxuICogQ2FsbHMgYGZldGNoYCB3aXRoIGFuIGludGVybmFsIHtAbGluayBBYm9ydFNpZ25hbH0gZm9yIGB0aW1lb3V0TXNgLlxuICpcbiAqIFdoZW4gYG9wdGlvbnMuc2lnbmFsYCBhYm9ydHMsIHRoYXQgaW50ZXJuYWwgc2lnbmFsIGFib3J0cyBhcyB3ZWxsLlxuICpcbiAqIEBwYXJhbSB1cmwgLSBSZXF1ZXN0IFVSTCBwYXNzZWQgdG8gYGZldGNoYFxuICogQHBhcmFtIG9wdGlvbnMgLSBUaW1lb3V0LCBpbml0LCBoZWFkZXJzLCBhbmQgb3B0aW9uYWwgZXh0ZXJuYWwgc2lnbmFsXG4gKiBAcmV0dXJucyBUaGUge0BsaW5rIFJlc3BvbnNlfSBmcm9tIHRoaXMgc2luZ2xlIGF0dGVtcHRcbiAqL1xuZXhwb3J0IGNvbnN0IHRpbWVkRmV0Y2ggPSBhc3luYyAodXJsOiBzdHJpbmcsIG9wdGlvbnM6IFRpbWVkRmV0Y2hPcHRpb25zKTogUHJvbWlzZTxSZXNwb25zZT4gPT4ge1xuICBjb25zdCB7IHRpbWVvdXRNcywgaW5pdCwgaGVhZGVycywgc2lnbmFsOiBleHRlcm5hbFNpZ25hbCB9ID0gb3B0aW9ucztcbiAgY29uc3QgY29udHJvbGxlciA9IG5ldyBBYm9ydENvbnRyb2xsZXIoKTtcbiAgY29uc3QgdGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IGNvbnRyb2xsZXIuYWJvcnQoKSwgdGltZW91dE1zKTtcblxuICBjb25zdCBvbkV4dGVybmFsQWJvcnQgPSAoKTogdm9pZCA9PiB7XG4gICAgY2xlYXJUaW1lb3V0KHRpbWVyKTtcbiAgICBjb250cm9sbGVyLmFib3J0KCk7XG4gIH07XG5cbiAgaWYgKGV4dGVybmFsU2lnbmFsKSB7XG4gICAgZXh0ZXJuYWxTaWduYWwuYWRkRXZlbnRMaXN0ZW5lcignYWJvcnQnLCBvbkV4dGVybmFsQWJvcnQpO1xuICB9XG5cbiAgdHJ5IHtcbiAgICByZXR1cm4gYXdhaXQgZmV0Y2godXJsLCB7XG4gICAgICAuLi5pbml0LFxuICAgICAgLi4uKGhlYWRlcnMgIT09IHVuZGVmaW5lZCA/IHsgaGVhZGVycyB9IDoge30pLFxuICAgICAgc2lnbmFsOiBjb250cm9sbGVyLnNpZ25hbCxcbiAgICB9KTtcbiAgfSBmaW5hbGx5IHtcbiAgICBjbGVhclRpbWVvdXQodGltZXIpO1xuICAgIGV4dGVybmFsU2lnbmFsPy5yZW1vdmVFdmVudExpc3RlbmVyKCdhYm9ydCcsIG9uRXh0ZXJuYWxBYm9ydCk7XG4gIH1cbn07XG4iXX0=
|
package/lib/core/options.d.ts
CHANGED
|
@@ -56,9 +56,11 @@ export interface RequestOptions {
|
|
|
56
56
|
/**
|
|
57
57
|
* Optional external {@link AbortSignal}. When aborted during an attempt, the in-flight request
|
|
58
58
|
* is aborted. On the last attempt this surfaces as {@link FetchRetrierAbortError}. If retries
|
|
59
|
-
* remain,
|
|
60
|
-
* {@link FetchRetrierAlreadyAbortedError}.
|
|
61
|
-
*
|
|
59
|
+
* remain, backoff is skipped and the next attempt throws
|
|
60
|
+
* {@link FetchRetrierAlreadyAbortedError}. Aborting during a full-jitter or `Retry-After` wait
|
|
61
|
+
* ends that wait immediately and throws {@link FetchRetrierAlreadyAbortedError}. Distinct from
|
|
62
|
+
* per-attempt timeout, which retries remaining attempts and only then throws
|
|
63
|
+
* {@link FetchRetrierAbortError}.
|
|
62
64
|
*/
|
|
63
65
|
signal?: AbortSignal;
|
|
64
66
|
/**
|
package/lib/core/options.js
CHANGED
|
@@ -3,4 +3,4 @@
|
|
|
3
3
|
* Public option types for {@link fetchRetrier}.
|
|
4
4
|
*/
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3B0aW9ucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb3JlL29wdGlvbnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOztHQUVHIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBQdWJsaWMgb3B0aW9uIHR5cGVzIGZvciB7QGxpbmsgZmV0Y2hSZXRyaWVyfS5cbiAqL1xuXG4vKipcbiAqIGBmZXRjaGAgb3B0aW9ucyBmb3J3YXJkZWQgdG8gZXZlcnkgYXR0ZW1wdCwgZXhjbHVkaW5nIGBzaWduYWxgLlxuICpcbiAqIFVzZSBmb3IgYG1ldGhvZGAsIGBib2R5YCwgYGNyZWRlbnRpYWxzYCwgYHJlZGlyZWN0YCwgYG1vZGVgLCBgY2FjaGVgLCBhbmQgb3RoZXJcbiAqIHtAbGluayBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvUmVxdWVzdEluaXQgfCBSZXF1ZXN0SW5pdH0gZmllbGRzLlxuICogUGVyLWF0dGVtcHQgYWJvcnQgYW5kIHRpbWVvdXQgYXJlIGhhbmRsZWQgaW50ZXJuYWxseSB2aWEgYHNpZ25hbGAgYW5kIG11c3Qgbm90IGJlIHNldCBoZXJlLlxuICovXG5leHBvcnQgdHlwZSBGZXRjaEluaXRPcHRpb25zID0gT21pdDxSZXF1ZXN0SW5pdCwgJ3NpZ25hbCc+O1xuXG4vKipcbiAqIE9wdGlvbnMgZm9yIHtAbGluayBmZXRjaFJldHJpZXJ9OiByZXRyeSBwb2xpY3ksIHRpbWVvdXQsIGJhY2tvZmYgKGluY2x1ZGluZyBgUmV0cnktQWZ0ZXJgKSxcbiAqIHJlcXVlc3QgcGF5bG9hZCwgYW5kIGNhbmNlbGxhdGlvbi5cbiAqXG4gKiBSZXF1ZXN0IHNoYXBlIGlzIGJ1aWx0IGFzIGB7IC4uLmluaXQsIGhlYWRlcnM/LCBzaWduYWwgfWAgb24gZWFjaCBhdHRlbXB0LiBUb3AtbGV2ZWwgYGhlYWRlcnNgXG4gKiBvdmVycmlkZSBgaW5pdC5oZWFkZXJzYCB3aGVuIGJvdGggYXJlIHByb3ZpZGVkLlxuICpcbiAqIE51bWVyaWMgZmllbGRzIGFyZSB2YWxpZGF0ZWQgd2hlbiB7QGxpbmsgZmV0Y2hSZXRyaWVyfSBpcyBjYWxsZWQ7IGludmFsaWQgdmFsdWVzIHRocm93XG4gKiB7QGxpbmsgRmV0Y2hSZXRyaWVySW52YWxpZE9wdGlvbnNFcnJvcn0uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUmVxdWVzdE9wdGlvbnMge1xuICAvKipcbiAgICogSFRUUCBoZWFkZXJzIHNlbnQgb24gZXZlcnkgYXR0ZW1wdC5cbiAgICogV2hlbiBgaW5pdC5oZWFkZXJzYCBpcyBhbHNvIHNldCwgdGhlc2UgdmFsdWVzIHRha2UgcHJlY2VkZW5jZSBmb3IgZHVwbGljYXRlIGtleXMuXG4gICAqL1xuICBoZWFkZXJzPzogUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcbiAgLyoqXG4gICAqIEFkZGl0aW9uYWwge0BsaW5rIEZldGNoSW5pdE9wdGlvbnN9IG1lcmdlZCBpbnRvIGVhY2ggYGZldGNoYCBjYWxsIChlLmcuIFBPU1QgYG1ldGhvZGAgYW5kIEpTT04gYGJvZHlgKS5cbiAgICogVGhlIHNhbWUgYGluaXRgIGlzIHJldXNlZCBhY3Jvc3MgcmV0cmllcy5cbiAgICovXG4gIGluaXQ/
|
|
6
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3B0aW9ucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb3JlL29wdGlvbnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOztHQUVHIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBQdWJsaWMgb3B0aW9uIHR5cGVzIGZvciB7QGxpbmsgZmV0Y2hSZXRyaWVyfS5cbiAqL1xuXG4vKipcbiAqIGBmZXRjaGAgb3B0aW9ucyBmb3J3YXJkZWQgdG8gZXZlcnkgYXR0ZW1wdCwgZXhjbHVkaW5nIGBzaWduYWxgLlxuICpcbiAqIFVzZSBmb3IgYG1ldGhvZGAsIGBib2R5YCwgYGNyZWRlbnRpYWxzYCwgYHJlZGlyZWN0YCwgYG1vZGVgLCBgY2FjaGVgLCBhbmQgb3RoZXJcbiAqIHtAbGluayBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvUmVxdWVzdEluaXQgfCBSZXF1ZXN0SW5pdH0gZmllbGRzLlxuICogUGVyLWF0dGVtcHQgYWJvcnQgYW5kIHRpbWVvdXQgYXJlIGhhbmRsZWQgaW50ZXJuYWxseSB2aWEgYHNpZ25hbGAgYW5kIG11c3Qgbm90IGJlIHNldCBoZXJlLlxuICovXG5leHBvcnQgdHlwZSBGZXRjaEluaXRPcHRpb25zID0gT21pdDxSZXF1ZXN0SW5pdCwgJ3NpZ25hbCc+O1xuXG4vKipcbiAqIE9wdGlvbnMgZm9yIHtAbGluayBmZXRjaFJldHJpZXJ9OiByZXRyeSBwb2xpY3ksIHRpbWVvdXQsIGJhY2tvZmYgKGluY2x1ZGluZyBgUmV0cnktQWZ0ZXJgKSxcbiAqIHJlcXVlc3QgcGF5bG9hZCwgYW5kIGNhbmNlbGxhdGlvbi5cbiAqXG4gKiBSZXF1ZXN0IHNoYXBlIGlzIGJ1aWx0IGFzIGB7IC4uLmluaXQsIGhlYWRlcnM/LCBzaWduYWwgfWAgb24gZWFjaCBhdHRlbXB0LiBUb3AtbGV2ZWwgYGhlYWRlcnNgXG4gKiBvdmVycmlkZSBgaW5pdC5oZWFkZXJzYCB3aGVuIGJvdGggYXJlIHByb3ZpZGVkLlxuICpcbiAqIE51bWVyaWMgZmllbGRzIGFyZSB2YWxpZGF0ZWQgd2hlbiB7QGxpbmsgZmV0Y2hSZXRyaWVyfSBpcyBjYWxsZWQ7IGludmFsaWQgdmFsdWVzIHRocm93XG4gKiB7QGxpbmsgRmV0Y2hSZXRyaWVySW52YWxpZE9wdGlvbnNFcnJvcn0uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUmVxdWVzdE9wdGlvbnMge1xuICAvKipcbiAgICogSFRUUCBoZWFkZXJzIHNlbnQgb24gZXZlcnkgYXR0ZW1wdC5cbiAgICogV2hlbiBgaW5pdC5oZWFkZXJzYCBpcyBhbHNvIHNldCwgdGhlc2UgdmFsdWVzIHRha2UgcHJlY2VkZW5jZSBmb3IgZHVwbGljYXRlIGtleXMuXG4gICAqL1xuICBoZWFkZXJzPzogUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcbiAgLyoqXG4gICAqIEFkZGl0aW9uYWwge0BsaW5rIEZldGNoSW5pdE9wdGlvbnN9IG1lcmdlZCBpbnRvIGVhY2ggYGZldGNoYCBjYWxsIChlLmcuIFBPU1QgYG1ldGhvZGAgYW5kIEpTT04gYGJvZHlgKS5cbiAgICogVGhlIHNhbWUgYGluaXRgIGlzIHJldXNlZCBhY3Jvc3MgcmV0cmllcy5cbiAgICovXG4gIGluaXQ/OiBGZXRjaEluaXRPcHRpb25zO1xuICAvKipcbiAgICogTWF4aW11bSBudW1iZXIgb2YgYXR0ZW1wdHMsIGluY2x1ZGluZyB0aGUgZmlyc3QuXG4gICAqIE11c3QgYmUgYD49IDFgLlxuICAgKi9cbiAgcmV0cmllczogbnVtYmVyO1xuICAvKipcbiAgICogUGVyLWF0dGVtcHQgdGltZW91dCBpbiBtaWxsaXNlY29uZHM7IHVzZXMgYW4gaW50ZXJuYWwge0BsaW5rIEFib3J0Q29udHJvbGxlcn0gd2hlbiBleGNlZWRlZC5cbiAgICogTXVzdCBiZSBgPiAwYC5cbiAgICovXG4gIHRpbWVvdXRNczogbnVtYmVyO1xuICAvKipcbiAgICogQmFzZSBiYWNrb2ZmIGluIG1pbGxpc2Vjb25kcyBmb3IgZnVsbCBqaXR0ZXIgd2hlbiBgUmV0cnktQWZ0ZXJgIGlzIGFic2VudCBvciBpbnZhbGlkLlxuICAgKiBUaGUgZXhwb25lbnRpYWwgc3BhbiBmb3IgYXR0ZW1wdCBgbmAgaXMgYGJhc2VCYWNrb2ZmTXMgKiAyXm5gLCB0aGVuIHRoZSByZXN1bHQgaXMgY2xpcHBlZFxuICAgKiBieSB7QGxpbmsgUmVxdWVzdE9wdGlvbnMubWF4QmFja29mZk1zfSB3aGVuIHRoYXQgb3B0aW9uIGlzIHNldC5cbiAgICogTXVzdCBiZSBgPj0gMGAgKGAwYCBza2lwcyBiYWNrb2ZmIGRlbGF5IGJldHdlZW4gYXR0ZW1wdHMgd2hlbiBmYWxsaW5nIGJhY2sgdG8gaml0dGVyKS5cbiAgICovXG4gIGJhc2VCYWNrb2ZmTXM6IG51bWJlcjtcbiAgLyoqXG4gICAqIE9wdGlvbmFsIGNlaWxpbmcgaW4gbWlsbGlzZWNvbmRzIGFwcGxpZWQgdG8gdGhlIGZ1bGwtaml0dGVyIGRlbGF5LlxuICAgKiBXaGVuIHNldCwgYE1hdGgubWluKGppdHRlciwgbWF4QmFja29mZk1zKWAgaXMgdXNlZC4gRG9lcyBub3QgY2xpcCBhIHZhbGlkIGBSZXRyeS1BZnRlcmAuXG4gICAqIE11c3QgYmUgYD49IDBgIHdoZW4gcHJvdmlkZWQgKGAwYCBza2lwcyBqaXR0ZXIgd2FpdCkuIE9taXR0ZWQgbWVhbnMgbm8gZXh0cmEgY2xpcC5cbiAgICovXG4gIG1heEJhY2tvZmZNcz86IG51bWJlcjtcbiAgLyoqXG4gICAqIE9wdGlvbmFsIGV4dGVybmFsIHtAbGluayBBYm9ydFNpZ25hbH0uIFdoZW4gYWJvcnRlZCBkdXJpbmcgYW4gYXR0ZW1wdCwgdGhlIGluLWZsaWdodCByZXF1ZXN0XG4gICAqIGlzIGFib3J0ZWQuIE9uIHRoZSBsYXN0IGF0dGVtcHQgdGhpcyBzdXJmYWNlcyBhcyB7QGxpbmsgRmV0Y2hSZXRyaWVyQWJvcnRFcnJvcn0uIElmIHJldHJpZXNcbiAgICogcmVtYWluLCBiYWNrb2ZmIGlzIHNraXBwZWQgYW5kIHRoZSBuZXh0IGF0dGVtcHQgdGhyb3dzXG4gICAqIHtAbGluayBGZXRjaFJldHJpZXJBbHJlYWR5QWJvcnRlZEVycm9yfS4gQWJvcnRpbmcgZHVyaW5nIGEgZnVsbC1qaXR0ZXIgb3IgYFJldHJ5LUFmdGVyYCB3YWl0XG4gICAqIGVuZHMgdGhhdCB3YWl0IGltbWVkaWF0ZWx5IGFuZCB0aHJvd3Mge0BsaW5rIEZldGNoUmV0cmllckFscmVhZHlBYm9ydGVkRXJyb3J9LiBEaXN0aW5jdCBmcm9tXG4gICAqIHBlci1hdHRlbXB0IHRpbWVvdXQsIHdoaWNoIHJldHJpZXMgcmVtYWluaW5nIGF0dGVtcHRzIGFuZCBvbmx5IHRoZW4gdGhyb3dzXG4gICAqIHtAbGluayBGZXRjaFJldHJpZXJBYm9ydEVycm9yfS5cbiAgICovXG4gIHNpZ25hbD86IEFib3J0U2lnbmFsO1xuICAvKipcbiAgICogSW52b2tlZCBhZnRlciBgcmVzcG9uc2UudGV4dCgpYCB3aGVuIGByZXNwb25zZS5va2AgaXMgZmFsc2UuXG4gICAqIFJldHVybiBgdHJ1ZWAgdG8gc2NoZWR1bGUgYW5vdGhlciBhdHRlbXB0ICh1bnRpbCBgcmV0cmllc2AgaXMgZXhoYXVzdGVkKS5cbiAgICogRGVmYXVsdDoge0BsaW5rIGRlZmF1bHRTaG91bGRSZXRyeX0gKHNlZSB7QGxpbmsgREVGQVVMVF9SRVRSWUFCTEVfSFRUUF9TVEFUVVNFU30pLlxuICAgKlxuICAgKiBAcGFyYW0gcmVzcG9uc2UgLSBOb24tT0sgcmVzcG9uc2UgZnJvbSB0aGUgY3VycmVudCBhdHRlbXB0XG4gICAqIEBwYXJhbSBib2R5IC0gUmVzcG9uc2UgYm9keSB0ZXh0IGZyb20gYHJlc3BvbnNlLnRleHQoKWBcbiAgICogQHJldHVybnMgYHRydWVgIHRvIHNjaGVkdWxlIGFub3RoZXIgYXR0ZW1wdCAodW50aWwgYHJldHJpZXNgIGlzIGV4aGF1c3RlZClcbiAgICovXG4gIHNob3VsZFJldHJ5PzogKHJlc3BvbnNlOiBSZXNwb25zZSwgYm9keTogc3RyaW5nKSA9PiBib29sZWFuO1xufVxuIl19
|
package/lib/core/time/wait.d.ts
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Delays execution for the given duration (used between retry attempts).
|
|
3
3
|
*
|
|
4
|
+
* When `signal` is already aborted, or aborts while waiting, the delay ends immediately so the
|
|
5
|
+
* caller can proceed to its next decision. The promise still resolves; the caller decides how
|
|
6
|
+
* cancellation is reported.
|
|
7
|
+
*
|
|
4
8
|
* @param ms - Delay in milliseconds
|
|
5
|
-
* @
|
|
9
|
+
* @param signal - Optional {@link AbortSignal} that ends the delay early
|
|
10
|
+
* @returns A promise that resolves after `ms`, or sooner if `signal` aborts
|
|
6
11
|
*/
|
|
7
|
-
export declare const wait: (ms: number) => Promise<void>;
|
|
12
|
+
export declare const wait: (ms: number, signal?: AbortSignal) => Promise<void>;
|
package/lib/core/time/wait.js
CHANGED
|
@@ -4,11 +4,29 @@ exports.wait = void 0;
|
|
|
4
4
|
/**
|
|
5
5
|
* Delays execution for the given duration (used between retry attempts).
|
|
6
6
|
*
|
|
7
|
+
* When `signal` is already aborted, or aborts while waiting, the delay ends immediately so the
|
|
8
|
+
* caller can proceed to its next decision. The promise still resolves; the caller decides how
|
|
9
|
+
* cancellation is reported.
|
|
10
|
+
*
|
|
7
11
|
* @param ms - Delay in milliseconds
|
|
8
|
-
* @
|
|
12
|
+
* @param signal - Optional {@link AbortSignal} that ends the delay early
|
|
13
|
+
* @returns A promise that resolves after `ms`, or sooner if `signal` aborts
|
|
9
14
|
*/
|
|
10
|
-
const wait = (ms) => {
|
|
11
|
-
|
|
15
|
+
const wait = (ms, signal) => {
|
|
16
|
+
if (signal?.aborted) {
|
|
17
|
+
return Promise.resolve();
|
|
18
|
+
}
|
|
19
|
+
return new Promise((resolve) => {
|
|
20
|
+
const onAbort = () => {
|
|
21
|
+
clearTimeout(timer);
|
|
22
|
+
resolve();
|
|
23
|
+
};
|
|
24
|
+
const timer = setTimeout(() => {
|
|
25
|
+
signal?.removeEventListener('abort', onAbort);
|
|
26
|
+
resolve();
|
|
27
|
+
}, ms);
|
|
28
|
+
signal?.addEventListener('abort', onAbort, { once: true });
|
|
29
|
+
});
|
|
12
30
|
};
|
|
13
31
|
exports.wait = wait;
|
|
14
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
32
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2FpdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jb3JlL3RpbWUvd2FpdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQTs7Ozs7Ozs7OztHQVVHO0FBQ0ksTUFBTSxJQUFJLEdBQUcsQ0FBQyxFQUFVLEVBQUUsTUFBb0IsRUFBaUIsRUFBRTtJQUN0RSxJQUFJLE1BQU0sRUFBRSxPQUFPLEVBQUUsQ0FBQztRQUNwQixPQUFPLE9BQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUMzQixDQUFDO0lBRUQsT0FBTyxJQUFJLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFO1FBQzdCLE1BQU0sT0FBTyxHQUFHLEdBQVMsRUFBRTtZQUN6QixZQUFZLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDcEIsT0FBTyxFQUFFLENBQUM7UUFDWixDQUFDLENBQUM7UUFFRixNQUFNLEtBQUssR0FBRyxVQUFVLENBQUMsR0FBRyxFQUFFO1lBQzVCLE1BQU0sRUFBRSxtQkFBbUIsQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUM7WUFDOUMsT0FBTyxFQUFFLENBQUM7UUFDWixDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFFUCxNQUFNLEVBQUUsZ0JBQWdCLENBQUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQzdELENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDO0FBbEJXLFFBQUEsSUFBSSxRQWtCZiIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogRGVsYXlzIGV4ZWN1dGlvbiBmb3IgdGhlIGdpdmVuIGR1cmF0aW9uICh1c2VkIGJldHdlZW4gcmV0cnkgYXR0ZW1wdHMpLlxuICpcbiAqIFdoZW4gYHNpZ25hbGAgaXMgYWxyZWFkeSBhYm9ydGVkLCBvciBhYm9ydHMgd2hpbGUgd2FpdGluZywgdGhlIGRlbGF5IGVuZHMgaW1tZWRpYXRlbHkgc28gdGhlXG4gKiBjYWxsZXIgY2FuIHByb2NlZWQgdG8gaXRzIG5leHQgZGVjaXNpb24uIFRoZSBwcm9taXNlIHN0aWxsIHJlc29sdmVzOyB0aGUgY2FsbGVyIGRlY2lkZXMgaG93XG4gKiBjYW5jZWxsYXRpb24gaXMgcmVwb3J0ZWQuXG4gKlxuICogQHBhcmFtIG1zIC0gRGVsYXkgaW4gbWlsbGlzZWNvbmRzXG4gKiBAcGFyYW0gc2lnbmFsIC0gT3B0aW9uYWwge0BsaW5rIEFib3J0U2lnbmFsfSB0aGF0IGVuZHMgdGhlIGRlbGF5IGVhcmx5XG4gKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyBhZnRlciBgbXNgLCBvciBzb29uZXIgaWYgYHNpZ25hbGAgYWJvcnRzXG4gKi9cbmV4cG9ydCBjb25zdCB3YWl0ID0gKG1zOiBudW1iZXIsIHNpZ25hbD86IEFib3J0U2lnbmFsKTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gIGlmIChzaWduYWw/LmFib3J0ZWQpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cblxuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICBjb25zdCBvbkFib3J0ID0gKCk6IHZvaWQgPT4ge1xuICAgICAgY2xlYXJUaW1lb3V0KHRpbWVyKTtcbiAgICAgIHJlc29sdmUoKTtcbiAgICB9O1xuXG4gICAgY29uc3QgdGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHNpZ25hbD8ucmVtb3ZlRXZlbnRMaXN0ZW5lcignYWJvcnQnLCBvbkFib3J0KTtcbiAgICAgIHJlc29sdmUoKTtcbiAgICB9LCBtcyk7XG5cbiAgICBzaWduYWw/LmFkZEV2ZW50TGlzdGVuZXIoJ2Fib3J0Jywgb25BYm9ydCwgeyBvbmNlOiB0cnVlIH0pO1xuICB9KTtcbn07XG4iXX0=
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public entry for the default HTTP retry predicate.
|
|
3
|
+
*
|
|
4
|
+
* The implementation stays in core so retry execution can share it without a feature-to-feature import.
|
|
5
|
+
*/
|
|
6
|
+
export { DEFAULT_RETRYABLE_HTTP_STATUSES, defaultShouldRetry, } from './core/policy/default-should-retry';
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.defaultShouldRetry = exports.DEFAULT_RETRYABLE_HTTP_STATUSES = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Public entry for the default HTTP retry predicate.
|
|
6
|
+
*
|
|
7
|
+
* The implementation stays in core so retry execution can share it without a feature-to-feature import.
|
|
8
|
+
*/
|
|
9
|
+
var default_should_retry_1 = require("./core/policy/default-should-retry");
|
|
10
|
+
Object.defineProperty(exports, "DEFAULT_RETRYABLE_HTTP_STATUSES", { enumerable: true, get: function () { return default_should_retry_1.DEFAULT_RETRYABLE_HTTP_STATUSES; } });
|
|
11
|
+
Object.defineProperty(exports, "defaultShouldRetry", { enumerable: true, get: function () { return default_should_retry_1.defaultShouldRetry; } });
|
|
12
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVmYXVsdC1zaG91bGQtcmV0cnkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvZGVmYXVsdC1zaG91bGQtcmV0cnkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUE7Ozs7R0FJRztBQUNILDJFQUc0QztBQUYxQyx1SUFBQSwrQkFBK0IsT0FBQTtBQUMvQiwwSEFBQSxrQkFBa0IsT0FBQSIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogUHVibGljIGVudHJ5IGZvciB0aGUgZGVmYXVsdCBIVFRQIHJldHJ5IHByZWRpY2F0ZS5cbiAqXG4gKiBUaGUgaW1wbGVtZW50YXRpb24gc3RheXMgaW4gY29yZSBzbyByZXRyeSBleGVjdXRpb24gY2FuIHNoYXJlIGl0IHdpdGhvdXQgYSBmZWF0dXJlLXRvLWZlYXR1cmUgaW1wb3J0LlxuICovXG5leHBvcnQge1xuICBERUZBVUxUX1JFVFJZQUJMRV9IVFRQX1NUQVRVU0VTLFxuICBkZWZhdWx0U2hvdWxkUmV0cnksXG59IGZyb20gJy4vY29yZS9wb2xpY3kvZGVmYXVsdC1zaG91bGQtcmV0cnknO1xuIl19
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { RequestOptions } from './options';
|
|
1
|
+
import { RequestOptions } from './core/options';
|
|
2
|
+
export type { FetchInitOptions, RequestOptions } from './core/options';
|
|
2
3
|
/**
|
|
3
4
|
* Wraps `fetch` with retries, per-attempt timeout, Retry-After support, full-jitter backoff, and
|
|
4
5
|
* optional cancellation.
|
|
@@ -6,9 +7,10 @@ import { RequestOptions } from './options';
|
|
|
6
7
|
* Each attempt calls {@link timedFetch} with `timeoutMs`. Non-OK responses are retried when
|
|
7
8
|
* `shouldRetry` returns `true` (default: {@link defaultShouldRetry}). Between HTTP retries, a
|
|
8
9
|
* valid `Retry-After` header (delta-seconds or HTTP-date) is preferred over full jitter; abort
|
|
9
|
-
* and network retries always use full jitter.
|
|
10
|
-
*
|
|
11
|
-
* `
|
|
10
|
+
* and network retries always use full jitter. Those waits end immediately when
|
|
11
|
+
* {@link RequestOptions.signal} aborts. Optional {@link RequestOptions.maxBackoffMs} clips the
|
|
12
|
+
* jitter result, not a valid `Retry-After`. The same {@link FetchInitOptions} (including `body`)
|
|
13
|
+
* is reused on every attempt.
|
|
12
14
|
*
|
|
13
15
|
* @param url - Request URL passed to `fetch`
|
|
14
16
|
* @param options - {@link RequestOptions} controlling retries, timeout, request init, and cancellation
|
|
@@ -17,7 +19,8 @@ import { RequestOptions } from './options';
|
|
|
17
19
|
* @throws {FetchRetrierInvalidOptionsError} If `retries < 1`, `timeoutMs <= 0`, `baseBackoffMs < 0`,
|
|
18
20
|
* or `maxBackoffMs` is set and `< 0`
|
|
19
21
|
* @throws {FetchRetrierAlreadyAbortedError} If `options.signal` is already aborted before an attempt,
|
|
20
|
-
* including
|
|
22
|
+
* including after an in-flight external abort while retries remain, or when it aborts during
|
|
23
|
+
* backoff before the next attempt
|
|
21
24
|
* @throws {FetchRetrierHttpError} On a non-OK response that is not retried or after the last attempt
|
|
22
25
|
* (includes `status` and `body`)
|
|
23
26
|
* @throws {FetchRetrierNetworkError} On a network `TypeError` after the last attempt
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fetchRetrier = void 0;
|
|
4
|
+
const jitter_1 = require("./core/backoff/jitter");
|
|
5
|
+
const retry_after_1 = require("./core/backoff/retry-after");
|
|
6
|
+
const errors_1 = require("./core/errors");
|
|
7
|
+
const timed_fetch_1 = require("./core/http/timed-fetch");
|
|
8
|
+
const default_should_retry_1 = require("./core/policy/default-should-retry");
|
|
9
|
+
const validate_options_1 = require("./core/policy/validate-options");
|
|
10
|
+
const retry_predicates_1 = require("./core/retry-predicates");
|
|
11
|
+
const wait_1 = require("./core/time/wait");
|
|
12
|
+
/**
|
|
13
|
+
* Wraps `fetch` with retries, per-attempt timeout, Retry-After support, full-jitter backoff, and
|
|
14
|
+
* optional cancellation.
|
|
15
|
+
*
|
|
16
|
+
* Each attempt calls {@link timedFetch} with `timeoutMs`. Non-OK responses are retried when
|
|
17
|
+
* `shouldRetry` returns `true` (default: {@link defaultShouldRetry}). Between HTTP retries, a
|
|
18
|
+
* valid `Retry-After` header (delta-seconds or HTTP-date) is preferred over full jitter; abort
|
|
19
|
+
* and network retries always use full jitter. Those waits end immediately when
|
|
20
|
+
* {@link RequestOptions.signal} aborts. Optional {@link RequestOptions.maxBackoffMs} clips the
|
|
21
|
+
* jitter result, not a valid `Retry-After`. The same {@link FetchInitOptions} (including `body`)
|
|
22
|
+
* is reused on every attempt.
|
|
23
|
+
*
|
|
24
|
+
* @param url - Request URL passed to `fetch`
|
|
25
|
+
* @param options - {@link RequestOptions} controlling retries, timeout, request init, and cancellation
|
|
26
|
+
* @returns The first {@link Response} for which `ok` is `true`
|
|
27
|
+
* @throws {FetchRetrierError} All failures from this function are subclasses of this class
|
|
28
|
+
* @throws {FetchRetrierInvalidOptionsError} If `retries < 1`, `timeoutMs <= 0`, `baseBackoffMs < 0`,
|
|
29
|
+
* or `maxBackoffMs` is set and `< 0`
|
|
30
|
+
* @throws {FetchRetrierAlreadyAbortedError} If `options.signal` is already aborted before an attempt,
|
|
31
|
+
* including after an in-flight external abort while retries remain, or when it aborts during
|
|
32
|
+
* backoff before the next attempt
|
|
33
|
+
* @throws {FetchRetrierHttpError} On a non-OK response that is not retried or after the last attempt
|
|
34
|
+
* (includes `status` and `body`)
|
|
35
|
+
* @throws {FetchRetrierNetworkError} On a network `TypeError` after the last attempt
|
|
36
|
+
* @throws {FetchRetrierAbortError} On per-attempt timeout after the last attempt, or external abort
|
|
37
|
+
* on the last attempt
|
|
38
|
+
* @throws {FetchRetrierUnreachableError} If the retry loop exits without returning (internal bug)
|
|
39
|
+
*/
|
|
40
|
+
const fetchRetrier = async (url, options) => {
|
|
41
|
+
const { headers, init, retries, timeoutMs, baseBackoffMs, maxBackoffMs, signal: externalSignal, shouldRetry = default_should_retry_1.defaultShouldRetry, } = options;
|
|
42
|
+
(0, validate_options_1.validateRequestOptions)({ retries, timeoutMs, baseBackoffMs, maxBackoffMs });
|
|
43
|
+
for (let attempt = 1; attempt <= retries; attempt++) {
|
|
44
|
+
if (externalSignal?.aborted) {
|
|
45
|
+
throw new errors_1.FetchRetrierAlreadyAbortedError();
|
|
46
|
+
}
|
|
47
|
+
try {
|
|
48
|
+
const res = await (0, timed_fetch_1.timedFetch)(url, {
|
|
49
|
+
timeoutMs,
|
|
50
|
+
init,
|
|
51
|
+
headers,
|
|
52
|
+
signal: externalSignal,
|
|
53
|
+
});
|
|
54
|
+
if (res.ok) {
|
|
55
|
+
return res;
|
|
56
|
+
}
|
|
57
|
+
const text = await res.text();
|
|
58
|
+
const isContinue = shouldRetry(res, text);
|
|
59
|
+
if (!isContinue) {
|
|
60
|
+
throw new errors_1.FetchRetrierHttpError(`Non-retriable HTTP error: ${res.status}`, res.status, text);
|
|
61
|
+
}
|
|
62
|
+
if ((0, retry_predicates_1.isLastAttempt)(attempt, retries)) {
|
|
63
|
+
throw new errors_1.FetchRetrierHttpError(`HTTP ${res.status}`, res.status, text);
|
|
64
|
+
}
|
|
65
|
+
await (0, wait_1.wait)((0, retry_after_1.resolveRetryDelayMs)(res, baseBackoffMs, attempt, maxBackoffMs), externalSignal);
|
|
66
|
+
}
|
|
67
|
+
catch (err) {
|
|
68
|
+
if (err instanceof Error && err.name === 'AbortError') {
|
|
69
|
+
if ((0, retry_predicates_1.isLastAttempt)(attempt, retries)) {
|
|
70
|
+
throw err instanceof errors_1.FetchRetrierAbortError ? err : new errors_1.FetchRetrierAbortError();
|
|
71
|
+
}
|
|
72
|
+
await (0, wait_1.wait)((0, jitter_1.fullJitter)(baseBackoffMs, attempt, maxBackoffMs), externalSignal);
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
if (err instanceof TypeError) {
|
|
76
|
+
if ((0, retry_predicates_1.isLastAttempt)(attempt, retries)) {
|
|
77
|
+
throw new errors_1.FetchRetrierNetworkError('Network error', err);
|
|
78
|
+
}
|
|
79
|
+
await (0, wait_1.wait)((0, jitter_1.fullJitter)(baseBackoffMs, attempt, maxBackoffMs), externalSignal);
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
throw err;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
throw new errors_1.FetchRetrierUnreachableError();
|
|
86
|
+
};
|
|
87
|
+
exports.fetchRetrier = fetchRetrier;
|
|
88
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmV0Y2gtcmV0cmllci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9mZXRjaC1yZXRyaWVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLGtEQUFtRDtBQUNuRCw0REFBaUU7QUFDakUsMENBTXVCO0FBQ3ZCLHlEQUFxRDtBQUVyRCw2RUFBd0U7QUFDeEUscUVBQXdFO0FBQ3hFLDhEQUF3RDtBQUN4RCwyQ0FBd0M7QUFJeEM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQTJCRztBQUNJLE1BQU0sWUFBWSxHQUFHLEtBQUssRUFBRSxHQUFXLEVBQUUsT0FBdUIsRUFBcUIsRUFBRTtJQUM1RixNQUFNLEVBQ0osT0FBTyxFQUNQLElBQUksRUFDSixPQUFPLEVBQ1AsU0FBUyxFQUNULGFBQWEsRUFDYixZQUFZLEVBQ1osTUFBTSxFQUFFLGNBQWMsRUFDdEIsV0FBVyxHQUFHLHlDQUFrQixHQUNqQyxHQUFHLE9BQU8sQ0FBQztJQUVaLElBQUEseUNBQXNCLEVBQUMsRUFBRSxPQUFPLEVBQUUsU0FBUyxFQUFFLGFBQWEsRUFBRSxZQUFZLEVBQUUsQ0FBQyxDQUFDO0lBRTVFLEtBQUssSUFBSSxPQUFPLEdBQUcsQ0FBQyxFQUFFLE9BQU8sSUFBSSxPQUFPLEVBQUUsT0FBTyxFQUFFLEVBQUUsQ0FBQztRQUNwRCxJQUFJLGNBQWMsRUFBRSxPQUFPLEVBQUUsQ0FBQztZQUM1QixNQUFNLElBQUksd0NBQStCLEVBQUUsQ0FBQztRQUM5QyxDQUFDO1FBRUQsSUFBSSxDQUFDO1lBQ0gsTUFBTSxHQUFHLEdBQUcsTUFBTSxJQUFBLHdCQUFVLEVBQUMsR0FBRyxFQUFFO2dCQUNoQyxTQUFTO2dCQUNULElBQUk7Z0JBQ0osT0FBTztnQkFDUCxNQUFNLEVBQUUsY0FBYzthQUN2QixDQUFDLENBQUM7WUFFSCxJQUFJLEdBQUcsQ0FBQyxFQUFFLEVBQUUsQ0FBQztnQkFDWCxPQUFPLEdBQUcsQ0FBQztZQUNiLENBQUM7WUFFRCxNQUFNLElBQUksR0FBRyxNQUFNLEdBQUcsQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUM5QixNQUFNLFVBQVUsR0FBRyxXQUFXLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDO1lBRTFDLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztnQkFDaEIsTUFBTSxJQUFJLDhCQUFxQixDQUFDLDZCQUE2QixHQUFHLENBQUMsTUFBTSxFQUFFLEVBQUUsR0FBRyxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsQ0FBQztZQUMvRixDQUFDO1lBRUQsSUFBSSxJQUFBLGdDQUFhLEVBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxFQUFFLENBQUM7Z0JBQ3BDLE1BQU0sSUFBSSw4QkFBcUIsQ0FBQyxRQUFRLEdBQUcsQ0FBQyxNQUFNLEVBQUUsRUFBRSxHQUFHLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQzFFLENBQUM7WUFFRCxNQUFNLElBQUEsV0FBSSxFQUFDLElBQUEsaUNBQW1CLEVBQUMsR0FBRyxFQUFFLGFBQWEsRUFBRSxPQUFPLEVBQUUsWUFBWSxDQUFDLEVBQUUsY0FBYyxDQUFDLENBQUM7UUFDN0YsQ0FBQztRQUFDLE9BQU8sR0FBWSxFQUFFLENBQUM7WUFDdEIsSUFBSSxHQUFHLFlBQVksS0FBSyxJQUFJLEdBQUcsQ0FBQyxJQUFJLEtBQUssWUFBWSxFQUFFLENBQUM7Z0JBQ3RELElBQUksSUFBQSxnQ0FBYSxFQUFDLE9BQU8sRUFBRSxPQUFPLENBQUMsRUFBRSxDQUFDO29CQUNwQyxNQUFNLEdBQUcsWUFBWSwrQkFBc0IsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxJQUFJLCtCQUFzQixFQUFFLENBQUM7Z0JBQ25GLENBQUM7Z0JBQ0QsTUFBTSxJQUFBLFdBQUksRUFBQyxJQUFBLG1CQUFVLEVBQUMsYUFBYSxFQUFFLE9BQU8sRUFBRSxZQUFZLENBQUMsRUFBRSxjQUFjLENBQUMsQ0FBQztnQkFDN0UsU0FBUztZQUNYLENBQUM7WUFFRCxJQUFJLEdBQUcsWUFBWSxTQUFTLEVBQUUsQ0FBQztnQkFDN0IsSUFBSSxJQUFBLGdDQUFhLEVBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxFQUFFLENBQUM7b0JBQ3BDLE1BQU0sSUFBSSxpQ0FBd0IsQ0FBQyxlQUFlLEVBQUUsR0FBRyxDQUFDLENBQUM7Z0JBQzNELENBQUM7Z0JBQ0QsTUFBTSxJQUFBLFdBQUksRUFBQyxJQUFBLG1CQUFVLEVBQUMsYUFBYSxFQUFFLE9BQU8sRUFBRSxZQUFZLENBQUMsRUFBRSxjQUFjLENBQUMsQ0FBQztnQkFDN0UsU0FBUztZQUNYLENBQUM7WUFFRCxNQUFNLEdBQUcsQ0FBQztRQUNaLENBQUM7SUFDSCxDQUFDO0lBRUQsTUFBTSxJQUFJLHFDQUE0QixFQUFFLENBQUM7QUFDM0MsQ0FBQyxDQUFDO0FBakVXLFFBQUEsWUFBWSxnQkFpRXZCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZnVsbEppdHRlciB9IGZyb20gJy4vY29yZS9iYWNrb2ZmL2ppdHRlcic7XG5pbXBvcnQgeyByZXNvbHZlUmV0cnlEZWxheU1zIH0gZnJvbSAnLi9jb3JlL2JhY2tvZmYvcmV0cnktYWZ0ZXInO1xuaW1wb3J0IHtcbiAgRmV0Y2hSZXRyaWVyQWJvcnRFcnJvcixcbiAgRmV0Y2hSZXRyaWVyQWxyZWFkeUFib3J0ZWRFcnJvcixcbiAgRmV0Y2hSZXRyaWVySHR0cEVycm9yLFxuICBGZXRjaFJldHJpZXJOZXR3b3JrRXJyb3IsXG4gIEZldGNoUmV0cmllclVucmVhY2hhYmxlRXJyb3IsXG59IGZyb20gJy4vY29yZS9lcnJvcnMnO1xuaW1wb3J0IHsgdGltZWRGZXRjaCB9IGZyb20gJy4vY29yZS9odHRwL3RpbWVkLWZldGNoJztcbmltcG9ydCB7IFJlcXVlc3RPcHRpb25zIH0gZnJvbSAnLi9jb3JlL29wdGlvbnMnO1xuaW1wb3J0IHsgZGVmYXVsdFNob3VsZFJldHJ5IH0gZnJvbSAnLi9jb3JlL3BvbGljeS9kZWZhdWx0LXNob3VsZC1yZXRyeSc7XG5pbXBvcnQgeyB2YWxpZGF0ZVJlcXVlc3RPcHRpb25zIH0gZnJvbSAnLi9jb3JlL3BvbGljeS92YWxpZGF0ZS1vcHRpb25zJztcbmltcG9ydCB7IGlzTGFzdEF0dGVtcHQgfSBmcm9tICcuL2NvcmUvcmV0cnktcHJlZGljYXRlcyc7XG5pbXBvcnQgeyB3YWl0IH0gZnJvbSAnLi9jb3JlL3RpbWUvd2FpdCc7XG5cbmV4cG9ydCB0eXBlIHsgRmV0Y2hJbml0T3B0aW9ucywgUmVxdWVzdE9wdGlvbnMgfSBmcm9tICcuL2NvcmUvb3B0aW9ucyc7XG5cbi8qKlxuICogV3JhcHMgYGZldGNoYCB3aXRoIHJldHJpZXMsIHBlci1hdHRlbXB0IHRpbWVvdXQsIFJldHJ5LUFmdGVyIHN1cHBvcnQsIGZ1bGwtaml0dGVyIGJhY2tvZmYsIGFuZFxuICogb3B0aW9uYWwgY2FuY2VsbGF0aW9uLlxuICpcbiAqIEVhY2ggYXR0ZW1wdCBjYWxscyB7QGxpbmsgdGltZWRGZXRjaH0gd2l0aCBgdGltZW91dE1zYC4gTm9uLU9LIHJlc3BvbnNlcyBhcmUgcmV0cmllZCB3aGVuXG4gKiBgc2hvdWxkUmV0cnlgIHJldHVybnMgYHRydWVgIChkZWZhdWx0OiB7QGxpbmsgZGVmYXVsdFNob3VsZFJldHJ5fSkuIEJldHdlZW4gSFRUUCByZXRyaWVzLCBhXG4gKiB2YWxpZCBgUmV0cnktQWZ0ZXJgIGhlYWRlciAoZGVsdGEtc2Vjb25kcyBvciBIVFRQLWRhdGUpIGlzIHByZWZlcnJlZCBvdmVyIGZ1bGwgaml0dGVyOyBhYm9ydFxuICogYW5kIG5ldHdvcmsgcmV0cmllcyBhbHdheXMgdXNlIGZ1bGwgaml0dGVyLiBUaG9zZSB3YWl0cyBlbmQgaW1tZWRpYXRlbHkgd2hlblxuICoge0BsaW5rIFJlcXVlc3RPcHRpb25zLnNpZ25hbH0gYWJvcnRzLiBPcHRpb25hbCB7QGxpbmsgUmVxdWVzdE9wdGlvbnMubWF4QmFja29mZk1zfSBjbGlwcyB0aGVcbiAqIGppdHRlciByZXN1bHQsIG5vdCBhIHZhbGlkIGBSZXRyeS1BZnRlcmAuIFRoZSBzYW1lIHtAbGluayBGZXRjaEluaXRPcHRpb25zfSAoaW5jbHVkaW5nIGBib2R5YClcbiAqIGlzIHJldXNlZCBvbiBldmVyeSBhdHRlbXB0LlxuICpcbiAqIEBwYXJhbSB1cmwgLSBSZXF1ZXN0IFVSTCBwYXNzZWQgdG8gYGZldGNoYFxuICogQHBhcmFtIG9wdGlvbnMgLSB7QGxpbmsgUmVxdWVzdE9wdGlvbnN9IGNvbnRyb2xsaW5nIHJldHJpZXMsIHRpbWVvdXQsIHJlcXVlc3QgaW5pdCwgYW5kIGNhbmNlbGxhdGlvblxuICogQHJldHVybnMgVGhlIGZpcnN0IHtAbGluayBSZXNwb25zZX0gZm9yIHdoaWNoIGBva2AgaXMgYHRydWVgXG4gKiBAdGhyb3dzIHtGZXRjaFJldHJpZXJFcnJvcn0gQWxsIGZhaWx1cmVzIGZyb20gdGhpcyBmdW5jdGlvbiBhcmUgc3ViY2xhc3NlcyBvZiB0aGlzIGNsYXNzXG4gKiBAdGhyb3dzIHtGZXRjaFJldHJpZXJJbnZhbGlkT3B0aW9uc0Vycm9yfSBJZiBgcmV0cmllcyA8IDFgLCBgdGltZW91dE1zIDw9IDBgLCBgYmFzZUJhY2tvZmZNcyA8IDBgLFxuICogICBvciBgbWF4QmFja29mZk1zYCBpcyBzZXQgYW5kIGA8IDBgXG4gKiBAdGhyb3dzIHtGZXRjaFJldHJpZXJBbHJlYWR5QWJvcnRlZEVycm9yfSBJZiBgb3B0aW9ucy5zaWduYWxgIGlzIGFscmVhZHkgYWJvcnRlZCBiZWZvcmUgYW4gYXR0ZW1wdCxcbiAqICAgaW5jbHVkaW5nIGFmdGVyIGFuIGluLWZsaWdodCBleHRlcm5hbCBhYm9ydCB3aGlsZSByZXRyaWVzIHJlbWFpbiwgb3Igd2hlbiBpdCBhYm9ydHMgZHVyaW5nXG4gKiAgIGJhY2tvZmYgYmVmb3JlIHRoZSBuZXh0IGF0dGVtcHRcbiAqIEB0aHJvd3Mge0ZldGNoUmV0cmllckh0dHBFcnJvcn0gT24gYSBub24tT0sgcmVzcG9uc2UgdGhhdCBpcyBub3QgcmV0cmllZCBvciBhZnRlciB0aGUgbGFzdCBhdHRlbXB0XG4gKiAgIChpbmNsdWRlcyBgc3RhdHVzYCBhbmQgYGJvZHlgKVxuICogQHRocm93cyB7RmV0Y2hSZXRyaWVyTmV0d29ya0Vycm9yfSBPbiBhIG5ldHdvcmsgYFR5cGVFcnJvcmAgYWZ0ZXIgdGhlIGxhc3QgYXR0ZW1wdFxuICogQHRocm93cyB7RmV0Y2hSZXRyaWVyQWJvcnRFcnJvcn0gT24gcGVyLWF0dGVtcHQgdGltZW91dCBhZnRlciB0aGUgbGFzdCBhdHRlbXB0LCBvciBleHRlcm5hbCBhYm9ydFxuICogICBvbiB0aGUgbGFzdCBhdHRlbXB0XG4gKiBAdGhyb3dzIHtGZXRjaFJldHJpZXJVbnJlYWNoYWJsZUVycm9yfSBJZiB0aGUgcmV0cnkgbG9vcCBleGl0cyB3aXRob3V0IHJldHVybmluZyAoaW50ZXJuYWwgYnVnKVxuICovXG5leHBvcnQgY29uc3QgZmV0Y2hSZXRyaWVyID0gYXN5bmMgKHVybDogc3RyaW5nLCBvcHRpb25zOiBSZXF1ZXN0T3B0aW9ucyk6IFByb21pc2U8UmVzcG9uc2U+ID0+IHtcbiAgY29uc3Qge1xuICAgIGhlYWRlcnMsXG4gICAgaW5pdCxcbiAgICByZXRyaWVzLFxuICAgIHRpbWVvdXRNcyxcbiAgICBiYXNlQmFja29mZk1zLFxuICAgIG1heEJhY2tvZmZNcyxcbiAgICBzaWduYWw6IGV4dGVybmFsU2lnbmFsLFxuICAgIHNob3VsZFJldHJ5ID0gZGVmYXVsdFNob3VsZFJldHJ5LFxuICB9ID0gb3B0aW9ucztcblxuICB2YWxpZGF0ZVJlcXVlc3RPcHRpb25zKHsgcmV0cmllcywgdGltZW91dE1zLCBiYXNlQmFja29mZk1zLCBtYXhCYWNrb2ZmTXMgfSk7XG5cbiAgZm9yIChsZXQgYXR0ZW1wdCA9IDE7IGF0dGVtcHQgPD0gcmV0cmllczsgYXR0ZW1wdCsrKSB7XG4gICAgaWYgKGV4dGVybmFsU2lnbmFsPy5hYm9ydGVkKSB7XG4gICAgICB0aHJvdyBuZXcgRmV0Y2hSZXRyaWVyQWxyZWFkeUFib3J0ZWRFcnJvcigpO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXMgPSBhd2FpdCB0aW1lZEZldGNoKHVybCwge1xuICAgICAgICB0aW1lb3V0TXMsXG4gICAgICAgIGluaXQsXG4gICAgICAgIGhlYWRlcnMsXG4gICAgICAgIHNpZ25hbDogZXh0ZXJuYWxTaWduYWwsXG4gICAgICB9KTtcblxuICAgICAgaWYgKHJlcy5vaykge1xuICAgICAgICByZXR1cm4gcmVzO1xuICAgICAgfVxuXG4gICAgICBjb25zdCB0ZXh0ID0gYXdhaXQgcmVzLnRleHQoKTtcbiAgICAgIGNvbnN0IGlzQ29udGludWUgPSBzaG91bGRSZXRyeShyZXMsIHRleHQpO1xuXG4gICAgICBpZiAoIWlzQ29udGludWUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEZldGNoUmV0cmllckh0dHBFcnJvcihgTm9uLXJldHJpYWJsZSBIVFRQIGVycm9yOiAke3Jlcy5zdGF0dXN9YCwgcmVzLnN0YXR1cywgdGV4dCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChpc0xhc3RBdHRlbXB0KGF0dGVtcHQsIHJldHJpZXMpKSB7XG4gICAgICAgIHRocm93IG5ldyBGZXRjaFJldHJpZXJIdHRwRXJyb3IoYEhUVFAgJHtyZXMuc3RhdHVzfWAsIHJlcy5zdGF0dXMsIHRleHQpO1xuICAgICAgfVxuXG4gICAgICBhd2FpdCB3YWl0KHJlc29sdmVSZXRyeURlbGF5TXMocmVzLCBiYXNlQmFja29mZk1zLCBhdHRlbXB0LCBtYXhCYWNrb2ZmTXMpLCBleHRlcm5hbFNpZ25hbCk7XG4gICAgfSBjYXRjaCAoZXJyOiB1bmtub3duKSB7XG4gICAgICBpZiAoZXJyIGluc3RhbmNlb2YgRXJyb3IgJiYgZXJyLm5hbWUgPT09ICdBYm9ydEVycm9yJykge1xuICAgICAgICBpZiAoaXNMYXN0QXR0ZW1wdChhdHRlbXB0LCByZXRyaWVzKSkge1xuICAgICAgICAgIHRocm93IGVyciBpbnN0YW5jZW9mIEZldGNoUmV0cmllckFib3J0RXJyb3IgPyBlcnIgOiBuZXcgRmV0Y2hSZXRyaWVyQWJvcnRFcnJvcigpO1xuICAgICAgICB9XG4gICAgICAgIGF3YWl0IHdhaXQoZnVsbEppdHRlcihiYXNlQmFja29mZk1zLCBhdHRlbXB0LCBtYXhCYWNrb2ZmTXMpLCBleHRlcm5hbFNpZ25hbCk7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoZXJyIGluc3RhbmNlb2YgVHlwZUVycm9yKSB7XG4gICAgICAgIGlmIChpc0xhc3RBdHRlbXB0KGF0dGVtcHQsIHJldHJpZXMpKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEZldGNoUmV0cmllck5ldHdvcmtFcnJvcignTmV0d29yayBlcnJvcicsIGVycik7XG4gICAgICAgIH1cbiAgICAgICAgYXdhaXQgd2FpdChmdWxsSml0dGVyKGJhc2VCYWNrb2ZmTXMsIGF0dGVtcHQsIG1heEJhY2tvZmZNcyksIGV4dGVybmFsU2lnbmFsKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIHRocm93IGVycjtcbiAgICB9XG4gIH1cblxuICB0aHJvdyBuZXcgRmV0Y2hSZXRyaWVyVW5yZWFjaGFibGVFcnJvcigpO1xufTtcbiJdfQ==
|
package/lib/index.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* @module fetch-retrier
|
|
6
6
|
*/
|
|
7
7
|
export { FetchRetrierAbortError, FetchRetrierAlreadyAbortedError, FetchRetrierError, FetchRetrierHttpError, FetchRetrierInvalidOptionsError, FetchRetrierNetworkError, FetchRetrierUnreachableError, } from './core/errors';
|
|
8
|
-
export
|
|
9
|
-
export {
|
|
10
|
-
export {
|
|
11
|
-
export {
|
|
8
|
+
export { DEFAULT_RETRYABLE_HTTP_STATUSES, defaultShouldRetry, } from './default-should-retry';
|
|
9
|
+
export { fetchRetrier } from './fetch-retrier';
|
|
10
|
+
export type { FetchInitOptions, RequestOptions } from './fetch-retrier';
|
|
11
|
+
export { parseRetryAfterMs } from './parse-retry-after';
|
package/lib/index.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* @module fetch-retrier
|
|
7
7
|
*/
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.
|
|
9
|
+
exports.parseRetryAfterMs = exports.fetchRetrier = exports.defaultShouldRetry = exports.DEFAULT_RETRYABLE_HTTP_STATUSES = exports.FetchRetrierUnreachableError = exports.FetchRetrierNetworkError = exports.FetchRetrierInvalidOptionsError = exports.FetchRetrierHttpError = exports.FetchRetrierError = exports.FetchRetrierAlreadyAbortedError = exports.FetchRetrierAbortError = void 0;
|
|
10
10
|
var errors_1 = require("./core/errors");
|
|
11
11
|
Object.defineProperty(exports, "FetchRetrierAbortError", { enumerable: true, get: function () { return errors_1.FetchRetrierAbortError; } });
|
|
12
12
|
Object.defineProperty(exports, "FetchRetrierAlreadyAbortedError", { enumerable: true, get: function () { return errors_1.FetchRetrierAlreadyAbortedError; } });
|
|
@@ -15,11 +15,11 @@ Object.defineProperty(exports, "FetchRetrierHttpError", { enumerable: true, get:
|
|
|
15
15
|
Object.defineProperty(exports, "FetchRetrierInvalidOptionsError", { enumerable: true, get: function () { return errors_1.FetchRetrierInvalidOptionsError; } });
|
|
16
16
|
Object.defineProperty(exports, "FetchRetrierNetworkError", { enumerable: true, get: function () { return errors_1.FetchRetrierNetworkError; } });
|
|
17
17
|
Object.defineProperty(exports, "FetchRetrierUnreachableError", { enumerable: true, get: function () { return errors_1.FetchRetrierUnreachableError; } });
|
|
18
|
-
var
|
|
19
|
-
Object.defineProperty(exports, "parseRetryAfterMs", { enumerable: true, get: function () { return retry_after_1.parseRetryAfterMs; } });
|
|
20
|
-
var fetch_retrier_1 = require("./core/fetch-retrier");
|
|
21
|
-
Object.defineProperty(exports, "fetchRetrier", { enumerable: true, get: function () { return fetch_retrier_1.fetchRetrier; } });
|
|
22
|
-
var default_should_retry_1 = require("./core/policy/default-should-retry");
|
|
18
|
+
var default_should_retry_1 = require("./default-should-retry");
|
|
23
19
|
Object.defineProperty(exports, "DEFAULT_RETRYABLE_HTTP_STATUSES", { enumerable: true, get: function () { return default_should_retry_1.DEFAULT_RETRYABLE_HTTP_STATUSES; } });
|
|
24
20
|
Object.defineProperty(exports, "defaultShouldRetry", { enumerable: true, get: function () { return default_should_retry_1.defaultShouldRetry; } });
|
|
25
|
-
|
|
21
|
+
var fetch_retrier_1 = require("./fetch-retrier");
|
|
22
|
+
Object.defineProperty(exports, "fetchRetrier", { enumerable: true, get: function () { return fetch_retrier_1.fetchRetrier; } });
|
|
23
|
+
var parse_retry_after_1 = require("./parse-retry-after");
|
|
24
|
+
Object.defineProperty(exports, "parseRetryAfterMs", { enumerable: true, get: function () { return parse_retry_after_1.parseRetryAfterMs; } });
|
|
25
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7OztHQUtHOzs7QUFFSCx3Q0FRdUI7QUFQckIsZ0hBQUEsc0JBQXNCLE9BQUE7QUFDdEIseUhBQUEsK0JBQStCLE9BQUE7QUFDL0IsMkdBQUEsaUJBQWlCLE9BQUE7QUFDakIsK0dBQUEscUJBQXFCLE9BQUE7QUFDckIseUhBQUEsK0JBQStCLE9BQUE7QUFDL0Isa0hBQUEsd0JBQXdCLE9BQUE7QUFDeEIsc0hBQUEsNEJBQTRCLE9BQUE7QUFFOUIsK0RBR2dDO0FBRjlCLHVJQUFBLCtCQUErQixPQUFBO0FBQy9CLDBIQUFBLGtCQUFrQixPQUFBO0FBRXBCLGlEQUErQztBQUF0Qyw2R0FBQSxZQUFZLE9BQUE7QUFFckIseURBQXdEO0FBQS9DLHNIQUFBLGlCQUFpQixPQUFBIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBSZXRyeS1lbmFibGVkIGBmZXRjaGAgd3JhcHBlciB3aXRoIHBlci1hdHRlbXB0IHRpbWVvdXQsIFJldHJ5LUFmdGVyIHN1cHBvcnQsIGZ1bGwtaml0dGVyIGJhY2tvZmYsXG4gKiBvcHRpb24gdmFsaWRhdGlvbiwgYW5kIHR5cGVkIGVycm9ycy5cbiAqXG4gKiBAbW9kdWxlIGZldGNoLXJldHJpZXJcbiAqL1xuXG5leHBvcnQge1xuICBGZXRjaFJldHJpZXJBYm9ydEVycm9yLFxuICBGZXRjaFJldHJpZXJBbHJlYWR5QWJvcnRlZEVycm9yLFxuICBGZXRjaFJldHJpZXJFcnJvcixcbiAgRmV0Y2hSZXRyaWVySHR0cEVycm9yLFxuICBGZXRjaFJldHJpZXJJbnZhbGlkT3B0aW9uc0Vycm9yLFxuICBGZXRjaFJldHJpZXJOZXR3b3JrRXJyb3IsXG4gIEZldGNoUmV0cmllclVucmVhY2hhYmxlRXJyb3IsXG59IGZyb20gJy4vY29yZS9lcnJvcnMnO1xuZXhwb3J0IHtcbiAgREVGQVVMVF9SRVRSWUFCTEVfSFRUUF9TVEFUVVNFUyxcbiAgZGVmYXVsdFNob3VsZFJldHJ5LFxufSBmcm9tICcuL2RlZmF1bHQtc2hvdWxkLXJldHJ5JztcbmV4cG9ydCB7IGZldGNoUmV0cmllciB9IGZyb20gJy4vZmV0Y2gtcmV0cmllcic7XG5leHBvcnQgdHlwZSB7IEZldGNoSW5pdE9wdGlvbnMsIFJlcXVlc3RPcHRpb25zIH0gZnJvbSAnLi9mZXRjaC1yZXRyaWVyJztcbmV4cG9ydCB7IHBhcnNlUmV0cnlBZnRlck1zIH0gZnJvbSAnLi9wYXJzZS1yZXRyeS1hZnRlcic7XG4iXX0=
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseRetryAfterMs = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Public entry for parsing a `Retry-After` header.
|
|
6
|
+
*
|
|
7
|
+
* The implementation stays in core because HTTP retry delay selection uses the same function.
|
|
8
|
+
*/
|
|
9
|
+
var retry_after_1 = require("./core/backoff/retry-after");
|
|
10
|
+
Object.defineProperty(exports, "parseRetryAfterMs", { enumerable: true, get: function () { return retry_after_1.parseRetryAfterMs; } });
|
|
11
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFyc2UtcmV0cnktYWZ0ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvcGFyc2UtcmV0cnktYWZ0ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUE7Ozs7R0FJRztBQUNILDBEQUErRDtBQUF0RCxnSEFBQSxpQkFBaUIsT0FBQSIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogUHVibGljIGVudHJ5IGZvciBwYXJzaW5nIGEgYFJldHJ5LUFmdGVyYCBoZWFkZXIuXG4gKlxuICogVGhlIGltcGxlbWVudGF0aW9uIHN0YXlzIGluIGNvcmUgYmVjYXVzZSBIVFRQIHJldHJ5IGRlbGF5IHNlbGVjdGlvbiB1c2VzIHRoZSBzYW1lIGZ1bmN0aW9uLlxuICovXG5leHBvcnQgeyBwYXJzZVJldHJ5QWZ0ZXJNcyB9IGZyb20gJy4vY29yZS9iYWNrb2ZmL3JldHJ5LWFmdGVyJztcbiJdfQ==
|
package/package.json
CHANGED
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
"organization": false
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
|
+
"@gammarers/projen-projects": "^0.5.8",
|
|
35
36
|
"@stylistic/eslint-plugin": "^2",
|
|
36
37
|
"@types/jest": "^30.0.0",
|
|
37
38
|
"@types/node": "^20",
|
|
@@ -44,7 +45,7 @@
|
|
|
44
45
|
"eslint-plugin-import": "^2.32.0",
|
|
45
46
|
"jest": "^30.5.2",
|
|
46
47
|
"jest-junit": "^17",
|
|
47
|
-
"projen": "^0.
|
|
48
|
+
"projen": "^0.104.4",
|
|
48
49
|
"ts-jest": "^29.4.14",
|
|
49
50
|
"ts-node": "^10.9.2",
|
|
50
51
|
"typescript": "6.0.x"
|
|
@@ -63,7 +64,7 @@
|
|
|
63
64
|
"publishConfig": {
|
|
64
65
|
"access": "public"
|
|
65
66
|
},
|
|
66
|
-
"version": "0.
|
|
67
|
+
"version": "0.7.0",
|
|
67
68
|
"jest": {
|
|
68
69
|
"coverageProvider": "v8",
|
|
69
70
|
"testMatch": [
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "dev-fetch-retrier",
|
|
3
|
-
"image": "mcr.microsoft.com/devcontainers/base:trixie",
|
|
4
|
-
"features": {
|
|
5
|
-
"ghcr.io/devcontainers/features/common-utils:2": {
|
|
6
|
-
"username": "developer",
|
|
7
|
-
"upgradePackages": true
|
|
8
|
-
},
|
|
9
|
-
"ghcr.io/devcontainers/features/git:1": {},
|
|
10
|
-
"ghcr.io/devcontainers/features/node:2": {
|
|
11
|
-
"version": "24",
|
|
12
|
-
"npmVersion": "12"
|
|
13
|
-
}
|
|
14
|
-
},
|
|
15
|
-
"workspaceMount": "source=${localWorkspaceFolder},target=/workspace,type=bind",
|
|
16
|
-
"workspaceFolder": "/workspace",
|
|
17
|
-
"mounts": [
|
|
18
|
-
"target=/workspace/node_modules"
|
|
19
|
-
],
|
|
20
|
-
"remoteUser": "developer",
|
|
21
|
-
"remoteEnv": {
|
|
22
|
-
"npm_config_loglevel": "error"
|
|
23
|
-
},
|
|
24
|
-
"postCreateCommand": {
|
|
25
|
-
"fixVolumePerms": "sudo chown -R $(whoami): /workspace"
|
|
26
|
-
}
|
|
27
|
-
}
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.fetchRetrier = void 0;
|
|
4
|
-
const jitter_1 = require("./backoff/jitter");
|
|
5
|
-
const retry_after_1 = require("./backoff/retry-after");
|
|
6
|
-
const errors_1 = require("./errors");
|
|
7
|
-
const timed_fetch_1 = require("./http/timed-fetch");
|
|
8
|
-
const default_should_retry_1 = require("./policy/default-should-retry");
|
|
9
|
-
const validate_options_1 = require("./policy/validate-options");
|
|
10
|
-
const retry_predicates_1 = require("./retry-predicates");
|
|
11
|
-
const wait_1 = require("./time/wait");
|
|
12
|
-
/**
|
|
13
|
-
* Wraps `fetch` with retries, per-attempt timeout, Retry-After support, full-jitter backoff, and
|
|
14
|
-
* optional cancellation.
|
|
15
|
-
*
|
|
16
|
-
* Each attempt calls {@link timedFetch} with `timeoutMs`. Non-OK responses are retried when
|
|
17
|
-
* `shouldRetry` returns `true` (default: {@link defaultShouldRetry}). Between HTTP retries, a
|
|
18
|
-
* valid `Retry-After` header (delta-seconds or HTTP-date) is preferred over full jitter; abort
|
|
19
|
-
* and network retries always use full jitter. Optional {@link RequestOptions.maxBackoffMs} clips
|
|
20
|
-
* the jitter result, not a valid `Retry-After`. The same {@link FetchInitOptions} (including
|
|
21
|
-
* `body`) is reused on every attempt.
|
|
22
|
-
*
|
|
23
|
-
* @param url - Request URL passed to `fetch`
|
|
24
|
-
* @param options - {@link RequestOptions} controlling retries, timeout, request init, and cancellation
|
|
25
|
-
* @returns The first {@link Response} for which `ok` is `true`
|
|
26
|
-
* @throws {FetchRetrierError} All failures from this function are subclasses of this class
|
|
27
|
-
* @throws {FetchRetrierInvalidOptionsError} If `retries < 1`, `timeoutMs <= 0`, `baseBackoffMs < 0`,
|
|
28
|
-
* or `maxBackoffMs` is set and `< 0`
|
|
29
|
-
* @throws {FetchRetrierAlreadyAbortedError} If `options.signal` is already aborted before an attempt,
|
|
30
|
-
* including the next attempt after an in-flight external abort while retries remain
|
|
31
|
-
* @throws {FetchRetrierHttpError} On a non-OK response that is not retried or after the last attempt
|
|
32
|
-
* (includes `status` and `body`)
|
|
33
|
-
* @throws {FetchRetrierNetworkError} On a network `TypeError` after the last attempt
|
|
34
|
-
* @throws {FetchRetrierAbortError} On per-attempt timeout after the last attempt, or external abort
|
|
35
|
-
* on the last attempt
|
|
36
|
-
* @throws {FetchRetrierUnreachableError} If the retry loop exits without returning (internal bug)
|
|
37
|
-
*/
|
|
38
|
-
const fetchRetrier = async (url, options) => {
|
|
39
|
-
const { headers, init, retries, timeoutMs, baseBackoffMs, maxBackoffMs, signal: externalSignal, shouldRetry = default_should_retry_1.defaultShouldRetry, } = options;
|
|
40
|
-
(0, validate_options_1.validateRequestOptions)({ retries, timeoutMs, baseBackoffMs, maxBackoffMs });
|
|
41
|
-
for (let attempt = 1; attempt <= retries; attempt++) {
|
|
42
|
-
if (externalSignal?.aborted) {
|
|
43
|
-
throw new errors_1.FetchRetrierAlreadyAbortedError();
|
|
44
|
-
}
|
|
45
|
-
try {
|
|
46
|
-
const res = await (0, timed_fetch_1.timedFetch)(url, {
|
|
47
|
-
timeoutMs,
|
|
48
|
-
init,
|
|
49
|
-
headers,
|
|
50
|
-
signal: externalSignal,
|
|
51
|
-
});
|
|
52
|
-
if (res.ok) {
|
|
53
|
-
return res;
|
|
54
|
-
}
|
|
55
|
-
const text = await res.text();
|
|
56
|
-
const isContinue = shouldRetry(res, text);
|
|
57
|
-
if (!isContinue) {
|
|
58
|
-
throw new errors_1.FetchRetrierHttpError(`Non-retriable HTTP error: ${res.status}`, res.status, text);
|
|
59
|
-
}
|
|
60
|
-
if ((0, retry_predicates_1.isLastAttempt)(attempt, retries)) {
|
|
61
|
-
throw new errors_1.FetchRetrierHttpError(`HTTP ${res.status}`, res.status, text);
|
|
62
|
-
}
|
|
63
|
-
await (0, wait_1.wait)((0, retry_after_1.resolveRetryDelayMs)(res, baseBackoffMs, attempt, maxBackoffMs));
|
|
64
|
-
}
|
|
65
|
-
catch (err) {
|
|
66
|
-
if (err instanceof Error && err.name === 'AbortError') {
|
|
67
|
-
if ((0, retry_predicates_1.isLastAttempt)(attempt, retries)) {
|
|
68
|
-
throw err instanceof errors_1.FetchRetrierAbortError ? err : new errors_1.FetchRetrierAbortError();
|
|
69
|
-
}
|
|
70
|
-
await (0, wait_1.wait)((0, jitter_1.fullJitter)(baseBackoffMs, attempt, maxBackoffMs));
|
|
71
|
-
continue;
|
|
72
|
-
}
|
|
73
|
-
if (err instanceof TypeError) {
|
|
74
|
-
if ((0, retry_predicates_1.isLastAttempt)(attempt, retries)) {
|
|
75
|
-
throw new errors_1.FetchRetrierNetworkError('Network error', err);
|
|
76
|
-
}
|
|
77
|
-
await (0, wait_1.wait)((0, jitter_1.fullJitter)(baseBackoffMs, attempt, maxBackoffMs));
|
|
78
|
-
continue;
|
|
79
|
-
}
|
|
80
|
-
throw err;
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
throw new errors_1.FetchRetrierUnreachableError();
|
|
84
|
-
};
|
|
85
|
-
exports.fetchRetrier = fetchRetrier;
|
|
86
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmV0Y2gtcmV0cmllci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb3JlL2ZldGNoLXJldHJpZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsNkNBQThDO0FBQzlDLHVEQUE0RDtBQUM1RCxxQ0FNa0I7QUFDbEIsb0RBQWdEO0FBRWhELHdFQUFtRTtBQUNuRSxnRUFBbUU7QUFDbkUseURBQW1EO0FBQ25ELHNDQUFtQztBQUVuQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXlCRztBQUNJLE1BQU0sWUFBWSxHQUFHLEtBQUssRUFBRSxHQUFXLEVBQUUsT0FBdUIsRUFBcUIsRUFBRTtJQUM1RixNQUFNLEVBQ0osT0FBTyxFQUNQLElBQUksRUFDSixPQUFPLEVBQ1AsU0FBUyxFQUNULGFBQWEsRUFDYixZQUFZLEVBQ1osTUFBTSxFQUFFLGNBQWMsRUFDdEIsV0FBVyxHQUFHLHlDQUFrQixHQUNqQyxHQUFHLE9BQU8sQ0FBQztJQUVaLElBQUEseUNBQXNCLEVBQUMsRUFBRSxPQUFPLEVBQUUsU0FBUyxFQUFFLGFBQWEsRUFBRSxZQUFZLEVBQUUsQ0FBQyxDQUFDO0lBRTVFLEtBQUssSUFBSSxPQUFPLEdBQUcsQ0FBQyxFQUFFLE9BQU8sSUFBSSxPQUFPLEVBQUUsT0FBTyxFQUFFLEVBQUUsQ0FBQztRQUNwRCxJQUFJLGNBQWMsRUFBRSxPQUFPLEVBQUUsQ0FBQztZQUM1QixNQUFNLElBQUksd0NBQStCLEVBQUUsQ0FBQztRQUM5QyxDQUFDO1FBRUQsSUFBSSxDQUFDO1lBQ0gsTUFBTSxHQUFHLEdBQUcsTUFBTSxJQUFBLHdCQUFVLEVBQUMsR0FBRyxFQUFFO2dCQUNoQyxTQUFTO2dCQUNULElBQUk7Z0JBQ0osT0FBTztnQkFDUCxNQUFNLEVBQUUsY0FBYzthQUN2QixDQUFDLENBQUM7WUFFSCxJQUFJLEdBQUcsQ0FBQyxFQUFFLEVBQUUsQ0FBQztnQkFDWCxPQUFPLEdBQUcsQ0FBQztZQUNiLENBQUM7WUFFRCxNQUFNLElBQUksR0FBRyxNQUFNLEdBQUcsQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUM5QixNQUFNLFVBQVUsR0FBRyxXQUFXLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDO1lBRTFDLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztnQkFDaEIsTUFBTSxJQUFJLDhCQUFxQixDQUFDLDZCQUE2QixHQUFHLENBQUMsTUFBTSxFQUFFLEVBQUUsR0FBRyxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsQ0FBQztZQUMvRixDQUFDO1lBRUQsSUFBSSxJQUFBLGdDQUFhLEVBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxFQUFFLENBQUM7Z0JBQ3BDLE1BQU0sSUFBSSw4QkFBcUIsQ0FBQyxRQUFRLEdBQUcsQ0FBQyxNQUFNLEVBQUUsRUFBRSxHQUFHLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQzFFLENBQUM7WUFFRCxNQUFNLElBQUEsV0FBSSxFQUFDLElBQUEsaUNBQW1CLEVBQUMsR0FBRyxFQUFFLGFBQWEsRUFBRSxPQUFPLEVBQUUsWUFBWSxDQUFDLENBQUMsQ0FBQztRQUM3RSxDQUFDO1FBQUMsT0FBTyxHQUFZLEVBQUUsQ0FBQztZQUN0QixJQUFJLEdBQUcsWUFBWSxLQUFLLElBQUksR0FBRyxDQUFDLElBQUksS0FBSyxZQUFZLEVBQUUsQ0FBQztnQkFDdEQsSUFBSSxJQUFBLGdDQUFhLEVBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxFQUFFLENBQUM7b0JBQ3BDLE1BQU0sR0FBRyxZQUFZLCtCQUFzQixDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLElBQUksK0JBQXNCLEVBQUUsQ0FBQztnQkFDbkYsQ0FBQztnQkFDRCxNQUFNLElBQUEsV0FBSSxFQUFDLElBQUEsbUJBQVUsRUFBQyxhQUFhLEVBQUUsT0FBTyxFQUFFLFlBQVksQ0FBQyxDQUFDLENBQUM7Z0JBQzdELFNBQVM7WUFDWCxDQUFDO1lBRUQsSUFBSSxHQUFHLFlBQVksU0FBUyxFQUFFLENBQUM7Z0JBQzdCLElBQUksSUFBQSxnQ0FBYSxFQUFDLE9BQU8sRUFBRSxPQUFPLENBQUMsRUFBRSxDQUFDO29CQUNwQyxNQUFNLElBQUksaUNBQXdCLENBQUMsZUFBZSxFQUFFLEdBQUcsQ0FBQyxDQUFDO2dCQUMzRCxDQUFDO2dCQUNELE1BQU0sSUFBQSxXQUFJLEVBQUMsSUFBQSxtQkFBVSxFQUFDLGFBQWEsRUFBRSxPQUFPLEVBQUUsWUFBWSxDQUFDLENBQUMsQ0FBQztnQkFDN0QsU0FBUztZQUNYLENBQUM7WUFFRCxNQUFNLEdBQUcsQ0FBQztRQUNaLENBQUM7SUFDSCxDQUFDO0lBRUQsTUFBTSxJQUFJLHFDQUE0QixFQUFFLENBQUM7QUFDM0MsQ0FBQyxDQUFDO0FBakVXLFFBQUEsWUFBWSxnQkFpRXZCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZnVsbEppdHRlciB9IGZyb20gJy4vYmFja29mZi9qaXR0ZXInO1xuaW1wb3J0IHsgcmVzb2x2ZVJldHJ5RGVsYXlNcyB9IGZyb20gJy4vYmFja29mZi9yZXRyeS1hZnRlcic7XG5pbXBvcnQge1xuICBGZXRjaFJldHJpZXJBYm9ydEVycm9yLFxuICBGZXRjaFJldHJpZXJBbHJlYWR5QWJvcnRlZEVycm9yLFxuICBGZXRjaFJldHJpZXJIdHRwRXJyb3IsXG4gIEZldGNoUmV0cmllck5ldHdvcmtFcnJvcixcbiAgRmV0Y2hSZXRyaWVyVW5yZWFjaGFibGVFcnJvcixcbn0gZnJvbSAnLi9lcnJvcnMnO1xuaW1wb3J0IHsgdGltZWRGZXRjaCB9IGZyb20gJy4vaHR0cC90aW1lZC1mZXRjaCc7XG5pbXBvcnQgeyBSZXF1ZXN0T3B0aW9ucyB9IGZyb20gJy4vb3B0aW9ucyc7XG5pbXBvcnQgeyBkZWZhdWx0U2hvdWxkUmV0cnkgfSBmcm9tICcuL3BvbGljeS9kZWZhdWx0LXNob3VsZC1yZXRyeSc7XG5pbXBvcnQgeyB2YWxpZGF0ZVJlcXVlc3RPcHRpb25zIH0gZnJvbSAnLi9wb2xpY3kvdmFsaWRhdGUtb3B0aW9ucyc7XG5pbXBvcnQgeyBpc0xhc3RBdHRlbXB0IH0gZnJvbSAnLi9yZXRyeS1wcmVkaWNhdGVzJztcbmltcG9ydCB7IHdhaXQgfSBmcm9tICcuL3RpbWUvd2FpdCc7XG5cbi8qKlxuICogV3JhcHMgYGZldGNoYCB3aXRoIHJldHJpZXMsIHBlci1hdHRlbXB0IHRpbWVvdXQsIFJldHJ5LUFmdGVyIHN1cHBvcnQsIGZ1bGwtaml0dGVyIGJhY2tvZmYsIGFuZFxuICogb3B0aW9uYWwgY2FuY2VsbGF0aW9uLlxuICpcbiAqIEVhY2ggYXR0ZW1wdCBjYWxscyB7QGxpbmsgdGltZWRGZXRjaH0gd2l0aCBgdGltZW91dE1zYC4gTm9uLU9LIHJlc3BvbnNlcyBhcmUgcmV0cmllZCB3aGVuXG4gKiBgc2hvdWxkUmV0cnlgIHJldHVybnMgYHRydWVgIChkZWZhdWx0OiB7QGxpbmsgZGVmYXVsdFNob3VsZFJldHJ5fSkuIEJldHdlZW4gSFRUUCByZXRyaWVzLCBhXG4gKiB2YWxpZCBgUmV0cnktQWZ0ZXJgIGhlYWRlciAoZGVsdGEtc2Vjb25kcyBvciBIVFRQLWRhdGUpIGlzIHByZWZlcnJlZCBvdmVyIGZ1bGwgaml0dGVyOyBhYm9ydFxuICogYW5kIG5ldHdvcmsgcmV0cmllcyBhbHdheXMgdXNlIGZ1bGwgaml0dGVyLiBPcHRpb25hbCB7QGxpbmsgUmVxdWVzdE9wdGlvbnMubWF4QmFja29mZk1zfSBjbGlwc1xuICogdGhlIGppdHRlciByZXN1bHQsIG5vdCBhIHZhbGlkIGBSZXRyeS1BZnRlcmAuIFRoZSBzYW1lIHtAbGluayBGZXRjaEluaXRPcHRpb25zfSAoaW5jbHVkaW5nXG4gKiBgYm9keWApIGlzIHJldXNlZCBvbiBldmVyeSBhdHRlbXB0LlxuICpcbiAqIEBwYXJhbSB1cmwgLSBSZXF1ZXN0IFVSTCBwYXNzZWQgdG8gYGZldGNoYFxuICogQHBhcmFtIG9wdGlvbnMgLSB7QGxpbmsgUmVxdWVzdE9wdGlvbnN9IGNvbnRyb2xsaW5nIHJldHJpZXMsIHRpbWVvdXQsIHJlcXVlc3QgaW5pdCwgYW5kIGNhbmNlbGxhdGlvblxuICogQHJldHVybnMgVGhlIGZpcnN0IHtAbGluayBSZXNwb25zZX0gZm9yIHdoaWNoIGBva2AgaXMgYHRydWVgXG4gKiBAdGhyb3dzIHtGZXRjaFJldHJpZXJFcnJvcn0gQWxsIGZhaWx1cmVzIGZyb20gdGhpcyBmdW5jdGlvbiBhcmUgc3ViY2xhc3NlcyBvZiB0aGlzIGNsYXNzXG4gKiBAdGhyb3dzIHtGZXRjaFJldHJpZXJJbnZhbGlkT3B0aW9uc0Vycm9yfSBJZiBgcmV0cmllcyA8IDFgLCBgdGltZW91dE1zIDw9IDBgLCBgYmFzZUJhY2tvZmZNcyA8IDBgLFxuICogICBvciBgbWF4QmFja29mZk1zYCBpcyBzZXQgYW5kIGA8IDBgXG4gKiBAdGhyb3dzIHtGZXRjaFJldHJpZXJBbHJlYWR5QWJvcnRlZEVycm9yfSBJZiBgb3B0aW9ucy5zaWduYWxgIGlzIGFscmVhZHkgYWJvcnRlZCBiZWZvcmUgYW4gYXR0ZW1wdCxcbiAqICAgaW5jbHVkaW5nIHRoZSBuZXh0IGF0dGVtcHQgYWZ0ZXIgYW4gaW4tZmxpZ2h0IGV4dGVybmFsIGFib3J0IHdoaWxlIHJldHJpZXMgcmVtYWluXG4gKiBAdGhyb3dzIHtGZXRjaFJldHJpZXJIdHRwRXJyb3J9IE9uIGEgbm9uLU9LIHJlc3BvbnNlIHRoYXQgaXMgbm90IHJldHJpZWQgb3IgYWZ0ZXIgdGhlIGxhc3QgYXR0ZW1wdFxuICogICAoaW5jbHVkZXMgYHN0YXR1c2AgYW5kIGBib2R5YClcbiAqIEB0aHJvd3Mge0ZldGNoUmV0cmllck5ldHdvcmtFcnJvcn0gT24gYSBuZXR3b3JrIGBUeXBlRXJyb3JgIGFmdGVyIHRoZSBsYXN0IGF0dGVtcHRcbiAqIEB0aHJvd3Mge0ZldGNoUmV0cmllckFib3J0RXJyb3J9IE9uIHBlci1hdHRlbXB0IHRpbWVvdXQgYWZ0ZXIgdGhlIGxhc3QgYXR0ZW1wdCwgb3IgZXh0ZXJuYWwgYWJvcnRcbiAqICAgb24gdGhlIGxhc3QgYXR0ZW1wdFxuICogQHRocm93cyB7RmV0Y2hSZXRyaWVyVW5yZWFjaGFibGVFcnJvcn0gSWYgdGhlIHJldHJ5IGxvb3AgZXhpdHMgd2l0aG91dCByZXR1cm5pbmcgKGludGVybmFsIGJ1ZylcbiAqL1xuZXhwb3J0IGNvbnN0IGZldGNoUmV0cmllciA9IGFzeW5jICh1cmw6IHN0cmluZywgb3B0aW9uczogUmVxdWVzdE9wdGlvbnMpOiBQcm9taXNlPFJlc3BvbnNlPiA9PiB7XG4gIGNvbnN0IHtcbiAgICBoZWFkZXJzLFxuICAgIGluaXQsXG4gICAgcmV0cmllcyxcbiAgICB0aW1lb3V0TXMsXG4gICAgYmFzZUJhY2tvZmZNcyxcbiAgICBtYXhCYWNrb2ZmTXMsXG4gICAgc2lnbmFsOiBleHRlcm5hbFNpZ25hbCxcbiAgICBzaG91bGRSZXRyeSA9IGRlZmF1bHRTaG91bGRSZXRyeSxcbiAgfSA9IG9wdGlvbnM7XG5cbiAgdmFsaWRhdGVSZXF1ZXN0T3B0aW9ucyh7IHJldHJpZXMsIHRpbWVvdXRNcywgYmFzZUJhY2tvZmZNcywgbWF4QmFja29mZk1zIH0pO1xuXG4gIGZvciAobGV0IGF0dGVtcHQgPSAxOyBhdHRlbXB0IDw9IHJldHJpZXM7IGF0dGVtcHQrKykge1xuICAgIGlmIChleHRlcm5hbFNpZ25hbD8uYWJvcnRlZCkge1xuICAgICAgdGhyb3cgbmV3IEZldGNoUmV0cmllckFscmVhZHlBYm9ydGVkRXJyb3IoKTtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzID0gYXdhaXQgdGltZWRGZXRjaCh1cmwsIHtcbiAgICAgICAgdGltZW91dE1zLFxuICAgICAgICBpbml0LFxuICAgICAgICBoZWFkZXJzLFxuICAgICAgICBzaWduYWw6IGV4dGVybmFsU2lnbmFsLFxuICAgICAgfSk7XG5cbiAgICAgIGlmIChyZXMub2spIHtcbiAgICAgICAgcmV0dXJuIHJlcztcbiAgICAgIH1cblxuICAgICAgY29uc3QgdGV4dCA9IGF3YWl0IHJlcy50ZXh0KCk7XG4gICAgICBjb25zdCBpc0NvbnRpbnVlID0gc2hvdWxkUmV0cnkocmVzLCB0ZXh0KTtcblxuICAgICAgaWYgKCFpc0NvbnRpbnVlKSB7XG4gICAgICAgIHRocm93IG5ldyBGZXRjaFJldHJpZXJIdHRwRXJyb3IoYE5vbi1yZXRyaWFibGUgSFRUUCBlcnJvcjogJHtyZXMuc3RhdHVzfWAsIHJlcy5zdGF0dXMsIHRleHQpO1xuICAgICAgfVxuXG4gICAgICBpZiAoaXNMYXN0QXR0ZW1wdChhdHRlbXB0LCByZXRyaWVzKSkge1xuICAgICAgICB0aHJvdyBuZXcgRmV0Y2hSZXRyaWVySHR0cEVycm9yKGBIVFRQICR7cmVzLnN0YXR1c31gLCByZXMuc3RhdHVzLCB0ZXh0KTtcbiAgICAgIH1cblxuICAgICAgYXdhaXQgd2FpdChyZXNvbHZlUmV0cnlEZWxheU1zKHJlcywgYmFzZUJhY2tvZmZNcywgYXR0ZW1wdCwgbWF4QmFja29mZk1zKSk7XG4gICAgfSBjYXRjaCAoZXJyOiB1bmtub3duKSB7XG4gICAgICBpZiAoZXJyIGluc3RhbmNlb2YgRXJyb3IgJiYgZXJyLm5hbWUgPT09ICdBYm9ydEVycm9yJykge1xuICAgICAgICBpZiAoaXNMYXN0QXR0ZW1wdChhdHRlbXB0LCByZXRyaWVzKSkge1xuICAgICAgICAgIHRocm93IGVyciBpbnN0YW5jZW9mIEZldGNoUmV0cmllckFib3J0RXJyb3IgPyBlcnIgOiBuZXcgRmV0Y2hSZXRyaWVyQWJvcnRFcnJvcigpO1xuICAgICAgICB9XG4gICAgICAgIGF3YWl0IHdhaXQoZnVsbEppdHRlcihiYXNlQmFja29mZk1zLCBhdHRlbXB0LCBtYXhCYWNrb2ZmTXMpKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGlmIChlcnIgaW5zdGFuY2VvZiBUeXBlRXJyb3IpIHtcbiAgICAgICAgaWYgKGlzTGFzdEF0dGVtcHQoYXR0ZW1wdCwgcmV0cmllcykpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRmV0Y2hSZXRyaWVyTmV0d29ya0Vycm9yKCdOZXR3b3JrIGVycm9yJywgZXJyKTtcbiAgICAgICAgfVxuICAgICAgICBhd2FpdCB3YWl0KGZ1bGxKaXR0ZXIoYmFzZUJhY2tvZmZNcywgYXR0ZW1wdCwgbWF4QmFja29mZk1zKSk7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICB0aHJvdyBlcnI7XG4gICAgfVxuICB9XG5cbiAgdGhyb3cgbmV3IEZldGNoUmV0cmllclVucmVhY2hhYmxlRXJyb3IoKTtcbn07XG4iXX0=
|