// Worker Bridge - Manages parallel workers for ArchDroid class WorkerBridge { constructor() { this.workers = new Map(); this.messageQueue = []; this.callbacks = new Map(); this.callbackId = 0; this.initWorkers(); this.setupServiceWorker(); } initWorkers() { const workerConfigs = [ { name: 'settings', url: 'workers/settings-worker.js' }, { name: 'apps', url: 'workers/app-data-worker.js' }, { name: 'gestures', url: 'workers/gesture-worker.js' }, { name: 'notifications', url: 'workers/notification-worker.js' }, { name: 'system', url: 'workers/system-sync-worker.js' } ]; workerConfigs.forEach(({ name, url }) => { try { const worker = new Worker(url); worker.onmessage = (e) => this.handleWorkerMessage(name, e.data); worker.onerror = (e) => console.error(`Worker ${name} error:`, e); this.workers.set(name, worker); } catch (err) { console.warn(`Failed to create worker ${name}:`, err); } }); } async setupServiceWorker() { if ('serviceWorker' in navigator) { try { const reg = await navigator.serviceWorker.register('/sw.js'); console.log('SW registered:', reg); navigator.serviceWorker.addEventListener('message', (e) => { this.handleServiceWorkerMessage(e.data); }); // Request background sync if ('sync' in reg) { await reg.sync.register('settings-sync'); } } catch (err) { console.error('SW registration failed:', err); } } } postToWorker(workerName, message, transferables = []) { const worker = this.workers.get(workerName); if (!worker) { console.warn(`Worker ${workerName} not available`); return Promise.reject(new Error('Worker not available')); } return new Promise((resolve) => { const id = ++this.callbackId; this.callbacks.set(id, resolve); worker.postMessage({ ...message, _callbackId: id, _workerName: workerName }, transferables); }); } handleWorkerMessage(workerName, data) { // Resolve pending callback if exists if (data._callbackId) { const callback = this.callbacks.get(data._callbackId); if (callback) { callback(data); this.callbacks.delete(data._callbackId); return; } } // Broadcast to window const event = new CustomEvent(`worker:${workerName}`, { detail: data }); window.dispatchEvent(event); // Also dispatch to specific handlers this.routeWorkerMessage(workerName, data); } routeWorkerMessage(workerName, data) { switch (workerName) { case 'settings': window.dispatchEvent(new CustomEvent('settings-updated', { detail: data })); break; case 'apps': window.dispatchEvent(new CustomEvent('apps-loaded', { detail: data })); break; case 'gestures': window.dispatchEvent(new CustomEvent('gesture', { detail: data.gesture })); break; case 'notifications': window.dispatchEvent(new CustomEvent('notifications-updated', { detail: data })); break; case 'system': window.dispatchEvent(new CustomEvent('system-status', { detail: data })); break; } } handleServiceWorkerMessage(data) { window.dispatchEvent(new CustomEvent('sw-message', { detail: data })); } // Public API methods async fetchSettings() { return this.postToWorker('settings', { action: 'READ_ALL' }); } async watchSetting(key) { this.postToWorker('settings', { action: 'WATCH', settings: { key } }); } async fetchApps() { return this.postToWorker('apps', { action: 'FETCH_ALL' }); } async searchApps(query) { return this.postToWorker('apps', { action: 'SEARCH', filter: { query } }); } async launchApp(packageName) { return this.postToWorker('apps', { action: 'LAUNCH_APP', filter: { package: packageName } }); } processGesture(type, event) { this.postToWorker('gestures', { type, event }); } async fetchNotifications() { return this.postToWorker('notifications', { action: 'FETCH' }); } clearNotification(id) { this.postToWorker('notifications', { action: 'CLEAR', data: { id } }); } startSystemSync() { this.postToWorker('system', { action: 'START_SYNC' }); } stopSystemSync() { this.postToWorker('system', { action: 'STOP_SYNC' }); } } // Initialize bridge window.workerBridge = new WorkerBridge();