Stem_Copilot / sw.js
Krishna111111's picture
Still Trying...
0930342
Raw
History Blame Contribute Delete
2.56 kB
// STEM Copilot β€” Service Worker (PWA installability + safe caching)
//
// Caching strategy:
// β€’ API calls (/chat, /auth, …) β†’ never touched, always network.
// β€’ Navigations + app code (HTML/JS/ β†’ NETWORK-FIRST. This is critical: a
// CSS) cache-first shell used to serve a stale
// index.html / app.js after every deploy,
// which forced users to hard-refresh
// (Ctrl+Shift+R) and could surface an old,
// un-gated build of the app. Network-first
// means everyone always gets the live code.
// β€’ Other static assets (images, β†’ cache-first (fine to be stale).
// fonts)
const CACHE_NAME = 'stemcopilot-v3';
const ASSET_URLS = [
'/assets/bot.png',
'/assets/stem_black.png',
'/assets/stembotix.png',
];
self.addEventListener('install', (e) => {
e.waitUntil(caches.open(CACHE_NAME).then((cache) => cache.addAll(ASSET_URLS)));
self.skipWaiting();
});
self.addEventListener('activate', (e) => {
e.waitUntil(
caches.keys().then((keys) =>
Promise.all(keys.filter((k) => k !== CACHE_NAME).map((k) => caches.delete(k)))
)
);
self.clients.claim();
});
function _isApi(url) {
return ['/chat', '/auth', '/threads', '/history', '/user', '/export',
'/health', '/feedback', '/notes', '/upload-doc', '/rename', '/thread']
.some((p) => url.includes(p));
}
// HTML navigations and the core app code must always come fresh from the network.
function _isAppCode(req, url) {
return req.mode === 'navigate'
|| url.endsWith('/')
|| url.includes('/static/app.js')
|| url.includes('/static/style.css')
|| url.includes('/static/index.html');
}
self.addEventListener('fetch', (e) => {
const url = e.request.url;
if (_isApi(url)) return; // straight to network, no SW involvement
if (_isAppCode(e.request, url)) {
// Network-first: fetch live, fall back to cache only when offline.
e.respondWith(
fetch(e.request)
.then((resp) => {
const copy = resp.clone();
caches.open(CACHE_NAME).then((c) => c.put(e.request, copy)).catch(() => {});
return resp;
})
.catch(() => caches.match(e.request))
);
return;
}
// Everything else (images, fonts): cache-first.
e.respondWith(caches.match(e.request).then((cached) => cached || fetch(e.request)));
});