@powersync/web 1.35.0 → 1.37.0
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 +1126 -1231
- package/dist/index.umd.js.map +1 -1
- package/dist/worker/SharedSyncImplementation.umd.js +599 -3086
- package/dist/worker/SharedSyncImplementation.umd.js.map +1 -1
- package/dist/worker/WASQLiteDB.umd.js +860 -868
- 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 -1878
- 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 -401
- 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 -490
- 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,482 +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))
|
|
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;
|
|
5347
5235
|
});
|
|
5348
|
-
this.initPromise = this._init();
|
|
5349
|
-
}
|
|
5350
|
-
get baseDB() {
|
|
5351
|
-
if (!this._db) {
|
|
5352
|
-
throw new Error(`Initialization has not completed yet. Cannot access base db`);
|
|
5353
|
-
}
|
|
5354
|
-
return this._db;
|
|
5355
|
-
}
|
|
5356
|
-
get name() {
|
|
5357
|
-
return this._dbIdentifier;
|
|
5358
5236
|
}
|
|
5359
|
-
/**
|
|
5360
|
-
* Init is automatic, this helps catch errors or explicitly await initialization
|
|
5361
|
-
*/
|
|
5362
5237
|
async init() {
|
|
5363
|
-
|
|
5364
|
-
}
|
|
5365
|
-
async openInternalDB() {
|
|
5366
|
-
/**
|
|
5367
|
-
* Execute opening of the db in a lock in order not to interfere with other operations.
|
|
5368
|
-
*/
|
|
5369
|
-
return this._acquireLock(async () => {
|
|
5370
|
-
// Dispose any previous table change listener.
|
|
5371
|
-
this._disposeTableChangeListener?.();
|
|
5372
|
-
this._disposeTableChangeListener = null;
|
|
5373
|
-
this._db?.close().catch((ex) => this.logger.warn(`Error closing database before opening new instance`, ex));
|
|
5374
|
-
const isReOpen = !!this._db;
|
|
5375
|
-
this._db = null;
|
|
5376
|
-
this._db = await this.options.openConnection();
|
|
5377
|
-
await this._db.init();
|
|
5378
|
-
this._config = await this._db.getConfig();
|
|
5379
|
-
await this.registerOnChangeListener(this._db);
|
|
5380
|
-
if (isReOpen) {
|
|
5381
|
-
this.iterateListeners((cb) => cb.databaseReOpened?.());
|
|
5382
|
-
}
|
|
5383
|
-
/**
|
|
5384
|
-
* This is only required for the long-lived shared IndexedDB connections.
|
|
5385
|
-
*/
|
|
5386
|
-
this.requiresHolds = this._config.vfs == _wa_sqlite_WASQLiteConnection_js__WEBPACK_IMPORTED_MODULE_3__.WASQLiteVFS.IDBBatchAtomicVFS;
|
|
5387
|
-
});
|
|
5388
|
-
}
|
|
5389
|
-
_reOpen() {
|
|
5390
|
-
this.databaseOpenPromise = this.openInternalDB().finally(() => {
|
|
5391
|
-
this.databaseOpenPromise = null;
|
|
5392
|
-
});
|
|
5393
|
-
return this.databaseOpenPromise;
|
|
5394
|
-
}
|
|
5395
|
-
/**
|
|
5396
|
-
* Re-opens the underlying database.
|
|
5397
|
-
* Returns a pending operation if one is already in progress.
|
|
5398
|
-
*/
|
|
5399
|
-
async reOpenInternalDB() {
|
|
5400
|
-
if (this.closing || !this.options.reOpenOnConnectionClosed) {
|
|
5401
|
-
// No-op
|
|
5402
|
-
return;
|
|
5403
|
-
}
|
|
5404
|
-
else if (this.databaseOpenPromise) {
|
|
5405
|
-
// Already busy opening
|
|
5406
|
-
return this.databaseOpenPromise;
|
|
5407
|
-
}
|
|
5408
|
-
else {
|
|
5409
|
-
return this._reOpen();
|
|
5410
|
-
}
|
|
5411
|
-
}
|
|
5412
|
-
async _init() {
|
|
5413
|
-
/**
|
|
5414
|
-
* For OPFS, we can see this open call sometimes fail due to NoModificationAllowedError.
|
|
5415
|
-
* We should be able to recover from this by re-opening the database.
|
|
5416
|
-
*/
|
|
5417
|
-
const maxAttempts = 3;
|
|
5418
|
-
for (let count = 0; count < maxAttempts; count++) {
|
|
5419
|
-
try {
|
|
5420
|
-
await this.openInternalDB();
|
|
5421
|
-
break;
|
|
5422
|
-
}
|
|
5423
|
-
catch (ex) {
|
|
5424
|
-
if (count == maxAttempts - 1) {
|
|
5425
|
-
throw ex;
|
|
5426
|
-
}
|
|
5427
|
-
this.logger.warn(`Attempt ${count + 1} of ${maxAttempts} to open database failed, retrying in 1 second...`, ex);
|
|
5428
|
-
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
5429
|
-
}
|
|
5430
|
-
}
|
|
5431
|
-
this.iterateListeners((cb) => cb.initialized?.());
|
|
5432
|
-
}
|
|
5433
|
-
getConfiguration() {
|
|
5434
|
-
if (!this._config) {
|
|
5435
|
-
throw new Error(`Cannot get config before initialization is completed`);
|
|
5436
|
-
}
|
|
5437
|
-
return {
|
|
5438
|
-
...this._config,
|
|
5439
|
-
// This can be overridden by the adapter later
|
|
5440
|
-
requiresPersistentTriggers: false
|
|
5441
|
-
};
|
|
5442
|
-
}
|
|
5443
|
-
async waitForInitialized() {
|
|
5444
|
-
// Awaiting this will expose errors on function calls like .execute etc
|
|
5445
|
-
await this.initPromise;
|
|
5446
|
-
}
|
|
5447
|
-
async shareConnection() {
|
|
5448
|
-
if (false == this._db instanceof _WorkerWrappedAsyncDatabaseConnection_js__WEBPACK_IMPORTED_MODULE_2__.WorkerWrappedAsyncDatabaseConnection) {
|
|
5449
|
-
throw new Error(`Only worker connections can be shared`);
|
|
5450
|
-
}
|
|
5451
|
-
return this._db.shareConnection();
|
|
5452
|
-
}
|
|
5453
|
-
/**
|
|
5454
|
-
* Registers a table change notification callback with the base database.
|
|
5455
|
-
* This can be extended by custom implementations in order to handle proxy events.
|
|
5456
|
-
*/
|
|
5457
|
-
async registerOnChangeListener(db) {
|
|
5458
|
-
this._disposeTableChangeListener = await db.registerOnTableChange((event) => {
|
|
5459
|
-
this.iterateListeners((cb) => cb.tablesUpdated?.(event));
|
|
5460
|
-
});
|
|
5461
|
-
}
|
|
5462
|
-
/**
|
|
5463
|
-
* This is currently a no-op on web
|
|
5464
|
-
*/
|
|
5465
|
-
async refreshSchema() { }
|
|
5466
|
-
async execute(query, params) {
|
|
5467
|
-
return this.writeLock((ctx) => ctx.execute(query, params));
|
|
5468
|
-
}
|
|
5469
|
-
async executeRaw(query, params) {
|
|
5470
|
-
return this.writeLock((ctx) => ctx.executeRaw(query, params));
|
|
5238
|
+
await this.inner;
|
|
5471
5239
|
}
|
|
5472
|
-
async executeBatch(query, params) {
|
|
5473
|
-
return this.writeLock((ctx) => this._executeBatch(query, params));
|
|
5474
|
-
}
|
|
5475
|
-
/**
|
|
5476
|
-
* Attempts to close the connection.
|
|
5477
|
-
* Shared workers might not actually close the connection if other
|
|
5478
|
-
* tabs are still using it.
|
|
5479
|
-
*/
|
|
5480
5240
|
async close() {
|
|
5481
|
-
|
|
5482
|
-
|
|
5483
|
-
* Note that we obtain a reference to the callback to avoid calling the callback with `this` as the context.
|
|
5484
|
-
* This is to avoid Comlink attempting to clone `this` when calling the method.
|
|
5485
|
-
*/
|
|
5486
|
-
const dispose = this._disposeTableChangeListener;
|
|
5487
|
-
if (dispose) {
|
|
5488
|
-
dispose();
|
|
5489
|
-
}
|
|
5490
|
-
this.pendingAbortControllers.forEach((controller) => controller.abort('Closed'));
|
|
5491
|
-
await this.baseDB?.close?.();
|
|
5492
|
-
this.closed = true;
|
|
5493
|
-
}
|
|
5494
|
-
async getAll(sql, parameters) {
|
|
5495
|
-
await this.waitForInitialized();
|
|
5496
|
-
return this.dbGetHelpers.getAll(sql, parameters);
|
|
5497
|
-
}
|
|
5498
|
-
async getOptional(sql, parameters) {
|
|
5499
|
-
await this.waitForInitialized();
|
|
5500
|
-
return this.dbGetHelpers.getOptional(sql, parameters);
|
|
5501
|
-
}
|
|
5502
|
-
async get(sql, parameters) {
|
|
5503
|
-
await this.waitForInitialized();
|
|
5504
|
-
return this.dbGetHelpers.get(sql, parameters);
|
|
5241
|
+
const inner = await this.inner;
|
|
5242
|
+
return await inner.close();
|
|
5505
5243
|
}
|
|
5506
5244
|
async readLock(fn, options) {
|
|
5507
|
-
await this.
|
|
5508
|
-
return
|
|
5509
|
-
timeoutMs: options?.timeoutMs ?? this.options.defaultLockTimeoutMs
|
|
5510
|
-
});
|
|
5245
|
+
const inner = await this.inner;
|
|
5246
|
+
return await inner.readLock(fn, options);
|
|
5511
5247
|
}
|
|
5512
5248
|
async writeLock(fn, options) {
|
|
5513
|
-
await this.
|
|
5514
|
-
return
|
|
5515
|
-
timeoutMs: options?.timeoutMs ?? this.options.defaultLockTimeoutMs
|
|
5516
|
-
});
|
|
5249
|
+
const inner = await this.inner;
|
|
5250
|
+
return await inner.writeLock(fn, options);
|
|
5517
5251
|
}
|
|
5518
|
-
async
|
|
5519
|
-
|
|
5520
|
-
throw new Error(`Cannot acquire lock, the database is closing`);
|
|
5521
|
-
}
|
|
5522
|
-
const abortController = new AbortController();
|
|
5523
|
-
this.pendingAbortControllers.add(abortController);
|
|
5524
|
-
const { timeoutMs } = options ?? {};
|
|
5525
|
-
const timeoutId = timeoutMs
|
|
5526
|
-
? setTimeout(() => {
|
|
5527
|
-
abortController.abort(`Timeout after ${timeoutMs}ms`);
|
|
5528
|
-
this.pendingAbortControllers.delete(abortController);
|
|
5529
|
-
}, timeoutMs)
|
|
5530
|
-
: null;
|
|
5531
|
-
return (0,_shared_navigator_js__WEBPACK_IMPORTED_MODULE_1__.getNavigatorLocks)().request(`db-lock-${this._dbIdentifier}`, { signal: abortController.signal }, async () => {
|
|
5532
|
-
this.pendingAbortControllers.delete(abortController);
|
|
5533
|
-
if (timeoutId) {
|
|
5534
|
-
clearTimeout(timeoutId);
|
|
5535
|
-
}
|
|
5536
|
-
return await callback();
|
|
5537
|
-
});
|
|
5252
|
+
async refreshSchema() {
|
|
5253
|
+
await (await this.inner).refreshSchema();
|
|
5538
5254
|
}
|
|
5539
|
-
|
|
5540
|
-
|
|
5541
|
-
|
|
5542
|
-
if (this.databaseOpenPromise) {
|
|
5543
|
-
await this.databaseOpenPromise;
|
|
5544
|
-
}
|
|
5545
|
-
else if (!this._db) {
|
|
5546
|
-
/**
|
|
5547
|
-
* The database is not open anymore, we might need to re-open it.
|
|
5548
|
-
* Typically, _db, can be `null` if we tried to reOpen the database, but failed to succeed in re-opening.
|
|
5549
|
-
* This can happen when disconnecting the client.
|
|
5550
|
-
* Note: It is safe to re-enter this method multiple times.
|
|
5551
|
-
*/
|
|
5552
|
-
await this.reOpenInternalDB();
|
|
5255
|
+
registerListener(listener) {
|
|
5256
|
+
if (this.resolvedClient) {
|
|
5257
|
+
return this.resolvedClient.registerListener(listener);
|
|
5553
5258
|
}
|
|
5554
|
-
|
|
5555
|
-
|
|
5556
|
-
|
|
5557
|
-
|
|
5558
|
-
|
|
5559
|
-
|
|
5560
|
-
* If there is no pending open, but there is also no database - the open
|
|
5561
|
-
* might have failed. We need to re-open the database.
|
|
5562
|
-
*/
|
|
5563
|
-
if (this.databaseOpenPromise || !this._db) {
|
|
5564
|
-
throw new _powersync_common__WEBPACK_IMPORTED_MODULE_0__.ConnectionClosedError('Connection is busy re-opening');
|
|
5565
|
-
}
|
|
5566
|
-
holdId = this.requiresHolds ? await this.baseDB.markHold() : null;
|
|
5567
|
-
return await callback();
|
|
5568
|
-
}
|
|
5569
|
-
catch (ex) {
|
|
5570
|
-
if (_powersync_common__WEBPACK_IMPORTED_MODULE_0__.ConnectionClosedError.MATCHES(ex)) {
|
|
5571
|
-
// Immediately re-open the database. We need to miss as little table updates as possible.
|
|
5572
|
-
// Note, don't await this since it uses the same lock as we're in now.
|
|
5573
|
-
this.reOpenInternalDB();
|
|
5259
|
+
else {
|
|
5260
|
+
const pending = { listener };
|
|
5261
|
+
this.pendingListeners.add(pending);
|
|
5262
|
+
return () => {
|
|
5263
|
+
if (pending.closeAfterRegisteredOnResolvedPool) {
|
|
5264
|
+
return pending.closeAfterRegisteredOnResolvedPool();
|
|
5574
5265
|
}
|
|
5575
|
-
|
|
5576
|
-
|
|
5577
|
-
|
|
5578
|
-
if (holdId) {
|
|
5579
|
-
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);
|
|
5580
5269
|
}
|
|
5581
|
-
}
|
|
5582
|
-
}
|
|
5583
|
-
}
|
|
5584
|
-
async readTransaction(fn, options) {
|
|
5585
|
-
return this.readLock(this.wrapTransaction(fn));
|
|
5586
|
-
}
|
|
5587
|
-
writeTransaction(fn, options) {
|
|
5588
|
-
return this.writeLock(this.wrapTransaction(fn, true));
|
|
5270
|
+
};
|
|
5271
|
+
}
|
|
5589
5272
|
}
|
|
5590
|
-
|
|
5591
|
-
|
|
5592
|
-
|
|
5593
|
-
|
|
5594
|
-
|
|
5595
|
-
*/
|
|
5596
|
-
async getAll(sql, parameters) {
|
|
5597
|
-
const res = await tx.execute(sql, parameters);
|
|
5598
|
-
return res.rows?._array ?? [];
|
|
5599
|
-
},
|
|
5600
|
-
/**
|
|
5601
|
-
* Execute a read-only query and return the first result, or null if the ResultSet is empty.
|
|
5602
|
-
*/
|
|
5603
|
-
async getOptional(sql, parameters) {
|
|
5604
|
-
const res = await tx.execute(sql, parameters);
|
|
5605
|
-
return res.rows?.item(0) ?? null;
|
|
5606
|
-
},
|
|
5607
|
-
/**
|
|
5608
|
-
* Execute a read-only query and return the first result, error if the ResultSet is empty.
|
|
5609
|
-
*/
|
|
5610
|
-
async get(sql, parameters) {
|
|
5611
|
-
const res = await tx.execute(sql, parameters);
|
|
5612
|
-
const first = res.rows?.item(0);
|
|
5613
|
-
if (!first) {
|
|
5614
|
-
throw new Error('Result set is empty');
|
|
5615
|
-
}
|
|
5616
|
-
return first;
|
|
5617
|
-
}
|
|
5618
|
-
};
|
|
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();
|
|
5619
5278
|
}
|
|
5620
|
-
|
|
5621
|
-
|
|
5622
|
-
|
|
5623
|
-
|
|
5624
|
-
|
|
5625
|
-
await this._execute(write ? 'BEGIN EXCLUSIVE' : 'BEGIN');
|
|
5626
|
-
let finalized = false;
|
|
5627
|
-
const commit = async () => {
|
|
5628
|
-
if (finalized) {
|
|
5629
|
-
return { rowsAffected: 0 };
|
|
5630
|
-
}
|
|
5631
|
-
finalized = true;
|
|
5632
|
-
return this._execute('COMMIT');
|
|
5633
|
-
};
|
|
5634
|
-
const rollback = () => {
|
|
5635
|
-
finalized = true;
|
|
5636
|
-
return this._execute('ROLLBACK');
|
|
5637
|
-
};
|
|
5638
|
-
try {
|
|
5639
|
-
const result = await cb({
|
|
5640
|
-
...tx,
|
|
5641
|
-
commit,
|
|
5642
|
-
rollback
|
|
5643
|
-
});
|
|
5644
|
-
if (!finalized) {
|
|
5645
|
-
await commit();
|
|
5646
|
-
}
|
|
5647
|
-
return result;
|
|
5648
|
-
}
|
|
5649
|
-
catch (ex) {
|
|
5650
|
-
this.logger.debug('Caught ex in transaction', ex);
|
|
5651
|
-
try {
|
|
5652
|
-
await rollback();
|
|
5653
|
-
}
|
|
5654
|
-
catch (ex2) {
|
|
5655
|
-
// In rare cases, a rollback may fail.
|
|
5656
|
-
// Safe to ignore.
|
|
5657
|
-
}
|
|
5658
|
-
throw ex;
|
|
5659
|
-
}
|
|
5660
|
-
};
|
|
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.');
|
|
5661
5284
|
}
|
|
5662
|
-
/**
|
|
5663
|
-
* Wraps the worker execute function, awaiting for it to be available
|
|
5664
|
-
*/
|
|
5665
|
-
_execute = async (sql, bindings) => {
|
|
5666
|
-
await this.waitForInitialized();
|
|
5667
|
-
const result = await this.baseDB.execute(sql, bindings);
|
|
5668
|
-
return {
|
|
5669
|
-
...result,
|
|
5670
|
-
rows: {
|
|
5671
|
-
...result.rows,
|
|
5672
|
-
item: (idx) => result.rows._array[idx]
|
|
5673
|
-
}
|
|
5674
|
-
};
|
|
5675
|
-
};
|
|
5676
|
-
/**
|
|
5677
|
-
* Wraps the worker executeRaw function, awaiting for it to be available
|
|
5678
|
-
*/
|
|
5679
|
-
_executeRaw = async (sql, bindings) => {
|
|
5680
|
-
await this.waitForInitialized();
|
|
5681
|
-
return await this.baseDB.executeRaw(sql, bindings);
|
|
5682
|
-
};
|
|
5683
|
-
/**
|
|
5684
|
-
* Wraps the worker executeBatch function, awaiting for it to be available
|
|
5685
|
-
*/
|
|
5686
|
-
_executeBatch = async (query, params) => {
|
|
5687
|
-
await this.waitForInitialized();
|
|
5688
|
-
const result = await this.baseDB.executeBatch(query, params);
|
|
5689
|
-
return {
|
|
5690
|
-
...result,
|
|
5691
|
-
rows: undefined
|
|
5692
|
-
};
|
|
5693
|
-
};
|
|
5694
5285
|
}
|
|
5695
5286
|
|
|
5696
5287
|
|
|
@@ -5707,8 +5298,6 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
5707
5298
|
/* harmony export */ SSRDBAdapter: () => (/* binding */ SSRDBAdapter)
|
|
5708
5299
|
/* harmony export */ });
|
|
5709
5300
|
/* harmony import */ var _powersync_common__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @powersync/common */ "@powersync/common");
|
|
5710
|
-
/* harmony import */ var async_mutex__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! async-mutex */ "async-mutex");
|
|
5711
|
-
|
|
5712
5301
|
|
|
5713
5302
|
const MOCK_QUERY_RESPONSE = {
|
|
5714
5303
|
rowsAffected: 0
|
|
@@ -5725,21 +5314,21 @@ class SSRDBAdapter extends _powersync_common__WEBPACK_IMPORTED_MODULE_0__.BaseOb
|
|
|
5725
5314
|
constructor() {
|
|
5726
5315
|
super();
|
|
5727
5316
|
this.name = 'SSR DB';
|
|
5728
|
-
this.readMutex = new
|
|
5729
|
-
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();
|
|
5730
5319
|
}
|
|
5731
5320
|
close() { }
|
|
5732
5321
|
async readLock(fn, options) {
|
|
5733
|
-
return this.readMutex.runExclusive(() => fn(this));
|
|
5322
|
+
return this.readMutex.runExclusive(() => fn(this), (0,_powersync_common__WEBPACK_IMPORTED_MODULE_0__.timeoutSignal)(options?.timeoutMs));
|
|
5734
5323
|
}
|
|
5735
5324
|
async readTransaction(fn, options) {
|
|
5736
|
-
return this.readLock(() => fn(this.generateMockTransactionContext()));
|
|
5325
|
+
return this.readLock(() => fn(this.generateMockTransactionContext()), options);
|
|
5737
5326
|
}
|
|
5738
5327
|
async writeLock(fn, options) {
|
|
5739
|
-
return this.writeMutex.runExclusive(() => fn(this));
|
|
5328
|
+
return this.writeMutex.runExclusive(() => fn(this), (0,_powersync_common__WEBPACK_IMPORTED_MODULE_0__.timeoutSignal)(options?.timeoutMs));
|
|
5740
5329
|
}
|
|
5741
5330
|
async writeTransaction(fn, options) {
|
|
5742
|
-
return this.writeLock(() => fn(this.generateMockTransactionContext()));
|
|
5331
|
+
return this.writeLock(() => fn(this.generateMockTransactionContext()), options);
|
|
5743
5332
|
}
|
|
5744
5333
|
async execute(query, params) {
|
|
5745
5334
|
return this.writeMutex.runExclusive(async () => MOCK_QUERY_RESPONSE);
|
|
@@ -5793,116 +5382,256 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
5793
5382
|
|
|
5794
5383
|
/***/ },
|
|
5795
5384
|
|
|
5796
|
-
/***/ "./lib/src/db/adapters/
|
|
5797
|
-
|
|
5798
|
-
!*** ./lib/src/db/adapters/
|
|
5799
|
-
|
|
5385
|
+
/***/ "./lib/src/db/adapters/wa-sqlite/ConcurrentConnection.js"
|
|
5386
|
+
/*!***************************************************************!*\
|
|
5387
|
+
!*** ./lib/src/db/adapters/wa-sqlite/ConcurrentConnection.js ***!
|
|
5388
|
+
\***************************************************************/
|
|
5800
5389
|
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
|
|
5801
5390
|
|
|
5802
5391
|
__webpack_require__.r(__webpack_exports__);
|
|
5803
5392
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
5804
|
-
/* harmony export */
|
|
5393
|
+
/* harmony export */ ConcurrentSqliteConnection: () => (/* binding */ ConcurrentSqliteConnection),
|
|
5394
|
+
/* harmony export */ ConnectionLeaseToken: () => (/* binding */ ConnectionLeaseToken)
|
|
5805
5395
|
/* harmony export */ });
|
|
5806
5396
|
/* harmony import */ var _powersync_common__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @powersync/common */ "@powersync/common");
|
|
5807
|
-
/* harmony import */ var comlink__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! comlink */ "comlink");
|
|
5808
|
-
|
|
5809
5397
|
|
|
5810
5398
|
/**
|
|
5811
|
-
*
|
|
5812
|
-
*
|
|
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.
|
|
5813
5406
|
*/
|
|
5814
|
-
class
|
|
5815
|
-
|
|
5816
|
-
lockAbortController = new AbortController();
|
|
5817
|
-
notifyRemoteClosed;
|
|
5818
|
-
constructor(options) {
|
|
5819
|
-
super();
|
|
5820
|
-
this.options = options;
|
|
5821
|
-
if (options.remoteCanCloseUnexpectedly) {
|
|
5822
|
-
this.notifyRemoteClosed = new AbortController();
|
|
5823
|
-
}
|
|
5824
|
-
}
|
|
5825
|
-
get baseConnection() {
|
|
5826
|
-
return this.options.baseConnection;
|
|
5827
|
-
}
|
|
5828
|
-
init() {
|
|
5829
|
-
return this.baseConnection.init();
|
|
5830
|
-
}
|
|
5407
|
+
class ConcurrentSqliteConnection {
|
|
5408
|
+
inner;
|
|
5831
5409
|
/**
|
|
5832
|
-
*
|
|
5410
|
+
* An outer mutex ensuring at most one {@link ConnectionLeaseToken} can exist for this connection at a time.
|
|
5833
5411
|
*
|
|
5834
|
-
*
|
|
5835
|
-
* it happens, all methods on the {@link baseConnection} would never resolve. To avoid livelocks in this scenario, we
|
|
5836
|
-
* throw on all outstanding promises and forbid new calls.
|
|
5412
|
+
* If null, we'll use navigator locks instead.
|
|
5837
5413
|
*/
|
|
5838
|
-
|
|
5839
|
-
|
|
5840
|
-
|
|
5841
|
-
|
|
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();
|
|
5842
5425
|
}
|
|
5843
|
-
|
|
5844
|
-
return this.
|
|
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
|
-
|
|
5851
|
-
|
|
5852
|
-
|
|
5853
|
-
|
|
5854
|
-
|
|
5855
|
-
|
|
5856
|
-
|
|
5857
|
-
|
|
5858
|
-
|
|
5859
|
-
|
|
5860
|
-
|
|
5861
|
-
|
|
5862
|
-
|
|
5863
|
-
|
|
5864
|
-
|
|
5865
|
-
|
|
5866
|
-
|
|
5867
|
-
|
|
5868
|
-
controller.signal.removeEventListener('abort', handleAbort);
|
|
5869
|
-
action();
|
|
5870
|
-
}
|
|
5871
|
-
controller.signal.addEventListener('abort', handleAbort);
|
|
5872
|
-
workerPromise()
|
|
5873
|
-
.then((data) => completePromise(() => resolve(data)))
|
|
5874
|
-
.catch((e) => completePromise(() => reject(e)));
|
|
5875
|
-
});
|
|
5446
|
+
// Unsafe, unguarded access to the SQLite connection.
|
|
5447
|
+
unsafeUseInner() {
|
|
5448
|
+
return this.inner;
|
|
5449
|
+
}
|
|
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
|
+
}
|
|
5876
5465
|
}
|
|
5877
|
-
|
|
5878
|
-
|
|
5879
|
-
|
|
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();
|
|
5880
5479
|
}
|
|
5881
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
|
+
}
|
|
5882
5495
|
/**
|
|
5883
|
-
*
|
|
5496
|
+
* Returns this lease, allowing another client to use the database connection.
|
|
5884
5497
|
*/
|
|
5885
|
-
async
|
|
5886
|
-
|
|
5887
|
-
|
|
5888
|
-
|
|
5889
|
-
|
|
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.
|
|
5890
5614
|
* This promise resolves once a lock is obtained.
|
|
5891
5615
|
* This lock will be held as long as this connection is open.
|
|
5892
5616
|
* The `shareConnection` method should not be called on multiple tabs concurrently.
|
|
5893
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
|
+
}
|
|
5894
5623
|
await new Promise((resolve, reject) => navigator.locks
|
|
5895
|
-
.request(`shared-connection-${this.
|
|
5896
|
-
signal:
|
|
5624
|
+
.request(`shared-connection-${this.name}-${Date.now()}-${Math.round(Math.random() * 10000)}`, {
|
|
5625
|
+
signal: abort.signal
|
|
5897
5626
|
}, async () => {
|
|
5898
5627
|
resolve();
|
|
5899
5628
|
// Free the lock when the connection is already closed.
|
|
5900
|
-
if (
|
|
5629
|
+
if (abort.signal.aborted) {
|
|
5901
5630
|
return;
|
|
5902
5631
|
}
|
|
5903
5632
|
// Hold the lock while the shared connection is in use.
|
|
5904
5633
|
await new Promise((releaseLock) => {
|
|
5905
|
-
|
|
5634
|
+
abort.signal.addEventListener('abort', () => {
|
|
5906
5635
|
releaseLock();
|
|
5907
5636
|
});
|
|
5908
5637
|
});
|
|
@@ -5916,280 +5645,335 @@ class WorkerWrappedAsyncDatabaseConnection extends _powersync_common__WEBPACK_IM
|
|
|
5916
5645
|
reject(ex);
|
|
5917
5646
|
}
|
|
5918
5647
|
}));
|
|
5919
|
-
const newPort = await
|
|
5920
|
-
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;
|
|
5921
5667
|
}
|
|
5922
5668
|
/**
|
|
5923
|
-
*
|
|
5924
|
-
* 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.
|
|
5925
5670
|
*/
|
|
5926
|
-
async
|
|
5927
|
-
|
|
5928
|
-
|
|
5929
|
-
|
|
5930
|
-
|
|
5931
|
-
|
|
5932
|
-
|
|
5933
|
-
|
|
5934
|
-
|
|
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
|
+
}
|
|
5935
5684
|
}
|
|
5936
|
-
|
|
5937
|
-
this
|
|
5938
|
-
|
|
5939
|
-
|
|
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
|
+
};
|
|
5940
5705
|
}
|
|
5706
|
+
return {
|
|
5707
|
+
rowsAffected: rs.changes,
|
|
5708
|
+
insertId: rs.lastInsertRowId,
|
|
5709
|
+
rows
|
|
5710
|
+
};
|
|
5941
5711
|
}
|
|
5942
|
-
|
|
5943
|
-
|
|
5712
|
+
async executeRaw(query, params) {
|
|
5713
|
+
const rs = await this.#executeOnWorker(query, params);
|
|
5714
|
+
return rs.resultSet?.rows ?? [];
|
|
5944
5715
|
}
|
|
5945
|
-
|
|
5946
|
-
return this.
|
|
5716
|
+
async #executeOnWorker(query, params) {
|
|
5717
|
+
return this.maybeTrace((c) => c.execute(this.#token, query, params), () => query);
|
|
5947
5718
|
}
|
|
5948
|
-
executeBatch(
|
|
5949
|
-
|
|
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
|
+
});
|
|
5950
5755
|
}
|
|
5951
|
-
|
|
5952
|
-
return
|
|
5756
|
+
else {
|
|
5757
|
+
// Can't close, so just return the inner worker promise unguarded.
|
|
5758
|
+
return workerPromise(state.connection);
|
|
5953
5759
|
}
|
|
5954
5760
|
}
|
|
5955
5761
|
|
|
5956
5762
|
|
|
5957
5763
|
/***/ },
|
|
5958
5764
|
|
|
5959
|
-
/***/ "./lib/src/db/adapters/wa-sqlite/
|
|
5960
|
-
|
|
5961
|
-
!*** ./lib/src/db/adapters/wa-sqlite/
|
|
5962
|
-
|
|
5765
|
+
/***/ "./lib/src/db/adapters/wa-sqlite/DatabaseServer.js"
|
|
5766
|
+
/*!*********************************************************!*\
|
|
5767
|
+
!*** ./lib/src/db/adapters/wa-sqlite/DatabaseServer.js ***!
|
|
5768
|
+
\*********************************************************/
|
|
5963
5769
|
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
|
|
5964
5770
|
|
|
5965
5771
|
__webpack_require__.r(__webpack_exports__);
|
|
5966
5772
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
5967
|
-
/* harmony export */
|
|
5773
|
+
/* harmony export */ DatabaseServer: () => (/* binding */ DatabaseServer)
|
|
5968
5774
|
/* harmony export */ });
|
|
5969
|
-
/* harmony import */ var _LockedAsyncDatabaseAdapter_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../LockedAsyncDatabaseAdapter.js */ "./lib/src/db/adapters/LockedAsyncDatabaseAdapter.js");
|
|
5970
|
-
/* harmony import */ var _WASQLiteConnection_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./WASQLiteConnection.js */ "./lib/src/db/adapters/wa-sqlite/WASQLiteConnection.js");
|
|
5971
|
-
|
|
5972
|
-
|
|
5973
5775
|
/**
|
|
5974
|
-
*
|
|
5975
|
-
*
|
|
5976
|
-
* constructor arguments as {@link LockedAsyncDatabaseAdapter}, but provides some
|
|
5977
|
-
* basic WA-SQLite specific functionality.
|
|
5978
|
-
* 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.
|
|
5979
5778
|
*/
|
|
5980
|
-
class
|
|
5981
|
-
|
|
5982
|
-
|
|
5983
|
-
|
|
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
|
+
}
|
|
5984
5855
|
return {
|
|
5985
|
-
|
|
5986
|
-
|
|
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
|
+
}
|
|
5987
5911
|
};
|
|
5988
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
|
+
}
|
|
5989
5920
|
}
|
|
5990
5921
|
|
|
5991
5922
|
|
|
5992
5923
|
/***/ },
|
|
5993
5924
|
|
|
5994
|
-
/***/ "./lib/src/db/adapters/wa-sqlite/
|
|
5995
|
-
|
|
5996
|
-
!*** ./lib/src/db/adapters/wa-sqlite/
|
|
5997
|
-
|
|
5925
|
+
/***/ "./lib/src/db/adapters/wa-sqlite/RawSqliteConnection.js"
|
|
5926
|
+
/*!**************************************************************!*\
|
|
5927
|
+
!*** ./lib/src/db/adapters/wa-sqlite/RawSqliteConnection.js ***!
|
|
5928
|
+
\**************************************************************/
|
|
5998
5929
|
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
|
|
5999
5930
|
|
|
6000
5931
|
__webpack_require__.r(__webpack_exports__);
|
|
6001
5932
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
6002
|
-
/* harmony export */
|
|
6003
|
-
/* harmony export */ DEFAULT_MODULE_FACTORIES: () => (/* binding */ DEFAULT_MODULE_FACTORIES),
|
|
6004
|
-
/* harmony export */ MultiCipherAsyncWASQLiteModuleFactory: () => (/* binding */ MultiCipherAsyncWASQLiteModuleFactory),
|
|
6005
|
-
/* harmony export */ MultiCipherSyncWASQLiteModuleFactory: () => (/* binding */ MultiCipherSyncWASQLiteModuleFactory),
|
|
6006
|
-
/* harmony export */ SyncWASQLiteModuleFactory: () => (/* binding */ SyncWASQLiteModuleFactory),
|
|
6007
|
-
/* harmony export */ WASQLiteVFS: () => (/* binding */ WASQLiteVFS),
|
|
6008
|
-
/* harmony export */ WASqliteConnection: () => (/* binding */ WASqliteConnection)
|
|
5933
|
+
/* harmony export */ RawSqliteConnection: () => (/* binding */ RawSqliteConnection)
|
|
6009
5934
|
/* harmony export */ });
|
|
6010
5935
|
/* harmony import */ var _journeyapps_wa_sqlite__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @journeyapps/wa-sqlite */ "@journeyapps/wa-sqlite");
|
|
6011
|
-
/* harmony import */ var
|
|
6012
|
-
/* harmony import */ var async_mutex__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! async-mutex */ "async-mutex");
|
|
6013
|
-
|
|
5936
|
+
/* harmony import */ var _vfs_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./vfs.js */ "./lib/src/db/adapters/wa-sqlite/vfs.js");
|
|
6014
5937
|
|
|
6015
5938
|
|
|
6016
5939
|
/**
|
|
6017
|
-
*
|
|
6018
|
-
|
|
6019
|
-
|
|
6020
|
-
|
|
6021
|
-
WASQLiteVFS["IDBBatchAtomicVFS"] = "IDBBatchAtomicVFS";
|
|
6022
|
-
WASQLiteVFS["OPFSCoopSyncVFS"] = "OPFSCoopSyncVFS";
|
|
6023
|
-
WASQLiteVFS["AccessHandlePoolVFS"] = "AccessHandlePoolVFS";
|
|
6024
|
-
})(WASQLiteVFS || (WASQLiteVFS = {}));
|
|
6025
|
-
/**
|
|
6026
|
-
* @internal
|
|
6027
|
-
*/
|
|
6028
|
-
const AsyncWASQLiteModuleFactory = async () => {
|
|
6029
|
-
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"));
|
|
6030
|
-
return factory();
|
|
6031
|
-
};
|
|
6032
|
-
/**
|
|
6033
|
-
* @internal
|
|
6034
|
-
*/
|
|
6035
|
-
const MultiCipherAsyncWASQLiteModuleFactory = async () => {
|
|
6036
|
-
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"));
|
|
6037
|
-
return factory();
|
|
6038
|
-
};
|
|
6039
|
-
/**
|
|
6040
|
-
* @internal
|
|
6041
|
-
*/
|
|
6042
|
-
const SyncWASQLiteModuleFactory = async () => {
|
|
6043
|
-
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"));
|
|
6044
|
-
return factory();
|
|
6045
|
-
};
|
|
6046
|
-
/**
|
|
6047
|
-
* @internal
|
|
6048
|
-
*/
|
|
6049
|
-
const MultiCipherSyncWASQLiteModuleFactory = async () => {
|
|
6050
|
-
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"));
|
|
6051
|
-
return factory();
|
|
6052
|
-
};
|
|
6053
|
-
/**
|
|
6054
|
-
* @internal
|
|
6055
|
-
*/
|
|
6056
|
-
const DEFAULT_MODULE_FACTORIES = {
|
|
6057
|
-
[WASQLiteVFS.IDBBatchAtomicVFS]: async (options) => {
|
|
6058
|
-
let module;
|
|
6059
|
-
if (options.encryptionKey) {
|
|
6060
|
-
module = await MultiCipherAsyncWASQLiteModuleFactory();
|
|
6061
|
-
}
|
|
6062
|
-
else {
|
|
6063
|
-
module = await AsyncWASQLiteModuleFactory();
|
|
6064
|
-
}
|
|
6065
|
-
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));
|
|
6066
|
-
return {
|
|
6067
|
-
module,
|
|
6068
|
-
// @ts-expect-error The types for this static method are missing upstream
|
|
6069
|
-
vfs: await IDBBatchAtomicVFS.create(options.dbFileName, module, { lockPolicy: 'exclusive' })
|
|
6070
|
-
};
|
|
6071
|
-
},
|
|
6072
|
-
[WASQLiteVFS.AccessHandlePoolVFS]: async (options) => {
|
|
6073
|
-
let module;
|
|
6074
|
-
if (options.encryptionKey) {
|
|
6075
|
-
module = await MultiCipherSyncWASQLiteModuleFactory();
|
|
6076
|
-
}
|
|
6077
|
-
else {
|
|
6078
|
-
module = await SyncWASQLiteModuleFactory();
|
|
6079
|
-
}
|
|
6080
|
-
// @ts-expect-error The types for this static method are missing upstream
|
|
6081
|
-
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));
|
|
6082
|
-
return {
|
|
6083
|
-
module,
|
|
6084
|
-
vfs: await AccessHandlePoolVFS.create(options.dbFileName, module)
|
|
6085
|
-
};
|
|
6086
|
-
},
|
|
6087
|
-
[WASQLiteVFS.OPFSCoopSyncVFS]: async (options) => {
|
|
6088
|
-
let module;
|
|
6089
|
-
if (options.encryptionKey) {
|
|
6090
|
-
module = await MultiCipherSyncWASQLiteModuleFactory();
|
|
6091
|
-
}
|
|
6092
|
-
else {
|
|
6093
|
-
module = await SyncWASQLiteModuleFactory();
|
|
6094
|
-
}
|
|
6095
|
-
// @ts-expect-error The types for this static method are missing upstream
|
|
6096
|
-
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));
|
|
6097
|
-
const vfs = await OPFSCoopSyncVFS.create(options.dbFileName, module);
|
|
6098
|
-
return {
|
|
6099
|
-
module,
|
|
6100
|
-
vfs
|
|
6101
|
-
};
|
|
6102
|
-
}
|
|
6103
|
-
};
|
|
6104
|
-
/**
|
|
6105
|
-
* @internal
|
|
6106
|
-
* WA-SQLite connection which directly interfaces with WA-SQLite.
|
|
6107
|
-
* 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.
|
|
6108
5944
|
*/
|
|
6109
|
-
class
|
|
5945
|
+
class RawSqliteConnection {
|
|
6110
5946
|
options;
|
|
6111
5947
|
_sqliteAPI = null;
|
|
6112
|
-
_dbP = null;
|
|
6113
|
-
_moduleFactory;
|
|
6114
|
-
updatedTables;
|
|
6115
|
-
updateTimer;
|
|
6116
|
-
statementMutex;
|
|
6117
|
-
broadcastChannel;
|
|
6118
5948
|
/**
|
|
6119
|
-
*
|
|
6120
|
-
* notification loops.
|
|
5949
|
+
* The `sqlite3*` connection pointer.
|
|
6121
5950
|
*/
|
|
6122
|
-
|
|
6123
|
-
|
|
6124
|
-
_holdId;
|
|
5951
|
+
db = 0;
|
|
5952
|
+
_moduleFactory;
|
|
6125
5953
|
constructor(options) {
|
|
6126
|
-
super();
|
|
6127
5954
|
this.options = options;
|
|
6128
|
-
this.
|
|
6129
|
-
this.updateTimer = null;
|
|
6130
|
-
this.broadcastChannel = null;
|
|
6131
|
-
this.connectionId = new Date().valueOf() + Math.random();
|
|
6132
|
-
this.statementMutex = new async_mutex__WEBPACK_IMPORTED_MODULE_2__.Mutex();
|
|
6133
|
-
this._moduleFactory = DEFAULT_MODULE_FACTORIES[this.options.vfs];
|
|
6134
|
-
this._holdCounter = 0;
|
|
6135
|
-
this._holdId = null;
|
|
5955
|
+
this._moduleFactory = _vfs_js__WEBPACK_IMPORTED_MODULE_1__.DEFAULT_MODULE_FACTORIES[this.options.vfs];
|
|
6136
5956
|
}
|
|
6137
|
-
|
|
6138
|
-
|
|
6139
|
-
* This can be used to check for invalid states.
|
|
6140
|
-
*/
|
|
6141
|
-
get currentHoldId() {
|
|
6142
|
-
return this._holdId;
|
|
6143
|
-
}
|
|
6144
|
-
get sqliteAPI() {
|
|
6145
|
-
if (!this._sqliteAPI) {
|
|
6146
|
-
throw new Error(`Initialization has not completed`);
|
|
6147
|
-
}
|
|
6148
|
-
return this._sqliteAPI;
|
|
5957
|
+
get isOpen() {
|
|
5958
|
+
return this.db != 0;
|
|
6149
5959
|
}
|
|
6150
|
-
|
|
6151
|
-
|
|
6152
|
-
|
|
6153
|
-
}
|
|
6154
|
-
return this._dbP;
|
|
6155
|
-
}
|
|
6156
|
-
/**
|
|
6157
|
-
* Checks if the database connection is in autocommit mode.
|
|
6158
|
-
* @returns true if in autocommit mode, false if in a transaction
|
|
6159
|
-
*/
|
|
6160
|
-
async isAutoCommit() {
|
|
6161
|
-
return this.sqliteAPI.get_autocommit(this.dbP) != 0;
|
|
6162
|
-
}
|
|
6163
|
-
async markHold() {
|
|
6164
|
-
const previousHoldId = this._holdId;
|
|
6165
|
-
this._holdId = `${++this._holdCounter}`;
|
|
6166
|
-
if (previousHoldId) {
|
|
6167
|
-
await this.iterateAsyncListeners(async (cb) => cb.holdOverwritten?.(previousHoldId));
|
|
6168
|
-
}
|
|
6169
|
-
return this._holdId;
|
|
6170
|
-
}
|
|
6171
|
-
async releaseHold(holdId) {
|
|
6172
|
-
if (holdId != this._holdId) {
|
|
6173
|
-
throw new Error(`Invalid hold state, expected ${this._holdId} but got ${holdId}`);
|
|
6174
|
-
}
|
|
6175
|
-
this._holdId = null;
|
|
6176
|
-
}
|
|
6177
|
-
async openDB() {
|
|
6178
|
-
this._dbP = await this.sqliteAPI.open_v2(this.options.dbFilename);
|
|
6179
|
-
return this._dbP;
|
|
6180
|
-
}
|
|
6181
|
-
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};`);
|
|
6182
5964
|
if (this.options.encryptionKey) {
|
|
6183
|
-
|
|
5965
|
+
const escapedKey = this.options.encryptionKey.replace("'", "''");
|
|
5966
|
+
await this.executeRaw(`PRAGMA key = '${escapedKey}'`);
|
|
6184
5967
|
}
|
|
6185
|
-
|
|
5968
|
+
await this.executeRaw(`PRAGMA cache_size = -${this.options.cacheSizeKb};`);
|
|
5969
|
+
await this.executeRaw(`SELECT powersync_update_hooks('install');`);
|
|
6186
5970
|
}
|
|
6187
5971
|
async openSQLiteAPI() {
|
|
6188
5972
|
const { module, vfs } = await this._moduleFactory({
|
|
6189
5973
|
dbFileName: this.options.dbFilename,
|
|
6190
5974
|
encryptionKey: this.options.encryptionKey
|
|
6191
5975
|
});
|
|
6192
|
-
const sqlite3 = _journeyapps_wa_sqlite__WEBPACK_IMPORTED_MODULE_0__.Factory(module);
|
|
5976
|
+
const sqlite3 = (0,_journeyapps_wa_sqlite__WEBPACK_IMPORTED_MODULE_0__.Factory)(module);
|
|
6193
5977
|
sqlite3.vfs_register(vfs, true);
|
|
6194
5978
|
/**
|
|
6195
5979
|
* Register the PowerSync core SQLite extension
|
|
@@ -6206,278 +5990,95 @@ class WASqliteConnection extends _powersync_common__WEBPACK_IMPORTED_MODULE_1__.
|
|
|
6206
5990
|
}
|
|
6207
5991
|
return sqlite3;
|
|
6208
5992
|
}
|
|
6209
|
-
|
|
6210
|
-
|
|
6211
|
-
|
|
6212
|
-
const data = event.data;
|
|
6213
|
-
if (this.connectionId == data.connectionId) {
|
|
6214
|
-
// Ignore messages from the same connection
|
|
6215
|
-
return;
|
|
6216
|
-
}
|
|
6217
|
-
// Ensuring that we don't rebroadcast the same message
|
|
6218
|
-
this.queueTableUpdate(data.changedTables, false);
|
|
6219
|
-
});
|
|
6220
|
-
}
|
|
6221
|
-
queueTableUpdate(tableNames, shouldBroadcast = true) {
|
|
6222
|
-
tableNames.forEach((tableName) => this.updatedTables.add(tableName));
|
|
6223
|
-
if (this.updateTimer == null) {
|
|
6224
|
-
this.updateTimer = setTimeout(() => this.fireUpdates(shouldBroadcast), 0);
|
|
6225
|
-
}
|
|
6226
|
-
}
|
|
6227
|
-
async init() {
|
|
6228
|
-
this._sqliteAPI = await this.openSQLiteAPI();
|
|
6229
|
-
await this.openDB();
|
|
6230
|
-
this.registerBroadcastListeners();
|
|
6231
|
-
await this.executeSingleStatement(`PRAGMA temp_store = ${this.options.temporaryStorage};`);
|
|
6232
|
-
await this.executeEncryptionPragma();
|
|
6233
|
-
await this.executeSingleStatement(`PRAGMA cache_size = -${this.options.cacheSizeKb};`);
|
|
6234
|
-
this.sqliteAPI.update_hook(this.dbP, (updateType, dbName, tableName) => {
|
|
6235
|
-
if (!tableName) {
|
|
6236
|
-
return;
|
|
6237
|
-
}
|
|
6238
|
-
const changedTables = new Set([tableName]);
|
|
6239
|
-
this.queueTableUpdate(changedTables);
|
|
6240
|
-
});
|
|
6241
|
-
}
|
|
6242
|
-
async getConfig() {
|
|
6243
|
-
return this.options;
|
|
6244
|
-
}
|
|
6245
|
-
fireUpdates(shouldBroadcast = true) {
|
|
6246
|
-
this.updateTimer = null;
|
|
6247
|
-
const event = { tables: [...this.updatedTables], groupedUpdates: {}, rawUpdates: [] };
|
|
6248
|
-
// Share to other connections
|
|
6249
|
-
if (shouldBroadcast) {
|
|
6250
|
-
this.broadcastChannel.postMessage({
|
|
6251
|
-
changedTables: this.updatedTables,
|
|
6252
|
-
connectionId: this.connectionId
|
|
6253
|
-
});
|
|
5993
|
+
requireSqlite() {
|
|
5994
|
+
if (!this._sqliteAPI) {
|
|
5995
|
+
throw new Error(`Initialization has not completed`);
|
|
6254
5996
|
}
|
|
6255
|
-
this.
|
|
6256
|
-
this.iterateListeners((cb) => cb.tablesUpdated?.(event));
|
|
5997
|
+
return this._sqliteAPI;
|
|
6257
5998
|
}
|
|
6258
5999
|
/**
|
|
6259
|
-
*
|
|
6000
|
+
* Checks if the database connection is in autocommit mode.
|
|
6001
|
+
* @returns true if in autocommit mode, false if in a transaction
|
|
6260
6002
|
*/
|
|
6261
|
-
|
|
6262
|
-
return this.
|
|
6263
|
-
let affectedRows = 0;
|
|
6264
|
-
try {
|
|
6265
|
-
await this.executeSingleStatement('BEGIN TRANSACTION');
|
|
6266
|
-
const wrappedBindings = bindings ? bindings : [];
|
|
6267
|
-
for await (const stmt of this.sqliteAPI.statements(this.dbP, sql)) {
|
|
6268
|
-
if (stmt === null) {
|
|
6269
|
-
return {
|
|
6270
|
-
rowsAffected: 0,
|
|
6271
|
-
rows: { _array: [], length: 0 }
|
|
6272
|
-
};
|
|
6273
|
-
}
|
|
6274
|
-
//Prepare statement once
|
|
6275
|
-
for (const binding of wrappedBindings) {
|
|
6276
|
-
// TODO not sure why this is needed currently, but booleans break
|
|
6277
|
-
for (let i = 0; i < binding.length; i++) {
|
|
6278
|
-
const b = binding[i];
|
|
6279
|
-
if (typeof b == 'boolean') {
|
|
6280
|
-
binding[i] = b ? 1 : 0;
|
|
6281
|
-
}
|
|
6282
|
-
}
|
|
6283
|
-
if (bindings) {
|
|
6284
|
-
this.sqliteAPI.bind_collection(stmt, binding);
|
|
6285
|
-
}
|
|
6286
|
-
const result = await this.sqliteAPI.step(stmt);
|
|
6287
|
-
if (result === _journeyapps_wa_sqlite__WEBPACK_IMPORTED_MODULE_0__.SQLITE_DONE) {
|
|
6288
|
-
//The value returned by sqlite3_changes() immediately after an INSERT, UPDATE or DELETE statement run on a view is always zero.
|
|
6289
|
-
affectedRows += this.sqliteAPI.changes(this.dbP);
|
|
6290
|
-
}
|
|
6291
|
-
this.sqliteAPI.reset(stmt);
|
|
6292
|
-
}
|
|
6293
|
-
}
|
|
6294
|
-
await this.executeSingleStatement('COMMIT');
|
|
6295
|
-
}
|
|
6296
|
-
catch (err) {
|
|
6297
|
-
await this.executeSingleStatement('ROLLBACK');
|
|
6298
|
-
return {
|
|
6299
|
-
rowsAffected: 0,
|
|
6300
|
-
rows: { _array: [], length: 0 }
|
|
6301
|
-
};
|
|
6302
|
-
}
|
|
6303
|
-
const result = {
|
|
6304
|
-
rowsAffected: affectedRows,
|
|
6305
|
-
rows: { _array: [], length: 0 }
|
|
6306
|
-
};
|
|
6307
|
-
return result;
|
|
6308
|
-
});
|
|
6003
|
+
isAutoCommit() {
|
|
6004
|
+
return this.requireSqlite().get_autocommit(this.db) != 0;
|
|
6309
6005
|
}
|
|
6310
|
-
/**
|
|
6311
|
-
* This executes single SQL statements inside a requested lock.
|
|
6312
|
-
*/
|
|
6313
6006
|
async execute(sql, bindings) {
|
|
6314
|
-
|
|
6315
|
-
return this.
|
|
6316
|
-
return this.executeSingleStatement(sql, bindings);
|
|
6317
|
-
});
|
|
6318
|
-
}
|
|
6319
|
-
async executeRaw(sql, bindings) {
|
|
6320
|
-
return this.acquireExecuteLock(async () => {
|
|
6321
|
-
return this.executeSingleStatementRaw(sql, bindings);
|
|
6322
|
-
});
|
|
6323
|
-
}
|
|
6324
|
-
async close() {
|
|
6325
|
-
this.broadcastChannel?.close();
|
|
6326
|
-
await this.acquireExecuteLock(async () => {
|
|
6327
|
-
/**
|
|
6328
|
-
* Running the close operation inside the same execute mutex prevents errors like:
|
|
6329
|
-
* ```
|
|
6330
|
-
* unable to close due to unfinalized statements or unfinished backups
|
|
6331
|
-
* ```
|
|
6332
|
-
*/
|
|
6333
|
-
await this.sqliteAPI.close(this.dbP);
|
|
6334
|
-
});
|
|
6335
|
-
}
|
|
6336
|
-
async registerOnTableChange(callback) {
|
|
6337
|
-
return this.registerListener({
|
|
6338
|
-
tablesUpdated: (event) => callback(event)
|
|
6339
|
-
});
|
|
6007
|
+
const resultSet = await this.executeSingleStatementRaw(sql, bindings);
|
|
6008
|
+
return this.wrapQueryResults(this.requireSqlite(), resultSet);
|
|
6340
6009
|
}
|
|
6341
|
-
|
|
6342
|
-
|
|
6343
|
-
|
|
6344
|
-
|
|
6345
|
-
|
|
6346
|
-
|
|
6347
|
-
|
|
6348
|
-
|
|
6349
|
-
* This executes a single statement using SQLite3.
|
|
6350
|
-
*/
|
|
6351
|
-
async executeSingleStatement(sql, bindings) {
|
|
6352
|
-
const results = await this._execute(sql, bindings);
|
|
6353
|
-
const rows = [];
|
|
6354
|
-
for (const resultSet of results) {
|
|
6355
|
-
for (const row of resultSet.rows) {
|
|
6356
|
-
const outRow = {};
|
|
6357
|
-
resultSet.columns.forEach((key, index) => {
|
|
6358
|
-
outRow[key] = row[index];
|
|
6359
|
-
});
|
|
6360
|
-
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));
|
|
6361
6018
|
}
|
|
6019
|
+
// executeBatch can only use a single statement
|
|
6020
|
+
break;
|
|
6362
6021
|
}
|
|
6363
|
-
|
|
6364
|
-
|
|
6365
|
-
|
|
6366
|
-
|
|
6367
|
-
|
|
6368
|
-
|
|
6369
|
-
|
|
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
|
|
6370
6030
|
};
|
|
6371
|
-
return result;
|
|
6372
6031
|
}
|
|
6373
6032
|
/**
|
|
6374
|
-
* 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}.
|
|
6375
6034
|
*/
|
|
6376
6035
|
async executeSingleStatementRaw(sql, bindings) {
|
|
6377
|
-
const results = await this.
|
|
6378
|
-
return results.
|
|
6036
|
+
const results = await this.executeRaw(sql, bindings);
|
|
6037
|
+
return results.length ? results[0] : undefined;
|
|
6379
6038
|
}
|
|
6380
|
-
async
|
|
6039
|
+
async executeRaw(sql, bindings) {
|
|
6381
6040
|
const results = [];
|
|
6382
|
-
|
|
6041
|
+
const api = this.requireSqlite();
|
|
6042
|
+
for await (const stmt of api.statements(this.db, sql)) {
|
|
6383
6043
|
let columns;
|
|
6384
|
-
const
|
|
6385
|
-
|
|
6386
|
-
|
|
6387
|
-
|
|
6388
|
-
if (typeof b == 'boolean') {
|
|
6389
|
-
arr[index] = b ? 1 : 0;
|
|
6390
|
-
}
|
|
6391
|
-
});
|
|
6392
|
-
this.sqliteAPI.reset(stmt);
|
|
6393
|
-
if (bindings) {
|
|
6394
|
-
this.sqliteAPI.bind_collection(stmt, binding);
|
|
6395
|
-
}
|
|
6396
|
-
const rows = [];
|
|
6397
|
-
while ((await this.sqliteAPI.step(stmt)) === _journeyapps_wa_sqlite__WEBPACK_IMPORTED_MODULE_0__.SQLITE_ROW) {
|
|
6398
|
-
const row = this.sqliteAPI.row(stmt);
|
|
6399
|
-
rows.push(row);
|
|
6400
|
-
}
|
|
6401
|
-
columns = columns ?? this.sqliteAPI.column_names(stmt);
|
|
6402
|
-
if (columns.length) {
|
|
6403
|
-
results.push({ columns, rows });
|
|
6404
|
-
}
|
|
6044
|
+
const rs = await this.stepThroughStatement(api, stmt, bindings ?? [], columns);
|
|
6045
|
+
columns = rs.columns;
|
|
6046
|
+
if (columns.length) {
|
|
6047
|
+
results.push(rs);
|
|
6405
6048
|
}
|
|
6406
6049
|
// When binding parameters, only a single statement is executed.
|
|
6407
6050
|
if (bindings) {
|
|
6408
6051
|
break;
|
|
6409
|
-
}
|
|
6410
|
-
}
|
|
6411
|
-
return results;
|
|
6412
|
-
}
|
|
6413
|
-
|
|
6414
|
-
|
|
6415
|
-
|
|
6416
|
-
|
|
6417
|
-
|
|
6418
|
-
|
|
6419
|
-
/*!************************************************************!*\
|
|
6420
|
-
!*** ./lib/src/db/adapters/wa-sqlite/WASQLiteDBAdapter.js ***!
|
|
6421
|
-
\************************************************************/
|
|
6422
|
-
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
|
|
6423
|
-
|
|
6424
|
-
__webpack_require__.r(__webpack_exports__);
|
|
6425
|
-
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
6426
|
-
/* harmony export */ WASQLiteDBAdapter: () => (/* binding */ WASQLiteDBAdapter)
|
|
6427
|
-
/* harmony export */ });
|
|
6428
|
-
/* harmony import */ var comlink__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! comlink */ "comlink");
|
|
6429
|
-
/* harmony import */ var _PowerSyncDatabase_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../PowerSyncDatabase.js */ "./lib/src/db/PowerSyncDatabase.js");
|
|
6430
|
-
/* 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");
|
|
6431
|
-
/* harmony import */ var _WorkerWrappedAsyncDatabaseConnection_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../WorkerWrappedAsyncDatabaseConnection.js */ "./lib/src/db/adapters/WorkerWrappedAsyncDatabaseConnection.js");
|
|
6432
|
-
/* harmony import */ var _InternalWASQLiteDBAdapter_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./InternalWASQLiteDBAdapter.js */ "./lib/src/db/adapters/wa-sqlite/InternalWASQLiteDBAdapter.js");
|
|
6433
|
-
/* harmony import */ var _WASQLiteOpenFactory_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./WASQLiteOpenFactory.js */ "./lib/src/db/adapters/wa-sqlite/WASQLiteOpenFactory.js");
|
|
6434
|
-
|
|
6435
|
-
|
|
6436
|
-
|
|
6437
|
-
|
|
6438
|
-
|
|
6439
|
-
|
|
6440
|
-
/**
|
|
6441
|
-
* Adapter for WA-SQLite SQLite connections.
|
|
6442
|
-
*/
|
|
6443
|
-
class WASQLiteDBAdapter extends _InternalWASQLiteDBAdapter_js__WEBPACK_IMPORTED_MODULE_4__.InternalWASQLiteDBAdapter {
|
|
6444
|
-
constructor(options) {
|
|
6445
|
-
super({
|
|
6446
|
-
name: options.dbFilename,
|
|
6447
|
-
openConnection: async () => {
|
|
6448
|
-
const { workerPort, temporaryStorage, cacheSizeKb } = options;
|
|
6449
|
-
if (workerPort) {
|
|
6450
|
-
const remote = comlink__WEBPACK_IMPORTED_MODULE_0__.wrap(workerPort);
|
|
6451
|
-
return new _WorkerWrappedAsyncDatabaseConnection_js__WEBPACK_IMPORTED_MODULE_3__.WorkerWrappedAsyncDatabaseConnection({
|
|
6452
|
-
remote,
|
|
6453
|
-
remoteCanCloseUnexpectedly: false,
|
|
6454
|
-
identifier: options.dbFilename,
|
|
6455
|
-
baseConnection: await remote({
|
|
6456
|
-
...options,
|
|
6457
|
-
temporaryStorage: temporaryStorage ?? _web_sql_flags_js__WEBPACK_IMPORTED_MODULE_2__.TemporaryStorageOption.MEMORY,
|
|
6458
|
-
cacheSizeKb: cacheSizeKb ?? _web_sql_flags_js__WEBPACK_IMPORTED_MODULE_2__.DEFAULT_CACHE_SIZE_KB,
|
|
6459
|
-
flags: (0,_PowerSyncDatabase_js__WEBPACK_IMPORTED_MODULE_1__.resolveWebPowerSyncFlags)(options.flags),
|
|
6460
|
-
encryptionKey: options.encryptionKey
|
|
6461
|
-
})
|
|
6462
|
-
});
|
|
6463
|
-
}
|
|
6464
|
-
const openFactory = new _WASQLiteOpenFactory_js__WEBPACK_IMPORTED_MODULE_5__.WASQLiteOpenFactory({
|
|
6465
|
-
dbFilename: options.dbFilename,
|
|
6466
|
-
dbLocation: options.dbLocation,
|
|
6467
|
-
debugMode: options.debugMode,
|
|
6468
|
-
flags: options.flags,
|
|
6469
|
-
temporaryStorage,
|
|
6470
|
-
cacheSizeKb,
|
|
6471
|
-
logger: options.logger,
|
|
6472
|
-
vfs: options.vfs,
|
|
6473
|
-
encryptionKey: options.encryptionKey,
|
|
6474
|
-
worker: options.worker
|
|
6475
|
-
});
|
|
6476
|
-
return openFactory.openConnection();
|
|
6477
|
-
},
|
|
6478
|
-
debugMode: options.debugMode,
|
|
6479
|
-
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
|
+
}
|
|
6480
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
|
+
}
|
|
6481
6082
|
}
|
|
6482
6083
|
}
|
|
6483
6084
|
|
|
@@ -6494,13 +6095,19 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
6494
6095
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
6495
6096
|
/* harmony export */ WASQLiteOpenFactory: () => (/* binding */ WASQLiteOpenFactory)
|
|
6496
6097
|
/* harmony export */ });
|
|
6497
|
-
/* harmony import */ var
|
|
6498
|
-
/* harmony import */ var
|
|
6499
|
-
/* harmony import */ var
|
|
6500
|
-
/* harmony import */ var
|
|
6501
|
-
/* harmony import */ var
|
|
6502
|
-
/* harmony import */ var
|
|
6503
|
-
/* 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
|
+
|
|
6504
6111
|
|
|
6505
6112
|
|
|
6506
6113
|
|
|
@@ -6511,56 +6118,82 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
6511
6118
|
/**
|
|
6512
6119
|
* Opens a SQLite connection using WA-SQLite.
|
|
6513
6120
|
*/
|
|
6514
|
-
class WASQLiteOpenFactory
|
|
6121
|
+
class WASQLiteOpenFactory {
|
|
6122
|
+
options;
|
|
6123
|
+
resolvedFlags;
|
|
6124
|
+
logger;
|
|
6515
6125
|
constructor(options) {
|
|
6516
|
-
|
|
6126
|
+
this.options = options;
|
|
6517
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}`);
|
|
6518
6130
|
}
|
|
6519
6131
|
get waOptions() {
|
|
6520
6132
|
// Cast to extended type
|
|
6521
6133
|
return this.options;
|
|
6522
6134
|
}
|
|
6523
6135
|
openAdapter() {
|
|
6524
|
-
return new
|
|
6525
|
-
|
|
6526
|
-
|
|
6527
|
-
|
|
6528
|
-
|
|
6529
|
-
|
|
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();
|
|
6530
6153
|
}
|
|
6531
6154
|
async openConnection() {
|
|
6532
6155
|
const { enableMultiTabs, useWebWorker } = this.resolvedFlags;
|
|
6533
|
-
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;
|
|
6534
6157
|
if (!enableMultiTabs) {
|
|
6535
6158
|
this.logger.warn('Multiple tabs are not enabled in this browser');
|
|
6536
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);
|
|
6537
6172
|
if (useWebWorker) {
|
|
6538
6173
|
const optionsDbWorker = this.options.worker;
|
|
6539
6174
|
const workerPort = typeof optionsDbWorker == 'function'
|
|
6540
|
-
? (0,
|
|
6175
|
+
? (0,_worker_db_open_worker_database_js__WEBPACK_IMPORTED_MODULE_2__.resolveWorkerDatabasePortFactory)(() => optionsDbWorker({
|
|
6541
6176
|
...this.options,
|
|
6542
6177
|
temporaryStorage,
|
|
6543
6178
|
cacheSizeKb,
|
|
6544
6179
|
flags: this.resolvedFlags,
|
|
6545
6180
|
encryptionKey
|
|
6546
6181
|
}))
|
|
6547
|
-
: (0,
|
|
6548
|
-
const
|
|
6549
|
-
|
|
6550
|
-
|
|
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,
|
|
6551
6193
|
// This tab owns the worker, so we're guaranteed to outlive it.
|
|
6552
6194
|
remoteCanCloseUnexpectedly: false,
|
|
6553
|
-
baseConnection: await workerDBOpener({
|
|
6554
|
-
dbFilename: this.options.dbFilename,
|
|
6555
|
-
vfs,
|
|
6556
|
-
temporaryStorage,
|
|
6557
|
-
cacheSizeKb,
|
|
6558
|
-
flags: this.resolvedFlags,
|
|
6559
|
-
encryptionKey: encryptionKey,
|
|
6560
|
-
logLevel: this.logger.getLevel()
|
|
6561
|
-
}),
|
|
6562
|
-
identifier: this.options.dbFilename,
|
|
6563
6195
|
onClose: () => {
|
|
6196
|
+
closeSignal.abort();
|
|
6564
6197
|
if (workerPort instanceof Worker) {
|
|
6565
6198
|
workerPort.terminate();
|
|
6566
6199
|
}
|
|
@@ -6568,21 +6201,19 @@ class WASQLiteOpenFactory extends _AbstractWebSQLOpenFactory_js__WEBPACK_IMPORTE
|
|
|
6568
6201
|
workerPort.close();
|
|
6569
6202
|
}
|
|
6570
6203
|
}
|
|
6571
|
-
}
|
|
6204
|
+
};
|
|
6572
6205
|
}
|
|
6573
6206
|
else {
|
|
6574
|
-
// Don't use a web worker
|
|
6575
|
-
|
|
6576
|
-
|
|
6577
|
-
|
|
6578
|
-
|
|
6579
|
-
|
|
6580
|
-
|
|
6581
|
-
|
|
6582
|
-
|
|
6583
|
-
|
|
6584
|
-
});
|
|
6585
|
-
}
|
|
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
|
+
});
|
|
6586
6217
|
}
|
|
6587
6218
|
}
|
|
6588
6219
|
/**
|
|
@@ -6592,7 +6223,7 @@ function assertValidWASQLiteOpenFactoryOptions(options) {
|
|
|
6592
6223
|
// The OPFS VFS only works in dedicated web workers.
|
|
6593
6224
|
if ('vfs' in options && 'flags' in options) {
|
|
6594
6225
|
const { vfs, flags = {} } = options;
|
|
6595
|
-
if (vfs
|
|
6226
|
+
if (vfs && (0,_vfs_js__WEBPACK_IMPORTED_MODULE_5__.vfsRequiresDedicatedWorkers)(vfs) && 'useWebWorker' in flags && !flags.useWebWorker) {
|
|
6596
6227
|
throw new Error(`Invalid configuration: The 'useWebWorker' flag must be true when using an OPFS-based VFS (${vfs}).`);
|
|
6597
6228
|
}
|
|
6598
6229
|
}
|
|
@@ -6637,6 +6268,117 @@ class WASQLitePowerSyncDatabaseOpenFactory extends _AbstractWebPowerSyncDatabase
|
|
|
6637
6268
|
}
|
|
6638
6269
|
|
|
6639
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
|
+
|
|
6640
6382
|
/***/ },
|
|
6641
6383
|
|
|
6642
6384
|
/***/ "./lib/src/db/adapters/web-sql-flags.js"
|
|
@@ -6704,8 +6446,6 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
6704
6446
|
/* harmony export */ SSRStreamingSyncImplementation: () => (/* binding */ SSRStreamingSyncImplementation)
|
|
6705
6447
|
/* harmony export */ });
|
|
6706
6448
|
/* harmony import */ var _powersync_common__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @powersync/common */ "@powersync/common");
|
|
6707
|
-
/* harmony import */ var async_mutex__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! async-mutex */ "async-mutex");
|
|
6708
|
-
|
|
6709
6449
|
|
|
6710
6450
|
class SSRStreamingSyncImplementation extends _powersync_common__WEBPACK_IMPORTED_MODULE_0__.BaseObserver {
|
|
6711
6451
|
syncMutex;
|
|
@@ -6715,14 +6455,14 @@ class SSRStreamingSyncImplementation extends _powersync_common__WEBPACK_IMPORTED
|
|
|
6715
6455
|
syncStatus;
|
|
6716
6456
|
constructor(options) {
|
|
6717
6457
|
super();
|
|
6718
|
-
this.syncMutex = new
|
|
6719
|
-
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();
|
|
6720
6460
|
this.syncStatus = new _powersync_common__WEBPACK_IMPORTED_MODULE_0__.SyncStatus({});
|
|
6721
6461
|
this.isConnected = false;
|
|
6722
6462
|
}
|
|
6723
6463
|
obtainLock(lockOptions) {
|
|
6724
6464
|
const mutex = lockOptions.type == _powersync_common__WEBPACK_IMPORTED_MODULE_0__.LockType.CRUD ? this.crudMutex : this.syncMutex;
|
|
6725
|
-
return mutex.runExclusive(lockOptions.callback);
|
|
6465
|
+
return mutex.runExclusive(lockOptions.callback, lockOptions.signal);
|
|
6726
6466
|
}
|
|
6727
6467
|
/**
|
|
6728
6468
|
* This is a no-op in SSR mode
|
|
@@ -6785,11 +6525,11 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
6785
6525
|
/* harmony export */ SharedWebStreamingSyncImplementation: () => (/* binding */ SharedWebStreamingSyncImplementation)
|
|
6786
6526
|
/* harmony export */ });
|
|
6787
6527
|
/* harmony import */ var comlink__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! comlink */ "comlink");
|
|
6788
|
-
/* harmony import */ var
|
|
6789
|
-
/* harmony import */ var
|
|
6790
|
-
/* harmony import */ var
|
|
6791
|
-
/* harmony import */ var
|
|
6792
|
-
/* 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");
|
|
6793
6533
|
|
|
6794
6534
|
|
|
6795
6535
|
|
|
@@ -6800,7 +6540,7 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
6800
6540
|
* The shared worker will trigger methods on this side of the message port
|
|
6801
6541
|
* via this client provider.
|
|
6802
6542
|
*/
|
|
6803
|
-
class SharedSyncClientProvider extends
|
|
6543
|
+
class SharedSyncClientProvider extends _worker_sync_AbstractSharedSyncClientProvider_js__WEBPACK_IMPORTED_MODULE_1__.AbstractSharedSyncClientProvider {
|
|
6804
6544
|
options;
|
|
6805
6545
|
statusChanged;
|
|
6806
6546
|
webDB;
|
|
@@ -6871,7 +6611,7 @@ class SharedSyncClientProvider extends _worker_sync_AbstractSharedSyncClientProv
|
|
|
6871
6611
|
/**
|
|
6872
6612
|
* The local part of the sync implementation on the web, which talks to a sync implementation hosted in a shared worker.
|
|
6873
6613
|
*/
|
|
6874
|
-
class SharedWebStreamingSyncImplementation extends
|
|
6614
|
+
class SharedWebStreamingSyncImplementation extends _WebStreamingSyncImplementation_js__WEBPACK_IMPORTED_MODULE_4__.WebStreamingSyncImplementation {
|
|
6875
6615
|
syncManager;
|
|
6876
6616
|
clientProvider;
|
|
6877
6617
|
messagePort;
|
|
@@ -6887,10 +6627,10 @@ class SharedWebStreamingSyncImplementation extends _WebStreamingSyncImplementati
|
|
|
6887
6627
|
*/
|
|
6888
6628
|
const resolvedWorkerOptions = {
|
|
6889
6629
|
dbFilename: this.options.identifier,
|
|
6890
|
-
temporaryStorage:
|
|
6891
|
-
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,
|
|
6892
6632
|
...options,
|
|
6893
|
-
flags: (0,
|
|
6633
|
+
flags: (0,_adapters_web_sql_flags_js__WEBPACK_IMPORTED_MODULE_3__.resolveWebSQLFlags)(options.flags)
|
|
6894
6634
|
};
|
|
6895
6635
|
const syncWorker = options.sync?.worker;
|
|
6896
6636
|
if (syncWorker) {
|
|
@@ -6905,7 +6645,7 @@ class SharedWebStreamingSyncImplementation extends _WebStreamingSyncImplementati
|
|
|
6905
6645
|
}
|
|
6906
6646
|
}
|
|
6907
6647
|
else {
|
|
6908
|
-
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), {
|
|
6909
6649
|
/* @vite-ignore */
|
|
6910
6650
|
name: `shared-sync-${this.webOptions.identifier}`,
|
|
6911
6651
|
type: undefined
|
|
@@ -6948,24 +6688,9 @@ class SharedWebStreamingSyncImplementation extends _WebStreamingSyncImplementati
|
|
|
6948
6688
|
* - We resolve the top-level promise after the lock has been registered with the shared worker.
|
|
6949
6689
|
* - The client sends the params to the shared worker after locks have been registered.
|
|
6950
6690
|
*/
|
|
6951
|
-
await
|
|
6952
|
-
|
|
6953
|
-
|
|
6954
|
-
// to free resources associated with this tab.
|
|
6955
|
-
// We take hold of this lock as soon-as-possible in order to cater for potentially closed tabs.
|
|
6956
|
-
(0,_shared_navigator_js__WEBPACK_IMPORTED_MODULE_1__.getNavigatorLocks)().request(`tab-close-signal-${crypto.randomUUID()}`, async (lock) => {
|
|
6957
|
-
if (this.abortOnClose.signal.aborted) {
|
|
6958
|
-
return;
|
|
6959
|
-
}
|
|
6960
|
-
// Awaiting here ensures the worker is waiting for the lock
|
|
6961
|
-
await this.syncManager.addLockBasedCloseSignal(lock.name);
|
|
6962
|
-
// The lock has been registered, we can continue with the initialization
|
|
6963
|
-
resolve();
|
|
6964
|
-
await new Promise((r) => {
|
|
6965
|
-
this.abortOnClose.signal.onabort = () => r();
|
|
6966
|
-
});
|
|
6967
|
-
});
|
|
6968
|
-
});
|
|
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);
|
|
6969
6694
|
const { crudUploadThrottleMs, identifier, retryDelayMs } = this.options;
|
|
6970
6695
|
const flags = { ...this.webOptions.flags, workers: undefined };
|
|
6971
6696
|
await this.syncManager.setParams({
|
|
@@ -7003,13 +6728,13 @@ class SharedWebStreamingSyncImplementation extends _WebStreamingSyncImplementati
|
|
|
7003
6728
|
// Listen for the close acknowledgment from the worker
|
|
7004
6729
|
this.messagePort.addEventListener('message', (event) => {
|
|
7005
6730
|
const payload = event.data;
|
|
7006
|
-
if (payload?.event ===
|
|
6731
|
+
if (payload?.event === _worker_sync_SharedSyncImplementation_js__WEBPACK_IMPORTED_MODULE_2__.SharedSyncClientEvent.CLOSE_ACK) {
|
|
7007
6732
|
resolve();
|
|
7008
6733
|
}
|
|
7009
6734
|
});
|
|
7010
6735
|
// Signal the shared worker that this client is closing its connection to the worker
|
|
7011
6736
|
const closeMessagePayload = {
|
|
7012
|
-
event:
|
|
6737
|
+
event: _worker_sync_SharedSyncImplementation_js__WEBPACK_IMPORTED_MODULE_2__.SharedSyncClientEvent.CLOSE_CLIENT,
|
|
7013
6738
|
data: {}
|
|
7014
6739
|
};
|
|
7015
6740
|
this.messagePort.postMessage(closeMessagePayload);
|
|
@@ -7221,6 +6946,153 @@ const getNavigatorLocks = () => {
|
|
|
7221
6946
|
};
|
|
7222
6947
|
|
|
7223
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
|
+
|
|
7224
7096
|
/***/ },
|
|
7225
7097
|
|
|
7226
7098
|
/***/ "./lib/src/worker/db/open-worker-database.js"
|
|
@@ -7237,14 +7109,14 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
7237
7109
|
/* harmony export */ resolveWorkerDatabasePortFactory: () => (/* binding */ resolveWorkerDatabasePortFactory)
|
|
7238
7110
|
/* harmony export */ });
|
|
7239
7111
|
/* harmony import */ var comlink__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! comlink */ "comlink");
|
|
7240
|
-
/* 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");
|
|
7241
7113
|
|
|
7242
7114
|
|
|
7243
7115
|
/**
|
|
7244
7116
|
* Opens a shared or dedicated worker which exposes opening of database connections
|
|
7245
7117
|
*/
|
|
7246
7118
|
function openWorkerDatabasePort(workerIdentifier, multipleTabs = true, worker = '', vfs) {
|
|
7247
|
-
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;
|
|
7248
7120
|
if (worker) {
|
|
7249
7121
|
return !needsDedicated && multipleTabs
|
|
7250
7122
|
? new SharedWorker(`${worker}`, {
|
|
@@ -7264,12 +7136,12 @@ function openWorkerDatabasePort(workerIdentifier, multipleTabs = true, worker =
|
|
|
7264
7136
|
* (in the case of Android)
|
|
7265
7137
|
*/
|
|
7266
7138
|
return !needsDedicated && multipleTabs
|
|
7267
|
-
? 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), {
|
|
7268
7140
|
/* @vite-ignore */
|
|
7269
7141
|
name: `shared-DB-worker-${workerIdentifier}`,
|
|
7270
7142
|
type: undefined
|
|
7271
7143
|
}).port
|
|
7272
|
-
: 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), {
|
|
7273
7145
|
/* @vite-ignore */
|
|
7274
7146
|
name: `DB-worker-${workerIdentifier}`,
|
|
7275
7147
|
type: undefined
|
|
@@ -7468,14 +7340,12 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
7468
7340
|
/* harmony export */ SharedSyncImplementation: () => (/* binding */ SharedSyncImplementation)
|
|
7469
7341
|
/* harmony export */ });
|
|
7470
7342
|
/* harmony import */ var _powersync_common__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @powersync/common */ "@powersync/common");
|
|
7471
|
-
/* harmony import */ var
|
|
7472
|
-
/* harmony import */ var
|
|
7473
|
-
/* harmony import */ var
|
|
7474
|
-
/* harmony import */ var
|
|
7475
|
-
/* harmony import */ var
|
|
7476
|
-
/* harmony import */ var
|
|
7477
|
-
/* harmony import */ var _BroadcastLogger_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./BroadcastLogger.js */ "./lib/src/worker/sync/BroadcastLogger.js");
|
|
7478
|
-
|
|
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");
|
|
7479
7349
|
|
|
7480
7350
|
|
|
7481
7351
|
|
|
@@ -7520,14 +7390,14 @@ class SharedSyncImplementation extends _powersync_common__WEBPACK_IMPORTED_MODUL
|
|
|
7520
7390
|
connectionManager;
|
|
7521
7391
|
syncStatus;
|
|
7522
7392
|
broadCastLogger;
|
|
7523
|
-
|
|
7393
|
+
database = this.generateReconnectableDatabase();
|
|
7524
7394
|
constructor() {
|
|
7525
7395
|
super();
|
|
7526
7396
|
this.ports = [];
|
|
7527
7397
|
this.syncParams = null;
|
|
7528
7398
|
this.logger = (0,_powersync_common__WEBPACK_IMPORTED_MODULE_0__.createLogger)('shared-sync');
|
|
7529
7399
|
this.lastConnectOptions = undefined;
|
|
7530
|
-
this.portMutex = new
|
|
7400
|
+
this.portMutex = new _powersync_common__WEBPACK_IMPORTED_MODULE_0__.Mutex();
|
|
7531
7401
|
this.isInitialized = new Promise((resolve) => {
|
|
7532
7402
|
const callback = this.registerListener({
|
|
7533
7403
|
initialized: () => {
|
|
@@ -7536,10 +7406,8 @@ class SharedSyncImplementation extends _powersync_common__WEBPACK_IMPORTED_MODUL
|
|
|
7536
7406
|
}
|
|
7537
7407
|
});
|
|
7538
7408
|
});
|
|
7539
|
-
// Should be configured once we get params
|
|
7540
|
-
this.distributedDB = null;
|
|
7541
7409
|
this.syncStatus = new _powersync_common__WEBPACK_IMPORTED_MODULE_0__.SyncStatus({});
|
|
7542
|
-
this.broadCastLogger = new
|
|
7410
|
+
this.broadCastLogger = new _BroadcastLogger_js__WEBPACK_IMPORTED_MODULE_4__.BroadcastLogger(this.ports);
|
|
7543
7411
|
this.connectionManager = new _powersync_common__WEBPACK_IMPORTED_MODULE_0__.ConnectionManager({
|
|
7544
7412
|
createSyncImplementation: async () => {
|
|
7545
7413
|
await this.waitForReady();
|
|
@@ -7637,38 +7505,8 @@ class SharedSyncImplementation extends _powersync_common__WEBPACK_IMPORTED_MODUL
|
|
|
7637
7505
|
if (params.streamOptions?.flags?.broadcastLogs) {
|
|
7638
7506
|
this.logger = this.broadCastLogger;
|
|
7639
7507
|
}
|
|
7640
|
-
|
|
7641
|
-
|
|
7642
|
-
openConnection: async () => {
|
|
7643
|
-
// Gets a connection from the clients when a new connection is requested.
|
|
7644
|
-
const db = await this.openInternalDB();
|
|
7645
|
-
db.registerListener({
|
|
7646
|
-
closing: () => {
|
|
7647
|
-
lockedAdapter.reOpenInternalDB();
|
|
7648
|
-
}
|
|
7649
|
-
});
|
|
7650
|
-
return db;
|
|
7651
|
-
},
|
|
7652
|
-
logger: this.logger,
|
|
7653
|
-
reOpenOnConnectionClosed: true
|
|
7654
|
-
});
|
|
7655
|
-
this.distributedDB = lockedAdapter;
|
|
7656
|
-
await lockedAdapter.init();
|
|
7657
|
-
lockedAdapter.registerListener({
|
|
7658
|
-
databaseReOpened: () => {
|
|
7659
|
-
// We may have missed some table updates while the database was closed.
|
|
7660
|
-
// We can poke the crud in case we missed any updates.
|
|
7661
|
-
this.connectionManager.syncStreamImplementation?.triggerCrudUpload();
|
|
7662
|
-
/**
|
|
7663
|
-
* FIXME or IMPROVE ME
|
|
7664
|
-
* The Rust client implementation stores sync state on the connection level.
|
|
7665
|
-
* Reopening the database causes a state machine error which should cause the
|
|
7666
|
-
* StreamingSyncImplementation to reconnect. It would be nicer if we could trigger
|
|
7667
|
-
* this reconnect earlier.
|
|
7668
|
-
* This reconnect is not required for IndexedDB.
|
|
7669
|
-
*/
|
|
7670
|
-
}
|
|
7671
|
-
});
|
|
7508
|
+
// Ensure we have a usable database connection, the reconnectable database will connect lazily on first use.
|
|
7509
|
+
await this.database.readLock(async () => { });
|
|
7672
7510
|
self.onerror = (event) => {
|
|
7673
7511
|
// Share any uncaught events on the broadcast logger
|
|
7674
7512
|
this.logger.error('Uncaught exception in PowerSync shared sync worker', event);
|
|
@@ -7700,7 +7538,7 @@ class SharedSyncImplementation extends _powersync_common__WEBPACK_IMPORTED_MODUL
|
|
|
7700
7538
|
return await this.portMutex.runExclusive(() => {
|
|
7701
7539
|
const portProvider = {
|
|
7702
7540
|
port,
|
|
7703
|
-
clientProvider:
|
|
7541
|
+
clientProvider: comlink__WEBPACK_IMPORTED_MODULE_1__.wrap(port),
|
|
7704
7542
|
currentSubscriptions: [],
|
|
7705
7543
|
closeListeners: [],
|
|
7706
7544
|
isClosing: false
|
|
@@ -7747,7 +7585,7 @@ class SharedSyncImplementation extends _powersync_common__WEBPACK_IMPORTED_MODUL
|
|
|
7747
7585
|
await closeListener();
|
|
7748
7586
|
}
|
|
7749
7587
|
this.collectActiveSubscriptions();
|
|
7750
|
-
return () => trackedPort.clientProvider[
|
|
7588
|
+
return () => trackedPort.clientProvider[comlink__WEBPACK_IMPORTED_MODULE_1__.releaseProxy]();
|
|
7751
7589
|
});
|
|
7752
7590
|
}
|
|
7753
7591
|
triggerCrudUpload() {
|
|
@@ -7784,9 +7622,9 @@ class SharedSyncImplementation extends _powersync_common__WEBPACK_IMPORTED_MODUL
|
|
|
7784
7622
|
// This should only be called after initialization has completed
|
|
7785
7623
|
const syncParams = this.syncParams;
|
|
7786
7624
|
// Create a new StreamingSyncImplementation for each connect call. This is usually done is all SDKs.
|
|
7787
|
-
return new
|
|
7788
|
-
adapter: new _powersync_common__WEBPACK_IMPORTED_MODULE_0__.SqliteBucketStorage(this.
|
|
7789
|
-
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({
|
|
7790
7628
|
invalidateCredentials: async () => {
|
|
7791
7629
|
const lastPort = await this.getLastWrappedPort();
|
|
7792
7630
|
if (!lastPort) {
|
|
@@ -7856,9 +7694,9 @@ class SharedSyncImplementation extends _powersync_common__WEBPACK_IMPORTED_MODUL
|
|
|
7856
7694
|
});
|
|
7857
7695
|
}
|
|
7858
7696
|
/**
|
|
7859
|
-
*
|
|
7697
|
+
* Requests a random client to share its database connection with us.
|
|
7860
7698
|
*/
|
|
7861
|
-
async openInternalDB() {
|
|
7699
|
+
async openInternalDB(handleClosed) {
|
|
7862
7700
|
const client = await this.getRandomWrappedPort();
|
|
7863
7701
|
if (!client) {
|
|
7864
7702
|
// Should not really happen in practice
|
|
@@ -7892,8 +7730,9 @@ class SharedSyncImplementation extends _powersync_common__WEBPACK_IMPORTED_MODUL
|
|
|
7892
7730
|
removeCloseListener();
|
|
7893
7731
|
throw ex;
|
|
7894
7732
|
});
|
|
7895
|
-
const remote =
|
|
7733
|
+
const remote = comlink__WEBPACK_IMPORTED_MODULE_1__.wrap(workerPort);
|
|
7896
7734
|
const identifier = this.syncParams.dbParams.dbFilename;
|
|
7735
|
+
const clientLockName = await (0,_shared_tab_close_signal_js__WEBPACK_IMPORTED_MODULE_6__.generateTabCloseSignal)();
|
|
7897
7736
|
/**
|
|
7898
7737
|
* The open could fail if the tab is closed while we're busy opening the database.
|
|
7899
7738
|
* This operation is typically executed inside an exclusive portMutex lock.
|
|
@@ -7901,7 +7740,16 @@ class SharedSyncImplementation extends _powersync_common__WEBPACK_IMPORTED_MODUL
|
|
|
7901
7740
|
* We can't rely on the closeListeners to abort the operation if the tab is closed.
|
|
7902
7741
|
*/
|
|
7903
7742
|
const db = await withAbort({
|
|
7904
|
-
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
|
+
},
|
|
7905
7753
|
signal: abortController.signal,
|
|
7906
7754
|
cleanupOnAbort: (db) => {
|
|
7907
7755
|
db.close();
|
|
@@ -7911,25 +7759,86 @@ class SharedSyncImplementation extends _powersync_common__WEBPACK_IMPORTED_MODUL
|
|
|
7911
7759
|
removeCloseListener();
|
|
7912
7760
|
});
|
|
7913
7761
|
clearTimeout(timeout);
|
|
7914
|
-
const wrapped = new _db_adapters_WorkerWrappedAsyncDatabaseConnection_js__WEBPACK_IMPORTED_MODULE_6__.WorkerWrappedAsyncDatabaseConnection({
|
|
7915
|
-
remote,
|
|
7916
|
-
baseConnection: db,
|
|
7917
|
-
identifier,
|
|
7918
|
-
// It's possible for this worker to outlive the client hosting the database for us. We need to be prepared for
|
|
7919
|
-
// that and ensure pending requests are aborted when the tab is closed.
|
|
7920
|
-
remoteCanCloseUnexpectedly: true
|
|
7921
|
-
});
|
|
7922
7762
|
client.closeListeners.push(async () => {
|
|
7923
7763
|
this.logger.info('Aborting open connection because associated tab closed.');
|
|
7764
|
+
handleClosed(db);
|
|
7924
7765
|
/**
|
|
7925
7766
|
* Don't await this close operation. It might never resolve if the tab is closed.
|
|
7926
7767
|
* We mark the remote as closed first, this will reject any pending requests.
|
|
7927
7768
|
* We then call close. The close operation is configured to fire-and-forget, the main promise will reject immediately.
|
|
7928
7769
|
*/
|
|
7929
|
-
|
|
7930
|
-
|
|
7770
|
+
db.markRemoteClosed();
|
|
7771
|
+
db.close().catch((ex) => this.logger.warn('error closing database connection', ex));
|
|
7931
7772
|
});
|
|
7932
|
-
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();
|
|
7933
7842
|
}
|
|
7934
7843
|
/**
|
|
7935
7844
|
* A method to update the all shared statuses for each
|
|
@@ -8148,51 +8057,37 @@ var __webpack_exports__ = {};
|
|
|
8148
8057
|
__webpack_require__.r(__webpack_exports__);
|
|
8149
8058
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
8150
8059
|
/* harmony export */ AbstractWebPowerSyncDatabaseOpenFactory: () => (/* reexport safe */ _db_adapters_AbstractWebPowerSyncDatabaseOpenFactory_js__WEBPACK_IMPORTED_MODULE_2__.AbstractWebPowerSyncDatabaseOpenFactory),
|
|
8151
|
-
/* harmony export */
|
|
8152
|
-
/* harmony export */
|
|
8153
|
-
/* harmony export */
|
|
8154
|
-
/* harmony export */ DEFAULT_MODULE_FACTORIES: () => (/* reexport safe */ _db_adapters_wa_sqlite_WASQLiteConnection_js__WEBPACK_IMPORTED_MODULE_5__.DEFAULT_MODULE_FACTORIES),
|
|
8155
|
-
/* harmony export */ DEFAULT_POWERSYNC_FLAGS: () => (/* reexport safe */ _db_PowerSyncDatabase_js__WEBPACK_IMPORTED_MODULE_10__.DEFAULT_POWERSYNC_FLAGS),
|
|
8156
|
-
/* 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),
|
|
8157
8063
|
/* harmony export */ IndexDBFileSystemStorageAdapter: () => (/* reexport safe */ _attachments_IndexDBFileSystemAdapter_js__WEBPACK_IMPORTED_MODULE_1__.IndexDBFileSystemStorageAdapter),
|
|
8158
|
-
/* harmony export */
|
|
8159
|
-
/* harmony export */
|
|
8160
|
-
/* harmony export */
|
|
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 */ WebRemote: () => (/* reexport safe */ _db_sync_WebRemote_js__WEBPACK_IMPORTED_MODULE_12__.WebRemote),
|
|
8170
|
-
/* harmony export */ WebStreamingSyncImplementation: () => (/* reexport safe */ _db_sync_WebStreamingSyncImplementation_js__WEBPACK_IMPORTED_MODULE_13__.WebStreamingSyncImplementation),
|
|
8171
|
-
/* harmony export */ isServerSide: () => (/* reexport safe */ _db_adapters_web_sql_flags_js__WEBPACK_IMPORTED_MODULE_9__.isServerSide),
|
|
8172
|
-
/* harmony export */ resolveWebPowerSyncFlags: () => (/* reexport safe */ _db_PowerSyncDatabase_js__WEBPACK_IMPORTED_MODULE_10__.resolveWebPowerSyncFlags),
|
|
8173
|
-
/* 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)
|
|
8174
8075
|
/* harmony export */ });
|
|
8175
8076
|
/* harmony import */ var _powersync_common__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @powersync/common */ "@powersync/common");
|
|
8176
8077
|
/* harmony reexport (unknown) */ var __WEBPACK_REEXPORT_OBJECT__ = {};
|
|
8177
|
-
/* 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__]
|
|
8178
8079
|
/* harmony reexport (unknown) */ __webpack_require__.d(__webpack_exports__, __WEBPACK_REEXPORT_OBJECT__);
|
|
8179
8080
|
/* harmony import */ var _attachments_IndexDBFileSystemAdapter_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./attachments/IndexDBFileSystemAdapter.js */ "./lib/src/attachments/IndexDBFileSystemAdapter.js");
|
|
8180
8081
|
/* harmony import */ var _db_adapters_AbstractWebPowerSyncDatabaseOpenFactory_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./db/adapters/AbstractWebPowerSyncDatabaseOpenFactory.js */ "./lib/src/db/adapters/AbstractWebPowerSyncDatabaseOpenFactory.js");
|
|
8181
|
-
/* harmony import */ var
|
|
8182
|
-
/* harmony import */ var
|
|
8183
|
-
/* harmony import */ var
|
|
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 _db_sync_WebRemote_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./db/sync/WebRemote.js */ "./lib/src/db/sync/WebRemote.js");
|
|
8191
|
-
/* harmony import */ var _db_sync_WebStreamingSyncImplementation_js__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./db/sync/WebStreamingSyncImplementation.js */ "./lib/src/db/sync/WebStreamingSyncImplementation.js");
|
|
8192
|
-
/* harmony import */ var _db_adapters_WebDBAdapter_js__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./db/adapters/WebDBAdapter.js */ "./lib/src/db/adapters/WebDBAdapter.js");
|
|
8193
|
-
|
|
8194
|
-
|
|
8195
|
-
|
|
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");
|
|
8196
8091
|
|
|
8197
8092
|
|
|
8198
8093
|
|