1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-09-24 17:51:14 +02:00

chore: use params object for swr cache clearing functions

This commit is contained in:
Thomas Heartman 2025-09-24 14:37:43 +02:00
parent e3fc88b11f
commit c73ee604f2
No known key found for this signature in database
GPG Key ID: BD1F880DAED1EE78
7 changed files with 90 additions and 24 deletions

View File

@ -69,7 +69,11 @@ const createChangeRequestSearch = () => {
const { KEY, fetcher } = getChangeRequestSearchFetcher(params); const { KEY, fetcher } = getChangeRequestSearchFetcher(params);
const swrKey = `${cachePrefix}${KEY}`; const swrKey = `${cachePrefix}${KEY}`;
const cacheId = 'global'; const cacheId = 'global';
useClearSWRCache(swrKey, PATH, SWR_CACHE_SIZE); useClearSWRCache({
currentKey: swrKey,
clearPrefix: PATH,
cacheSize: SWR_CACHE_SIZE,
});
useEffect(() => { useEffect(() => {
initCache(cacheId); initCache(cacheId);

View File

@ -60,7 +60,11 @@ const createEventSearch = () => {
const { KEY, fetcher } = getEventSearchFetcher(params); const { KEY, fetcher } = getEventSearchFetcher(params);
const swrKey = `${cachePrefix}${KEY}`; const swrKey = `${cachePrefix}${KEY}`;
const cacheId = params.project || ''; const cacheId = params.project || '';
useClearSWRCache(swrKey, PATH, SWR_CACHE_SIZE); useClearSWRCache({
currentKey: swrKey,
clearPrefix: PATH,
cacheSize: SWR_CACHE_SIZE,
});
useEffect(() => { useEffect(() => {
initCache(params.project || ''); initCache(params.project || '');

View File

@ -60,7 +60,11 @@ const createFeatureSearch = () => {
const { KEY, fetcher } = getFeatureSearchFetcher(params); const { KEY, fetcher } = getFeatureSearchFetcher(params);
const swrKey = `${cachePrefix}${KEY}`; const swrKey = `${cachePrefix}${KEY}`;
const cacheId = params.project || ''; const cacheId = params.project || '';
useClearSWRCache(swrKey, PATH, SWR_CACHE_SIZE); useClearSWRCache({
currentKey: swrKey,
clearPrefix: PATH,
cacheSize: SWR_CACHE_SIZE,
});
useEffect(() => { useEffect(() => {
initCache(cacheId); initCache(cacheId);

View File

@ -29,7 +29,10 @@ export function createPaginatedHook<T extends { total?: number }>(
const prefix = dynamicPrefixKey || defaultPrefixKey; const prefix = dynamicPrefixKey || defaultPrefixKey;
const KEY = `${prefix}${urlSearchParams}`; const KEY = `${prefix}${urlSearchParams}`;
useClearSWRCache(KEY, prefix); useClearSWRCache({
currentKey: KEY,
clearPrefix: prefix,
});
const fetcher = async () => { const fetcher = async () => {
return fetch(formatApiPath(KEY), { return fetch(formatApiPath(KEY), {

View File

@ -61,7 +61,11 @@ const createSignalQuery = () => {
const { KEY, fetcher } = getSignalQueryFetcher(params); const { KEY, fetcher } = getSignalQueryFetcher(params);
const swrKey = `${cachePrefix}${KEY}`; const swrKey = `${cachePrefix}${KEY}`;
useClearSWRCache(swrKey, PATH, SWR_CACHE_SIZE); useClearSWRCache({
currentKey: swrKey,
clearPrefix: PATH,
cacheSize: SWR_CACHE_SIZE,
});
const { data, error, mutate, isLoading } = const { data, error, mutate, isLoading } =
useConditionalSWR<SignalQueryResponse>( useConditionalSWR<SignalQueryResponse>(

View File

@ -7,7 +7,11 @@ describe('manageCacheEntries', () => {
cacheMock.set('prefix-2', {}); cacheMock.set('prefix-2', {});
cacheMock.set('prefix-3', {}); 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-1')).toBe(false);
expect(cacheMock.has('prefix-2')).toBe(false); expect(cacheMock.has('prefix-2')).toBe(false);
@ -21,7 +25,12 @@ describe('manageCacheEntries', () => {
cacheMock.set('prefix-3', {}); cacheMock.set('prefix-3', {});
cacheMock.set('prefix-4', {}); 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']); expect([...cacheMock.keys()]).toStrictEqual(['prefix-3', 'prefix-4']);
}); });
@ -33,7 +42,12 @@ describe('manageCacheEntries', () => {
cacheMock.set('prefix-3', {}); cacheMock.set('prefix-3', {});
cacheMock.set('prefix-4', {}); 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']); expect([...cacheMock.keys()]).toStrictEqual(['prefix-2', 'prefix-4']);
}); });
@ -43,7 +57,12 @@ describe('manageCacheEntries', () => {
cacheMock.set('prefix-1', {}); cacheMock.set('prefix-1', {});
cacheMock.set('prefix-2', {}); 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-1')).toBe(true);
expect(cacheMock.has('prefix-2')).toBe(true); expect(cacheMock.has('prefix-2')).toBe(true);
@ -55,7 +74,12 @@ describe('manageCacheEntries', () => {
cacheMock.set('other-2', {}); cacheMock.set('other-2', {});
cacheMock.set('prefix-3', {}); 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('prefix-1')).toBe(true);
expect(cacheMock.has('other-2')).toBe(true); expect(cacheMock.has('other-2')).toBe(true);
@ -69,7 +93,12 @@ describe('manageCacheEntries', () => {
cacheMock.set('prefix-3', {}); cacheMock.set('prefix-3', {});
cacheMock.set('prefix-4', {}); 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']); expect([...cacheMock.keys()]).toStrictEqual(['prefix-3']);
}); });

View File

@ -2,19 +2,26 @@ import { useSWRConfig } from 'swr';
type Cache = ReturnType<typeof useSWRConfig>['cache']; type Cache = ReturnType<typeof useSWRConfig>['cache'];
export const clearCacheEntries = ( type ClearCacheEntriesProps = {
cache: Cache, cache: Cache;
currentKey: string, currentKey: string;
clearPrefix: string, clearPrefix: string;
SWR_CACHE_SIZE = 1, cacheSize?: number;
) => { };
export const clearCacheEntries = ({
cache,
currentKey,
clearPrefix,
cacheSize = 1,
}: ClearCacheEntriesProps) => {
const keys = [...cache.keys()]; const keys = [...cache.keys()];
const filteredKeys = keys.filter( const filteredKeys = keys.filter(
(key) => key.startsWith(clearPrefix) && key !== currentKey, (key) => key.startsWith(clearPrefix) && key !== currentKey,
); );
const entriesToLeave = SWR_CACHE_SIZE - 1; const entriesToLeave = cacheSize - 1;
const keysToDelete = const keysToDelete =
entriesToLeave <= 0 entriesToLeave <= 0
? filteredKeys ? filteredKeys
@ -23,16 +30,27 @@ export const clearCacheEntries = (
keysToDelete.forEach((key) => cache.delete(key)); 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. 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 We only keep the latest cache key `currentKey` and remove all other entries identified
by the `clearPrefix` by the `clearPrefix`
*/ */
export const useClearSWRCache = ( export const useClearSWRCache = ({
currentKey: string, currentKey,
clearPrefix: string, clearPrefix,
SWR_CACHE_SIZE = 1, cacheSize = 1,
) => { }: useClearSWRCacheProps) => {
const { cache } = useSWRConfig(); const { cache } = useSWRConfig();
clearCacheEntries(cache, currentKey, clearPrefix, SWR_CACHE_SIZE); clearCacheEntries({
cache,
currentKey,
clearPrefix,
cacheSize,
});
}; };