Select the types of activity you want to include in your feed.
fix(db): use @libsql/client/web for remote Turso on Linux/deploy
Avoid native @libsql/linux-x64-gnu bindings that break under Deno Deploy's Node compat layer. file: URLs still use the full client in dev only (import.meta.env.DEV).
···50505. **Run command:** `deno task start` (or `deno serve -A _fresh/server.js` per
5151 `deno.json`).
52525353+Remote Turso (`libsql://…`) uses `@libsql/client/web` so the deploy runtime does
5454+not need native `@libsql/*` platform binaries. Local `file:./local.db` still
5555+uses the full client when running `deno task dev`.
5656+5357Adjust if your host uses different entrypoints.
54585559## Contributing
+42-9
lib/db.ts
···99 *
1010 * If TURSO_DATABASE_URL is unset the client falls back to file:./local.db
1111 * so `deno task dev` works without configuration.
1212+ *
1313+ * **Deploy note:** The default `@libsql/client` entry pulls native bindings
1414+ * (`@libsql/linux-x64-gnu`, etc.) that break on Linux/serverless when the
1515+ * bundle was resolved for another OS. Remote Turso URLs use
1616+ * `@libsql/client/web` (HTTP only, no natives). Local `file:` URLs still
1717+ * use the full client in dev only.
1218 */
1313-import { type Client, createClient } from "@libsql/client";
1919+import type { Client } from "@libsql/client/web";
14201521let _client: Client | null = null;
2222+let _clientPromise: Promise<Client> | null = null;
1623let _migrated = false;
1724let _migrationPromise: Promise<void> | null = null;
1825···2431 }
2532}
26332727-export function db(): Client {
2828- if (_client) return _client;
2929- const url = getEnv("TURSO_DATABASE_URL") ?? "file:./local.db";
3030- const authToken = getEnv("TURSO_AUTH_TOKEN");
3131- _client = createClient({ url, authToken });
3232- return _client;
3434+function resolveDbUrl(): string {
3535+ return getEnv("TURSO_DATABASE_URL") ?? "file:./local.db";
3636+}
3737+3838+/**
3939+ * Production / `deno task start` must not load the native libsql binary; only
4040+ * the web client. Vite sets import.meta.env.DEV in dev; omitting env is
4141+ * treated as production (Deploy).
4242+ */
4343+function shouldLoadNativeFileClient(url: string): boolean {
4444+ if (!url.startsWith("file:")) return false;
4545+ return import.meta.env?.DEV === true;
4646+}
4747+4848+function getClient(): Promise<Client> {
4949+ if (_client) return Promise.resolve(_client);
5050+ if (!_clientPromise) {
5151+ _clientPromise = (async () => {
5252+ const url = resolveDbUrl();
5353+ const authToken = getEnv("TURSO_AUTH_TOKEN");
5454+ if (shouldLoadNativeFileClient(url)) {
5555+ const { createClient } = await import("@libsql/client");
5656+ _client = createClient({ url, authToken }) as unknown as Client;
5757+ return _client;
5858+ }
5959+ const { createClient } = await import("@libsql/client/web");
6060+ _client = createClient({ url, authToken });
6161+ return _client;
6262+ })();
6363+ }
6464+ return _clientPromise;
3365}
34663567const SCHEMA_STATEMENTS: string[] = [
···111143 if (_migrated) return Promise.resolve();
112144 if (_migrationPromise) return _migrationPromise;
113145 _migrationPromise = (async () => {
114114- const c = db();
146146+ const c = await getClient();
115147 for (const stmt of SCHEMA_STATEMENTS) {
116148 await c.execute(stmt);
117149 }
···123155/** Convenience: ensure schema is in place before running a callback. */
124156export async function withDb<T>(fn: (c: Client) => Promise<T>): Promise<T> {
125157 await migrate();
126126- return fn(db());
158158+ const c = await getClient();
159159+ return fn(c);
127160}