Files

90 lines
2.2 KiB
JavaScript
Raw Permalink Normal View History

// Falah PWA Service Worker
const CACHE = "falah-cache-v1";
const IMMUTABLE_CACHE = "falah-immutable-v1";
// Assets to pre-cache on install
const PRECACHE_ASSETS = [
"/mobile/manifest.json",
"/mobile/icons/icon-192x192.png",
"/mobile/icons/icon-512x512.png",
"/mobile/apple-touch-icon.png",
"/mobile/offline"
];
// Install: pre-cache core assets
self.addEventListener("install", (event) => {
event.waitUntil(
caches.open(IMMUTABLE_CACHE).then((cache) => cache.addAll(PRECACHE_ASSETS))
);
self.skipWaiting();
});
// Activate: clean old caches
self.addEventListener("activate", (event) => {
event.waitUntil(
caches.keys().then((keys) =>
Promise.all(
keys
.filter((k) => k !== CACHE && k !== IMMUTABLE_CACHE)
.map((k) => caches.delete(k))
)
)
);
self.clients.claim();
});
// Fetch: network-first for pages, cache-first for static assets
self.addEventListener("fetch", (event) => {
const { request } = event;
const url = new URL(request.url);
// Only handle same-origin /mobile requests
if (!url.pathname.startsWith("/mobile")) return;
// API calls — never cache
if (url.pathname.startsWith("/mobile/api/")) return;
// Static assets (icons, fonts, images) — cache-first
if (
url.pathname.match(/\.(png|jpg|jpeg|gif|svg|ico|webp|woff2?|css)$/)
) {
event.respondWith(cacheFirst(request));
return;
}
// Navigation & pages — network-first with fallback
if (request.mode === "navigate") {
event.respondWith(networkFirst(request));
return;
}
// Everything else — network-only
event.respondWith(fetch(request).catch(() => caches.match(request)));
});
async function networkFirst(request) {
try {
const response = await fetch(request);
if (response.ok) {
const cache = await caches.open(CACHE);
cache.put(request, response.clone());
}
return response;
} catch {
const cached = await caches.match(request);
if (cached) return cached;
// Offline fallback page
return caches.match("/mobile/offline");
}
}
async function cacheFirst(request) {
const cached = await caches.match(request);
if (cached) return cached;
try {
return await fetch(request);
} catch {
return new Response("", { status: 408 });
}
}