# bun-driver ## Purpose Provides `createBunDriver`, the server-side SQLite driver for `@suaveplan/db-sqlite`. It dynamically imports `bun:sqlite` (a built-in Bun module) and returns a thin wrapper holding the raw `Database` instance plus an idempotent `close()` function. The `isBunEnvironment()` guard ensures the driver is never accidentally called in a browser context — doing so raises `SQLITE.ENVIRONMENT_ERROR` immediately rather than surfacing a confusing module-not-found error at import time. The dynamic `import("bun:sqlite")` pattern keeps the module evaluatable in non-Bun environments (so bundlers can tree-shake it out and browser builds do not fail), while still providing full type information from `@types/bun`. ## Features - `createBunDriver(options?)` — opens an in-memory (default) or file-backed SQLite database via `bun:sqlite` - `isBunEnvironment()` — detects Bun runtime via `process.versions.bun` - `BunDriverResult` — `{ sqlite, close }` shape; `close()` is idempotent (safe to call multiple times) - Throws `SqliteError(SQLITE.ENVIRONMENT_ERROR)` when called outside Bun - Throws `SqliteError(SQLITE.DRIVER_INIT_FAILED)` if `Database` constructor throws (e.g. bad path, locked file) - `readonly` option forwarded to `bun:sqlite` `Database` constructor ## Usage: Basic Example ```ts import { createBunDriver } from "@suaveplan/db-sqlite/drivers/bun-driver"; const { sqlite, close } = await createBunDriver(); // sqlite is a bun:sqlite Database instance — run raw SQL or pass to Drizzle await close(); ``` ## Usage: Advanced Example ```ts import { createBunDriver, isBunEnvironment } from "@suaveplan/db-sqlite/drivers/bun-driver"; if (!isBunEnvironment()) { throw new Error("Server-side only path"); } const { sqlite, close } = await createBunDriver({ filename: "/data/app.db", readonly: false, }); try { sqlite.run("CREATE TABLE IF NOT EXISTS kv (key TEXT PRIMARY KEY, value TEXT)"); sqlite.run("INSERT OR REPLACE INTO kv VALUES (?, ?)", ["hello", "world"]); } finally { await close(); // second call is a no-op await close(); // safe } ``` ## API Reference ### `isBunEnvironment(): boolean` Returns `true` when `process.versions.bun` is defined. Safe to call in any environment. ### `createBunDriver(options?: BunDriverOptions): Promise` Opens a SQLite database. Throws `SqliteError(SQLITE.ENVIRONMENT_ERROR)` outside Bun, `SqliteError(SQLITE.DRIVER_INIT_FAILED)` on open failure. **Parameters** | Name | Type | Default | Description | |------|------|---------|-------------| | `options.filename` | `string` | `":memory:"` | File path or `":memory:"` | | `options.readonly` | `boolean` | `false` | Open in read-only mode | ### `BunDriverResult` ```ts interface BunDriverResult { sqlite: Database; // bun:sqlite Database instance close: () => Promise; // idempotent — safe to call multiple times } ``` ## Implementation Notes `close()` sets a `closed` flag so repeated calls are no-ops rather than throwing "database already closed". This is intentional: callers cleaning up in `finally` blocks should not have to track whether they already closed. The `bun:sqlite` import is deferred via `await import("bun:sqlite")` inside the function body so that bundlers processing non-Bun targets (e.g. a Vite browser build) can externalize or ignore the module without causing a build error at parse time. The `isBunEnvironment()` guard before the import provides an early exit in the rare case this driver is invoked in a test environment that stubs the process object.