Files

59 lines
2.4 KiB
JavaScript
Raw Permalink Normal View History

2026-11-14 20:23:59 +01:00
const CACHE = 'codexpi-shell-v18'
const SHELL = ['/', '/manifest.webmanifest', '/icons/icon-192.png', '/icons/icon-512.png', '/icons/apple-touch-icon.png']
self.addEventListener('install', event => {
event.waitUntil(caches.open(CACHE).then(cache => cache.addAll(SHELL)).then(() => self.skipWaiting()))
})
self.addEventListener('activate', event => {
event.waitUntil(caches.keys().then(keys => Promise.all(keys.filter(key => key !== CACHE).map(key => caches.delete(key)))).then(() => self.clients.claim()))
})
self.addEventListener('fetch', event => {
const request = event.request
const url = new URL(request.url)
if (request.method !== 'GET' || url.origin !== location.origin || url.pathname.startsWith('/api/') || url.pathname.startsWith('/ws/')) return
if (url.pathname === '/version.json' || url.pathname === '/sw.js') {
event.respondWith(fetch(request, {cache: 'no-store'}))
return
}
if (request.mode === 'navigate') {
event.respondWith(fetch(request).then(response => {
const copy = response.clone()
caches.open(CACHE).then(cache => cache.put('/', copy))
return response
}).catch(() => caches.match('/')))
return
}
event.respondWith(caches.match(request).then(cached => cached || fetch(request).then(response => {
if (response.ok) caches.open(CACHE).then(cache => cache.put(request, response.clone()))
return response
})))
})
self.addEventListener('push', event => {
let message = {}
try { message = event.data ? event.data.json() : {} } catch {}
event.waitUntil(self.registration.showNotification(message.title || 'Tâche CodexPi terminée', {
body: message.body || 'Ouvrez CodexPi pour consulter le résultat.',
icon: '/icons/icon-192.png', badge: '/icons/icon-192.png',
tag: message.tag || 'codexpi-task', data: {url: message.url || '/'},
}))
})
self.addEventListener('notificationclick', event => {
event.notification.close()
event.waitUntil((async () => {
const target = new URL(event.notification.data?.url || '/', self.location.origin)
if (target.origin !== self.location.origin) return
const windows = await self.clients.matchAll({type: 'window', includeUncontrolled: true})
for (const client of windows) {
if (new URL(client.url).origin === target.origin && 'navigate' in client) {
const navigated = await client.navigate(target.href)
if (navigated) { await navigated.focus(); return }
}
}
await self.clients.openWindow(target.href)
})())
})