// hidden11 service worker. // // Scope is deliberately narrow: it exists to deliver the daily reminder, not to // cache the app. The push messages are sent WITHOUT a payload (the sender only // needs a VAPID header, no content encryption), so the notification copy is // written into the Cache API when the user subscribes and read back here — a // service worker cannot reach localStorage. const MESSAGE_CACHE = "hidden11-push"; const MESSAGE_KEY = "/__push-message"; const FALLBACK = { title: "hidden11", body: "Today's hidden XI is live.", url: "/", }; async function reminderMessage() { try { const cache = await caches.open(MESSAGE_CACHE); const stored = await cache.match(MESSAGE_KEY); if (!stored) return FALLBACK; const data = await stored.json(); return { title: data.title || FALLBACK.title, body: data.body || FALLBACK.body, url: data.url || FALLBACK.url, }; } catch { return FALLBACK; } } self.addEventListener("install", () => { self.skipWaiting(); }); self.addEventListener("activate", (event) => { event.waitUntil(self.clients.claim()); }); self.addEventListener("push", (event) => { event.waitUntil( (async () => { const message = await reminderMessage(); await self.registration.showNotification(message.title, { body: message.body, icon: "/icon-192.png", badge: "/icon-192.png", tag: "hidden11-daily", renotify: true, data: { url: message.url }, }); })(), ); }); self.addEventListener("notificationclick", (event) => { event.notification.close(); const target = event.notification.data?.url || FALLBACK.url; event.waitUntil( (async () => { const allClients = await self.clients.matchAll({ type: "window", includeUncontrolled: true }); const existing = allClients.find((client) => client.url.includes(self.location.origin)); if (existing) { await existing.focus(); if ("navigate" in existing) await existing.navigate(target); return; } await self.clients.openWindow(target); })(), ); });