@internetarchive/fetch-handler 1.1.0-webdev-7731.7 → 1.1.0-webdev-7731.9
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/README.md +75 -5
- package/demo/app-root.ts +6 -6
- package/dist/demo/app-root.d.ts +1 -1
- package/dist/demo/app-root.js +4 -4
- package/dist/demo/app-root.js.map +1 -1
- package/dist/index.d.ts +6 -5
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/src/fetch-handler-interface.d.ts +18 -8
- package/dist/src/fetch-handler-interface.js.map +1 -1
- package/dist/src/fetch-handler.d.ts +26 -3
- package/dist/src/fetch-handler.js +29 -5
- package/dist/src/fetch-handler.js.map +1 -1
- package/dist/src/fetch-retry/configuration/configurations.d.ts +21 -0
- package/dist/src/fetch-retry/configuration/configurations.js +21 -0
- package/dist/src/fetch-retry/configuration/configurations.js.map +1 -1
- package/dist/src/fetch-retry/configuration/default-retry-configuration.d.ts +5 -1
- package/dist/src/fetch-retry/configuration/default-retry-configuration.js +4 -0
- package/dist/src/fetch-retry/configuration/default-retry-configuration.js.map +1 -1
- package/dist/src/fetch-retry/configuration/no-retry-configuration.d.ts +4 -1
- package/dist/src/fetch-retry/configuration/no-retry-configuration.js +4 -1
- package/dist/src/fetch-retry/configuration/no-retry-configuration.js.map +1 -1
- package/dist/src/fetch-retry/configuration/retry-configuring.d.ts +1 -1
- package/dist/src/fetch-retry/configuration/retry-configuring.js.map +1 -1
- package/dist/src/fetch-retry/fetch-retrier.d.ts +3 -3
- package/dist/src/fetch-retry/fetch-retrier.js +26 -20
- package/dist/src/fetch-retry/fetch-retrier.js.map +1 -1
- package/dist/test/fetch-handler.test.js +62 -12
- package/dist/test/fetch-handler.test.js.map +1 -1
- package/dist/test/fetch-retrier.test.js +9 -9
- package/dist/test/fetch-retrier.test.js.map +1 -1
- package/dist/test/legacy-args.test.js +3 -0
- package/dist/test/legacy-args.test.js.map +1 -1
- package/dist/test/mocks/mock-retry-config.d.ts +1 -1
- package/dist/test/mocks/mock-retry-config.js +1 -1
- package/dist/test/mocks/mock-retry-config.js.map +1 -1
- package/dist/test/no-retry-config.test.js +1 -1
- package/dist/test/no-retry-config.test.js.map +1 -1
- package/index.ts +9 -7
- package/package.json +1 -1
- package/src/fetch-handler-interface.ts +22 -8
- package/src/fetch-handler.ts +39 -6
- package/src/fetch-retry/configuration/configurations.ts +21 -0
- package/src/fetch-retry/configuration/default-retry-configuration.ts +8 -1
- package/src/fetch-retry/configuration/no-retry-configuration.ts +5 -2
- package/src/fetch-retry/configuration/retry-configuring.ts +4 -1
- package/src/fetch-retry/fetch-retrier.ts +31 -26
- package/test/fetch-handler.test.ts +70 -12
- package/test/fetch-retrier.test.ts +9 -9
- package/test/legacy-args.test.ts +3 -0
- package/test/mocks/mock-retry-config.ts +1 -5
- package/test/no-retry-config.test.ts +1 -1
- package/dist/test/retrier-legacy-args.test.d.ts +0 -1
- package/dist/test/retrier-legacy-args.test.js +0 -27
- package/dist/test/retrier-legacy-args.test.js.map +0 -1
- package/test/retrier-legacy-args.test.ts +0 -28
package/README.md
CHANGED
|
@@ -17,16 +17,16 @@ npm install @internetarchive/fetch-handler
|
|
|
17
17
|
## Sample Usage
|
|
18
18
|
|
|
19
19
|
```ts
|
|
20
|
-
import {
|
|
20
|
+
import { FetchHandler } from '@internetarchive/fetch-handler';
|
|
21
21
|
|
|
22
22
|
@property({ type: Object }) data: any = null;
|
|
23
23
|
@property({ type: String }) error: string = '';
|
|
24
24
|
@property({ type: Boolean }) loading: boolean = false;
|
|
25
25
|
|
|
26
|
-
private fetchHandler:
|
|
26
|
+
private fetchHandler: FetchHandler;
|
|
27
27
|
|
|
28
|
-
this.fetchHandler = new
|
|
29
|
-
|
|
28
|
+
this.fetchHandler = new FetchHandler({
|
|
29
|
+
apiBaseUrl: 'https://archive.org',
|
|
30
30
|
});
|
|
31
31
|
|
|
32
32
|
|
|
@@ -35,7 +35,7 @@ async fetchData() {
|
|
|
35
35
|
this.error = '';
|
|
36
36
|
try {
|
|
37
37
|
const result =
|
|
38
|
-
await this.fetchHandler.
|
|
38
|
+
await this.fetchHandler.fetchApiPathResponse('/metadata/goody');
|
|
39
39
|
this.data = result;
|
|
40
40
|
} catch (error) {
|
|
41
41
|
this.error = `Error fetching data: ${error}`;
|
|
@@ -47,6 +47,76 @@ async fetchData() {
|
|
|
47
47
|
|
|
48
48
|
See the `demo` directory for a more detailed example.
|
|
49
49
|
|
|
50
|
+
## Configuring Retry
|
|
51
|
+
|
|
52
|
+
You can customize how you'd like `FetchHandler` to retry a request, both globally and per-request.
|
|
53
|
+
|
|
54
|
+
### Basic Usage
|
|
55
|
+
|
|
56
|
+
There are two included configurations, `DefaultRetryConfiguration` and `NoRetryConfiguration`, which can be accessed via `FetchRetryConfig.default` and `FetchRetryConfig.noRetry`. `.default` (the default) will retry twice with exponential backoff delay and `.noRetry` will not retry.
|
|
57
|
+
|
|
58
|
+
Example:
|
|
59
|
+
|
|
60
|
+
```ts
|
|
61
|
+
import { FetchHandler, FetchRetrier, FetchRetryConfig } from '@internetarchive/fetch-handler';
|
|
62
|
+
|
|
63
|
+
// setting default: retry twice with exponential backoff delay
|
|
64
|
+
const fetchRetrier = new FetchRetrier({
|
|
65
|
+
retryConfig: FetchRetryConfig.default
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
const fetchHandler = new FetchHandler({
|
|
69
|
+
fetchRetrier
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
// use default retry configuration
|
|
73
|
+
await fetchHander.fetch('https://foo.com/api')
|
|
74
|
+
|
|
75
|
+
// specify retry config per-request: will not retry this request
|
|
76
|
+
await fetchHandler.fetch('https://foo.com/api', {
|
|
77
|
+
retryConfig: FetchRetryConfig.noRetry
|
|
78
|
+
})
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Custom Retry Configuration
|
|
82
|
+
|
|
83
|
+
Fetch retrying can be configured using a `RetryConfiguring` object. This interface has two methods:
|
|
84
|
+
```ts
|
|
85
|
+
interface RetryConfiguring {
|
|
86
|
+
shouldRetry(
|
|
87
|
+
response: Response | null,
|
|
88
|
+
retryNumber: number,
|
|
89
|
+
error?: unknown,
|
|
90
|
+
): boolean;
|
|
91
|
+
|
|
92
|
+
retryDelay(
|
|
93
|
+
retryNumber: number,
|
|
94
|
+
response?: Response | null,
|
|
95
|
+
): Milliseconds | null;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
class MyCustomRetryConfig implements RetryConfiguring {
|
|
99
|
+
shouldRetry(
|
|
100
|
+
response: Response | null,
|
|
101
|
+
retryNumber: number
|
|
102
|
+
): boolean {
|
|
103
|
+
if (response === null) return false;
|
|
104
|
+
if (retryNumber > 1) return false;
|
|
105
|
+
return response.status !== 404;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
retryDelay(retryNumber: number): Milliseconds | null {
|
|
109
|
+
return 1000;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const customRetryConfig = new MyCustomRetryConfig();
|
|
114
|
+
// use your custom retry config on a request or globally
|
|
115
|
+
await fetchHandler.fetch('https://foo.com/api', {
|
|
116
|
+
retryConfig: customRetryConfig
|
|
117
|
+
})
|
|
118
|
+
```
|
|
119
|
+
|
|
50
120
|
## Local Demo with `web-dev-server`
|
|
51
121
|
Add `127.0.0.1 local.archive.org` to your `/etc/hosts` file
|
|
52
122
|
|
package/demo/app-root.ts
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import { html, LitElement, css } from 'lit';
|
|
2
2
|
import { customElement, property } from 'lit/decorators.js';
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import { FetchHandler } from '../src/fetch-handler';
|
|
5
5
|
|
|
6
6
|
@customElement('app-root')
|
|
7
7
|
export class AppRoot extends LitElement {
|
|
8
|
-
@property({ type: Object }) data:
|
|
8
|
+
@property({ type: Object }) data: unknown = null;
|
|
9
9
|
@property({ type: String }) error: string = '';
|
|
10
10
|
@property({ type: Boolean }) loading: boolean = false;
|
|
11
11
|
|
|
12
|
-
private fetchHandler:
|
|
12
|
+
private fetchHandler: FetchHandler;
|
|
13
13
|
|
|
14
14
|
constructor() {
|
|
15
15
|
super();
|
|
16
|
-
this.fetchHandler = new
|
|
17
|
-
|
|
16
|
+
this.fetchHandler = new FetchHandler({
|
|
17
|
+
apiBaseUrl: 'https://archive.org',
|
|
18
18
|
});
|
|
19
19
|
}
|
|
20
20
|
|
|
@@ -28,7 +28,7 @@ export class AppRoot extends LitElement {
|
|
|
28
28
|
this.error = '';
|
|
29
29
|
try {
|
|
30
30
|
const result =
|
|
31
|
-
await this.fetchHandler.
|
|
31
|
+
await this.fetchHandler.fetchApiPathResponse('/metadata/goody');
|
|
32
32
|
this.data = result;
|
|
33
33
|
} catch (error) {
|
|
34
34
|
this.error = `Error fetching data: ${error}`;
|
package/dist/demo/app-root.d.ts
CHANGED
package/dist/demo/app-root.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { __decorate } from "tslib";
|
|
2
2
|
import { html, LitElement, css } from 'lit';
|
|
3
3
|
import { customElement, property } from 'lit/decorators.js';
|
|
4
|
-
import {
|
|
4
|
+
import { FetchHandler } from '../src/fetch-handler';
|
|
5
5
|
let AppRoot = class AppRoot extends LitElement {
|
|
6
6
|
constructor() {
|
|
7
7
|
super();
|
|
8
8
|
this.data = null;
|
|
9
9
|
this.error = '';
|
|
10
10
|
this.loading = false;
|
|
11
|
-
this.fetchHandler = new
|
|
12
|
-
|
|
11
|
+
this.fetchHandler = new FetchHandler({
|
|
12
|
+
apiBaseUrl: 'https://archive.org',
|
|
13
13
|
});
|
|
14
14
|
}
|
|
15
15
|
connectedCallback() {
|
|
@@ -20,7 +20,7 @@ let AppRoot = class AppRoot extends LitElement {
|
|
|
20
20
|
this.loading = true;
|
|
21
21
|
this.error = '';
|
|
22
22
|
try {
|
|
23
|
-
const result = await this.fetchHandler.
|
|
23
|
+
const result = await this.fetchHandler.fetchApiPathResponse('/metadata/goody');
|
|
24
24
|
this.data = result;
|
|
25
25
|
}
|
|
26
26
|
catch (error) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app-root.js","sourceRoot":"","sources":["../../demo/app-root.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE5D,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"app-root.js","sourceRoot":"","sources":["../../demo/app-root.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE5D,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAG7C,IAAM,OAAO,GAAb,MAAM,OAAQ,SAAQ,UAAU;IAOrC;QACE,KAAK,EAAE,CAAC;QAPkB,SAAI,GAAY,IAAI,CAAC;QACrB,UAAK,GAAW,EAAE,CAAC;QAClB,YAAO,GAAY,KAAK,CAAC;QAMpD,IAAI,CAAC,YAAY,GAAG,IAAI,YAAY,CAAC;YACnC,UAAU,EAAE,qBAAqB;SAClC,CAAC,CAAC;IACL,CAAC;IAED,iBAAiB;QACf,KAAK,CAAC,iBAAiB,EAAE,CAAC;QAC1B,IAAI,CAAC,SAAS,EAAE,CAAC;IACnB,CAAC;IAED,KAAK,CAAC,SAAS;QACb,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACpB,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;QAChB,IAAI,CAAC;YACH,MAAM,MAAM,GACV,MAAM,IAAI,CAAC,YAAY,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,CAAC;YAClE,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC;QACrB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,KAAK,GAAG,wBAAwB,KAAK,EAAE,CAAC;QAC/C,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;QACvB,CAAC;IACH,CAAC;IAED,MAAM;QACJ,OAAO,IAAI,CAAA;;;UAGL,IAAI,CAAC,OAAO;YACZ,CAAC,CAAC,IAAI,CAAA,mBAAmB;YACzB,CAAC,CAAC,IAAI,CAAC,KAAK;gBACV,CAAC,CAAC,IAAI,CAAA,oBAAoB,IAAI,CAAC,KAAK,MAAM;gBAC1C,CAAC,CAAC,IAAI,CAAC,IAAI;oBACT,CAAC,CAAC,IAAI,CAAA,QAAQ,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,QAAQ;oBACxD,CAAC,CAAC,IAAI,CAAA,2BAA2B;0BACrB,IAAI,CAAC,SAAS;;KAEnC,CAAC;IACJ,CAAC;;AAEM,cAAM,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BlB,AA3BY,CA2BX;AA3E0B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;qCAAsB;AACrB;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;sCAAoB;AAClB;IAA5B,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;wCAA0B;AAH3C,OAAO;IADnB,aAAa,CAAC,UAAU,CAAC;GACb,OAAO,CA6EnB","sourcesContent":["import { html, LitElement, css } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\n\nimport { FetchHandler } from '../src/fetch-handler';\n\n@customElement('app-root')\nexport class AppRoot extends LitElement {\n @property({ type: Object }) data: unknown = null;\n @property({ type: String }) error: string = '';\n @property({ type: Boolean }) loading: boolean = false;\n\n private fetchHandler: FetchHandler;\n\n constructor() {\n super();\n this.fetchHandler = new FetchHandler({\n apiBaseUrl: 'https://archive.org',\n });\n }\n\n connectedCallback() {\n super.connectedCallback();\n this.fetchData();\n }\n\n async fetchData() {\n this.loading = true;\n this.error = '';\n try {\n const result =\n await this.fetchHandler.fetchApiPathResponse('/metadata/goody');\n this.data = result;\n } catch (error) {\n this.error = `Error fetching data: ${error}`;\n } finally {\n this.loading = false;\n }\n }\n\n render() {\n return html`\n <div class=\"container\">\n <h1>Fetch Data</h1>\n ${this.loading\n ? html`<p>Loading...</p>`\n : this.error\n ? html`<p class=\"error\">${this.error}</p>`\n : this.data\n ? html`<pre>${JSON.stringify(this.data, null, 2)}</pre>`\n : html`<p>No data available.</p>`}\n <button @click=\"${this.fetchData}\">Retry</button>\n </div>\n `;\n }\n\n static styles = css`\n .container {\n padding: 20px;\n font-family: Arial, sans-serif;\n }\n\n h1 {\n color: #333;\n }\n\n .error {\n color: red;\n }\n\n button {\n margin-top: 20px;\n padding: 10px 20px;\n background-color: #007bff;\n color: white;\n border: none;\n cursor: pointer;\n border-radius: 5px;\n }\n\n button:hover {\n background-color: #0056b3;\n }\n `;\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
export { IaFetchHandler } from './src/fetch-handler';
|
|
2
|
-
export { FetchHandlerInterface } from './src/fetch-handler-interface';
|
|
3
|
-
export {
|
|
1
|
+
export { FetchHandler, IaFetchHandler } from './src/fetch-handler';
|
|
2
|
+
export type { FetchHandlerInterface } from './src/fetch-handler-interface';
|
|
3
|
+
export type { FetchOptions } from './src/fetch-options';
|
|
4
|
+
export type { Milliseconds } from './src/fetch-retry/configuration/milliseconds';
|
|
5
|
+
export { FetchRetryConfig } from './src/fetch-retry/configuration/configurations';
|
|
4
6
|
export { DefaultRetryConfiguration } from './src/fetch-retry/configuration/default-retry-configuration';
|
|
5
7
|
export { NoRetryConfiguration } from './src/fetch-retry/configuration/no-retry-configuration';
|
|
6
8
|
export type { RetryConfiguring } from './src/fetch-retry/configuration/retry-configuring';
|
|
7
|
-
export
|
|
8
|
-
export { FetchRetryConfig } from './src/fetch-retry/configuration/configurations';
|
|
9
|
+
export { FetchRetrier, FetchRetrierInterface, } from './src/fetch-retry/fetch-retrier';
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export { IaFetchHandler } from './src/fetch-handler';
|
|
2
|
-
export {
|
|
1
|
+
export { FetchHandler, IaFetchHandler } from './src/fetch-handler';
|
|
2
|
+
export { FetchRetryConfig } from './src/fetch-retry/configuration/configurations';
|
|
3
3
|
export { DefaultRetryConfiguration } from './src/fetch-retry/configuration/default-retry-configuration';
|
|
4
4
|
export { NoRetryConfiguration } from './src/fetch-retry/configuration/no-retry-configuration';
|
|
5
|
-
export {
|
|
5
|
+
export { FetchRetrier, } from './src/fetch-retry/fetch-retrier';
|
|
6
6
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAKnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,gDAAgD,CAAC;AAClF,OAAO,EAAE,yBAAyB,EAAE,MAAM,6DAA6D,CAAC;AACxG,OAAO,EAAE,oBAAoB,EAAE,MAAM,wDAAwD,CAAC;AAE9F,OAAO,EACL,YAAY,GAEb,MAAM,iCAAiC,CAAC","sourcesContent":["export { FetchHandler, IaFetchHandler } from './src/fetch-handler';\nexport type { FetchHandlerInterface } from './src/fetch-handler-interface';\nexport type { FetchOptions } from './src/fetch-options';\nexport type { Milliseconds } from './src/fetch-retry/configuration/milliseconds';\n\nexport { FetchRetryConfig } from './src/fetch-retry/configuration/configurations';\nexport { DefaultRetryConfiguration } from './src/fetch-retry/configuration/default-retry-configuration';\nexport { NoRetryConfiguration } from './src/fetch-retry/configuration/no-retry-configuration';\nexport type { RetryConfiguring } from './src/fetch-retry/configuration/retry-configuring';\nexport {\n FetchRetrier,\n FetchRetrierInterface,\n} from './src/fetch-retry/fetch-retrier';\n"]}
|
|
@@ -27,14 +27,24 @@ export interface FetchHandlerInterface {
|
|
|
27
27
|
* This allows you to just pass the path to the API and get the response instead
|
|
28
28
|
* of the full URL. If you need a full URL, use `fetchApiResponse` instead.
|
|
29
29
|
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
30
|
+
* ie `fetchApiPathResponse('/items/123')` will fetch from `${apiBaseUrl}/items/123`
|
|
31
|
+
*
|
|
32
|
+
* @param path - Path to API endpoint
|
|
33
|
+
* @param options - Options including credentials, method, body, headers, and retryConfig
|
|
34
|
+
*/
|
|
35
|
+
fetchApiPathResponse<T>(path: string, options?: {
|
|
36
|
+
includeCredentials?: boolean;
|
|
37
|
+
method?: string;
|
|
38
|
+
body?: BodyInit;
|
|
39
|
+
headers?: HeadersInit;
|
|
40
|
+
retryConfig?: RetryConfiguring;
|
|
41
|
+
}): Promise<T>;
|
|
42
|
+
/**
|
|
43
|
+
* Fetch a response from the IA API by path
|
|
44
|
+
*
|
|
45
|
+
* @deprecated Use `fetchApiPathResponse` instead.
|
|
46
|
+
* @param path - Path to API endpoint
|
|
47
|
+
* @param options - Options including credentials, method, body, headers, and retryConfig
|
|
38
48
|
*/
|
|
39
49
|
fetchIAApiResponse<T>(path: string, options?: {
|
|
40
50
|
includeCredentials?: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch-handler-interface.js","sourceRoot":"","sources":["../../src/fetch-handler-interface.ts"],"names":[],"mappings":"","sourcesContent":["import type { FetchOptions } from './fetch-options';\nimport type { RetryConfiguring } from './fetch-retry/configuration/retry-configuring';\n\nexport interface FetchHandlerInterface {\n /**\n * Generic fetch function that handles retries and common IA parameters like `reCache=1`\n *\n * @param input RequestInfo\n * @param options RequestInit | FetchOptions\n */\n fetch(\n request: RequestInfo,\n options?: RequestInit | FetchOptions,\n ): Promise<Response>;\n\n /**\n * A helper function to fetch a response from an API and get a JSON object\n *\n * @param path string\n * @param options?: { includeCredentials?: boolean }\n */\n fetchApiResponse<T>(\n url: string,\n options?: {\n includeCredentials?: boolean;\n method?: string;\n body?: BodyInit;\n headers?: HeadersInit;\n retryConfig?: RetryConfiguring;\n },\n ): Promise<T>;\n\n /**\n * A helper function to fetch a response from the IA API and get a JSON object\n *\n * This allows you to just pass the path to the API and get the response instead\n * of the full URL. If you need a full URL, use `fetchApiResponse` instead.\n *\n * @param path
|
|
1
|
+
{"version":3,"file":"fetch-handler-interface.js","sourceRoot":"","sources":["../../src/fetch-handler-interface.ts"],"names":[],"mappings":"","sourcesContent":["import type { FetchOptions } from './fetch-options';\nimport type { RetryConfiguring } from './fetch-retry/configuration/retry-configuring';\n\nexport interface FetchHandlerInterface {\n /**\n * Generic fetch function that handles retries and common IA parameters like `reCache=1`\n *\n * @param input RequestInfo\n * @param options RequestInit | FetchOptions\n */\n fetch(\n request: RequestInfo,\n options?: RequestInit | FetchOptions,\n ): Promise<Response>;\n\n /**\n * A helper function to fetch a response from an API and get a JSON object\n *\n * @param path string\n * @param options?: { includeCredentials?: boolean }\n */\n fetchApiResponse<T>(\n url: string,\n options?: {\n includeCredentials?: boolean;\n method?: string;\n body?: BodyInit;\n headers?: HeadersInit;\n retryConfig?: RetryConfiguring;\n },\n ): Promise<T>;\n\n /**\n * A helper function to fetch a response from the IA API and get a JSON object\n *\n * This allows you to just pass the path to the API and get the response instead\n * of the full URL. If you need a full URL, use `fetchApiResponse` instead.\n *\n * ie `fetchApiPathResponse('/items/123')` will fetch from `${apiBaseUrl}/items/123`\n *\n * @param path - Path to API endpoint\n * @param options - Options including credentials, method, body, headers, and retryConfig\n */\n fetchApiPathResponse<T>(\n path: string,\n options?: {\n includeCredentials?: boolean;\n method?: string;\n body?: BodyInit;\n headers?: HeadersInit;\n retryConfig?: RetryConfiguring;\n },\n ): Promise<T>;\n\n /**\n * Fetch a response from the IA API by path\n *\n * @deprecated Use `fetchApiPathResponse` instead.\n * @param path - Path to API endpoint\n * @param options - Options including credentials, method, body, headers, and retryConfig\n */\n fetchIAApiResponse<T>(\n path: string,\n options?: {\n includeCredentials?: boolean;\n method?: string;\n body?: BodyInit;\n headers?: HeadersInit;\n retryConfig?: RetryConfiguring;\n },\n ): Promise<T>;\n}\n"]}
|
|
@@ -8,17 +8,33 @@ import type { RetryConfiguring } from './fetch-retry/configuration/retry-configu
|
|
|
8
8
|
* - add `reCache=1` to the request if it's in the current url so the backend sees it
|
|
9
9
|
* - add convenience method for fetching/decoding an API response by just the path
|
|
10
10
|
*/
|
|
11
|
-
export declare class
|
|
12
|
-
private
|
|
11
|
+
export declare class FetchHandler implements FetchHandlerInterface {
|
|
12
|
+
private apiBaseUrl;
|
|
13
13
|
private fetchRetrier;
|
|
14
14
|
private searchParams?;
|
|
15
|
+
/**
|
|
16
|
+
*
|
|
17
|
+
* @param options {
|
|
18
|
+
* iaApiBaseUrl - deprecated Use `apiBaseUrl` instead.
|
|
19
|
+
* apiBaseUrl - The base URL for API requests for `fetchApiPathResponse`
|
|
20
|
+
* fetchRetrier - FetchRetrier to use instead of the default
|
|
21
|
+
* searchParams - Search params to check for `reCache=1` (defaults to current window location)
|
|
22
|
+
*/
|
|
15
23
|
constructor(options?: {
|
|
16
24
|
iaApiBaseUrl?: string;
|
|
25
|
+
apiBaseUrl?: string;
|
|
17
26
|
fetchRetrier?: FetchRetrierInterface;
|
|
18
27
|
searchParams?: string;
|
|
19
|
-
defaultRetryConfiguration?: RetryConfiguring;
|
|
20
28
|
});
|
|
21
29
|
/** @inheritdoc */
|
|
30
|
+
fetchApiPathResponse<T>(path: string, options?: {
|
|
31
|
+
includeCredentials?: boolean;
|
|
32
|
+
method?: string;
|
|
33
|
+
body?: BodyInit;
|
|
34
|
+
headers?: HeadersInit;
|
|
35
|
+
retryConfig?: RetryConfiguring;
|
|
36
|
+
}): Promise<T>;
|
|
37
|
+
/** @inheritdoc */
|
|
22
38
|
fetchIAApiResponse<T>(path: string, options?: {
|
|
23
39
|
includeCredentials?: boolean;
|
|
24
40
|
method?: string;
|
|
@@ -42,3 +58,10 @@ export declare class IaFetchHandler implements FetchHandlerInterface {
|
|
|
42
58
|
*/
|
|
43
59
|
private addSearchParams;
|
|
44
60
|
}
|
|
61
|
+
/**
|
|
62
|
+
* Backwards compatibility class
|
|
63
|
+
*
|
|
64
|
+
* @deprecated Use `FetchHandler` instead.
|
|
65
|
+
*/
|
|
66
|
+
export declare class IaFetchHandler extends FetchHandler {
|
|
67
|
+
}
|
|
@@ -5,11 +5,24 @@ import { FetchRetrier, } from './fetch-retry/fetch-retrier';
|
|
|
5
5
|
* - add `reCache=1` to the request if it's in the current url so the backend sees it
|
|
6
6
|
* - add convenience method for fetching/decoding an API response by just the path
|
|
7
7
|
*/
|
|
8
|
-
export class
|
|
8
|
+
export class FetchHandler {
|
|
9
|
+
/**
|
|
10
|
+
*
|
|
11
|
+
* @param options {
|
|
12
|
+
* iaApiBaseUrl - deprecated Use `apiBaseUrl` instead.
|
|
13
|
+
* apiBaseUrl - The base URL for API requests for `fetchApiPathResponse`
|
|
14
|
+
* fetchRetrier - FetchRetrier to use instead of the default
|
|
15
|
+
* searchParams - Search params to check for `reCache=1` (defaults to current window location)
|
|
16
|
+
*/
|
|
9
17
|
constructor(options) {
|
|
18
|
+
this.apiBaseUrl = '';
|
|
10
19
|
this.fetchRetrier = new FetchRetrier();
|
|
11
|
-
if (options === null || options === void 0 ? void 0 : options.
|
|
12
|
-
this.
|
|
20
|
+
if (options === null || options === void 0 ? void 0 : options.apiBaseUrl) {
|
|
21
|
+
this.apiBaseUrl = options.apiBaseUrl;
|
|
22
|
+
}
|
|
23
|
+
else if (options === null || options === void 0 ? void 0 : options.iaApiBaseUrl) {
|
|
24
|
+
this.apiBaseUrl = options.iaApiBaseUrl;
|
|
25
|
+
}
|
|
13
26
|
if (options === null || options === void 0 ? void 0 : options.fetchRetrier)
|
|
14
27
|
this.fetchRetrier = options.fetchRetrier;
|
|
15
28
|
if (options === null || options === void 0 ? void 0 : options.searchParams) {
|
|
@@ -20,11 +33,15 @@ export class IaFetchHandler {
|
|
|
20
33
|
}
|
|
21
34
|
}
|
|
22
35
|
/** @inheritdoc */
|
|
23
|
-
async
|
|
24
|
-
const url = `${this.
|
|
36
|
+
async fetchApiPathResponse(path, options) {
|
|
37
|
+
const url = `${this.apiBaseUrl}${path}`;
|
|
25
38
|
return this.fetchApiResponse(url, options);
|
|
26
39
|
}
|
|
27
40
|
/** @inheritdoc */
|
|
41
|
+
async fetchIAApiResponse(path, options) {
|
|
42
|
+
return this.fetchApiPathResponse(path, options);
|
|
43
|
+
}
|
|
44
|
+
/** @inheritdoc */
|
|
28
45
|
async fetchApiResponse(url, options) {
|
|
29
46
|
const requestInit = {};
|
|
30
47
|
if (options === null || options === void 0 ? void 0 : options.includeCredentials)
|
|
@@ -64,4 +81,11 @@ export class IaFetchHandler {
|
|
|
64
81
|
return url.href;
|
|
65
82
|
}
|
|
66
83
|
}
|
|
84
|
+
/**
|
|
85
|
+
* Backwards compatibility class
|
|
86
|
+
*
|
|
87
|
+
* @deprecated Use `FetchHandler` instead.
|
|
88
|
+
*/
|
|
89
|
+
export class IaFetchHandler extends FetchHandler {
|
|
90
|
+
}
|
|
67
91
|
//# sourceMappingURL=fetch-handler.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch-handler.js","sourceRoot":"","sources":["../../src/fetch-handler.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,GAEb,MAAM,6BAA6B,CAAC;AAKrC;;;;;GAKG;AACH,MAAM,OAAO,
|
|
1
|
+
{"version":3,"file":"fetch-handler.js","sourceRoot":"","sources":["../../src/fetch-handler.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n FetchRetrier,\n FetchRetrierInterface,\n} from './fetch-retry/fetch-retrier';\nimport type { FetchHandlerInterface } from './fetch-handler-interface';\nimport type { FetchOptions } from './fetch-options';\nimport type { RetryConfiguring } from './fetch-retry/configuration/retry-configuring';\n\n/**\n * The FetchHandler adds some common helpers:\n * - retry the request if it fails\n * - add `reCache=1` to the request if it's in the current url so the backend sees it\n * - add convenience method for fetching/decoding an API response by just the path\n */\nexport class FetchHandler implements FetchHandlerInterface {\n private apiBaseUrl: string = '';\n\n private fetchRetrier: FetchRetrierInterface = new FetchRetrier();\n\n private searchParams?: string;\n\n /**\n *\n * @param options {\n * iaApiBaseUrl - deprecated Use `apiBaseUrl` instead.\n * apiBaseUrl - The base URL for API requests for `fetchApiPathResponse`\n * fetchRetrier - FetchRetrier to use instead of the default\n * searchParams - Search params to check for `reCache=1` (defaults to current window location)\n */\n constructor(options?: {\n iaApiBaseUrl?: string;\n apiBaseUrl?: string;\n fetchRetrier?: FetchRetrierInterface;\n searchParams?: string;\n }) {\n if (options?.apiBaseUrl) {\n this.apiBaseUrl = options.apiBaseUrl;\n } else if (options?.iaApiBaseUrl) {\n this.apiBaseUrl = options.iaApiBaseUrl;\n }\n if (options?.fetchRetrier) this.fetchRetrier = options.fetchRetrier;\n if (options?.searchParams) {\n this.searchParams = options.searchParams;\n } else {\n this.searchParams = window.location.search;\n }\n }\n\n /** @inheritdoc */\n async fetchApiPathResponse<T>(\n path: string,\n options?: {\n includeCredentials?: boolean;\n method?: string;\n body?: BodyInit;\n headers?: HeadersInit;\n retryConfig?: RetryConfiguring;\n },\n ): Promise<T> {\n const url = `${this.apiBaseUrl}${path}`;\n return this.fetchApiResponse(url, options);\n }\n\n /** @inheritdoc */\n async fetchIAApiResponse<T>(\n path: string,\n options?: {\n includeCredentials?: boolean;\n method?: string;\n body?: BodyInit;\n headers?: HeadersInit;\n retryConfig?: RetryConfiguring;\n },\n ): Promise<T> {\n return this.fetchApiPathResponse(path, options);\n }\n\n /** @inheritdoc */\n async fetchApiResponse<T>(\n url: string,\n options?: {\n includeCredentials?: boolean;\n method?: string;\n body?: BodyInit;\n headers?: HeadersInit;\n retryConfig?: RetryConfiguring;\n },\n ): Promise<T> {\n const requestInit: RequestInit = {};\n if (options?.includeCredentials) requestInit.credentials = 'include';\n if (options?.method) requestInit.method = options.method;\n if (options?.body) requestInit.body = options.body;\n if (options?.headers) requestInit.headers = options.headers;\n const response = await this.fetch(url, {\n requestInit: requestInit,\n retryConfig: options?.retryConfig,\n });\n const json = await response.json();\n return json as T;\n }\n\n /** @inheritdoc */\n async fetch(\n request: RequestInfo,\n options?: RequestInit | FetchOptions,\n ): Promise<Response> {\n let finalRequest = request;\n const urlParams = new URLSearchParams(this.searchParams);\n if (urlParams.get('reCache') === '1') {\n const urlString = typeof request === 'string' ? request : request.url;\n finalRequest = this.addSearchParams(urlString, { reCache: '1' });\n }\n return this.fetchRetrier.fetchRetry(finalRequest, options);\n }\n\n /**\n * Since RequestInfo can be either a `Request` or `string`, we need to change\n * the way we add search params to it depending on the input.\n */\n private addSearchParams(\n urlString: string,\n params: Record<string, string>,\n ): string {\n const url = new URL(urlString, window.location.href);\n\n for (const [key, value] of Object.entries(params)) {\n url.searchParams.set(key, value);\n }\n\n return url.href;\n }\n}\n\n/**\n * Backwards compatibility class\n *\n * @deprecated Use `FetchHandler` instead.\n */\nexport class IaFetchHandler extends FetchHandler {}\n"]}
|
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
import type { RetryConfiguring } from './retry-configuring';
|
|
2
|
+
/**
|
|
3
|
+
* This class provides easy access to common retry configurations.
|
|
4
|
+
*
|
|
5
|
+
* ie `FetchRetryConfig.default` or `FetchRetryConfig.noRetry` vs
|
|
6
|
+
* `new DefaultRetryConfiguration()` or `new NoRetryConfiguration()`
|
|
7
|
+
*/
|
|
2
8
|
export declare class FetchRetryConfig {
|
|
9
|
+
/**
|
|
10
|
+
* A retry configuration that retries twice for transient errors
|
|
11
|
+
* with exponential retry delay as well as `Retry-After` header support.
|
|
12
|
+
*
|
|
13
|
+
* @static
|
|
14
|
+
* @type {Readonly<RetryConfiguring>}
|
|
15
|
+
* @memberof FetchRetryConfig
|
|
16
|
+
*/
|
|
3
17
|
static readonly default: Readonly<RetryConfiguring>;
|
|
18
|
+
/**
|
|
19
|
+
* A retry configuration that does not perform any retries.
|
|
20
|
+
*
|
|
21
|
+
* @static
|
|
22
|
+
* @type {Readonly<RetryConfiguring>}
|
|
23
|
+
* @memberof FetchRetryConfig
|
|
24
|
+
*/
|
|
4
25
|
static readonly noRetry: Readonly<RetryConfiguring>;
|
|
5
26
|
}
|
|
@@ -1,7 +1,28 @@
|
|
|
1
1
|
import { DefaultRetryConfiguration } from './default-retry-configuration';
|
|
2
2
|
import { NoRetryConfiguration } from './no-retry-configuration';
|
|
3
|
+
/**
|
|
4
|
+
* This class provides easy access to common retry configurations.
|
|
5
|
+
*
|
|
6
|
+
* ie `FetchRetryConfig.default` or `FetchRetryConfig.noRetry` vs
|
|
7
|
+
* `new DefaultRetryConfiguration()` or `new NoRetryConfiguration()`
|
|
8
|
+
*/
|
|
3
9
|
export class FetchRetryConfig {
|
|
4
10
|
}
|
|
11
|
+
/**
|
|
12
|
+
* A retry configuration that retries twice for transient errors
|
|
13
|
+
* with exponential retry delay as well as `Retry-After` header support.
|
|
14
|
+
*
|
|
15
|
+
* @static
|
|
16
|
+
* @type {Readonly<RetryConfiguring>}
|
|
17
|
+
* @memberof FetchRetryConfig
|
|
18
|
+
*/
|
|
5
19
|
FetchRetryConfig.default = DefaultRetryConfiguration.shared;
|
|
20
|
+
/**
|
|
21
|
+
* A retry configuration that does not perform any retries.
|
|
22
|
+
*
|
|
23
|
+
* @static
|
|
24
|
+
* @type {Readonly<RetryConfiguring>}
|
|
25
|
+
* @memberof FetchRetryConfig
|
|
26
|
+
*/
|
|
6
27
|
FetchRetryConfig.noRetry = NoRetryConfiguration.shared;
|
|
7
28
|
//# sourceMappingURL=configurations.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"configurations.js","sourceRoot":"","sources":["../../../../src/fetch-retry/configuration/configurations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,+BAA+B,CAAC;AAC1E,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAGhE,MAAM,OAAO,gBAAgB;;
|
|
1
|
+
{"version":3,"file":"configurations.js","sourceRoot":"","sources":["../../../../src/fetch-retry/configuration/configurations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,+BAA+B,CAAC;AAC1E,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAGhE;;;;;GAKG;AACH,MAAM,OAAO,gBAAgB;;AAC3B;;;;;;;GAOG;AACa,wBAAO,GACrB,yBAAyB,CAAC,MAAM,CAAC;AAEnC;;;;;;GAMG;AACa,wBAAO,GACrB,oBAAoB,CAAC,MAAM,CAAC","sourcesContent":["import { DefaultRetryConfiguration } from './default-retry-configuration';\nimport { NoRetryConfiguration } from './no-retry-configuration';\nimport type { RetryConfiguring } from './retry-configuring';\n\n/**\n * This class provides easy access to common retry configurations.\n *\n * ie `FetchRetryConfig.default` or `FetchRetryConfig.noRetry` vs\n * `new DefaultRetryConfiguration()` or `new NoRetryConfiguration()`\n */\nexport class FetchRetryConfig {\n /**\n * A retry configuration that retries twice for transient errors\n * with exponential retry delay as well as `Retry-After` header support.\n *\n * @static\n * @type {Readonly<RetryConfiguring>}\n * @memberof FetchRetryConfig\n */\n static readonly default: Readonly<RetryConfiguring> =\n DefaultRetryConfiguration.shared;\n\n /**\n * A retry configuration that does not perform any retries.\n *\n * @static\n * @type {Readonly<RetryConfiguring>}\n * @memberof FetchRetryConfig\n */\n static readonly noRetry: Readonly<RetryConfiguring> =\n NoRetryConfiguration.shared;\n}\n"]}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import type { RetryConfiguring } from './retry-configuring';
|
|
2
2
|
import type { Milliseconds } from './milliseconds';
|
|
3
|
+
/**
|
|
4
|
+
* A retry configuration that retries twice for transient errors
|
|
5
|
+
* with exponential retry delay as well as `Retry-After` header support.
|
|
6
|
+
*/
|
|
3
7
|
export declare class DefaultRetryConfiguration implements RetryConfiguring {
|
|
4
8
|
static readonly shared: Readonly<RetryConfiguring>;
|
|
5
9
|
private readonly maxRetries;
|
|
@@ -9,5 +13,5 @@ export declare class DefaultRetryConfiguration implements RetryConfiguring {
|
|
|
9
13
|
});
|
|
10
14
|
readonly transientStatusCodes: ReadonlySet<number>;
|
|
11
15
|
shouldRetry(response: Response | null, retryNumber: number): boolean;
|
|
12
|
-
retryDelay(retryNumber: number, response?: Response | null): Milliseconds;
|
|
16
|
+
retryDelay(retryNumber: number, response?: Response | null): Milliseconds | null;
|
|
13
17
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"default-retry-configuration.js","sourceRoot":"","sources":["../../../../src/fetch-retry/configuration/default-retry-configuration.ts"],"names":[],"mappings":"AAGA,MAAM,OAAO,yBAAyB;IAMpC,YAAY,OAGX;QALgB,eAAU,GAAqB,CAAC,CAAC;QAczC,yBAAoB,GAAwB,IAAI,GAAG,CAAC;YAC3D,GAAG,EAAE,kBAAkB;YACvB,GAAG,EAAE,oBAAoB;YACzB,GAAG,EAAE,wBAAwB;YAC7B,GAAG,EAAE,cAAc;YACnB,GAAG,EAAE,sBAAsB;YAC3B,GAAG,EAAE,kBAAkB;YACvB,GAAG,EAAE,gDAAgD;SACtD,CAAC,CAAC;QAhBD,IAAI,CAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,UAAU,MAAK,SAAS,EAAE,CAAC;YACtC,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;QACvC,CAAC;QACD,IAAI,CAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,oBAAoB,MAAK,SAAS,EAAE,CAAC;YAChD,IAAI,CAAC,oBAAoB,GAAG,OAAO,CAAC,oBAAoB,CAAC;QAC3D,CAAC;IACH,CAAC;IAYD,WAAW,CAAC,QAAyB,EAAE,WAAmB;QACxD,IAAI,QAAQ,KAAK,IAAI;YAAE,OAAO,KAAK,CAAC;QACpC,IAAI,WAAW,GAAG,IAAI,CAAC,UAAU;YAAE,OAAO,KAAK,CAAC;QAChD,MAAM,WAAW,GAAG,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QACnE,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,UAAU,
|
|
1
|
+
{"version":3,"file":"default-retry-configuration.js","sourceRoot":"","sources":["../../../../src/fetch-retry/configuration/default-retry-configuration.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,MAAM,OAAO,yBAAyB;IAMpC,YAAY,OAGX;QALgB,eAAU,GAAqB,CAAC,CAAC;QAczC,yBAAoB,GAAwB,IAAI,GAAG,CAAC;YAC3D,GAAG,EAAE,kBAAkB;YACvB,GAAG,EAAE,oBAAoB;YACzB,GAAG,EAAE,wBAAwB;YAC7B,GAAG,EAAE,cAAc;YACnB,GAAG,EAAE,sBAAsB;YAC3B,GAAG,EAAE,kBAAkB;YACvB,GAAG,EAAE,gDAAgD;SACtD,CAAC,CAAC;QAhBD,IAAI,CAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,UAAU,MAAK,SAAS,EAAE,CAAC;YACtC,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;QACvC,CAAC;QACD,IAAI,CAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,oBAAoB,MAAK,SAAS,EAAE,CAAC;YAChD,IAAI,CAAC,oBAAoB,GAAG,OAAO,CAAC,oBAAoB,CAAC;QAC3D,CAAC;IACH,CAAC;IAYD,WAAW,CAAC,QAAyB,EAAE,WAAmB;QACxD,IAAI,QAAQ,KAAK,IAAI;YAAE,OAAO,KAAK,CAAC;QACpC,IAAI,WAAW,GAAG,IAAI,CAAC,UAAU;YAAE,OAAO,KAAK,CAAC;QAChD,MAAM,WAAW,GAAG,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QACnE,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,UAAU,CACR,WAAmB,EACnB,QAA0B;QAE1B,4CAA4C;QAC5C,MAAM,UAAU,GAAG,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;QACxD,IAAI,UAAU,EAAE,CAAC;YACf,MAAM,iBAAiB,GAAG,QAAQ,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;YACnD,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,EAAE,CAAC;gBAC9B,OAAO,iBAAiB,GAAG,IAAI,CAAC;YAClC,CAAC;QACH,CAAC;QAED,uCAAuC;QACvC,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,IAAI,WAAW,EAAE,KAAK,CAAC,CAAC;IACjD,CAAC;;AAjDe,gCAAM,GACpB,IAAI,yBAAyB,EAAE,AADX,CACY","sourcesContent":["import type { RetryConfiguring } from './retry-configuring';\nimport type { Milliseconds } from './milliseconds';\n\n/**\n * A retry configuration that retries twice for transient errors\n * with exponential retry delay as well as `Retry-After` header support.\n */\nexport class DefaultRetryConfiguration implements RetryConfiguring {\n static readonly shared: Readonly<RetryConfiguring> =\n new DefaultRetryConfiguration();\n\n private readonly maxRetries: Readonly<number> = 2;\n\n constructor(options?: {\n maxRetries?: number;\n transientStatusCodes?: Set<number>;\n }) {\n if (options?.maxRetries !== undefined) {\n this.maxRetries = options.maxRetries;\n }\n if (options?.transientStatusCodes !== undefined) {\n this.transientStatusCodes = options.transientStatusCodes;\n }\n }\n\n readonly transientStatusCodes: ReadonlySet<number> = new Set([\n 408, // Request Timeout\n 429, // Too Many Requests\n 500, // Internal Server Error\n 502, // Bad Gateway\n 503, // Service Unavailable\n 504, // Gateway Timeout\n 522, // Cloudflare Origin Server Connection Timed Out\n ]);\n\n shouldRetry(response: Response | null, retryNumber: number): boolean {\n if (response === null) return false;\n if (retryNumber > this.maxRetries) return false;\n const isTransient = this.transientStatusCodes.has(response.status);\n return isTransient;\n }\n\n retryDelay(\n retryNumber: number,\n response?: Response | null,\n ): Milliseconds | null {\n // If we have a Retry-After header, use that\n const retryAfter = response?.headers.get('Retry-After');\n if (retryAfter) {\n const retryAfterSeconds = parseInt(retryAfter, 10);\n if (!isNaN(retryAfterSeconds)) {\n return retryAfterSeconds * 1000;\n }\n }\n\n // Exponential backoff up to 10 seconds\n return Math.min(500 * 2 ** retryNumber, 10000);\n }\n}\n"]}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import type { RetryConfiguring } from './retry-configuring';
|
|
2
2
|
import type { Milliseconds } from './milliseconds';
|
|
3
|
+
/**
|
|
4
|
+
* A retry configuration that does not perform any retries.
|
|
5
|
+
*/
|
|
3
6
|
export declare class NoRetryConfiguration implements RetryConfiguring {
|
|
4
7
|
static readonly shared: Readonly<RetryConfiguring>;
|
|
5
8
|
shouldRetry(): boolean;
|
|
6
|
-
retryDelay(): Milliseconds;
|
|
9
|
+
retryDelay(): Milliseconds | null;
|
|
7
10
|
}
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A retry configuration that does not perform any retries.
|
|
3
|
+
*/
|
|
1
4
|
export class NoRetryConfiguration {
|
|
2
5
|
shouldRetry() {
|
|
3
6
|
return false;
|
|
4
7
|
}
|
|
5
8
|
retryDelay() {
|
|
6
|
-
return
|
|
9
|
+
return null;
|
|
7
10
|
}
|
|
8
11
|
}
|
|
9
12
|
NoRetryConfiguration.shared = new NoRetryConfiguration();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"no-retry-configuration.js","sourceRoot":"","sources":["../../../../src/fetch-retry/configuration/no-retry-configuration.ts"],"names":[],"mappings":"AAGA,MAAM,OAAO,oBAAoB;IAI/B,WAAW;QACT,OAAO,KAAK,CAAC;IACf,CAAC;IAED,UAAU;QACR,OAAO,
|
|
1
|
+
{"version":3,"file":"no-retry-configuration.js","sourceRoot":"","sources":["../../../../src/fetch-retry/configuration/no-retry-configuration.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,MAAM,OAAO,oBAAoB;IAI/B,WAAW;QACT,OAAO,KAAK,CAAC;IACf,CAAC;IAED,UAAU;QACR,OAAO,IAAI,CAAC;IACd,CAAC;;AATe,2BAAM,GACpB,IAAI,oBAAoB,EAAE,CAAC","sourcesContent":["import type { RetryConfiguring } from './retry-configuring';\nimport type { Milliseconds } from './milliseconds';\n\n/**\n * A retry configuration that does not perform any retries.\n */\nexport class NoRetryConfiguration implements RetryConfiguring {\n static readonly shared: Readonly<RetryConfiguring> =\n new NoRetryConfiguration();\n\n shouldRetry(): boolean {\n return false;\n }\n\n retryDelay(): Milliseconds | null {\n return null;\n }\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Milliseconds } from './milliseconds';
|
|
2
2
|
export interface RetryConfiguring {
|
|
3
3
|
shouldRetry(response: Response | null, retryNumber: number, error?: unknown): boolean;
|
|
4
|
-
retryDelay(retryNumber: number, response?: Response | null): Milliseconds;
|
|
4
|
+
retryDelay(retryNumber: number, response?: Response | null): Milliseconds | null;
|
|
5
5
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"retry-configuring.js","sourceRoot":"","sources":["../../../../src/fetch-retry/configuration/retry-configuring.ts"],"names":[],"mappings":"","sourcesContent":["import type { Milliseconds } from './milliseconds';\n\nexport interface RetryConfiguring {\n shouldRetry(\n response: Response | null,\n retryNumber: number,\n error?: unknown,\n ): boolean;\n\n retryDelay(retryNumber: number
|
|
1
|
+
{"version":3,"file":"retry-configuring.js","sourceRoot":"","sources":["../../../../src/fetch-retry/configuration/retry-configuring.ts"],"names":[],"mappings":"","sourcesContent":["import type { Milliseconds } from './milliseconds';\n\nexport interface RetryConfiguring {\n shouldRetry(\n response: Response | null,\n retryNumber: number,\n error?: unknown,\n ): boolean;\n\n retryDelay(\n retryNumber: number,\n response?: Response | null,\n ): Milliseconds | null;\n}\n"]}
|
|
@@ -17,14 +17,14 @@ export interface FetchRetrierInterface {
|
|
|
17
17
|
/** @inheritdoc */
|
|
18
18
|
export declare class FetchRetrier implements FetchRetrierInterface {
|
|
19
19
|
private analyticsHandler?;
|
|
20
|
-
private
|
|
20
|
+
private retryConfig;
|
|
21
21
|
constructor(options?: {
|
|
22
22
|
analyticsHandler?: AnalyticsHandlerInterface;
|
|
23
|
-
|
|
23
|
+
retryConfig?: RetryConfiguring;
|
|
24
24
|
});
|
|
25
25
|
/** @inheritdoc */
|
|
26
26
|
fetchRetry(request: RequestInfo, options?: RequestInit | FetchOptions): Promise<Response>;
|
|
27
|
-
private
|
|
27
|
+
private doFetchRetry;
|
|
28
28
|
private isContentBlockerError;
|
|
29
29
|
private readonly eventCategory;
|
|
30
30
|
private logRetryEvent;
|