const CACHE_NAME = 'archdroid-v1'; const PARALLEL_WORKERS = [ '/workers/settings-worker.js', '/workers/app-data-worker.js', '/workers/gesture-worker.js', '/workers/notification-worker.js', '/workers/system-sync-worker.js' ]; const STATIC_ASSETS = [ '/', '/index.html', '/style.css', '/script.js', '/components/arch-status-bar.js', '/components/arch-app-icon.js', '/components/arch-app-grid.js', '/components/arch-app-drawer.js', '/components/arch-server-panel.js', '/components/arch-settings-panel.js', '/components/arch-notifications.js' ]; // Install: Cache static assets self.addEventListener('install', (event) => { event.waitUntil( caches.open(CACHE_NAME).then((cache) => { return cache.addAll(STATIC_ASSETS); }) ); self.skipWaiting(); }); // Activate: Clean old caches self.addEventListener('activate', (event) => { event.waitUntil( caches.keys().then((cacheNames) => { return Promise.all( cacheNames .filter((name) => name !== CACHE_NAME) .map((name) => caches.delete(name)) ); }) ); self.clients.claim(); }); // Message handling from main thread self.addEventListener('message', async (event) => { const { type, payload } = event.data; switch (type) { case 'SYNC_SETTINGS': await syncSettings(event.source.id); break; case 'FETCH_APPS': await fetchAppsParallel(event.source.id); break; case 'REQUEST_PERMISSION': await handlePermission(payload); break; } }); // Parallel settings sync async function syncSettings(clientId) { const settings = await Promise.all([ fetch('/api/android/settings/display').catch(() => null), fetch('/api/android/settings/sound').catch(() => null), fetch('/api/android/settings/notifications').catch(() => null), fetch('/api/android/settings/accessibility').catch(() => null) ]); const client = await self.clients.get(clientId); if (client) { client.postMessage({ type: 'SETTINGS_SYNCED', payload: { display: settings[0], sound: settings[1], notifications: settings[2], accessibility: settings[3] } }); } } // Parallel app data fetching with worker pool async function fetchAppsParallel(clientId) { const channels = ['system', 'user', 'disabled', 'work']; const results = await Promise.all(channels.map(channel => fetch(`/api/android/apps/${channel}`).catch(() => []) )); const allApps = results.flat(); const client = await self.clients.get(clientId); if (client) { client.postMessage({ type: 'APPS_FETCHED', payload: allApps }); } } // Fetch strategy with network first, cache fallback self.addEventListener('fetch', (event) => { event.respondWith( fetch(event.request) .then((response) => { // Cache successful responses if (response.ok) { const clone = response.clone(); caches.open(CACHE_NAME).then((cache) => { cache.put(event.request, clone); }); } return response; }) .catch(() => { // Fallback to cache return caches.match(event.request); }) ); }); // Background sync for settings self.addEventListener('sync', (event) => { if (event.tag === 'settings-sync') { event.waitUntil(syncSettings(self.clients.matchAll()[0]?.id)); } });