mirror of
https://github.com/jakejarvis/sofa.git
synced 2026-08-29 05:05:38 -04:00
Switch from Node.js + pnpm to Bun runtime and package manager
Replace @libsql/client with bun:sqlite for zero-dependency SQLite access, swap drizzle-orm/libsql adapter for drizzle-orm/bun-sqlite, and rewrite Dockerfile to use oven/bun:1-alpine. The raw Database instance is no longer exported via Proxy (native C++ methods lose `this` binding through Reflect.get); instead, a closeDatabase() helper handles graceful shutdown and the health check uses Drizzle's db.run() directly. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
+25
-16
@@ -1,23 +1,34 @@
|
||||
import { createClient } from "@libsql/client";
|
||||
import { drizzle } from "drizzle-orm/libsql";
|
||||
import { Database } from "bun:sqlite";
|
||||
import path from "node:path";
|
||||
import { drizzle } from "drizzle-orm/bun-sqlite";
|
||||
import * as schema from "./schema";
|
||||
|
||||
// Lazy-init singleton via globalThis. Next.js evaluates module-level code at
|
||||
// build time (when no database exists) and re-imports modules on HMR in dev
|
||||
// (which would create duplicate connections). Stashing the instances on
|
||||
// globalThis and wrapping `db` in a Proxy defers all real work to the first
|
||||
// property access at runtime, sidestepping both problems.
|
||||
//
|
||||
// Only the Drizzle instance (`db`) is exported as a Proxy — the raw bun:sqlite
|
||||
// Database is kept internal because its native C++ methods lose their `this`
|
||||
// binding when accessed through Reflect.get, so a Proxy around it would break.
|
||||
// Use `closeDatabase()` for graceful shutdown instead.
|
||||
|
||||
const globalForDb = globalThis as unknown as {
|
||||
_db: ReturnType<typeof drizzle> | undefined;
|
||||
_client: ReturnType<typeof createClient> | undefined;
|
||||
_client: Database | undefined;
|
||||
};
|
||||
|
||||
const DATA_DIR = process.env.DATA_DIR || "./data";
|
||||
const DATABASE_URL = process.env.DATABASE_URL || `file:${DATA_DIR}/sqlite.db`;
|
||||
const DATABASE_URL =
|
||||
process.env.DATABASE_URL ||
|
||||
path.join(process.env.DATA_DIR || "./data", "sqlite.db");
|
||||
|
||||
function getClient() {
|
||||
if (!globalForDb._client) {
|
||||
globalForDb._client = createClient({
|
||||
url: DATABASE_URL,
|
||||
});
|
||||
globalForDb._client.execute("PRAGMA journal_mode = WAL");
|
||||
globalForDb._client.execute("PRAGMA foreign_keys = ON");
|
||||
globalForDb._client.execute("PRAGMA busy_timeout = 5000");
|
||||
globalForDb._client = new Database(DATABASE_URL);
|
||||
globalForDb._client.run("PRAGMA journal_mode = WAL");
|
||||
globalForDb._client.run("PRAGMA foreign_keys = ON");
|
||||
globalForDb._client.run("PRAGMA busy_timeout = 5000");
|
||||
}
|
||||
return globalForDb._client;
|
||||
}
|
||||
@@ -35,8 +46,6 @@ export const db = new Proxy({} as ReturnType<typeof drizzle>, {
|
||||
},
|
||||
});
|
||||
|
||||
export const client = new Proxy({} as ReturnType<typeof createClient>, {
|
||||
get(_, prop) {
|
||||
return Reflect.get(getClient(), prop);
|
||||
},
|
||||
});
|
||||
export function closeDatabase() {
|
||||
globalForDb._client?.close();
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,8 +1,8 @@
|
||||
import { migrate } from "drizzle-orm/libsql/migrator";
|
||||
import { migrate } from "drizzle-orm/bun-sqlite/migrator";
|
||||
import { db } from "./client";
|
||||
|
||||
export async function runMigrations() {
|
||||
export function runMigrations() {
|
||||
console.log("[migrate] Running database migrations...");
|
||||
await migrate(db, { migrationsFolder: "./drizzle" });
|
||||
migrate(db, { migrationsFolder: "./drizzle" });
|
||||
console.log("[migrate] Database migrations complete");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user