{"version":3,"file":"index.modern.mjs","sources":["../src/abort-controller.ts","../src/api-call.ts","../src/options.ts","../src/create.ts"],"sourcesContent":["import type { AxiosCacheHooksOptions } from './options';\nimport type { ApiCall } from './types';\n\nexport function applyAbortController<D, A extends unknown[]>(\n  apiCall: ApiCall<D, A>,\n  options: AxiosCacheHooksOptions,\n  args: A,\n  abort: AbortController\n) {\n  const confIndex = options.configIndexFinder(apiCall, ...args);\n\n  args[confIndex] ??= {};\n\n  // Overriding the axios signal opens space\n  // to cancel the request if the component\n  // is unmounted before the request is resolved.\n  //@ts-expect-error - Trust the found parameter index.\n  args[confIndex].signal = abort.signal;\n}\n","import type { Dispatch, SetStateAction } from 'react';\nimport type { AxiosCacheHooksOptions } from './options';\nimport type { ApiCall, State } from './types';\n\nexport function executeApiCall<Data, Args extends unknown[]>(\n  apiCall: ApiCall<Data, Args>,\n  args: Args,\n  [state, setState]: [State<Data>, Dispatch<SetStateAction<State<Data>>>],\n  options: AxiosCacheHooksOptions\n): Promise<void> {\n  return (\n    apiCall(...args)\n      .then(\n        // Successful response\n        (response) => {\n          const rid = options.hashGenerator(response, undefined);\n\n          // Request never had data before or there is new data available\n          if (state.rid !== rid) {\n            setState({ loading: false, data: response.data, response, rid });\n          }\n        },\n\n        // Error response\n        (error) => {\n          // Request was aborted because the component was unmounted\n          // Update the state now will throw a \"Called SetState()\n          // on an Unmounted Component\" error.\n          if (isAxiosCancel(error)) {\n            return;\n          }\n\n          const rid = options.hashGenerator(undefined, error);\n\n          if (rid !== state.rid) {\n            // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n            setState({ loading: false, error, rid });\n          }\n        }\n      )\n      // This avoids a unhandled promise exception in case of an unhandled\n      // error thrown above.\n      .catch((error) => {\n        /* istanbul ignore next */\n        console.error('Unknown error thrown by axios cache hooks', error);\n      })\n  );\n}\n\n/**\n * Copied from Axios source code to avoid importing the whole library.\n *\n * @see https://github.com/axios/axios/blob/master/lib/cancel/isCancel.js\n */\nfunction isAxiosCancel(error: unknown): boolean {\n  return !!(error && (error as Record<string, boolean>)['__CANCEL__']);\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport type { CacheAxiosResponse } from 'axios-cache-interceptor';\nimport { hash } from 'object-code';\n\n/**\n * All available options for the `axios-cache-hooks` package.\n *\n * @see https://tinylibs.js.org/packages/axios-cache-hooks\n */\nexport type AxiosCacheHooksOptions = {\n  /**\n   * A function that must return parameter index that accepts a `CacheRequestConfig` object.\n   *\n   * **Tip**: You can use `function.length` to find the number of available parameters.\n   *\n   * Default implementation returns the last function parameter.\n   *\n   * @default defaultConfigIndexFinder\n   * @param {Function} fn The provided axios call function\n   * @param {any[]} args All provided arguments to the function. Note, unprovided\n   *   arguments won't be present in the array.\n   * @see {@link defaultConfigIndexFinder}\n   */\n  configIndexFinder: ConfigIndexFinder;\n\n  /**\n   * A function that returns a unique id for a given response or error.\n   *\n   * Used to determine if a response is different than the previous one by comparing its\n   * generated hash.\n   *\n   * Default implementation uses `object-code` library.\n   *\n   * **Note**: Returning undefined will ignore the given error or response.\n   *\n   * @default defaultHashGenerator\n   * @param {CacheAxiosResponse} [response] The axios response, if present.\n   * @param {any} [error] A thrown error, if any\n   * @see {@link defaultHashGenerator}\n   */\n  hashGenerator: HashGenerator;\n};\n\n/**\n * A function that must return parameter index that accepts a `CacheRequestConfig` object.\n *\n * **Tip**: You can use `function.length` to find the number of available parameters.\n *\n * Default implementation returns the last function parameter.\n *\n * @default defaultConfigIndexFinder\n * @param {Function} fn The provided axios call function\n * @param {any[]} args All provided arguments to the function. Note, unprovided arguments\n *   won't be present in the array.\n * @see {@link defaultConfigIndexFinder}\n */\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport type ConfigIndexFinder = (fn: Function, ...args: any[]) => number;\n\n/**\n * A function that returns a unique id for a given response or error.\n *\n * Used to determine if a response is different than the previous one by comparing its\n * generated hash.\n *\n * Default implementation uses `object-code` library.\n *\n * **Note**: Returning undefined will ignore the given error or response.\n *\n * @default defaultHashGenerator\n * @param {CacheAxiosResponse} [response] The axios response, if present.\n * @param {any} [error] A thrown error, if any\n * @see {@link defaultHashGenerator}\n */\nexport type HashGenerator = (response?: CacheAxiosResponse, error?: any) => number;\n\nexport const defaultConfigIndexFinder: ConfigIndexFinder = (fn) => {\n  return fn.length - 1;\n};\n\nexport const defaultHashGenerator: HashGenerator = (res, err) => {\n  return res\n    ? hash({ h: res.headers, s: res.status, t: res.statusText })\n    : err\n    ? // eslint-disable-next-line\n      hash({ m: err.message, c: err.code, n: err.name, j: err.toJSON?.() })\n    : 0;\n};\n","import { useEffect, useState } from 'react';\nimport { applyAbortController } from './abort-controller';\nimport { executeApiCall } from './api-call';\nimport {\n  AxiosCacheHooksOptions,\n  defaultConfigIndexFinder,\n  defaultHashGenerator\n} from './options';\nimport type { ApiCall, AxiosCacheHooks, DataLessState, State } from './types';\n\nexport function createAxiosCacheHooks(\n  hookOptions?: Partial<AxiosCacheHooksOptions>\n): AxiosCacheHooks {\n  const options = (hookOptions || {}) as AxiosCacheHooksOptions;\n\n  options.configIndexFinder ??= defaultConfigIndexFinder;\n  options.hashGenerator ??= defaultHashGenerator;\n\n  return {\n    useQuery<D, A extends unknown[]>(apiCall: ApiCall<D, A>, ...args: A) {\n      const internalState = useState<State<D>>({ loading: true });\n\n      // Always create a new abort controller.\n      // If the request is cached, the abort wont be used.\n      const source = new AbortController();\n      useEffect(() => () => source.abort(), []);\n\n      applyAbortController(apiCall, options, args, source);\n      // eslint-disable-next-line @typescript-eslint/no-floating-promises\n      executeApiCall(apiCall, args, internalState, options);\n\n      return [internalState[0].data, internalState[0] as DataLessState<D>];\n    },\n\n    useMutation<D, A extends unknown[]>(apiCall: ApiCall<D, A>) {\n      const internalState = useState<State<D>>({ loading: true });\n\n      // Always create a new abort controller.\n      // If the request is cached, the abort wont be used.\n      const source = new AbortController();\n      useEffect(() => () => source.abort(), []);\n\n      return [\n        internalState[0],\n        (...args: A) => {\n          applyAbortController(apiCall, options, args, source);\n          return executeApiCall(apiCall, args, internalState, options);\n        }\n      ];\n    }\n  };\n}\n"],"names":["applyAbortController","apiCall","options","args","abort","confIndex","configIndexFinder","signal","executeApiCall","state","setState","then","response","rid","hashGenerator","undefined","loading","data","error","isAxiosCancel","catch","console","defaultConfigIndexFinder","fn","length","defaultHashGenerator","res","err","hash","h","headers","s","status","t","statusText","m","message","c","code","n","name","j","toJSON","createAxiosCacheHooks","hookOptions","useQuery","internalState","useState","source","AbortController","useEffect","useMutation"],"mappings":"mFAGM,SAAUA,EACdC,EACAC,EACAC,EACAC,GAEA,MAAMC,EAAYH,EAAQI,kBAAkBL,KAAYE,GAExD,MAAAA,EAAKE,KAALF,EAAKE,GAAe,IAMpBF,EAAKE,GAAWE,OAASH,EAAMG,OCbjBC,SAAAA,EACdP,EACAE,GACCM,EAAOC,GACRR,GAEA,OACED,KAAWE,GACRQ,KAEEC,IACC,MAAMC,EAAMX,EAAQY,cAAcF,OAAUG,GAGxCN,EAAMI,MAAQA,GAChBH,EAAS,CAAEM,SAAS,EAAOC,KAAML,EAASK,KAAML,SAAAA,EAAUC,IAAAA,KAK7DK,IAIC,GA0BV,SAAuBA,GACrB,SAAUA,IAAUA,EAAiC,YA3BzCC,CAAcD,GAChB,OAGF,MAAML,EAAMX,EAAQY,mBAAcC,EAAWG,GAEzCL,IAAQJ,EAAMI,KAEhBH,EAAS,CAAEM,SAAS,EAAOE,MAAAA,EAAOL,IAAAA,MAMvCO,MAAOF,IAENG,QAAQH,MAAM,4CAA6CA,KCgCtDI,MAAAA,EAA+CC,GACnDA,EAAGC,OAAS,EAGRC,EAAsC,CAACC,EAAKC,IAChDD,EACHE,EAAK,CAAEC,EAAGH,EAAII,QAASC,EAAGL,EAAIM,OAAQC,EAAGP,EAAIQ,aAC7CP,EAEAC,EAAK,CAAEO,EAAGR,EAAIS,QAASC,EAAGV,EAAIW,KAAMC,EAAGZ,EAAIa,KAAMC,EAAC,MAAEd,EAAIe,YAAN,EAAEf,EAAIe,WACxD,EC5EA,SAAUC,EACdC,GAEA,MAAM1C,EAAW0C,GAAe,GAKhC,OAHA,MAAA1C,EAAQI,oBAARJ,EAAQI,kBAAsBgB,GAC9BpB,MAAAA,EAAQY,gBAARZ,EAAQY,cAAkBW,GAEnB,CACLoB,SAAiC5C,KAA2BE,GAC1D,MAAM2C,EAAgBC,EAAmB,CAAE/B,SAAS,IAI9CgC,EAAS,IAAIC,gBAOnB,OANAC,EAAU,IAAM,IAAMF,EAAO5C,QAAS,IAEtCJ,EAAqBC,EAASC,EAASC,EAAM6C,GAE7CxC,EAAeP,EAASE,EAAM2C,EAAe5C,GAEtC,CAAC4C,EAAc,GAAG7B,KAAM6B,EAAc,KAG/CK,YAAoClD,GAClC,MAAM6C,EAAgBC,EAAmB,CAAE/B,SAAS,IAI9CgC,EAAS,IAAIC,gBAGnB,OAFAC,EAAU,IAAM,IAAMF,EAAO5C,QAAS,IAE/B,CACL0C,EAAc,GACd,IAAI3C,KACFH,EAAqBC,EAASC,EAASC,EAAM6C,GACtCxC,EAAeP,EAASE,EAAM2C,EAAe5C"}