@powersync/web 0.0.0-dev-20260225163712 → 0.0.0-dev-20260226160529

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 (33) hide show
  1. package/dist/26d61ca9f5694d064635.wasm +0 -0
  2. package/dist/b4c6283dc473b6b3fd24.wasm +0 -0
  3. package/dist/c78985091a0b22aaef03.wasm +0 -0
  4. package/dist/ca59e199e1138b553fad.wasm +0 -0
  5. package/dist/index.umd.js +299 -180
  6. package/dist/index.umd.js.map +1 -1
  7. package/dist/worker/SharedSyncImplementation.umd.js +302 -276
  8. package/dist/worker/SharedSyncImplementation.umd.js.map +1 -1
  9. package/dist/worker/WASQLiteDB.umd.js +303 -277
  10. package/dist/worker/WASQLiteDB.umd.js.map +1 -1
  11. package/dist/worker/{node_modules_pnpm_journeyapps_wa-sqlite_0_0_0-dev-20260225162137_node_modules_journeyapps_wa--416f63.umd.js → node_modules_pnpm_journeyapps_wa-sqlite_0_0_0-dev-20260226145021_node_modules_journeyapps_wa--0e69f0.umd.js} +12 -12
  12. package/dist/worker/{node_modules_pnpm_journeyapps_wa-sqlite_0_0_0-dev-20260225162137_node_modules_journeyapps_wa--416f63.umd.js.map → node_modules_pnpm_journeyapps_wa-sqlite_0_0_0-dev-20260226145021_node_modules_journeyapps_wa--0e69f0.umd.js.map} +1 -1
  13. package/dist/worker/{node_modules_pnpm_journeyapps_wa-sqlite_0_0_0-dev-20260225162137_node_modules_journeyapps_wa--f08dda.umd.js → node_modules_pnpm_journeyapps_wa-sqlite_0_0_0-dev-20260226145021_node_modules_journeyapps_wa--1787c2.umd.js} +16 -16
  14. package/dist/worker/{node_modules_pnpm_journeyapps_wa-sqlite_0_0_0-dev-20260225162137_node_modules_journeyapps_wa--f08dda.umd.js.map → node_modules_pnpm_journeyapps_wa-sqlite_0_0_0-dev-20260226145021_node_modules_journeyapps_wa--1787c2.umd.js.map} +1 -1
  15. package/dist/worker/{node_modules_pnpm_journeyapps_wa-sqlite_0_0_0-dev-20260225162137_node_modules_journeyapps_wa--3f11fc.umd.js → node_modules_pnpm_journeyapps_wa-sqlite_0_0_0-dev-20260226145021_node_modules_journeyapps_wa--24f702.umd.js} +270 -151
  16. package/dist/worker/node_modules_pnpm_journeyapps_wa-sqlite_0_0_0-dev-20260226145021_node_modules_journeyapps_wa--24f702.umd.js.map +1 -0
  17. package/dist/worker/{node_modules_pnpm_journeyapps_wa-sqlite_0_0_0-dev-20260225162137_node_modules_journeyapps_wa--8c697a.umd.js → node_modules_pnpm_journeyapps_wa-sqlite_0_0_0-dev-20260226145021_node_modules_journeyapps_wa--4e15a2.umd.js} +8 -8
  18. package/dist/worker/{node_modules_pnpm_journeyapps_wa-sqlite_0_0_0-dev-20260225162137_node_modules_journeyapps_wa--8c697a.umd.js.map → node_modules_pnpm_journeyapps_wa-sqlite_0_0_0-dev-20260226145021_node_modules_journeyapps_wa--4e15a2.umd.js.map} +1 -1
  19. package/dist/worker/{node_modules_pnpm_journeyapps_wa-sqlite_0_0_0-dev-20260225162137_node_modules_journeyapps_wa--2cbf50.umd.js → node_modules_pnpm_journeyapps_wa-sqlite_0_0_0-dev-20260226145021_node_modules_journeyapps_wa--7ba318.umd.js} +8 -8
  20. package/dist/worker/{node_modules_pnpm_journeyapps_wa-sqlite_0_0_0-dev-20260225162137_node_modules_journeyapps_wa--2cbf50.umd.js.map → node_modules_pnpm_journeyapps_wa-sqlite_0_0_0-dev-20260226145021_node_modules_journeyapps_wa--7ba318.umd.js.map} +1 -1
  21. package/dist/worker/{node_modules_pnpm_journeyapps_wa-sqlite_0_0_0-dev-20260225162137_node_modules_journeyapps_wa--dccfb9.umd.js → node_modules_pnpm_journeyapps_wa-sqlite_0_0_0-dev-20260226145021_node_modules_journeyapps_wa--919198.umd.js} +8 -8
  22. package/dist/worker/{node_modules_pnpm_journeyapps_wa-sqlite_0_0_0-dev-20260225162137_node_modules_journeyapps_wa--dccfb9.umd.js.map → node_modules_pnpm_journeyapps_wa-sqlite_0_0_0-dev-20260226145021_node_modules_journeyapps_wa--919198.umd.js.map} +1 -1
  23. package/dist/worker/{node_modules_pnpm_journeyapps_wa-sqlite_0_0_0-dev-20260225162137_node_modules_journeyapps_wa--f02f25.umd.js → node_modules_pnpm_journeyapps_wa-sqlite_0_0_0-dev-20260226145021_node_modules_journeyapps_wa--997c14.umd.js} +8 -8
  24. package/dist/worker/{node_modules_pnpm_journeyapps_wa-sqlite_0_0_0-dev-20260225162137_node_modules_journeyapps_wa--f02f25.umd.js.map → node_modules_pnpm_journeyapps_wa-sqlite_0_0_0-dev-20260226145021_node_modules_journeyapps_wa--997c14.umd.js.map} +1 -1
  25. package/dist/worker/{node_modules_pnpm_journeyapps_wa-sqlite_0_0_0-dev-20260225162137_node_modules_journeyapps_wa--2a0897.umd.js → node_modules_pnpm_journeyapps_wa-sqlite_0_0_0-dev-20260226145021_node_modules_journeyapps_wa--a6ce73.umd.js} +12 -12
  26. package/dist/worker/{node_modules_pnpm_journeyapps_wa-sqlite_0_0_0-dev-20260225162137_node_modules_journeyapps_wa--2a0897.umd.js.map → node_modules_pnpm_journeyapps_wa-sqlite_0_0_0-dev-20260226145021_node_modules_journeyapps_wa--a6ce73.umd.js.map} +1 -1
  27. package/lib/tsconfig.tsbuildinfo +1 -1
  28. package/package.json +5 -5
  29. package/dist/0b773f34701fc3938b2f.wasm +0 -0
  30. package/dist/687fe6480511183aa1de.wasm +0 -0
  31. package/dist/87c58d5d82e1759b558e.wasm +0 -0
  32. package/dist/90aaeb7a1019ddabcbd4.wasm +0 -0
  33. package/dist/worker/node_modules_pnpm_journeyapps_wa-sqlite_0_0_0-dev-20260225162137_node_modules_journeyapps_wa--3f11fc.umd.js.map +0 -1
@@ -1,9 +1,9 @@
1
1
  "use strict";
2
- (self["webpackChunksdk_web"] = self["webpackChunksdk_web"] || []).push([["node_modules_pnpm_journeyapps_wa-sqlite_0_0_0-dev-20260225162137_node_modules_journeyapps_wa--3f11fc"],{
2
+ (self["webpackChunksdk_web"] = self["webpackChunksdk_web"] || []).push([["node_modules_pnpm_journeyapps_wa-sqlite_0_0_0-dev-20260226145021_node_modules_journeyapps_wa--24f702"],{
3
3
 
4
- /***/ "../../node_modules/.pnpm/@journeyapps+wa-sqlite@0.0.0-dev-20260225162137/node_modules/@journeyapps/wa-sqlite/src/FacadeVFS.js"
4
+ /***/ "../../node_modules/.pnpm/@journeyapps+wa-sqlite@0.0.0-dev-20260226145021/node_modules/@journeyapps/wa-sqlite/src/FacadeVFS.js"
5
5
  /*!*************************************************************************************************************************************!*\
6
- !*** ../../node_modules/.pnpm/@journeyapps+wa-sqlite@0.0.0-dev-20260225162137/node_modules/@journeyapps/wa-sqlite/src/FacadeVFS.js ***!
6
+ !*** ../../node_modules/.pnpm/@journeyapps+wa-sqlite@0.0.0-dev-20260226145021/node_modules/@journeyapps/wa-sqlite/src/FacadeVFS.js ***!
7
7
  \*************************************************************************************************************************************/
8
8
  (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
9
9
 
@@ -11,7 +11,7 @@ __webpack_require__.r(__webpack_exports__);
11
11
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
12
12
  /* harmony export */ FacadeVFS: () => (/* binding */ FacadeVFS)
13
13
  /* harmony export */ });
14
- /* harmony import */ var _VFS_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./VFS.js */ "../../node_modules/.pnpm/@journeyapps+wa-sqlite@0.0.0-dev-20260225162137/node_modules/@journeyapps/wa-sqlite/src/VFS.js");
14
+ /* harmony import */ var _VFS_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./VFS.js */ "../../node_modules/.pnpm/@journeyapps+wa-sqlite@0.0.0-dev-20260226145021/node_modules/@journeyapps/wa-sqlite/src/VFS.js");
15
15
  // Copyright 2024 Roy T. Hashimoto. All Rights Reserved.
16
16
 
17
17
 
@@ -735,9 +735,9 @@ class DataViewProxy {
735
735
 
736
736
  /***/ },
737
737
 
738
- /***/ "../../node_modules/.pnpm/@journeyapps+wa-sqlite@0.0.0-dev-20260225162137/node_modules/@journeyapps/wa-sqlite/src/VFS.js"
738
+ /***/ "../../node_modules/.pnpm/@journeyapps+wa-sqlite@0.0.0-dev-20260226145021/node_modules/@journeyapps/wa-sqlite/src/VFS.js"
739
739
  /*!*******************************************************************************************************************************!*\
740
- !*** ../../node_modules/.pnpm/@journeyapps+wa-sqlite@0.0.0-dev-20260225162137/node_modules/@journeyapps/wa-sqlite/src/VFS.js ***!
740
+ !*** ../../node_modules/.pnpm/@journeyapps+wa-sqlite@0.0.0-dev-20260226145021/node_modules/@journeyapps/wa-sqlite/src/VFS.js ***!
741
741
  \*******************************************************************************************************************************/
742
742
  (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
743
743
 
@@ -978,7 +978,7 @@ __webpack_require__.r(__webpack_exports__);
978
978
  /* harmony export */ SQLITE_UTF8: () => (/* reexport safe */ _sqlite_constants_js__WEBPACK_IMPORTED_MODULE_0__.SQLITE_UTF8),
979
979
  /* harmony export */ SQLITE_WARNING: () => (/* reexport safe */ _sqlite_constants_js__WEBPACK_IMPORTED_MODULE_0__.SQLITE_WARNING)
980
980
  /* harmony export */ });
981
- /* harmony import */ var _sqlite_constants_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./sqlite-constants.js */ "../../node_modules/.pnpm/@journeyapps+wa-sqlite@0.0.0-dev-20260225162137/node_modules/@journeyapps/wa-sqlite/src/sqlite-constants.js");
981
+ /* harmony import */ var _sqlite_constants_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./sqlite-constants.js */ "../../node_modules/.pnpm/@journeyapps+wa-sqlite@0.0.0-dev-20260226145021/node_modules/@journeyapps/wa-sqlite/src/sqlite-constants.js");
982
982
  // Copyright 2024 Roy T. Hashimoto. All Rights Reserved.
983
983
 
984
984
 
@@ -1204,9 +1204,9 @@ const FILE_TYPE_MASK = [
1204
1204
 
1205
1205
  /***/ },
1206
1206
 
1207
- /***/ "../../node_modules/.pnpm/@journeyapps+wa-sqlite@0.0.0-dev-20260225162137/node_modules/@journeyapps/wa-sqlite/src/examples/LazyLock.js"
1207
+ /***/ "../../node_modules/.pnpm/@journeyapps+wa-sqlite@0.0.0-dev-20260226145021/node_modules/@journeyapps/wa-sqlite/src/examples/LazyLock.js"
1208
1208
  /*!*********************************************************************************************************************************************!*\
1209
- !*** ../../node_modules/.pnpm/@journeyapps+wa-sqlite@0.0.0-dev-20260225162137/node_modules/@journeyapps/wa-sqlite/src/examples/LazyLock.js ***!
1209
+ !*** ../../node_modules/.pnpm/@journeyapps+wa-sqlite@0.0.0-dev-20260226145021/node_modules/@journeyapps/wa-sqlite/src/examples/LazyLock.js ***!
1210
1210
  \*********************************************************************************************************************************************/
1211
1211
  (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
1212
1212
 
@@ -1214,7 +1214,7 @@ __webpack_require__.r(__webpack_exports__);
1214
1214
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
1215
1215
  /* harmony export */ LazyLock: () => (/* binding */ LazyLock)
1216
1216
  /* harmony export */ });
1217
- /* harmony import */ var _Lock_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Lock.js */ "../../node_modules/.pnpm/@journeyapps+wa-sqlite@0.0.0-dev-20260225162137/node_modules/@journeyapps/wa-sqlite/src/examples/Lock.js");
1217
+ /* harmony import */ var _Lock_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Lock.js */ "../../node_modules/.pnpm/@journeyapps+wa-sqlite@0.0.0-dev-20260226145021/node_modules/@journeyapps/wa-sqlite/src/examples/Lock.js");
1218
1218
 
1219
1219
 
1220
1220
  class LazyLock extends _Lock_js__WEBPACK_IMPORTED_MODULE_0__.Lock {
@@ -1239,7 +1239,7 @@ class LazyLock extends _Lock_js__WEBPACK_IMPORTED_MODULE_0__.Lock {
1239
1239
  }
1240
1240
 
1241
1241
  close() {
1242
- super.close
1242
+ super.close();
1243
1243
  this.#channel.onmessage = null;
1244
1244
  this.#channel.close();
1245
1245
  }
@@ -1308,9 +1308,9 @@ class LazyLock extends _Lock_js__WEBPACK_IMPORTED_MODULE_0__.Lock {
1308
1308
 
1309
1309
  /***/ },
1310
1310
 
1311
- /***/ "../../node_modules/.pnpm/@journeyapps+wa-sqlite@0.0.0-dev-20260225162137/node_modules/@journeyapps/wa-sqlite/src/examples/Lock.js"
1311
+ /***/ "../../node_modules/.pnpm/@journeyapps+wa-sqlite@0.0.0-dev-20260226145021/node_modules/@journeyapps/wa-sqlite/src/examples/Lock.js"
1312
1312
  /*!*****************************************************************************************************************************************!*\
1313
- !*** ../../node_modules/.pnpm/@journeyapps+wa-sqlite@0.0.0-dev-20260225162137/node_modules/@journeyapps/wa-sqlite/src/examples/Lock.js ***!
1313
+ !*** ../../node_modules/.pnpm/@journeyapps+wa-sqlite@0.0.0-dev-20260226145021/node_modules/@journeyapps/wa-sqlite/src/examples/Lock.js ***!
1314
1314
  \*****************************************************************************************************************************************/
1315
1315
  (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
1316
1316
 
@@ -1389,9 +1389,9 @@ class Lock {
1389
1389
 
1390
1390
  /***/ },
1391
1391
 
1392
- /***/ "../../node_modules/.pnpm/@journeyapps+wa-sqlite@0.0.0-dev-20260225162137/node_modules/@journeyapps/wa-sqlite/src/examples/OPFSWriteAheadVFS.js"
1392
+ /***/ "../../node_modules/.pnpm/@journeyapps+wa-sqlite@0.0.0-dev-20260226145021/node_modules/@journeyapps/wa-sqlite/src/examples/OPFSWriteAheadVFS.js"
1393
1393
  /*!******************************************************************************************************************************************************!*\
1394
- !*** ../../node_modules/.pnpm/@journeyapps+wa-sqlite@0.0.0-dev-20260225162137/node_modules/@journeyapps/wa-sqlite/src/examples/OPFSWriteAheadVFS.js ***!
1394
+ !*** ../../node_modules/.pnpm/@journeyapps+wa-sqlite@0.0.0-dev-20260226145021/node_modules/@journeyapps/wa-sqlite/src/examples/OPFSWriteAheadVFS.js ***!
1395
1395
  \******************************************************************************************************************************************************/
1396
1396
  (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
1397
1397
 
@@ -1399,12 +1399,10 @@ __webpack_require__.r(__webpack_exports__);
1399
1399
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
1400
1400
  /* harmony export */ OPFSWriteAheadVFS: () => (/* binding */ OPFSWriteAheadVFS)
1401
1401
  /* harmony export */ });
1402
- /* harmony import */ var _FacadeVFS_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../FacadeVFS.js */ "../../node_modules/.pnpm/@journeyapps+wa-sqlite@0.0.0-dev-20260225162137/node_modules/@journeyapps/wa-sqlite/src/FacadeVFS.js");
1403
- /* harmony import */ var _VFS_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../VFS.js */ "../../node_modules/.pnpm/@journeyapps+wa-sqlite@0.0.0-dev-20260225162137/node_modules/@journeyapps/wa-sqlite/src/VFS.js");
1404
- /* harmony import */ var _Lock_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Lock.js */ "../../node_modules/.pnpm/@journeyapps+wa-sqlite@0.0.0-dev-20260225162137/node_modules/@journeyapps/wa-sqlite/src/examples/Lock.js");
1405
- /* harmony import */ var _LazyLock_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./LazyLock.js */ "../../node_modules/.pnpm/@journeyapps+wa-sqlite@0.0.0-dev-20260225162137/node_modules/@journeyapps/wa-sqlite/src/examples/LazyLock.js");
1406
- /* harmony import */ var _WriteAhead_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./WriteAhead.js */ "../../node_modules/.pnpm/@journeyapps+wa-sqlite@0.0.0-dev-20260225162137/node_modules/@journeyapps/wa-sqlite/src/examples/WriteAhead.js");
1407
-
1402
+ /* harmony import */ var _FacadeVFS_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../FacadeVFS.js */ "../../node_modules/.pnpm/@journeyapps+wa-sqlite@0.0.0-dev-20260226145021/node_modules/@journeyapps/wa-sqlite/src/FacadeVFS.js");
1403
+ /* harmony import */ var _VFS_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../VFS.js */ "../../node_modules/.pnpm/@journeyapps+wa-sqlite@0.0.0-dev-20260226145021/node_modules/@journeyapps/wa-sqlite/src/VFS.js");
1404
+ /* harmony import */ var _LazyLock_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./LazyLock.js */ "../../node_modules/.pnpm/@journeyapps+wa-sqlite@0.0.0-dev-20260226145021/node_modules/@journeyapps/wa-sqlite/src/examples/LazyLock.js");
1405
+ /* harmony import */ var _WriteAhead_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./WriteAhead.js */ "../../node_modules/.pnpm/@journeyapps+wa-sqlite@0.0.0-dev-20260226145021/node_modules/@journeyapps/wa-sqlite/src/examples/WriteAhead.js");
1408
1406
 
1409
1407
 
1410
1408
 
@@ -1431,8 +1429,10 @@ const finalizationRegistry = new FinalizationRegistry((/** @type {() => void} */
1431
1429
  * @property {'normal'|'exclusive'|null} [lockingMode]
1432
1430
  * @property {number} [lockState] SQLITE_LOCK_*
1433
1431
  * @property {LazyLock} [readLock]
1434
- * @property {Lock} [writeLock]
1432
+ * @property {LazyLock} [writeLock]
1433
+ * @property {'none'|'read'|'write'|'readwrite'} [useLazyLock]
1435
1434
  * @property {number} [timeout]
1435
+ * @property {0|1|2|3} [synchronous]
1436
1436
  *
1437
1437
  * @property {WriteAhead} [writeAhead]
1438
1438
  */
@@ -1556,14 +1556,17 @@ class OPFSWriteAheadVFS extends _FacadeVFS_js__WEBPACK_IMPORTED_MODULE_0__.Facad
1556
1556
  // Initialize database file state.
1557
1557
  file.accessHandle = file.retryResult.accessHandle;
1558
1558
  file.journalHandle = file.retryResult.journalHandle;
1559
+ file.waHandle = file.retryResult.waHandle;
1559
1560
  file.writeAhead = file.retryResult.writeAhead;
1560
1561
  file.retryResult = null;
1561
1562
 
1562
1563
  file.lockState = _VFS_js__WEBPACK_IMPORTED_MODULE_1__.SQLITE_LOCK_NONE;
1563
1564
  file.lockingMode = null;
1564
- file.readLock = new _LazyLock_js__WEBPACK_IMPORTED_MODULE_3__.LazyLock(`${zName}#read`);
1565
- file.writeLock = new _Lock_js__WEBPACK_IMPORTED_MODULE_2__.Lock(`${zName}#write`);
1565
+ file.readLock = new _LazyLock_js__WEBPACK_IMPORTED_MODULE_2__.LazyLock(`${zName}#read`);
1566
+ file.writeLock = new _LazyLock_js__WEBPACK_IMPORTED_MODULE_2__.LazyLock(`${zName}#write`);
1567
+ file.useLazyLock = 'readwrite';
1566
1568
  file.timeout = -1;
1569
+ file.synchronous = 1; // NORMAL
1567
1570
  file.useWriteAhead = true;
1568
1571
  file.writeHint = null;
1569
1572
  } else if (flags & _VFS_js__WEBPACK_IMPORTED_MODULE_1__.SQLITE_OPEN_MAIN_JOURNAL) {
@@ -1813,8 +1816,8 @@ class OPFSWriteAheadVFS extends _FacadeVFS_js__WEBPACK_IMPORTED_MODULE_0__.Facad
1813
1816
  const file = this.mapIdToFile.get(fileId);
1814
1817
  if (file.flags & _VFS_js__WEBPACK_IMPORTED_MODULE_1__.SQLITE_OPEN_MAIN_DB) {
1815
1818
  if (file.useWriteAhead) {
1816
- // TODO: Track PRAGMA synchronous setting.
1817
- file.writeAhead.sync('normal');
1819
+ const durability = file.synchronous > 1 ? 'strict' : 'relaxed';
1820
+ file.writeAhead.sync({ durability });
1818
1821
  } else {
1819
1822
  file.accessHandle.flush();
1820
1823
  }
@@ -1879,18 +1882,35 @@ class OPFSWriteAheadVFS extends _FacadeVFS_js__WEBPACK_IMPORTED_MODULE_0__.Facad
1879
1882
  file.useWriteAhead = false;
1880
1883
  }
1881
1884
 
1882
- if (file.writeHint || file.readLock.mode !== 'shared') {
1883
- // Asynchronous lock acquisition is needed. Set retryResult to
1884
- // non-null so when SQLite calls jUnlock() it knows not to reset
1885
- // any locks we have in progress.
1886
- file.retryResult = {};
1887
- this._module.retryOps.push(this.#retryLock(pFile, lockType));
1888
- return _VFS_js__WEBPACK_IMPORTED_MODULE_1__.SQLITE_BUSY;
1885
+ // There are three distinct cases. In each case if the required
1886
+ // lock is already held then we can proceed synchronously.
1887
+ // Otherwise we need to acquire state asynchronously and retry.
1888
+ if (!file.writeHint) {
1889
+ // Case 1: Read transaction with write-ahead logging.
1890
+ if (!file.readLock.acquireIfHeld('shared')) {
1891
+ file.retryResult = {};
1892
+ this._module.retryOps.push(this.#retryLockRead(file));
1893
+ return _VFS_js__WEBPACK_IMPORTED_MODULE_1__.SQLITE_BUSY;
1894
+ } else {
1895
+ file.writeAhead.isolateForRead();
1896
+ }
1897
+ } else {
1898
+ if (file.useWriteAhead) {
1899
+ // Case 2: Write transaction with write-ahead logging.
1900
+ if (!file.writeLock.acquireIfHeld('exclusive')) {
1901
+ file.retryResult = {};
1902
+ this._module.retryOps.push(this.#retryLockWrite(file));
1903
+ return _VFS_js__WEBPACK_IMPORTED_MODULE_1__.SQLITE_BUSY;
1904
+ } else {
1905
+ file.writeAhead.isolateForWrite();
1906
+ }
1907
+ } else {
1908
+ // Case 3: Transaction without write-ahead logging.
1909
+ file.retryResult = {};
1910
+ this._module.retryOps.push(this.#retryLockExclusive(file));
1911
+ return _VFS_js__WEBPACK_IMPORTED_MODULE_1__.SQLITE_BUSY;
1912
+ }
1889
1913
  }
1890
-
1891
- // This is a read transaction and we can get the shared
1892
- // lock synchronously.
1893
- file.readLock.acquireIfHeld('shared');
1894
1914
  } else if (file.retryResult instanceof Error) {
1895
1915
  throw file.retryResult;
1896
1916
  }
@@ -1898,13 +1918,6 @@ class OPFSWriteAheadVFS extends _FacadeVFS_js__WEBPACK_IMPORTED_MODULE_0__.Facad
1898
1918
  // We have acquired the needed locks, either synchronously or
1899
1919
  // via retry.
1900
1920
  file.retryResult = null;
1901
- if (file.writeHint === null) {
1902
- // Ensure that our read-only view of the database does not change
1903
- // while in the SHARED lock state. The corresponding method
1904
- // isolateForWrite() is not called in this method, but instead
1905
- // in retryLock() because it is asynchronous.
1906
- file.writeAhead.isolateForRead();
1907
- }
1908
1921
  } else if (lockType >= _VFS_js__WEBPACK_IMPORTED_MODULE_1__.SQLITE_LOCK_RESERVED && !file.writeLock.mode) {
1909
1922
  // This is a write transaction but we don't already have the write
1910
1923
  // lock. This happens when the write hint was not used, which this
@@ -1943,15 +1956,28 @@ class OPFSWriteAheadVFS extends _FacadeVFS_js__WEBPACK_IMPORTED_MODULE_0__.Facad
1943
1956
  file.writeAhead.rejoin();
1944
1957
  }
1945
1958
 
1946
- file.writeLock.release();
1947
- if (file.readLock.mode === 'exclusive') {
1948
- // TODO: Consider lazy release here as well.
1949
- file.readLock.release();
1950
- } else {
1951
- file.readLock.releaseLazy();
1959
+ // Release any locks.
1960
+ switch (file.useLazyLock) {
1961
+ case 'none':
1962
+ file.writeLock.release();
1963
+ file.readLock.release();
1964
+ break;
1965
+ case 'read':
1966
+ file.writeLock.release();
1967
+ file.readLock.releaseLazy();
1968
+ break;
1969
+ case 'write':
1970
+ file.writeLock.releaseLazy();
1971
+ file.readLock.release();
1972
+ break;
1973
+ case 'readwrite':
1974
+ file.writeLock.releaseLazy();
1975
+ file.readLock.releaseLazy();
1976
+ break;
1952
1977
  }
1953
- file.writeHint = null;
1954
1978
 
1979
+ // Reset state for the next transaction.
1980
+ file.writeHint = null;
1955
1981
  if (file.lockingMode === 'normal') {
1956
1982
  file.useWriteAhead = true;
1957
1983
  }
@@ -2035,6 +2061,30 @@ class OPFSWriteAheadVFS extends _FacadeVFS_js__WEBPACK_IMPORTED_MODULE_0__.Facad
2035
2061
  break;
2036
2062
  }
2037
2063
  break;
2064
+ case 'synchronous':
2065
+ if (value !== null) {
2066
+ switch (value.toLowerCase()) {
2067
+ case 'off':
2068
+ case '0':
2069
+ file.synchronous = 0;
2070
+ break;
2071
+ case 'normal':
2072
+ case '1':
2073
+ file.synchronous = 1;
2074
+ break;
2075
+ case 'full':
2076
+ case '2':
2077
+ file.synchronous = 2;
2078
+ break;
2079
+ case 'extra':
2080
+ case '3':
2081
+ file.synchronous = 3;
2082
+ break;
2083
+ default:
2084
+ throw new Error(`unexpected synchronous value: ${value}`);
2085
+ }
2086
+ }
2087
+ break;
2038
2088
  case 'vfs_trace':
2039
2089
  // This is a trace feature for debugging only.
2040
2090
  if (value !== null) {
@@ -2044,15 +2094,13 @@ class OPFSWriteAheadVFS extends _FacadeVFS_js__WEBPACK_IMPORTED_MODULE_0__.Facad
2044
2094
  return _VFS_js__WEBPACK_IMPORTED_MODULE_1__.SQLITE_OK;
2045
2095
  case 'wal_autocheckpoint':
2046
2096
  if (value !== null) {
2047
- const pageCount = parseInt(value);
2048
- if (pageCount > 0) {
2049
- file.writeAhead.options.autoCheckpointPages = pageCount;
2050
- }
2097
+ const nPages = parseInt(value);
2098
+ file.writeAhead.options.autoCheckpointPages = Math.max(nPages, 0);
2051
2099
  }
2052
2100
  break;
2053
2101
  case 'wal_checkpoint':
2054
2102
  const checkpointMode = (value ?? 'passive').toLowerCase();
2055
- switch ((value ?? 'passive').toLowerCase()) {
2103
+ switch (checkpointMode) {
2056
2104
  case 'passive':
2057
2105
  case 'full':
2058
2106
  case 'restart':
@@ -2064,19 +2112,41 @@ class OPFSWriteAheadVFS extends _FacadeVFS_js__WEBPACK_IMPORTED_MODULE_0__.Facad
2064
2112
  this._module.pendingOps.push(this.#pendingCheckpoint(file, checkpointMode));
2065
2113
  break;
2066
2114
  case 'noop':
2067
- // Return the current size of the write-ahead file. SQLite
2068
- // returns different information, but that is not feasible
2069
- // from a VFS.
2070
- {
2071
- const s = file.writeAhead.getWriteAheadSize().toString();
2072
- const ptr = this._module._sqlite3_malloc64(s.length + 1);
2073
- this._module.stringToUTF8(s, ptr, s.length + 1);
2074
- pArg.setUint32(0, ptr, true);
2075
- }
2076
2115
  break;
2077
2116
  default:
2078
2117
  throw new Error(`unexpected wal_checkpoint mode: ${value}`);
2079
2118
  }
2119
+
2120
+ // Return the approximate size of the write-ahead data (which
2121
+ // may be smaller than the actual file size). SQLite returns
2122
+ // different information, but that is not feasible from a VFS.
2123
+ {
2124
+ const s = file.writeAhead.getWriteAheadSize().toString();
2125
+ const ptr = this._module._sqlite3_malloc64(s.length + 1);
2126
+ this._module.stringToUTF8(s, ptr, s.length + 1);
2127
+ pArg.setUint32(0, ptr, true);
2128
+ }
2129
+ return _VFS_js__WEBPACK_IMPORTED_MODULE_1__.SQLITE_OK;
2130
+ case 'lazy_lock':
2131
+ if (value !== null) {
2132
+ const useLazyLock = value.toLowerCase();
2133
+ switch (useLazyLock) {
2134
+ case 'read':
2135
+ case 'write':
2136
+ case 'readwrite':
2137
+ case 'none':
2138
+ file.useLazyLock = useLazyLock;
2139
+ break;
2140
+ default:
2141
+ throw new Error(`unexpected value for lazy_lock: ${value}`);
2142
+ }
2143
+ }
2144
+ {
2145
+ const s = file.useLazyLock;
2146
+ const ptr = this._module._sqlite3_malloc64(s.length + 1);
2147
+ this._module.stringToUTF8(s, ptr, s.length + 1);
2148
+ pArg.setUint32(0, ptr, true);
2149
+ }
2080
2150
  return _VFS_js__WEBPACK_IMPORTED_MODULE_1__.SQLITE_OK;
2081
2151
  case 'write_ahead':
2082
2152
  // For testing purposes only: enable or disable write-ahead mode.
@@ -2205,61 +2275,81 @@ class OPFSWriteAheadVFS extends _FacadeVFS_js__WEBPACK_IMPORTED_MODULE_0__.Facad
2205
2275
  }
2206
2276
 
2207
2277
  /**
2208
- *
2278
+ * Asynchronous PRAGMA operation to checkpoint the write-ahead log.
2209
2279
  * @param {FileEntry} file
2210
2280
  * @param {'passive'|'full'|'restart'|'truncate'} mode
2211
2281
  */
2212
2282
  async #pendingCheckpoint(file, mode) {
2213
2283
  try {
2214
- const ckptLockOptions = { ifAvailable: mode === 'passive' };
2215
2284
  if (mode !== 'passive') {
2216
- await file.readLock.acquire('exclusive', file.timeout);
2217
2285
  await file.writeLock.acquire('exclusive');
2218
2286
  }
2219
2287
 
2220
2288
  await file.writeAhead.checkpoint(mode);
2221
2289
  } catch (e) {
2222
- console.error(e);
2290
+ if (e.name === 'AbortError') {
2291
+ e.code = _VFS_js__WEBPACK_IMPORTED_MODULE_1__.SQLITE_BUSY;
2292
+ }
2293
+ throw e;
2223
2294
  } finally {
2224
- file.readLock.release();
2225
2295
  file.writeLock.release();
2226
2296
  }
2227
2297
  }
2228
2298
 
2229
2299
  /**
2230
- * Handle asynchronous jLock() tasks.
2231
- * @param {number} pFile
2232
- * @param {number} lockType
2300
+ * @param {FileEntry} file
2233
2301
  */
2234
- async #retryLock(pFile, lockType) {
2235
- const file = this.mapIdToFile.get(pFile);
2302
+ async #retryLockRead(file) {
2236
2303
  try {
2237
- switch (file.writeHint) {
2238
- case 'reserved':
2239
- case 'exclusive':
2240
- if (file.useWriteAhead) {
2241
- // Write-ahead transactions only need writeLock, not readLock.
2242
- await file.writeLock.acquire('exclusive', file.timeout);
2243
- file.writeAhead.isolateForWrite();
2244
- } else {
2245
- // This transaction will write directly to the database,
2246
- // i.e. not using write-ahead. Get exclusive access.
2247
- await file.readLock.acquire('exclusive', file.timeout);
2248
- await file.writeLock.acquire('exclusive');
2304
+ await file.readLock.acquire('shared', file.timeout);
2305
+ file.writeAhead.isolateForRead();
2306
+ file.retryResult = {};
2307
+ } catch (e) {
2308
+ if (file.readLock.mode) {
2309
+ file.readLock.release();
2310
+ }
2311
+ file.retryResult = e;
2312
+ }
2313
+ }
2249
2314
 
2250
- // Transfer everything in write-ahead to the OPFS file.
2251
- await file.writeAhead.checkpoint('restart');
2252
- }
2253
- break;
2254
- default:
2255
- // This transaction will only read.
2256
- await file.readLock.acquire('shared', file.timeout);
2257
- break;
2315
+ /**
2316
+ * @param {FileEntry} file
2317
+ */
2318
+ async #retryLockWrite(file) {
2319
+ try {
2320
+ // Write-ahead transactions only need writeLock, not readLock.
2321
+ await file.writeLock.acquire('exclusive', file.timeout);
2322
+ file.writeAhead.isolateForWrite();
2323
+ file.retryResult = {};
2324
+ } catch (e) {
2325
+ if (file.writeLock.mode) {
2326
+ file.writeLock.release();
2258
2327
  }
2328
+ file.retryResult = e;
2329
+ }
2330
+ }
2331
+
2332
+ /**
2333
+ * @param {FileEntry} file
2334
+ */
2335
+ async #retryLockExclusive(file) {
2336
+ try {
2337
+ // This transaction will write directly to the database,
2338
+ // i.e. not using write-ahead. Get exclusive access.
2339
+ await file.readLock.acquire('exclusive', file.timeout);
2340
+ await file.writeLock.acquire('exclusive', file.timeout);
2341
+
2342
+ // Transfer everything in write-ahead to the OPFS file.
2343
+ await file.writeAhead.checkpoint('restart');
2259
2344
  file.retryResult = {};
2260
2345
  } catch (e) {
2346
+ if (file.writeLock.mode) {
2347
+ file.writeLock.release();
2348
+ }
2349
+ if (file.readLock.mode) {
2350
+ file.readLock.release();
2351
+ }
2261
2352
  file.retryResult = e;
2262
- return;
2263
2353
  }
2264
2354
  }
2265
2355
 
@@ -2347,7 +2437,7 @@ class OPFSWriteAheadVFS extends _FacadeVFS_js__WEBPACK_IMPORTED_MODULE_0__.Facad
2347
2437
  });
2348
2438
 
2349
2439
  // Create the write-ahead manager.
2350
- const writeAhead = new _WriteAhead_js__WEBPACK_IMPORTED_MODULE_4__.WriteAhead(
2440
+ const writeAhead = new _WriteAhead_js__WEBPACK_IMPORTED_MODULE_3__.WriteAhead(
2351
2441
  zName,
2352
2442
  accessHandle,
2353
2443
  waHandle,
@@ -2368,9 +2458,9 @@ class OPFSWriteAheadVFS extends _FacadeVFS_js__WEBPACK_IMPORTED_MODULE_0__.Facad
2368
2458
 
2369
2459
  /***/ },
2370
2460
 
2371
- /***/ "../../node_modules/.pnpm/@journeyapps+wa-sqlite@0.0.0-dev-20260225162137/node_modules/@journeyapps/wa-sqlite/src/examples/WriteAhead.js"
2461
+ /***/ "../../node_modules/.pnpm/@journeyapps+wa-sqlite@0.0.0-dev-20260226145021/node_modules/@journeyapps/wa-sqlite/src/examples/WriteAhead.js"
2372
2462
  /*!***********************************************************************************************************************************************!*\
2373
- !*** ../../node_modules/.pnpm/@journeyapps+wa-sqlite@0.0.0-dev-20260225162137/node_modules/@journeyapps/wa-sqlite/src/examples/WriteAhead.js ***!
2463
+ !*** ../../node_modules/.pnpm/@journeyapps+wa-sqlite@0.0.0-dev-20260226145021/node_modules/@journeyapps/wa-sqlite/src/examples/WriteAhead.js ***!
2374
2464
  \***********************************************************************************************************************************************/
2375
2465
  (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
2376
2466
 
@@ -2378,10 +2468,10 @@ __webpack_require__.r(__webpack_exports__);
2378
2468
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
2379
2469
  /* harmony export */ WriteAhead: () => (/* binding */ WriteAhead)
2380
2470
  /* harmony export */ });
2381
- /* harmony import */ var _Lock_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Lock.js */ "../../node_modules/.pnpm/@journeyapps+wa-sqlite@0.0.0-dev-20260225162137/node_modules/@journeyapps/wa-sqlite/src/examples/Lock.js");
2471
+ /* harmony import */ var _Lock_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Lock.js */ "../../node_modules/.pnpm/@journeyapps+wa-sqlite@0.0.0-dev-20260226145021/node_modules/@journeyapps/wa-sqlite/src/examples/Lock.js");
2382
2472
 
2383
2473
 
2384
- const DEFAULT_AUTOCHECKPOINT_PAGES = 1_000;
2474
+ const DEFAULT_AUTOCHECKPOINT_PAGES = 1000;
2385
2475
  const DEFAULT_BACKSTOP_INTERVAL = 30_000;
2386
2476
 
2387
2477
  const SECTOR_SIZE = 4096;
@@ -2434,6 +2524,7 @@ class WriteAhead {
2434
2524
  /** @type {Map<number, PageEntry>} */ #waOverlay = new Map();
2435
2525
  /** @type {Map<number, Transaction>} */ #mapIdToTx = new Map();
2436
2526
  /** @type {Map<number, Transaction>} */ #pendingTx = new Map();
2527
+ #mapIdToTxPageCount = 0;
2437
2528
 
2438
2529
  #broadcastChannel;
2439
2530
  /** @type {number} */ #backstopTimer;
@@ -2453,9 +2544,8 @@ class WriteAhead {
2453
2544
  // All the asynchronous initialization is done here.
2454
2545
  this.#ready = (async () => {
2455
2546
  // Disable checkpointing by other connections until we're ready.
2456
- await this.#updateTxIdLock();
2457
2547
  await navigator.locks.request(`${this.#zName}-ckpt`, async () => {
2458
- // This is just a barrier; nothing needs to be done here.
2548
+ await this.#updateTxIdLock();
2459
2549
  });
2460
2550
 
2461
2551
  // Load all the transactions from the WAL file.
@@ -2467,6 +2557,7 @@ class WriteAhead {
2467
2557
  for (const tx of this.#waFile.readAllTx()) {
2468
2558
  this.#activateTx(tx);
2469
2559
  }
2560
+ this.#updateTxIdLock(); // doesn't need await
2470
2561
 
2471
2562
  // Listen for transactions and checkpoints from other connections.
2472
2563
  this.#broadcastChannel = new BroadcastChannel(`${zName}#wa`);
@@ -2474,11 +2565,8 @@ class WriteAhead {
2474
2565
  this.#handleMessage(event);
2475
2566
  };
2476
2567
 
2477
- // Update our tx lock to reflect the current txId.
2478
- await this.#updateTxIdLock();
2479
-
2480
- // Schedule first backstop. The backstop is a guard against a crash
2481
- // in another context between persisting a transaction and broadcasting
2568
+ // Schedule backstop. The backstop is a guard against a crash in
2569
+ // another context between persisting a transaction and broadcasting
2482
2570
  // it.
2483
2571
  this.#backstop();
2484
2572
  })();
@@ -2514,8 +2602,8 @@ class WriteAhead {
2514
2602
  this.#isolationState = 'read';
2515
2603
 
2516
2604
  if (this.#waFile.checkReset()) {
2517
- // The WAL file has been reset with a full checkpoint. Our view
2518
- // must be at the final transaction before the checkpoint for
2605
+ // The WAL file has been restarted after a full checkpoint. Our
2606
+ // view must be at the final transaction before the checkpoint for
2519
2607
  // that to have happened. The previous overlay is now stale. In
2520
2608
  // case we haven't received the checkpoint broadcast, make sure
2521
2609
  // the overlay is cleared.
@@ -2538,8 +2626,8 @@ class WriteAhead {
2538
2626
  this.#backstopTimer = null;
2539
2627
 
2540
2628
  if (this.#waFile.checkReset()) {
2541
- // The WAL file has been reset with a full checkpoint. Our view
2542
- // must be at the final transaction before the checkpoint for
2629
+ // The WAL file has been restarted after a full checkpoint. Our
2630
+ // view must be at the final transaction before the checkpoint for
2543
2631
  // that to have happened. The previous overlay is now stale. In
2544
2632
  // case we haven't received the checkpoint broadcast, make sure
2545
2633
  // the overlay is cleared.
@@ -2554,9 +2642,14 @@ class WriteAhead {
2554
2642
  if (this.#isolationState === 'write') {
2555
2643
  // Resume backstop after write isolation.
2556
2644
  this.#backstop();
2645
+
2646
+ // We need a place for a connection that only does write transactions
2647
+ // to auto-checkpoint. This the best place because writing is
2648
+ // complete.
2649
+ this.#autoCheckpoint();
2557
2650
  } else {
2558
2651
  // Catch up on new transactions that arrived while isolated.
2559
- this.#advanceTxId();
2652
+ this.#advanceTxId({ autoCheckpoint: true });
2560
2653
  }
2561
2654
  this.#isolationState = null;
2562
2655
  }
@@ -2629,13 +2722,11 @@ class WriteAhead {
2629
2722
  this.#activateTx(this.#txActive);
2630
2723
  this.#updateTxIdLock();
2631
2724
 
2725
+ // Send the transaction to other connections.
2632
2726
  const payload = { type: 'tx', tx: this.#txActive };
2633
- // this.#handleMessage(new MessageEvent('message', { data: payload }));
2634
- // this.#advanceTxId();
2727
+ this.#broadcastChannel.postMessage(payload);
2635
2728
  this.#txActive = null;
2636
2729
 
2637
- // Send the transaction to other connections.
2638
- this.#broadcastChannel.postMessage(payload);
2639
2730
  }
2640
2731
 
2641
2732
  rollback() {
@@ -2645,10 +2736,10 @@ class WriteAhead {
2645
2736
  }
2646
2737
 
2647
2738
  /**
2648
- * @param {'normal'|'full'} mode
2739
+ * @param {{durability: 'strict'|'relaxed'}} options
2649
2740
  */
2650
- sync(mode) {
2651
- if (mode === 'full') {
2741
+ sync(options) {
2742
+ if (options.durability === 'strict') {
2652
2743
  this.#waFile.accessHandle.flush();
2653
2744
  }
2654
2745
  }
@@ -2682,8 +2773,8 @@ class WriteAhead {
2682
2773
 
2683
2774
  /**
2684
2775
  * Return the known usage size of the write-ahead file. Note that the
2685
- * actual file size may be larger if this connection is not current
2686
- * or if the file has obsolete content past the current point.
2776
+ * actual file size may be larger than reported if this connection is
2777
+ * not current or if the file has obsolete content past the current point.
2687
2778
  * @returns {number}
2688
2779
  */
2689
2780
  getWriteAheadSize() {
@@ -2697,6 +2788,7 @@ class WriteAhead {
2697
2788
  #activateTx(tx) {
2698
2789
  // Transfer to the active collection of transactions.
2699
2790
  this.#mapIdToTx.set(tx.id, tx);
2791
+ this.#mapIdToTxPageCount += tx.pages.size;
2700
2792
 
2701
2793
  // Add transaction pages to the write-ahead overlay.
2702
2794
  for (const [offset, pageEntry] of tx.pages) {
@@ -2710,7 +2802,7 @@ class WriteAhead {
2710
2802
  * last broadcast transaction. Optionally, also advance through any
2711
2803
  * additional transactions in the WAL file to be fully current.
2712
2804
  *
2713
- * @param {{readToCurrent?: boolean}} options
2805
+ * @param {{readToCurrent?: boolean, autoCheckpoint?: boolean}} options
2714
2806
  */
2715
2807
  #advanceTxId(options = {}) {
2716
2808
  let didAdvance = false;
@@ -2742,6 +2834,21 @@ class WriteAhead {
2742
2834
  if (didAdvance) {
2743
2835
  // Publish our new view txId.
2744
2836
  this.#updateTxIdLock();
2837
+
2838
+ if (options.autoCheckpoint) {
2839
+ this.#autoCheckpoint();
2840
+ }
2841
+ }
2842
+ }
2843
+
2844
+ #autoCheckpoint() {
2845
+ // Perform an automatic checkpoint if enabled and needed. Automatic
2846
+ // checkpoints are passive, so this will not change the WAL file
2847
+ // usage or size.
2848
+ if (this.options.autoCheckpointPages > 0 &&
2849
+ this.#mapIdToTxPageCount >= this.options.autoCheckpointPages) {
2850
+ this.log?.(`%cauto-checkpoint`, 'background-color: lightgreen;');
2851
+ this.checkpoint('passive');
2745
2852
  }
2746
2853
  }
2747
2854
 
@@ -2767,24 +2874,8 @@ class WriteAhead {
2767
2874
  // Full checkpoint, use the current WAL file txId.
2768
2875
  ckptId = this.#waFile.txId;
2769
2876
 
2770
- // Wait for all connections to reach this txId. Each connection
2771
- // acquires a shared lock whose name contains the database name,
2772
- // the minimum and maximum txId it has in mapIdToTx. We want all
2773
- // maximum txId values to be ckptId.
2774
- let pendingLockNames = [];
2775
- do {
2776
- // Wait for connections with lower maximum txIds. When a
2777
- // connection advances its txId, it will release its previous
2778
- // lock and acquire a new one.
2779
- await Promise.all(
2780
- pendingLockNames.map(name => navigator.locks.request(name, async () => {}))
2781
- );
2782
-
2783
- // Refresh the list of locks with lower txIds.
2784
- pendingLockNames = (await this.#getTxIdLocks())
2785
- .filter(value => value.maxTxId < ckptId)
2786
- .map(value => value.name);
2787
- } while (pendingLockNames.length > 0);
2877
+ // Wait for all connections to reach this txId.
2878
+ await this.#waitForTxIdLocks(value => value.maxTxId >= ckptId);
2788
2879
  this.log?.(`%c#checkpoint full txId ${ckptId}`, 'background-color: lightgreen;');
2789
2880
  } else {
2790
2881
  // Not a full checkpoint, so find the lowest txId in use by any
@@ -2840,8 +2931,11 @@ class WriteAhead {
2840
2931
  }
2841
2932
 
2842
2933
  if (writtenOffsets.size > 0) {
2843
- // Ensure data is safely in the file.
2844
- this.#dbHandle.flush();
2934
+ if (ckptId == this.#waFile.txId) {
2935
+ // Ensure data is safely in the file.
2936
+ this.log?.(`%c#checkpoint flush database file`, 'background-color: lightgreen;');
2937
+ this.#dbHandle.flush();
2938
+ }
2845
2939
 
2846
2940
  // Notify other connections and ourselves of the checkpoint.
2847
2941
  this.#broadcastChannel.postMessage({
@@ -2852,6 +2946,9 @@ class WriteAhead {
2852
2946
  }
2853
2947
 
2854
2948
  if (options.isRestart) {
2949
+ // Wait for all connections to clear their overlay.
2950
+ await this.#waitForTxIdLocks(value => value.minTxId > ckptId);
2951
+
2855
2952
  this.#waFile.reset();
2856
2953
  }
2857
2954
  });
@@ -2880,6 +2977,7 @@ class WriteAhead {
2880
2977
 
2881
2978
  // Remove transaction.
2882
2979
  this.#mapIdToTx.delete(tx.id);
2980
+ this.#mapIdToTxPageCount -= tx.pages.size;
2883
2981
  }
2884
2982
  this.#updateTxIdLock();
2885
2983
  }
@@ -2896,7 +2994,7 @@ class WriteAhead {
2896
2994
  this.#pendingTx.set(tx.id, tx);
2897
2995
  if (this.#isolationState === null) {
2898
2996
  // Not in an isolated state, so advance our view of the database.
2899
- this.#advanceTxId();
2997
+ this.#advanceTxId({ autoCheckpoint: true });
2900
2998
  }
2901
2999
  }
2902
3000
  } else if (event.data.type === 'ckpt') {
@@ -2998,6 +3096,25 @@ class WriteAhead {
2998
3096
  }
2999
3097
  return null;
3000
3098
  }
3099
+
3100
+ /**
3101
+ * Wait for all txId locks that fail the provided predicate.
3102
+ * @param {(lock: {name: string, minTxId: number, maxTxId: number}) => boolean} predicate
3103
+ */
3104
+ async #waitForTxIdLocks(predicate) {
3105
+ /** @type {string[]} */ let failingLockNames = [];
3106
+ do {
3107
+ // Wait for all connections that fail the predicate.
3108
+ await Promise.all(
3109
+ failingLockNames.map(name => navigator.locks.request(name, async () => {}))
3110
+ );
3111
+
3112
+ // Refresh the list of failing locks.
3113
+ failingLockNames = (await this.#getTxIdLocks())
3114
+ .filter(value => !predicate(value))
3115
+ .map(value => value.name);
3116
+ } while (failingLockNames.length > 0);
3117
+ }
3001
3118
  }
3002
3119
 
3003
3120
  class WriteAheadFile {
@@ -3257,6 +3374,7 @@ class WriteAheadFile {
3257
3374
  #readFrame(offset) {
3258
3375
  const headerView = new DataView(new ArrayBuffer(WriteAheadFile.FRAME_HEADER_SIZE));
3259
3376
  if (this.accessHandle.read(headerView, { at: offset }) !== headerView.byteLength) {
3377
+ // EOF, not an error.
3260
3378
  return null;
3261
3379
  }
3262
3380
 
@@ -3264,6 +3382,8 @@ class WriteAheadFile {
3264
3382
  const frameSalt1 = headerView.getUint32(16);
3265
3383
  const frameSalt2 = headerView.getUint32(20);
3266
3384
  if (frameSalt1 !== this.salt1 || frameSalt2 !== this.salt2) {
3385
+ // Not necessarily an error, could be from a restart without
3386
+ // truncation.
3267
3387
  return null;
3268
3388
  }
3269
3389
 
@@ -3283,6 +3403,8 @@ class WriteAheadFile {
3283
3403
  checksum.update(payloadData);
3284
3404
  }
3285
3405
  if (!checksum.matches(headerView.getUint32(24), headerView.getUint32(28))) {
3406
+ // Not necessarily an error, could be from a restart without
3407
+ // truncation.
3286
3408
  return null;
3287
3409
  }
3288
3410
 
@@ -3295,6 +3417,9 @@ class WriteAheadFile {
3295
3417
  pageData: payloadData
3296
3418
  }
3297
3419
  } else if (frameType === WriteAheadFile.FRAME_TYPE_COMMIT) {
3420
+ // Flags byte is currently unused. A possible future use would be
3421
+ // to indicate an overwrite commit to trigger clearing the overlay.
3422
+ // This might allow a page size change by VACUUM.
3298
3423
  const flags = headerView.getUint8(1);
3299
3424
  return {
3300
3425
  frameType,
@@ -3362,14 +3487,8 @@ class Checksum {
3362
3487
  }
3363
3488
  }
3364
3489
 
3365
- class InvalidFrameError extends Error {
3366
- constructor(message) {
3367
- super(message);
3368
- this.name = 'InvalidFrameError';
3369
- }
3370
- }
3371
3490
 
3372
3491
  /***/ }
3373
3492
 
3374
3493
  }]);
3375
- //# sourceMappingURL=node_modules_pnpm_journeyapps_wa-sqlite_0_0_0-dev-20260225162137_node_modules_journeyapps_wa--3f11fc.umd.js.map
3494
+ //# sourceMappingURL=node_modules_pnpm_journeyapps_wa-sqlite_0_0_0-dev-20260226145021_node_modules_journeyapps_wa--24f702.umd.js.map