PageSourceSearch

https://www.hydrovacnews.com/sw.js

js hydrovacnews.com collected 2026-10-04 22:43:45 UTC 2,507 bytes, 81 lines download raw bytes

1/**
2 * Hydrovac News service worker.
3 *
4 * Strategy:
5 *  - /_next/static/*, /images/*, /pdfs/*, favicon/icon assets, /sw.js itself
6 *    → cache-first with a long TTL. These are content-hashed or rarely change.
7 *  - Everything else (HTML, API responses, dynamic next/image transforms) →
8 *    network-only. We never cache HTML to avoid serving stale pages.
9 *
10 * Update strategy:
11 *  - Bump CACHE_VERSION when changing this file. Old caches are deleted on activate.
12 *  - The Cache-Control on /sw.js (set in vercel.json) forces revalidation on
13 *    every page load, so this file itself updates immediately.
14 *  - We call self.skipWaiting() so the new SW takes over without requiring a
15 *    second tab close.
16 */
17const CACHE_VERSION = 'v1';
18const STATIC_CACHE = `hvn-static-${CACHE_VERSION}`;
19
20// Paths that are safe to serve cache-first. Each must be content-hashed or
21// immutable in practice (we expect the underlying file never changes).
22const STATIC_PATTERNS = [
23  /^\/_next\/static\//,
24  /^\/images\//,
25  /^\/pdfs\//,
26  /^\/(favicon-32|favicon-64|icon-192|icon-512|apple-icon|logo|og-image)\.(png|svg)$/,
27  /^\/pdf\.worker\.min\.mjs$/,
28];
29
30function isStaticAsset(url) {
31  return STATIC_PATTERNS.some((rx) => rx.test(url.pathname));
32}
33
34self.addEventListener('install', (event) => {
35  // Take over immediately on first install
36  self.skipWaiting();
37});
38
39self.addEventListener('activate', (event) => {
40  event.waitUntil(
41    (async () => {
42      const keys = await caches.keys();
43      await Promise.all(
44        keys.filter((k) => k !== STATIC_CACHE).map((k) => caches.delete(k))
45      );
46      await self.clients.claim();
47    })()
48  );
49});
50
51self.addEventListener('fetch', (event) => {
52  const request = event.request;
53  if (request.method !== 'GET') return;
54
55  const url = new URL(request.url);
56
57  // Only handle same-origin requests
58  if (url.origin !== self.location.origin) return;
59
60  if (!isStaticAsset(url)) return;
61
62  event.respondWith(
63    (async () => {
64      const cache = await caches.open(STATIC_CACHE);
65      const cached = await cache.match(request);
66      if (cached) return cached;
67
68      try {
69        const response = await fetch(request);
70        // Only cache successful, basic responses
71        if (response && response.ok && response.type === 'basic') {
72          cache.put(request, response.clone());
73        }
74        return response;
75      } catch (err) {
76        // If offline and not cached, let the browser handle the error
77        throw err;
78      }
79    })()
80  );
81});

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.