| import { ensureDirs, DATA_FILE } from "./paths.js"; |
|
|
| |
| if (!global._dbAdapter) global._dbAdapter = { instance: null, initPromise: null, logged: false }; |
| const state = global._dbAdapter; |
|
|
| async function tryBunSqlite() { |
| |
| 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() { |
| |
| 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() { |
| |
| 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(); |
| |
| |
| |
| 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; |
| } |
|
|