/// const CACHE_NAME = 'wolfpack-v1'; const STATIC_ASSETS = [ '/', '/index.html', '/manifest.json' ]; const API_CACHE = 'wolfpack-api-v1'; const API_CACHE_MAX_AGE = 5 * 60 * 1000; // 5 minutes declare const self: ServiceWorkerGlobalScope; // Install event - cache static assets self.addEventListener('install', (event) => { event.waitUntil( caches.open(CACHE_NAME).then((cache) => { console.log('[SW] Caching static assets'); return cache.addAll(STATIC_ASSETS); }) ); self.skipWaiting(); }); // Activate event - clean old caches self.addEventListener('activate', (event) => { event.waitUntil( caches.keys().then((cacheNames) => { return Promise.all( cacheNames .filter((name) => name !== CACHE_NAME && name !== API_CACHE) .map((name) => caches.delete(name)) ); }) ); self.clients.claim(); }); // Fetch event - network-first for API, cache-first for assets self.addEventListener('fetch', (event) => { const { request } = event; const url = new URL(request.url); // Skip non-GET requests if (request.method !== 'GET') return; // API requests - network first, fallback to cache if (url.pathname.startsWith('/api')) { event.respondWith(networkFirstWithCache(request)); return; } // Static assets - cache first, fallback to network event.respondWith(cacheFirstWithNetwork(request)); }); async function networkFirstWithCache(request: Request): Promise { try { const response = await fetch(request); // Cache successful GET responses if (response.ok) { const cache = await caches.open(API_CACHE); cache.put(request, response.clone()); } return response; } catch (error) { // Network failed, try cache const cached = await caches.match(request); if (cached) { console.log('[SW] Serving from cache:', request.url); return cached; } // Return offline response for API return new Response( JSON.stringify({ error: 'You are offline', offline: true }), { status: 503, headers: { 'Content-Type': 'application/json' } } ); } } async function cacheFirstWithNetwork(request: Request): Promise { const cached = await caches.match(request); if (cached) { return cached; } try { const response = await fetch(request); // Cache successful responses if (response.ok) { const cache = await caches.open(CACHE_NAME); cache.put(request, response.clone()); } return response; } catch (error) { // Return offline page for navigation requests if (request.mode === 'navigate') { const offlinePage = await caches.match('/'); if (offlinePage) return offlinePage; } throw error; } } // Background sync for offline actions self.addEventListener('sync', (event) => { if (event.tag === 'sync-touchpoints') { event.waitUntil(syncTouchpoints()); } }); async function syncTouchpoints() { // This would sync any queued offline actions console.log('[SW] Syncing offline actions...'); } // Push notifications self.addEventListener('push', (event) => { if (!event.data) return; const data = event.data.json(); event.waitUntil( self.registration.showNotification(data.title || '777 Wolfpack', { body: data.body, icon: '/icon-192.png', badge: '/badge-72.png', tag: data.tag || 'notification', data: data.url }) ); }); self.addEventListener('notificationclick', (event) => { event.notification.close(); if (event.notification.data) { event.waitUntil( self.clients.openWindow(event.notification.data) ); } }); export { };