46 lines
1.9 KiB
TypeScript
46 lines
1.9 KiB
TypeScript
import { Capacitor } from '@capacitor/core';
|
|
|
|
let started = false;
|
|
|
|
/**
|
|
* Register the app-shell service worker on the web only.
|
|
*
|
|
* The same worker also handles Web Push, so registering it unconditionally does
|
|
* not conflict with the push opt-in path. Native Capacitor uses its local asset
|
|
* server instead — a service worker there would only add a second cache.
|
|
*/
|
|
export function registerAppServiceWorker(): void {
|
|
if (started || typeof window === 'undefined' || !('serviceWorker' in navigator)) return;
|
|
if (Capacitor.isNativePlatform()) {
|
|
// The native shell must never inherit an old web app-shell worker. Some
|
|
// Android WebViews expose a partial/absent Service Worker API, so every
|
|
// call is feature-checked and wrapped — this cleanup must never abort React
|
|
// boot (that produced a black screen after the native splash).
|
|
try {
|
|
if (navigator.serviceWorker && typeof navigator.serviceWorker.getRegistrations === 'function') {
|
|
void navigator.serviceWorker.getRegistrations()
|
|
.then((regs) => regs.forEach((reg) => { try { reg.unregister(); } catch { /* ignore */ } }))
|
|
.catch(() => undefined);
|
|
}
|
|
if (typeof caches !== 'undefined' && typeof caches.keys === 'function') {
|
|
void caches.keys()
|
|
.then((keys) => keys.filter((key) => key.startsWith('skate-spots-shell-'))
|
|
.forEach((key) => { void caches.delete(key).catch(() => undefined); }))
|
|
.catch(() => undefined);
|
|
}
|
|
} catch {
|
|
// Best-effort only; boot must continue.
|
|
}
|
|
return;
|
|
}
|
|
started = true;
|
|
|
|
const register = () => {
|
|
navigator.serviceWorker.register('/push-sw.js', { updateViaCache: 'none' }).catch(() => {
|
|
// Private mode / unsupported browser — the app works without it.
|
|
});
|
|
};
|
|
|
|
if (document.readyState === 'complete') register();
|
|
else window.addEventListener('load', register, { once: true });
|
|
}
|