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,113 @@
# adapter
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs --> - adapter.wasm — Browser-runtime entry point for the……
- [adapter.wasm](./adapter.wasm.md) — Browser-runtime entry point for the `./adapter` conditional export in `@suaveplan/db-sqlite`. When a browser bundler re…
- adapter.wasm — Browser-runtime entry point for the……
- [adapter.wasm](./adapter.wasm.md) — Browser-runtime entry point for the `./adapter` conditional export in `@suaveplan/db-sqlite`. When a browser bundler re…
- adapter.wasm — Browser-runtime entry point for the……
- [adapter.wasm](./adapter.wasm.md) — Browser-runtime entry point for the `./adapter` conditional export in `@suaveplan/db-sqlite`. When a browser bundler re…
- adapter.wasm — Browser-runtime entry point for the…
- [adapter.wasm](./adapter.wasm.md) — Browser-runtime entry point for the `./adapter` conditional export in `@suaveplan/db-sqlite`. When a browser bundler re…
- [adapter.wasm](./adapter.wasm.md) — Browser-runtime entry point for the `./adapter` conditional export in `@suaveplan/db-sqlite`. When a browser bundler re…
## Purpose
`SqliteAdapter` is the main `DatabaseAdapter` implementation for `@suaveplan/db-sqlite`. It implements the full `DatabaseAdapter` contract from `@suaveplan/db`, backing it with a `bun:sqlite` database instance, an LRU `PreparedStatementCache`, a `MigrationRunner`, and OTel span instrumentation on every public operation.
The adapter is designed for the Bun server runtime only. Attempting to construct it outside Bun throws `SqliteError(SQLITE.ENVIRONMENT_ERROR)` immediately. Browser callers should use `createWasmDriver` directly via the `./adapter` conditional export, which resolves to `adapter.wasm.ts` in browser bundles.
## Features
- Implements `DatabaseAdapter` from `@suaveplan/db` — fully substitutable wherever `DatabaseLike` is expected
- Idempotent `connect()` — concurrent callers share one in-flight connection promise
- `PreparedStatementCache` (LRU, default 128 entries) reused across `query()` calls
- `transaction()` uses `BEGIN IMMEDIATE` to prevent deadlocks on concurrent writes; auto-rollback on failure
- `migrate()` delegates to `MigrationRunner` and invalidates the cache on success
- `AbortSignal` respected on every public method — throws `SqliteError(SQLITE.*)` when aborted
- All operations wrapped in `withQuerySpan` for OTel tracing and latency metrics
- `sideEffects: false` — safe for tree-shaking
## Usage: Basic Example
```ts
import { SqliteAdapter } from "@suaveplan/db-sqlite";
const adapter = new SqliteAdapter({ filename: ":memory:" });
await adapter.connect();
const rows = await adapter.query<{ id: number }>(
"SELECT id FROM users WHERE active = ?",
[1]
);
await adapter.disconnect();
```
## Usage: Advanced Example
```ts
import { SqliteAdapter } from "@suaveplan/db-sqlite";
const adapter = new SqliteAdapter({ filename: "/data/app.db" });
await adapter.connect();
// Transactional insert
await adapter.transaction(async (tx) => {
await tx.execute("INSERT INTO accounts VALUES (?, ?)", [1, "Alice"]);
await tx.execute("INSERT INTO accounts VALUES (?, ?)", [2, "Bob"]);
});
// Run migrations
const result = await adapter.migrate({
migrationsFolder: "./db/migrations",
});
console.log(`Applied ${result.applied} migration(s)`);
await adapter.disconnect();
```
## API Reference
### `new SqliteAdapter(options?, schema?)`
Validates options, throws `SqliteError(SQLITE.ENVIRONMENT_ERROR)` outside Bun.
### `connect(config?, opts?): Promise<void>`
Opens the SQLite file or `:memory:` database. Idempotent under concurrent calls — only one connection is opened.
### `disconnect(opts?): Promise<void>`
Closes the database, invalidates the prepared-statement cache, and resets connection state.
### `query<T>(sql, params?, opts?): Promise<T[]>`
Executes a `SELECT` query. Uses the prepared-statement cache for repeated SQL strings.
### `execute(sql, params?, opts?): Promise<{ rowsAffected: number }>`
Executes a `INSERT`/`UPDATE`/`DELETE` statement. Returns affected row count.
### `transaction<T>(fn, opts?): Promise<T>`
Runs `fn` inside a `BEGIN IMMEDIATE` transaction. Commits on success, rolls back on failure.
### `migrate(config?, opts?): Promise<MigrationResult>`
Delegates to `MigrationRunner` and invalidates the prepared-statement cache on success.
### `isConnected: boolean`
`true` after `connect()` and before `disconnect()`.
## Implementation Notes
The `_connectingPromise` field serialises concurrent `connect()` calls — the second caller awaits the same in-flight promise rather than opening a second connection. This is safe because `bun:sqlite` uses synchronous I/O under the covers and does not support concurrent connections to the same file.
`transaction()` casts `this` to `DatabaseLike` when passing it to `fn`. This is sound because `SqliteAdapter` implements all `DatabaseLike` methods. The cast avoids exposing internal `_sqlite` state to transaction callbacks while keeping the type constraint tight.