@powersync/web 0.0.0-dev-20251129133952 → 0.0.0-dev-20251201150812
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/1807036ae51c10ee4d23.wasm +0 -0
- package/dist/{10072fe45f0a8fab0a0e.wasm → 307d8ce2280e3bae09d5.wasm} +0 -0
- package/dist/{6e435e51534839845554.wasm → cd8b9e8f4c87bf81c169.wasm} +0 -0
- package/dist/e797080f5ed0b5324166.wasm +0 -0
- package/dist/index.umd.js +137 -104
- package/dist/index.umd.js.map +1 -1
- package/dist/worker/SharedSyncImplementation.umd.js +137 -110
- package/dist/worker/SharedSyncImplementation.umd.js.map +1 -1
- package/dist/worker/WASQLiteDB.umd.js +15 -1
- package/dist/worker/WASQLiteDB.umd.js.map +1 -1
- package/dist/worker/node_modules_journeyapps_wa-sqlite_dist_mc-wa-sqlite-async_mjs.umd.js +2 -2
- package/dist/worker/node_modules_journeyapps_wa-sqlite_dist_mc-wa-sqlite-async_mjs.umd.js.map +1 -1
- package/dist/worker/node_modules_journeyapps_wa-sqlite_dist_mc-wa-sqlite_mjs.umd.js +2 -2
- package/dist/worker/node_modules_journeyapps_wa-sqlite_dist_mc-wa-sqlite_mjs.umd.js.map +1 -1
- package/dist/worker/node_modules_journeyapps_wa-sqlite_dist_wa-sqlite-async_mjs.umd.js +2 -2
- package/dist/worker/node_modules_journeyapps_wa-sqlite_dist_wa-sqlite-async_mjs.umd.js.map +1 -1
- package/dist/worker/node_modules_journeyapps_wa-sqlite_dist_wa-sqlite_mjs.umd.js +2 -2
- package/dist/worker/node_modules_journeyapps_wa-sqlite_dist_wa-sqlite_mjs.umd.js.map +1 -1
- package/dist/worker/node_modules_journeyapps_wa-sqlite_src_examples_IDBBatchAtomicVFS_js.umd.js +20 -23
- package/dist/worker/node_modules_journeyapps_wa-sqlite_src_examples_IDBBatchAtomicVFS_js.umd.js.map +1 -1
- package/lib/src/db/PowerSyncDatabase.d.ts +1 -1
- package/lib/src/db/PowerSyncDatabase.js +4 -4
- package/lib/src/db/adapters/AsyncDatabaseConnection.d.ts +5 -0
- package/lib/src/db/adapters/AsyncDatabaseConnection.js +5 -0
- package/lib/src/db/adapters/LockedAsyncDatabaseAdapter.d.ts +6 -1
- package/lib/src/db/adapters/LockedAsyncDatabaseAdapter.js +20 -5
- package/lib/src/db/adapters/WorkerWrappedAsyncDatabaseConnection.d.ts +5 -1
- package/lib/src/db/adapters/WorkerWrappedAsyncDatabaseConnection.js +12 -5
- package/lib/src/db/sync/SharedWebStreamingSyncImplementation.d.ts +0 -4
- package/lib/src/db/sync/SharedWebStreamingSyncImplementation.js +3 -8
- package/lib/src/worker/sync/MockSyncService.d.ts +2 -0
- package/lib/src/worker/sync/MockSyncService.js +3 -0
- package/lib/src/worker/sync/MockSyncServiceTypes.d.ts +101 -0
- package/lib/src/worker/sync/MockSyncServiceTypes.js +1 -0
- package/lib/src/worker/sync/MockSyncServiceWorker.d.ts +56 -0
- package/lib/src/worker/sync/MockSyncServiceWorker.js +369 -0
- package/lib/src/worker/sync/SharedSyncImplementation.d.ts +6 -11
- package/lib/src/worker/sync/SharedSyncImplementation.js +73 -64
- package/lib/src/worker/sync/SharedSyncImplementation.worker.js +1 -1
- package/lib/src/worker/sync/WorkerClient.d.ts +1 -3
- package/lib/src/worker/sync/WorkerClient.js +3 -27
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
- package/src/db/PowerSyncDatabase.ts +13 -15
- package/src/db/adapters/AsyncDatabaseConnection.ts +5 -0
- package/src/db/adapters/LockedAsyncDatabaseAdapter.ts +22 -5
- package/src/db/adapters/WorkerWrappedAsyncDatabaseConnection.ts +16 -4
- package/src/db/sync/SharedWebStreamingSyncImplementation.ts +5 -11
- package/src/worker/sync/MockSyncService.ts +3 -0
- package/src/worker/sync/MockSyncServiceTypes.ts +71 -0
- package/src/worker/sync/MockSyncServiceWorker.ts +406 -0
- package/src/worker/sync/SharedSyncImplementation.ts +85 -78
- package/src/worker/sync/SharedSyncImplementation.worker.ts +1 -1
- package/src/worker/sync/WorkerClient.ts +4 -30
- package/dist/a730f7ca717b02234beb.wasm +0 -0
- package/dist/aa2f408d64445fed090e.wasm +0 -0
|
@@ -3228,12 +3228,26 @@ class SyncStatus {
|
|
|
3228
3228
|
return {
|
|
3229
3229
|
connected: this.connected,
|
|
3230
3230
|
connecting: this.connecting,
|
|
3231
|
-
dataFlow:
|
|
3231
|
+
dataFlow: {
|
|
3232
|
+
...this.dataFlowStatus,
|
|
3233
|
+
uploadError: this.serializeError(this.dataFlowStatus.uploadError),
|
|
3234
|
+
downloadError: this.serializeError(this.dataFlowStatus.downloadError)
|
|
3235
|
+
},
|
|
3232
3236
|
lastSyncedAt: this.lastSyncedAt,
|
|
3233
3237
|
hasSynced: this.hasSynced,
|
|
3234
3238
|
priorityStatusEntries: this.priorityStatusEntries
|
|
3235
3239
|
};
|
|
3236
3240
|
}
|
|
3241
|
+
serializeError(error) {
|
|
3242
|
+
if (typeof error == 'undefined') {
|
|
3243
|
+
return undefined;
|
|
3244
|
+
}
|
|
3245
|
+
return {
|
|
3246
|
+
name: error.name,
|
|
3247
|
+
message: error.message,
|
|
3248
|
+
stack: error.stack
|
|
3249
|
+
};
|
|
3250
|
+
}
|
|
3237
3251
|
static comparePriorities(a, b) {
|
|
3238
3252
|
return b.priority - a.priority; // Reverse because higher priorities have lower numbers
|
|
3239
3253
|
}
|
|
@@ -17612,6 +17626,11 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
17612
17626
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
17613
17627
|
/* harmony export */ ConnectionClosedError: () => (/* binding */ ConnectionClosedError)
|
|
17614
17628
|
/* harmony export */ });
|
|
17629
|
+
/**
|
|
17630
|
+
* Thrown when an underlying database connection is closed.
|
|
17631
|
+
* This is particularly relevant when worker connections are marked as closed while
|
|
17632
|
+
* operations are still in progress.
|
|
17633
|
+
*/
|
|
17615
17634
|
class ConnectionClosedError extends Error {
|
|
17616
17635
|
constructor(message) {
|
|
17617
17636
|
super(message);
|
|
@@ -17659,7 +17678,6 @@ class LockedAsyncDatabaseAdapter extends _powersync_common__WEBPACK_IMPORTED_MOD
|
|
|
17659
17678
|
_config = null;
|
|
17660
17679
|
pendingAbortControllers;
|
|
17661
17680
|
requiresHolds;
|
|
17662
|
-
requiresReOpen;
|
|
17663
17681
|
databaseOpenPromise = null;
|
|
17664
17682
|
closing;
|
|
17665
17683
|
closed;
|
|
@@ -17672,7 +17690,6 @@ class LockedAsyncDatabaseAdapter extends _powersync_common__WEBPACK_IMPORTED_MOD
|
|
|
17672
17690
|
this.closed = false;
|
|
17673
17691
|
this.closing = false;
|
|
17674
17692
|
this.requiresHolds = null;
|
|
17675
|
-
this.requiresReOpen = false;
|
|
17676
17693
|
// Set the name if provided. We can query for the name if not available yet
|
|
17677
17694
|
this.debugMode = options.debugMode ?? false;
|
|
17678
17695
|
if (this.debugMode) {
|
|
@@ -17728,6 +17745,25 @@ class LockedAsyncDatabaseAdapter extends _powersync_common__WEBPACK_IMPORTED_MOD
|
|
|
17728
17745
|
*/
|
|
17729
17746
|
this.requiresHolds = this._config.vfs == _wa_sqlite_WASQLiteConnection__WEBPACK_IMPORTED_MODULE_4__.WASQLiteVFS.IDBBatchAtomicVFS;
|
|
17730
17747
|
}
|
|
17748
|
+
_reOpen() {
|
|
17749
|
+
this.databaseOpenPromise = this.openInternalDB().finally(() => {
|
|
17750
|
+
this.databaseOpenPromise = null;
|
|
17751
|
+
});
|
|
17752
|
+
return this.databaseOpenPromise;
|
|
17753
|
+
}
|
|
17754
|
+
/**
|
|
17755
|
+
* Re-opens the underlying database.
|
|
17756
|
+
* Returns a pending operation if one is already in progress.
|
|
17757
|
+
*/
|
|
17758
|
+
async reOpenInternalDB() {
|
|
17759
|
+
if (!this.options.reOpenOnConnectionClosed) {
|
|
17760
|
+
throw new Error(`Cannot re-open underlying database, reOpenOnConnectionClosed is not enabled`);
|
|
17761
|
+
}
|
|
17762
|
+
if (this.databaseOpenPromise) {
|
|
17763
|
+
return this.databaseOpenPromise;
|
|
17764
|
+
}
|
|
17765
|
+
return this._reOpen();
|
|
17766
|
+
}
|
|
17731
17767
|
async _init() {
|
|
17732
17768
|
await this.openInternalDB();
|
|
17733
17769
|
this.iterateListeners((cb) => cb.initialized?.());
|
|
@@ -17846,9 +17882,7 @@ class LockedAsyncDatabaseAdapter extends _powersync_common__WEBPACK_IMPORTED_MOD
|
|
|
17846
17882
|
if (ex instanceof _AsyncDatabaseConnection__WEBPACK_IMPORTED_MODULE_2__.ConnectionClosedError) {
|
|
17847
17883
|
if (this.options.reOpenOnConnectionClosed && !this.databaseOpenPromise && !this.closing) {
|
|
17848
17884
|
// Immediately re-open the database. We need to miss as little table updates as possible.
|
|
17849
|
-
this.
|
|
17850
|
-
this.databaseOpenPromise = null;
|
|
17851
|
-
});
|
|
17885
|
+
this.reOpenInternalDB();
|
|
17852
17886
|
}
|
|
17853
17887
|
}
|
|
17854
17888
|
throw ex;
|
|
@@ -17985,19 +18019,22 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
17985
18019
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
17986
18020
|
/* harmony export */ WorkerWrappedAsyncDatabaseConnection: () => (/* binding */ WorkerWrappedAsyncDatabaseConnection)
|
|
17987
18021
|
/* harmony export */ });
|
|
17988
|
-
/* harmony import */ var
|
|
17989
|
-
/* harmony import */ var
|
|
18022
|
+
/* harmony import */ var _powersync_common__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @powersync/common */ "../common/dist/bundle.mjs");
|
|
18023
|
+
/* harmony import */ var comlink__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! comlink */ "../../node_modules/comlink/dist/esm/comlink.mjs");
|
|
18024
|
+
/* harmony import */ var _AsyncDatabaseConnection__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./AsyncDatabaseConnection */ "./lib/src/db/adapters/AsyncDatabaseConnection.js");
|
|
18025
|
+
|
|
17990
18026
|
|
|
17991
18027
|
|
|
17992
18028
|
/**
|
|
17993
18029
|
* Wraps a provided instance of {@link AsyncDatabaseConnection}, providing necessary proxy
|
|
17994
18030
|
* functions for worker listeners.
|
|
17995
18031
|
*/
|
|
17996
|
-
class WorkerWrappedAsyncDatabaseConnection {
|
|
18032
|
+
class WorkerWrappedAsyncDatabaseConnection extends _powersync_common__WEBPACK_IMPORTED_MODULE_0__.BaseObserver {
|
|
17997
18033
|
options;
|
|
17998
18034
|
lockAbortController = new AbortController();
|
|
17999
18035
|
notifyRemoteClosed;
|
|
18000
18036
|
constructor(options) {
|
|
18037
|
+
super();
|
|
18001
18038
|
this.options = options;
|
|
18002
18039
|
if (options.remoteCanCloseUnexpectedly) {
|
|
18003
18040
|
this.notifyRemoteClosed = new AbortController();
|
|
@@ -18030,17 +18067,20 @@ class WorkerWrappedAsyncDatabaseConnection {
|
|
|
18030
18067
|
isAutoCommit() {
|
|
18031
18068
|
return this.withRemote(() => this.baseConnection.isAutoCommit());
|
|
18032
18069
|
}
|
|
18033
|
-
withRemote(workerPromise) {
|
|
18070
|
+
withRemote(workerPromise, fireActionOnAbort = false) {
|
|
18034
18071
|
const controller = this.notifyRemoteClosed;
|
|
18035
18072
|
if (controller) {
|
|
18036
18073
|
return new Promise((resolve, reject) => {
|
|
18037
18074
|
if (controller.signal.aborted) {
|
|
18038
|
-
reject(new
|
|
18039
|
-
|
|
18040
|
-
|
|
18075
|
+
reject(new _AsyncDatabaseConnection__WEBPACK_IMPORTED_MODULE_1__.ConnectionClosedError('Called operation on closed remote'));
|
|
18076
|
+
if (!fireActionOnAbort) {
|
|
18077
|
+
// Don't run the operation if we're going to reject
|
|
18078
|
+
// We might want to fire-and-forget the operation in some cases (like a close operation)
|
|
18079
|
+
return;
|
|
18080
|
+
}
|
|
18041
18081
|
}
|
|
18042
18082
|
function handleAbort() {
|
|
18043
|
-
reject(new
|
|
18083
|
+
reject(new _AsyncDatabaseConnection__WEBPACK_IMPORTED_MODULE_1__.ConnectionClosedError('Remote peer closed with request in flight'));
|
|
18044
18084
|
}
|
|
18045
18085
|
function completePromise(action) {
|
|
18046
18086
|
controller.signal.removeEventListener('abort', handleAbort);
|
|
@@ -18094,7 +18134,7 @@ class WorkerWrappedAsyncDatabaseConnection {
|
|
|
18094
18134
|
reject(ex);
|
|
18095
18135
|
}
|
|
18096
18136
|
}));
|
|
18097
|
-
const newPort = await remote[
|
|
18137
|
+
const newPort = await remote[comlink__WEBPACK_IMPORTED_MODULE_2__.createEndpoint]();
|
|
18098
18138
|
return { port: newPort, identifier };
|
|
18099
18139
|
}
|
|
18100
18140
|
/**
|
|
@@ -18102,17 +18142,19 @@ class WorkerWrappedAsyncDatabaseConnection {
|
|
|
18102
18142
|
* This can be extended by custom implementations in order to handle proxy events.
|
|
18103
18143
|
*/
|
|
18104
18144
|
async registerOnTableChange(callback) {
|
|
18105
|
-
return this.baseConnection.registerOnTableChange(
|
|
18145
|
+
return this.baseConnection.registerOnTableChange(comlink__WEBPACK_IMPORTED_MODULE_2__.proxy(callback));
|
|
18106
18146
|
}
|
|
18107
18147
|
async close() {
|
|
18108
18148
|
// Abort any pending lock requests.
|
|
18109
18149
|
this.lockAbortController.abort();
|
|
18110
18150
|
try {
|
|
18111
|
-
|
|
18151
|
+
// fire and forget the close operation
|
|
18152
|
+
await this.withRemote(() => this.baseConnection.close(), true);
|
|
18112
18153
|
}
|
|
18113
18154
|
finally {
|
|
18114
|
-
this.options.remote[
|
|
18155
|
+
this.options.remote[comlink__WEBPACK_IMPORTED_MODULE_2__.releaseProxy]();
|
|
18115
18156
|
this.options.onClose?.();
|
|
18157
|
+
this.iterateListeners((l) => l.closing?.());
|
|
18116
18158
|
}
|
|
18117
18159
|
}
|
|
18118
18160
|
execute(sql, params) {
|
|
@@ -18992,14 +19034,25 @@ class SharedSyncImplementation extends _powersync_common__WEBPACK_IMPORTED_MODUL
|
|
|
18992
19034
|
/**
|
|
18993
19035
|
* Gets the last client port which we know is safe from unexpected closes.
|
|
18994
19036
|
*/
|
|
18995
|
-
|
|
18996
|
-
// Find the last port which is
|
|
18997
|
-
|
|
18998
|
-
|
|
18999
|
-
|
|
19037
|
+
async getLastWrappedPort() {
|
|
19038
|
+
// Find the last port which is not closing
|
|
19039
|
+
return await this.portMutex.runExclusive(() => {
|
|
19040
|
+
for (let i = this.ports.length - 1; i >= 0; i--) {
|
|
19041
|
+
if (!this.ports[i].isClosing) {
|
|
19042
|
+
return this.ports[i];
|
|
19043
|
+
}
|
|
19000
19044
|
}
|
|
19001
|
-
|
|
19002
|
-
|
|
19045
|
+
return;
|
|
19046
|
+
});
|
|
19047
|
+
}
|
|
19048
|
+
/**
|
|
19049
|
+
* In some very rare cases a specific tab might not respond to requests.
|
|
19050
|
+
* This returns a random port which is not closing.
|
|
19051
|
+
*/
|
|
19052
|
+
async getRandomWrappedPort() {
|
|
19053
|
+
return await this.portMutex.runExclusive(() => {
|
|
19054
|
+
return this.ports[Math.floor(Math.random() * this.ports.length)];
|
|
19055
|
+
});
|
|
19003
19056
|
}
|
|
19004
19057
|
async waitForStatus(status) {
|
|
19005
19058
|
return this.withSyncImplementation(async (sync) => {
|
|
@@ -19041,39 +19094,45 @@ class SharedSyncImplementation extends _powersync_common__WEBPACK_IMPORTED_MODUL
|
|
|
19041
19094
|
async setParams(params) {
|
|
19042
19095
|
await this.portMutex.runExclusive(async () => {
|
|
19043
19096
|
this.collectActiveSubscriptions();
|
|
19044
|
-
|
|
19045
|
-
|
|
19046
|
-
|
|
19047
|
-
|
|
19048
|
-
|
|
19049
|
-
|
|
19050
|
-
|
|
19051
|
-
|
|
19097
|
+
});
|
|
19098
|
+
if (this.syncParams) {
|
|
19099
|
+
// Cannot modify already existing sync implementation params
|
|
19100
|
+
return;
|
|
19101
|
+
}
|
|
19102
|
+
// First time setting params
|
|
19103
|
+
this.syncParams = params;
|
|
19104
|
+
if (params.streamOptions?.flags?.broadcastLogs) {
|
|
19105
|
+
this.logger = this.broadCastLogger;
|
|
19106
|
+
}
|
|
19107
|
+
const lockedAdapter = new _db_adapters_LockedAsyncDatabaseAdapter__WEBPACK_IMPORTED_MODULE_4__.LockedAsyncDatabaseAdapter({
|
|
19108
|
+
name: params.dbParams.dbFilename,
|
|
19109
|
+
openConnection: async () => {
|
|
19110
|
+
// Gets a connection from the clients when a new connection is requested.
|
|
19111
|
+
const db = await this.openInternalDB();
|
|
19112
|
+
db.registerListener({
|
|
19113
|
+
closing: () => {
|
|
19114
|
+
lockedAdapter.reOpenInternalDB();
|
|
19115
|
+
}
|
|
19116
|
+
});
|
|
19117
|
+
return db;
|
|
19118
|
+
},
|
|
19119
|
+
logger: this.logger,
|
|
19120
|
+
reOpenOnConnectionClosed: true
|
|
19121
|
+
});
|
|
19122
|
+
this.distributedDB = lockedAdapter;
|
|
19123
|
+
await lockedAdapter.init();
|
|
19124
|
+
lockedAdapter.registerListener({
|
|
19125
|
+
databaseReOpened: () => {
|
|
19126
|
+
// We may have missed some table updates while the database was closed.
|
|
19127
|
+
// We can poke the crud in case we missed any updates.
|
|
19128
|
+
this.connectionManager.syncStreamImplementation?.triggerCrudUpload();
|
|
19052
19129
|
}
|
|
19053
|
-
const lockedAdapter = new _db_adapters_LockedAsyncDatabaseAdapter__WEBPACK_IMPORTED_MODULE_4__.LockedAsyncDatabaseAdapter({
|
|
19054
|
-
name: params.dbParams.dbFilename,
|
|
19055
|
-
openConnection: async () => {
|
|
19056
|
-
// Gets a connection from the clients when a new connection is requested.
|
|
19057
|
-
return await this.openInternalDB();
|
|
19058
|
-
},
|
|
19059
|
-
logger: this.logger,
|
|
19060
|
-
reOpenOnConnectionClosed: true
|
|
19061
|
-
});
|
|
19062
|
-
this.distributedDB = lockedAdapter;
|
|
19063
|
-
await lockedAdapter.init();
|
|
19064
|
-
lockedAdapter.registerListener({
|
|
19065
|
-
databaseReOpened: () => {
|
|
19066
|
-
// We may have missed some table updates while the database was closed.
|
|
19067
|
-
// We can poke the crud in case we missed any updates.
|
|
19068
|
-
this.connectionManager.syncStreamImplementation?.triggerCrudUpload();
|
|
19069
|
-
}
|
|
19070
|
-
});
|
|
19071
|
-
self.onerror = (event) => {
|
|
19072
|
-
// Share any uncaught events on the broadcast logger
|
|
19073
|
-
this.logger.error('Uncaught exception in PowerSync shared sync worker', event);
|
|
19074
|
-
};
|
|
19075
|
-
this.iterateListeners((l) => l.initialized?.());
|
|
19076
19130
|
});
|
|
19131
|
+
self.onerror = (event) => {
|
|
19132
|
+
// Share any uncaught events on the broadcast logger
|
|
19133
|
+
this.logger.error('Uncaught exception in PowerSync shared sync worker', event);
|
|
19134
|
+
};
|
|
19135
|
+
this.iterateListeners((l) => l.initialized?.());
|
|
19077
19136
|
}
|
|
19078
19137
|
async dispose() {
|
|
19079
19138
|
await this.waitForReady();
|
|
@@ -19103,7 +19162,6 @@ class SharedSyncImplementation extends _powersync_common__WEBPACK_IMPORTED_MODUL
|
|
|
19103
19162
|
clientProvider: comlink__WEBPACK_IMPORTED_MODULE_7__.wrap(port),
|
|
19104
19163
|
currentSubscriptions: [],
|
|
19105
19164
|
closeListeners: [],
|
|
19106
|
-
isProtectedFromClose: false,
|
|
19107
19165
|
isClosing: false
|
|
19108
19166
|
};
|
|
19109
19167
|
this.ports.push(portProvider);
|
|
@@ -19189,7 +19247,7 @@ class SharedSyncImplementation extends _powersync_common__WEBPACK_IMPORTED_MODUL
|
|
|
19189
19247
|
adapter: new _powersync_common__WEBPACK_IMPORTED_MODULE_0__.SqliteBucketStorage(this.distributedDB, this.logger),
|
|
19190
19248
|
remote: new _db_sync_WebRemote__WEBPACK_IMPORTED_MODULE_2__.WebRemote({
|
|
19191
19249
|
invalidateCredentials: async () => {
|
|
19192
|
-
const lastPort = this.
|
|
19250
|
+
const lastPort = await this.getLastWrappedPort();
|
|
19193
19251
|
if (!lastPort) {
|
|
19194
19252
|
throw new Error('No client port found to invalidate credentials');
|
|
19195
19253
|
}
|
|
@@ -19202,7 +19260,7 @@ class SharedSyncImplementation extends _powersync_common__WEBPACK_IMPORTED_MODUL
|
|
|
19202
19260
|
}
|
|
19203
19261
|
},
|
|
19204
19262
|
fetchCredentials: async () => {
|
|
19205
|
-
const lastPort = this.
|
|
19263
|
+
const lastPort = await this.getLastWrappedPort();
|
|
19206
19264
|
if (!lastPort) {
|
|
19207
19265
|
throw new Error('No client port found to fetch credentials');
|
|
19208
19266
|
}
|
|
@@ -19227,7 +19285,7 @@ class SharedSyncImplementation extends _powersync_common__WEBPACK_IMPORTED_MODUL
|
|
|
19227
19285
|
}
|
|
19228
19286
|
}, this.logger),
|
|
19229
19287
|
uploadCrud: async () => {
|
|
19230
|
-
const lastPort = this.
|
|
19288
|
+
const lastPort = await this.getLastWrappedPort();
|
|
19231
19289
|
if (!lastPort) {
|
|
19232
19290
|
throw new Error('No client port found to upload crud');
|
|
19233
19291
|
}
|
|
@@ -19262,11 +19320,15 @@ class SharedSyncImplementation extends _powersync_common__WEBPACK_IMPORTED_MODUL
|
|
|
19262
19320
|
async openInternalDB() {
|
|
19263
19321
|
while (true) {
|
|
19264
19322
|
try {
|
|
19265
|
-
const
|
|
19266
|
-
if (!
|
|
19323
|
+
const client = await this.getRandomWrappedPort();
|
|
19324
|
+
if (!client) {
|
|
19267
19325
|
// Should not really happen in practice
|
|
19268
19326
|
throw new Error(`Could not open DB connection since no client is connected.`);
|
|
19269
19327
|
}
|
|
19328
|
+
// Fail-safe timeout for opening a database connection.
|
|
19329
|
+
const timeout = setTimeout(() => {
|
|
19330
|
+
abortController.abort();
|
|
19331
|
+
}, 10_000);
|
|
19270
19332
|
/**
|
|
19271
19333
|
* Handle cases where the client might close while opening a connection.
|
|
19272
19334
|
*/
|
|
@@ -19275,13 +19337,13 @@ class SharedSyncImplementation extends _powersync_common__WEBPACK_IMPORTED_MODUL
|
|
|
19275
19337
|
abortController.abort();
|
|
19276
19338
|
};
|
|
19277
19339
|
const removeCloseListener = () => {
|
|
19278
|
-
const index =
|
|
19340
|
+
const index = client.closeListeners.indexOf(closeListener);
|
|
19279
19341
|
if (index >= 0) {
|
|
19280
|
-
|
|
19342
|
+
client.closeListeners.splice(index, 1);
|
|
19281
19343
|
}
|
|
19282
19344
|
};
|
|
19283
|
-
|
|
19284
|
-
const workerPort = await withAbort(() =>
|
|
19345
|
+
client.closeListeners.push(closeListener);
|
|
19346
|
+
const workerPort = await withAbort(() => client.clientProvider.getDBWorkerPort(), abortController.signal).catch((ex) => {
|
|
19285
19347
|
removeCloseListener();
|
|
19286
19348
|
throw ex;
|
|
19287
19349
|
});
|
|
@@ -19297,6 +19359,7 @@ class SharedSyncImplementation extends _powersync_common__WEBPACK_IMPORTED_MODUL
|
|
|
19297
19359
|
// We can remove the close listener here since we no longer need it past this point.
|
|
19298
19360
|
removeCloseListener();
|
|
19299
19361
|
});
|
|
19362
|
+
clearTimeout(timeout);
|
|
19300
19363
|
const wrapped = new _db_adapters_WorkerWrappedAsyncDatabaseConnection__WEBPACK_IMPORTED_MODULE_5__.WorkerWrappedAsyncDatabaseConnection({
|
|
19301
19364
|
remote,
|
|
19302
19365
|
baseConnection: db,
|
|
@@ -19305,15 +19368,15 @@ class SharedSyncImplementation extends _powersync_common__WEBPACK_IMPORTED_MODUL
|
|
|
19305
19368
|
// that and ensure pending requests are aborted when the tab is closed.
|
|
19306
19369
|
remoteCanCloseUnexpectedly: true
|
|
19307
19370
|
});
|
|
19308
|
-
|
|
19371
|
+
client.closeListeners.push(async () => {
|
|
19309
19372
|
this.logger.info('Aborting open connection because associated tab closed.');
|
|
19310
19373
|
/**
|
|
19311
19374
|
* Don't await this close operation. It might never resolve if the tab is closed.
|
|
19312
|
-
* We
|
|
19313
|
-
*
|
|
19375
|
+
* We mark the remote as closed first, this will reject any pending requests.
|
|
19376
|
+
* We then call close. The close operation is configured to fire-and-forget, the main promise will reject immediately.
|
|
19314
19377
|
*/
|
|
19315
|
-
wrapped.close().catch((ex) => this.logger.warn('error closing database connection', ex));
|
|
19316
19378
|
wrapped.markRemoteClosed();
|
|
19379
|
+
wrapped.close().catch((ex) => this.logger.warn('error closing database connection', ex));
|
|
19317
19380
|
});
|
|
19318
19381
|
return wrapped;
|
|
19319
19382
|
}
|
|
@@ -19331,18 +19394,6 @@ class SharedSyncImplementation extends _powersync_common__WEBPACK_IMPORTED_MODUL
|
|
|
19331
19394
|
this.syncStatus = new _powersync_common__WEBPACK_IMPORTED_MODULE_0__.SyncStatus(status);
|
|
19332
19395
|
this.ports.forEach((p) => p.clientProvider.statusChanged(status));
|
|
19333
19396
|
}
|
|
19334
|
-
/**
|
|
19335
|
-
* A function only used for unit tests which updates the internal
|
|
19336
|
-
* sync stream client and all tab client's sync status
|
|
19337
|
-
*/
|
|
19338
|
-
async _testUpdateAllStatuses(status) {
|
|
19339
|
-
if (!this.connectionManager.syncStreamImplementation) {
|
|
19340
|
-
throw new Error('Cannot update status without a sync stream implementation');
|
|
19341
|
-
}
|
|
19342
|
-
// Only assigning, don't call listeners for this test
|
|
19343
|
-
this.connectionManager.syncStreamImplementation.syncStatus = new _powersync_common__WEBPACK_IMPORTED_MODULE_0__.SyncStatus(status);
|
|
19344
|
-
this.updateAllStatuses(status);
|
|
19345
|
-
}
|
|
19346
19397
|
}
|
|
19347
19398
|
/**
|
|
19348
19399
|
* Runs the action with an abort controller.
|
|
@@ -19402,8 +19453,6 @@ class WorkerClient {
|
|
|
19402
19453
|
this.sync = sync;
|
|
19403
19454
|
this.port = port;
|
|
19404
19455
|
comlink__WEBPACK_IMPORTED_MODULE_2__.expose(this, this.port);
|
|
19405
|
-
}
|
|
19406
|
-
async initialize() {
|
|
19407
19456
|
/**
|
|
19408
19457
|
* Adds an extra listener which can remove this port
|
|
19409
19458
|
* from the list of monitored ports.
|
|
@@ -19414,15 +19463,6 @@ class WorkerClient {
|
|
|
19414
19463
|
await this.removePort();
|
|
19415
19464
|
}
|
|
19416
19465
|
});
|
|
19417
|
-
/**
|
|
19418
|
-
* Keep a reference to the resolved port promise.
|
|
19419
|
-
* The init timing is difficult to predict due to the async message passing.
|
|
19420
|
-
* We only want to use a port if we are know it's been protected from being closed.
|
|
19421
|
-
* The lock based close signal will be added asynchronously. We need to use the
|
|
19422
|
-
* added port once the lock is configured.
|
|
19423
|
-
*/
|
|
19424
|
-
this.resolvedPortPromise = this.sync.addPort(this.port);
|
|
19425
|
-
this.resolvedPort = await this.resolvedPortPromise;
|
|
19426
19466
|
}
|
|
19427
19467
|
async removePort() {
|
|
19428
19468
|
if (this.resolvedPort) {
|
|
@@ -19444,19 +19484,9 @@ class WorkerClient {
|
|
|
19444
19484
|
* it can consider the connection to be closed.
|
|
19445
19485
|
*/
|
|
19446
19486
|
async addLockBasedCloseSignal(name) {
|
|
19447
|
-
|
|
19448
|
-
|
|
19449
|
-
|
|
19450
|
-
}
|
|
19451
|
-
else {
|
|
19452
|
-
const wrappedPort = await this.resolvedPortPromise;
|
|
19453
|
-
/**
|
|
19454
|
-
* The client registered a navigator lock. We now can guarantee detecting if the client has closed.
|
|
19455
|
-
* E.g. before this point: It's possible some ports might have been created and closed before the
|
|
19456
|
-
* lock based close signal is added. We should not trust those ports.
|
|
19457
|
-
*/
|
|
19458
|
-
wrappedPort.isProtectedFromClose = true;
|
|
19459
|
-
}
|
|
19487
|
+
// Only add the port once the lock has been obtained on the client.
|
|
19488
|
+
this.resolvedPort = await this.sync.addPort(this.port);
|
|
19489
|
+
// Don't await this lock request
|
|
19460
19490
|
(0,_shared_navigator__WEBPACK_IMPORTED_MODULE_0__.getNavigatorLocks)().request(name, async () => {
|
|
19461
19491
|
await this.removePort();
|
|
19462
19492
|
});
|
|
@@ -19488,9 +19518,6 @@ class WorkerClient {
|
|
|
19488
19518
|
disconnect() {
|
|
19489
19519
|
return this.sync.disconnect();
|
|
19490
19520
|
}
|
|
19491
|
-
async _testUpdateAllStatuses(status) {
|
|
19492
|
-
return this.sync._testUpdateAllStatuses(status);
|
|
19493
|
-
}
|
|
19494
19521
|
}
|
|
19495
19522
|
|
|
19496
19523
|
|
|
@@ -19672,7 +19699,7 @@ logger.useDefaults();
|
|
|
19672
19699
|
const sharedSyncImplementation = new _SharedSyncImplementation__WEBPACK_IMPORTED_MODULE_1__.SharedSyncImplementation();
|
|
19673
19700
|
_self.onconnect = async function (event) {
|
|
19674
19701
|
const port = event.ports[0];
|
|
19675
|
-
|
|
19702
|
+
new _WorkerClient__WEBPACK_IMPORTED_MODULE_2__.WorkerClient(sharedSyncImplementation, port);
|
|
19676
19703
|
};
|
|
19677
19704
|
|
|
19678
19705
|
})();
|