// MyDay service worker (SPEC-009 §6, register A5). // // THE RULE: cache STATIC ASSETS ONLY. An authenticated response and a /{GUID} // page are NEVER cached — and not merely "not cached": such a request is not // intercepted by this worker at all, so it cannot reach a cache. Offline is // explicitly out of scope. // // CACHEABLE_PREFIXES is kept in step with web.StaticCachePrefixes (Go) by // TestAC5_ServiceWorkerPolicy — there is no second, drifting copy of the rule. "use strict"; var CACHEABLE_PREFIXES = ["/static/"]; var CACHE_NAME = "myday-static-v1"; // isCacheable is the single gate: GET · same origin · a static asset. function isCacheable(request) { if (request.method !== "GET") { return false; } var url = new URL(request.url); if (url.origin !== self.location.origin) { return false; } for (var i = 0; i < CACHEABLE_PREFIXES.length; i++) { if (url.pathname.indexOf(CACHEABLE_PREFIXES[i]) === 0) { return true; } } return false; } self.addEventListener("install", function (event) { // Nothing is precached (offline is out of scope) — just take over. event.waitUntil(self.skipWaiting()); }); self.addEventListener("activate", function (event) { event.waitUntil( caches .keys() .then(function (keys) { return Promise.all( keys .filter(function (key) { return key !== CACHE_NAME; }) .map(function (key) { return caches.delete(key); }) ); }) .then(function () { return self.clients.claim(); }) ); }); self.addEventListener("fetch", function (event) { // Anything that is not a static asset is NOT intercepted: an authenticated // response can never be read from — or written to — a cache (A5). if (!isCacheable(event.request)) { return; } event.respondWith( caches.open(CACHE_NAME).then(function (cache) { return cache.match(event.request).then(function (hit) { if (hit) { return hit; } return fetch(event.request).then(function (response) { if (response && response.ok && response.type === "basic") { cache.put(event.request, response.clone()); } return response; }); }); }) ); });