add client side caching

This commit is contained in:
bkellam 2025-11-18 13:31:51 -08:00
parent 74376c022a
commit c7ba32f3bd

View file

@ -3,6 +3,31 @@
import { RepositoryInfo, SearchRequest, SearchResponse, SearchResultFile } from '@/features/search/types';
import { useState, useCallback, useRef, useEffect } from 'react';
interface CacheEntry {
files: SearchResultFile[];
repoInfo: Record<number, RepositoryInfo>;
numMatches: number;
durationMs: number;
timestamp: number;
}
const searchCache = new Map<string, CacheEntry>();
const CACHE_TTL = 5 * 60 * 1000;
const createCacheKey = (params: SearchRequest): string => {
return JSON.stringify({
query: params.query,
matches: params.matches,
contextLines: params.contextLines,
whole: params.whole,
isRegexEnabled: params.isRegexEnabled,
isCaseSensitivityEnabled: params.isCaseSensitivityEnabled,
});
};
const isCacheValid = (entry: CacheEntry): boolean => {
return Date.now() - entry.timestamp < CACHE_TTL;
};
export const useStreamedSearch = ({ query, matches, contextLines, whole, isRegexEnabled, isCaseSensitivityEnabled }: SearchRequest) => {
@ -44,6 +69,30 @@ export const useStreamedSearch = ({ query, matches, contextLines, whole, isRegex
}
abortControllerRef.current = new AbortController();
const cacheKey = createCacheKey({
query,
matches,
contextLines,
whole,
isRegexEnabled,
isCaseSensitivityEnabled,
});
// Check if we have a valid cached result. If so, use it.
const cachedEntry = searchCache.get(cacheKey);
if (cachedEntry && isCacheValid(cachedEntry)) {
console.debug('Using cached search results');
setState({
isStreaming: false,
error: null,
files: cachedEntry.files,
repoInfo: cachedEntry.repoInfo,
durationMs: cachedEntry.durationMs,
numMatches: cachedEntry.numMatches,
});
return;
}
setState({
isStreaming: true,
error: null,
@ -153,10 +202,19 @@ export const useStreamedSearch = ({ query, matches, contextLines, whole, isRegex
} finally {
const endTime = performance.now();
const durationMs = endTime - startTime;
setState(prev => ({
setState(prev => {
searchCache.set(cacheKey, {
files: prev.files,
repoInfo: prev.repoInfo,
numMatches: prev.numMatches,
durationMs,
timestamp: Date.now(),
});
return {
...prev,
durationMs,
}));
}
});
}
}