mirror of
https://github.com/wizarrrr/wizarr.git
synced 2026-07-30 23:07:19 -04:00
- Set updateViaCache to 'none' in SW registration to bypass HTTP cache for the worker script. - Implemented periodic update checks every hour and update listeners. - Integrated immediate activation (self.skipWaiting) and adoption (self.clients.claim) in sw.js to resolve cache lock-in instantly. - Optimized stale-while-revalidate strategy in sw.js to use event.waitUntil to guarantee background fetches complete. - Removed duplicate css/main.css stylesheet load in base.html template. - Added app/static/js/vendor/ and app/static/css/vendor/ to .dockerignore to keep Docker daemon build contexts clean.
97 lines
3.2 KiB
JavaScript
97 lines
3.2 KiB
JavaScript
const CACHE_NAME = 'wizarr-v2';
|
|
const urlsToCache = [
|
|
'/static/css/main.css',
|
|
'/static/js/dark-mode-switch.js',
|
|
'/static/favicon.ico',
|
|
'/static/wizarr-logo.png',
|
|
'/static/js/vendor/htmx.min.js',
|
|
'/static/js/vendor/alpine.min.js',
|
|
'/static/js/vendor/flowbite.min.js',
|
|
'/static/js/vendor/alpine-collapse.min.js'
|
|
];
|
|
|
|
// Install event - cache resources and activate immediately
|
|
self.addEventListener('install', (event) => {
|
|
// Skip waiting so the new service worker activates immediately,
|
|
// ensuring users with stale caches get the fix without closing all tabs.
|
|
self.skipWaiting();
|
|
event.waitUntil(
|
|
caches.open(CACHE_NAME)
|
|
.then((cache) => {
|
|
console.log('Opened cache:', CACHE_NAME);
|
|
return cache.addAll(urlsToCache);
|
|
})
|
|
);
|
|
});
|
|
|
|
// Fetch event - network-first for HTML pages, stale-while-revalidate for static assets
|
|
self.addEventListener('fetch', (event) => {
|
|
// Only handle GET requests
|
|
if (event.request.method !== 'GET') {
|
|
return;
|
|
}
|
|
|
|
// Network-first for HTML page navigation to ensure dynamic Flask backend state works
|
|
if (event.request.mode === 'navigate' || (event.request.headers.get('accept') && event.request.headers.get('accept').includes('text/html'))) {
|
|
event.respondWith(
|
|
fetch(event.request)
|
|
.catch(() => {
|
|
return caches.match(event.request);
|
|
})
|
|
);
|
|
return;
|
|
}
|
|
|
|
// Stale-while-revalidate for static assets:
|
|
// Serve from cache immediately for speed, but fetch a fresh copy in the
|
|
// background so the next load always has the latest version.
|
|
event.respondWith(
|
|
caches.open(CACHE_NAME).then((cache) => {
|
|
return cache.match(event.request).then((cachedResponse) => {
|
|
const fetchPromise = fetch(event.request).then((networkResponse) => {
|
|
// Only cache successful responses from our own origin
|
|
if (networkResponse && networkResponse.status === 200 && networkResponse.type === 'basic') {
|
|
cache.put(event.request, networkResponse.clone());
|
|
}
|
|
return networkResponse;
|
|
}).catch(() => {
|
|
// Network failed, cachedResponse (if any) is already being returned
|
|
});
|
|
if (cachedResponse) {
|
|
// Keep the service worker alive to complete the background fetch and cache update
|
|
event.waitUntil(fetchPromise);
|
|
return cachedResponse;
|
|
}
|
|
return fetchPromise;
|
|
});
|
|
})
|
|
);
|
|
});
|
|
|
|
// Activate event - clean up old caches and claim all open clients immediately
|
|
self.addEventListener('activate', (event) => {
|
|
event.waitUntil(
|
|
caches.keys().then((cacheNames) => {
|
|
return Promise.all(
|
|
cacheNames.map((cacheName) => {
|
|
if (cacheName !== CACHE_NAME) {
|
|
console.log('Deleting old cache:', cacheName);
|
|
return caches.delete(cacheName);
|
|
}
|
|
})
|
|
);
|
|
})
|
|
// Claim all open clients so the new service worker takes control immediately,
|
|
// without requiring a page reload.
|
|
.then(() => self.clients.claim())
|
|
);
|
|
});
|
|
|
|
// Handle background sync and push notifications
|
|
self.addEventListener('sync', (event) => {
|
|
console.log('Background sync event:', event);
|
|
});
|
|
|
|
self.addEventListener('push', (event) => {
|
|
console.log('Push event:', event);
|
|
});
|