BT  ·  2026-05-09

sw.js

 1// sw.js
 2import { registerRoute, Route } from "workbox-routing";
 3import { StaleWhileRevalidate, CacheFirst } from "workbox-strategies";
 4import { ExpirationPlugin } from "workbox-expiration";
 5
 6// Log service worker startup
 7console.log('[SW] Service worker starting up');
 8
 9// Global error handler for service worker
10self.addEventListener('error', (event) => {
11  console.error('[SW] Global error:', event.error);
12});
13
14self.addEventListener('unhandledrejection', (event) => {
15  console.error('[SW] Unhandled promise rejection:', event.reason);
16});
17
18// A new route that matches same-origin image requests and handles
19// them with the cache-first, falling back to network strategy:
20
21const tileRoute = new Route(
22  ({ url }) => {
23    const u = url.toString();
24    const r = /.+\/tiles\//gm;
25    console.log("[SW] url=", u, "match=", u.match(r) !== null);
26    return u.match(r) !== null;
27  },
28  new StaleWhileRevalidate({
29    cacheName: "tiles",
30  }),
31);
32
33// Register the new route
34registerRoute(tileRoute);
35
36// CacheFirst route for route GeoJSON (immutable, content-addressed)
37// Routes are identified by hash and never change once created
38registerRoute(
39  ({ url }) => {
40    // Match /route/{hash}.geojson URLs
41    const isMatch = url.pathname.startsWith('/route/') && url.pathname.endsWith('.geojson');
42    console.log('[SW] Checking route:', url.pathname, 'match:', isMatch);
43    return isMatch;
44  },
45  new CacheFirst({
46    cacheName: "route-geojson",
47    plugins: [
48      new ExpirationPlugin({
49        maxEntries: 100,              // Max 100 routes cached
50        maxAgeSeconds: 60 * 60 * 24 * 30, // 30 days
51      }),
52      {
53        // Custom plugin for debugging
54        cacheWillUpdate: async ({ request, response }) => {
55          console.log('[SW] cacheWillUpdate:', request.url, 'status:', response.status);
56          return response;
57        },
58        handlerWillRespond: async ({ request, response }) => {
59          console.log('[SW] handlerWillRespond:', request.url, 'status:', response?.status);
60          return response;
61        },
62      },
63    ],
64  })
65);