/** * Abstract SQLite interface to decouple SessionStore from a specific SQLite * binding. Enables Bun standalone binary builds (bun:sqlite) and modern * Node.js (node:sqlite) while preserving the existing better-sqlite3 path as * a fallback for older Node runtimes that lack a built-in SQLite module. * * Three implementations: * - NodeBuiltinSqliteAdapter — wraps node:sqlite (Node >= 22.5, zero deps) * - NodeSqliteAdapter — wraps better-sqlite3 (legacy Node fallback) * - BunSqliteAdapter — wraps bun:sqlite (Bun built-in, zero deps) * * The factory `createSqliteAdapter()` detects the runtime and returns the * correct adapter. Callers (SessionStore) only interact with the `SqliteAdapter` * interface — they never import better-sqlite3, node:sqlite or bun:sqlite * directly. */ /** Result shape from statement.run(). Matches both better-sqlite3 and bun:sqlite. */ export interface SqliteRunResult { changes: number; } /** * Typed prepared statement. Params is a tuple of bound parameter types; * Row is the returned row shape for .all() and .get(). */ export interface SqliteStatement { all(...params: Params): Row[]; get(...params: Params): Row | undefined; run(...params: Params): SqliteRunResult; /** * Lazy row iterator used by the Node adapter's `queryAll` to page large * result sets without materializing them in one native `stmt.all()` call. * Bun statements do not expose a compatible iterator; implementations may * omit it and callers must fall back to `all`. */ iterate?(...params: Params): IterableIterator; } /** Full SQLite adapter. Mirrors the better-sqlite3 API surface used by SessionStore. */ export interface SqliteAdapter { prepare(sql: string): SqliteStatement; /** * Off-main-thread query path used by the relay REST dispatcher. * * Node/better-sqlite3 is synchronous at the native layer, so this wraps * the query in a `setImmediate` trampoline that yields to the event loop * BEFORE executing the query. This is intentionally a yield rather than a * worker-thread offload: it does not remove CPU cost, but it prevents a * queue of relay requests from being serialized into one uninterrupted * blocking burst, which was what caused each queued request to miss the * backend's 30s timeout. * * Bun does not expose an equivalent promise-based query API, so the Bun * adapter falls back to the synchronous `prepare(...).all(...)` path. * That keeps the same wire shapes and lets Bun builds remain dependency * free. */ queryAll(sql: string, ...params: unknown[]): Promise; /** * Node-only paged query path. `queryAll` uses this when the statement * exposes a lazy iterator so large result sets are read in bounded chunks * with an event-loop yield between chunks. Bun has no compatible iterator * and falls back to the existing synchronous `all()` trampoline. */ queryAllPaged(sql: string, pageSize: number, ...params: unknown[]): Promise; exec(sql: string): void; pragma(sql: string): void; transaction(fn: () => T): () => T; close(): void; } /** * Create a SQLite adapter for the given filesystem path. Auto-detects the * runtime (Bun → bun:sqlite, Node >= 22.5 → node:sqlite, older Node → * better-sqlite3) and returns the matching implementation. */ export declare function createSqliteAdapter(path: string): SqliteAdapter; //# sourceMappingURL=sqlite-adapter.d.ts.map