chore(pwa): reconcile dual service worker after mobile-app-bootstrap merge
The mobile bootstrap shipped a hand-written public/sw.js plus a manual
navigator.serviceWorker.register('/sw.js') in main.tsx. The offline-sync
Workbox SW (vite-plugin-pwa, generateSW) functionally supersedes it
(NetworkOnly for /api,/collab,/socket.io, navigateFallback to the app shell,
runtime caching) and adds precache + prompt-based updates, so:
- Remove the hand-written apps/client/public/sw.js.
- Remove the manual SW registration block from main.tsx; registration is now
owned by <PwaUpdatePrompt/> via useRegisterSW (skipped in Capacitor native).
- Regenerate pnpm-lock.yaml for the merged Capacitor + @nestjs/swagger deps.
Kept from mobile-app-bootstrap: the richer manifest.json (offline-sync uses
manifest:false), capacitor.config.ts, the apple-touch-icon, and all server
mobile-auth/CORS/Swagger changes.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
committed by
claude code agent 227
parent
caeb555039
commit
7ac7fcba2d
@@ -1,82 +0,0 @@
|
||||
// Gitmost PWA service worker.
|
||||
// Conservative strategy:
|
||||
// - Never intercept API, websocket or collaboration traffic (always network).
|
||||
// - Navigations: network-first, fall back to the cached app shell offline.
|
||||
// - Other same-origin GET assets: stale-while-revalidate.
|
||||
// Bump CACHE_VERSION to invalidate stale assets on deploy.
|
||||
const CACHE_VERSION = "gitmost-v1";
|
||||
const APP_SHELL_URL = "/";
|
||||
|
||||
// Path prefixes that must always hit the network (auth/state/realtime).
|
||||
const NETWORK_ONLY_PREFIXES = ["/api", "/socket.io", "/collab"];
|
||||
|
||||
self.addEventListener("install", (event) => {
|
||||
// Activate this worker immediately without waiting for old tabs to close.
|
||||
self.skipWaiting();
|
||||
event.waitUntil(
|
||||
caches
|
||||
.open(CACHE_VERSION)
|
||||
.then((cache) => cache.add(APP_SHELL_URL))
|
||||
.catch(() => {}),
|
||||
);
|
||||
});
|
||||
|
||||
self.addEventListener("activate", (event) => {
|
||||
event.waitUntil(
|
||||
(async () => {
|
||||
const keys = await caches.keys();
|
||||
await Promise.all(
|
||||
keys
|
||||
.filter((key) => key !== CACHE_VERSION)
|
||||
.map((key) => caches.delete(key)),
|
||||
);
|
||||
await self.clients.claim();
|
||||
})(),
|
||||
);
|
||||
});
|
||||
|
||||
self.addEventListener("fetch", (event) => {
|
||||
const { request } = event;
|
||||
|
||||
// Only handle same-origin GET requests; everything else goes to the network.
|
||||
if (request.method !== "GET") return;
|
||||
|
||||
const url = new URL(request.url);
|
||||
if (url.origin !== self.location.origin) return;
|
||||
if (NETWORK_ONLY_PREFIXES.some((prefix) => url.pathname.startsWith(prefix)))
|
||||
return;
|
||||
|
||||
// Navigations: network-first with an offline fallback to the cached shell.
|
||||
if (request.mode === "navigate") {
|
||||
event.respondWith(
|
||||
(async () => {
|
||||
try {
|
||||
return await fetch(request);
|
||||
} catch {
|
||||
const cache = await caches.open(CACHE_VERSION);
|
||||
const cached = await cache.match(APP_SHELL_URL);
|
||||
return cached || Response.error();
|
||||
}
|
||||
})(),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Static assets: stale-while-revalidate.
|
||||
event.respondWith(
|
||||
(async () => {
|
||||
const cache = await caches.open(CACHE_VERSION);
|
||||
const cached = await cache.match(request);
|
||||
const network = fetch(request)
|
||||
.then((response) => {
|
||||
// Only cache successful, same-origin (basic) responses.
|
||||
if (response && response.status === 200 && response.type === "basic") {
|
||||
cache.put(request, response.clone());
|
||||
}
|
||||
return response;
|
||||
})
|
||||
.catch(() => undefined);
|
||||
return cached || (await network) || Response.error();
|
||||
})(),
|
||||
);
|
||||
});
|
||||
@@ -85,12 +85,8 @@ root.render(
|
||||
</BrowserRouter>,
|
||||
);
|
||||
|
||||
// Register the service worker for PWA installability and an offline app shell.
|
||||
// Production only: in dev the Vite server and HMR must not be intercepted.
|
||||
if (import.meta.env.PROD && "serviceWorker" in navigator) {
|
||||
window.addEventListener("load", () => {
|
||||
navigator.serviceWorker.register("/sw.js").catch((err) => {
|
||||
console.error("Service worker registration failed:", err);
|
||||
});
|
||||
});
|
||||
}
|
||||
// Service worker registration is owned by <PwaUpdatePrompt /> above (via
|
||||
// vite-plugin-pwa's useRegisterSW: Workbox precache + prompt-based updates,
|
||||
// and skipped inside the Capacitor native WebView). The earlier hand-written
|
||||
// /sw.js registration from the mobile bootstrap was removed here to avoid a
|
||||
// double registration / competing service worker.
|
||||
|
||||
Reference in New Issue
Block a user