From db16010f1bab2384dffe56a4bfc6bf0b6f85ab5a Mon Sep 17 00:00:00 2001 From: Yuri Tatishchev Date: Thu, 5 Feb 2026 04:45:06 -0800 Subject: [PATCH] succuess pt. 10 fix ssr on preview and prod builds --- src/lib/db/client-db/index.ts | 47 ++++++++++++++++++++++----- src/lib/db/client-db/seed.ts | 4 ++- src/routes/+page.svelte | 4 ++- src/routes/anime/[annId]/+page.svelte | 3 +- 4 files changed, 46 insertions(+), 12 deletions(-) diff --git a/src/lib/db/client-db/index.ts b/src/lib/db/client-db/index.ts index 222bd80..4922dbe 100644 --- a/src/lib/db/client-db/index.ts +++ b/src/lib/db/client-db/index.ts @@ -2,19 +2,48 @@ export * from "./queries"; export * from "./seed"; import { drizzle } from "drizzle-orm/sqlite-proxy"; -import { SQLocalDrizzle } from "sqlocal/drizzle"; - -const { driver, batchDriver, overwriteDatabaseFile } = new SQLocalDrizzle( - "database.sqlite3", -); - -export const db = drizzle(driver, batchDriver); +import { browser } from "$app/environment"; /** * Concrete client DB type (SQLocal-backed Drizzle via sqlite-proxy). * Exported to allow query helpers to accept the specific type without * creating circular type references. */ -export type ClientDb = typeof db; +export type ClientDb = ReturnType; -export { overwriteDatabaseFile }; +type ClientDbHolder = { + db: ClientDb; + overwriteDatabaseFile: ( + input: ReadableStream | Blob | Uint8Array, + ) => Promise; +}; + +let holder: ClientDbHolder | null = null; + +/** + * Lazily create the SQLocal-backed Drizzle DB. + * Must only be called in the browser (Workers SSR does not provide `BroadcastChannel`). + */ +export async function getClientDb(): Promise { + if (!browser) { + throw new Error( + "Client DB is only available in the browser (SSR is not supported).", + ); + } + + if (holder) return holder; + + // Dynamic import keeps SQLocal (and its browser-only APIs) out of SSR evaluation. + const { SQLocalDrizzle } = await import("sqlocal/drizzle"); + + const { driver, batchDriver, overwriteDatabaseFile } = new SQLocalDrizzle( + "database.sqlite3", + ); + + holder = { + db: drizzle(driver, batchDriver), + overwriteDatabaseFile, + }; + + return holder; +} diff --git a/src/lib/db/client-db/seed.ts b/src/lib/db/client-db/seed.ts index 7499e8e..a5c8145 100644 --- a/src/lib/db/client-db/seed.ts +++ b/src/lib/db/client-db/seed.ts @@ -1,6 +1,6 @@ import { browser } from "$app/environment"; import { asset } from "$app/paths"; -import { overwriteDatabaseFile } from "$lib/db/client-db"; +import { getClientDb } from "$lib/db/client-db"; /** * Version-keyed seeding for the client-side SQLocal database. @@ -64,6 +64,8 @@ export async function ensureSeeded( } // Prefer streaming when possible. + const { overwriteDatabaseFile } = await getClientDb(); + if (res.body) { await overwriteDatabaseFile(res.body); } else { diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index eacf976..de249df 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -3,9 +3,9 @@ import { useSearchParams } from "runed/kit"; import { onMount } from "svelte"; import { - db, ensureSeeded, getAnimeList, + getClientDb, searchAnimeByName, } from "$lib/db/client-db"; import { AmqBrowseSearchSchema } from "$lib/types/search/amq-browse"; @@ -34,6 +34,8 @@ try { isSearching = true; + const { db } = await getClientDb(); + if (!q) { anime = await getAnimeList(db, 20); } else { diff --git a/src/routes/anime/[annId]/+page.svelte b/src/routes/anime/[annId]/+page.svelte index f89b6f3..357e7f5 100644 --- a/src/routes/anime/[annId]/+page.svelte +++ b/src/routes/anime/[annId]/+page.svelte @@ -1,7 +1,7 @@