@powersync/web 1.38.7 → 1.39.1

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 (44) hide show
  1. package/dist/index.umd.js +344 -83
  2. package/dist/index.umd.js.map +1 -1
  3. package/dist/worker/SharedSyncImplementation.umd.js +18 -9
  4. package/dist/worker/SharedSyncImplementation.umd.js.map +1 -1
  5. package/dist/worker/WASQLiteDB.umd.js +94 -60
  6. package/dist/worker/WASQLiteDB.umd.js.map +1 -1
  7. package/dist/worker/node_modules_pnpm_journeyapps_wa-sqlite_1_7_0_node_modules_journeyapps_wa-sqlite_src_examples-833585.umd.js +1400 -0
  8. package/dist/worker/node_modules_pnpm_journeyapps_wa-sqlite_1_7_0_node_modules_journeyapps_wa-sqlite_src_examples-833585.umd.js.map +1 -0
  9. package/lib/package.json +2 -2
  10. package/lib/src/db/adapters/AsyncWebAdapter.js +1 -1
  11. package/lib/src/db/adapters/AsyncWebAdapter.js.map +1 -1
  12. package/lib/src/db/adapters/wa-sqlite/RawSqliteConnection.d.ts +8 -1
  13. package/lib/src/db/adapters/wa-sqlite/RawSqliteConnection.js +13 -9
  14. package/lib/src/db/adapters/wa-sqlite/RawSqliteConnection.js.map +1 -1
  15. package/lib/src/db/adapters/wa-sqlite/WASQLiteOpenFactory.js +8 -2
  16. package/lib/src/db/adapters/wa-sqlite/WASQLiteOpenFactory.js.map +1 -1
  17. package/lib/src/db/adapters/wa-sqlite/vfs.d.ts +20 -30
  18. package/lib/src/db/adapters/wa-sqlite/vfs.js +57 -39
  19. package/lib/src/db/adapters/wa-sqlite/vfs.js.map +1 -1
  20. package/lib/src/db/sync/SharedWebStreamingSyncImplementation.d.ts +1 -0
  21. package/lib/src/db/sync/SharedWebStreamingSyncImplementation.js +10 -5
  22. package/lib/src/db/sync/SharedWebStreamingSyncImplementation.js.map +1 -1
  23. package/lib/src/worker/db/MultiDatabaseServer.js +5 -3
  24. package/lib/src/worker/db/MultiDatabaseServer.js.map +1 -1
  25. package/lib/src/worker/db/open-worker-database.d.ts +3 -2
  26. package/lib/src/worker/db/open-worker-database.js +30 -22
  27. package/lib/src/worker/db/open-worker-database.js.map +1 -1
  28. package/lib/src/worker/errors.d.ts +2 -0
  29. package/lib/src/worker/errors.js +7 -0
  30. package/lib/src/worker/errors.js.map +1 -0
  31. package/lib/src/worker/sync/SharedSyncImplementation.d.ts +1 -0
  32. package/lib/src/worker/sync/SharedSyncImplementation.js +2 -1
  33. package/lib/src/worker/sync/SharedSyncImplementation.js.map +1 -1
  34. package/lib/tsconfig.tsbuildinfo +1 -1
  35. package/package.json +3 -3
  36. package/src/db/adapters/AsyncWebAdapter.ts +1 -1
  37. package/src/db/adapters/wa-sqlite/RawSqliteConnection.ts +15 -11
  38. package/src/db/adapters/wa-sqlite/WASQLiteOpenFactory.ts +24 -9
  39. package/src/db/adapters/wa-sqlite/vfs.ts +67 -54
  40. package/src/db/sync/SharedWebStreamingSyncImplementation.ts +17 -11
  41. package/src/worker/db/MultiDatabaseServer.ts +5 -3
  42. package/src/worker/db/open-worker-database.ts +34 -22
  43. package/src/worker/errors.ts +9 -0
  44. package/src/worker/sync/SharedSyncImplementation.ts +3 -1
@@ -2414,12 +2414,21 @@ class DatabaseServer {
2414
2414
 
2415
2415
  __webpack_require__.r(__webpack_exports__);
2416
2416
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
2417
- /* harmony export */ RawSqliteConnection: () => (/* binding */ RawSqliteConnection)
2417
+ /* harmony export */ RawSqliteConnection: () => (/* binding */ RawSqliteConnection),
2418
+ /* harmony export */ maxPathNameLength: () => (/* binding */ maxPathNameLength)
2418
2419
  /* harmony export */ });
2419
2420
  /* harmony import */ var _journeyapps_wa_sqlite__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @journeyapps/wa-sqlite */ "../../node_modules/.pnpm/@journeyapps+wa-sqlite@1.7.0/node_modules/@journeyapps/wa-sqlite/src/sqlite-api.js");
2420
2421
  /* harmony import */ var _vfs_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./vfs.js */ "./lib/src/db/adapters/wa-sqlite/vfs.js");
2421
2422
 
2422
2423
 
2424
+ /**
2425
+ * The maximum length of a db filename we support.
2426
+ *
2427
+ * We configure the same on WA-SQLite (which otherwise defaults to a maximum length of 64). We don't want to support
2428
+ * very long path names as Safari maps OPFS files directly to OS files, and APFS has a 255-byte filename limit. Since
2429
+ * some VFS append additional characters for pooled file access handles, we want to stay well below that.
2430
+ */
2431
+ const maxPathNameLength = 128;
2423
2432
  /**
2424
2433
  * A small wrapper around WA-sqlite to help with opening databases and running statements by preparing them internally.
2425
2434
  *
@@ -2433,10 +2442,8 @@ class RawSqliteConnection {
2433
2442
  * The `sqlite3*` connection pointer.
2434
2443
  */
2435
2444
  db = 0;
2436
- _moduleFactory;
2437
2445
  constructor(options) {
2438
2446
  this.options = options;
2439
- this._moduleFactory = _vfs_js__WEBPACK_IMPORTED_MODULE_1__.DEFAULT_MODULE_FACTORIES[this.options.vfs];
2440
2447
  }
2441
2448
  get isOpen() {
2442
2449
  return this.db != 0;
@@ -2446,17 +2453,15 @@ class RawSqliteConnection {
2446
2453
  this.db = await api.open_v2(this.options.dbFilename, this.options.isReadOnly ? 1 /* SQLITE_OPEN_READONLY */ : 6 /* SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE */);
2447
2454
  await this.executeRaw(`PRAGMA temp_store = ${this.options.temporaryStorage};`);
2448
2455
  if (this.options.encryptionKey) {
2449
- const escapedKey = this.options.encryptionKey.replace("'", "''");
2450
- await this.executeRaw(`PRAGMA key = '${escapedKey}'`);
2456
+ const escapedKey = this.options.encryptionKey.replaceAll("'", "''");
2457
+ await this.executeRaw(`PRAGMA key = '${escapedKey}';`);
2451
2458
  }
2452
2459
  await this.executeRaw(`PRAGMA cache_size = -${this.options.cacheSizeKb};`);
2453
2460
  await this.executeRaw(`SELECT powersync_update_hooks('install');`);
2454
2461
  }
2455
2462
  async openSQLiteAPI() {
2456
- const { module, vfs } = await this._moduleFactory({
2457
- dbFileName: this.options.dbFilename,
2458
- encryptionKey: this.options.encryptionKey
2459
- });
2463
+ const { module, vfs } = await (0,_vfs_js__WEBPACK_IMPORTED_MODULE_1__.loadModuleAndVfs)(this.options);
2464
+ vfs.mxPathname = maxPathNameLength;
2460
2465
  const sqlite3 = (0,_journeyapps_wa_sqlite__WEBPACK_IMPORTED_MODULE_0__.Factory)(module);
2461
2466
  sqlite3.vfs_register(vfs, true);
2462
2467
  /**
@@ -2577,8 +2582,8 @@ class RawSqliteConnection {
2577
2582
 
2578
2583
  __webpack_require__.r(__webpack_exports__);
2579
2584
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
2580
- /* harmony export */ DEFAULT_MODULE_FACTORIES: () => (/* binding */ DEFAULT_MODULE_FACTORIES),
2581
2585
  /* harmony export */ WASQLiteVFS: () => (/* binding */ WASQLiteVFS),
2586
+ /* harmony export */ loadModuleAndVfs: () => (/* binding */ loadModuleAndVfs),
2582
2587
  /* harmony export */ vfsRequiresDedicatedWorkers: () => (/* binding */ vfsRequiresDedicatedWorkers)
2583
2588
  /* harmony export */ });
2584
2589
  /**
@@ -2590,9 +2595,26 @@ var WASQLiteVFS;
2590
2595
  WASQLiteVFS["OPFSCoopSyncVFS"] = "OPFSCoopSyncVFS";
2591
2596
  WASQLiteVFS["AccessHandlePoolVFS"] = "AccessHandlePoolVFS";
2592
2597
  WASQLiteVFS["OPFSWriteAheadVFS"] = "OPFSWriteAheadVFS";
2598
+ /**
2599
+ * A virtual file system storing data in-memory only, without persistence.
2600
+ *
2601
+ * This file system can be used in three configurations:
2602
+ *
2603
+ * 1. In shared workers (the default when available): All tabs share the same in-memory database, which is cleared
2604
+ * once the last tab is closed.
2605
+ * 2. In dedicated workers (used when `enableMultiTabs` is disabled). Each tab has its own in-memory database cleared
2606
+ * when the tab is closed. Queries are offloaded to a dedicated worker.
2607
+ * 3. In the context of the tab itself (used when both `enableMultiTabs` and `useWebWorker` are disabled). The per-tab
2608
+ * database is hosted in the tab itself, and queries run synchronously. This is _a lot_ faster than any other
2609
+ * single-threadedVFS, but can block JavaScript for computationally-intensive queries.
2610
+ *
2611
+ * This VFS primarily intended for development, but it also useful for online-first deployments not syncing large
2612
+ * amounts of data, as it is quicker to start up.
2613
+ */
2614
+ WASQLiteVFS["InMemoryVfs"] = "InMemoryVFS";
2593
2615
  })(WASQLiteVFS || (WASQLiteVFS = {}));
2594
2616
  function vfsRequiresDedicatedWorkers(vfs) {
2595
- return vfs != WASQLiteVFS.IDBBatchAtomicVFS;
2617
+ return vfs != WASQLiteVFS.IDBBatchAtomicVFS && vfs != WASQLiteVFS.InMemoryVfs;
2596
2618
  }
2597
2619
  async function asyncModuleFactory(encryptionKey) {
2598
2620
  if (encryptionKey) {
@@ -2617,46 +2639,47 @@ async function syncModuleFactory(encryptionKey) {
2617
2639
  /**
2618
2640
  * @internal
2619
2641
  */
2620
- const DEFAULT_MODULE_FACTORIES = {
2621
- [WASQLiteVFS.IDBBatchAtomicVFS]: async (options) => {
2622
- const module = await asyncModuleFactory(options.encryptionKey);
2623
- const { IDBBatchAtomicVFS } = await __webpack_require__.e(/*! import() */ "node_modules_pnpm_journeyapps_wa-sqlite_1_7_0_node_modules_journeyapps_wa-sqlite_src_examples-96fb23").then(__webpack_require__.bind(__webpack_require__, /*! @journeyapps/wa-sqlite/src/examples/IDBBatchAtomicVFS.js */ "../../node_modules/.pnpm/@journeyapps+wa-sqlite@1.7.0/node_modules/@journeyapps/wa-sqlite/src/examples/IDBBatchAtomicVFS.js"));
2624
- return {
2625
- module,
2642
+ async function loadModuleAndVfs({ vfs, dbFilename, encryptionKey }) {
2643
+ let moduleFactory = syncModuleFactory;
2644
+ let resolveVfs;
2645
+ switch (vfs) {
2646
+ case WASQLiteVFS.IDBBatchAtomicVFS: {
2647
+ moduleFactory = asyncModuleFactory;
2648
+ const { IDBBatchAtomicVFS } = await __webpack_require__.e(/*! import() */ "node_modules_pnpm_journeyapps_wa-sqlite_1_7_0_node_modules_journeyapps_wa-sqlite_src_examples-96fb23").then(__webpack_require__.bind(__webpack_require__, /*! @journeyapps/wa-sqlite/src/examples/IDBBatchAtomicVFS.js */ "../../node_modules/.pnpm/@journeyapps+wa-sqlite@1.7.0/node_modules/@journeyapps/wa-sqlite/src/examples/IDBBatchAtomicVFS.js"));
2649
+ resolveVfs = (module) => {
2650
+ // @ts-expect-error The types for this static method are missing upstream
2651
+ return IDBBatchAtomicVFS.create(dbFilename, module, { lockPolicy: 'exclusive' });
2652
+ };
2653
+ break;
2654
+ }
2655
+ case WASQLiteVFS.AccessHandlePoolVFS: {
2656
+ // @ts-expect-error The types for this import are missing upstream
2657
+ const { AccessHandlePoolVFS } = await __webpack_require__.e(/*! import() */ "node_modules_pnpm_journeyapps_wa-sqlite_1_7_0_node_modules_journeyapps_wa-sqlite_src_examples-c89911").then(__webpack_require__.bind(__webpack_require__, /*! @journeyapps/wa-sqlite/src/examples/AccessHandlePoolVFS.js */ "../../node_modules/.pnpm/@journeyapps+wa-sqlite@1.7.0/node_modules/@journeyapps/wa-sqlite/src/examples/AccessHandlePoolVFS.js"));
2658
+ resolveVfs = (module) => AccessHandlePoolVFS.create(dbFilename, module);
2659
+ break;
2660
+ }
2661
+ case WASQLiteVFS.OPFSCoopSyncVFS: {
2662
+ // @ts-expect-error The types for this import are missing upstream
2663
+ const { OPFSCoopSyncVFS } = await __webpack_require__.e(/*! import() */ "node_modules_pnpm_journeyapps_wa-sqlite_1_7_0_node_modules_journeyapps_wa-sqlite_src_examples-ec4eb1").then(__webpack_require__.bind(__webpack_require__, /*! @journeyapps/wa-sqlite/src/examples/OPFSCoopSyncVFS.js */ "../../node_modules/.pnpm/@journeyapps+wa-sqlite@1.7.0/node_modules/@journeyapps/wa-sqlite/src/examples/OPFSCoopSyncVFS.js"));
2664
+ resolveVfs = (module) => OPFSCoopSyncVFS.create(dbFilename, module);
2665
+ break;
2666
+ }
2667
+ case WASQLiteVFS.OPFSWriteAheadVFS: {
2668
+ // @ts-expect-error The types for this import are missing upstream
2669
+ const { OPFSWriteAheadVFS } = await __webpack_require__.e(/*! import() */ "node_modules_pnpm_journeyapps_wa-sqlite_1_7_0_node_modules_journeyapps_wa-sqlite_src_examples-2fb422").then(__webpack_require__.bind(__webpack_require__, /*! @journeyapps/wa-sqlite/src/examples/OPFSWriteAheadVFS.js */ "../../node_modules/.pnpm/@journeyapps+wa-sqlite@1.7.0/node_modules/@journeyapps/wa-sqlite/src/examples/OPFSWriteAheadVFS.js"));
2670
+ resolveVfs = (module) => OPFSWriteAheadVFS.create(dbFilename, module, {});
2671
+ break;
2672
+ }
2673
+ case WASQLiteVFS.InMemoryVfs: {
2674
+ const { MemoryVFS } = await __webpack_require__.e(/*! import() */ "node_modules_pnpm_journeyapps_wa-sqlite_1_7_0_node_modules_journeyapps_wa-sqlite_src_examples-833585").then(__webpack_require__.bind(__webpack_require__, /*! @journeyapps/wa-sqlite/src/examples/MemoryVFS.js */ "../../node_modules/.pnpm/@journeyapps+wa-sqlite@1.7.0/node_modules/@journeyapps/wa-sqlite/src/examples/MemoryVFS.js"));
2626
2675
  // @ts-expect-error The types for this static method are missing upstream
2627
- vfs: await IDBBatchAtomicVFS.create(options.dbFileName, module, { lockPolicy: 'exclusive' })
2628
- };
2629
- },
2630
- [WASQLiteVFS.AccessHandlePoolVFS]: async (options) => {
2631
- const module = await syncModuleFactory(options.encryptionKey);
2632
- // @ts-expect-error The types for this static method are missing upstream
2633
- const { AccessHandlePoolVFS } = await __webpack_require__.e(/*! import() */ "node_modules_pnpm_journeyapps_wa-sqlite_1_7_0_node_modules_journeyapps_wa-sqlite_src_examples-c89911").then(__webpack_require__.bind(__webpack_require__, /*! @journeyapps/wa-sqlite/src/examples/AccessHandlePoolVFS.js */ "../../node_modules/.pnpm/@journeyapps+wa-sqlite@1.7.0/node_modules/@journeyapps/wa-sqlite/src/examples/AccessHandlePoolVFS.js"));
2634
- return {
2635
- module,
2636
- vfs: await AccessHandlePoolVFS.create(options.dbFileName, module)
2637
- };
2638
- },
2639
- [WASQLiteVFS.OPFSCoopSyncVFS]: async (options) => {
2640
- const module = await syncModuleFactory(options.encryptionKey);
2641
- // @ts-expect-error The types for this static method are missing upstream
2642
- const { OPFSCoopSyncVFS } = await __webpack_require__.e(/*! import() */ "node_modules_pnpm_journeyapps_wa-sqlite_1_7_0_node_modules_journeyapps_wa-sqlite_src_examples-ec4eb1").then(__webpack_require__.bind(__webpack_require__, /*! @journeyapps/wa-sqlite/src/examples/OPFSCoopSyncVFS.js */ "../../node_modules/.pnpm/@journeyapps+wa-sqlite@1.7.0/node_modules/@journeyapps/wa-sqlite/src/examples/OPFSCoopSyncVFS.js"));
2643
- const vfs = await OPFSCoopSyncVFS.create(options.dbFileName, module);
2644
- return {
2645
- module,
2646
- vfs
2647
- };
2648
- },
2649
- [WASQLiteVFS.OPFSWriteAheadVFS]: async (options) => {
2650
- const module = await syncModuleFactory(options.encryptionKey);
2651
- // @ts-expect-error The types for this static method are missing upstream
2652
- const { OPFSWriteAheadVFS } = await __webpack_require__.e(/*! import() */ "node_modules_pnpm_journeyapps_wa-sqlite_1_7_0_node_modules_journeyapps_wa-sqlite_src_examples-2fb422").then(__webpack_require__.bind(__webpack_require__, /*! @journeyapps/wa-sqlite/src/examples/OPFSWriteAheadVFS.js */ "../../node_modules/.pnpm/@journeyapps+wa-sqlite@1.7.0/node_modules/@journeyapps/wa-sqlite/src/examples/OPFSWriteAheadVFS.js"));
2653
- const vfs = await OPFSWriteAheadVFS.create(options.dbFileName, module, {});
2654
- return {
2655
- module,
2656
- vfs
2657
- };
2676
+ resolveVfs = (module) => MemoryVFS.create(dbFilename, module);
2677
+ break;
2678
+ }
2658
2679
  }
2659
- };
2680
+ const module = await moduleFactory(encryptionKey);
2681
+ return { module, vfs: await resolveVfs(module) };
2682
+ }
2660
2683
 
2661
2684
 
2662
2685
  /***/ },
@@ -2697,6 +2720,8 @@ __webpack_require__.r(__webpack_exports__);
2697
2720
  /* harmony import */ var _shared_navigator_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../shared/navigator.js */ "./lib/src/shared/navigator.js");
2698
2721
  /* harmony import */ var _db_adapters_wa_sqlite_RawSqliteConnection_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../db/adapters/wa-sqlite/RawSqliteConnection.js */ "./lib/src/db/adapters/wa-sqlite/RawSqliteConnection.js");
2699
2722
  /* harmony import */ var _db_adapters_wa_sqlite_ConcurrentConnection_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../db/adapters/wa-sqlite/ConcurrentConnection.js */ "./lib/src/db/adapters/wa-sqlite/ConcurrentConnection.js");
2723
+ /* harmony import */ var _db_adapters_wa_sqlite_vfs_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../db/adapters/wa-sqlite/vfs.js */ "./lib/src/db/adapters/wa-sqlite/vfs.js");
2724
+
2700
2725
 
2701
2726
 
2702
2727
 
@@ -2745,13 +2770,14 @@ class MultiDatabaseServer {
2745
2770
  }
2746
2771
  async databaseOpenAttempt(options) {
2747
2772
  return (0,_shared_navigator_js__WEBPACK_IMPORTED_MODULE_2__.getNavigatorLocks)().request(OPEN_DB_LOCK, async () => {
2748
- const { dbFilename } = options;
2773
+ const { dbFilename, isReadOnly, vfs } = options;
2749
2774
  let server = this.activeDatabases.get(dbFilename);
2750
2775
  if (server == null) {
2751
2776
  // We don't need navigator locks for shared workers because all queries run in this shared worker exclusively.
2752
2777
  // For read-only connections, we use a VFS that supports concurrent reads (so a single lock on the connection is
2753
- // fine).
2754
- const needsNavigatorLocks = !(isSharedWorker || options.isReadOnly);
2778
+ // fine). In-memory databases either run in a shared worker or aren't shared across tabs at all, so the internal
2779
+ // lock is enough.
2780
+ const needsNavigatorLocks = !(isSharedWorker || isReadOnly || vfs == _db_adapters_wa_sqlite_vfs_js__WEBPACK_IMPORTED_MODULE_5__.WASQLiteVFS.InMemoryVfs);
2755
2781
  const connection = new _db_adapters_wa_sqlite_RawSqliteConnection_js__WEBPACK_IMPORTED_MODULE_3__.RawSqliteConnection(options);
2756
2782
  const withSafeConcurrency = new _db_adapters_wa_sqlite_ConcurrentConnection_js__WEBPACK_IMPORTED_MODULE_4__.ConcurrentSqliteConnection(connection, needsNavigatorLocks);
2757
2783
  // Initializing the RawSqliteConnection will run some pragmas that might write to the database file, so we want
@@ -5282,12 +5308,16 @@ class ControlledExecutor {
5282
5308
  }
5283
5309
  async execute(param) {
5284
5310
  this.runningTask = this.task(param);
5285
- await this.runningTask;
5286
- this.runningTask = undefined;
5287
- if (this.pendingTaskParam) {
5288
- const pendingParam = this.pendingTaskParam;
5289
- this.pendingTaskParam = undefined;
5290
- this.execute(pendingParam);
5311
+ try {
5312
+ await this.runningTask;
5313
+ }
5314
+ finally {
5315
+ this.runningTask = undefined;
5316
+ if (this.pendingTaskParam) {
5317
+ const pendingParam = this.pendingTaskParam;
5318
+ this.pendingTaskParam = undefined;
5319
+ this.execute(pendingParam);
5320
+ }
5291
5321
  }
5292
5322
  }
5293
5323
  }
@@ -13867,7 +13897,7 @@ function requireDist () {
13867
13897
 
13868
13898
  var distExports = requireDist();
13869
13899
 
13870
- var version = "1.57.1";
13900
+ var version = "1.57.3";
13871
13901
  var PACKAGE = {
13872
13902
  version: version};
13873
13903
 
@@ -14481,6 +14511,9 @@ class AbstractRemote {
14481
14511
  if (!res.ok || !res.body) {
14482
14512
  const text = await res.text();
14483
14513
  this.logger.error(`Could not POST streaming to ${path} - ${res.status} - ${res.statusText}: ${text}`);
14514
+ if (res.status === 401) {
14515
+ this.invalidateCredentials();
14516
+ }
14484
14517
  const error = new Error(`HTTP ${res.statusText}: ${text}`);
14485
14518
  error.status = res.status;
14486
14519
  throw error;
@@ -14737,6 +14770,7 @@ class AbstractStreamingSyncImplementation extends BaseObserver {
14737
14770
  async _uploadAllCrud(signal) {
14738
14771
  return this.obtainLock({
14739
14772
  type: LockType.CRUD,
14773
+ signal,
14740
14774
  callback: async () => {
14741
14775
  /**
14742
14776
  * Keep track of the first item in the CRUD queue for the last `uploadCrud` iteration.
@@ -16361,7 +16395,7 @@ SELECT * FROM crud_entries;
16361
16395
  }
16362
16396
  /**
16363
16397
  * Open a read-only transaction.
16364
- * Read transactions can run concurrently to a write transaction.
16398
+ * When multiple connections are available, read transactions can run concurrently to a write transaction.
16365
16399
  * Changes from any write transaction are not visible to read transactions started before it.
16366
16400
  *
16367
16401
  * @param callback - Function to execute within the transaction