Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/@types/global.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ export type APIProcessingHook<TProcessingResponse, TData = unknown> = (params: I
/**
* Represents the cache key for an API endpoint. It can be a string param key, an array of param keys, or a function that generates the key from params.
*/
export type CacheKey<TArgs> = keyof TArgs | Array<keyof TArgs> | ((params?: TArgs) => string);
export type CacheKey<TArgs> = keyof Required<NonNullable<TArgs>> | Array<keyof Required<NonNullable<TArgs>>> | ((params?: Partial<TArgs>) => string);

/**
* Represents the additional cache key argument that can be added to a `cacheKey` getter function.
Expand All @@ -106,7 +106,7 @@ export interface IHookBaseConfig<TFunc extends AnyPromiseFunction, TConfig exten
export interface IUseQueryConfig<TFunc extends AnyPromiseFunction, TConfig extends object | undefined, TResponse = Awaited<ReturnType<TFunc>>>
extends IHookBaseConfig<TFunc, TConfig, TResponse> {
/** The cache key to store the response against, it can be a string param key, an array of param keys, or a function that generates the key from params. */
cacheKey?: CacheKey<Partial<FirstArg<TFunc>>>;
cacheKey?: CacheKey<FirstArg<TFunc>>;
/** Additional config to send to SWR (like settings or fallback data for SSR) */
swrConfig?: SWRConfiguration<TResponse | undefined>;
/** If this property is false, the query fetch will wait until it becomes true or undefined. Useful for holding back queries until conditions are met */
Expand Down
2 changes: 1 addition & 1 deletion src/hooks/useInfiniteQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export const useInfiniteQuery = <
const cacheKeyValue = React.useCallback(
(index: number, prevData?: any) => {
const finalParams = hookConfig?.params?.(index, prevData);
return [readCacheKey<Partial<FirstArg<TFunc>>>(endpointId, hookConfig?.cacheKey, finalParams), finalParams];
return [readCacheKey<FirstArg<TFunc>>(endpointId, hookConfig?.cacheKey, finalParams), finalParams];
},
[hookConfig?.cacheKey, hookConfig?.params, endpointId]
);
Expand Down
2 changes: 1 addition & 1 deletion src/hooks/useQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export const useQuery = <TFunc extends (...args: Array<unknown>) => Promise<unkn
if (hookConfig?.waitFor === false) {
return undefined;
}
return readCacheKey<Partial<FirstArg<TFunc>>>(endpointId, hookConfig?.cacheKey, hookConfig?.params);
return readCacheKey<FirstArg<TFunc>>(endpointId, hookConfig?.cacheKey, hookConfig?.params);
}, [hookConfig?.cacheKey, hookConfig?.params, hookConfig?.waitFor, endpointId]);

/** Protect the root fetcher from causing dependency changes in SWR */
Expand Down
2 changes: 1 addition & 1 deletion src/utils/caching.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ describe('readCacheKey', () => {
});

it('should return cache key built when executed with a function', () => {
const cacheKey = (params?: { id: number; name: string }) => `${params?.id}-${params?.name}`;
const cacheKey = (params?: { id?: number; name?: string }) => `${params?.id}-${params?.name}`;
const result = readCacheKey('endpoint', cacheKey, { id: 123, name: 'test' });
expect(result).toEqual('endpoint.123-test');
});
Expand Down
6 changes: 3 additions & 3 deletions src/utils/caching.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export const cacheKeyConcat = (...args: Array<string | undefined>): string => {
* @param {TArgs} [params] - The parameters for the API call.
* @returns {string|undefined} - The final concatenated cache key, or undefined if the cache key params are not all present.
*/
export const readCacheKey = <TArgs>(endpointId?: string, cacheKey?: CacheKey<TArgs>, params?: TArgs): string | undefined => {
export const readCacheKey = <TArgs>(endpointId?: string, cacheKey?: CacheKey<TArgs>, params?: Partial<TArgs>): string | undefined => {
switch (typeof cacheKey) {
case 'function':
const funcResult = cacheKey(params);
Expand All @@ -32,14 +32,14 @@ export const readCacheKey = <TArgs>(endpointId?: string, cacheKey?: CacheKey<TAr
}
return cacheKeyConcat(endpointId, funcResult);
case 'string':
const lookupResult = `${(params?.[cacheKey] as string | undefined) ?? ''}`;
const lookupResult = `${(params?.[cacheKey as string] as string | undefined) ?? ''}`;
if (!lookupResult) {
return undefined;
}
return cacheKeyConcat(endpointId, lookupResult);
case 'object':
if (Array.isArray(cacheKey)) {
const lookupResults = cacheKey.map((key) => `${(params?.[key] as string | undefined) ?? ''}`).filter((key) => !!key);
const lookupResults = cacheKey.map((key) => `${(params?.[key as string] as string | undefined) ?? ''}`).filter((key) => !!key);
return cacheKeyConcat(endpointId, ...lookupResults);
}
return undefined;
Expand Down
Loading