@powersync/web 0.0.0-dev-20251126195153 → 0.0.0-dev-20251127205344

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 CHANGED
@@ -40046,11 +40046,11 @@ __webpack_require__.r(__webpack_exports__);
40046
40046
  /* harmony export */ });
40047
40047
  /* harmony import */ var comlink__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! comlink */ "comlink");
40048
40048
  /* harmony import */ var comlink__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(comlink__WEBPACK_IMPORTED_MODULE_0__);
40049
- /* harmony import */ var _worker_sync_AbstractSharedSyncClientProvider__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../worker/sync/AbstractSharedSyncClientProvider */ "./lib/src/worker/sync/AbstractSharedSyncClientProvider.js");
40050
- /* harmony import */ var _worker_sync_SharedSyncImplementation__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../worker/sync/SharedSyncImplementation */ "./lib/src/worker/sync/SharedSyncImplementation.js");
40051
- /* harmony import */ var _adapters_web_sql_flags__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../adapters/web-sql-flags */ "./lib/src/db/adapters/web-sql-flags.js");
40052
- /* harmony import */ var _WebStreamingSyncImplementation__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./WebStreamingSyncImplementation */ "./lib/src/db/sync/WebStreamingSyncImplementation.js");
40053
- /* harmony import */ var _shared_navigator__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../shared/navigator */ "./lib/src/shared/navigator.js");
40049
+ /* harmony import */ var _shared_navigator__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../shared/navigator */ "./lib/src/shared/navigator.js");
40050
+ /* harmony import */ var _worker_sync_AbstractSharedSyncClientProvider__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../worker/sync/AbstractSharedSyncClientProvider */ "./lib/src/worker/sync/AbstractSharedSyncClientProvider.js");
40051
+ /* harmony import */ var _worker_sync_SharedSyncImplementation__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../worker/sync/SharedSyncImplementation */ "./lib/src/worker/sync/SharedSyncImplementation.js");
40052
+ /* harmony import */ var _adapters_web_sql_flags__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../adapters/web-sql-flags */ "./lib/src/db/adapters/web-sql-flags.js");
40053
+ /* harmony import */ var _WebStreamingSyncImplementation__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./WebStreamingSyncImplementation */ "./lib/src/db/sync/WebStreamingSyncImplementation.js");
40054
40054
 
40055
40055
 
40056
40056
 
@@ -40061,7 +40061,7 @@ __webpack_require__.r(__webpack_exports__);
40061
40061
  * The shared worker will trigger methods on this side of the message port
40062
40062
  * via this client provider.
40063
40063
  */
40064
- class SharedSyncClientProvider extends _worker_sync_AbstractSharedSyncClientProvider__WEBPACK_IMPORTED_MODULE_1__.AbstractSharedSyncClientProvider {
40064
+ class SharedSyncClientProvider extends _worker_sync_AbstractSharedSyncClientProvider__WEBPACK_IMPORTED_MODULE_2__.AbstractSharedSyncClientProvider {
40065
40065
  options;
40066
40066
  statusChanged;
40067
40067
  webDB;
@@ -40132,7 +40132,7 @@ class SharedSyncClientProvider extends _worker_sync_AbstractSharedSyncClientProv
40132
40132
  /**
40133
40133
  * The local part of the sync implementation on the web, which talks to a sync implementation hosted in a shared worker.
40134
40134
  */
40135
- class SharedWebStreamingSyncImplementation extends _WebStreamingSyncImplementation__WEBPACK_IMPORTED_MODULE_4__.WebStreamingSyncImplementation {
40135
+ class SharedWebStreamingSyncImplementation extends _WebStreamingSyncImplementation__WEBPACK_IMPORTED_MODULE_5__.WebStreamingSyncImplementation {
40136
40136
  syncManager;
40137
40137
  clientProvider;
40138
40138
  messagePort;
@@ -40148,10 +40148,10 @@ class SharedWebStreamingSyncImplementation extends _WebStreamingSyncImplementati
40148
40148
  */
40149
40149
  const resolvedWorkerOptions = {
40150
40150
  dbFilename: this.options.identifier,
40151
- temporaryStorage: _adapters_web_sql_flags__WEBPACK_IMPORTED_MODULE_3__.TemporaryStorageOption.MEMORY,
40152
- cacheSizeKb: _adapters_web_sql_flags__WEBPACK_IMPORTED_MODULE_3__.DEFAULT_CACHE_SIZE_KB,
40151
+ temporaryStorage: _adapters_web_sql_flags__WEBPACK_IMPORTED_MODULE_4__.TemporaryStorageOption.MEMORY,
40152
+ cacheSizeKb: _adapters_web_sql_flags__WEBPACK_IMPORTED_MODULE_4__.DEFAULT_CACHE_SIZE_KB,
40153
40153
  ...options,
40154
- flags: (0,_adapters_web_sql_flags__WEBPACK_IMPORTED_MODULE_3__.resolveWebSQLFlags)(options.flags)
40154
+ flags: (0,_adapters_web_sql_flags__WEBPACK_IMPORTED_MODULE_4__.resolveWebSQLFlags)(options.flags)
40155
40155
  };
40156
40156
  const syncWorker = options.sync?.worker;
40157
40157
  if (syncWorker) {
@@ -40183,6 +40183,19 @@ class SharedWebStreamingSyncImplementation extends _WebStreamingSyncImplementati
40183
40183
  */
40184
40184
  const { crudUploadThrottleMs, identifier, retryDelayMs } = this.options;
40185
40185
  const flags = { ...this.webOptions.flags, workers: undefined };
40186
+ // Request a random lock until this client is disposed. The name of the lock is sent to the shared worker, which
40187
+ // will also attempt to acquire it. Since the lock is returned when the tab is closed, this allows the share worker
40188
+ // to free resources associated with this tab.
40189
+ // We take hold of this lock as soon-as-possible in order to cater for potentially closed tabs.
40190
+ (0,_shared_navigator__WEBPACK_IMPORTED_MODULE_1__.getNavigatorLocks)().request(`tab-close-signal-${crypto.randomUUID()}`, async (lock) => {
40191
+ if (!this.abortOnClose.signal.aborted) {
40192
+ // Awaiting here ensures the worker is waiting for the lock
40193
+ await this.syncManager.addLockBasedCloseSignal(lock.name);
40194
+ await new Promise((r) => {
40195
+ this.abortOnClose.signal.onabort = () => r();
40196
+ });
40197
+ }
40198
+ });
40186
40199
  this.isInitialized = this.syncManager.setParams({
40187
40200
  dbParams: this.dbAdapter.getConfiguration(),
40188
40201
  streamOptions: {
@@ -40204,17 +40217,6 @@ class SharedWebStreamingSyncImplementation extends _WebStreamingSyncImplementati
40204
40217
  * This performs bi-directional method calling.
40205
40218
  */
40206
40219
  comlink__WEBPACK_IMPORTED_MODULE_0__.expose(this.clientProvider, this.messagePort);
40207
- // Request a random lock until this client is disposed. The name of the lock is sent to the shared worker, which
40208
- // will also attempt to acquire it. Since the lock is returned when the tab is closed, this allows the share worker
40209
- // to free resources associated with this tab.
40210
- (0,_shared_navigator__WEBPACK_IMPORTED_MODULE_5__.getNavigatorLocks)().request(`tab-close-signal-${crypto.randomUUID()}`, async (lock) => {
40211
- if (!this.abortOnClose.signal.aborted) {
40212
- this.syncManager.addLockBasedCloseSignal(lock.name);
40213
- await new Promise((r) => {
40214
- this.abortOnClose.signal.onabort = () => r();
40215
- });
40216
- }
40217
- });
40218
40220
  }
40219
40221
  /**
40220
40222
  * Starts the sync process, this effectively acts as a call to
@@ -40242,13 +40244,13 @@ class SharedWebStreamingSyncImplementation extends _WebStreamingSyncImplementati
40242
40244
  // Listen for the close acknowledgment from the worker
40243
40245
  this.messagePort.addEventListener('message', (event) => {
40244
40246
  const payload = event.data;
40245
- if (payload?.event === _worker_sync_SharedSyncImplementation__WEBPACK_IMPORTED_MODULE_2__.SharedSyncClientEvent.CLOSE_ACK) {
40247
+ if (payload?.event === _worker_sync_SharedSyncImplementation__WEBPACK_IMPORTED_MODULE_3__.SharedSyncClientEvent.CLOSE_ACK) {
40246
40248
  resolve();
40247
40249
  }
40248
40250
  });
40249
40251
  // Signal the shared worker that this client is closing its connection to the worker
40250
40252
  const closeMessagePayload = {
40251
- event: _worker_sync_SharedSyncImplementation__WEBPACK_IMPORTED_MODULE_2__.SharedSyncClientEvent.CLOSE_CLIENT,
40253
+ event: _worker_sync_SharedSyncImplementation__WEBPACK_IMPORTED_MODULE_3__.SharedSyncClientEvent.CLOSE_CLIENT,
40252
40254
  data: {}
40253
40255
  };
40254
40256
  this.messagePort.postMessage(closeMessagePayload);
@@ -40955,6 +40957,20 @@ class SharedSyncImplementation extends _powersync_common__WEBPACK_IMPORTED_MODUL
40955
40957
  }
40956
40958
  });
40957
40959
  const shouldReconnect = !!this.connectionManager.syncStreamImplementation && this.ports.length > 0;
40960
+ /**
40961
+ * If the current database adapter is the one that is being closed, we need to disconnect from the backend.
40962
+ * We can disconnect in the portMutex lock. This ensures the disconnect is not affected by potential other
40963
+ * connect operations coming from other tabs.
40964
+ */
40965
+ if (this.dbAdapter && this.dbAdapter == trackedPort.db) {
40966
+ this.logger.debug(`Disconnecting due to closed database: should reconnect: ${shouldReconnect}`);
40967
+ this.dbAdapter = null;
40968
+ // Unconditionally close the connection because the database it's writing to has just been closed.
40969
+ // The connection has been closed previously, this might throw. We should be able to ignore it.
40970
+ await this.connectionManager
40971
+ .disconnect()
40972
+ .catch((ex) => this.logger.warn('Error while disconnecting. Will attempt to reconnect.', ex));
40973
+ }
40958
40974
  return {
40959
40975
  shouldReconnect,
40960
40976
  trackedPort
@@ -40967,17 +40983,8 @@ class SharedSyncImplementation extends _powersync_common__WEBPACK_IMPORTED_MODUL
40967
40983
  for (const closeListener of trackedPort.closeListeners) {
40968
40984
  await closeListener();
40969
40985
  }
40970
- if (this.dbAdapter && this.dbAdapter == trackedPort.db) {
40971
- // Unconditionally close the connection because the database it's writing to has just been closed.
40972
- // The connection has been closed previously, this might throw. We should be able to ignore it.
40973
- await this.connectionManager
40974
- .disconnect()
40975
- .catch((ex) => this.logger.warn('Error while disconnecting. Will attempt to reconnect.', ex));
40976
- // Clearing the adapter will result in a new one being opened in connect
40977
- this.dbAdapter = null;
40978
- if (shouldReconnect) {
40979
- await this.connectionManager.connect(CONNECTOR_PLACEHOLDER, this.lastConnectOptions ?? {});
40980
- }
40986
+ if (shouldReconnect) {
40987
+ await this.connectionManager.connect(CONNECTOR_PLACEHOLDER, this.lastConnectOptions ?? {});
40981
40988
  }
40982
40989
  // Re-index subscriptions, the subscriptions of the removed port would no longer be considered.
40983
40990
  this.collectActiveSubscriptions();
@@ -41103,6 +41110,11 @@ class SharedSyncImplementation extends _powersync_common__WEBPACK_IMPORTED_MODUL
41103
41110
  });
41104
41111
  lastClient.closeListeners.push(async () => {
41105
41112
  this.logger.info('Aborting open connection because associated tab closed.');
41113
+ /**
41114
+ * Don't await this close operation. It might never resolve if the tab is closed.
41115
+ * We run the close operation first, before marking the remote as closed. This gives the database some chance
41116
+ * to close the connection.
41117
+ */
41106
41118
  wrapped.close().catch((ex) => this.logger.warn('error closing database connection', ex));
41107
41119
  wrapped.markRemoteClosed();
41108
41120
  });