const EMPTY32BYTES = String('').padStart(64, '0'); self.addEventListener('install', (event) => { event.waitUntil(self.skipWaiting()); // Activate worker immediately }); self.addEventListener('activate', (event) => { event.waitUntil(self.clients.claim()); // Become available to all pages }); // Event listener for messages from clients self.addEventListener('message', async (event) => { const data = event.data; console.log(data); if (data.type === 'SCAN') { try { const myProcessesId = data.payload; if (myProcessesId && myProcessesId.length != 0) { const toDownload = await scanMissingData(myProcessesId); if (toDownload.length != 0) { console.log('Sending TO_DOWNLOAD message'); event.source.postMessage({ type: 'TO_DOWNLOAD', data: toDownload}); } } else { event.source.postMessage({ status: 'error', message: 'Empty lists' }); } } catch (error) { event.source.postMessage({ status: 'error', message: error.message }); } } else if (data.type === 'ADD_OBJECT') { try { const { storeName, object, key } = data.payload; const db = await openDatabase(); const tx = db.transaction(storeName, 'readwrite'); const store = tx.objectStore(storeName); if (key) { await store.put(object, key); } else { await store.put(object); } event.ports[0].postMessage({ status: 'success', message: '' }); } catch (error) { event.ports[0].postMessage({ status: 'error', message: error.message }); } } else if (data.type === 'BATCH_WRITING') { const { storeName, objects } = data.payload; const db = await openDatabase(); const tx = db.transaction(storeName, 'readwrite'); const store = tx.objectStore(storeName); for (const { key, object } of objects) { if (key) { await store.put(object, key); } else { await store.put(object); } } await tx.done; } }); async function scanMissingData(processesToScan) { console.log('Scanning for missing data...'); const myProcesses = await getProcesses(processesToScan); let toDownload = new Set(); // Iterate on each process if (myProcesses && myProcesses.length != 0) { for (const process of myProcesses) { // Iterate on states const firstState = process.states[0]; const processId = firstState.commited_in; for (const state of process.states) { if (state.state_id === EMPTY32BYTES) continue; // iterate on pcd_commitment for (const [field, hash] of Object.entries(state.pcd_commitment)) { // Skip public fields if (state.public_data[field] !== undefined || field === 'roles') continue; // Check if we have the data in db const existingData = await getBlob(hash); if (!existingData) { toDownload.add(hash); // We also add an entry in diff, in case it doesn't already exist await addDiff(processId, state.state_id, hash, state.roles, field); } else { // We remove it if we have it in the set if (toDownload.delete(hash)) { console.log(`Removing ${hash} from the set`); } } } } } } console.log('[Service Worker] Scan complete:', { toDownload: toDownload.size, diffsToCreate: diffsToCreate.length }); return { toDownload: Array.from(toDownload), diffsToCreate: diffsToCreate }; }