Service worker fixes

This commit is contained in:
Christian Semmler 2025-07-18 08:20:05 -07:00
parent a9f3940e22
commit 05b6e93d13
No known key found for this signature in database
GPG Key ID: 086DAA1360BEEE5C
2 changed files with 53 additions and 42 deletions

20
app.js
View File

@ -362,8 +362,10 @@ document.addEventListener('DOMContentLoaded', function () {
progressCircular.className = 'progress-circular'; progressCircular.className = 'progress-circular';
controlsContainer.appendChild(progressCircular); controlsContainer.appendChild(progressCircular);
installBtn.addEventListener('click', () => { installBtn.addEventListener('click', async () => {
if (navigator.serviceWorker.controller) { if (navigator.serviceWorker && navigator.serviceWorker.controller) {
await requestPersistentStorage();
const selectedLanguage = languageSelect.value; const selectedLanguage = languageSelect.value;
installBtn.style.display = 'none'; installBtn.style.display = 'none';
uninstallBtn.style.display = 'none'; uninstallBtn.style.display = 'none';
@ -390,6 +392,20 @@ document.addEventListener('DOMContentLoaded', function () {
checkInitialCacheStatus(); checkInitialCacheStatus();
}); });
async function requestPersistentStorage() {
if (navigator.storage && navigator.storage.persist) {
const isPersisted = await navigator.storage.persisted();
if (!isPersisted) {
const wasGranted = await navigator.storage.persist();
if (wasGranted) {
console.log('Persistent storage was granted.');
} else {
console.log('Persistent storage request was denied.');
}
}
}
}
function checkInitialCacheStatus() { function checkInitialCacheStatus() {
if (navigator.serviceWorker.controller) { if (navigator.serviceWorker.controller) {
const selectedLanguage = languageSelect.value; const selectedLanguage = languageSelect.value;

75
sw.js
View File

@ -13,9 +13,9 @@ const coreAppFiles = [
'/', '/index.html', '/cancel_off.webp', '/cancel_on.webp', '/cdspin.gif', '/', '/index.html', '/cancel_off.webp', '/cancel_on.webp', '/cdspin.gif',
'/configure_off.webp', '/configure_on.webp', '/favicon.png', '/favicon.svg', '/configure_off.webp', '/configure_on.webp', '/favicon.png', '/favicon.svg',
'/free_stuff_off.webp', '/free_stuff_on.webp', '/install_off.webp', '/install_on.webp', '/free_stuff_off.webp', '/free_stuff_on.webp', '/install_off.webp', '/install_on.webp',
'/island.webp', '/isle.js', '/isle.wasm', '/poster.pdf', '/read_me_off.webp', '/island.webp', '/isle.js', '/isle.wasm', '/poster.pdf', '/read_me_off.webp',
'/read_me_on.webp', '/run_game_off.webp', '/run_game_on.webp', '/shark.webp', '/read_me_on.webp', '/run_game_off.webp', '/run_game_on.webp', '/shark.webp',
'/uninstall_off.webp', '/uninstall_on.webp', 'app.js', 'style.css', 'manifest.json' '/uninstall_off.webp', '/uninstall_on.webp', '/app.js', '/style.css', '/manifest.json'
]; ];
const gameFiles = [ const gameFiles = [
@ -45,6 +45,7 @@ self.addEventListener('install', (event) => {
}); });
}) })
); );
self.skipWaiting();
}); });
registerRoute( registerRoute(
@ -131,43 +132,36 @@ async function installLanguagePack(language, client) {
for (const file of fileMetadata) { for (const file of fileMetadata) {
const request = new Request(file.url, { headers: { 'Accept-Language': language } }); const request = new Request(file.url, { headers: { 'Accept-Language': language } });
const response = await fetch(request);
try { if (!response.ok || !response.body) {
const response = await fetch(request); throw new Error(`Failed to fetch ${file.url}`);
if (!response.ok || !response.body) {
throw new Error(`Failed to fetch ${file.url}`);
}
const [streamForCaching, streamForProgress] = response.body.tee();
const responseToCache = new Response(streamForCaching, response);
const cachePromise = cache.put(request, responseToCache);
const reader = streamForProgress.getReader();
while (true) {
const { done, value } = await reader.read();
if (done) break;
bytesDownloaded += value.length;
const now = Date.now();
if (now - lastProgressUpdate > THROTTLE_MS) {
lastProgressUpdate = now;
client.postMessage({
action: 'install_progress',
progress: (bytesDownloaded / totalBytesToDownload) * 100,
language: language
});
}
}
await cachePromise;
} catch (error) {
console.error("Aborting installation due to a persistent error:", error);
await caches.delete(cacheName);
client.postMessage({ action: 'install_failed', language: language });
} }
const [streamForCaching, streamForProgress] = response.body.tee();
const responseToCache = new Response(streamForCaching, response);
const cachePromise = cache.put(request, responseToCache);
const reader = streamForProgress.getReader();
while (true) {
const { done, value } = await reader.read();
if (done) break;
bytesDownloaded += value.length;
const now = Date.now();
if (now - lastProgressUpdate > THROTTLE_MS) {
lastProgressUpdate = now;
client.postMessage({
action: 'install_progress',
progress: (bytesDownloaded / totalBytesToDownload) * 100,
language: language
});
}
}
await cachePromise;
} }
client.postMessage({ client.postMessage({
@ -177,8 +171,9 @@ async function installLanguagePack(language, client) {
}); });
client.postMessage({ action: 'install_complete', success: true, language: language }); client.postMessage({ action: 'install_complete', success: true, language: language });
} catch (error) { } catch (error) {
console.error('Error during language pack installation:', error); console.error("Aborting installation due to an error:", error);
client.postMessage({ action: 'install_failed', success: false, language: language, error: error.message }); await caches.delete(cacheName);
client.postMessage({ action: 'install_failed', language: language });
} }
} }
@ -214,5 +209,5 @@ self.addEventListener('activate', (event) => {
); );
}) })
); );
self.clients.claim(); event.waitUntil(self.clients.claim());
}); });