// Runtime adapter for SQLite — works under both Bun and Node. // // - Bun: uses built-in `bun:sqlite` // - Node: uses `better-sqlite3` // // The interfaces are intentionally tiny so the wrapping cost is minimal. export interface Statement { run(...params: unknown[]): { lastInsertRowid: number | bigint; changes: number }; get(...params: unknown[]): unknown; all(...params: unknown[]): unknown[]; } export interface DbHandle { exec(sql: string): void; prepare(sql: string): Statement; close(): void; } export async function openDatabase(path: string): Promise { // Bun runtime check. // eslint-disable-next-line @typescript-eslint/no-explicit-any const isBun = typeof (globalThis as any).Bun !== "undefined"; if (isBun) { const mod = await import("bun:sqlite"); return new BunAdapter(new mod.Database(path)); } // Node runtime. const mod = await import("better-sqlite3"); const DbCtor = (mod as unknown as { default: new (p: string) => unknown }).default; return new BetterAdapter(new (DbCtor as new (p: string) => unknown)(path) as unknown as BetterLike); } // ── Bun adapter ──────────────────────────────────────────────────────────── interface BunStmt { run(...params: unknown[]): { lastInsertRowid: number | bigint; changes: number }; get(...params: unknown[]): unknown; all(...params: unknown[]): unknown[]; } interface BunDb { exec(sql: string): void; prepare(sql: string): BunStmt; close(): void; } class BunAdapter implements DbHandle { constructor(private db: BunDb) {} exec(sql: string): void { this.db.exec(sql); } prepare(sql: string): Statement { return this.db.prepare(sql); } close(): void { this.db.close(); } } // ── better-sqlite3 adapter ────────────────────────────────────────────────── interface BetterStmt { run(...params: unknown[]): { lastInsertRowid: number | bigint; changes: number }; get(...params: unknown[]): unknown; all(...params: unknown[]): unknown[]; } interface BetterLike { exec(sql: string): void; prepare(sql: string): BetterStmt; pragma(s: string): unknown; close(): void; } class BetterAdapter implements DbHandle { constructor(private db: BetterLike) { this.db.pragma("journal_mode = WAL"); } exec(sql: string): void { this.db.exec(sql); } prepare(sql: string): Statement { return this.db.prepare(sql); } close(): void { this.db.close(); } }