@mikro-orm/pglite 7.2.6-dev.37 → 7.2.6-dev.38
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/PgliteConnection.js +53 -24
- package/package.json +3 -3
package/PgliteConnection.js
CHANGED
|
@@ -2,6 +2,37 @@ import { PGlite } from '@electric-sql/pglite';
|
|
|
2
2
|
import { PGliteDialect } from 'kysely';
|
|
3
3
|
import array from 'postgres-array';
|
|
4
4
|
import { AbstractSqlConnection, createPostgreSqlTypeParsers } from '@mikro-orm/sql';
|
|
5
|
+
/**
|
|
6
|
+
* PostgreSQL answers `COMMIT` of an aborted transaction (e.g. after a caught unique violation) with the command
|
|
7
|
+
* tag `ROLLBACK` instead of an error, and PGlite's `transaction()` commits without looking at the tag. Any server
|
|
8
|
+
* error aborts the transaction, and the only statement that then succeeds is `ROLLBACK TO SAVEPOINT`, which
|
|
9
|
+
* recovers it, so the last statement's outcome tells whether the commit would be a rollback.
|
|
10
|
+
*/
|
|
11
|
+
const rejectAbortedCommit = (transaction) => callback => transaction(async (tx) => {
|
|
12
|
+
let aborted = false;
|
|
13
|
+
const result = await callback(Object.create(tx, {
|
|
14
|
+
query: {
|
|
15
|
+
value: async (...args) => {
|
|
16
|
+
try {
|
|
17
|
+
const res = await tx.query(...args);
|
|
18
|
+
aborted = false;
|
|
19
|
+
return res;
|
|
20
|
+
}
|
|
21
|
+
catch (e) {
|
|
22
|
+
// client-side failures (e.g. a serializer throwing) have no SQLSTATE and leave the transaction alone
|
|
23
|
+
aborted ||= !!e.code;
|
|
24
|
+
throw e;
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
}));
|
|
29
|
+
if (aborted) {
|
|
30
|
+
throw Object.assign(new Error('current transaction is aborted, COMMIT would be answered with ROLLBACK'), {
|
|
31
|
+
code: '25P02',
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
return result;
|
|
35
|
+
});
|
|
5
36
|
const isInMemoryDataDir = (dataDir) => !dataDir || dataDir === 'memory://' || dataDir.startsWith('memory:');
|
|
6
37
|
/**
|
|
7
38
|
* Named-database mode is active when `driverOptions.dataDir` points at a real
|
|
@@ -63,30 +94,28 @@ export class PgliteConnection extends AbstractSqlConnection {
|
|
|
63
94
|
});
|
|
64
95
|
}
|
|
65
96
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
}
|
|
89
|
-
return new PGliteDialect({ pglite: () => this.#pglite, onCreateConnection });
|
|
97
|
+
// Hand kysely a delegating wrapper rather than mutating the underlying
|
|
98
|
+
// instance — proxies can't pierce PGlite's private fields, and patching
|
|
99
|
+
// `close` directly would orphan a user-supplied PGlite (its real `close`
|
|
100
|
+
// would stay neutered after `orm.close()`). Each method call hits the
|
|
101
|
+
// original `p`, so `#private` fields stay reachable.
|
|
102
|
+
const neuterClose = this.#neuterClose;
|
|
103
|
+
const pglitePromise = this.#pglite.then(p => ({
|
|
104
|
+
query: p.query.bind(p),
|
|
105
|
+
transaction: rejectAbortedCommit(p.transaction.bind(p)),
|
|
106
|
+
close: neuterClose ? () => Promise.resolve() : p.close.bind(p),
|
|
107
|
+
get closed() {
|
|
108
|
+
return p.closed;
|
|
109
|
+
},
|
|
110
|
+
get ready() {
|
|
111
|
+
return p.ready;
|
|
112
|
+
},
|
|
113
|
+
// `waitReady` is a stable Promise on the underlying instance — capture it
|
|
114
|
+
// directly so coverage doesn't hinge on `kysely` actually awaiting it (which
|
|
115
|
+
// only happens in the WASM-not-yet-loaded transient window).
|
|
116
|
+
waitReady: p.waitReady,
|
|
117
|
+
}));
|
|
118
|
+
return new PGliteDialect({ pglite: () => pglitePromise, onCreateConnection });
|
|
90
119
|
}
|
|
91
120
|
async close(force) {
|
|
92
121
|
await super.close(force);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mikro-orm/pglite",
|
|
3
|
-
"version": "7.2.6-dev.
|
|
3
|
+
"version": "7.2.6-dev.38",
|
|
4
4
|
"description": "TypeScript ORM for Node.js based on Data Mapper, Unit of Work and Identity Map patterns. Supports MongoDB, MySQL, PostgreSQL and SQLite databases as well as usage with vanilla JavaScript.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"data-mapper",
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
51
|
"@electric-sql/pglite": "0.5.13",
|
|
52
|
-
"@mikro-orm/sql": "7.2.6-dev.
|
|
52
|
+
"@mikro-orm/sql": "7.2.6-dev.38",
|
|
53
53
|
"kysely": "0.29.7",
|
|
54
54
|
"postgres-array": "3.0.4",
|
|
55
55
|
"postgres-date": "2.1.0",
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
"@mikro-orm/core": "^7.2.5"
|
|
60
60
|
},
|
|
61
61
|
"peerDependencies": {
|
|
62
|
-
"@mikro-orm/core": "7.2.6-dev.
|
|
62
|
+
"@mikro-orm/core": "7.2.6-dev.38"
|
|
63
63
|
},
|
|
64
64
|
"engines": {
|
|
65
65
|
"node": ">= 22.17.0"
|