Update SmartSearchBar component
🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
2014e3434d
commit
4f2894987d
|
|
@ -81,10 +81,29 @@ export default function SmartSearchBar({
|
||||||
const skipSearchRef = useRef(false);
|
const skipSearchRef = useRef(false);
|
||||||
const boxRef = useRef(null);
|
const boxRef = useRef(null);
|
||||||
const inputRef = useRef(null);
|
const inputRef = useRef(null);
|
||||||
const searchCacheRef = useRef(new Map());
|
const searchCacheRef = useRef(new Map()); // key -> { value, expiresAt }
|
||||||
const latestQueryRef = useRef("");
|
const latestQueryRef = useRef("");
|
||||||
const emptySuggestionsFetchedRef = useRef(false);
|
const emptySuggestionsFetchedRef = useRef(false);
|
||||||
|
|
||||||
|
// Cache helpers with TTL and case-insensitive keys
|
||||||
|
const cacheKey = (q) => (q || "").toLowerCase().trim();
|
||||||
|
const cacheGet = (q) => {
|
||||||
|
const key = cacheKey(q);
|
||||||
|
const entry = searchCacheRef.current.get(key);
|
||||||
|
if (!entry) return null;
|
||||||
|
if (entry.expiresAt <= Date.now()) {
|
||||||
|
searchCacheRef.current.delete(key);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return entry.value;
|
||||||
|
};
|
||||||
|
const cacheSet = (q, value, ttlMs = 30000) => {
|
||||||
|
const key = cacheKey(q);
|
||||||
|
// Don't cache empty results - always re-fetch
|
||||||
|
if (!value || value.length === 0) return;
|
||||||
|
searchCacheRef.current.set(key, { value, expiresAt: Date.now() + ttlMs });
|
||||||
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
function onDocDown(e) {
|
function onDocDown(e) {
|
||||||
if (!boxRef.current) return;
|
if (!boxRef.current) return;
|
||||||
|
|
@ -98,7 +117,7 @@ export default function SmartSearchBar({
|
||||||
const triggerSearch = async (searchQuery) => {
|
const triggerSearch = async (searchQuery) => {
|
||||||
if (abortRef.current) abortRef.current.abort();
|
if (abortRef.current) abortRef.current.abort();
|
||||||
|
|
||||||
const cached = searchCacheRef.current.get(searchQuery);
|
const cached = cacheGet(searchQuery);
|
||||||
if (cached) {
|
if (cached) {
|
||||||
setItems(cached);
|
setItems(cached);
|
||||||
setActive(cached.length ? 0 : -1);
|
setActive(cached.length ? 0 : -1);
|
||||||
|
|
@ -121,7 +140,7 @@ export default function SmartSearchBar({
|
||||||
setItems(res);
|
setItems(res);
|
||||||
setActive(res.length ? 0 : -1);
|
setActive(res.length ? 0 : -1);
|
||||||
setHasSearched(true);
|
setHasSearched(true);
|
||||||
searchCacheRef.current.set(searchQuery, res);
|
cacheSet(searchQuery, res); // Won't cache empty results
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (ctrl.signal.aborted) return;
|
if (ctrl.signal.aborted) return;
|
||||||
setErr((e && e.message) ? e.message : "Search error");
|
setErr((e && e.message) ? e.message : "Search error");
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue