UNPKG

9.42 kBSource Map (JSON)View Raw
1{"version":3,"file":"index.modern.mjs","sources":["../src/abort-controller.ts","../src/api-call.ts","../src/options.ts","../src/create.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-unsafe-member-access */\nimport 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","/* eslint-disable @typescript-eslint/no-unsafe-assignment */\nimport Axios from 'axios';\nimport 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 (Axios.isCancel(error)) {\n return;\n }\n\n const rid = options.hashGenerator(undefined, error);\n\n if (rid !== state.rid) {\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 console.error('Unknown error thrown by axios cache hooks', error);\n })\n );\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","Axios","isCancel","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":"wGAIM,SAAUA,EACdC,EACAC,EACAC,EACAC,GAEA,MAAMC,EAAYH,EAAQI,kBAAkBL,KAAYE,GAExD,MAAAA,EAAKE,KAALF,EAAKE,GAAe,IAMpBF,EAAKE,GAAWE,OAASH,EAAMG,OCZjB,SAAAC,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,GAAIC,EAAMC,SAASF,GACjB,OAGF,MAAML,EAAMX,EAAQY,mBAAcC,EAAWG,GAEzCL,IAAQJ,EAAMI,KAChBH,EAAS,CAAEM,SAAS,EAAOE,MAAAA,EAAOL,IAAAA,MAMvCQ,MAAOH,IACNI,QAAQJ,MAAM,4CAA6CA,KCgCtDK,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,EAAGd,EAAIe,WACxD,EC5EA,SAAUC,EACdC,GAEA,MAAM3C,EAAW2C,GAAe,GAKhC,OAHA,MAAA3C,EAAQI,oBAARJ,EAAQI,kBAAsBiB,GAC9BrB,MAAAA,EAAQY,gBAARZ,EAAQY,cAAkBY,GAEnB,CACLoB,SAAiC7C,KAA2BE,GAC1D,MAAM4C,EAAgBC,EAAmB,CAAEhC,SAAS,IAI9CiC,EAAS,IAAIC,gBAOnB,OANAC,EAAU,IAAM,IAAMF,EAAO7C,QAAS,IAEtCJ,EAAqBC,EAASC,EAASC,EAAM8C,GAE7CzC,EAAeP,EAASE,EAAM4C,EAAe7C,GAEtC,CAAC6C,EAAc,GAAG9B,KAAM8B,EAAc,KAG/CK,YAAoCnD,GAClC,MAAM8C,EAAgBC,EAAmB,CAAEhC,SAAS,IAI9CiC,EAAS,IAAIC,gBAGnB,OAFAC,EAAU,IAAM,IAAMF,EAAO7C,QAAS,IAE/B,CACL2C,EAAc,GACd,IAAI5C,KACFH,EAAqBC,EAASC,EAASC,EAAM8C,GACtCzC,EAAeP,EAASE,EAAM4C,EAAe7C"}
\No newline at end of file