diff --git a/frontend/src/hooks/api/getters/useChangeRequestSearch/useChangeRequestSearch.ts b/frontend/src/hooks/api/getters/useChangeRequestSearch/useChangeRequestSearch.ts index 3ac7d4966c..9ec263f42f 100644 --- a/frontend/src/hooks/api/getters/useChangeRequestSearch/useChangeRequestSearch.ts +++ b/frontend/src/hooks/api/getters/useChangeRequestSearch/useChangeRequestSearch.ts @@ -69,7 +69,11 @@ const createChangeRequestSearch = () => { const { KEY, fetcher } = getChangeRequestSearchFetcher(params); const swrKey = `${cachePrefix}${KEY}`; const cacheId = 'global'; - useClearSWRCache(swrKey, PATH, SWR_CACHE_SIZE); + useClearSWRCache({ + currentKey: swrKey, + clearPrefix: PATH, + cacheSize: SWR_CACHE_SIZE, + }); useEffect(() => { initCache(cacheId); diff --git a/frontend/src/hooks/api/getters/useEventSearch/useEventSearch.ts b/frontend/src/hooks/api/getters/useEventSearch/useEventSearch.ts index aab3ad9ed4..961a9aee26 100644 --- a/frontend/src/hooks/api/getters/useEventSearch/useEventSearch.ts +++ b/frontend/src/hooks/api/getters/useEventSearch/useEventSearch.ts @@ -60,7 +60,11 @@ const createEventSearch = () => { const { KEY, fetcher } = getEventSearchFetcher(params); const swrKey = `${cachePrefix}${KEY}`; const cacheId = params.project || ''; - useClearSWRCache(swrKey, PATH, SWR_CACHE_SIZE); + useClearSWRCache({ + currentKey: swrKey, + clearPrefix: PATH, + cacheSize: SWR_CACHE_SIZE, + }); useEffect(() => { initCache(params.project || ''); diff --git a/frontend/src/hooks/api/getters/useFeatureSearch/useFeatureSearch.ts b/frontend/src/hooks/api/getters/useFeatureSearch/useFeatureSearch.ts index 2d252a5cff..f5122535b1 100644 --- a/frontend/src/hooks/api/getters/useFeatureSearch/useFeatureSearch.ts +++ b/frontend/src/hooks/api/getters/useFeatureSearch/useFeatureSearch.ts @@ -60,7 +60,11 @@ const createFeatureSearch = () => { const { KEY, fetcher } = getFeatureSearchFetcher(params); const swrKey = `${cachePrefix}${KEY}`; const cacheId = params.project || ''; - useClearSWRCache(swrKey, PATH, SWR_CACHE_SIZE); + useClearSWRCache({ + currentKey: swrKey, + clearPrefix: PATH, + cacheSize: SWR_CACHE_SIZE, + }); useEffect(() => { initCache(cacheId); diff --git a/frontend/src/hooks/api/getters/usePaginatedData/usePaginatedData.ts b/frontend/src/hooks/api/getters/usePaginatedData/usePaginatedData.ts index 8924ef32f0..c009ecb409 100644 --- a/frontend/src/hooks/api/getters/usePaginatedData/usePaginatedData.ts +++ b/frontend/src/hooks/api/getters/usePaginatedData/usePaginatedData.ts @@ -29,7 +29,10 @@ export function createPaginatedHook( const prefix = dynamicPrefixKey || defaultPrefixKey; const KEY = `${prefix}${urlSearchParams}`; - useClearSWRCache(KEY, prefix); + useClearSWRCache({ + currentKey: KEY, + clearPrefix: prefix, + }); const fetcher = async () => { return fetch(formatApiPath(KEY), { diff --git a/frontend/src/hooks/api/getters/useSignalQuery/useSignalQuery.ts b/frontend/src/hooks/api/getters/useSignalQuery/useSignalQuery.ts index 040558a623..ebd78f1e89 100644 --- a/frontend/src/hooks/api/getters/useSignalQuery/useSignalQuery.ts +++ b/frontend/src/hooks/api/getters/useSignalQuery/useSignalQuery.ts @@ -61,7 +61,11 @@ const createSignalQuery = () => { const { KEY, fetcher } = getSignalQueryFetcher(params); const swrKey = `${cachePrefix}${KEY}`; - useClearSWRCache(swrKey, PATH, SWR_CACHE_SIZE); + useClearSWRCache({ + currentKey: swrKey, + clearPrefix: PATH, + cacheSize: SWR_CACHE_SIZE, + }); const { data, error, mutate, isLoading } = useConditionalSWR( diff --git a/frontend/src/hooks/useClearSWRCache.test.ts b/frontend/src/hooks/useClearSWRCache.test.ts index f6dd61d765..514b02eb9c 100644 --- a/frontend/src/hooks/useClearSWRCache.test.ts +++ b/frontend/src/hooks/useClearSWRCache.test.ts @@ -7,7 +7,11 @@ describe('manageCacheEntries', () => { cacheMock.set('prefix-2', {}); cacheMock.set('prefix-3', {}); - clearCacheEntries(cacheMock, 'prefix-3', 'prefix-'); + clearCacheEntries({ + cache: cacheMock, + currentKey: 'prefix-3', + clearPrefix: 'prefix-', + }); expect(cacheMock.has('prefix-1')).toBe(false); expect(cacheMock.has('prefix-2')).toBe(false); @@ -21,7 +25,12 @@ describe('manageCacheEntries', () => { cacheMock.set('prefix-3', {}); cacheMock.set('prefix-4', {}); - clearCacheEntries(cacheMock, 'prefix-4', 'prefix-', 2); + clearCacheEntries({ + cache: cacheMock, + currentKey: 'prefix-4', + clearPrefix: 'prefix-', + cacheSize: 2, + }); expect([...cacheMock.keys()]).toStrictEqual(['prefix-3', 'prefix-4']); }); @@ -33,7 +42,12 @@ describe('manageCacheEntries', () => { cacheMock.set('prefix-3', {}); cacheMock.set('prefix-4', {}); - clearCacheEntries(cacheMock, 'prefix-2', 'prefix-', 2); + clearCacheEntries({ + cache: cacheMock, + currentKey: 'prefix-2', + clearPrefix: 'prefix-', + cacheSize: 2, + }); expect([...cacheMock.keys()]).toStrictEqual(['prefix-2', 'prefix-4']); }); @@ -43,7 +57,12 @@ describe('manageCacheEntries', () => { cacheMock.set('prefix-1', {}); cacheMock.set('prefix-2', {}); - clearCacheEntries(cacheMock, 'prefix-2', 'prefix-', 5); + clearCacheEntries({ + cache: cacheMock, + currentKey: 'prefix-2', + clearPrefix: 'prefix-', + cacheSize: 5, + }); expect(cacheMock.has('prefix-1')).toBe(true); expect(cacheMock.has('prefix-2')).toBe(true); @@ -55,7 +74,12 @@ describe('manageCacheEntries', () => { cacheMock.set('other-2', {}); cacheMock.set('prefix-3', {}); - clearCacheEntries(cacheMock, 'prefix-3', 'prefix-', 2); + clearCacheEntries({ + cache: cacheMock, + currentKey: 'prefix-3', + clearPrefix: 'prefix-', + cacheSize: 2, + }); expect(cacheMock.has('prefix-1')).toBe(true); expect(cacheMock.has('other-2')).toBe(true); @@ -69,7 +93,12 @@ describe('manageCacheEntries', () => { cacheMock.set('prefix-3', {}); cacheMock.set('prefix-4', {}); - clearCacheEntries(cacheMock, 'prefix-3', 'prefix-', -1); + clearCacheEntries({ + cache: cacheMock, + currentKey: 'prefix-3', + clearPrefix: 'prefix-', + cacheSize: -1, + }); expect([...cacheMock.keys()]).toStrictEqual(['prefix-3']); }); diff --git a/frontend/src/hooks/useClearSWRCache.ts b/frontend/src/hooks/useClearSWRCache.ts index 50bbdee3e8..ef19f4c18e 100644 --- a/frontend/src/hooks/useClearSWRCache.ts +++ b/frontend/src/hooks/useClearSWRCache.ts @@ -2,19 +2,26 @@ import { useSWRConfig } from 'swr'; type Cache = ReturnType['cache']; -export const clearCacheEntries = ( - cache: Cache, - currentKey: string, - clearPrefix: string, - SWR_CACHE_SIZE = 1, -) => { +type ClearCacheEntriesProps = { + cache: Cache; + currentKey: string; + clearPrefix: string; + cacheSize?: number; +}; + +export const clearCacheEntries = ({ + cache, + currentKey, + clearPrefix, + cacheSize = 1, +}: ClearCacheEntriesProps) => { const keys = [...cache.keys()]; const filteredKeys = keys.filter( (key) => key.startsWith(clearPrefix) && key !== currentKey, ); - const entriesToLeave = SWR_CACHE_SIZE - 1; + const entriesToLeave = cacheSize - 1; const keysToDelete = entriesToLeave <= 0 ? filteredKeys @@ -23,16 +30,27 @@ export const clearCacheEntries = ( keysToDelete.forEach((key) => cache.delete(key)); }; +type UseClearSWRCacheProps = { + currentKey: string; + clearPrefix: string; + cacheSize?: number; +}; + /** With dynamic search and filter parameters we want to prevent cache from growing extensively. We only keep the latest cache key `currentKey` and remove all other entries identified by the `clearPrefix` */ -export const useClearSWRCache = ( - currentKey: string, - clearPrefix: string, - SWR_CACHE_SIZE = 1, -) => { +export const useClearSWRCache = ({ + currentKey, + clearPrefix, + cacheSize = 1, +}: UseClearSWRCacheProps) => { const { cache } = useSWRConfig(); - clearCacheEntries(cache, currentKey, clearPrefix, SWR_CACHE_SIZE); + clearCacheEntries({ + cache, + currentKey, + clearPrefix, + cacheSize, + }); };