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;
}
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<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() {
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<void> {
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<void> {
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',