diff --git a/apps/web/src/common/sqlite/shared-service.ts b/apps/web/src/common/sqlite/shared-service.ts index d79a7bdcb..b2c610d0b 100644 --- a/apps/web/src/common/sqlite/shared-service.ts +++ b/apps/web/src/common/sqlite/shared-service.ts @@ -83,7 +83,7 @@ export class SharedService extends EventTarget { } activate( - portProviderFunc: () => MessagePort | Promise, + portProviderFunc: () => Promise<{ port: MessagePort; onclose: () => void }>, onClientConnected: () => Promise ) { if (this.#onDeactivate) return; @@ -97,7 +97,7 @@ export class SharedService extends EventTarget { navigator.locks .request(LOCK_NAME, { signal: this.#onDeactivate.signal }, async () => { // Get the port to request client ports. - const port = await portProviderFunc(); + const { port, onclose } = await portProviderFunc(); port.start(); // Listen for client requests. A separate BroadcastChannel @@ -159,6 +159,7 @@ export class SharedService extends EventTarget { // Release the lock only on user abort or context destruction. return new Promise((_, reject) => { this.#onDeactivate?.signal.addEventListener("abort", () => { + onclose(); broadcastChannel.close(); reject(this.#onDeactivate?.signal.reason); }); diff --git a/apps/web/src/common/sqlite/sqlite.worker.ts b/apps/web/src/common/sqlite/sqlite.worker.ts index c4f253836..5354c222f 100644 --- a/apps/web/src/common/sqlite/sqlite.worker.ts +++ b/apps/web/src/common/sqlite/sqlite.worker.ts @@ -233,6 +233,8 @@ addEventListener("message", async (event) => { await worker.open(event.data.dbName, event.data.async, event.data.uri); const providerPort = createSharedServicePort(worker); postMessage(null, [providerPort]); + + self.addEventListener("beforeunload", () => worker.close()); } }); diff --git a/apps/web/src/common/sqlite/wa-sqlite-kysely-driver.ts b/apps/web/src/common/sqlite/wa-sqlite-kysely-driver.ts index d6766ed65..4c6bda569 100644 --- a/apps/web/src/common/sqlite/wa-sqlite-kysely-driver.ts +++ b/apps/web/src/common/sqlite/wa-sqlite-kysely-driver.ts @@ -72,14 +72,18 @@ export class WaSqliteWorkerDriver implements Driver { service.activate( () => - new Promise((resolve) => { + new Promise<{ port: MessagePort; onclose: () => void }>((resolve) => { console.log("initializing worker"); this.needsInitialization = true; const worker = new Worker(); worker.addEventListener( "message", - (event) => resolve(event.ports[0]), + (event) => + resolve({ + port: event.ports[0], + onclose: () => worker.terminate() + }), { once: true } ); worker.postMessage({