@vibeorm/adapter-pglite 2.4.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 +2 -2
- package/dist/index.d.ts +5 -4
- package/dist/index.js +119 -40
- package/dist/index.js.map +7 -7
- package/dist/params.d.ts +3 -2
- package/dist/queue.d.ts +4 -1
- package/dist/transaction-sql.d.ts +10 -0
- package/package.json +6 -4
- package/dist/errors.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/params.d.ts.map +0 -1
- package/dist/queue.d.ts.map +0 -1
- package/dist/transaction-sql.d.ts.map +0 -1
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 VibeORM contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -29,7 +29,7 @@ const persistent = pgliteAdapter({ dataDir: "./.pglite" }); // persisted on
|
|
|
29
29
|
const shared = pgliteAdapter({ pglite: existingInstance }); // reuse a warm instance
|
|
30
30
|
```
|
|
31
31
|
|
|
32
|
-
`disconnect()`
|
|
32
|
+
`disconnect()` ends the adapter for good: work that already started finishes, an instance the adapter created is closed, and every later call refuses with `VIBE_ADAPTER_CLOSED`. Create a new adapter to connect again; with no `dataDir` its instance is a new, empty database.
|
|
33
33
|
|
|
34
34
|
## Options
|
|
35
35
|
|
|
@@ -38,7 +38,7 @@ const shared = pgliteAdapter({ pglite: existingInstance }); // reuse a warm
|
|
|
38
38
|
| Option | Type | Default | Meaning |
|
|
39
39
|
|---|---|---|---|
|
|
40
40
|
| `dataDir` | `string` | — (in-memory) | Directory to persist the database in. PGlite's own prefixes (`idb://`, `memory://`) work here too |
|
|
41
|
-
| `pglite` | `PGliteInterface` | — | An already-created PGlite instance to run on. The adapter never closes an instance it did not create
|
|
41
|
+
| `pglite` | `PGliteInterface` | — | An already-created PGlite instance to run on. The adapter never closes an instance it did not create; `disconnect()` then only ends the adapter |
|
|
42
42
|
|
|
43
43
|
There is no pool size and no connection URL: PGlite is a single embedded connection.
|
|
44
44
|
|
package/dist/index.d.ts
CHANGED
|
@@ -21,7 +21,7 @@ export type PgliteAdapterOptions = {
|
|
|
21
21
|
/**
|
|
22
22
|
* An already-created PGlite instance to run on (sharing one database across
|
|
23
23
|
* adapters, or reusing a warm instance between test files). The adapter never
|
|
24
|
-
* closes an instance it did not create
|
|
24
|
+
* closes an instance it did not create: `disconnect()` only ends this adapter.
|
|
25
25
|
*/
|
|
26
26
|
readonly pglite?: PGliteInterface;
|
|
27
27
|
/**
|
|
@@ -50,9 +50,10 @@ export type PgliteAdapterOptions = {
|
|
|
50
50
|
* const shared = pgliteAdapter({ pglite: existingInstance });
|
|
51
51
|
* ```
|
|
52
52
|
*
|
|
53
|
-
* `disconnect()`
|
|
54
|
-
*
|
|
55
|
-
*
|
|
53
|
+
* `disconnect()` ends the adapter for good: it waits for admitted work, closes
|
|
54
|
+
* an instance the adapter created (never a provided `pglite`), and every later
|
|
55
|
+
* call refuses with `VIBE_ADAPTER_CLOSED`. Create a new adapter to connect
|
|
56
|
+
* again; with no `dataDir` that is a new, empty in-memory database.
|
|
56
57
|
*
|
|
57
58
|
* @example Bundled extensions (pgvector) without hand-constructing PGlite
|
|
58
59
|
* ```ts
|
package/dist/index.js
CHANGED
|
@@ -6,13 +6,17 @@ import {
|
|
|
6
6
|
observeRowChanges,
|
|
7
7
|
readRowChanges,
|
|
8
8
|
statementRowChanges,
|
|
9
|
+
createAdapterLifecycleGate,
|
|
9
10
|
runPinnedSession,
|
|
11
|
+
transactionLifecycleRefusal,
|
|
10
12
|
createSavepointScope,
|
|
11
13
|
runNestedSavepoint,
|
|
12
14
|
runRootScope,
|
|
13
15
|
scopeTurn,
|
|
16
|
+
settleFailedTransaction,
|
|
14
17
|
startTransactionBudget,
|
|
15
|
-
validateTransactionDeadline
|
|
18
|
+
validateTransactionDeadline,
|
|
19
|
+
readOnlyRequested
|
|
16
20
|
} from "@vibeorm/runtime/adapter-kit";
|
|
17
21
|
|
|
18
22
|
// packages/adapter-pglite/src/errors.ts
|
|
@@ -33,14 +37,16 @@ var PGLITE_SQLSTATE_ERROR_CODES = Object.freeze({
|
|
|
33
37
|
"40001": "VIBE_TRANSACTION",
|
|
34
38
|
"55P03": "VIBE_LOCK_NOT_AVAILABLE",
|
|
35
39
|
"40P01": "VIBE_TRANSACTION",
|
|
36
|
-
"57014": "VIBE_TRANSACTION"
|
|
40
|
+
"57014": "VIBE_TRANSACTION",
|
|
41
|
+
"25006": "VIBE_TRANSACTION"
|
|
37
42
|
});
|
|
38
43
|
var PGLITE_SQLSTATE_REASONS = Object.freeze({
|
|
39
44
|
"23P01": "exclusion-violation",
|
|
40
45
|
"57014": "timeout",
|
|
41
46
|
"55P03": "lock-not-available",
|
|
42
47
|
"40P01": "deadlock",
|
|
43
|
-
"40001": "serialization-failure"
|
|
48
|
+
"40001": "serialization-failure",
|
|
49
|
+
"25006": "read-only-transaction"
|
|
44
50
|
});
|
|
45
51
|
var SQLSTATE_PATTERN = /^[0-9A-Z]{5}$/;
|
|
46
52
|
function readStringField(params) {
|
|
@@ -88,6 +94,7 @@ async function runMapped(fn) {
|
|
|
88
94
|
}
|
|
89
95
|
|
|
90
96
|
// packages/adapter-pglite/src/params.ts
|
|
97
|
+
import { Buffer } from "buffer";
|
|
91
98
|
import { VibeError as VibeError2 } from "@vibeorm/schema";
|
|
92
99
|
|
|
93
100
|
class PgliteArrayParam {
|
|
@@ -108,6 +115,9 @@ function toPgArrayLiteral(values) {
|
|
|
108
115
|
}
|
|
109
116
|
if (value instanceof Date)
|
|
110
117
|
return quoteElement(value.toISOString());
|
|
118
|
+
if (value instanceof Uint8Array) {
|
|
119
|
+
return quoteElement(`\\x${Buffer.from(value.buffer, value.byteOffset, value.byteLength).toString("hex")}`);
|
|
120
|
+
}
|
|
111
121
|
if (ArrayBuffer.isView(value) || value instanceof ArrayBuffer) {
|
|
112
122
|
throw new VibeError2({
|
|
113
123
|
code: "VIBE_VALIDATION",
|
|
@@ -154,7 +164,17 @@ function connectionOwnership(params) {
|
|
|
154
164
|
const existing = params.database === undefined ? undefined : INJECTED_OWNERSHIP.get(params.database);
|
|
155
165
|
if (existing !== undefined)
|
|
156
166
|
return existing;
|
|
157
|
-
const
|
|
167
|
+
const txContext = new AsyncLocalStorage;
|
|
168
|
+
const ownership = {
|
|
169
|
+
queue: createOperationQueue(),
|
|
170
|
+
txContext,
|
|
171
|
+
runInCallback(run) {
|
|
172
|
+
const token = { active: true };
|
|
173
|
+
return txContext.run(token, run).finally(() => {
|
|
174
|
+
token.active = false;
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
};
|
|
158
178
|
if (params.database !== undefined)
|
|
159
179
|
INJECTED_OWNERSHIP.set(params.database, ownership);
|
|
160
180
|
return ownership;
|
|
@@ -184,6 +204,12 @@ var ISOLATION_LEVEL_SQL = Object.freeze({
|
|
|
184
204
|
function setIsolationLevelStatement(params) {
|
|
185
205
|
return `SET TRANSACTION ISOLATION LEVEL ${ISOLATION_LEVEL_SQL[params.isolationLevel]}`;
|
|
186
206
|
}
|
|
207
|
+
function setTransactionModesStatement(params) {
|
|
208
|
+
const { isolationLevel, readOnly } = params;
|
|
209
|
+
if (readOnly !== true)
|
|
210
|
+
return isolationLevel === undefined ? undefined : setIsolationLevelStatement({ isolationLevel });
|
|
211
|
+
return isolationLevel === undefined ? "SET TRANSACTION READ ONLY" : `SET TRANSACTION ISOLATION LEVEL ${ISOLATION_LEVEL_SQL[isolationLevel]}, READ ONLY`;
|
|
212
|
+
}
|
|
187
213
|
|
|
188
214
|
// packages/adapter-pglite/src/index.ts
|
|
189
215
|
import { createSavepointCounter, nextSavepointName } from "@vibeorm/runtime/adapter-kit";
|
|
@@ -231,10 +257,12 @@ class CallbackError extends Error {
|
|
|
231
257
|
var DIALECT = "postgres";
|
|
232
258
|
var PROVIDER = "pglite";
|
|
233
259
|
var WIRE = Object.freeze({ dateTime: "native", json: "parsed", numbers: "native" });
|
|
260
|
+
var ROUND_TRIPS = "in-process";
|
|
234
261
|
var BUDGETS = Object.freeze({
|
|
235
262
|
acquireTimeout: false,
|
|
236
263
|
statementTimeout: "unsupported",
|
|
237
|
-
transactionDeadline: "between-statements"
|
|
264
|
+
transactionDeadline: "between-statements",
|
|
265
|
+
accessModes: Object.freeze(["readOnly"])
|
|
238
266
|
});
|
|
239
267
|
function pgliteAdapter(options) {
|
|
240
268
|
if (options?.pglite !== undefined && options.extensions !== undefined) {
|
|
@@ -244,10 +272,10 @@ function pgliteAdapter(options) {
|
|
|
244
272
|
meta: { provider: PROVIDER }
|
|
245
273
|
});
|
|
246
274
|
}
|
|
247
|
-
const { queue, txContext } = connectionOwnership({ database: options?.pglite });
|
|
275
|
+
const { queue, txContext, runInCallback } = connectionOwnership({ database: options?.pglite });
|
|
248
276
|
const ownsInstance = options?.pglite === undefined;
|
|
249
277
|
function assertNotInsideTransaction() {
|
|
250
|
-
if (txContext.getStore() === true) {
|
|
278
|
+
if (txContext.getStore()?.active === true) {
|
|
251
279
|
throw new VibeError3({
|
|
252
280
|
code: "VIBE_TRANSACTION",
|
|
253
281
|
message: "root client used inside a transaction callback \u2014 use the tx client the callback receives; the root connection would deadlock behind the open transaction",
|
|
@@ -284,7 +312,7 @@ function pgliteAdapter(options) {
|
|
|
284
312
|
const parsers = utcParsers ?? await getUtcParsers();
|
|
285
313
|
const result = await runMapped(() => params.queryable.query(params.text, values, { parsers }));
|
|
286
314
|
if (params.scope !== undefined)
|
|
287
|
-
observeRowChanges({ scope: params.scope, count: statementRowChanges({ effect: params.effect, count: result.affectedRows }) });
|
|
315
|
+
observeRowChanges({ scope: params.scope, count: statementRowChanges({ effect: params.effect, count: result.affectedRows, rows: result.rows.length, resultRows: result.rows }) });
|
|
288
316
|
return result.rows;
|
|
289
317
|
}
|
|
290
318
|
async function runExecuteUnsafe(params) {
|
|
@@ -313,6 +341,7 @@ function pgliteAdapter(options) {
|
|
|
313
341
|
provider: PROVIDER,
|
|
314
342
|
wire: WIRE,
|
|
315
343
|
budgets: BUDGETS,
|
|
344
|
+
roundTrips: ROUND_TRIPS,
|
|
316
345
|
rowChanges: () => {
|
|
317
346
|
budget.assertUsable({ stage: "statement" });
|
|
318
347
|
return readRowChanges({ scope });
|
|
@@ -336,27 +365,47 @@ function pgliteAdapter(options) {
|
|
|
336
365
|
budget.assertUsable({ stage: "nested" });
|
|
337
366
|
return runNestedSavepoint({
|
|
338
367
|
scope,
|
|
339
|
-
execute: (statement) => runMapped(() => tx.
|
|
368
|
+
execute: (statement) => runMapped(() => tx.exec(statement)),
|
|
340
369
|
body: (child) => fn(createTransactionAdapter({ tx, scope: child, budget }))
|
|
341
370
|
});
|
|
342
371
|
},
|
|
343
|
-
async connect() {
|
|
344
|
-
|
|
372
|
+
async connect() {
|
|
373
|
+
budget.assertUsable({ stage: "statement" });
|
|
374
|
+
throw transactionLifecycleRefusal({ method: "connect" });
|
|
375
|
+
},
|
|
376
|
+
async disconnect() {
|
|
377
|
+
budget.assertUsable({ stage: "statement" });
|
|
378
|
+
throw transactionLifecycleRefusal({ method: "disconnect" });
|
|
379
|
+
},
|
|
345
380
|
formatArrayParam(values) {
|
|
346
381
|
return new PgliteArrayParam(values);
|
|
347
382
|
}
|
|
348
383
|
};
|
|
349
384
|
}
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
385
|
+
const lifecycle = createAdapterLifecycleGate({
|
|
386
|
+
driver: "pglite",
|
|
387
|
+
isConnectionReentrant: () => txContext.getStore()?.active === true,
|
|
388
|
+
cleanup: async () => {
|
|
389
|
+
if (!ownsInstance)
|
|
390
|
+
return;
|
|
391
|
+
await queue.run(async () => {
|
|
392
|
+
if (instance === null) {
|
|
393
|
+
pending = null;
|
|
394
|
+
return;
|
|
395
|
+
}
|
|
396
|
+
const closing = instance;
|
|
397
|
+
instance = null;
|
|
398
|
+
pending = null;
|
|
399
|
+
await runMapped(() => closing.close());
|
|
400
|
+
});
|
|
401
|
+
}
|
|
402
|
+
});
|
|
403
|
+
const root = {
|
|
355
404
|
async withSession({ run }) {
|
|
356
405
|
assertNotInsideTransaction();
|
|
357
406
|
return queue.run(async () => {
|
|
358
407
|
const db = await getInstance();
|
|
359
|
-
return
|
|
408
|
+
return runInCallback(() => runPinnedSession({
|
|
360
409
|
run,
|
|
361
410
|
execute: async (query) => (await runExecuteUnsafe({ queryable: db, ...query })).rows,
|
|
362
411
|
isLost: () => db.closed,
|
|
@@ -389,50 +438,80 @@ function pgliteAdapter(options) {
|
|
|
389
438
|
support: BUDGETS.transactionDeadline,
|
|
390
439
|
provider: PROVIDER
|
|
391
440
|
});
|
|
441
|
+
const modesText = setTransactionModesStatement({
|
|
442
|
+
isolationLevel: transactionOptions?.isolationLevel,
|
|
443
|
+
readOnly: readOnlyRequested({ options: transactionOptions, provider: PROVIDER })
|
|
444
|
+
});
|
|
392
445
|
const scope = createSavepointScope();
|
|
393
446
|
return queue.run(async () => {
|
|
394
447
|
const db = await getInstance();
|
|
395
448
|
const budget = startTransactionBudget({ options: transactionOptions, provider: PROVIDER });
|
|
449
|
+
const commit = { progress: "not-sent" };
|
|
450
|
+
const handed = {};
|
|
396
451
|
try {
|
|
397
452
|
const result = await db.transaction(async (tx) => {
|
|
398
|
-
if (transactionOptions?.isolationLevel !== undefined) {
|
|
399
|
-
await tx.query(setIsolationLevelStatement({ isolationLevel: transactionOptions.isolationLevel }));
|
|
400
|
-
}
|
|
401
453
|
try {
|
|
402
|
-
|
|
454
|
+
if (modesText !== undefined)
|
|
455
|
+
await runMapped(() => tx.exec(modesText));
|
|
456
|
+
const value = await runInCallback(() => runRootScope({ scope, body: () => fn(createTransactionAdapter({ tx, scope, budget })) }));
|
|
403
457
|
budget.assertUsable({ stage: "commit" });
|
|
458
|
+
commit.progress = "sent";
|
|
404
459
|
return value;
|
|
405
460
|
} catch (error) {
|
|
406
|
-
|
|
461
|
+
handed.failure = new CallbackError(error);
|
|
462
|
+
throw handed.failure;
|
|
407
463
|
}
|
|
408
464
|
});
|
|
409
465
|
budget.close({ outcome: "committed" });
|
|
410
466
|
return result;
|
|
411
467
|
} catch (error) {
|
|
412
|
-
|
|
413
|
-
if (
|
|
414
|
-
|
|
415
|
-
|
|
468
|
+
const failure = handed.failure;
|
|
469
|
+
if (commit.progress === "sent" && failure === undefined)
|
|
470
|
+
commit.progress = "answered";
|
|
471
|
+
const rollback = failure === undefined ? "not-needed" : error === failure ? "acknowledged" : "failed";
|
|
472
|
+
throw settleFailedTransaction({
|
|
473
|
+
error: failure === undefined ? mapPgliteDriverError({ error }) : failure.inner,
|
|
474
|
+
provider: PROVIDER,
|
|
475
|
+
budget,
|
|
476
|
+
scope,
|
|
477
|
+
commit: commit.progress,
|
|
478
|
+
rollback,
|
|
479
|
+
connection: "returned"
|
|
480
|
+
});
|
|
416
481
|
}
|
|
417
482
|
});
|
|
418
483
|
},
|
|
419
484
|
async connect() {
|
|
420
|
-
await getInstance();
|
|
421
|
-
},
|
|
422
|
-
async disconnect() {
|
|
423
485
|
assertNotInsideTransaction();
|
|
424
|
-
if (!ownsInstance)
|
|
425
|
-
return;
|
|
426
486
|
await queue.run(async () => {
|
|
427
|
-
|
|
428
|
-
pending = null;
|
|
429
|
-
return;
|
|
430
|
-
}
|
|
431
|
-
const closing = instance;
|
|
432
|
-
instance = null;
|
|
433
|
-
pending = null;
|
|
434
|
-
await runMapped(() => closing.close());
|
|
487
|
+
await getInstance();
|
|
435
488
|
});
|
|
489
|
+
}
|
|
490
|
+
};
|
|
491
|
+
return {
|
|
492
|
+
dialect: DIALECT,
|
|
493
|
+
provider: PROVIDER,
|
|
494
|
+
wire: WIRE,
|
|
495
|
+
budgets: BUDGETS,
|
|
496
|
+
roundTrips: ROUND_TRIPS,
|
|
497
|
+
transactionOutcome: "reported",
|
|
498
|
+
withSession({ run }) {
|
|
499
|
+
return lifecycle.admit({ run: () => root.withSession({ run }) });
|
|
500
|
+
},
|
|
501
|
+
execute(params) {
|
|
502
|
+
return lifecycle.admit({ run: () => root.execute(params) });
|
|
503
|
+
},
|
|
504
|
+
executeUnsafe(params) {
|
|
505
|
+
return lifecycle.admit({ run: () => root.executeUnsafe(params) });
|
|
506
|
+
},
|
|
507
|
+
transaction(fn, transactionOptions) {
|
|
508
|
+
return lifecycle.admit({ run: () => root.transaction(fn, transactionOptions) });
|
|
509
|
+
},
|
|
510
|
+
connect() {
|
|
511
|
+
return lifecycle.admit({ run: () => root.connect() });
|
|
512
|
+
},
|
|
513
|
+
disconnect() {
|
|
514
|
+
return lifecycle.disconnect();
|
|
436
515
|
},
|
|
437
516
|
formatArrayParam(values) {
|
|
438
517
|
return new PgliteArrayParam(values);
|
|
@@ -465,4 +544,4 @@ export {
|
|
|
465
544
|
validateTransactionDeadline2 as validateTransactionDeadline
|
|
466
545
|
};
|
|
467
546
|
|
|
468
|
-
//# debugId=
|
|
547
|
+
//# debugId=F326F27D7631562D64756E2164756E21
|
package/dist/index.js.map
CHANGED
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/index.ts", "../src/errors.ts", "../src/params.ts", "../src/queue.ts", "../src/transaction-sql.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"/**\n * @vibeorm/adapter-pglite — PGlite (in-process PostgreSQL, WASM) adapter for\n * VibeORM v2.\n *\n * PGlite is a *single* embedded connection, so this adapter serializes every\n * operation through one queue — including whole transactions, which hold the\n * queue until they commit or roll back. That makes concurrent client calls safe\n * without a pool, and makes an in-memory instance an honest postgres target for\n * tests (no Docker).\n */\n\nimport { VibeError } from \"@vibeorm/schema\";\nimport type {\n AdapterBudgetSupport,\n DatabaseAdapter,\n QueryResult,\n RowChangeCount,\n StatementEffect,\n TransactionOptions,\n WireFidelity,\n} from \"@vibeorm/runtime\";\nimport {\n abortTransactionOnServerFailure,\n observeRowChanges,\n readRowChanges,\n statementRowChanges,\n runPinnedSession,\n createSavepointScope,\n runNestedSavepoint,\n runRootScope,\n type SavepointScope,\n scopeTurn,\n startTransactionBudget,\n type TransactionBudget,\n validateTransactionDeadline,\n} from \"@vibeorm/runtime/adapter-kit\";\nimport type { Dialect, Provider } from \"@vibeorm/schema\";\nimport type { Extensions, PGliteInterface, ParserOptions, Transaction } from \"@electric-sql/pglite\";\nimport { mapPgliteDriverError, runMapped } from \"./errors.ts\";\nimport { PgliteArrayParam, serializeParams, serializeParamsRaw } from \"./params.ts\";\nimport { connectionOwnership } from \"./queue.ts\";\nimport { refuseNestedTransactionOptions, setIsolationLevelStatement } from \"./transaction-sql.ts\";\n\n// ─── Options ──────────────────────────────────────────────────────\n\n/** Options for {@link pgliteAdapter}. */\nexport type PgliteAdapterOptions = {\n /**\n * Directory to persist the database in. Omit for a fresh in-memory database —\n * the usual choice for tests. Prefixes PGlite understands (`idb://`,\n * `memory://`) work here too.\n */\n readonly dataDir?: string;\n /**\n * An already-created PGlite instance to run on (sharing one database across\n * adapters, or reusing a warm instance between test files). The adapter never\n * closes an instance it did not create, so `disconnect()` is a no-op then.\n */\n readonly pglite?: PGliteInterface;\n /**\n * PGlite extension bundles to load into the instance the ADAPTER creates —\n * `{ vector }` from `@electric-sql/pglite-pgvector`, `pg_trgm` from\n * `@electric-sql/pglite/contrib/pg_trgm`, … The bundles still come from\n * their own packages; this option removes the need to construct PGlite\n * yourself just to attach them. Mutually exclusive with `pglite` (that\n * instance was already constructed with its extensions) — passing both\n * throws `VIBE_CONFIG`.\n */\n readonly extensions?: Extensions;\n};\n\n// ─── Internals ────────────────────────────────────────────────────\n\n/** Anything that runs SQL: the PGlite instance itself or an open transaction. */\ntype Queryable = Pick<Transaction, \"query\" | \"exec\">;\n\n// ─── UTC zone-less timestamps ─────────────────────────────────────\n\n/** `timestamp without time zone` and its array form. */\nconst TIMESTAMP_OID = 1114;\nconst TIMESTAMP_ARRAY_OID = 1115;\n\n/** PGlite's text output for a zone-less timestamp: `2026-03-08 19:38:08.538`. */\nconst ZONE_LESS_TEXT = /^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}(?:\\.\\d{1,6})?$/;\n\n/**\n * Zone-less timestamp text read as **UTC** — the codec table's\n * `parseDateTimeText` rule (@vibeorm/sql) applied at the driver level, because\n * PGlite hands these columns to the ORM as `Date` objects already\n * (`wire.dateTime: \"native\"` prunes the codec decode). PGlite's own parser is\n * `new Date(text)`, which ECMA-262 reads as host-LOCAL time — while PGlite\n * SERIALIZES a `Date` parameter as UTC (`toISOString()`), so a value did not\n * even round-trip on a non-UTC host. `date` is unaffected (date-only text is\n * UTC midnight under ECMA-262 already). Anything outside the plain form keeps\n * PGlite's parser.\n */\nfunction parseTimestampAsUtc(value: string): unknown {\n if (ZONE_LESS_TEXT.test(value)) {\n const parsed = new Date(`${value.replace(\" \", \"T\").replace(/(\\.\\d{3})\\d+$/, \"$1\")}Z`);\n if (!Number.isNaN(parsed.getTime())) return parsed;\n }\n return new Date(value);\n}\n\nlet utcParsers: ParserOptions | null = null;\n\n/**\n * Per-query parsers (`QueryOptions.parsers`) — never `instance.parsers`, which\n * a caller-supplied instance shares with everyone else. The array parser is\n * PGlite's own (`types.arrayParser`), resolved lazily from the same dynamic\n * import `getInstance` uses, so the WASM module is never loaded just to build\n * this table.\n */\nasync function getUtcParsers(): Promise<ParserOptions> {\n if (utcParsers !== null) return utcParsers;\n const { types } = await import(\"@electric-sql/pglite\");\n utcParsers = {\n [TIMESTAMP_OID]: parseTimestampAsUtc,\n [TIMESTAMP_ARRAY_OID]: (text: string): unknown => types.arrayParser(text, parseTimestampAsUtc, TIMESTAMP_ARRAY_OID),\n };\n return utcParsers;\n}\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 PGlite has passed it back out of `transaction()`.\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\nconst DIALECT: Dialect = \"postgres\";\nconst PROVIDER: Provider = \"pglite\";\n\n/**\n * pglite wire (board #30, live-verified on both execute paths): timestamptz →\n * `Date`, json/jsonb → parsed values, int4/float8 → numbers. (int8 arrives as\n * a native `bigint` here — the BigInt codec passes it through; not declared.)\n */\nconst WIRE: WireFidelity = Object.freeze({ dateTime: \"native\", json: \"parsed\", numbers: \"native\" } as const);\n\n/**\n * Timing budgets this adapter genuinely enforces (EPIC 6).\n *\n * - `acquireTimeout: false` — one in-process WASM instance behind a queue.\n * There is no pool to exhaust.\n * - `statementTimeout: \"unsupported\"` — **PGlite ACCEPTING `statement_timeout`\n * is not support.** The single-threaded WASM build reports the setting back\n * via SHOW and never fires it (board #2, live-verified: `pg_sleep(2)` under a\n * 100 ms timeout runs to completion), which is why the `timeout` option is\n * refused outright below.\n * - `transactionDeadline: \"between-statements\"` — the budget is checked before\n * each statement and before the commit, which PGlite CAN honour because those\n * checks happen in JavaScript. It is not cancellation, for the same\n * single-threaded reason, so `\"cancel-running-statements\"` is refused.\n */\nconst BUDGETS: AdapterBudgetSupport = Object.freeze({\n acquireTimeout: false,\n statementTimeout: \"unsupported\",\n transactionDeadline: \"between-statements\",\n} as const);\n\n// ─── Adapter ──────────────────────────────────────────────────────\n\n/**\n * Create a VibeORM adapter backed by PGlite.\n *\n * @example In-memory database (tests)\n * ```ts\n * const adapter = pgliteAdapter();\n * await adapter.executeUnsafe({ text: `CREATE TABLE \"User\" (\"id\" serial primary key)` });\n * ```\n *\n * @example Persistent database, or a shared instance\n * ```ts\n * const adapter = pgliteAdapter({ dataDir: \"./.pglite\" });\n * const shared = pgliteAdapter({ pglite: existingInstance });\n * ```\n *\n * `disconnect()` closes an instance the adapter created; a later call opens a\n * fresh one (lazy reconnect, matching the pool-backed adapters). With no\n * `dataDir` that fresh instance is a new, empty in-memory database.\n *\n * @example Bundled extensions (pgvector) without hand-constructing PGlite\n * ```ts\n * import { vector } from \"@electric-sql/pglite-pgvector\";\n * const adapter = pgliteAdapter({ dataDir: \"./.pglite\", extensions: { vector } });\n * ```\n */\nexport function pgliteAdapter(options?: PgliteAdapterOptions): DatabaseAdapter {\n if (options?.pglite !== undefined && options.extensions !== undefined) {\n throw new VibeError({\n code: \"VIBE_CONFIG\",\n message:\n \"pgliteAdapter: `extensions` applies to an instance the adapter CREATES — a provided `pglite` instance was already constructed with its own extensions; pass one or the other\",\n meta: { provider: PROVIDER },\n });\n }\n const { queue, txContext } = connectionOwnership({ database: options?.pglite });\n const ownsInstance = options?.pglite === undefined;\n\n /**\n * Deadlock guard (review F6): PGlite is a single connection, and a whole\n * transaction holds the operation queue — so a ROOT-adapter call issued from\n * inside a `transaction()` callback would queue behind the very transaction\n * it is running in and hang forever. The callback runs inside this context;\n * root entry points refuse instead of deadlocking. The tx-bound adapter\n * bypasses the queue and stays fully usable.\n */\n function assertNotInsideTransaction(): void {\n if (txContext.getStore() === true) {\n throw new VibeError({\n code: \"VIBE_TRANSACTION\",\n message:\n \"root client used inside a transaction callback — use the tx client the callback receives; the root connection would deadlock behind the open transaction\",\n meta: { provider: PROVIDER },\n });\n }\n }\n\n let instance: PGliteInterface | null = options?.pglite ?? null;\n let pending: Promise<PGliteInterface> | null = null;\n\n async function getInstance(): Promise<PGliteInterface> {\n if (instance !== null) return instance;\n if (pending === null) {\n pending = runMapped(async () => {\n const { PGlite } = await import(\"@electric-sql/pglite\");\n const created = new PGlite({\n ...(options?.dataDir === undefined ? {} : { dataDir: options.dataDir }),\n ...(options?.extensions === undefined ? {} : { extensions: options.extensions }),\n });\n await created.waitReady;\n return created;\n });\n }\n try {\n instance = await pending;\n return instance;\n } catch (error) {\n // Let the next caller retry instead of caching the failure forever.\n pending = null;\n throw error;\n }\n }\n\n async function runExecute(params: {\n queryable: Queryable;\n text: string;\n values: unknown[];\n scope?: SavepointScope;\n effect?: StatementEffect;\n }): Promise<Record<string, unknown>[]> {\n const values = serializeParams({ values: params.values });\n const parsers = utcParsers ?? (await getUtcParsers());\n const result = await runMapped(() =>\n params.queryable.query<Record<string, unknown>>(params.text, values, { parsers }),\n );\n if (params.scope !== undefined) observeRowChanges({ scope: params.scope, count: statementRowChanges({ effect: params.effect, count: result.affectedRows }) });\n return result.rows;\n }\n\n /**\n * Raw path. Without parameters the statement goes through `exec()` (simple\n * protocol) so multi-statement DDL — what @vibeorm/migrate emits — runs as\n * one call; with parameters it goes through the extended protocol.\n */\n async function runExecuteUnsafe(params: {\n queryable: Queryable;\n text: string;\n values?: unknown[];\n scope?: SavepointScope;\n effect?: StatementEffect;\n }): Promise<QueryResult> {\n const parsers = utcParsers ?? (await getUtcParsers());\n if (params.values === undefined) {\n const results = await runMapped(() => params.queryable.exec(params.text, { parsers }));\n if (params.scope !== undefined) {\n for (const result of results) observeRowChanges({ scope: params.scope, count: statementRowChanges({ effect: params.effect, count: result.affectedRows }) });\n if (results.length === 0) observeRowChanges({ scope: params.scope, count: statementRowChanges({ effect: params.effect }) });\n }\n const last = results.at(-1);\n return { rows: last?.rows ?? [], affectedRows: last?.affectedRows ?? 0 };\n }\n const values = serializeParamsRaw({ values: params.values });\n const result = await runMapped(() =>\n params.queryable.query<Record<string, unknown>>(params.text, values, { parsers }),\n );\n if (params.scope !== undefined) observeRowChanges({ scope: params.scope, count: statementRowChanges({ effect: params.effect, count: result.affectedRows }) });\n return { rows: result.rows, affectedRows: result.affectedRows ?? 0 };\n }\n\n /**\n * Adapter bound to an open transaction. It never re-enters the queue — the\n * enclosing `transaction()` call already owns the connection — and nested\n * `transaction()` calls become savepoints whose LIFETIMES are serialized by\n * the savepoint gate (F14): overlapping siblings would share one savepoint\n * stack, and the earlier one's rollback would erase the later one's work.\n */\n function createTransactionAdapter(params: {\n tx: Transaction;\n scope: SavepointScope;\n budget: TransactionBudget;\n }): DatabaseAdapter {\n const { tx, scope, budget } = params;\n\n return {\n dialect: DIALECT,\n provider: PROVIDER,\n wire: WIRE,\n budgets: BUDGETS,\n rowChanges: (): RowChangeCount => { budget.assertUsable({ stage: \"statement\" }); return readRowChanges({ scope }); },\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 // A server-reported failure aborts a postgres transaction: record it so\n // a callback that swallows it cannot commit nothing (PGlite's COMMIT\n // would be answered with a silent ROLLBACK).\n return runExecute({ queryable: tx, scope, ...execParams })\n .catch((error: unknown) => abortTransactionOnServerFailure({ scope, error }));\n },\n\n async executeUnsafe(execParams) {\n const turn = scopeTurn({ scope });\n if (turn !== undefined) await turn;\n budget.assertUsable({ stage: \"statement\" });\n return runExecuteUnsafe({ queryable: tx, scope, ...execParams })\n .catch((error: unknown) => abortTransactionOnServerFailure({ scope, error }));\n },\n\n async transaction<T>(\n fn: (txAdapter: DatabaseAdapter) => Promise<T>,\n nestedOptions?: TransactionOptions,\n ): Promise<T> {\n refuseNestedTransactionOptions({ options: nestedOptions, provider: PROVIDER });\n budget.assertUsable({ stage: \"nested\" });\n return runNestedSavepoint({\n scope,\n execute: (statement) => runMapped(() => tx.query(statement)),\n // The child shares the ROOT budget by reference: a savepoint never\n // gets an independent clock or session setting.\n body: (child) => fn(createTransactionAdapter({ tx, scope: child, budget })),\n });\n },\n\n async connect(): Promise<void> {\n // Already connected — this adapter is bound to an open transaction.\n },\n\n async disconnect(): Promise<void> {\n // The database outlives the transaction; closing here would be wrong.\n },\n\n formatArrayParam(values: unknown[]): unknown {\n return new PgliteArrayParam(values);\n },\n };\n }\n\n return {\n dialect: DIALECT,\n provider: PROVIDER,\n wire: WIRE,\n budgets: BUDGETS,\n\n async withSession({ run }) {\n assertNotInsideTransaction();\n return queue.run(async () => {\n const db = await getInstance();\n return txContext.run(true, () => runPinnedSession({\n run,\n execute: async (query) => (await runExecuteUnsafe({ queryable: db, ...query })).rows,\n isLost: () => db.closed,\n release: async () => {\n if (!db.closed) await runMapped(() => db.exec(\"ROLLBACK\"));\n },\n }));\n });\n },\n\n async execute(params) {\n assertNotInsideTransaction();\n // The instance is acquired INSIDE the queue (F15): capturing it first and\n // enqueueing after let a `disconnect()` issued in between overtake this\n // statement and close the instance out from under it.\n return queue.run(async () => runExecute({ queryable: await getInstance(), ...params }));\n },\n\n async executeUnsafe(params) {\n assertNotInsideTransaction();\n return queue.run(async () => runExecuteUnsafe({ queryable: await getInstance(), ...params }));\n },\n\n async transaction<T>(\n fn: (txAdapter: DatabaseAdapter) => Promise<T>,\n transactionOptions?: TransactionOptions,\n ): Promise<T> {\n assertNotInsideTransaction();\n // Dialect honesty (constitution rule 4, board #2): PGlite ACCEPTS\n // `SET LOCAL statement_timeout` and even reports it back via SHOW, but\n // never FIRES it — the single-threaded WASM build has no timer interrupt\n // to cancel a running statement (live-verified: `pg_sleep(2)` under a\n // 100ms timeout runs to completion). A timeout the engine cannot enforce\n // is refused at the earliest knowable moment instead of becoming a\n // silent no-op; the postgres SERVER adapters honor the same option for\n // real (SQLSTATE 57014 → VIBE_TRANSACTION, meta.reason \"timeout\").\n if (transactionOptions?.timeout !== undefined) {\n throw new VibeError({\n code: \"VIBE_UNSUPPORTED_CAPABILITY\",\n message:\n \"pglite cannot enforce a transaction timeout: the single-threaded WASM build accepts statement_timeout but never cancels a running statement — remove the option, or use a postgres server adapter where it is genuinely enforced\",\n meta: { provider: PROVIDER, feature: \"transactionTimeout\", timeout: transactionOptions.timeout },\n });\n }\n // Same earliest-moment rule for the deadline: a budget this engine\n // cannot honour is refused before the transaction is ever opened.\n validateTransactionDeadline({\n options: transactionOptions,\n support: BUDGETS.transactionDeadline,\n provider: PROVIDER,\n });\n const scope = createSavepointScope();\n\n return queue.run(async () => {\n const db = await getInstance();\n // The deadline clock starts here — after the queue turn, immediately\n // before PGlite opens the transaction.\n const budget = startTransactionBudget({ options: transactionOptions, provider: PROVIDER });\n try {\n const result = await db.transaction(async (tx) => {\n if (transactionOptions?.isolationLevel !== undefined) {\n await tx.query(\n setIsolationLevelStatement({ isolationLevel: transactionOptions.isolationLevel }),\n );\n }\n try {\n const value = await txContext.run(true, () =>\n runRootScope({ scope, body: () => fn(createTransactionAdapter({ tx, scope, budget })) }),\n );\n // An expired budget must never commit. PGlite commits when this\n // callback returns, so the refusal has to be thrown from INSIDE\n // it — which makes PGlite roll back, exactly as intended.\n budget.assertUsable({ stage: \"commit\" });\n return value;\n } catch (error) {\n throw new CallbackError(error);\n }\n });\n budget.close({ outcome: \"committed\" });\n return result;\n } catch (error) {\n // A successful outer rollback cannot erase uncertainty from a failed\n // nested rollback (the transaction may have ended before cleanup).\n budget.close({ outcome: scope.state.poisoned === null ? \"rolled-back\" : \"unknown\" });\n // Preserve the callback's own failure; the budget retains any\n // uncertainty reported by nested transaction cleanup.\n if (error instanceof CallbackError) throw error.inner;\n throw mapPgliteDriverError({ error });\n }\n });\n },\n\n async connect(): Promise<void> {\n await getInstance();\n },\n\n /**\n * ONE ordered lifecycle (F15): the reference is cleared and the instance\n * closed INSIDE the queue, so work this adapter already accepted completes\n * on the instance it was accepted against instead of being overtaken by the\n * close. Lazy reconnect is unchanged — a later call creates a fresh\n * instance (with no `dataDir`, a new empty one).\n *\n * Refuses inside a transaction callback for the same reason the other entry\n * points do: the close would queue behind the transaction that is waiting\n * for it. Before this guard that call hung forever.\n */\n async disconnect(): Promise<void> {\n assertNotInsideTransaction();\n if (!ownsInstance) return;\n await queue.run(async () => {\n if (instance === null) {\n pending = null;\n return;\n }\n const closing = instance;\n instance = null;\n pending = null;\n await runMapped(() => closing.close());\n });\n },\n\n formatArrayParam(values: unknown[]): unknown {\n return new PgliteArrayParam(values);\n },\n };\n}\n\n// ─── Re-exports (driver-error table, markers, helpers) ────────────\n\nexport {\n PGLITE_SQLSTATE_ERROR_CODES,\n PGLITE_SQLSTATE_REASONS,\n mapPgliteDriverError,\n pgliteErrorSqlstate,\n} from \"./errors.ts\";\nexport { PgliteArrayParam, serializeParams, serializeParamsRaw, toPgArrayLiteral } from \"./params.ts\";\nexport { createOperationQueue } from \"./queue.ts\";\nexport type { OperationQueue } from \"./queue.ts\";\nexport { createSavepointCounter, nextSavepointName } from \"@vibeorm/runtime/adapter-kit\";\nexport type { SavepointCounter } from \"@vibeorm/runtime/adapter-kit\";\nexport {\n ISOLATION_LEVEL_SQL,\n refuseNestedTransactionOptions,\n setIsolationLevelStatement,\n} 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 * Driver-error mapping for PGlite.\n *\n * PGlite runs the real PostgreSQL error protocol in-process, so its errors\n * carry the same SQLSTATE (`code`) plus `constraint` / `table` / `column` as a\n * server would. Constitution rule 5: only `VibeError` 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 maps to `VIBE_ADAPTER`.\n */\nexport const PGLITE_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 /** Data exceptions the same bad input raises (mirrors adapter-pg): too long, out of range, bad datetime, datetime overflow. */\n \"22001\": \"VIBE_VALIDATION\",\n \"22003\": \"VIBE_VALIDATION\",\n \"22007\": \"VIBE_VALIDATION\",\n \"22008\": \"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 /**\n * lock_not_available. PGlite has ONE session, so nothing can contend with the\n * caller — the mapping exists for parity with the server adapters (identical\n * PostgreSQL SQLSTATEs), not because this engine is expected to raise it.\n */\n \"55P03\": \"VIBE_LOCK_NOT_AVAILABLE\",\n /** deadlock_detected */\n \"40P01\": \"VIBE_TRANSACTION\",\n /** query_canceled — statement_timeout fired */\n \"57014\": \"VIBE_TRANSACTION\",\n});\n\n/** SQLSTATEs that additionally explain themselves through `meta.reason`. */\nexport const PGLITE_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 PGlite error. Failures raised by PGlite itself\n * (closed database, WASM init) carry no SQLSTATE and yield `undefined`.\n */\nexport function pgliteErrorSqlstate(params: { error: unknown }): string | undefined {\n const { error } = params;\n if (error === null || typeof error !== \"object\") return undefined;\n const code = readStringField({ source: error as Record<string, unknown>, key: \"code\" });\n return code !== undefined && SQLSTATE_PATTERN.test(code) ? code : undefined;\n}\n\n// ─── Mapping ──────────────────────────────────────────────────────\n\n/**\n * Map any error thrown by PGlite 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 mapPgliteDriverError(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 = pgliteErrorSqlstate({ error });\n const code: VibeErrorCode =\n (sqlstate === undefined ? undefined : PGLITE_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 : PGLITE_SQLSTATE_REASONS[sqlstate];\n if (reason !== undefined) meta.reason = reason;\n\n const message =\n readStringField({ source, key: \"message\" }) ??\n (typeof error === \"string\" ? error : \"unknown pglite 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 mapPgliteDriverError({ error });\n }\n}\n",
|
|
7
|
-
"/**\n * Parameter serialization for PGlite.\n *\n * PGlite takes JS arrays natively for the array types it knows, but it picks a\n * parameter serializer from the BACKEND-INFERRED type OID and falls back to\n * `String(value)` for anything else — so a scalar list bound against a column\n * of a custom type (a native `enum`, i.e. every `Role[]` / `role IN (…)` query)\n * reached the server as `ADMIN,MODERATOR` and was rejected with `malformed\n * array literal`. ORM-path scalar lists are therefore rendered as PostgreSQL\n * array literals here, exactly like the bun:sql adapter does\n * (`@vibeorm/adapter-bun`'s `toPgArrayLiteral`); the server then coerces the\n * literal to whichever array type the statement needs (`text[]`, `int[]`,\n * `timestamptz[]`, `\"Role\"[]`).\n *\n * The ORM path and the raw path still split the same way (LEARNINGS.md): the\n * ORM path cannot tell a `jsonb` value that happens to be an array from a\n * scalar-list parameter, so it JSON-stringifies plain arrays and only treats\n * values tagged with {@link PgliteArrayParam} as scalar lists; the raw path\n * passes plain JS arrays straight through to the driver.\n */\n\nimport { VibeError } from \"@vibeorm/schema\";\n\n// ─── Scalar-list marker ───────────────────────────────────────────\n\n/**\n * Opaque token returned by `pgliteAdapter().formatArrayParam` marking a value\n * as a PostgreSQL array parameter (rather than a JSON value that happens to be\n * an array). The wrapped array is rendered as an array literal on the way out.\n */\nexport class PgliteArrayParam {\n /** The untouched scalar-list values. */\n readonly values: unknown[];\n\n constructor(values: unknown[]) {\n this.values = values;\n }\n}\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 — the same element\n * rules as `@vibeorm/adapter-bun`'s `toPgArrayLiteral` (kept per-adapter: an\n * array literal is driver transport, not SQL text):\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 (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\n * -
|
|
8
|
-
"/**\n * Operation queue for PGlite.\n *\n * PGlite is a single embedded PostgreSQL connection: two overlapping\n * operations would interleave on the same wire, and an interleaved statement\n * inside a transaction would silently join that transaction. Every adapter\n * entry point therefore runs through one serial chain — including whole\n * `transaction()` calls, which occupy the chain until they commit or roll back.\n */\n\nimport { AsyncLocalStorage } from \"node:async_hooks\";\n\n/** Connection-wide exclusion shared by wrappers of an injected instance. */\nexport type ConnectionOwnership = {\n readonly queue: OperationQueue;\n readonly txContext: AsyncLocalStorage<
|
|
9
|
-
"/**\n * Transaction-control SQL text (postgres dialect, PGlite flavour).\n *\n * PGlite issues its own `BEGIN` inside `pglite.transaction(cb)`, so isolation\n * is set with `SET TRANSACTION …` as the first statement of the callback rather\n * than as a `BEGIN` clause.\n */\n\nimport type { IsolationLevel } from \"@vibeorm/runtime\";\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/**\n * `SET TRANSACTION ISOLATION LEVEL <level>` — valid only as the first statement\n * of an open transaction, which is where the adapter issues it.\n */\nexport function setIsolationLevelStatement(params: { isolationLevel: IsolationLevel }): string {\n return `SET TRANSACTION ISOLATION LEVEL ${ISOLATION_LEVEL_SQL[params.isolationLevel]}`;\n}\n\n// NOTE (board #2): this module deliberately has NO statementTimeoutStatement.\n// PGlite accepts `SET LOCAL statement_timeout` and reports it back via SHOW,\n// but the single-threaded WASM build never fires it (live-verified:\n// `pg_sleep(2)` under a 100ms timeout runs to completion) — so the adapter\n// refuses the `timeout` option outright with VIBE_UNSUPPORTED_CAPABILITY\n// instead of rendering SQL that silently does nothing.\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"
|
|
5
|
+
"/**\n * @vibeorm/adapter-pglite — PGlite (in-process PostgreSQL, WASM) adapter for\n * VibeORM v2.\n *\n * PGlite is a *single* embedded connection, so this adapter serializes every\n * operation through one queue — including whole transactions, which hold the\n * queue until they commit or roll back. That makes concurrent client calls safe\n * without a pool, and makes an in-memory instance an honest postgres target for\n * tests (no Docker).\n */\n\nimport { VibeError } from \"@vibeorm/schema\";\nimport type {\n AdapterBudgetSupport,\n DatabaseAdapter,\n QueryResult,\n RowChangeCount,\n StatementEffect,\n TransactionOptions,\n WireFidelity,\n} from \"@vibeorm/runtime\";\nimport {\n abortTransactionOnServerFailure,\n observeRowChanges,\n readRowChanges,\n statementRowChanges,\n createAdapterLifecycleGate,\n runPinnedSession,\n type CommitProgress,\n transactionLifecycleRefusal,\n createSavepointScope,\n type RollbackOutcome,\n runNestedSavepoint,\n runRootScope,\n type SavepointScope,\n scopeTurn,\n settleFailedTransaction,\n startTransactionBudget,\n type TransactionBudget,\n validateTransactionDeadline,\n readOnlyRequested,\n} from \"@vibeorm/runtime/adapter-kit\";\nimport type { Dialect, Provider } from \"@vibeorm/schema\";\nimport type { Extensions, PGliteInterface, ParserOptions, Transaction } from \"@electric-sql/pglite\";\nimport { mapPgliteDriverError, runMapped } from \"./errors.ts\";\nimport { PgliteArrayParam, serializeParams, serializeParamsRaw } from \"./params.ts\";\nimport { connectionOwnership } from \"./queue.ts\";\nimport { refuseNestedTransactionOptions, setTransactionModesStatement } from \"./transaction-sql.ts\";\n\n// ─── Options ──────────────────────────────────────────────────────\n\n/** Options for {@link pgliteAdapter}. */\nexport type PgliteAdapterOptions = {\n /**\n * Directory to persist the database in. Omit for a fresh in-memory database —\n * the usual choice for tests. Prefixes PGlite understands (`idb://`,\n * `memory://`) work here too.\n */\n readonly dataDir?: string;\n /**\n * An already-created PGlite instance to run on (sharing one database across\n * adapters, or reusing a warm instance between test files). The adapter never\n * closes an instance it did not create: `disconnect()` only ends this adapter.\n */\n readonly pglite?: PGliteInterface;\n /**\n * PGlite extension bundles to load into the instance the ADAPTER creates —\n * `{ vector }` from `@electric-sql/pglite-pgvector`, `pg_trgm` from\n * `@electric-sql/pglite/contrib/pg_trgm`, … The bundles still come from\n * their own packages; this option removes the need to construct PGlite\n * yourself just to attach them. Mutually exclusive with `pglite` (that\n * instance was already constructed with its extensions) — passing both\n * throws `VIBE_CONFIG`.\n */\n readonly extensions?: Extensions;\n};\n\n// ─── Internals ────────────────────────────────────────────────────\n\n/** Anything that runs SQL: the PGlite instance itself or an open transaction. */\ntype Queryable = Pick<Transaction, \"query\" | \"exec\">;\n\n// ─── UTC zone-less timestamps ─────────────────────────────────────\n\n/** `timestamp without time zone` and its array form. */\nconst TIMESTAMP_OID = 1114;\nconst TIMESTAMP_ARRAY_OID = 1115;\n\n/** PGlite's text output for a zone-less timestamp: `2026-03-08 19:38:08.538`. */\nconst ZONE_LESS_TEXT = /^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}(?:\\.\\d{1,6})?$/;\n\n/**\n * Zone-less timestamp text read as **UTC** — the codec table's\n * `parseDateTimeText` rule (@vibeorm/sql) applied at the driver level, because\n * PGlite hands these columns to the ORM as `Date` objects already\n * (`wire.dateTime: \"native\"` prunes the codec decode). PGlite's own parser is\n * `new Date(text)`, which ECMA-262 reads as host-LOCAL time — while PGlite\n * SERIALIZES a `Date` parameter as UTC (`toISOString()`), so a value did not\n * even round-trip on a non-UTC host. `date` is unaffected (date-only text is\n * UTC midnight under ECMA-262 already). Anything outside the plain form keeps\n * PGlite's parser.\n */\nfunction parseTimestampAsUtc(value: string): unknown {\n if (ZONE_LESS_TEXT.test(value)) {\n const parsed = new Date(`${value.replace(\" \", \"T\").replace(/(\\.\\d{3})\\d+$/, \"$1\")}Z`);\n if (!Number.isNaN(parsed.getTime())) return parsed;\n }\n return new Date(value);\n}\n\nlet utcParsers: ParserOptions | null = null;\n\n/**\n * Per-query parsers (`QueryOptions.parsers`) — never `instance.parsers`, which\n * a caller-supplied instance shares with everyone else. The array parser is\n * PGlite's own (`types.arrayParser`), resolved lazily from the same dynamic\n * import `getInstance` uses, so the WASM module is never loaded just to build\n * this table.\n */\nasync function getUtcParsers(): Promise<ParserOptions> {\n if (utcParsers !== null) return utcParsers;\n const { types } = await import(\"@electric-sql/pglite\");\n utcParsers = {\n [TIMESTAMP_OID]: parseTimestampAsUtc,\n [TIMESTAMP_ARRAY_OID]: (text: string): unknown => types.arrayParser(text, parseTimestampAsUtc, TIMESTAMP_ARRAY_OID),\n };\n return utcParsers;\n}\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 PGlite has passed it back out of `transaction()`.\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\nconst DIALECT: Dialect = \"postgres\";\nconst PROVIDER: Provider = \"pglite\";\n\n/**\n * pglite wire (board #30, live-verified on both execute paths): timestamptz →\n * `Date`, json/jsonb → parsed values, int4/float8 → numbers. (int8 arrives as\n * a native `bigint` here — the BigInt codec passes it through; not declared.)\n */\nconst WIRE: WireFidelity = Object.freeze({ dateTime: \"native\", json: \"parsed\", numbers: \"native\" } as const);\n\n/**\n * PGlite runs inside this process (WASM): a round trip crosses no network, so\n * the runtime keeps its multi-statement paths instead of the one-statement\n * folds. The transaction facades carry the same declaration.\n */\nconst ROUND_TRIPS: NonNullable<DatabaseAdapter[\"roundTrips\"]> = \"in-process\";\n\n/**\n * Timing budgets this adapter genuinely enforces (EPIC 6).\n *\n * - `acquireTimeout: false` — one in-process WASM instance behind a queue.\n * There is no pool to exhaust.\n * - `statementTimeout: \"unsupported\"` — **PGlite ACCEPTING `statement_timeout`\n * is not support.** The single-threaded WASM build reports the setting back\n * via SHOW and never fires it (board #2, live-verified: `pg_sleep(2)` under a\n * 100 ms timeout runs to completion), which is why the `timeout` option is\n * refused outright below.\n * - `transactionDeadline: \"between-statements\"` — the budget is checked before\n * each statement and before the commit, which PGlite CAN honour because those\n * checks happen in JavaScript. It is not cancellation, for the same\n * single-threaded reason, so `\"cancel-running-statements\"` is refused.\n */\nconst BUDGETS: AdapterBudgetSupport = Object.freeze({\n acquireTimeout: false,\n statementTimeout: \"unsupported\",\n transactionDeadline: \"between-statements\",\n accessModes: Object.freeze([\"readOnly\"] as const),\n} as const);\n\n// ─── Adapter ──────────────────────────────────────────────────────\n\n/**\n * Create a VibeORM adapter backed by PGlite.\n *\n * @example In-memory database (tests)\n * ```ts\n * const adapter = pgliteAdapter();\n * await adapter.executeUnsafe({ text: `CREATE TABLE \"User\" (\"id\" serial primary key)` });\n * ```\n *\n * @example Persistent database, or a shared instance\n * ```ts\n * const adapter = pgliteAdapter({ dataDir: \"./.pglite\" });\n * const shared = pgliteAdapter({ pglite: existingInstance });\n * ```\n *\n * `disconnect()` ends the adapter for good: it waits for admitted work, closes\n * an instance the adapter created (never a provided `pglite`), and every later\n * call refuses with `VIBE_ADAPTER_CLOSED`. Create a new adapter to connect\n * again; with no `dataDir` that is a new, empty in-memory database.\n *\n * @example Bundled extensions (pgvector) without hand-constructing PGlite\n * ```ts\n * import { vector } from \"@electric-sql/pglite-pgvector\";\n * const adapter = pgliteAdapter({ dataDir: \"./.pglite\", extensions: { vector } });\n * ```\n */\nexport function pgliteAdapter(options?: PgliteAdapterOptions): DatabaseAdapter {\n if (options?.pglite !== undefined && options.extensions !== undefined) {\n throw new VibeError({\n code: \"VIBE_CONFIG\",\n message:\n \"pgliteAdapter: `extensions` applies to an instance the adapter CREATES — a provided `pglite` instance was already constructed with its own extensions; pass one or the other\",\n meta: { provider: PROVIDER },\n });\n }\n const { queue, txContext, runInCallback } = connectionOwnership({ database: options?.pglite });\n const ownsInstance = options?.pglite === undefined;\n\n /**\n * Deadlock guard (review F6): PGlite is a single connection, and a whole\n * transaction holds the operation queue — so a ROOT-adapter call issued from\n * inside a `transaction()` callback would queue behind the very transaction\n * it is running in and hang forever. The callback runs inside this context;\n * root entry points refuse instead of deadlocking. The tx-bound adapter\n * bypasses the queue and stays fully usable.\n */\n function assertNotInsideTransaction(): void {\n if (txContext.getStore()?.active === true) {\n throw new VibeError({\n code: \"VIBE_TRANSACTION\",\n message:\n \"root client used inside a transaction callback — use the tx client the callback receives; the root connection would deadlock behind the open transaction\",\n meta: { provider: PROVIDER },\n });\n }\n }\n\n let instance: PGliteInterface | null = options?.pglite ?? null;\n let pending: Promise<PGliteInterface> | null = null;\n\n async function getInstance(): Promise<PGliteInterface> {\n if (instance !== null) return instance;\n if (pending === null) {\n pending = runMapped(async () => {\n const { PGlite } = await import(\"@electric-sql/pglite\");\n const created = new PGlite({\n ...(options?.dataDir === undefined ? {} : { dataDir: options.dataDir }),\n ...(options?.extensions === undefined ? {} : { extensions: options.extensions }),\n });\n await created.waitReady;\n return created;\n });\n }\n try {\n instance = await pending;\n return instance;\n } catch (error) {\n // Let the next caller retry instead of caching the failure forever.\n pending = null;\n throw error;\n }\n }\n\n async function runExecute(params: {\n queryable: Queryable;\n text: string;\n values: unknown[];\n scope?: SavepointScope;\n effect?: StatementEffect;\n }): Promise<Record<string, unknown>[]> {\n const values = serializeParams({ values: params.values });\n const parsers = utcParsers ?? (await getUtcParsers());\n const result = await runMapped(() =>\n params.queryable.query<Record<string, unknown>>(params.text, values, { parsers }),\n );\n if (params.scope !== undefined) observeRowChanges({ scope: params.scope, count: statementRowChanges({ effect: params.effect, count: result.affectedRows, rows: result.rows.length, resultRows: result.rows }) });\n return result.rows;\n }\n\n /**\n * Raw path. Without parameters the statement goes through `exec()` (simple\n * protocol) so multi-statement DDL — what @vibeorm/migrate emits — runs as\n * one call; with parameters it goes through the extended protocol.\n */\n async function runExecuteUnsafe(params: {\n queryable: Queryable;\n text: string;\n values?: unknown[];\n scope?: SavepointScope;\n effect?: StatementEffect;\n }): Promise<QueryResult> {\n const parsers = utcParsers ?? (await getUtcParsers());\n if (params.values === undefined) {\n const results = await runMapped(() => params.queryable.exec(params.text, { parsers }));\n if (params.scope !== undefined) {\n for (const result of results) observeRowChanges({ scope: params.scope, count: statementRowChanges({ effect: params.effect, count: result.affectedRows }) });\n if (results.length === 0) observeRowChanges({ scope: params.scope, count: statementRowChanges({ effect: params.effect }) });\n }\n const last = results.at(-1);\n return { rows: last?.rows ?? [], affectedRows: last?.affectedRows ?? 0 };\n }\n const values = serializeParamsRaw({ values: params.values });\n const result = await runMapped(() =>\n params.queryable.query<Record<string, unknown>>(params.text, values, { parsers }),\n );\n if (params.scope !== undefined) observeRowChanges({ scope: params.scope, count: statementRowChanges({ effect: params.effect, count: result.affectedRows }) });\n return { rows: result.rows, affectedRows: result.affectedRows ?? 0 };\n }\n\n /**\n * Adapter bound to an open transaction. It never re-enters the queue — the\n * enclosing `transaction()` call already owns the connection — and nested\n * `transaction()` calls become savepoints whose LIFETIMES are serialized by\n * the savepoint gate (F14): overlapping siblings would share one savepoint\n * stack, and the earlier one's rollback would erase the later one's work.\n */\n function createTransactionAdapter(params: {\n tx: Transaction;\n scope: SavepointScope;\n budget: TransactionBudget;\n }): DatabaseAdapter {\n const { tx, scope, budget } = params;\n\n return {\n dialect: DIALECT,\n provider: PROVIDER,\n wire: WIRE,\n budgets: BUDGETS,\n roundTrips: ROUND_TRIPS,\n rowChanges: (): RowChangeCount => { budget.assertUsable({ stage: \"statement\" }); return readRowChanges({ scope }); },\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 // A server-reported failure aborts a postgres transaction: record it so\n // a callback that swallows it cannot commit nothing (PGlite's COMMIT\n // would be answered with a silent ROLLBACK).\n return runExecute({ queryable: tx, scope, ...execParams })\n .catch((error: unknown) => abortTransactionOnServerFailure({ scope, error }));\n },\n\n async executeUnsafe(execParams) {\n const turn = scopeTurn({ scope });\n if (turn !== undefined) await turn;\n budget.assertUsable({ stage: \"statement\" });\n return runExecuteUnsafe({ queryable: tx, scope, ...execParams })\n .catch((error: unknown) => abortTransactionOnServerFailure({ scope, error }));\n },\n\n async transaction<T>(\n fn: (txAdapter: DatabaseAdapter) => Promise<T>,\n nestedOptions?: TransactionOptions,\n ): Promise<T> {\n refuseNestedTransactionOptions({ options: nestedOptions, provider: PROVIDER });\n budget.assertUsable({ stage: \"nested\" });\n return runNestedSavepoint({\n scope,\n execute: (statement) => runMapped(() => tx.exec(statement)),\n // The child shares the ROOT budget by reference: a savepoint never\n // gets an independent clock or session setting.\n body: (child) => fn(createTransactionAdapter({ tx, scope: child, budget })),\n });\n },\n\n // The open transaction owns this connection: neither call may act on it.\n // An expired handle keeps its own refusal (the budget check comes first).\n async connect(): Promise<void> {\n budget.assertUsable({ stage: \"statement\" });\n throw transactionLifecycleRefusal({ method: \"connect\" });\n },\n\n async disconnect(): Promise<void> {\n budget.assertUsable({ stage: \"statement\" });\n throw transactionLifecycleRefusal({ method: \"disconnect\" });\n },\n\n formatArrayParam(values: unknown[]): unknown {\n return new PgliteArrayParam(values);\n },\n };\n }\n\n /**\n * Terminal lifetime (EPIC A2). The cleanup runs ONCE, after every admitted\n * operation settled, and closes an instance the adapter created — never an\n * injected one. A running callback of the shared connection (this wrapper's\n * or another wrapper's over the same injected instance) cannot disconnect:\n * the close would wait behind the transaction that is waiting for it.\n */\n const lifecycle = createAdapterLifecycleGate({\n driver: \"pglite\",\n isConnectionReentrant: () => txContext.getStore()?.active === true,\n cleanup: async () => {\n if (!ownsInstance) return;\n await queue.run(async () => {\n if (instance === null) {\n pending = null;\n return;\n }\n const closing = instance;\n instance = null;\n pending = null;\n await runMapped(() => closing.close());\n });\n },\n });\n\n /** The root operations; the adapter below admits each one through {@link lifecycle}. */\n const root: Pick<Required<DatabaseAdapter>, \"withSession\" | \"execute\" | \"executeUnsafe\" | \"transaction\" | \"connect\"> = {\n async withSession({ run }) {\n assertNotInsideTransaction();\n return queue.run(async () => {\n const db = await getInstance();\n return runInCallback( () => runPinnedSession({\n run,\n execute: async (query) => (await runExecuteUnsafe({ queryable: db, ...query })).rows,\n isLost: () => db.closed,\n release: async () => {\n if (!db.closed) await runMapped(() => db.exec(\"ROLLBACK\"));\n },\n }));\n });\n },\n\n async execute(params) {\n assertNotInsideTransaction();\n // The instance is acquired INSIDE the queue (F15): capturing it first and\n // enqueueing after let a `disconnect()` issued in between overtake this\n // statement and close the instance out from under it.\n return queue.run(async () => runExecute({ queryable: await getInstance(), ...params }));\n },\n\n async executeUnsafe(params) {\n assertNotInsideTransaction();\n return queue.run(async () => runExecuteUnsafe({ queryable: await getInstance(), ...params }));\n },\n\n async transaction<T>(\n fn: (txAdapter: DatabaseAdapter) => Promise<T>,\n transactionOptions?: TransactionOptions,\n ): Promise<T> {\n assertNotInsideTransaction();\n // Dialect honesty (constitution rule 4, board #2): PGlite ACCEPTS\n // `SET LOCAL statement_timeout` and even reports it back via SHOW, but\n // never FIRES it — the single-threaded WASM build has no timer interrupt\n // to cancel a running statement (live-verified: `pg_sleep(2)` under a\n // 100ms timeout runs to completion). A timeout the engine cannot enforce\n // is refused at the earliest knowable moment instead of becoming a\n // silent no-op; the postgres SERVER adapters honor the same option for\n // real (SQLSTATE 57014 → VIBE_TRANSACTION, meta.reason \"timeout\").\n if (transactionOptions?.timeout !== undefined) {\n throw new VibeError({\n code: \"VIBE_UNSUPPORTED_CAPABILITY\",\n message:\n \"pglite cannot enforce a transaction timeout: the single-threaded WASM build accepts statement_timeout but never cancels a running statement — remove the option, or use a postgres server adapter where it is genuinely enforced\",\n meta: { provider: PROVIDER, feature: \"transactionTimeout\", timeout: transactionOptions.timeout },\n });\n }\n // Same earliest-moment rule for the deadline: a budget this engine\n // cannot honour is refused before the transaction is ever opened.\n validateTransactionDeadline({\n options: transactionOptions,\n support: BUDGETS.transactionDeadline,\n provider: PROVIDER,\n });\n const modesText = setTransactionModesStatement({\n isolationLevel: transactionOptions?.isolationLevel,\n readOnly: readOnlyRequested({ options: transactionOptions, provider: PROVIDER }),\n });\n const scope = createSavepointScope();\n\n return queue.run(async () => {\n const db = await getInstance();\n // The deadline clock starts here — after the queue turn, immediately\n // before PGlite opens the transaction.\n const budget = startTransactionBudget({ options: transactionOptions, provider: PROVIDER });\n /**\n * EPIC T facts, in holders because PGlite's callback sets them out of\n * sight of the compiler's narrowing: how far COMMIT got (PGlite sends\n * it the moment the callback returns), and the failure the callback\n * handed PGlite to roll back.\n */\n const commit: { progress: CommitProgress } = { progress: \"not-sent\" };\n const handed: { failure?: CallbackError } = {};\n try {\n const result = await db.transaction(async (tx) => {\n try {\n // Isolation and READ ONLY (`accessMode`) in one in-process exec,\n // right after PGlite's own BEGIN.\n if (modesText !== undefined) await runMapped(() => tx.exec(modesText));\n const value = await runInCallback( () =>\n runRootScope({ scope, body: () => fn(createTransactionAdapter({ tx, scope, budget })) }),\n );\n // An expired budget must never commit. PGlite commits when this\n // callback returns, so the refusal has to be thrown from INSIDE\n // it — which makes PGlite roll back, exactly as intended.\n budget.assertUsable({ stage: \"commit\" });\n commit.progress = \"sent\";\n return value;\n } catch (error) {\n handed.failure = new CallbackError(error);\n throw handed.failure;\n }\n });\n budget.close({ outcome: \"committed\" });\n return result;\n } catch (error) {\n const failure = handed.failure;\n // No callback failure after COMMIT was sent: PGlite's COMMIT failed.\n // The engine runs in-process, so that failure IS its answer, and\n // PGlite sends no ROLLBACK after it.\n if (commit.progress === \"sent\" && failure === undefined) commit.progress = \"answered\";\n // PGlite rolls back a failed callback itself. When that ROLLBACK\n // fails, PGlite throws the ROLLBACK's error INSTEAD of the callback's:\n // the callback's own failure is rethrown anyway, as on every other\n // adapter, and the failed ROLLBACK is reported beside it.\n const rollback: RollbackOutcome = failure === undefined ? \"not-needed\" : error === failure ? \"acknowledged\" : \"failed\";\n // EPIC T: the same error, with the facts recorded beside it. The one\n // instance is kept — there is no pool to discard it from. A lost\n // savepoint stack keeps the unknown outcome (settleFailedTransaction).\n throw settleFailedTransaction({\n error: failure === undefined ? mapPgliteDriverError({ error }) : failure.inner,\n provider: PROVIDER,\n budget,\n scope,\n commit: commit.progress,\n rollback,\n connection: \"returned\",\n });\n }\n });\n },\n\n async connect(): Promise<void> {\n assertNotInsideTransaction();\n await queue.run(async () => { await getInstance(); });\n },\n };\n\n return {\n dialect: DIALECT,\n provider: PROVIDER,\n wire: WIRE,\n budgets: BUDGETS,\n roundTrips: ROUND_TRIPS,\n transactionOutcome: \"reported\",\n\n withSession({ run }) {\n return lifecycle.admit({ run: () => root.withSession({ run }) });\n },\n\n execute(params) {\n return lifecycle.admit({ run: () => root.execute(params) });\n },\n\n executeUnsafe(params) {\n return lifecycle.admit({ run: () => root.executeUnsafe(params) });\n },\n\n transaction<T>(\n fn: (txAdapter: DatabaseAdapter) => Promise<T>,\n transactionOptions?: TransactionOptions,\n ): Promise<T> {\n return lifecycle.admit({ run: () => root.transaction(fn, transactionOptions) });\n },\n\n connect(): Promise<void> {\n return lifecycle.admit({ run: () => root.connect() });\n },\n\n /**\n * Terminal (EPIC A2): refuses new work at once, waits for admitted work —\n * queued statements and whole transaction/session callbacks — then closes\n * an instance the adapter created, once (inside the queue, F15). Repeated\n * calls share that completion. A new adapter is the only way to connect\n * again; with no `dataDir` that is a new, empty database.\n */\n disconnect(): Promise<void> {\n return lifecycle.disconnect();\n },\n\n formatArrayParam(values: unknown[]): unknown {\n return new PgliteArrayParam(values);\n },\n };\n}\n\n// ─── Re-exports (driver-error table, markers, helpers) ────────────\n\nexport {\n PGLITE_SQLSTATE_ERROR_CODES,\n PGLITE_SQLSTATE_REASONS,\n mapPgliteDriverError,\n pgliteErrorSqlstate,\n} from \"./errors.ts\";\nexport { PgliteArrayParam, serializeParams, serializeParamsRaw, toPgArrayLiteral } from \"./params.ts\";\nexport { createOperationQueue } from \"./queue.ts\";\nexport type { OperationQueue } from \"./queue.ts\";\nexport { createSavepointCounter, nextSavepointName } from \"@vibeorm/runtime/adapter-kit\";\nexport type { SavepointCounter } from \"@vibeorm/runtime/adapter-kit\";\nexport {\n ISOLATION_LEVEL_SQL,\n refuseNestedTransactionOptions,\n setIsolationLevelStatement,\n} 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 * Driver-error mapping for PGlite.\n *\n * PGlite runs the real PostgreSQL error protocol in-process, so its errors\n * carry the same SQLSTATE (`code`) plus `constraint` / `table` / `column` as a\n * server would. Constitution rule 5: only `VibeError` 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 maps to `VIBE_ADAPTER`.\n */\nexport const PGLITE_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 /** Data exceptions the same bad input raises (mirrors adapter-pg): too long, out of range, bad datetime, datetime overflow. */\n \"22001\": \"VIBE_VALIDATION\",\n \"22003\": \"VIBE_VALIDATION\",\n \"22007\": \"VIBE_VALIDATION\",\n \"22008\": \"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 /**\n * lock_not_available. PGlite has ONE session, so nothing can contend with the\n * caller — the mapping exists for parity with the server adapters (identical\n * PostgreSQL SQLSTATEs), not because this engine is expected to raise it.\n */\n \"55P03\": \"VIBE_LOCK_NOT_AVAILABLE\",\n /** deadlock_detected */\n \"40P01\": \"VIBE_TRANSACTION\",\n /** query_canceled — statement_timeout fired */\n \"57014\": \"VIBE_TRANSACTION\",\n /** read_only_sql_transaction — a write inside a READ ONLY transaction (mirrors adapter-pg). */\n \"25006\": \"VIBE_TRANSACTION\",\n});\n\n/** SQLSTATEs that additionally explain themselves through `meta.reason`. */\nexport const PGLITE_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 \"25006\": \"read-only-transaction\",\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 PGlite error. Failures raised by PGlite itself\n * (closed database, WASM init) carry no SQLSTATE and yield `undefined`.\n */\nexport function pgliteErrorSqlstate(params: { error: unknown }): string | undefined {\n const { error } = params;\n if (error === null || typeof error !== \"object\") return undefined;\n const code = readStringField({ source: error as Record<string, unknown>, key: \"code\" });\n return code !== undefined && SQLSTATE_PATTERN.test(code) ? code : undefined;\n}\n\n// ─── Mapping ──────────────────────────────────────────────────────\n\n/**\n * Map any error thrown by PGlite 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 mapPgliteDriverError(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 = pgliteErrorSqlstate({ error });\n const code: VibeErrorCode =\n (sqlstate === undefined ? undefined : PGLITE_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 : PGLITE_SQLSTATE_REASONS[sqlstate];\n if (reason !== undefined) meta.reason = reason;\n\n const message =\n readStringField({ source, key: \"message\" }) ??\n (typeof error === \"string\" ? error : \"unknown pglite 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 mapPgliteDriverError({ error });\n }\n}\n",
|
|
7
|
+
"/**\n * Parameter serialization for PGlite.\n *\n * PGlite takes JS arrays natively for the array types it knows, but it picks a\n * parameter serializer from the BACKEND-INFERRED type OID and falls back to\n * `String(value)` for anything else — so a scalar list bound against a column\n * of a custom type (a native `enum`, i.e. every `Role[]` / `role IN (…)` query)\n * reached the server as `ADMIN,MODERATOR` and was rejected with `malformed\n * array literal`. ORM-path scalar lists are therefore rendered as PostgreSQL\n * array literals here, exactly like the bun:sql adapter does\n * (`@vibeorm/adapter-bun`'s `toPgArrayLiteral`); the server then coerces the\n * literal to whichever array type the statement needs (`text[]`, `int[]`,\n * `timestamptz[]`, `\"Role\"[]`).\n *\n * The ORM path and the raw path still split the same way (LEARNINGS.md): the\n * ORM path cannot tell a `jsonb` value that happens to be an array from a\n * scalar-list parameter, so it JSON-stringifies plain arrays and only treats\n * values tagged with {@link PgliteArrayParam} as scalar lists; the raw path\n * passes plain JS arrays straight through to the driver.\n */\n\nimport { Buffer } from \"node:buffer\";\nimport { VibeError } from \"@vibeorm/schema\";\n\n// ─── Scalar-list marker ───────────────────────────────────────────\n\n/**\n * Opaque token returned by `pgliteAdapter().formatArrayParam` marking a value\n * as a PostgreSQL array parameter (rather than a JSON value that happens to be\n * an array). The wrapped array is rendered as an array literal on the way out.\n */\nexport class PgliteArrayParam {\n /** The untouched scalar-list values. */\n readonly values: unknown[];\n\n constructor(values: unknown[]) {\n this.values = values;\n }\n}\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 — the same element\n * rules as `@vibeorm/adapter-bun`'s `toPgArrayLiteral` (kept per-adapter: an\n * array literal is driver transport, not SQL text):\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 (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\n * - `Uint8Array` (including `Buffer`) → quoted PostgreSQL bytea hex\n * - other binary views / `ArrayBuffer` → unsupported, throws\n *\n * @throws VibeError `VIBE_VALIDATION` for unsupported 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 (value instanceof Uint8Array) {\n return quoteElement(`\\\\x${Buffer.from(value.buffer, value.byteOffset, value.byteLength).toString(\"hex\")}`);\n }\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: \"pglite\" },\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/** True for values PGlite must receive verbatim (dates, binary, primitives, null). */\nfunction isDriverNativeValue(value: unknown): boolean {\n return (\n value === null ||\n value === undefined ||\n typeof value !== \"object\" ||\n value instanceof Date ||\n ArrayBuffer.isView(value) ||\n value instanceof ArrayBuffer\n );\n}\n\n/**\n * ORM hot path: render scalar-list markers as array literals, JSON-stringify\n * plain objects **and** plain arrays (they can only be `json`/`jsonb` values at\n * this point).\n */\nexport function serializeParams(params: { values: readonly unknown[] }): unknown[] {\n return params.values.map((value) => {\n if (value instanceof PgliteArrayParam) return toPgArrayLiteral(value.values);\n if (isDriverNativeValue(value)) return value;\n return JSON.stringify(value);\n });\n}\n\n/**\n * Raw path (`$queryRaw*` / `$executeRaw*` / DDL): identical to\n * {@link serializeParams} except that plain JS arrays pass straight through, so\n * `db.$queryRawUnsafe('… WHERE \"id\" = ANY($1)', [1, 2, 3])` matches rows.\n */\nexport function serializeParamsRaw(params: { values: readonly unknown[] }): unknown[] {\n return params.values.map((value) => {\n if (value instanceof PgliteArrayParam) return toPgArrayLiteral(value.values);\n if (Array.isArray(value)) return value;\n if (isDriverNativeValue(value)) return value;\n return JSON.stringify(value);\n });\n}\n",
|
|
8
|
+
"/**\n * Operation queue for PGlite.\n *\n * PGlite is a single embedded PostgreSQL connection: two overlapping\n * operations would interleave on the same wire, and an interleaved statement\n * inside a transaction would silently join that transaction. Every adapter\n * entry point therefore runs through one serial chain — including whole\n * `transaction()` calls, which occupy the chain until they commit or roll back.\n */\n\nimport { AsyncLocalStorage } from \"node:async_hooks\";\n\n/** Connection-wide exclusion shared by wrappers of an injected instance. */\nexport type ConnectionOwnership = {\n readonly queue: OperationQueue;\n readonly txContext: AsyncLocalStorage<{ active: boolean }>;\n readonly runInCallback: <T>(run: () => Promise<T>) => Promise<T>;\n};\n\nconst INJECTED_OWNERSHIP: WeakMap<object, ConnectionOwnership> = new WeakMap();\n\n/** Reuse the same operation queue for the same caller-owned PGlite instance. */\nexport function connectionOwnership(params: { database?: object }): ConnectionOwnership {\n const existing = params.database === undefined ? undefined : INJECTED_OWNERSHIP.get(params.database);\n if (existing !== undefined) return existing;\n const txContext = new AsyncLocalStorage<{ active: boolean }>();\n const ownership: ConnectionOwnership = { queue: createOperationQueue(), txContext,\n runInCallback<T>(run: () => Promise<T>): Promise<T> {\n const token = { active: true };\n return txContext.run(token, run).finally(() => { token.active = false; });\n },\n };\n if (params.database !== undefined) INJECTED_OWNERSHIP.set(params.database, ownership);\n return ownership;\n}\n\n/** A serial chain: jobs run one at a time, in the order they were queued. */\nexport type OperationQueue = {\n /** Queue `job`, resolving with its result once every earlier job has settled. */\n run<T>(job: () => Promise<T>): Promise<T>;\n};\n\n/** Create an empty operation queue. */\nexport function createOperationQueue(): OperationQueue {\n let tail: Promise<unknown> = Promise.resolve();\n\n return {\n run<T>(job: () => Promise<T>): Promise<T> {\n // Run after the previous job settles, whether it resolved or rejected.\n const result = tail.then(job, job);\n // Keep the chain alive: a rejected job must not reject every later job.\n tail = result.then(\n () => undefined,\n () => undefined,\n );\n return result;\n },\n };\n}\n",
|
|
9
|
+
"/**\n * Transaction-control SQL text (postgres dialect, PGlite flavour).\n *\n * PGlite issues its own `BEGIN` inside `pglite.transaction(cb)`, so isolation\n * is set with `SET TRANSACTION …` as the first statement of the callback rather\n * than as a `BEGIN` clause.\n */\n\nimport type { IsolationLevel } from \"@vibeorm/runtime\";\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/**\n * `SET TRANSACTION ISOLATION LEVEL <level>` — valid only as the first statement\n * of an open transaction, which is where the adapter issues it.\n */\nexport function setIsolationLevelStatement(params: { isolationLevel: IsolationLevel }): string {\n return `SET TRANSACTION ISOLATION LEVEL ${ISOLATION_LEVEL_SQL[params.isolationLevel]}`;\n}\n\n/**\n * `SET TRANSACTION [ISOLATION LEVEL <level>][, ]READ ONLY` — the transaction\n * modes PGlite cannot put in its own `BEGIN`, sent as the first exec inside\n * `pglite.transaction(cb)`. Returns `undefined` when nothing was asked for.\n * The isolation-only text is exactly {@link setIsolationLevelStatement}.\n */\nexport function setTransactionModesStatement(params: { isolationLevel?: IsolationLevel; readOnly?: boolean }): string | undefined {\n const { isolationLevel, readOnly } = params;\n if (readOnly !== true) return isolationLevel === undefined ? undefined : setIsolationLevelStatement({ isolationLevel });\n return isolationLevel === undefined\n ? \"SET TRANSACTION READ ONLY\"\n : `SET TRANSACTION ISOLATION LEVEL ${ISOLATION_LEVEL_SQL[isolationLevel]}, READ ONLY`;\n}\n\n// NOTE (board #2): this module deliberately has NO statementTimeoutStatement.\n// PGlite accepts `SET LOCAL statement_timeout` and reports it back via SHOW,\n// but the single-threaded WASM build never fires it (live-verified:\n// `pg_sleep(2)` under a 100ms timeout runs to completion) — so the adapter\n// refuses the `timeout` option outright with VIBE_UNSUPPORTED_CAPABILITY\n// instead of rendering SQL that silently does nothing.\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"
|
|
10
10
|
],
|
|
11
|
-
"mappings": "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",
|
|
12
|
-
"debugId": "
|
|
11
|
+
"mappings": "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",
|
|
12
|
+
"debugId": "F326F27D7631562D64756E2164756E21",
|
|
13
13
|
"names": []
|
|
14
14
|
}
|
package/dist/params.d.ts
CHANGED
|
@@ -39,9 +39,10 @@ export declare class PgliteArrayParam {
|
|
|
39
39
|
* inside an element are safe)
|
|
40
40
|
* - any other object, **including a nested array** → quoted `JSON.stringify`,
|
|
41
41
|
* which is what a `Json[]` scalar list needs
|
|
42
|
-
* -
|
|
42
|
+
* - `Uint8Array` (including `Buffer`) → quoted PostgreSQL bytea hex
|
|
43
|
+
* - other binary views / `ArrayBuffer` → unsupported, throws
|
|
43
44
|
*
|
|
44
|
-
* @throws VibeError `VIBE_VALIDATION` for binary elements.
|
|
45
|
+
* @throws VibeError `VIBE_VALIDATION` for unsupported binary elements.
|
|
45
46
|
*/
|
|
46
47
|
export declare function toPgArrayLiteral(values: readonly unknown[]): string;
|
|
47
48
|
/**
|
package/dist/queue.d.ts
CHANGED
|
@@ -11,7 +11,10 @@ import { AsyncLocalStorage } from "node:async_hooks";
|
|
|
11
11
|
/** Connection-wide exclusion shared by wrappers of an injected instance. */
|
|
12
12
|
export type ConnectionOwnership = {
|
|
13
13
|
readonly queue: OperationQueue;
|
|
14
|
-
readonly txContext: AsyncLocalStorage<
|
|
14
|
+
readonly txContext: AsyncLocalStorage<{
|
|
15
|
+
active: boolean;
|
|
16
|
+
}>;
|
|
17
|
+
readonly runInCallback: <T>(run: () => Promise<T>) => Promise<T>;
|
|
15
18
|
};
|
|
16
19
|
/** Reuse the same operation queue for the same caller-owned PGlite instance. */
|
|
17
20
|
export declare function connectionOwnership(params: {
|
|
@@ -15,5 +15,15 @@ export declare const ISOLATION_LEVEL_SQL: Readonly<Record<IsolationLevel, string
|
|
|
15
15
|
export declare function setIsolationLevelStatement(params: {
|
|
16
16
|
isolationLevel: IsolationLevel;
|
|
17
17
|
}): string;
|
|
18
|
+
/**
|
|
19
|
+
* `SET TRANSACTION [ISOLATION LEVEL <level>][, ]READ ONLY` — the transaction
|
|
20
|
+
* modes PGlite cannot put in its own `BEGIN`, sent as the first exec inside
|
|
21
|
+
* `pglite.transaction(cb)`. Returns `undefined` when nothing was asked for.
|
|
22
|
+
* The isolation-only text is exactly {@link setIsolationLevelStatement}.
|
|
23
|
+
*/
|
|
24
|
+
export declare function setTransactionModesStatement(params: {
|
|
25
|
+
isolationLevel?: IsolationLevel;
|
|
26
|
+
readOnly?: boolean;
|
|
27
|
+
}): string | undefined;
|
|
18
28
|
export { refuseNestedTransactionOptions } from "@vibeorm/runtime/adapter-kit";
|
|
19
29
|
//# sourceMappingURL=transaction-sql.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vibeorm/adapter-pglite",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "PGlite (in-process Postgres) adapter for VibeORM v2",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"orm",
|
|
@@ -36,7 +36,9 @@
|
|
|
36
36
|
},
|
|
37
37
|
"files": [
|
|
38
38
|
"dist",
|
|
39
|
-
"
|
|
39
|
+
"!dist/**/*.d.ts.map",
|
|
40
|
+
"README.md",
|
|
41
|
+
"LICENSE"
|
|
40
42
|
],
|
|
41
43
|
"engines": {
|
|
42
44
|
"node": ">=18",
|
|
@@ -44,8 +46,8 @@
|
|
|
44
46
|
},
|
|
45
47
|
"dependencies": {
|
|
46
48
|
"@electric-sql/pglite": "^0.3.0 || ^0.4.0 || ^0.5.0",
|
|
47
|
-
"@vibeorm/runtime": "
|
|
48
|
-
"@vibeorm/schema": "
|
|
49
|
+
"@vibeorm/runtime": "3.0.0",
|
|
50
|
+
"@vibeorm/schema": "3.0.0"
|
|
49
51
|
},
|
|
50
52
|
"publishConfig": {
|
|
51
53
|
"access": "public"
|
package/dist/errors.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,SAAS,EAAE,KAAK,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAIhE;;;GAGG;AACH,eAAO,MAAM,2BAA2B,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CA0C9E,CAAC;AAEH,4EAA4E;AAC5E,eAAO,MAAM,uBAAuB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAMnE,CAAC;AAYH;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE;IAAE,KAAK,EAAE,OAAO,CAAA;CAAE,GAAG,MAAM,GAAG,SAAS,CAKlF;AAID;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE;IAAE,KAAK,EAAE,OAAO,CAAA;CAAE,GAAG,SAAS,CA0B1E;AAED,wEAAwE;AACxE,wBAAsB,SAAS,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAMnE"}
|
package/dist/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EAEV,eAAe,EAMhB,MAAM,kBAAkB,CAAC;AAiB1B,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAA8B,MAAM,sBAAsB,CAAC;AAQpG,yCAAyC;AACzC,MAAM,MAAM,oBAAoB,GAAG;IACjC;;;;OAIG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;OAIG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,eAAe,CAAC;IAClC;;;;;;;;OAQG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,UAAU,CAAC;CAClC,CAAC;AAsGF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,aAAa,CAAC,OAAO,CAAC,EAAE,oBAAoB,GAAG,eAAe,CAuT7E;AAID,OAAO,EACL,2BAA2B,EAC3B,uBAAuB,EACvB,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACtG,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAClD,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACzF,YAAY,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,EACL,mBAAmB,EACnB,8BAA8B,EAC9B,0BAA0B,GAC3B,MAAM,sBAAsB,CAAC;AAE9B,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/params.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"params.d.ts","sourceRoot":"","sources":["../src/params.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAMH;;;;GAIG;AACH,qBAAa,gBAAgB;IAC3B,wCAAwC;IACxC,QAAQ,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;IAE3B,YAAY,MAAM,EAAE,OAAO,EAAE,EAE5B;CACF;AASD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,OAAO,EAAE,GAAG,MAAM,CAmBnE;AAgBD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE;IAAE,MAAM,EAAE,SAAS,OAAO,EAAE,CAAA;CAAE,GAAG,OAAO,EAAE,CAMjF;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE;IAAE,MAAM,EAAE,SAAS,OAAO,EAAE,CAAA;CAAE,GAAG,OAAO,EAAE,CAOpF"}
|
package/dist/queue.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["../src/queue.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAErD,4EAA4E;AAC5E,MAAM,MAAM,mBAAmB,GAAG;IAChC,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAC;IAC/B,QAAQ,CAAC,SAAS,EAAE,iBAAiB,CAAC,IAAI,CAAC,CAAC;CAC7C,CAAC;AAIF,gFAAgF;AAChF,wBAAgB,mBAAmB,CAAC,MAAM,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,mBAAmB,CAMtF;AAED,6EAA6E;AAC7E,MAAM,MAAM,cAAc,GAAG;IAC3B,iFAAiF;IACjF,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CAC3C,CAAC;AAEF,uCAAuC;AACvC,wBAAgB,oBAAoB,IAAI,cAAc,CAerD"}
|
|
@@ -1 +0,0 @@
|
|
|
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;AAEvD,oEAAoE;AACpE,eAAO,MAAM,mBAAmB,EAAE,QAAQ,CAAC,MAAM,CAAC,cAAc,EAAE,MAAM,CAAC,CAIvE,CAAC;AAEH;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE;IAAE,cAAc,EAAE,cAAc,CAAA;CAAE,GAAG,MAAM,CAE7F;AAaD,OAAO,EAAE,8BAA8B,EAAE,MAAM,8BAA8B,CAAC"}
|