1const CACHE_NAME = 'bhargavachary-v1.0.1'; // Incremented to bust cache for theme toggle fix 2const OFFLINE_URL = '/offline.html'; 3 4// Files to cache for offline functionality 5const CACHE_FILES = [ 6 '/', 7 '/assets/css/app.css', 8 '/assets/js/app.js', 9 '/images/avatar.jpg', 10 OFFLINE_URL 11]; 12 13// Install event - cache essential files 14self.addEventListener('install', (event) => { 15 console.log('Service Worker: Installing...'); 16 17 event.waitUntil( 18 caches.open(CACHE_NAME) 19 .then((cache) => { 20 console.log('Service Worker: Caching essential files'); 21 return cache.addAll(CACHE_FILES); 22 }) 23 .then(() => { 24 // Take control immediately 25 return self.skipWaiting(); 26 }) 27 .catch((err) => { 28 console.error('Service Worker: Cache failed:', err); 29 }) 30 ); 31}); 32 33// Activate event - clean up old caches 34self.addEventListener('activate', (event) => { 35 console.log('Service Worker: Activating...'); 36 37 event.waitUntil( 38 caches.keys() 39 .then((cacheNames) => { 40 return Promise.all( 41 cacheNames.map((cacheName) => { 42 if (cacheName !== CACHE_NAME) { 43 console.log('Service Worker: Deleting old cache:', cacheName); 44 return caches.delete(cacheName); 45 } 46 }) 47 ); 48 }) 49 .then(() => { 50 // Take control of all pages 51 return self.clients.claim(); 52 }) 53 ); 54}); 55 56// Fetch event - implement caching strategies 57self.addEventListener('fetch', (event) => { 58 // Only handle GET requests 59 if (event.request.method !== 'GET') return; 60 61 // Skip cross-origin requests 62 if (!event.request.url.startsWith(self.location.origin)) return; 63 64 event.respondWith( 65 (async () => { 66 try { 67 // Try network first for HTML pages 68 if (event.request.headers.get('accept').includes('text/html')) { 69 return await networkFirstStrategy(event.request); 70 } 71 72 // Cache first for assets (CSS, JS, images) 73 if (event.request.url.includes('/assets/') || 74 event.request.url.includes('/images/')) { 75 return await cacheFirstStrategy(event.request); 76 } 77 78 // Network first for other requests 79 return await networkFirstStrategy(event.request); 80 81 } catch (err) { 82 console.error('Service Worker: Fetch failed:', err); 83 84 // Return offline page for navigation requests 85 if (event.request.mode === 'navigate') { 86 return caches.match(OFFLINE_URL); 87 } 88 89 // Return cached version if available 90 return caches.match(event.request); 91 } 92 })() 93 ); 94}); 95 96// Network first strategy (good for HTML pages) 97async function networkFirstStrategy(request) { 98 try { 99 const networkResponse = await fetch(request); 100 101 // Cache successful responses 102 if (networkResponse.ok) { 103 const cache = await caches.open(CACHE_NAME); 104 cache.put(request, networkResponse.clone()); 105 } 106 107 return networkResponse; 108 } catch (err) { 109 // Fall back to cache 110 const cachedResponse = await caches.match(request); 111 if (cachedResponse) { 112 return cachedResponse; 113 } 114 throw err; 115 } 116} 117 118// Cache first strategy (good for assets) 119async function cacheFirstStrategy(request) { 120 const cachedResponse = await caches.match(request); 121 122 if (cachedResponse) { 123 // Update cache in background 124 updateCacheInBackground(request); 125 return cachedResponse; 126 } 127 128 // Not in cache, fetch from network 129 const networkResponse = await fetch(request); 130 131 if (networkResponse.ok) { 132 const cache = await caches.open(CACHE_NAME); 133 cache.put(request, networkResponse.clone()); 134 } 135 136 return networkResponse; 137} 138 139// Update cache in background 140async function updateCacheInBackground(request) { 141 try { 142 const networkResponse = await fetch(request); 143 if (networkResponse.ok) { 144 const cache = await caches.open(CACHE_NAME); 145 cache.put(request, networkResponse); 146 } 147 } catch (err) { 148 // Silently fail background updates
149 console.log('Background cache update failed:', err); 150 } 151} 152 153// Background sync for offline actions 154self.addEventListener('sync', (event) => { 155 if (event.tag === 'background-sync') { 156 event.waitUntil( 157 // Handle background sync tasks 158 console.log('Service Worker: Background sync triggered') 159 ); 160 } 161}); 162 163// Push notification support 164self.addEventListener('push', (event) => { 165 const options = { 166 body: event.data ? event.data.text() : 'New content available!', 167 icon: '/images/avatar.jpg', 168 badge: '/images/avatar.jpg', 169 data: { 170 url: '/' 171 } 172 }; 173 174 event.waitUntil( 175 self.registration.showNotification('BhargavAchary.in', options) 176 ); 177}); 178 179// Handle notification clicks 180self.addEventListener('notificationclick', (event) => { 181 event.notification.close(); 182 183 event.waitUntil( 184 clients.openWindow(event.notification.data.url || '/') 185 ); 186}); 187 188// Performance monitoring 189self.addEventListener('message', (event) => { 190 if (event.data && event.data.type === 'PERFORMANCE_METRICS') { 191 // Handle performance metrics from main thread 192 console.log('Performance metrics received:', event.data.metrics); 193 } 194});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.