importation JS to TS changed
This commit is contained in:
parent
60b49a65e5
commit
c0f8cc537c
@ -1,24 +1,73 @@
|
|||||||
let processesToScan = new Set();
|
declare var self: ServiceWorkerGlobalScope;
|
||||||
let toDownload = new Set();
|
|
||||||
|
|
||||||
self.addEventListener('install', (event) => {
|
// Interfaces
|
||||||
event.waitUntil(self.skipWaiting()); // Activate worker immediately
|
interface Process {
|
||||||
|
states: State[];
|
||||||
|
merkle_root: string;
|
||||||
|
key: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface State {
|
||||||
|
state_id: string;
|
||||||
|
commited_in: string;
|
||||||
|
merkle_root: string;
|
||||||
|
pcd_commitment?: {
|
||||||
|
[key: string]: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Diff {
|
||||||
|
process_id: string;
|
||||||
|
state_id: string;
|
||||||
|
value_commitment: string;
|
||||||
|
field: string;
|
||||||
|
description: string | null;
|
||||||
|
previous_value: any;
|
||||||
|
new_value: any;
|
||||||
|
notify_user: boolean;
|
||||||
|
need_validation: boolean;
|
||||||
|
validation_status: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ProcessWithDiffs {
|
||||||
|
process: State[];
|
||||||
|
processId: string;
|
||||||
|
diffs: Diff[][];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface MessagePayload {
|
||||||
|
myProcessesId?: string[];
|
||||||
|
storeName?: string;
|
||||||
|
object?: any;
|
||||||
|
key?: IDBValidKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface MessageEvent {
|
||||||
|
type: string;
|
||||||
|
payload?: MessagePayload;
|
||||||
|
}
|
||||||
|
|
||||||
|
let processesToScan: Set<string> = new Set();
|
||||||
|
let toDownload: Set<string> = new Set();
|
||||||
|
|
||||||
|
self.addEventListener('install', (event: ExtendableEvent) => {
|
||||||
|
event.waitUntil(self.skipWaiting());
|
||||||
});
|
});
|
||||||
|
|
||||||
self.addEventListener('activate', (event) => {
|
self.addEventListener('activate', (event: ExtendableEvent) => {
|
||||||
event.waitUntil(self.clients.claim()); // Become available to all pages
|
event.waitUntil(self.clients.claim());
|
||||||
});
|
});
|
||||||
|
|
||||||
// Event listener for messages from clients
|
self.addEventListener('message', async (event: ExtendableMessageEvent) => {
|
||||||
self.addEventListener('message', async (event) => {
|
const data = event.data as MessageEvent;
|
||||||
const data = event.data;
|
|
||||||
if (data.type === 'START') {
|
if (data.type === 'START') {
|
||||||
const fetchNotifications = async () => {
|
processesToScan.clear();
|
||||||
|
const fetchNotifications = async (): Promise<void> => {
|
||||||
const itemsWithFlag = await getAllDiffsNeedValidation();
|
const itemsWithFlag = await getAllDiffsNeedValidation();
|
||||||
|
|
||||||
// Process items with the specific flag
|
|
||||||
itemsWithFlag?.forEach((item) => {
|
itemsWithFlag?.forEach((item) => {
|
||||||
console.log(item); // Do something with each flagged item
|
console.log(item);
|
||||||
});
|
});
|
||||||
|
|
||||||
event.ports[0].postMessage({
|
event.ports[0].postMessage({
|
||||||
@ -26,28 +75,23 @@ self.addEventListener('message', async (event) => {
|
|||||||
data: itemsWithFlag,
|
data: itemsWithFlag,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
const scanMissingData = async () => {
|
|
||||||
|
const scanMissingData = async (): Promise<void> => {
|
||||||
console.log('Scanning for missing data...');
|
console.log('Scanning for missing data...');
|
||||||
const myProcesses = await getProcesses(processesToScan);
|
const myProcesses = await getProcesses(processesToScan);
|
||||||
|
|
||||||
// Iterate on each process
|
if (myProcesses && myProcesses.length !== 0) {
|
||||||
if (myProcesses && myProcesses.length != 0) {
|
|
||||||
for (const process of myProcesses) {
|
for (const process of myProcesses) {
|
||||||
// Iterate on states
|
|
||||||
const firstState = process.states[0];
|
const firstState = process.states[0];
|
||||||
const processId = firstState.commited_in;
|
const processId = firstState.commited_in;
|
||||||
for (const state of process.states) {
|
for (const state of process.states) {
|
||||||
if (!state.pcd_commitment) continue;
|
if (!state.pcd_commitment) continue;
|
||||||
// iterate on pcd_commitment
|
|
||||||
for (const [field, hash] of Object.entries(state.pcd_commitment)) {
|
for (const [field, hash] of Object.entries(state.pcd_commitment)) {
|
||||||
// Check if we have the data in db
|
|
||||||
const existingData = await getBlob(hash);
|
const existingData = await getBlob(hash);
|
||||||
if (!existingData) {
|
if (!existingData) {
|
||||||
toDownload.add(hash);
|
toDownload.add(hash);
|
||||||
// We also add an entry in diff, in case it doesn't already exist
|
await addDiff(processId, state.state_id, hash, field);
|
||||||
await addDiff(processId, state.state_id, hash, field)
|
|
||||||
} else {
|
} else {
|
||||||
// We remove it if we have it in the set
|
|
||||||
if (toDownload.delete(hash)) {
|
if (toDownload.delete(hash)) {
|
||||||
console.log(`Removing ${hash} from the set`);
|
console.log(`Removing ${hash} from the set`);
|
||||||
}
|
}
|
||||||
@ -57,13 +101,14 @@ self.addEventListener('message', async (event) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (toDownload.size != 0) {
|
if (toDownload.size !== 0) {
|
||||||
event.ports[0].postMessage({
|
event.ports[0].postMessage({
|
||||||
type: 'TO_DOWNLOAD',
|
type: 'TO_DOWNLOAD',
|
||||||
data: Array.from(toDownload),
|
data: Array.from(toDownload),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
fetchNotifications();
|
fetchNotifications();
|
||||||
setInterval(fetchNotifications, 2 * 60 * 1000);
|
setInterval(fetchNotifications, 2 * 60 * 1000);
|
||||||
scanMissingData();
|
scanMissingData();
|
||||||
@ -72,24 +117,26 @@ self.addEventListener('message', async (event) => {
|
|||||||
|
|
||||||
if (data.type === 'UPDATE_PROCESSES') {
|
if (data.type === 'UPDATE_PROCESSES') {
|
||||||
try {
|
try {
|
||||||
const { myProcessesId } = data.payload;
|
const { myProcessesId } = data.payload || {};
|
||||||
console.log(myProcessesId);
|
console.log(myProcessesId);
|
||||||
if (myProcessesId && myProcessesId.length != 0) {
|
if (myProcessesId && myProcessesId.length !== 0) {
|
||||||
for (const processId of myProcessesId) {
|
for (const processId of myProcessesId) {
|
||||||
processesToScan.add(processId);
|
processesToScan.add(processId);
|
||||||
}
|
}
|
||||||
console.log(processesToScan);
|
console.log(processesToScan);
|
||||||
} else {
|
} else {
|
||||||
event.ports[0].postMessage({ status: 'error', message: 'Empty lists' });
|
event.ports[0].postMessage({ status: 'error', message: 'Empty lists' });
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
event.ports[0].postMessage({ status: 'error', message: error.message });
|
event.ports[0].postMessage({ status: 'error', message: (error as Error).message });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.type === 'ADD_OBJECT') {
|
if (data.type === 'ADD_OBJECT') {
|
||||||
try {
|
try {
|
||||||
const { storeName, object, key } = data.payload;
|
const { storeName, object, key } = data.payload || {};
|
||||||
|
if (!storeName) throw new Error('Store name is required');
|
||||||
|
|
||||||
const db = await openDatabase();
|
const db = await openDatabase();
|
||||||
const tx = db.transaction(storeName, 'readwrite');
|
const tx = db.transaction(storeName, 'readwrite');
|
||||||
const store = tx.objectStore(storeName);
|
const store = tx.objectStore(storeName);
|
||||||
@ -102,22 +149,25 @@ self.addEventListener('message', async (event) => {
|
|||||||
|
|
||||||
event.ports[0].postMessage({ status: 'success', message: '' });
|
event.ports[0].postMessage({ status: 'success', message: '' });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
event.ports[0].postMessage({ status: 'error', message: error.message });
|
event.ports[0].postMessage({ status: 'error', message: (error as Error).message });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
async function openDatabase() {
|
async function openDatabase(): Promise<IDBDatabase> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const request = indexedDB.open('4nk', 1);
|
const request = indexedDB.open('4nk', 1);
|
||||||
request.onerror = (event) => {
|
|
||||||
|
request.onerror = () => {
|
||||||
reject(request.error);
|
reject(request.error);
|
||||||
};
|
};
|
||||||
request.onsuccess = (event) => {
|
|
||||||
|
request.onsuccess = () => {
|
||||||
resolve(request.result);
|
resolve(request.result);
|
||||||
};
|
};
|
||||||
request.onupgradeneeded = (event) => {
|
|
||||||
const db = event.target.result;
|
request.onupgradeneeded = (event: IDBVersionChangeEvent) => {
|
||||||
|
const db = (event.target as IDBOpenDBRequest).result;
|
||||||
if (!db.objectStoreNames.contains('wallet')) {
|
if (!db.objectStoreNames.contains('wallet')) {
|
||||||
db.createObjectStore('wallet', { keyPath: 'pre_id' });
|
db.createObjectStore('wallet', { keyPath: 'pre_id' });
|
||||||
}
|
}
|
||||||
@ -125,8 +175,7 @@ async function openDatabase() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function to get all processes because it is asynchronous
|
async function getAllProcesses(): Promise<Process[]> {
|
||||||
async function getAllProcesses() {
|
|
||||||
const db = await openDatabase();
|
const db = await openDatabase();
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (!db) {
|
if (!db) {
|
||||||
@ -145,10 +194,10 @@ async function getAllProcesses() {
|
|||||||
reject(request.error);
|
reject(request.error);
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
async function getProcesses(processIds) {
|
async function getProcesses(processIds: Set<string>): Promise<Process[]> {
|
||||||
if (!processIds || processIds.length === 0) {
|
if (!processIds || processIds.size === 0) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,34 +210,33 @@ async function getProcesses(processIds) {
|
|||||||
const store = tx.objectStore('processes');
|
const store = tx.objectStore('processes');
|
||||||
|
|
||||||
const requests = Array.from(processIds).map((processId) => {
|
const requests = Array.from(processIds).map((processId) => {
|
||||||
return new Promise((resolve) => {
|
return new Promise<Process | undefined>((resolve) => {
|
||||||
const request = store.get(processId);
|
const request = store.get(processId);
|
||||||
request.onsuccess = () => resolve(request.result);
|
request.onsuccess = () => resolve(request.result);
|
||||||
request.onerror = () => {
|
request.onerror = () => {
|
||||||
console.error(`Error fetching process ${processId}:`, request.error);
|
console.error(`Error fetching process ${processId}:`, request.error);
|
||||||
resolve(undefined);
|
resolve(undefined);
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
const results = await Promise.all(requests);
|
const results = await Promise.all(requests);
|
||||||
return results.filter(result => result !== undefined);
|
return results.filter((result): result is Process => result !== undefined);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getAllDiffsNeedValidation() {
|
async function getAllDiffsNeedValidation(): Promise<ProcessWithDiffs[]> {
|
||||||
const db = await openDatabase();
|
const db = await openDatabase();
|
||||||
|
|
||||||
const allProcesses = await getAllProcesses();
|
const allProcesses = await getAllProcesses();
|
||||||
const tx = db.transaction('diffs', 'readonly');
|
const tx = db.transaction('diffs', 'readonly');
|
||||||
const store = tx.objectStore('diffs');
|
const store = tx.objectStore('diffs');
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const request = store.getAll();
|
const request = store.getAll();
|
||||||
request.onsuccess = (event) => {
|
request.onsuccess = (event: Event) => {
|
||||||
const allItems = event.target.result;
|
const allItems = (event.target as IDBRequest).result as Diff[];
|
||||||
const itemsWithFlag = allItems.filter((item) => item.need_validation);
|
const itemsWithFlag = allItems.filter((item) => item.need_validation);
|
||||||
|
|
||||||
const processMap = {};
|
const processMap: { [key: string]: { process: State[]; processId: string; diffs: Diff[]; } } = {};
|
||||||
|
|
||||||
for (const diff of itemsWithFlag) {
|
for (const diff of itemsWithFlag) {
|
||||||
const currentProcess = allProcesses.find((item) => {
|
const currentProcess = allProcesses.find((item) => {
|
||||||
@ -210,11 +258,11 @@ async function getAllDiffsNeedValidation() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const results = Object.values(processMap).map((entry) => {
|
const results = Object.values(processMap).map((entry) => {
|
||||||
const diffs = []
|
const diffs: Diff[][] = [];
|
||||||
for(const state of entry.process) {
|
for(const state of entry.process) {
|
||||||
const filteredDiff = entry.diffs.filter(diff => diff.new_state_merkle_root === state.merkle_root);
|
const filteredDiff = entry.diffs.filter(diff => diff.new_state_merkle_root === state.merkle_root);
|
||||||
if(filteredDiff && filteredDiff.length) {
|
if(filteredDiff && filteredDiff.length) {
|
||||||
diffs.push(filteredDiff)
|
diffs.push(filteredDiff);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
@ -227,44 +275,43 @@ async function getAllDiffsNeedValidation() {
|
|||||||
resolve(results);
|
resolve(results);
|
||||||
};
|
};
|
||||||
|
|
||||||
request.onerror = (event) => {
|
request.onerror = (event: Event) => {
|
||||||
reject(event.target.error);
|
reject((event.target as IDBRequest).error);
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getBlob(hash) {
|
async function getBlob(hash: string): Promise<any> {
|
||||||
const db = await openDatabase();
|
const db = await openDatabase();
|
||||||
const storeName = 'data';
|
const storeName = 'data';
|
||||||
const tx = db.transaction(storeName, 'readonly');
|
const tx = db.transaction(storeName, 'readonly');
|
||||||
const store = tx.objectStore(storeName);
|
const store = tx.objectStore(storeName);
|
||||||
const result = await new Promise((resolve, reject) => {
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
const getRequest = store.get(hash);
|
const getRequest = store.get(hash);
|
||||||
getRequest.onsuccess = () => resolve(getRequest.result);
|
getRequest.onsuccess = () => resolve(getRequest.result);
|
||||||
getRequest.onerror = () => reject(getRequest.error);
|
getRequest.onerror = () => reject(getRequest.error);
|
||||||
});
|
});
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function addDiff(processId, stateId, hash) {
|
async function addDiff(processId: string, stateId: string, hash: string, field: string): Promise<IDBValidKey> {
|
||||||
const db = await openDatabase();
|
const db = await openDatabase();
|
||||||
const storeName = 'diffs';
|
const storeName = 'diffs';
|
||||||
const tx = db.transaction(storeName, 'readwrite');
|
const tx = db.transaction(storeName, 'readwrite');
|
||||||
const store = tx.objectStore(storeName);
|
const store = tx.objectStore(storeName);
|
||||||
|
|
||||||
// Check if the diff already exists
|
const existingDiff = await new Promise<Diff | undefined>((resolve, reject) => {
|
||||||
const existingDiff = await new Promise((resolve, reject) => {
|
|
||||||
const getRequest = store.get(hash);
|
const getRequest = store.get(hash);
|
||||||
getRequest.onsuccess = () => resolve(getRequest.result);
|
getRequest.onsuccess = () => resolve(getRequest.result);
|
||||||
getRequest.onerror = () => reject(getRequest.error);
|
getRequest.onerror = () => reject(getRequest.error);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!existingDiff) {
|
if (!existingDiff) {
|
||||||
const newDiff = {
|
const newDiff: Diff = {
|
||||||
process_id: processId,
|
process_id: processId,
|
||||||
state_id: stateId,
|
state_id: stateId,
|
||||||
value_commitment: hash,
|
value_commitment: hash,
|
||||||
field: '',
|
field: field,
|
||||||
description: null,
|
description: null,
|
||||||
previous_value: null,
|
previous_value: null,
|
||||||
new_value: null,
|
new_value: null,
|
||||||
@ -273,13 +320,11 @@ async function addDiff(processId, stateId, hash) {
|
|||||||
validation_status: 'None'
|
validation_status: 'None'
|
||||||
};
|
};
|
||||||
|
|
||||||
const insertResult = await new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const putRequest = store.put(newDiff);
|
const putRequest = store.put(newDiff);
|
||||||
putRequest.onsuccess = () => resolve(putRequest.result);
|
putRequest.onsuccess = () => resolve(putRequest.result);
|
||||||
putRequest.onerror = () => reject(putRequest.error);
|
putRequest.onerror = () => reject(putRequest.error);
|
||||||
});
|
});
|
||||||
|
|
||||||
return insertResult;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return existingDiff;
|
return existingDiff;
|
@ -119,7 +119,7 @@ export class Database {
|
|||||||
const registrations = await navigator.serviceWorker.getRegistrations();
|
const registrations = await navigator.serviceWorker.getRegistrations();
|
||||||
if (registrations.length === 0) {
|
if (registrations.length === 0) {
|
||||||
// No existing workers: register a new one.
|
// No existing workers: register a new one.
|
||||||
this.serviceWorkerRegistration = await navigator.serviceWorker.register('/src/service-workers/database.worker.js', { type: 'module' });
|
this.serviceWorkerRegistration = await navigator.serviceWorker.register('/src/service-workers/database.worker.ts', { type: 'module' });
|
||||||
console.log('Service Worker registered with scope:', registration.scope);
|
console.log('Service Worker registered with scope:', registration.scope);
|
||||||
} else if (registrations.length === 1) {
|
} else if (registrations.length === 1) {
|
||||||
// One existing worker: update it (restart it) without unregistering.
|
// One existing worker: update it (restart it) without unregistering.
|
||||||
@ -131,7 +131,7 @@ export class Database {
|
|||||||
console.log('Multiple Service Worker(s) detected. Unregistering all...');
|
console.log('Multiple Service Worker(s) detected. Unregistering all...');
|
||||||
await Promise.all(registrations.map(reg => reg.unregister()));
|
await Promise.all(registrations.map(reg => reg.unregister()));
|
||||||
console.log('All previous Service Workers unregistered.');
|
console.log('All previous Service Workers unregistered.');
|
||||||
this.serviceWorkerRegistration = await navigator.serviceWorker.register('/src/service-workers/database.worker.js', { type: 'module' });
|
this.serviceWorkerRegistration = await navigator.serviceWorker.register('/src/service-workers/database.worker.ts', { type: 'module' });
|
||||||
console.log('Service Worker registered with scope:', registration.scope);
|
console.log('Service Worker registered with scope:', registration.scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user