@vibeorm/runtime 2.6.0 → 3.0.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/LICENSE +21 -0
- package/README.md +3 -1
- package/dist/adapter-kit/adapter-lifecycle.d.ts +79 -0
- package/dist/adapter-kit/deferred-control.d.ts +58 -0
- package/dist/adapter-kit/index.d.ts +10 -3
- package/dist/adapter-kit/index.js +317 -24
- package/dist/adapter-kit/index.js.map +10 -7
- package/dist/adapter-kit/nested-options.d.ts +16 -2
- package/dist/adapter-kit/row-changes.d.ts +15 -1
- package/dist/adapter-kit/savepoint-gate.d.ts +17 -3
- package/dist/adapter-kit/transaction-budget.d.ts +23 -13
- package/dist/adapter-kit/transaction-outcome.d.ts +167 -0
- package/dist/adapter.d.ts +103 -11
- package/dist/client.d.ts +7 -0
- package/dist/codecs.d.ts +35 -0
- package/dist/config.d.ts +15 -0
- package/dist/extensions.d.ts +10 -0
- package/dist/find-page.d.ts +9 -2
- package/dist/index.d.ts +8 -4
- package/dist/index.js +4086 -1295
- package/dist/index.js.map +40 -28
- package/dist/keyset-iterator.d.ts +12 -2
- package/dist/keyset.d.ts +65 -10
- package/dist/lateral-projection.d.ts +31 -1
- package/dist/model-meta.d.ts +12 -0
- package/dist/nested-fold.d.ts +98 -0
- package/dist/nested-update-data.d.ts +11 -0
- package/dist/nested-writes.d.ts +38 -1
- package/dist/query-builder.d.ts +78 -19
- package/dist/read-only.d.ts +5 -0
- package/dist/relation-key.d.ts +50 -0
- package/dist/relation-loader.d.ts +13 -1
- package/dist/relation-plan.d.ts +16 -0
- package/dist/strict-args.d.ts +1 -0
- package/dist/upsert-fold.d.ts +77 -0
- package/dist/write-scope.d.ts +9 -0
- package/package.json +7 -5
- package/dist/adapter-kit/index.d.ts.map +0 -1
- package/dist/adapter-kit/nested-options.d.ts.map +0 -1
- package/dist/adapter-kit/row-changes.d.ts.map +0 -1
- package/dist/adapter-kit/savepoint-gate.d.ts.map +0 -1
- package/dist/adapter-kit/savepoints.d.ts.map +0 -1
- package/dist/adapter-kit/session.d.ts.map +0 -1
- package/dist/adapter-kit/sqlite-session.d.ts.map +0 -1
- package/dist/adapter-kit/transaction-budget.d.ts.map +0 -1
- package/dist/adapter.d.ts.map +0 -1
- package/dist/advisory-key.d.ts.map +0 -1
- package/dist/advisory-lock.d.ts.map +0 -1
- package/dist/bulk-upsert.d.ts.map +0 -1
- package/dist/client-types.d.ts.map +0 -1
- package/dist/client.d.ts.map +0 -1
- package/dist/codecs.d.ts.map +0 -1
- package/dist/computed.d.ts.map +0 -1
- package/dist/database-module.d.ts.map +0 -1
- package/dist/db-now.d.ts.map +0 -1
- package/dist/diagnostics/index.d.ts.map +0 -1
- package/dist/diagnostics/insight.d.ts.map +0 -1
- package/dist/diagnostics/plan.d.ts.map +0 -1
- package/dist/diagnostics/preview.d.ts.map +0 -1
- package/dist/diagnostics/statement-diagnostics.d.ts.map +0 -1
- package/dist/diagnostics/types.d.ts.map +0 -1
- package/dist/diagnostics/workload.d.ts.map +0 -1
- package/dist/extensions.d.ts.map +0 -1
- package/dist/find-page.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/keyset-iterator.d.ts.map +0 -1
- package/dist/keyset-projection.d.ts.map +0 -1
- package/dist/keyset.d.ts.map +0 -1
- package/dist/lateral-projection.d.ts.map +0 -1
- package/dist/model-meta.d.ts.map +0 -1
- package/dist/module-context.d.ts.map +0 -1
- package/dist/nested-writes.d.ts.map +0 -1
- package/dist/policy-operation.d.ts.map +0 -1
- package/dist/policy.d.ts.map +0 -1
- package/dist/query-builder.d.ts.map +0 -1
- package/dist/read-only.d.ts.map +0 -1
- package/dist/relation-key.d.ts.map +0 -1
- package/dist/relation-loader.d.ts.map +0 -1
- package/dist/relation-plan.d.ts.map +0 -1
- package/dist/render-cache.d.ts.map +0 -1
- package/dist/rls-context.d.ts.map +0 -1
- package/dist/rls-readiness.d.ts.map +0 -1
- package/dist/scoped.d.ts.map +0 -1
- package/dist/sql-access.d.ts.map +0 -1
- package/dist/sql.d.ts.map +0 -1
- package/dist/strict-args.d.ts.map +0 -1
- package/dist/telemetry/collector.d.ts.map +0 -1
- package/dist/telemetry/config.d.ts.map +0 -1
- package/dist/telemetry/fingerprint.d.ts.map +0 -1
- package/dist/telemetry/index.d.ts.map +0 -1
- package/dist/telemetry/recorder.d.ts.map +0 -1
- package/dist/telemetry/statement.d.ts.map +0 -1
- package/dist/telemetry/types.d.ts.map +0 -1
- package/dist/transaction-row-changes.d.ts.map +0 -1
- package/dist/validators.d.ts.map +0 -1
- package/dist/views.d.ts.map +0 -1
- package/dist/write-scope.d.ts.map +0 -1
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transaction outcome reports — what a FAILED top-level transaction did and
|
|
3
|
+
* did not do (EPIC T).
|
|
4
|
+
*
|
|
5
|
+
* ONE copy, shared by every adapter package through the
|
|
6
|
+
* `@vibeorm/runtime/adapter-kit` subpath (like `transaction-budget.ts`), so the
|
|
7
|
+
* rule cannot drift into a per-engine difference.
|
|
8
|
+
*
|
|
9
|
+
* THE RULE
|
|
10
|
+
*
|
|
11
|
+
* The commit outcome follows from how far the adapter's OWN `COMMIT` got —
|
|
12
|
+
* never from the type of the error that ended the transaction:
|
|
13
|
+
*
|
|
14
|
+
* - `"not-committed"`: `COMMIT` never left the client (the callback failed, a
|
|
15
|
+
* deadline or a closed handle refused it, or the driver had already seen the
|
|
16
|
+
* connection die and refused it locally), or the engine ANSWERED it with an
|
|
17
|
+
* error or a ROLLBACK tag. Only this session can send `COMMIT`, and a
|
|
18
|
+
* server ends an open transaction when its connection closes, so a failed
|
|
19
|
+
* cleanup `ROLLBACK` does not change this.
|
|
20
|
+
* - `"unknown"`: a `COMMIT` that left the client got no answer — the
|
|
21
|
+
* connection was lost while it was in flight, or a client-side deadline
|
|
22
|
+
* stopped waiting for it. Also when the savepoint stack was lost before
|
|
23
|
+
* `COMMIT` (`savepoint-rollback-failed`): an implicit commit (MySQL DDL) or a
|
|
24
|
+
* raw `COMMIT` may already have ended the transaction.
|
|
25
|
+
* - `"committed"`: the engine acknowledged `COMMIT`. A successful transaction
|
|
26
|
+
* throws nothing, so no report is recorded for it.
|
|
27
|
+
*
|
|
28
|
+
* The cleanup is reported APART from the commit outcome: whether the cleanup
|
|
29
|
+
* `ROLLBACK` was acknowledged, failed or not needed, and whether the
|
|
30
|
+
* connection went back to the pool or was discarded.
|
|
31
|
+
*
|
|
32
|
+
* WHERE THE FACTS LIVE
|
|
33
|
+
*
|
|
34
|
+
* The error a failed transaction throws stays the SAME value — callers match
|
|
35
|
+
* their own errors and stable codes. The facts ride beside it in a registry
|
|
36
|
+
* keyed by that value, read with {@link transactionOutcomeOf}. The registry is
|
|
37
|
+
* a `WeakMap` held on `globalThis` under a `Symbol.for` key: the runtime's
|
|
38
|
+
* main entry and this subpath are separate bundles, each with its own copy of
|
|
39
|
+
* this module, and both must read the same map. A `WeakMap` never keeps an
|
|
40
|
+
* error alive and never changes the error object. Under a frozen or sealed
|
|
41
|
+
* `globalThis` (SES, hardened JavaScript) the key cannot be added: each copy
|
|
42
|
+
* then keeps a module-local map, so a report recorded by one bundle is not
|
|
43
|
+
* visible from the other, and the accessor returns `undefined` — the runtime
|
|
44
|
+
* stays importable.
|
|
45
|
+
*
|
|
46
|
+
* A CROSS-VERSION CONTRACT
|
|
47
|
+
*
|
|
48
|
+
* Two installed copies of `@vibeorm/runtime` (an adapter built against one,
|
|
49
|
+
* a framework reading with another) share the one global map. Each stored
|
|
50
|
+
* record therefore carries a `version`. The report shape is append-only:
|
|
51
|
+
* fields are only ever added; a change of meaning bumps the version, and a
|
|
52
|
+
* reader that does not know a record's version returns `undefined` ("no
|
|
53
|
+
* facts") rather than misreading it.
|
|
54
|
+
*/
|
|
55
|
+
import { type SavepointScope } from "./savepoint-gate.ts";
|
|
56
|
+
import { type TransactionBudget, type TransactionOutcome } from "./transaction-budget.ts";
|
|
57
|
+
/**
|
|
58
|
+
* How far an adapter's own `COMMIT` got. The adapter moves it to `"sent"`
|
|
59
|
+
* IMMEDIATELY before `COMMIT` is handed to the driver, and on a failure
|
|
60
|
+
* classifies a sent `COMMIT` as `"answered"` (the engine replied with an error
|
|
61
|
+
* or a ROLLBACK tag) or `"unanswered"` (the reply was lost or abandoned). A
|
|
62
|
+
* `"sent"` that was never classified counts as unanswered: without an answer
|
|
63
|
+
* nothing proves that the write did not commit.
|
|
64
|
+
*/
|
|
65
|
+
export type CommitProgress = "not-sent" | "sent" | "answered" | "unanswered";
|
|
66
|
+
/** What the cleanup `ROLLBACK` of a failed top-level transaction did. */
|
|
67
|
+
export type RollbackOutcome = "acknowledged" | "failed" | "not-needed";
|
|
68
|
+
/** Where the transaction's connection went after the failure. */
|
|
69
|
+
export type ConnectionOutcome = "returned" | "discarded";
|
|
70
|
+
/**
|
|
71
|
+
* The facts of one failed top-level transaction, read with
|
|
72
|
+
* {@link transactionOutcomeOf}.
|
|
73
|
+
*
|
|
74
|
+
* - `commit`: the commit outcome (see the module rule). `"not-committed"` is
|
|
75
|
+
* safe to retry as far as the database is concerned; `"unknown"` is not.
|
|
76
|
+
* - `commitSent`: whether the adapter handed its `COMMIT` to the driver.
|
|
77
|
+
* - `rollback`: `"acknowledged"` (the engine confirmed the cleanup
|
|
78
|
+
* `ROLLBACK`), `"failed"` (it was sent and failed — the connection is lost,
|
|
79
|
+
* or the engine refused it), `"not-needed"` (no transaction was open on the
|
|
80
|
+
* connection: nothing was sent yet, or the engine had already ended it
|
|
81
|
+
* when it answered `COMMIT`).
|
|
82
|
+
* - `connection`: `"returned"` to the pool (or kept, on a single-connection
|
|
83
|
+
* engine) or `"discarded"` (destroyed, so the server ends whatever it still
|
|
84
|
+
* holds when it sees the close).
|
|
85
|
+
*/
|
|
86
|
+
export type TransactionOutcomeReport = {
|
|
87
|
+
readonly commit: FailedCommitOutcome;
|
|
88
|
+
readonly commitSent: boolean;
|
|
89
|
+
readonly rollback: RollbackOutcome;
|
|
90
|
+
readonly connection: ConnectionOutcome;
|
|
91
|
+
};
|
|
92
|
+
/**
|
|
93
|
+
* The commit outcome of a FAILED transaction. `"committed"` is never recorded:
|
|
94
|
+
* a transaction that committed throws nothing.
|
|
95
|
+
*/
|
|
96
|
+
export type FailedCommitOutcome = Exclude<TransactionOutcome, "committed">;
|
|
97
|
+
/**
|
|
98
|
+
* Attach `report` to the value a failed top-level transaction is about to
|
|
99
|
+
* throw. A later report for the same value replaces the earlier one, so a
|
|
100
|
+
* value rethrown through several top-level transactions carries the facts of
|
|
101
|
+
* the LAST one it left. A primitive thrown value (a string, a number,
|
|
102
|
+
* `undefined`) cannot key a `WeakMap`, so nothing is recorded for it.
|
|
103
|
+
*/
|
|
104
|
+
export declare function recordTransactionOutcome(params: {
|
|
105
|
+
error: unknown;
|
|
106
|
+
report: TransactionOutcomeReport;
|
|
107
|
+
}): void;
|
|
108
|
+
/**
|
|
109
|
+
* The facts of the failed top-level transaction that threw `error`, or
|
|
110
|
+
* `undefined` when there are none.
|
|
111
|
+
*
|
|
112
|
+
* `undefined` means one of: the adapter does not declare
|
|
113
|
+
* `transactionOutcome: "reported"`; `error` did not leave a top-level
|
|
114
|
+
* `transaction()` (a nested savepoint records nothing); the transaction was
|
|
115
|
+
* refused before it started (an invalid option, a connection that could not be
|
|
116
|
+
* acquired — nothing was sent); the thrown value is not an object (a
|
|
117
|
+
* primitive cannot key the registry — throw `Error` objects to keep the facts);
|
|
118
|
+
* the record was written by a runtime copy with a report version this copy
|
|
119
|
+
* does not know; or `globalThis` is frozen and the report was recorded by the
|
|
120
|
+
* other bundle (see the module doc).
|
|
121
|
+
*/
|
|
122
|
+
export declare function transactionOutcomeOf(params: {
|
|
123
|
+
error: unknown;
|
|
124
|
+
}): TransactionOutcomeReport | undefined;
|
|
125
|
+
/** The commit outcome of a failed transaction — the ONE rule (see the module doc). */
|
|
126
|
+
export declare function failedCommitOutcome(params: {
|
|
127
|
+
commit: CommitProgress;
|
|
128
|
+
stateLost: boolean;
|
|
129
|
+
}): FailedCommitOutcome;
|
|
130
|
+
/**
|
|
131
|
+
* Close a failed top-level transaction's budget with its commit outcome (the
|
|
132
|
+
* rule above) and return that outcome. The first close wins: an adapter that
|
|
133
|
+
* closed `unknown` the moment it lost a COMMIT reply keeps that.
|
|
134
|
+
*
|
|
135
|
+
* {@link settleFailedTransaction} calls it. An adapter whose connection must
|
|
136
|
+
* leave BEFORE it can settle (adapter-mysql resets the session and releases the
|
|
137
|
+
* connection to learn where it went) calls it first, so every handle of the
|
|
138
|
+
* failed transaction is refused before the connection is handed back.
|
|
139
|
+
*/
|
|
140
|
+
export declare function closeFailedTransactionBudget(params: {
|
|
141
|
+
error: unknown;
|
|
142
|
+
budget: TransactionBudget;
|
|
143
|
+
scope: SavepointScope;
|
|
144
|
+
commit: CommitProgress;
|
|
145
|
+
}): FailedCommitOutcome;
|
|
146
|
+
/**
|
|
147
|
+
* Settle a failed top-level transaction AFTER its cleanup ran: close the
|
|
148
|
+
* budget with the commit outcome, choose the value to throw, and record the
|
|
149
|
+
* facts on it. Returns that value; the adapter throws it.
|
|
150
|
+
*
|
|
151
|
+
* The value is `error` itself — the same object, the same code — except when
|
|
152
|
+
* a client-side deadline abandoned a COMMIT that had already left the client
|
|
153
|
+
* (`commit: "unanswered"` with the deadline refusal as `error`): only then is
|
|
154
|
+
* it {@link transactionOutcomeUnknownError}. A deadline that refused the
|
|
155
|
+
* COMMIT before it was sent is a known outcome (`"not-committed"`), and its own
|
|
156
|
+
* deadline error is rethrown even when the cleanup `ROLLBACK` failed.
|
|
157
|
+
*/
|
|
158
|
+
export declare function settleFailedTransaction(params: {
|
|
159
|
+
error: unknown;
|
|
160
|
+
provider: string;
|
|
161
|
+
budget: TransactionBudget;
|
|
162
|
+
scope: SavepointScope;
|
|
163
|
+
commit: CommitProgress;
|
|
164
|
+
rollback: RollbackOutcome;
|
|
165
|
+
connection: ConnectionOutcome;
|
|
166
|
+
}): unknown;
|
|
167
|
+
//# sourceMappingURL=transaction-outcome.d.ts.map
|
package/dist/adapter.d.ts
CHANGED
|
@@ -68,12 +68,26 @@ export type TransactionDeadline = {
|
|
|
68
68
|
* a nested timeout is not enforceable, and a nested deadline would need an
|
|
69
69
|
* independent session setting on a connection it does not own. A nested
|
|
70
70
|
* savepoint instead INHERITS the top-level deadline, by reference.
|
|
71
|
+
*
|
|
72
|
+
* `accessMode: "readOnly"` opens a READ ONLY transaction in the opening
|
|
73
|
+
* statement itself (`BEGIN … READ ONLY` on postgres servers, `START
|
|
74
|
+
* TRANSACTION READ ONLY` on mysql, `SET TRANSACTION READ ONLY` right after
|
|
75
|
+
* PGlite's own BEGIN) — no extra round trip. A write inside it is refused by
|
|
76
|
+
* the engine and raises `VIBE_TRANSACTION` with `meta.reason:
|
|
77
|
+
* "read-only-transaction"`. sqlite adapters refuse the option with
|
|
78
|
+
* `VIBE_UNSUPPORTED_CAPABILITY`; a nested call refuses it like the others.
|
|
71
79
|
*/
|
|
72
80
|
export type TransactionOptions = {
|
|
73
81
|
isolationLevel?: IsolationLevel;
|
|
74
82
|
timeout?: number;
|
|
75
83
|
deadline?: TransactionDeadline;
|
|
84
|
+
accessMode?: TransactionAccessMode;
|
|
76
85
|
};
|
|
86
|
+
/**
|
|
87
|
+
* Transaction access mode. Only `"readOnly"` exists: omitting the option keeps
|
|
88
|
+
* the engine's default (read/write), exactly as before the option existed.
|
|
89
|
+
*/
|
|
90
|
+
export type TransactionAccessMode = "readOnly";
|
|
77
91
|
/**
|
|
78
92
|
* How far an engine's per-statement timeout actually reaches.
|
|
79
93
|
*
|
|
@@ -83,6 +97,15 @@ export type TransactionOptions = {
|
|
|
83
97
|
* forbids.
|
|
84
98
|
*/
|
|
85
99
|
export type StatementTimeoutSupport = "all-statements" | "select-only" | "unsupported";
|
|
100
|
+
/**
|
|
101
|
+
* Whether a failed top-level `transaction()` reports its facts (EPIC T).
|
|
102
|
+
* `"reported"`: every object it throws once the transaction has started
|
|
103
|
+
* carries a `TransactionOutcomeReport`, read with `transactionOutcomeOf({ error })`
|
|
104
|
+
* from `@vibeorm/runtime` — the commit outcome (`not-committed` / `unknown`),
|
|
105
|
+
* whether COMMIT was sent, what the cleanup ROLLBACK did and whether the
|
|
106
|
+
* connection was returned or discarded.
|
|
107
|
+
*/
|
|
108
|
+
export type TransactionOutcomeSupport = "reported";
|
|
86
109
|
/** The strongest transaction-deadline guarantee an adapter can honestly deliver. */
|
|
87
110
|
export type TransactionDeadlineSupport = "cancel-running-statements" | "between-statements" | "unsupported";
|
|
88
111
|
/**
|
|
@@ -100,11 +123,35 @@ export type AdapterBudgetSupport = {
|
|
|
100
123
|
readonly statementTimeout: StatementTimeoutSupport;
|
|
101
124
|
/** What `TransactionOptions.deadline.enforcement` may ask for on this engine. */
|
|
102
125
|
readonly transactionDeadline: TransactionDeadlineSupport;
|
|
126
|
+
/**
|
|
127
|
+
* The `TransactionOptions.accessMode` values this adapter honours in its
|
|
128
|
+
* opening statement. Not a timing budget, but declared here for the same
|
|
129
|
+
* reason as `transactionDeadline`: the runtime refuses an access mode the
|
|
130
|
+
* adapter does not declare with `VIBE_UNSUPPORTED_CAPABILITY` before it calls
|
|
131
|
+
* `transaction()`, so an adapter that predates the option (or a third-party
|
|
132
|
+
* one) can never open a read/write transaction for a caller who asked for a
|
|
133
|
+
* read-only one. Optional (additive); undeclared = none.
|
|
134
|
+
*/
|
|
135
|
+
readonly accessModes?: readonly TransactionAccessMode[];
|
|
103
136
|
};
|
|
104
137
|
/** Surviving direct DML effects, or an honest unknown when observation is incomplete. */
|
|
105
138
|
export type RowChangeCount = number | "unknown";
|
|
106
|
-
/**
|
|
107
|
-
|
|
139
|
+
/**
|
|
140
|
+
* Internal structured execution intent. Never accepted as an ORM/raw query argument.
|
|
141
|
+
*
|
|
142
|
+
* `writeRows` (round-trip campaign EPIC 4): a data-modifying statement chain
|
|
143
|
+
* whose RESULT ROWS are its direct effects — one returned row per changed row.
|
|
144
|
+
* An adapter counts the rows it received, never the command tag: a chain's tag
|
|
145
|
+
* is `SELECT n`, and PGlite reports zero affected rows for any SELECT. An
|
|
146
|
+
* adapter that cannot count rows reports `unknown` for it.
|
|
147
|
+
*
|
|
148
|
+
* `writeTally` (round-trip campaign EPIC F): a statement chain that REPORTS its
|
|
149
|
+
* direct effects in the result column `ROW_CHANGES_COLUMN` (adapter-kit) — the
|
|
150
|
+
* rows its data-modifying steps changed, which its result rows do not show.
|
|
151
|
+
* An adapter sums that column over the rows it received (adapter-kit
|
|
152
|
+
* `statementRowChanges` with `resultRows`); one that cannot reports `unknown`.
|
|
153
|
+
*/
|
|
154
|
+
export type StatementEffect = "read" | "write" | "writeRows" | "writeTally" | "unknown";
|
|
108
155
|
/** Result of an unsafe/raw execution: rows plus affected-row count. */
|
|
109
156
|
export type QueryResult = {
|
|
110
157
|
rows: Record<string, unknown>[];
|
|
@@ -212,15 +259,45 @@ export type DatabaseAdapter = {
|
|
|
212
259
|
* provider name. Every adapter in this repository declares it.
|
|
213
260
|
*/
|
|
214
261
|
readonly budgets?: AdapterBudgetSupport;
|
|
262
|
+
/**
|
|
263
|
+
* Whether a round trip to this adapter's engine crosses a network
|
|
264
|
+
* (`"network"`: a database server, even on a local socket) or stays inside
|
|
265
|
+
* this process (`"in-process"`: an embedded engine such as PGlite or SQLite).
|
|
266
|
+
*
|
|
267
|
+
* The runtime folds some multi-statement calls into ONE larger statement to
|
|
268
|
+
* save round trips (the nested-write fold and the upsert-fallback fold). On an
|
|
269
|
+
* in-process engine a round trip costs nothing, so only the larger
|
|
270
|
+
* statement's cost would remain: there the runtime keeps the multi-statement
|
|
271
|
+
* path, with the same results, errors and counts.
|
|
272
|
+
*
|
|
273
|
+
* OPTIONAL, so the frozen contract stays additive — exactly like
|
|
274
|
+
* {@link DatabaseAdapter.budgets}. An adapter that declares nothing is treated
|
|
275
|
+
* as `"network"`. Callers branch on this declaration, never on a provider
|
|
276
|
+
* name. Transactional adapters must carry the same declaration.
|
|
277
|
+
*/
|
|
278
|
+
readonly roundTrips?: "network" | "in-process";
|
|
279
|
+
/**
|
|
280
|
+
* Whether a failed top-level {@link DatabaseAdapter.transaction} records a
|
|
281
|
+
* `TransactionOutcomeReport` on the value it throws (EPIC T) — read it with
|
|
282
|
+
* `transactionOutcomeOf({ error })`. The thrown value itself is unchanged.
|
|
283
|
+
*
|
|
284
|
+
* OPTIONAL, so the frozen contract stays additive — exactly like
|
|
285
|
+
* {@link DatabaseAdapter.roundTrips}. Undeclared = no reports. Callers branch
|
|
286
|
+
* on this declaration, never on a provider name. It describes the TOP-LEVEL
|
|
287
|
+
* call only: a transactional handle's nested `transaction()` (a savepoint)
|
|
288
|
+
* records nothing, so transactional handles do not declare it.
|
|
289
|
+
*/
|
|
290
|
+
readonly transactionOutcome?: TransactionOutcomeSupport;
|
|
215
291
|
/**
|
|
216
292
|
* Run `fn` inside a transaction; the callback receives a transactional
|
|
217
293
|
* adapter with this same interface. Nested calls create savepoints. Throwing
|
|
218
294
|
* rolls back (the savepoint or the whole transaction) and rethrows.
|
|
219
295
|
*
|
|
220
296
|
* `options` is honored on TOP-LEVEL calls only. A NESTED call refuses any
|
|
221
|
-
* `isolationLevel
|
|
222
|
-
* true`), identically on every adapter: a
|
|
223
|
-
* isolation level of the transaction it joins,
|
|
297
|
+
* `isolationLevel`, `timeout`, `deadline` or `accessMode` with
|
|
298
|
+
* `VIBE_VALIDATION` (`meta.nested: true`), identically on every adapter: a
|
|
299
|
+
* savepoint cannot change the isolation level of the transaction it joins,
|
|
300
|
+
* and a nested timeout is not
|
|
224
301
|
* enforceable. Silently dropping the option was the pre-#3 behaviour of the
|
|
225
302
|
* pg/pglite/mysql/bun adapters and is forbidden by constitution rule 4.
|
|
226
303
|
*/
|
|
@@ -232,14 +309,29 @@ export type DatabaseAdapter = {
|
|
|
232
309
|
* Optional for third-party adapters; migration use refuses when unavailable.
|
|
233
310
|
*/
|
|
234
311
|
readonly withSession?: SessionRunner;
|
|
235
|
-
/**
|
|
312
|
+
/**
|
|
313
|
+
* Eagerly open/verify connectivity (pool warm-up or first connection).
|
|
314
|
+
* Refuses with `VIBE_ADAPTER_CLOSED` once {@link DatabaseAdapter.disconnect}
|
|
315
|
+
* was called. On a transaction handle it refuses with `VIBE_VALIDATION`
|
|
316
|
+
* (`meta: { method, inTransaction: true }`): the transaction owns the connection.
|
|
317
|
+
*/
|
|
236
318
|
connect(): Promise<void>;
|
|
237
319
|
/**
|
|
238
|
-
*
|
|
239
|
-
* adapter
|
|
240
|
-
* `
|
|
241
|
-
*
|
|
242
|
-
*
|
|
320
|
+
* End this adapter for good (terminal since EPIC A2). The first call seals
|
|
321
|
+
* the adapter synchronously: every later root call (`execute`,
|
|
322
|
+
* `executeUnsafe`, `transaction`, `withSession`, `connect`, …) refuses with
|
|
323
|
+
* `VIBE_ADAPTER_CLOSED` (`meta: { driver, state: "closing" | "closed" }`)
|
|
324
|
+
* and opens no pool or connection. Work admitted before the call drains
|
|
325
|
+
* first — a whole transaction or session callback included, whose handle
|
|
326
|
+
* keeps working until it returns — then the adapter closes what it OWNS,
|
|
327
|
+
* once; an injected pool/instance/database is never ended. Every call
|
|
328
|
+
* returns the same completion (a cleanup failure included). Called from
|
|
329
|
+
* inside one of this adapter's own running transaction/session callbacks,
|
|
330
|
+
* it refuses with `VIBE_TRANSACTION` (`meta.reason:
|
|
331
|
+
* "disconnect-in-active-callback"`) instead of waiting for itself. There is
|
|
332
|
+
* no timeout: stop producers and await pending work before closing. To
|
|
333
|
+
* connect again, create a new adapter. On a transaction handle it refuses
|
|
334
|
+
* with `VIBE_VALIDATION`, like `connect()`.
|
|
243
335
|
*/
|
|
244
336
|
disconnect(): Promise<void>;
|
|
245
337
|
/**
|
package/dist/client.d.ts
CHANGED
|
@@ -254,6 +254,13 @@ export type DynamicClient = {
|
|
|
254
254
|
*/
|
|
255
255
|
readonly $tryAdvisoryLock: (options: AdvisoryLockOptions) => Promise<boolean>;
|
|
256
256
|
readonly $connect: () => Promise<void>;
|
|
257
|
+
/**
|
|
258
|
+
* Flush pending diagnostics, end the adapter for good, then flush telemetry.
|
|
259
|
+
* The adapter's `disconnect()` is terminal: work this client (or any client
|
|
260
|
+
* sharing the adapter) issues afterwards refuses with `VIBE_ADAPTER_CLOSED`,
|
|
261
|
+
* `$connect()` included. Stop producers and await pending ORM work first;
|
|
262
|
+
* to connect again, create a new adapter and client.
|
|
263
|
+
*/
|
|
257
264
|
readonly $disconnect: () => Promise<void>;
|
|
258
265
|
/**
|
|
259
266
|
* Field-masking views (v1 `defineView` parity, board #11) — a read-only
|
package/dist/codecs.d.ts
CHANGED
|
@@ -24,6 +24,35 @@ export declare function getCodec(params: {
|
|
|
24
24
|
dialect: Dialect;
|
|
25
25
|
type: FieldType;
|
|
26
26
|
}): ScalarCodec;
|
|
27
|
+
/**
|
|
28
|
+
* Field-aware routing: membership survives identity pruning despite String
|
|
29
|
+
* transport, and `Float @db.Real` takes the float32 codec (shortest decimal
|
|
30
|
+
* that round-trips through float32 — a binary-format driver widens `0.1` to
|
|
31
|
+
* `0.10000000149011612`), and `DateTime @db.Time`/`@db.Timetz` take the
|
|
32
|
+
* time-of-day codec (UTC time of day out, `1970-01-01` in).
|
|
33
|
+
*/
|
|
34
|
+
/**
|
|
35
|
+
* Does this field hold a time of day (`DateTime @db.Time(n)` / `@db.Timetz(n)`)?
|
|
36
|
+
* The same rule that routes it to the time-of-day codec; membership predicates
|
|
37
|
+
* carry it to the dialect (`inArray.timeOfDay`).
|
|
38
|
+
*/
|
|
39
|
+
export declare function isTimeOfDayField(params: {
|
|
40
|
+
field: FieldMeta;
|
|
41
|
+
}): boolean;
|
|
42
|
+
/**
|
|
43
|
+
* Is this column projected as `"col"::text AS "col"` (SELECT and RETURNING)?
|
|
44
|
+
* True for postgres `Float[]` and `Json[]` columns: bun:sql's text array parser
|
|
45
|
+
* refuses a float array holding a value postgres prints with an exponent
|
|
46
|
+
* (`1e-05`, `1e+15`) and a json/jsonb array holding an integer beyond int32 or
|
|
47
|
+
* a nested `[null]` — the whole statement fails, after a write has already
|
|
48
|
+
* happened on RETURNING. The array literal text is parsed by the list decoder
|
|
49
|
+
* below instead (`fieldDecoder`). Other list types parse fine on every driver
|
|
50
|
+
* and are left alone — the text path costs JS parsing.
|
|
51
|
+
*/
|
|
52
|
+
export declare function projectsListAsText(params: {
|
|
53
|
+
dialect: Dialect;
|
|
54
|
+
field: FieldMeta;
|
|
55
|
+
}): boolean;
|
|
27
56
|
/**
|
|
28
57
|
* Encode one value for parameter binding. `null`/`undefined` pass through
|
|
29
58
|
* untouched (SQL NULL). List fields encode element-wise; the adapter's
|
|
@@ -161,6 +190,12 @@ export type PositionalMaterializer = (row: unknown) => Record<string, unknown>;
|
|
|
161
190
|
export declare function positionalMaterializer(params: {
|
|
162
191
|
model: ModelMeta;
|
|
163
192
|
columns: readonly ColRef[];
|
|
193
|
+
/**
|
|
194
|
+
* R-02: trailing slots after `columns`, kept RAW under these names — a
|
|
195
|
+
* nested lateral's JSON, decoded by the next level with its own model's
|
|
196
|
+
* codecs. Never a schema field (`__rel_<name>` is a reserved prefix).
|
|
197
|
+
*/
|
|
198
|
+
passthrough?: readonly string[];
|
|
164
199
|
}): PositionalMaterializer;
|
|
165
200
|
/**
|
|
166
201
|
* Normalize one aggregate value — the contract, tested live on PGlite:
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime tunables. Internal: not exported from the package entry.
|
|
3
|
+
*/
|
|
4
|
+
/** Tunables of the client runtime, grouped in one frozen object. */
|
|
5
|
+
export declare const RUNTIME_CONFIG: {
|
|
6
|
+
/**
|
|
7
|
+
* The nested write as ONE statement (round-trip campaign EPIC F) covers at
|
|
8
|
+
* most this many children; a longer list keeps today's path (parent
|
|
9
|
+
* statement + child statement in a transaction). EPIC F decision 3: at 1000
|
|
10
|
+
* children the one statement measured ~1.5× slower than the plain child
|
|
11
|
+
* INSERT locally; at 100 or fewer it is within ~1 ms.
|
|
12
|
+
*/
|
|
13
|
+
readonly nestedFoldMaxChildren: number;
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=config.d.ts.map
|
package/dist/extensions.d.ts
CHANGED
|
@@ -32,6 +32,16 @@ export type ExtensionMountContext = {
|
|
|
32
32
|
values: readonly unknown[];
|
|
33
33
|
method?: string;
|
|
34
34
|
}) => Promise<Record<string, unknown>[]>;
|
|
35
|
+
/**
|
|
36
|
+
* The mount model's full row projection (`"t"."id", "t"."scores"::text AS
|
|
37
|
+
* "scores"`), every column qualified by `qualify`. Select this instead of
|
|
38
|
+
* `"t".*`: rows then hold exactly the model's columns, read the way
|
|
39
|
+
* `findMany` reads them — bun:sql refuses some `Float[]`/`Json[]` values
|
|
40
|
+
* when the driver parses the list itself.
|
|
41
|
+
*/
|
|
42
|
+
readonly projection: (params: {
|
|
43
|
+
qualify: string;
|
|
44
|
+
}) => string;
|
|
35
45
|
/** Compile a user `where` tree for AND-ing into extension SQL. */
|
|
36
46
|
readonly compileWhere: (params: {
|
|
37
47
|
where: Record<string, unknown>;
|
package/dist/find-page.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { SqlDialect } from "@vibeorm/sql";
|
|
2
|
-
import type { KeysetOrderPlan } from "./keyset.ts";
|
|
2
|
+
import type { KeysetOrderPlan, KeysetQueryBinding } from "./keyset.ts";
|
|
3
3
|
import type { ModelMeta, RuntimeMeta } from "./model-meta.ts";
|
|
4
4
|
/** One bounded keyset page. A null continuation means the lookahead found no further row. */
|
|
5
5
|
export type KeysetPage<T> = {
|
|
@@ -14,7 +14,12 @@ export declare function validatePageArgs(params: {
|
|
|
14
14
|
model: string;
|
|
15
15
|
args: unknown;
|
|
16
16
|
}): PageArgs;
|
|
17
|
-
/**
|
|
17
|
+
/**
|
|
18
|
+
* Compile the first page's order too; findMany alone only requires a total
|
|
19
|
+
* order with after. The binding is the query the page's tokens belong to: the
|
|
20
|
+
* `where` this engine compiles (any `$scoped` / `$withPolicy` predicate
|
|
21
|
+
* included) plus the caller's `keyset.scope`.
|
|
22
|
+
*/
|
|
18
23
|
export declare function preparePage(params: {
|
|
19
24
|
meta: RuntimeMeta;
|
|
20
25
|
model: ModelMeta;
|
|
@@ -22,11 +27,13 @@ export declare function preparePage(params: {
|
|
|
22
27
|
args: PageArgs;
|
|
23
28
|
}): {
|
|
24
29
|
readonly plan: KeysetOrderPlan;
|
|
30
|
+
readonly binding: KeysetQueryBinding;
|
|
25
31
|
readonly args: Record<string, unknown>;
|
|
26
32
|
};
|
|
27
33
|
/** Mint from the last delivered row before its hidden fields are projected away. */
|
|
28
34
|
export declare function pageContinuation(params: {
|
|
29
35
|
plan: KeysetOrderPlan;
|
|
36
|
+
binding: KeysetQueryBinding;
|
|
30
37
|
rows: readonly Record<string, unknown>[];
|
|
31
38
|
take: number;
|
|
32
39
|
after: unknown;
|
package/dist/index.d.ts
CHANGED
|
@@ -15,13 +15,17 @@ export { compileAdvisoryLock } from "./advisory-lock.ts";
|
|
|
15
15
|
export { advisoryKeyOf } from "./advisory-key.ts";
|
|
16
16
|
export { transactionRowChanges } from "./transaction-row-changes.ts";
|
|
17
17
|
export type { AdvisoryLockMethod, AdvisoryLockOptions } from "./advisory-lock.ts";
|
|
18
|
-
export type { DatabaseAdapter, IsolationLevel, QueryResult, RowChangeCount, StatementEffect, SessionRunner, SqlExecutor, TransactionOptions, } from "./adapter.ts";
|
|
18
|
+
export type { DatabaseAdapter, IsolationLevel, QueryResult, RowChangeCount, StatementEffect, SessionRunner, SqlExecutor, TransactionAccessMode, TransactionOptions, } from "./adapter.ts";
|
|
19
19
|
export type { AdapterBudgetSupport, StatementTimeoutSupport, TransactionDeadline, TransactionDeadlineEnforcement, TransactionDeadlineSupport, } from "./adapter.ts";
|
|
20
|
+
export { transactionOutcomeOf } from "./adapter-kit/transaction-outcome.ts";
|
|
21
|
+
export type { ConnectionOutcome, RollbackOutcome, FailedCommitOutcome, TransactionOutcomeReport, } from "./adapter-kit/transaction-outcome.ts";
|
|
22
|
+
export type { TransactionOutcome } from "./adapter-kit/transaction-budget.ts";
|
|
23
|
+
export type { TransactionOutcomeSupport } from "./adapter.ts";
|
|
20
24
|
export { buildRuntimeMeta, generateCuid, generateDefaultValue, generateNanoid, generateUlid, generateUuid, getFieldMeta, getModelMeta, toClientName, } from "./model-meta.ts";
|
|
21
25
|
export type { ComputedFieldMeta, DefaultOrigin, ExtensionOperatorFn, FieldMeta, ModelMeta, RuntimeMeta, } from "./model-meta.ts";
|
|
22
26
|
export { DIALECT_CODECS, MYSQL_CODECS, POSTGRES_CODECS, SQLITE_CODECS, decodeAggregateValue, decodeIsNoop, decodeRow, decodeRows, decodeValue, encodeValue, getCodec, } from "./codecs.ts";
|
|
23
27
|
export type { CodecTable, ScalarCodec, WireFidelity } from "./codecs.ts";
|
|
24
|
-
export { COUNT_ALIAS, buildQuery, compileOrderBy, compileSelect, compileWhere, lateralColumnAlias, resolveResultShape, } from "./query-builder.ts";
|
|
28
|
+
export { COUNT_ALIAS, buildQuery, compileOrderBy, compileProjection, compileSelect, compileWhere, lateralColumnAlias, resolveResultShape, } from "./query-builder.ts";
|
|
25
29
|
export type { AggregateKey, AggregateSelection, AggregateSpec, BuilderClientOptions, QueryMethod, QueryPlan, RelationStrategy, } from "./query-builder.ts";
|
|
26
30
|
export { DIAGNOSTIC_THRESHOLDS, PLAN_DEFAULTS, STATEMENT_DIAGNOSTICS_DEFAULTS, analyzeOperationTelemetry, createStatementDiagnostics, explainOnSession, explainOperation, explainSql, formatStatementDiagnostic, isExecutableRead, parameterTypeTag, parseDiagnosticsEnv, parsePostgresPlan, previewOperation, readWorkloadStatistics, recommendFromPlan, resolveStatementDiagnostics, summarizePlan, } from "./diagnostics/index.ts";
|
|
27
31
|
export type { DiagnosticFinding, DiagnosticFindingCode, ExplainMode, ExplainSkipReason, ObservedStatement, ResolvedStatementDiagnostics, StatementDiagnostic, StatementDiagnosticPlan, StatementDiagnosticsHook, StatementDiagnosticsOptions, StatementExplainMode, IndexCandidate, IndexFacts, OperationPreview, ParsedPlan, PlanContext, PlanNode, PreviewLimitation, PreviewLimitationCode, PreviewStatement, QueryPlanReport, SlowOperation, SuspectedPattern, TableFacts, TelemetryDiagnosticReport, WorkloadAvailability, WorkloadReport, WorkloadStatement, } from "./diagnostics/index.ts";
|
|
@@ -53,8 +57,8 @@ export type { BatchResult, ClientOptions, ClientRow, DynamicClient, ModelDelegat
|
|
|
53
57
|
export { CLIENT_MEMBER_ACCESS, DELEGATE_METHOD_ACCESS, READ_DELEGATE_METHODS, WRITE_DELEGATE_METHODS, attachReadOnly, clientMemberAccess, createDelegateMethodClassifier, delegateMethodAccess, inheritReadOnly, readOnlyRefusal, } from "./read-only.ts";
|
|
54
58
|
export type { ClientMemberAccess, DelegateMethodAccess, DelegateMethodClassifier, LazyOperationBridge, } from "./read-only.ts";
|
|
55
59
|
export type { KeysetPage } from "./find-page.ts";
|
|
56
|
-
export { KEYSET_MAX_PAGE_SIZE, KEYSET_TOKEN_PREFIX, KEYSET_TOKEN_VERSION, compileKeysetOrderPlan, decodeKeysetToken, encodeKeysetToken, keysetRowIsAfter, keysetRowValues, } from "./keyset.ts";
|
|
57
|
-
export type { KeysetDirection, KeysetNulls, KeysetOrderInput, KeysetOrderKey, KeysetOrderPlan, KeysetTimestampPrecision, KeysetValueTag, } from "./keyset.ts";
|
|
60
|
+
export { KEYSET_MAX_PAGE_SIZE, KEYSET_TOKEN_PREFIX, KEYSET_TOKEN_VERSION, compileKeysetOrderPlan, decodeKeysetToken, encodeKeysetToken, keysetQueryBinding, keysetRowIsAfter, keysetRowValues, } from "./keyset.ts";
|
|
61
|
+
export type { KeysetDirection, KeysetNulls, KeysetOrderInput, KeysetOrderKey, KeysetOrderPlan, KeysetQueryBinding, KeysetTimestampPrecision, KeysetValueTag, } from "./keyset.ts";
|
|
58
62
|
export { iterateKeyset } from "./keyset-iterator.ts";
|
|
59
63
|
export type { KeysetIterateOptions, KeysetIterator, KeysetPageSource } from "./keyset-iterator.ts";
|
|
60
64
|
export { compileKeysetOrderInputs } from "./query-builder.ts";
|