/** * quicprochat Service Worker — provides offline caching and background * notification support for the PWA. */ const CACHE_NAME = "qpq-cache-v1"; const STATIC_ASSETS = [ "/", "/index.html", "/style.css", "/app.js", "/manifest.json", ]; // Install: cache static assets. self.addEventListener("install", (event) => { event.waitUntil( caches.open(CACHE_NAME).then((cache) => cache.addAll(STATIC_ASSETS)), ); self.skipWaiting(); }); // Activate: clean up old caches. 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(); }); // Fetch: serve from cache, fall back to network. self.addEventListener("fetch", (event) => { // Only cache GET requests for same-origin resources. if (event.request.method !== "GET") return; event.respondWith( caches.match(event.request).then((cached) => { if (cached) return cached; return fetch(event.request).then((response) => { // Cache successful same-origin responses. if ( response.ok && new URL(event.request.url).origin === self.location.origin ) { const clone = response.clone(); caches.open(CACHE_NAME).then((cache) => { cache.put(event.request, clone); }); } return response; }); }), ); }); // Push notifications (future: wired to server push events). self.addEventListener("push", (event) => { if (!event.data) return; let payload; try { payload = event.data.json(); } catch { payload = { title: "quicprochat", body: event.data.text() }; } event.waitUntil( self.registration.showNotification(payload.title || "quicprochat", { body: payload.body || "New message", icon: "/icon-192.png", badge: "/icon-192.png", tag: payload.conversationId || "default", }), ); }); // Notification click: open the app. self.addEventListener("notificationclick", (event) => { event.notification.close(); event.waitUntil( self.clients .matchAll({ type: "window" }) .then((clients) => { if (clients.length > 0) { return clients[0].focus(); } return self.clients.openWindow("/"); }), ); });