import { Kysely } from 'kysely'; import type { Database } from './schema.js'; import type { BatchTarget, BatchStatement } from './batch.js'; import type { D1DatabaseLike } from './dialects/d1.js'; /** * Where Taproot's data lives. One dialect, two drivers: `node:sqlite` locally, D1 in production. * * **Not two dialects.** Both go through Kysely's `SqliteQueryCompiler`, so the SQL is byte-identical * and there is no branch anywhere in query building — what differs is the driver underneath (a real * transaction here, `batch()` there; see `batchWrite`). That is why the local driver is not a * portability layer and dropping it would buy nothing: 31 test files and every CLI script run on it, * and workerd has no `node:sqlite`, which is exactly why dev renders on Node. * * A Postgres driver was wired here from Phase 0 and removed once it was clear nothing tested it, * nothing documented it, and no deployment used it — while the *promise* of it was what ruled out * FTS5 for search (`0021_item_text`), since a second real dialect means two index implementations * that have to agree. Committing to Cloudflare is what bought real ranking; see `0025_item_text_fts`. */ export type DbConfig = { driver: 'sqlite'; location: string; } | { driver: 'd1'; database: D1DatabaseLike; }; export type DbDriver = DbConfig['driver']; /** * A live database handle. * * Carries the D1 binding alongside the Kysely instance so `batch()` can reach the native atomic * batch when running on D1 — see `batchWrite` for why atomic writes are expressed as statement * lists rather than transaction callbacks. */ export interface TaprootDb extends BatchTarget { readonly db: Kysely; readonly d1?: D1DatabaseLike; readonly driver: DbDriver; /** Run statements atomically on whichever backend is configured. */ batch(statements: BatchStatement[]): Promise; destroy(): Promise; } /** * Create a database handle from configuration. * * Dialect modules are loaded by dynamic import so that a bundle built for one target never pulls * in another's driver — the Workers bundle must not reach `node:sqlite`, and Node must not reach * the D1 binding types. */ export declare function createDb(config: DbConfig): Promise; /** * Build a `DbConfig` from environment variables. * * Precedence is deliberate: an explicit D1 binding always wins, because in a Workers deployment * the binding is the only thing that can work. Everything else falls back to a local SQLite file so * `npm run dev` needs no configuration. */ export declare function dbConfigFromEnv(env: Record, bindings?: { DB?: D1DatabaseLike; }): DbConfig;