db.ts 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. /**
  2. * db.ts - Cross-runtime SQLite compatibility layer
  3. *
  4. * Provides a unified Database export that works under both Bun (bun:sqlite)
  5. * and Node.js (better-sqlite3). The APIs are nearly identical — the main
  6. * difference is the import path.
  7. */
  8. export const isBun = typeof globalThis.Bun !== "undefined";
  9. let _Database: any;
  10. let _sqliteVecLoad: (db: any) => void;
  11. if (isBun) {
  12. // Dynamic string prevents tsc from resolving bun:sqlite on Node.js builds
  13. const bunSqlite = "bun:" + "sqlite";
  14. _Database = (await import(/* @vite-ignore */ bunSqlite)).Database;
  15. const { getLoadablePath } = await import("sqlite-vec");
  16. _sqliteVecLoad = (db: any) => db.loadExtension(getLoadablePath());
  17. } else {
  18. _Database = (await import("better-sqlite3")).default;
  19. const sqliteVec = await import("sqlite-vec");
  20. _sqliteVecLoad = (db: any) => sqliteVec.load(db);
  21. }
  22. /**
  23. * Open a SQLite database. Works with both bun:sqlite and better-sqlite3.
  24. */
  25. export function openDatabase(path: string): Database {
  26. return new _Database(path) as Database;
  27. }
  28. /**
  29. * Common subset of the Database interface used throughout QMD.
  30. */
  31. export interface Database {
  32. exec(sql: string): void;
  33. prepare(sql: string): Statement;
  34. loadExtension(path: string): void;
  35. close(): void;
  36. }
  37. export interface Statement {
  38. run(...params: any[]): { changes: number; lastInsertRowid: number | bigint };
  39. get(...params: any[]): any;
  40. all(...params: any[]): any[];
  41. }
  42. /**
  43. * Load the sqlite-vec extension into a database.
  44. */
  45. export function loadSqliteVec(db: Database): void {
  46. _sqliteVecLoad(db);
  47. }