@vibeorm/adapter-bun 1.3.0 → 2.0.0-alpha.10

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.
@@ -0,0 +1,144 @@
1
+ /**
2
+ * Transaction budgets — the total-deadline clock and the handle-closure gate.
3
+ *
4
+ * BYTE-IDENTICAL in all six adapter packages, exactly like `savepoint-gate.ts`:
5
+ * adapters depend on `@vibeorm/runtime` for TYPES only, so a shared value
6
+ * module there would invert the dependency direction, and `@vibeorm/schema` is
7
+ * the IR package, not a home for a transaction clock. Keep the six copies in
8
+ * lockstep — a divergence here is a silent per-engine behaviour difference.
9
+ *
10
+ * WHAT A DEADLINE IS, AND IS NOT
11
+ *
12
+ * `TransactionOptions.timeout` is unchanged: a PER-STATEMENT engine-side bound.
13
+ * `TransactionOptions.deadline` is new and different — a TOTAL wall-clock bound
14
+ * on one top-level transaction. Its clock starts immediately before `BEGIN` is
15
+ * sent, so connection acquisition (which has its own budget on the pooled
16
+ * adapters) is deliberately NOT counted.
17
+ *
18
+ * Enforcement is never `Promise.race` over a statement that keeps running:
19
+ *
20
+ * - `"between-statements"` (the default, and all six adapters can deliver it):
21
+ * before every statement, every nested `transaction()` and the `COMMIT`, an
22
+ * expired budget refuses. The statement is never sent and the transaction is
23
+ * rolled back. A statement ALREADY IN FLIGHT is not interrupted.
24
+ * - `"cancel-running-statements"` (postgres servers only): additionally hands
25
+ * the engine the remaining budget as `statement_timeout`, so the SERVER
26
+ * cancels an over-long statement. An adapter that cannot do this refuses the
27
+ * request outright rather than quietly delivering the weaker level.
28
+ *
29
+ * JavaScript cannot forcibly stop a running callback. A callback that keeps
30
+ * going past the deadline finds its later database calls refused; work it does
31
+ * outside the database (an HTTP call, an SMS) is not stopped and cannot be.
32
+ * There is no automatic retry: a deadline failure is terminal for that
33
+ * transaction, because external side effects may already have happened.
34
+ */
35
+ import type { TransactionDeadlineEnforcement, TransactionDeadlineSupport, TransactionOptions } from "@vibeorm/runtime";
36
+ import { VibeError } from "@vibeorm/schema";
37
+ /** Where a budget check happened, reported as `meta.stage`. */
38
+ export type BudgetStage = "statement" | "nested" | "commit";
39
+ /**
40
+ * What is known about a finished transaction. `"unknown"` is a first-class
41
+ * outcome, not a failure to decide: when a rollback itself fails the commit
42
+ * state genuinely cannot be asserted, and claiming "rolled back" would be a lie.
43
+ */
44
+ export type TransactionOutcome = "committed" | "rolled-back" | "unknown";
45
+ /** Wall clock, injectable so tests are deterministic instead of sleep-timed. */
46
+ export type DeadlineClock = () => number;
47
+ /** The ambient clock, used whenever no seam is injected. */
48
+ export declare const DEFAULT_DEADLINE_CLOCK: DeadlineClock;
49
+ /**
50
+ * One top-level transaction's budget. Nested savepoint handles share this
51
+ * object BY REFERENCE — they never get an independent clock, connection or
52
+ * session setting.
53
+ */
54
+ export type TransactionBudget = {
55
+ /** The enforcement level in force, or `null` when no deadline was requested. */
56
+ readonly enforcement: TransactionDeadlineEnforcement | null;
57
+ /** The requested total budget in milliseconds, or `null` when none was. */
58
+ readonly totalMs: number | null;
59
+ /** Existing per-statement limit, independent of the total deadline. Zero disables it. */
60
+ readonly statementTimeoutMs: number | null;
61
+ /** Milliseconds left (never negative), or `null` when no deadline is set. */
62
+ remainingMs(): number | null;
63
+ /** True only when a deadline is set and has passed. */
64
+ expired(): boolean;
65
+ /** Refuse a closed handle or an expired budget. Called BEFORE anything is sent. */
66
+ assertUsable(params: {
67
+ stage: BudgetStage;
68
+ }): void;
69
+ /** Record the terminal outcome; the first call wins and later ones are ignored. */
70
+ close(params: {
71
+ outcome: TransactionOutcome;
72
+ }): void;
73
+ /** The recorded outcome, or `null` while the transaction is still open. */
74
+ readonly outcome: TransactionOutcome | null;
75
+ };
76
+ /**
77
+ * Check `options.deadline` against what this adapter can honestly deliver.
78
+ * Called BEFORE `BEGIN` — a budget this engine cannot honour must never leave
79
+ * a transaction open behind it.
80
+ *
81
+ * @throws VibeError `VIBE_VALIDATION` when `totalMs` is not a positive integer.
82
+ * @throws VibeError `VIBE_UNSUPPORTED_CAPABILITY` when the requested
83
+ * `enforcement` is stronger than `support` — refused, never silently degraded.
84
+ */
85
+ export declare function validateTransactionDeadline(params: {
86
+ options?: TransactionOptions;
87
+ support: TransactionDeadlineSupport;
88
+ provider: string;
89
+ }): void;
90
+ /**
91
+ * Start the clock for one top-level transaction. Call it immediately before
92
+ * `BEGIN`; {@link validateTransactionDeadline} must already have run.
93
+ */
94
+ export declare function startTransactionBudget(params: {
95
+ options?: TransactionOptions;
96
+ provider: string;
97
+ clock?: DeadlineClock;
98
+ }): TransactionBudget;
99
+ /**
100
+ * The engine-side bound for the NEXT statement, or `null` when the caller did
101
+ * not buy `"cancel-running-statements"`. Floored at 1 ms: on postgres `0` means
102
+ * "no limit", so a spent budget must never be handed over as a zero.
103
+ */
104
+ export declare function engineStatementBudgetMs(params: {
105
+ budget: TransactionBudget;
106
+ }): number | null;
107
+ /**
108
+ * The refusal an expired budget raises. `VIBE_TRANSACTION` with a stable
109
+ * `meta.reason` — no SQL text, no parameter values, no credentials.
110
+ */
111
+ export declare function transactionDeadlineError(params: {
112
+ provider: string;
113
+ stage: BudgetStage;
114
+ totalMs: number;
115
+ overdueMs: number;
116
+ }): VibeError;
117
+ /**
118
+ * The refusal an ESCAPED transaction handle raises — a transactional adapter
119
+ * kept past the end of its transaction. Without this it would run on a
120
+ * connection that is back in the pool, outside any transaction.
121
+ */
122
+ export declare function transactionClosedError(params: {
123
+ provider: string;
124
+ outcome: TransactionOutcome;
125
+ stage: BudgetStage;
126
+ }): VibeError;
127
+ /**
128
+ * The stable typed outcome for "the deadline expired and the rollback that was
129
+ * supposed to clean up failed too". Promising a rollback here would be false;
130
+ * promising a retry would be worse.
131
+ *
132
+ * `cause` is the CAUSAL error (the deadline refusal), so the reason the
133
+ * transaction was being abandoned survives. The rollback failure itself is
134
+ * reported only as `meta.rollbackFailed`: a raw driver failure can carry
135
+ * statement text, and this error is meant to be logged.
136
+ */
137
+ export declare function transactionOutcomeUnknownError(params: {
138
+ provider: string;
139
+ totalMs: number;
140
+ cause: unknown;
141
+ }): VibeError;
142
+ /** Whether `error` is this module's deadline refusal (used to pick the cleanup path). */
143
+ export declare function isTransactionDeadlineError(error: unknown): boolean;
144
+ //# sourceMappingURL=transaction-budget.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transaction-budget.d.ts","sourceRoot":"","sources":["../src/transaction-budget.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,OAAO,KAAK,EACV,8BAA8B,EAC9B,0BAA0B,EAC1B,kBAAkB,EACnB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAI5C,+DAA+D;AAC/D,MAAM,MAAM,WAAW,GAAG,WAAW,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAE5D;;;;GAIG;AACH,MAAM,MAAM,kBAAkB,GAAG,WAAW,GAAG,aAAa,GAAG,SAAS,CAAC;AAEzE,gFAAgF;AAChF,MAAM,MAAM,aAAa,GAAG,MAAM,MAAM,CAAC;AAEzC,4DAA4D;AAC5D,eAAO,MAAM,sBAAsB,EAAE,aAAwC,CAAC;AAE9E;;;;GAIG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,gFAAgF;IAChF,QAAQ,CAAC,WAAW,EAAE,8BAA8B,GAAG,IAAI,CAAC;IAC5D,2EAA2E;IAC3E,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,yFAAyF;IACzF,QAAQ,CAAC,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3C,6EAA6E;IAC7E,WAAW,IAAI,MAAM,GAAG,IAAI,CAAC;IAC7B,uDAAuD;IACvD,OAAO,IAAI,OAAO,CAAC;IACnB,mFAAmF;IACnF,YAAY,CAAC,MAAM,EAAE;QAAE,KAAK,EAAE,WAAW,CAAA;KAAE,GAAG,IAAI,CAAC;IACnD,mFAAmF;IACnF,KAAK,CAAC,MAAM,EAAE;QAAE,OAAO,EAAE,kBAAkB,CAAA;KAAE,GAAG,IAAI,CAAC;IACrD,2EAA2E;IAC3E,QAAQ,CAAC,OAAO,EAAE,kBAAkB,GAAG,IAAI,CAAC;CAC7C,CAAC;AAIF;;;;;;;;GAQG;AACH,wBAAgB,2BAA2B,CAAC,MAAM,EAAE;IAClD,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAC7B,OAAO,EAAE,0BAA0B,CAAC;IACpC,QAAQ,EAAE,MAAM,CAAC;CAClB,GAAG,IAAI,CAgCP;AAID;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE;IAC7C,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,aAAa,CAAC;CACvB,GAAG,iBAAiB,CAyCpB;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE;IAAE,MAAM,EAAE,iBAAiB,CAAA;CAAE,GAAG,MAAM,GAAG,IAAI,CAQ5F;AAID;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE;IAC/C,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,WAAW,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG,SAAS,CAaZ;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE;IAC7C,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,kBAAkB,CAAC;IAC5B,KAAK,EAAE,WAAW,CAAC;CACpB,GAAG,SAAS,CAUZ;AAED;;;;;;;;;GASG;AACH,wBAAgB,8BAA8B,CAAC,MAAM,EAAE;IACrD,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;CAChB,GAAG,SAAS,CAiBZ;AAED,yFAAyF;AACzF,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAGlE"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Transaction-control SQL text (postgres dialect, bun:sql flavour).
3
+ *
4
+ * Used by the reserved-connection path, which issues `BEGIN` itself so that
5
+ * isolation level and statement timeout can be applied — bun:sql's
6
+ * `sql.begin(fn)` fast path takes no such options.
7
+ */
8
+ import type { IsolationLevel, TransactionOptions } from "@vibeorm/runtime";
9
+ /** VibeORM isolation level → PostgreSQL isolation level keyword. */
10
+ export declare const ISOLATION_LEVEL_SQL: Readonly<Record<IsolationLevel, string>>;
11
+ /** `BEGIN`, with an `ISOLATION LEVEL` clause when the caller asked for one. */
12
+ export declare function beginStatement(params: {
13
+ isolationLevel?: IsolationLevel;
14
+ }): string;
15
+ /**
16
+ * `SET LOCAL statement_timeout = <ms>` — transaction-scoped, so PostgreSQL
17
+ * cancels an over-long statement with SQLSTATE 57014 (mapped to
18
+ * `VIBE_TRANSACTION` with `meta.reason = "timeout"`).
19
+ *
20
+ * @throws VibeError `VIBE_VALIDATION` when the timeout is not a non-negative
21
+ * integer — the value is interpolated into SQL, so it is never trusted blindly.
22
+ */
23
+ export declare function statementTimeoutStatement(params: {
24
+ timeout: number;
25
+ }): string;
26
+ /** How a raw statement steers the adapter's session-affine raw transaction. */
27
+ export type RawTransactionControl = "open" | "close" | null;
28
+ /**
29
+ * Classify a raw statement as transaction control.
30
+ *
31
+ * @vibeorm/migrate drives transactional DDL by sending literal `BEGIN` /
32
+ * `COMMIT` / `ROLLBACK` through its stateless `SqlExecutor` — sound only when
33
+ * every statement in between rides the SAME connection. The adapter uses this
34
+ * to pin one connection for the whole raw transaction ("open" reserves,
35
+ * "close" releases). On a pooled bun:sql instance an unpinned `BEGIN` is
36
+ * refused outright by the driver (`ERR_POSTGRES_UNSAFE_TRANSACTION`); other
37
+ * pool drivers would only work by checkout luck.
38
+ *
39
+ * Deliberately strict: only PURE single-statement control text matches
40
+ * (`BEGIN`, `BEGIN ISOLATION LEVEL …;`, `COMMIT`, `ROLLBACK WORK`, `END`,
41
+ * `ABORT`). Compound scripts, `ROLLBACK TO SAVEPOINT`, two-phase
42
+ * `COMMIT PREPARED` and `COMMIT AND CHAIN` (which keeps a transaction open)
43
+ * never engage the pinning.
44
+ */
45
+ export declare function classifyRawTransactionControl(params: {
46
+ text: string;
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;
62
+ //# sourceMappingURL=transaction-sql.d.ts.map
@@ -0,0 +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"}
package/package.json CHANGED
@@ -1,39 +1,49 @@
1
1
  {
2
2
  "name": "@vibeorm/adapter-bun",
3
- "version": "1.3.0",
4
- "description": "Bun-native database adapter for VibeORM using bun:sql",
5
- "license": "MIT",
3
+ "version": "2.0.0-alpha.10",
4
+ "description": "bun:sql (Postgres) adapter for VibeORM v2",
6
5
  "keywords": [
7
6
  "orm",
8
- "adapter",
7
+ "typescript",
8
+ "sql",
9
+ "database",
9
10
  "bun",
11
+ "type-safe",
12
+ "postgres",
10
13
  "postgresql",
11
- "typescript"
14
+ "bun-sql",
15
+ "adapter",
16
+ "driver"
12
17
  ],
13
- "type": "module",
14
- "exports": {
15
- ".": {
16
- "default": "./src/index.ts",
17
- "types": "./src/index.ts"
18
- }
18
+ "homepage": "https://github.com/vibeorm/vibeorm/tree/master/packages/adapter-bun#readme",
19
+ "bugs": {
20
+ "url": "https://github.com/vibeorm/vibeorm/issues"
19
21
  },
20
- "files": [
21
- "src"
22
- ],
23
22
  "repository": {
24
23
  "type": "git",
25
24
  "url": "https://github.com/vibeorm/vibeorm.git",
26
25
  "directory": "packages/adapter-bun"
27
26
  },
28
- "homepage": "https://github.com/vibeorm/vibeorm/tree/master/packages/adapter-bun",
29
- "bugs": {
30
- "url": "https://github.com/vibeorm/vibeorm/issues"
27
+ "license": "MIT",
28
+ "author": "VibeORM contributors",
29
+ "type": "module",
30
+ "exports": {
31
+ ".": {
32
+ "types": "./dist/index.d.ts",
33
+ "default": "./dist/index.js"
34
+ }
31
35
  },
36
+ "files": [
37
+ "dist",
38
+ "README.md"
39
+ ],
32
40
  "engines": {
33
- "bun": ">=1.1.0"
41
+ "bun": ">=1.2.0"
34
42
  },
35
43
  "dependencies": {
36
- "@vibeorm/runtime": "1.3.0"
44
+ "@vibeorm/runtime": "2.0.0-alpha.10",
45
+ "@vibeorm/schema": "2.0.0-alpha.8",
46
+ "@vibeorm/sql": "2.0.0-alpha.8"
37
47
  },
38
48
  "publishConfig": {
39
49
  "access": "public"