refactoring of database.service + fixes

This commit is contained in:
NicolasCantu 2025-02-11 23:31:09 +01:00
parent 8fbcb769d6
commit 8d267f5b12

View File

@ -111,23 +111,29 @@ export class Database {
return objectList; return objectList;
} }
private createMessageChannel(responseHandler: (event: MessageEvent) => void): MessageChannel { private async initServiceWorker() {
const messageChannel = new MessageChannel(); if (!('serviceWorker' in navigator)) return; // Ensure service workers are supported
messageChannel.port1.onmessage = responseHandler;
return messageChannel; 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.');
} }
private async initServiceWorker() { // Now check the messageChannel to avoid unnecessary reinitialization
if (this.messageChannel) { if (this.messageChannel) {
console.log('Persistent update channel already initialized.'); console.log('Persistent update channel already initialized.');
return; return;
} }
if ('serviceWorker' in navigator) {
try { // Register the new service worker
const registration = await navigator.serviceWorker.register('/src/service-workers/database.worker.js', { type: 'module' }); const registration = await navigator.serviceWorker.register('/src/service-workers/database.worker.js', { type: 'module' });
console.log('Service Worker registered with scope:', registration.scope); console.log('Service Worker registered with scope:', registration.scope);
this.serviceWorkerRegistration = registration this.serviceWorkerRegistration = registration;
await this.checkForUpdates(); await this.checkForUpdates();
// Set up the message channels // Set up the message channels
@ -135,17 +141,34 @@ export class Database {
this.messageChannelForGet = new MessageChannel(); this.messageChannelForGet = new MessageChannel();
this.messageChannel.port1.onmessage = this.handleAddObjectResponse; this.messageChannel.port1.onmessage = this.handleAddObjectResponse;
this.messageChannelForGet.port1.onmessage = this.handleGetObjectResponse; this.messageChannelForGet.port1.onmessage = this.handleGetObjectResponse;
registration.active?.postMessage(
{ // Ensure the new service worker is activated before sending messages
type: 'START', const activeWorker = registration.active || (await this.waitForServiceWorkerActivation(registration));
},
activeWorker?.postMessage(
{ type: 'START' },
[this.messageChannel.port2], [this.messageChannel.port2],
); );
// Optionally, initialize service worker with some data
} catch (error) { } catch (error) {
console.error('Service Worker registration failed:', error); console.error('Service Worker registration failed:', error);
} }
} }
// Helper function to wait for service worker activation
private async waitForServiceWorkerActivation(registration: ServiceWorkerRegistration): Promise<ServiceWorker | null> {
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() { private async checkForUpdates() {
@ -172,16 +195,23 @@ export class Database {
service.setNotifications(data.data); service.setNotifications(data.data);
} else if (data.type === 'TO_DOWNLOAD') { } else if (data.type === 'TO_DOWNLOAD') {
// Download the missing data // Download the missing data
for (const hash in data.data) { for (const hash of data.data) {
try { try {
const value = await service.fetchValueFromStorage(hash); const value = await service.fetchValueFromStorage(hash);
if (value) {
// Save data to db // Save data to db
const blob = new Blob([value], {type: "text/plain"}); const blob = new Blob([value], {type: "text/plain"});
await service.saveDataToDb(hash, blob); await service.saveBlobToDb(hash, blob);
} else {
// We first request the data from managers
console.log('Request data from managers of the process');
}
} catch (e) { } catch (e) {
console.error(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<void> { public updateMyProcesses(myProcessesId: string[]): Promise<void> {
return new Promise((resolve, reject) => { if (myProcessesId.length === 0) {
// Check if the service worker is active
if (!this.serviceWorkerRegistration?.active) {
reject(new Error('Service worker is not active'));
return; 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 // Create a message channel for communication
const messageChannel = new MessageChannel(); const messageChannel = new MessageChannel();
@ -247,8 +281,9 @@ export class Database {
}; };
try { try {
const payload = { myProcessesId };
console.log('Sending UPDATE_PROCESSES msg with payload', payload); console.log('Sending UPDATE_PROCESSES msg with payload', payload);
this.serviceWorkerRegistration.active.postMessage( activeWorker?.postMessage(
{ {
type: 'UPDATE_PROCESSES', type: 'UPDATE_PROCESSES',