Skip to content

Commit dbfc647

Browse files
moved & updated trip
1 parent 0414f18 commit dbfc647

12 files changed

Lines changed: 874 additions & 46 deletions

File tree

File renamed without changes.
File renamed without changes.

public/static/j9vubfuw/index.html

Lines changed: 821 additions & 0 deletions
Large diffs are not rendered by default.

public/static/j9vubfuw/sw.js

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// Trip PWA service worker — offline shell + map tiles + self-update.
2+
// Ships UNENCRYPTED next to the HTML (must NOT be staticrypt-wrapped).
3+
//
4+
// Self-update: skipWaiting + clients.claim means a newly-published sw.js takes over immediately;
5+
// the page reloads once on controllerchange to pick up the fresh shell. Navigation is network-first,
6+
// so an online open always fetches the latest app; the cache is only a fallback for dead zones.
7+
//
8+
// Bump VERSION to force-drop every cached tile / Leaflet / font (old caches are deleted on activate).
9+
const VERSION='v1'; // fresh cache namespace for the /static/ URL
10+
const CACHE='trip-'+VERSION, MAX=3000, TRIM=200, NET_TIMEOUT=4000;
11+
12+
self.addEventListener('install', ()=>self.skipWaiting());
13+
self.addEventListener('activate', e=>e.waitUntil((async()=>{
14+
const names=await caches.keys();
15+
await Promise.all(names.filter(n=>n.startsWith('trip-') && n!==CACHE).map(n=>caches.delete(n)));
16+
await self.clients.claim();
17+
})()));
18+
19+
self.addEventListener('fetch', e=>{
20+
const req=e.request;
21+
if(req.method!=='GET') return;
22+
23+
// App shell / HTML: network-first so an updated site shows on the next open. Falls back to cache
24+
// (and keeps refreshing it in the background) when the signal is slow or gone — Big Sur / Lassen have none.
25+
if(req.mode==='navigate'){
26+
e.respondWith((async()=>{
27+
const cache=await caches.open(CACHE);
28+
const net=fetch(req).then(r=>{ cache.put(req, r.clone()); return r; });
29+
const cached=await cache.match(req);
30+
if(!cached) return net.catch(()=>Response.error()); // first-ever load must reach the network
31+
// ponytail: 4s ceiling — prefer fresh, don't hang on flaky signal; net still updates the cache for next open.
32+
return Promise.race([ net.catch(()=>cached), new Promise(res=>setTimeout(()=>res(cached), NET_TIMEOUT)) ]);
33+
})());
34+
return;
35+
}
36+
37+
// Tiles, Leaflet, fonts: cache-first (immutable, URL-versioned). Cached on first fetch.
38+
// Only cache genuine 200s — never an opaque/error response, or a failed tile would poison the
39+
// cache-first path forever. Everything we need offline is CORS (tiles crossOrigin, Leaflet SRI) or
40+
// same-origin (fonts, HTML), so res.ok is always observable here.
41+
e.respondWith(caches.open(CACHE).then(async cache=>{
42+
const hit=await cache.match(req);
43+
if(hit) return hit;
44+
const res=await fetch(req);
45+
if(res && res.ok){
46+
cache.put(req, res.clone());
47+
// ponytail: crude FIFO trim, LRU if it ever matters. ~3000 tiles ≈ 60 MB, within iOS quota.
48+
cache.keys().then(keys=>{ if(keys.length>MAX) for(let i=0;i<TRIM;i++) cache.delete(keys[i]); });
49+
}
50+
return res;
51+
}).catch(()=>caches.match(req)));
52+
});

0 commit comments

Comments
 (0)