UNPKG

1.82 kBPlain TextView Raw
1import { useEffect, useState } from 'react';
2import { applyAbortController } from './abort-controller';
3import { executeApiCall } from './api-call';
4import {
5 AxiosCacheHooksOptions,
6 defaultConfigIndexFinder,
7 defaultHashGenerator
8} from './options';
9import type { ApiCall, AxiosCacheHooks, DataLessState, State } from './types';
10
11export function createAxiosCacheHooks(
12 hookOptions?: Partial<AxiosCacheHooksOptions>
13): AxiosCacheHooks {
14 const options = (hookOptions || {}) as AxiosCacheHooksOptions;
15
16 options.configIndexFinder ??= defaultConfigIndexFinder;
17 options.hashGenerator ??= defaultHashGenerator;
18
19 return {
20 useQuery<D, A extends unknown[]>(apiCall: ApiCall<D, A>, ...args: A) {
21 const internalState = useState<State<D>>({ loading: true });
22
23 // Always create a new abort controller.
24 // If the request is cached, the abort wont be used.
25 const source = new AbortController();
26 useEffect(() => () => source.abort(), []);
27
28 applyAbortController(apiCall, options, args, source);
29 // eslint-disable-next-line @typescript-eslint/no-floating-promises
30 executeApiCall(apiCall, args, internalState, options);
31
32 return [internalState[0].data, internalState[0] as DataLessState<D>];
33 },
34
35 useMutation<D, A extends unknown[]>(apiCall: ApiCall<D, A>) {
36 const internalState = useState<State<D>>({ loading: true });
37
38 // Always create a new abort controller.
39 // If the request is cached, the abort wont be used.
40 const source = new AbortController();
41 useEffect(() => () => source.abort(), []);
42
43 return [
44 internalState[0],
45 (...args: A) => {
46 applyAbortController(apiCall, options, args, source);
47 return executeApiCall(apiCall, args, internalState, options);
48 }
49 ];
50 }
51 };
52}