@vibeorm/adapter-bun 2.1.1 → 2.2.0

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 CHANGED
@@ -38,12 +38,16 @@ await db.$disconnect();
38
38
  | `stmtCacheMax` | `number` | `1000` | Maximum entries in the synthetic template cache (LRU) |
39
39
  | `planCacheMode` | `"auto" \| "force_custom_plan" \| "force_generic_plan"` | `"force_custom_plan"` | PostgreSQL `plan_cache_mode` for every connection |
40
40
 
41
- `planCacheMode` and `statementTimeout` travel in the `options` startup parameter appended to the connection URL, so they apply to every pooled connection without a per-query round trip. Client-side libpq options such as `connect_timeout` must never go in the URL — bun:sql forwards unrecognised URL parameters to the server, which rejects them. (The same forwarding is how a server setting reaches every connection: `?jit=off` on the URL disables JIT compilation for the pool — see `docs/dialect-notes.md` "PostgreSQL JIT and statistics".)
41
+ `planCacheMode` and `statementTimeout` merge into one `options` startup parameter, with adapter settings taking precedence over matching URL settings. Other URL settings are preserved. With PG* environment variables and no URL, the adapter sends the same startup options through Bun's `connection` constructor option. Client-side libpq options such as `connect_timeout` must never go in the URL — bun:sql forwards unrecognised URL parameters to the server, which rejects them. (The same forwarding is how a server setting reaches every connection: `?jit=off` on the URL disables JIT compilation for the pool — see `docs/dialect-notes.md` "PostgreSQL JIT and statistics".)
42
+
43
+ `connectionTimeout` does **not** bound waiting for a busy pool connection. The adapter therefore declares `budgets.acquireTimeout: false`. Newer Bun versions support cancellable explicit reservations, but implicit query and transaction checkout does not expose the same guarantee across supported versions. There is no timer race that leaves an abandoned checkout running.
42
44
 
43
45
  `Date` parameters are spelled as UTC ISO text on both paths: bun:sql's own serializer for a `date`-typed parameter is `Date#toString()`, which the server rejects in every host time zone. Zone-less columns (`@db.Timestamp(n)`, `@db.Date`) therefore hold the UTC wall-clock on write — the contract shared with node-postgres, PGlite and Prisma. On read, bun:sql is UTC from **Bun 1.4.1**; earlier Bun versions parse zone-less timestamp text as host-local time (1.3.x: scalars on parameterless statements and every array element; 1.4.0: array elements), and bun:sql has no per-query parser hook the adapter could use to correct it. On Bun < 1.4.1 keep the process on `TZ=UTC` when the schema has zone-less columns, or upgrade (`docs/dialect-notes.md` "DateTime without time zone on postgres").
44
46
 
45
47
  ## Raw parameters
46
48
 
49
+ Trusted parameterless SQL scripts remain supported. The raw result contains the final command's rows and affected-row count; preceding commands still execute once. Empty final DDL results remain empty. The first ORM query observes Bun's JSON wire format. A failed or unrecognized observation rejects that operation before its user statement is sent; a later call can probe again on a healthy connection.
50
+
47
51
  bun:sql types every parameter by the OID the server infers for its slot, and for a `json`/`jsonb` slot it JSON-encodes **whatever JavaScript value is bound** — an object becomes the document, and a string that already holds JSON text becomes a JSON *string* (double-encoded). node-postgres sends a string as text regardless of the slot, so the same raw statement stores the document there. Measured on Bun 1.4.3 / PostgreSQL 18 (`tests/raw-jsonb.live.test.ts` here and in `@vibeorm/adapter-pg`):
48
52
 
49
53
  | `$executeRaw` … `VALUES (${value}::jsonb)` | adapter-bun stores | adapter-pg stores |
@@ -78,13 +82,17 @@ This is a postgres-dialect adapter, so the full capability set is available: `RE
78
82
 
79
83
  ## Transactions
80
84
 
81
- A top-level `transaction()` without options uses `sql.begin()` and lets bun:sql drive `BEGIN`/`COMMIT`. With `isolationLevel` or `timeout` the adapter reserves one connection and issues the statements itself, because `begin()` takes no such options.
85
+ A top-level `transaction()` without options uses `sql.begin()` and lets bun:sql drive `BEGIN`/`COMMIT`. With `isolationLevel`, `timeout` or `deadline` the adapter reserves one connection and issues the statements itself, because `begin()` takes no such options.
82
86
 
83
87
  Nested transactions become savepoints, chosen by probing the handle:
84
88
 
85
89
  - Modern bun:sql exposes `savepoint(fn)` on the in-transaction handle, and the adapter uses it. `begin()` is never called inside a transaction — it throws there ("use savepoint() instead").
86
90
  - Reserved connections (and older bun:sql builds) expose no `savepoint` helper, so the adapter issues `SAVEPOINT` / `RELEASE SAVEPOINT` / `ROLLBACK TO SAVEPOINT` SQL by hand, with a name counter shared across the whole top-level transaction.
87
91
 
92
+ Nested handles share the root budget and expire when their own callback finishes. Deadline-bearing statements are serialized on the connection, so each checks the remaining time after earlier work completes. Server-cancellation mode installs a fresh `statement_timeout` before each adapter statement and before COMMIT. This does not cancel JavaScript callbacks, network waits or pool acquisition. Trusted raw SQL can change server settings, and a multi-command script applies PostgreSQL's timeout separately to its commands; it is not a hard wall-clock limit for the whole script. Use individual adapter calls when the total deadline must be checked between commands.
93
+
94
+ If native savepoint recovery cannot be confirmed, the whole transaction is poisoned. Catching that error cannot permit further statements or a successful root commit. A lost COMMIT reply or failed rollback reports `meta.outcome: "unknown"`; no query or transaction callback is replayed. A reserved connection whose root rollback fails is closed rather than returned to the pool.
95
+
88
96
  Raw transaction control (`BEGIN` / `COMMIT` / `ROLLBACK` through the raw path, as `@vibeorm/migrate` does) reserves one connection for the duration: bun:sql refuses transaction control through `sql.unsafe()` on a pooled instance (`ERR_POSTGRES_UNSAFE_TRANSACTION`). Concurrent raw transactions on a single adapter are unsupported.
89
97
 
90
98
  ## Error mapping
@@ -0,0 +1,6 @@
1
+ /** Migration-only driver instance; never force-close the application's pool. */
2
+ export declare const SESSION_CONNECTION: Readonly<{
3
+ max: number;
4
+ closeGraceSeconds: number;
5
+ }>;
6
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,eAAO,MAAM,kBAAkB,EAAE,QAAQ,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,iBAAiB,EAAE,MAAM,CAAA;CAAE,CAKlF,CAAC"}
@@ -29,7 +29,7 @@ export declare function buildStartupOptions(params: {
29
29
  planCacheMode: PlanCacheMode;
30
30
  statementTimeout?: number;
31
31
  }): string | undefined;
32
- /** Append the `options` startup parameter to a connection URL. */
32
+ /** Merge startup settings into one `options` key; adapter settings take precedence. */
33
33
  export declare function applyStartupOptions(params: {
34
34
  url: string;
35
35
  startupOptions: string;
@@ -1 +1 @@
1
- {"version":3,"file":"connection-url.d.ts","sourceRoot":"","sources":["../src/connection-url.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH;;;;;GAKG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,mBAAmB,GAAG,oBAAoB,CAAC;AAEhF;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE;IAC1C,aAAa,EAAE,aAAa,CAAC;IAC7B,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B,GAAG,MAAM,GAAG,SAAS,CAerB;AAED,kEAAkE;AAClE,wBAAgB,mBAAmB,CAAC,MAAM,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAI3F"}
1
+ {"version":3,"file":"connection-url.d.ts","sourceRoot":"","sources":["../src/connection-url.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH;;;;;GAKG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,mBAAmB,GAAG,oBAAoB,CAAC;AAEhF;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE;IAC1C,aAAa,EAAE,aAAa,CAAC;IAC7B,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B,GAAG,MAAM,GAAG,SAAS,CAerB;AAED,uFAAuF;AACvF,wBAAgB,mBAAmB,CAAC,MAAM,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAS3F"}
@@ -0,0 +1,7 @@
1
+ import { SQL } from "bun";
2
+ /** Internal constructor boundary; keeps the driver double out of the public adapter API. */
3
+ export declare function createBunSql(params: {
4
+ url?: string;
5
+ options: Record<string, unknown>;
6
+ }): SQL;
7
+ //# sourceMappingURL=driver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"driver.d.ts","sourceRoot":"","sources":["../src/driver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAE1B,4FAA4F;AAC5F,wBAAgB,YAAY,CAAC,MAAM,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GAAG,GAAG,CAE5F"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAEV,eAAe,EAIhB,MAAM,kBAAkB,CAAC;AAe1B,OAAO,EAA4C,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAuEnG,sCAAsC;AACtC,MAAM,MAAM,iBAAiB,GAAG;IAC9B,oGAAoG;IACpG,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,+CAA+C;IAC/C,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC;;;OAGG;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IACpC;;;;;;OAMG;IACH,QAAQ,CAAC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IACtC,2EAA2E;IAC3E,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,uFAAuF;IACvF,QAAQ,CAAC,aAAa,CAAC,EAAE,aAAa,CAAC;CACxC,CAAC;AA+CF;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,eAAe,CA0bvE;AAgBD,OAAO,EACL,wBAAwB,EACxB,oBAAoB,EACpB,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACpF,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC/E,YAAY,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACzF,YAAY,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1E,YAAY,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EACL,mBAAmB,EACnB,cAAc,EACd,6BAA6B,EAC7B,8BAA8B,EAC9B,yBAAyB,GAC1B,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAElE,OAAO,EACL,sBAAsB,EACtB,uBAAuB,EACvB,0BAA0B,EAC1B,sBAAsB,EACtB,sBAAsB,EACtB,wBAAwB,EACxB,8BAA8B,EAC9B,2BAA2B,GAC5B,MAAM,8BAA8B,CAAC;AACtC,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,KAAK,EAEV,eAAe,EAIhB,MAAM,kBAAkB,CAAC;AAiB1B,OAAO,EAA4C,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAyEnG,sCAAsC;AACtC,MAAM,MAAM,iBAAiB,GAAG;IAC9B,oGAAoG;IACpG,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,+CAA+C;IAC/C,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC;;;OAGG;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IACpC;;;;;;OAMG;IACH,QAAQ,CAAC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IACtC,2EAA2E;IAC3E,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,uFAAuF;IACvF,QAAQ,CAAC,aAAa,CAAC,EAAE,aAAa,CAAC;CACxC,CAAC;AA8CF;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,eAAe,CA2gBvE;AAgCD,OAAO,EACL,wBAAwB,EACxB,oBAAoB,EACpB,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACpF,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC/E,YAAY,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACzF,YAAY,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1E,YAAY,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EACL,mBAAmB,EACnB,cAAc,EACd,6BAA6B,EAC7B,8BAA8B,EAC9B,yBAAyB,GAC1B,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAElE,OAAO,EACL,sBAAsB,EACtB,uBAAuB,EACvB,0BAA0B,EAC1B,sBAAsB,EACtB,sBAAsB,EACtB,wBAAwB,EACxB,8BAA8B,EAC9B,2BAA2B,GAC5B,MAAM,8BAA8B,CAAC;AACtC,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC"}
package/dist/index.js CHANGED
@@ -1,9 +1,22 @@
1
1
  // @bun
2
- // packages/adapter-bun/src/index.ts
2
+ // packages/adapter-bun/src/driver.ts
3
3
  var {SQL } = globalThis.Bun;
4
+ function createBunSql(params) {
5
+ return params.url === undefined ? new SQL(params.options) : new SQL(params.url, params.options);
6
+ }
7
+
8
+ // packages/adapter-bun/src/config.ts
9
+ var SESSION_CONNECTION = Object.freeze({
10
+ max: 1,
11
+ closeGraceSeconds: 0.001
12
+ });
13
+
14
+ // packages/adapter-bun/src/index.ts
4
15
  import { postgresDialect, renderDiagnostic } from "@vibeorm/sql";
5
16
  import {
17
+ runPinnedSession,
6
18
  createSavepointScope,
19
+ savepointRollbackFailedError,
7
20
  engineStatementBudgetMs,
8
21
  isTransactionDeadlineError,
9
22
  runNestedSavepoint,
@@ -13,6 +26,7 @@ import {
13
26
  transactionOutcomeUnknownError,
14
27
  validateTransactionDeadline
15
28
  } from "@vibeorm/runtime/adapter-kit";
29
+ import { VibeError as VibeError6 } from "@vibeorm/schema";
16
30
 
17
31
  // packages/adapter-bun/src/connection-url.ts
18
32
  import { VibeError } from "@vibeorm/schema";
@@ -34,9 +48,14 @@ function buildStartupOptions(params) {
34
48
  return parts.length === 0 ? undefined : parts.join(" ");
35
49
  }
36
50
  function applyStartupOptions(params) {
37
- const { url, startupOptions } = params;
38
- const separator = url.includes("?") ? "&" : "?";
39
- return `${url}${separator}options=${encodeURIComponent(startupOptions)}`;
51
+ if (!URL.canParse(params.url)) {
52
+ throw new VibeError({ code: "VIBE_VALIDATION", message: "invalid PostgreSQL connection URL" });
53
+ }
54
+ const url = new URL(params.url);
55
+ const merged = [...url.searchParams.getAll("options"), params.startupOptions].filter(Boolean).join(" ");
56
+ url.searchParams.set("options", merged);
57
+ url.search = url.searchParams.toString().replace(/\+/g, "%20");
58
+ return url.toString();
40
59
  }
41
60
 
42
61
  // packages/adapter-bun/src/errors.ts
@@ -311,6 +330,7 @@ function createTemplateCache(params) {
311
330
 
312
331
  // packages/adapter-bun/src/transaction-sql.ts
313
332
  import { VibeError as VibeError5 } from "@vibeorm/schema";
333
+ import { refuseNestedTransactionOptions } from "@vibeorm/runtime/adapter-kit";
314
334
  var ISOLATION_LEVEL_SQL = Object.freeze({
315
335
  ReadCommitted: "READ COMMITTED",
316
336
  RepeatableRead: "REPEATABLE READ",
@@ -340,32 +360,6 @@ function classifyRawTransactionControl(params) {
340
360
  return "close";
341
361
  return null;
342
362
  }
343
- function refuseNestedTransactionOptions(params) {
344
- const { options, provider } = params;
345
- if (options === undefined)
346
- return;
347
- const passed = [];
348
- if (options.isolationLevel !== undefined)
349
- passed.push("isolationLevel");
350
- if (options.timeout !== undefined)
351
- passed.push("timeout");
352
- if (options.deadline !== undefined)
353
- passed.push("deadline");
354
- if (passed.length === 0)
355
- return;
356
- const meta = { provider, nested: true };
357
- if (options.isolationLevel !== undefined)
358
- meta.isolationLevel = options.isolationLevel;
359
- if (options.timeout !== undefined)
360
- meta.timeout = options.timeout;
361
- if (options.deadline !== undefined)
362
- meta.deadline = options.deadline;
363
- throw new VibeError5({
364
- code: "VIBE_VALIDATION",
365
- 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, a nested timeout is not enforceable, and a nested deadline would need its own session setting on a connection it does not own (it inherits the top-level one instead); pass options on the top-level $transaction`,
366
- meta
367
- });
368
- }
369
363
 
370
364
  // packages/adapter-bun/src/index.ts
371
365
  import { createSavepointCounter, nextSavepointName } from "@vibeorm/runtime/adapter-kit";
@@ -391,7 +385,7 @@ class CallbackError extends Error {
391
385
  var DIALECT = "postgres";
392
386
  var PROVIDER = "postgresql";
393
387
  var BUDGETS = Object.freeze({
394
- acquireTimeout: true,
388
+ acquireTimeout: false,
395
389
  statementTimeout: "all-statements",
396
390
  transactionDeadline: "cancel-running-statements"
397
391
  });
@@ -404,11 +398,35 @@ function bunAdapter(options) {
404
398
  let wireSettled = false;
405
399
  let wireProbe = null;
406
400
  let instance = null;
401
+ const deadlineTurns = new WeakMap;
402
+ function budgetTurn(params) {
403
+ const { source, budget, body, guard } = params;
404
+ const run = async () => {
405
+ if (params.cleanup === true)
406
+ return body();
407
+ budget?.assertUsable({ stage: params.stage ?? "statement" });
408
+ guard?.();
409
+ const ms = budget === undefined ? null : engineStatementBudgetMs({ budget });
410
+ if (ms !== null) {
411
+ await runMapped(() => source.unsafe(statementTimeoutStatement({ timeout: ms })));
412
+ budget?.assertUsable({ stage: params.stage ?? "statement" });
413
+ guard?.();
414
+ }
415
+ return body();
416
+ };
417
+ if (budget === undefined || budget.totalMs === null)
418
+ return run();
419
+ const result = (deadlineTurns.get(budget) ?? Promise.resolve()).then(run);
420
+ deadlineTurns.set(budget, result.then(() => {
421
+ return;
422
+ }, () => {
423
+ return;
424
+ }));
425
+ return result;
426
+ }
407
427
  let rawSession = null;
408
- function getSql() {
409
- if (instance !== null)
410
- return instance;
411
- const sqlOptions = { max: options?.max ?? 10 };
428
+ function createSqlInstance(params) {
429
+ const sqlOptions = { max: params.max };
412
430
  if (options?.connectionTimeout !== undefined) {
413
431
  sqlOptions.connectionTimeout = Math.max(1, Math.ceil(options.connectionTimeout / 1000));
414
432
  }
@@ -418,82 +436,115 @@ function bunAdapter(options) {
418
436
  });
419
437
  const baseUrl = options?.url ?? process.env.DATABASE_URL;
420
438
  const url = baseUrl === undefined || startupOptions === undefined ? baseUrl : applyStartupOptions({ url: baseUrl, startupOptions });
421
- instance = url === undefined ? new SQL(sqlOptions) : new SQL(url, sqlOptions);
439
+ if (url === undefined && startupOptions !== undefined) {
440
+ sqlOptions.connection = { options: startupOptions };
441
+ }
442
+ return createBunSql({ url, options: sqlOptions });
443
+ }
444
+ function getSql() {
445
+ instance ??= createSqlInstance({ max: options?.max ?? 10 });
422
446
  return instance;
423
447
  }
424
448
  async function probeJsonWire(source) {
425
449
  const probe = renderDiagnostic({ dialect: postgresDialect, query: "postgresJsonWire" });
426
- try {
427
- const rows = usePrepared ? await source(templates.getTemplate({ text: probe.text }).template) : await source.unsafe(probe.text, []);
428
- const probed = rows[0]?.probe;
429
- if (typeof probed === "object" && probed !== null)
430
- activeWire = WIRE_PARSED;
431
- } catch {} finally {
432
- wireSettled = true;
450
+ const rows = finalRows({ result: await runMapped(() => usePrepared ? source(templates.getTemplate({ text: probe.text }).template) : source.unsafe(probe.text, [])) });
451
+ const probed = rows[0]?.probe;
452
+ if (typeof probed === "object" && probed !== null && "__vibeorm" in probed && probed.__vibeorm === 1)
453
+ activeWire = WIRE_PARSED;
454
+ else if (typeof probed === "string" && /^\{\s*"__vibeorm"\s*:\s*1\s*\}$/.test(probed))
455
+ activeWire = WIRE_TEXT;
456
+ else {
457
+ throw new VibeError6({
458
+ code: "VIBE_ADAPTER",
459
+ message: "Bun returned an unrecognized JSON wire probe result; no ORM statement was sent",
460
+ meta: { reason: "json-wire-probe" }
461
+ });
433
462
  }
463
+ wireSettled = true;
434
464
  }
435
465
  async function runExecute(params) {
436
466
  if (!wireSettled) {
437
- wireProbe ??= probeJsonWire(params.source);
467
+ wireProbe ??= probeJsonWire(params.source).finally(() => {
468
+ wireProbe = null;
469
+ });
438
470
  await wireProbe;
439
471
  }
440
472
  const values = serializeParams({ values: params.values });
441
473
  if (usePrepared) {
442
474
  const prepared = templates.getTemplate({ text: params.text });
443
475
  const bound = bindTemplateValues({ text: params.text, indices: prepared.indices, values });
444
- return runMapped(() => params.source(prepared.template, ...bound));
476
+ return finalRows({ result: await runMapped(() => params.source(prepared.template, ...bound)) });
445
477
  }
446
- return runMapped(() => params.source.unsafe(params.text, values));
478
+ return finalRows({ result: await runMapped(() => params.source.unsafe(params.text, values)) });
447
479
  }
448
480
  async function runExecuteUnsafe(params) {
449
481
  const values = params.values === undefined ? undefined : serializeParamsRaw({ values: params.values });
450
- const rows = await runMapped(() => params.source.unsafe(params.text, values));
482
+ const rows = finalRows({ result: await runMapped(() => params.source.unsafe(params.text, values)) });
451
483
  return { rows, affectedRows: readAffectedRows({ rows }) };
452
484
  }
453
485
  function createAdapter(params) {
454
- const { source, parentMode, scope, budget } = params;
455
- async function applyEngineBudget() {
456
- if (budget === undefined)
457
- return;
458
- const ms = engineStatementBudgetMs({ budget });
459
- if (ms === null)
460
- return;
461
- await runMapped(() => source.unsafe(statementTimeoutStatement({ timeout: ms })));
486
+ const { source, parentMode, scope, budget, lifetime } = params;
487
+ function assertHandle() {
488
+ budget?.assertUsable({ stage: "statement" });
489
+ if (lifetime?.active === false) {
490
+ throw new VibeError6({
491
+ code: "VIBE_TRANSACTION",
492
+ message: "this savepoint callback has finished; its transaction handle has expired",
493
+ meta: { reason: "expired" }
494
+ });
495
+ }
496
+ if (scope.state.poisoned !== null)
497
+ throw scope.state.poisoned;
462
498
  }
499
+ const guardedSource = Object.assign((strings, ...values) => budgetTurn({ source, budget, guard: assertHandle, body: () => source(strings, ...values) }), { unsafe: (text, values) => budgetTurn({ source, budget, guard: assertHandle, body: () => source.unsafe(text, values) }) });
463
500
  async function transactionViaSavepoint(fn, nestedOptions) {
464
501
  refuseNestedTransactionOptions({ options: nestedOptions, provider: PROVIDER });
502
+ assertHandle();
465
503
  budget?.assertUsable({ stage: "nested" });
466
504
  const transactional = source;
505
+ const runChild = async (child, childSource) => {
506
+ assertHandle();
507
+ const childLifetime = { active: true };
508
+ try {
509
+ return await fn(createAdapter({ source: childSource, parentMode: "tx", scope: child, budget, lifetime: childLifetime }));
510
+ } finally {
511
+ childLifetime.active = false;
512
+ }
513
+ };
467
514
  const driverSavepoint = transactional.savepoint?.bind(transactional);
468
515
  if (driverSavepoint !== undefined) {
469
516
  return runNestedSavepoint({
470
517
  scope,
471
518
  body: async (child) => {
519
+ let callbackFailure;
472
520
  try {
473
521
  return await driverSavepoint(async (savepointSql) => {
474
- const nested = createAdapter({
475
- source: savepointSql,
476
- parentMode: "tx",
477
- scope: child
478
- });
479
522
  try {
480
- return await fn(nested);
523
+ return await runChild(child, savepointSql);
481
524
  } catch (error) {
482
- throw new CallbackError(error);
525
+ callbackFailure = new CallbackError(error);
526
+ throw callbackFailure;
483
527
  }
484
528
  });
485
529
  } catch (error) {
486
- if (error instanceof CallbackError)
487
- throw error.inner;
488
- throw mapBunDriverError({ error });
530
+ if (callbackFailure !== undefined && error === callbackFailure)
531
+ throw callbackFailure.inner;
532
+ const poisoned = callbackFailure !== undefined ? savepointRollbackFailedError({ cause: callbackFailure.inner, rollbackFailure: mapBunDriverError({ error }) }) : unknownOutcome({ cause: mapBunDriverError({ error }), reason: "savepoint-outcome-unknown" });
533
+ scope.state.poisoned = poisoned;
534
+ throw poisoned;
489
535
  }
490
536
  }
491
537
  });
492
538
  }
493
539
  return runNestedSavepoint({
494
540
  scope,
495
- execute: (statement) => runMapped(() => transactional.unsafe(statement)),
496
- body: (child) => fn(createAdapter({ source: transactional, parentMode: "tx", scope: child, budget }))
541
+ execute: (statement) => budgetTurn({
542
+ source,
543
+ budget,
544
+ cleanup: statement.startsWith("ROLLBACK TO SAVEPOINT "),
545
+ body: () => runMapped(() => transactional.unsafe(statement))
546
+ }),
547
+ body: (child) => runChild(child, transactional)
497
548
  });
498
549
  }
499
550
  async function transactionViaPool(fn, transactionOptions) {
@@ -505,38 +556,43 @@ function bunAdapter(options) {
505
556
  });
506
557
  if (transactionOptions?.isolationLevel === undefined && transactionOptions?.timeout === undefined && transactionOptions?.deadline === undefined) {
507
558
  const budget3 = startTransactionBudget({ provider: PROVIDER });
559
+ const txScope2 = createSavepointScope();
560
+ let callbackFailure;
508
561
  try {
509
562
  const result = await pool.begin(async (txSql) => {
510
- const txScope = createSavepointScope();
511
563
  const txAdapter = createAdapter({
512
564
  source: txSql,
513
565
  parentMode: "tx",
514
- scope: txScope,
566
+ scope: txScope2,
515
567
  budget: budget3
516
568
  });
517
569
  try {
518
- return await runRootScope({ scope: txScope, body: () => fn(txAdapter) });
570
+ return await runRootScope({ scope: txScope2, body: () => fn(txAdapter) });
519
571
  } catch (error) {
520
- throw new CallbackError(error);
572
+ callbackFailure = new CallbackError(error);
573
+ throw callbackFailure;
521
574
  }
522
575
  });
523
576
  budget3.close({ outcome: "committed" });
524
577
  return result;
525
578
  } catch (error) {
526
- budget3.close({ outcome: "rolled-back" });
527
- if (error instanceof CallbackError)
528
- throw error.inner;
529
- throw mapBunDriverError({ error });
579
+ const knownRollback = callbackFailure !== undefined && error === callbackFailure && txScope2.state.poisoned === null;
580
+ budget3.close({ outcome: knownRollback ? "rolled-back" : "unknown" });
581
+ if (callbackFailure !== undefined && error === callbackFailure)
582
+ throw callbackFailure.inner;
583
+ throw unknownOutcome({ cause: callbackFailure?.inner ?? mapBunDriverError({ error }) });
530
584
  }
531
585
  }
532
586
  const timeoutText = transactionOptions.timeout === undefined ? undefined : statementTimeoutStatement({ timeout: transactionOptions.timeout });
533
587
  const reserved = await runMapped(() => pool.reserve());
534
588
  const budget2 = startTransactionBudget({ options: transactionOptions, provider: PROVIDER });
589
+ const txScope = createSavepointScope();
590
+ let commitSent = false;
591
+ let discard = false;
535
592
  try {
536
593
  await runMapped(() => reserved.unsafe(beginStatement({ isolationLevel: transactionOptions.isolationLevel })));
537
594
  if (timeoutText !== undefined)
538
595
  await runMapped(() => reserved.unsafe(timeoutText));
539
- const txScope = createSavepointScope();
540
596
  const txAdapter = createAdapter({
541
597
  source: reserved,
542
598
  parentMode: "tx",
@@ -544,15 +600,18 @@ function bunAdapter(options) {
544
600
  budget: budget2
545
601
  });
546
602
  const result = await runRootScope({ scope: txScope, body: () => fn(txAdapter) });
547
- budget2.assertUsable({ stage: "commit" });
548
- await runMapped(() => reserved.unsafe("COMMIT"));
603
+ await budgetTurn({ source: reserved, budget: budget2, stage: "commit", body: () => {
604
+ commitSent = true;
605
+ return runMapped(() => reserved.unsafe("COMMIT"));
606
+ } });
549
607
  budget2.close({ outcome: "committed" });
550
608
  return result;
551
609
  } catch (error) {
552
610
  try {
553
611
  await reserved.unsafe("ROLLBACK");
554
- budget2.close({ outcome: "rolled-back" });
612
+ budget2.close({ outcome: commitSent || txScope.state.poisoned !== null ? "unknown" : "rolled-back" });
555
613
  } catch {
614
+ discard = true;
556
615
  budget2.close({ outcome: "unknown" });
557
616
  if (budget2.totalMs !== null && isTransactionDeadlineError(error)) {
558
617
  throw transactionOutcomeUnknownError({
@@ -562,9 +621,14 @@ function bunAdapter(options) {
562
621
  });
563
622
  }
564
623
  }
624
+ if (budget2.outcome === "unknown" && txScope.state.poisoned === null)
625
+ throw unknownOutcome({ cause: error });
565
626
  throw error;
566
627
  } finally {
567
- reserved.release();
628
+ if (discard)
629
+ await runMapped(() => reserved.close());
630
+ else
631
+ reserved.release();
568
632
  }
569
633
  }
570
634
  return {
@@ -575,20 +639,20 @@ function bunAdapter(options) {
575
639
  return activeWire;
576
640
  },
577
641
  async execute(execParams) {
642
+ assertHandle();
578
643
  const turn = scopeTurn({ scope });
579
644
  if (turn !== undefined)
580
645
  await turn;
581
- budget?.assertUsable({ stage: "statement" });
582
- await applyEngineBudget();
583
- return runExecute({ source, ...execParams });
646
+ assertHandle();
647
+ return runExecute({ source: guardedSource, ...execParams });
584
648
  },
585
649
  async executeUnsafe(execParams) {
650
+ assertHandle();
586
651
  const turn = scopeTurn({ scope });
587
652
  if (turn !== undefined)
588
653
  await turn;
589
- budget?.assertUsable({ stage: "statement" });
590
- await applyEngineBudget();
591
- return runExecuteUnsafe({ source, ...execParams });
654
+ assertHandle();
655
+ return runExecuteUnsafe({ source: guardedSource, ...execParams });
592
656
  },
593
657
  async transaction(fn, transactionOptions) {
594
658
  return parentMode === "pool" ? transactionViaPool(fn, transactionOptions) : transactionViaSavepoint(fn, transactionOptions);
@@ -624,6 +688,20 @@ function bunAdapter(options) {
624
688
  get wire() {
625
689
  return activeWire;
626
690
  },
691
+ async withSession({ run }) {
692
+ const sessionPool = createSqlInstance({ max: SESSION_CONNECTION.max });
693
+ const close = () => runMapped(() => sessionPool.close({ timeout: SESSION_CONNECTION.closeGraceSeconds }));
694
+ const reserved = await runMapped(() => sessionPool.reserve()).catch(async (cause) => {
695
+ await close();
696
+ throw cause;
697
+ });
698
+ return runPinnedSession({
699
+ run,
700
+ execute: async (query) => (await runExecuteUnsafe({ source: reserved, ...query })).rows,
701
+ isLost: (error) => error instanceof VibeError6 && (typeof error.meta.sqlstate !== "string" || error.meta.sqlstate.startsWith("08") || ["57P01", "57P02", "57P03"].includes(error.meta.sqlstate)),
702
+ release: close
703
+ });
704
+ },
627
705
  async execute(params) {
628
706
  return poolAdapter().execute(params);
629
707
  },
@@ -688,6 +766,20 @@ function readAffectedRows(params) {
688
766
  return rows.affectedRows;
689
767
  return rows.length;
690
768
  }
769
+ function finalRows(params) {
770
+ const { result } = params;
771
+ if (result === null)
772
+ return [];
773
+ return Array.isArray(result[0]) ? result.at(-1) ?? [] : result;
774
+ }
775
+ function unknownOutcome(params) {
776
+ return new VibeError6({
777
+ code: "VIBE_TRANSACTION",
778
+ message: "Bun could not confirm transaction recovery or completion; the outcome is unknown. Nothing is retried automatically.",
779
+ meta: { reason: params.reason ?? "transaction-outcome-unknown", outcome: "unknown" },
780
+ cause: params.cause
781
+ });
782
+ }
691
783
  export {
692
784
  validateTransactionDeadline2 as validateTransactionDeadline,
693
785
  transactionOutcomeUnknownError2 as transactionOutcomeUnknownError,
@@ -718,4 +810,4 @@ export {
718
810
  BUN_SQLSTATE_ERROR_CODES
719
811
  };
720
812
 
721
- //# debugId=18C3745F22387C6364756E2164756E21
813
+ //# debugId=F30E26CAE4DC1AC464756E2164756E21
package/dist/index.js.map CHANGED
@@ -1,15 +1,17 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../src/index.ts", "../src/connection-url.ts", "../src/errors.ts", "../src/params.ts", "../src/template-cache.ts", "../src/transaction-sql.ts"],
3
+ "sources": ["../src/driver.ts", "../src/config.ts", "../src/index.ts", "../src/connection-url.ts", "../src/errors.ts", "../src/params.ts", "../src/template-cache.ts", "../src/transaction-sql.ts"],
4
4
  "sourcesContent": [
5
- "/**\n * @vibeorm/adapter-bun — bun:sql (PostgreSQL) adapter for VibeORM v2.\n *\n * Uses Bun's built-in SQL driver and its internal connection pool. Owns\n * optional prepared statements (synthetic tagged templates), transactions\n * (nested → savepoints), array-literal parameter formatting and driver-error\n * mapping. Only `VibeError` ever escapes.\n */\n\nimport { SQL } from \"bun\";\nimport { postgresDialect, renderDiagnostic } from \"@vibeorm/sql\";\nimport type {\n AdapterBudgetSupport,\n DatabaseAdapter,\n QueryResult,\n TransactionOptions,\n WireFidelity,\n} from \"@vibeorm/runtime\";\nimport {\n createSavepointScope,\n engineStatementBudgetMs,\n isTransactionDeadlineError,\n runNestedSavepoint,\n runRootScope,\n type SavepointScope,\n scopeTurn,\n startTransactionBudget,\n type TransactionBudget,\n transactionOutcomeUnknownError,\n validateTransactionDeadline,\n} from \"@vibeorm/runtime/adapter-kit\";\nimport type { Dialect, Provider } from \"@vibeorm/schema\";\nimport { applyStartupOptions, buildStartupOptions, type PlanCacheMode } from \"./connection-url.ts\";\nimport { mapBunDriverError, runMapped } from \"./errors.ts\";\nimport { serializeParams, serializeParamsRaw, toPgArrayLiteral } from \"./params.ts\";\nimport { bindTemplateValues, createTemplateCache } from \"./template-cache.ts\";\nimport {\n beginStatement,\n classifyRawTransactionControl,\n refuseNestedTransactionOptions,\n statementTimeoutStatement,\n} from \"./transaction-sql.ts\";\n\n// ─── Minimal bun:sql surface ──────────────────────────────────────\n\n/**\n * What bun:sql resolves a query to: the row array, with driver metadata\n * (`count`, `command`) attached as properties.\n */\ntype BunRows = Record<string, unknown>[] & { count?: number; affectedRows?: number };\n\n/** Anything that executes SQL through bun:sql. */\ntype BunExecutor = {\n (strings: TemplateStringsArray, ...values: unknown[]): Promise<BunRows>;\n unsafe(text: string, values?: unknown[]): Promise<BunRows>;\n};\n\n/**\n * The handle passed to `sql.begin(cb)`. Modern bun:sql exposes `savepoint(fn)`\n * for sub-transactions; `begin()` throws inside a transaction (\"use\n * savepoint() instead\"), so it is never called here. Older builds lack\n * `savepoint`, which is why it is optional and probed at runtime.\n */\ntype BunTransaction = BunExecutor & {\n savepoint?: <T>(fn: (sp: BunTransaction) => Promise<T>) => Promise<T>;\n};\n\n/** A connection checked out with `sql.reserve()` — no `savepoint`, must be released. */\ntype BunReserved = BunExecutor & { release(): void };\n\n/** The pool-level bun:sql client. */\ntype BunInstance = BunExecutor & {\n begin<T>(fn: (tx: BunTransaction) => Promise<T>): Promise<T>;\n reserve(): Promise<BunReserved>;\n close(): Promise<void>;\n};\n\n/** Any bun:sql handle the adapter can be built on top of. */\ntype BunSource = BunInstance | BunReserved | BunTransaction;\n\n/**\n * Whether a handle is the pool (can open a real transaction) or is already\n * inside one (must nest through savepoints).\n */\ntype ParentMode = \"pool\" | \"tx\";\n\n/**\n * Wrapper that marks an error as \"thrown by the user's transaction callback\",\n * so it can be rethrown untouched instead of being mapped as a driver failure\n * after bun:sql has passed it back out of `begin()` / `savepoint()`.\n */\nclass CallbackError extends Error {\n readonly inner: unknown;\n\n constructor(inner: unknown) {\n super(\"vibeorm: transaction callback failed\");\n this.name = \"CallbackError\";\n this.inner = inner;\n }\n}\n\n// ─── Options ──────────────────────────────────────────────────────\n\n/** Options for {@link bunAdapter}. */\nexport type BunAdapterOptions = {\n /** PostgreSQL connection URL. Defaults to `process.env.DATABASE_URL`, then bun's `PG*` env vars. */\n readonly url?: string;\n /** Maximum pooled connections (default 10). */\n readonly max?: number;\n /**\n * Pool-wide `statement_timeout` in milliseconds, sent as a startup parameter\n * so every connection inherits it. A per-transaction `timeout` overrides it\n * for that transaction.\n */\n readonly statementTimeout?: number;\n /**\n * Milliseconds to wait for a connection to be established. Passed to bun:sql\n * as `connectionTimeout` (which expects **seconds**; converted here).\n */\n readonly connectionTimeout?: number;\n /**\n * Execute ORM-path queries as tagged templates, creating named prepared\n * statements (default false). Saves planning time but lets PostgreSQL fall\n * back to a generic plan after ~5 executions — leave off unless profiling\n * says otherwise. bun:sql's `prepare: false` constructor option is never set\n * (it triggers a known bun:sql performance regression).\n */\n readonly preparedStatements?: boolean;\n /** Maximum entries in the synthetic template cache (default 1000, LRU). */\n readonly stmtCacheMax?: number;\n /** PostgreSQL `plan_cache_mode` for every connection (default `force_custom_plan`). */\n readonly planCacheMode?: PlanCacheMode;\n};\n\n// ─── Adapter ──────────────────────────────────────────────────────\n\nconst DIALECT: Dialect = \"postgres\";\nconst PROVIDER: Provider = \"postgresql\";\n\n/**\n * bun:sql wire (board #30, live-verified on both execute paths): timestamptz\n * → `Date`, int4/float8 → numbers. (int8 arrives as a string — BigInt\n * decoding is real work and never pruned.)\n *\n * The `json` half is NOT a constant, because bun:sql's answer changed between\n * Bun versions and this package supports a range of them: on Bun 1.3.14 the\n * tagged-template path parsed json/jsonb while `sql.unsafe` did not (board\n * #34 — declaring \"parsed\" there made the runtime prune the Json decoder and\n * leak raw strings), and on Bun 1.4.1 BOTH paths parse (leaving \"text\" makes\n * the guarded decode re-parse a stored top-level JSON string: `\"123\"` becomes\n * the number 123, `\"hello\"` throws). Either constant is wrong on one of those\n * runtimes, so the adapter OBSERVES its own driver once instead of guessing —\n * see {@link probeJsonWire}. {@link WIRE_TEXT} is the conservative claim it\n * starts from and keeps if the probe cannot run.\n */\n/**\n * Timing budgets this adapter genuinely enforces (EPIC 6).\n *\n * - `acquireTimeout: true` — {@link BunAdapterOptions.connectionTimeout} maps\n * to bun:sql's own `connectionTimeout` (\"maximum time to wait for a\n * connection to become available\"). Declared as a capability; the effective\n * value is whatever the option is set to.\n * - `statementTimeout: \"all-statements\"` — a real PostgreSQL server, so\n * `statement_timeout` cancels ANY over-long statement, writes included.\n * - `transactionDeadline: \"cancel-running-statements\"` — the remaining budget\n * is handed to the SERVER before each statement, so the database itself stops\n * work that would outlive the deadline.\n */\nconst BUDGETS: AdapterBudgetSupport = Object.freeze({\n acquireTimeout: true,\n statementTimeout: \"all-statements\",\n transactionDeadline: \"cancel-running-statements\",\n} as const);\n\nconst WIRE_TEXT: WireFidelity = Object.freeze({ dateTime: \"native\", json: \"text\", numbers: \"native\" } as const);\n\n/** The same wire, for a driver observed to hand back parsed json. */\nconst WIRE_PARSED: WireFidelity = Object.freeze({ dateTime: \"native\", json: \"parsed\", numbers: \"native\" } as const);\n\n/**\n * Create a VibeORM adapter backed by bun:sql.\n *\n * @example\n * ```ts\n * const adapter = bunAdapter({ url: process.env.DATABASE_URL, max: 10 });\n * await adapter.connect();\n * const rows = await adapter.execute({ text: 'SELECT * FROM \"User\" WHERE \"id\" = $1', values: [1] });\n * ```\n */\nexport function bunAdapter(options?: BunAdapterOptions): DatabaseAdapter {\n const usePrepared = options?.preparedStatements ?? false;\n const templates = createTemplateCache({ max: options?.stmtCacheMax ?? 1000 });\n\n /**\n * The wire claim this adapter currently makes. Starts conservative and is\n * replaced at most once, by {@link probeJsonWire}'s observation. Every handle\n * this factory builds — pool, transaction, savepoint, reserved session —\n * reads this one variable, so a transaction can never disagree with its\n * parent (the contract requires transactional adapters to carry the same\n * declaration).\n */\n let activeWire: WireFidelity = WIRE_TEXT;\n let wireSettled = false;\n let wireProbe: Promise<void> | null = null;\n\n let instance: BunInstance | null = null;\n\n /**\n * The reserved connection of an OPEN raw transaction — session affinity for\n * the raw path. @vibeorm/migrate wraps transactional DDL in literal `BEGIN`\n * / `COMMIT` / `ROLLBACK` sent through `executeUnsafe`; bun:sql refuses\n * transaction control through `sql.unsafe()` on a pooled instance\n * (`ERR_POSTGRES_UNSAFE_TRANSACTION`), so a pure `BEGIN` reserves one\n * connection, every raw statement until the matching `COMMIT`/`ROLLBACK`\n * rides it, and the close releases it. The ORM path (`execute`) and\n * `transaction()` stay on the pool — they never participate in a raw\n * transaction. Concurrent raw transactions on one adapter are unsupported\n * (they were driver-refused before this pinning existed).\n */\n let rawSession: BunReserved | null = null;\n\n function getSql(): BunInstance {\n if (instance !== null) return instance;\n\n const sqlOptions: Record<string, unknown> = { max: options?.max ?? 10 };\n if (options?.connectionTimeout !== undefined) {\n // bun:sql expects seconds; the VibeORM surface is milliseconds everywhere.\n sqlOptions.connectionTimeout = Math.max(1, Math.ceil(options.connectionTimeout / 1000));\n }\n\n const startupOptions = buildStartupOptions({\n planCacheMode: options?.planCacheMode ?? \"force_custom_plan\",\n statementTimeout: options?.statementTimeout,\n });\n const baseUrl = options?.url ?? process.env.DATABASE_URL;\n const url =\n baseUrl === undefined || startupOptions === undefined\n ? baseUrl\n : applyStartupOptions({ url: baseUrl, startupOptions });\n\n // Without a URL, bun:sql falls back to PG* environment variables (startup\n // options cannot be attached in that case).\n instance =\n url === undefined\n ? (new SQL(sqlOptions) as unknown as BunInstance)\n : (new SQL(url, sqlOptions) as unknown as BunInstance);\n return instance;\n }\n\n /**\n * Ask THIS driver, once, whether it parses json on the path the ORM reads\n * rows over — the same `execute` path, prepared or unsafe as configured, so\n * the answer describes the traffic the claim is applied to.\n *\n * Runs on the handle that is already in hand (pool, transaction or reserved\n * session): a `SELECT` is harmless inside a transaction, and probing the pool\n * from inside one could deadlock an adapter configured with `max: 1`.\n * Failure is not fatal — the conservative `WIRE_TEXT` claim stands, the\n * caller's own statement reports the real error, and the probe never runs\n * again.\n */\n async function probeJsonWire(source: BunExecutor): Promise<void> {\n const probe = renderDiagnostic({ dialect: postgresDialect, query: \"postgresJsonWire\" });\n try {\n const rows = usePrepared\n ? await source(templates.getTemplate({ text: probe.text }).template)\n : await source.unsafe(probe.text, []);\n const probed = rows[0]?.probe;\n if (typeof probed === \"object\" && probed !== null) activeWire = WIRE_PARSED;\n } catch {\n /* undeclared beats wrongly declared — keep WIRE_TEXT */\n } finally {\n wireSettled = true;\n }\n }\n\n async function runExecute(params: {\n source: BunExecutor;\n text: string;\n values: unknown[];\n }): Promise<Record<string, unknown>[]> {\n // One extra round trip on the first ORM query of this adapter's life; a\n // single boolean test on every one after it. It must complete BEFORE the\n // first rows are handed back, because the runtime reads `wire` to build\n // that read's decode plan.\n if (!wireSettled) {\n wireProbe ??= probeJsonWire(params.source);\n await wireProbe;\n }\n const values = serializeParams({ values: params.values });\n if (usePrepared) {\n // F19: a tagged template binds POSITIONALLY, one value per gap — so the\n // values follow the placeholder ORDER found in the text (`$2, $1` binds\n // backwards otherwise, and a repeated `$1` needs its value twice).\n const prepared = templates.getTemplate({ text: params.text });\n const bound = bindTemplateValues({ text: params.text, indices: prepared.indices, values });\n return runMapped(() => params.source(prepared.template, ...bound));\n }\n return runMapped(() => params.source.unsafe(params.text, values));\n }\n\n async function runExecuteUnsafe(params: {\n source: BunExecutor;\n text: string;\n values?: unknown[];\n }): Promise<QueryResult> {\n const values = params.values === undefined ? undefined : serializeParamsRaw({ values: params.values });\n const rows = await runMapped(() => params.source.unsafe(params.text, values));\n return { rows, affectedRows: readAffectedRows({ rows }) };\n }\n\n /**\n * Build the adapter facade over any bun:sql handle. `parentMode` decides\n * whether a nested `transaction()` opens a real transaction or a savepoint;\n * `scope` is shared by reference across one top-level transaction, and the\n * savepoint gate serializes overlapping sibling savepoints (F14) on BOTH the\n * driver-managed and the manual path.\n */\n function createAdapter(params: {\n source: BunSource;\n parentMode: ParentMode;\n scope: SavepointScope;\n /** The enclosing transaction's budget; absent on the pool-level adapter. */\n budget?: TransactionBudget;\n }): DatabaseAdapter {\n const { source, parentMode, scope, budget } = params;\n\n /**\n * Hand the SERVER the remaining budget before a statement runs, when the\n * caller bought `\"cancel-running-statements\"`. `SET LOCAL` is\n * transaction-scoped, so PostgreSQL reverts it at COMMIT/ROLLBACK and the\n * connection goes back to the pool with its session settings intact. One\n * extra round trip per statement, only while a deadline is active.\n */\n async function applyEngineBudget(): Promise<void> {\n if (budget === undefined) return;\n const ms = engineStatementBudgetMs({ budget });\n if (ms === null) return;\n await runMapped(() => (source as BunTransaction).unsafe(statementTimeoutStatement({ timeout: ms })));\n }\n\n /** Nested transaction: a savepoint on the connection we are already on. */\n async function transactionViaSavepoint<T>(\n fn: (txAdapter: DatabaseAdapter) => Promise<T>,\n nestedOptions?: TransactionOptions,\n ): Promise<T> {\n refuseNestedTransactionOptions({ options: nestedOptions, provider: PROVIDER });\n budget?.assertUsable({ stage: \"nested\" });\n const transactional = source as BunTransaction;\n\n // Modern bun:sql: the in-transaction handle drives savepoints itself —\n // the gate then owns only the LIFETIME, not the SQL. Captured before the\n // callback because narrowing does not reach into a nested closure.\n const driverSavepoint = transactional.savepoint?.bind(transactional);\n if (driverSavepoint !== undefined) {\n return runNestedSavepoint({\n scope,\n body: async (child) => {\n try {\n return await driverSavepoint(async (savepointSql) => {\n const nested = createAdapter({\n source: savepointSql,\n parentMode: \"tx\",\n scope: child,\n });\n try {\n return await fn(nested);\n } catch (error) {\n throw new CallbackError(error);\n }\n });\n } catch (error) {\n if (error instanceof CallbackError) throw error.inner;\n throw mapBunDriverError({ error });\n }\n },\n });\n }\n\n // Reserved connections (and older bun:sql) expose no savepoint helper —\n // drive SAVEPOINT / RELEASE / ROLLBACK TO by hand.\n return runNestedSavepoint({\n scope,\n execute: (statement) => runMapped(() => transactional.unsafe(statement)),\n // The child shares the ROOT budget by reference: a savepoint never gets\n // an independent clock or session setting.\n body: (child) =>\n fn(createAdapter({ source: transactional, parentMode: \"tx\", scope: child, budget })),\n });\n }\n\n /** Top-level transaction on the pool. */\n async function transactionViaPool<T>(\n fn: (txAdapter: DatabaseAdapter) => Promise<T>,\n transactionOptions?: TransactionOptions,\n ): Promise<T> {\n const pool = source as BunInstance;\n\n // Refuse an unsupportable budget before any connection is taken.\n validateTransactionDeadline({\n options: transactionOptions,\n support: BUDGETS.transactionDeadline,\n provider: PROVIDER,\n });\n\n // Fast path: bun:sql drives BEGIN/COMMIT itself. A DEADLINE opts out of\n // it deliberately — the clock must start after the connection is in hand,\n // and only the reserved path below gives that seam.\n if (\n transactionOptions?.isolationLevel === undefined &&\n transactionOptions?.timeout === undefined &&\n transactionOptions?.deadline === undefined\n ) {\n // A budget with no deadline: it still closes the handle at the end, so\n // an escaped transaction client cannot run on a pooled connection.\n const budget = startTransactionBudget({ provider: PROVIDER });\n try {\n const result = await pool.begin(async (txSql) => {\n const txScope = createSavepointScope();\n const txAdapter = createAdapter({\n source: txSql,\n parentMode: \"tx\",\n scope: txScope,\n budget,\n });\n try {\n return await runRootScope({ scope: txScope, body: () => fn(txAdapter) });\n } catch (error) {\n throw new CallbackError(error);\n }\n });\n budget.close({ outcome: \"committed\" });\n return result;\n } catch (error) {\n // bun:sql owns this transaction's rollback and has already performed\n // it by the time control reaches here.\n budget.close({ outcome: \"rolled-back\" });\n if (error instanceof CallbackError) throw error.inner;\n throw mapBunDriverError({ error });\n }\n }\n\n // Options path: reserve one connection and drive the transaction by hand,\n // because bun:sql's begin() takes no isolation/timeout options.\n const timeoutText =\n transactionOptions.timeout === undefined\n ? undefined\n : statementTimeoutStatement({ timeout: transactionOptions.timeout });\n const reserved = await runMapped(() => pool.reserve());\n // The deadline clock starts HERE: the connection is reserved, so waiting\n // for it is not charged against the caller's transaction budget.\n const budget = startTransactionBudget({ options: transactionOptions, provider: PROVIDER });\n try {\n await runMapped(() =>\n reserved.unsafe(beginStatement({ isolationLevel: transactionOptions.isolationLevel })),\n );\n if (timeoutText !== undefined) await runMapped(() => reserved.unsafe(timeoutText));\n const txScope = createSavepointScope();\n const txAdapter = createAdapter({\n source: reserved,\n parentMode: \"tx\",\n scope: txScope,\n budget,\n });\n const result = await runRootScope({ scope: txScope, body: () => fn(txAdapter) });\n // An expired budget must never commit, however the callback ended.\n budget.assertUsable({ stage: \"commit\" });\n await runMapped(() => reserved.unsafe(\"COMMIT\"));\n budget.close({ outcome: \"committed\" });\n return result;\n } catch (error) {\n try {\n await reserved.unsafe(\"ROLLBACK\");\n budget.close({ outcome: \"rolled-back\" });\n } catch {\n // The rollback that should have cleaned up failed: the commit state is\n // genuinely unknown. `SET LOCAL` reverts with the transaction, but\n // this session's transaction state can no longer be asserted.\n budget.close({ outcome: \"unknown\" });\n if (budget.totalMs !== null && isTransactionDeadlineError(error)) {\n throw transactionOutcomeUnknownError({\n provider: PROVIDER,\n totalMs: budget.totalMs,\n cause: error,\n });\n }\n }\n throw error;\n } finally {\n reserved.release();\n }\n }\n\n return {\n dialect: DIALECT,\n provider: PROVIDER,\n budgets: BUDGETS,\n get wire(): WireFidelity {\n return activeWire;\n },\n\n async execute(execParams) {\n const turn = scopeTurn({ scope });\n if (turn !== undefined) await turn;\n // After the turn, not before: waiting for a sibling savepoint spends\n // the same budget the statement is about to run against.\n budget?.assertUsable({ stage: \"statement\" });\n await applyEngineBudget();\n return runExecute({ source, ...execParams });\n },\n\n async executeUnsafe(execParams) {\n const turn = scopeTurn({ scope });\n if (turn !== undefined) await turn;\n budget?.assertUsable({ stage: \"statement\" });\n await applyEngineBudget();\n return runExecuteUnsafe({ source, ...execParams });\n },\n\n async transaction<T>(\n fn: (txAdapter: DatabaseAdapter) => Promise<T>,\n transactionOptions?: TransactionOptions,\n ): Promise<T> {\n return parentMode === \"pool\"\n ? transactionViaPool(fn, transactionOptions)\n : transactionViaSavepoint(fn, transactionOptions);\n },\n\n async connect(): Promise<void> {\n if (parentMode !== \"pool\") return;\n const reserved = await runMapped(() => (source as BunInstance).reserve());\n reserved.release();\n },\n\n async disconnect(): Promise<void> {\n if (parentMode !== \"pool\") return;\n await runMapped(() => (source as BunInstance).close());\n instance = null;\n },\n\n formatArrayParam(values: unknown[]): unknown {\n return toPgArrayLiteral(values);\n },\n };\n }\n\n /** Pool-level facade — the bun:sql client is created on first use. */\n function poolAdapter(): DatabaseAdapter {\n return createAdapter({\n source: getSql(),\n parentMode: \"pool\",\n scope: createSavepointScope(),\n });\n }\n\n return {\n dialect: DIALECT,\n provider: PROVIDER,\n budgets: BUDGETS,\n get wire(): WireFidelity {\n return activeWire;\n },\n\n async execute(params) {\n return poolAdapter().execute(params);\n },\n\n async executeUnsafe(params) {\n const control = classifyRawTransactionControl({ text: params.text });\n if (rawSession !== null) {\n if (control === \"close\") {\n const session = rawSession;\n rawSession = null;\n try {\n return await runExecuteUnsafe({ source: session, ...params });\n } finally {\n session.release();\n }\n }\n // A nested raw BEGIN lands here too — postgres treats it as a warning\n // no-op on the open session, exactly like a single connection would.\n return runExecuteUnsafe({ source: rawSession, ...params });\n }\n if (control === \"open\") {\n const reserved = await runMapped(() => getSql().reserve());\n try {\n const result = await runExecuteUnsafe({ source: reserved, ...params });\n rawSession = reserved;\n return result;\n } catch (error) {\n reserved.release();\n throw error;\n }\n }\n return poolAdapter().executeUnsafe(params);\n },\n\n async transaction<T>(\n fn: (txAdapter: DatabaseAdapter) => Promise<T>,\n transactionOptions?: TransactionOptions,\n ): Promise<T> {\n return poolAdapter().transaction(fn, transactionOptions);\n },\n\n async connect(): Promise<void> {\n return poolAdapter().connect();\n },\n\n async disconnect(): Promise<void> {\n if (rawSession !== null) {\n // An abandoned raw transaction must not leak an in-transaction\n // connection; roll it back best-effort before the pool closes.\n const session = rawSession;\n rawSession = null;\n try {\n await session.unsafe(\"ROLLBACK\");\n } catch {\n /* the pool is closing; the session is going away regardless */\n }\n session.release();\n }\n if (instance === null) return;\n const closing = instance;\n instance = null;\n await runMapped(() => closing.close());\n },\n\n formatArrayParam(values: unknown[]): unknown {\n return toPgArrayLiteral(values);\n },\n };\n}\n\n/**\n * Rows affected by a bun:sql statement: the driver attaches `count` (and, on\n * some versions, `affectedRows`) to the returned array; otherwise the number of\n * returned rows is the best available answer.\n */\nfunction readAffectedRows(params: { rows: BunRows }): number {\n const { rows } = params;\n if (typeof rows.count === \"number\") return rows.count;\n if (typeof rows.affectedRows === \"number\") return rows.affectedRows;\n return rows.length;\n}\n\n// ─── Re-exports (driver-error table, params, helpers) ─────────────\n\nexport {\n BUN_SQLSTATE_ERROR_CODES,\n BUN_SQLSTATE_REASONS,\n bunErrorSqlstate,\n mapBunDriverError,\n} from \"./errors.ts\";\nexport { serializeParams, serializeParamsRaw, toPgArrayLiteral } from \"./params.ts\";\nexport { applyStartupOptions, buildStartupOptions } from \"./connection-url.ts\";\nexport type { PlanCacheMode } from \"./connection-url.ts\";\nexport { createSavepointCounter, nextSavepointName } from \"@vibeorm/runtime/adapter-kit\";\nexport type { SavepointCounter } from \"@vibeorm/runtime/adapter-kit\";\nexport { createTemplateCache, templateChunks } from \"./template-cache.ts\";\nexport type { TemplateCache } from \"./template-cache.ts\";\nexport {\n ISOLATION_LEVEL_SQL,\n beginStatement,\n classifyRawTransactionControl,\n refuseNestedTransactionOptions,\n statementTimeoutStatement,\n} from \"./transaction-sql.ts\";\nexport type { RawTransactionControl } from \"./transaction-sql.ts\";\n// ─── EPIC 6: transaction budgets (shared, @vibeorm/runtime/adapter-kit) ───\nexport {\n DEFAULT_DEADLINE_CLOCK,\n engineStatementBudgetMs,\n isTransactionDeadlineError,\n startTransactionBudget,\n transactionClosedError,\n transactionDeadlineError,\n transactionOutcomeUnknownError,\n validateTransactionDeadline,\n} from \"@vibeorm/runtime/adapter-kit\";\nexport type { BudgetStage, DeadlineClock, TransactionBudget, TransactionOutcome } from \"@vibeorm/runtime/adapter-kit\";\n",
6
- "/**\n * Connection-URL handling for bun:sql.\n *\n * Per-connection PostgreSQL settings (`plan_cache_mode`, `statement_timeout`)\n * travel in the `options` startup parameter, which the server parses for\n * `-c key=value` pairs — so every connection in bun's internal pool inherits\n * them without a per-query round trip.\n *\n * v1 lesson (LEARNINGS.md): bun:sql forwards *unrecognised* URL parameters to\n * the server as runtime configuration, so a libpq client-side option such as\n * `connect_timeout` must never be put in the URL (PostgreSQL rejects it as an\n * unrecognised configuration parameter). Connection timeouts use bun:sql's\n * `connectionTimeout` constructor option instead.\n */\n\nimport { VibeError } from \"@vibeorm/schema\";\n\n/**\n * PostgreSQL plan-cache behaviour for the implicit prepared statements bun:sql\n * creates. `force_custom_plan` replans with the real parameter values (≈0.1 ms\n * per query) and keeps index selection optimal on range/LIKE/skewed filters —\n * `auto` lets PostgreSQL switch to a generic plan after ~5 executions.\n */\nexport type PlanCacheMode = \"auto\" | \"force_custom_plan\" | \"force_generic_plan\";\n\n/**\n * Build the `options` startup string, or `undefined` when nothing needs setting.\n *\n * @throws VibeError `VIBE_VALIDATION` when `statementTimeout` is not a\n * non-negative integer — the value ends up inside the startup string verbatim.\n */\nexport function buildStartupOptions(params: {\n planCacheMode: PlanCacheMode;\n statementTimeout?: number;\n}): string | undefined {\n const { planCacheMode, statementTimeout } = params;\n const parts: string[] = [];\n if (planCacheMode !== \"auto\") parts.push(`-c plan_cache_mode=${planCacheMode}`);\n if (statementTimeout !== undefined) {\n if (!Number.isInteger(statementTimeout) || statementTimeout < 0) {\n throw new VibeError({\n code: \"VIBE_VALIDATION\",\n message: `statementTimeout must be a non-negative integer of milliseconds, received ${String(statementTimeout)}`,\n meta: { statementTimeout },\n });\n }\n parts.push(`-c statement_timeout=${statementTimeout}`);\n }\n return parts.length === 0 ? undefined : parts.join(\" \");\n}\n\n/** Append the `options` startup parameter to a connection URL. */\nexport function applyStartupOptions(params: { url: string; startupOptions: string }): string {\n const { url, startupOptions } = params;\n const separator = url.includes(\"?\") ? \"&\" : \"?\";\n return `${url}${separator}options=${encodeURIComponent(startupOptions)}`;\n}\n",
5
+ "import { SQL } from \"bun\";\n\n/** Internal constructor boundary; keeps the driver double out of the public adapter API. */\nexport function createBunSql(params: { url?: string; options: Record<string, unknown> }): SQL {\n return params.url === undefined ? new SQL(params.options) : new SQL(params.url, params.options);\n}\n",
6
+ "/** Migration-only driver instance; never force-close the application's pool. */\nexport const SESSION_CONNECTION: Readonly<{ max: number; closeGraceSeconds: number }> = Object.freeze({\n max: 1,\n // Bun 1.3 treats timeout: 0 as unbounded. A positive millisecond closes only\n // this private instance after the session gate has drained dispatched work.\n closeGraceSeconds: 0.001,\n});\n",
7
+ "/**\n * @vibeorm/adapter-bun — bun:sql (PostgreSQL) adapter for VibeORM v2.\n *\n * Uses Bun's built-in SQL driver and its internal connection pool. Owns\n * optional prepared statements (synthetic tagged templates), transactions\n * (nested → savepoints), array-literal parameter formatting and driver-error\n * mapping. Only `VibeError` ever escapes.\n */\n\nimport { createBunSql } from \"./driver.ts\";\nimport { SESSION_CONNECTION } from \"./config.ts\";\nimport { postgresDialect, renderDiagnostic } from \"@vibeorm/sql\";\nimport type {\n AdapterBudgetSupport,\n DatabaseAdapter,\n QueryResult,\n TransactionOptions,\n WireFidelity,\n} from \"@vibeorm/runtime\";\nimport {\n runPinnedSession,\n createSavepointScope,\n savepointRollbackFailedError,\n engineStatementBudgetMs,\n isTransactionDeadlineError,\n runNestedSavepoint,\n runRootScope,\n type SavepointScope,\n scopeTurn,\n startTransactionBudget,\n type TransactionBudget,\n transactionOutcomeUnknownError,\n validateTransactionDeadline,\n} from \"@vibeorm/runtime/adapter-kit\";\nimport { VibeError, type Dialect, type Provider } from \"@vibeorm/schema\";\nimport { applyStartupOptions, buildStartupOptions, type PlanCacheMode } from \"./connection-url.ts\";\nimport { mapBunDriverError, runMapped } from \"./errors.ts\";\nimport { serializeParams, serializeParamsRaw, toPgArrayLiteral } from \"./params.ts\";\nimport { bindTemplateValues, createTemplateCache } from \"./template-cache.ts\";\nimport {\n beginStatement,\n classifyRawTransactionControl,\n refuseNestedTransactionOptions,\n statementTimeoutStatement,\n} from \"./transaction-sql.ts\";\n\n// ─── Minimal bun:sql surface ──────────────────────────────────────\n\n/**\n * What bun:sql resolves a query to: the row array, with driver metadata\n * (`count`, `command`) attached as properties.\n */\ntype BunRows = Record<string, unknown>[] & { count?: number; affectedRows?: number };\n\ntype BunResults = BunRows | BunRows[] | null;\n\n/** Anything that executes SQL through bun:sql. */\ntype BunExecutor = {\n (strings: TemplateStringsArray, ...values: unknown[]): Promise<BunResults>;\n unsafe(text: string, values?: unknown[]): Promise<BunResults>;\n};\n\n/**\n * The handle passed to `sql.begin(cb)`. Modern bun:sql exposes `savepoint(fn)`\n * for sub-transactions; `begin()` throws inside a transaction (\"use\n * savepoint() instead\"), so it is never called here. Older builds lack\n * `savepoint`, which is why it is optional and probed at runtime.\n */\ntype BunTransaction = BunExecutor & {\n savepoint?: <T>(fn: (sp: BunTransaction) => Promise<T>) => Promise<T>;\n};\n\n/** A connection checked out with `sql.reserve()` — no `savepoint`, must be released. */\ntype BunReserved = BunExecutor & { release(): void; close(): Promise<void> };\n\n/** The pool-level bun:sql client. */\ntype BunInstance = BunExecutor & {\n begin<T>(fn: (tx: BunTransaction) => Promise<T>): Promise<T>;\n reserve(): Promise<BunReserved>;\n close(options?: { timeout: number }): Promise<void>;\n};\n\n/** Any bun:sql handle the adapter can be built on top of. */\ntype BunSource = BunInstance | BunReserved | BunTransaction;\n\n/**\n * Whether a handle is the pool (can open a real transaction) or is already\n * inside one (must nest through savepoints).\n */\ntype ParentMode = \"pool\" | \"tx\";\n\n/**\n * Wrapper that marks an error as \"thrown by the user's transaction callback\",\n * so it can be rethrown untouched instead of being mapped as a driver failure\n * after bun:sql has passed it back out of `begin()` / `savepoint()`.\n */\nclass CallbackError extends Error {\n readonly inner: unknown;\n\n constructor(inner: unknown) {\n super(\"vibeorm: transaction callback failed\");\n this.name = \"CallbackError\";\n this.inner = inner;\n }\n}\n\n// ─── Options ──────────────────────────────────────────────────────\n\n/** Options for {@link bunAdapter}. */\nexport type BunAdapterOptions = {\n /** PostgreSQL connection URL. Defaults to `process.env.DATABASE_URL`, then bun's `PG*` env vars. */\n readonly url?: string;\n /** Maximum pooled connections (default 10). */\n readonly max?: number;\n /**\n * Pool-wide `statement_timeout` in milliseconds, sent as a startup parameter\n * so every connection inherits it. A per-transaction `timeout` overrides it\n * for that transaction.\n */\n readonly statementTimeout?: number;\n /**\n * Milliseconds to wait for a connection to be established. Passed to bun:sql\n * as `connectionTimeout` (which expects **seconds**; converted here).\n */\n readonly connectionTimeout?: number;\n /**\n * Execute ORM-path queries as tagged templates, creating named prepared\n * statements (default false). Saves planning time but lets PostgreSQL fall\n * back to a generic plan after ~5 executions — leave off unless profiling\n * says otherwise. bun:sql's `prepare: false` constructor option is never set\n * (it triggers a known bun:sql performance regression).\n */\n readonly preparedStatements?: boolean;\n /** Maximum entries in the synthetic template cache (default 1000, LRU). */\n readonly stmtCacheMax?: number;\n /** PostgreSQL `plan_cache_mode` for every connection (default `force_custom_plan`). */\n readonly planCacheMode?: PlanCacheMode;\n};\n\n// ─── Adapter ──────────────────────────────────────────────────────\n\nconst DIALECT: Dialect = \"postgres\";\nconst PROVIDER: Provider = \"postgresql\";\n\n/**\n * bun:sql wire (board #30, live-verified on both execute paths): timestamptz\n * → `Date`, int4/float8 → numbers. (int8 arrives as a string — BigInt\n * decoding is real work and never pruned.)\n *\n * The `json` half is NOT a constant, because bun:sql's answer changed between\n * Bun versions and this package supports a range of them: on Bun 1.3.14 the\n * tagged-template path parsed json/jsonb while `sql.unsafe` did not (board\n * #34 — declaring \"parsed\" there made the runtime prune the Json decoder and\n * leak raw strings), and on Bun 1.4.1 BOTH paths parse (leaving \"text\" makes\n * the guarded decode re-parse a stored top-level JSON string: `\"123\"` becomes\n * the number 123, `\"hello\"` throws). Either constant is wrong on one of those\n * runtimes, so the adapter OBSERVES its own driver once instead of guessing —\n * see {@link probeJsonWire}. {@link WIRE_TEXT} is the conservative claim it\n * starts from; no ORM rows are returned until the probe succeeds.\n */\n/**\n * Timing budgets this adapter genuinely enforces (EPIC 6).\n *\n * - `acquireTimeout: false` — `connectionTimeout` bounds establishment only.\n * Modern Bun supports reserve({ signal }), but implicit query/begin checkout\n * and older supported Bun versions do not provide that cancellation contract.\n * - `statementTimeout: \"all-statements\"` — a real PostgreSQL server, so\n * `statement_timeout` cancels ANY over-long statement, writes included.\n * - `transactionDeadline: \"cancel-running-statements\"` — the remaining budget\n * is handed to the SERVER before each statement, so the database itself stops\n * work that would outlive the deadline.\n */\nconst BUDGETS: AdapterBudgetSupport = Object.freeze({\n acquireTimeout: false,\n statementTimeout: \"all-statements\",\n transactionDeadline: \"cancel-running-statements\",\n} as const);\n\nconst WIRE_TEXT: WireFidelity = Object.freeze({ dateTime: \"native\", json: \"text\", numbers: \"native\" } as const);\n\n/** The same wire, for a driver observed to hand back parsed json. */\nconst WIRE_PARSED: WireFidelity = Object.freeze({ dateTime: \"native\", json: \"parsed\", numbers: \"native\" } as const);\n\n/**\n * Create a VibeORM adapter backed by bun:sql.\n *\n * @example\n * ```ts\n * const adapter = bunAdapter({ url: process.env.DATABASE_URL, max: 10 });\n * await adapter.connect();\n * const rows = await adapter.execute({ text: 'SELECT * FROM \"User\" WHERE \"id\" = $1', values: [1] });\n * ```\n */\nexport function bunAdapter(options?: BunAdapterOptions): DatabaseAdapter {\n const usePrepared = options?.preparedStatements ?? false;\n const templates = createTemplateCache({ max: options?.stmtCacheMax ?? 1000 });\n\n /**\n * The wire claim this adapter currently makes. Starts conservative and is\n * replaced at most once, by {@link probeJsonWire}'s observation. Every handle\n * this factory builds — pool, transaction, savepoint, reserved session —\n * reads this one variable, so a transaction can never disagree with its\n * parent (the contract requires transactional adapters to carry the same\n * declaration).\n */\n let activeWire: WireFidelity = WIRE_TEXT;\n let wireSettled = false;\n let wireProbe: Promise<void> | null = null;\n\n let instance: BunInstance | null = null;\n const deadlineTurns = new WeakMap<TransactionBudget, Promise<void>>();\n\n // Only deadline-bearing connections need a queue. Share it across every\n // nested facade, not one queue per handle. Probe, statement and COMMIT each\n // receive a fresh bound after preceding work finishes.\n function budgetTurn<T>(params: {\n source: BunExecutor;\n budget?: TransactionBudget;\n stage?: \"statement\" | \"commit\";\n cleanup?: boolean;\n guard?: () => void;\n body: () => Promise<T>;\n }): Promise<T> {\n const { source, budget, body, guard } = params;\n const run = async (): Promise<T> => {\n if (params.cleanup === true) return body();\n budget?.assertUsable({ stage: params.stage ?? \"statement\" });\n guard?.();\n const ms = budget === undefined ? null : engineStatementBudgetMs({ budget });\n if (ms !== null) {\n await runMapped(() => source.unsafe(statementTimeoutStatement({ timeout: ms })));\n budget?.assertUsable({ stage: params.stage ?? \"statement\" });\n guard?.();\n }\n return body();\n };\n if (budget === undefined || budget.totalMs === null) return run();\n const result = (deadlineTurns.get(budget) ?? Promise.resolve()).then(run);\n deadlineTurns.set(budget, result.then(() => undefined, () => undefined));\n return result;\n }\n\n /**\n * The reserved connection of an OPEN raw transaction — session affinity for\n * the raw path. @vibeorm/migrate wraps transactional DDL in literal `BEGIN`\n * / `COMMIT` / `ROLLBACK` sent through `executeUnsafe`; bun:sql refuses\n * transaction control through `sql.unsafe()` on a pooled instance\n * (`ERR_POSTGRES_UNSAFE_TRANSACTION`), so a pure `BEGIN` reserves one\n * connection, every raw statement until the matching `COMMIT`/`ROLLBACK`\n * rides it, and the close releases it. The ORM path (`execute`) and\n * `transaction()` stay on the pool — they never participate in a raw\n * transaction. Concurrent raw transactions on one adapter are unsupported\n * (they were driver-refused before this pinning existed).\n */\n let rawSession: BunReserved | null = null;\n\n function createSqlInstance(params: { max: number }): BunInstance {\n const sqlOptions: Record<string, unknown> = { max: params.max };\n if (options?.connectionTimeout !== undefined) {\n // bun:sql expects seconds; the VibeORM surface is milliseconds everywhere.\n sqlOptions.connectionTimeout = Math.max(1, Math.ceil(options.connectionTimeout / 1000));\n }\n\n const startupOptions = buildStartupOptions({\n planCacheMode: options?.planCacheMode ?? \"force_custom_plan\",\n statementTimeout: options?.statementTimeout,\n });\n const baseUrl = options?.url ?? process.env.DATABASE_URL;\n const url =\n baseUrl === undefined || startupOptions === undefined\n ? baseUrl\n : applyStartupOptions({ url: baseUrl, startupOptions });\n\n // Bun's constructor connection object also supports PG*-only configuration.\n if (url === undefined && startupOptions !== undefined) {\n sqlOptions.connection = { options: startupOptions };\n }\n return createBunSql({ url, options: sqlOptions }) as unknown as BunInstance;\n }\n\n function getSql(): BunInstance {\n instance ??= createSqlInstance({ max: options?.max ?? 10 });\n return instance;\n }\n\n /**\n * Ask THIS driver, once, whether it parses json on the path the ORM reads\n * rows over — the same `execute` path, prepared or unsafe as configured, so\n * the answer describes the traffic the claim is applied to.\n *\n * Runs on the handle that is already in hand (pool, transaction or reserved\n * session): a `SELECT` is harmless inside a transaction, and probing the pool\n * from inside one could deadlock an adapter configured with `max: 1`.\n * Failure refuses this operation. A later call can observe the wire again;\n * no user statement or transaction is retried.\n */\n async function probeJsonWire(source: BunExecutor): Promise<void> {\n const probe = renderDiagnostic({ dialect: postgresDialect, query: \"postgresJsonWire\" });\n const rows = finalRows({ result: await runMapped(() => usePrepared\n ? source(templates.getTemplate({ text: probe.text }).template)\n : source.unsafe(probe.text, [])) });\n const probed = rows[0]?.probe;\n if (typeof probed === \"object\" && probed !== null && \"__vibeorm\" in probed && probed.__vibeorm === 1) activeWire = WIRE_PARSED;\n else if (typeof probed === \"string\" && /^\\{\\s*\"__vibeorm\"\\s*:\\s*1\\s*\\}$/.test(probed)) activeWire = WIRE_TEXT;\n else {\n throw new VibeError({\n code: \"VIBE_ADAPTER\",\n message: \"Bun returned an unrecognized JSON wire probe result; no ORM statement was sent\",\n meta: { reason: \"json-wire-probe\" },\n });\n }\n wireSettled = true;\n }\n\n async function runExecute(params: {\n source: BunExecutor;\n text: string;\n values: unknown[];\n }): Promise<Record<string, unknown>[]> {\n // One extra round trip on the first ORM query of this adapter's life; a\n // single boolean test on every one after it. It must complete BEFORE the\n // first rows are handed back, because the runtime reads `wire` to build\n // that read's decode plan.\n if (!wireSettled) {\n wireProbe ??= probeJsonWire(params.source).finally(() => { wireProbe = null; });\n await wireProbe;\n }\n const values = serializeParams({ values: params.values });\n if (usePrepared) {\n // F19: a tagged template binds POSITIONALLY, one value per gap — so the\n // values follow the placeholder ORDER found in the text (`$2, $1` binds\n // backwards otherwise, and a repeated `$1` needs its value twice).\n const prepared = templates.getTemplate({ text: params.text });\n const bound = bindTemplateValues({ text: params.text, indices: prepared.indices, values });\n return finalRows({ result: await runMapped(() => params.source(prepared.template, ...bound)) });\n }\n return finalRows({ result: await runMapped(() => params.source.unsafe(params.text, values)) });\n }\n\n async function runExecuteUnsafe(params: {\n source: BunExecutor;\n text: string;\n values?: unknown[];\n }): Promise<QueryResult> {\n const values = params.values === undefined ? undefined : serializeParamsRaw({ values: params.values });\n const rows = finalRows({ result: await runMapped(() => params.source.unsafe(params.text, values)) });\n return { rows, affectedRows: readAffectedRows({ rows }) };\n }\n\n /**\n * Build the adapter facade over any bun:sql handle. `parentMode` decides\n * whether a nested `transaction()` opens a real transaction or a savepoint;\n * `scope` is shared by reference across one top-level transaction, and the\n * savepoint gate serializes overlapping sibling savepoints (F14) on BOTH the\n * driver-managed and the manual path.\n */\n function createAdapter(params: {\n source: BunSource;\n parentMode: ParentMode;\n scope: SavepointScope;\n /** The enclosing transaction's budget; absent on the pool-level adapter. */\n budget?: TransactionBudget;\n lifetime?: { active: boolean };\n }): DatabaseAdapter {\n const { source, parentMode, scope, budget, lifetime } = params;\n\n function assertHandle(): void {\n budget?.assertUsable({ stage: \"statement\" });\n if (lifetime?.active === false) {\n throw new VibeError({\n code: \"VIBE_TRANSACTION\",\n message: \"this savepoint callback has finished; its transaction handle has expired\",\n meta: { reason: \"expired\" },\n });\n }\n if (scope.state.poisoned !== null) throw scope.state.poisoned;\n }\n\n const guardedSource: BunExecutor = Object.assign(\n (strings: TemplateStringsArray, ...values: unknown[]): Promise<BunResults> =>\n budgetTurn({ source, budget, guard: assertHandle, body: () => source(strings, ...values) }),\n { unsafe: (text: string, values?: unknown[]): Promise<BunResults> =>\n budgetTurn({ source, budget, guard: assertHandle, body: () => source.unsafe(text, values) }) },\n );\n\n /** Nested transaction: a savepoint on the connection we are already on. */\n async function transactionViaSavepoint<T>(\n fn: (txAdapter: DatabaseAdapter) => Promise<T>,\n nestedOptions?: TransactionOptions,\n ): Promise<T> {\n refuseNestedTransactionOptions({ options: nestedOptions, provider: PROVIDER });\n assertHandle();\n budget?.assertUsable({ stage: \"nested\" });\n const transactional = source as BunTransaction;\n const runChild = async (child: SavepointScope, childSource: BunTransaction): Promise<T> => {\n assertHandle();\n const childLifetime = { active: true };\n try {\n return await fn(createAdapter({ source: childSource, parentMode: \"tx\", scope: child, budget, lifetime: childLifetime }));\n } finally {\n childLifetime.active = false;\n }\n };\n\n // Modern bun:sql: the in-transaction handle drives savepoints itself —\n // the gate then owns only the LIFETIME, not the SQL. Captured before the\n // callback because narrowing does not reach into a nested closure.\n const driverSavepoint = transactional.savepoint?.bind(transactional);\n if (driverSavepoint !== undefined) {\n return runNestedSavepoint({\n scope,\n body: async (child) => {\n let callbackFailure: CallbackError | undefined;\n try {\n return await driverSavepoint(async (savepointSql) => {\n try {\n return await runChild(child, savepointSql);\n } catch (error) {\n callbackFailure = new CallbackError(error);\n throw callbackFailure;\n }\n });\n } catch (error) {\n // Bun rethrows the identical callback marker only after successful\n // rollback. A replacement error loses that proof. Creation/release\n // errors likewise do not expose whether recovery succeeded.\n if (callbackFailure !== undefined && error === callbackFailure) throw callbackFailure.inner;\n const poisoned = callbackFailure !== undefined\n ? savepointRollbackFailedError({ cause: callbackFailure.inner, rollbackFailure: mapBunDriverError({ error }) })\n : unknownOutcome({ cause: mapBunDriverError({ error }), reason: \"savepoint-outcome-unknown\" });\n scope.state.poisoned = poisoned;\n throw poisoned;\n }\n },\n });\n }\n\n // Reserved connections (and older bun:sql) expose no savepoint helper —\n // drive SAVEPOINT / RELEASE / ROLLBACK TO by hand.\n return runNestedSavepoint({\n scope,\n execute: (statement) => budgetTurn({\n source, budget, cleanup: statement.startsWith(\"ROLLBACK TO SAVEPOINT \"),\n body: () => runMapped(() => transactional.unsafe(statement)),\n }),\n body: (child) => runChild(child, transactional),\n });\n }\n\n /** Top-level transaction on the pool. */\n async function transactionViaPool<T>(\n fn: (txAdapter: DatabaseAdapter) => Promise<T>,\n transactionOptions?: TransactionOptions,\n ): Promise<T> {\n const pool = source as BunInstance;\n\n // Refuse an unsupportable budget before any connection is taken.\n validateTransactionDeadline({\n options: transactionOptions,\n support: BUDGETS.transactionDeadline,\n provider: PROVIDER,\n });\n\n // Fast path: bun:sql drives BEGIN/COMMIT itself. A DEADLINE opts out of\n // it deliberately — the clock must start after the connection is in hand,\n // and only the reserved path below gives that seam.\n if (\n transactionOptions?.isolationLevel === undefined &&\n transactionOptions?.timeout === undefined &&\n transactionOptions?.deadline === undefined\n ) {\n // A budget with no deadline: it still closes the handle at the end, so\n // an escaped transaction client cannot run on a pooled connection.\n const budget = startTransactionBudget({ provider: PROVIDER });\n const txScope = createSavepointScope();\n let callbackFailure: CallbackError | undefined;\n try {\n const result = await pool.begin(async (txSql) => {\n const txAdapter = createAdapter({\n source: txSql,\n parentMode: \"tx\",\n scope: txScope,\n budget,\n });\n try {\n return await runRootScope({ scope: txScope, body: () => fn(txAdapter) });\n } catch (error) {\n callbackFailure = new CallbackError(error);\n throw callbackFailure;\n }\n });\n budget.close({ outcome: \"committed\" });\n return result;\n } catch (error) {\n const knownRollback = callbackFailure !== undefined && error === callbackFailure && txScope.state.poisoned === null;\n budget.close({ outcome: knownRollback ? \"rolled-back\" : \"unknown\" });\n if (callbackFailure !== undefined && error === callbackFailure) throw callbackFailure.inner;\n throw unknownOutcome({ cause: callbackFailure?.inner ?? mapBunDriverError({ error }) });\n }\n }\n\n // Options path: reserve one connection and drive the transaction by hand,\n // because bun:sql's begin() takes no isolation/timeout options.\n const timeoutText =\n transactionOptions.timeout === undefined\n ? undefined\n : statementTimeoutStatement({ timeout: transactionOptions.timeout });\n const reserved = await runMapped(() => pool.reserve());\n // The deadline clock starts HERE: the connection is reserved, so waiting\n // for it is not charged against the caller's transaction budget.\n const budget = startTransactionBudget({ options: transactionOptions, provider: PROVIDER });\n const txScope = createSavepointScope();\n let commitSent = false;\n let discard = false;\n try {\n await runMapped(() =>\n reserved.unsafe(beginStatement({ isolationLevel: transactionOptions.isolationLevel })),\n );\n if (timeoutText !== undefined) await runMapped(() => reserved.unsafe(timeoutText));\n const txAdapter = createAdapter({\n source: reserved,\n parentMode: \"tx\",\n scope: txScope,\n budget,\n });\n const result = await runRootScope({ scope: txScope, body: () => fn(txAdapter) });\n // An expired budget must never commit, however the callback ended.\n await budgetTurn({ source: reserved, budget, stage: \"commit\", body: () => {\n commitSent = true;\n return runMapped(() => reserved.unsafe(\"COMMIT\"));\n } });\n budget.close({ outcome: \"committed\" });\n return result;\n } catch (error) {\n try {\n await reserved.unsafe(\"ROLLBACK\");\n budget.close({ outcome: commitSent || txScope.state.poisoned !== null ? \"unknown\" : \"rolled-back\" });\n } catch {\n // The rollback that should have cleaned up failed: the commit state is\n // genuinely unknown. `SET LOCAL` reverts with the transaction, but\n // this session's transaction state can no longer be asserted.\n discard = true;\n budget.close({ outcome: \"unknown\" });\n if (budget.totalMs !== null && isTransactionDeadlineError(error)) {\n throw transactionOutcomeUnknownError({\n provider: PROVIDER,\n totalMs: budget.totalMs,\n cause: error,\n });\n }\n }\n if (budget.outcome === \"unknown\" && txScope.state.poisoned === null) throw unknownOutcome({ cause: error });\n throw error;\n } finally {\n if (discard) await runMapped(() => reserved.close());\n else reserved.release();\n }\n }\n\n return {\n dialect: DIALECT,\n provider: PROVIDER,\n budgets: BUDGETS,\n get wire(): WireFidelity {\n return activeWire;\n },\n\n async execute(execParams) {\n assertHandle();\n const turn = scopeTurn({ scope });\n if (turn !== undefined) await turn;\n assertHandle();\n return runExecute({ source: guardedSource, ...execParams });\n },\n\n async executeUnsafe(execParams) {\n assertHandle();\n const turn = scopeTurn({ scope });\n if (turn !== undefined) await turn;\n assertHandle();\n return runExecuteUnsafe({ source: guardedSource, ...execParams });\n },\n\n async transaction<T>(\n fn: (txAdapter: DatabaseAdapter) => Promise<T>,\n transactionOptions?: TransactionOptions,\n ): Promise<T> {\n return parentMode === \"pool\"\n ? transactionViaPool(fn, transactionOptions)\n : transactionViaSavepoint(fn, transactionOptions);\n },\n\n async connect(): Promise<void> {\n if (parentMode !== \"pool\") return;\n const reserved = await runMapped(() => (source as BunInstance).reserve());\n reserved.release();\n },\n\n async disconnect(): Promise<void> {\n if (parentMode !== \"pool\") return;\n await runMapped(() => (source as BunInstance).close());\n instance = null;\n },\n\n formatArrayParam(values: unknown[]): unknown {\n return toPgArrayLiteral(values);\n },\n };\n }\n\n /** Pool-level facade — the bun:sql client is created on first use. */\n function poolAdapter(): DatabaseAdapter {\n return createAdapter({\n source: getSql(),\n parentMode: \"pool\",\n scope: createSavepointScope(),\n });\n }\n\n return {\n dialect: DIALECT,\n provider: PROVIDER,\n budgets: BUDGETS,\n get wire(): WireFidelity {\n return activeWire;\n },\n\n async withSession({ run }) {\n // Bun 1.3 does not decrement its pool's pending counter when a reserved\n // connection closes or dies. Own a private one-connection driver instance\n // so cleanup cannot hang or force-close unrelated application work.\n const sessionPool = createSqlInstance({ max: SESSION_CONNECTION.max });\n const close = (): Promise<void> => runMapped(() => sessionPool.close({ timeout: SESSION_CONNECTION.closeGraceSeconds }));\n const reserved = await runMapped(() => sessionPool.reserve()).catch(async (cause: unknown) => {\n await close();\n throw cause;\n });\n return runPinnedSession({\n run,\n execute: async (query) => (await runExecuteUnsafe({ source: reserved, ...query })).rows,\n isLost: (error) => error instanceof VibeError && (\n typeof error.meta.sqlstate !== \"string\" || error.meta.sqlstate.startsWith(\"08\") ||\n [\"57P01\", \"57P02\", \"57P03\"].includes(error.meta.sqlstate)\n ),\n release: close,\n });\n },\n\n async execute(params) {\n return poolAdapter().execute(params);\n },\n\n async executeUnsafe(params) {\n const control = classifyRawTransactionControl({ text: params.text });\n if (rawSession !== null) {\n if (control === \"close\") {\n const session = rawSession;\n rawSession = null;\n try {\n return await runExecuteUnsafe({ source: session, ...params });\n } finally {\n session.release();\n }\n }\n // A nested raw BEGIN lands here too — postgres treats it as a warning\n // no-op on the open session, exactly like a single connection would.\n return runExecuteUnsafe({ source: rawSession, ...params });\n }\n if (control === \"open\") {\n const reserved = await runMapped(() => getSql().reserve());\n try {\n const result = await runExecuteUnsafe({ source: reserved, ...params });\n rawSession = reserved;\n return result;\n } catch (error) {\n reserved.release();\n throw error;\n }\n }\n return poolAdapter().executeUnsafe(params);\n },\n\n async transaction<T>(\n fn: (txAdapter: DatabaseAdapter) => Promise<T>,\n transactionOptions?: TransactionOptions,\n ): Promise<T> {\n return poolAdapter().transaction(fn, transactionOptions);\n },\n\n async connect(): Promise<void> {\n return poolAdapter().connect();\n },\n\n async disconnect(): Promise<void> {\n if (rawSession !== null) {\n // An abandoned raw transaction must not leak an in-transaction\n // connection; roll it back best-effort before the pool closes.\n const session = rawSession;\n rawSession = null;\n try {\n await session.unsafe(\"ROLLBACK\");\n } catch {\n /* the pool is closing; the session is going away regardless */\n }\n session.release();\n }\n if (instance === null) return;\n const closing = instance;\n instance = null;\n await runMapped(() => closing.close());\n },\n\n formatArrayParam(values: unknown[]): unknown {\n return toPgArrayLiteral(values);\n },\n };\n}\n\n/**\n * Rows affected by a bun:sql statement: the driver attaches `count` (and, on\n * some versions, `affectedRows`) to the returned array; otherwise the number of\n * returned rows is the best available answer.\n */\nfunction readAffectedRows(params: { rows: BunRows }): number {\n const { rows } = params;\n if (typeof rows.count === \"number\") return rows.count;\n if (typeof rows.affectedRows === \"number\") return rows.affectedRows;\n return rows.length;\n}\n\n/** Bun's simple protocol returns an outer array for scripts; final command wins. */\nfunction finalRows(params: { result: BunResults }): BunRows {\n const { result } = params;\n if (result === null) return [];\n return Array.isArray(result[0]) ? (result as BunRows[]).at(-1) ?? [] : result as BunRows;\n}\n\nfunction unknownOutcome(params: { cause: unknown; reason?: string }): VibeError {\n return new VibeError({\n code: \"VIBE_TRANSACTION\",\n message: \"Bun could not confirm transaction recovery or completion; the outcome is unknown. Nothing is retried automatically.\",\n meta: { reason: params.reason ?? \"transaction-outcome-unknown\", outcome: \"unknown\" },\n cause: params.cause,\n });\n}\n\n// ─── Re-exports (driver-error table, params, helpers) ─────────────\n\nexport {\n BUN_SQLSTATE_ERROR_CODES,\n BUN_SQLSTATE_REASONS,\n bunErrorSqlstate,\n mapBunDriverError,\n} from \"./errors.ts\";\nexport { serializeParams, serializeParamsRaw, toPgArrayLiteral } from \"./params.ts\";\nexport { applyStartupOptions, buildStartupOptions } from \"./connection-url.ts\";\nexport type { PlanCacheMode } from \"./connection-url.ts\";\nexport { createSavepointCounter, nextSavepointName } from \"@vibeorm/runtime/adapter-kit\";\nexport type { SavepointCounter } from \"@vibeorm/runtime/adapter-kit\";\nexport { createTemplateCache, templateChunks } from \"./template-cache.ts\";\nexport type { TemplateCache } from \"./template-cache.ts\";\nexport {\n ISOLATION_LEVEL_SQL,\n beginStatement,\n classifyRawTransactionControl,\n refuseNestedTransactionOptions,\n statementTimeoutStatement,\n} from \"./transaction-sql.ts\";\nexport type { RawTransactionControl } from \"./transaction-sql.ts\";\n// ─── EPIC 6: transaction budgets (shared, @vibeorm/runtime/adapter-kit) ───\nexport {\n DEFAULT_DEADLINE_CLOCK,\n engineStatementBudgetMs,\n isTransactionDeadlineError,\n startTransactionBudget,\n transactionClosedError,\n transactionDeadlineError,\n transactionOutcomeUnknownError,\n validateTransactionDeadline,\n} from \"@vibeorm/runtime/adapter-kit\";\nexport type { BudgetStage, DeadlineClock, TransactionBudget, TransactionOutcome } from \"@vibeorm/runtime/adapter-kit\";\n",
8
+ "/**\n * Connection-URL handling for bun:sql.\n *\n * Per-connection PostgreSQL settings (`plan_cache_mode`, `statement_timeout`)\n * travel in the `options` startup parameter, which the server parses for\n * `-c key=value` pairs — so every connection in bun's internal pool inherits\n * them without a per-query round trip.\n *\n * v1 lesson (LEARNINGS.md): bun:sql forwards *unrecognised* URL parameters to\n * the server as runtime configuration, so a libpq client-side option such as\n * `connect_timeout` must never be put in the URL (PostgreSQL rejects it as an\n * unrecognised configuration parameter). Connection timeouts use bun:sql's\n * `connectionTimeout` constructor option instead.\n */\n\nimport { VibeError } from \"@vibeorm/schema\";\n\n/**\n * PostgreSQL plan-cache behaviour for the implicit prepared statements bun:sql\n * creates. `force_custom_plan` replans with the real parameter values (≈0.1 ms\n * per query) and keeps index selection optimal on range/LIKE/skewed filters —\n * `auto` lets PostgreSQL switch to a generic plan after ~5 executions.\n */\nexport type PlanCacheMode = \"auto\" | \"force_custom_plan\" | \"force_generic_plan\";\n\n/**\n * Build the `options` startup string, or `undefined` when nothing needs setting.\n *\n * @throws VibeError `VIBE_VALIDATION` when `statementTimeout` is not a\n * non-negative integer — the value ends up inside the startup string verbatim.\n */\nexport function buildStartupOptions(params: {\n planCacheMode: PlanCacheMode;\n statementTimeout?: number;\n}): string | undefined {\n const { planCacheMode, statementTimeout } = params;\n const parts: string[] = [];\n if (planCacheMode !== \"auto\") parts.push(`-c plan_cache_mode=${planCacheMode}`);\n if (statementTimeout !== undefined) {\n if (!Number.isInteger(statementTimeout) || statementTimeout < 0) {\n throw new VibeError({\n code: \"VIBE_VALIDATION\",\n message: `statementTimeout must be a non-negative integer of milliseconds, received ${String(statementTimeout)}`,\n meta: { statementTimeout },\n });\n }\n parts.push(`-c statement_timeout=${statementTimeout}`);\n }\n return parts.length === 0 ? undefined : parts.join(\" \");\n}\n\n/** Merge startup settings into one `options` key; adapter settings take precedence. */\nexport function applyStartupOptions(params: { url: string; startupOptions: string }): string {\n if (!URL.canParse(params.url)) {\n throw new VibeError({ code: \"VIBE_VALIDATION\", message: \"invalid PostgreSQL connection URL\" });\n }\n const url = new URL(params.url);\n const merged = [...url.searchParams.getAll(\"options\"), params.startupOptions].filter(Boolean).join(\" \");\n url.searchParams.set(\"options\", merged);\n url.search = url.searchParams.toString().replace(/\\+/g, \"%20\");\n return url.toString();\n}\n",
7
9
  "/**\n * Driver-error mapping for `bun:sql`.\n *\n * bun:sql raises `SQL.PostgresError` for server failures and for client-side\n * problems alike. Server failures carry the PostgreSQL SQLSTATE — depending on\n * the Bun version on `code` or on `errno` — while client-side failures use a\n * `ERR_POSTGRES_*` identifier in `code`. Both shapes are read here, so the\n * mapping is stable across Bun versions. Constitution rule 5: only `VibeError`\n * escapes the adapter.\n */\n\nimport { VibeError, type VibeErrorCode } from \"@vibeorm/schema\";\n\n// ─── SQLSTATE table ───────────────────────────────────────────────\n\n/**\n * PostgreSQL SQLSTATE → stable VibeError code. Frozen and mirrored by tests;\n * anything absent from this table (including every `ERR_POSTGRES_*` connection\n * or auth failure) maps to `VIBE_ADAPTER`.\n */\nexport const BUN_SQLSTATE_ERROR_CODES: Readonly<Record<string, VibeErrorCode>> = Object.freeze({\n /** exclusion_violation */\n \"23P01\": \"VIBE_EXCLUSION_VIOLATION\",\n /** unique_violation */\n \"23505\": \"VIBE_UNIQUE_VIOLATION\",\n /** foreign_key_violation */\n \"23503\": \"VIBE_FK_VIOLATION\",\n /** restrict_violation — PostgreSQL 18+ ON DELETE/UPDATE RESTRICT */\n \"23001\": \"VIBE_FK_VIOLATION\",\n /** not_null_violation */\n \"23502\": \"VIBE_VALIDATION\",\n /** check_violation */\n \"23514\": \"VIBE_VALIDATION\",\n /**\n * invalid_text_representation — a value the server cannot parse into the\n * column's type (out-of-range enum value, `\"abc\"` for an integer). Bad input,\n * so the same code sqlite reports for its enum CHECK violation.\n */\n \"22P02\": \"VIBE_VALIDATION\",\n /**\n * insufficient_privilege — a denied table/column privilege, and the SQLSTATE a\n * native row-level-security policy raises when its WITH CHECK refuses a write.\n * Callers identify it by this code, never by message text.\n */\n \"42501\": \"VIBE_PERMISSION_DENIED\",\n /** serialization_failure */\n \"40001\": \"VIBE_TRANSACTION\",\n /** deadlock_detected */\n \"40P01\": \"VIBE_TRANSACTION\",\n /** query_canceled — statement_timeout fired */\n \"57014\": \"VIBE_TRANSACTION\",\n /**\n * lock_not_available — a `nowait` locking read on already-locked rows, or an\n * expired `lock_timeout`. Postgres reports both with this one SQLSTATE.\n */\n \"55P03\": \"VIBE_LOCK_NOT_AVAILABLE\",\n});\n\n/** SQLSTATEs that additionally explain themselves through `meta.reason`. */\nexport const BUN_SQLSTATE_REASONS: Readonly<Record<string, string>> = Object.freeze({\n \"23P01\": \"exclusion-violation\",\n \"57014\": \"timeout\",\n \"55P03\": \"lock-not-available\",\n \"40P01\": \"deadlock\",\n \"40001\": \"serialization-failure\",\n});\n\n// ─── Reading driver errors ────────────────────────────────────────\n\n/** A PostgreSQL SQLSTATE is exactly five digits/uppercase letters (e.g. `40P01`). */\nconst SQLSTATE_PATTERN = /^[0-9A-Z]{5}$/;\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 SQLSTATE from a bun:sql error, accepting it on either `code` or\n * `errno`. `ERR_POSTGRES_*` identifiers are not SQLSTATEs and yield `undefined`.\n */\nexport function bunErrorSqlstate(params: { error: unknown }): string | undefined {\n const { error } = params;\n if (error === null || typeof error !== \"object\") return undefined;\n const source = error as Record<string, unknown>;\n for (const key of [\"code\", \"errno\"]) {\n const value = readStringField({ source, key });\n if (value !== undefined && SQLSTATE_PATTERN.test(value)) return value;\n }\n return undefined;\n}\n\n// ─── Mapping ──────────────────────────────────────────────────────\n\n/**\n * Map any error thrown by bun:sql 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.\n */\nexport function mapBunDriverError(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 sqlstate = bunErrorSqlstate({ error });\n const code: VibeErrorCode =\n (sqlstate === undefined ? undefined : BUN_SQLSTATE_ERROR_CODES[sqlstate]) ?? \"VIBE_ADAPTER\";\n\n const meta: Record<string, unknown> = {};\n if (sqlstate !== undefined) meta.sqlstate = sqlstate;\n const constraint = readStringField({ source, key: \"constraint\" });\n if (constraint !== undefined) meta.constraint = constraint;\n const table = readStringField({ source, key: \"table\" });\n if (table !== undefined) meta.table = table;\n const column = readStringField({ source, key: \"column\" });\n if (column !== undefined) meta.column = column;\n const reason = sqlstate === undefined ? undefined : BUN_SQLSTATE_REASONS[sqlstate];\n if (reason !== undefined) meta.reason = reason;\n // Keep bun's own identifier when it is not a SQLSTATE — it is the only clue\n // a connection/auth/protocol failure carries.\n const driverCode = readStringField({ source, key: \"code\" });\n if (driverCode !== undefined && driverCode !== sqlstate) meta.driverCode = driverCode;\n\n const message =\n readStringField({ source, key: \"message\" }) ??\n (typeof error === \"string\" ? error : \"unknown bun:sql driver error\");\n\n return new VibeError({ code, message, meta, cause: error });\n}\n\n/** Run a driver call, mapping anything it throws onto a `VibeError`. */\nexport async function runMapped<T>(fn: () => Promise<T>): Promise<T> {\n try {\n return await fn();\n } catch (error) {\n throw mapBunDriverError({ error });\n }\n}\n",
8
10
  "/**\n * Parameter serialization for bun:sql.\n *\n * Verified against Bun 1.3 (re-verified on 1.3.14; `tests/live.test.ts` and\n * the notes below):\n * - a plain object or array bound to a `json`/`jsonb` column is JSON-encoded by\n * bun:sql itself — encoding it here as well double-encodes it and stores a\n * JSON *string* (`jsonb_typeof` = `\"string\"`), so the ORM path must not touch it;\n * - a plain JS array bound to a scalar-list column (`text[]`, `int[]`) is NOT\n * turned into a PostgreSQL array literal by bun:sql — it arrives as `a,b` and\n * the server rejects it with `malformed array literal`. Scalar lists therefore\n * have to be pre-rendered with {@link toPgArrayLiteral}, which is exactly what\n * the adapter's `formatArrayParam` returns.\n *\n * Hence the split (LEARNINGS.md): the ORM path passes values through (scalar\n * lists already arrived as literal strings), while the raw path renders plain JS\n * arrays as array literals so `db.$queryRawUnsafe('… = ANY($1)', [1, 2, 3])`\n * matches rows.\n */\n\nimport { VibeError } from \"@vibeorm/schema\";\n\n// ─── PostgreSQL array literals ────────────────────────────────────\n\n/** Quote and escape one array element: `\"` and `\\` are the special characters. */\nfunction quoteElement(value: string): string {\n return `\"${value.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"')}\"`;\n}\n\n/**\n * Render a JS array as a PostgreSQL array literal string.\n *\n * Element handling:\n * - `null` / `undefined` → unquoted `NULL`\n * - `number` / `bigint` / `boolean` → unquoted primitive\n * - `Date` → quoted ISO-8601 (PostgreSQL cannot parse `String(date)`)\n * - `string` → quoted, with `\"` and `\\` escaped (so commas, braces and quotes\n * inside an element are safe)\n * - any other object, **including a nested array** → quoted `JSON.stringify`,\n * which is what a `Json[]` scalar list needs (PostgreSQL scalar lists are\n * one-dimensional, so a nested array is a JSON value, not a matrix)\n * - binary (`Uint8Array` / `ArrayBuffer`) → unsupported, throws\n *\n * @throws VibeError `VIBE_VALIDATION` for binary elements.\n */\nexport function toPgArrayLiteral(values: readonly unknown[]): string {\n const elements = values.map((value) => {\n if (value === null || value === undefined) return \"NULL\";\n if (typeof value === \"number\" || typeof value === \"bigint\" || typeof value === \"boolean\") {\n return String(value);\n }\n if (value instanceof Date) return quoteElement(value.toISOString());\n if (ArrayBuffer.isView(value) || value instanceof ArrayBuffer) {\n throw new VibeError({\n code: \"VIBE_VALIDATION\",\n message: \"binary values are not supported inside a postgres array literal\",\n meta: { driver: \"bun:sql\" },\n });\n }\n if (typeof value === \"string\") return quoteElement(value);\n if (typeof value === \"object\") return quoteElement(JSON.stringify(value));\n return quoteElement(String(value));\n });\n return `{${elements.join(\",\")}}`;\n}\n\n// ─── Serialization ────────────────────────────────────────────────\n\n/**\n * `Date` → UTC ISO-8601 text (`2026-03-08T19:38:08.538Z`), the same spelling\n * the array literal above uses.\n *\n * bun:sql serializes a `Date` by the parameter's RESOLVED postgres type\n * (LEARNINGS): fine for `timestamp`/`timestamptz` (UTC text), but a `date`\n * parameter gets `Date#toString()` — `Sun Mar 08 2026 23:30:00 GMT+0000\n * (Coordinated Universal Time)` — which the server rejects in every host TZ\n * (live on Bun 1.4.3: `invalid input syntax for type date` under UTC, `time\n * zone \"gmt-0400\" not recognized` under America/New_York). The ISO text\n * parses for all three, and pins the UTC wall-clock contract the codec table\n * and the other postgres adapters share. Dates the ISO form cannot spell\n * (invalid, BC, beyond year 9999) keep the driver's serializer.\n */\nexport function serializeDate(params: { value: Date }): unknown {\n const { value } = params;\n if (Number.isNaN(value.getTime())) return value;\n const year = value.getUTCFullYear();\n if (year < 1 || year > 9999) return value;\n return value.toISOString();\n}\n\n/**\n * ORM hot path: pass every value straight to bun:sql, except `Date`\n * ({@link serializeDate}).\n *\n * Scalar lists already arrived as array-literal strings from\n * `formatArrayParam`, and bun:sql JSON-encodes objects and arrays for\n * `json`/`jsonb` columns by itself — re-encoding here would store a\n * double-encoded JSON string.\n */\nexport function serializeParams(params: { values: readonly unknown[] }): unknown[] {\n return params.values.map((value) => (value instanceof Date ? serializeDate({ value }) : value));\n}\n\n/**\n * Raw path: render plain JS arrays as PostgreSQL array literals so\n * `db.$queryRawUnsafe('… WHERE \"id\" = ANY($1)', [1, 2, 3])` matches rows;\n * everything else (objects included) goes to bun:sql untouched.\n *\n * Trade-off (v1 lesson): binding a JS array **into** a `jsonb` column from a raw\n * query means calling `JSON.stringify` yourself.\n */\nexport function serializeParamsRaw(params: { values: readonly unknown[] }): unknown[] {\n return params.values.map((value) => {\n if (Array.isArray(value)) return toPgArrayLiteral(value);\n if (value instanceof Date) return serializeDate({ value });\n return value;\n });\n}\n",
9
11
  "/**\n * Synthetic tagged-template cache — bun:sql's prepared-statement path.\n *\n * bun:sql only creates a *named* prepared statement (one PostgreSQL keeps a\n * plan for) when the query arrives as a tagged template. Generated SQL is a\n * plain string, so with `preparedStatements: true` the adapter turns each SQL\n * text into a synthetic `TemplateStringsArray` — split at its `$1`, `$2`, …\n * placeholders — and reuses that same object identity for every execution.\n *\n * A tagged template binds its values POSITIONALLY, one per gap, so the split\n * has to keep two things a plain `text.split(/\\$\\d+/)` throws away (F19):\n *\n * - **which** placeholder each gap is. `SELECT $2, $1` has to bind\n * `values[1]` then `values[0]`, and a repeated `$1` needs its value bound at\n * every occurrence — otherwise the statement silently returns other rows, or\n * reaches the server with too few parameters and fails to parse.\n * - **where** a `$n` is not a placeholder at all: inside a string literal, a\n * quoted identifier, a line or block comment, or a dollar-quoted body. A\n * split there tears the literal apart and produces invalid SQL.\n *\n * The cache is LRU-bounded so a long-running process never grows it without\n * limit.\n */\n\nimport { VibeError } from \"@vibeorm/schema\";\n\n/** A SQL text split for bun:sql, with the placeholder index behind each gap. */\nexport type PreparedTemplate = {\n /** The synthetic template; stable by identity so bun:sql can cache its plan. */\n readonly template: TemplateStringsArray;\n /** 1-based `$n` for each gap, in TEXT order (`SELECT $2, $1` → `[2, 1]`). */\n readonly indices: readonly number[];\n};\n\n/** LRU map from SQL text to the synthetic template used to execute it. */\nexport type TemplateCache = {\n /** Template for `text`, creating one on first sight. Stable by identity. */\n getTemplate(params: { text: string }): PreparedTemplate;\n /** Number of texts currently held — diagnostics and tests. */\n size(): number;\n};\n\n// ─── Scanning ─────────────────────────────────────────────────────\n\n/** Is this character part of an unquoted SQL identifier? */\nfunction isIdentChar(char: string | undefined): boolean {\n if (char === undefined) return false;\n return /[A-Za-z0-9_]/.test(char);\n}\n\n/**\n * Index just past a quoted run starting at `start` (`'…'` or `\"…\"`). A doubled\n * quote (`''`, `\"\"`) continues the run — postgres' own escape. A backslash\n * escapes the next character ONLY in an `E'…'` string; with the default\n * `standard_conforming_strings = on` a backslash inside an ordinary literal is\n * just a backslash, and treating it as an escape would run past the literal's\n * real end.\n */\nfunction skipQuoted(text: string, start: number, quote: string): number {\n const escaping =\n quote === \"'\" && (text[start - 1] === \"e\" || text[start - 1] === \"E\") && !isIdentChar(text[start - 2]);\n let index = start + 1;\n while (index < text.length) {\n const char = text[index];\n if (escaping && char === \"\\\\\") {\n index += 2;\n continue;\n }\n if (char === quote) {\n if (text[index + 1] === quote) {\n index += 2;\n continue;\n }\n return index + 1;\n }\n index += 1;\n }\n return text.length; // unterminated — the driver reports it, not this scanner\n}\n\n/** Index just past a block comment, honouring postgres' nesting. */\nfunction skipBlockComment(text: string, start: number): number {\n let depth = 0;\n let index = start;\n while (index < text.length) {\n if (text[index] === \"/\" && text[index + 1] === \"*\") {\n depth += 1;\n index += 2;\n continue;\n }\n if (text[index] === \"*\" && text[index + 1] === \"/\") {\n depth -= 1;\n index += 2;\n if (depth === 0) return index;\n continue;\n }\n index += 1;\n }\n return text.length;\n}\n\n/**\n * Index just past a dollar-quoted body (`$$…$$`, `$tag$…$tag$`) starting at\n * `start`, or `-1` when no dollar quote opens there. `$1` never matches: a tag\n * has to start with a letter or underscore.\n */\nfunction skipDollarQuoted(text: string, start: number): number {\n const opener = /^\\$(?:[A-Za-z_][A-Za-z0-9_]*)?\\$/.exec(text.slice(start));\n if (opener === null) return -1;\n const tag = opener[0];\n const close = text.indexOf(tag, start + tag.length);\n return close === -1 ? text.length : close + tag.length;\n}\n\n/**\n * Split `text` at its real `$n` placeholders. `chunks.length` is always\n * `indices.length + 1`, which is exactly the shape a tagged template needs.\n */\nexport function scanPlaceholders(params: { text: string }): PreparedTemplate {\n const { text } = params;\n const chunks: string[] = [];\n const indices: number[] = [];\n let chunkStart = 0;\n let index = 0;\n\n while (index < text.length) {\n const char = text[index];\n if (char === \"'\" || char === '\"') {\n index = skipQuoted(text, index, char);\n continue;\n }\n if (char === \"-\" && text[index + 1] === \"-\") {\n const newline = text.indexOf(\"\\n\", index);\n index = newline === -1 ? text.length : newline + 1;\n continue;\n }\n if (char === \"/\" && text[index + 1] === \"*\") {\n index = skipBlockComment(text, index);\n continue;\n }\n if (char === \"$\") {\n const dollarEnd = skipDollarQuoted(text, index);\n if (dollarEnd !== -1) {\n index = dollarEnd;\n continue;\n }\n let digits = index + 1;\n while (digits < text.length && text[digits] !== undefined && /[0-9]/.test(text[digits] as string)) digits += 1;\n if (digits > index + 1) {\n chunks.push(text.slice(chunkStart, index));\n indices.push(Number(text.slice(index + 1, digits)));\n chunkStart = digits;\n index = digits;\n continue;\n }\n }\n index += 1;\n }\n\n chunks.push(text.slice(chunkStart));\n const template = Object.assign(chunks, { raw: chunks }) as unknown as TemplateStringsArray;\n return { template, indices };\n}\n\n/**\n * Split a SQL text on `$n` placeholders into the literal chunks around them.\n *\n * Kept for callers that only want the chunks; it is quote-, comment- and\n * dollar-quote-aware through {@link scanPlaceholders}, so `'$1'` inside a\n * string literal is NOT a split point.\n */\nexport function templateChunks(params: { text: string }): string[] {\n return [...scanPlaceholders(params).template];\n}\n\n// ─── Binding ──────────────────────────────────────────────────────\n\n/**\n * The values to hand a synthetic template, in gap order: `$n` picks\n * `values[n - 1]`, a repeated placeholder repeats its value.\n *\n * A `$n` with no matching value is REFUSED (`VIBE_VALIDATION`) rather than\n * bound to `undefined` — misbinding is exactly the failure mode F19 records.\n */\nexport function bindTemplateValues(params: {\n text: string;\n indices: readonly number[];\n values: readonly unknown[];\n}): unknown[] {\n const { text, indices, values } = params;\n return indices.map((placeholder) => {\n if (placeholder < 1 || placeholder > values.length) {\n throw new VibeError({\n code: \"VIBE_VALIDATION\",\n message: `bun:sql prepared statement references $${placeholder} but only ${values.length} parameter(s) were given`,\n meta: { text, placeholder, provided: values.length },\n });\n }\n return values[placeholder - 1];\n });\n}\n\n// ─── Cache ────────────────────────────────────────────────────────\n\n/**\n * Create a template cache holding at most `max` texts (least recently used\n * evicted first).\n */\nexport function createTemplateCache(params: { max: number }): TemplateCache {\n const { max } = params;\n const templates = new Map<string, PreparedTemplate>();\n\n return {\n getTemplate(templateParams: { text: string }): PreparedTemplate {\n const { text } = templateParams;\n const existing = templates.get(text);\n if (existing !== undefined) {\n // Re-insert to mark most-recently-used.\n templates.delete(text);\n templates.set(text, existing);\n return existing;\n }\n const prepared = scanPlaceholders({ text });\n if (templates.size >= max) {\n const oldest = templates.keys().next().value;\n if (oldest !== undefined) templates.delete(oldest);\n }\n templates.set(text, prepared);\n return prepared;\n },\n\n size(): number {\n return templates.size;\n },\n };\n}\n",
10
- "/**\n * Transaction-control SQL text (postgres dialect, bun:sql flavour).\n *\n * Used by the reserved-connection path, which issues `BEGIN` itself so that\n * isolation level and statement timeout can be applied — bun:sql's\n * `sql.begin(fn)` fast path takes no such options.\n */\n\nimport type { IsolationLevel, TransactionOptions } from \"@vibeorm/runtime\";\nimport { VibeError } from \"@vibeorm/schema\";\n\n/** VibeORM isolation level → PostgreSQL isolation level keyword. */\nexport const ISOLATION_LEVEL_SQL: Readonly<Record<IsolationLevel, string>> = Object.freeze({\n ReadCommitted: \"READ COMMITTED\",\n RepeatableRead: \"REPEATABLE READ\",\n Serializable: \"SERIALIZABLE\",\n});\n\n/** `BEGIN`, with an `ISOLATION LEVEL` clause when the caller asked for one. */\nexport function beginStatement(params: { isolationLevel?: IsolationLevel }): string {\n const { isolationLevel } = params;\n return isolationLevel === undefined\n ? \"BEGIN\"\n : `BEGIN ISOLATION LEVEL ${ISOLATION_LEVEL_SQL[isolationLevel]}`;\n}\n\n/**\n * `SET LOCAL statement_timeout = <ms>` — transaction-scoped, so PostgreSQL\n * cancels an over-long statement with SQLSTATE 57014 (mapped to\n * `VIBE_TRANSACTION` with `meta.reason = \"timeout\"`).\n *\n * @throws VibeError `VIBE_VALIDATION` when the timeout is not a non-negative\n * integer — the value is interpolated into SQL, so it is never trusted blindly.\n */\nexport function statementTimeoutStatement(params: { timeout: number }): string {\n const { timeout } = params;\n if (!Number.isInteger(timeout) || timeout < 0) {\n throw new VibeError({\n code: \"VIBE_VALIDATION\",\n message: `transaction timeout must be a non-negative integer of milliseconds, received ${String(timeout)}`,\n meta: { timeout },\n });\n }\n return `SET LOCAL statement_timeout = ${timeout}`;\n}\n\n// ─── Raw transaction control (session affinity) ─────────────────\n\n/** How a raw statement steers the adapter's session-affine raw transaction. */\nexport type RawTransactionControl = \"open\" | \"close\" | null;\n\nconst RAW_OPEN_PATTERN: RegExp = /^\\s*(?:begin|start\\s+transaction)\\b[^;]*;?\\s*$/i;\nconst RAW_CLOSE_PATTERN: RegExp = /^\\s*(?:commit|end|rollback|abort)(?:\\s+(?:transaction|work))?\\s*;?\\s*$/i;\n\n/**\n * Classify a raw statement as transaction control.\n *\n * @vibeorm/migrate drives transactional DDL by sending literal `BEGIN` /\n * `COMMIT` / `ROLLBACK` through its stateless `SqlExecutor` — sound only when\n * every statement in between rides the SAME connection. The adapter uses this\n * to pin one connection for the whole raw transaction (\"open\" reserves,\n * \"close\" releases). On a pooled bun:sql instance an unpinned `BEGIN` is\n * refused outright by the driver (`ERR_POSTGRES_UNSAFE_TRANSACTION`); other\n * pool drivers would only work by checkout luck.\n *\n * Deliberately strict: only PURE single-statement control text matches\n * (`BEGIN`, `BEGIN ISOLATION LEVEL …;`, `COMMIT`, `ROLLBACK WORK`, `END`,\n * `ABORT`). Compound scripts, `ROLLBACK TO SAVEPOINT`, two-phase\n * `COMMIT PREPARED` and `COMMIT AND CHAIN` (which keeps a transaction open)\n * never engage the pinning.\n */\nexport function classifyRawTransactionControl(params: { text: string }): RawTransactionControl {\n if (RAW_OPEN_PATTERN.test(params.text)) return \"open\";\n if (RAW_CLOSE_PATTERN.test(params.text)) return \"close\";\n return null;\n}\n\n// ─── Nested transaction options (the cross-adapter contract) ──────\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 * Silently dropping the option (the pre-#3 behaviour) hid exactly that.\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 (options.deadline !== undefined) passed.push(\"deadline\");\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 if (options.deadline !== undefined) meta.deadline = options.deadline;\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, a nested timeout is not enforceable, and a nested deadline would need its own session setting on a connection it does not own (it inherits the top-level one instead); pass options on the top-level $transaction`,\n meta,\n });\n}\n"
12
+ "/**\n * Transaction-control SQL text (postgres dialect, bun:sql flavour).\n *\n * Used by the reserved-connection path, which issues `BEGIN` itself so that\n * isolation level and statement timeout can be applied — bun:sql's\n * `sql.begin(fn)` fast path takes no such options.\n */\n\nimport type { IsolationLevel } from \"@vibeorm/runtime\";\nimport { VibeError } from \"@vibeorm/schema\";\n\n/** VibeORM isolation level → PostgreSQL isolation level keyword. */\nexport const ISOLATION_LEVEL_SQL: Readonly<Record<IsolationLevel, string>> = Object.freeze({\n ReadCommitted: \"READ COMMITTED\",\n RepeatableRead: \"REPEATABLE READ\",\n Serializable: \"SERIALIZABLE\",\n});\n\n/** `BEGIN`, with an `ISOLATION LEVEL` clause when the caller asked for one. */\nexport function beginStatement(params: { isolationLevel?: IsolationLevel }): string {\n const { isolationLevel } = params;\n return isolationLevel === undefined\n ? \"BEGIN\"\n : `BEGIN ISOLATION LEVEL ${ISOLATION_LEVEL_SQL[isolationLevel]}`;\n}\n\n/**\n * `SET LOCAL statement_timeout = <ms>` — transaction-scoped, so PostgreSQL\n * cancels an over-long statement with SQLSTATE 57014 (mapped to\n * `VIBE_TRANSACTION` with `meta.reason = \"timeout\"`).\n *\n * @throws VibeError `VIBE_VALIDATION` when the timeout is not a non-negative\n * integer — the value is interpolated into SQL, so it is never trusted blindly.\n */\nexport function statementTimeoutStatement(params: { timeout: number }): string {\n const { timeout } = params;\n if (!Number.isInteger(timeout) || timeout < 0) {\n throw new VibeError({\n code: \"VIBE_VALIDATION\",\n message: `transaction timeout must be a non-negative integer of milliseconds, received ${String(timeout)}`,\n meta: { timeout },\n });\n }\n return `SET LOCAL statement_timeout = ${timeout}`;\n}\n\n// ─── Raw transaction control (session affinity) ─────────────────\n\n/** How a raw statement steers the adapter's session-affine raw transaction. */\nexport type RawTransactionControl = \"open\" | \"close\" | null;\n\nconst RAW_OPEN_PATTERN: RegExp = /^\\s*(?:begin|start\\s+transaction)\\b[^;]*;?\\s*$/i;\nconst RAW_CLOSE_PATTERN: RegExp = /^\\s*(?:commit|end|rollback|abort)(?:\\s+(?:transaction|work))?\\s*;?\\s*$/i;\n\n/**\n * Classify a raw statement as transaction control.\n *\n * @vibeorm/migrate drives transactional DDL by sending literal `BEGIN` /\n * `COMMIT` / `ROLLBACK` through its stateless `SqlExecutor` — sound only when\n * every statement in between rides the SAME connection. The adapter uses this\n * to pin one connection for the whole raw transaction (\"open\" reserves,\n * \"close\" releases). On a pooled bun:sql instance an unpinned `BEGIN` is\n * refused outright by the driver (`ERR_POSTGRES_UNSAFE_TRANSACTION`); other\n * pool drivers would only work by checkout luck.\n *\n * Deliberately strict: only PURE single-statement control text matches\n * (`BEGIN`, `BEGIN ISOLATION LEVEL …;`, `COMMIT`, `ROLLBACK WORK`, `END`,\n * `ABORT`). Compound scripts, `ROLLBACK TO SAVEPOINT`, two-phase\n * `COMMIT PREPARED` and `COMMIT AND CHAIN` (which keeps a transaction open)\n * never engage the pinning.\n */\nexport function classifyRawTransactionControl(params: { text: string }): RawTransactionControl {\n if (RAW_OPEN_PATTERN.test(params.text)) return \"open\";\n if (RAW_CLOSE_PATTERN.test(params.text)) return \"close\";\n return null;\n}\n\n// ─── Nested transaction options (the cross-adapter contract) ──────\n\n// ONE copy, shared by every adapter through the runtime's adapter-kit;\n// re-exported here so this adapter's public surface is unchanged.\nexport { refuseNestedTransactionOptions } from \"@vibeorm/runtime/adapter-kit\";\n"
11
13
  ],
12
- "mappings": ";;AASA;AACA;AAQA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACHA;AAgBO,SAAS,mBAAmB,CAAC,QAGb;AAAA,EACrB,QAAQ,eAAe,qBAAqB;AAAA,EAC5C,MAAM,QAAkB,CAAC;AAAA,EACzB,IAAI,kBAAkB;AAAA,IAAQ,MAAM,KAAK,sBAAsB,eAAe;AAAA,EAC9E,IAAI,qBAAqB,WAAW;AAAA,IAClC,IAAI,CAAC,OAAO,UAAU,gBAAgB,KAAK,mBAAmB,GAAG;AAAA,MAC/D,MAAM,IAAI,UAAU;AAAA,QAClB,MAAM;AAAA,QACN,SAAS,6EAA6E,OAAO,gBAAgB;AAAA,QAC7G,MAAM,EAAE,iBAAiB;AAAA,MAC3B,CAAC;AAAA,IACH;AAAA,IACA,MAAM,KAAK,wBAAwB,kBAAkB;AAAA,EACvD;AAAA,EACA,OAAO,MAAM,WAAW,IAAI,YAAY,MAAM,KAAK,GAAG;AAAA;AAIjD,SAAS,mBAAmB,CAAC,QAAyD;AAAA,EAC3F,QAAQ,KAAK,mBAAmB;AAAA,EAChC,MAAM,YAAY,IAAI,SAAS,GAAG,IAAI,MAAM;AAAA,EAC5C,OAAO,GAAG,MAAM,oBAAoB,mBAAmB,cAAc;AAAA;;;AC5CvE,sBAAS;AASF,IAAM,2BAAoE,OAAO,OAAO;AAAA,EAE7F,SAAS;AAAA,EAET,SAAS;AAAA,EAET,SAAS;AAAA,EAET,SAAS;AAAA,EAET,SAAS;AAAA,EAET,SAAS;AAAA,EAMT,SAAS;AAAA,EAMT,SAAS;AAAA,EAET,SAAS;AAAA,EAET,SAAS;AAAA,EAET,SAAS;AAAA,EAKT,SAAS;AACX,CAAC;AAGM,IAAM,uBAAyD,OAAO,OAAO;AAAA,EAClF,SAAS;AAAA,EACT,SAAS;AAAA,EACT,SAAS;AAAA,EACT,SAAS;AAAA,EACT,SAAS;AACX,CAAC;AAKD,IAAM,mBAAmB;AAEzB,SAAS,eAAe,CAAC,QAA8E;AAAA,EACrG,MAAM,QAAQ,OAAO,OAAO,OAAO;AAAA,EACnC,OAAO,OAAO,UAAU,YAAY,MAAM,SAAS,IAAI,QAAQ;AAAA;AAO1D,SAAS,gBAAgB,CAAC,QAAgD;AAAA,EAC/E,QAAQ,UAAU;AAAA,EAClB,IAAI,UAAU,QAAQ,OAAO,UAAU;AAAA,IAAU;AAAA,EACjD,MAAM,SAAS;AAAA,EACf,WAAW,OAAO,CAAC,QAAQ,OAAO,GAAG;AAAA,IACnC,MAAM,QAAQ,gBAAgB,EAAE,QAAQ,IAAI,CAAC;AAAA,IAC7C,IAAI,UAAU,aAAa,iBAAiB,KAAK,KAAK;AAAA,MAAG,OAAO;AAAA,EAClE;AAAA,EACA;AAAA;AAWK,SAAS,iBAAiB,CAAC,QAAuC;AAAA,EACvE,QAAQ,UAAU;AAAA,EAClB,IAAI,iBAAiB;AAAA,IAAW,OAAO;AAAA,EAEvC,MAAM,SACJ,UAAU,QAAQ,OAAO,UAAU,WAAY,QAAoC,CAAC;AAAA,EACtF,MAAM,WAAW,iBAAiB,EAAE,MAAM,CAAC;AAAA,EAC3C,MAAM,QACH,aAAa,YAAY,YAAY,yBAAyB,cAAc;AAAA,EAE/E,MAAM,OAAgC,CAAC;AAAA,EACvC,IAAI,aAAa;AAAA,IAAW,KAAK,WAAW;AAAA,EAC5C,MAAM,aAAa,gBAAgB,EAAE,QAAQ,KAAK,aAAa,CAAC;AAAA,EAChE,IAAI,eAAe;AAAA,IAAW,KAAK,aAAa;AAAA,EAChD,MAAM,QAAQ,gBAAgB,EAAE,QAAQ,KAAK,QAAQ,CAAC;AAAA,EACtD,IAAI,UAAU;AAAA,IAAW,KAAK,QAAQ;AAAA,EACtC,MAAM,SAAS,gBAAgB,EAAE,QAAQ,KAAK,SAAS,CAAC;AAAA,EACxD,IAAI,WAAW;AAAA,IAAW,KAAK,SAAS;AAAA,EACxC,MAAM,SAAS,aAAa,YAAY,YAAY,qBAAqB;AAAA,EACzE,IAAI,WAAW;AAAA,IAAW,KAAK,SAAS;AAAA,EAGxC,MAAM,aAAa,gBAAgB,EAAE,QAAQ,KAAK,OAAO,CAAC;AAAA,EAC1D,IAAI,eAAe,aAAa,eAAe;AAAA,IAAU,KAAK,aAAa;AAAA,EAE3E,MAAM,UACJ,gBAAgB,EAAE,QAAQ,KAAK,UAAU,CAAC,MACzC,OAAO,UAAU,WAAW,QAAQ;AAAA,EAEvC,OAAO,IAAI,WAAU,EAAE,MAAM,SAAS,MAAM,OAAO,MAAM,CAAC;AAAA;AAI5D,eAAsB,SAAY,CAAC,IAAkC;AAAA,EACnE,IAAI;AAAA,IACF,OAAO,MAAM,GAAG;AAAA,IAChB,OAAO,OAAO;AAAA,IACd,MAAM,kBAAkB,EAAE,MAAM,CAAC;AAAA;AAAA;;;ACrHrC,sBAAS;AAKT,SAAS,YAAY,CAAC,OAAuB;AAAA,EAC3C,OAAO,IAAI,MAAM,QAAQ,OAAO,MAAM,EAAE,QAAQ,MAAM,MAAK;AAAA;AAmBtD,SAAS,gBAAgB,CAAC,QAAoC;AAAA,EACnE,MAAM,WAAW,OAAO,IAAI,CAAC,UAAU;AAAA,IACrC,IAAI,UAAU,QAAQ,UAAU;AAAA,MAAW,OAAO;AAAA,IAClD,IAAI,OAAO,UAAU,YAAY,OAAO,UAAU,YAAY,OAAO,UAAU,WAAW;AAAA,MACxF,OAAO,OAAO,KAAK;AAAA,IACrB;AAAA,IACA,IAAI,iBAAiB;AAAA,MAAM,OAAO,aAAa,MAAM,YAAY,CAAC;AAAA,IAClE,IAAI,YAAY,OAAO,KAAK,KAAK,iBAAiB,aAAa;AAAA,MAC7D,MAAM,IAAI,WAAU;AAAA,QAClB,MAAM;AAAA,QACN,SAAS;AAAA,QACT,MAAM,EAAE,QAAQ,UAAU;AAAA,MAC5B,CAAC;AAAA,IACH;AAAA,IACA,IAAI,OAAO,UAAU;AAAA,MAAU,OAAO,aAAa,KAAK;AAAA,IACxD,IAAI,OAAO,UAAU;AAAA,MAAU,OAAO,aAAa,KAAK,UAAU,KAAK,CAAC;AAAA,IACxE,OAAO,aAAa,OAAO,KAAK,CAAC;AAAA,GAClC;AAAA,EACD,OAAO,IAAI,SAAS,KAAK,GAAG;AAAA;AAmBvB,SAAS,aAAa,CAAC,QAAkC;AAAA,EAC9D,QAAQ,UAAU;AAAA,EAClB,IAAI,OAAO,MAAM,MAAM,QAAQ,CAAC;AAAA,IAAG,OAAO;AAAA,EAC1C,MAAM,OAAO,MAAM,eAAe;AAAA,EAClC,IAAI,OAAO,KAAK,OAAO;AAAA,IAAM,OAAO;AAAA,EACpC,OAAO,MAAM,YAAY;AAAA;AAYpB,SAAS,eAAe,CAAC,QAAmD;AAAA,EACjF,OAAO,OAAO,OAAO,IAAI,CAAC,UAAW,iBAAiB,OAAO,cAAc,EAAE,MAAM,CAAC,IAAI,KAAM;AAAA;AAWzF,SAAS,kBAAkB,CAAC,QAAmD;AAAA,EACpF,OAAO,OAAO,OAAO,IAAI,CAAC,UAAU;AAAA,IAClC,IAAI,MAAM,QAAQ,KAAK;AAAA,MAAG,OAAO,iBAAiB,KAAK;AAAA,IACvD,IAAI,iBAAiB;AAAA,MAAM,OAAO,cAAc,EAAE,MAAM,CAAC;AAAA,IACzD,OAAO;AAAA,GACR;AAAA;;;AC5FH,sBAAS;AAqBT,SAAS,WAAW,CAAC,MAAmC;AAAA,EACtD,IAAI,SAAS;AAAA,IAAW,OAAO;AAAA,EAC/B,OAAO,eAAe,KAAK,IAAI;AAAA;AAWjC,SAAS,UAAU,CAAC,MAAc,OAAe,OAAuB;AAAA,EACtE,MAAM,WACJ,UAAU,QAAQ,KAAK,QAAQ,OAAO,OAAO,KAAK,QAAQ,OAAO,QAAQ,CAAC,YAAY,KAAK,QAAQ,EAAE;AAAA,EACvG,IAAI,QAAQ,QAAQ;AAAA,EACpB,OAAO,QAAQ,KAAK,QAAQ;AAAA,IAC1B,MAAM,OAAO,KAAK;AAAA,IAClB,IAAI,YAAY,SAAS,MAAM;AAAA,MAC7B,SAAS;AAAA,MACT;AAAA,IACF;AAAA,IACA,IAAI,SAAS,OAAO;AAAA,MAClB,IAAI,KAAK,QAAQ,OAAO,OAAO;AAAA,QAC7B,SAAS;AAAA,QACT;AAAA,MACF;AAAA,MACA,OAAO,QAAQ;AAAA,IACjB;AAAA,IACA,SAAS;AAAA,EACX;AAAA,EACA,OAAO,KAAK;AAAA;AAId,SAAS,gBAAgB,CAAC,MAAc,OAAuB;AAAA,EAC7D,IAAI,QAAQ;AAAA,EACZ,IAAI,QAAQ;AAAA,EACZ,OAAO,QAAQ,KAAK,QAAQ;AAAA,IAC1B,IAAI,KAAK,WAAW,OAAO,KAAK,QAAQ,OAAO,KAAK;AAAA,MAClD,SAAS;AAAA,MACT,SAAS;AAAA,MACT;AAAA,IACF;AAAA,IACA,IAAI,KAAK,WAAW,OAAO,KAAK,QAAQ,OAAO,KAAK;AAAA,MAClD,SAAS;AAAA,MACT,SAAS;AAAA,MACT,IAAI,UAAU;AAAA,QAAG,OAAO;AAAA,MACxB;AAAA,IACF;AAAA,IACA,SAAS;AAAA,EACX;AAAA,EACA,OAAO,KAAK;AAAA;AAQd,SAAS,gBAAgB,CAAC,MAAc,OAAuB;AAAA,EAC7D,MAAM,SAAS,mCAAmC,KAAK,KAAK,MAAM,KAAK,CAAC;AAAA,EACxE,IAAI,WAAW;AAAA,IAAM,OAAO;AAAA,EAC5B,MAAM,MAAM,OAAO;AAAA,EACnB,MAAM,QAAQ,KAAK,QAAQ,KAAK,QAAQ,IAAI,MAAM;AAAA,EAClD,OAAO,UAAU,KAAK,KAAK,SAAS,QAAQ,IAAI;AAAA;AAO3C,SAAS,gBAAgB,CAAC,QAA4C;AAAA,EAC3E,QAAQ,SAAS;AAAA,EACjB,MAAM,SAAmB,CAAC;AAAA,EAC1B,MAAM,UAAoB,CAAC;AAAA,EAC3B,IAAI,aAAa;AAAA,EACjB,IAAI,QAAQ;AAAA,EAEZ,OAAO,QAAQ,KAAK,QAAQ;AAAA,IAC1B,MAAM,OAAO,KAAK;AAAA,IAClB,IAAI,SAAS,OAAO,SAAS,KAAK;AAAA,MAChC,QAAQ,WAAW,MAAM,OAAO,IAAI;AAAA,MACpC;AAAA,IACF;AAAA,IACA,IAAI,SAAS,OAAO,KAAK,QAAQ,OAAO,KAAK;AAAA,MAC3C,MAAM,UAAU,KAAK,QAAQ;AAAA,GAAM,KAAK;AAAA,MACxC,QAAQ,YAAY,KAAK,KAAK,SAAS,UAAU;AAAA,MACjD;AAAA,IACF;AAAA,IACA,IAAI,SAAS,OAAO,KAAK,QAAQ,OAAO,KAAK;AAAA,MAC3C,QAAQ,iBAAiB,MAAM,KAAK;AAAA,MACpC;AAAA,IACF;AAAA,IACA,IAAI,SAAS,KAAK;AAAA,MAChB,MAAM,YAAY,iBAAiB,MAAM,KAAK;AAAA,MAC9C,IAAI,cAAc,IAAI;AAAA,QACpB,QAAQ;AAAA,QACR;AAAA,MACF;AAAA,MACA,IAAI,SAAS,QAAQ;AAAA,MACrB,OAAO,SAAS,KAAK,UAAU,KAAK,YAAY,aAAa,QAAQ,KAAK,KAAK,OAAiB;AAAA,QAAG,UAAU;AAAA,MAC7G,IAAI,SAAS,QAAQ,GAAG;AAAA,QACtB,OAAO,KAAK,KAAK,MAAM,YAAY,KAAK,CAAC;AAAA,QACzC,QAAQ,KAAK,OAAO,KAAK,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC;AAAA,QAClD,aAAa;AAAA,QACb,QAAQ;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAAA,IACA,SAAS;AAAA,EACX;AAAA,EAEA,OAAO,KAAK,KAAK,MAAM,UAAU,CAAC;AAAA,EAClC,MAAM,WAAW,OAAO,OAAO,QAAQ,EAAE,KAAK,OAAO,CAAC;AAAA,EACtD,OAAO,EAAE,UAAU,QAAQ;AAAA;AAUtB,SAAS,cAAc,CAAC,QAAoC;AAAA,EACjE,OAAO,CAAC,GAAG,iBAAiB,MAAM,EAAE,QAAQ;AAAA;AAYvC,SAAS,kBAAkB,CAAC,QAIrB;AAAA,EACZ,QAAQ,MAAM,SAAS,WAAW;AAAA,EAClC,OAAO,QAAQ,IAAI,CAAC,gBAAgB;AAAA,IAClC,IAAI,cAAc,KAAK,cAAc,OAAO,QAAQ;AAAA,MAClD,MAAM,IAAI,WAAU;AAAA,QAClB,MAAM;AAAA,QACN,SAAS,0CAA0C,wBAAwB,OAAO;AAAA,QAClF,MAAM,EAAE,MAAM,aAAa,UAAU,OAAO,OAAO;AAAA,MACrD,CAAC;AAAA,IACH;AAAA,IACA,OAAO,OAAO,cAAc;AAAA,GAC7B;AAAA;AASI,SAAS,mBAAmB,CAAC,QAAwC;AAAA,EAC1E,QAAQ,QAAQ;AAAA,EAChB,MAAM,YAAY,IAAI;AAAA,EAEtB,OAAO;AAAA,IACL,WAAW,CAAC,gBAAoD;AAAA,MAC9D,QAAQ,SAAS;AAAA,MACjB,MAAM,WAAW,UAAU,IAAI,IAAI;AAAA,MACnC,IAAI,aAAa,WAAW;AAAA,QAE1B,UAAU,OAAO,IAAI;AAAA,QACrB,UAAU,IAAI,MAAM,QAAQ;AAAA,QAC5B,OAAO;AAAA,MACT;AAAA,MACA,MAAM,WAAW,iBAAiB,EAAE,KAAK,CAAC;AAAA,MAC1C,IAAI,UAAU,QAAQ,KAAK;AAAA,QACzB,MAAM,SAAS,UAAU,KAAK,EAAE,KAAK,EAAE;AAAA,QACvC,IAAI,WAAW;AAAA,UAAW,UAAU,OAAO,MAAM;AAAA,MACnD;AAAA,MACA,UAAU,IAAI,MAAM,QAAQ;AAAA,MAC5B,OAAO;AAAA;AAAA,IAGT,IAAI,GAAW;AAAA,MACb,OAAO,UAAU;AAAA;AAAA,EAErB;AAAA;;;ACjOF,sBAAS;AAGF,IAAM,sBAAgE,OAAO,OAAO;AAAA,EACzF,eAAe;AAAA,EACf,gBAAgB;AAAA,EAChB,cAAc;AAChB,CAAC;AAGM,SAAS,cAAc,CAAC,QAAqD;AAAA,EAClF,QAAQ,mBAAmB;AAAA,EAC3B,OAAO,mBAAmB,YACtB,UACA,yBAAyB,oBAAoB;AAAA;AAW5C,SAAS,yBAAyB,CAAC,QAAqC;AAAA,EAC7E,QAAQ,YAAY;AAAA,EACpB,IAAI,CAAC,OAAO,UAAU,OAAO,KAAK,UAAU,GAAG;AAAA,IAC7C,MAAM,IAAI,WAAU;AAAA,MAClB,MAAM;AAAA,MACN,SAAS,gFAAgF,OAAO,OAAO;AAAA,MACvG,MAAM,EAAE,QAAQ;AAAA,IAClB,CAAC;AAAA,EACH;AAAA,EACA,OAAO,iCAAiC;AAAA;AAQ1C,IAAM,mBAA2B;AACjC,IAAM,oBAA4B;AAmB3B,SAAS,6BAA6B,CAAC,QAAiD;AAAA,EAC7F,IAAI,iBAAiB,KAAK,OAAO,IAAI;AAAA,IAAG,OAAO;AAAA,EAC/C,IAAI,kBAAkB,KAAK,OAAO,IAAI;AAAA,IAAG,OAAO;AAAA,EAChD,OAAO;AAAA;AAeF,SAAS,8BAA8B,CAAC,QAGtC;AAAA,EACP,QAAQ,SAAS,aAAa;AAAA,EAC9B,IAAI,YAAY;AAAA,IAAW;AAAA,EAE3B,MAAM,SAAmB,CAAC;AAAA,EAC1B,IAAI,QAAQ,mBAAmB;AAAA,IAAW,OAAO,KAAK,gBAAgB;AAAA,EACtE,IAAI,QAAQ,YAAY;AAAA,IAAW,OAAO,KAAK,SAAS;AAAA,EACxD,IAAI,QAAQ,aAAa;AAAA,IAAW,OAAO,KAAK,UAAU;AAAA,EAC1D,IAAI,OAAO,WAAW;AAAA,IAAG;AAAA,EAEzB,MAAM,OAAgC,EAAE,UAAU,QAAQ,KAAK;AAAA,EAC/D,IAAI,QAAQ,mBAAmB;AAAA,IAAW,KAAK,iBAAiB,QAAQ;AAAA,EACxE,IAAI,QAAQ,YAAY;AAAA,IAAW,KAAK,UAAU,QAAQ;AAAA,EAC1D,IAAI,QAAQ,aAAa;AAAA,IAAW,KAAK,WAAW,QAAQ;AAAA,EAE5D,MAAM,IAAI,WAAU;AAAA,IAClB,MAAM;AAAA,IACN,SAAS,0DAA0D,OAAO,KAAK,MAAM;AAAA,IACrF;AAAA,EACF,CAAC;AAAA;;;ALiiBH;AAaA;AAAA;AAAA,6BAEE;AAAA,gCACA;AAAA,4BACA;AAAA;AAAA;AAAA,oCAGA;AAAA,iCACA;AAAA;AAAA;AA1kBF,MAAM,sBAAsB,MAAM;AAAA,EACvB;AAAA,EAET,WAAW,CAAC,OAAgB;AAAA,IAC1B,MAAM,sCAAsC;AAAA,IAC5C,KAAK,OAAO;AAAA,IACZ,KAAK,QAAQ;AAAA;AAEjB;AAqCA,IAAM,UAAmB;AACzB,IAAM,WAAqB;AA+B3B,IAAM,UAAgC,OAAO,OAAO;AAAA,EAClD,gBAAgB;AAAA,EAChB,kBAAkB;AAAA,EAClB,qBAAqB;AACvB,CAAU;AAEV,IAAM,YAA0B,OAAO,OAAO,EAAE,UAAU,UAAU,MAAM,QAAQ,SAAS,SAAS,CAAU;AAG9G,IAAM,cAA4B,OAAO,OAAO,EAAE,UAAU,UAAU,MAAM,UAAU,SAAS,SAAS,CAAU;AAY3G,SAAS,UAAU,CAAC,SAA8C;AAAA,EACvE,MAAM,cAAc,SAAS,sBAAsB;AAAA,EACnD,MAAM,YAAY,oBAAoB,EAAE,KAAK,SAAS,gBAAgB,KAAK,CAAC;AAAA,EAU5E,IAAI,aAA2B;AAAA,EAC/B,IAAI,cAAc;AAAA,EAClB,IAAI,YAAkC;AAAA,EAEtC,IAAI,WAA+B;AAAA,EAcnC,IAAI,aAAiC;AAAA,EAErC,SAAS,MAAM,GAAgB;AAAA,IAC7B,IAAI,aAAa;AAAA,MAAM,OAAO;AAAA,IAE9B,MAAM,aAAsC,EAAE,KAAK,SAAS,OAAO,GAAG;AAAA,IACtE,IAAI,SAAS,sBAAsB,WAAW;AAAA,MAE5C,WAAW,oBAAoB,KAAK,IAAI,GAAG,KAAK,KAAK,QAAQ,oBAAoB,IAAI,CAAC;AAAA,IACxF;AAAA,IAEA,MAAM,iBAAiB,oBAAoB;AAAA,MACzC,eAAe,SAAS,iBAAiB;AAAA,MACzC,kBAAkB,SAAS;AAAA,IAC7B,CAAC;AAAA,IACD,MAAM,UAAU,SAAS,OAAO,QAAQ,IAAI;AAAA,IAC5C,MAAM,MACJ,YAAY,aAAa,mBAAmB,YACxC,UACA,oBAAoB,EAAE,KAAK,SAAS,eAAe,CAAC;AAAA,IAI1D,WACE,QAAQ,YACH,IAAI,IAAI,UAAU,IAClB,IAAI,IAAI,KAAK,UAAU;AAAA,IAC9B,OAAO;AAAA;AAAA,EAeT,eAAe,aAAa,CAAC,QAAoC;AAAA,IAC/D,MAAM,QAAQ,iBAAiB,EAAE,SAAS,iBAAiB,OAAO,mBAAmB,CAAC;AAAA,IACtF,IAAI;AAAA,MACF,MAAM,OAAO,cACT,MAAM,OAAO,UAAU,YAAY,EAAE,MAAM,MAAM,KAAK,CAAC,EAAE,QAAQ,IACjE,MAAM,OAAO,OAAO,MAAM,MAAM,CAAC,CAAC;AAAA,MACtC,MAAM,SAAS,KAAK,IAAI;AAAA,MACxB,IAAI,OAAO,WAAW,YAAY,WAAW;AAAA,QAAM,aAAa;AAAA,MAChE,MAAM,WAEN;AAAA,MACA,cAAc;AAAA;AAAA;AAAA,EAIlB,eAAe,UAAU,CAAC,QAIa;AAAA,IAKrC,IAAI,CAAC,aAAa;AAAA,MAChB,cAAc,cAAc,OAAO,MAAM;AAAA,MACzC,MAAM;AAAA,IACR;AAAA,IACA,MAAM,SAAS,gBAAgB,EAAE,QAAQ,OAAO,OAAO,CAAC;AAAA,IACxD,IAAI,aAAa;AAAA,MAIf,MAAM,WAAW,UAAU,YAAY,EAAE,MAAM,OAAO,KAAK,CAAC;AAAA,MAC5D,MAAM,QAAQ,mBAAmB,EAAE,MAAM,OAAO,MAAM,SAAS,SAAS,SAAS,OAAO,CAAC;AAAA,MACzF,OAAO,UAAU,MAAM,OAAO,OAAO,SAAS,UAAU,GAAG,KAAK,CAAC;AAAA,IACnE;AAAA,IACA,OAAO,UAAU,MAAM,OAAO,OAAO,OAAO,OAAO,MAAM,MAAM,CAAC;AAAA;AAAA,EAGlE,eAAe,gBAAgB,CAAC,QAIP;AAAA,IACvB,MAAM,SAAS,OAAO,WAAW,YAAY,YAAY,mBAAmB,EAAE,QAAQ,OAAO,OAAO,CAAC;AAAA,IACrG,MAAM,OAAO,MAAM,UAAU,MAAM,OAAO,OAAO,OAAO,OAAO,MAAM,MAAM,CAAC;AAAA,IAC5E,OAAO,EAAE,MAAM,cAAc,iBAAiB,EAAE,KAAK,CAAC,EAAE;AAAA;AAAA,EAU1D,SAAS,aAAa,CAAC,QAMH;AAAA,IAClB,QAAQ,QAAQ,YAAY,OAAO,WAAW;AAAA,IAS9C,eAAe,iBAAiB,GAAkB;AAAA,MAChD,IAAI,WAAW;AAAA,QAAW;AAAA,MAC1B,MAAM,KAAK,wBAAwB,EAAE,OAAO,CAAC;AAAA,MAC7C,IAAI,OAAO;AAAA,QAAM;AAAA,MACjB,MAAM,UAAU,MAAO,OAA0B,OAAO,0BAA0B,EAAE,SAAS,GAAG,CAAC,CAAC,CAAC;AAAA;AAAA,IAIrG,eAAe,uBAA0B,CACvC,IACA,eACY;AAAA,MACZ,+BAA+B,EAAE,SAAS,eAAe,UAAU,SAAS,CAAC;AAAA,MAC7E,QAAQ,aAAa,EAAE,OAAO,SAAS,CAAC;AAAA,MACxC,MAAM,gBAAgB;AAAA,MAKtB,MAAM,kBAAkB,cAAc,WAAW,KAAK,aAAa;AAAA,MACnE,IAAI,oBAAoB,WAAW;AAAA,QACjC,OAAO,mBAAmB;AAAA,UACxB;AAAA,UACA,MAAM,OAAO,UAAU;AAAA,YACrB,IAAI;AAAA,cACF,OAAO,MAAM,gBAAgB,OAAO,iBAAiB;AAAA,gBACnD,MAAM,SAAS,cAAc;AAAA,kBAC3B,QAAQ;AAAA,kBACR,YAAY;AAAA,kBACZ,OAAO;AAAA,gBACT,CAAC;AAAA,gBACD,IAAI;AAAA,kBACF,OAAO,MAAM,GAAG,MAAM;AAAA,kBACtB,OAAO,OAAO;AAAA,kBACd,MAAM,IAAI,cAAc,KAAK;AAAA;AAAA,eAEhC;AAAA,cACD,OAAO,OAAO;AAAA,cACd,IAAI,iBAAiB;AAAA,gBAAe,MAAM,MAAM;AAAA,cAChD,MAAM,kBAAkB,EAAE,MAAM,CAAC;AAAA;AAAA;AAAA,QAGvC,CAAC;AAAA,MACH;AAAA,MAIA,OAAO,mBAAmB;AAAA,QACxB;AAAA,QACA,SAAS,CAAC,cAAc,UAAU,MAAM,cAAc,OAAO,SAAS,CAAC;AAAA,QAGvE,MAAM,CAAC,UACL,GAAG,cAAc,EAAE,QAAQ,eAAe,YAAY,MAAM,OAAO,OAAO,OAAO,CAAC,CAAC;AAAA,MACvF,CAAC;AAAA;AAAA,IAIH,eAAe,kBAAqB,CAClC,IACA,oBACY;AAAA,MACZ,MAAM,OAAO;AAAA,MAGb,4BAA4B;AAAA,QAC1B,SAAS;AAAA,QACT,SAAS,QAAQ;AAAA,QACjB,UAAU;AAAA,MACZ,CAAC;AAAA,MAKD,IACE,oBAAoB,mBAAmB,aACvC,oBAAoB,YAAY,aAChC,oBAAoB,aAAa,WACjC;AAAA,QAGA,MAAM,UAAS,uBAAuB,EAAE,UAAU,SAAS,CAAC;AAAA,QAC5D,IAAI;AAAA,UACF,MAAM,SAAS,MAAM,KAAK,MAAM,OAAO,UAAU;AAAA,YAC/C,MAAM,UAAU,qBAAqB;AAAA,YACrC,MAAM,YAAY,cAAc;AAAA,cAC9B,QAAQ;AAAA,cACR,YAAY;AAAA,cACZ,OAAO;AAAA,cACP;AAAA,YACF,CAAC;AAAA,YACD,IAAI;AAAA,cACF,OAAO,MAAM,aAAa,EAAE,OAAO,SAAS,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;AAAA,cACvE,OAAO,OAAO;AAAA,cACd,MAAM,IAAI,cAAc,KAAK;AAAA;AAAA,WAEhC;AAAA,UACD,QAAO,MAAM,EAAE,SAAS,YAAY,CAAC;AAAA,UACrC,OAAO;AAAA,UACP,OAAO,OAAO;AAAA,UAGd,QAAO,MAAM,EAAE,SAAS,cAAc,CAAC;AAAA,UACvC,IAAI,iBAAiB;AAAA,YAAe,MAAM,MAAM;AAAA,UAChD,MAAM,kBAAkB,EAAE,MAAM,CAAC;AAAA;AAAA,MAErC;AAAA,MAIA,MAAM,cACJ,mBAAmB,YAAY,YAC3B,YACA,0BAA0B,EAAE,SAAS,mBAAmB,QAAQ,CAAC;AAAA,MACvE,MAAM,WAAW,MAAM,UAAU,MAAM,KAAK,QAAQ,CAAC;AAAA,MAGrD,MAAM,UAAS,uBAAuB,EAAE,SAAS,oBAAoB,UAAU,SAAS,CAAC;AAAA,MACzF,IAAI;AAAA,QACF,MAAM,UAAU,MACd,SAAS,OAAO,eAAe,EAAE,gBAAgB,mBAAmB,eAAe,CAAC,CAAC,CACvF;AAAA,QACA,IAAI,gBAAgB;AAAA,UAAW,MAAM,UAAU,MAAM,SAAS,OAAO,WAAW,CAAC;AAAA,QACjF,MAAM,UAAU,qBAAqB;AAAA,QACrC,MAAM,YAAY,cAAc;AAAA,UAC9B,QAAQ;AAAA,UACR,YAAY;AAAA,UACZ,OAAO;AAAA,UACP;AAAA,QACF,CAAC;AAAA,QACD,MAAM,SAAS,MAAM,aAAa,EAAE,OAAO,SAAS,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;AAAA,QAE/E,QAAO,aAAa,EAAE,OAAO,SAAS,CAAC;AAAA,QACvC,MAAM,UAAU,MAAM,SAAS,OAAO,QAAQ,CAAC;AAAA,QAC/C,QAAO,MAAM,EAAE,SAAS,YAAY,CAAC;AAAA,QACrC,OAAO;AAAA,QACP,OAAO,OAAO;AAAA,QACd,IAAI;AAAA,UACF,MAAM,SAAS,OAAO,UAAU;AAAA,UAChC,QAAO,MAAM,EAAE,SAAS,cAAc,CAAC;AAAA,UACvC,MAAM;AAAA,UAIN,QAAO,MAAM,EAAE,SAAS,UAAU,CAAC;AAAA,UACnC,IAAI,QAAO,YAAY,QAAQ,2BAA2B,KAAK,GAAG;AAAA,YAChE,MAAM,+BAA+B;AAAA,cACnC,UAAU;AAAA,cACV,SAAS,QAAO;AAAA,cAChB,OAAO;AAAA,YACT,CAAC;AAAA,UACH;AAAA;AAAA,QAEF,MAAM;AAAA,gBACN;AAAA,QACA,SAAS,QAAQ;AAAA;AAAA;AAAA,IAIrB,OAAO;AAAA,MACL,SAAS;AAAA,MACT,UAAU;AAAA,MACV,SAAS;AAAA,UACL,IAAI,GAAiB;AAAA,QACvB,OAAO;AAAA;AAAA,WAGH,QAAO,CAAC,YAAY;AAAA,QACxB,MAAM,OAAO,UAAU,EAAE,MAAM,CAAC;AAAA,QAChC,IAAI,SAAS;AAAA,UAAW,MAAM;AAAA,QAG9B,QAAQ,aAAa,EAAE,OAAO,YAAY,CAAC;AAAA,QAC3C,MAAM,kBAAkB;AAAA,QACxB,OAAO,WAAW,EAAE,WAAW,WAAW,CAAC;AAAA;AAAA,WAGvC,cAAa,CAAC,YAAY;AAAA,QAC9B,MAAM,OAAO,UAAU,EAAE,MAAM,CAAC;AAAA,QAChC,IAAI,SAAS;AAAA,UAAW,MAAM;AAAA,QAC9B,QAAQ,aAAa,EAAE,OAAO,YAAY,CAAC;AAAA,QAC3C,MAAM,kBAAkB;AAAA,QACxB,OAAO,iBAAiB,EAAE,WAAW,WAAW,CAAC;AAAA;AAAA,WAG7C,YAAc,CAClB,IACA,oBACY;AAAA,QACZ,OAAO,eAAe,SAClB,mBAAmB,IAAI,kBAAkB,IACzC,wBAAwB,IAAI,kBAAkB;AAAA;AAAA,WAG9C,QAAO,GAAkB;AAAA,QAC7B,IAAI,eAAe;AAAA,UAAQ;AAAA,QAC3B,MAAM,WAAW,MAAM,UAAU,MAAO,OAAuB,QAAQ,CAAC;AAAA,QACxE,SAAS,QAAQ;AAAA;AAAA,WAGb,WAAU,GAAkB;AAAA,QAChC,IAAI,eAAe;AAAA,UAAQ;AAAA,QAC3B,MAAM,UAAU,MAAO,OAAuB,MAAM,CAAC;AAAA,QACrD,WAAW;AAAA;AAAA,MAGb,gBAAgB,CAAC,QAA4B;AAAA,QAC3C,OAAO,iBAAiB,MAAM;AAAA;AAAA,IAElC;AAAA;AAAA,EAIF,SAAS,WAAW,GAAoB;AAAA,IACtC,OAAO,cAAc;AAAA,MACnB,QAAQ,OAAO;AAAA,MACf,YAAY;AAAA,MACZ,OAAO,qBAAqB;AAAA,IAC9B,CAAC;AAAA;AAAA,EAGH,OAAO;AAAA,IACL,SAAS;AAAA,IACT,UAAU;AAAA,IACV,SAAS;AAAA,QACL,IAAI,GAAiB;AAAA,MACvB,OAAO;AAAA;AAAA,SAGH,QAAO,CAAC,QAAQ;AAAA,MACpB,OAAO,YAAY,EAAE,QAAQ,MAAM;AAAA;AAAA,SAG/B,cAAa,CAAC,QAAQ;AAAA,MAC1B,MAAM,UAAU,8BAA8B,EAAE,MAAM,OAAO,KAAK,CAAC;AAAA,MACnE,IAAI,eAAe,MAAM;AAAA,QACvB,IAAI,YAAY,SAAS;AAAA,UACvB,MAAM,UAAU;AAAA,UAChB,aAAa;AAAA,UACb,IAAI;AAAA,YACF,OAAO,MAAM,iBAAiB,EAAE,QAAQ,YAAY,OAAO,CAAC;AAAA,oBAC5D;AAAA,YACA,QAAQ,QAAQ;AAAA;AAAA,QAEpB;AAAA,QAGA,OAAO,iBAAiB,EAAE,QAAQ,eAAe,OAAO,CAAC;AAAA,MAC3D;AAAA,MACA,IAAI,YAAY,QAAQ;AAAA,QACtB,MAAM,WAAW,MAAM,UAAU,MAAM,OAAO,EAAE,QAAQ,CAAC;AAAA,QACzD,IAAI;AAAA,UACF,MAAM,SAAS,MAAM,iBAAiB,EAAE,QAAQ,aAAa,OAAO,CAAC;AAAA,UACrE,aAAa;AAAA,UACb,OAAO;AAAA,UACP,OAAO,OAAO;AAAA,UACd,SAAS,QAAQ;AAAA,UACjB,MAAM;AAAA;AAAA,MAEV;AAAA,MACA,OAAO,YAAY,EAAE,cAAc,MAAM;AAAA;AAAA,SAGrC,YAAc,CAClB,IACA,oBACY;AAAA,MACZ,OAAO,YAAY,EAAE,YAAY,IAAI,kBAAkB;AAAA;AAAA,SAGnD,QAAO,GAAkB;AAAA,MAC7B,OAAO,YAAY,EAAE,QAAQ;AAAA;AAAA,SAGzB,WAAU,GAAkB;AAAA,MAChC,IAAI,eAAe,MAAM;AAAA,QAGvB,MAAM,UAAU;AAAA,QAChB,aAAa;AAAA,QACb,IAAI;AAAA,UACF,MAAM,QAAQ,OAAO,UAAU;AAAA,UAC/B,MAAM;AAAA,QAGR,QAAQ,QAAQ;AAAA,MAClB;AAAA,MACA,IAAI,aAAa;AAAA,QAAM;AAAA,MACvB,MAAM,UAAU;AAAA,MAChB,WAAW;AAAA,MACX,MAAM,UAAU,MAAM,QAAQ,MAAM,CAAC;AAAA;AAAA,IAGvC,gBAAgB,CAAC,QAA4B;AAAA,MAC3C,OAAO,iBAAiB,MAAM;AAAA;AAAA,EAElC;AAAA;AAQF,SAAS,gBAAgB,CAAC,QAAmC;AAAA,EAC3D,QAAQ,SAAS;AAAA,EACjB,IAAI,OAAO,KAAK,UAAU;AAAA,IAAU,OAAO,KAAK;AAAA,EAChD,IAAI,OAAO,KAAK,iBAAiB;AAAA,IAAU,OAAO,KAAK;AAAA,EACvD,OAAO,KAAK;AAAA;",
13
- "debugId": "18C3745F22387C6364756E2164756E21",
14
+ "mappings": "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",
15
+ "debugId": "F30E26CAE4DC1AC464756E2164756E21",
14
16
  "names": []
15
17
  }
@@ -5,7 +5,7 @@
5
5
  * isolation level and statement timeout can be applied — bun:sql's
6
6
  * `sql.begin(fn)` fast path takes no such options.
7
7
  */
8
- import type { IsolationLevel, TransactionOptions } from "@vibeorm/runtime";
8
+ import type { IsolationLevel } from "@vibeorm/runtime";
9
9
  /** VibeORM isolation level → PostgreSQL isolation level keyword. */
10
10
  export declare const ISOLATION_LEVEL_SQL: Readonly<Record<IsolationLevel, string>>;
11
11
  /** `BEGIN`, with an `ISOLATION LEVEL` clause when the caller asked for one. */
@@ -45,18 +45,5 @@ export type RawTransactionControl = "open" | "close" | null;
45
45
  export declare function classifyRawTransactionControl(params: {
46
46
  text: string;
47
47
  }): RawTransactionControl;
48
- /**
49
- * Refuse options on a NESTED `transaction()` call — the same contract on every
50
- * adapter (see the `DatabaseAdapter.transaction` JSDoc in @vibeorm/runtime):
51
- * a nested transaction is a SAVEPOINT, and a savepoint can neither change the
52
- * isolation level of the transaction it joins nor enforce its own timeout.
53
- * Silently dropping the option (the pre-#3 behaviour) hid exactly that.
54
- *
55
- * @throws VibeError `VIBE_VALIDATION` when `isolationLevel` or `timeout` is
56
- * present (an `undefined` or empty options object is accepted).
57
- */
58
- export declare function refuseNestedTransactionOptions(params: {
59
- options?: TransactionOptions;
60
- provider: string;
61
- }): void;
48
+ export { refuseNestedTransactionOptions } from "@vibeorm/runtime/adapter-kit";
62
49
  //# sourceMappingURL=transaction-sql.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"transaction-sql.d.ts","sourceRoot":"","sources":["../src/transaction-sql.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAG3E,oEAAoE;AACpE,eAAO,MAAM,mBAAmB,EAAE,QAAQ,CAAC,MAAM,CAAC,cAAc,EAAE,MAAM,CAAC,CAIvE,CAAC;AAEH,+EAA+E;AAC/E,wBAAgB,cAAc,CAAC,MAAM,EAAE;IAAE,cAAc,CAAC,EAAE,cAAc,CAAA;CAAE,GAAG,MAAM,CAKlF;AAED;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAU7E;AAID,+EAA+E;AAC/E,MAAM,MAAM,qBAAqB,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;AAK5D;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,6BAA6B,CAAC,MAAM,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,qBAAqB,CAI7F;AAID;;;;;;;;;GASG;AACH,wBAAgB,8BAA8B,CAAC,MAAM,EAAE;IACrD,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAC7B,QAAQ,EAAE,MAAM,CAAC;CAClB,GAAG,IAAI,CAoBP"}
1
+ {"version":3,"file":"transaction-sql.d.ts","sourceRoot":"","sources":["../src/transaction-sql.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAGvD,oEAAoE;AACpE,eAAO,MAAM,mBAAmB,EAAE,QAAQ,CAAC,MAAM,CAAC,cAAc,EAAE,MAAM,CAAC,CAIvE,CAAC;AAEH,+EAA+E;AAC/E,wBAAgB,cAAc,CAAC,MAAM,EAAE;IAAE,cAAc,CAAC,EAAE,cAAc,CAAA;CAAE,GAAG,MAAM,CAKlF;AAED;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAU7E;AAID,+EAA+E;AAC/E,MAAM,MAAM,qBAAqB,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;AAK5D;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,6BAA6B,CAAC,MAAM,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,qBAAqB,CAI7F;AAMD,OAAO,EAAE,8BAA8B,EAAE,MAAM,8BAA8B,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibeorm/adapter-bun",
3
- "version": "2.1.1",
3
+ "version": "2.2.0",
4
4
  "description": "bun:sql (Postgres) adapter for VibeORM v2",
5
5
  "keywords": [
6
6
  "orm",
@@ -41,9 +41,9 @@
41
41
  "bun": ">=1.2.0"
42
42
  },
43
43
  "dependencies": {
44
- "@vibeorm/runtime": "2.2.0",
45
- "@vibeorm/schema": "2.1.1",
46
- "@vibeorm/sql": "2.1.1"
44
+ "@vibeorm/runtime": "2.3.0",
45
+ "@vibeorm/schema": "2.2.0",
46
+ "@vibeorm/sql": "2.2.0"
47
47
  },
48
48
  "publishConfig": {
49
49
  "access": "public"