From 4f2894987daf16702e5d1fcd017e305cb0325b8b Mon Sep 17 00:00:00 2001 From: SocioWire Date: Mon, 5 Jan 2026 06:43:44 +0000 Subject: [PATCH] Update SmartSearchBar component MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- src/components/Search/SmartSearchBar.jsx | 25 +++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/src/components/Search/SmartSearchBar.jsx b/src/components/Search/SmartSearchBar.jsx index 03c8349..dc9414b 100644 --- a/src/components/Search/SmartSearchBar.jsx +++ b/src/components/Search/SmartSearchBar.jsx @@ -81,10 +81,29 @@ export default function SmartSearchBar({ const skipSearchRef = useRef(false); const boxRef = useRef(null); const inputRef = useRef(null); - const searchCacheRef = useRef(new Map()); + const searchCacheRef = useRef(new Map()); // key -> { value, expiresAt } const latestQueryRef = useRef(""); 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(() => { function onDocDown(e) { if (!boxRef.current) return; @@ -98,7 +117,7 @@ export default function SmartSearchBar({ const triggerSearch = async (searchQuery) => { if (abortRef.current) abortRef.current.abort(); - const cached = searchCacheRef.current.get(searchQuery); + const cached = cacheGet(searchQuery); if (cached) { setItems(cached); setActive(cached.length ? 0 : -1); @@ -121,7 +140,7 @@ export default function SmartSearchBar({ setItems(res); setActive(res.length ? 0 : -1); setHasSearched(true); - searchCacheRef.current.set(searchQuery, res); + cacheSet(searchQuery, res); // Won't cache empty results } catch (e) { if (ctrl.signal.aborted) return; setErr((e && e.message) ? e.message : "Search error");