@internetarchive/fetch-handler 1.1.0-webdev-7731.10 → 1.1.0-webdev-7731.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/src/fetch-handler-interface.d.ts +7 -26
- package/dist/src/fetch-handler-interface.js.map +1 -1
- package/dist/src/fetch-handler.d.ts +18 -40
- package/dist/src/fetch-handler.js +20 -25
- package/dist/src/fetch-handler.js.map +1 -1
- package/dist/src/fetch-options.d.ts +13 -0
- package/dist/src/fetch-options.js.map +1 -1
- package/dist/src/fetch-retry/fetch-retrier.js +1 -1
- package/dist/src/fetch-retry/fetch-retrier.js.map +1 -1
- package/index.ts +6 -2
- package/package.json +1 -1
- package/src/fetch-handler-interface.ts +7 -35
- package/src/fetch-handler.ts +41 -62
- package/src/fetch-options.ts +14 -0
- package/src/fetch-retry/fetch-retrier.ts +3 -4
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export { FetchHandler, IaFetchHandler } from './src/fetch-handler';
|
|
1
|
+
export { FetchHandler, IaFetchHandler, type FetchHandlerConstructorOptions, } from './src/fetch-handler';
|
|
2
2
|
export type { FetchHandlerInterface } from './src/fetch-handler-interface';
|
|
3
|
-
export type { FetchOptions } from './src/fetch-options';
|
|
3
|
+
export type { ApiFetchOptions, FetchOptions } from './src/fetch-options';
|
|
4
4
|
export type { Milliseconds } from './src/fetch-retry/configuration/milliseconds';
|
|
5
5
|
export { FetchRetryConfig } from './src/fetch-retry/configuration/configurations';
|
|
6
6
|
export { DefaultRetryConfiguration } from './src/fetch-retry/configuration/default-retry-configuration';
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { FetchHandler, IaFetchHandler } from './src/fetch-handler';
|
|
1
|
+
export { FetchHandler, IaFetchHandler, } from './src/fetch-handler';
|
|
2
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';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,cAAc,GAEf,MAAM,qBAAqB,CAAC;AAK7B,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 {\n FetchHandler,\n IaFetchHandler,\n type FetchHandlerConstructorOptions,\n} from './src/fetch-handler';\nexport type { FetchHandlerInterface } from './src/fetch-handler-interface';\nexport type { ApiFetchOptions, 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"]}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import type { FetchOptions } from './fetch-options';
|
|
2
|
-
import type { RetryConfiguring } from './fetch-retry/configuration/retry-configuring';
|
|
1
|
+
import type { ApiFetchOptions, FetchOptions } from './fetch-options';
|
|
3
2
|
export interface FetchHandlerInterface {
|
|
4
3
|
/**
|
|
5
4
|
* Generic fetch function that handles retries and common IA parameters like `reCache=1`
|
|
@@ -12,15 +11,9 @@ export interface FetchHandlerInterface {
|
|
|
12
11
|
* A helper function to fetch a response from an API and get a JSON object
|
|
13
12
|
*
|
|
14
13
|
* @param path string
|
|
15
|
-
* @param options?:
|
|
14
|
+
* @param options?: ApiFetchOptions
|
|
16
15
|
*/
|
|
17
|
-
fetchApiResponse<T>(url: string, options?:
|
|
18
|
-
includeCredentials?: boolean;
|
|
19
|
-
method?: string;
|
|
20
|
-
body?: BodyInit;
|
|
21
|
-
headers?: HeadersInit;
|
|
22
|
-
retryConfig?: RetryConfiguring;
|
|
23
|
-
}): Promise<T>;
|
|
16
|
+
fetchApiResponse<T>(url: string, options?: ApiFetchOptions): Promise<T>;
|
|
24
17
|
/**
|
|
25
18
|
* A helper function to fetch a response from the IA API and get a JSON object
|
|
26
19
|
*
|
|
@@ -30,27 +23,15 @@ export interface FetchHandlerInterface {
|
|
|
30
23
|
* ie `fetchApiPathResponse('/items/123')` will fetch from `${apiBaseUrl}/items/123`
|
|
31
24
|
*
|
|
32
25
|
* @param path - Path to API endpoint
|
|
33
|
-
* @param options -
|
|
26
|
+
* @param options - ApiFetchOptions
|
|
34
27
|
*/
|
|
35
|
-
fetchApiPathResponse<T>(path: string, options?:
|
|
36
|
-
includeCredentials?: boolean;
|
|
37
|
-
method?: string;
|
|
38
|
-
body?: BodyInit;
|
|
39
|
-
headers?: HeadersInit;
|
|
40
|
-
retryConfig?: RetryConfiguring;
|
|
41
|
-
}): Promise<T>;
|
|
28
|
+
fetchApiPathResponse<T>(path: string, options?: ApiFetchOptions): Promise<T>;
|
|
42
29
|
/**
|
|
43
30
|
* Fetch a response from the IA API by path
|
|
44
31
|
*
|
|
45
32
|
* @deprecated Use `fetchApiPathResponse` instead.
|
|
46
33
|
* @param path - Path to API endpoint
|
|
47
|
-
* @param options -
|
|
34
|
+
* @param options - ApiFetchOptions
|
|
48
35
|
*/
|
|
49
|
-
fetchIAApiResponse<T>(path: string, options?:
|
|
50
|
-
includeCredentials?: boolean;
|
|
51
|
-
method?: string;
|
|
52
|
-
body?: BodyInit;
|
|
53
|
-
headers?: HeadersInit;
|
|
54
|
-
retryConfig?: RetryConfiguring;
|
|
55
|
-
}): Promise<T>;
|
|
36
|
+
fetchIAApiResponse<T>(path: string, options?: ApiFetchOptions): Promise<T>;
|
|
56
37
|
}
|
|
@@ -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';\
|
|
1
|
+
{"version":3,"file":"fetch-handler-interface.js","sourceRoot":"","sources":["../../src/fetch-handler-interface.ts"],"names":[],"mappings":"","sourcesContent":["import type { ApiFetchOptions, FetchOptions } from './fetch-options';\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?: ApiFetchOptions\n */\n fetchApiResponse<T>(url: string, options?: ApiFetchOptions): 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 - ApiFetchOptions\n */\n fetchApiPathResponse<T>(path: string, options?: ApiFetchOptions): 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 - ApiFetchOptions\n */\n fetchIAApiResponse<T>(path: string, options?: ApiFetchOptions): Promise<T>;\n}\n"]}
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import { FetchRetrierInterface } from './fetch-retry/fetch-retrier';
|
|
2
2
|
import type { FetchHandlerInterface } from './fetch-handler-interface';
|
|
3
|
-
import type { FetchOptions } from './fetch-options';
|
|
4
|
-
|
|
3
|
+
import type { ApiFetchOptions, FetchOptions } from './fetch-options';
|
|
4
|
+
export type FetchHandlerConstructorOptions = {
|
|
5
|
+
/** @deprecated Use `apiBaseUrl` instead. */
|
|
6
|
+
iaApiBaseUrl?: string;
|
|
7
|
+
apiBaseUrl?: string;
|
|
8
|
+
fetchRetrier?: FetchRetrierInterface;
|
|
9
|
+
searchParams?: string;
|
|
10
|
+
};
|
|
5
11
|
/**
|
|
6
12
|
* The FetchHandler adds some common helpers:
|
|
7
13
|
* - retry the request if it fails
|
|
@@ -12,49 +18,21 @@ export declare class FetchHandler implements FetchHandlerInterface {
|
|
|
12
18
|
private apiBaseUrl;
|
|
13
19
|
private fetchRetrier;
|
|
14
20
|
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
|
-
*/
|
|
23
|
-
constructor(options?: {
|
|
24
|
-
iaApiBaseUrl?: string;
|
|
25
|
-
apiBaseUrl?: string;
|
|
26
|
-
fetchRetrier?: FetchRetrierInterface;
|
|
27
|
-
searchParams?: string;
|
|
28
|
-
});
|
|
21
|
+
constructor(options?: FetchHandlerConstructorOptions);
|
|
29
22
|
/** @inheritdoc */
|
|
30
|
-
|
|
31
|
-
includeCredentials?: boolean;
|
|
32
|
-
method?: string;
|
|
33
|
-
body?: BodyInit;
|
|
34
|
-
headers?: HeadersInit;
|
|
35
|
-
retryConfig?: RetryConfiguring;
|
|
36
|
-
}): Promise<T>;
|
|
23
|
+
fetch(request: RequestInfo, options?: RequestInit | FetchOptions): Promise<Response>;
|
|
37
24
|
/** @inheritdoc */
|
|
38
|
-
|
|
39
|
-
includeCredentials?: boolean;
|
|
40
|
-
method?: string;
|
|
41
|
-
body?: BodyInit;
|
|
42
|
-
headers?: HeadersInit;
|
|
43
|
-
retryConfig?: RetryConfiguring;
|
|
44
|
-
}): Promise<T>;
|
|
25
|
+
fetchApiResponse<T>(url: string, options?: ApiFetchOptions): Promise<T>;
|
|
45
26
|
/** @inheritdoc */
|
|
46
|
-
|
|
47
|
-
includeCredentials?: boolean;
|
|
48
|
-
method?: string;
|
|
49
|
-
body?: BodyInit;
|
|
50
|
-
headers?: HeadersInit;
|
|
51
|
-
retryConfig?: RetryConfiguring;
|
|
52
|
-
}): Promise<T>;
|
|
27
|
+
fetchApiPathResponse<T>(path: string, options?: ApiFetchOptions): Promise<T>;
|
|
53
28
|
/** @inheritdoc */
|
|
54
|
-
|
|
29
|
+
fetchIAApiResponse<T>(path: string, options?: ApiFetchOptions): Promise<T>;
|
|
55
30
|
/**
|
|
56
|
-
*
|
|
57
|
-
*
|
|
31
|
+
* Construct a new URL with the given search params added
|
|
32
|
+
*
|
|
33
|
+
* @param urlString - Original URL string
|
|
34
|
+
* @param params - Params to add
|
|
35
|
+
* @returns New URL string with params added
|
|
58
36
|
*/
|
|
59
37
|
private addSearchParams;
|
|
60
38
|
}
|
|
@@ -6,14 +6,6 @@ import { FetchRetrier, } from './fetch-retry/fetch-retrier';
|
|
|
6
6
|
* - add convenience method for fetching/decoding an API response by just the path
|
|
7
7
|
*/
|
|
8
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
|
-
*/
|
|
17
9
|
constructor(options) {
|
|
18
10
|
this.apiBaseUrl = '';
|
|
19
11
|
this.fetchRetrier = new FetchRetrier();
|
|
@@ -33,13 +25,14 @@ export class FetchHandler {
|
|
|
33
25
|
}
|
|
34
26
|
}
|
|
35
27
|
/** @inheritdoc */
|
|
36
|
-
async
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
28
|
+
async fetch(request, options) {
|
|
29
|
+
let finalRequest = request;
|
|
30
|
+
const urlParams = new URLSearchParams(this.searchParams);
|
|
31
|
+
if (urlParams.get('reCache') === '1') {
|
|
32
|
+
const urlString = typeof request === 'string' ? request : request.url;
|
|
33
|
+
finalRequest = this.addSearchParams(urlString, { reCache: '1' });
|
|
34
|
+
}
|
|
35
|
+
return this.fetchRetrier.fetchRetry(finalRequest, options);
|
|
43
36
|
}
|
|
44
37
|
/** @inheritdoc */
|
|
45
38
|
async fetchApiResponse(url, options) {
|
|
@@ -60,18 +53,20 @@ export class FetchHandler {
|
|
|
60
53
|
return json;
|
|
61
54
|
}
|
|
62
55
|
/** @inheritdoc */
|
|
63
|
-
async
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
return this.fetchRetrier.fetchRetry(finalRequest, options);
|
|
56
|
+
async fetchApiPathResponse(path, options) {
|
|
57
|
+
const url = `${this.apiBaseUrl}${path}`;
|
|
58
|
+
return this.fetchApiResponse(url, options);
|
|
59
|
+
}
|
|
60
|
+
/** @inheritdoc */
|
|
61
|
+
async fetchIAApiResponse(path, options) {
|
|
62
|
+
return this.fetchApiPathResponse(path, options);
|
|
71
63
|
}
|
|
72
64
|
/**
|
|
73
|
-
*
|
|
74
|
-
*
|
|
65
|
+
* Construct a new URL with the given search params added
|
|
66
|
+
*
|
|
67
|
+
* @param urlString - Original URL string
|
|
68
|
+
* @param params - Params to add
|
|
69
|
+
* @returns New URL string with params added
|
|
75
70
|
*/
|
|
76
71
|
addSearchParams(urlString, params) {
|
|
77
72
|
const url = new URL(urlString, window.location.href);
|
|
@@ -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;
|
|
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 { ApiFetchOptions, FetchOptions } from './fetch-options';\n\nexport type FetchHandlerConstructorOptions = {\n /** @deprecated Use `apiBaseUrl` instead. */\n iaApiBaseUrl?: string;\n apiBaseUrl?: string;\n fetchRetrier?: FetchRetrierInterface;\n searchParams?: string;\n};\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 constructor(options?: FetchHandlerConstructorOptions) {\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 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 /** @inheritdoc */\n async fetchApiResponse<T>(\n url: string,\n options?: ApiFetchOptions,\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 fetchApiPathResponse<T>(\n path: string,\n options?: ApiFetchOptions,\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?: ApiFetchOptions,\n ): Promise<T> {\n return this.fetchApiPathResponse(path, options);\n }\n\n /**\n * Construct a new URL with the given search params added\n *\n * @param urlString - Original URL string\n * @param params - Params to add\n * @returns New URL string with params added\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 constructor(options?: {\n iaApiBaseUrl?: string;\n apiBaseUrl?: string;\n fetchRetrier?: FetchRetrierInterface;\n searchParams?: string;\n }) {\n const superOptions = { ...options };\n superOptions.iaApiBaseUrl = options?.iaApiBaseUrl ?? 'https://archive.org';\n super(superOptions);\n }\n}\n"]}
|
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
import type { RetryConfiguring } from './fetch-retry/configuration/retry-configuring';
|
|
2
|
+
/**
|
|
3
|
+
* Base fetch options for FetchHandler
|
|
4
|
+
*/
|
|
2
5
|
export type FetchOptions = {
|
|
3
6
|
requestInit?: RequestInit;
|
|
4
7
|
retryConfig?: RetryConfiguring;
|
|
5
8
|
};
|
|
9
|
+
/**
|
|
10
|
+
* A convenience type for FetchHandler methods with common API fetch options.
|
|
11
|
+
*/
|
|
12
|
+
export type ApiFetchOptions = {
|
|
13
|
+
includeCredentials?: boolean;
|
|
14
|
+
method?: string;
|
|
15
|
+
body?: BodyInit;
|
|
16
|
+
headers?: HeadersInit;
|
|
17
|
+
retryConfig?: RetryConfiguring;
|
|
18
|
+
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch-options.js","sourceRoot":"","sources":["../../src/fetch-options.ts"],"names":[],"mappings":"","sourcesContent":["import type { RetryConfiguring } from './fetch-retry/configuration/retry-configuring';\n\nexport type FetchOptions = {\n requestInit?: RequestInit;\n retryConfig?: RetryConfiguring;\n};\n"]}
|
|
1
|
+
{"version":3,"file":"fetch-options.js","sourceRoot":"","sources":["../../src/fetch-options.ts"],"names":[],"mappings":"","sourcesContent":["import type { RetryConfiguring } from './fetch-retry/configuration/retry-configuring';\n\n/**\n * Base fetch options for FetchHandler\n */\nexport type FetchOptions = {\n requestInit?: RequestInit;\n retryConfig?: RetryConfiguring;\n};\n\n/**\n * A convenience type for FetchHandler methods with common API fetch options.\n */\nexport type ApiFetchOptions = {\n includeCredentials?: boolean;\n method?: string;\n body?: BodyInit;\n headers?: HeadersInit;\n retryConfig?: RetryConfiguring;\n};\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { promisedSleep } from '../utils/promised-sleep';
|
|
2
|
-
import { legacyArgsAsFetchOptions } from './legacy-args';
|
|
3
2
|
import { FetchRetryConfig } from './configuration/configurations';
|
|
3
|
+
import { legacyArgsAsFetchOptions } from './legacy-args';
|
|
4
4
|
/** @inheritdoc */
|
|
5
5
|
export class FetchRetrier {
|
|
6
6
|
constructor(options) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch-retrier.js","sourceRoot":"","sources":["../../../src/fetch-retry/fetch-retrier.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"fetch-retrier.js","sourceRoot":"","sources":["../../../src/fetch-retry/fetch-retrier.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AnalyticsHandlerInterface } from '@internetarchive/analytics-manager';\nimport { type FetchOptions } from '../fetch-options';\nimport { promisedSleep } from '../utils/promised-sleep';\nimport { FetchRetryConfig } from './configuration/configurations';\nimport type { RetryConfiguring } from './configuration/retry-configuring';\nimport { legacyArgsAsFetchOptions } from './legacy-args';\n\n/**\n * A class that retries a fetch request.\n */\nexport interface FetchRetrierInterface {\n /**\n * Execute a fetch with retry.\n *\n * @param request RequestInfo\n * @param options Optional RequestInit | FetchOptions\n * @returns Promise<Response>\n */\n fetchRetry(\n request: RequestInfo,\n options?: RequestInit | FetchOptions,\n ): Promise<Response>;\n}\n\n/** @inheritdoc */\nexport class FetchRetrier implements FetchRetrierInterface {\n private analyticsHandler?: AnalyticsHandlerInterface;\n\n private retryConfig: RetryConfiguring = FetchRetryConfig.default;\n\n constructor(options?: {\n analyticsHandler?: AnalyticsHandlerInterface;\n retryConfig?: RetryConfiguring;\n }) {\n if (options?.analyticsHandler)\n this.analyticsHandler = options.analyticsHandler;\n if (options?.retryConfig) this.retryConfig = options.retryConfig;\n }\n\n /** @inheritdoc */\n public async fetchRetry(\n request: RequestInfo,\n options?: RequestInit | FetchOptions,\n ): Promise<Response> {\n const fetchOptions = legacyArgsAsFetchOptions(options);\n return await this.doFetchRetry(request, 0, fetchOptions);\n }\n\n private async doFetchRetry(\n request: RequestInfo,\n retryNumber: number,\n options?: FetchOptions,\n ): Promise<Response> {\n const urlString = typeof request === 'string' ? request : request.url;\n\n try {\n const response = await fetch(request, options?.requestInit);\n if (response.ok) return response;\n\n if (response.status >= 400 && response.status < 600) {\n this.log4xx5xxResponse(response);\n }\n\n const retryConfig = options?.retryConfig ?? this.retryConfig;\n const shouldRetry = retryConfig.shouldRetry(response, retryNumber);\n if (shouldRetry) {\n const retryDelay = retryConfig.retryDelay(retryNumber, response);\n if (retryDelay !== null) {\n await promisedSleep(retryDelay);\n this.logRetryEvent(\n urlString,\n retryNumber,\n response.statusText,\n response.status,\n );\n return this.doFetchRetry(request, retryNumber + 1, options);\n }\n }\n this.logFailureEvent(urlString, response.status);\n return response;\n } catch (error) {\n // if a content blocker is detected, log it and don't retry\n if (this.isContentBlockerError(error)) {\n this.logContentBlockingEvent(urlString, error);\n throw error;\n }\n\n const retryConfig = options?.retryConfig ?? this.retryConfig;\n const shouldRetry = retryConfig.shouldRetry(null, retryNumber);\n if (shouldRetry) {\n const retryDelay = retryConfig.retryDelay(retryNumber);\n if (retryDelay !== null) {\n await promisedSleep(retryDelay);\n this.logRetryEvent(urlString, retryNumber, error, error);\n return this.doFetchRetry(request, retryNumber + 1, options);\n }\n }\n this.logFailureEvent(urlString, error);\n throw error;\n }\n }\n\n private isContentBlockerError(error: unknown): boolean {\n // all of the content blocker errors are `TypeError`\n if (!(error instanceof TypeError)) return false;\n const message = error.message.toLowerCase();\n return message.includes('content blocker');\n }\n\n private readonly eventCategory = 'offshootFetchRetry';\n\n private logRetryEvent(\n urlString: string,\n retryNumber: number,\n status: unknown,\n code: unknown,\n ) {\n this.analyticsHandler?.sendEvent({\n category: this.eventCategory,\n action: 'retryingFetch',\n label: `retryNumber: ${retryNumber}, code: ${code}, status: ${status}, url: ${urlString}`,\n });\n }\n\n private logFailureEvent(urlString: string, error: unknown) {\n this.analyticsHandler?.sendEvent({\n category: this.eventCategory,\n action: 'fetchFailed',\n label: `error: ${error}, url: ${urlString}`,\n });\n }\n\n private log4xx5xxResponse(response: Response) {\n const status = response.status;\n\n this.analyticsHandler?.sendEvent({\n category: this.eventCategory,\n action: `status${status}Response`,\n label: `url: ${response.url}`,\n });\n }\n\n private logContentBlockingEvent(urlString: string, error: unknown) {\n this.analyticsHandler?.sendEvent({\n category: this.eventCategory,\n action: 'contentBlockerDetectedNotRetrying',\n label: `error: ${error}, url: ${urlString}`,\n });\n }\n}\n"]}
|
package/index.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export {
|
|
2
|
+
FetchHandler,
|
|
3
|
+
IaFetchHandler,
|
|
4
|
+
type FetchHandlerConstructorOptions,
|
|
5
|
+
} from './src/fetch-handler';
|
|
2
6
|
export type { FetchHandlerInterface } from './src/fetch-handler-interface';
|
|
3
|
-
export type { FetchOptions } from './src/fetch-options';
|
|
7
|
+
export type { ApiFetchOptions, FetchOptions } from './src/fetch-options';
|
|
4
8
|
export type { Milliseconds } from './src/fetch-retry/configuration/milliseconds';
|
|
5
9
|
|
|
6
10
|
export { FetchRetryConfig } from './src/fetch-retry/configuration/configurations';
|
package/package.json
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import type { FetchOptions } from './fetch-options';
|
|
2
|
-
import type { RetryConfiguring } from './fetch-retry/configuration/retry-configuring';
|
|
1
|
+
import type { ApiFetchOptions, FetchOptions } from './fetch-options';
|
|
3
2
|
|
|
4
3
|
export interface FetchHandlerInterface {
|
|
5
4
|
/**
|
|
@@ -17,18 +16,9 @@ export interface FetchHandlerInterface {
|
|
|
17
16
|
* A helper function to fetch a response from an API and get a JSON object
|
|
18
17
|
*
|
|
19
18
|
* @param path string
|
|
20
|
-
* @param options?:
|
|
19
|
+
* @param options?: ApiFetchOptions
|
|
21
20
|
*/
|
|
22
|
-
fetchApiResponse<T>(
|
|
23
|
-
url: string,
|
|
24
|
-
options?: {
|
|
25
|
-
includeCredentials?: boolean;
|
|
26
|
-
method?: string;
|
|
27
|
-
body?: BodyInit;
|
|
28
|
-
headers?: HeadersInit;
|
|
29
|
-
retryConfig?: RetryConfiguring;
|
|
30
|
-
},
|
|
31
|
-
): Promise<T>;
|
|
21
|
+
fetchApiResponse<T>(url: string, options?: ApiFetchOptions): Promise<T>;
|
|
32
22
|
|
|
33
23
|
/**
|
|
34
24
|
* A helper function to fetch a response from the IA API and get a JSON object
|
|
@@ -39,34 +29,16 @@ export interface FetchHandlerInterface {
|
|
|
39
29
|
* ie `fetchApiPathResponse('/items/123')` will fetch from `${apiBaseUrl}/items/123`
|
|
40
30
|
*
|
|
41
31
|
* @param path - Path to API endpoint
|
|
42
|
-
* @param options -
|
|
32
|
+
* @param options - ApiFetchOptions
|
|
43
33
|
*/
|
|
44
|
-
fetchApiPathResponse<T>(
|
|
45
|
-
path: string,
|
|
46
|
-
options?: {
|
|
47
|
-
includeCredentials?: boolean;
|
|
48
|
-
method?: string;
|
|
49
|
-
body?: BodyInit;
|
|
50
|
-
headers?: HeadersInit;
|
|
51
|
-
retryConfig?: RetryConfiguring;
|
|
52
|
-
},
|
|
53
|
-
): Promise<T>;
|
|
34
|
+
fetchApiPathResponse<T>(path: string, options?: ApiFetchOptions): Promise<T>;
|
|
54
35
|
|
|
55
36
|
/**
|
|
56
37
|
* Fetch a response from the IA API by path
|
|
57
38
|
*
|
|
58
39
|
* @deprecated Use `fetchApiPathResponse` instead.
|
|
59
40
|
* @param path - Path to API endpoint
|
|
60
|
-
* @param options -
|
|
41
|
+
* @param options - ApiFetchOptions
|
|
61
42
|
*/
|
|
62
|
-
fetchIAApiResponse<T>(
|
|
63
|
-
path: string,
|
|
64
|
-
options?: {
|
|
65
|
-
includeCredentials?: boolean;
|
|
66
|
-
method?: string;
|
|
67
|
-
body?: BodyInit;
|
|
68
|
-
headers?: HeadersInit;
|
|
69
|
-
retryConfig?: RetryConfiguring;
|
|
70
|
-
},
|
|
71
|
-
): Promise<T>;
|
|
43
|
+
fetchIAApiResponse<T>(path: string, options?: ApiFetchOptions): Promise<T>;
|
|
72
44
|
}
|
package/src/fetch-handler.ts
CHANGED
|
@@ -3,8 +3,15 @@ import {
|
|
|
3
3
|
FetchRetrierInterface,
|
|
4
4
|
} from './fetch-retry/fetch-retrier';
|
|
5
5
|
import type { FetchHandlerInterface } from './fetch-handler-interface';
|
|
6
|
-
import type { FetchOptions } from './fetch-options';
|
|
7
|
-
|
|
6
|
+
import type { ApiFetchOptions, FetchOptions } from './fetch-options';
|
|
7
|
+
|
|
8
|
+
export type FetchHandlerConstructorOptions = {
|
|
9
|
+
/** @deprecated Use `apiBaseUrl` instead. */
|
|
10
|
+
iaApiBaseUrl?: string;
|
|
11
|
+
apiBaseUrl?: string;
|
|
12
|
+
fetchRetrier?: FetchRetrierInterface;
|
|
13
|
+
searchParams?: string;
|
|
14
|
+
};
|
|
8
15
|
|
|
9
16
|
/**
|
|
10
17
|
* The FetchHandler adds some common helpers:
|
|
@@ -19,20 +26,7 @@ export class FetchHandler implements FetchHandlerInterface {
|
|
|
19
26
|
|
|
20
27
|
private searchParams?: string;
|
|
21
28
|
|
|
22
|
-
|
|
23
|
-
*
|
|
24
|
-
* @param options {
|
|
25
|
-
* iaApiBaseUrl - deprecated Use `apiBaseUrl` instead.
|
|
26
|
-
* apiBaseUrl - The base URL for API requests for `fetchApiPathResponse`
|
|
27
|
-
* fetchRetrier - FetchRetrier to use instead of the default
|
|
28
|
-
* searchParams - Search params to check for `reCache=1` (defaults to current window location)
|
|
29
|
-
*/
|
|
30
|
-
constructor(options?: {
|
|
31
|
-
iaApiBaseUrl?: string;
|
|
32
|
-
apiBaseUrl?: string;
|
|
33
|
-
fetchRetrier?: FetchRetrierInterface;
|
|
34
|
-
searchParams?: string;
|
|
35
|
-
}) {
|
|
29
|
+
constructor(options?: FetchHandlerConstructorOptions) {
|
|
36
30
|
if (options?.apiBaseUrl) {
|
|
37
31
|
this.apiBaseUrl = options.apiBaseUrl;
|
|
38
32
|
} else if (options?.iaApiBaseUrl) {
|
|
@@ -47,44 +41,23 @@ export class FetchHandler implements FetchHandlerInterface {
|
|
|
47
41
|
}
|
|
48
42
|
|
|
49
43
|
/** @inheritdoc */
|
|
50
|
-
async
|
|
51
|
-
|
|
52
|
-
options?:
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
return this.fetchApiResponse(url, options);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/** @inheritdoc */
|
|
65
|
-
async fetchIAApiResponse<T>(
|
|
66
|
-
path: string,
|
|
67
|
-
options?: {
|
|
68
|
-
includeCredentials?: boolean;
|
|
69
|
-
method?: string;
|
|
70
|
-
body?: BodyInit;
|
|
71
|
-
headers?: HeadersInit;
|
|
72
|
-
retryConfig?: RetryConfiguring;
|
|
73
|
-
},
|
|
74
|
-
): Promise<T> {
|
|
75
|
-
return this.fetchApiPathResponse(path, options);
|
|
44
|
+
async fetch(
|
|
45
|
+
request: RequestInfo,
|
|
46
|
+
options?: RequestInit | FetchOptions,
|
|
47
|
+
): Promise<Response> {
|
|
48
|
+
let finalRequest = request;
|
|
49
|
+
const urlParams = new URLSearchParams(this.searchParams);
|
|
50
|
+
if (urlParams.get('reCache') === '1') {
|
|
51
|
+
const urlString = typeof request === 'string' ? request : request.url;
|
|
52
|
+
finalRequest = this.addSearchParams(urlString, { reCache: '1' });
|
|
53
|
+
}
|
|
54
|
+
return this.fetchRetrier.fetchRetry(finalRequest, options);
|
|
76
55
|
}
|
|
77
56
|
|
|
78
57
|
/** @inheritdoc */
|
|
79
58
|
async fetchApiResponse<T>(
|
|
80
59
|
url: string,
|
|
81
|
-
options?:
|
|
82
|
-
includeCredentials?: boolean;
|
|
83
|
-
method?: string;
|
|
84
|
-
body?: BodyInit;
|
|
85
|
-
headers?: HeadersInit;
|
|
86
|
-
retryConfig?: RetryConfiguring;
|
|
87
|
-
},
|
|
60
|
+
options?: ApiFetchOptions,
|
|
88
61
|
): Promise<T> {
|
|
89
62
|
const requestInit: RequestInit = {};
|
|
90
63
|
if (options?.includeCredentials) requestInit.credentials = 'include';
|
|
@@ -100,22 +73,28 @@ export class FetchHandler implements FetchHandlerInterface {
|
|
|
100
73
|
}
|
|
101
74
|
|
|
102
75
|
/** @inheritdoc */
|
|
103
|
-
async
|
|
104
|
-
|
|
105
|
-
options?:
|
|
106
|
-
): Promise<
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
76
|
+
async fetchApiPathResponse<T>(
|
|
77
|
+
path: string,
|
|
78
|
+
options?: ApiFetchOptions,
|
|
79
|
+
): Promise<T> {
|
|
80
|
+
const url = `${this.apiBaseUrl}${path}`;
|
|
81
|
+
return this.fetchApiResponse(url, options);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/** @inheritdoc */
|
|
85
|
+
async fetchIAApiResponse<T>(
|
|
86
|
+
path: string,
|
|
87
|
+
options?: ApiFetchOptions,
|
|
88
|
+
): Promise<T> {
|
|
89
|
+
return this.fetchApiPathResponse(path, options);
|
|
114
90
|
}
|
|
115
91
|
|
|
116
92
|
/**
|
|
117
|
-
*
|
|
118
|
-
*
|
|
93
|
+
* Construct a new URL with the given search params added
|
|
94
|
+
*
|
|
95
|
+
* @param urlString - Original URL string
|
|
96
|
+
* @param params - Params to add
|
|
97
|
+
* @returns New URL string with params added
|
|
119
98
|
*/
|
|
120
99
|
private addSearchParams(
|
|
121
100
|
urlString: string,
|
package/src/fetch-options.ts
CHANGED
|
@@ -1,6 +1,20 @@
|
|
|
1
1
|
import type { RetryConfiguring } from './fetch-retry/configuration/retry-configuring';
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Base fetch options for FetchHandler
|
|
5
|
+
*/
|
|
3
6
|
export type FetchOptions = {
|
|
4
7
|
requestInit?: RequestInit;
|
|
5
8
|
retryConfig?: RetryConfiguring;
|
|
6
9
|
};
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* A convenience type for FetchHandler methods with common API fetch options.
|
|
13
|
+
*/
|
|
14
|
+
export type ApiFetchOptions = {
|
|
15
|
+
includeCredentials?: boolean;
|
|
16
|
+
method?: string;
|
|
17
|
+
body?: BodyInit;
|
|
18
|
+
headers?: HeadersInit;
|
|
19
|
+
retryConfig?: RetryConfiguring;
|
|
20
|
+
};
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import type { AnalyticsHandlerInterface } from '@internetarchive/analytics-manager';
|
|
2
|
-
import { promisedSleep } from '../utils/promised-sleep';
|
|
3
2
|
import { type FetchOptions } from '../fetch-options';
|
|
4
|
-
import {
|
|
5
|
-
import { DefaultRetryConfiguration } from './configuration/default-retry-configuration';
|
|
6
|
-
import type { RetryConfiguring } from './configuration/retry-configuring';
|
|
3
|
+
import { promisedSleep } from '../utils/promised-sleep';
|
|
7
4
|
import { FetchRetryConfig } from './configuration/configurations';
|
|
5
|
+
import type { RetryConfiguring } from './configuration/retry-configuring';
|
|
6
|
+
import { legacyArgsAsFetchOptions } from './legacy-args';
|
|
8
7
|
|
|
9
8
|
/**
|
|
10
9
|
* A class that retries a fetch request.
|