@mikro-orm/libsql 7.2.0-dev.0 → 7.2.0-dev.10

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.
@@ -1,5 +1,5 @@
1
1
  import { BaseSqliteConnection, type Dictionary } from '@mikro-orm/sql';
2
- import { type Options } from 'libsql';
2
+ import Database, { type Options } from 'libsql';
3
3
  import type { Routine, Transaction } from '@mikro-orm/core';
4
4
  import { LibSqlDialect } from './LibSqlDialect.js';
5
5
  /** libSQL database connection supporting both local and remote databases. */
@@ -9,9 +9,16 @@ export declare class LibSqlConnection extends BaseSqliteConnection {
9
9
  skipOnConnect?: boolean;
10
10
  }): Promise<void>;
11
11
  createKyselyDialect(options: Dictionary & Options): LibSqlDialect;
12
+ /** Restores the state a recycled connection was replaced with, run on the raw handle to skip the held mutex. */
13
+ protected replayConnectionSetup(): Promise<void>;
12
14
  /** libsql's `Database.function()` is declared but throws "not implemented"; better-sqlite3 has the UDF bridge. */
13
15
  callRoutine<T>(routine: Routine, _args?: Record<string, unknown>, _ctx?: Transaction): Promise<T>;
14
16
  /** @inheritDoc */
15
17
  executeDump(source: string): Promise<void>;
18
+ /**
19
+ * Returns the `libsql` database backing this connection. Remote/replica connections are
20
+ * recycled, so re-read it rather than holding on to the returned handle.
21
+ */
22
+ getNativeClient(): Promise<Database.Database>;
16
23
  private validateAttachSupport;
17
24
  }
@@ -1,6 +1,7 @@
1
1
  import { BaseSqliteConnection } from '@mikro-orm/sql';
2
2
  import Database from 'libsql';
3
3
  import { LibSqlDialect } from './LibSqlDialect.js';
4
+ const REMOTE_URL = /^(https?|libsql):\/\//;
4
5
  /** libSQL database connection supporting both local and remote databases. */
5
6
  export class LibSqlConnection extends BaseSqliteConnection {
6
7
  database;
@@ -16,8 +17,16 @@ export class LibSqlConnection extends BaseSqliteConnection {
16
17
  return (this.database = new Database(dbName, options));
17
18
  },
18
19
  onCreateConnection: this.options.onCreateConnection ?? this.config.get('onCreateConnection'),
20
+ recycleConnection: !!options.syncUrl || REMOTE_URL.test(dbName),
21
+ onRecycleConnection: this.replayConnectionSetup.bind(this),
19
22
  });
20
23
  }
24
+ /** Restores the state a recycled connection was replaced with, run on the raw handle to skip the held mutex. */
25
+ async replayConnectionSetup() {
26
+ for (const sql of await this.getConnectionSetupSql()) {
27
+ this.database.exec(sql);
28
+ }
29
+ }
21
30
  /** libsql's `Database.function()` is declared but throws "not implemented"; better-sqlite3 has the UDF bridge. */
22
31
  async callRoutine(routine, _args = {}, _ctx) {
23
32
  throw new Error(`Stored routines are not supported on libSQL. The libsql client does not implement user-defined-function registration; calling routine ${routine.name} would fail at runtime. Use the better-sqlite3 driver for cross-DB testing, or call against a server-side database.`);
@@ -27,13 +36,21 @@ export class LibSqlConnection extends BaseSqliteConnection {
27
36
  await this.ensureConnection();
28
37
  this.database.exec(source);
29
38
  }
39
+ /**
40
+ * Returns the `libsql` database backing this connection. Remote/replica connections are
41
+ * recycled, so re-read it rather than holding on to the returned handle.
42
+ */
43
+ async getNativeClient() {
44
+ await this.ensureConnection();
45
+ return this.requireNativeClient(this.database);
46
+ }
30
47
  validateAttachSupport() {
31
48
  const attachDatabases = this.config.get('attachDatabases');
32
49
  if (!attachDatabases?.length) {
33
50
  return;
34
51
  }
35
52
  const dbName = this.config.get('dbName');
36
- if (/^(https?|libsql):\/\//.exec(dbName)) {
53
+ if (REMOTE_URL.test(dbName)) {
37
54
  throw new Error('ATTACH DATABASE is not supported for remote libSQL connections. ' + 'Use local file-based databases only.');
38
55
  }
39
56
  }
@@ -1,7 +1,18 @@
1
1
  import { SqliteDialect, type SqliteDialectConfig, SqliteDriver } from 'kysely';
2
+ /** Kysely SQLite dialect config extended with the connection recycling libSQL needs for embedded replicas. */
3
+ export interface LibSqlDialectConfig extends SqliteDialectConfig {
4
+ /**
5
+ * Recreates the underlying connection once it gets stale. Embedded replicas swap the local file out when
6
+ * syncing, so a long lived handle would keep serving the pre-sync data. A plain local database never goes
7
+ * stale, and recycling it would silently drop per-connection state like pragmas and attached databases.
8
+ */
9
+ recycleConnection?: boolean;
10
+ /** Re-applies the per-connection state after a stale connection was replaced. */
11
+ onRecycleConnection?: () => Promise<void>;
12
+ }
2
13
  /** Kysely dialect adapter for libSQL. */
3
14
  export declare class LibSqlDialect extends SqliteDialect {
4
15
  #private;
5
- constructor(config: SqliteDialectConfig);
16
+ constructor(config: LibSqlDialectConfig);
6
17
  createDriver(): SqliteDriver;
7
18
  }
package/LibSqlDialect.js CHANGED
@@ -25,7 +25,7 @@ class LibSqlConnection {
25
25
  this.#db = db;
26
26
  }
27
27
  isValid() {
28
- return this.memory || this.#created > Date.now() - CONNECTION_TIMEOUT;
28
+ return this.#created > Date.now() - CONNECTION_TIMEOUT;
29
29
  }
30
30
  async executeQuery(compiledQuery) {
31
31
  const { sql, parameters } = compiledQuery;
@@ -83,10 +83,10 @@ class LibSqlKyselyDriver extends SqliteDriver {
83
83
  }
84
84
  async acquireConnection() {
85
85
  await this.#connectionMutex.lock();
86
- /* v8 ignore next */
87
- if (!this.#connection.isValid()) {
86
+ if (this.#config.recycleConnection && !this.#connection.isValid()) {
88
87
  await this.destroy();
89
88
  await this.init();
89
+ await this.#config.onRecycleConnection?.();
90
90
  }
91
91
  return this.#connection;
92
92
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mikro-orm/libsql",
3
- "version": "7.2.0-dev.0",
3
+ "version": "7.2.0-dev.10",
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",
@@ -47,15 +47,15 @@
47
47
  "copy": "node ../../scripts/copy.mjs"
48
48
  },
49
49
  "dependencies": {
50
- "@mikro-orm/sql": "7.2.0-dev.0",
51
- "kysely": "0.29.3",
50
+ "@mikro-orm/sql": "7.2.0-dev.10",
51
+ "kysely": "0.29.5",
52
52
  "libsql": "0.5.29"
53
53
  },
54
54
  "devDependencies": {
55
- "@mikro-orm/core": "^7.1.6"
55
+ "@mikro-orm/core": "^7.1.11"
56
56
  },
57
57
  "peerDependencies": {
58
- "@mikro-orm/core": "7.2.0-dev.0"
58
+ "@mikro-orm/core": "7.2.0-dev.10"
59
59
  },
60
60
  "engines": {
61
61
  "node": ">= 22.17.0"