@powersync/web 1.36.0 → 1.37.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.
- package/dist/index.umd.js +1127 -1235
- package/dist/index.umd.js.map +1 -1
- package/dist/worker/SharedSyncImplementation.umd.js +550 -3089
- package/dist/worker/SharedSyncImplementation.umd.js.map +1 -1
- package/dist/worker/WASQLiteDB.umd.js +797 -854
- package/dist/worker/WASQLiteDB.umd.js.map +1 -1
- package/lib/package.json +2 -3
- package/lib/src/db/PowerSyncDatabase.d.ts +1 -2
- package/lib/src/db/PowerSyncDatabase.js +3 -4
- package/lib/src/db/adapters/AsyncWebAdapter.d.ts +40 -0
- package/lib/src/db/adapters/AsyncWebAdapter.js +69 -0
- package/lib/src/db/adapters/SSRDBAdapter.d.ts +1 -2
- package/lib/src/db/adapters/SSRDBAdapter.js +5 -6
- package/lib/src/db/adapters/wa-sqlite/ConcurrentConnection.d.ts +56 -0
- package/lib/src/db/adapters/wa-sqlite/ConcurrentConnection.js +121 -0
- package/lib/src/db/adapters/wa-sqlite/DatabaseClient.d.ts +54 -0
- package/lib/src/db/adapters/wa-sqlite/DatabaseClient.js +227 -0
- package/lib/src/db/adapters/wa-sqlite/DatabaseServer.d.ts +47 -0
- package/lib/src/db/adapters/wa-sqlite/DatabaseServer.js +146 -0
- package/lib/src/db/adapters/wa-sqlite/RawSqliteConnection.d.ts +46 -0
- package/lib/src/db/adapters/wa-sqlite/RawSqliteConnection.js +147 -0
- package/lib/src/db/adapters/wa-sqlite/WASQLiteOpenFactory.d.ts +14 -6
- package/lib/src/db/adapters/wa-sqlite/WASQLiteOpenFactory.js +66 -39
- package/lib/src/db/adapters/wa-sqlite/vfs.d.ts +61 -0
- package/lib/src/db/adapters/wa-sqlite/vfs.js +91 -0
- package/lib/src/db/adapters/web-sql-flags.d.ts +5 -0
- package/lib/src/db/sync/SSRWebStreamingSyncImplementation.d.ts +1 -2
- package/lib/src/db/sync/SSRWebStreamingSyncImplementation.js +2 -3
- package/lib/src/db/sync/SharedWebStreamingSyncImplementation.js +4 -19
- package/lib/src/index.d.ts +1 -4
- package/lib/src/index.js +1 -4
- package/lib/src/shared/tab_close_signal.d.ts +11 -0
- package/lib/src/shared/tab_close_signal.js +26 -0
- package/lib/src/worker/db/MultiDatabaseServer.d.ts +17 -0
- package/lib/src/worker/db/MultiDatabaseServer.js +86 -0
- package/lib/src/worker/db/WASQLiteDB.worker.js +9 -48
- package/lib/src/worker/db/open-worker-database.d.ts +3 -3
- package/lib/src/worker/db/open-worker-database.js +1 -1
- package/lib/src/worker/sync/SharedSyncImplementation.d.ts +5 -6
- package/lib/src/worker/sync/SharedSyncImplementation.js +92 -54
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -4
- package/src/db/PowerSyncDatabase.ts +3 -3
- package/src/db/adapters/AsyncWebAdapter.ts +91 -0
- package/src/db/adapters/SSRDBAdapter.ts +7 -7
- package/src/db/adapters/wa-sqlite/ConcurrentConnection.ts +137 -0
- package/src/db/adapters/wa-sqlite/DatabaseClient.ts +325 -0
- package/src/db/adapters/wa-sqlite/DatabaseServer.ts +201 -0
- package/src/db/adapters/wa-sqlite/RawSqliteConnection.ts +191 -0
- package/src/db/adapters/wa-sqlite/WASQLiteOpenFactory.ts +87 -43
- package/src/db/adapters/wa-sqlite/vfs.ts +112 -0
- package/src/db/adapters/web-sql-flags.ts +6 -0
- package/src/db/sync/SSRWebStreamingSyncImplementation.ts +2 -3
- package/src/db/sync/SharedWebStreamingSyncImplementation.ts +4 -20
- package/src/index.ts +1 -4
- package/src/shared/tab_close_signal.ts +28 -0
- package/src/worker/db/MultiDatabaseServer.ts +104 -0
- package/src/worker/db/WASQLiteDB.worker.ts +10 -57
- package/src/worker/db/open-worker-database.ts +3 -3
- package/src/worker/sync/SharedSyncImplementation.ts +118 -58
- package/dist/_journeyapps_wa-sqlite-_journeyapps_wa-sqlite_src_examples_AccessHandlePoolVFS_js-_journeyapp-89f0ba.index.umd.js +0 -1881
- package/dist/_journeyapps_wa-sqlite-_journeyapps_wa-sqlite_src_examples_AccessHandlePoolVFS_js-_journeyapp-89f0ba.index.umd.js.map +0 -1
- package/dist/_journeyapps_wa-sqlite_src_examples_AccessHandlePoolVFS_js-_journeyapps_wa-sqlite_src_example-97ebe9.index.umd.js +0 -555
- package/dist/_journeyapps_wa-sqlite_src_examples_AccessHandlePoolVFS_js-_journeyapps_wa-sqlite_src_example-97ebe9.index.umd.js.map +0 -1
- package/lib/src/db/adapters/AbstractWebSQLOpenFactory.d.ts +0 -17
- package/lib/src/db/adapters/AbstractWebSQLOpenFactory.js +0 -33
- package/lib/src/db/adapters/AsyncDatabaseConnection.d.ts +0 -49
- package/lib/src/db/adapters/AsyncDatabaseConnection.js +0 -1
- package/lib/src/db/adapters/LockedAsyncDatabaseAdapter.d.ts +0 -109
- package/lib/src/db/adapters/LockedAsyncDatabaseAdapter.js +0 -404
- package/lib/src/db/adapters/WorkerWrappedAsyncDatabaseConnection.d.ts +0 -59
- package/lib/src/db/adapters/WorkerWrappedAsyncDatabaseConnection.js +0 -147
- package/lib/src/db/adapters/wa-sqlite/InternalWASQLiteDBAdapter.d.ts +0 -12
- package/lib/src/db/adapters/wa-sqlite/InternalWASQLiteDBAdapter.js +0 -19
- package/lib/src/db/adapters/wa-sqlite/WASQLiteConnection.d.ts +0 -155
- package/lib/src/db/adapters/wa-sqlite/WASQLiteConnection.js +0 -401
- package/lib/src/db/adapters/wa-sqlite/WASQLiteDBAdapter.d.ts +0 -32
- package/lib/src/db/adapters/wa-sqlite/WASQLiteDBAdapter.js +0 -49
- package/lib/src/worker/db/SharedWASQLiteConnection.d.ts +0 -42
- package/lib/src/worker/db/SharedWASQLiteConnection.js +0 -90
- package/lib/src/worker/db/WorkerWASQLiteConnection.d.ts +0 -9
- package/lib/src/worker/db/WorkerWASQLiteConnection.js +0 -12
- package/src/db/adapters/AbstractWebSQLOpenFactory.ts +0 -48
- package/src/db/adapters/AsyncDatabaseConnection.ts +0 -55
- package/src/db/adapters/LockedAsyncDatabaseAdapter.ts +0 -489
- package/src/db/adapters/WorkerWrappedAsyncDatabaseConnection.ts +0 -201
- package/src/db/adapters/wa-sqlite/InternalWASQLiteDBAdapter.ts +0 -23
- package/src/db/adapters/wa-sqlite/WASQLiteConnection.ts +0 -497
- package/src/db/adapters/wa-sqlite/WASQLiteDBAdapter.ts +0 -86
- package/src/worker/db/SharedWASQLiteConnection.ts +0 -131
- package/src/worker/db/WorkerWASQLiteConnection.ts +0 -14
package/dist/index.umd.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
(function webpackUniversalModuleDefinition(root, factory) {
|
|
2
2
|
if(typeof exports === 'object' && typeof module === 'object')
|
|
3
|
-
module.exports = factory(require("@powersync/common"), require("
|
|
3
|
+
module.exports = factory(require("@powersync/common"), require("comlink"), require("@journeyapps/wa-sqlite"), require("@journeyapps/wa-sqlite/src/examples/OPFSCoopSyncVFS.js"), require("@journeyapps/wa-sqlite/src/examples/AccessHandlePoolVFS.js"), require("@journeyapps/wa-sqlite/src/examples/IDBBatchAtomicVFS.js"));
|
|
4
4
|
else if(typeof define === 'function' && define.amd)
|
|
5
|
-
define(["@powersync/common", "
|
|
5
|
+
define(["@powersync/common", "comlink", "@journeyapps/wa-sqlite", "@journeyapps/wa-sqlite/src/examples/OPFSCoopSyncVFS.js", "@journeyapps/wa-sqlite/src/examples/AccessHandlePoolVFS.js", "@journeyapps/wa-sqlite/src/examples/IDBBatchAtomicVFS.js"], factory);
|
|
6
6
|
else if(typeof exports === 'object')
|
|
7
|
-
exports["sdk_web"] = factory(require("@powersync/common"), require("
|
|
7
|
+
exports["sdk_web"] = factory(require("@powersync/common"), require("comlink"), require("@journeyapps/wa-sqlite"), require("@journeyapps/wa-sqlite/src/examples/OPFSCoopSyncVFS.js"), require("@journeyapps/wa-sqlite/src/examples/AccessHandlePoolVFS.js"), require("@journeyapps/wa-sqlite/src/examples/IDBBatchAtomicVFS.js"));
|
|
8
8
|
else
|
|
9
|
-
root["sdk_web"] = factory(root["@powersync/common"], root["
|
|
10
|
-
})(self, (__WEBPACK_EXTERNAL_MODULE__powersync_common__,
|
|
9
|
+
root["sdk_web"] = factory(root["@powersync/common"], root["comlink"], root["@journeyapps/wa-sqlite"], root["@journeyapps/wa-sqlite/src/examples/OPFSCoopSyncVFS.js"], root["@journeyapps/wa-sqlite/src/examples/AccessHandlePoolVFS.js"], root["@journeyapps/wa-sqlite/src/examples/IDBBatchAtomicVFS.js"]);
|
|
10
|
+
})(self, (__WEBPACK_EXTERNAL_MODULE__powersync_common__, __WEBPACK_EXTERNAL_MODULE_comlink__, __WEBPACK_EXTERNAL_MODULE__journeyapps_wa_sqlite__, __WEBPACK_EXTERNAL_MODULE__journeyapps_wa_sqlite_src_examples_OPFSCoopSyncVFS_js__, __WEBPACK_EXTERNAL_MODULE__journeyapps_wa_sqlite_src_examples_AccessHandlePoolVFS_js__, __WEBPACK_EXTERNAL_MODULE__journeyapps_wa_sqlite_src_examples_IDBBatchAtomicVFS_js__) => {
|
|
11
11
|
return /******/ (() => { // webpackBootstrap
|
|
12
12
|
/******/ "use strict";
|
|
13
13
|
/******/ var __webpack_modules__ = ({
|
|
@@ -102,16 +102,6 @@ module.exports = __WEBPACK_EXTERNAL_MODULE__powersync_common__;
|
|
|
102
102
|
|
|
103
103
|
/***/ },
|
|
104
104
|
|
|
105
|
-
/***/ "async-mutex"
|
|
106
|
-
/*!******************************!*\
|
|
107
|
-
!*** external "async-mutex" ***!
|
|
108
|
-
\******************************/
|
|
109
|
-
(module) {
|
|
110
|
-
|
|
111
|
-
module.exports = __WEBPACK_EXTERNAL_MODULE_async_mutex__;
|
|
112
|
-
|
|
113
|
-
/***/ },
|
|
114
|
-
|
|
115
105
|
/***/ "comlink"
|
|
116
106
|
/*!**************************!*\
|
|
117
107
|
!*** external "comlink" ***!
|
|
@@ -4993,17 +4983,15 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
4993
4983
|
/* harmony export */ resolveWebPowerSyncFlags: () => (/* binding */ resolveWebPowerSyncFlags)
|
|
4994
4984
|
/* harmony export */ });
|
|
4995
4985
|
/* harmony import */ var _powersync_common__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @powersync/common */ "@powersync/common");
|
|
4996
|
-
/* harmony import */ var
|
|
4997
|
-
/* harmony import */ var
|
|
4998
|
-
/* harmony import */ var
|
|
4999
|
-
/* harmony import */ var
|
|
5000
|
-
/* harmony import */ var
|
|
5001
|
-
/* harmony import */ var
|
|
5002
|
-
/* harmony import */ var
|
|
5003
|
-
/* harmony import */ var
|
|
5004
|
-
/* harmony import */ var
|
|
5005
|
-
/* harmony import */ var _sync_WebStreamingSyncImplementation_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./sync/WebStreamingSyncImplementation.js */ "./lib/src/db/sync/WebStreamingSyncImplementation.js");
|
|
5006
|
-
|
|
4986
|
+
/* harmony import */ var _shared_navigator_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../shared/navigator.js */ "./lib/src/shared/navigator.js");
|
|
4987
|
+
/* harmony import */ var _NavigatorTriggerClaimManager_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./NavigatorTriggerClaimManager.js */ "./lib/src/db/NavigatorTriggerClaimManager.js");
|
|
4988
|
+
/* harmony import */ var _adapters_wa_sqlite_WASQLiteOpenFactory_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./adapters/wa-sqlite/WASQLiteOpenFactory.js */ "./lib/src/db/adapters/wa-sqlite/WASQLiteOpenFactory.js");
|
|
4989
|
+
/* harmony import */ var _adapters_web_sql_flags_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./adapters/web-sql-flags.js */ "./lib/src/db/adapters/web-sql-flags.js");
|
|
4990
|
+
/* harmony import */ var _sync_SSRWebStreamingSyncImplementation_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./sync/SSRWebStreamingSyncImplementation.js */ "./lib/src/db/sync/SSRWebStreamingSyncImplementation.js");
|
|
4991
|
+
/* harmony import */ var _sync_SharedWebStreamingSyncImplementation_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./sync/SharedWebStreamingSyncImplementation.js */ "./lib/src/db/sync/SharedWebStreamingSyncImplementation.js");
|
|
4992
|
+
/* harmony import */ var _sync_WebRemote_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./sync/WebRemote.js */ "./lib/src/db/sync/WebRemote.js");
|
|
4993
|
+
/* harmony import */ var _sync_WebStreamingSyncImplementation_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./sync/WebStreamingSyncImplementation.js */ "./lib/src/db/sync/WebStreamingSyncImplementation.js");
|
|
4994
|
+
/* harmony import */ var _adapters_AsyncWebAdapter_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./adapters/AsyncWebAdapter.js */ "./lib/src/db/adapters/AsyncWebAdapter.js");
|
|
5007
4995
|
|
|
5008
4996
|
|
|
5009
4997
|
|
|
@@ -5015,14 +5003,14 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
5015
5003
|
|
|
5016
5004
|
|
|
5017
5005
|
const DEFAULT_POWERSYNC_FLAGS = {
|
|
5018
|
-
...
|
|
5006
|
+
..._adapters_web_sql_flags_js__WEBPACK_IMPORTED_MODULE_4__.DEFAULT_WEB_SQL_FLAGS,
|
|
5019
5007
|
externallyUnload: false
|
|
5020
5008
|
};
|
|
5021
5009
|
const resolveWebPowerSyncFlags = (flags) => {
|
|
5022
5010
|
return {
|
|
5023
5011
|
...DEFAULT_POWERSYNC_FLAGS,
|
|
5024
5012
|
...flags,
|
|
5025
|
-
...(0,
|
|
5013
|
+
...(0,_adapters_web_sql_flags_js__WEBPACK_IMPORTED_MODULE_4__.resolveWebSQLFlags)(flags)
|
|
5026
5014
|
};
|
|
5027
5015
|
};
|
|
5028
5016
|
/**
|
|
@@ -5052,7 +5040,7 @@ function assertValidDatabaseOptions(options) {
|
|
|
5052
5040
|
*/
|
|
5053
5041
|
class PowerSyncDatabase extends _powersync_common__WEBPACK_IMPORTED_MODULE_0__.AbstractPowerSyncDatabase {
|
|
5054
5042
|
options;
|
|
5055
|
-
static SHARED_MUTEX = new
|
|
5043
|
+
static SHARED_MUTEX = new _powersync_common__WEBPACK_IMPORTED_MODULE_0__.Mutex();
|
|
5056
5044
|
unloadListener;
|
|
5057
5045
|
resolvedFlags;
|
|
5058
5046
|
constructor(options) {
|
|
@@ -5066,7 +5054,7 @@ class PowerSyncDatabase extends _powersync_common__WEBPACK_IMPORTED_MODULE_0__.A
|
|
|
5066
5054
|
}
|
|
5067
5055
|
}
|
|
5068
5056
|
async _initialize() {
|
|
5069
|
-
if (this.database instanceof
|
|
5057
|
+
if (this.database instanceof _adapters_AsyncWebAdapter_js__WEBPACK_IMPORTED_MODULE_9__.AsyncDbAdapter) {
|
|
5070
5058
|
/**
|
|
5071
5059
|
* While init is done automatically,
|
|
5072
5060
|
* LockedAsyncDatabaseAdapter only exposes config after init.
|
|
@@ -5087,11 +5075,11 @@ class PowerSyncDatabase extends _powersync_common__WEBPACK_IMPORTED_MODULE_0__.A
|
|
|
5087
5075
|
generateTriggerManagerConfig() {
|
|
5088
5076
|
return {
|
|
5089
5077
|
// We need to share hold information between tabs for web
|
|
5090
|
-
claimManager:
|
|
5078
|
+
claimManager: _NavigatorTriggerClaimManager_js__WEBPACK_IMPORTED_MODULE_2__.NAVIGATOR_TRIGGER_CLAIM_MANAGER
|
|
5091
5079
|
};
|
|
5092
5080
|
}
|
|
5093
5081
|
openDBAdapter(options) {
|
|
5094
|
-
const defaultFactory = new
|
|
5082
|
+
const defaultFactory = new _adapters_wa_sqlite_WASQLiteOpenFactory_js__WEBPACK_IMPORTED_MODULE_3__.WASQLiteOpenFactory({
|
|
5095
5083
|
...options.database,
|
|
5096
5084
|
flags: resolveWebPowerSyncFlags(options.flags),
|
|
5097
5085
|
encryptionKey: options.encryptionKey
|
|
@@ -5113,13 +5101,13 @@ class PowerSyncDatabase extends _powersync_common__WEBPACK_IMPORTED_MODULE_0__.A
|
|
|
5113
5101
|
});
|
|
5114
5102
|
}
|
|
5115
5103
|
async loadVersion() {
|
|
5116
|
-
if ((0,
|
|
5104
|
+
if ((0,_adapters_web_sql_flags_js__WEBPACK_IMPORTED_MODULE_4__.isServerSide)()) {
|
|
5117
5105
|
return;
|
|
5118
5106
|
}
|
|
5119
5107
|
return super.loadVersion();
|
|
5120
5108
|
}
|
|
5121
5109
|
async resolveOfflineSyncStatus() {
|
|
5122
|
-
if ((0,
|
|
5110
|
+
if ((0,_adapters_web_sql_flags_js__WEBPACK_IMPORTED_MODULE_4__.isServerSide)()) {
|
|
5123
5111
|
return;
|
|
5124
5112
|
}
|
|
5125
5113
|
return super.resolveOfflineSyncStatus();
|
|
@@ -5131,10 +5119,10 @@ class PowerSyncDatabase extends _powersync_common__WEBPACK_IMPORTED_MODULE_0__.A
|
|
|
5131
5119
|
if (this.resolvedFlags.ssrMode) {
|
|
5132
5120
|
return PowerSyncDatabase.SHARED_MUTEX.runExclusive(cb);
|
|
5133
5121
|
}
|
|
5134
|
-
return (0,
|
|
5122
|
+
return (0,_shared_navigator_js__WEBPACK_IMPORTED_MODULE_1__.getNavigatorLocks)().request(`lock-${this.database.name}`, cb);
|
|
5135
5123
|
}
|
|
5136
5124
|
generateSyncStreamImplementation(connector, options) {
|
|
5137
|
-
const remote = new
|
|
5125
|
+
const remote = new _sync_WebRemote_js__WEBPACK_IMPORTED_MODULE_7__.WebRemote(connector, this.logger);
|
|
5138
5126
|
const syncOptions = {
|
|
5139
5127
|
...this.options,
|
|
5140
5128
|
...options,
|
|
@@ -5150,7 +5138,7 @@ class PowerSyncDatabase extends _powersync_common__WEBPACK_IMPORTED_MODULE_0__.A
|
|
|
5150
5138
|
};
|
|
5151
5139
|
switch (true) {
|
|
5152
5140
|
case this.resolvedFlags.ssrMode:
|
|
5153
|
-
return new
|
|
5141
|
+
return new _sync_SSRWebStreamingSyncImplementation_js__WEBPACK_IMPORTED_MODULE_5__.SSRStreamingSyncImplementation(syncOptions);
|
|
5154
5142
|
case this.resolvedFlags.enableMultiTabs:
|
|
5155
5143
|
if (!this.resolvedFlags.broadcastLogs) {
|
|
5156
5144
|
const warning = `
|
|
@@ -5160,12 +5148,12 @@ class PowerSyncDatabase extends _powersync_common__WEBPACK_IMPORTED_MODULE_0__.A
|
|
|
5160
5148
|
const logger = this.options.logger;
|
|
5161
5149
|
logger ? logger.warn(warning) : console.warn(warning);
|
|
5162
5150
|
}
|
|
5163
|
-
return new
|
|
5151
|
+
return new _sync_SharedWebStreamingSyncImplementation_js__WEBPACK_IMPORTED_MODULE_6__.SharedWebStreamingSyncImplementation({
|
|
5164
5152
|
...syncOptions,
|
|
5165
5153
|
db: this.database // This should always be the case
|
|
5166
5154
|
});
|
|
5167
5155
|
default:
|
|
5168
|
-
return new
|
|
5156
|
+
return new _sync_WebStreamingSyncImplementation_js__WEBPACK_IMPORTED_MODULE_8__.WebStreamingSyncImplementation(syncOptions);
|
|
5169
5157
|
}
|
|
5170
5158
|
}
|
|
5171
5159
|
}
|
|
@@ -5215,485 +5203,85 @@ class AbstractWebPowerSyncDatabaseOpenFactory extends _powersync_common__WEBPACK
|
|
|
5215
5203
|
|
|
5216
5204
|
/***/ },
|
|
5217
5205
|
|
|
5218
|
-
/***/ "./lib/src/db/adapters/
|
|
5219
|
-
|
|
5220
|
-
!*** ./lib/src/db/adapters/
|
|
5221
|
-
|
|
5222
|
-
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
|
|
5223
|
-
|
|
5224
|
-
__webpack_require__.r(__webpack_exports__);
|
|
5225
|
-
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
5226
|
-
/* harmony export */ AbstractWebSQLOpenFactory: () => (/* binding */ AbstractWebSQLOpenFactory)
|
|
5227
|
-
/* harmony export */ });
|
|
5228
|
-
/* harmony import */ var _powersync_common__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @powersync/common */ "@powersync/common");
|
|
5229
|
-
/* harmony import */ var _SSRDBAdapter_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./SSRDBAdapter.js */ "./lib/src/db/adapters/SSRDBAdapter.js");
|
|
5230
|
-
/* harmony import */ var _web_sql_flags_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./web-sql-flags.js */ "./lib/src/db/adapters/web-sql-flags.js");
|
|
5231
|
-
|
|
5232
|
-
|
|
5233
|
-
|
|
5234
|
-
class AbstractWebSQLOpenFactory {
|
|
5235
|
-
options;
|
|
5236
|
-
resolvedFlags;
|
|
5237
|
-
logger;
|
|
5238
|
-
constructor(options) {
|
|
5239
|
-
this.options = options;
|
|
5240
|
-
this.resolvedFlags = (0,_web_sql_flags_js__WEBPACK_IMPORTED_MODULE_2__.resolveWebSQLFlags)(options.flags);
|
|
5241
|
-
this.logger = options.logger ?? (0,_powersync_common__WEBPACK_IMPORTED_MODULE_0__.createLogger)(`AbstractWebSQLOpenFactory - ${this.options.dbFilename}`);
|
|
5242
|
-
}
|
|
5243
|
-
/**
|
|
5244
|
-
* Opens a {@link DBAdapter} using resolved flags.
|
|
5245
|
-
* A SSR implementation is loaded if SSR mode is detected.
|
|
5246
|
-
*/
|
|
5247
|
-
openDB() {
|
|
5248
|
-
const { resolvedFlags: { disableSSRWarning, enableMultiTabs, ssrMode = (0,_web_sql_flags_js__WEBPACK_IMPORTED_MODULE_2__.isServerSide)() } } = this;
|
|
5249
|
-
if (ssrMode && !disableSSRWarning) {
|
|
5250
|
-
this.logger.warn(`
|
|
5251
|
-
Running PowerSync in SSR mode.
|
|
5252
|
-
Only empty query results will be returned.
|
|
5253
|
-
Disable this warning by setting 'disableSSRWarning: true' in options.`);
|
|
5254
|
-
}
|
|
5255
|
-
if (!enableMultiTabs) {
|
|
5256
|
-
this.logger.warn('Multiple tab support is not enabled. Using this site across multiple tabs may not function correctly.');
|
|
5257
|
-
}
|
|
5258
|
-
if (ssrMode) {
|
|
5259
|
-
return new _SSRDBAdapter_js__WEBPACK_IMPORTED_MODULE_1__.SSRDBAdapter();
|
|
5260
|
-
}
|
|
5261
|
-
return this.openAdapter();
|
|
5262
|
-
}
|
|
5263
|
-
}
|
|
5264
|
-
|
|
5265
|
-
|
|
5266
|
-
/***/ },
|
|
5267
|
-
|
|
5268
|
-
/***/ "./lib/src/db/adapters/AsyncDatabaseConnection.js"
|
|
5269
|
-
/*!********************************************************!*\
|
|
5270
|
-
!*** ./lib/src/db/adapters/AsyncDatabaseConnection.js ***!
|
|
5271
|
-
\********************************************************/
|
|
5272
|
-
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
|
|
5273
|
-
|
|
5274
|
-
__webpack_require__.r(__webpack_exports__);
|
|
5275
|
-
|
|
5276
|
-
|
|
5277
|
-
|
|
5278
|
-
/***/ },
|
|
5279
|
-
|
|
5280
|
-
/***/ "./lib/src/db/adapters/LockedAsyncDatabaseAdapter.js"
|
|
5281
|
-
/*!***********************************************************!*\
|
|
5282
|
-
!*** ./lib/src/db/adapters/LockedAsyncDatabaseAdapter.js ***!
|
|
5283
|
-
\***********************************************************/
|
|
5206
|
+
/***/ "./lib/src/db/adapters/AsyncWebAdapter.js"
|
|
5207
|
+
/*!************************************************!*\
|
|
5208
|
+
!*** ./lib/src/db/adapters/AsyncWebAdapter.js ***!
|
|
5209
|
+
\************************************************/
|
|
5284
5210
|
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
|
|
5285
5211
|
|
|
5286
5212
|
__webpack_require__.r(__webpack_exports__);
|
|
5287
5213
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
5288
|
-
/* harmony export */
|
|
5214
|
+
/* harmony export */ AsyncDbAdapter: () => (/* binding */ AsyncDbAdapter)
|
|
5289
5215
|
/* harmony export */ });
|
|
5290
5216
|
/* harmony import */ var _powersync_common__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @powersync/common */ "@powersync/common");
|
|
5291
|
-
/* harmony import */ var _shared_navigator_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../shared/navigator.js */ "./lib/src/shared/navigator.js");
|
|
5292
|
-
/* harmony import */ var _WorkerWrappedAsyncDatabaseConnection_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./WorkerWrappedAsyncDatabaseConnection.js */ "./lib/src/db/adapters/WorkerWrappedAsyncDatabaseConnection.js");
|
|
5293
|
-
/* harmony import */ var _wa_sqlite_WASQLiteConnection_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./wa-sqlite/WASQLiteConnection.js */ "./lib/src/db/adapters/wa-sqlite/WASQLiteConnection.js");
|
|
5294
|
-
|
|
5295
|
-
|
|
5296
|
-
|
|
5297
5217
|
|
|
5298
5218
|
/**
|
|
5299
|
-
*
|
|
5300
|
-
* Wraps a {@link AsyncDatabaseConnection} and provides exclusive locking functions in
|
|
5301
|
-
* order to implement {@link DBAdapter}.
|
|
5219
|
+
* A connection pool implementation delegating to another pool opened asynchronnously.
|
|
5302
5220
|
*/
|
|
5303
|
-
class
|
|
5304
|
-
|
|
5305
|
-
|
|
5306
|
-
|
|
5307
|
-
|
|
5308
|
-
|
|
5309
|
-
|
|
5310
|
-
|
|
5311
|
-
|
|
5312
|
-
|
|
5313
|
-
|
|
5314
|
-
|
|
5315
|
-
|
|
5316
|
-
|
|
5317
|
-
closed;
|
|
5318
|
-
constructor(options) {
|
|
5319
|
-
super();
|
|
5320
|
-
this.options = options;
|
|
5321
|
-
this._dbIdentifier = options.name;
|
|
5322
|
-
this.logger = options.logger ?? (0,_powersync_common__WEBPACK_IMPORTED_MODULE_0__.createLogger)(`LockedAsyncDatabaseAdapter - ${this._dbIdentifier}`);
|
|
5323
|
-
this.pendingAbortControllers = new Set();
|
|
5324
|
-
this.closed = false;
|
|
5325
|
-
this.closing = false;
|
|
5326
|
-
this.requiresHolds = null;
|
|
5327
|
-
// Set the name if provided. We can query for the name if not available yet
|
|
5328
|
-
this.debugMode = options.debugMode ?? false;
|
|
5329
|
-
if (this.debugMode) {
|
|
5330
|
-
const originalExecute = this._execute.bind(this);
|
|
5331
|
-
this._execute = async (sql, bindings) => {
|
|
5332
|
-
const start = performance.now();
|
|
5333
|
-
try {
|
|
5334
|
-
const r = await originalExecute(sql, bindings);
|
|
5335
|
-
performance.measure(`[SQL] ${sql}`, { start });
|
|
5336
|
-
return r;
|
|
5337
|
-
}
|
|
5338
|
-
catch (e) {
|
|
5339
|
-
performance.measure(`[SQL] [ERROR: ${e.message}] ${sql}`, { start });
|
|
5340
|
-
throw e;
|
|
5341
|
-
}
|
|
5342
|
-
};
|
|
5343
|
-
}
|
|
5344
|
-
this.dbGetHelpers = this.generateDBHelpers({
|
|
5345
|
-
execute: (query, params) => this.acquireLock(() => this._execute(query, params)),
|
|
5346
|
-
executeRaw: (query, params) => this.acquireLock(() => this._executeRaw(query, params)),
|
|
5347
|
-
executeBatch: (query, params) => this.acquireLock(() => this._executeBatch(query, params))
|
|
5221
|
+
class AsyncConnectionPool {
|
|
5222
|
+
name;
|
|
5223
|
+
inner;
|
|
5224
|
+
resolvedClient;
|
|
5225
|
+
pendingListeners = new Set();
|
|
5226
|
+
constructor(inner, name) {
|
|
5227
|
+
this.name = name;
|
|
5228
|
+
this.inner = inner.then((client) => {
|
|
5229
|
+
for (const pending of this.pendingListeners) {
|
|
5230
|
+
pending.closeAfterRegisteredOnResolvedPool = client.registerListener(pending.listener);
|
|
5231
|
+
}
|
|
5232
|
+
this.pendingListeners.clear();
|
|
5233
|
+
this.resolvedClient = client;
|
|
5234
|
+
return client;
|
|
5348
5235
|
});
|
|
5349
|
-
this.initPromise = this._init();
|
|
5350
|
-
}
|
|
5351
|
-
get baseDB() {
|
|
5352
|
-
if (!this._db) {
|
|
5353
|
-
throw new Error(`Initialization has not completed yet. Cannot access base db`);
|
|
5354
|
-
}
|
|
5355
|
-
return this._db;
|
|
5356
|
-
}
|
|
5357
|
-
get name() {
|
|
5358
|
-
return this._dbIdentifier;
|
|
5359
5236
|
}
|
|
5360
|
-
/**
|
|
5361
|
-
* Init is automatic, this helps catch errors or explicitly await initialization
|
|
5362
|
-
*/
|
|
5363
5237
|
async init() {
|
|
5364
|
-
|
|
5365
|
-
}
|
|
5366
|
-
async openInternalDB() {
|
|
5367
|
-
/**
|
|
5368
|
-
* Execute opening of the db in a lock in order not to interfere with other operations.
|
|
5369
|
-
*/
|
|
5370
|
-
return this._acquireLock(async () => {
|
|
5371
|
-
// Dispose any previous table change listener.
|
|
5372
|
-
this._disposeTableChangeListener?.();
|
|
5373
|
-
this._disposeTableChangeListener = null;
|
|
5374
|
-
this._db?.close().catch((ex) => this.logger.warn(`Error closing database before opening new instance`, ex));
|
|
5375
|
-
const isReOpen = !!this._db;
|
|
5376
|
-
this._db = null;
|
|
5377
|
-
this._db = await this.options.openConnection();
|
|
5378
|
-
await this._db.init();
|
|
5379
|
-
this._config = await this._db.getConfig();
|
|
5380
|
-
await this.registerOnChangeListener(this._db);
|
|
5381
|
-
if (isReOpen) {
|
|
5382
|
-
this.iterateListeners((cb) => cb.databaseReOpened?.());
|
|
5383
|
-
}
|
|
5384
|
-
/**
|
|
5385
|
-
* This is only required for the long-lived shared IndexedDB connections.
|
|
5386
|
-
*/
|
|
5387
|
-
this.requiresHolds = this._config.vfs == _wa_sqlite_WASQLiteConnection_js__WEBPACK_IMPORTED_MODULE_3__.WASQLiteVFS.IDBBatchAtomicVFS;
|
|
5388
|
-
});
|
|
5389
|
-
}
|
|
5390
|
-
_reOpen() {
|
|
5391
|
-
this.databaseOpenPromise = this.openInternalDB().finally(() => {
|
|
5392
|
-
this.databaseOpenPromise = null;
|
|
5393
|
-
});
|
|
5394
|
-
return this.databaseOpenPromise;
|
|
5395
|
-
}
|
|
5396
|
-
/**
|
|
5397
|
-
* Re-opens the underlying database.
|
|
5398
|
-
* Returns a pending operation if one is already in progress.
|
|
5399
|
-
*/
|
|
5400
|
-
async reOpenInternalDB() {
|
|
5401
|
-
if (this.closing || !this.options.reOpenOnConnectionClosed) {
|
|
5402
|
-
// No-op
|
|
5403
|
-
return;
|
|
5404
|
-
}
|
|
5405
|
-
else if (this.databaseOpenPromise) {
|
|
5406
|
-
// Already busy opening
|
|
5407
|
-
return this.databaseOpenPromise;
|
|
5408
|
-
}
|
|
5409
|
-
else {
|
|
5410
|
-
return this._reOpen();
|
|
5411
|
-
}
|
|
5412
|
-
}
|
|
5413
|
-
async _init() {
|
|
5414
|
-
/**
|
|
5415
|
-
* For OPFS, we can see this open call sometimes fail due to NoModificationAllowedError.
|
|
5416
|
-
* We should be able to recover from this by re-opening the database.
|
|
5417
|
-
*/
|
|
5418
|
-
const maxAttempts = 3;
|
|
5419
|
-
for (let count = 0; count < maxAttempts; count++) {
|
|
5420
|
-
try {
|
|
5421
|
-
await this.openInternalDB();
|
|
5422
|
-
break;
|
|
5423
|
-
}
|
|
5424
|
-
catch (ex) {
|
|
5425
|
-
if (count == maxAttempts - 1) {
|
|
5426
|
-
throw ex;
|
|
5427
|
-
}
|
|
5428
|
-
this.logger.warn(`Attempt ${count + 1} of ${maxAttempts} to open database failed, retrying in 1 second...`, ex);
|
|
5429
|
-
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
5430
|
-
}
|
|
5431
|
-
}
|
|
5432
|
-
this.iterateListeners((cb) => cb.initialized?.());
|
|
5433
|
-
}
|
|
5434
|
-
getConfiguration() {
|
|
5435
|
-
if (!this._config) {
|
|
5436
|
-
throw new Error(`Cannot get config before initialization is completed`);
|
|
5437
|
-
}
|
|
5438
|
-
return {
|
|
5439
|
-
...this._config,
|
|
5440
|
-
// This can be overridden by the adapter later
|
|
5441
|
-
requiresPersistentTriggers: false
|
|
5442
|
-
};
|
|
5443
|
-
}
|
|
5444
|
-
async waitForInitialized() {
|
|
5445
|
-
// Awaiting this will expose errors on function calls like .execute etc
|
|
5446
|
-
await this.initPromise;
|
|
5447
|
-
}
|
|
5448
|
-
async shareConnection() {
|
|
5449
|
-
if (false == this._db instanceof _WorkerWrappedAsyncDatabaseConnection_js__WEBPACK_IMPORTED_MODULE_2__.WorkerWrappedAsyncDatabaseConnection) {
|
|
5450
|
-
throw new Error(`Only worker connections can be shared`);
|
|
5451
|
-
}
|
|
5452
|
-
return this._db.shareConnection();
|
|
5453
|
-
}
|
|
5454
|
-
/**
|
|
5455
|
-
* Registers a table change notification callback with the base database.
|
|
5456
|
-
* This can be extended by custom implementations in order to handle proxy events.
|
|
5457
|
-
*/
|
|
5458
|
-
async registerOnChangeListener(db) {
|
|
5459
|
-
this._disposeTableChangeListener = await db.registerOnTableChange((event) => {
|
|
5460
|
-
this.iterateListeners((cb) => cb.tablesUpdated?.(event));
|
|
5461
|
-
});
|
|
5462
|
-
}
|
|
5463
|
-
/**
|
|
5464
|
-
* This is currently a no-op on web
|
|
5465
|
-
*/
|
|
5466
|
-
async refreshSchema() { }
|
|
5467
|
-
async execute(query, params) {
|
|
5468
|
-
return this.writeLock((ctx) => ctx.execute(query, params));
|
|
5469
|
-
}
|
|
5470
|
-
async executeRaw(query, params) {
|
|
5471
|
-
return this.writeLock((ctx) => ctx.executeRaw(query, params));
|
|
5238
|
+
await this.inner;
|
|
5472
5239
|
}
|
|
5473
|
-
async executeBatch(query, params) {
|
|
5474
|
-
return this.writeLock((ctx) => this._executeBatch(query, params));
|
|
5475
|
-
}
|
|
5476
|
-
/**
|
|
5477
|
-
* Attempts to close the connection.
|
|
5478
|
-
* Shared workers might not actually close the connection if other
|
|
5479
|
-
* tabs are still using it.
|
|
5480
|
-
*/
|
|
5481
5240
|
async close() {
|
|
5482
|
-
|
|
5483
|
-
|
|
5484
|
-
* Note that we obtain a reference to the callback to avoid calling the callback with `this` as the context.
|
|
5485
|
-
* This is to avoid Comlink attempting to clone `this` when calling the method.
|
|
5486
|
-
*/
|
|
5487
|
-
const dispose = this._disposeTableChangeListener;
|
|
5488
|
-
if (dispose) {
|
|
5489
|
-
dispose();
|
|
5490
|
-
}
|
|
5491
|
-
this.pendingAbortControllers.forEach((controller) => controller.abort('Closed'));
|
|
5492
|
-
await this.baseDB?.close?.();
|
|
5493
|
-
this.closed = true;
|
|
5494
|
-
}
|
|
5495
|
-
async getAll(sql, parameters) {
|
|
5496
|
-
await this.waitForInitialized();
|
|
5497
|
-
return this.dbGetHelpers.getAll(sql, parameters);
|
|
5498
|
-
}
|
|
5499
|
-
async getOptional(sql, parameters) {
|
|
5500
|
-
await this.waitForInitialized();
|
|
5501
|
-
return this.dbGetHelpers.getOptional(sql, parameters);
|
|
5502
|
-
}
|
|
5503
|
-
async get(sql, parameters) {
|
|
5504
|
-
await this.waitForInitialized();
|
|
5505
|
-
return this.dbGetHelpers.get(sql, parameters);
|
|
5241
|
+
const inner = await this.inner;
|
|
5242
|
+
return await inner.close();
|
|
5506
5243
|
}
|
|
5507
5244
|
async readLock(fn, options) {
|
|
5508
|
-
|
|
5509
|
-
return
|
|
5245
|
+
const inner = await this.inner;
|
|
5246
|
+
return await inner.readLock(fn, options);
|
|
5510
5247
|
}
|
|
5511
5248
|
async writeLock(fn, options) {
|
|
5512
|
-
await this.
|
|
5513
|
-
return
|
|
5514
|
-
execute: this._execute,
|
|
5515
|
-
executeRaw: this._executeRaw,
|
|
5516
|
-
executeBatch: this._executeBatch
|
|
5517
|
-
})), {
|
|
5518
|
-
timeoutMs: options?.timeoutMs ?? this.options.defaultLockTimeoutMs
|
|
5519
|
-
});
|
|
5249
|
+
const inner = await this.inner;
|
|
5250
|
+
return await inner.writeLock(fn, options);
|
|
5520
5251
|
}
|
|
5521
|
-
async
|
|
5522
|
-
|
|
5523
|
-
throw new Error(`Cannot acquire lock, the database is closing`);
|
|
5524
|
-
}
|
|
5525
|
-
const abortController = new AbortController();
|
|
5526
|
-
this.pendingAbortControllers.add(abortController);
|
|
5527
|
-
const { timeoutMs } = options ?? {};
|
|
5528
|
-
const timeoutId = timeoutMs
|
|
5529
|
-
? setTimeout(() => {
|
|
5530
|
-
abortController.abort(`Timeout after ${timeoutMs}ms`);
|
|
5531
|
-
this.pendingAbortControllers.delete(abortController);
|
|
5532
|
-
}, timeoutMs)
|
|
5533
|
-
: null;
|
|
5534
|
-
return (0,_shared_navigator_js__WEBPACK_IMPORTED_MODULE_1__.getNavigatorLocks)().request(`db-lock-${this._dbIdentifier}`, { signal: abortController.signal }, async () => {
|
|
5535
|
-
this.pendingAbortControllers.delete(abortController);
|
|
5536
|
-
if (timeoutId) {
|
|
5537
|
-
clearTimeout(timeoutId);
|
|
5538
|
-
}
|
|
5539
|
-
return await callback();
|
|
5540
|
-
});
|
|
5252
|
+
async refreshSchema() {
|
|
5253
|
+
await (await this.inner).refreshSchema();
|
|
5541
5254
|
}
|
|
5542
|
-
|
|
5543
|
-
|
|
5544
|
-
|
|
5545
|
-
if (this.databaseOpenPromise) {
|
|
5546
|
-
await this.databaseOpenPromise;
|
|
5547
|
-
}
|
|
5548
|
-
else if (!this._db) {
|
|
5549
|
-
/**
|
|
5550
|
-
* The database is not open anymore, we might need to re-open it.
|
|
5551
|
-
* Typically, _db, can be `null` if we tried to reOpen the database, but failed to succeed in re-opening.
|
|
5552
|
-
* This can happen when disconnecting the client.
|
|
5553
|
-
* Note: It is safe to re-enter this method multiple times.
|
|
5554
|
-
*/
|
|
5555
|
-
await this.reOpenInternalDB();
|
|
5255
|
+
registerListener(listener) {
|
|
5256
|
+
if (this.resolvedClient) {
|
|
5257
|
+
return this.resolvedClient.registerListener(listener);
|
|
5556
5258
|
}
|
|
5557
|
-
|
|
5558
|
-
|
|
5559
|
-
|
|
5560
|
-
|
|
5561
|
-
|
|
5562
|
-
|
|
5563
|
-
* If there is no pending open, but there is also no database - the open
|
|
5564
|
-
* might have failed. We need to re-open the database.
|
|
5565
|
-
*/
|
|
5566
|
-
if (this.databaseOpenPromise || !this._db) {
|
|
5567
|
-
throw new _powersync_common__WEBPACK_IMPORTED_MODULE_0__.ConnectionClosedError('Connection is busy re-opening');
|
|
5568
|
-
}
|
|
5569
|
-
holdId = this.requiresHolds ? await this.baseDB.markHold() : null;
|
|
5570
|
-
return await callback();
|
|
5571
|
-
}
|
|
5572
|
-
catch (ex) {
|
|
5573
|
-
if (_powersync_common__WEBPACK_IMPORTED_MODULE_0__.ConnectionClosedError.MATCHES(ex)) {
|
|
5574
|
-
// Immediately re-open the database. We need to miss as little table updates as possible.
|
|
5575
|
-
// Note, don't await this since it uses the same lock as we're in now.
|
|
5576
|
-
this.reOpenInternalDB();
|
|
5259
|
+
else {
|
|
5260
|
+
const pending = { listener };
|
|
5261
|
+
this.pendingListeners.add(pending);
|
|
5262
|
+
return () => {
|
|
5263
|
+
if (pending.closeAfterRegisteredOnResolvedPool) {
|
|
5264
|
+
return pending.closeAfterRegisteredOnResolvedPool();
|
|
5577
5265
|
}
|
|
5578
|
-
|
|
5579
|
-
|
|
5580
|
-
|
|
5581
|
-
if (holdId) {
|
|
5582
|
-
await this.baseDB.releaseHold(holdId);
|
|
5266
|
+
else {
|
|
5267
|
+
// Has not been registered yet, we can just remove the pending listener.
|
|
5268
|
+
this.pendingListeners.delete(pending);
|
|
5583
5269
|
}
|
|
5584
|
-
}
|
|
5585
|
-
}
|
|
5586
|
-
}
|
|
5587
|
-
async readTransaction(fn, options) {
|
|
5588
|
-
return this.readLock(this.wrapTransaction(fn));
|
|
5589
|
-
}
|
|
5590
|
-
writeTransaction(fn, options) {
|
|
5591
|
-
return this.writeLock(this.wrapTransaction(fn, true));
|
|
5270
|
+
};
|
|
5271
|
+
}
|
|
5592
5272
|
}
|
|
5593
|
-
|
|
5594
|
-
|
|
5595
|
-
|
|
5596
|
-
|
|
5597
|
-
|
|
5598
|
-
*/
|
|
5599
|
-
async getAll(sql, parameters) {
|
|
5600
|
-
const res = await tx.execute(sql, parameters);
|
|
5601
|
-
return res.rows?._array ?? [];
|
|
5602
|
-
},
|
|
5603
|
-
/**
|
|
5604
|
-
* Execute a read-only query and return the first result, or null if the ResultSet is empty.
|
|
5605
|
-
*/
|
|
5606
|
-
async getOptional(sql, parameters) {
|
|
5607
|
-
const res = await tx.execute(sql, parameters);
|
|
5608
|
-
return res.rows?.item(0) ?? null;
|
|
5609
|
-
},
|
|
5610
|
-
/**
|
|
5611
|
-
* Execute a read-only query and return the first result, error if the ResultSet is empty.
|
|
5612
|
-
*/
|
|
5613
|
-
async get(sql, parameters) {
|
|
5614
|
-
const res = await tx.execute(sql, parameters);
|
|
5615
|
-
const first = res.rows?.item(0);
|
|
5616
|
-
if (!first) {
|
|
5617
|
-
throw new Error('Result set is empty');
|
|
5618
|
-
}
|
|
5619
|
-
return first;
|
|
5620
|
-
}
|
|
5621
|
-
};
|
|
5273
|
+
}
|
|
5274
|
+
class AsyncDbAdapter extends (0,_powersync_common__WEBPACK_IMPORTED_MODULE_0__.DBAdapterDefaultMixin)(AsyncConnectionPool) {
|
|
5275
|
+
async shareConnection() {
|
|
5276
|
+
const inner = await this.inner;
|
|
5277
|
+
return inner.shareConnection();
|
|
5622
5278
|
}
|
|
5623
|
-
|
|
5624
|
-
|
|
5625
|
-
|
|
5626
|
-
|
|
5627
|
-
|
|
5628
|
-
await this._execute(write ? 'BEGIN EXCLUSIVE' : 'BEGIN');
|
|
5629
|
-
let finalized = false;
|
|
5630
|
-
const commit = async () => {
|
|
5631
|
-
if (finalized) {
|
|
5632
|
-
return { rowsAffected: 0 };
|
|
5633
|
-
}
|
|
5634
|
-
finalized = true;
|
|
5635
|
-
return this._execute('COMMIT');
|
|
5636
|
-
};
|
|
5637
|
-
const rollback = () => {
|
|
5638
|
-
finalized = true;
|
|
5639
|
-
return this._execute('ROLLBACK');
|
|
5640
|
-
};
|
|
5641
|
-
try {
|
|
5642
|
-
const result = await cb({
|
|
5643
|
-
...tx,
|
|
5644
|
-
commit,
|
|
5645
|
-
rollback
|
|
5646
|
-
});
|
|
5647
|
-
if (!finalized) {
|
|
5648
|
-
await commit();
|
|
5649
|
-
}
|
|
5650
|
-
return result;
|
|
5651
|
-
}
|
|
5652
|
-
catch (ex) {
|
|
5653
|
-
this.logger.debug('Caught ex in transaction', ex);
|
|
5654
|
-
try {
|
|
5655
|
-
await rollback();
|
|
5656
|
-
}
|
|
5657
|
-
catch (ex2) {
|
|
5658
|
-
// In rare cases, a rollback may fail.
|
|
5659
|
-
// Safe to ignore.
|
|
5660
|
-
}
|
|
5661
|
-
throw ex;
|
|
5662
|
-
}
|
|
5663
|
-
};
|
|
5279
|
+
getConfiguration() {
|
|
5280
|
+
if (this.resolvedClient) {
|
|
5281
|
+
return this.resolvedClient.getConfiguration();
|
|
5282
|
+
}
|
|
5283
|
+
throw new Error('AsyncDbAdapter.getConfiguration() can only be called after initializing it.');
|
|
5664
5284
|
}
|
|
5665
|
-
/**
|
|
5666
|
-
* Wraps the worker execute function, awaiting for it to be available
|
|
5667
|
-
*/
|
|
5668
|
-
_execute = async (sql, bindings) => {
|
|
5669
|
-
await this.waitForInitialized();
|
|
5670
|
-
const result = await this.baseDB.execute(sql, bindings);
|
|
5671
|
-
return {
|
|
5672
|
-
...result,
|
|
5673
|
-
rows: {
|
|
5674
|
-
...result.rows,
|
|
5675
|
-
item: (idx) => result.rows._array[idx]
|
|
5676
|
-
}
|
|
5677
|
-
};
|
|
5678
|
-
};
|
|
5679
|
-
/**
|
|
5680
|
-
* Wraps the worker executeRaw function, awaiting for it to be available
|
|
5681
|
-
*/
|
|
5682
|
-
_executeRaw = async (sql, bindings) => {
|
|
5683
|
-
await this.waitForInitialized();
|
|
5684
|
-
return await this.baseDB.executeRaw(sql, bindings);
|
|
5685
|
-
};
|
|
5686
|
-
/**
|
|
5687
|
-
* Wraps the worker executeBatch function, awaiting for it to be available
|
|
5688
|
-
*/
|
|
5689
|
-
_executeBatch = async (query, params) => {
|
|
5690
|
-
await this.waitForInitialized();
|
|
5691
|
-
const result = await this.baseDB.executeBatch(query, params);
|
|
5692
|
-
return {
|
|
5693
|
-
...result,
|
|
5694
|
-
rows: undefined
|
|
5695
|
-
};
|
|
5696
|
-
};
|
|
5697
5285
|
}
|
|
5698
5286
|
|
|
5699
5287
|
|
|
@@ -5710,8 +5298,6 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
5710
5298
|
/* harmony export */ SSRDBAdapter: () => (/* binding */ SSRDBAdapter)
|
|
5711
5299
|
/* harmony export */ });
|
|
5712
5300
|
/* harmony import */ var _powersync_common__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @powersync/common */ "@powersync/common");
|
|
5713
|
-
/* harmony import */ var async_mutex__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! async-mutex */ "async-mutex");
|
|
5714
|
-
|
|
5715
5301
|
|
|
5716
5302
|
const MOCK_QUERY_RESPONSE = {
|
|
5717
5303
|
rowsAffected: 0
|
|
@@ -5728,21 +5314,21 @@ class SSRDBAdapter extends _powersync_common__WEBPACK_IMPORTED_MODULE_0__.BaseOb
|
|
|
5728
5314
|
constructor() {
|
|
5729
5315
|
super();
|
|
5730
5316
|
this.name = 'SSR DB';
|
|
5731
|
-
this.readMutex = new
|
|
5732
|
-
this.writeMutex = new
|
|
5317
|
+
this.readMutex = new _powersync_common__WEBPACK_IMPORTED_MODULE_0__.Mutex();
|
|
5318
|
+
this.writeMutex = new _powersync_common__WEBPACK_IMPORTED_MODULE_0__.Mutex();
|
|
5733
5319
|
}
|
|
5734
5320
|
close() { }
|
|
5735
5321
|
async readLock(fn, options) {
|
|
5736
|
-
return this.readMutex.runExclusive(() => fn(this));
|
|
5322
|
+
return this.readMutex.runExclusive(() => fn(this), (0,_powersync_common__WEBPACK_IMPORTED_MODULE_0__.timeoutSignal)(options?.timeoutMs));
|
|
5737
5323
|
}
|
|
5738
5324
|
async readTransaction(fn, options) {
|
|
5739
|
-
return this.readLock(() => fn(this.generateMockTransactionContext()));
|
|
5325
|
+
return this.readLock(() => fn(this.generateMockTransactionContext()), options);
|
|
5740
5326
|
}
|
|
5741
5327
|
async writeLock(fn, options) {
|
|
5742
|
-
return this.writeMutex.runExclusive(() => fn(this));
|
|
5328
|
+
return this.writeMutex.runExclusive(() => fn(this), (0,_powersync_common__WEBPACK_IMPORTED_MODULE_0__.timeoutSignal)(options?.timeoutMs));
|
|
5743
5329
|
}
|
|
5744
5330
|
async writeTransaction(fn, options) {
|
|
5745
|
-
return this.writeLock(() => fn(this.generateMockTransactionContext()));
|
|
5331
|
+
return this.writeLock(() => fn(this.generateMockTransactionContext()), options);
|
|
5746
5332
|
}
|
|
5747
5333
|
async execute(query, params) {
|
|
5748
5334
|
return this.writeMutex.runExclusive(async () => MOCK_QUERY_RESPONSE);
|
|
@@ -5796,116 +5382,256 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
5796
5382
|
|
|
5797
5383
|
/***/ },
|
|
5798
5384
|
|
|
5799
|
-
/***/ "./lib/src/db/adapters/
|
|
5800
|
-
|
|
5801
|
-
!*** ./lib/src/db/adapters/
|
|
5802
|
-
|
|
5385
|
+
/***/ "./lib/src/db/adapters/wa-sqlite/ConcurrentConnection.js"
|
|
5386
|
+
/*!***************************************************************!*\
|
|
5387
|
+
!*** ./lib/src/db/adapters/wa-sqlite/ConcurrentConnection.js ***!
|
|
5388
|
+
\***************************************************************/
|
|
5803
5389
|
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
|
|
5804
5390
|
|
|
5805
5391
|
__webpack_require__.r(__webpack_exports__);
|
|
5806
5392
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
5807
|
-
/* harmony export */
|
|
5393
|
+
/* harmony export */ ConcurrentSqliteConnection: () => (/* binding */ ConcurrentSqliteConnection),
|
|
5394
|
+
/* harmony export */ ConnectionLeaseToken: () => (/* binding */ ConnectionLeaseToken)
|
|
5808
5395
|
/* harmony export */ });
|
|
5809
5396
|
/* harmony import */ var _powersync_common__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @powersync/common */ "@powersync/common");
|
|
5810
|
-
/* harmony import */ var comlink__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! comlink */ "comlink");
|
|
5811
|
-
|
|
5812
5397
|
|
|
5813
5398
|
/**
|
|
5814
|
-
*
|
|
5815
|
-
*
|
|
5399
|
+
* A wrapper around a {@link RawSqliteConnection} allowing multiple tabs to access it.
|
|
5400
|
+
*
|
|
5401
|
+
* To allow potentially concurrent accesses from different clients, this requires a local mutex implementation here.
|
|
5402
|
+
*
|
|
5403
|
+
* Note that instances of this class are not safe to proxy across context boundaries with comlink! We need to be able to
|
|
5404
|
+
* rely on mutexes being returned reliably, so additional checks to detect say a client tab closing are required to
|
|
5405
|
+
* avoid deadlocks.
|
|
5816
5406
|
*/
|
|
5817
|
-
class
|
|
5818
|
-
|
|
5819
|
-
lockAbortController = new AbortController();
|
|
5820
|
-
notifyRemoteClosed;
|
|
5821
|
-
constructor(options) {
|
|
5822
|
-
super();
|
|
5823
|
-
this.options = options;
|
|
5824
|
-
if (options.remoteCanCloseUnexpectedly) {
|
|
5825
|
-
this.notifyRemoteClosed = new AbortController();
|
|
5826
|
-
}
|
|
5827
|
-
}
|
|
5828
|
-
get baseConnection() {
|
|
5829
|
-
return this.options.baseConnection;
|
|
5830
|
-
}
|
|
5831
|
-
init() {
|
|
5832
|
-
return this.baseConnection.init();
|
|
5833
|
-
}
|
|
5407
|
+
class ConcurrentSqliteConnection {
|
|
5408
|
+
inner;
|
|
5834
5409
|
/**
|
|
5835
|
-
*
|
|
5410
|
+
* An outer mutex ensuring at most one {@link ConnectionLeaseToken} can exist for this connection at a time.
|
|
5836
5411
|
*
|
|
5837
|
-
*
|
|
5838
|
-
* it happens, all methods on the {@link baseConnection} would never resolve. To avoid livelocks in this scenario, we
|
|
5839
|
-
* throw on all outstanding promises and forbid new calls.
|
|
5412
|
+
* If null, we'll use navigator locks instead.
|
|
5840
5413
|
*/
|
|
5841
|
-
|
|
5842
|
-
|
|
5843
|
-
|
|
5844
|
-
|
|
5414
|
+
leaseMutex;
|
|
5415
|
+
/**
|
|
5416
|
+
* @param needsNavigatorLocks Whether access to the database needs an additional navigator lock guard.
|
|
5417
|
+
*
|
|
5418
|
+
* While {@link ConcurrentSqliteConnection} prevents concurrent access to a database _connection_, it's possible we
|
|
5419
|
+
* might have multiple connections to the same physical database (e.g. if multiple tabs use dedicated workers).
|
|
5420
|
+
* In those setups, we use navigator locks instead of an internal mutex to guard access..
|
|
5421
|
+
*/
|
|
5422
|
+
constructor(inner, needsNavigatorLocks) {
|
|
5423
|
+
this.inner = inner;
|
|
5424
|
+
this.leaseMutex = needsNavigatorLocks ? null : new _powersync_common__WEBPACK_IMPORTED_MODULE_0__.Mutex();
|
|
5425
|
+
}
|
|
5426
|
+
get options() {
|
|
5427
|
+
return this.inner.options;
|
|
5845
5428
|
}
|
|
5846
|
-
|
|
5847
|
-
|
|
5429
|
+
acquireMutex(abort) {
|
|
5430
|
+
if (this.leaseMutex) {
|
|
5431
|
+
return this.leaseMutex.acquire(abort);
|
|
5432
|
+
}
|
|
5433
|
+
return new Promise((resolve, reject) => {
|
|
5434
|
+
const options = { signal: abort };
|
|
5435
|
+
navigator.locks
|
|
5436
|
+
.request(`db-lock-${this.options.dbFilename}`, options, (_) => {
|
|
5437
|
+
return new Promise((returnLock) => {
|
|
5438
|
+
return resolve(() => {
|
|
5439
|
+
returnLock();
|
|
5440
|
+
});
|
|
5441
|
+
});
|
|
5442
|
+
})
|
|
5443
|
+
.catch(reject);
|
|
5444
|
+
});
|
|
5848
5445
|
}
|
|
5849
|
-
|
|
5850
|
-
|
|
5446
|
+
// Unsafe, unguarded access to the SQLite connection.
|
|
5447
|
+
unsafeUseInner() {
|
|
5448
|
+
return this.inner;
|
|
5851
5449
|
}
|
|
5852
|
-
|
|
5853
|
-
|
|
5854
|
-
|
|
5855
|
-
|
|
5856
|
-
const
|
|
5857
|
-
|
|
5858
|
-
|
|
5859
|
-
|
|
5860
|
-
|
|
5861
|
-
|
|
5862
|
-
|
|
5863
|
-
|
|
5864
|
-
|
|
5865
|
-
|
|
5866
|
-
|
|
5867
|
-
function handleAbort() {
|
|
5868
|
-
reject(new _powersync_common__WEBPACK_IMPORTED_MODULE_0__.ConnectionClosedError('Remote peer closed with request in flight'));
|
|
5869
|
-
}
|
|
5870
|
-
function completePromise(action) {
|
|
5871
|
-
controller.signal.removeEventListener('abort', handleAbort);
|
|
5872
|
-
action();
|
|
5873
|
-
}
|
|
5874
|
-
controller.signal.addEventListener('abort', handleAbort);
|
|
5875
|
-
workerPromise()
|
|
5876
|
-
.then((data) => completePromise(() => resolve(data)))
|
|
5877
|
-
.catch((e) => completePromise(() => reject(e)));
|
|
5878
|
-
});
|
|
5450
|
+
/**
|
|
5451
|
+
* @returns A {@link ConnectionLeaseToken}. Until that token is returned, no other client can use the database.
|
|
5452
|
+
*/
|
|
5453
|
+
async acquireConnection(abort) {
|
|
5454
|
+
const returnMutex = await this.acquireMutex(abort);
|
|
5455
|
+
const token = new ConnectionLeaseToken(returnMutex, this.inner);
|
|
5456
|
+
try {
|
|
5457
|
+
// Assert that the inner connection is initialized at this point, fail early if it's not.
|
|
5458
|
+
this.inner.requireSqlite();
|
|
5459
|
+
// If a previous client was interrupted in the middle of a transaction AND this is a shared worker, it's possible
|
|
5460
|
+
// for the connection to still be in a transaction. To avoid inconsistent state, we roll back connection leases
|
|
5461
|
+
// that haven't been comitted.
|
|
5462
|
+
if (!this.inner.isAutoCommit()) {
|
|
5463
|
+
await this.inner.executeRaw('ROLLBACK');
|
|
5464
|
+
}
|
|
5879
5465
|
}
|
|
5880
|
-
|
|
5881
|
-
|
|
5882
|
-
|
|
5466
|
+
catch (e) {
|
|
5467
|
+
returnMutex();
|
|
5468
|
+
throw e;
|
|
5469
|
+
}
|
|
5470
|
+
return token;
|
|
5471
|
+
}
|
|
5472
|
+
async close() {
|
|
5473
|
+
const returnMutex = await this.acquireMutex();
|
|
5474
|
+
try {
|
|
5475
|
+
await this.inner.close();
|
|
5476
|
+
}
|
|
5477
|
+
finally {
|
|
5478
|
+
returnMutex();
|
|
5883
5479
|
}
|
|
5884
5480
|
}
|
|
5481
|
+
}
|
|
5482
|
+
/**
|
|
5483
|
+
* An instance representing temporary exclusive access to a {@link ConcurrentSqliteConnection}.
|
|
5484
|
+
*/
|
|
5485
|
+
class ConnectionLeaseToken {
|
|
5486
|
+
returnMutex;
|
|
5487
|
+
connection;
|
|
5488
|
+
/** Ensures that the client with access to this token can't run statements concurrently. */
|
|
5489
|
+
useMutex = new _powersync_common__WEBPACK_IMPORTED_MODULE_0__.Mutex();
|
|
5490
|
+
closed = false;
|
|
5491
|
+
constructor(returnMutex, connection) {
|
|
5492
|
+
this.returnMutex = returnMutex;
|
|
5493
|
+
this.connection = connection;
|
|
5494
|
+
}
|
|
5885
5495
|
/**
|
|
5886
|
-
*
|
|
5496
|
+
* Returns this lease, allowing another client to use the database connection.
|
|
5887
5497
|
*/
|
|
5888
|
-
async
|
|
5889
|
-
|
|
5890
|
-
|
|
5891
|
-
|
|
5892
|
-
|
|
5893
|
-
|
|
5498
|
+
async returnLease() {
|
|
5499
|
+
await this.useMutex.runExclusive(async () => {
|
|
5500
|
+
if (!this.closed) {
|
|
5501
|
+
this.closed = true;
|
|
5502
|
+
this.returnMutex();
|
|
5503
|
+
}
|
|
5504
|
+
});
|
|
5505
|
+
}
|
|
5506
|
+
/**
|
|
5507
|
+
* This should only be used internally, since the callback must not use the raw connection after resolving.
|
|
5508
|
+
*/
|
|
5509
|
+
async use(callback) {
|
|
5510
|
+
return await this.useMutex.runExclusive(async () => {
|
|
5511
|
+
if (this.closed) {
|
|
5512
|
+
throw new Error('lease token has already been closed');
|
|
5513
|
+
}
|
|
5514
|
+
return await callback(this.connection);
|
|
5515
|
+
});
|
|
5516
|
+
}
|
|
5517
|
+
}
|
|
5518
|
+
|
|
5519
|
+
|
|
5520
|
+
/***/ },
|
|
5521
|
+
|
|
5522
|
+
/***/ "./lib/src/db/adapters/wa-sqlite/DatabaseClient.js"
|
|
5523
|
+
/*!*********************************************************!*\
|
|
5524
|
+
!*** ./lib/src/db/adapters/wa-sqlite/DatabaseClient.js ***!
|
|
5525
|
+
\*********************************************************/
|
|
5526
|
+
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
|
|
5527
|
+
|
|
5528
|
+
__webpack_require__.r(__webpack_exports__);
|
|
5529
|
+
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
5530
|
+
/* harmony export */ DatabaseClient: () => (/* binding */ DatabaseClient)
|
|
5531
|
+
/* harmony export */ });
|
|
5532
|
+
/* harmony import */ var _powersync_common__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @powersync/common */ "@powersync/common");
|
|
5533
|
+
/* harmony import */ var comlink__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! comlink */ "comlink");
|
|
5534
|
+
|
|
5535
|
+
|
|
5536
|
+
/**
|
|
5537
|
+
* A single-connection {@link ConnectionPool} implementation based on a worker connection.
|
|
5538
|
+
*/
|
|
5539
|
+
class DatabaseClient extends _powersync_common__WEBPACK_IMPORTED_MODULE_0__.BaseObserver {
|
|
5540
|
+
options;
|
|
5541
|
+
config;
|
|
5542
|
+
#connection;
|
|
5543
|
+
#shareConnectionAbortController = new AbortController();
|
|
5544
|
+
#receiveTableUpdates;
|
|
5545
|
+
constructor(options, config) {
|
|
5546
|
+
super();
|
|
5547
|
+
this.options = options;
|
|
5548
|
+
this.config = config;
|
|
5549
|
+
this.#connection = {
|
|
5550
|
+
connection: options.connection,
|
|
5551
|
+
notifyRemoteClosed: options.remoteCanCloseUnexpectedly ? new AbortController() : undefined,
|
|
5552
|
+
traceQueries: config.debugMode === true
|
|
5553
|
+
};
|
|
5554
|
+
const { port1, port2 } = new MessageChannel();
|
|
5555
|
+
options.connection.setUpdateListener(comlink__WEBPACK_IMPORTED_MODULE_1__.transfer(port1, [port1]));
|
|
5556
|
+
this.#receiveTableUpdates = port2;
|
|
5557
|
+
port2.onmessage = (event) => {
|
|
5558
|
+
const tables = event.data;
|
|
5559
|
+
const notification = {
|
|
5560
|
+
tables,
|
|
5561
|
+
groupedUpdates: {},
|
|
5562
|
+
rawUpdates: []
|
|
5563
|
+
};
|
|
5564
|
+
this.iterateListeners((l) => {
|
|
5565
|
+
l.tablesUpdated && l.tablesUpdated(notification);
|
|
5566
|
+
});
|
|
5567
|
+
};
|
|
5568
|
+
}
|
|
5569
|
+
get name() {
|
|
5570
|
+
return this.config.dbFilename;
|
|
5571
|
+
}
|
|
5572
|
+
/**
|
|
5573
|
+
* Marks the remote as closed.
|
|
5574
|
+
*
|
|
5575
|
+
* This can sometimes happen outside of our control, e.g. when a shared worker requests a connection from a tab. When
|
|
5576
|
+
* it happens, all outstanding requests on this pool would never resolve. To avoid livelocks in this scenario, we
|
|
5577
|
+
* throw on all outstanding promises and forbid new calls.
|
|
5578
|
+
*/
|
|
5579
|
+
markRemoteClosed() {
|
|
5580
|
+
// Can non-null assert here because this function is only supposed to be called when remoteCanCloseUnexpectedly was
|
|
5581
|
+
// set.
|
|
5582
|
+
this.#connection.notifyRemoteClosed.abort();
|
|
5583
|
+
}
|
|
5584
|
+
async close() {
|
|
5585
|
+
// This connection is no longer shared, so we can close locks held for shareConnection calls.
|
|
5586
|
+
this.#shareConnectionAbortController.abort();
|
|
5587
|
+
this.#receiveTableUpdates.close();
|
|
5588
|
+
await useConnectionState(this.#connection, (c) => c.close(), true);
|
|
5589
|
+
this.options.onClose?.();
|
|
5590
|
+
this.options.source?.[comlink__WEBPACK_IMPORTED_MODULE_1__.releaseProxy]();
|
|
5591
|
+
}
|
|
5592
|
+
readLock(fn, options) {
|
|
5593
|
+
return this.#lock(false, fn, options);
|
|
5594
|
+
}
|
|
5595
|
+
writeLock(fn, options) {
|
|
5596
|
+
return this.#lock(true, fn, options);
|
|
5597
|
+
}
|
|
5598
|
+
async #lock(write, fn, options) {
|
|
5599
|
+
const token = await useConnectionState(this.#connection, (c) => c.requestAccess(write, options?.timeoutMs));
|
|
5600
|
+
try {
|
|
5601
|
+
return await fn(new ClientLockContext(this.#connection, token));
|
|
5602
|
+
}
|
|
5603
|
+
finally {
|
|
5604
|
+
await useConnectionState(this.#connection, (c) => c.completeAccess(token));
|
|
5605
|
+
}
|
|
5606
|
+
}
|
|
5607
|
+
async refreshSchema() {
|
|
5608
|
+
// Currently a no-op on the web.
|
|
5609
|
+
}
|
|
5610
|
+
async shareConnection() {
|
|
5611
|
+
/**
|
|
5612
|
+
* Hold a navigator lock in order to avoid features such as Chrome's frozen tabs,
|
|
5613
|
+
* or Edge's sleeping tabs from pausing the thread for this connection.
|
|
5614
|
+
* This promise resolves once a lock is obtained.
|
|
5894
5615
|
* This lock will be held as long as this connection is open.
|
|
5895
5616
|
* The `shareConnection` method should not be called on multiple tabs concurrently.
|
|
5896
5617
|
*/
|
|
5618
|
+
const abort = this.#shareConnectionAbortController;
|
|
5619
|
+
const source = this.options.source;
|
|
5620
|
+
if (source == null) {
|
|
5621
|
+
throw new Error(`shareConnection() is only available for connections based by workers.`);
|
|
5622
|
+
}
|
|
5897
5623
|
await new Promise((resolve, reject) => navigator.locks
|
|
5898
|
-
.request(`shared-connection-${this.
|
|
5899
|
-
signal:
|
|
5624
|
+
.request(`shared-connection-${this.name}-${Date.now()}-${Math.round(Math.random() * 10000)}`, {
|
|
5625
|
+
signal: abort.signal
|
|
5900
5626
|
}, async () => {
|
|
5901
5627
|
resolve();
|
|
5902
5628
|
// Free the lock when the connection is already closed.
|
|
5903
|
-
if (
|
|
5629
|
+
if (abort.signal.aborted) {
|
|
5904
5630
|
return;
|
|
5905
5631
|
}
|
|
5906
5632
|
// Hold the lock while the shared connection is in use.
|
|
5907
5633
|
await new Promise((releaseLock) => {
|
|
5908
|
-
|
|
5634
|
+
abort.signal.addEventListener('abort', () => {
|
|
5909
5635
|
releaseLock();
|
|
5910
5636
|
});
|
|
5911
5637
|
});
|
|
@@ -5919,280 +5645,335 @@ class WorkerWrappedAsyncDatabaseConnection extends _powersync_common__WEBPACK_IM
|
|
|
5919
5645
|
reject(ex);
|
|
5920
5646
|
}
|
|
5921
5647
|
}));
|
|
5922
|
-
const newPort = await
|
|
5923
|
-
return { port: newPort, identifier };
|
|
5648
|
+
const newPort = await source[comlink__WEBPACK_IMPORTED_MODULE_1__.createEndpoint]();
|
|
5649
|
+
return { port: newPort, identifier: this.name };
|
|
5650
|
+
}
|
|
5651
|
+
getConfiguration() {
|
|
5652
|
+
return this.config;
|
|
5653
|
+
}
|
|
5654
|
+
}
|
|
5655
|
+
/**
|
|
5656
|
+
* A {@link SqlExecutor} implemented by sending commands to a worker.
|
|
5657
|
+
*
|
|
5658
|
+
* While an instance is active, it has exclusive access to the underlying database connection (as represented by its
|
|
5659
|
+
* token).
|
|
5660
|
+
*/
|
|
5661
|
+
class ClientSqlExecutor {
|
|
5662
|
+
#connection;
|
|
5663
|
+
#token;
|
|
5664
|
+
constructor(connection, token) {
|
|
5665
|
+
this.#connection = connection;
|
|
5666
|
+
this.#token = token;
|
|
5924
5667
|
}
|
|
5925
5668
|
/**
|
|
5926
|
-
*
|
|
5927
|
-
* This can be extended by custom implementations in order to handle proxy events.
|
|
5669
|
+
* Requests an operation from the worker, potentially tracing it if that option has been enabled.
|
|
5928
5670
|
*/
|
|
5929
|
-
async
|
|
5930
|
-
|
|
5931
|
-
|
|
5932
|
-
|
|
5933
|
-
|
|
5934
|
-
|
|
5935
|
-
|
|
5936
|
-
|
|
5937
|
-
|
|
5671
|
+
async maybeTrace(fn, describeForTrace) {
|
|
5672
|
+
if (this.#connection.traceQueries) {
|
|
5673
|
+
const start = performance.now();
|
|
5674
|
+
const description = describeForTrace();
|
|
5675
|
+
try {
|
|
5676
|
+
const r = await useConnectionState(this.#connection, fn);
|
|
5677
|
+
performance.measure(`[SQL] ${description}`, { start });
|
|
5678
|
+
return r;
|
|
5679
|
+
}
|
|
5680
|
+
catch (e) {
|
|
5681
|
+
performance.measure(`[SQL] [ERROR: ${e.message}] ${description}`, { start });
|
|
5682
|
+
throw e;
|
|
5683
|
+
}
|
|
5938
5684
|
}
|
|
5939
|
-
|
|
5940
|
-
this
|
|
5941
|
-
|
|
5942
|
-
|
|
5685
|
+
else {
|
|
5686
|
+
return useConnectionState(this.#connection, fn);
|
|
5687
|
+
}
|
|
5688
|
+
}
|
|
5689
|
+
async execute(query, params) {
|
|
5690
|
+
const rs = await this.#executeOnWorker(query, params);
|
|
5691
|
+
let rows;
|
|
5692
|
+
if (rs.resultSet) {
|
|
5693
|
+
const resultSet = rs.resultSet;
|
|
5694
|
+
function rowToJavaScriptObject(row) {
|
|
5695
|
+
const obj = {};
|
|
5696
|
+
resultSet.columns.forEach((key, idx) => (obj[key] = row[idx]));
|
|
5697
|
+
return obj;
|
|
5698
|
+
}
|
|
5699
|
+
const mapped = resultSet.rows.map(rowToJavaScriptObject);
|
|
5700
|
+
rows = {
|
|
5701
|
+
_array: mapped,
|
|
5702
|
+
length: mapped.length,
|
|
5703
|
+
item: (idx) => mapped[idx]
|
|
5704
|
+
};
|
|
5943
5705
|
}
|
|
5706
|
+
return {
|
|
5707
|
+
rowsAffected: rs.changes,
|
|
5708
|
+
insertId: rs.lastInsertRowId,
|
|
5709
|
+
rows
|
|
5710
|
+
};
|
|
5944
5711
|
}
|
|
5945
|
-
|
|
5946
|
-
|
|
5712
|
+
async executeRaw(query, params) {
|
|
5713
|
+
const rs = await this.#executeOnWorker(query, params);
|
|
5714
|
+
return rs.resultSet?.rows ?? [];
|
|
5947
5715
|
}
|
|
5948
|
-
|
|
5949
|
-
return this.
|
|
5716
|
+
async #executeOnWorker(query, params) {
|
|
5717
|
+
return this.maybeTrace((c) => c.execute(this.#token, query, params), () => query);
|
|
5950
5718
|
}
|
|
5951
|
-
executeBatch(
|
|
5952
|
-
|
|
5719
|
+
async executeBatch(query, params = []) {
|
|
5720
|
+
const results = await this.maybeTrace((c) => c.executeBatch(this.#token, query, params), () => `${query} (batch of ${params.length})`);
|
|
5721
|
+
const result = { insertId: undefined, rowsAffected: 0 };
|
|
5722
|
+
for (const source of results) {
|
|
5723
|
+
result.insertId = source.lastInsertRowId;
|
|
5724
|
+
result.rowsAffected += source.changes;
|
|
5725
|
+
}
|
|
5726
|
+
return result;
|
|
5727
|
+
}
|
|
5728
|
+
}
|
|
5729
|
+
class ClientLockContext extends (0,_powersync_common__WEBPACK_IMPORTED_MODULE_0__.DBGetUtilsDefaultMixin)(ClientSqlExecutor) {
|
|
5730
|
+
}
|
|
5731
|
+
async function useConnectionState(state, workerPromise, fireActionOnAbort = false) {
|
|
5732
|
+
const controller = state.notifyRemoteClosed;
|
|
5733
|
+
if (controller) {
|
|
5734
|
+
return new Promise((resolve, reject) => {
|
|
5735
|
+
if (controller.signal.aborted) {
|
|
5736
|
+
reject(new _powersync_common__WEBPACK_IMPORTED_MODULE_0__.ConnectionClosedError('Called operation on closed remote'));
|
|
5737
|
+
if (!fireActionOnAbort) {
|
|
5738
|
+
// Don't run the operation if we're going to reject
|
|
5739
|
+
// We might want to fire-and-forget the operation in some cases (like a close operation)
|
|
5740
|
+
return;
|
|
5741
|
+
}
|
|
5742
|
+
}
|
|
5743
|
+
function handleAbort() {
|
|
5744
|
+
reject(new _powersync_common__WEBPACK_IMPORTED_MODULE_0__.ConnectionClosedError('Remote peer closed with request in flight'));
|
|
5745
|
+
}
|
|
5746
|
+
function completePromise(action) {
|
|
5747
|
+
controller.signal.removeEventListener('abort', handleAbort);
|
|
5748
|
+
action();
|
|
5749
|
+
}
|
|
5750
|
+
controller.signal.addEventListener('abort', handleAbort);
|
|
5751
|
+
workerPromise(state.connection)
|
|
5752
|
+
.then((data) => completePromise(() => resolve(data)))
|
|
5753
|
+
.catch((e) => completePromise(() => reject(e)));
|
|
5754
|
+
});
|
|
5953
5755
|
}
|
|
5954
|
-
|
|
5955
|
-
return
|
|
5756
|
+
else {
|
|
5757
|
+
// Can't close, so just return the inner worker promise unguarded.
|
|
5758
|
+
return workerPromise(state.connection);
|
|
5956
5759
|
}
|
|
5957
5760
|
}
|
|
5958
5761
|
|
|
5959
5762
|
|
|
5960
5763
|
/***/ },
|
|
5961
5764
|
|
|
5962
|
-
/***/ "./lib/src/db/adapters/wa-sqlite/
|
|
5963
|
-
|
|
5964
|
-
!*** ./lib/src/db/adapters/wa-sqlite/
|
|
5965
|
-
|
|
5765
|
+
/***/ "./lib/src/db/adapters/wa-sqlite/DatabaseServer.js"
|
|
5766
|
+
/*!*********************************************************!*\
|
|
5767
|
+
!*** ./lib/src/db/adapters/wa-sqlite/DatabaseServer.js ***!
|
|
5768
|
+
\*********************************************************/
|
|
5966
5769
|
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
|
|
5967
5770
|
|
|
5968
5771
|
__webpack_require__.r(__webpack_exports__);
|
|
5969
5772
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
5970
|
-
/* harmony export */
|
|
5773
|
+
/* harmony export */ DatabaseServer: () => (/* binding */ DatabaseServer)
|
|
5971
5774
|
/* harmony export */ });
|
|
5972
|
-
/* harmony import */ var _LockedAsyncDatabaseAdapter_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../LockedAsyncDatabaseAdapter.js */ "./lib/src/db/adapters/LockedAsyncDatabaseAdapter.js");
|
|
5973
|
-
/* harmony import */ var _WASQLiteConnection_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./WASQLiteConnection.js */ "./lib/src/db/adapters/wa-sqlite/WASQLiteConnection.js");
|
|
5974
|
-
|
|
5975
|
-
|
|
5976
5775
|
/**
|
|
5977
|
-
*
|
|
5978
|
-
*
|
|
5979
|
-
* constructor arguments as {@link LockedAsyncDatabaseAdapter}, but provides some
|
|
5980
|
-
* basic WA-SQLite specific functionality.
|
|
5981
|
-
* This base class is used to avoid requiring overloading the constructor of {@link WASQLiteDBAdapter}
|
|
5776
|
+
* Access to a WA-sqlite connection that can be shared with multiple clients sending queries over an RPC protocol built
|
|
5777
|
+
* with the Comlink package.
|
|
5982
5778
|
*/
|
|
5983
|
-
class
|
|
5984
|
-
|
|
5985
|
-
|
|
5986
|
-
|
|
5779
|
+
class DatabaseServer {
|
|
5780
|
+
#options;
|
|
5781
|
+
#nextClientId = 0;
|
|
5782
|
+
#activeClients = new Set();
|
|
5783
|
+
// TODO: Don't use a broadcast channel for connections managed by a shared worker.
|
|
5784
|
+
#updateBroadcastChannel;
|
|
5785
|
+
#clientTableListeners = new Set();
|
|
5786
|
+
constructor(options) {
|
|
5787
|
+
this.#options = options;
|
|
5788
|
+
const inner = options.inner;
|
|
5789
|
+
this.#updateBroadcastChannel = new BroadcastChannel(`${inner.options.dbFilename}-table-updates`);
|
|
5790
|
+
this.#updateBroadcastChannel.onmessage = ({ data }) => {
|
|
5791
|
+
this.#pushTableUpdateToClients(data);
|
|
5792
|
+
};
|
|
5793
|
+
}
|
|
5794
|
+
#pushTableUpdateToClients(changedTables) {
|
|
5795
|
+
for (const listener of this.#clientTableListeners) {
|
|
5796
|
+
listener.postMessage(changedTables);
|
|
5797
|
+
}
|
|
5798
|
+
}
|
|
5799
|
+
get #inner() {
|
|
5800
|
+
return this.#options.inner;
|
|
5801
|
+
}
|
|
5802
|
+
get #logger() {
|
|
5803
|
+
return this.#options.logger;
|
|
5804
|
+
}
|
|
5805
|
+
/**
|
|
5806
|
+
* Called by clients when they wish to connect to this database.
|
|
5807
|
+
*
|
|
5808
|
+
* @param lockName A lock that is currently held by the client. When the lock is returned, we know the client is gone
|
|
5809
|
+
* and that we need to clean up resources.
|
|
5810
|
+
*/
|
|
5811
|
+
async connect(lockName) {
|
|
5812
|
+
let isOpen = true;
|
|
5813
|
+
const clientId = this.#nextClientId++;
|
|
5814
|
+
this.#activeClients.add(clientId);
|
|
5815
|
+
let connectionLeases = new Map();
|
|
5816
|
+
let currentTableListener;
|
|
5817
|
+
function requireOpen() {
|
|
5818
|
+
if (!isOpen) {
|
|
5819
|
+
throw new Error('Client has already been closed');
|
|
5820
|
+
}
|
|
5821
|
+
}
|
|
5822
|
+
function requireOpenAndLease(lease) {
|
|
5823
|
+
requireOpen();
|
|
5824
|
+
const token = connectionLeases.get(lease);
|
|
5825
|
+
if (!token) {
|
|
5826
|
+
throw new Error('Attempted to use a connection lease that has already been returned.');
|
|
5827
|
+
}
|
|
5828
|
+
return token;
|
|
5829
|
+
}
|
|
5830
|
+
const close = async () => {
|
|
5831
|
+
if (isOpen) {
|
|
5832
|
+
isOpen = false;
|
|
5833
|
+
if (currentTableListener) {
|
|
5834
|
+
this.#clientTableListeners.delete(currentTableListener);
|
|
5835
|
+
}
|
|
5836
|
+
// If the client holds a connection lease it hasn't returned, return that now.
|
|
5837
|
+
for (const { lease } of connectionLeases.values()) {
|
|
5838
|
+
this.#logger.debug(`Closing connection lease that hasn't been returned.`);
|
|
5839
|
+
await lease.returnLease();
|
|
5840
|
+
}
|
|
5841
|
+
this.#activeClients.delete(clientId);
|
|
5842
|
+
if (this.#activeClients.size == 0) {
|
|
5843
|
+
await this.forceClose();
|
|
5844
|
+
}
|
|
5845
|
+
else {
|
|
5846
|
+
this.#logger.debug('Keeping underlying connection active since its used by other clients.');
|
|
5847
|
+
}
|
|
5848
|
+
}
|
|
5849
|
+
};
|
|
5850
|
+
if (lockName) {
|
|
5851
|
+
navigator.locks.request(lockName, {}, () => {
|
|
5852
|
+
close();
|
|
5853
|
+
});
|
|
5854
|
+
}
|
|
5987
5855
|
return {
|
|
5988
|
-
|
|
5989
|
-
|
|
5856
|
+
close,
|
|
5857
|
+
debugIsAutoCommit: async () => {
|
|
5858
|
+
return this.#inner.unsafeUseInner().isAutoCommit();
|
|
5859
|
+
},
|
|
5860
|
+
requestAccess: async (write, timeoutMs) => {
|
|
5861
|
+
requireOpen();
|
|
5862
|
+
// TODO: Support timeouts, they don't seem to be supported by the async-mutex package.
|
|
5863
|
+
const lease = await this.#inner.acquireConnection();
|
|
5864
|
+
if (!isOpen) {
|
|
5865
|
+
// Race between requestAccess and close(), the connection was closed while we tried to acquire a lease.
|
|
5866
|
+
await lease.returnLease();
|
|
5867
|
+
return requireOpen();
|
|
5868
|
+
}
|
|
5869
|
+
const token = crypto.randomUUID();
|
|
5870
|
+
connectionLeases.set(token, { lease, write });
|
|
5871
|
+
return token;
|
|
5872
|
+
},
|
|
5873
|
+
completeAccess: async (token) => {
|
|
5874
|
+
const lease = requireOpenAndLease(token);
|
|
5875
|
+
connectionLeases.delete(token);
|
|
5876
|
+
try {
|
|
5877
|
+
if (lease.write) {
|
|
5878
|
+
// Collect update hooks invoked while the client had the write connection.
|
|
5879
|
+
const { resultSet } = await lease.lease.use((conn) => conn.execute(`SELECT powersync_update_hooks('get')`));
|
|
5880
|
+
if (resultSet) {
|
|
5881
|
+
const updatedTables = JSON.parse(resultSet.rows[0][0]);
|
|
5882
|
+
if (updatedTables.length) {
|
|
5883
|
+
this.#updateBroadcastChannel.postMessage(updatedTables);
|
|
5884
|
+
this.#pushTableUpdateToClients(updatedTables);
|
|
5885
|
+
}
|
|
5886
|
+
}
|
|
5887
|
+
}
|
|
5888
|
+
}
|
|
5889
|
+
finally {
|
|
5890
|
+
await lease.lease.returnLease();
|
|
5891
|
+
}
|
|
5892
|
+
},
|
|
5893
|
+
execute: async (token, sql, params) => {
|
|
5894
|
+
const { lease } = requireOpenAndLease(token);
|
|
5895
|
+
return await lease.use((db) => db.execute(sql, params));
|
|
5896
|
+
},
|
|
5897
|
+
executeBatch: async (token, sql, params) => {
|
|
5898
|
+
const { lease } = requireOpenAndLease(token);
|
|
5899
|
+
return await lease.use((db) => db.executeBatch(sql, params));
|
|
5900
|
+
},
|
|
5901
|
+
setUpdateListener: async (listener) => {
|
|
5902
|
+
requireOpen();
|
|
5903
|
+
if (currentTableListener) {
|
|
5904
|
+
this.#clientTableListeners.delete(currentTableListener);
|
|
5905
|
+
}
|
|
5906
|
+
currentTableListener = listener;
|
|
5907
|
+
if (listener) {
|
|
5908
|
+
this.#clientTableListeners.add(listener);
|
|
5909
|
+
}
|
|
5910
|
+
}
|
|
5990
5911
|
};
|
|
5991
5912
|
}
|
|
5913
|
+
async forceClose() {
|
|
5914
|
+
this.#logger.debug(`Closing connection to ${this.#inner.options}.`);
|
|
5915
|
+
const connection = this.#inner;
|
|
5916
|
+
this.#options.onClose();
|
|
5917
|
+
this.#updateBroadcastChannel.close();
|
|
5918
|
+
await connection.close();
|
|
5919
|
+
}
|
|
5992
5920
|
}
|
|
5993
5921
|
|
|
5994
5922
|
|
|
5995
5923
|
/***/ },
|
|
5996
5924
|
|
|
5997
|
-
/***/ "./lib/src/db/adapters/wa-sqlite/
|
|
5998
|
-
|
|
5999
|
-
!*** ./lib/src/db/adapters/wa-sqlite/
|
|
6000
|
-
|
|
5925
|
+
/***/ "./lib/src/db/adapters/wa-sqlite/RawSqliteConnection.js"
|
|
5926
|
+
/*!**************************************************************!*\
|
|
5927
|
+
!*** ./lib/src/db/adapters/wa-sqlite/RawSqliteConnection.js ***!
|
|
5928
|
+
\**************************************************************/
|
|
6001
5929
|
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
|
|
6002
5930
|
|
|
6003
5931
|
__webpack_require__.r(__webpack_exports__);
|
|
6004
5932
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
6005
|
-
/* harmony export */
|
|
6006
|
-
/* harmony export */ DEFAULT_MODULE_FACTORIES: () => (/* binding */ DEFAULT_MODULE_FACTORIES),
|
|
6007
|
-
/* harmony export */ MultiCipherAsyncWASQLiteModuleFactory: () => (/* binding */ MultiCipherAsyncWASQLiteModuleFactory),
|
|
6008
|
-
/* harmony export */ MultiCipherSyncWASQLiteModuleFactory: () => (/* binding */ MultiCipherSyncWASQLiteModuleFactory),
|
|
6009
|
-
/* harmony export */ SyncWASQLiteModuleFactory: () => (/* binding */ SyncWASQLiteModuleFactory),
|
|
6010
|
-
/* harmony export */ WASQLiteVFS: () => (/* binding */ WASQLiteVFS),
|
|
6011
|
-
/* harmony export */ WASqliteConnection: () => (/* binding */ WASqliteConnection)
|
|
5933
|
+
/* harmony export */ RawSqliteConnection: () => (/* binding */ RawSqliteConnection)
|
|
6012
5934
|
/* harmony export */ });
|
|
6013
5935
|
/* harmony import */ var _journeyapps_wa_sqlite__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @journeyapps/wa-sqlite */ "@journeyapps/wa-sqlite");
|
|
6014
|
-
/* harmony import */ var
|
|
6015
|
-
/* harmony import */ var async_mutex__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! async-mutex */ "async-mutex");
|
|
6016
|
-
|
|
5936
|
+
/* harmony import */ var _vfs_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./vfs.js */ "./lib/src/db/adapters/wa-sqlite/vfs.js");
|
|
6017
5937
|
|
|
6018
5938
|
|
|
6019
5939
|
/**
|
|
6020
|
-
*
|
|
6021
|
-
|
|
6022
|
-
|
|
6023
|
-
|
|
6024
|
-
WASQLiteVFS["IDBBatchAtomicVFS"] = "IDBBatchAtomicVFS";
|
|
6025
|
-
WASQLiteVFS["OPFSCoopSyncVFS"] = "OPFSCoopSyncVFS";
|
|
6026
|
-
WASQLiteVFS["AccessHandlePoolVFS"] = "AccessHandlePoolVFS";
|
|
6027
|
-
})(WASQLiteVFS || (WASQLiteVFS = {}));
|
|
6028
|
-
/**
|
|
6029
|
-
* @internal
|
|
6030
|
-
*/
|
|
6031
|
-
const AsyncWASQLiteModuleFactory = async () => {
|
|
6032
|
-
const { default: factory } = await Promise.resolve(/*! import() */).then(__webpack_require__.bind(__webpack_require__, /*! @journeyapps/wa-sqlite/dist/wa-sqlite-async.mjs */ "../../node_modules/.pnpm/@journeyapps+wa-sqlite@1.5.0/node_modules/@journeyapps/wa-sqlite/dist/wa-sqlite-async.mjs"));
|
|
6033
|
-
return factory();
|
|
6034
|
-
};
|
|
6035
|
-
/**
|
|
6036
|
-
* @internal
|
|
6037
|
-
*/
|
|
6038
|
-
const MultiCipherAsyncWASQLiteModuleFactory = async () => {
|
|
6039
|
-
const { default: factory } = await Promise.resolve(/*! import() */).then(__webpack_require__.bind(__webpack_require__, /*! @journeyapps/wa-sqlite/dist/mc-wa-sqlite-async.mjs */ "../../node_modules/.pnpm/@journeyapps+wa-sqlite@1.5.0/node_modules/@journeyapps/wa-sqlite/dist/mc-wa-sqlite-async.mjs"));
|
|
6040
|
-
return factory();
|
|
6041
|
-
};
|
|
6042
|
-
/**
|
|
6043
|
-
* @internal
|
|
6044
|
-
*/
|
|
6045
|
-
const SyncWASQLiteModuleFactory = async () => {
|
|
6046
|
-
const { default: factory } = await Promise.resolve(/*! import() */).then(__webpack_require__.bind(__webpack_require__, /*! @journeyapps/wa-sqlite/dist/wa-sqlite.mjs */ "../../node_modules/.pnpm/@journeyapps+wa-sqlite@1.5.0/node_modules/@journeyapps/wa-sqlite/dist/wa-sqlite.mjs"));
|
|
6047
|
-
return factory();
|
|
6048
|
-
};
|
|
6049
|
-
/**
|
|
6050
|
-
* @internal
|
|
6051
|
-
*/
|
|
6052
|
-
const MultiCipherSyncWASQLiteModuleFactory = async () => {
|
|
6053
|
-
const { default: factory } = await Promise.resolve(/*! import() */).then(__webpack_require__.bind(__webpack_require__, /*! @journeyapps/wa-sqlite/dist/mc-wa-sqlite.mjs */ "../../node_modules/.pnpm/@journeyapps+wa-sqlite@1.5.0/node_modules/@journeyapps/wa-sqlite/dist/mc-wa-sqlite.mjs"));
|
|
6054
|
-
return factory();
|
|
6055
|
-
};
|
|
6056
|
-
/**
|
|
6057
|
-
* @internal
|
|
6058
|
-
*/
|
|
6059
|
-
const DEFAULT_MODULE_FACTORIES = {
|
|
6060
|
-
[WASQLiteVFS.IDBBatchAtomicVFS]: async (options) => {
|
|
6061
|
-
let module;
|
|
6062
|
-
if (options.encryptionKey) {
|
|
6063
|
-
module = await MultiCipherAsyncWASQLiteModuleFactory();
|
|
6064
|
-
}
|
|
6065
|
-
else {
|
|
6066
|
-
module = await AsyncWASQLiteModuleFactory();
|
|
6067
|
-
}
|
|
6068
|
-
const { IDBBatchAtomicVFS } = await Promise.resolve(/*! import() */).then(__webpack_require__.t.bind(__webpack_require__, /*! @journeyapps/wa-sqlite/src/examples/IDBBatchAtomicVFS.js */ "@journeyapps/wa-sqlite/src/examples/IDBBatchAtomicVFS.js", 19));
|
|
6069
|
-
return {
|
|
6070
|
-
module,
|
|
6071
|
-
// @ts-expect-error The types for this static method are missing upstream
|
|
6072
|
-
vfs: await IDBBatchAtomicVFS.create(options.dbFileName, module, { lockPolicy: 'exclusive' })
|
|
6073
|
-
};
|
|
6074
|
-
},
|
|
6075
|
-
[WASQLiteVFS.AccessHandlePoolVFS]: async (options) => {
|
|
6076
|
-
let module;
|
|
6077
|
-
if (options.encryptionKey) {
|
|
6078
|
-
module = await MultiCipherSyncWASQLiteModuleFactory();
|
|
6079
|
-
}
|
|
6080
|
-
else {
|
|
6081
|
-
module = await SyncWASQLiteModuleFactory();
|
|
6082
|
-
}
|
|
6083
|
-
// @ts-expect-error The types for this static method are missing upstream
|
|
6084
|
-
const { AccessHandlePoolVFS } = await Promise.resolve(/*! import() */).then(__webpack_require__.t.bind(__webpack_require__, /*! @journeyapps/wa-sqlite/src/examples/AccessHandlePoolVFS.js */ "@journeyapps/wa-sqlite/src/examples/AccessHandlePoolVFS.js", 19));
|
|
6085
|
-
return {
|
|
6086
|
-
module,
|
|
6087
|
-
vfs: await AccessHandlePoolVFS.create(options.dbFileName, module)
|
|
6088
|
-
};
|
|
6089
|
-
},
|
|
6090
|
-
[WASQLiteVFS.OPFSCoopSyncVFS]: async (options) => {
|
|
6091
|
-
let module;
|
|
6092
|
-
if (options.encryptionKey) {
|
|
6093
|
-
module = await MultiCipherSyncWASQLiteModuleFactory();
|
|
6094
|
-
}
|
|
6095
|
-
else {
|
|
6096
|
-
module = await SyncWASQLiteModuleFactory();
|
|
6097
|
-
}
|
|
6098
|
-
// @ts-expect-error The types for this static method are missing upstream
|
|
6099
|
-
const { OPFSCoopSyncVFS } = await Promise.resolve(/*! import() */).then(__webpack_require__.t.bind(__webpack_require__, /*! @journeyapps/wa-sqlite/src/examples/OPFSCoopSyncVFS.js */ "@journeyapps/wa-sqlite/src/examples/OPFSCoopSyncVFS.js", 19));
|
|
6100
|
-
const vfs = await OPFSCoopSyncVFS.create(options.dbFileName, module);
|
|
6101
|
-
return {
|
|
6102
|
-
module,
|
|
6103
|
-
vfs
|
|
6104
|
-
};
|
|
6105
|
-
}
|
|
6106
|
-
};
|
|
6107
|
-
/**
|
|
6108
|
-
* @internal
|
|
6109
|
-
* WA-SQLite connection which directly interfaces with WA-SQLite.
|
|
6110
|
-
* This is usually instantiated inside a worker.
|
|
5940
|
+
* A small wrapper around WA-sqlite to help with opening databases and running statements by preparing them internally.
|
|
5941
|
+
*
|
|
5942
|
+
* This is an internal class, and it must never be used directly. Wrappers are required to ensure raw connections aren't
|
|
5943
|
+
* used concurrently across tabs.
|
|
6111
5944
|
*/
|
|
6112
|
-
class
|
|
5945
|
+
class RawSqliteConnection {
|
|
6113
5946
|
options;
|
|
6114
5947
|
_sqliteAPI = null;
|
|
6115
|
-
_dbP = null;
|
|
6116
|
-
_moduleFactory;
|
|
6117
|
-
updatedTables;
|
|
6118
|
-
updateTimer;
|
|
6119
|
-
statementMutex;
|
|
6120
|
-
broadcastChannel;
|
|
6121
5948
|
/**
|
|
6122
|
-
*
|
|
6123
|
-
* notification loops.
|
|
5949
|
+
* The `sqlite3*` connection pointer.
|
|
6124
5950
|
*/
|
|
6125
|
-
|
|
6126
|
-
|
|
6127
|
-
_holdId;
|
|
5951
|
+
db = 0;
|
|
5952
|
+
_moduleFactory;
|
|
6128
5953
|
constructor(options) {
|
|
6129
|
-
super();
|
|
6130
5954
|
this.options = options;
|
|
6131
|
-
this.
|
|
6132
|
-
this.updateTimer = null;
|
|
6133
|
-
this.broadcastChannel = null;
|
|
6134
|
-
this.connectionId = new Date().valueOf() + Math.random();
|
|
6135
|
-
this.statementMutex = new async_mutex__WEBPACK_IMPORTED_MODULE_2__.Mutex();
|
|
6136
|
-
this._moduleFactory = DEFAULT_MODULE_FACTORIES[this.options.vfs];
|
|
6137
|
-
this._holdCounter = 0;
|
|
6138
|
-
this._holdId = null;
|
|
5955
|
+
this._moduleFactory = _vfs_js__WEBPACK_IMPORTED_MODULE_1__.DEFAULT_MODULE_FACTORIES[this.options.vfs];
|
|
6139
5956
|
}
|
|
6140
|
-
|
|
6141
|
-
|
|
6142
|
-
* This can be used to check for invalid states.
|
|
6143
|
-
*/
|
|
6144
|
-
get currentHoldId() {
|
|
6145
|
-
return this._holdId;
|
|
5957
|
+
get isOpen() {
|
|
5958
|
+
return this.db != 0;
|
|
6146
5959
|
}
|
|
6147
|
-
|
|
6148
|
-
|
|
6149
|
-
|
|
6150
|
-
}
|
|
6151
|
-
return this._sqliteAPI;
|
|
6152
|
-
}
|
|
6153
|
-
get dbP() {
|
|
6154
|
-
if (!this._dbP) {
|
|
6155
|
-
throw new Error(`Initialization has not completed`);
|
|
6156
|
-
}
|
|
6157
|
-
return this._dbP;
|
|
6158
|
-
}
|
|
6159
|
-
/**
|
|
6160
|
-
* Checks if the database connection is in autocommit mode.
|
|
6161
|
-
* @returns true if in autocommit mode, false if in a transaction
|
|
6162
|
-
*/
|
|
6163
|
-
async isAutoCommit() {
|
|
6164
|
-
return this.sqliteAPI.get_autocommit(this.dbP) != 0;
|
|
6165
|
-
}
|
|
6166
|
-
async markHold() {
|
|
6167
|
-
const previousHoldId = this._holdId;
|
|
6168
|
-
this._holdId = `${++this._holdCounter}`;
|
|
6169
|
-
if (previousHoldId) {
|
|
6170
|
-
await this.iterateAsyncListeners(async (cb) => cb.holdOverwritten?.(previousHoldId));
|
|
6171
|
-
}
|
|
6172
|
-
return this._holdId;
|
|
6173
|
-
}
|
|
6174
|
-
async releaseHold(holdId) {
|
|
6175
|
-
if (holdId != this._holdId) {
|
|
6176
|
-
throw new Error(`Invalid hold state, expected ${this._holdId} but got ${holdId}`);
|
|
6177
|
-
}
|
|
6178
|
-
this._holdId = null;
|
|
6179
|
-
}
|
|
6180
|
-
async openDB() {
|
|
6181
|
-
this._dbP = await this.sqliteAPI.open_v2(this.options.dbFilename);
|
|
6182
|
-
return this._dbP;
|
|
6183
|
-
}
|
|
6184
|
-
async executeEncryptionPragma() {
|
|
5960
|
+
async init() {
|
|
5961
|
+
const api = (this._sqliteAPI = await this.openSQLiteAPI());
|
|
5962
|
+
this.db = await api.open_v2(this.options.dbFilename);
|
|
5963
|
+
await this.executeRaw(`PRAGMA temp_store = ${this.options.temporaryStorage};`);
|
|
6185
5964
|
if (this.options.encryptionKey) {
|
|
6186
|
-
|
|
5965
|
+
const escapedKey = this.options.encryptionKey.replace("'", "''");
|
|
5966
|
+
await this.executeRaw(`PRAGMA key = '${escapedKey}'`);
|
|
6187
5967
|
}
|
|
6188
|
-
|
|
5968
|
+
await this.executeRaw(`PRAGMA cache_size = -${this.options.cacheSizeKb};`);
|
|
5969
|
+
await this.executeRaw(`SELECT powersync_update_hooks('install');`);
|
|
6189
5970
|
}
|
|
6190
5971
|
async openSQLiteAPI() {
|
|
6191
5972
|
const { module, vfs } = await this._moduleFactory({
|
|
6192
5973
|
dbFileName: this.options.dbFilename,
|
|
6193
5974
|
encryptionKey: this.options.encryptionKey
|
|
6194
5975
|
});
|
|
6195
|
-
const sqlite3 = _journeyapps_wa_sqlite__WEBPACK_IMPORTED_MODULE_0__.Factory(module);
|
|
5976
|
+
const sqlite3 = (0,_journeyapps_wa_sqlite__WEBPACK_IMPORTED_MODULE_0__.Factory)(module);
|
|
6196
5977
|
sqlite3.vfs_register(vfs, true);
|
|
6197
5978
|
/**
|
|
6198
5979
|
* Register the PowerSync core SQLite extension
|
|
@@ -6209,278 +5990,95 @@ class WASqliteConnection extends _powersync_common__WEBPACK_IMPORTED_MODULE_1__.
|
|
|
6209
5990
|
}
|
|
6210
5991
|
return sqlite3;
|
|
6211
5992
|
}
|
|
6212
|
-
|
|
6213
|
-
|
|
6214
|
-
|
|
6215
|
-
const data = event.data;
|
|
6216
|
-
if (this.connectionId == data.connectionId) {
|
|
6217
|
-
// Ignore messages from the same connection
|
|
6218
|
-
return;
|
|
6219
|
-
}
|
|
6220
|
-
// Ensuring that we don't rebroadcast the same message
|
|
6221
|
-
this.queueTableUpdate(data.changedTables, false);
|
|
6222
|
-
});
|
|
6223
|
-
}
|
|
6224
|
-
queueTableUpdate(tableNames, shouldBroadcast = true) {
|
|
6225
|
-
tableNames.forEach((tableName) => this.updatedTables.add(tableName));
|
|
6226
|
-
if (this.updateTimer == null) {
|
|
6227
|
-
this.updateTimer = setTimeout(() => this.fireUpdates(shouldBroadcast), 0);
|
|
6228
|
-
}
|
|
6229
|
-
}
|
|
6230
|
-
async init() {
|
|
6231
|
-
this._sqliteAPI = await this.openSQLiteAPI();
|
|
6232
|
-
await this.openDB();
|
|
6233
|
-
this.registerBroadcastListeners();
|
|
6234
|
-
await this.executeSingleStatement(`PRAGMA temp_store = ${this.options.temporaryStorage};`);
|
|
6235
|
-
await this.executeEncryptionPragma();
|
|
6236
|
-
await this.executeSingleStatement(`PRAGMA cache_size = -${this.options.cacheSizeKb};`);
|
|
6237
|
-
this.sqliteAPI.update_hook(this.dbP, (updateType, dbName, tableName) => {
|
|
6238
|
-
if (!tableName) {
|
|
6239
|
-
return;
|
|
6240
|
-
}
|
|
6241
|
-
const changedTables = new Set([tableName]);
|
|
6242
|
-
this.queueTableUpdate(changedTables);
|
|
6243
|
-
});
|
|
6244
|
-
}
|
|
6245
|
-
async getConfig() {
|
|
6246
|
-
return this.options;
|
|
6247
|
-
}
|
|
6248
|
-
fireUpdates(shouldBroadcast = true) {
|
|
6249
|
-
this.updateTimer = null;
|
|
6250
|
-
const event = { tables: [...this.updatedTables], groupedUpdates: {}, rawUpdates: [] };
|
|
6251
|
-
// Share to other connections
|
|
6252
|
-
if (shouldBroadcast) {
|
|
6253
|
-
this.broadcastChannel.postMessage({
|
|
6254
|
-
changedTables: this.updatedTables,
|
|
6255
|
-
connectionId: this.connectionId
|
|
6256
|
-
});
|
|
5993
|
+
requireSqlite() {
|
|
5994
|
+
if (!this._sqliteAPI) {
|
|
5995
|
+
throw new Error(`Initialization has not completed`);
|
|
6257
5996
|
}
|
|
6258
|
-
this.
|
|
6259
|
-
this.iterateListeners((cb) => cb.tablesUpdated?.(event));
|
|
5997
|
+
return this._sqliteAPI;
|
|
6260
5998
|
}
|
|
6261
5999
|
/**
|
|
6262
|
-
*
|
|
6000
|
+
* Checks if the database connection is in autocommit mode.
|
|
6001
|
+
* @returns true if in autocommit mode, false if in a transaction
|
|
6263
6002
|
*/
|
|
6264
|
-
|
|
6265
|
-
return this.
|
|
6266
|
-
let affectedRows = 0;
|
|
6267
|
-
try {
|
|
6268
|
-
await this.executeSingleStatement('BEGIN TRANSACTION');
|
|
6269
|
-
const wrappedBindings = bindings ? bindings : [];
|
|
6270
|
-
for await (const stmt of this.sqliteAPI.statements(this.dbP, sql)) {
|
|
6271
|
-
if (stmt === null) {
|
|
6272
|
-
return {
|
|
6273
|
-
rowsAffected: 0,
|
|
6274
|
-
rows: { _array: [], length: 0 }
|
|
6275
|
-
};
|
|
6276
|
-
}
|
|
6277
|
-
//Prepare statement once
|
|
6278
|
-
for (const binding of wrappedBindings) {
|
|
6279
|
-
// TODO not sure why this is needed currently, but booleans break
|
|
6280
|
-
for (let i = 0; i < binding.length; i++) {
|
|
6281
|
-
const b = binding[i];
|
|
6282
|
-
if (typeof b == 'boolean') {
|
|
6283
|
-
binding[i] = b ? 1 : 0;
|
|
6284
|
-
}
|
|
6285
|
-
}
|
|
6286
|
-
if (bindings) {
|
|
6287
|
-
this.sqliteAPI.bind_collection(stmt, binding);
|
|
6288
|
-
}
|
|
6289
|
-
const result = await this.sqliteAPI.step(stmt);
|
|
6290
|
-
if (result === _journeyapps_wa_sqlite__WEBPACK_IMPORTED_MODULE_0__.SQLITE_DONE) {
|
|
6291
|
-
//The value returned by sqlite3_changes() immediately after an INSERT, UPDATE or DELETE statement run on a view is always zero.
|
|
6292
|
-
affectedRows += this.sqliteAPI.changes(this.dbP);
|
|
6293
|
-
}
|
|
6294
|
-
this.sqliteAPI.reset(stmt);
|
|
6295
|
-
}
|
|
6296
|
-
}
|
|
6297
|
-
await this.executeSingleStatement('COMMIT');
|
|
6298
|
-
}
|
|
6299
|
-
catch (err) {
|
|
6300
|
-
await this.executeSingleStatement('ROLLBACK');
|
|
6301
|
-
return {
|
|
6302
|
-
rowsAffected: 0,
|
|
6303
|
-
rows: { _array: [], length: 0 }
|
|
6304
|
-
};
|
|
6305
|
-
}
|
|
6306
|
-
const result = {
|
|
6307
|
-
rowsAffected: affectedRows,
|
|
6308
|
-
rows: { _array: [], length: 0 }
|
|
6309
|
-
};
|
|
6310
|
-
return result;
|
|
6311
|
-
});
|
|
6003
|
+
isAutoCommit() {
|
|
6004
|
+
return this.requireSqlite().get_autocommit(this.db) != 0;
|
|
6312
6005
|
}
|
|
6313
|
-
/**
|
|
6314
|
-
* This executes single SQL statements inside a requested lock.
|
|
6315
|
-
*/
|
|
6316
6006
|
async execute(sql, bindings) {
|
|
6317
|
-
|
|
6318
|
-
return this.
|
|
6319
|
-
return this.executeSingleStatement(sql, bindings);
|
|
6320
|
-
});
|
|
6321
|
-
}
|
|
6322
|
-
async executeRaw(sql, bindings) {
|
|
6323
|
-
return this.acquireExecuteLock(async () => {
|
|
6324
|
-
return this.executeSingleStatementRaw(sql, bindings);
|
|
6325
|
-
});
|
|
6326
|
-
}
|
|
6327
|
-
async close() {
|
|
6328
|
-
this.broadcastChannel?.close();
|
|
6329
|
-
await this.acquireExecuteLock(async () => {
|
|
6330
|
-
/**
|
|
6331
|
-
* Running the close operation inside the same execute mutex prevents errors like:
|
|
6332
|
-
* ```
|
|
6333
|
-
* unable to close due to unfinalized statements or unfinished backups
|
|
6334
|
-
* ```
|
|
6335
|
-
*/
|
|
6336
|
-
await this.sqliteAPI.close(this.dbP);
|
|
6337
|
-
});
|
|
6338
|
-
}
|
|
6339
|
-
async registerOnTableChange(callback) {
|
|
6340
|
-
return this.registerListener({
|
|
6341
|
-
tablesUpdated: (event) => callback(event)
|
|
6342
|
-
});
|
|
6007
|
+
const resultSet = await this.executeSingleStatementRaw(sql, bindings);
|
|
6008
|
+
return this.wrapQueryResults(this.requireSqlite(), resultSet);
|
|
6343
6009
|
}
|
|
6344
|
-
|
|
6345
|
-
|
|
6346
|
-
|
|
6347
|
-
|
|
6348
|
-
|
|
6349
|
-
|
|
6350
|
-
|
|
6351
|
-
|
|
6352
|
-
* This executes a single statement using SQLite3.
|
|
6353
|
-
*/
|
|
6354
|
-
async executeSingleStatement(sql, bindings) {
|
|
6355
|
-
const results = await this._execute(sql, bindings);
|
|
6356
|
-
const rows = [];
|
|
6357
|
-
for (const resultSet of results) {
|
|
6358
|
-
for (const row of resultSet.rows) {
|
|
6359
|
-
const outRow = {};
|
|
6360
|
-
resultSet.columns.forEach((key, index) => {
|
|
6361
|
-
outRow[key] = row[index];
|
|
6362
|
-
});
|
|
6363
|
-
rows.push(outRow);
|
|
6010
|
+
async executeBatch(sql, bindings) {
|
|
6011
|
+
const results = [];
|
|
6012
|
+
const api = this.requireSqlite();
|
|
6013
|
+
for await (const stmt of api.statements(this.db, sql)) {
|
|
6014
|
+
let columns;
|
|
6015
|
+
for (const parameterSet of bindings) {
|
|
6016
|
+
const rs = await this.stepThroughStatement(api, stmt, parameterSet, columns, false);
|
|
6017
|
+
results.push(this.wrapQueryResults(api, rs));
|
|
6364
6018
|
}
|
|
6019
|
+
// executeBatch can only use a single statement
|
|
6020
|
+
break;
|
|
6365
6021
|
}
|
|
6366
|
-
|
|
6367
|
-
|
|
6368
|
-
|
|
6369
|
-
|
|
6370
|
-
|
|
6371
|
-
|
|
6372
|
-
|
|
6022
|
+
return results;
|
|
6023
|
+
}
|
|
6024
|
+
wrapQueryResults(api, rs) {
|
|
6025
|
+
return {
|
|
6026
|
+
changes: api.changes(this.db),
|
|
6027
|
+
lastInsertRowId: api.last_insert_id(this.db),
|
|
6028
|
+
autocommit: api.get_autocommit(this.db) != 0,
|
|
6029
|
+
resultSet: rs
|
|
6373
6030
|
};
|
|
6374
|
-
return result;
|
|
6375
6031
|
}
|
|
6376
6032
|
/**
|
|
6377
|
-
* This executes a single statement using SQLite3 and returns the results as
|
|
6033
|
+
* This executes a single statement using SQLite3 and returns the results as a {@link RawResultSet}.
|
|
6378
6034
|
*/
|
|
6379
6035
|
async executeSingleStatementRaw(sql, bindings) {
|
|
6380
|
-
const results = await this.
|
|
6381
|
-
return results.
|
|
6036
|
+
const results = await this.executeRaw(sql, bindings);
|
|
6037
|
+
return results.length ? results[0] : undefined;
|
|
6382
6038
|
}
|
|
6383
|
-
async
|
|
6039
|
+
async executeRaw(sql, bindings) {
|
|
6384
6040
|
const results = [];
|
|
6385
|
-
|
|
6041
|
+
const api = this.requireSqlite();
|
|
6042
|
+
for await (const stmt of api.statements(this.db, sql)) {
|
|
6386
6043
|
let columns;
|
|
6387
|
-
const
|
|
6388
|
-
|
|
6389
|
-
|
|
6390
|
-
|
|
6391
|
-
if (typeof b == 'boolean') {
|
|
6392
|
-
arr[index] = b ? 1 : 0;
|
|
6393
|
-
}
|
|
6394
|
-
});
|
|
6395
|
-
this.sqliteAPI.reset(stmt);
|
|
6396
|
-
if (bindings) {
|
|
6397
|
-
this.sqliteAPI.bind_collection(stmt, binding);
|
|
6398
|
-
}
|
|
6399
|
-
const rows = [];
|
|
6400
|
-
while ((await this.sqliteAPI.step(stmt)) === _journeyapps_wa_sqlite__WEBPACK_IMPORTED_MODULE_0__.SQLITE_ROW) {
|
|
6401
|
-
const row = this.sqliteAPI.row(stmt);
|
|
6402
|
-
rows.push(row);
|
|
6403
|
-
}
|
|
6404
|
-
columns = columns ?? this.sqliteAPI.column_names(stmt);
|
|
6405
|
-
if (columns.length) {
|
|
6406
|
-
results.push({ columns, rows });
|
|
6407
|
-
}
|
|
6044
|
+
const rs = await this.stepThroughStatement(api, stmt, bindings ?? [], columns);
|
|
6045
|
+
columns = rs.columns;
|
|
6046
|
+
if (columns.length) {
|
|
6047
|
+
results.push(rs);
|
|
6408
6048
|
}
|
|
6409
6049
|
// When binding parameters, only a single statement is executed.
|
|
6410
6050
|
if (bindings) {
|
|
6411
6051
|
break;
|
|
6412
|
-
}
|
|
6413
|
-
}
|
|
6414
|
-
return results;
|
|
6415
|
-
}
|
|
6416
|
-
|
|
6417
|
-
|
|
6418
|
-
|
|
6419
|
-
|
|
6420
|
-
|
|
6421
|
-
|
|
6422
|
-
/*!************************************************************!*\
|
|
6423
|
-
!*** ./lib/src/db/adapters/wa-sqlite/WASQLiteDBAdapter.js ***!
|
|
6424
|
-
\************************************************************/
|
|
6425
|
-
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
|
|
6426
|
-
|
|
6427
|
-
__webpack_require__.r(__webpack_exports__);
|
|
6428
|
-
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
6429
|
-
/* harmony export */ WASQLiteDBAdapter: () => (/* binding */ WASQLiteDBAdapter)
|
|
6430
|
-
/* harmony export */ });
|
|
6431
|
-
/* harmony import */ var comlink__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! comlink */ "comlink");
|
|
6432
|
-
/* harmony import */ var _PowerSyncDatabase_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../PowerSyncDatabase.js */ "./lib/src/db/PowerSyncDatabase.js");
|
|
6433
|
-
/* harmony import */ var _web_sql_flags_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../web-sql-flags.js */ "./lib/src/db/adapters/web-sql-flags.js");
|
|
6434
|
-
/* harmony import */ var _WorkerWrappedAsyncDatabaseConnection_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../WorkerWrappedAsyncDatabaseConnection.js */ "./lib/src/db/adapters/WorkerWrappedAsyncDatabaseConnection.js");
|
|
6435
|
-
/* harmony import */ var _InternalWASQLiteDBAdapter_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./InternalWASQLiteDBAdapter.js */ "./lib/src/db/adapters/wa-sqlite/InternalWASQLiteDBAdapter.js");
|
|
6436
|
-
/* harmony import */ var _WASQLiteOpenFactory_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./WASQLiteOpenFactory.js */ "./lib/src/db/adapters/wa-sqlite/WASQLiteOpenFactory.js");
|
|
6437
|
-
|
|
6438
|
-
|
|
6439
|
-
|
|
6440
|
-
|
|
6441
|
-
|
|
6442
|
-
|
|
6443
|
-
/**
|
|
6444
|
-
* Adapter for WA-SQLite SQLite connections.
|
|
6445
|
-
*/
|
|
6446
|
-
class WASQLiteDBAdapter extends _InternalWASQLiteDBAdapter_js__WEBPACK_IMPORTED_MODULE_4__.InternalWASQLiteDBAdapter {
|
|
6447
|
-
constructor(options) {
|
|
6448
|
-
super({
|
|
6449
|
-
name: options.dbFilename,
|
|
6450
|
-
openConnection: async () => {
|
|
6451
|
-
const { workerPort, temporaryStorage, cacheSizeKb } = options;
|
|
6452
|
-
if (workerPort) {
|
|
6453
|
-
const remote = comlink__WEBPACK_IMPORTED_MODULE_0__.wrap(workerPort);
|
|
6454
|
-
return new _WorkerWrappedAsyncDatabaseConnection_js__WEBPACK_IMPORTED_MODULE_3__.WorkerWrappedAsyncDatabaseConnection({
|
|
6455
|
-
remote,
|
|
6456
|
-
remoteCanCloseUnexpectedly: false,
|
|
6457
|
-
identifier: options.dbFilename,
|
|
6458
|
-
baseConnection: await remote({
|
|
6459
|
-
...options,
|
|
6460
|
-
temporaryStorage: temporaryStorage ?? _web_sql_flags_js__WEBPACK_IMPORTED_MODULE_2__.TemporaryStorageOption.MEMORY,
|
|
6461
|
-
cacheSizeKb: cacheSizeKb ?? _web_sql_flags_js__WEBPACK_IMPORTED_MODULE_2__.DEFAULT_CACHE_SIZE_KB,
|
|
6462
|
-
flags: (0,_PowerSyncDatabase_js__WEBPACK_IMPORTED_MODULE_1__.resolveWebPowerSyncFlags)(options.flags),
|
|
6463
|
-
encryptionKey: options.encryptionKey
|
|
6464
|
-
})
|
|
6465
|
-
});
|
|
6466
|
-
}
|
|
6467
|
-
const openFactory = new _WASQLiteOpenFactory_js__WEBPACK_IMPORTED_MODULE_5__.WASQLiteOpenFactory({
|
|
6468
|
-
dbFilename: options.dbFilename,
|
|
6469
|
-
dbLocation: options.dbLocation,
|
|
6470
|
-
debugMode: options.debugMode,
|
|
6471
|
-
flags: options.flags,
|
|
6472
|
-
temporaryStorage,
|
|
6473
|
-
cacheSizeKb,
|
|
6474
|
-
logger: options.logger,
|
|
6475
|
-
vfs: options.vfs,
|
|
6476
|
-
encryptionKey: options.encryptionKey,
|
|
6477
|
-
worker: options.worker
|
|
6478
|
-
});
|
|
6479
|
-
return openFactory.openConnection();
|
|
6480
|
-
},
|
|
6481
|
-
debugMode: options.debugMode,
|
|
6482
|
-
logger: options.logger
|
|
6052
|
+
}
|
|
6053
|
+
}
|
|
6054
|
+
return results;
|
|
6055
|
+
}
|
|
6056
|
+
async stepThroughStatement(api, stmt, bindings, knownColumns, includeResults = true) {
|
|
6057
|
+
// TODO not sure why this is needed currently, but booleans break
|
|
6058
|
+
bindings.forEach((b, index, arr) => {
|
|
6059
|
+
if (typeof b == 'boolean') {
|
|
6060
|
+
arr[index] = b ? 1 : 0;
|
|
6061
|
+
}
|
|
6483
6062
|
});
|
|
6063
|
+
api.reset(stmt);
|
|
6064
|
+
if (bindings) {
|
|
6065
|
+
api.bind_collection(stmt, bindings);
|
|
6066
|
+
}
|
|
6067
|
+
const rows = [];
|
|
6068
|
+
while ((await api.step(stmt)) === _journeyapps_wa_sqlite__WEBPACK_IMPORTED_MODULE_0__.SQLITE_ROW) {
|
|
6069
|
+
if (includeResults) {
|
|
6070
|
+
const row = api.row(stmt);
|
|
6071
|
+
rows.push(row);
|
|
6072
|
+
}
|
|
6073
|
+
}
|
|
6074
|
+
knownColumns ??= api.column_names(stmt);
|
|
6075
|
+
return { columns: knownColumns, rows };
|
|
6076
|
+
}
|
|
6077
|
+
async close() {
|
|
6078
|
+
if (this.isOpen) {
|
|
6079
|
+
await this.requireSqlite().close(this.db);
|
|
6080
|
+
this.db = 0;
|
|
6081
|
+
}
|
|
6484
6082
|
}
|
|
6485
6083
|
}
|
|
6486
6084
|
|
|
@@ -6497,13 +6095,19 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
6497
6095
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
6498
6096
|
/* harmony export */ WASQLiteOpenFactory: () => (/* binding */ WASQLiteOpenFactory)
|
|
6499
6097
|
/* harmony export */ });
|
|
6500
|
-
/* harmony import */ var
|
|
6501
|
-
/* harmony import */ var
|
|
6502
|
-
/* harmony import */ var
|
|
6503
|
-
/* harmony import */ var
|
|
6504
|
-
/* harmony import */ var
|
|
6505
|
-
/* harmony import */ var
|
|
6506
|
-
/* harmony import */ var
|
|
6098
|
+
/* harmony import */ var _powersync_common__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @powersync/common */ "@powersync/common");
|
|
6099
|
+
/* harmony import */ var comlink__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! comlink */ "comlink");
|
|
6100
|
+
/* harmony import */ var _worker_db_open_worker_database_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../worker/db/open-worker-database.js */ "./lib/src/worker/db/open-worker-database.js");
|
|
6101
|
+
/* harmony import */ var _web_sql_flags_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../web-sql-flags.js */ "./lib/src/db/adapters/web-sql-flags.js");
|
|
6102
|
+
/* harmony import */ var _SSRDBAdapter_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../SSRDBAdapter.js */ "./lib/src/db/adapters/SSRDBAdapter.js");
|
|
6103
|
+
/* harmony import */ var _vfs_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./vfs.js */ "./lib/src/db/adapters/wa-sqlite/vfs.js");
|
|
6104
|
+
/* harmony import */ var _worker_db_MultiDatabaseServer_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../../worker/db/MultiDatabaseServer.js */ "./lib/src/worker/db/MultiDatabaseServer.js");
|
|
6105
|
+
/* harmony import */ var _DatabaseClient_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./DatabaseClient.js */ "./lib/src/db/adapters/wa-sqlite/DatabaseClient.js");
|
|
6106
|
+
/* harmony import */ var _shared_tab_close_signal_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../../shared/tab_close_signal.js */ "./lib/src/shared/tab_close_signal.js");
|
|
6107
|
+
/* harmony import */ var _AsyncWebAdapter_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../AsyncWebAdapter.js */ "./lib/src/db/adapters/AsyncWebAdapter.js");
|
|
6108
|
+
|
|
6109
|
+
|
|
6110
|
+
|
|
6507
6111
|
|
|
6508
6112
|
|
|
6509
6113
|
|
|
@@ -6514,56 +6118,82 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
6514
6118
|
/**
|
|
6515
6119
|
* Opens a SQLite connection using WA-SQLite.
|
|
6516
6120
|
*/
|
|
6517
|
-
class WASQLiteOpenFactory
|
|
6121
|
+
class WASQLiteOpenFactory {
|
|
6122
|
+
options;
|
|
6123
|
+
resolvedFlags;
|
|
6124
|
+
logger;
|
|
6518
6125
|
constructor(options) {
|
|
6519
|
-
|
|
6126
|
+
this.options = options;
|
|
6520
6127
|
assertValidWASQLiteOpenFactoryOptions(options);
|
|
6128
|
+
this.resolvedFlags = (0,_web_sql_flags_js__WEBPACK_IMPORTED_MODULE_3__.resolveWebSQLFlags)(options.flags);
|
|
6129
|
+
this.logger = options.logger ?? (0,_powersync_common__WEBPACK_IMPORTED_MODULE_0__.createLogger)(`WASQLiteOpenFactory - ${this.options.dbFilename}`);
|
|
6521
6130
|
}
|
|
6522
6131
|
get waOptions() {
|
|
6523
6132
|
// Cast to extended type
|
|
6524
6133
|
return this.options;
|
|
6525
6134
|
}
|
|
6526
6135
|
openAdapter() {
|
|
6527
|
-
return new
|
|
6528
|
-
|
|
6529
|
-
|
|
6530
|
-
|
|
6531
|
-
|
|
6532
|
-
|
|
6136
|
+
return new _AsyncWebAdapter_js__WEBPACK_IMPORTED_MODULE_9__.AsyncDbAdapter(this.openConnection(), this.options.dbFilename);
|
|
6137
|
+
}
|
|
6138
|
+
openDB() {
|
|
6139
|
+
const { resolvedFlags: { disableSSRWarning, enableMultiTabs, ssrMode = (0,_web_sql_flags_js__WEBPACK_IMPORTED_MODULE_3__.isServerSide)() } } = this;
|
|
6140
|
+
if (ssrMode) {
|
|
6141
|
+
if (!disableSSRWarning) {
|
|
6142
|
+
this.logger.warn(`
|
|
6143
|
+
Running PowerSync in SSR mode.
|
|
6144
|
+
Only empty query results will be returned.
|
|
6145
|
+
Disable this warning by setting 'disableSSRWarning: true' in options.`);
|
|
6146
|
+
}
|
|
6147
|
+
return new _SSRDBAdapter_js__WEBPACK_IMPORTED_MODULE_4__.SSRDBAdapter();
|
|
6148
|
+
}
|
|
6149
|
+
if (!enableMultiTabs) {
|
|
6150
|
+
this.logger.warn('Multiple tab support is not enabled. Using this site across multiple tabs may not function correctly.');
|
|
6151
|
+
}
|
|
6152
|
+
return this.openAdapter();
|
|
6533
6153
|
}
|
|
6534
6154
|
async openConnection() {
|
|
6535
6155
|
const { enableMultiTabs, useWebWorker } = this.resolvedFlags;
|
|
6536
|
-
const { vfs =
|
|
6156
|
+
const { vfs = _vfs_js__WEBPACK_IMPORTED_MODULE_5__.WASQLiteVFS.IDBBatchAtomicVFS, temporaryStorage = _web_sql_flags_js__WEBPACK_IMPORTED_MODULE_3__.TemporaryStorageOption.MEMORY, cacheSizeKb = _web_sql_flags_js__WEBPACK_IMPORTED_MODULE_3__.DEFAULT_CACHE_SIZE_KB, encryptionKey } = this.waOptions;
|
|
6537
6157
|
if (!enableMultiTabs) {
|
|
6538
6158
|
this.logger.warn('Multiple tabs are not enabled in this browser');
|
|
6539
6159
|
}
|
|
6160
|
+
const resolvedOptions = {
|
|
6161
|
+
dbFilename: this.options.dbFilename,
|
|
6162
|
+
dbLocation: this.options.dbLocation,
|
|
6163
|
+
debugMode: this.options.debugMode,
|
|
6164
|
+
vfs,
|
|
6165
|
+
temporaryStorage,
|
|
6166
|
+
cacheSizeKb,
|
|
6167
|
+
flags: this.resolvedFlags,
|
|
6168
|
+
encryptionKey: encryptionKey
|
|
6169
|
+
};
|
|
6170
|
+
let clientOptions;
|
|
6171
|
+
let requiresPersistentTriggers = (0,_vfs_js__WEBPACK_IMPORTED_MODULE_5__.vfsRequiresDedicatedWorkers)(vfs);
|
|
6540
6172
|
if (useWebWorker) {
|
|
6541
6173
|
const optionsDbWorker = this.options.worker;
|
|
6542
6174
|
const workerPort = typeof optionsDbWorker == 'function'
|
|
6543
|
-
? (0,
|
|
6175
|
+
? (0,_worker_db_open_worker_database_js__WEBPACK_IMPORTED_MODULE_2__.resolveWorkerDatabasePortFactory)(() => optionsDbWorker({
|
|
6544
6176
|
...this.options,
|
|
6545
6177
|
temporaryStorage,
|
|
6546
6178
|
cacheSizeKb,
|
|
6547
6179
|
flags: this.resolvedFlags,
|
|
6548
6180
|
encryptionKey
|
|
6549
6181
|
}))
|
|
6550
|
-
: (0,
|
|
6551
|
-
const
|
|
6552
|
-
|
|
6553
|
-
|
|
6182
|
+
: (0,_worker_db_open_worker_database_js__WEBPACK_IMPORTED_MODULE_2__.openWorkerDatabasePort)(this.options.dbFilename, enableMultiTabs, optionsDbWorker, this.waOptions.vfs);
|
|
6183
|
+
const source = comlink__WEBPACK_IMPORTED_MODULE_1__.wrap(workerPort);
|
|
6184
|
+
const closeSignal = new AbortController();
|
|
6185
|
+
const connection = await source.connect({
|
|
6186
|
+
...resolvedOptions,
|
|
6187
|
+
logLevel: this.logger.getLevel(),
|
|
6188
|
+
lockName: await (0,_shared_tab_close_signal_js__WEBPACK_IMPORTED_MODULE_8__.generateTabCloseSignal)(closeSignal.signal)
|
|
6189
|
+
});
|
|
6190
|
+
clientOptions = {
|
|
6191
|
+
connection,
|
|
6192
|
+
source,
|
|
6554
6193
|
// This tab owns the worker, so we're guaranteed to outlive it.
|
|
6555
6194
|
remoteCanCloseUnexpectedly: false,
|
|
6556
|
-
baseConnection: await workerDBOpener({
|
|
6557
|
-
dbFilename: this.options.dbFilename,
|
|
6558
|
-
vfs,
|
|
6559
|
-
temporaryStorage,
|
|
6560
|
-
cacheSizeKb,
|
|
6561
|
-
flags: this.resolvedFlags,
|
|
6562
|
-
encryptionKey: encryptionKey,
|
|
6563
|
-
logLevel: this.logger.getLevel()
|
|
6564
|
-
}),
|
|
6565
|
-
identifier: this.options.dbFilename,
|
|
6566
6195
|
onClose: () => {
|
|
6196
|
+
closeSignal.abort();
|
|
6567
6197
|
if (workerPort instanceof Worker) {
|
|
6568
6198
|
workerPort.terminate();
|
|
6569
6199
|
}
|
|
@@ -6571,21 +6201,19 @@ class WASQLiteOpenFactory extends _AbstractWebSQLOpenFactory_js__WEBPACK_IMPORTE
|
|
|
6571
6201
|
workerPort.close();
|
|
6572
6202
|
}
|
|
6573
6203
|
}
|
|
6574
|
-
}
|
|
6204
|
+
};
|
|
6575
6205
|
}
|
|
6576
6206
|
else {
|
|
6577
|
-
// Don't use a web worker
|
|
6578
|
-
|
|
6579
|
-
|
|
6580
|
-
|
|
6581
|
-
|
|
6582
|
-
|
|
6583
|
-
|
|
6584
|
-
|
|
6585
|
-
|
|
6586
|
-
|
|
6587
|
-
});
|
|
6588
|
-
}
|
|
6207
|
+
// Don't use a web worker. Instead, open the MultiDatabaseServer a worker would use locally.
|
|
6208
|
+
const localServer = new _worker_db_MultiDatabaseServer_js__WEBPACK_IMPORTED_MODULE_6__.MultiDatabaseServer(this.logger);
|
|
6209
|
+
requiresPersistentTriggers = true;
|
|
6210
|
+
const connection = await localServer.openConnectionLocally(resolvedOptions);
|
|
6211
|
+
clientOptions = { connection, source: null, remoteCanCloseUnexpectedly: false };
|
|
6212
|
+
}
|
|
6213
|
+
return new _DatabaseClient_js__WEBPACK_IMPORTED_MODULE_7__.DatabaseClient(clientOptions, {
|
|
6214
|
+
...resolvedOptions,
|
|
6215
|
+
requiresPersistentTriggers
|
|
6216
|
+
});
|
|
6589
6217
|
}
|
|
6590
6218
|
}
|
|
6591
6219
|
/**
|
|
@@ -6595,7 +6223,7 @@ function assertValidWASQLiteOpenFactoryOptions(options) {
|
|
|
6595
6223
|
// The OPFS VFS only works in dedicated web workers.
|
|
6596
6224
|
if ('vfs' in options && 'flags' in options) {
|
|
6597
6225
|
const { vfs, flags = {} } = options;
|
|
6598
|
-
if (vfs
|
|
6226
|
+
if (vfs && (0,_vfs_js__WEBPACK_IMPORTED_MODULE_5__.vfsRequiresDedicatedWorkers)(vfs) && 'useWebWorker' in flags && !flags.useWebWorker) {
|
|
6599
6227
|
throw new Error(`Invalid configuration: The 'useWebWorker' flag must be true when using an OPFS-based VFS (${vfs}).`);
|
|
6600
6228
|
}
|
|
6601
6229
|
}
|
|
@@ -6640,6 +6268,117 @@ class WASQLitePowerSyncDatabaseOpenFactory extends _AbstractWebPowerSyncDatabase
|
|
|
6640
6268
|
}
|
|
6641
6269
|
|
|
6642
6270
|
|
|
6271
|
+
/***/ },
|
|
6272
|
+
|
|
6273
|
+
/***/ "./lib/src/db/adapters/wa-sqlite/vfs.js"
|
|
6274
|
+
/*!**********************************************!*\
|
|
6275
|
+
!*** ./lib/src/db/adapters/wa-sqlite/vfs.js ***!
|
|
6276
|
+
\**********************************************/
|
|
6277
|
+
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
|
|
6278
|
+
|
|
6279
|
+
__webpack_require__.r(__webpack_exports__);
|
|
6280
|
+
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
6281
|
+
/* harmony export */ AsyncWASQLiteModuleFactory: () => (/* binding */ AsyncWASQLiteModuleFactory),
|
|
6282
|
+
/* harmony export */ DEFAULT_MODULE_FACTORIES: () => (/* binding */ DEFAULT_MODULE_FACTORIES),
|
|
6283
|
+
/* harmony export */ MultiCipherAsyncWASQLiteModuleFactory: () => (/* binding */ MultiCipherAsyncWASQLiteModuleFactory),
|
|
6284
|
+
/* harmony export */ MultiCipherSyncWASQLiteModuleFactory: () => (/* binding */ MultiCipherSyncWASQLiteModuleFactory),
|
|
6285
|
+
/* harmony export */ SyncWASQLiteModuleFactory: () => (/* binding */ SyncWASQLiteModuleFactory),
|
|
6286
|
+
/* harmony export */ WASQLiteVFS: () => (/* binding */ WASQLiteVFS),
|
|
6287
|
+
/* harmony export */ vfsRequiresDedicatedWorkers: () => (/* binding */ vfsRequiresDedicatedWorkers)
|
|
6288
|
+
/* harmony export */ });
|
|
6289
|
+
/**
|
|
6290
|
+
* List of currently tested virtual filesystems
|
|
6291
|
+
*/
|
|
6292
|
+
var WASQLiteVFS;
|
|
6293
|
+
(function (WASQLiteVFS) {
|
|
6294
|
+
WASQLiteVFS["IDBBatchAtomicVFS"] = "IDBBatchAtomicVFS";
|
|
6295
|
+
WASQLiteVFS["OPFSCoopSyncVFS"] = "OPFSCoopSyncVFS";
|
|
6296
|
+
WASQLiteVFS["AccessHandlePoolVFS"] = "AccessHandlePoolVFS";
|
|
6297
|
+
})(WASQLiteVFS || (WASQLiteVFS = {}));
|
|
6298
|
+
function vfsRequiresDedicatedWorkers(vfs) {
|
|
6299
|
+
return vfs != WASQLiteVFS.IDBBatchAtomicVFS;
|
|
6300
|
+
}
|
|
6301
|
+
/**
|
|
6302
|
+
* @internal
|
|
6303
|
+
*/
|
|
6304
|
+
const AsyncWASQLiteModuleFactory = async () => {
|
|
6305
|
+
const { default: factory } = await Promise.resolve(/*! import() */).then(__webpack_require__.bind(__webpack_require__, /*! @journeyapps/wa-sqlite/dist/wa-sqlite-async.mjs */ "../../node_modules/.pnpm/@journeyapps+wa-sqlite@1.5.0/node_modules/@journeyapps/wa-sqlite/dist/wa-sqlite-async.mjs"));
|
|
6306
|
+
return factory();
|
|
6307
|
+
};
|
|
6308
|
+
/**
|
|
6309
|
+
* @internal
|
|
6310
|
+
*/
|
|
6311
|
+
const MultiCipherAsyncWASQLiteModuleFactory = async () => {
|
|
6312
|
+
const { default: factory } = await Promise.resolve(/*! import() */).then(__webpack_require__.bind(__webpack_require__, /*! @journeyapps/wa-sqlite/dist/mc-wa-sqlite-async.mjs */ "../../node_modules/.pnpm/@journeyapps+wa-sqlite@1.5.0/node_modules/@journeyapps/wa-sqlite/dist/mc-wa-sqlite-async.mjs"));
|
|
6313
|
+
return factory();
|
|
6314
|
+
};
|
|
6315
|
+
/**
|
|
6316
|
+
* @internal
|
|
6317
|
+
*/
|
|
6318
|
+
const SyncWASQLiteModuleFactory = async () => {
|
|
6319
|
+
const { default: factory } = await Promise.resolve(/*! import() */).then(__webpack_require__.bind(__webpack_require__, /*! @journeyapps/wa-sqlite/dist/wa-sqlite.mjs */ "../../node_modules/.pnpm/@journeyapps+wa-sqlite@1.5.0/node_modules/@journeyapps/wa-sqlite/dist/wa-sqlite.mjs"));
|
|
6320
|
+
return factory();
|
|
6321
|
+
};
|
|
6322
|
+
/**
|
|
6323
|
+
* @internal
|
|
6324
|
+
*/
|
|
6325
|
+
const MultiCipherSyncWASQLiteModuleFactory = async () => {
|
|
6326
|
+
const { default: factory } = await Promise.resolve(/*! import() */).then(__webpack_require__.bind(__webpack_require__, /*! @journeyapps/wa-sqlite/dist/mc-wa-sqlite.mjs */ "../../node_modules/.pnpm/@journeyapps+wa-sqlite@1.5.0/node_modules/@journeyapps/wa-sqlite/dist/mc-wa-sqlite.mjs"));
|
|
6327
|
+
return factory();
|
|
6328
|
+
};
|
|
6329
|
+
/**
|
|
6330
|
+
* @internal
|
|
6331
|
+
*/
|
|
6332
|
+
const DEFAULT_MODULE_FACTORIES = {
|
|
6333
|
+
[WASQLiteVFS.IDBBatchAtomicVFS]: async (options) => {
|
|
6334
|
+
let module;
|
|
6335
|
+
if (options.encryptionKey) {
|
|
6336
|
+
module = await MultiCipherAsyncWASQLiteModuleFactory();
|
|
6337
|
+
}
|
|
6338
|
+
else {
|
|
6339
|
+
module = await AsyncWASQLiteModuleFactory();
|
|
6340
|
+
}
|
|
6341
|
+
const { IDBBatchAtomicVFS } = await Promise.resolve(/*! import() */).then(__webpack_require__.t.bind(__webpack_require__, /*! @journeyapps/wa-sqlite/src/examples/IDBBatchAtomicVFS.js */ "@journeyapps/wa-sqlite/src/examples/IDBBatchAtomicVFS.js", 19));
|
|
6342
|
+
return {
|
|
6343
|
+
module,
|
|
6344
|
+
// @ts-expect-error The types for this static method are missing upstream
|
|
6345
|
+
vfs: await IDBBatchAtomicVFS.create(options.dbFileName, module, { lockPolicy: 'exclusive' })
|
|
6346
|
+
};
|
|
6347
|
+
},
|
|
6348
|
+
[WASQLiteVFS.AccessHandlePoolVFS]: async (options) => {
|
|
6349
|
+
let module;
|
|
6350
|
+
if (options.encryptionKey) {
|
|
6351
|
+
module = await MultiCipherSyncWASQLiteModuleFactory();
|
|
6352
|
+
}
|
|
6353
|
+
else {
|
|
6354
|
+
module = await SyncWASQLiteModuleFactory();
|
|
6355
|
+
}
|
|
6356
|
+
// @ts-expect-error The types for this static method are missing upstream
|
|
6357
|
+
const { AccessHandlePoolVFS } = await Promise.resolve(/*! import() */).then(__webpack_require__.t.bind(__webpack_require__, /*! @journeyapps/wa-sqlite/src/examples/AccessHandlePoolVFS.js */ "@journeyapps/wa-sqlite/src/examples/AccessHandlePoolVFS.js", 19));
|
|
6358
|
+
return {
|
|
6359
|
+
module,
|
|
6360
|
+
vfs: await AccessHandlePoolVFS.create(options.dbFileName, module)
|
|
6361
|
+
};
|
|
6362
|
+
},
|
|
6363
|
+
[WASQLiteVFS.OPFSCoopSyncVFS]: async (options) => {
|
|
6364
|
+
let module;
|
|
6365
|
+
if (options.encryptionKey) {
|
|
6366
|
+
module = await MultiCipherSyncWASQLiteModuleFactory();
|
|
6367
|
+
}
|
|
6368
|
+
else {
|
|
6369
|
+
module = await SyncWASQLiteModuleFactory();
|
|
6370
|
+
}
|
|
6371
|
+
// @ts-expect-error The types for this static method are missing upstream
|
|
6372
|
+
const { OPFSCoopSyncVFS } = await Promise.resolve(/*! import() */).then(__webpack_require__.t.bind(__webpack_require__, /*! @journeyapps/wa-sqlite/src/examples/OPFSCoopSyncVFS.js */ "@journeyapps/wa-sqlite/src/examples/OPFSCoopSyncVFS.js", 19));
|
|
6373
|
+
const vfs = await OPFSCoopSyncVFS.create(options.dbFileName, module);
|
|
6374
|
+
return {
|
|
6375
|
+
module,
|
|
6376
|
+
vfs
|
|
6377
|
+
};
|
|
6378
|
+
}
|
|
6379
|
+
};
|
|
6380
|
+
|
|
6381
|
+
|
|
6643
6382
|
/***/ },
|
|
6644
6383
|
|
|
6645
6384
|
/***/ "./lib/src/db/adapters/web-sql-flags.js"
|
|
@@ -6707,8 +6446,6 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
6707
6446
|
/* harmony export */ SSRStreamingSyncImplementation: () => (/* binding */ SSRStreamingSyncImplementation)
|
|
6708
6447
|
/* harmony export */ });
|
|
6709
6448
|
/* harmony import */ var _powersync_common__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @powersync/common */ "@powersync/common");
|
|
6710
|
-
/* harmony import */ var async_mutex__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! async-mutex */ "async-mutex");
|
|
6711
|
-
|
|
6712
6449
|
|
|
6713
6450
|
class SSRStreamingSyncImplementation extends _powersync_common__WEBPACK_IMPORTED_MODULE_0__.BaseObserver {
|
|
6714
6451
|
syncMutex;
|
|
@@ -6718,14 +6455,14 @@ class SSRStreamingSyncImplementation extends _powersync_common__WEBPACK_IMPORTED
|
|
|
6718
6455
|
syncStatus;
|
|
6719
6456
|
constructor(options) {
|
|
6720
6457
|
super();
|
|
6721
|
-
this.syncMutex = new
|
|
6722
|
-
this.crudMutex = new
|
|
6458
|
+
this.syncMutex = new _powersync_common__WEBPACK_IMPORTED_MODULE_0__.Mutex();
|
|
6459
|
+
this.crudMutex = new _powersync_common__WEBPACK_IMPORTED_MODULE_0__.Mutex();
|
|
6723
6460
|
this.syncStatus = new _powersync_common__WEBPACK_IMPORTED_MODULE_0__.SyncStatus({});
|
|
6724
6461
|
this.isConnected = false;
|
|
6725
6462
|
}
|
|
6726
6463
|
obtainLock(lockOptions) {
|
|
6727
6464
|
const mutex = lockOptions.type == _powersync_common__WEBPACK_IMPORTED_MODULE_0__.LockType.CRUD ? this.crudMutex : this.syncMutex;
|
|
6728
|
-
return mutex.runExclusive(lockOptions.callback);
|
|
6465
|
+
return mutex.runExclusive(lockOptions.callback, lockOptions.signal);
|
|
6729
6466
|
}
|
|
6730
6467
|
/**
|
|
6731
6468
|
* This is a no-op in SSR mode
|
|
@@ -6788,11 +6525,11 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
6788
6525
|
/* harmony export */ SharedWebStreamingSyncImplementation: () => (/* binding */ SharedWebStreamingSyncImplementation)
|
|
6789
6526
|
/* harmony export */ });
|
|
6790
6527
|
/* harmony import */ var comlink__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! comlink */ "comlink");
|
|
6791
|
-
/* harmony import */ var
|
|
6792
|
-
/* harmony import */ var
|
|
6793
|
-
/* harmony import */ var
|
|
6794
|
-
/* harmony import */ var
|
|
6795
|
-
/* harmony import */ var
|
|
6528
|
+
/* harmony import */ var _worker_sync_AbstractSharedSyncClientProvider_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../worker/sync/AbstractSharedSyncClientProvider.js */ "./lib/src/worker/sync/AbstractSharedSyncClientProvider.js");
|
|
6529
|
+
/* harmony import */ var _worker_sync_SharedSyncImplementation_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../worker/sync/SharedSyncImplementation.js */ "./lib/src/worker/sync/SharedSyncImplementation.js");
|
|
6530
|
+
/* harmony import */ var _adapters_web_sql_flags_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../adapters/web-sql-flags.js */ "./lib/src/db/adapters/web-sql-flags.js");
|
|
6531
|
+
/* harmony import */ var _WebStreamingSyncImplementation_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./WebStreamingSyncImplementation.js */ "./lib/src/db/sync/WebStreamingSyncImplementation.js");
|
|
6532
|
+
/* harmony import */ var _shared_tab_close_signal_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../shared/tab_close_signal.js */ "./lib/src/shared/tab_close_signal.js");
|
|
6796
6533
|
|
|
6797
6534
|
|
|
6798
6535
|
|
|
@@ -6803,7 +6540,7 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
6803
6540
|
* The shared worker will trigger methods on this side of the message port
|
|
6804
6541
|
* via this client provider.
|
|
6805
6542
|
*/
|
|
6806
|
-
class SharedSyncClientProvider extends
|
|
6543
|
+
class SharedSyncClientProvider extends _worker_sync_AbstractSharedSyncClientProvider_js__WEBPACK_IMPORTED_MODULE_1__.AbstractSharedSyncClientProvider {
|
|
6807
6544
|
options;
|
|
6808
6545
|
statusChanged;
|
|
6809
6546
|
webDB;
|
|
@@ -6874,7 +6611,7 @@ class SharedSyncClientProvider extends _worker_sync_AbstractSharedSyncClientProv
|
|
|
6874
6611
|
/**
|
|
6875
6612
|
* The local part of the sync implementation on the web, which talks to a sync implementation hosted in a shared worker.
|
|
6876
6613
|
*/
|
|
6877
|
-
class SharedWebStreamingSyncImplementation extends
|
|
6614
|
+
class SharedWebStreamingSyncImplementation extends _WebStreamingSyncImplementation_js__WEBPACK_IMPORTED_MODULE_4__.WebStreamingSyncImplementation {
|
|
6878
6615
|
syncManager;
|
|
6879
6616
|
clientProvider;
|
|
6880
6617
|
messagePort;
|
|
@@ -6890,10 +6627,10 @@ class SharedWebStreamingSyncImplementation extends _WebStreamingSyncImplementati
|
|
|
6890
6627
|
*/
|
|
6891
6628
|
const resolvedWorkerOptions = {
|
|
6892
6629
|
dbFilename: this.options.identifier,
|
|
6893
|
-
temporaryStorage:
|
|
6894
|
-
cacheSizeKb:
|
|
6630
|
+
temporaryStorage: _adapters_web_sql_flags_js__WEBPACK_IMPORTED_MODULE_3__.TemporaryStorageOption.MEMORY,
|
|
6631
|
+
cacheSizeKb: _adapters_web_sql_flags_js__WEBPACK_IMPORTED_MODULE_3__.DEFAULT_CACHE_SIZE_KB,
|
|
6895
6632
|
...options,
|
|
6896
|
-
flags: (0,
|
|
6633
|
+
flags: (0,_adapters_web_sql_flags_js__WEBPACK_IMPORTED_MODULE_3__.resolveWebSQLFlags)(options.flags)
|
|
6897
6634
|
};
|
|
6898
6635
|
const syncWorker = options.sync?.worker;
|
|
6899
6636
|
if (syncWorker) {
|
|
@@ -6908,7 +6645,7 @@ class SharedWebStreamingSyncImplementation extends _WebStreamingSyncImplementati
|
|
|
6908
6645
|
}
|
|
6909
6646
|
}
|
|
6910
6647
|
else {
|
|
6911
|
-
this.messagePort = new SharedWorker(new URL(/* worker import */ __webpack_require__.p + __webpack_require__.u("
|
|
6648
|
+
this.messagePort = new SharedWorker(new URL(/* worker import */ __webpack_require__.p + __webpack_require__.u("lib_src_worker_sync_SharedSyncImplementation_worker_js"), __webpack_require__.b), {
|
|
6912
6649
|
/* @vite-ignore */
|
|
6913
6650
|
name: `shared-sync-${this.webOptions.identifier}`,
|
|
6914
6651
|
type: undefined
|
|
@@ -6951,24 +6688,9 @@ class SharedWebStreamingSyncImplementation extends _WebStreamingSyncImplementati
|
|
|
6951
6688
|
* - We resolve the top-level promise after the lock has been registered with the shared worker.
|
|
6952
6689
|
* - The client sends the params to the shared worker after locks have been registered.
|
|
6953
6690
|
*/
|
|
6954
|
-
await
|
|
6955
|
-
|
|
6956
|
-
|
|
6957
|
-
// to free resources associated with this tab.
|
|
6958
|
-
// We take hold of this lock as soon-as-possible in order to cater for potentially closed tabs.
|
|
6959
|
-
(0,_shared_navigator_js__WEBPACK_IMPORTED_MODULE_1__.getNavigatorLocks)().request(`tab-close-signal-${crypto.randomUUID()}`, async (lock) => {
|
|
6960
|
-
if (this.abortOnClose.signal.aborted) {
|
|
6961
|
-
return;
|
|
6962
|
-
}
|
|
6963
|
-
// Awaiting here ensures the worker is waiting for the lock
|
|
6964
|
-
await this.syncManager.addLockBasedCloseSignal(lock.name);
|
|
6965
|
-
// The lock has been registered, we can continue with the initialization
|
|
6966
|
-
resolve();
|
|
6967
|
-
await new Promise((r) => {
|
|
6968
|
-
this.abortOnClose.signal.onabort = () => r();
|
|
6969
|
-
});
|
|
6970
|
-
});
|
|
6971
|
-
});
|
|
6691
|
+
const closeSignal = await (0,_shared_tab_close_signal_js__WEBPACK_IMPORTED_MODULE_5__.generateTabCloseSignal)(this.abortOnClose.signal);
|
|
6692
|
+
// Awaiting here ensures the worker is waiting for the lock
|
|
6693
|
+
await this.syncManager.addLockBasedCloseSignal(closeSignal);
|
|
6972
6694
|
const { crudUploadThrottleMs, identifier, retryDelayMs } = this.options;
|
|
6973
6695
|
const flags = { ...this.webOptions.flags, workers: undefined };
|
|
6974
6696
|
await this.syncManager.setParams({
|
|
@@ -7006,13 +6728,13 @@ class SharedWebStreamingSyncImplementation extends _WebStreamingSyncImplementati
|
|
|
7006
6728
|
// Listen for the close acknowledgment from the worker
|
|
7007
6729
|
this.messagePort.addEventListener('message', (event) => {
|
|
7008
6730
|
const payload = event.data;
|
|
7009
|
-
if (payload?.event ===
|
|
6731
|
+
if (payload?.event === _worker_sync_SharedSyncImplementation_js__WEBPACK_IMPORTED_MODULE_2__.SharedSyncClientEvent.CLOSE_ACK) {
|
|
7010
6732
|
resolve();
|
|
7011
6733
|
}
|
|
7012
6734
|
});
|
|
7013
6735
|
// Signal the shared worker that this client is closing its connection to the worker
|
|
7014
6736
|
const closeMessagePayload = {
|
|
7015
|
-
event:
|
|
6737
|
+
event: _worker_sync_SharedSyncImplementation_js__WEBPACK_IMPORTED_MODULE_2__.SharedSyncClientEvent.CLOSE_CLIENT,
|
|
7016
6738
|
data: {}
|
|
7017
6739
|
};
|
|
7018
6740
|
this.messagePort.postMessage(closeMessagePayload);
|
|
@@ -7224,6 +6946,153 @@ const getNavigatorLocks = () => {
|
|
|
7224
6946
|
};
|
|
7225
6947
|
|
|
7226
6948
|
|
|
6949
|
+
/***/ },
|
|
6950
|
+
|
|
6951
|
+
/***/ "./lib/src/shared/tab_close_signal.js"
|
|
6952
|
+
/*!********************************************!*\
|
|
6953
|
+
!*** ./lib/src/shared/tab_close_signal.js ***!
|
|
6954
|
+
\********************************************/
|
|
6955
|
+
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
|
|
6956
|
+
|
|
6957
|
+
__webpack_require__.r(__webpack_exports__);
|
|
6958
|
+
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
6959
|
+
/* harmony export */ generateTabCloseSignal: () => (/* binding */ generateTabCloseSignal)
|
|
6960
|
+
/* harmony export */ });
|
|
6961
|
+
/* harmony import */ var _navigator_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./navigator.js */ "./lib/src/shared/navigator.js");
|
|
6962
|
+
|
|
6963
|
+
/**
|
|
6964
|
+
* Requests a random lock that will be released once the optional signal is aborted (or, if no signal is given, when the
|
|
6965
|
+
* tab is closed).
|
|
6966
|
+
*
|
|
6967
|
+
* This allows sending the name of the lock to another context (e.g. a shared worker), which will also attempt to
|
|
6968
|
+
* acquire it. Since the lock is returned when the tab is closed, this allows the shared worker to free resources
|
|
6969
|
+
* assocatiated with this tab.
|
|
6970
|
+
*
|
|
6971
|
+
* We take hold of this lock as soon-as-possible in order to cater for potentially closed tabs.
|
|
6972
|
+
*/
|
|
6973
|
+
function generateTabCloseSignal(abort) {
|
|
6974
|
+
return new Promise((resolve, reject) => {
|
|
6975
|
+
const options = { signal: abort };
|
|
6976
|
+
(0,_navigator_js__WEBPACK_IMPORTED_MODULE_0__.getNavigatorLocks)()
|
|
6977
|
+
.request(`tab-close-signal-${crypto.randomUUID()}`, options, (lock) => {
|
|
6978
|
+
resolve(lock.name);
|
|
6979
|
+
return new Promise((resolve) => {
|
|
6980
|
+
if (abort) {
|
|
6981
|
+
abort.addEventListener('abort', () => resolve());
|
|
6982
|
+
}
|
|
6983
|
+
});
|
|
6984
|
+
})
|
|
6985
|
+
.catch(reject);
|
|
6986
|
+
});
|
|
6987
|
+
}
|
|
6988
|
+
|
|
6989
|
+
|
|
6990
|
+
/***/ },
|
|
6991
|
+
|
|
6992
|
+
/***/ "./lib/src/worker/db/MultiDatabaseServer.js"
|
|
6993
|
+
/*!**************************************************!*\
|
|
6994
|
+
!*** ./lib/src/worker/db/MultiDatabaseServer.js ***!
|
|
6995
|
+
\**************************************************/
|
|
6996
|
+
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
|
|
6997
|
+
|
|
6998
|
+
__webpack_require__.r(__webpack_exports__);
|
|
6999
|
+
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
7000
|
+
/* harmony export */ MultiDatabaseServer: () => (/* binding */ MultiDatabaseServer),
|
|
7001
|
+
/* harmony export */ isSharedWorker: () => (/* binding */ isSharedWorker)
|
|
7002
|
+
/* harmony export */ });
|
|
7003
|
+
/* harmony import */ var comlink__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! comlink */ "comlink");
|
|
7004
|
+
/* harmony import */ var _db_adapters_wa_sqlite_DatabaseServer_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../db/adapters/wa-sqlite/DatabaseServer.js */ "./lib/src/db/adapters/wa-sqlite/DatabaseServer.js");
|
|
7005
|
+
/* harmony import */ var _shared_navigator_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../shared/navigator.js */ "./lib/src/shared/navigator.js");
|
|
7006
|
+
/* 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");
|
|
7007
|
+
/* 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");
|
|
7008
|
+
|
|
7009
|
+
|
|
7010
|
+
|
|
7011
|
+
|
|
7012
|
+
|
|
7013
|
+
const OPEN_DB_LOCK = 'open-wasqlite-db';
|
|
7014
|
+
/**
|
|
7015
|
+
* Shared state to manage multiple database connections hosted by a worker.
|
|
7016
|
+
*/
|
|
7017
|
+
class MultiDatabaseServer {
|
|
7018
|
+
logger;
|
|
7019
|
+
activeDatabases = new Map();
|
|
7020
|
+
constructor(logger) {
|
|
7021
|
+
this.logger = logger;
|
|
7022
|
+
}
|
|
7023
|
+
async handleConnection(options) {
|
|
7024
|
+
this.logger.setLevel(options.logLevel);
|
|
7025
|
+
return comlink__WEBPACK_IMPORTED_MODULE_0__.proxy(await this.openConnectionLocally(options, options.lockName));
|
|
7026
|
+
}
|
|
7027
|
+
async connectToExisting(name, lockName) {
|
|
7028
|
+
return (0,_shared_navigator_js__WEBPACK_IMPORTED_MODULE_2__.getNavigatorLocks)().request(OPEN_DB_LOCK, async () => {
|
|
7029
|
+
const server = this.activeDatabases.get(name);
|
|
7030
|
+
if (server == null) {
|
|
7031
|
+
throw new Error(`connectToExisting(${name}) failed because the worker doesn't own a database with that name.`);
|
|
7032
|
+
}
|
|
7033
|
+
return comlink__WEBPACK_IMPORTED_MODULE_0__.proxy(await server.connect(lockName));
|
|
7034
|
+
});
|
|
7035
|
+
}
|
|
7036
|
+
async openConnectionLocally(options, lockName) {
|
|
7037
|
+
// Especially on Firefox, we're sometimes seeing "NoModificationAllowedError"s when opening OPFS databases we can
|
|
7038
|
+
// work around by retrying.
|
|
7039
|
+
const maxAttempts = 3;
|
|
7040
|
+
let server;
|
|
7041
|
+
for (let count = 0; count < maxAttempts - 1; count++) {
|
|
7042
|
+
try {
|
|
7043
|
+
server = await this.databaseOpenAttempt(options);
|
|
7044
|
+
}
|
|
7045
|
+
catch (ex) {
|
|
7046
|
+
this.logger.warn(`Attempt ${count + 1} of ${maxAttempts} to open database failed, retrying in 1 second...`, ex);
|
|
7047
|
+
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
7048
|
+
}
|
|
7049
|
+
}
|
|
7050
|
+
// Final attempt if we haven't been able to open the server - rethrow errors if we still can't open.
|
|
7051
|
+
server ??= await this.databaseOpenAttempt(options);
|
|
7052
|
+
return server.connect(lockName);
|
|
7053
|
+
}
|
|
7054
|
+
async databaseOpenAttempt(options) {
|
|
7055
|
+
return (0,_shared_navigator_js__WEBPACK_IMPORTED_MODULE_2__.getNavigatorLocks)().request(OPEN_DB_LOCK, async () => {
|
|
7056
|
+
const { dbFilename } = options;
|
|
7057
|
+
let server = this.activeDatabases.get(dbFilename);
|
|
7058
|
+
if (server == null) {
|
|
7059
|
+
const needsNavigatorLocks = !isSharedWorker;
|
|
7060
|
+
const connection = new _db_adapters_wa_sqlite_RawSqliteConnection_js__WEBPACK_IMPORTED_MODULE_3__.RawSqliteConnection(options);
|
|
7061
|
+
const withSafeConcurrency = new _db_adapters_wa_sqlite_ConcurrentConnection_js__WEBPACK_IMPORTED_MODULE_4__.ConcurrentSqliteConnection(connection, needsNavigatorLocks);
|
|
7062
|
+
// Initializing the RawSqliteConnection will run some pragmas that might write to the database file, so we want
|
|
7063
|
+
// to do that in an exclusive lock. Note that OPEN_DB_LOCK is not enough for that, as another tab might have
|
|
7064
|
+
// already created a connection (and is thus outside of OPEN_DB_LOCK) while currently writing to it.
|
|
7065
|
+
const returnLease = await withSafeConcurrency.acquireMutex();
|
|
7066
|
+
try {
|
|
7067
|
+
await connection.init();
|
|
7068
|
+
}
|
|
7069
|
+
catch (e) {
|
|
7070
|
+
returnLease();
|
|
7071
|
+
await connection.close();
|
|
7072
|
+
throw e;
|
|
7073
|
+
}
|
|
7074
|
+
returnLease();
|
|
7075
|
+
const onClose = () => this.activeDatabases.delete(dbFilename);
|
|
7076
|
+
server = new _db_adapters_wa_sqlite_DatabaseServer_js__WEBPACK_IMPORTED_MODULE_1__.DatabaseServer({
|
|
7077
|
+
inner: withSafeConcurrency,
|
|
7078
|
+
logger: this.logger,
|
|
7079
|
+
onClose
|
|
7080
|
+
});
|
|
7081
|
+
this.activeDatabases.set(dbFilename, server);
|
|
7082
|
+
}
|
|
7083
|
+
return server;
|
|
7084
|
+
});
|
|
7085
|
+
}
|
|
7086
|
+
closeAll() {
|
|
7087
|
+
const existingDatabases = [...this.activeDatabases.values()];
|
|
7088
|
+
return Promise.all(existingDatabases.map((db) => {
|
|
7089
|
+
db.forceClose();
|
|
7090
|
+
}));
|
|
7091
|
+
}
|
|
7092
|
+
}
|
|
7093
|
+
const isSharedWorker = 'SharedWorkerGlobalScope' in globalThis;
|
|
7094
|
+
|
|
7095
|
+
|
|
7227
7096
|
/***/ },
|
|
7228
7097
|
|
|
7229
7098
|
/***/ "./lib/src/worker/db/open-worker-database.js"
|
|
@@ -7240,14 +7109,14 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
7240
7109
|
/* harmony export */ resolveWorkerDatabasePortFactory: () => (/* binding */ resolveWorkerDatabasePortFactory)
|
|
7241
7110
|
/* harmony export */ });
|
|
7242
7111
|
/* harmony import */ var comlink__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! comlink */ "comlink");
|
|
7243
|
-
/* harmony import */ var
|
|
7112
|
+
/* harmony import */ var _db_adapters_wa_sqlite_vfs_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../db/adapters/wa-sqlite/vfs.js */ "./lib/src/db/adapters/wa-sqlite/vfs.js");
|
|
7244
7113
|
|
|
7245
7114
|
|
|
7246
7115
|
/**
|
|
7247
7116
|
* Opens a shared or dedicated worker which exposes opening of database connections
|
|
7248
7117
|
*/
|
|
7249
7118
|
function openWorkerDatabasePort(workerIdentifier, multipleTabs = true, worker = '', vfs) {
|
|
7250
|
-
const needsDedicated = vfs ==
|
|
7119
|
+
const needsDedicated = vfs == _db_adapters_wa_sqlite_vfs_js__WEBPACK_IMPORTED_MODULE_1__.WASQLiteVFS.AccessHandlePoolVFS || vfs == _db_adapters_wa_sqlite_vfs_js__WEBPACK_IMPORTED_MODULE_1__.WASQLiteVFS.OPFSCoopSyncVFS;
|
|
7251
7120
|
if (worker) {
|
|
7252
7121
|
return !needsDedicated && multipleTabs
|
|
7253
7122
|
? new SharedWorker(`${worker}`, {
|
|
@@ -7267,12 +7136,12 @@ function openWorkerDatabasePort(workerIdentifier, multipleTabs = true, worker =
|
|
|
7267
7136
|
* (in the case of Android)
|
|
7268
7137
|
*/
|
|
7269
7138
|
return !needsDedicated && multipleTabs
|
|
7270
|
-
? new SharedWorker(new URL(/* worker import */ __webpack_require__.p + __webpack_require__.u("
|
|
7139
|
+
? new SharedWorker(new URL(/* worker import */ __webpack_require__.p + __webpack_require__.u("lib_src_worker_db_WASQLiteDB_worker_js"), __webpack_require__.b), {
|
|
7271
7140
|
/* @vite-ignore */
|
|
7272
7141
|
name: `shared-DB-worker-${workerIdentifier}`,
|
|
7273
7142
|
type: undefined
|
|
7274
7143
|
}).port
|
|
7275
|
-
: new Worker(new URL(/* worker import */ __webpack_require__.p + __webpack_require__.u("
|
|
7144
|
+
: new Worker(new URL(/* worker import */ __webpack_require__.p + __webpack_require__.u("lib_src_worker_db_WASQLiteDB_worker_js"), __webpack_require__.b), {
|
|
7276
7145
|
/* @vite-ignore */
|
|
7277
7146
|
name: `DB-worker-${workerIdentifier}`,
|
|
7278
7147
|
type: undefined
|
|
@@ -7471,14 +7340,12 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
7471
7340
|
/* harmony export */ SharedSyncImplementation: () => (/* binding */ SharedSyncImplementation)
|
|
7472
7341
|
/* harmony export */ });
|
|
7473
7342
|
/* harmony import */ var _powersync_common__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @powersync/common */ "@powersync/common");
|
|
7474
|
-
/* harmony import */ var
|
|
7475
|
-
/* harmony import */ var
|
|
7476
|
-
/* harmony import */ var
|
|
7477
|
-
/* harmony import */ var
|
|
7478
|
-
/* harmony import */ var
|
|
7479
|
-
/* harmony import */ var
|
|
7480
|
-
/* harmony import */ var _BroadcastLogger_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./BroadcastLogger.js */ "./lib/src/worker/sync/BroadcastLogger.js");
|
|
7481
|
-
|
|
7343
|
+
/* harmony import */ var comlink__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! comlink */ "comlink");
|
|
7344
|
+
/* harmony import */ var _db_sync_WebRemote_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../db/sync/WebRemote.js */ "./lib/src/db/sync/WebRemote.js");
|
|
7345
|
+
/* harmony import */ var _db_sync_WebStreamingSyncImplementation_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../db/sync/WebStreamingSyncImplementation.js */ "./lib/src/db/sync/WebStreamingSyncImplementation.js");
|
|
7346
|
+
/* harmony import */ var _BroadcastLogger_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./BroadcastLogger.js */ "./lib/src/worker/sync/BroadcastLogger.js");
|
|
7347
|
+
/* harmony import */ var _db_adapters_wa_sqlite_DatabaseClient_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../db/adapters/wa-sqlite/DatabaseClient.js */ "./lib/src/db/adapters/wa-sqlite/DatabaseClient.js");
|
|
7348
|
+
/* harmony import */ var _shared_tab_close_signal_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../shared/tab_close_signal.js */ "./lib/src/shared/tab_close_signal.js");
|
|
7482
7349
|
|
|
7483
7350
|
|
|
7484
7351
|
|
|
@@ -7523,14 +7390,14 @@ class SharedSyncImplementation extends _powersync_common__WEBPACK_IMPORTED_MODUL
|
|
|
7523
7390
|
connectionManager;
|
|
7524
7391
|
syncStatus;
|
|
7525
7392
|
broadCastLogger;
|
|
7526
|
-
|
|
7393
|
+
database = this.generateReconnectableDatabase();
|
|
7527
7394
|
constructor() {
|
|
7528
7395
|
super();
|
|
7529
7396
|
this.ports = [];
|
|
7530
7397
|
this.syncParams = null;
|
|
7531
7398
|
this.logger = (0,_powersync_common__WEBPACK_IMPORTED_MODULE_0__.createLogger)('shared-sync');
|
|
7532
7399
|
this.lastConnectOptions = undefined;
|
|
7533
|
-
this.portMutex = new
|
|
7400
|
+
this.portMutex = new _powersync_common__WEBPACK_IMPORTED_MODULE_0__.Mutex();
|
|
7534
7401
|
this.isInitialized = new Promise((resolve) => {
|
|
7535
7402
|
const callback = this.registerListener({
|
|
7536
7403
|
initialized: () => {
|
|
@@ -7539,10 +7406,8 @@ class SharedSyncImplementation extends _powersync_common__WEBPACK_IMPORTED_MODUL
|
|
|
7539
7406
|
}
|
|
7540
7407
|
});
|
|
7541
7408
|
});
|
|
7542
|
-
// Should be configured once we get params
|
|
7543
|
-
this.distributedDB = null;
|
|
7544
7409
|
this.syncStatus = new _powersync_common__WEBPACK_IMPORTED_MODULE_0__.SyncStatus({});
|
|
7545
|
-
this.broadCastLogger = new
|
|
7410
|
+
this.broadCastLogger = new _BroadcastLogger_js__WEBPACK_IMPORTED_MODULE_4__.BroadcastLogger(this.ports);
|
|
7546
7411
|
this.connectionManager = new _powersync_common__WEBPACK_IMPORTED_MODULE_0__.ConnectionManager({
|
|
7547
7412
|
createSyncImplementation: async () => {
|
|
7548
7413
|
await this.waitForReady();
|
|
@@ -7640,38 +7505,8 @@ class SharedSyncImplementation extends _powersync_common__WEBPACK_IMPORTED_MODUL
|
|
|
7640
7505
|
if (params.streamOptions?.flags?.broadcastLogs) {
|
|
7641
7506
|
this.logger = this.broadCastLogger;
|
|
7642
7507
|
}
|
|
7643
|
-
|
|
7644
|
-
|
|
7645
|
-
openConnection: async () => {
|
|
7646
|
-
// Gets a connection from the clients when a new connection is requested.
|
|
7647
|
-
const db = await this.openInternalDB();
|
|
7648
|
-
db.registerListener({
|
|
7649
|
-
closing: () => {
|
|
7650
|
-
lockedAdapter.reOpenInternalDB();
|
|
7651
|
-
}
|
|
7652
|
-
});
|
|
7653
|
-
return db;
|
|
7654
|
-
},
|
|
7655
|
-
logger: this.logger,
|
|
7656
|
-
reOpenOnConnectionClosed: true
|
|
7657
|
-
});
|
|
7658
|
-
this.distributedDB = lockedAdapter;
|
|
7659
|
-
await lockedAdapter.init();
|
|
7660
|
-
lockedAdapter.registerListener({
|
|
7661
|
-
databaseReOpened: () => {
|
|
7662
|
-
// We may have missed some table updates while the database was closed.
|
|
7663
|
-
// We can poke the crud in case we missed any updates.
|
|
7664
|
-
this.connectionManager.syncStreamImplementation?.triggerCrudUpload();
|
|
7665
|
-
/**
|
|
7666
|
-
* FIXME or IMPROVE ME
|
|
7667
|
-
* The Rust client implementation stores sync state on the connection level.
|
|
7668
|
-
* Reopening the database causes a state machine error which should cause the
|
|
7669
|
-
* StreamingSyncImplementation to reconnect. It would be nicer if we could trigger
|
|
7670
|
-
* this reconnect earlier.
|
|
7671
|
-
* This reconnect is not required for IndexedDB.
|
|
7672
|
-
*/
|
|
7673
|
-
}
|
|
7674
|
-
});
|
|
7508
|
+
// Ensure we have a usable database connection, the reconnectable database will connect lazily on first use.
|
|
7509
|
+
await this.database.readLock(async () => { });
|
|
7675
7510
|
self.onerror = (event) => {
|
|
7676
7511
|
// Share any uncaught events on the broadcast logger
|
|
7677
7512
|
this.logger.error('Uncaught exception in PowerSync shared sync worker', event);
|
|
@@ -7703,7 +7538,7 @@ class SharedSyncImplementation extends _powersync_common__WEBPACK_IMPORTED_MODUL
|
|
|
7703
7538
|
return await this.portMutex.runExclusive(() => {
|
|
7704
7539
|
const portProvider = {
|
|
7705
7540
|
port,
|
|
7706
|
-
clientProvider:
|
|
7541
|
+
clientProvider: comlink__WEBPACK_IMPORTED_MODULE_1__.wrap(port),
|
|
7707
7542
|
currentSubscriptions: [],
|
|
7708
7543
|
closeListeners: [],
|
|
7709
7544
|
isClosing: false
|
|
@@ -7750,7 +7585,7 @@ class SharedSyncImplementation extends _powersync_common__WEBPACK_IMPORTED_MODUL
|
|
|
7750
7585
|
await closeListener();
|
|
7751
7586
|
}
|
|
7752
7587
|
this.collectActiveSubscriptions();
|
|
7753
|
-
return () => trackedPort.clientProvider[
|
|
7588
|
+
return () => trackedPort.clientProvider[comlink__WEBPACK_IMPORTED_MODULE_1__.releaseProxy]();
|
|
7754
7589
|
});
|
|
7755
7590
|
}
|
|
7756
7591
|
triggerCrudUpload() {
|
|
@@ -7787,9 +7622,9 @@ class SharedSyncImplementation extends _powersync_common__WEBPACK_IMPORTED_MODUL
|
|
|
7787
7622
|
// This should only be called after initialization has completed
|
|
7788
7623
|
const syncParams = this.syncParams;
|
|
7789
7624
|
// Create a new StreamingSyncImplementation for each connect call. This is usually done is all SDKs.
|
|
7790
|
-
return new
|
|
7791
|
-
adapter: new _powersync_common__WEBPACK_IMPORTED_MODULE_0__.SqliteBucketStorage(this.
|
|
7792
|
-
remote: new
|
|
7625
|
+
return new _db_sync_WebStreamingSyncImplementation_js__WEBPACK_IMPORTED_MODULE_3__.WebStreamingSyncImplementation({
|
|
7626
|
+
adapter: new _powersync_common__WEBPACK_IMPORTED_MODULE_0__.SqliteBucketStorage(this.database, this.logger),
|
|
7627
|
+
remote: new _db_sync_WebRemote_js__WEBPACK_IMPORTED_MODULE_2__.WebRemote({
|
|
7793
7628
|
invalidateCredentials: async () => {
|
|
7794
7629
|
const lastPort = await this.getLastWrappedPort();
|
|
7795
7630
|
if (!lastPort) {
|
|
@@ -7859,9 +7694,9 @@ class SharedSyncImplementation extends _powersync_common__WEBPACK_IMPORTED_MODUL
|
|
|
7859
7694
|
});
|
|
7860
7695
|
}
|
|
7861
7696
|
/**
|
|
7862
|
-
*
|
|
7697
|
+
* Requests a random client to share its database connection with us.
|
|
7863
7698
|
*/
|
|
7864
|
-
async openInternalDB() {
|
|
7699
|
+
async openInternalDB(handleClosed) {
|
|
7865
7700
|
const client = await this.getRandomWrappedPort();
|
|
7866
7701
|
if (!client) {
|
|
7867
7702
|
// Should not really happen in practice
|
|
@@ -7895,8 +7730,9 @@ class SharedSyncImplementation extends _powersync_common__WEBPACK_IMPORTED_MODUL
|
|
|
7895
7730
|
removeCloseListener();
|
|
7896
7731
|
throw ex;
|
|
7897
7732
|
});
|
|
7898
|
-
const remote =
|
|
7733
|
+
const remote = comlink__WEBPACK_IMPORTED_MODULE_1__.wrap(workerPort);
|
|
7899
7734
|
const identifier = this.syncParams.dbParams.dbFilename;
|
|
7735
|
+
const clientLockName = await (0,_shared_tab_close_signal_js__WEBPACK_IMPORTED_MODULE_6__.generateTabCloseSignal)();
|
|
7900
7736
|
/**
|
|
7901
7737
|
* The open could fail if the tab is closed while we're busy opening the database.
|
|
7902
7738
|
* This operation is typically executed inside an exclusive portMutex lock.
|
|
@@ -7904,7 +7740,16 @@ class SharedSyncImplementation extends _powersync_common__WEBPACK_IMPORTED_MODUL
|
|
|
7904
7740
|
* We can't rely on the closeListeners to abort the operation if the tab is closed.
|
|
7905
7741
|
*/
|
|
7906
7742
|
const db = await withAbort({
|
|
7907
|
-
action: () =>
|
|
7743
|
+
action: async () => {
|
|
7744
|
+
const clientView = await remote.connectToExisting({ identifier, lockName: clientLockName });
|
|
7745
|
+
return new _db_adapters_wa_sqlite_DatabaseClient_js__WEBPACK_IMPORTED_MODULE_5__.DatabaseClient({
|
|
7746
|
+
connection: clientView,
|
|
7747
|
+
source: remote,
|
|
7748
|
+
// It's possible for this worker to outlive the client hosting the database for us. We need to be prepared for
|
|
7749
|
+
// that and ensure pending requests are aborted when the tab is closed.
|
|
7750
|
+
remoteCanCloseUnexpectedly: true
|
|
7751
|
+
}, this.syncParams.dbParams);
|
|
7752
|
+
},
|
|
7908
7753
|
signal: abortController.signal,
|
|
7909
7754
|
cleanupOnAbort: (db) => {
|
|
7910
7755
|
db.close();
|
|
@@ -7914,25 +7759,86 @@ class SharedSyncImplementation extends _powersync_common__WEBPACK_IMPORTED_MODUL
|
|
|
7914
7759
|
removeCloseListener();
|
|
7915
7760
|
});
|
|
7916
7761
|
clearTimeout(timeout);
|
|
7917
|
-
const wrapped = new _db_adapters_WorkerWrappedAsyncDatabaseConnection_js__WEBPACK_IMPORTED_MODULE_6__.WorkerWrappedAsyncDatabaseConnection({
|
|
7918
|
-
remote,
|
|
7919
|
-
baseConnection: db,
|
|
7920
|
-
identifier,
|
|
7921
|
-
// It's possible for this worker to outlive the client hosting the database for us. We need to be prepared for
|
|
7922
|
-
// that and ensure pending requests are aborted when the tab is closed.
|
|
7923
|
-
remoteCanCloseUnexpectedly: true
|
|
7924
|
-
});
|
|
7925
7762
|
client.closeListeners.push(async () => {
|
|
7926
7763
|
this.logger.info('Aborting open connection because associated tab closed.');
|
|
7764
|
+
handleClosed(db);
|
|
7927
7765
|
/**
|
|
7928
7766
|
* Don't await this close operation. It might never resolve if the tab is closed.
|
|
7929
7767
|
* We mark the remote as closed first, this will reject any pending requests.
|
|
7930
7768
|
* We then call close. The close operation is configured to fire-and-forget, the main promise will reject immediately.
|
|
7931
7769
|
*/
|
|
7932
|
-
|
|
7933
|
-
|
|
7770
|
+
db.markRemoteClosed();
|
|
7771
|
+
db.close().catch((ex) => this.logger.warn('error closing database connection', ex));
|
|
7934
7772
|
});
|
|
7935
|
-
return
|
|
7773
|
+
return db;
|
|
7774
|
+
}
|
|
7775
|
+
generateReconnectableDatabase() {
|
|
7776
|
+
const syncParams = this.syncParams;
|
|
7777
|
+
const sharedSync = this;
|
|
7778
|
+
class ReconnectPool extends _powersync_common__WEBPACK_IMPORTED_MODULE_0__.BaseObserver {
|
|
7779
|
+
connectionState = null;
|
|
7780
|
+
get name() {
|
|
7781
|
+
return syncParams?.dbParams.dbFilename;
|
|
7782
|
+
}
|
|
7783
|
+
async connect() {
|
|
7784
|
+
if (this.connectionState == null) {
|
|
7785
|
+
const handleClosed = this.handleClientClosed.bind(this);
|
|
7786
|
+
this.connectionState = (async () => {
|
|
7787
|
+
try {
|
|
7788
|
+
const db = await sharedSync.openInternalDB(handleClosed);
|
|
7789
|
+
db.registerListener({
|
|
7790
|
+
tablesUpdated: (notification) => {
|
|
7791
|
+
this.iterateListeners((l) => l.tablesUpdated?.(notification));
|
|
7792
|
+
}
|
|
7793
|
+
});
|
|
7794
|
+
this.connectionState = db;
|
|
7795
|
+
return db;
|
|
7796
|
+
}
|
|
7797
|
+
catch (e) {
|
|
7798
|
+
// Allow reconnecting when the database is used again.
|
|
7799
|
+
this.connectionState = null;
|
|
7800
|
+
throw e;
|
|
7801
|
+
}
|
|
7802
|
+
})();
|
|
7803
|
+
}
|
|
7804
|
+
return await this.connectionState;
|
|
7805
|
+
}
|
|
7806
|
+
async close() {
|
|
7807
|
+
if (this.connectionState != null) {
|
|
7808
|
+
await (await this.connectionState).close();
|
|
7809
|
+
}
|
|
7810
|
+
}
|
|
7811
|
+
handleClientClosed(client) {
|
|
7812
|
+
if (client === this.connectionState) {
|
|
7813
|
+
this.connectionState = null;
|
|
7814
|
+
// We may have missed some table updates while the database was closed.
|
|
7815
|
+
// We can poke the crud in case we missed any updates.
|
|
7816
|
+
const impl = sharedSync.connectionManager.syncStreamImplementation;
|
|
7817
|
+
impl?.triggerCrudUpload();
|
|
7818
|
+
/**
|
|
7819
|
+
* FIXME or IMPROVE ME
|
|
7820
|
+
* The Rust client implementation stores sync state on the connection level.
|
|
7821
|
+
* Reopening the database causes a state machine error which should cause the
|
|
7822
|
+
* StreamingSyncImplementation to reconnect. It would be nicer if we could trigger
|
|
7823
|
+
* this reconnect earlier.
|
|
7824
|
+
* This reconnect is not required for IndexedDB.
|
|
7825
|
+
*/
|
|
7826
|
+
}
|
|
7827
|
+
}
|
|
7828
|
+
async readLock(fn, options) {
|
|
7829
|
+
const db = await this.connect();
|
|
7830
|
+
return db.readLock(fn, options);
|
|
7831
|
+
}
|
|
7832
|
+
async writeLock(fn, options) {
|
|
7833
|
+
const db = await this.connect();
|
|
7834
|
+
return db.writeLock(fn, options);
|
|
7835
|
+
}
|
|
7836
|
+
async refreshSchema() {
|
|
7837
|
+
// Not used by sync client.
|
|
7838
|
+
}
|
|
7839
|
+
}
|
|
7840
|
+
const Adapter = (0,_powersync_common__WEBPACK_IMPORTED_MODULE_0__.DBAdapterDefaultMixin)(ReconnectPool);
|
|
7841
|
+
return new Adapter();
|
|
7936
7842
|
}
|
|
7937
7843
|
/**
|
|
7938
7844
|
* A method to update the all shared statuses for each
|
|
@@ -8151,51 +8057,37 @@ var __webpack_exports__ = {};
|
|
|
8151
8057
|
__webpack_require__.r(__webpack_exports__);
|
|
8152
8058
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
8153
8059
|
/* harmony export */ AbstractWebPowerSyncDatabaseOpenFactory: () => (/* reexport safe */ _db_adapters_AbstractWebPowerSyncDatabaseOpenFactory_js__WEBPACK_IMPORTED_MODULE_2__.AbstractWebPowerSyncDatabaseOpenFactory),
|
|
8154
|
-
/* harmony export */
|
|
8155
|
-
/* harmony export */
|
|
8156
|
-
/* harmony export */
|
|
8157
|
-
/* harmony export */ DEFAULT_MODULE_FACTORIES: () => (/* reexport safe */ _db_adapters_wa_sqlite_WASQLiteConnection_js__WEBPACK_IMPORTED_MODULE_5__.DEFAULT_MODULE_FACTORIES),
|
|
8158
|
-
/* harmony export */ DEFAULT_POWERSYNC_FLAGS: () => (/* reexport safe */ _db_PowerSyncDatabase_js__WEBPACK_IMPORTED_MODULE_10__.DEFAULT_POWERSYNC_FLAGS),
|
|
8159
|
-
/* harmony export */ DEFAULT_WEB_SQL_FLAGS: () => (/* reexport safe */ _db_adapters_web_sql_flags_js__WEBPACK_IMPORTED_MODULE_9__.DEFAULT_WEB_SQL_FLAGS),
|
|
8060
|
+
/* harmony export */ DEFAULT_CACHE_SIZE_KB: () => (/* reexport safe */ _db_adapters_web_sql_flags_js__WEBPACK_IMPORTED_MODULE_6__.DEFAULT_CACHE_SIZE_KB),
|
|
8061
|
+
/* harmony export */ DEFAULT_POWERSYNC_FLAGS: () => (/* reexport safe */ _db_PowerSyncDatabase_js__WEBPACK_IMPORTED_MODULE_7__.DEFAULT_POWERSYNC_FLAGS),
|
|
8062
|
+
/* harmony export */ DEFAULT_WEB_SQL_FLAGS: () => (/* reexport safe */ _db_adapters_web_sql_flags_js__WEBPACK_IMPORTED_MODULE_6__.DEFAULT_WEB_SQL_FLAGS),
|
|
8160
8063
|
/* harmony export */ IndexDBFileSystemStorageAdapter: () => (/* reexport safe */ _attachments_IndexDBFileSystemAdapter_js__WEBPACK_IMPORTED_MODULE_1__.IndexDBFileSystemStorageAdapter),
|
|
8161
|
-
/* harmony export */
|
|
8162
|
-
/* harmony export */
|
|
8163
|
-
/* harmony export */
|
|
8164
|
-
/* harmony export */
|
|
8165
|
-
/* harmony export */
|
|
8166
|
-
/* harmony export */
|
|
8167
|
-
/* harmony export */
|
|
8168
|
-
/* harmony export */
|
|
8169
|
-
/* harmony export */
|
|
8170
|
-
/* harmony export */
|
|
8171
|
-
/* harmony export */
|
|
8172
|
-
/* harmony export */ WebRemote: () => (/* reexport safe */ _db_sync_WebRemote_js__WEBPACK_IMPORTED_MODULE_12__.WebRemote),
|
|
8173
|
-
/* harmony export */ WebStreamingSyncImplementation: () => (/* reexport safe */ _db_sync_WebStreamingSyncImplementation_js__WEBPACK_IMPORTED_MODULE_13__.WebStreamingSyncImplementation),
|
|
8174
|
-
/* harmony export */ isServerSide: () => (/* reexport safe */ _db_adapters_web_sql_flags_js__WEBPACK_IMPORTED_MODULE_9__.isServerSide),
|
|
8175
|
-
/* harmony export */ resolveWebPowerSyncFlags: () => (/* reexport safe */ _db_PowerSyncDatabase_js__WEBPACK_IMPORTED_MODULE_10__.resolveWebPowerSyncFlags),
|
|
8176
|
-
/* harmony export */ resolveWebSQLFlags: () => (/* reexport safe */ _db_adapters_web_sql_flags_js__WEBPACK_IMPORTED_MODULE_9__.resolveWebSQLFlags)
|
|
8064
|
+
/* harmony export */ PowerSyncDatabase: () => (/* reexport safe */ _db_PowerSyncDatabase_js__WEBPACK_IMPORTED_MODULE_7__.PowerSyncDatabase),
|
|
8065
|
+
/* harmony export */ SharedWebStreamingSyncImplementation: () => (/* reexport safe */ _db_sync_SharedWebStreamingSyncImplementation_js__WEBPACK_IMPORTED_MODULE_8__.SharedWebStreamingSyncImplementation),
|
|
8066
|
+
/* harmony export */ TemporaryStorageOption: () => (/* reexport safe */ _db_adapters_web_sql_flags_js__WEBPACK_IMPORTED_MODULE_6__.TemporaryStorageOption),
|
|
8067
|
+
/* harmony export */ WASQLiteOpenFactory: () => (/* reexport safe */ _db_adapters_wa_sqlite_WASQLiteOpenFactory_js__WEBPACK_IMPORTED_MODULE_4__.WASQLiteOpenFactory),
|
|
8068
|
+
/* harmony export */ WASQLitePowerSyncDatabaseOpenFactory: () => (/* reexport safe */ _db_adapters_wa_sqlite_WASQLitePowerSyncDatabaseOpenFactory_js__WEBPACK_IMPORTED_MODULE_5__.WASQLitePowerSyncDatabaseOpenFactory),
|
|
8069
|
+
/* harmony export */ WASQLiteVFS: () => (/* reexport safe */ _db_adapters_wa_sqlite_vfs_js__WEBPACK_IMPORTED_MODULE_3__.WASQLiteVFS),
|
|
8070
|
+
/* harmony export */ WebRemote: () => (/* reexport safe */ _db_sync_WebRemote_js__WEBPACK_IMPORTED_MODULE_9__.WebRemote),
|
|
8071
|
+
/* harmony export */ WebStreamingSyncImplementation: () => (/* reexport safe */ _db_sync_WebStreamingSyncImplementation_js__WEBPACK_IMPORTED_MODULE_10__.WebStreamingSyncImplementation),
|
|
8072
|
+
/* harmony export */ isServerSide: () => (/* reexport safe */ _db_adapters_web_sql_flags_js__WEBPACK_IMPORTED_MODULE_6__.isServerSide),
|
|
8073
|
+
/* harmony export */ resolveWebPowerSyncFlags: () => (/* reexport safe */ _db_PowerSyncDatabase_js__WEBPACK_IMPORTED_MODULE_7__.resolveWebPowerSyncFlags),
|
|
8074
|
+
/* harmony export */ resolveWebSQLFlags: () => (/* reexport safe */ _db_adapters_web_sql_flags_js__WEBPACK_IMPORTED_MODULE_6__.resolveWebSQLFlags)
|
|
8177
8075
|
/* harmony export */ });
|
|
8178
8076
|
/* harmony import */ var _powersync_common__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @powersync/common */ "@powersync/common");
|
|
8179
8077
|
/* harmony reexport (unknown) */ var __WEBPACK_REEXPORT_OBJECT__ = {};
|
|
8180
|
-
/* harmony reexport (unknown) */ for(const __WEBPACK_IMPORT_KEY__ in _powersync_common__WEBPACK_IMPORTED_MODULE_0__) if(
|
|
8078
|
+
/* harmony reexport (unknown) */ for(const __WEBPACK_IMPORT_KEY__ in _powersync_common__WEBPACK_IMPORTED_MODULE_0__) if(["default","WASQLiteVFS"].indexOf(__WEBPACK_IMPORT_KEY__) < 0) __WEBPACK_REEXPORT_OBJECT__[__WEBPACK_IMPORT_KEY__] = () => _powersync_common__WEBPACK_IMPORTED_MODULE_0__[__WEBPACK_IMPORT_KEY__]
|
|
8181
8079
|
/* harmony reexport (unknown) */ __webpack_require__.d(__webpack_exports__, __WEBPACK_REEXPORT_OBJECT__);
|
|
8182
8080
|
/* harmony import */ var _attachments_IndexDBFileSystemAdapter_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./attachments/IndexDBFileSystemAdapter.js */ "./lib/src/attachments/IndexDBFileSystemAdapter.js");
|
|
8183
8081
|
/* harmony import */ var _db_adapters_AbstractWebPowerSyncDatabaseOpenFactory_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./db/adapters/AbstractWebPowerSyncDatabaseOpenFactory.js */ "./lib/src/db/adapters/AbstractWebPowerSyncDatabaseOpenFactory.js");
|
|
8184
|
-
/* harmony import */ var
|
|
8185
|
-
/* harmony import */ var
|
|
8186
|
-
/* harmony import */ var
|
|
8187
|
-
/* harmony import */ var
|
|
8188
|
-
/* harmony import */ var
|
|
8189
|
-
/* harmony import */ var
|
|
8190
|
-
/* harmony import */ var
|
|
8191
|
-
/* harmony import */ var
|
|
8192
|
-
/* harmony import */ var
|
|
8193
|
-
/* harmony import */ var _db_sync_WebRemote_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./db/sync/WebRemote.js */ "./lib/src/db/sync/WebRemote.js");
|
|
8194
|
-
/* harmony import */ var _db_sync_WebStreamingSyncImplementation_js__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./db/sync/WebStreamingSyncImplementation.js */ "./lib/src/db/sync/WebStreamingSyncImplementation.js");
|
|
8195
|
-
/* harmony import */ var _db_adapters_WebDBAdapter_js__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./db/adapters/WebDBAdapter.js */ "./lib/src/db/adapters/WebDBAdapter.js");
|
|
8196
|
-
|
|
8197
|
-
|
|
8198
|
-
|
|
8082
|
+
/* harmony import */ var _db_adapters_wa_sqlite_vfs_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./db/adapters/wa-sqlite/vfs.js */ "./lib/src/db/adapters/wa-sqlite/vfs.js");
|
|
8083
|
+
/* harmony import */ var _db_adapters_wa_sqlite_WASQLiteOpenFactory_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./db/adapters/wa-sqlite/WASQLiteOpenFactory.js */ "./lib/src/db/adapters/wa-sqlite/WASQLiteOpenFactory.js");
|
|
8084
|
+
/* harmony import */ var _db_adapters_wa_sqlite_WASQLitePowerSyncDatabaseOpenFactory_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./db/adapters/wa-sqlite/WASQLitePowerSyncDatabaseOpenFactory.js */ "./lib/src/db/adapters/wa-sqlite/WASQLitePowerSyncDatabaseOpenFactory.js");
|
|
8085
|
+
/* harmony import */ var _db_adapters_web_sql_flags_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./db/adapters/web-sql-flags.js */ "./lib/src/db/adapters/web-sql-flags.js");
|
|
8086
|
+
/* harmony import */ var _db_PowerSyncDatabase_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./db/PowerSyncDatabase.js */ "./lib/src/db/PowerSyncDatabase.js");
|
|
8087
|
+
/* harmony import */ var _db_sync_SharedWebStreamingSyncImplementation_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./db/sync/SharedWebStreamingSyncImplementation.js */ "./lib/src/db/sync/SharedWebStreamingSyncImplementation.js");
|
|
8088
|
+
/* harmony import */ var _db_sync_WebRemote_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./db/sync/WebRemote.js */ "./lib/src/db/sync/WebRemote.js");
|
|
8089
|
+
/* harmony import */ var _db_sync_WebStreamingSyncImplementation_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./db/sync/WebStreamingSyncImplementation.js */ "./lib/src/db/sync/WebStreamingSyncImplementation.js");
|
|
8090
|
+
/* harmony import */ var _db_adapters_WebDBAdapter_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./db/adapters/WebDBAdapter.js */ "./lib/src/db/adapters/WebDBAdapter.js");
|
|
8199
8091
|
|
|
8200
8092
|
|
|
8201
8093
|
|