@mikro-orm/pglite 7.1.0-dev.32 → 7.1.0-dev.34
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 +67 -66
- package/PglitePlatform.js +33 -33
- package/PgliteSchemaHelper.js +12 -12
- package/package.json +3 -3
package/PgliteConnection.js
CHANGED
|
@@ -2,75 +2,76 @@ 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
|
-
const isInMemoryDataDir = dataDir => !dataDir || dataDir === 'memory://' || dataDir.startsWith('memory:');
|
|
5
|
+
const isInMemoryDataDir = (dataDir) => !dataDir || dataDir === 'memory://' || dataDir.startsWith('memory:');
|
|
6
6
|
/** PostgreSQL-in-WASM database connection using `@electric-sql/pglite`. */
|
|
7
7
|
export class PgliteConnection extends AbstractSqlConnection {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
8
|
+
// Stored as a Promise so `createKyselyDialect` can stay synchronous (else
|
|
9
|
+
// `getClient()` would throw "Current driver requires async initialization")
|
|
10
|
+
// while `executeDump` and the kysely dialect both `await` the same instance.
|
|
11
|
+
#pglite;
|
|
12
|
+
#neuterClose = false;
|
|
13
|
+
#ownsPglite = true;
|
|
14
|
+
createKyselyDialect(overrides) {
|
|
15
|
+
const onCreateConnection = this.options.onCreateConnection ?? this.config.get('onCreateConnection');
|
|
16
|
+
const options = (overrides ?? {});
|
|
17
|
+
const { pglite: userPglite, ...pgliteOptions } = options;
|
|
18
|
+
const dataDir = options.dataDir ?? this.config.get('dbName');
|
|
19
|
+
const parsers = { ...createPostgreSqlTypeParsers(s => array.parse(s)), ...options.parsers };
|
|
20
|
+
this.#ownsPglite = !userPglite;
|
|
21
|
+
// Skip `pglite.close()` (called by kysely's `PGliteDriver.destroy()`) when:
|
|
22
|
+
// - the user owns the instance (closing it is their responsibility), or
|
|
23
|
+
// - we hold an in-memory DB whose data would otherwise be lost on
|
|
24
|
+
// reconnect (e.g. test harnesses that drive `orm.close()` + `orm.connect()`).
|
|
25
|
+
// For file/IDB-backed instances we let kysely close so file handles / IDB
|
|
26
|
+
// connections are released; we drop our cached promise in `close()` below
|
|
27
|
+
// so the next dialect-construction rebuilds the PGlite instance.
|
|
28
|
+
this.#neuterClose = !this.#ownsPglite || isInMemoryDataDir(dataDir);
|
|
29
|
+
if (!this.#pglite) {
|
|
30
|
+
if (userPglite) {
|
|
31
|
+
this.#pglite = typeof userPglite === 'function' ? Promise.resolve(userPglite()) : Promise.resolve(userPglite);
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
this.#pglite = PGlite.create({ ...pgliteOptions, dataDir, parsers });
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
if (this.#neuterClose) {
|
|
38
|
+
// Hand kysely a delegating wrapper rather than mutating the underlying
|
|
39
|
+
// instance — proxies can't pierce PGlite's private fields, and patching
|
|
40
|
+
// `close` directly would orphan a user-supplied PGlite (its real `close`
|
|
41
|
+
// would stay neutered after `orm.close()`). Each method call hits the
|
|
42
|
+
// original `p`, so `#private` fields stay reachable.
|
|
43
|
+
const sharedPglitePromise = this.#pglite.then(p => ({
|
|
44
|
+
query: p.query.bind(p),
|
|
45
|
+
transaction: p.transaction.bind(p),
|
|
46
|
+
close: () => Promise.resolve(),
|
|
47
|
+
get closed() {
|
|
48
|
+
return p.closed;
|
|
49
|
+
},
|
|
50
|
+
get ready() {
|
|
51
|
+
return p.ready;
|
|
52
|
+
},
|
|
53
|
+
// `waitReady` is a stable Promise on the underlying instance — capture it
|
|
54
|
+
// directly so coverage doesn't hinge on `kysely` actually awaiting it (which
|
|
55
|
+
// only happens in the WASM-not-yet-loaded transient window).
|
|
56
|
+
waitReady: p.waitReady,
|
|
57
|
+
}));
|
|
58
|
+
return new PGliteDialect({ pglite: () => sharedPglitePromise, onCreateConnection });
|
|
59
|
+
}
|
|
60
|
+
return new PGliteDialect({ pglite: () => this.#pglite, onCreateConnection });
|
|
35
61
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
transaction: p.transaction.bind(p),
|
|
45
|
-
close: () => Promise.resolve(),
|
|
46
|
-
get closed() {
|
|
47
|
-
return p.closed;
|
|
48
|
-
},
|
|
49
|
-
get ready() {
|
|
50
|
-
return p.ready;
|
|
51
|
-
},
|
|
52
|
-
// `waitReady` is a stable Promise on the underlying instance — capture it
|
|
53
|
-
// directly so coverage doesn't hinge on `kysely` actually awaiting it (which
|
|
54
|
-
// only happens in the WASM-not-yet-loaded transient window).
|
|
55
|
-
waitReady: p.waitReady,
|
|
56
|
-
}));
|
|
57
|
-
return new PGliteDialect({ pglite: () => sharedPglitePromise, onCreateConnection });
|
|
62
|
+
async close(force) {
|
|
63
|
+
await super.close(force);
|
|
64
|
+
// Persistent backings (file/IDB) we own get really closed by kysely — drop
|
|
65
|
+
// the cached promise so a subsequent reconnect rebuilds a fresh instance
|
|
66
|
+
// (which then re-reads the persisted data from disk / IDB).
|
|
67
|
+
if (this.#ownsPglite && !this.#neuterClose) {
|
|
68
|
+
this.#pglite = undefined;
|
|
69
|
+
}
|
|
58
70
|
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
// the cached promise so a subsequent reconnect rebuilds a fresh instance
|
|
65
|
-
// (which then re-reads the persisted data from disk / IDB).
|
|
66
|
-
if (this.#ownsPglite && !this.#neuterClose) {
|
|
67
|
-
this.#pglite = undefined;
|
|
71
|
+
/** PGlite supports multi-statement scripts via `exec()`, which is what schema dumps need. */
|
|
72
|
+
async executeDump(source) {
|
|
73
|
+
await this.ensureConnection();
|
|
74
|
+
const pglite = await this.#pglite;
|
|
75
|
+
await pglite.exec(source);
|
|
68
76
|
}
|
|
69
|
-
}
|
|
70
|
-
/** PGlite supports multi-statement scripts via `exec()`, which is what schema dumps need. */
|
|
71
|
-
async executeDump(source) {
|
|
72
|
-
await this.ensureConnection();
|
|
73
|
-
const pglite = await this.#pglite;
|
|
74
|
-
await pglite.exec(source);
|
|
75
|
-
}
|
|
76
77
|
}
|
package/PglitePlatform.js
CHANGED
|
@@ -5,41 +5,41 @@ import { BasePostgreSqlPlatform, Utils } from '@mikro-orm/sql';
|
|
|
5
5
|
import { PgliteSchemaHelper } from './PgliteSchemaHelper.js';
|
|
6
6
|
/** Platform implementation for PGlite (PostgreSQL in WASM, single-database). */
|
|
7
7
|
export class PglitePlatform extends BasePostgreSqlPlatform {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
13
|
-
convertIntervalToJSValue(value) {
|
|
14
|
-
return PostgresInterval(value);
|
|
15
|
-
}
|
|
16
|
-
convertIntervalToDatabaseValue(value) {
|
|
17
|
-
if (Utils.isObject(value) && 'toPostgres' in value && typeof value.toPostgres === 'function') {
|
|
18
|
-
return value.toPostgres();
|
|
8
|
+
schemaHelper = new PgliteSchemaHelper(this);
|
|
9
|
+
/** PGlite uses the extended query protocol — one statement per `query()` call. */
|
|
10
|
+
supportsMultipleStatements() {
|
|
11
|
+
return false;
|
|
19
12
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
unmarshallArray(value) {
|
|
23
|
-
return array.parse(value);
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* @inheritDoc
|
|
27
|
-
*/
|
|
28
|
-
parseDate(value) {
|
|
29
|
-
// postgres-date returns `null` for a JS ISO string which has the `T` separator
|
|
30
|
-
if (typeof value === 'string' && value.charAt(10) === 'T') {
|
|
31
|
-
return new Date(value);
|
|
13
|
+
convertIntervalToJSValue(value) {
|
|
14
|
+
return PostgresInterval(value);
|
|
32
15
|
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
16
|
+
convertIntervalToDatabaseValue(value) {
|
|
17
|
+
if (Utils.isObject(value) && 'toPostgres' in value && typeof value.toPostgres === 'function') {
|
|
18
|
+
return value.toPostgres();
|
|
19
|
+
}
|
|
20
|
+
return value;
|
|
36
21
|
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
22
|
+
unmarshallArray(value) {
|
|
23
|
+
return array.parse(value);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* @inheritDoc
|
|
27
|
+
*/
|
|
28
|
+
parseDate(value) {
|
|
29
|
+
// postgres-date returns `null` for a JS ISO string which has the `T` separator
|
|
30
|
+
if (typeof value === 'string' && value.charAt(10) === 'T') {
|
|
31
|
+
return new Date(value);
|
|
32
|
+
}
|
|
33
|
+
/* v8 ignore next */
|
|
34
|
+
if (typeof value === 'number') {
|
|
35
|
+
return new Date(value);
|
|
36
|
+
}
|
|
37
|
+
// @ts-ignore fix wrong type resolution during build
|
|
38
|
+
const parsed = parseDate(value);
|
|
39
|
+
/* v8 ignore next */
|
|
40
|
+
if (parsed === null) {
|
|
41
|
+
return value;
|
|
42
|
+
}
|
|
43
|
+
return parsed;
|
|
42
44
|
}
|
|
43
|
-
return parsed;
|
|
44
|
-
}
|
|
45
45
|
}
|
package/PgliteSchemaHelper.js
CHANGED
|
@@ -4,16 +4,16 @@ import { PostgreSqlSchemaHelper } from '@mikro-orm/sql';
|
|
|
4
4
|
* `CREATE DATABASE`. Override the relevant lifecycle hooks to no-ops.
|
|
5
5
|
*/
|
|
6
6
|
export class PgliteSchemaHelper extends PostgreSqlSchemaHelper {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
7
|
+
getManagementDbName() {
|
|
8
|
+
return '';
|
|
9
|
+
}
|
|
10
|
+
getCreateDatabaseSQL() {
|
|
11
|
+
return '';
|
|
12
|
+
}
|
|
13
|
+
getDropDatabaseSQL() {
|
|
14
|
+
return '';
|
|
15
|
+
}
|
|
16
|
+
async databaseExists(_connection, _name) {
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
19
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mikro-orm/pglite",
|
|
3
|
-
"version": "7.1.0-dev.
|
|
3
|
+
"version": "7.1.0-dev.34",
|
|
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.4.4",
|
|
52
|
-
"@mikro-orm/sql": "7.1.0-dev.
|
|
52
|
+
"@mikro-orm/sql": "7.1.0-dev.34",
|
|
53
53
|
"kysely": "0.29.0",
|
|
54
54
|
"postgres-array": "3.0.4",
|
|
55
55
|
"postgres-date": "2.1.0",
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
"@mikro-orm/core": "^7.0.15"
|
|
60
60
|
},
|
|
61
61
|
"peerDependencies": {
|
|
62
|
-
"@mikro-orm/core": "7.1.0-dev.
|
|
62
|
+
"@mikro-orm/core": "7.1.0-dev.34"
|
|
63
63
|
},
|
|
64
64
|
"engines": {
|
|
65
65
|
"node": ">= 22.17.0"
|