This repository has been archived on 2026-04-03. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
core/src/sw.js
2026-02-27 16:25:39 +00:00

96 lines
2.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// ==========================================
// Chat Switchboard Service Worker
// ==========================================
// Caches the app shell for offline / instant load.
// API calls always go to network (never cached).
//
// Cache key includes a build hash computed at container
// startup from the JS file contents. Every deploy produces
// a new hash, which triggers install → precache → activate
// → purge old caches automatically.
const CACHE_NAME = 'switchboard-%%APP_VERSION%%-%%BUILD_HASH%%';
// App shell files to pre-cache on install
const SHELL_FILES = [
'./',
'./index.html',
'./css/styles.css',
'./js/debug.js',
'./js/events.js',
'./js/extensions.js',
'./js/api.js',
'./js/ui-format.js',
'./js/ui-primitives.js',
'./js/ui-core.js',
'./js/ui-settings.js',
'./js/ui-admin.js',
'./js/tokens.js',
'./js/notes.js',
'./js/attachments.js',
'./js/tools-toggle.js',
'./js/knowledge-ui.js',
'./js/chat.js',
'./js/settings-handlers.js',
'./js/admin-handlers.js',
'./js/app.js',
'./vendor/marked.min.js',
'./vendor/purify.min.js',
'./favicon.svg',
'./favicon.ico',
'./favicon-32.png',
'./favicon-256.png',
'./manifest.json',
];
// Install: pre-cache the shell
self.addEventListener('install', (event) => {
event.waitUntil(
caches.open(CACHE_NAME)
.then(cache => cache.addAll(SHELL_FILES))
.then(() => self.skipWaiting())
);
});
// Activate: purge old caches
self.addEventListener('activate', (event) => {
event.waitUntil(
caches.keys().then(keys =>
Promise.all(
keys.filter(k => k !== CACHE_NAME)
.map(k => caches.delete(k))
)
).then(() => self.clients.claim())
);
});
// Fetch: network-first for API/WS, stale-while-revalidate for shell assets
self.addEventListener('fetch', (event) => {
const url = new URL(event.request.url);
// Never cache API calls, WebSocket upgrades, branding, or extension assets
if (url.pathname.includes('/api/') ||
url.pathname.includes('/ws') ||
url.pathname.includes('/branding/') ||
url.pathname.includes('/extensions/') ||
event.request.method !== 'GET') {
return;
}
// Stale-while-revalidate: serve cached, update in background
event.respondWith(
caches.match(event.request).then(cached => {
const fetchPromise = fetch(event.request).then(response => {
// Update cache with fresh version
if (response.ok) {
const clone = response.clone();
caches.open(CACHE_NAME).then(cache => cache.put(event.request, clone));
}
return response;
}).catch(() => cached); // offline fallback to cache
return cached || fetchPromise;
})
);
});