@delali/sirannon-db 0.2.3-next.29 → 0.2.3-next.30

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.
Files changed (32) hide show
  1. package/dist/backup-scheduler/index.d.ts +1 -1
  2. package/dist/{change-tracker-C2Z8UbI0.d.ts → change-tracker-rTXrPhQq.d.ts} +1 -1
  3. package/dist/{chunk-UPKKSUPA.mjs → chunk-BD3XGHFC.mjs} +24 -4
  4. package/dist/{chunk-DVWQD3GF.mjs → chunk-GVYLZVUZ.mjs} +10 -1
  5. package/dist/client/index.d.ts +6 -6
  6. package/dist/client/topology.d.ts +4 -4
  7. package/dist/{client-base-CqTMYzQP.d.ts → client-base-DkjHphzB.d.ts} +2 -2
  8. package/dist/core/index.d.ts +10 -8
  9. package/dist/core/index.mjs +134 -28
  10. package/dist/core/writer-worker.mjs +11 -0
  11. package/dist/{database-DvSvONb-.d.ts → database-DvURlr-n.d.ts} +2 -2
  12. package/dist/driver/better-sqlite3.d.ts +1 -1
  13. package/dist/driver/better-sqlite3.mjs +4 -1
  14. package/dist/driver/bun.d.ts +1 -1
  15. package/dist/driver/bun.mjs +16 -1
  16. package/dist/driver/expo.d.ts +1 -1
  17. package/dist/driver/expo.mjs +7 -1
  18. package/dist/driver/node.d.ts +1 -1
  19. package/dist/driver/node.mjs +20 -3
  20. package/dist/driver/wa-sqlite.d.ts +1 -1
  21. package/dist/driver/wa-sqlite.mjs +15 -0
  22. package/dist/file-migrations/index.d.ts +1 -1
  23. package/dist/{protocol-CEBVo1tO.d.ts → protocol-BQMNEubg.d.ts} +1 -1
  24. package/dist/replication/index.d.ts +6 -6
  25. package/dist/server/index.d.ts +6 -6
  26. package/dist/{server-options-BVAFmguz.d.ts → server-options-Bc6WuuFf.d.ts} +1 -1
  27. package/dist/{sirannon-DVYfrNiq.d.ts → sirannon-Bs0WBW1o.d.ts} +2 -2
  28. package/dist/transport/grpc.d.ts +3 -3
  29. package/dist/transport/memory.d.ts +3 -3
  30. package/dist/{types-DxoEm08T.d.ts → types-BgVF0xhd.d.ts} +2 -2
  31. package/dist/{types-CXoPBeDM.d.ts → types-OGVLZjPS.d.ts} +9 -0
  32. package/package.json +1 -1
@@ -1,4 +1,4 @@
1
- import { e as SQLiteConnection, f as BackupScheduleOptions } from '../types-CXoPBeDM.js';
1
+ import { e as SQLiteConnection, f as BackupScheduleOptions } from '../types-OGVLZjPS.js';
2
2
  import '../query-types-BvkzxKQv.js';
3
3
 
4
4
  declare class BackupManager {
@@ -1,4 +1,4 @@
1
- import { e as SQLiteConnection } from './types-CXoPBeDM.js';
1
+ import { e as SQLiteConnection } from './types-OGVLZjPS.js';
2
2
  import { C as ChangeEvent } from './query-types-BvkzxKQv.js';
3
3
 
4
4
  /**
@@ -1,12 +1,22 @@
1
1
  import { BackupManager, BackupScheduler } from './chunk-VOYGMAU7.mjs';
2
2
  import { WORKER_CANCELLED_CODE, deserializeError } from './chunk-4ISB7XMA.mjs';
3
- import { SirannonError } from './chunk-PBRXXISQ.mjs';
3
+ import { SirannonError, ExtensionError } from './chunk-PBRXXISQ.mjs';
4
4
  import { Worker } from 'worker_threads';
5
5
  import { existsSync } from 'fs';
6
6
  import { resolve, dirname, join, sep } from 'path';
7
7
  import { fileURLToPath, pathToFileURL } from 'url';
8
8
  import { AsyncLocalStorage } from 'async_hooks';
9
9
 
10
+ // src/core/driver/extension.ts
11
+ async function loadThroughRuntime(extensionPath, load) {
12
+ try {
13
+ load();
14
+ } catch (err) {
15
+ if (err instanceof SirannonError) throw err;
16
+ throw new ExtensionError(extensionPath, err instanceof Error ? err.message : String(err));
17
+ }
18
+ }
19
+
10
20
  // src/core/driver/statement-cache.ts
11
21
  var STATEMENT_CACHE_CAPACITY = 128;
12
22
  function createStatementCache(prepare) {
@@ -102,6 +112,7 @@ var WriterWorker = class _WriterWorker {
102
112
  closed = false;
103
113
  fatal = null;
104
114
  restarts = 0;
115
+ loadedExtensions = [];
105
116
  connection;
106
117
  static async start(entry, path, options, workerOptions) {
107
118
  const worker = new _WriterWorker(
@@ -134,10 +145,15 @@ var WriterWorker = class _WriterWorker {
134
145
  this.fault(new SirannonError(`Writer worker exited with code ${code}`, "WRITER_WORKER_EXIT"));
135
146
  }
136
147
  });
137
- this.ready = this.send(this.openRequest).then(() => void 0);
148
+ this.ready = this.send(this.openRequest).then(() => this.reloadExtensionsOntoRestartedConnection());
138
149
  this.ready.catch(() => {
139
150
  });
140
151
  }
152
+ async reloadExtensionsOntoRestartedConnection() {
153
+ for (const path of this.loadedExtensions) {
154
+ await this.send({ kind: "loadExtension", path });
155
+ }
156
+ }
141
157
  onResponse(res) {
142
158
  const entry = this.pending.get(res.id);
143
159
  if (!entry) return;
@@ -241,7 +257,7 @@ var WriterWorker = class _WriterWorker {
241
257
  timer = setTimeout(() => this.onDeadline(id), this.timeoutMs);
242
258
  timer.unref?.();
243
259
  }
244
- const cancellable = request.kind !== "open" && request.kind !== "close";
260
+ const cancellable = request.kind !== "open" && request.kind !== "close" && request.kind !== "loadExtension";
245
261
  this.pending.set(id, { resolve: resolve2, reject, timer, graceTimer: null, cancellable });
246
262
  try {
247
263
  worker.postMessage(message);
@@ -286,6 +302,10 @@ var WriterWorker = class _WriterWorker {
286
302
  }))
287
303
  }))
288
304
  }),
305
+ loadExtension: async (extensionPath) => {
306
+ await this.request({ kind: "loadExtension", path: extensionPath });
307
+ if (!this.loadedExtensions.includes(extensionPath)) this.loadedExtensions.push(extensionPath);
308
+ },
289
309
  transaction: async (fn) => {
290
310
  await conn.exec("BEGIN");
291
311
  try {
@@ -354,4 +374,4 @@ function nodeBackupEngine() {
354
374
  };
355
375
  }
356
376
 
357
- export { WriterWorker, createStatementCache, narrowRowIntegers, narrowRowsIntegers, narrowSafeBigInt, nodeBackupEngine, nodeResolveExtensionPath, nodeWriterContext };
377
+ export { WriterWorker, createStatementCache, loadThroughRuntime, narrowRowIntegers, narrowRowsIntegers, narrowSafeBigInt, nodeBackupEngine, nodeResolveExtensionPath, nodeWriterContext };
@@ -6,6 +6,15 @@ var SirannonError = class extends Error {
6
6
  this.name = "SirannonError";
7
7
  }
8
8
  };
9
+ var ExtensionError = class extends SirannonError {
10
+ constructor(path, cause) {
11
+ super(
12
+ cause ? `Failed to load extension '${path}': ${cause}` : `Failed to load extension '${path}'`,
13
+ "EXTENSION_ERROR"
14
+ );
15
+ this.name = "ExtensionError";
16
+ }
17
+ };
9
18
 
10
19
  // src/core/driver/define.ts
11
20
  function defineDriver(config) {
@@ -46,4 +55,4 @@ function synchronousPragmaValue(level) {
46
55
  return value;
47
56
  }
48
57
 
49
- export { defineDriver, synchronousPragmaValue };
58
+ export { ExtensionError, SirannonError, defineDriver, synchronousPragmaValue };
@@ -1,15 +1,15 @@
1
1
  export { F as FieldMergeResolver, L as LWWResolver, P as PrimaryWinsResolver } from '../primary-wins-B0np8JS3.js';
2
2
  import { C as ConflictResolver, R as ReplicationBatch } from '../types-CjhxcjhA.js';
3
3
  export { a as ConflictContext, b as ConflictResolution } from '../types-CjhxcjhA.js';
4
- import { C as ClientOptions, B as BulkLoadDurability } from '../server-options-BVAFmguz.js';
5
- import { D as DatabaseClient, T as Transport, L as LiveHandlers, R as RemoteSubscription, a as RemoteSubscriptionBuilder, S as SubscribeOptions, b as RegistryDigestSource } from '../client-base-CqTMYzQP.js';
6
- export { c as LoadAllOptions, d as RemoteDatabase, e as RemoteError, f as SQL_REFUSED_MESSAGE, g as ServerCapabilities, h as ServerCapabilityCheck } from '../client-base-CqTMYzQP.js';
4
+ import { C as ClientOptions, B as BulkLoadDurability } from '../server-options-Bc6WuuFf.js';
5
+ import { D as DatabaseClient, T as Transport, L as LiveHandlers, R as RemoteSubscription, a as RemoteSubscriptionBuilder, S as SubscribeOptions, b as RegistryDigestSource } from '../client-base-DkjHphzB.js';
6
+ export { c as LoadAllOptions, d as RemoteDatabase, e as RemoteError, f as SQL_REFUSED_MESSAGE, g as ServerCapabilities, h as ServerCapabilityCheck } from '../client-base-DkjHphzB.js';
7
7
  import { a as LiveQuery, b as LiveQueryState, c as LiveUpdate } from '../types-BCejqzNA.js';
8
- import { e as DeviceSyncPort, D as Database } from '../database-DvSvONb-.js';
8
+ import { e as DeviceSyncPort, D as Database } from '../database-DvURlr-n.js';
9
9
  import { C as ChangeEvent, P as Params, R as ReadConcern, W as WriteConcern } from '../query-types-BvkzxKQv.js';
10
- import { Q as QueryResponse, E as ExecuteResponse, a as TransactionResponse, B as BatchResponse, L as LoadResponse, A as AckResponse } from '../protocol-CEBVo1tO.js';
10
+ import { Q as QueryResponse, E as ExecuteResponse, a as TransactionResponse, B as BatchResponse, L as LoadResponse, A as AckResponse } from '../protocol-BQMNEubg.js';
11
11
  import '../operation-registry-6qErmUT2.js';
12
- import '../types-CXoPBeDM.js';
12
+ import '../types-OGVLZjPS.js';
13
13
 
14
14
  /**
15
15
  * @public
@@ -1,11 +1,11 @@
1
1
  import { a as ReadConcernLevel } from '../query-types-BvkzxKQv.js';
2
- import { C as ClientOptions } from '../server-options-BVAFmguz.js';
3
- import { T as Transport, D as DatabaseClient } from '../client-base-CqTMYzQP.js';
2
+ import { C as ClientOptions } from '../server-options-Bc6WuuFf.js';
3
+ import { T as Transport, D as DatabaseClient } from '../client-base-DkjHphzB.js';
4
4
  import '../operation-registry-6qErmUT2.js';
5
5
  import '../types-CjhxcjhA.js';
6
- import '../types-CXoPBeDM.js';
6
+ import '../types-OGVLZjPS.js';
7
7
  import '../types-BCejqzNA.js';
8
- import '../protocol-CEBVo1tO.js';
8
+ import '../protocol-BQMNEubg.js';
9
9
 
10
10
  interface TopologyRouting {
11
11
  _getReadEndpoint(databaseId?: string, readConcern?: ReadConcernLevel): Promise<string>;
@@ -1,8 +1,8 @@
1
- import { B as BulkLoadDurability, a as BulkLoadResult, C as ClientOptions } from './server-options-BVAFmguz.js';
1
+ import { B as BulkLoadDurability, a as BulkLoadResult, C as ClientOptions } from './server-options-Bc6WuuFf.js';
2
2
  import { R as ResultOp, a as LiveQuery } from './types-BCejqzNA.js';
3
3
  import { O as OperationRef, b as OperationArguments } from './operation-registry-6qErmUT2.js';
4
4
  import { P as Params, R as ReadConcern, W as WriteConcern, C as ChangeEvent, Q as QueryOptions } from './query-types-BvkzxKQv.js';
5
- import { Q as QueryResponse, E as ExecuteResponse, a as TransactionResponse, B as BatchResponse, L as LoadResponse } from './protocol-CEBVo1tO.js';
5
+ import { Q as QueryResponse, E as ExecuteResponse, a as TransactionResponse, B as BatchResponse, L as LoadResponse } from './protocol-BQMNEubg.js';
6
6
 
7
7
  /**
8
8
  * Message a client raises when the server accepts no SQL over the network.
@@ -1,16 +1,16 @@
1
- import { e as SQLiteConnection, n as SynchronousLevel, a as SQLiteDriver, W as WorkerHostOptions, D as DatabaseOptions, L as LifecycleConfig, M as Migration, m as MigrationResult, R as RollbackResult } from '../types-CXoPBeDM.js';
2
- export { A as AfterQueryHook, o as AppliedMigration, p as AppliedMigrationEntry, f as BackupScheduleOptions, q as BatchSummary, b as BeforeConnectHook, B as BeforeQueryHook, h as BeforeSubscribeHook, l as CDCMetrics, r as ClusterReadEndpointInfo, C as ClusterStatusInfo, g as ConnectionHookContext, k as ConnectionMetrics, d as DatabaseCloseHook, c as DatabaseOpenHook, s as DriverCapabilities, t as DriverWorkerEntry, H as HookConfig, u as MIGRATION_NAME_RE, i as MetricsConfig, v as MigrationBaseline, w as MigrationSource, N as NodeHealth, x as NodeHealthReason, y as NodeHealthState, O as OpenOptions, Q as QueryHookContext, j as QueryMetrics, z as RunResult, E as SQLiteStatement, S as SirannonOptions, T as Transaction, F as WriterWorkerOptions } from '../types-CXoPBeDM.js';
3
- import { B as BulkLoadDurability, a as BulkLoadResult } from '../server-options-BVAFmguz.js';
4
- export { c as AuthenticateHook, b as BulkLoadOptions, C as ClientOptions, d as ClusterStatusAuthorizer, e as CorsOptions, R as ReplicationStatusInfo, f as RequestContext, g as ServerExecutionTarget, h as ServerExecutionTargetResolver, S as ServerOptions, W as WSHandlerOptions } from '../server-options-BVAFmguz.js';
5
- export { C as ChangeTracker, a as ChangeTrackerOptions } from '../change-tracker-C2Z8UbI0.js';
6
- import { D as Database } from '../database-DvSvONb-.js';
7
- export { H as HookDispose, a as HookEvent, b as HookEventContextMap, c as HookHandler, d as HookRegistry, M as MetricsCollector, S as SubscribeHookContext } from '../database-DvSvONb-.js';
1
+ import { e as SQLiteConnection, n as SynchronousLevel, a as SQLiteDriver, W as WorkerHostOptions, D as DatabaseOptions, L as LifecycleConfig, M as Migration, m as MigrationResult, R as RollbackResult } from '../types-OGVLZjPS.js';
2
+ export { A as AfterQueryHook, o as AppliedMigration, p as AppliedMigrationEntry, f as BackupScheduleOptions, q as BatchSummary, b as BeforeConnectHook, B as BeforeQueryHook, h as BeforeSubscribeHook, l as CDCMetrics, r as ClusterReadEndpointInfo, C as ClusterStatusInfo, g as ConnectionHookContext, k as ConnectionMetrics, d as DatabaseCloseHook, c as DatabaseOpenHook, s as DriverCapabilities, t as DriverWorkerEntry, H as HookConfig, u as MIGRATION_NAME_RE, i as MetricsConfig, v as MigrationBaseline, w as MigrationSource, N as NodeHealth, x as NodeHealthReason, y as NodeHealthState, O as OpenOptions, Q as QueryHookContext, j as QueryMetrics, z as RunResult, E as SQLiteStatement, S as SirannonOptions, T as Transaction, F as WriterWorkerOptions } from '../types-OGVLZjPS.js';
3
+ import { B as BulkLoadDurability, a as BulkLoadResult } from '../server-options-Bc6WuuFf.js';
4
+ export { c as AuthenticateHook, b as BulkLoadOptions, C as ClientOptions, d as ClusterStatusAuthorizer, e as CorsOptions, R as ReplicationStatusInfo, f as RequestContext, g as ServerExecutionTarget, h as ServerExecutionTargetResolver, S as ServerOptions, W as WSHandlerOptions } from '../server-options-Bc6WuuFf.js';
5
+ export { C as ChangeTracker, a as ChangeTrackerOptions } from '../change-tracker-rTXrPhQq.js';
6
+ import { D as Database } from '../database-DvURlr-n.js';
7
+ export { H as HookDispose, a as HookEvent, b as HookEventContextMap, c as HookHandler, d as HookRegistry, M as MetricsCollector, S as SubscribeHookContext } from '../database-DvURlr-n.js';
8
8
  export { B as BackupError, C as CDCError, a as ConnectionPoolError, D as DatabaseAlreadyExistsError, b as DatabaseNotFoundError, E as ExtensionError, F as ForbiddenSqlError, H as HookDeniedError, M as MaxDatabasesError, c as MigrationError, Q as QueryError, R as ReadOnlyError, d as RequestDeniedError, S as SirannonError, T as TransactionError, W as WriteOverloadError } from '../errors-Dei4GdBb.js';
9
9
  export { a as LiveQuery, L as LiveQueryOptions, b as LiveQueryState, c as LiveUpdate, R as ResultOp } from '../types-BCejqzNA.js';
10
10
  import { B as BaselineFileOption } from '../baseline-D93hcIEE.js';
11
11
  import { P as Params, E as ExecuteResult } from '../query-types-BvkzxKQv.js';
12
12
  export { C as ChangeEvent, b as ChangeOperation, Q as QueryOptions, R as ReadConcern, a as ReadConcernLevel, c as Subscription, S as SubscriptionBuilder, W as WriteConcern, d as WriteConcernLevel } from '../query-types-BvkzxKQv.js';
13
- export { S as Sirannon } from '../sirannon-DVYfrNiq.js';
13
+ export { S as Sirannon } from '../sirannon-Bs0WBW1o.js';
14
14
  export { D as DatabaseOperations, b as OperationArguments, O as OperationRef, a as OperationRegistry, c as OperationStatement, R as ReadOperation, W as WriteOperation, o as operationName, d as operationRef } from '../operation-registry-6qErmUT2.js';
15
15
  import '../types-CjhxcjhA.js';
16
16
 
@@ -99,6 +99,8 @@ declare class ConnectionPool {
99
99
  static create(options: ConnectionPoolOptions): Promise<ConnectionPool>;
100
100
  acquireReader(): SQLiteConnection;
101
101
  acquireWriter(): SQLiteConnection;
102
+ /** Returns the writer and every reader, for an operation that must apply to the whole pool. */
103
+ connections(): readonly SQLiteConnection[];
102
104
  get readerCount(): number;
103
105
  get isReadOnly(): boolean;
104
106
  close(): Promise<void>;
@@ -89,6 +89,13 @@ var ConnectionPool = class _ConnectionPool {
89
89
  }
90
90
  return this.writer;
91
91
  }
92
+ /** Returns the writer and every reader, for an operation that must apply to the whole pool. */
93
+ connections() {
94
+ if (this.closed) {
95
+ throw new ConnectionPoolError("Connection pool is closed");
96
+ }
97
+ return this.writer ? [this.writer, ...this.readers] : [...this.readers];
98
+ }
92
99
  get readerCount() {
93
100
  return this.readers.length;
94
101
  }
@@ -1517,32 +1524,6 @@ var DatabaseWriteController = class {
1517
1524
  }
1518
1525
  };
1519
1526
 
1520
- // src/core/extension-loader.ts
1521
- async function loadExtension(driver, writer, extensionPath) {
1522
- if (!driver.capabilities.extensions || !driver.resolveExtensionPath) {
1523
- throw new ExtensionError(extensionPath, "Extensions are not supported by the current driver");
1524
- }
1525
- if (!extensionPath || extensionPath.includes("\0")) {
1526
- throw new ExtensionError(extensionPath || "", "Extension path is empty or contains null bytes");
1527
- }
1528
- for (let i = 0; i < extensionPath.length; i++) {
1529
- if (extensionPath.charCodeAt(i) <= 31) {
1530
- throw new ExtensionError(extensionPath, "Extension path contains control characters");
1531
- }
1532
- }
1533
- const segments = extensionPath.split(/[/\\]/);
1534
- if (segments.includes("..")) {
1535
- throw new ExtensionError(extensionPath, "Extension path must not contain directory traversal segments");
1536
- }
1537
- const resolved = driver.resolveExtensionPath(extensionPath);
1538
- try {
1539
- const escaped = resolved.replace(/'/g, "''");
1540
- await writer.exec(`SELECT load_extension('${escaped}')`);
1541
- } catch (err) {
1542
- throw new ExtensionError(extensionPath, err instanceof Error ? err.message : String(err));
1543
- }
1544
- }
1545
-
1546
1527
  // src/core/hooks/registry.ts
1547
1528
  var HOOK_CONFIG_MAP = {
1548
1529
  onBeforeQuery: "beforeQuery",
@@ -1625,6 +1606,129 @@ var HookRegistry = class {
1625
1606
  }
1626
1607
  };
1627
1608
 
1609
+ // src/core/extension-loader.ts
1610
+ function assertPathIsSafe(extensionPath) {
1611
+ if (!extensionPath || extensionPath.includes("\0")) {
1612
+ throw new ExtensionError(extensionPath || "", "Extension path is empty or contains null bytes");
1613
+ }
1614
+ for (let i = 0; i < extensionPath.length; i++) {
1615
+ if (extensionPath.charCodeAt(i) <= 31) {
1616
+ throw new ExtensionError(extensionPath, "Extension path contains control characters");
1617
+ }
1618
+ }
1619
+ const segments = extensionPath.split(/[/\\]/);
1620
+ if (segments.includes("..")) {
1621
+ throw new ExtensionError(extensionPath, "Extension path must not contain directory traversal segments");
1622
+ }
1623
+ }
1624
+ function isAbsolutePath(candidate) {
1625
+ return candidate.startsWith("/") || candidate.startsWith("\\") || /^[A-Za-z]:[/\\]/.test(candidate);
1626
+ }
1627
+ async function loadExtension(driver, connections, extensionPath) {
1628
+ assertPathIsSafe(extensionPath);
1629
+ if (connections.some((connection) => connection.loadExtension === void 0)) {
1630
+ throw new ExtensionError(
1631
+ extensionPath,
1632
+ driver.capabilities.extensions ? "The current driver declares extension support but opens connections with no loading call" : "Extensions are not supported by the current driver"
1633
+ );
1634
+ }
1635
+ if (driver.capabilities.extensions && !driver.resolveExtensionPath) {
1636
+ throw new ExtensionError(
1637
+ extensionPath,
1638
+ "The current driver declares extension support but resolves no absolute path, which would let the dynamic linker search its own paths"
1639
+ );
1640
+ }
1641
+ const resolved = driver.resolveExtensionPath?.(extensionPath) ?? extensionPath;
1642
+ if (driver.resolveExtensionPath && !isAbsolutePath(resolved)) {
1643
+ throw new ExtensionError(
1644
+ extensionPath,
1645
+ "The current driver resolved the extension to a relative path, which would let the dynamic linker search its own paths"
1646
+ );
1647
+ }
1648
+ for (const connection of connections) {
1649
+ try {
1650
+ await connection.loadExtension?.(resolved);
1651
+ } catch (err) {
1652
+ if (err instanceof SirannonError) throw err;
1653
+ throw new ExtensionError(extensionPath, err instanceof Error ? err.message : String(err));
1654
+ }
1655
+ }
1656
+ return resolved;
1657
+ }
1658
+
1659
+ // src/core/loaded-extensions.ts
1660
+ function forwardingConnection(connection, onClose) {
1661
+ const { loadExtension: loadExtension2, runBatch, runBatchSummary, runGroup } = connection;
1662
+ const forwarding = {
1663
+ exec: (sql) => connection.exec(sql),
1664
+ prepare: (sql) => connection.prepare(sql),
1665
+ transaction: (fn) => connection.transaction(fn),
1666
+ close: async () => {
1667
+ onClose();
1668
+ await connection.close();
1669
+ }
1670
+ };
1671
+ if (loadExtension2) forwarding.loadExtension = (path) => loadExtension2.call(connection, path);
1672
+ if (runBatch) forwarding.runBatch = (sql, paramsBatch) => runBatch.call(connection, sql, paramsBatch);
1673
+ if (runBatchSummary) {
1674
+ forwarding.runBatchSummary = (sql, paramsBatch) => runBatchSummary.call(connection, sql, paramsBatch);
1675
+ }
1676
+ if (runGroup) forwarding.runGroup = (units) => runGroup.call(connection, units);
1677
+ return forwarding;
1678
+ }
1679
+ var LoadedExtensions = class {
1680
+ constructor(driver) {
1681
+ this.driver = driver;
1682
+ }
1683
+ resolvedPaths = [];
1684
+ openedConnections = /* @__PURE__ */ new Set();
1685
+ queue = Promise.resolve();
1686
+ runInTurn(operation) {
1687
+ const result = this.queue.then(operation, operation);
1688
+ this.queue = result.catch(() => void 0);
1689
+ return result;
1690
+ }
1691
+ async loadRecorded(connection) {
1692
+ for (const resolvedPath of this.resolvedPaths) {
1693
+ if (!connection.loadExtension) {
1694
+ throw new ExtensionError(resolvedPath, "The current driver opened a connection with no extension loading call");
1695
+ }
1696
+ await connection.loadExtension(resolvedPath);
1697
+ }
1698
+ }
1699
+ /** Loads an extension onto the pool's connections and every connection opened beyond it, then records it. */
1700
+ load(poolConnections, extensionPath) {
1701
+ return this.runInTurn(async () => {
1702
+ const resolved = await loadExtension(this.driver, [...poolConnections, ...this.openedConnections], extensionPath);
1703
+ if (!this.resolvedPaths.includes(resolved)) this.resolvedPaths.push(resolved);
1704
+ });
1705
+ }
1706
+ /**
1707
+ * Opens a connection, loads every recorded extension onto it, and returns a
1708
+ * connection that forwards to it. Closing the returned connection stops the
1709
+ * tracking and closes the one underneath.
1710
+ *
1711
+ * @param openConnection - Opens the connection this database needs.
1712
+ * @returns The connection to read and write through.
1713
+ */
1714
+ open(openConnection) {
1715
+ return this.runInTurn(async () => {
1716
+ const connection = await openConnection();
1717
+ try {
1718
+ await this.loadRecorded(connection);
1719
+ } catch (err) {
1720
+ await connection.close().catch(() => void 0);
1721
+ throw err;
1722
+ }
1723
+ const tracked = forwardingConnection(connection, () => {
1724
+ this.openedConnections.delete(tracked);
1725
+ });
1726
+ this.openedConnections.add(tracked);
1727
+ return tracked;
1728
+ });
1729
+ }
1730
+ };
1731
+
1628
1732
  // src/core/worker/config.ts
1629
1733
  var DEFAULT_MAX_PENDING_WRITES = 1024;
1630
1734
  var DEFAULT_RETRY_AFTER_MS = 1e3;
@@ -1728,12 +1832,14 @@ async function createDatabaseRuntime(id, path, driver, options, internals) {
1728
1832
  driver.createBackupEngine?.()
1729
1833
  );
1730
1834
  const canOpenSnapshotConnection = driver.capabilities.multipleConnections && path !== ":memory:";
1835
+ const extensions = new LoadedExtensions(driver);
1836
+ const openSnapshotConnection = () => extensions.open(() => driver.open(path, { readonly: true, walMode: false }));
1731
1837
  const cdc = new DatabaseCdcController(
1732
1838
  (op) => writerLock.run(op),
1733
1839
  () => pool.acquireWriter(),
1734
1840
  options?.cdcPollInterval ?? 50,
1735
1841
  options?.cdcRetention ?? 36e5,
1736
- canOpenSnapshotConnection ? () => driver.open(path, { readonly: true, walMode: false }) : null
1842
+ canOpenSnapshotConnection ? openSnapshotConnection : null
1737
1843
  );
1738
1844
  const sync = new DatabaseSyncController(
1739
1845
  (op) => writeGate.run(() => writerLock.run(op)),
@@ -1776,7 +1882,7 @@ async function createDatabaseRuntime(id, path, driver, options, internals) {
1776
1882
  writes,
1777
1883
  reads: { pool, writerLock, observer },
1778
1884
  migrations,
1779
- loadExtension: (extensionPath) => writerLock.run(() => loadExtension(driver, pool.acquireWriter(), extensionPath))
1885
+ loadExtension: (extensionPath) => writerLock.run(() => extensions.load(pool.connections(), extensionPath))
1780
1886
  };
1781
1887
  }
1782
1888
  async function closeDatabaseRuntime(runtime, closeListeners) {
@@ -86,6 +86,17 @@ async function dispatch(req) {
86
86
  (outcome) => outcome.ok ? { ok: true, results: outcome.values } : { ok: false, error: serializeError(outcome.error) }
87
87
  );
88
88
  }
89
+ case "loadExtension": {
90
+ const conn = requireConnection();
91
+ if (!conn.loadExtension) {
92
+ throw new SirannonError(
93
+ "The driver rebuilt inside the writer worker opens connections without an extension loading call",
94
+ "EXTENSION_ERROR"
95
+ );
96
+ }
97
+ await conn.loadExtension(req.path);
98
+ return void 0;
99
+ }
89
100
  case "close":
90
101
  if (connection) await connection.close();
91
102
  connection = null;
@@ -1,7 +1,7 @@
1
- import { Q as QueryHookContext, g as ConnectionHookContext, h as BeforeSubscribeHook, H as HookConfig, i as MetricsConfig, j as QueryMetrics, k as ConnectionMetrics, l as CDCMetrics, a as SQLiteDriver, D as DatabaseOptions, T as Transaction, e as SQLiteConnection, M as Migration, m as MigrationResult, R as RollbackResult, f as BackupScheduleOptions, B as BeforeQueryHook, A as AfterQueryHook } from './types-CXoPBeDM.js';
1
+ import { Q as QueryHookContext, g as ConnectionHookContext, h as BeforeSubscribeHook, H as HookConfig, i as MetricsConfig, j as QueryMetrics, k as ConnectionMetrics, l as CDCMetrics, a as SQLiteDriver, D as DatabaseOptions, T as Transaction, e as SQLiteConnection, M as Migration, m as MigrationResult, R as RollbackResult, f as BackupScheduleOptions, B as BeforeQueryHook, A as AfterQueryHook } from './types-OGVLZjPS.js';
2
2
  import { c as ReplicationChange, C as ConflictResolver, A as ApplyResult, R as ReplicationBatch } from './types-CjhxcjhA.js';
3
3
  import { C as ChangeEvent, P as Params, Q as QueryOptions, E as ExecuteResult, S as SubscriptionBuilder } from './query-types-BvkzxKQv.js';
4
- import { A as AppliedMigrationRow, b as BulkLoadOptions, a as BulkLoadResult } from './server-options-BVAFmguz.js';
4
+ import { A as AppliedMigrationRow, b as BulkLoadOptions, a as BulkLoadResult } from './server-options-Bc6WuuFf.js';
5
5
  import { L as LiveQueryOptions, a as LiveQuery } from './types-BCejqzNA.js';
6
6
 
7
7
  /**
@@ -1,4 +1,4 @@
1
- import { a as SQLiteDriver } from '../types-CXoPBeDM.js';
1
+ import { a as SQLiteDriver } from '../types-OGVLZjPS.js';
2
2
  import '../query-types-BvkzxKQv.js';
3
3
 
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { nodeResolveExtensionPath, nodeBackupEngine, nodeWriterContext, WriterWorker, createStatementCache, narrowSafeBigInt, narrowRowIntegers, narrowRowsIntegers } from '../chunk-UPKKSUPA.mjs';
1
+ import { nodeResolveExtensionPath, nodeBackupEngine, nodeWriterContext, WriterWorker, createStatementCache, loadThroughRuntime, narrowSafeBigInt, narrowRowIntegers, narrowRowsIntegers } from '../chunk-BD3XGHFC.mjs';
2
2
  import '../chunk-VOYGMAU7.mjs';
3
3
  import { defineDriver } from '../chunk-BQFQ65OL.mjs';
4
4
  import '../chunk-4ISB7XMA.mjs';
@@ -67,6 +67,9 @@ function createConnection(db) {
67
67
  throw err;
68
68
  }
69
69
  },
70
+ async loadExtension(extensionPath) {
71
+ await loadThroughRuntime(extensionPath, () => db.loadExtension(extensionPath));
72
+ },
70
73
  async close() {
71
74
  db.close();
72
75
  }
@@ -1,4 +1,4 @@
1
- import { a as SQLiteDriver } from '../types-CXoPBeDM.js';
1
+ import { a as SQLiteDriver } from '../types-OGVLZjPS.js';
2
2
  import '../query-types-BvkzxKQv.js';
3
3
 
4
4
  /**
@@ -1,4 +1,15 @@
1
- import { defineDriver, synchronousPragmaValue } from '../chunk-DVWQD3GF.mjs';
1
+ import { defineDriver, synchronousPragmaValue, SirannonError, ExtensionError } from '../chunk-GVYLZVUZ.mjs';
2
+ import { resolve } from 'path';
3
+
4
+ // src/core/driver/extension.ts
5
+ async function loadThroughRuntime(extensionPath, load) {
6
+ try {
7
+ load();
8
+ } catch (err) {
9
+ if (err instanceof SirannonError) throw err;
10
+ throw new ExtensionError(extensionPath, err instanceof Error ? err.message : String(err));
11
+ }
12
+ }
2
13
 
3
14
  // src/core/driver/values.ts
4
15
  var SAFE_INT_BOUND = 9007199254740991n;
@@ -30,6 +41,7 @@ function narrowRowsIntegers(rows) {
30
41
  function bunSqlite(driverOptions) {
31
42
  return defineDriver({
32
43
  capabilities: { multipleConnections: true, extensions: true },
44
+ resolveExtensionPath: (extensionPath) => resolve(extensionPath),
33
45
  async open(path, options) {
34
46
  const { Database } = await import('bun:sqlite');
35
47
  const db = new Database(path, { readonly: options?.readonly ?? false, safeIntegers: true });
@@ -78,6 +90,9 @@ function bunSqlite(driverOptions) {
78
90
  throw err;
79
91
  }
80
92
  },
93
+ async loadExtension(extensionPath) {
94
+ await loadThroughRuntime(extensionPath, () => db.loadExtension(extensionPath));
95
+ },
81
96
  async close() {
82
97
  db.close();
83
98
  }
@@ -1,4 +1,4 @@
1
- import { a as SQLiteDriver } from '../types-CXoPBeDM.js';
1
+ import { a as SQLiteDriver } from '../types-OGVLZjPS.js';
2
2
  import '../query-types-BvkzxKQv.js';
3
3
 
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { defineDriver, synchronousPragmaValue } from '../chunk-DVWQD3GF.mjs';
1
+ import { defineDriver, synchronousPragmaValue, ExtensionError } from '../chunk-GVYLZVUZ.mjs';
2
2
 
3
3
  // src/drivers/expo/index.ts
4
4
  function expoSqlite() {
@@ -42,6 +42,12 @@ function expoSqlite() {
42
42
  });
43
43
  return result;
44
44
  },
45
+ async loadExtension(extensionPath) {
46
+ throw new ExtensionError(
47
+ extensionPath,
48
+ "expo-sqlite carries no extension loading call, so a device running Expo loads no compiled extension"
49
+ );
50
+ },
45
51
  async close() {
46
52
  await dbHandle.closeAsync();
47
53
  }
@@ -1,4 +1,4 @@
1
- import { a as SQLiteDriver } from '../types-CXoPBeDM.js';
1
+ import { a as SQLiteDriver } from '../types-OGVLZjPS.js';
2
2
  import '../query-types-BvkzxKQv.js';
3
3
 
4
4
  /**
@@ -1,9 +1,9 @@
1
- import { nodeResolveExtensionPath, nodeBackupEngine, nodeWriterContext, createStatementCache, WriterWorker, narrowSafeBigInt, narrowRowIntegers, narrowRowsIntegers } from '../chunk-UPKKSUPA.mjs';
1
+ import { nodeResolveExtensionPath, nodeBackupEngine, nodeWriterContext, createStatementCache, WriterWorker, loadThroughRuntime, narrowSafeBigInt, narrowRowIntegers, narrowRowsIntegers } from '../chunk-BD3XGHFC.mjs';
2
2
  import '../chunk-VOYGMAU7.mjs';
3
3
  import { defineDriver } from '../chunk-BQFQ65OL.mjs';
4
4
  import '../chunk-4ISB7XMA.mjs';
5
5
  import { synchronousPragmaValue } from '../chunk-OUSWVNWT.mjs';
6
- import '../chunk-PBRXXISQ.mjs';
6
+ import { ExtensionError } from '../chunk-PBRXXISQ.mjs';
7
7
 
8
8
  // src/drivers/node/index.ts
9
9
  function nodeSqlite(driverOptions) {
@@ -20,7 +20,8 @@ function nodeSqlite(driverOptions) {
20
20
  resolveExtensionPath: nodeResolveExtensionPath,
21
21
  async open(path, options) {
22
22
  const { DatabaseSync } = await import('node:sqlite');
23
- const db = new DatabaseSync(path, { readOnly: options?.readonly ?? false });
23
+ const db = new DatabaseSync(path, { readOnly: options?.readonly ?? false, allowExtension: true });
24
+ db.enableLoadExtension?.(false);
24
25
  if (options?.walMode !== false) db.exec("PRAGMA journal_mode = WAL");
25
26
  db.exec(`PRAGMA synchronous = ${synchronousPragmaValue(options?.synchronous)}`);
26
27
  db.exec("PRAGMA foreign_keys = ON");
@@ -91,6 +92,22 @@ function nodeSqlite(driverOptions) {
91
92
  throw err;
92
93
  }
93
94
  },
95
+ async loadExtension(extensionPath) {
96
+ if (typeof db.loadExtension !== "function" || typeof db.enableLoadExtension !== "function") {
97
+ throw new ExtensionError(
98
+ extensionPath,
99
+ `Node's own SQLite module on ${process.version} carries no extension loading call`
100
+ );
101
+ }
102
+ await loadThroughRuntime(extensionPath, () => {
103
+ db.enableLoadExtension(true);
104
+ try {
105
+ db.loadExtension(extensionPath);
106
+ } finally {
107
+ db.enableLoadExtension(false);
108
+ }
109
+ });
110
+ },
94
111
  async close() {
95
112
  db.close();
96
113
  }
@@ -1,4 +1,4 @@
1
- import { a as SQLiteDriver } from '../types-CXoPBeDM.js';
1
+ import { a as SQLiteDriver } from '../types-OGVLZjPS.js';
2
2
  import '../query-types-BvkzxKQv.js';
3
3
 
4
4
  /**
@@ -6,6 +6,15 @@ var SirannonError = class extends Error {
6
6
  this.name = "SirannonError";
7
7
  }
8
8
  };
9
+ var ExtensionError = class extends SirannonError {
10
+ constructor(path, cause) {
11
+ super(
12
+ cause ? `Failed to load extension '${path}': ${cause}` : `Failed to load extension '${path}'`,
13
+ "EXTENSION_ERROR"
14
+ );
15
+ this.name = "ExtensionError";
16
+ }
17
+ };
9
18
 
10
19
  // src/core/driver/define.ts
11
20
  function defineDriver(config) {
@@ -157,6 +166,12 @@ function waSqlite(driverOptions) {
157
166
  throw err;
158
167
  }
159
168
  },
169
+ async loadExtension(extensionPath) {
170
+ throw new ExtensionError(
171
+ extensionPath,
172
+ "wa-sqlite runs SQLite compiled to WebAssembly, which carries no dynamic loading call, so a browser loads no compiled extension"
173
+ );
174
+ },
160
175
  async close() {
161
176
  sqlite3.close(db);
162
177
  }
@@ -1,5 +1,5 @@
1
1
  import { B as BaselineFileOption } from '../baseline-D93hcIEE.js';
2
- import { M as Migration } from '../types-CXoPBeDM.js';
2
+ import { M as Migration } from '../types-OGVLZjPS.js';
3
3
  import '../query-types-BvkzxKQv.js';
4
4
 
5
5
  /**
@@ -1,5 +1,5 @@
1
1
  import { W as WriteConcern, R as ReadConcern, E as ExecuteResult } from './query-types-BvkzxKQv.js';
2
- import { B as BulkLoadDurability, a as BulkLoadResult } from './server-options-BVAFmguz.js';
2
+ import { B as BulkLoadDurability, a as BulkLoadResult } from './server-options-Bc6WuuFf.js';
3
3
 
4
4
  /**
5
5
  * Body of `POST /db/{id}/query`.
@@ -1,15 +1,15 @@
1
1
  export { F as FieldMergeResolver, L as LWWResolver, P as PrimaryWinsResolver } from '../primary-wins-B0np8JS3.js';
2
2
  import { H as HLCTimestamp, R as ReplicationBatch, C as ConflictResolver, A as ApplyResult, S as SyncTableManifest } from '../types-CjhxcjhA.js';
3
3
  export { a as ConflictContext, b as ConflictResolution, c as ReplicationChange } from '../types-CjhxcjhA.js';
4
- import { R as ReplicationStatusInfo } from '../server-options-BVAFmguz.js';
5
- import { r as ClusterReadEndpointInfo, C as ClusterStatusInfo, e as SQLiteConnection, T as Transaction } from '../types-CXoPBeDM.js';
6
- import { C as CoordinatorRuntimeStatus, g as ReplicationStatus, h as SyncPhase, I as InFlightBatch, P as PeerState, a as ForwardedTransactionResult, b as SyncBatch, c as SyncComplete, d as SyncAck, S as SyncRequest, i as ReplicationConfig, j as SyncState, k as ReplicationErrorEvent, R as ReplicationAck, l as Topology, f as TopologyRole } from '../types-DxoEm08T.js';
7
- export { F as ForwardedTransaction, N as NodeInfo, e as ReplicationTransport, T as TransportConfig } from '../types-DxoEm08T.js';
4
+ import { R as ReplicationStatusInfo } from '../server-options-Bc6WuuFf.js';
5
+ import { r as ClusterReadEndpointInfo, C as ClusterStatusInfo, e as SQLiteConnection, T as Transaction } from '../types-OGVLZjPS.js';
6
+ import { C as CoordinatorRuntimeStatus, g as ReplicationStatus, h as SyncPhase, I as InFlightBatch, P as PeerState, a as ForwardedTransactionResult, b as SyncBatch, c as SyncComplete, d as SyncAck, S as SyncRequest, i as ReplicationConfig, j as SyncState, k as ReplicationErrorEvent, R as ReplicationAck, l as Topology, f as TopologyRole } from '../types-BgVF0xhd.js';
7
+ export { F as ForwardedTransaction, N as NodeInfo, e as ReplicationTransport, T as TransportConfig } from '../types-BgVF0xhd.js';
8
8
  import { c as ReplicationGroupState, e as CoordinatorWatchDisposer } from '../types-CMBcFPhb.js';
9
9
  export { A as AcquireControllerLeaseInput, a as AcquireControllerLeaseResult, h as AdmitNodeToInSyncSetInput, C as ClusterCoordinator, f as CompareAndAdvancePrimaryTermInput, g as CompareAndAdvancePrimaryTermResult, j as CoordinatorCompatibilityMetadata, k as CoordinatorLease, b as CoordinatorNodeSession, l as CoordinatorPrimary, P as PromoteEligibleReplicaInput, R as RegisterNodeSessionInput, d as ReplicationGroupWatcher, S as SetReplicationGroupStateInput, U as UpdateInSyncSetInput, i as UpdateNodeMaintenanceInput } from '../types-CMBcFPhb.js';
10
10
  import { EventEmitter } from 'node:events';
11
- import { C as ChangeTracker } from '../change-tracker-C2Z8UbI0.js';
12
- import { D as Database } from '../database-DvSvONb-.js';
11
+ import { C as ChangeTracker } from '../change-tracker-rTXrPhQq.js';
12
+ import { D as Database } from '../database-DvURlr-n.js';
13
13
  import { P as Params, Q as QueryOptions, E as ExecuteResult } from '../query-types-BvkzxKQv.js';
14
14
  import { S as SirannonError } from '../errors-Dei4GdBb.js';
15
15
  import '../operation-registry-6qErmUT2.js';
@@ -1,10 +1,10 @@
1
- import { T as TransactionStatement, Q as QueryResponse, E as ExecuteResponse, a as TransactionResponse, B as BatchResponse, L as LoadResponse, A as AckResponse } from '../protocol-CEBVo1tO.js';
2
- export { b as BatchRequest, c as ErrorResponse, d as ExecuteRequest, e as LoadRequest, f as QueryRequest, g as TransactionRequest, t as toExecuteResponse } from '../protocol-CEBVo1tO.js';
3
- import { S as Sirannon } from '../sirannon-DVYfrNiq.js';
4
- import { B as BulkLoadDurability, S as ServerOptions, W as WSHandlerOptions } from '../server-options-BVAFmguz.js';
1
+ import { T as TransactionStatement, Q as QueryResponse, E as ExecuteResponse, a as TransactionResponse, B as BatchResponse, L as LoadResponse, A as AckResponse } from '../protocol-BQMNEubg.js';
2
+ export { b as BatchRequest, c as ErrorResponse, d as ExecuteRequest, e as LoadRequest, f as QueryRequest, g as TransactionRequest, t as toExecuteResponse } from '../protocol-BQMNEubg.js';
3
+ import { S as Sirannon } from '../sirannon-Bs0WBW1o.js';
4
+ import { B as BulkLoadDurability, S as ServerOptions, W as WSHandlerOptions } from '../server-options-Bc6WuuFf.js';
5
5
  import { W as WriteConcern, R as ReadConcern } from '../query-types-BvkzxKQv.js';
6
- import '../database-DvSvONb-.js';
7
- import '../types-CXoPBeDM.js';
6
+ import '../database-DvURlr-n.js';
7
+ import '../types-OGVLZjPS.js';
8
8
  import '../types-CjhxcjhA.js';
9
9
  import '../types-BCejqzNA.js';
10
10
  import '../operation-registry-6qErmUT2.js';
@@ -1,6 +1,6 @@
1
1
  import { a as OperationRegistry } from './operation-registry-6qErmUT2.js';
2
2
  import { R as ReplicationBatch, C as ConflictResolver, A as ApplyResult } from './types-CjhxcjhA.js';
3
- import { N as NodeHealth, T as Transaction, C as ClusterStatusInfo } from './types-CXoPBeDM.js';
3
+ import { N as NodeHealth, T as Transaction, C as ClusterStatusInfo } from './types-OGVLZjPS.js';
4
4
  import { P as Params, Q as QueryOptions, E as ExecuteResult } from './query-types-BvkzxKQv.js';
5
5
 
6
6
  interface AppliedMigrationRow {
@@ -1,5 +1,5 @@
1
- import { D as Database } from './database-DvSvONb-.js';
2
- import { S as SirannonOptions, a as SQLiteDriver, D as DatabaseOptions, M as Migration, B as BeforeQueryHook, A as AfterQueryHook, b as BeforeConnectHook, c as DatabaseOpenHook, d as DatabaseCloseHook } from './types-CXoPBeDM.js';
1
+ import { D as Database } from './database-DvURlr-n.js';
2
+ import { S as SirannonOptions, a as SQLiteDriver, D as DatabaseOptions, M as Migration, B as BeforeQueryHook, A as AfterQueryHook, b as BeforeConnectHook, c as DatabaseOpenHook, d as DatabaseCloseHook } from './types-OGVLZjPS.js';
3
3
 
4
4
  /**
5
5
  * A registry of open SQLite databases, keyed by identifier.
@@ -1,10 +1,10 @@
1
1
  import { BinaryWriter, BinaryReader } from '@bufbuild/protobuf/wire';
2
2
  import { Client, ClientDuplexStream, CallOptions, Metadata, ServiceError, ClientUnaryCall, ChannelCredentials, ClientOptions, ServerDuplexStream, Server } from '@grpc/grpc-js';
3
3
  import { HealthImplementation } from 'grpc-health-check';
4
- import { R as ReplicationAck, F as ForwardedTransaction, a as ForwardedTransactionResult, N as NodeInfo, S as SyncRequest, b as SyncBatch, c as SyncComplete, d as SyncAck, e as ReplicationTransport, f as TopologyRole, T as TransportConfig } from '../types-DxoEm08T.js';
4
+ import { R as ReplicationAck, F as ForwardedTransaction, a as ForwardedTransactionResult, N as NodeInfo, S as SyncRequest, b as SyncBatch, c as SyncComplete, d as SyncAck, e as ReplicationTransport, f as TopologyRole, T as TransportConfig } from '../types-BgVF0xhd.js';
5
5
  import { R as ReplicationBatch } from '../types-CjhxcjhA.js';
6
- import '../change-tracker-C2Z8UbI0.js';
7
- import '../types-CXoPBeDM.js';
6
+ import '../change-tracker-rTXrPhQq.js';
7
+ import '../types-OGVLZjPS.js';
8
8
  import '../query-types-BvkzxKQv.js';
9
9
  import '../types-CMBcFPhb.js';
10
10
 
@@ -1,7 +1,7 @@
1
- import { R as ReplicationAck, F as ForwardedTransaction, a as ForwardedTransactionResult, S as SyncRequest, b as SyncBatch, c as SyncComplete, d as SyncAck, N as NodeInfo, e as ReplicationTransport, T as TransportConfig } from '../types-DxoEm08T.js';
1
+ import { R as ReplicationAck, F as ForwardedTransaction, a as ForwardedTransactionResult, S as SyncRequest, b as SyncBatch, c as SyncComplete, d as SyncAck, N as NodeInfo, e as ReplicationTransport, T as TransportConfig } from '../types-BgVF0xhd.js';
2
2
  import { R as ReplicationBatch } from '../types-CjhxcjhA.js';
3
- import '../change-tracker-C2Z8UbI0.js';
4
- import '../types-CXoPBeDM.js';
3
+ import '../change-tracker-rTXrPhQq.js';
4
+ import '../types-OGVLZjPS.js';
5
5
  import '../query-types-BvkzxKQv.js';
6
6
  import '../types-CMBcFPhb.js';
7
7
 
@@ -1,5 +1,5 @@
1
- import { C as ChangeTracker } from './change-tracker-C2Z8UbI0.js';
2
- import { e as SQLiteConnection, N as NodeHealth } from './types-CXoPBeDM.js';
1
+ import { C as ChangeTracker } from './change-tracker-rTXrPhQq.js';
2
+ import { e as SQLiteConnection, N as NodeHealth } from './types-OGVLZjPS.js';
3
3
  import { S as SyncTableManifest, R as ReplicationBatch, C as ConflictResolver } from './types-CjhxcjhA.js';
4
4
  import { C as ClusterCoordinator, j as CoordinatorCompatibilityMetadata, c as ReplicationGroupState } from './types-CMBcFPhb.js';
5
5
 
@@ -496,6 +496,15 @@ interface SQLiteConnection {
496
496
  transaction<T>(fn: (conn: SQLiteConnection) => Promise<T>): Promise<T>;
497
497
  /** Closes the connection. */
498
498
  close(): Promise<void>;
499
+ /**
500
+ * Loads a compiled SQLite extension into this connection through the
501
+ * runtime's own loading call, so a query on this connection can call the
502
+ * extension's functions. SQLite scopes a loaded extension to the connection
503
+ * that loaded it, so a caller that needs it everywhere loads it on every
504
+ * connection. Where the runtime carries no loading call, this rejects with an
505
+ * error that names that runtime.
506
+ */
507
+ loadExtension?(extensionPath: string): Promise<void>;
499
508
  /** Optional fast path that applies one statement over many parameter sets. */
500
509
  runBatch?(sql: string, paramsBatch: readonly unknown[][]): Promise<RunResult[]>;
501
510
  /** Optional fast path that applies one statement over many parameter sets and returns only the totals. */
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@delali/sirannon-db",
3
3
  "type": "module",
4
- "version": "0.2.3-next.29",
4
+ "version": "0.2.3-next.30",
5
5
  "description": "A production-grade library that turns SQLite databases into a networked data layer with real-time subscriptions.",
6
6
  "author": "Delali (https://sondelali.com)",
7
7
  "license": "Apache-2.0",