File size: 2,925 Bytes
88c4c60 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | import { ensureDirs, DATA_FILE } from "./paths.js";
// Use global to survive Next.js dev hot-reload (module state resets on reload)
if (!global._dbAdapter) global._dbAdapter = { instance: null, initPromise: null, logged: false };
const state = global._dbAdapter;
async function tryBunSqlite() {
// Bun runtime only β built-in, no install needed
if (!process.versions.bun) return null;
try {
const { createBunSqliteAdapter } = await import("./adapters/bunSqliteAdapter.js");
return await createBunSqliteAdapter(DATA_FILE);
} catch (e) {
console.warn(`[DB] bun:sqlite unavailable: ${e.message}`);
return null;
}
}
async function tryBetterSqlite() {
// Skip on Bun β better-sqlite3 native bindings unsupported
if (process.versions.bun) return null;
try {
const { createBetterSqliteAdapter } = await import("./adapters/betterSqliteAdapter.js");
return createBetterSqliteAdapter(DATA_FILE);
} catch (e) {
console.warn(`[DB] better-sqlite3 unavailable: ${e.message}`);
return null;
}
}
async function tryNodeSqlite() {
// Built-in since Node 22.5.0 β no install needed. Skip under Bun (no node:sqlite).
if (process.versions.bun) return null;
const [maj, min] = process.versions.node.split(".").map(Number);
if (maj < 22 || (maj === 22 && min < 5)) return null;
try {
const { createNodeSqliteAdapter } = await import("./adapters/nodeSqliteAdapter.js");
return await createNodeSqliteAdapter(DATA_FILE);
} catch (e) {
console.warn(`[DB] node:sqlite unavailable: ${e.message}`);
return null;
}
}
async function trySqlJs() {
try {
const { createSqlJsAdapter } = await import("./adapters/sqljsAdapter.js");
return await createSqlJsAdapter(DATA_FILE);
} catch (e) {
console.warn(`[DB] sql.js unavailable: ${e.message}`);
return null;
}
}
async function initAdapter() {
ensureDirs();
// Order per runtime:
// Bun: bun:sqlite β sql.js
// Node: better-sqlite3 β node:sqlite (β₯22.5) β sql.js
let adapter = await tryBunSqlite();
if (!adapter) adapter = await tryBetterSqlite();
if (!adapter) adapter = await tryNodeSqlite();
if (!adapter) adapter = await trySqlJs();
if (!adapter) throw new Error("[DB] No SQLite driver available (bun/better/node/sql.js all failed)");
if (!state.logged) {
console.log(`[DB] Driver: ${adapter.driver} | file: ${DATA_FILE}`);
state.logged = true;
}
const { runMigrationOnce } = await import("./migrate.js");
await runMigrationOnce(adapter);
return adapter;
}
export async function getAdapter() {
if (state.instance) return state.instance;
if (!state.initPromise) state.initPromise = initAdapter().then((a) => { state.instance = a; return a; });
return state.initPromise;
}
export function getAdapterSync() {
if (!state.instance) throw new Error("[DB] adapter not initialized β await getAdapter() first");
return state.instance;
}
|