// Everclone PWA Service Worker (v1.1.0) const CACHE_NAME = 'everclone-cache-v2'; const PRECACHE_URLS = [ '/', '/manifest.json', '/icon.svg', '/icon-192.png', '/icon-512.png', '/apple-touch-icon.png' ]; self.addEventListener('install', (event) => { event.waitUntil( caches.open(CACHE_NAME).then((cache) => { return cache.addAll(PRECACHE_URLS).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! // This ensures Android Web Share Target multipart POSTs stream directly to /api/hooks/note if (event.request.method !== 'GET') { return; } const url = new URL(event.request.url); // Bypass API endpoints, hooks, and share endpoint to always get fresh data if (url.pathname.startsWith('/api/') || url.pathname === '/share') { return; } // Network-first strategy for navigation and static assets with cache fallback event.respondWith( 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(() => { return caches.match(event.request).then((cachedResponse) => { if (cachedResponse) { return cachedResponse; } if (event.request.mode === 'navigate') { return caches.match('/'); } return new Response('Network error occurred', { status: 503, statusText: 'Offline' }); }); }) ); });