{
  "version": 3,
  "sources": ["../src/main.ts", "../src/error.ts"],
  "sourcesContent": ["/**\n * @module @alwatr/fetch\n *\n * An enhanced, lightweight, and dependency-free wrapper for the native `fetch`\n * API. It provides modern features like caching strategies, request retries,\n * timeouts, and duplicate request handling.\n */\n\nimport {delay} from '@alwatr/delay';\nimport {getGlobalThis} from '@alwatr/global-this';\nimport {hasOwn} from '@alwatr/has-own';\nimport {HttpStatusCodes, MimeTypes} from '@alwatr/http-primer';\nimport {createLogger} from '@alwatr/logger';\nimport {parseDuration} from '@alwatr/parse-duration';\n\nimport {FetchError} from './error.js';\n\nimport type {AlwatrFetchOptions_, FetchOptions, FetchResponse} from './type.js';\n\nexport {cacheSupported};\nexport type * from './type.js';\nexport * from './error.js';\n\nconst logger_ = createLogger('@alwatr/fetch');\nconst globalThis_ = getGlobalThis();\n\n/**\n * A boolean flag indicating whether the browser's Cache API is supported.\n */\nconst cacheSupported = /* #__PURE__ */ hasOwn(globalThis_, 'caches');\n\n/**\n * A simple in-memory storage for tracking and managing duplicate in-flight requests.\n * The key is a unique identifier for the request (e.g., method + URL + body),\n * and the value is the promise of the ongoing fetch operation.\n */\nconst duplicateRequestStorage_: Record<string, Promise<Response>> = {};\n\n/**\n * Default options for all fetch requests. These can be overridden by passing\n * a custom `options` object to the `fetch` function.\n */\nconst defaultFetchOptions: AlwatrFetchOptions_ = {\n  method: 'GET',\n  headers: {},\n  timeout: 8_000,\n  retry: 3,\n  retryDelay: 1_000,\n  removeDuplicate: 'never',\n  cacheStrategy: 'network_only',\n  cacheStorageName: 'fetch_cache',\n};\n\n/**\n * Internal-only fetch options type, which includes the URL and ensures all\n * optional properties from AlwatrFetchOptions_ are present.\n */\ntype FetchOptions__ = AlwatrFetchOptions_ & Omit<RequestInit, 'headers'> & {url: string};\n\n/**\n * An enhanced wrapper for the native `fetch` function.\n *\n * This function extends the standard `fetch` with additional features such as:\n * - **Timeout**: Aborts the request if it takes too long.\n * - **Retry Pattern**: Automatically retries the request on failure (e.g., server errors or network issues).\n * - **Duplicate Request Handling**: Prevents sending multiple identical requests in parallel.\n * - **Cache Strategies**: Provides various caching mechanisms using the browser's Cache API.\n * - **Simplified API**: Offers convenient options for adding query parameters, JSON bodies, and auth tokens.\n *\n * @see {@link FetchOptions} for a detailed list of available options.\n *\n * @param {string} url - The URL to fetch.\n * @param {FetchOptions} options - Optional configuration for the fetch request.\n * @returns {Promise<FetchResponse>} A promise that resolves to a tuple. On\n * success, it returns `[response, null]`. On failure, it returns `[null,\n * FetchError]`.\n *\n * @example\n * ```typescript\n * import {fetch} from '@alwatr/fetch';\n *\n * async function fetchProducts() {\n *   const [response, error] = await fetch('/api/products', {\n *     queryParams: { limit: 10 },\n *     timeout: 5_000,\n *   });\n *\n *   if (error) {\n *     console.error('Request failed:', error.reason);\n *     return;\n *   }\n *\n *   // At this point, response is guaranteed to be valid and ok.\n *   const data = await response.json();\n *   console.log('Products:', data);\n * }\n *\n * fetchProducts();\n * ```\n */\nexport async function fetch(url: string, options: FetchOptions = {}): Promise<FetchResponse> {\n  logger_.logMethodArgs?.('fetch', {url, options});\n\n  const options_ = _processOptions(url, options);\n\n  try {\n    // Start the fetch lifecycle, beginning with the cache strategy.\n    const response = await handleCacheStrategy_(options_);\n\n    if (!response.ok) {\n      throw new FetchError('http_error', `HTTP error! status: ${response.status} ${response.statusText}`, response);\n    }\n\n    return [response, null];\n  }\n  catch (err) {\n    let error: FetchError;\n\n    if (err instanceof FetchError) {\n      error = err;\n\n      if (error.response !== undefined && error.data === undefined) {\n        const bodyText = await error.response.text().catch(() => '');\n\n        if (bodyText.trim().length > 0) {\n          try {\n            // Try to parse as JSON\n            error.data = JSON.parse(bodyText);\n          }\n          catch {\n            error.data = bodyText;\n          }\n        }\n      }\n    }\n    else if (err instanceof Error) {\n      if (err.name === 'AbortError') {\n        error = new FetchError('aborted', err.message);\n      }\n      else {\n        error = new FetchError('network_error', err.message);\n      }\n    }\n    else {\n      error = new FetchError('unknown_error', String(err ?? 'unknown_error'));\n    }\n\n    logger_.error('fetch', error.reason, {error});\n    return [null, error];\n  }\n}\n\n/**\n * Processes and sanitizes the fetch options.\n *\n * @param {string} url - The URL to fetch.\n * @param {FetchOptions} options - The user-provided options.\n * @returns {FetchOptions__} The processed and complete fetch options.\n * @private\n */\nfunction _processOptions(url: string, options: FetchOptions): FetchOptions__ {\n  logger_.logMethodArgs?.('_processOptions', {url, options});\n\n  const options_: FetchOptions__ = {\n    ...defaultFetchOptions,\n    ...options,\n    url,\n  };\n\n  options_.window ??= null;\n\n  if (options_.removeDuplicate === 'auto') {\n    options_.removeDuplicate = cacheSupported ? 'until_load' : 'always';\n  }\n\n  // Append query parameters to the URL if they are provided and the URL doesn't already have them.\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 => `${encodeURIComponent(key)}=${encodeURIComponent(String(queryParams[key]))}`);\n\n    if (queryArray.length > 0) {\n      options_.url += '?' + queryArray.join('&');\n    }\n  }\n\n  // If `bodyJson` is provided, stringify it and set the appropriate 'Content-Type' header.\n  if (options_.bodyJson !== undefined) {\n    options_.body = JSON.stringify(options_.bodyJson);\n    options_.headers['content-type'] = MimeTypes.JSON;\n  }\n\n  // Set the 'Authorization' header for bearer tokens or Alwatr's authentication scheme.\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  logger_.logProperty?.('fetch.options', options_);\n\n  return options_;\n}\n\n/**\n * Manages caching strategies for the fetch request.\n * If the strategy is `network_only`, it bypasses caching and proceeds to the next step.\n * Otherwise, it interacts with the browser's Cache API based on the selected strategy.\n *\n * @param {FetchOptions__} options - The fully configured fetch options.\n * @returns {Promise<Response>} A promise resolving to a `Response` object, either from the cache or the network.\n * @private\n */\nasync function handleCacheStrategy_(options: FetchOptions__): Promise<Response> {\n  if (options.cacheStrategy === 'network_only') {\n    return handleRemoveDuplicate_(options);\n  }\n  // else\n\n  logger_.logMethod?.('handleCacheStrategy_');\n\n  if (!cacheSupported) {\n    logger_.incident?.('fetch', 'fetch_cache_strategy_unsupported', {\n      cacheSupported,\n    });\n    // Fallback to network_only if Cache API is not available.\n    options.cacheStrategy = 'network_only';\n    return handleRemoveDuplicate_(options);\n  }\n  // else\n\n  const cacheStorage = await caches.open(options.cacheStorageName);\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\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        throw new FetchError('cache_not_found', 'Resource not found in cache');\n      }\n      // else\n\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\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 * Handles duplicate request elimination.\n *\n * It creates a unique key based on the request method, URL, and body. If a request with the\n * same key is already in flight, it returns the promise of the existing request instead of\n * creating a new one. This prevents redundant network calls for identical parallel requests.\n *\n * @param {FetchOptions__} options - The fully configured fetch options.\n * @returns {Promise<Response>} A promise resolving to a cloned `Response` object.\n * @private\n */\nasync function handleRemoveDuplicate_(options: FetchOptions__): Promise<Response> {\n  if (options.removeDuplicate === 'never') {\n    return handleRetryPattern_(options);\n  }\n  // else\n\n  logger_.logMethod?.('handleRemoveDuplicate_');\n\n  // Create a unique key for the request. Including the body is crucial to differentiate\n  // between requests to the same URL but with different payloads (e.g., POST requests).\n  const bodyString = typeof options.body === 'string' ? options.body : '';\n  const cacheKey = `${options.method} ${options.url} ${bodyString}`;\n\n  // If a request with the same key doesn't exist, create it and store its promise.\n  duplicateRequestStorage_[cacheKey] ??= handleRetryPattern_(options);\n\n  try {\n    // Await the shared promise to get the response.\n    const response = await duplicateRequestStorage_[cacheKey];\n\n    // Clean up the stored promise based on the removal strategy.\n    if (duplicateRequestStorage_[cacheKey] != null) {\n      if (response.ok !== true || options.removeDuplicate === 'until_load') {\n        // Remove after completion for 'until_load' or if the request failed.\n        delete duplicateRequestStorage_[cacheKey];\n      }\n    }\n\n    // Return a clone of the response, so each caller can consume the body independently.\n    return response.clone();\n  }\n  catch (err) {\n    // If the request fails, remove it from storage to allow for retries.\n    delete duplicateRequestStorage_[cacheKey];\n    throw err;\n  }\n}\n\n/**\n * Implements a retry mechanism for the fetch request.\n * If the request fails due to a server error (status >= 500) or a timeout,\n * it will be retried up to the specified number of times.\n *\n * @param {FetchOptions__} options - The fully configured fetch options.\n * @returns {Promise<Response>} A promise that resolves to the final `Response` after all retries.\n * @private\n */\nasync function handleRetryPattern_(options: FetchOptions__): Promise<Response> {\n  if (!(options.retry > 1)) {\n    return handleTimeout_(options);\n  }\n  // else\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.ok && response.status >= HttpStatusCodes.Error_Server_500_Internal_Server_Error) {\n      // only retry for server errors (5xx)\n      throw new FetchError('http_error', `HTTP error! status: ${response.status} ${response.statusText}`, response);\n    }\n\n    return response;\n  }\n  catch (err) {\n    logger_.accident('fetch', 'fetch_failed_retry', err);\n\n    // Do not retry if the browser is offline.\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    // Restore the original signal for the next attempt.\n    options.signal = externalAbortSignal;\n    return handleRetryPattern_(options);\n  }\n}\n\n/**\n * Wraps the native fetch call with a timeout mechanism.\n *\n * It uses an `AbortController` to abort the request if it does not complete\n * within the specified `timeout` duration. It also respects external abort signals.\n *\n * @param {FetchOptions__} options - The fully configured fetch options.\n * @returns {Promise<Response>} A promise that resolves with the `Response` or rejects on timeout.\n * @private\n */\nfunction handleTimeout_(options: FetchOptions__): Promise<Response> {\n  if (options.timeout === 0) {\n    // If timeout is disabled, call fetch directly.\n    return globalThis_.fetch(options.url, options);\n  }\n\n  logger_.logMethod?.('handleTimeout_');\n\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 an external AbortSignal is provided, listen to it and propagate the abort.\n    if (abortController !== null && externalAbortSignal != null) {\n      externalAbortSignal.addEventListener('abort', () => abortController.abort(), {once: true});\n    }\n\n    const timeoutId = setTimeout(() => {\n      reject(new FetchError('timeout', 'fetch_timeout'));\n      abortController?.abort('fetch_timeout');\n    }, parseDuration(options.timeout!));\n\n    globalThis_\n      .fetch(options.url, options)\n      .then((response) => resolved(response))\n      .catch((reason) => reject(reason))\n      .finally(() => {\n        // Clean up the timeout to prevent it from firing after the request has completed.\n        clearTimeout(timeoutId);\n      });\n  });\n}\n", "import type { FetchErrorReason } from \"./type.js\";\n\n/**\n * Custom error class for fetch-related failures.\n *\n * This error is thrown when a fetch request fails, either due to a network issue\n * or an HTTP error status (i.e., `response.ok` is `false`). It enriches the\n * standard `Error` object with the `response` and the parsed `data` from the\n * response body, allowing for more detailed error handling.\n *\n * @example\n * ```typescript\n * const [response, error] = await fetch('/api/endpoint');\n * if (error) {\n *   console.error(`Request failed with status ${error.response?.status}`);\n *   console.error('Server response:', error.data);\n * }\n * ```\n */\nexport class FetchError extends Error {\n  /**\n   * The original `Response` object.\n   * This is useful for accessing headers and other response metadata.\n   * It will be `undefined` for non-HTTP errors like network failures or timeouts.\n   */\n  public response?: Response;\n\n  /**\n   * The parsed body of the error response, typically a JSON object.\n   * It will be `undefined` for non-HTTP errors.\n   */\n  public data?: JsonObject | string;\n\n  /**\n   * The specific reason for the fetch failure.\n   */\n  public reason: FetchErrorReason;\n\n  constructor(reason: FetchErrorReason, message: string, response?: Response, data?: JsonObject | string) {\n    super(message);\n    this.name = 'FetchError';\n    this.reason = reason;\n    this.response = response;\n    this.data = data;\n  }\n}\n"],
  "mappings": "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",
  "names": []
}
