PageSourceSearch

https://bhargavachary.in/sw.js

js bhargavachary.in collected 2026-09-28 07:13:32 UTC 5,228 bytes, 194 lines download raw bytes

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.