1'use strict'; 2 3// Increment this manually or with build time if needed 4const CACHE_NAME = 'armenia.travel-cache-pwa' + new Date().getTime(); 5const OFFLINE_URL = '/offline.html'; 6 7// URLs we want to pre-cache for offline mode 8const FILES_TO_CACHE = ['/', OFFLINE_URL]; 9 10// URLs we never want to cache (dynamic build assets, manifest) 11const NEVER_CACHE = ['/_next/static/', '/manifest.json', '/manifest.js']; 12 13// ---------------------------------------------------------------------- 14// ð INSTALL 15self.addEventListener('install', (event) => { 16 console.log('[Armenia Travel PWA] Installing new service worker...'); 17 18 event.waitUntil( 19 caches.open(CACHE_NAME).then(async (cache) => { 20 console.log('[Armenia Travel PWA] Caching offline essentials...'); 21 try { 22 await Promise.all( 23 FILES_TO_CACHE.map(async (url) => { 24 try { 25 const response = await fetch(url, { cache: 'no-store' }); 26 if (response.ok) { 27 await cache.put(url, response); 28 } 29 } catch (err) { 30 console.warn('[Armenia Travel PWA] Failed to cache:', url, err); 31 } 32 }) 33 ); 34 } catch (error) { 35 console.error('[Armenia Travel PWA] Cache install error:', error); 36 } 37 }) 38 ); 39 40 self.skipWaiting(); 41}); 42 43// ---------------------------------------------------------------------- 44// ð ACTIVATE 45self.addEventListener('activate', (event) => { 46 console.log('[Armenia Travel PWA] Activating and cleaning old caches...'); 47 48 event.waitUntil( 49 caches.keys().then((keys) => 50 Promise.all( 51 keys.map((key) => { 52 if (key !== CACHE_NAME) { 53 console.log('[Armenia Travel PWA] Removing old cache:', key); 54 return caches.delete(key); 55 } 56 }) 57 ) 58 ) 59 ); 60 61 // Take control of clients and force reload 62 event.waitUntil( 63 (async () => { 64 const clients = await self.clients.matchAll({ type: 'window' }); 65 for (const client of clients) { 66 client.navigate(client.url); 67 } 68 })() 69 ); 70 71 self.clients.claim(); 72}); 73 74// ---------------------------------------------------------------------- 75// ð FETCH 76self.addEventListener('fetch', (event) => { 77 const { request } = event; 78 79 // Skip non-HTTP(S) requests 80 if (!/^https?:\/\//i.test(request.url)) return; 81 82 // Skip requests from other origins 83 if (new URL(request.url).origin !== location.origin) return; 84 85 // Skip Next.js build files & manifest 86 if (NEVER_CACHE.some((pattern) => request.url.includes(pattern))) { 87 return; 88 } 89 90 // Don't cache POST/PUT/DELETE 91 if (request.method !== 'GET') { 92 event.respondWith(fetch(request).catch(() => caches.match(OFFLINE_URL))); 93 return; 94 } 95 96 // Try network first, then cache, then offline 97 event.respondWith( 98 fetch(request) 99 .then((response) => { 100 // Cache successful responses 101 const copy = response.clone(); 102 caches.open(CACHE_NAME).then((cache) => cache.put(request, copy)); 103 return response; 104 }) 105 .catch(() => caches.match(request).then((cached) => cached || caches.match(OFFLINE_URL))) 106 ); 107});
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.