diff --git a/src/services/database.service.ts b/src/services/database.service.ts index 340616b..27ccf3f 100755 --- a/src/services/database.service.ts +++ b/src/services/database.service.ts @@ -111,23 +111,29 @@ export class Database { return objectList; } - private createMessageChannel(responseHandler: (event: MessageEvent) => void): MessageChannel { - const messageChannel = new MessageChannel(); - messageChannel.port1.onmessage = responseHandler; - return messageChannel; - } - private async initServiceWorker() { - if (this.messageChannel) { - console.log('Persistent update channel already initialized.'); - return; - } - if ('serviceWorker' in navigator) { - try { + if (!('serviceWorker' in navigator)) return; // Ensure service workers are supported + + try { + // Get existing service worker registrations + const registrations = await navigator.serviceWorker.getRegistrations(); + if (registrations.length > 0) { + console.log('Existing Service Worker(s) detected. Unregistering...'); + await Promise.all(registrations.map(reg => reg.unregister())); + console.log('All previous Service Workers unregistered.'); + } + + // Now check the messageChannel to avoid unnecessary reinitialization + if (this.messageChannel) { + console.log('Persistent update channel already initialized.'); + return; + } + + // Register the new service worker const registration = await navigator.serviceWorker.register('/src/service-workers/database.worker.js', { type: 'module' }); console.log('Service Worker registered with scope:', registration.scope); - this.serviceWorkerRegistration = registration + this.serviceWorkerRegistration = registration; await this.checkForUpdates(); // Set up the message channels @@ -135,19 +141,36 @@ export class Database { this.messageChannelForGet = new MessageChannel(); this.messageChannel.port1.onmessage = this.handleAddObjectResponse; this.messageChannelForGet.port1.onmessage = this.handleGetObjectResponse; - registration.active?.postMessage( - { - type: 'START', - }, - [this.messageChannel.port2], + + // Ensure the new service worker is activated before sending messages + const activeWorker = registration.active || (await this.waitForServiceWorkerActivation(registration)); + + activeWorker?.postMessage( + { type: 'START' }, + [this.messageChannel.port2], ); - // Optionally, initialize service worker with some data - } catch (error) { + } catch (error) { console.error('Service Worker registration failed:', error); - } } } + // Helper function to wait for service worker activation + private async waitForServiceWorkerActivation(registration: ServiceWorkerRegistration): Promise { + return new Promise((resolve) => { + if (registration.active) { + resolve(registration.active); + } else { + const listener = () => { + if (registration.active) { + navigator.serviceWorker.removeEventListener('controllerchange', listener); + resolve(registration.active); + } + }; + navigator.serviceWorker.addEventListener('controllerchange', listener); + } + }); + } + private async checkForUpdates() { if (this.serviceWorkerRegistration) { // Check for updates to the service worker @@ -172,16 +195,23 @@ export class Database { service.setNotifications(data.data); } else if (data.type === 'TO_DOWNLOAD') { // Download the missing data - for (const hash in data.data) { + for (const hash of data.data) { try { const value = await service.fetchValueFromStorage(hash); - // Save data to db - const blob = new Blob([value], {type: "text/plain"}); - await service.saveDataToDb(hash, blob); + if (value) { + // Save data to db + const blob = new Blob([value], {type: "text/plain"}); + await service.saveBlobToDb(hash, blob); + } else { + // We first request the data from managers + console.log('Request data from managers of the process'); + } } catch (e) { console.error(e); } } + // try to update list of my processes + await service.getMyProcesses(); } }; @@ -225,14 +255,18 @@ export class Database { }); } - public updateMyProcesses(payload: { myProcessesId: string[] }): Promise { - return new Promise((resolve, reject) => { - // Check if the service worker is active - if (!this.serviceWorkerRegistration?.active) { - reject(new Error('Service worker is not active')); - return; + public updateMyProcesses(myProcessesId: string[]): Promise { + if (myProcessesId.length === 0) { + return; + } + + return new Promise(async (resolve, reject) => { + if (!this.serviceWorkerRegistration) { + // console.warn('Service worker registration is not ready. Waiting...'); + this.serviceWorkerRegistration = await navigator.serviceWorker.ready; } + const activeWorker = await this.waitForServiceWorkerActivation(this.serviceWorkerRegistration); // Create a message channel for communication const messageChannel = new MessageChannel(); @@ -247,8 +281,9 @@ export class Database { }; try { + const payload = { myProcessesId }; console.log('Sending UPDATE_PROCESSES msg with payload', payload); - this.serviceWorkerRegistration.active.postMessage( + activeWorker?.postMessage( { type: 'UPDATE_PROCESSES',