Skip to content

Commit c7ba32f

Browse files
add client side caching
1 parent 74376c0 commit c7ba32f

File tree

1 file changed

+62
-4
lines changed

1 file changed

+62
-4
lines changed

packages/web/src/app/[domain]/search/useStreamedSearch.ts

Lines changed: 62 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,31 @@
33
import { RepositoryInfo, SearchRequest, SearchResponse, SearchResultFile } from '@/features/search/types';
44
import { useState, useCallback, useRef, useEffect } from 'react';
55

6+
interface CacheEntry {
7+
files: SearchResultFile[];
8+
repoInfo: Record<number, RepositoryInfo>;
9+
numMatches: number;
10+
durationMs: number;
11+
timestamp: number;
12+
}
13+
14+
const searchCache = new Map<string, CacheEntry>();
15+
const CACHE_TTL = 5 * 60 * 1000;
16+
17+
const createCacheKey = (params: SearchRequest): string => {
18+
return JSON.stringify({
19+
query: params.query,
20+
matches: params.matches,
21+
contextLines: params.contextLines,
22+
whole: params.whole,
23+
isRegexEnabled: params.isRegexEnabled,
24+
isCaseSensitivityEnabled: params.isCaseSensitivityEnabled,
25+
});
26+
};
27+
28+
const isCacheValid = (entry: CacheEntry): boolean => {
29+
return Date.now() - entry.timestamp < CACHE_TTL;
30+
};
631

732
export const useStreamedSearch = ({ query, matches, contextLines, whole, isRegexEnabled, isCaseSensitivityEnabled }: SearchRequest) => {
833

@@ -44,6 +69,30 @@ export const useStreamedSearch = ({ query, matches, contextLines, whole, isRegex
4469
}
4570
abortControllerRef.current = new AbortController();
4671

72+
const cacheKey = createCacheKey({
73+
query,
74+
matches,
75+
contextLines,
76+
whole,
77+
isRegexEnabled,
78+
isCaseSensitivityEnabled,
79+
});
80+
81+
// Check if we have a valid cached result. If so, use it.
82+
const cachedEntry = searchCache.get(cacheKey);
83+
if (cachedEntry && isCacheValid(cachedEntry)) {
84+
console.debug('Using cached search results');
85+
setState({
86+
isStreaming: false,
87+
error: null,
88+
files: cachedEntry.files,
89+
repoInfo: cachedEntry.repoInfo,
90+
durationMs: cachedEntry.durationMs,
91+
numMatches: cachedEntry.numMatches,
92+
});
93+
return;
94+
}
95+
4796
setState({
4897
isStreaming: true,
4998
error: null,
@@ -153,10 +202,19 @@ export const useStreamedSearch = ({ query, matches, contextLines, whole, isRegex
153202
} finally {
154203
const endTime = performance.now();
155204
const durationMs = endTime - startTime;
156-
setState(prev => ({
157-
...prev,
158-
durationMs,
159-
}));
205+
setState(prev => {
206+
searchCache.set(cacheKey, {
207+
files: prev.files,
208+
repoInfo: prev.repoInfo,
209+
numMatches: prev.numMatches,
210+
durationMs,
211+
timestamp: Date.now(),
212+
});
213+
return {
214+
...prev,
215+
durationMs,
216+
}
217+
});
160218
}
161219
}
162220

0 commit comments

Comments
 (0)