@alwatr/fetch 2.2.1 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -452
- package/README.md +8 -6
- package/dist/core.d.ts +28 -0
- package/dist/core.d.ts.map +1 -0
- package/dist/main.cjs +3 -0
- package/dist/main.cjs.map +7 -0
- package/dist/main.d.ts +54 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.mjs +3 -0
- package/dist/main.mjs.map +7 -0
- package/dist/type.d.ts +133 -0
- package/dist/type.d.ts.map +1 -0
- package/package.json +57 -14
- package/src/main.test.js +21 -0
- package/fetch.d.ts +0 -26
- package/fetch.d.ts.map +0 -1
- package/fetch.js +0 -293
- package/fetch.js.map +0 -1
- package/type.d.ts +0 -90
- package/type.d.ts.map +0 -1
- package/type.js +0 -2
- package/type.js.map +0 -1
package/dist/main.d.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { cacheSupported } from './core';
|
|
2
|
+
import type { FetchOptions, ResponseError, ResponseSuccess } from './type';
|
|
3
|
+
import type { JsonObject } from '@alwatr/type-helper';
|
|
4
|
+
export { cacheSupported };
|
|
5
|
+
export type * from './type';
|
|
6
|
+
/**
|
|
7
|
+
* It's a wrapper around the browser's `fetch` function that adds retry pattern, timeout, cacheStrategy,
|
|
8
|
+
* remove duplicates, etc.
|
|
9
|
+
*
|
|
10
|
+
* @see {@link FetchOptions}
|
|
11
|
+
* @see {@link ResponseSuccess}
|
|
12
|
+
* @see {@link ResponseError}
|
|
13
|
+
*
|
|
14
|
+
* @param options Fetch options.
|
|
15
|
+
*
|
|
16
|
+
* @returns A success or error response.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```typescript
|
|
20
|
+
* const responseJson = await fetchJson({
|
|
21
|
+
* url: '/api/products',
|
|
22
|
+
* queryParameters: {limit: 10},
|
|
23
|
+
* timeout: 8_000,
|
|
24
|
+
* retry: 3,
|
|
25
|
+
* cacheStrategy: 'stale_while_revalidate',
|
|
26
|
+
* cacheDuplicate: 'auto',
|
|
27
|
+
* });
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export declare function fetchJson<T extends JsonObject>(options: FetchOptions): Promise<ResponseSuccess<T> | ResponseError>;
|
|
31
|
+
/**
|
|
32
|
+
* It's a wrapper around the browser's `fetch` function that adds retry pattern, timeout, cacheStrategy,
|
|
33
|
+
* remove duplicates, etc.
|
|
34
|
+
*
|
|
35
|
+
* @see {@link FetchOptions}
|
|
36
|
+
*
|
|
37
|
+
* @param options Fetch options.
|
|
38
|
+
*
|
|
39
|
+
* @returns A promise that resolves to the Response to that request, whether it is successful or not.
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```typescript
|
|
43
|
+
* const response = await fetch({
|
|
44
|
+
* url: '/api/products',
|
|
45
|
+
* queryParameters: {limit: 10},
|
|
46
|
+
* timeout: 8_000,
|
|
47
|
+
* retry: 3,
|
|
48
|
+
* cacheStrategy: 'stale_while_revalidate',
|
|
49
|
+
* cacheDuplicate: 'auto',
|
|
50
|
+
* });
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
export declare function fetch(options: FetchOptions): Promise<Response>;
|
|
54
|
+
//# sourceMappingURL=main.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiD,cAAc,EAAC,MAAM,QAAQ,CAAC;AAEtF,OAAO,KAAK,EAAC,YAAY,EAAE,aAAa,EAAE,eAAe,EAAC,MAAM,QAAQ,CAAC;AACzE,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,qBAAqB,CAAC;AAEpD,OAAO,EAAC,cAAc,EAAC,CAAC;AACxB,mBAAmB,QAAQ,CAAC;AAE5B;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAsB,SAAS,CAAC,CAAC,SAAS,UAAU,EAAE,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,GAAG,aAAa,CAAC,CAyBxH;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,QAAQ,CAAC,CAI9D"}
|
package/dist/main.mjs
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
/* @alwatr/fetch v3.1.0 */
|
|
2
|
+
import{globalScope as f}from"@alwatr/global-scope";import{definePackage as w}from"@alwatr/logger";import{waitForTimeout as g}from"@alwatr/wait";var n=w("@alwatr/fetch","3.1.0"),m,s=Object.hasOwn(f,"caches"),u={};function y(e){if(e.method??(e.method="GET"),e.window??(e.window=null),e.timeout??(e.timeout=8e3),e.retry??(e.retry=3),e.retryDelay??(e.retryDelay=1e3),e.cacheStrategy??(e.cacheStrategy="network_only"),e.removeDuplicate??(e.removeDuplicate="never"),e.headers??(e.headers={}),e.cacheStrategy!=="network_only"&&s!==!0&&(n.incident?.("fetch","fetch_cache_strategy_unsupported",{cacheSupported:s}),e.cacheStrategy="network_only"),e.removeDuplicate==="auto"&&(e.removeDuplicate=s?"until_load":"always"),e.url.lastIndexOf("?")===-1&&e.queryParameters!=null){let a=e.queryParameters,t=Object.keys(a).map(r=>`${r}=${String(a[r])}`);t.length>0&&(e.url+="?"+t.join("&"))}return e.bodyJson!==void 0&&(e.body=JSON.stringify(e.bodyJson),e.headers["Content-Type"]="application/json"),e.bearerToken!==void 0?e.headers.Authorization=`Bearer ${e.bearerToken}`:e.alwatrAuth!==void 0&&(e.headers.Authorization=`Alwatr ${e.alwatrAuth.userId}:${e.alwatrAuth.userToken}`),e}async function _(e){if(e.cacheStrategy==="network_only")return h(e);n.logMethod?.("_handleCacheStrategy"),m==null&&e.cacheStorageName==null&&(m=await caches.open("fetch_cache"));let a=e.cacheStorageName!=null?await caches.open(e.cacheStorageName):m,t=new Request(e.url,e);switch(e.cacheStrategy){case"cache_first":{let r=await a.match(t);if(r!=null)return r;let c=await h(e);return c.ok&&a.put(t,c.clone()),c}case"cache_only":{let r=await a.match(t);if(r==null)throw n.accident("_handleCacheStrategy","fetch_cache_not_found",{url:t.url}),new Error("fetch_cache_not_found");return r}case"network_first":try{let r=await h(e);return r.ok&&a.put(t,r.clone()),r}catch(r){let c=await a.match(t);if(c!=null)return c;throw r}case"update_cache":{let r=await h(e);return r.ok&&a.put(t,r.clone()),r}case"stale_while_revalidate":{let r=await a.match(t),c=h(e).then(l=>(l.ok&&(a.put(t,l.clone()),typeof e.revalidateCallback=="function"&&setTimeout(e.revalidateCallback,0,l.clone())),l));return r??c}default:return h(e)}}async function h(e){if(e.removeDuplicate==="never")return i(e);n.logMethod?.("handleRemoveDuplicate_");let a=e.method+" "+e.url;u[a]??(u[a]=i(e));try{let t=await u[a];return u[a]!=null&&(t.ok!==!0||e.removeDuplicate==="until_load")&&delete u[a],t.clone()}catch(t){throw delete u[a],t}}async function i(e){if(!(e.retry>1))return o(e);n.logMethod?.("_handleRetryPattern"),e.retry--;let a=e.signal;try{let t=await o(e);if(t.status<500)return t;throw new Error("fetch_server_error")}catch(t){if(n.accident("fetch","fetch_failed_retry",t),f.navigator?.onLine===!1)throw n.accident("handleRetryPattern_","offline","Skip retry because offline"),t;return await g(e.retryDelay),e.signal=a,i(e)}}function o(e){return e.timeout===0?f.fetch(e.url,e):(n.logMethod?.("handleTimeout_"),new Promise((a,t)=>{let r=typeof AbortController=="function"?new AbortController:null,c=e.signal;e.signal=r?.signal,r!==null&&c!=null&&c.addEventListener("abort",()=>r.abort(),{once:!0});let l=setTimeout(()=>{t(new Error("fetch_timeout")),r?.abort("fetch_timeout")},e.timeout);f.fetch(e.url,e).then(d=>a(d)).catch(d=>t(d)).finally(()=>{delete e.signal,clearTimeout(l)})}))}async function T(e){let a,t,r;try{return a=await R(e),t=await a.text(),r=JSON.parse(t),r.ok=!0,r.statusCode=a.status,r}catch(c){let l={ok:!1,statusCode:a?.status,statusText:a?.statusText,errorCode:r?.errorCode??c.message,responseText:t,meta:r?.meta};return n.accident("fetchJson","fetch_failed",{responseError:l,error:c}),l}}function R(e){return e=y(e),n.logMethodArgs?.("fetch",{options:e}),_(e)}export{s as cacheSupported,R as fetch,T as fetchJson};
|
|
3
|
+
//# sourceMappingURL=main.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/core.ts", "../src/main.ts"],
|
|
4
|
+
"sourcesContent": ["import {globalScope} from '@alwatr/global-scope';\nimport {definePackage} from '@alwatr/logger';\nimport {waitForTimeout} from '@alwatr/wait';\n\nimport type {FetchOptions} from './type';\nimport type {} from '@alwatr/nano-build';\n\nexport const logger_ = definePackage('@alwatr/fetch', __package_version__);\n\nlet cacheStorage_: Cache;\nexport const cacheSupported = Object.hasOwn(globalScope, 'caches');\n\nconst duplicateRequestStorage_: Record<string, Promise<Response>> = {};\n\n/**\n * Process fetch options and set defaults, etc.\n *\n * @param options Fetch options.\n *\n * @returns Required fetch options.\n */\nexport function processOptions_(options: FetchOptions): Required<FetchOptions> {\n options.method ??= 'GET';\n options.window ??= null;\n\n options.timeout ??= 8_000;\n options.retry ??= 3;\n options.retryDelay ??= 1_000;\n options.cacheStrategy ??= 'network_only';\n options.removeDuplicate ??= 'never';\n options.headers ??= {};\n\n if (options.cacheStrategy !== 'network_only' && cacheSupported !== true) {\n logger_.incident?.('fetch', 'fetch_cache_strategy_unsupported', {\n cacheSupported,\n });\n options.cacheStrategy = 'network_only';\n }\n\n if (options.removeDuplicate === 'auto') {\n options.removeDuplicate = cacheSupported ? 'until_load' : 'always';\n }\n\n if (options.url.lastIndexOf('?') === -1 && options.queryParameters != null) {\n const queryParameters = options.queryParameters;\n // prettier-ignore\n const queryArray = Object\n .keys(queryParameters)\n .map((key) => `${key}=${String(queryParameters[key])}`);\n\n if (queryArray.length > 0) {\n options.url += '?' + queryArray.join('&');\n }\n }\n\n if (options.bodyJson !== undefined) {\n options.body = JSON.stringify(options.bodyJson);\n options.headers['Content-Type'] = 'application/json';\n }\n\n if (options.bearerToken !== undefined) {\n options.headers.Authorization = `Bearer ${options.bearerToken}`;\n }\n else if (options.alwatrAuth !== undefined) {\n options.headers.Authorization = `Alwatr ${options.alwatrAuth.userId}:${options.alwatrAuth.userToken}`;\n }\n\n return options as Required<FetchOptions>;\n}\n\n/**\n * Handle Cache Strategy over `handleRemoveDuplicate_`.\n */\nexport async function handleCacheStrategy_(options: Required<FetchOptions>): Promise<Response> {\n if (options.cacheStrategy === 'network_only') {\n return handleRemoveDuplicate_(options);\n }\n // else handle cache strategies!\n logger_.logMethod?.('_handleCacheStrategy');\n\n if (cacheStorage_ == null && options.cacheStorageName == null) {\n cacheStorage_ = await caches.open('fetch_cache');\n }\n\n const cacheStorage = options.cacheStorageName != null ? await caches.open(options.cacheStorageName) : cacheStorage_;\n\n const request = new Request(options.url, options);\n\n switch (options.cacheStrategy) {\n case 'cache_first': {\n const cachedResponse = await cacheStorage.match(request);\n if (cachedResponse != null) {\n return cachedResponse;\n }\n // else\n const response = await handleRemoveDuplicate_(options);\n if (response.ok) {\n cacheStorage.put(request, response.clone());\n }\n return response;\n }\n\n case 'cache_only': {\n const cachedResponse = await cacheStorage.match(request);\n if (cachedResponse == null) {\n logger_.accident('_handleCacheStrategy', 'fetch_cache_not_found', {url: request.url});\n throw new Error('fetch_cache_not_found');\n }\n // else\n return cachedResponse;\n }\n\n case 'network_first': {\n try {\n const networkResponse = await handleRemoveDuplicate_(options);\n if (networkResponse.ok) {\n cacheStorage.put(request, networkResponse.clone());\n }\n return networkResponse;\n }\n catch (err) {\n const cachedResponse = await cacheStorage.match(request);\n if (cachedResponse != null) {\n return cachedResponse;\n }\n // else\n throw err;\n }\n }\n\n case 'update_cache': {\n const networkResponse = await handleRemoveDuplicate_(options);\n if (networkResponse.ok) {\n cacheStorage.put(request, networkResponse.clone());\n }\n return networkResponse;\n }\n\n case 'stale_while_revalidate': {\n const cachedResponse = await cacheStorage.match(request);\n const fetchedResponsePromise = handleRemoveDuplicate_(options).then((networkResponse) => {\n if (networkResponse.ok) {\n cacheStorage.put(request, networkResponse.clone());\n if (typeof options.revalidateCallback === 'function') {\n setTimeout(options.revalidateCallback, 0, networkResponse.clone());\n }\n }\n return networkResponse;\n });\n\n return cachedResponse ?? fetchedResponsePromise;\n }\n\n default: {\n return handleRemoveDuplicate_(options);\n }\n }\n}\n\n/**\n * Handle Remove Duplicates over `_handleRetryPattern`.\n */\nexport async function handleRemoveDuplicate_(options: Required<FetchOptions>): Promise<Response> {\n if (options.removeDuplicate === 'never') return handleRetryPattern_(options);\n\n logger_.logMethod?.('handleRemoveDuplicate_');\n\n const cacheKey = options.method + ' ' + options.url;\n\n // We must cache fetch promise without await for handle other parallel requests.\n duplicateRequestStorage_[cacheKey] ??= handleRetryPattern_(options);\n\n try {\n // For all requests need to await for clone responses.\n const response = await duplicateRequestStorage_[cacheKey];\n\n if (duplicateRequestStorage_[cacheKey] != null) {\n if (response.ok !== true || options.removeDuplicate === 'until_load') {\n delete duplicateRequestStorage_[cacheKey];\n }\n }\n\n return response.clone();\n }\n catch (err) {\n // clean cache on any error.\n delete duplicateRequestStorage_[cacheKey];\n throw err;\n }\n}\n\n/**\n * Handle retry pattern over `handleTimeout_`.\n */\nexport async function handleRetryPattern_(options: Required<FetchOptions>): Promise<Response> {\n if (!(options.retry > 1)) return handleTimeout_(options);\n\n logger_.logMethod?.('_handleRetryPattern');\n options.retry--;\n\n const externalAbortSignal = options.signal;\n\n try {\n const response = await handleTimeout_(options);\n\n if (response.status < 500) {\n return response;\n }\n // else\n throw new Error('fetch_server_error');\n }\n catch (err) {\n logger_.accident('fetch', 'fetch_failed_retry', err);\n\n if (globalScope.navigator?.onLine === false) {\n logger_.accident('handleRetryPattern_', 'offline', 'Skip retry because offline');\n throw err;\n }\n\n await waitForTimeout(options.retryDelay);\n\n options.signal = externalAbortSignal;\n return handleRetryPattern_(options);\n }\n}\n\n/**\n * It's a wrapper around the browser's `fetch` with timeout.\n */\nexport function handleTimeout_(options: FetchOptions): Promise<Response> {\n if (options.timeout === 0) {\n return globalScope.fetch(options.url, options);\n }\n // else\n logger_.logMethod?.('handleTimeout_');\n return new Promise((resolved, reject) => {\n const abortController = typeof AbortController === 'function' ? new AbortController() : null;\n const externalAbortSignal = options.signal;\n options.signal = abortController?.signal;\n\n if (abortController !== null && externalAbortSignal != null) {\n // Respect external abort signal\n externalAbortSignal.addEventListener('abort', () => abortController.abort(), {once: true});\n }\n\n const timeoutId = setTimeout(() => {\n reject(new Error('fetch_timeout'));\n abortController?.abort('fetch_timeout');\n }, options.timeout);\n\n // abortController.signal.addEventListener('abort', () => {\n // logger.incident('fetch', 'fetch_abort_signal', {\n // reason: abortController.signal.reason,\n // });\n // });\n\n globalScope\n .fetch(options.url, options)\n .then((response) => resolved(response))\n .catch((reason) => reject(reason))\n .finally(() => {\n delete options.signal; // try to avoid memory leak in nodejs!\n clearTimeout(timeoutId);\n });\n });\n}\n", "import {handleCacheStrategy_, logger_, processOptions_, cacheSupported} from './core';\n\nimport type {FetchOptions, ResponseError, ResponseSuccess} from './type';\nimport type {JsonObject} from '@alwatr/type-helper';\n\nexport {cacheSupported};\nexport type * from './type';\n\n/**\n * It's a wrapper around the browser's `fetch` function that adds retry pattern, timeout, cacheStrategy,\n * remove duplicates, etc.\n *\n * @see {@link FetchOptions}\n * @see {@link ResponseSuccess}\n * @see {@link ResponseError}\n *\n * @param options Fetch options.\n *\n * @returns A success or error response.\n *\n * @example\n * ```typescript\n * const responseJson = await fetchJson({\n * url: '/api/products',\n * queryParameters: {limit: 10},\n * timeout: 8_000,\n * retry: 3,\n * cacheStrategy: 'stale_while_revalidate',\n * cacheDuplicate: 'auto',\n * });\n * ```\n */\nexport async function fetchJson<T extends JsonObject>(options: FetchOptions): Promise<ResponseSuccess<T> | ResponseError> {\n let response;\n let responseText;\n let responseJson;\n try {\n response = await fetch(options);\n responseText = await response.text();\n responseJson = JSON.parse(responseText) as ResponseSuccess<T>;\n responseJson.ok = true;\n responseJson.statusCode = response.status;\n return responseJson;\n }\n catch (error) {\n const responseError: ResponseError = {\n ok: false,\n statusCode: response?.status,\n statusText: response?.statusText,\n errorCode: (responseJson?.errorCode as string) ?? (error as Error).message,\n responseText,\n meta: responseJson?.meta as JsonObject,\n };\n\n logger_.accident('fetchJson', 'fetch_failed', {responseError, error});\n return responseError;\n }\n}\n\n/**\n * It's a wrapper around the browser's `fetch` function that adds retry pattern, timeout, cacheStrategy,\n * remove duplicates, etc.\n *\n * @see {@link FetchOptions}\n *\n * @param options Fetch options.\n *\n * @returns A promise that resolves to the Response to that request, whether it is successful or not.\n *\n * @example\n * ```typescript\n * const response = await fetch({\n * url: '/api/products',\n * queryParameters: {limit: 10},\n * timeout: 8_000,\n * retry: 3,\n * cacheStrategy: 'stale_while_revalidate',\n * cacheDuplicate: 'auto',\n * });\n * ```\n */\nexport function fetch(options: FetchOptions): Promise<Response> {\n options = processOptions_(options);\n logger_.logMethodArgs?.('fetch', {options});\n return handleCacheStrategy_(options as Required<FetchOptions>);\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["globalScope", "definePackage", "waitForTimeout", "logger_", "cacheStorage_", "cacheSupported", "duplicateRequestStorage_", "processOptions_", "options", "queryParameters", "queryArray", "key", "handleCacheStrategy_", "handleRemoveDuplicate_", "cacheStorage", "request", "cachedResponse", "response", "networkResponse", "err", "fetchedResponsePromise", "handleRetryPattern_", "cacheKey", "handleTimeout_", "externalAbortSignal", "resolved", "reject", "abortController", "timeoutId", "reason", "fetchJson", "options", "response", "responseText", "responseJson", "fetch", "error", "responseError", "logger_", "processOptions_", "handleCacheStrategy_"]
|
|
7
|
+
}
|
package/dist/type.d.ts
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import type { Dictionary, Json, JsonObject } from '@alwatr/type-helper';
|
|
2
|
+
/**
|
|
3
|
+
* Represents the available HTTP methods.
|
|
4
|
+
*/
|
|
5
|
+
export type Methods = 'GET' | 'HEAD' | 'POST' | 'PUT' | 'DELETE' | 'CONNECT' | 'TRACE' | 'OPTIONS' | 'PATCH';
|
|
6
|
+
/**
|
|
7
|
+
* Represents a dictionary of query parameters.
|
|
8
|
+
* The keys are strings and the values can be strings, numbers, or booleans.
|
|
9
|
+
*/
|
|
10
|
+
export type QueryParameters = Dictionary<string | number | boolean>;
|
|
11
|
+
/**
|
|
12
|
+
* Represents the cache strategy for fetching data.
|
|
13
|
+
*
|
|
14
|
+
* - 'network_only': Fetches data from the network only.
|
|
15
|
+
* - 'network_first': Tries to fetch data from the network first, and falls back to the cache if the network request fails.
|
|
16
|
+
* - 'cache_only': Fetches data from the cache only.
|
|
17
|
+
* - 'cache_first': Tries to fetch data from the cache first, and falls back to the network if the cache request fails.
|
|
18
|
+
* - 'update_cache': Fetches data from the network and updates the cache with the new data.
|
|
19
|
+
* - 'stale_while_revalidate': Returns the stale data from the cache while fetching updated data from the network.
|
|
20
|
+
*/
|
|
21
|
+
export type CacheStrategy = 'network_only' | 'network_first' | 'cache_only' | 'cache_first' | 'update_cache' | 'stale_while_revalidate';
|
|
22
|
+
/**
|
|
23
|
+
* Represents the caching behavior for duplicate requests.
|
|
24
|
+
* - 'never': The response will not be cached.
|
|
25
|
+
* - 'always': The response will always be cached.
|
|
26
|
+
* - 'until_load': The response will be cached until the page is reloaded.
|
|
27
|
+
* - 'auto': The caching behavior will be determined automatically.
|
|
28
|
+
*/
|
|
29
|
+
export type CacheDuplicate = 'never' | 'always' | 'until_load' | 'auto';
|
|
30
|
+
/**
|
|
31
|
+
* Options for the fetch request.
|
|
32
|
+
*/
|
|
33
|
+
export interface FetchOptions extends RequestInit {
|
|
34
|
+
/**
|
|
35
|
+
* Request URL.
|
|
36
|
+
*/
|
|
37
|
+
url: string;
|
|
38
|
+
/**
|
|
39
|
+
* A string to set the request's method.
|
|
40
|
+
*
|
|
41
|
+
* @default 'GET'
|
|
42
|
+
*/
|
|
43
|
+
method?: Methods;
|
|
44
|
+
/**
|
|
45
|
+
* A Headers object to set the request's headers.
|
|
46
|
+
*/
|
|
47
|
+
headers?: Dictionary<string>;
|
|
48
|
+
/**
|
|
49
|
+
* A timeout for the fetch request.
|
|
50
|
+
* Set `0` to disable it.
|
|
51
|
+
*
|
|
52
|
+
* Use with caution, as it may cause memory leaks in Node.js.
|
|
53
|
+
*
|
|
54
|
+
* @default 8_000 ms
|
|
55
|
+
*/
|
|
56
|
+
timeout?: number;
|
|
57
|
+
/**
|
|
58
|
+
* If the fetch response is not acceptable or timed out, it will retry the request.
|
|
59
|
+
*
|
|
60
|
+
* @default 3
|
|
61
|
+
*/
|
|
62
|
+
retry?: number;
|
|
63
|
+
/**
|
|
64
|
+
* Delay before each retry.
|
|
65
|
+
*
|
|
66
|
+
* @default 1_000 ms
|
|
67
|
+
*/
|
|
68
|
+
retryDelay?: number;
|
|
69
|
+
/**
|
|
70
|
+
* Simple memory caching to remove duplicate/parallel requests.
|
|
71
|
+
*
|
|
72
|
+
* - `never`: Never use memory caching.
|
|
73
|
+
* - `always`: Always use memory caching and remove all duplicate requests.
|
|
74
|
+
* - `until_load`: Cache parallel requests until the request is completed (it will be removed after the promise is resolved).
|
|
75
|
+
* - `auto`: If CacheStorage is supported, use `until_load` strategy; otherwise, use `always`.
|
|
76
|
+
*
|
|
77
|
+
* @default 'never'
|
|
78
|
+
*/
|
|
79
|
+
removeDuplicate?: CacheDuplicate;
|
|
80
|
+
/**
|
|
81
|
+
* Strategies for caching.
|
|
82
|
+
*
|
|
83
|
+
* - `network_only`: Only network request without any cache.
|
|
84
|
+
* - `network_first`: Network first, falling back to cache.
|
|
85
|
+
* - `cache_only`: Cache only without any network request.
|
|
86
|
+
* - `cache_first`: Cache first, falling back to network.
|
|
87
|
+
* - `update_cache`: Like `network_only` but with update cache.
|
|
88
|
+
* - `stale_while_revalidate`: Fastest strategy, use cached first but always request network to update the cache.
|
|
89
|
+
*
|
|
90
|
+
* @default 'network_only'
|
|
91
|
+
*/
|
|
92
|
+
cacheStrategy?: CacheStrategy;
|
|
93
|
+
/**
|
|
94
|
+
* Revalidate callback for `stale_while_revalidate` cache strategy.
|
|
95
|
+
*/
|
|
96
|
+
revalidateCallback?: (response: Response) => void | Promise<void>;
|
|
97
|
+
/**
|
|
98
|
+
* Custom name for the cache storage.
|
|
99
|
+
*/
|
|
100
|
+
cacheStorageName?: string;
|
|
101
|
+
/**
|
|
102
|
+
* Body as a JavaScript object.
|
|
103
|
+
*/
|
|
104
|
+
bodyJson?: Json;
|
|
105
|
+
/**
|
|
106
|
+
* URL query parameters as a JavaScript object.
|
|
107
|
+
*/
|
|
108
|
+
queryParameters?: QueryParameters;
|
|
109
|
+
/**
|
|
110
|
+
* Add token to the Authentication bearer header.
|
|
111
|
+
*/
|
|
112
|
+
bearerToken?: string;
|
|
113
|
+
/**
|
|
114
|
+
* Alwatr token scheme
|
|
115
|
+
*/
|
|
116
|
+
alwatrAuth?: {
|
|
117
|
+
userId: string;
|
|
118
|
+
userToken: string;
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
export type ResponseSuccess<T extends JsonObject> = T & {
|
|
122
|
+
ok: true;
|
|
123
|
+
statusCode: number;
|
|
124
|
+
};
|
|
125
|
+
export type ResponseError = {
|
|
126
|
+
ok: false;
|
|
127
|
+
statusCode?: number;
|
|
128
|
+
statusText?: string;
|
|
129
|
+
errorCode: string;
|
|
130
|
+
responseText?: string;
|
|
131
|
+
meta?: JsonObject;
|
|
132
|
+
};
|
|
133
|
+
//# sourceMappingURL=type.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"type.d.ts","sourceRoot":"","sources":["../src/type.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,UAAU,EAAE,IAAI,EAAE,UAAU,EAAC,MAAM,qBAAqB,CAAC;AAEtE;;GAEG;AACH,MAAM,MAAM,OAAO,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,OAAO,CAAC;AAE7G;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG,UAAU,CAAC,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;AAEpE;;;;;;;;;GASG;AACH,MAAM,MAAM,aAAa,GAAG,cAAc,GAAG,eAAe,GAAG,YAAY,GAAG,aAAa,GAAG,cAAc,GAAG,wBAAwB,CAAC;AAExI;;;;;;GAMG;AACH,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,QAAQ,GAAG,YAAY,GAAG,MAAM,CAAC;AAExE;;GAEG;AACH,MAAM,WAAW,YAAa,SAAQ,WAAW;IAC/C;;OAEG;IACH,GAAG,EAAE,MAAM,CAAC;IAEZ;;;;OAIG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB;;OAEG;IACH,OAAO,CAAC,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;IAE7B;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;;;;;;;OASG;IACH,eAAe,CAAC,EAAE,cAAc,CAAC;IAEjC;;;;;;;;;;;OAWG;IACH,aAAa,CAAC,EAAE,aAAa,CAAC;IAE9B;;OAEG;IACH,kBAAkB,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAElE;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B;;OAEG;IACH,QAAQ,CAAC,EAAE,IAAI,CAAC;IAEhB;;OAEG;IACH,eAAe,CAAC,EAAE,eAAe,CAAC;IAElC;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,UAAU,CAAC,EAAE;QACX,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAED,MAAM,MAAM,eAAe,CAAC,CAAC,SAAS,UAAU,IAAI,CAAC,GAAG;IACtD,EAAE,EAAE,IAAI,CAAC;IACT,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,EAAE,EAAE,KAAK,CAAC;IACV,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,UAAU,CAAC;CACnB,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alwatr/fetch",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "Enhanced fetch API with cache strategy, retry pattern, timeout, helper methods and enhanced types
|
|
3
|
+
"version": "3.1.0",
|
|
4
|
+
"description": "Enhanced fetch API with cache strategy, retry pattern, timeout, helper methods and enhanced types.",
|
|
5
|
+
"author": "S. Ali Mihandoost <ali.mihandoost@gmail.com>",
|
|
5
6
|
"keywords": [
|
|
6
7
|
"fetch",
|
|
7
8
|
"request",
|
|
@@ -9,37 +10,79 @@
|
|
|
9
10
|
"retry",
|
|
10
11
|
"cache",
|
|
11
12
|
"timeout",
|
|
13
|
+
"cross-platform",
|
|
14
|
+
"ECMAScript",
|
|
12
15
|
"typescript",
|
|
16
|
+
"javascript",
|
|
17
|
+
"node",
|
|
18
|
+
"nodejs",
|
|
19
|
+
"browser",
|
|
13
20
|
"esm",
|
|
21
|
+
"module",
|
|
22
|
+
"utility",
|
|
23
|
+
"util",
|
|
24
|
+
"utils",
|
|
25
|
+
"nanolib",
|
|
14
26
|
"alwatr"
|
|
15
27
|
],
|
|
16
|
-
"main": "fetch.js",
|
|
17
28
|
"type": "module",
|
|
18
|
-
"
|
|
19
|
-
"
|
|
29
|
+
"main": "./dist/main.cjs",
|
|
30
|
+
"module": "./dist/main.mjs",
|
|
31
|
+
"types": "./dist/main.d.ts",
|
|
32
|
+
"exports": {
|
|
33
|
+
".": {
|
|
34
|
+
"import": "./dist/main.mjs",
|
|
35
|
+
"require": "./dist/main.cjs",
|
|
36
|
+
"types": "./dist/main.d.ts"
|
|
37
|
+
}
|
|
38
|
+
},
|
|
20
39
|
"license": "MIT",
|
|
21
40
|
"files": [
|
|
22
|
-
"**/*.{
|
|
41
|
+
"**/*.{js,mjs,cjs,map,d.ts,html,md}",
|
|
42
|
+
"!demo/**/*"
|
|
23
43
|
],
|
|
24
44
|
"publishConfig": {
|
|
25
45
|
"access": "public"
|
|
26
46
|
},
|
|
27
47
|
"repository": {
|
|
28
48
|
"type": "git",
|
|
29
|
-
"url": "https://github.com/Alwatr/
|
|
49
|
+
"url": "https://github.com/Alwatr/nanolib",
|
|
30
50
|
"directory": "packages/fetch"
|
|
31
51
|
},
|
|
32
|
-
"homepage": "https://github.com/Alwatr/
|
|
52
|
+
"homepage": "https://github.com/Alwatr/nanolib/tree/next/packages/fetch#readme",
|
|
33
53
|
"bugs": {
|
|
34
|
-
"url": "https://github.com/Alwatr/
|
|
54
|
+
"url": "https://github.com/Alwatr/nanolib/issues"
|
|
55
|
+
},
|
|
56
|
+
"prettier": "@alwatr/prettier-config",
|
|
57
|
+
"scripts": {
|
|
58
|
+
"b": "yarn run build",
|
|
59
|
+
"t": "yarn run test",
|
|
60
|
+
"w": "yarn run watch",
|
|
61
|
+
"c": "yarn run clean",
|
|
62
|
+
"cb": "yarn run clean && yarn run build",
|
|
63
|
+
"d": "yarn run build:es && yarn node --enable-source-maps --trace-warnings",
|
|
64
|
+
"build": "yarn run build:ts & yarn run build:es",
|
|
65
|
+
"build:es": "nano-build --preset=module",
|
|
66
|
+
"build:ts": "tsc --build",
|
|
67
|
+
"test": "NODE_OPTIONS=\"$NODE_OPTIONS --enable-source-maps --experimental-vm-modules\" jest",
|
|
68
|
+
"watch": "yarn run watch:ts & yarn run watch:es",
|
|
69
|
+
"watch:es": "yarn run build:es --watch",
|
|
70
|
+
"watch:ts": "yarn run build:ts --watch --preserveWatchOutput",
|
|
71
|
+
"clean": "rm -rfv dist *.tsbuildinfo"
|
|
35
72
|
},
|
|
36
73
|
"dependencies": {
|
|
37
|
-
"@alwatr/
|
|
38
|
-
"@alwatr/
|
|
74
|
+
"@alwatr/global-scope": "^1.1.12",
|
|
75
|
+
"@alwatr/logger": "^3.2.4",
|
|
76
|
+
"@alwatr/wait": "^1.1.7"
|
|
39
77
|
},
|
|
40
78
|
"devDependencies": {
|
|
41
|
-
"@alwatr/
|
|
42
|
-
"@
|
|
79
|
+
"@alwatr/nano-build": "^1.3.2",
|
|
80
|
+
"@alwatr/prettier-config": "^1.0.4",
|
|
81
|
+
"@alwatr/tsconfig-base": "^1.1.1",
|
|
82
|
+
"@alwatr/type-helper": "^1.2.0",
|
|
83
|
+
"@types/node": "^20.11.6",
|
|
84
|
+
"jest": "^29.7.0",
|
|
85
|
+
"typescript": "^5.3.3"
|
|
43
86
|
},
|
|
44
|
-
"gitHead": "
|
|
87
|
+
"gitHead": "3486060abc5f331a3b8c78da7f1d671ba1139b5d"
|
|
45
88
|
}
|
package/src/main.test.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import {fetch} from '@alwatr/fetch'
|
|
2
|
+
|
|
3
|
+
describe('fetch with search params', () => {
|
|
4
|
+
it('should make a GET request to the specified URL', async () => {
|
|
5
|
+
const options = {
|
|
6
|
+
url: 'http://httpbin.org/get',
|
|
7
|
+
queryParameters: {
|
|
8
|
+
a: 2
|
|
9
|
+
},
|
|
10
|
+
cacheStrategy: 'network_only',
|
|
11
|
+
removeDuplicate: 'auto'
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
fetch(options);
|
|
15
|
+
const response = await fetch(options);
|
|
16
|
+
const responseJson = await response.json();
|
|
17
|
+
|
|
18
|
+
expect(response.status).toBe(200);
|
|
19
|
+
expect(responseJson.args.a).toBe('2');
|
|
20
|
+
});
|
|
21
|
+
});
|
package/fetch.d.ts
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import type { FetchOptions } from './type.js';
|
|
2
|
-
import type { AlwatrServiceResponse } from '@alwatr/type';
|
|
3
|
-
export type * from './type.js';
|
|
4
|
-
/**
|
|
5
|
-
* Fetch from alwatr services and return standard response.
|
|
6
|
-
*/
|
|
7
|
-
export declare function serviceRequest<T extends AlwatrServiceResponse = AlwatrServiceResponse>(options: FetchOptions): Promise<T>;
|
|
8
|
-
/**
|
|
9
|
-
* It's a wrapper around the browser's `fetch` function that adds retry pattern, timeout, cacheStrategy,
|
|
10
|
-
* remove duplicates, etc.
|
|
11
|
-
*
|
|
12
|
-
* Example:
|
|
13
|
-
*
|
|
14
|
-
* ```ts
|
|
15
|
-
* const response = await fetch({
|
|
16
|
-
* url: '/api/products',
|
|
17
|
-
* queryParameters: {limit: 10},
|
|
18
|
-
* timeout: 10_000,
|
|
19
|
-
* retry: 3,
|
|
20
|
-
* cacheStrategy: 'stale_while_revalidate',
|
|
21
|
-
* cacheDuplicate: 'auto',
|
|
22
|
-
* });
|
|
23
|
-
* ```
|
|
24
|
-
*/
|
|
25
|
-
export declare function fetch(options: FetchOptions): Promise<Response>;
|
|
26
|
-
//# sourceMappingURL=fetch.d.ts.map
|
package/fetch.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["src/fetch.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,WAAW,CAAC;AAC5C,OAAO,KAAK,EAAC,qBAAqB,EAAC,MAAM,cAAc,CAAC;AAExD,mBAAmB,WAAW,CAAC;AAW/B;;GAEG;AACH,wBAAsB,cAAc,CAAC,CAAC,SAAS,qBAAqB,GAAG,qBAAqB,EAC1F,OAAO,EAAE,YAAY,GACpB,OAAO,CAAC,CAAC,CAAC,CAwDZ;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,QAAQ,CAAC,CAI9D"}
|