first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,81 @@
# 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<BunDriverResult>`
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<void>; // 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.