@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.
- package/dist/26d61ca9f5694d064635.wasm +0 -0
- package/dist/b4c6283dc473b6b3fd24.wasm +0 -0
- package/dist/c78985091a0b22aaef03.wasm +0 -0
- package/dist/ca59e199e1138b553fad.wasm +0 -0
- package/dist/index.umd.js +299 -180
- package/dist/index.umd.js.map +1 -1
- package/dist/worker/SharedSyncImplementation.umd.js +302 -276
- package/dist/worker/SharedSyncImplementation.umd.js.map +1 -1
- package/dist/worker/WASQLiteDB.umd.js +303 -277
- package/dist/worker/WASQLiteDB.umd.js.map +1 -1
- 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
- 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
- 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
- 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
- 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
- package/dist/worker/node_modules_pnpm_journeyapps_wa-sqlite_0_0_0-dev-20260226145021_node_modules_journeyapps_wa--24f702.umd.js.map +1 -0
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +5 -5
- package/dist/0b773f34701fc3938b2f.wasm +0 -0
- package/dist/687fe6480511183aa1de.wasm +0 -0
- package/dist/87c58d5d82e1759b558e.wasm +0 -0
- package/dist/90aaeb7a1019ddabcbd4.wasm +0 -0
- 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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
1403
|
-
/* harmony import */ var _VFS_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../VFS.js */ "../../node_modules/.pnpm/@journeyapps+wa-sqlite@0.0.0-dev-
|
|
1404
|
-
/* harmony import */ var
|
|
1405
|
-
/* harmony import */ var
|
|
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 {
|
|
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
|
|
1565
|
-
file.writeLock = new
|
|
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
|
-
|
|
1817
|
-
file.writeAhead.sync(
|
|
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
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
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
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
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
|
|
2048
|
-
|
|
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 (
|
|
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
|
-
|
|
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
|
-
*
|
|
2231
|
-
* @param {number} pFile
|
|
2232
|
-
* @param {number} lockType
|
|
2300
|
+
* @param {FileEntry} file
|
|
2233
2301
|
*/
|
|
2234
|
-
async #
|
|
2235
|
-
const file = this.mapIdToFile.get(pFile);
|
|
2302
|
+
async #retryLockRead(file) {
|
|
2236
2303
|
try {
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
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
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
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
|
|
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-
|
|
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-
|
|
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-
|
|
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 =
|
|
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
|
-
|
|
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
|
-
//
|
|
2478
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
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 {'
|
|
2739
|
+
* @param {{durability: 'strict'|'relaxed'}} options
|
|
2649
2740
|
*/
|
|
2650
|
-
sync(
|
|
2651
|
-
if (
|
|
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
|
|
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.
|
|
2771
|
-
|
|
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
|
-
|
|
2844
|
-
|
|
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-
|
|
3494
|
+
//# sourceMappingURL=node_modules_pnpm_journeyapps_wa-sqlite_0_0_0-dev-20260226145021_node_modules_journeyapps_wa--24f702.umd.js.map
|