@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.
@@ -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
- // 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
- } else {
33
- this.#pglite = PGlite.create({ ...pgliteOptions, dataDir, parsers });
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
- if (this.#neuterClose) {
37
- // Hand kysely a delegating wrapper rather than mutating the underlying
38
- // instance proxies can't pierce PGlite's private fields, and patching
39
- // `close` directly would orphan a user-supplied PGlite (its real `close`
40
- // would stay neutered after `orm.close()`). Each method call hits the
41
- // original `p`, so `#private` fields stay reachable.
42
- const sharedPglitePromise = this.#pglite.then(p => ({
43
- query: p.query.bind(p),
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
- return new PGliteDialect({ pglite: () => this.#pglite, onCreateConnection });
60
- }
61
- async close(force) {
62
- await super.close(force);
63
- // Persistent backings (file/IDB) we own get really closed by kysely — drop
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
- schemaHelper = new PgliteSchemaHelper(this);
9
- /** PGlite uses the extended query protocol — one statement per `query()` call. */
10
- supportsMultipleStatements() {
11
- return false;
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
- return value;
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
- /* v8 ignore next */
34
- if (typeof value === 'number') {
35
- return new Date(value);
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
- // @ts-ignore fix wrong type resolution during build
38
- const parsed = parseDate(value);
39
- /* v8 ignore next */
40
- if (parsed === null) {
41
- return value;
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
  }
@@ -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
- getManagementDbName() {
8
- return '';
9
- }
10
- getCreateDatabaseSQL() {
11
- return '';
12
- }
13
- getDropDatabaseSQL() {
14
- return '';
15
- }
16
- async databaseExists(_connection, _name) {
17
- return true;
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.32",
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.32",
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.32"
62
+ "@mikro-orm/core": "7.1.0-dev.34"
63
63
  },
64
64
  "engines": {
65
65
  "node": ">= 22.17.0"