@alwatr/fetch 2.1.5 → 2.2.1

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 CHANGED
@@ -3,6 +3,20 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [2.2.1](https://github.com/Alwatr/alwatr-es-sdk/compare/@alwatr/fetch@2.2.0...@alwatr/fetch@2.2.1) (2023-12-19)
7
+
8
+ **Note:** Version bump only for package @alwatr/fetch
9
+
10
+ # [2.2.0](https://github.com/Alwatr/alwatr-es-sdk/compare/@alwatr/fetch@2.1.5...@alwatr/fetch@2.2.0) (2023-12-19)
11
+
12
+ ### Bug Fixes
13
+
14
+ * **fetch:** AbortController not support issue ([10f6dbc](https://github.com/Alwatr/alwatr-es-sdk/commit/10f6dbc816d6f07a81d49945ec0291b132a75fb7)) by @AliMD
15
+
16
+ ### Features
17
+
18
+ * use globalScope instead globalThis ([94342bb](https://github.com/Alwatr/alwatr-es-sdk/commit/94342bb7b467376173a65d8cdf6bb106338f425b)) by @njfamirm
19
+
6
20
  ## [2.1.5](https://github.com/Alwatr/alwatr-es-sdk/compare/@alwatr/fetch@2.1.4...@alwatr/fetch@2.1.5) (2023-12-11)
7
21
 
8
22
  **Note:** Version bump only for package @alwatr/fetch
package/fetch.d.ts.map CHANGED
@@ -1 +1 @@
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;AAY/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"}
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"}
package/fetch.js CHANGED
@@ -1,9 +1,9 @@
1
- import { createLogger, definePackage, NODE_MODE } from '@alwatr/logger';
1
+ import { createLogger, definePackage, NODE_MODE, globalScope } from '@alwatr/logger';
2
2
  import { getClientId, delay } from '@alwatr/util';
3
3
  const logger = createLogger('alwatr/fetch');
4
4
  definePackage('fetch', '2.x');
5
5
  let alwatrCacheStorage;
6
- const cacheSupported = 'caches' in globalThis;
6
+ const cacheSupported = 'caches' in globalScope;
7
7
  const duplicateRequestStorage = {};
8
8
  /**
9
9
  * Fetch from alwatr services and return standard response.
@@ -246,7 +246,7 @@ async function _handleRetryPattern(options) {
246
246
  }
247
247
  catch (err) {
248
248
  logger.accident('fetch', 'fetch_failed_retry', err);
249
- if (globalThis.navigator?.onLine === false) {
249
+ if (globalScope.navigator?.onLine === false) {
250
250
  throw new Error('offline');
251
251
  }
252
252
  await delay(options.retryDelay);
@@ -259,29 +259,28 @@ async function _handleRetryPattern(options) {
259
259
  */
260
260
  function _handleTimeout(options) {
261
261
  if (options.timeout === 0) {
262
- return globalThis.fetch(options.url, options);
262
+ return globalScope.fetch(options.url, options);
263
263
  }
264
264
  // else
265
265
  logger.logMethod?.('_handleTimeout');
266
266
  return new Promise((resolved, reject) => {
267
- // TODO: AbortController polyfill
268
- const abortController = new AbortController();
267
+ const abortController = typeof globalScope.AbortController === 'function' ? new AbortController() : null;
269
268
  const externalAbortSignal = options.signal;
270
- options.signal = abortController.signal;
271
- const timeoutId = setTimeout(() => {
272
- reject(new Error('fetch_timeout'));
273
- abortController.abort('fetch_timeout');
274
- }, options.timeout);
275
- if (externalAbortSignal != null) {
269
+ options.signal = abortController?.signal;
270
+ if (abortController !== null && externalAbortSignal != null) {
276
271
  // Respect external abort signal
277
272
  externalAbortSignal.addEventListener('abort', () => abortController.abort(), { once: true });
278
273
  }
274
+ const timeoutId = setTimeout(() => {
275
+ reject(new Error('fetch_timeout'));
276
+ abortController?.abort('fetch_timeout');
277
+ }, options.timeout);
279
278
  // abortController.signal.addEventListener('abort', () => {
280
279
  // logger.incident('fetch', 'fetch_abort_signal', {
281
280
  // reason: abortController.signal.reason,
282
281
  // });
283
282
  // });
284
- globalThis
283
+ globalScope
285
284
  .fetch(options.url, options)
286
285
  .then((response) => resolved(response))
287
286
  .catch((reason) => reject(reason))
package/fetch.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"fetch.js","sourceRoot":"","sources":["src/fetch.ts"],"names":[],"mappings":"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","sourcesContent":["import {createLogger, definePackage, NODE_MODE} from '@alwatr/logger';\nimport {getClientId, delay} from '@alwatr/util';\n\nimport type {FetchOptions} from './type.js';\nimport type {AlwatrServiceResponse} from '@alwatr/type';\n\nexport type * from './type.js';\n\nconst logger = createLogger('alwatr/fetch');\n\ndefinePackage('fetch', '2.x');\n\n\nlet alwatrCacheStorage: Cache;\nconst cacheSupported = 'caches' in globalThis;\n\nconst duplicateRequestStorage: Record<string, Promise<Response>> = {};\n\n/**\n * Fetch from alwatr services and return standard response.\n */\nexport async function serviceRequest<T extends AlwatrServiceResponse = AlwatrServiceResponse>(\n options: FetchOptions,\n): Promise<T> {\n logger.logMethodArgs?.('serviceRequest', {url: options.url});\n\n if (!NODE_MODE) {\n options.headers ??= {};\n if (!options.headers['client-id']) {\n options.headers['client-id'] = getClientId();\n }\n }\n\n let response: Response;\n try {\n response = await fetch(options);\n }\n catch (err) {\n const errMessage = (err as Error).message;\n if (errMessage !== 'fetch_cache_not_found') {\n logger.error('serviceRequest', (err as Error).message || 'fetch_failed', err, options);\n }\n throw err;\n }\n\n let responseText: string;\n try {\n responseText = await response.text();\n }\n catch (err) {\n logger.error('serviceRequest', 'invalid_response', err, {\n response,\n });\n throw err;\n }\n\n let responseJson: T;\n try {\n responseJson = JSON.parse(responseText);\n }\n catch (err) {\n logger.error('serviceRequest', 'invalid_json', err, {responseText});\n throw err;\n }\n\n if (responseJson.ok !== true) {\n if (typeof responseJson.errorCode === 'string') {\n logger.accident('serviceRequest', responseJson.errorCode, {responseJson});\n throw new Error(responseJson.errorCode);\n }\n else {\n logger.error('serviceRequest', 'fetch_nok', {responseJson});\n throw new Error('fetch_nok');\n }\n }\n\n // TODO: generate fetch signals hook (for easier handle loading and show error toast)\n\n return responseJson;\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 * Example:\n *\n * ```ts\n * const response = await fetch({\n * url: '/api/products',\n * queryParameters: {limit: 10},\n * timeout: 10_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\n/**\n * Process fetch options and set defaults, etc.\n */\nfunction _processOptions(options: FetchOptions): Required<FetchOptions> {\n options.method ??= 'GET';\n options.window ??= null;\n\n options.timeout ??= 10_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 != null) {\n options.body = JSON.stringify(options.bodyJson);\n options.headers['Content-Type'] = 'application/json';\n }\n\n if (options.token != null) {\n options.headers.Authorization = `Bearer ${options.token}`;\n }\n\n if (options.userAuth != null) {\n options.headers.Authorization = `Bearer ${options.userAuth.id}/${options.userAuth.token}`;\n }\n\n return options as Required<FetchOptions>;\n}\n\n/**\n * Handle Cache Strategy over `_handleRemoveDuplicate`.\n */\nasync 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 (alwatrCacheStorage == null && options.cacheStorageName == null) {\n alwatrCacheStorage = await caches.open('alwatr_fetch_cache');\n }\n\n const cacheStorage =\n options.cacheStorageName != null ? await caches.open(options.cacheStorageName) : alwatrCacheStorage;\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(\n '_handleCacheStrategy',\n 'fetch_cache_not_found',\n {url: request.url},\n );\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 */\nasync 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 */\nasync 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 (globalThis.navigator?.onLine === false) {\n throw new Error('offline');\n }\n\n await delay(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 */\nfunction _handleTimeout(options: FetchOptions): Promise<Response> {\n if (options.timeout === 0) {\n return globalThis.fetch(options.url, options);\n }\n // else\n logger.logMethod?.('_handleTimeout');\n return new Promise((resolved, reject) => {\n // TODO: AbortController polyfill\n const abortController = new AbortController();\n const externalAbortSignal = options.signal;\n options.signal = abortController.signal;\n\n const timeoutId = setTimeout(() => {\n reject(new Error('fetch_timeout'));\n abortController.abort('fetch_timeout');\n }, options.timeout);\n\n if (externalAbortSignal != null) {\n // Respect external abort signal\n externalAbortSignal.addEventListener('abort', () => abortController.abort(), {once: true});\n }\n\n // abortController.signal.addEventListener('abort', () => {\n // logger.incident('fetch', 'fetch_abort_signal', {\n // reason: abortController.signal.reason,\n // });\n // });\n\n globalThis\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"]}
1
+ {"version":3,"file":"fetch.js","sourceRoot":"","sources":["src/fetch.ts"],"names":[],"mappings":"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","sourcesContent":["import {createLogger, definePackage, NODE_MODE, globalScope} from '@alwatr/logger';\nimport {getClientId, delay} from '@alwatr/util';\n\nimport type {FetchOptions} from './type.js';\nimport type {AlwatrServiceResponse} from '@alwatr/type';\n\nexport type * from './type.js';\n\nconst logger = createLogger('alwatr/fetch');\n\ndefinePackage('fetch', '2.x');\n\nlet alwatrCacheStorage: Cache;\nconst cacheSupported = 'caches' in globalScope;\n\nconst duplicateRequestStorage: Record<string, Promise<Response>> = {};\n\n/**\n * Fetch from alwatr services and return standard response.\n */\nexport async function serviceRequest<T extends AlwatrServiceResponse = AlwatrServiceResponse>(\n options: FetchOptions,\n): Promise<T> {\n logger.logMethodArgs?.('serviceRequest', {url: options.url});\n\n if (!NODE_MODE) {\n options.headers ??= {};\n if (!options.headers['client-id']) {\n options.headers['client-id'] = getClientId();\n }\n }\n\n let response: Response;\n try {\n response = await fetch(options);\n }\n catch (err) {\n const errMessage = (err as Error).message;\n if (errMessage !== 'fetch_cache_not_found') {\n logger.error('serviceRequest', (err as Error).message || 'fetch_failed', err, options);\n }\n throw err;\n }\n\n let responseText: string;\n try {\n responseText = await response.text();\n }\n catch (err) {\n logger.error('serviceRequest', 'invalid_response', err, {\n response,\n });\n throw err;\n }\n\n let responseJson: T;\n try {\n responseJson = JSON.parse(responseText);\n }\n catch (err) {\n logger.error('serviceRequest', 'invalid_json', err, {responseText});\n throw err;\n }\n\n if (responseJson.ok !== true) {\n if (typeof responseJson.errorCode === 'string') {\n logger.accident('serviceRequest', responseJson.errorCode, {responseJson});\n throw new Error(responseJson.errorCode);\n }\n else {\n logger.error('serviceRequest', 'fetch_nok', {responseJson});\n throw new Error('fetch_nok');\n }\n }\n\n // TODO: generate fetch signals hook (for easier handle loading and show error toast)\n\n return responseJson;\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 * Example:\n *\n * ```ts\n * const response = await fetch({\n * url: '/api/products',\n * queryParameters: {limit: 10},\n * timeout: 10_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\n/**\n * Process fetch options and set defaults, etc.\n */\nfunction _processOptions(options: FetchOptions): Required<FetchOptions> {\n options.method ??= 'GET';\n options.window ??= null;\n\n options.timeout ??= 10_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 != null) {\n options.body = JSON.stringify(options.bodyJson);\n options.headers['Content-Type'] = 'application/json';\n }\n\n if (options.token != null) {\n options.headers.Authorization = `Bearer ${options.token}`;\n }\n\n if (options.userAuth != null) {\n options.headers.Authorization = `Bearer ${options.userAuth.id}/${options.userAuth.token}`;\n }\n\n return options as Required<FetchOptions>;\n}\n\n/**\n * Handle Cache Strategy over `_handleRemoveDuplicate`.\n */\nasync 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 (alwatrCacheStorage == null && options.cacheStorageName == null) {\n alwatrCacheStorage = await caches.open('alwatr_fetch_cache');\n }\n\n const cacheStorage =\n options.cacheStorageName != null ? await caches.open(options.cacheStorageName) : alwatrCacheStorage;\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 */\nasync 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 */\nasync 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 throw new Error('offline');\n }\n\n await delay(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 */\nfunction _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 globalScope.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"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alwatr/fetch",
3
- "version": "2.1.5",
3
+ "version": "2.2.1",
4
4
  "description": "Enhanced fetch API with cache strategy, retry pattern, timeout, helper methods and enhanced types written in tiny TypeScript, ES module.",
5
5
  "keywords": [
6
6
  "fetch",
@@ -34,12 +34,12 @@
34
34
  "url": "https://github.com/Alwatr/alwatr-es-sdk/issues"
35
35
  },
36
36
  "dependencies": {
37
- "@alwatr/logger": "^2.3.3",
38
- "@alwatr/util": "^1.3.5"
37
+ "@alwatr/logger": "^2.4.1",
38
+ "@alwatr/util": "^1.4.1"
39
39
  },
40
40
  "devDependencies": {
41
- "@alwatr/type": "^1.2.3",
42
- "@types/node": "^20.10.4"
41
+ "@alwatr/type": "^1.2.4",
42
+ "@types/node": "^20.10.5"
43
43
  },
44
- "gitHead": "7f4b8af06224bea811c74ddb3bac1480ed8a9fed"
44
+ "gitHead": "8df92c67b69527b5474e8741a8633e0e67b5d09a"
45
45
  }