File size: 3,409 Bytes
3a08226 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | 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));
}
}); |