@powersync/web 1.14.2 → 1.15.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.
@@ -562,8 +562,10 @@ __webpack_require__.r(__webpack_exports__);
562
562
  */
563
563
  class WorkerWrappedAsyncDatabaseConnection {
564
564
  options;
565
+ lockAbortController;
565
566
  constructor(options) {
566
567
  this.options = options;
568
+ this.lockAbortController = new AbortController();
567
569
  }
568
570
  get baseConnection() {
569
571
  return this.options.baseConnection;
@@ -576,6 +578,38 @@ class WorkerWrappedAsyncDatabaseConnection {
576
578
  */
577
579
  async shareConnection() {
578
580
  const { identifier, remote } = this.options;
581
+ /**
582
+ * Hold a navigator lock in order to avoid features such as Chrome's frozen tabs,
583
+ * or Edge's sleeping tabs from pausing the thread for this connection.
584
+ * This promise resolves once a lock is obtained.
585
+ * This lock will be held as long as this connection is open.
586
+ * The `shareConnection` method should not be called on multiple tabs concurrently.
587
+ */
588
+ await new Promise((resolve, reject) => navigator.locks
589
+ .request(`shared-connection-${this.options.identifier}`, {
590
+ signal: this.lockAbortController.signal
591
+ }, async () => {
592
+ resolve();
593
+ // Free the lock when the connection is already closed.
594
+ if (this.lockAbortController.signal.aborted) {
595
+ return;
596
+ }
597
+ // Hold the lock while the shared connection is in use.
598
+ await new Promise((releaseLock) => {
599
+ this.lockAbortController.signal.addEventListener('abort', () => {
600
+ releaseLock();
601
+ });
602
+ });
603
+ })
604
+ // We aren't concerned with abort errors here
605
+ .catch((ex) => {
606
+ if (ex.name == 'AbortError') {
607
+ resolve();
608
+ }
609
+ else {
610
+ reject(ex);
611
+ }
612
+ }));
579
613
  const newPort = await remote[comlink__WEBPACK_IMPORTED_MODULE_0__.createEndpoint]();
580
614
  return { port: newPort, identifier };
581
615
  }
@@ -587,6 +621,8 @@ class WorkerWrappedAsyncDatabaseConnection {
587
621
  return this.baseConnection.registerOnTableChange(comlink__WEBPACK_IMPORTED_MODULE_0__.proxy(callback));
588
622
  }
589
623
  async close() {
624
+ // Abort any pending lock requests.
625
+ this.lockAbortController.abort();
590
626
  await this.baseConnection.close();
591
627
  this.options.remote[comlink__WEBPACK_IMPORTED_MODULE_0__.releaseProxy]();
592
628
  this.options.onClose?.();