// Everclone PWA Service Worker (v2.0.0) const CACHE_NAME = 'everclone-cache-v3'; const STATIC_ASSETS = [ '/', '/manifest.json', '/icon-192.png', '/icon-512.png', '/icon-maskable-192.png', '/icon-maskable-512.png', '/apple-touch-icon.png', '/icon.svg' ]; self.addEventListener('install', (event) => { event.waitUntil( caches.open(CACHE_NAME).then((cache) => { return cache.addAll(STATIC_ASSETS).catch(() => {}); }) ); self.skipWaiting(); }); self.addEventListener('activate', (event) => { event.waitUntil( caches.keys().then((keys) => { return Promise.all( keys.filter((key) => key !== CACHE_NAME).map((key) => caches.delete(key)) ); }) ); self.clients.claim(); }); self.addEventListener('fetch', (event) => { // CRITICAL: Never intercept POST/PUT/DELETE requests! if (event.request.method !== 'GET') { return; } const url = new URL(event.request.url); // Bypass API endpoints and share endpoint if (url.pathname.startsWith('/api/') || url.pathname.startsWith('/share')) { return; } // For page navigations (including share target queries like /?url=... or /?noteId=...) if (event.request.mode === 'navigate') { event.respondWith( fetch(event.request).catch(() => { return caches.match('/'); }) ); return; } // Stale-while-revalidate for static assets event.respondWith( caches.match(event.request).then((cachedResponse) => { const fetchPromise = fetch(event.request) .then((networkResponse) => { if ( networkResponse && networkResponse.status === 200 && (url.pathname === '/' || url.pathname.startsWith('/_next/static/')) ) { const responseClone = networkResponse.clone(); caches.open(CACHE_NAME).then((cache) => { cache.put(event.request, responseClone); }); } return networkResponse; }) .catch(() => cachedResponse); return cachedResponse || fetchPromise; }) ); });