const CACHE_NAME = "espj-upst-pwa-v2"; const OFFLINE_URL = "/driver/offline.html"; const PRECACHE_URLS = [ "/upst", "/upst/kosong", "/driver/manifest.json", "/driver/favicon.ico", "/driver/images/pwa_192.png", "/driver/images/pwa_512.png", OFFLINE_URL ]; self.addEventListener("install", (event) => { event.waitUntil( caches.open(CACHE_NAME).then(async (cache) => { const results = await Promise.allSettled( PRECACHE_URLS.map(async (url) => { const response = await fetch(url, { cache: "no-store" }); if (!response.ok) { throw new Error(`Gagal precache: ${url} (${response.status})`); } await cache.put(url, response.clone()); }) ); const offlineCached = results.some( (result, index) => PRECACHE_URLS[index] === OFFLINE_URL && result.status === "fulfilled" ); if (!offlineCached) { throw new Error(`Offline page gagal diprecache: ${OFFLINE_URL}`); } }) ); self.skipWaiting(); }); self.addEventListener("activate", (event) => { event.waitUntil( caches.keys().then((keys) => Promise.all( keys .filter((key) => key !== CACHE_NAME) .map((key) => caches.delete(key)) ) ) ); self.clients.claim(); }); const AUTH_PATHS = [ "/signin-oidc", "/signout-callback-oidc", "/signout-oidc", "/connect/", "/Identity/", "/.well-known/", ]; function isAuthPath(url) { return AUTH_PATHS.some((path) => url.pathname.startsWith(path)); } const BYPASS_CACHE_PATHS = [ "/upst/detail-penjemputan/api/", "/uploads/penjemputan/", "/driver/json/" ]; function shouldBypassCache(url) { return BYPASS_CACHE_PATHS.some((path) => url.pathname.startsWith(path)); } self.addEventListener("fetch", (event) => { const { request } = event; const url = new URL(request.url); if (request.method !== "GET") { return; } if (url.origin !== self.location.origin) { return; } if (isAuthPath(url)) { return; } if (shouldBypassCache(url)) { event.respondWith( fetch(new Request(request, { cache: "no-store" })).catch(async () => { if (request.mode === "navigate") { return (await caches.match(OFFLINE_URL)) || Response.error(); } return Response.error(); }) ); return; } if (request.mode === "navigate") { event.respondWith( fetch(request) .then((response) => { if (url.pathname.startsWith("/upst")) { const responseClone = response.clone(); caches.open(CACHE_NAME).then((cache) => cache.put(request, responseClone)); } return response; }) .catch(async () => { const cachedPage = await caches.match(request); return cachedPage || (await caches.match(OFFLINE_URL)) || Response.error(); }) ); return; } if (url.origin !== self.location.origin) { return; } event.respondWith( caches.match(request).then((cachedResponse) => { const networkFetch = fetch(request) .then((response) => { if (response && response.ok) { const responseClone = response.clone(); caches.open(CACHE_NAME).then((cache) => cache.put(request, responseClone)); } return response; }) .catch(() => cachedResponse); return cachedResponse || networkFetch; }) ); });