diff options
Diffstat (limited to 'apps/browser-extension/src/utils/trpc.ts')
| -rw-r--r-- | apps/browser-extension/src/utils/trpc.ts | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/apps/browser-extension/src/utils/trpc.ts b/apps/browser-extension/src/utils/trpc.ts index e56968b8..76534bcb 100644 --- a/apps/browser-extension/src/utils/trpc.ts +++ b/apps/browser-extension/src/utils/trpc.ts @@ -1,5 +1,121 @@ +import { QueryClient } from "@tanstack/react-query"; +import { persistQueryClient } from "@tanstack/react-query-persist-client"; +import { createTRPCClient, httpBatchLink } from "@trpc/client"; import { createTRPCReact } from "@trpc/react-query"; +import superjson from "superjson"; import type { AppRouter } from "@karakeep/trpc/routers/_app"; +import { getPluginSettings } from "./settings"; +import { createChromeStorage } from "./storagePersister"; + export const api = createTRPCReact<AppRouter>(); + +let apiClient: ReturnType<typeof createTRPCClient<AppRouter>> | null = null; +let queryClient: QueryClient | null = null; +let currentSettings: { + address: string; + apiKey: string; + badgeCacheExpireMs: number; + useBadgeCache: boolean; +} | null = null; + +export async function initializeClients() { + const { address, apiKey, badgeCacheExpireMs, useBadgeCache } = + await getPluginSettings(); + + if (currentSettings) { + const addressChanged = currentSettings.address !== address; + const apiKeyChanged = currentSettings.apiKey !== apiKey; + const cacheTimeChanged = + currentSettings.badgeCacheExpireMs !== badgeCacheExpireMs; + const useBadgeCacheChanged = + currentSettings.useBadgeCache !== useBadgeCache; + + if (!address || !apiKey) { + // Invalid configuration, clean + const persisterForCleanup = createChromeStorage(); + await persisterForCleanup.removeClient(); + cleanupApiClient(); + return; + } + + if (addressChanged || apiKeyChanged) { + // Switch context completely → discard the old instance and wipe persisted cache + const persisterForCleanup = createChromeStorage(); + await persisterForCleanup.removeClient(); + cleanupApiClient(); + } else if ((cacheTimeChanged || useBadgeCacheChanged) && queryClient) { + // Change the cache policy only → Clean up the data, but reuse the instance + queryClient.clear(); + } + + // If there is already existing and there is no major change in settings, reuse it + if ( + queryClient && + apiClient && + currentSettings && + !addressChanged && + !apiKeyChanged && + !cacheTimeChanged && + !useBadgeCacheChanged + ) { + return; + } + } + + if (address && apiKey) { + // Store current settings + currentSettings = { address, apiKey, badgeCacheExpireMs, useBadgeCache }; + + // Create new QueryClient with updated settings + queryClient = new QueryClient(); + + const persister = createChromeStorage(); + if (useBadgeCache) { + persistQueryClient({ + queryClient, + persister, + // Avoid restoring very old data and bust on policy changes + maxAge: badgeCacheExpireMs * 2, + buster: `badge:${address}:${badgeCacheExpireMs}`, + }); + } else { + // Ensure disk cache is cleared when caching is disabled + await persister.removeClient(); + } + + apiClient = createTRPCClient<AppRouter>({ + links: [ + httpBatchLink({ + url: `${address}/api/trpc`, + headers() { + return { + Authorization: `Bearer ${apiKey}`, + }; + }, + transformer: superjson, + }), + ], + }); + } +} + +export async function getApiClient() { + if (!apiClient) { + await initializeClients(); + } + return apiClient; +} + +export async function getQueryClient() { + // Check if settings have changed and reinitialize if needed + await initializeClients(); + return queryClient; +} + +export function cleanupApiClient() { + apiClient = null; + queryClient = null; + currentSettings = null; +} |
