@vibeorm/adapter-sqlite 2.0.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,86 @@
1
+ # @vibeorm/adapter-sqlite
2
+
3
+ > Part of **[VibeORM](https://github.com/vibeorm/vibeorm)** — a type-safe TypeScript ORM for Bun and Node. Prisma-schema or TypeScript-DSL input, a canonical schema IR, a generated client, and a dialect-aware SQL layer over PostgreSQL, PGlite, SQLite and MySQL.
4
+
5
+ SQLite adapter built on `bun:sqlite`, the embedded SQLite driver that ships inside Bun. There is no driver to install, and the package runs on Bun only; on Node use [`@vibeorm/adapter-better-sqlite3`](https://github.com/vibeorm/vibeorm/tree/master/packages/adapter-better-sqlite3), which speaks the same dialect with the same semantics.
6
+
7
+ ```bash
8
+ bun add @vibeorm/adapter-sqlite@alpha
9
+ ```
10
+
11
+ > **Pre-release.** `2.0.0-alpha.x`, published under the `alpha` dist-tag. `npm i vibeorm` still resolves to the stable v1 line.
12
+
13
+ ## Usage
14
+
15
+ ```ts
16
+ import { VibeClient } from "./generated/vibeorm/index.js";
17
+ import { sqliteAdapter } from "@vibeorm/adapter-sqlite";
18
+
19
+ const db = VibeClient({ adapter: sqliteAdapter({ filename: "./app.db" }) });
20
+
21
+ const users = await db.user.findMany({ where: { email: { contains: "@example.com" } }, take: 10 });
22
+
23
+ await db.$disconnect();
24
+ ```
25
+
26
+ ## Options
27
+
28
+ `sqliteAdapter(options?: SqliteAdapterOptions)`
29
+
30
+ | Option | Type | Default | Meaning |
31
+ |---|---|---|---|
32
+ | `filename` | `string` | `":memory:"` | Database file to open. Ignored when `database` is injected. |
33
+ | `readonly` | `boolean` | `false` | Open the file read-only. Writes fail with `SQLITE_READONLY`, mapped to `VIBE_ADAPTER`. The WAL pragma is skipped. |
34
+ | `busyTimeoutMs` | `number` | `5000` | `PRAGMA busy_timeout` in milliseconds. Must be a non-negative integer, validated eagerly (`VIBE_VALIDATION`). |
35
+ | `wal` | `boolean` | `true` | Switch file databases to `PRAGMA journal_mode = WAL`. Skipped for in-memory, read-only and injected databases. |
36
+ | `database` | `Database` (from `bun:sqlite`) | — | Run on an already-open database. It is never closed (`disconnect()` is a no-op) and its journal mode is left alone; `PRAGMA foreign_keys = ON` is still applied. |
37
+
38
+ Every transaction opens with `BEGIN IMMEDIATE`, so the write lock is taken up front and a write after a read cannot deadlock on a lock upgrade. Nested transactions become savepoints, and a nested call that passes `isolationLevel` or `timeout` is refused with `VIBE_VALIDATION`.
39
+
40
+ Integers are read losslessly: the adapter enables `safeIntegers` on every statement it prepares, then normalizes rows so values inside ±(2^53−1) arrive as `number` and larger ones stay `bigint`.
41
+
42
+ ## Runtime support
43
+
44
+ Bun only (`engines.bun >= 1.2.0`) — `bun:sqlite` is a Bun built-in and does not exist on Node. For Node use `@vibeorm/adapter-better-sqlite3`, the Node-compatible sibling with identical semantics and the same error mapping.
45
+
46
+ ## Capabilities and limits
47
+
48
+ The sqlite dialect's capability table is frozen and mirrored by tests; the generated matrix lives in [`docs/dialects.md`](https://github.com/vibeorm/vibeorm/blob/master/docs/dialects.md). A feature the dialect cannot express throws `VibeError` code `VIBE_UNSUPPORTED_CAPABILITY` at the earliest knowable moment (generate, then build, then execute) — it never silently misbehaves.
49
+
50
+ Refused:
51
+
52
+ - `scalarArrays` — scalar list columns (`String[]`, `Int[]`, …) are rejected at generate and migrate time.
53
+ - `lateralJoin` — the `"join"` relation strategy is refused. Use the default `"query"` strategy.
54
+
55
+ Handled by a documented fallback instead of native support:
56
+
57
+ - Enums are stored as `TEXT` with a `CHECK` constraint.
58
+ - `mode: "insensitive"` renders `LOWER(x) LIKE LOWER(?)`; there is no native `ILIKE`.
59
+ - `distinct` keeps the first row per key client-side, in the query's row order (no `DISTINCT ON`).
60
+ - `Json` fields are stored as `TEXT`; JSON functions operate on that text.
61
+
62
+ Native: `RETURNING`, `createManyAndReturn`, partial indexes, transactional DDL, `NULLS FIRST`/`NULLS LAST`, and the `fts5` full-text engine.
63
+
64
+ Two SQLite semantics worth knowing: a plain `contains` is ASCII-case-insensitive, and Decimal comparisons/aggregates go through `CAST(col AS REAL)`, so they are float64-bounded. Both are documented in [`docs/dialect-notes.md`](https://github.com/vibeorm/vibeorm/blob/master/docs/dialect-notes.md).
65
+
66
+ Transaction `timeout` is refused with `VIBE_VALIDATION`: SQLite's `busy_timeout` bounds lock acquisition, not statement runtime, so the adapter says so instead of no-opping.
67
+
68
+ ## Error mapping
69
+
70
+ Driver errors are mapped through a frozen table keyed by the SQLite extended result-code name; only `VibeError` ever escapes, with the original error as `cause` and `{ code, errno }` in `meta`.
71
+
72
+ | SQLite result code | VibeError code |
73
+ |---|---|
74
+ | `SQLITE_CONSTRAINT_UNIQUE`, `SQLITE_CONSTRAINT_PRIMARYKEY`, `SQLITE_CONSTRAINT_ROWID` | `VIBE_UNIQUE_VIOLATION` |
75
+ | `SQLITE_CONSTRAINT_FOREIGNKEY` | `VIBE_FK_VIOLATION` |
76
+ | `SQLITE_CONSTRAINT_NOTNULL`, `SQLITE_CONSTRAINT_CHECK`, `SQLITE_CONSTRAINT_DATATYPE` | `VIBE_VALIDATION` |
77
+ | `SQLITE_BUSY` (+ `_SNAPSHOT`, `_RECOVERY`, `_TIMEOUT`), `SQLITE_LOCKED` (+ `_SHAREDCACHE`) | `VIBE_TRANSACTION`, `meta.reason: "busy"` |
78
+ | anything else | `VIBE_ADAPTER` |
79
+
80
+ ## Links
81
+
82
+ - [Documentation](https://github.com/vibeorm/vibeorm/tree/master/docs)
83
+ - [Getting started](https://github.com/vibeorm/vibeorm/blob/master/docs/getting-started.md)
84
+ - [Dialect capability tables](https://github.com/vibeorm/vibeorm/blob/master/docs/dialects.md)
85
+ - [Repository and issues](https://github.com/vibeorm/vibeorm)
86
+ - MIT licensed
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Driver-error mapping for `bun:sqlite`.
3
+ *
4
+ * bun:sqlite throws `SQLiteError` carrying the SQLite *extended* result-code
5
+ * name in `code` (e.g. `"SQLITE_CONSTRAINT_UNIQUE"`) and the numeric extended
6
+ * result code in `errno` (e.g. `2067`). Real shapes pinned against Bun 1.3.14:
7
+ *
8
+ * unique → code "SQLITE_CONSTRAINT_UNIQUE" errno 2067
9
+ * pk → code "SQLITE_CONSTRAINT_PRIMARYKEY" errno 1555
10
+ * notnull → code "SQLITE_CONSTRAINT_NOTNULL" errno 1299
11
+ * check → code "SQLITE_CONSTRAINT_CHECK" errno 275
12
+ * fk → code "SQLITE_CONSTRAINT_FOREIGNKEY" errno 787
13
+ * busy → code "SQLITE_BUSY" errno 5
14
+ *
15
+ * Constitution rule 5: only `VibeError` escapes the adapter.
16
+ */
17
+ import { VibeError, type VibeErrorCode } from "@vibeorm/schema";
18
+ /**
19
+ * SQLite extended result-code name → stable VibeError code. Frozen and
20
+ * mirrored by tests; anything absent from this table maps to `VIBE_ADAPTER`.
21
+ */
22
+ export declare const SQLITE_ERROR_CODES: Readonly<Record<string, VibeErrorCode>>;
23
+ /** Result codes that additionally explain themselves through `meta.reason`. */
24
+ export declare const SQLITE_ERROR_REASONS: Readonly<Record<string, string>>;
25
+ /**
26
+ * Extract the SQLite result-code name from a bun:sqlite error. Failures raised
27
+ * outside the database engine (a closed handle, a bad filename) may carry no
28
+ * `SQLITE_*` code and yield `undefined`.
29
+ */
30
+ export declare function sqliteErrorCode(params: {
31
+ error: unknown;
32
+ }): string | undefined;
33
+ /**
34
+ * Map any error thrown by bun:sqlite onto a `VibeError`.
35
+ *
36
+ * A `VibeError` passes through unchanged, so an error raised deeper inside the
37
+ * ORM (or by a nested adapter call) is never re-wrapped. Everything else keeps
38
+ * the original error as `cause` and carries `{ code, errno }` in `meta`.
39
+ */
40
+ export declare function mapSqliteDriverError(params: {
41
+ error: unknown;
42
+ }): VibeError;
43
+ /**
44
+ * Run a driver call, mapping anything it throws onto a `VibeError`. Synchronous
45
+ * because bun:sqlite is a synchronous driver — the adapter's async surface
46
+ * wraps results in already-resolved promises.
47
+ */
48
+ export declare function runMapped<T>(fn: () => T): T;
49
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,SAAS,EAAE,KAAK,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAIhE;;;GAGG;AACH,eAAO,MAAM,kBAAkB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CA2BrE,CAAC;AAEH,+EAA+E;AAC/E,eAAO,MAAM,oBAAoB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAOhE,CAAC;AAYH;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE;IAAE,KAAK,EAAE,OAAO,CAAA;CAAE,GAAG,MAAM,GAAG,SAAS,CAK9E;AAID;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE;IAAE,KAAK,EAAE,OAAO,CAAA;CAAE,GAAG,SAAS,CAsB1E;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAM3C"}
@@ -0,0 +1,105 @@
1
+ /**
2
+ * @vibeorm/adapter-sqlite — bun:sqlite (embedded SQLite) adapter for
3
+ * VibeORM v2.
4
+ *
5
+ * bun:sqlite is a *synchronous* single-connection driver, so every call
6
+ * completes without I/O waits and the adapter wraps results in
7
+ * already-resolved promises — the cheapest possible `execute`. Like PGlite,
8
+ * one connection means every operation runs through one serial queue:
9
+ * a whole `transaction()` holds the queue until it commits or rolls back, so
10
+ * concurrent client calls can never interleave into an open transaction.
11
+ *
12
+ * INTEGER WIDTH (the BigInt story): SQLite INTEGER columns are 64-bit, but JS
13
+ * numbers are only exact to ±(2^53−1) — a plain read of a large BigInt column
14
+ * silently corrupts (pinned on Bun 1.3.14: `SELECT 9007199254740993` returns
15
+ * `9007199254740992` without safeIntegers). The adapter therefore ALWAYS reads
16
+ * through bun:sqlite's `safeIntegers` (database-level for connections it
17
+ * opens, statement-level `stmt.safeIntegers(true)` for every statement it
18
+ * prepares, which also covers injected databases), then normalizes rows:
19
+ * bigints inside the safe range become `number`, larger ones stay `bigint`.
20
+ * That is exactly the shape the runtime's `SQLITE_CODECS` expect — Int and
21
+ * Boolean columns arrive as numbers, and >2^53 BigInt columns round-trip
22
+ * losslessly as bigint. See params.ts for the full reasoning.
23
+ *
24
+ * PRAGMAS applied on open (each documented on {@link SqliteAdapterOptions}):
25
+ * `foreign_keys = ON` (mandatory — SQLite defaults OFF and the ORM's FK
26
+ * semantics depend on it), `busy_timeout` (lock-wait bound), and
27
+ * `journal_mode = WAL` for file databases (readers no longer block the
28
+ * writer). Transactions open with `BEGIN IMMEDIATE`: the write lock is taken
29
+ * up front, so a write after a read inside the transaction can never hit the
30
+ * SQLITE_BUSY deadlock that lock *upgrades* are prone to.
31
+ */
32
+ import { Database } from "bun:sqlite";
33
+ import type { DatabaseAdapter } from "@vibeorm/runtime";
34
+ /** Options for {@link sqliteAdapter}. (Factories are the documented exception allowed a plain options object.) */
35
+ export type SqliteAdapterOptions = {
36
+ /**
37
+ * Database file to open. Defaults to `":memory:"` — a fresh private
38
+ * in-memory database, the usual choice for tests. Ignored when `database`
39
+ * is injected.
40
+ */
41
+ readonly filename?: string;
42
+ /**
43
+ * Open the file read-only (`SQLITE_READONLY` errors on writes, mapped to
44
+ * `VIBE_ADAPTER`). The WAL pragma is skipped on read-only connections —
45
+ * switching journal modes is a write. Ignored when `database` is injected.
46
+ */
47
+ readonly readonly?: boolean;
48
+ /**
49
+ * `PRAGMA busy_timeout` in milliseconds — how long a statement blocks on a
50
+ * competing lock before failing with SQLITE_BUSY (mapped to
51
+ * `VIBE_TRANSACTION`, `meta.reason: "busy"`). Default 5000. On an injected
52
+ * `database` the pragma is applied only when this option is passed
53
+ * explicitly, so the adapter never silently overrides the owner's setting.
54
+ */
55
+ readonly busyTimeoutMs?: number;
56
+ /**
57
+ * Switch file databases to `PRAGMA journal_mode = WAL` on open (default
58
+ * true): readers stop blocking the writer, the sane default for anything
59
+ * long-lived. Skipped for `":memory:"` databases (they have no WAL),
60
+ * read-only connections, and injected `database` instances (the owner
61
+ * decides their journal mode).
62
+ */
63
+ readonly wal?: boolean;
64
+ /**
65
+ * An already-open `bun:sqlite` Database to run on — sharing one in-memory
66
+ * database across adapters makes multi-adapter tests trivial. The adapter
67
+ * never closes an injected instance (`disconnect()` is a no-op), never
68
+ * changes its journal mode, and still applies `PRAGMA foreign_keys = ON`
69
+ * (the ORM requires it). For lossless >2^53 BigInt reads the adapter sets
70
+ * statement-level safeIntegers on every statement it prepares, so an
71
+ * injected database needs no special construction flags.
72
+ */
73
+ readonly database?: Database;
74
+ };
75
+ /**
76
+ * Create a VibeORM adapter backed by bun:sqlite.
77
+ *
78
+ * @example In-memory database (tests)
79
+ * ```ts
80
+ * const adapter = sqliteAdapter();
81
+ * await adapter.executeUnsafe({ text: `CREATE TABLE "User" ("id" INTEGER PRIMARY KEY)` });
82
+ * ```
83
+ *
84
+ * @example File database / shared instance
85
+ * ```ts
86
+ * const file = sqliteAdapter({ filename: "./app.db" });
87
+ * const shared = sqliteAdapter({ database: existingDatabase });
88
+ * ```
89
+ *
90
+ * `disconnect()` closes a database the adapter opened; a later call opens a
91
+ * fresh one (lazy reconnect, matching the pool-backed adapters). With the
92
+ * default `":memory:"` filename that fresh database is a new, empty one.
93
+ *
94
+ * @throws VibeError `VIBE_VALIDATION` when `busyTimeoutMs` is not a
95
+ * non-negative integer — validated eagerly, the value lands in PRAGMA text.
96
+ */
97
+ export declare function sqliteAdapter(options?: SqliteAdapterOptions): DatabaseAdapter;
98
+ export { SQLITE_ERROR_CODES, SQLITE_ERROR_REASONS, mapSqliteDriverError, runMapped, sqliteErrorCode, } from "./errors.ts";
99
+ export { normalizeRow, normalizeRows, serializeParamsRaw } from "./params.ts";
100
+ export { createOperationQueue } from "./queue.ts";
101
+ export type { OperationQueue } from "./queue.ts";
102
+ export { createSavepointCounter, nextSavepointName } from "./savepoints.ts";
103
+ export type { SavepointCounter } from "./savepoints.ts";
104
+ export { refuseNestedTransactionOptions, validateTransactionOptions } from "./transaction-options.ts";
105
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAKtC,OAAO,KAAK,EAAE,eAAe,EAAiD,MAAM,kBAAkB,CAAC;AASvG,kHAAkH;AAClH,MAAM,MAAM,oBAAoB,GAAG;IACjC;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B;;;;;;OAMG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC;;;;;;OAMG;IACH,QAAQ,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC;IACvB;;;;;;;;OAQG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC;CAC9B,CAAC;AA8CF;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,aAAa,CAAC,OAAO,CAAC,EAAE,oBAAoB,GAAG,eAAe,CAwR7E;AAID,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,oBAAoB,EACpB,SAAS,EACT,eAAe,GAChB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAC9E,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAClD,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAC5E,YAAY,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,8BAA8B,EAAE,0BAA0B,EAAE,MAAM,0BAA0B,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,365 @@
1
+ // @bun
2
+ // packages/adapter-sqlite/src/index.ts
3
+ import { Database } from "bun:sqlite";
4
+ import { AsyncLocalStorage } from "async_hooks";
5
+ import { VibeError as VibeError3, internalError } from "@vibeorm/schema";
6
+
7
+ // packages/adapter-sqlite/src/errors.ts
8
+ import { VibeError } from "@vibeorm/schema";
9
+ var SQLITE_ERROR_CODES = Object.freeze({
10
+ SQLITE_CONSTRAINT_UNIQUE: "VIBE_UNIQUE_VIOLATION",
11
+ SQLITE_CONSTRAINT_PRIMARYKEY: "VIBE_UNIQUE_VIOLATION",
12
+ SQLITE_CONSTRAINT_ROWID: "VIBE_UNIQUE_VIOLATION",
13
+ SQLITE_CONSTRAINT_FOREIGNKEY: "VIBE_FK_VIOLATION",
14
+ SQLITE_CONSTRAINT_NOTNULL: "VIBE_VALIDATION",
15
+ SQLITE_CONSTRAINT_CHECK: "VIBE_VALIDATION",
16
+ SQLITE_CONSTRAINT_DATATYPE: "VIBE_VALIDATION",
17
+ SQLITE_BUSY: "VIBE_TRANSACTION",
18
+ SQLITE_BUSY_SNAPSHOT: "VIBE_TRANSACTION",
19
+ SQLITE_BUSY_RECOVERY: "VIBE_TRANSACTION",
20
+ SQLITE_BUSY_TIMEOUT: "VIBE_TRANSACTION",
21
+ SQLITE_LOCKED: "VIBE_TRANSACTION",
22
+ SQLITE_LOCKED_SHAREDCACHE: "VIBE_TRANSACTION"
23
+ });
24
+ var SQLITE_ERROR_REASONS = Object.freeze({
25
+ SQLITE_BUSY: "busy",
26
+ SQLITE_BUSY_SNAPSHOT: "busy",
27
+ SQLITE_BUSY_RECOVERY: "busy",
28
+ SQLITE_BUSY_TIMEOUT: "busy",
29
+ SQLITE_LOCKED: "busy",
30
+ SQLITE_LOCKED_SHAREDCACHE: "busy"
31
+ });
32
+ var RESULT_CODE_PATTERN = /^SQLITE_[A-Z0-9_]+$/;
33
+ function readStringField(params) {
34
+ const value = params.source[params.key];
35
+ return typeof value === "string" && value.length > 0 ? value : undefined;
36
+ }
37
+ function sqliteErrorCode(params) {
38
+ const { error } = params;
39
+ if (error === null || typeof error !== "object")
40
+ return;
41
+ const code = readStringField({ source: error, key: "code" });
42
+ return code !== undefined && RESULT_CODE_PATTERN.test(code) ? code : undefined;
43
+ }
44
+ function mapSqliteDriverError(params) {
45
+ const { error } = params;
46
+ if (error instanceof VibeError)
47
+ return error;
48
+ const source = error !== null && typeof error === "object" ? error : {};
49
+ const driverCode = sqliteErrorCode({ error });
50
+ const code = (driverCode === undefined ? undefined : SQLITE_ERROR_CODES[driverCode]) ?? "VIBE_ADAPTER";
51
+ const meta = {};
52
+ if (driverCode !== undefined)
53
+ meta.code = driverCode;
54
+ const errno = source.errno;
55
+ if (typeof errno === "number")
56
+ meta.errno = errno;
57
+ const reason = driverCode === undefined ? undefined : SQLITE_ERROR_REASONS[driverCode];
58
+ if (reason !== undefined)
59
+ meta.reason = reason;
60
+ const message = readStringField({ source, key: "message" }) ?? (typeof error === "string" ? error : "unknown bun:sqlite driver error");
61
+ return new VibeError({ code, message, meta, cause: error });
62
+ }
63
+ function runMapped(fn) {
64
+ try {
65
+ return fn();
66
+ } catch (error) {
67
+ throw mapSqliteDriverError({ error });
68
+ }
69
+ }
70
+
71
+ // packages/adapter-sqlite/src/params.ts
72
+ function serializeParamsRaw(params) {
73
+ return params.values.map((value) => {
74
+ if (value === undefined)
75
+ return null;
76
+ if (typeof value === "boolean")
77
+ return value ? 1 : 0;
78
+ if (value === null || typeof value !== "object")
79
+ return value;
80
+ if (value instanceof Date)
81
+ return value.toISOString();
82
+ if (ArrayBuffer.isView(value) || value instanceof ArrayBuffer)
83
+ return value;
84
+ return JSON.stringify(value);
85
+ });
86
+ }
87
+ var MAX_SAFE = BigInt(Number.MAX_SAFE_INTEGER);
88
+ var MIN_SAFE = -MAX_SAFE;
89
+ function normalizeRow(params) {
90
+ const { row } = params;
91
+ for (const key of Object.keys(row)) {
92
+ const value = row[key];
93
+ if (typeof value === "bigint" && value <= MAX_SAFE && value >= MIN_SAFE) {
94
+ row[key] = Number(value);
95
+ }
96
+ }
97
+ return row;
98
+ }
99
+ function normalizeRows(params) {
100
+ for (const row of params.rows)
101
+ normalizeRow({ row });
102
+ return params.rows;
103
+ }
104
+
105
+ // packages/adapter-sqlite/src/queue.ts
106
+ function createOperationQueue() {
107
+ let tail = Promise.resolve();
108
+ return {
109
+ run(job) {
110
+ const result = tail.then(job, job);
111
+ tail = result.then(() => {
112
+ return;
113
+ }, () => {
114
+ return;
115
+ });
116
+ return result;
117
+ }
118
+ };
119
+ }
120
+
121
+ // packages/adapter-sqlite/src/savepoints.ts
122
+ function createSavepointCounter() {
123
+ return { n: 0 };
124
+ }
125
+ function nextSavepointName(params) {
126
+ return `vibeorm_sp_${params.counter.n++}`;
127
+ }
128
+
129
+ // packages/adapter-sqlite/src/transaction-options.ts
130
+ import { VibeError as VibeError2 } from "@vibeorm/schema";
131
+ function validateTransactionOptions(params) {
132
+ const { options } = params;
133
+ if (options === undefined)
134
+ return;
135
+ if (options.isolationLevel !== undefined && options.isolationLevel !== "Serializable") {
136
+ throw new VibeError2({
137
+ code: "VIBE_VALIDATION",
138
+ message: `sqlite transactions are always serializable \u2014 isolationLevel "${options.isolationLevel}" cannot be honored; pass "Serializable" or omit the option`,
139
+ meta: { dialect: "sqlite", isolationLevel: options.isolationLevel }
140
+ });
141
+ }
142
+ if (options.timeout !== undefined) {
143
+ throw new VibeError2({
144
+ code: "VIBE_VALIDATION",
145
+ message: "sqlite has no per-statement timeout, so a transaction `timeout` cannot be enforced database-side (busy_timeout only bounds lock acquisition, not statement runtime) \u2014 remove the option",
146
+ meta: { dialect: "sqlite", timeout: options.timeout }
147
+ });
148
+ }
149
+ }
150
+ function refuseNestedTransactionOptions(params) {
151
+ const { options, provider } = params;
152
+ if (options === undefined)
153
+ return;
154
+ const passed = [];
155
+ if (options.isolationLevel !== undefined)
156
+ passed.push("isolationLevel");
157
+ if (options.timeout !== undefined)
158
+ passed.push("timeout");
159
+ if (passed.length === 0)
160
+ return;
161
+ const meta = { provider, nested: true };
162
+ if (options.isolationLevel !== undefined)
163
+ meta.isolationLevel = options.isolationLevel;
164
+ if (options.timeout !== undefined)
165
+ meta.timeout = options.timeout;
166
+ throw new VibeError2({
167
+ code: "VIBE_VALIDATION",
168
+ message: `nested transactions run as savepoints and cannot honor ${passed.join(" or ")} \u2014 a savepoint cannot change the isolation level of the transaction it joins, and a nested timeout is not enforceable; pass options on the top-level $transaction`,
169
+ meta
170
+ });
171
+ }
172
+
173
+ // packages/adapter-sqlite/src/index.ts
174
+ var DIALECT = "sqlite";
175
+ var PROVIDER = "sqlite";
176
+ var WIRE = Object.freeze({ dateTime: "text", json: "text", numbers: "native" });
177
+ var DEFAULT_BUSY_TIMEOUT_MS = 5000;
178
+ function isMemoryFilename(params) {
179
+ return params.filename === "" || params.filename.includes(":memory:");
180
+ }
181
+ function asBindings(values) {
182
+ return values;
183
+ }
184
+ function withSafeIntegers(statement) {
185
+ statement.safeIntegers(true);
186
+ return statement;
187
+ }
188
+ function sqliteAdapter(options) {
189
+ const busyTimeoutMs = options?.busyTimeoutMs;
190
+ if (busyTimeoutMs !== undefined && (!Number.isInteger(busyTimeoutMs) || busyTimeoutMs < 0)) {
191
+ throw new VibeError3({
192
+ code: "VIBE_VALIDATION",
193
+ message: `busyTimeoutMs must be a non-negative integer of milliseconds, received ${String(busyTimeoutMs)}`,
194
+ meta: { busyTimeoutMs }
195
+ });
196
+ }
197
+ const queue = createOperationQueue();
198
+ const ownsDatabase = options?.database === undefined;
199
+ const filename = options?.filename ?? ":memory:";
200
+ const txContext = new AsyncLocalStorage;
201
+ function assertNotInsideTransaction() {
202
+ if (txContext.getStore() === true) {
203
+ throw new VibeError3({
204
+ code: "VIBE_TRANSACTION",
205
+ message: "root client used inside a transaction callback \u2014 use the tx client the callback receives; the root connection would deadlock behind the open transaction",
206
+ meta: { provider: PROVIDER }
207
+ });
208
+ }
209
+ }
210
+ let database = options?.database ?? null;
211
+ let configured = false;
212
+ function applyPragmas(params) {
213
+ const { db } = params;
214
+ db.run("PRAGMA foreign_keys = ON");
215
+ if (ownsDatabase || busyTimeoutMs !== undefined) {
216
+ db.run(`PRAGMA busy_timeout = ${busyTimeoutMs ?? DEFAULT_BUSY_TIMEOUT_MS}`);
217
+ }
218
+ if (ownsDatabase && options?.wal !== false && options?.readonly !== true && !isMemoryFilename({ filename })) {
219
+ db.run("PRAGMA journal_mode = WAL");
220
+ }
221
+ }
222
+ function getDatabase() {
223
+ if (database === null) {
224
+ database = runMapped(() => new Database(filename, options?.readonly === true ? { readonly: true, safeIntegers: true } : { create: true, readwrite: true, safeIntegers: true }));
225
+ configured = false;
226
+ }
227
+ if (!configured) {
228
+ runMapped(() => applyPragmas({ db: database }));
229
+ configured = true;
230
+ }
231
+ return database;
232
+ }
233
+ function runExecute(params) {
234
+ return runMapped(() => {
235
+ const statement = withSafeIntegers(params.db.query(params.text));
236
+ const rows = statement.all(...asBindings(params.values));
237
+ return normalizeRows({ rows });
238
+ });
239
+ }
240
+ function runExecuteUnsafe(params) {
241
+ return runMapped(() => {
242
+ const { db, text, values } = params;
243
+ if (values === undefined) {
244
+ const changes = db.run(text);
245
+ return { rows: [], affectedRows: changes.changes };
246
+ }
247
+ const statement = withSafeIntegers(db.prepare(text));
248
+ try {
249
+ const bound = asBindings(serializeParamsRaw({ values }));
250
+ if (statement.columnNames.length > 0) {
251
+ const rows = statement.all(...bound);
252
+ return { rows: normalizeRows({ rows }), affectedRows: rows.length };
253
+ }
254
+ const result = statement.run(...bound);
255
+ return { rows: [], affectedRows: result.changes };
256
+ } finally {
257
+ statement.finalize();
258
+ }
259
+ });
260
+ }
261
+ function createTransactionAdapter(params) {
262
+ const { db, savepointCounter } = params;
263
+ return {
264
+ dialect: DIALECT,
265
+ provider: PROVIDER,
266
+ wire: WIRE,
267
+ async execute(execParams) {
268
+ return runExecute({ db, ...execParams });
269
+ },
270
+ async executeUnsafe(execParams) {
271
+ return runExecuteUnsafe({ db, ...execParams });
272
+ },
273
+ async transaction(fn, nestedOptions) {
274
+ refuseNestedTransactionOptions({ options: nestedOptions, provider: PROVIDER });
275
+ const savepoint = nextSavepointName({ counter: savepointCounter });
276
+ runMapped(() => db.run(`SAVEPOINT ${savepoint}`));
277
+ try {
278
+ const result = await fn(createTransactionAdapter({ db, savepointCounter }));
279
+ runMapped(() => db.run(`RELEASE SAVEPOINT ${savepoint}`));
280
+ return result;
281
+ } catch (error) {
282
+ try {
283
+ db.run(`ROLLBACK TO SAVEPOINT ${savepoint}`);
284
+ } catch {}
285
+ throw error;
286
+ }
287
+ },
288
+ async connect() {},
289
+ async disconnect() {},
290
+ formatArrayParam(values) {
291
+ throw arrayParamBug({ values });
292
+ }
293
+ };
294
+ }
295
+ function arrayParamBug(params) {
296
+ return internalError({
297
+ message: "formatArrayParam called on the sqlite adapter \u2014 sqlite has no array parameters; the dialect expands IN lists to individual placeholders, so this call is an upstream runtime bug",
298
+ meta: { provider: PROVIDER, valueCount: params.values.length }
299
+ });
300
+ }
301
+ return {
302
+ dialect: DIALECT,
303
+ provider: PROVIDER,
304
+ wire: WIRE,
305
+ async execute(params) {
306
+ assertNotInsideTransaction();
307
+ return queue.run(async () => runExecute({ db: getDatabase(), ...params }));
308
+ },
309
+ async executeUnsafe(params) {
310
+ assertNotInsideTransaction();
311
+ return queue.run(async () => runExecuteUnsafe({ db: getDatabase(), ...params }));
312
+ },
313
+ async transaction(fn, transactionOptions) {
314
+ assertNotInsideTransaction();
315
+ validateTransactionOptions({ options: transactionOptions });
316
+ return queue.run(async () => {
317
+ const db = getDatabase();
318
+ const savepointCounter = createSavepointCounter();
319
+ runMapped(() => db.run("BEGIN IMMEDIATE"));
320
+ try {
321
+ const result = await txContext.run(true, () => fn(createTransactionAdapter({ db, savepointCounter })));
322
+ runMapped(() => db.run("COMMIT"));
323
+ return result;
324
+ } catch (error) {
325
+ try {
326
+ db.run("ROLLBACK");
327
+ } catch {}
328
+ throw error;
329
+ }
330
+ });
331
+ },
332
+ async connect() {
333
+ getDatabase();
334
+ },
335
+ async disconnect() {
336
+ if (!ownsDatabase || database === null)
337
+ return;
338
+ const closing = database;
339
+ database = null;
340
+ configured = false;
341
+ await queue.run(async () => runMapped(() => closing.close()));
342
+ },
343
+ formatArrayParam(values) {
344
+ throw arrayParamBug({ values });
345
+ }
346
+ };
347
+ }
348
+ export {
349
+ validateTransactionOptions,
350
+ sqliteErrorCode,
351
+ sqliteAdapter,
352
+ serializeParamsRaw,
353
+ runMapped,
354
+ refuseNestedTransactionOptions,
355
+ normalizeRows,
356
+ normalizeRow,
357
+ nextSavepointName,
358
+ mapSqliteDriverError,
359
+ createSavepointCounter,
360
+ createOperationQueue,
361
+ SQLITE_ERROR_REASONS,
362
+ SQLITE_ERROR_CODES
363
+ };
364
+
365
+ //# debugId=2ED07CFCABD292FE64756E2164756E21
@@ -0,0 +1,15 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/index.ts", "../src/errors.ts", "../src/params.ts", "../src/queue.ts", "../src/savepoints.ts", "../src/transaction-options.ts"],
4
+ "sourcesContent": [
5
+ "/**\n * @vibeorm/adapter-sqlite — bun:sqlite (embedded SQLite) adapter for\n * VibeORM v2.\n *\n * bun:sqlite is a *synchronous* single-connection driver, so every call\n * completes without I/O waits and the adapter wraps results in\n * already-resolved promises — the cheapest possible `execute`. Like PGlite,\n * one connection means every operation runs through one serial queue:\n * a whole `transaction()` holds the queue until it commits or rolls back, so\n * concurrent client calls can never interleave into an open transaction.\n *\n * INTEGER WIDTH (the BigInt story): SQLite INTEGER columns are 64-bit, but JS\n * numbers are only exact to ±(2^53−1) — a plain read of a large BigInt column\n * silently corrupts (pinned on Bun 1.3.14: `SELECT 9007199254740993` returns\n * `9007199254740992` without safeIntegers). The adapter therefore ALWAYS reads\n * through bun:sqlite's `safeIntegers` (database-level for connections it\n * opens, statement-level `stmt.safeIntegers(true)` for every statement it\n * prepares, which also covers injected databases), then normalizes rows:\n * bigints inside the safe range become `number`, larger ones stay `bigint`.\n * That is exactly the shape the runtime's `SQLITE_CODECS` expect — Int and\n * Boolean columns arrive as numbers, and >2^53 BigInt columns round-trip\n * losslessly as bigint. See params.ts for the full reasoning.\n *\n * PRAGMAS applied on open (each documented on {@link SqliteAdapterOptions}):\n * `foreign_keys = ON` (mandatory — SQLite defaults OFF and the ORM's FK\n * semantics depend on it), `busy_timeout` (lock-wait bound), and\n * `journal_mode = WAL` for file databases (readers no longer block the\n * writer). Transactions open with `BEGIN IMMEDIATE`: the write lock is taken\n * up front, so a write after a read inside the transaction can never hit the\n * SQLITE_BUSY deadlock that lock *upgrades* are prone to.\n */\n\nimport { Database } from \"bun:sqlite\";\nimport type { SQLQueryBindings } from \"bun:sqlite\";\nimport { AsyncLocalStorage } from \"node:async_hooks\";\nimport { VibeError, internalError } from \"@vibeorm/schema\";\nimport type { Dialect, Provider } from \"@vibeorm/schema\";\nimport type { DatabaseAdapter, QueryResult, TransactionOptions, WireFidelity } from \"@vibeorm/runtime\";\nimport { mapSqliteDriverError, runMapped } from \"./errors.ts\";\nimport { normalizeRows, serializeParamsRaw } from \"./params.ts\";\nimport { createOperationQueue } from \"./queue.ts\";\nimport { createSavepointCounter, nextSavepointName, type SavepointCounter } from \"./savepoints.ts\";\nimport { refuseNestedTransactionOptions, validateTransactionOptions } from \"./transaction-options.ts\";\n\n// ─── Options ──────────────────────────────────────────────────────\n\n/** Options for {@link sqliteAdapter}. (Factories are the documented exception allowed a plain options object.) */\nexport type SqliteAdapterOptions = {\n /**\n * Database file to open. Defaults to `\":memory:\"` — a fresh private\n * in-memory database, the usual choice for tests. Ignored when `database`\n * is injected.\n */\n readonly filename?: string;\n /**\n * Open the file read-only (`SQLITE_READONLY` errors on writes, mapped to\n * `VIBE_ADAPTER`). The WAL pragma is skipped on read-only connections —\n * switching journal modes is a write. Ignored when `database` is injected.\n */\n readonly readonly?: boolean;\n /**\n * `PRAGMA busy_timeout` in milliseconds — how long a statement blocks on a\n * competing lock before failing with SQLITE_BUSY (mapped to\n * `VIBE_TRANSACTION`, `meta.reason: \"busy\"`). Default 5000. On an injected\n * `database` the pragma is applied only when this option is passed\n * explicitly, so the adapter never silently overrides the owner's setting.\n */\n readonly busyTimeoutMs?: number;\n /**\n * Switch file databases to `PRAGMA journal_mode = WAL` on open (default\n * true): readers stop blocking the writer, the sane default for anything\n * long-lived. Skipped for `\":memory:\"` databases (they have no WAL),\n * read-only connections, and injected `database` instances (the owner\n * decides their journal mode).\n */\n readonly wal?: boolean;\n /**\n * An already-open `bun:sqlite` Database to run on — sharing one in-memory\n * database across adapters makes multi-adapter tests trivial. The adapter\n * never closes an injected instance (`disconnect()` is a no-op), never\n * changes its journal mode, and still applies `PRAGMA foreign_keys = ON`\n * (the ORM requires it). For lossless >2^53 BigInt reads the adapter sets\n * statement-level safeIntegers on every statement it prepares, so an\n * injected database needs no special construction flags.\n */\n readonly database?: Database;\n};\n\n// ─── Internals ────────────────────────────────────────────────────\n\nconst DIALECT: Dialect = \"sqlite\";\nconst PROVIDER: Provider = \"sqlite\";\n\n/**\n * bun:sqlite wire (board #30, live-verified): INTEGER/REAL → numbers (large\n * INTEGER → native `bigint`, which every decoder passes through); DateTime and\n * Json ride TEXT, so their decoders do real work and are declared \"text\"\n * (prunes nothing — the declaration is the honest record).\n */\nconst WIRE: WireFidelity = Object.freeze({ dateTime: \"text\", json: \"text\", numbers: \"native\" } as const);\nconst DEFAULT_BUSY_TIMEOUT_MS = 5000;\n\n/** `\":memory:\"` (also in URI form) and `\"\"` (anonymous temp) have no WAL. */\nfunction isMemoryFilename(params: { filename: string }): boolean {\n return params.filename === \"\" || params.filename.includes(\":memory:\");\n}\n\n/**\n * The one cast at the driver boundary. ORM-path values were encoded by the\n * runtime codec table into driver-native shapes; raw-path values went through\n * `serializeParamsRaw`. Verified by the param-passthrough unit tests.\n */\nfunction asBindings(values: readonly unknown[]): SQLQueryBindings[] {\n return values as SQLQueryBindings[];\n}\n\n/**\n * `Statement.safeIntegers()` exists at runtime since Bun 1.1.14 (pinned by\n * the integer-width unit tests: it returns the statement and applies to\n * cached statements too) but is missing from the installed @types/bun — this\n * minimal structural view bridges the gap without `any`.\n */\ntype SafeIntegersStatement = { safeIntegers(toggle: boolean): unknown };\n\n/** Flip a prepared statement to lossless 64-bit integer reads (see module doc). */\nfunction withSafeIntegers<S>(statement: S): S {\n (statement as unknown as SafeIntegersStatement).safeIntegers(true);\n return statement;\n}\n\n// ─── Adapter ──────────────────────────────────────────────────────\n\n/**\n * Create a VibeORM adapter backed by bun:sqlite.\n *\n * @example In-memory database (tests)\n * ```ts\n * const adapter = sqliteAdapter();\n * await adapter.executeUnsafe({ text: `CREATE TABLE \"User\" (\"id\" INTEGER PRIMARY KEY)` });\n * ```\n *\n * @example File database / shared instance\n * ```ts\n * const file = sqliteAdapter({ filename: \"./app.db\" });\n * const shared = sqliteAdapter({ database: existingDatabase });\n * ```\n *\n * `disconnect()` closes a database the adapter opened; a later call opens a\n * fresh one (lazy reconnect, matching the pool-backed adapters). With the\n * default `\":memory:\"` filename that fresh database is a new, empty one.\n *\n * @throws VibeError `VIBE_VALIDATION` when `busyTimeoutMs` is not a\n * non-negative integer — validated eagerly, the value lands in PRAGMA text.\n */\nexport function sqliteAdapter(options?: SqliteAdapterOptions): DatabaseAdapter {\n const busyTimeoutMs = options?.busyTimeoutMs;\n if (busyTimeoutMs !== undefined && (!Number.isInteger(busyTimeoutMs) || busyTimeoutMs < 0)) {\n throw new VibeError({\n code: \"VIBE_VALIDATION\",\n message: `busyTimeoutMs must be a non-negative integer of milliseconds, received ${String(busyTimeoutMs)}`,\n meta: { busyTimeoutMs },\n });\n }\n\n const queue = createOperationQueue();\n const ownsDatabase = options?.database === undefined;\n const filename = options?.filename ?? \":memory:\";\n\n /**\n * Deadlock guard (the pglite F6 lesson): a whole transaction holds the\n * operation queue, so a ROOT-adapter call issued from inside a\n * `transaction()` callback would queue behind the very transaction it is\n * running in and hang forever. Root entry points refuse instead; the\n * tx-bound adapter bypasses the queue and stays fully usable.\n */\n const txContext = new AsyncLocalStorage<true>();\n\n function assertNotInsideTransaction(): void {\n if (txContext.getStore() === true) {\n throw new VibeError({\n code: \"VIBE_TRANSACTION\",\n message:\n \"root client used inside a transaction callback — use the tx client the callback receives; the root connection would deadlock behind the open transaction\",\n meta: { provider: PROVIDER },\n });\n }\n }\n\n let database: Database | null = options?.database ?? null;\n let configured = false;\n\n /**\n * Session pragmas, applied once per opened connection (see module doc).\n * On an injected database only `foreign_keys` is unconditional; the\n * busy timeout is applied only when explicitly configured, and the journal\n * mode is never touched.\n */\n function applyPragmas(params: { db: Database }): void {\n const { db } = params;\n // MANDATORY: sqlite ships with foreign-key enforcement OFF; every FK\n // semantic the ORM promises (RESTRICT errors, ON DELETE CASCADE) needs it.\n db.run(\"PRAGMA foreign_keys = ON\");\n if (ownsDatabase || busyTimeoutMs !== undefined) {\n db.run(`PRAGMA busy_timeout = ${busyTimeoutMs ?? DEFAULT_BUSY_TIMEOUT_MS}`);\n }\n if (\n ownsDatabase &&\n options?.wal !== false &&\n options?.readonly !== true &&\n !isMemoryFilename({ filename })\n ) {\n db.run(\"PRAGMA journal_mode = WAL\");\n }\n }\n\n /** Open (or reuse) the connection lazily; sync because the driver is. */\n function getDatabase(): Database {\n if (database === null) {\n database = runMapped(\n () =>\n new Database(\n filename,\n options?.readonly === true\n ? { readonly: true, safeIntegers: true }\n : { create: true, readwrite: true, safeIntegers: true },\n ),\n );\n configured = false;\n }\n if (!configured) {\n runMapped(() => applyPragmas({ db: database as Database }));\n configured = true;\n }\n return database;\n }\n\n /**\n * ORM hot path: `db.query()` prepares through bun:sqlite's built-in\n * per-connection statement cache (pinned: same text ⇒ same Statement\n * object), so no adapter-side LRU is needed. Values bind verbatim — the\n * runtime codec table already encoded them (params.ts).\n */\n function runExecute(params: {\n db: Database;\n text: string;\n values: unknown[];\n }): Record<string, unknown>[] {\n return runMapped(() => {\n const statement = withSafeIntegers(params.db.query(params.text));\n const rows = statement.all(...asBindings(params.values)) as Record<string, unknown>[];\n return normalizeRows({ rows });\n });\n }\n\n /**\n * Raw path — uncached (`db.prepare`), finalized after use, raw-path\n * serialization for user-supplied values.\n *\n * With `values` present the text must be a SINGLE statement: bun:sqlite's\n * prepare SILENTLY DROPS everything after the first statement (pinned on\n * Bun 1.3.14), so multi-statement text with parameters would half-run.\n * Rows come from `all()` when the statement has result columns\n * (`columnNames`), with `affectedRows` = the row count (exact for\n * DML…RETURNING); otherwise from `run()`, whose driver-reported `changes`\n * is exact for UPDATE/DELETE/INSERT.\n *\n * With `values` absent the text runs as a multi-statement batch through\n * `db.run()` — the shape @vibeorm/migrate emits for DDL. The driver executes\n * every statement and reports cumulative changes; rows are always `[]` on\n * this path (the sync driver cannot both batch and read), so callers that\n * want rows from a single statement pass `values: []` — the runtime's\n * `$queryRawUnsafe` always does.\n */\n function runExecuteUnsafe(params: { db: Database; text: string; values?: unknown[] }): QueryResult {\n return runMapped(() => {\n const { db, text, values } = params;\n if (values === undefined) {\n const changes = db.run(text);\n return { rows: [], affectedRows: changes.changes };\n }\n const statement = withSafeIntegers(db.prepare(text));\n try {\n const bound = asBindings(serializeParamsRaw({ values }));\n if (statement.columnNames.length > 0) {\n const rows = statement.all(...bound) as Record<string, unknown>[];\n return { rows: normalizeRows({ rows }), affectedRows: rows.length };\n }\n const result = statement.run(...bound);\n return { rows: [], affectedRows: result.changes };\n } finally {\n statement.finalize();\n }\n });\n }\n\n /**\n * Adapter bound to an open transaction. It never re-enters the queue — the\n * enclosing `transaction()` call already owns the connection — and nested\n * `transaction()` calls become savepoints named from the counter shared\n * across the whole top-level transaction.\n */\n function createTransactionAdapter(params: {\n db: Database;\n savepointCounter: SavepointCounter;\n }): DatabaseAdapter {\n const { db, savepointCounter } = params;\n\n return {\n dialect: DIALECT,\n provider: PROVIDER,\n wire: WIRE,\n\n async execute(execParams) {\n return runExecute({ db, ...execParams });\n },\n\n async executeUnsafe(execParams) {\n return runExecuteUnsafe({ db, ...execParams });\n },\n\n async transaction<T>(\n fn: (txAdapter: DatabaseAdapter) => Promise<T>,\n nestedOptions?: TransactionOptions,\n ): Promise<T> {\n refuseNestedTransactionOptions({ options: nestedOptions, provider: PROVIDER });\n const savepoint = nextSavepointName({ counter: savepointCounter });\n runMapped(() => db.run(`SAVEPOINT ${savepoint}`));\n try {\n const result = await fn(createTransactionAdapter({ db, savepointCounter }));\n runMapped(() => db.run(`RELEASE SAVEPOINT ${savepoint}`));\n return result;\n } catch (error) {\n // Best effort: never mask the original failure with a rollback failure.\n try {\n db.run(`ROLLBACK TO SAVEPOINT ${savepoint}`);\n } catch {\n /* rollback is best-effort */\n }\n throw error;\n }\n },\n\n async connect(): Promise<void> {\n // Already connected — this adapter is bound to an open transaction.\n },\n\n async disconnect(): Promise<void> {\n // The database outlives the transaction; closing here would be wrong.\n },\n\n formatArrayParam(values: unknown[]): unknown {\n throw arrayParamBug({ values });\n },\n };\n }\n\n /**\n * sqlite has no array parameters — the sqlite dialect declares\n * `scalarArrays: false` and expands `IN` lists to individual placeholders\n * (`inArrayStrategy: \"expand\"`), so this method being reached means an\n * upstream runtime bug routed an array here.\n */\n function arrayParamBug(params: { values: unknown[] }): VibeError {\n return internalError({\n message:\n \"formatArrayParam called on the sqlite adapter — sqlite has no array parameters; the dialect expands IN lists to individual placeholders, so this call is an upstream runtime bug\",\n meta: { provider: PROVIDER, valueCount: params.values.length },\n });\n }\n\n return {\n dialect: DIALECT,\n provider: PROVIDER,\n wire: WIRE,\n\n async execute(params) {\n assertNotInsideTransaction();\n return queue.run(async () => runExecute({ db: getDatabase(), ...params }));\n },\n\n async executeUnsafe(params) {\n assertNotInsideTransaction();\n return queue.run(async () => runExecuteUnsafe({ db: getDatabase(), ...params }));\n },\n\n async transaction<T>(\n fn: (txAdapter: DatabaseAdapter) => Promise<T>,\n transactionOptions?: TransactionOptions,\n ): Promise<T> {\n assertNotInsideTransaction();\n // Refuse unsupportable options BEFORE taking the queue or issuing BEGIN,\n // so a bad option fails fast and leaves no transaction open.\n validateTransactionOptions({ options: transactionOptions });\n\n return queue.run(async () => {\n const db = getDatabase();\n const savepointCounter = createSavepointCounter();\n // Write-intent lock up front — see module doc on BEGIN IMMEDIATE.\n runMapped(() => db.run(\"BEGIN IMMEDIATE\"));\n try {\n const result = await txContext.run(true, () =>\n fn(createTransactionAdapter({ db, savepointCounter })),\n );\n runMapped(() => db.run(\"COMMIT\"));\n return result;\n } catch (error) {\n // Best effort: never mask the original failure (the user callback's\n // own error, or a failed COMMIT) with a rollback failure.\n try {\n db.run(\"ROLLBACK\");\n } catch {\n /* rollback is best-effort */\n }\n throw error;\n }\n });\n },\n\n async connect(): Promise<void> {\n getDatabase();\n },\n\n async disconnect(): Promise<void> {\n if (!ownsDatabase || database === null) return;\n const closing = database;\n database = null;\n configured = false;\n await queue.run(async () => runMapped(() => closing.close()));\n },\n\n formatArrayParam(values: unknown[]): unknown {\n throw arrayParamBug({ values });\n },\n };\n}\n\n// ─── Re-exports (driver-error table, helpers) ─────────────────────\n\nexport {\n SQLITE_ERROR_CODES,\n SQLITE_ERROR_REASONS,\n mapSqliteDriverError,\n runMapped,\n sqliteErrorCode,\n} from \"./errors.ts\";\nexport { normalizeRow, normalizeRows, serializeParamsRaw } from \"./params.ts\";\nexport { createOperationQueue } from \"./queue.ts\";\nexport type { OperationQueue } from \"./queue.ts\";\nexport { createSavepointCounter, nextSavepointName } from \"./savepoints.ts\";\nexport type { SavepointCounter } from \"./savepoints.ts\";\nexport { refuseNestedTransactionOptions, validateTransactionOptions } from \"./transaction-options.ts\";\n",
6
+ "/**\n * Driver-error mapping for `bun:sqlite`.\n *\n * bun:sqlite throws `SQLiteError` carrying the SQLite *extended* result-code\n * name in `code` (e.g. `\"SQLITE_CONSTRAINT_UNIQUE\"`) and the numeric extended\n * result code in `errno` (e.g. `2067`). Real shapes pinned against Bun 1.3.14:\n *\n * unique → code \"SQLITE_CONSTRAINT_UNIQUE\" errno 2067\n * pk → code \"SQLITE_CONSTRAINT_PRIMARYKEY\" errno 1555\n * notnull → code \"SQLITE_CONSTRAINT_NOTNULL\" errno 1299\n * check → code \"SQLITE_CONSTRAINT_CHECK\" errno 275\n * fk → code \"SQLITE_CONSTRAINT_FOREIGNKEY\" errno 787\n * busy → code \"SQLITE_BUSY\" errno 5\n *\n * Constitution rule 5: only `VibeError` escapes the adapter.\n */\n\nimport { VibeError, type VibeErrorCode } from \"@vibeorm/schema\";\n\n// ─── Result-code table ────────────────────────────────────────────\n\n/**\n * SQLite extended result-code name → stable VibeError code. Frozen and\n * mirrored by tests; anything absent from this table maps to `VIBE_ADAPTER`.\n */\nexport const SQLITE_ERROR_CODES: Readonly<Record<string, VibeErrorCode>> = Object.freeze({\n /** UNIQUE constraint failed on a declared unique index. */\n SQLITE_CONSTRAINT_UNIQUE: \"VIBE_UNIQUE_VIOLATION\",\n /** UNIQUE constraint failed on the primary key. */\n SQLITE_CONSTRAINT_PRIMARYKEY: \"VIBE_UNIQUE_VIOLATION\",\n /** rowid collision — the rowid alias flavour of a PK violation. */\n SQLITE_CONSTRAINT_ROWID: \"VIBE_UNIQUE_VIOLATION\",\n /** FOREIGN KEY constraint failed (requires `PRAGMA foreign_keys = ON`). */\n SQLITE_CONSTRAINT_FOREIGNKEY: \"VIBE_FK_VIOLATION\",\n /** NOT NULL constraint failed. */\n SQLITE_CONSTRAINT_NOTNULL: \"VIBE_VALIDATION\",\n /** CHECK constraint failed (enum emulation uses CHECK on sqlite). */\n SQLITE_CONSTRAINT_CHECK: \"VIBE_VALIDATION\",\n /** STRICT-table type mismatch. */\n SQLITE_CONSTRAINT_DATATYPE: \"VIBE_VALIDATION\",\n /** Another connection holds a conflicting lock. */\n SQLITE_BUSY: \"VIBE_TRANSACTION\",\n /** WAL snapshot invalidated by a concurrent writer. */\n SQLITE_BUSY_SNAPSHOT: \"VIBE_TRANSACTION\",\n /** Locked while another connection recovers the WAL. */\n SQLITE_BUSY_RECOVERY: \"VIBE_TRANSACTION\",\n /** busy_timeout elapsed while blocking (sqlite ≥3.41 setlk timeouts). */\n SQLITE_BUSY_TIMEOUT: \"VIBE_TRANSACTION\",\n /** Conflict on the same connection (e.g. dropping a table mid-read). */\n SQLITE_LOCKED: \"VIBE_TRANSACTION\",\n /** Shared-cache lock contention. */\n SQLITE_LOCKED_SHAREDCACHE: \"VIBE_TRANSACTION\",\n});\n\n/** Result codes that additionally explain themselves through `meta.reason`. */\nexport const SQLITE_ERROR_REASONS: Readonly<Record<string, string>> = Object.freeze({\n SQLITE_BUSY: \"busy\",\n SQLITE_BUSY_SNAPSHOT: \"busy\",\n SQLITE_BUSY_RECOVERY: \"busy\",\n SQLITE_BUSY_TIMEOUT: \"busy\",\n SQLITE_LOCKED: \"busy\",\n SQLITE_LOCKED_SHAREDCACHE: \"busy\",\n});\n\n// ─── Reading driver errors ────────────────────────────────────────\n\n/** bun:sqlite result-code names are SCREAMING_SNAKE with the SQLITE_ prefix. */\nconst RESULT_CODE_PATTERN = /^SQLITE_[A-Z0-9_]+$/;\n\nfunction readStringField(params: { source: Record<string, unknown>; key: string }): string | undefined {\n const value = params.source[params.key];\n return typeof value === \"string\" && value.length > 0 ? value : undefined;\n}\n\n/**\n * Extract the SQLite result-code name from a bun:sqlite error. Failures raised\n * outside the database engine (a closed handle, a bad filename) may carry no\n * `SQLITE_*` code and yield `undefined`.\n */\nexport function sqliteErrorCode(params: { error: unknown }): string | undefined {\n const { error } = params;\n if (error === null || typeof error !== \"object\") return undefined;\n const code = readStringField({ source: error as Record<string, unknown>, key: \"code\" });\n return code !== undefined && RESULT_CODE_PATTERN.test(code) ? code : undefined;\n}\n\n// ─── Mapping ──────────────────────────────────────────────────────\n\n/**\n * Map any error thrown by bun:sqlite onto a `VibeError`.\n *\n * A `VibeError` passes through unchanged, so an error raised deeper inside the\n * ORM (or by a nested adapter call) is never re-wrapped. Everything else keeps\n * the original error as `cause` and carries `{ code, errno }` in `meta`.\n */\nexport function mapSqliteDriverError(params: { error: unknown }): VibeError {\n const { error } = params;\n if (error instanceof VibeError) return error;\n\n const source: Record<string, unknown> =\n error !== null && typeof error === \"object\" ? (error as Record<string, unknown>) : {};\n const driverCode = sqliteErrorCode({ error });\n const code: VibeErrorCode =\n (driverCode === undefined ? undefined : SQLITE_ERROR_CODES[driverCode]) ?? \"VIBE_ADAPTER\";\n\n const meta: Record<string, unknown> = {};\n if (driverCode !== undefined) meta.code = driverCode;\n const errno = source.errno;\n if (typeof errno === \"number\") meta.errno = errno;\n const reason = driverCode === undefined ? undefined : SQLITE_ERROR_REASONS[driverCode];\n if (reason !== undefined) meta.reason = reason;\n\n const message =\n readStringField({ source, key: \"message\" }) ??\n (typeof error === \"string\" ? error : \"unknown bun:sqlite driver error\");\n\n return new VibeError({ code, message, meta, cause: error });\n}\n\n/**\n * Run a driver call, mapping anything it throws onto a `VibeError`. Synchronous\n * because bun:sqlite is a synchronous driver — the adapter's async surface\n * wraps results in already-resolved promises.\n */\nexport function runMapped<T>(fn: () => T): T {\n try {\n return fn();\n } catch (error) {\n throw mapSqliteDriverError({ error });\n }\n}\n",
7
+ "/**\n * Parameter serialization and row normalization for bun:sqlite.\n *\n * TWO SERIALIZATION PATHS (LEARNINGS.md — raw vs ORM differ):\n *\n * ORM hot path — NO conversion at all. The runtime codec table\n * (`SQLITE_CODECS` in @vibeorm/runtime) already encoded every parameter:\n * booleans are 0/1, Dates are ISO-8601 text, Json is stringified, BigInt is\n * decimal text. Converting again here would be exactly the double-coercion\n * v1's constitution rule 6 forbids, so `execute` binds values verbatim.\n *\n * Raw path (`$queryRaw*` / `$executeRaw*` / DDL) — user-supplied values that\n * never met a codec. bun:sqlite silently binds JS values it does not\n * understand as NULL (pinned on Bun 1.3.14: a `Date` and a plain object both\n * arrive as NULL), so {@link serializeParamsRaw} converts them explicitly\n * instead of letting data vanish.\n *\n * ROW NORMALIZATION: the adapter always reads INTEGER columns with\n * `safeIntegers` (see index.ts), so the driver hands back `bigint` for every\n * integer value. {@link normalizeRows} converts each bigint that fits the\n * IEEE-754 safe range back to `number`, and keeps the rest as `bigint`:\n *\n * - Int columns arrive as `number` (the Int codec passes numbers through),\n * - Boolean 0/1 arrive as `number` → decoded to boolean by the codec,\n * - BigInt columns ≤ 2^53−1 arrive as `number` → `BigInt(value)` (lossless),\n * - BigInt columns > 2^53−1 STAY `bigint` → codec passes them through — the\n * round-trip is lossless where plain number reads would silently corrupt.\n */\n\n// ─── Raw-path serialization ───────────────────────────────────────\n\n/**\n * Serialize raw-path parameters into values bun:sqlite binds faithfully:\n * `Date` → ISO-8601 text (matches the DateTime column encoding), `boolean` →\n * 1/0 (matches the Boolean column encoding), plain objects **and arrays** →\n * JSON text (sqlite has no array parameters — a JS array can only be a JSON\n * value here), `undefined` → NULL. Strings, numbers, bigints, NULL and binary\n * views pass through untouched.\n */\nexport function serializeParamsRaw(params: { values: readonly unknown[] }): unknown[] {\n return params.values.map((value) => {\n if (value === undefined) return null;\n if (typeof value === \"boolean\") return value ? 1 : 0;\n if (value === null || typeof value !== \"object\") return value;\n if (value instanceof Date) return value.toISOString();\n if (ArrayBuffer.isView(value) || value instanceof ArrayBuffer) return value;\n return JSON.stringify(value);\n });\n}\n\n// ─── Row normalization (safeIntegers → JS expectations) ───────────\n\nconst MAX_SAFE: bigint = BigInt(Number.MAX_SAFE_INTEGER);\nconst MIN_SAFE: bigint = -MAX_SAFE;\n\n/**\n * Downcast every lossless `bigint` in a row to `number`, in place. Values\n * outside ±(2^53−1) stay `bigint` so oversized BigInt columns round-trip\n * exactly (see the module doc for why this matches the runtime codec table).\n */\nexport function normalizeRow(params: { row: Record<string, unknown> }): Record<string, unknown> {\n const { row } = params;\n for (const key of Object.keys(row)) {\n const value = row[key];\n if (typeof value === \"bigint\" && value <= MAX_SAFE && value >= MIN_SAFE) {\n row[key] = Number(value);\n }\n }\n return row;\n}\n\n/** {@link normalizeRow} over a result set (mutates and returns the same array). */\nexport function normalizeRows(params: { rows: Record<string, unknown>[] }): Record<string, unknown>[] {\n for (const row of params.rows) normalizeRow({ row });\n return params.rows;\n}\n",
8
+ "/**\n * Operation queue for bun:sqlite.\n *\n * The driver itself is synchronous — a single statement can never interleave —\n * but a `transaction()` callback is async: while it awaits, a concurrent root\n * adapter call would run on the SAME connection and silently join the open\n * transaction. Every adapter entry point therefore runs through one serial\n * chain — including whole `transaction()` calls, which occupy the chain until\n * they commit or roll back (mirroring adapter-pglite).\n */\n\n/** A serial chain: jobs run one at a time, in the order they were queued. */\nexport type OperationQueue = {\n /** Queue `job`, resolving with its result once every earlier job has settled. */\n run<T>(job: () => Promise<T>): Promise<T>;\n};\n\n/** Create an empty operation queue. */\nexport function createOperationQueue(): OperationQueue {\n let tail: Promise<unknown> = Promise.resolve();\n\n return {\n run<T>(job: () => Promise<T>): Promise<T> {\n // Run after the previous job settles, whether it resolved or rejected.\n const result = tail.then(job, job);\n // Keep the chain alive: a rejected job must not reject every later job.\n tail = result.then(\n () => undefined,\n () => undefined,\n );\n return result;\n },\n };\n}\n",
9
+ "/**\n * Savepoint naming for nested transactions.\n *\n * v1 lesson (LEARNINGS.md): the counter is shared **by reference** across every\n * adapter created for one top-level transaction, so sibling and deeply nested\n * savepoints can never collide on a name.\n */\n\n/** Mutable counter shared by reference across one top-level transaction. */\nexport type SavepointCounter = { n: number };\n\n/** Fresh counter — one per top-level transaction. */\nexport function createSavepointCounter(): SavepointCounter {\n return { n: 0 };\n}\n\n/**\n * Allocate the next savepoint name (`vibeorm_sp_0`, `vibeorm_sp_1`, …) and\n * advance the shared counter. The name is an identifier by construction, so it\n * is safe to interpolate into `SAVEPOINT` / `RELEASE` / `ROLLBACK TO` SQL.\n */\nexport function nextSavepointName(params: { counter: SavepointCounter }): string {\n return `vibeorm_sp_${params.counter.n++}`;\n}\n",
10
+ "/**\n * Transaction-option validation for sqlite — dialect honesty (constitution\n * rule 4): what sqlite cannot honor is refused loudly at the earliest knowable\n * moment, before `BEGIN` is ever issued, instead of being silently ignored.\n *\n * - SQLite transactions are always serializable. `Serializable` (and omitting\n * the option) is accepted; `ReadCommitted` / `RepeatableRead` would be a\n * silent upgrade the caller did not ask for, so they throw `VIBE_VALIDATION`.\n * - SQLite has no per-statement timeout. `busy_timeout` only bounds LOCK\n * ACQUISITION, not statement runtime, so it is NOT an honest implementation\n * of the contract's transaction-scoped `timeout` — the option throws\n * `VIBE_VALIDATION`.\n * - NESTED transactions are savepoints: no adapter can change the isolation\n * level mid-transaction or enforce a nested timeout, so nested options are\n * refused with `VIBE_VALIDATION` on EVERY adapter (the shared contract in\n * @vibeorm/runtime's adapter.ts).\n */\n\nimport type { TransactionOptions } from \"@vibeorm/runtime\";\nimport { VibeError } from \"@vibeorm/schema\";\n\n/**\n * Validate `$transaction` options against what sqlite can actually honor.\n *\n * @throws VibeError `VIBE_VALIDATION` for `ReadCommitted` / `RepeatableRead`\n * isolation or any `timeout` (see module doc).\n */\nexport function validateTransactionOptions(params: { options?: TransactionOptions }): void {\n const { options } = params;\n if (options === undefined) return;\n\n if (options.isolationLevel !== undefined && options.isolationLevel !== \"Serializable\") {\n throw new VibeError({\n code: \"VIBE_VALIDATION\",\n message: `sqlite transactions are always serializable — isolationLevel \"${options.isolationLevel}\" cannot be honored; pass \"Serializable\" or omit the option`,\n meta: { dialect: \"sqlite\", isolationLevel: options.isolationLevel },\n });\n }\n\n if (options.timeout !== undefined) {\n throw new VibeError({\n code: \"VIBE_VALIDATION\",\n message:\n \"sqlite has no per-statement timeout, so a transaction `timeout` cannot be enforced database-side (busy_timeout only bounds lock acquisition, not statement runtime) — remove the option\",\n meta: { dialect: \"sqlite\", timeout: options.timeout },\n });\n }\n}\n\n/**\n * Refuse options on a NESTED `transaction()` call — the same contract on every\n * adapter (see the `DatabaseAdapter.transaction` JSDoc in @vibeorm/runtime):\n * a nested transaction is a SAVEPOINT, and a savepoint can neither change the\n * isolation level of the transaction it joins nor enforce its own timeout.\n *\n * @throws VibeError `VIBE_VALIDATION` when `isolationLevel` or `timeout` is\n * present (an `undefined` or empty options object is accepted).\n */\nexport function refuseNestedTransactionOptions(params: {\n options?: TransactionOptions;\n provider: string;\n}): void {\n const { options, provider } = params;\n if (options === undefined) return;\n\n const passed: string[] = [];\n if (options.isolationLevel !== undefined) passed.push(\"isolationLevel\");\n if (options.timeout !== undefined) passed.push(\"timeout\");\n if (passed.length === 0) return;\n\n const meta: Record<string, unknown> = { provider, nested: true };\n if (options.isolationLevel !== undefined) meta.isolationLevel = options.isolationLevel;\n if (options.timeout !== undefined) meta.timeout = options.timeout;\n\n throw new VibeError({\n code: \"VIBE_VALIDATION\",\n message: `nested transactions run as savepoints and cannot honor ${passed.join(\" or \")} — a savepoint cannot change the isolation level of the transaction it joins, and a nested timeout is not enforceable; pass options on the top-level $transaction`,\n meta,\n });\n}\n"
11
+ ],
12
+ "mappings": "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",
13
+ "debugId": "2ED07CFCABD292FE64756E2164756E21",
14
+ "names": []
15
+ }
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Parameter serialization and row normalization for bun:sqlite.
3
+ *
4
+ * TWO SERIALIZATION PATHS (LEARNINGS.md — raw vs ORM differ):
5
+ *
6
+ * ORM hot path — NO conversion at all. The runtime codec table
7
+ * (`SQLITE_CODECS` in @vibeorm/runtime) already encoded every parameter:
8
+ * booleans are 0/1, Dates are ISO-8601 text, Json is stringified, BigInt is
9
+ * decimal text. Converting again here would be exactly the double-coercion
10
+ * v1's constitution rule 6 forbids, so `execute` binds values verbatim.
11
+ *
12
+ * Raw path (`$queryRaw*` / `$executeRaw*` / DDL) — user-supplied values that
13
+ * never met a codec. bun:sqlite silently binds JS values it does not
14
+ * understand as NULL (pinned on Bun 1.3.14: a `Date` and a plain object both
15
+ * arrive as NULL), so {@link serializeParamsRaw} converts them explicitly
16
+ * instead of letting data vanish.
17
+ *
18
+ * ROW NORMALIZATION: the adapter always reads INTEGER columns with
19
+ * `safeIntegers` (see index.ts), so the driver hands back `bigint` for every
20
+ * integer value. {@link normalizeRows} converts each bigint that fits the
21
+ * IEEE-754 safe range back to `number`, and keeps the rest as `bigint`:
22
+ *
23
+ * - Int columns arrive as `number` (the Int codec passes numbers through),
24
+ * - Boolean 0/1 arrive as `number` → decoded to boolean by the codec,
25
+ * - BigInt columns ≤ 2^53−1 arrive as `number` → `BigInt(value)` (lossless),
26
+ * - BigInt columns > 2^53−1 STAY `bigint` → codec passes them through — the
27
+ * round-trip is lossless where plain number reads would silently corrupt.
28
+ */
29
+ /**
30
+ * Serialize raw-path parameters into values bun:sqlite binds faithfully:
31
+ * `Date` → ISO-8601 text (matches the DateTime column encoding), `boolean` →
32
+ * 1/0 (matches the Boolean column encoding), plain objects **and arrays** →
33
+ * JSON text (sqlite has no array parameters — a JS array can only be a JSON
34
+ * value here), `undefined` → NULL. Strings, numbers, bigints, NULL and binary
35
+ * views pass through untouched.
36
+ */
37
+ export declare function serializeParamsRaw(params: {
38
+ values: readonly unknown[];
39
+ }): unknown[];
40
+ /**
41
+ * Downcast every lossless `bigint` in a row to `number`, in place. Values
42
+ * outside ±(2^53−1) stay `bigint` so oversized BigInt columns round-trip
43
+ * exactly (see the module doc for why this matches the runtime codec table).
44
+ */
45
+ export declare function normalizeRow(params: {
46
+ row: Record<string, unknown>;
47
+ }): Record<string, unknown>;
48
+ /** {@link normalizeRow} over a result set (mutates and returns the same array). */
49
+ export declare function normalizeRows(params: {
50
+ rows: Record<string, unknown>[];
51
+ }): Record<string, unknown>[];
52
+ //# sourceMappingURL=params.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"params.d.ts","sourceRoot":"","sources":["../src/params.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAIH;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE;IAAE,MAAM,EAAE,SAAS,OAAO,EAAE,CAAA;CAAE,GAAG,OAAO,EAAE,CASpF;AAOD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAS9F;AAED,mFAAmF;AACnF,wBAAgB,aAAa,CAAC,MAAM,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAA;CAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAGpG"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Operation queue for bun:sqlite.
3
+ *
4
+ * The driver itself is synchronous — a single statement can never interleave —
5
+ * but a `transaction()` callback is async: while it awaits, a concurrent root
6
+ * adapter call would run on the SAME connection and silently join the open
7
+ * transaction. Every adapter entry point therefore runs through one serial
8
+ * chain — including whole `transaction()` calls, which occupy the chain until
9
+ * they commit or roll back (mirroring adapter-pglite).
10
+ */
11
+ /** A serial chain: jobs run one at a time, in the order they were queued. */
12
+ export type OperationQueue = {
13
+ /** Queue `job`, resolving with its result once every earlier job has settled. */
14
+ run<T>(job: () => Promise<T>): Promise<T>;
15
+ };
16
+ /** Create an empty operation queue. */
17
+ export declare function createOperationQueue(): OperationQueue;
18
+ //# sourceMappingURL=queue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["../src/queue.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,6EAA6E;AAC7E,MAAM,MAAM,cAAc,GAAG;IAC3B,iFAAiF;IACjF,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CAC3C,CAAC;AAEF,uCAAuC;AACvC,wBAAgB,oBAAoB,IAAI,cAAc,CAerD"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Savepoint naming for nested transactions.
3
+ *
4
+ * v1 lesson (LEARNINGS.md): the counter is shared **by reference** across every
5
+ * adapter created for one top-level transaction, so sibling and deeply nested
6
+ * savepoints can never collide on a name.
7
+ */
8
+ /** Mutable counter shared by reference across one top-level transaction. */
9
+ export type SavepointCounter = {
10
+ n: number;
11
+ };
12
+ /** Fresh counter — one per top-level transaction. */
13
+ export declare function createSavepointCounter(): SavepointCounter;
14
+ /**
15
+ * Allocate the next savepoint name (`vibeorm_sp_0`, `vibeorm_sp_1`, …) and
16
+ * advance the shared counter. The name is an identifier by construction, so it
17
+ * is safe to interpolate into `SAVEPOINT` / `RELEASE` / `ROLLBACK TO` SQL.
18
+ */
19
+ export declare function nextSavepointName(params: {
20
+ counter: SavepointCounter;
21
+ }): string;
22
+ //# sourceMappingURL=savepoints.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"savepoints.d.ts","sourceRoot":"","sources":["../src/savepoints.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,4EAA4E;AAC5E,MAAM,MAAM,gBAAgB,GAAG;IAAE,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAE7C,qDAAqD;AACrD,wBAAgB,sBAAsB,IAAI,gBAAgB,CAEzD;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE;IAAE,OAAO,EAAE,gBAAgB,CAAA;CAAE,GAAG,MAAM,CAE/E"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Transaction-option validation for sqlite — dialect honesty (constitution
3
+ * rule 4): what sqlite cannot honor is refused loudly at the earliest knowable
4
+ * moment, before `BEGIN` is ever issued, instead of being silently ignored.
5
+ *
6
+ * - SQLite transactions are always serializable. `Serializable` (and omitting
7
+ * the option) is accepted; `ReadCommitted` / `RepeatableRead` would be a
8
+ * silent upgrade the caller did not ask for, so they throw `VIBE_VALIDATION`.
9
+ * - SQLite has no per-statement timeout. `busy_timeout` only bounds LOCK
10
+ * ACQUISITION, not statement runtime, so it is NOT an honest implementation
11
+ * of the contract's transaction-scoped `timeout` — the option throws
12
+ * `VIBE_VALIDATION`.
13
+ * - NESTED transactions are savepoints: no adapter can change the isolation
14
+ * level mid-transaction or enforce a nested timeout, so nested options are
15
+ * refused with `VIBE_VALIDATION` on EVERY adapter (the shared contract in
16
+ * @vibeorm/runtime's adapter.ts).
17
+ */
18
+ import type { TransactionOptions } from "@vibeorm/runtime";
19
+ /**
20
+ * Validate `$transaction` options against what sqlite can actually honor.
21
+ *
22
+ * @throws VibeError `VIBE_VALIDATION` for `ReadCommitted` / `RepeatableRead`
23
+ * isolation or any `timeout` (see module doc).
24
+ */
25
+ export declare function validateTransactionOptions(params: {
26
+ options?: TransactionOptions;
27
+ }): void;
28
+ /**
29
+ * Refuse options on a NESTED `transaction()` call — the same contract on every
30
+ * adapter (see the `DatabaseAdapter.transaction` JSDoc in @vibeorm/runtime):
31
+ * a nested transaction is a SAVEPOINT, and a savepoint can neither change the
32
+ * isolation level of the transaction it joins nor enforce its own timeout.
33
+ *
34
+ * @throws VibeError `VIBE_VALIDATION` when `isolationLevel` or `timeout` is
35
+ * present (an `undefined` or empty options object is accepted).
36
+ */
37
+ export declare function refuseNestedTransactionOptions(params: {
38
+ options?: TransactionOptions;
39
+ provider: string;
40
+ }): void;
41
+ //# sourceMappingURL=transaction-options.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transaction-options.d.ts","sourceRoot":"","sources":["../src/transaction-options.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAG3D;;;;;GAKG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE;IAAE,OAAO,CAAC,EAAE,kBAAkB,CAAA;CAAE,GAAG,IAAI,CAoBzF;AAED;;;;;;;;GAQG;AACH,wBAAgB,8BAA8B,CAAC,MAAM,EAAE;IACrD,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAC7B,QAAQ,EAAE,MAAM,CAAC;CAClB,GAAG,IAAI,CAkBP"}
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "@vibeorm/adapter-sqlite",
3
+ "version": "2.0.0-alpha.1",
4
+ "description": "bun:sqlite adapter for VibeORM v2",
5
+ "keywords": [
6
+ "orm",
7
+ "typescript",
8
+ "sql",
9
+ "database",
10
+ "bun",
11
+ "type-safe",
12
+ "sqlite",
13
+ "bun-sqlite",
14
+ "embedded",
15
+ "adapter",
16
+ "driver"
17
+ ],
18
+ "homepage": "https://github.com/vibeorm/vibeorm/tree/master/packages/adapter-sqlite#readme",
19
+ "bugs": {
20
+ "url": "https://github.com/vibeorm/vibeorm/issues"
21
+ },
22
+ "repository": {
23
+ "type": "git",
24
+ "url": "https://github.com/vibeorm/vibeorm.git",
25
+ "directory": "packages/adapter-sqlite"
26
+ },
27
+ "license": "MIT",
28
+ "author": "VibeORM contributors",
29
+ "type": "module",
30
+ "exports": {
31
+ ".": {
32
+ "types": "./dist/index.d.ts",
33
+ "default": "./dist/index.js"
34
+ }
35
+ },
36
+ "files": [
37
+ "dist",
38
+ "README.md"
39
+ ],
40
+ "engines": {
41
+ "bun": ">=1.2.0"
42
+ },
43
+ "dependencies": {
44
+ "@vibeorm/runtime": "2.0.0-alpha.1",
45
+ "@vibeorm/schema": "2.0.0-alpha.1"
46
+ },
47
+ "publishConfig": {
48
+ "access": "public"
49
+ }
50
+ }