@alwatr/fetch 5.0.0 → 5.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,18 @@
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
+ ## [5.2.1](https://github.com/Alwatr/nanolib/compare/v5.2.0...v5.2.1) (2024-11-07)
7
+
8
+ ### Bug Fixes
9
+
10
+ * **fetch:** refine error handling in fetchJson to improve response error structure ([2942563](https://github.com/Alwatr/nanolib/commit/29425639c268f091711ab195a4285e49b762e497)) by @
11
+
12
+ ## [5.2.0](https://github.com/Alwatr/nanolib/compare/v5.1.0...v5.2.0) (2024-11-06)
13
+
14
+ ### Features
15
+
16
+ * **fetch:** improve error handling for fetch responses and JSON parsing ([8692bb1](https://github.com/Alwatr/nanolib/commit/8692bb1123e8b3a6d6f8aea20464c55b344da9d2)) by @AliMD
17
+
6
18
  ## 5.0.0 (2024-11-02)
7
19
 
8
20
  ### ⚠ BREAKING CHANGES
package/dist/main.cjs CHANGED
@@ -1,4 +1,4 @@
1
- /* @alwatr/fetch v5.0.0 */
1
+ /* @alwatr/fetch v5.2.1 */
2
2
  "use strict";
3
3
  var __defProp = Object.defineProperty;
4
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -35,7 +35,7 @@ var import_http_primer = require("@alwatr/http-primer");
35
35
  var import_logger = require("@alwatr/logger");
36
36
  var import_package_tracer = require("@alwatr/package-tracer");
37
37
  var import_parse_duration = require("@alwatr/parse-duration");
38
- __dev_mode__: import_package_tracer.packageTracer.add("@alwatr/fetch", "5.0.0");
38
+ __dev_mode__: import_package_tracer.packageTracer.add("@alwatr/fetch", "5.2.1");
39
39
  var logger_ = /* @__PURE__ */ (0, import_logger.createLogger)("@alwatr/fetch");
40
40
  var globalThis_ = /* @__PURE__ */ (0, import_global_this.getGlobalThis)();
41
41
  var cacheStorage_;
@@ -219,17 +219,18 @@ async function fetchJson(options) {
219
219
  response = await fetch(options);
220
220
  responseText = await response.text();
221
221
  responseJson = JSON.parse(responseText);
222
- responseJson.ok = true;
223
- responseJson.statusCode = response.status;
222
+ if (responseJson.ok === false) {
223
+ throw new Error(`fetch_response_nok`);
224
+ }
224
225
  return responseJson;
225
226
  } catch (error) {
226
227
  const responseError = {
228
+ ...responseJson,
227
229
  ok: false,
228
230
  statusCode: response?.status ?? import_http_primer2.HttpStatusCodes.Error_Server_500_Internal_Server_Error,
229
231
  errorCode: responseJson?.errorCode ?? error.message,
230
- errorMessage: responseJson?.errorMessage ?? error.message,
231
- responseText,
232
- meta: responseJson?.meta
232
+ errorMessage: responseJson?.errorMessage ?? error.message
233
+ // responseText,
233
234
  };
234
235
  logger_.accident("fetchJson", "fetch_json_failed", { responseError, error });
235
236
  return responseError;
package/dist/main.cjs.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/main.ts", "../src/core.ts"],
4
- "sourcesContent": ["import {HttpStatusCodes, type HttpStatusCode} from '@alwatr/http-primer';\n\nimport {handleCacheStrategy_, logger_, processOptions_, cacheSupported} from './core.js';\n\nimport type {FetchOptions, ResponseError, ResponseSuccess} from './type.js';\n\nexport {cacheSupported};\nexport type * from './type.js';\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\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 as HttpStatusCode;\n return responseJson;\n }\n catch (error) {\n const responseError: ResponseError = {\n ok: false,\n statusCode: (response?.status as HttpStatusCode) ?? HttpStatusCodes.Error_Server_500_Internal_Server_Error,\n errorCode: (responseJson?.errorCode as string) ?? (error as Error).message,\n errorMessage: (responseJson?.errorMessage as string) ?? (error as Error).message,\n responseText,\n meta: responseJson?.meta as JsonObject,\n };\n\n logger_.accident('fetchJson', 'fetch_json_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", "import {delay} from '@alwatr/delay';\nimport {getGlobalThis} from '@alwatr/global-this';\nimport {HttpStatusCodes, MimeTypes} from '@alwatr/http-primer';\nimport {createLogger} from '@alwatr/logger';\nimport {packageTracer} from '@alwatr/package-tracer';\nimport {parseDuration} from '@alwatr/parse-duration';\n\nimport type {FetchOptions} from './type.js';\n\n__dev_mode__: packageTracer.add(__package_name__, __package_version__);\n\nexport const logger_ = /* #__PURE__ */ createLogger('@alwatr/fetch');\n\nconst globalThis_ = /* #__PURE__ */ getGlobalThis();\n\nlet cacheStorage_: Cache;\nexport const cacheSupported = /* #__PURE__ */ Object.hasOwn(globalThis_, '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.queryParams != null) {\n const queryParams = options.queryParams;\n // prettier-ignore\n const queryArray = Object\n .keys(queryParams)\n .map((key) => `${key}=${String(queryParams[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'] = MimeTypes.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 < HttpStatusCodes.Error_Server_500_Internal_Server_Error) {\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 logger_.accident('handleRetryPattern_', 'offline', 'Skip retry because offline');\n throw err;\n }\n\n await delay.by(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 globalThis_.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 }, parseDuration(options.timeout!));\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"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import {HttpStatusCodes, type HttpStatusCode} from '@alwatr/http-primer';\n\nimport {handleCacheStrategy_, logger_, processOptions_, cacheSupported} from './core.js';\n\nimport type {FetchOptions, ResponseError, ResponseSuccess} from './type.js';\n\nexport {cacheSupported};\nexport type * from './type.js';\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\n try {\n response = await fetch(options);\n responseText = await response.text();\n responseJson = JSON.parse(responseText) as (ResponseError | ResponseSuccess<T>);\n if (responseJson.ok === false) {\n throw new Error(`fetch_response_nok`);\n }\n // responseJson.statusCode ??= response.status as HttpStatusCode;\n return responseJson;\n }\n catch (error) {\n const responseError: ResponseError = {\n ...responseJson,\n ok: false,\n statusCode: (response?.status as HttpStatusCode) ?? HttpStatusCodes.Error_Server_500_Internal_Server_Error,\n errorCode: (responseJson?.errorCode as string) ?? (error as Error).message,\n errorMessage: (responseJson?.errorMessage as string) ?? (error as Error).message,\n // responseText,\n };\n\n logger_.accident('fetchJson', 'fetch_json_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", "import {delay} from '@alwatr/delay';\nimport {getGlobalThis} from '@alwatr/global-this';\nimport {HttpStatusCodes, MimeTypes} from '@alwatr/http-primer';\nimport {createLogger} from '@alwatr/logger';\nimport {packageTracer} from '@alwatr/package-tracer';\nimport {parseDuration} from '@alwatr/parse-duration';\n\nimport type {FetchOptions} from './type.js';\n\n__dev_mode__: packageTracer.add(__package_name__, __package_version__);\n\nexport const logger_ = /* #__PURE__ */ createLogger('@alwatr/fetch');\n\nconst globalThis_ = /* #__PURE__ */ getGlobalThis();\n\nlet cacheStorage_: Cache;\nexport const cacheSupported = /* #__PURE__ */ Object.hasOwn(globalThis_, '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.queryParams != null) {\n const queryParams = options.queryParams;\n // prettier-ignore\n const queryArray = Object\n .keys(queryParams)\n .map((key) => `${key}=${String(queryParams[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'] = MimeTypes.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 < HttpStatusCodes.Error_Server_500_Internal_Server_Error) {\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 logger_.accident('handleRetryPattern_', 'offline', 'Skip retry because offline');\n throw err;\n }\n\n await delay.by(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 globalThis_.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 }, parseDuration(options.timeout!));\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"],
5
+ "mappings": "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",
6
6
  "names": ["import_http_primer"]
7
7
  }
@@ -1 +1 @@
1
- {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AAEA,OAAO,EAAiD,cAAc,EAAC,MAAM,WAAW,CAAC;AAEzF,OAAO,KAAK,EAAC,YAAY,EAAE,aAAa,EAAE,eAAe,EAAC,MAAM,WAAW,CAAC;AAE5E,OAAO,EAAC,cAAc,EAAC,CAAC;AACxB,mBAAmB,WAAW,CAAC;AAE/B;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAsB,SAAS,CAAC,CAAC,SAAS,UAAU,EAAE,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,GAAG,aAAa,CAAC,CA0BxH;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,QAAQ,CAAC,CAI9D"}
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AAEA,OAAO,EAAiD,cAAc,EAAC,MAAM,WAAW,CAAC;AAEzF,OAAO,KAAK,EAAC,YAAY,EAAE,aAAa,EAAE,eAAe,EAAC,MAAM,WAAW,CAAC;AAE5E,OAAO,EAAC,cAAc,EAAC,CAAC;AACxB,mBAAmB,WAAW,CAAC;AAE/B;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAsB,SAAS,CAAC,CAAC,SAAS,UAAU,EAAE,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,GAAG,aAAa,CAAC,CA4BxH;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,QAAQ,CAAC,CAI9D"}
package/dist/main.mjs CHANGED
@@ -1,4 +1,4 @@
1
- /* @alwatr/fetch v5.0.0 */
1
+ /* @alwatr/fetch v5.2.1 */
2
2
 
3
3
  // src/main.ts
4
4
  import { HttpStatusCodes as HttpStatusCodes2 } from "@alwatr/http-primer";
@@ -10,7 +10,7 @@ import { HttpStatusCodes, MimeTypes } from "@alwatr/http-primer";
10
10
  import { createLogger } from "@alwatr/logger";
11
11
  import { packageTracer } from "@alwatr/package-tracer";
12
12
  import { parseDuration } from "@alwatr/parse-duration";
13
- __dev_mode__: packageTracer.add("@alwatr/fetch", "5.0.0");
13
+ __dev_mode__: packageTracer.add("@alwatr/fetch", "5.2.1");
14
14
  var logger_ = /* @__PURE__ */ createLogger("@alwatr/fetch");
15
15
  var globalThis_ = /* @__PURE__ */ getGlobalThis();
16
16
  var cacheStorage_;
@@ -194,17 +194,18 @@ async function fetchJson(options) {
194
194
  response = await fetch(options);
195
195
  responseText = await response.text();
196
196
  responseJson = JSON.parse(responseText);
197
- responseJson.ok = true;
198
- responseJson.statusCode = response.status;
197
+ if (responseJson.ok === false) {
198
+ throw new Error(`fetch_response_nok`);
199
+ }
199
200
  return responseJson;
200
201
  } catch (error) {
201
202
  const responseError = {
203
+ ...responseJson,
202
204
  ok: false,
203
205
  statusCode: response?.status ?? HttpStatusCodes2.Error_Server_500_Internal_Server_Error,
204
206
  errorCode: responseJson?.errorCode ?? error.message,
205
- errorMessage: responseJson?.errorMessage ?? error.message,
206
- responseText,
207
- meta: responseJson?.meta
207
+ errorMessage: responseJson?.errorMessage ?? error.message
208
+ // responseText,
208
209
  };
209
210
  logger_.accident("fetchJson", "fetch_json_failed", { responseError, error });
210
211
  return responseError;
package/dist/main.mjs.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/main.ts", "../src/core.ts"],
4
- "sourcesContent": ["import {HttpStatusCodes, type HttpStatusCode} from '@alwatr/http-primer';\n\nimport {handleCacheStrategy_, logger_, processOptions_, cacheSupported} from './core.js';\n\nimport type {FetchOptions, ResponseError, ResponseSuccess} from './type.js';\n\nexport {cacheSupported};\nexport type * from './type.js';\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\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 as HttpStatusCode;\n return responseJson;\n }\n catch (error) {\n const responseError: ResponseError = {\n ok: false,\n statusCode: (response?.status as HttpStatusCode) ?? HttpStatusCodes.Error_Server_500_Internal_Server_Error,\n errorCode: (responseJson?.errorCode as string) ?? (error as Error).message,\n errorMessage: (responseJson?.errorMessage as string) ?? (error as Error).message,\n responseText,\n meta: responseJson?.meta as JsonObject,\n };\n\n logger_.accident('fetchJson', 'fetch_json_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", "import {delay} from '@alwatr/delay';\nimport {getGlobalThis} from '@alwatr/global-this';\nimport {HttpStatusCodes, MimeTypes} from '@alwatr/http-primer';\nimport {createLogger} from '@alwatr/logger';\nimport {packageTracer} from '@alwatr/package-tracer';\nimport {parseDuration} from '@alwatr/parse-duration';\n\nimport type {FetchOptions} from './type.js';\n\n__dev_mode__: packageTracer.add(__package_name__, __package_version__);\n\nexport const logger_ = /* #__PURE__ */ createLogger('@alwatr/fetch');\n\nconst globalThis_ = /* #__PURE__ */ getGlobalThis();\n\nlet cacheStorage_: Cache;\nexport const cacheSupported = /* #__PURE__ */ Object.hasOwn(globalThis_, '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.queryParams != null) {\n const queryParams = options.queryParams;\n // prettier-ignore\n const queryArray = Object\n .keys(queryParams)\n .map((key) => `${key}=${String(queryParams[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'] = MimeTypes.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 < HttpStatusCodes.Error_Server_500_Internal_Server_Error) {\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 logger_.accident('handleRetryPattern_', 'offline', 'Skip retry because offline');\n throw err;\n }\n\n await delay.by(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 globalThis_.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 }, parseDuration(options.timeout!));\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"],
5
- "mappings": ";;;AAAA,SAAQ,mBAAAA,wBAA2C;;;ACAnD,SAAQ,aAAY;AACpB,SAAQ,qBAAoB;AAC5B,SAAQ,iBAAiB,iBAAgB;AACzC,SAAQ,oBAAmB;AAC3B,SAAQ,qBAAoB;AAC5B,SAAQ,qBAAoB;AAI5B,aAAc,eAAc,IAAI,iBAAkB,OAAmB;AAE9D,IAAM,UAA0B,6BAAa,eAAe;AAEnE,IAAM,cAA8B,8BAAc;AAElD,IAAI;AACG,IAAM,iBAAiC,uBAAO,OAAO,aAAa,QAAQ;AAEjF,IAAM,2BAA8D,CAAC;AAS9D,SAAS,gBAAgB,SAA+C;AAC7E,UAAQ,WAAR,QAAQ,SAAW;AACnB,UAAQ,WAAR,QAAQ,SAAW;AAEnB,UAAQ,YAAR,QAAQ,UAAY;AACpB,UAAQ,UAAR,QAAQ,QAAU;AAClB,UAAQ,eAAR,QAAQ,aAAe;AACvB,UAAQ,kBAAR,QAAQ,gBAAkB;AAC1B,UAAQ,oBAAR,QAAQ,kBAAoB;AAC5B,UAAQ,YAAR,QAAQ,UAAY,CAAC;AAErB,MAAI,QAAQ,kBAAkB,kBAAkB,mBAAmB,MAAM;AACvE,YAAQ,WAAW,SAAS,oCAAoC;AAAA,MAC9D;AAAA,IACF,CAAC;AACD,YAAQ,gBAAgB;AAAA,EAC1B;AAEA,MAAI,QAAQ,oBAAoB,QAAQ;AACtC,YAAQ,kBAAkB,iBAAiB,eAAe;AAAA,EAC5D;AAEA,MAAI,QAAQ,IAAI,YAAY,GAAG,MAAM,MAAM,QAAQ,eAAe,MAAM;AACtE,UAAM,cAAc,QAAQ;AAE5B,UAAM,aAAa,OAChB,KAAK,WAAW,EAChB,IAAI,CAAC,QAAQ,GAAG,GAAG,IAAI,OAAO,YAAY,GAAG,CAAC,CAAC,EAAE;AAEpD,QAAI,WAAW,SAAS,GAAG;AACzB,cAAQ,OAAO,MAAM,WAAW,KAAK,GAAG;AAAA,IAC1C;AAAA,EACF;AAEA,MAAI,QAAQ,aAAa,QAAW;AAClC,YAAQ,OAAO,KAAK,UAAU,QAAQ,QAAQ;AAC9C,YAAQ,QAAQ,cAAc,IAAI,UAAU;AAAA,EAC9C;AAEA,MAAI,QAAQ,gBAAgB,QAAW;AACrC,YAAQ,QAAQ,gBAAgB,UAAU,QAAQ,WAAW;AAAA,EAC/D,WACS,QAAQ,eAAe,QAAW;AACzC,YAAQ,QAAQ,gBAAgB,UAAU,QAAQ,WAAW,MAAM,IAAI,QAAQ,WAAW,SAAS;AAAA,EACrG;AAEA,SAAO;AACT;AAKA,eAAsB,qBAAqB,SAAoD;AAC7F,MAAI,QAAQ,kBAAkB,gBAAgB;AAC5C,WAAO,uBAAuB,OAAO;AAAA,EACvC;AAEA,UAAQ,YAAY,sBAAsB;AAE1C,MAAI,iBAAiB,QAAQ,QAAQ,oBAAoB,MAAM;AAC7D,oBAAgB,MAAM,OAAO,KAAK,aAAa;AAAA,EACjD;AAEA,QAAM,eAAe,QAAQ,oBAAoB,OAAO,MAAM,OAAO,KAAK,QAAQ,gBAAgB,IAAI;AAEtG,QAAM,UAAU,IAAI,QAAQ,QAAQ,KAAK,OAAO;AAEhD,UAAQ,QAAQ,eAAe;AAAA,IAC7B,KAAK,eAAe;AAClB,YAAM,iBAAiB,MAAM,aAAa,MAAM,OAAO;AACvD,UAAI,kBAAkB,MAAM;AAC1B,eAAO;AAAA,MACT;AAEA,YAAM,WAAW,MAAM,uBAAuB,OAAO;AACrD,UAAI,SAAS,IAAI;AACf,qBAAa,IAAI,SAAS,SAAS,MAAM,CAAC;AAAA,MAC5C;AACA,aAAO;AAAA,IACT;AAAA,IAEA,KAAK,cAAc;AACjB,YAAM,iBAAiB,MAAM,aAAa,MAAM,OAAO;AACvD,UAAI,kBAAkB,MAAM;AAC1B,gBAAQ,SAAS,wBAAwB,yBAAyB,EAAC,KAAK,QAAQ,IAAG,CAAC;AACpF,cAAM,IAAI,MAAM,uBAAuB;AAAA,MACzC;AAEA,aAAO;AAAA,IACT;AAAA,IAEA,KAAK,iBAAiB;AACpB,UAAI;AACF,cAAM,kBAAkB,MAAM,uBAAuB,OAAO;AAC5D,YAAI,gBAAgB,IAAI;AACtB,uBAAa,IAAI,SAAS,gBAAgB,MAAM,CAAC;AAAA,QACnD;AACA,eAAO;AAAA,MACT,SACO,KAAK;AACV,cAAM,iBAAiB,MAAM,aAAa,MAAM,OAAO;AACvD,YAAI,kBAAkB,MAAM;AAC1B,iBAAO;AAAA,QACT;AAEA,cAAM;AAAA,MACR;AAAA,IACF;AAAA,IAEA,KAAK,gBAAgB;AACnB,YAAM,kBAAkB,MAAM,uBAAuB,OAAO;AAC5D,UAAI,gBAAgB,IAAI;AACtB,qBAAa,IAAI,SAAS,gBAAgB,MAAM,CAAC;AAAA,MACnD;AACA,aAAO;AAAA,IACT;AAAA,IAEA,KAAK,0BAA0B;AAC7B,YAAM,iBAAiB,MAAM,aAAa,MAAM,OAAO;AACvD,YAAM,yBAAyB,uBAAuB,OAAO,EAAE,KAAK,CAAC,oBAAoB;AACvF,YAAI,gBAAgB,IAAI;AACtB,uBAAa,IAAI,SAAS,gBAAgB,MAAM,CAAC;AACjD,cAAI,OAAO,QAAQ,uBAAuB,YAAY;AACpD,uBAAW,QAAQ,oBAAoB,GAAG,gBAAgB,MAAM,CAAC;AAAA,UACnE;AAAA,QACF;AACA,eAAO;AAAA,MACT,CAAC;AAED,aAAO,kBAAkB;AAAA,IAC3B;AAAA,IAEA,SAAS;AACP,aAAO,uBAAuB,OAAO;AAAA,IACvC;AAAA,EACF;AACF;AAKA,eAAsB,uBAAuB,SAAoD;AAC/F,MAAI,QAAQ,oBAAoB,QAAS,QAAO,oBAAoB,OAAO;AAE3E,UAAQ,YAAY,wBAAwB;AAE5C,QAAM,WAAW,QAAQ,SAAS,MAAM,QAAQ;AAGhD,8EAAuC,oBAAoB,OAAO;AAElE,MAAI;AAEF,UAAM,WAAW,MAAM,yBAAyB,QAAQ;AAExD,QAAI,yBAAyB,QAAQ,KAAK,MAAM;AAC9C,UAAI,SAAS,OAAO,QAAQ,QAAQ,oBAAoB,cAAc;AACpE,eAAO,yBAAyB,QAAQ;AAAA,MAC1C;AAAA,IACF;AAEA,WAAO,SAAS,MAAM;AAAA,EACxB,SACO,KAAK;AAEV,WAAO,yBAAyB,QAAQ;AACxC,UAAM;AAAA,EACR;AACF;AAKA,eAAsB,oBAAoB,SAAoD;AAC5F,MAAI,EAAE,QAAQ,QAAQ,GAAI,QAAO,eAAe,OAAO;AAEvD,UAAQ,YAAY,qBAAqB;AACzC,UAAQ;AAER,QAAM,sBAAsB,QAAQ;AAEpC,MAAI;AACF,UAAM,WAAW,MAAM,eAAe,OAAO;AAE7C,QAAI,SAAS,SAAS,gBAAgB,wCAAwC;AAC5E,aAAO;AAAA,IACT;AAEA,UAAM,IAAI,MAAM,oBAAoB;AAAA,EACtC,SACO,KAAK;AACV,YAAQ,SAAS,SAAS,sBAAsB,GAAG;AAEnD,QAAI,YAAY,WAAW,WAAW,OAAO;AAC3C,cAAQ,SAAS,uBAAuB,WAAW,4BAA4B;AAC/E,YAAM;AAAA,IACR;AAEA,UAAM,MAAM,GAAG,QAAQ,UAAU;AAEjC,YAAQ,SAAS;AACjB,WAAO,oBAAoB,OAAO;AAAA,EACpC;AACF;AAKO,SAAS,eAAe,SAA0C;AACvE,MAAI,QAAQ,YAAY,GAAG;AACzB,WAAO,YAAY,MAAM,QAAQ,KAAK,OAAO;AAAA,EAC/C;AAEA,UAAQ,YAAY,gBAAgB;AACpC,SAAO,IAAI,QAAQ,CAAC,UAAU,WAAW;AACvC,UAAM,kBAAkB,OAAO,oBAAoB,aAAa,IAAI,gBAAgB,IAAI;AACxF,UAAM,sBAAsB,QAAQ;AACpC,YAAQ,SAAS,iBAAiB;AAElC,QAAI,oBAAoB,QAAQ,uBAAuB,MAAM;AAE3D,0BAAoB,iBAAiB,SAAS,MAAM,gBAAgB,MAAM,GAAG,EAAC,MAAM,KAAI,CAAC;AAAA,IAC3F;AAEA,UAAM,YAAY,WAAW,MAAM;AACjC,aAAO,IAAI,MAAM,eAAe,CAAC;AACjC,uBAAiB,MAAM,eAAe;AAAA,IACxC,GAAG,cAAc,QAAQ,OAAQ,CAAC;AAQlC,gBACG,MAAM,QAAQ,KAAK,OAAO,EAC1B,KAAK,CAAC,aAAa,SAAS,QAAQ,CAAC,EACrC,MAAM,CAAC,WAAW,OAAO,MAAM,CAAC,EAChC,QAAQ,MAAM;AACb,aAAO,QAAQ;AACf,mBAAa,SAAS;AAAA,IACxB,CAAC;AAAA,EACL,CAAC;AACH;;;AD9OA,eAAsB,UAAgC,SAAoE;AACxH,MAAI;AACJ,MAAI;AACJ,MAAI;AAEJ,MAAI;AACF,eAAW,MAAM,MAAM,OAAO;AAC9B,mBAAe,MAAM,SAAS,KAAK;AACnC,mBAAe,KAAK,MAAM,YAAY;AACtC,iBAAa,KAAK;AAClB,iBAAa,aAAa,SAAS;AACnC,WAAO;AAAA,EACT,SACO,OAAO;AACZ,UAAM,gBAA+B;AAAA,MACnC,IAAI;AAAA,MACJ,YAAa,UAAU,UAA6BC,iBAAgB;AAAA,MACpE,WAAY,cAAc,aAAyB,MAAgB;AAAA,MACnE,cAAe,cAAc,gBAA4B,MAAgB;AAAA,MACzE;AAAA,MACA,MAAM,cAAc;AAAA,IACtB;AAEA,YAAQ,SAAS,aAAa,qBAAqB,EAAC,eAAe,MAAK,CAAC;AACzE,WAAO;AAAA,EACT;AACF;AAwBO,SAAS,MAAM,SAA0C;AAC9D,YAAU,gBAAgB,OAAO;AACjC,UAAQ,gBAAgB,SAAS,EAAC,QAAO,CAAC;AAC1C,SAAO,qBAAqB,OAAiC;AAC/D;",
4
+ "sourcesContent": ["import {HttpStatusCodes, type HttpStatusCode} from '@alwatr/http-primer';\n\nimport {handleCacheStrategy_, logger_, processOptions_, cacheSupported} from './core.js';\n\nimport type {FetchOptions, ResponseError, ResponseSuccess} from './type.js';\n\nexport {cacheSupported};\nexport type * from './type.js';\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\n try {\n response = await fetch(options);\n responseText = await response.text();\n responseJson = JSON.parse(responseText) as (ResponseError | ResponseSuccess<T>);\n if (responseJson.ok === false) {\n throw new Error(`fetch_response_nok`);\n }\n // responseJson.statusCode ??= response.status as HttpStatusCode;\n return responseJson;\n }\n catch (error) {\n const responseError: ResponseError = {\n ...responseJson,\n ok: false,\n statusCode: (response?.status as HttpStatusCode) ?? HttpStatusCodes.Error_Server_500_Internal_Server_Error,\n errorCode: (responseJson?.errorCode as string) ?? (error as Error).message,\n errorMessage: (responseJson?.errorMessage as string) ?? (error as Error).message,\n // responseText,\n };\n\n logger_.accident('fetchJson', 'fetch_json_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", "import {delay} from '@alwatr/delay';\nimport {getGlobalThis} from '@alwatr/global-this';\nimport {HttpStatusCodes, MimeTypes} from '@alwatr/http-primer';\nimport {createLogger} from '@alwatr/logger';\nimport {packageTracer} from '@alwatr/package-tracer';\nimport {parseDuration} from '@alwatr/parse-duration';\n\nimport type {FetchOptions} from './type.js';\n\n__dev_mode__: packageTracer.add(__package_name__, __package_version__);\n\nexport const logger_ = /* #__PURE__ */ createLogger('@alwatr/fetch');\n\nconst globalThis_ = /* #__PURE__ */ getGlobalThis();\n\nlet cacheStorage_: Cache;\nexport const cacheSupported = /* #__PURE__ */ Object.hasOwn(globalThis_, '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.queryParams != null) {\n const queryParams = options.queryParams;\n // prettier-ignore\n const queryArray = Object\n .keys(queryParams)\n .map((key) => `${key}=${String(queryParams[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'] = MimeTypes.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 < HttpStatusCodes.Error_Server_500_Internal_Server_Error) {\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 logger_.accident('handleRetryPattern_', 'offline', 'Skip retry because offline');\n throw err;\n }\n\n await delay.by(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 globalThis_.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 }, parseDuration(options.timeout!));\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"],
5
+ "mappings": "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",
6
6
  "names": ["HttpStatusCodes", "HttpStatusCodes"]
7
7
  }
package/dist/type.d.ts CHANGED
@@ -124,7 +124,6 @@ export type ResponseError = {
124
124
  statusCode: HttpStatusCode;
125
125
  errorCode: string;
126
126
  errorMessage: string;
127
- responseText?: string;
128
127
  meta?: Json;
129
128
  };
130
129
  //# sourceMappingURL=type.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"type.d.ts","sourceRoot":"","sources":["../src/type.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,UAAU,EAAE,kBAAkB,EAAE,cAAc,EAAC,MAAM,qBAAqB,CAAC;AACxF,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,wBAAwB,CAAC;AAErD;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG,aAAa,CAAC,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;AAEnE;;;;;;;;;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,UAAU,CAAC;IAEpB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,kBAAkB,CAAC;IAEtD;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,QAAQ,CAAC;IAEnB;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;;;OAIG;IACH,UAAU,CAAC,EAAE,QAAQ,CAAC;IAEtB;;;;;;;;;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,WAAW,CAAC,EAAE,WAAW,CAAC;IAE1B;;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,cAAc,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,EAAE,EAAE,KAAK,CAAC;IACV,UAAU,EAAE,cAAc,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,IAAI,CAAC;CACb,CAAC"}
1
+ {"version":3,"file":"type.d.ts","sourceRoot":"","sources":["../src/type.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,UAAU,EAAE,kBAAkB,EAAE,cAAc,EAAC,MAAM,qBAAqB,CAAC;AACxF,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,wBAAwB,CAAC;AAErD;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG,aAAa,CAAC,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;AAEnE;;;;;;;;;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,UAAU,CAAC;IAEpB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,kBAAkB,CAAC;IAEtD;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,QAAQ,CAAC;IAEnB;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;;;OAIG;IACH,UAAU,CAAC,EAAE,QAAQ,CAAC;IAEtB;;;;;;;;;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,WAAW,CAAC,EAAE,WAAW,CAAC;IAE1B;;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,cAAc,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,EAAE,EAAE,KAAK,CAAC;IACV,UAAU,EAAE,cAAc,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IAErB,IAAI,CAAC,EAAE,IAAI,CAAC;CACb,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alwatr/fetch",
3
- "version": "5.0.0",
3
+ "version": "5.2.1",
4
4
  "description": "Enhanced fetch API with cache strategy, retry pattern, timeout, helper methods and enhanced types.",
5
5
  "author": "S. Ali Mihandoost <ali.mihandoost@gmail.com>",
6
6
  "keywords": [
@@ -87,5 +87,5 @@
87
87
  "jest": "^29.7.0",
88
88
  "typescript": "^5.6.3"
89
89
  },
90
- "gitHead": "7d12943fafa8ef50636346e66ff56c50e2fd0c72"
90
+ "gitHead": "d0473e4010c39cb805f5a96a2c496d9d7d59852b"
91
91
  }