PageSourceSearch

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

js workadabra.com collected 2026-10-02 01:49:12 UTC 3,175 bytes, 89 lines download raw bytes

1// GENERATED by packages/service-worker/typescript. Do not edit this file: edit the
2// source there and run `bun run --filter=@bomdisoft/service-worker generate`.
3//
4// Native service worker: runtime caching only, no precache manifest. Next.js's static assets
5// under /_next/static/ are content-hashed in production (immutable URLs), so there is no need
6// for Workbox-style install-time precaching with revisioned cache invalidation: everything
7// caches progressively as it's requested.
8const CACHE_NAME = 'bomdisoft-v2';
9
10self.addEventListener('install', () => {
11  self.skipWaiting();
12});
13
14self.addEventListener('activate', event => {
15  event.waitUntil(
16    (async () => {
17      const keys = await caches.keys();
18      await Promise.all(keys.filter(key => key !== CACHE_NAME).map(key => caches.delete(key)));
19      await self.clients.claim();
20    })(),
21  );
22});
23
24// Content-hashing is a PRODUCTION property. A dev server serves mutable chunks under this same
25// prefix, so caching them first pins whatever was there: a prod build run once on a dev port
26// left the worker answering that origin's dev chunks from the prod bundle, and the page ran new
27// code against an old module until the worker was unregistered by hand (2026-08-30).
28//
29// Reads through an absent `self.location`, because clepit's suite evaluates this file in a fake
30// scope that has none and an unguarded read threw there on every test in it.
31const devHost = (self.location && self.location.hostname) || '';
32const isDevOrigin = devHost === 'localhost' || devHost === '127.0.0.1' || devHost.endsWith('.localhost');
33
34const isImmutableAsset = url => !isDevOrigin && url.pathname.startsWith('/_next/static/');
35const isImage = url => /\.(png|jpe?g|gif|webp|avif|svg|ico)$/.test(url.pathname);
36
37async function cacheFirst(request) {
38  const cache = await caches.open(CACHE_NAME);
39  const cached = await cache.match(request);
40  if (cached) return cached;
41  const response = await fetch(request);
42  if (response.ok) cache.put(request, response.clone());
43  return response;
44}
45
46async function networkFirst(request) {
47  const cache = await caches.open(CACHE_NAME);
48  try {
49    const response = await fetch(request);
50    if (response.ok) cache.put(request, response.clone());
51    return response;
52  } catch (error) {
53    const cached = await cache.match(request);
54    if (cached) return cached;
55    throw error;
56  }
57}
58
59async function staleWhileRevalidate(request) {
60  const cache = await caches.open(CACHE_NAME);
61  const cached = await cache.match(request);
62  const fetchPromise = fetch(request).then(response => {
63    if (response.ok) cache.put(request, response.clone());
64    return response;
65  });
66  return cached || fetchPromise;
67}
68
69self.addEventListener('fetch', event => {
70  const { request } = event;
71  if (request.method !== 'GET') return;
72
73  const url = new URL(request.url);
74  if (url.origin !== self.location.origin) return;
75
76  if (request.mode === 'navigate') {
77    event.respondWith(networkFirst(request));
78    return;
79  }
80
81  if (isImmutableAsset(url)) {
82    event.respondWith(cacheFirst(request));
83    return;
84  }
85
86  if (isImage(url)) {
87    event.respondWith(staleWhileRevalidate(request));
88  }
89});

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.