diff --git a/src/plugins/built-in/globalSearch/src/core/index.ts b/src/plugins/built-in/globalSearch/src/core/index.ts index adf199c3..c86d9f34 100644 --- a/src/plugins/built-in/globalSearch/src/core/index.ts +++ b/src/plugins/built-in/globalSearch/src/core/index.ts @@ -151,6 +151,17 @@ const globalSearchPlugin: Plugin = { run: async (api) => { const appRef = { current: null }; + // Check for extension updates and clear caches if needed + try { + const { checkAndHandleUpdate } = await import("../utils/versionCheck"); + const wasUpdated = await checkAndHandleUpdate(); + if (wasUpdated) { + console.log("[Global Search] Extension updated - caches cleared"); + } + } catch (error) { + console.warn("[Global Search] Failed to check for updates:", error); + } + try { await IndexedDbManager.create("embeddiaDB", "embeddiaObjectStore", { primaryKey: "id", diff --git a/src/plugins/built-in/globalSearch/src/search/searchUtils.ts b/src/plugins/built-in/globalSearch/src/search/searchUtils.ts index ed7e72c2..3343e839 100644 --- a/src/plugins/built-in/globalSearch/src/search/searchUtils.ts +++ b/src/plugins/built-in/globalSearch/src/search/searchUtils.ts @@ -30,6 +30,21 @@ function setCachedResults(query: string, results: CombinedResult[]) { searchCache.set(query, { results, timestamp: Date.now() }); } +/** + * Clears the search result cache + */ +export function clearSearchCache(): void { + searchCache.clear(); + console.debug("[Search] Search result cache cleared"); +} + +// Listen for cache clear events (e.g., on extension update) +if (typeof window !== 'undefined') { + window.addEventListener('betterseqta-clear-search-cache', () => { + clearSearchCache(); + }); +} + export function createSearchIndexes() { const commands = getStaticCommands(); const dynamicItems = getDynamicItems(); diff --git a/src/plugins/built-in/globalSearch/src/search/vector/vectorSearch.ts b/src/plugins/built-in/globalSearch/src/search/vector/vectorSearch.ts index 6f45fa6b..59013d60 100644 --- a/src/plugins/built-in/globalSearch/src/search/vector/vectorSearch.ts +++ b/src/plugins/built-in/globalSearch/src/search/vector/vectorSearch.ts @@ -60,6 +60,21 @@ function setCachedEmbedding(query: string, embedding: number[]) { embeddingCache.set(query, embedding); } +/** + * Clears the embedding cache + */ +export function clearEmbeddingCache(): void { + embeddingCache.clear(); + console.debug("[Vector Search] Embedding cache cleared"); +} + +// Listen for cache clear events (e.g., on extension update) +if (typeof window !== 'undefined') { + window.addEventListener('betterseqta-clear-embedding-cache', () => { + clearEmbeddingCache(); + }); +} + export async function searchVectors( query: string, topK: number = 20, diff --git a/src/plugins/built-in/globalSearch/src/utils/versionCheck.ts b/src/plugins/built-in/globalSearch/src/utils/versionCheck.ts new file mode 100644 index 00000000..c3dec89d --- /dev/null +++ b/src/plugins/built-in/globalSearch/src/utils/versionCheck.ts @@ -0,0 +1,106 @@ +import browser from "webextension-polyfill"; + +const VERSION_STORAGE_KEY = "betterseqta-global-search-version"; +const VERSION_CACHE_KEY = "betterseqta-global-search-cache-version"; + +/** + * Gets the current extension version from the manifest + */ +export function getCurrentVersion(): string { + try { + return browser.runtime.getManifest().version; + } catch (e) { + console.warn("[Version Check] Failed to get manifest version:", e); + return "0.0.0"; + } +} + +/** + * Gets the last stored version from localStorage + */ +export function getStoredVersion(): string | null { + try { + return localStorage.getItem(VERSION_STORAGE_KEY); + } catch (e) { + console.warn("[Version Check] Failed to get stored version:", e); + return null; + } +} + +/** + * Stores the current version in localStorage + */ +export function storeVersion(version: string): void { + try { + localStorage.setItem(VERSION_STORAGE_KEY, version); + localStorage.setItem(VERSION_CACHE_KEY, version); + } catch (e) { + console.warn("[Version Check] Failed to store version:", e); + } +} + +/** + * Checks if the extension has been updated and clears caches if needed + * Returns true if an update was detected + */ +export async function checkAndHandleUpdate(): Promise { + const currentVersion = getCurrentVersion(); + const storedVersion = getStoredVersion(); + + // If no stored version, this is first run - store current version + if (!storedVersion) { + console.debug(`[Version Check] First run detected, storing version ${currentVersion}`); + storeVersion(currentVersion); + return false; + } + + // If versions match, no update + if (storedVersion === currentVersion) { + return false; + } + + // Version mismatch detected - extension was updated + console.log(`[Version Check] Extension updated from ${storedVersion} to ${currentVersion}, clearing caches...`); + + // Clear all caches + await clearAllCaches(); + + // Store new version + storeVersion(currentVersion); + + return true; +} + +/** + * Clears all search-related caches + */ +export async function clearAllCaches(): Promise { + try { + // Clear search result cache (in-memory Map) + if (typeof window !== 'undefined') { + // Dispatch event to clear caches in other modules + window.dispatchEvent(new CustomEvent('betterseqta-clear-search-cache')); + window.dispatchEvent(new CustomEvent('betterseqta-clear-embedding-cache')); + } + + // Also try to directly clear caches if modules are already loaded + try { + const { clearSearchCache } = await import("../search/searchUtils"); + clearSearchCache(); + } catch (e) { + // Module might not be loaded yet, that's okay + } + + try { + const { clearEmbeddingCache } = await import("../search/vector/vectorSearch"); + clearEmbeddingCache(); + } catch (e) { + // Module might not be loaded yet, that's okay + } + + console.debug("[Version Check] All caches cleared"); + } catch (e) { + console.error("[Version Check] Error clearing caches:", e); + } +} +