const VERSION = '1.0.0' const APP_NAME = 'WeatherLens' const APP_ICON = './icons/icon-192.png' self.addEventListener('install', () => { self.skipWaiting() }) self.addEventListener('activate', () => { self.clients?.claim?.() }) function showNotification({ title = APP_NAME, body = '', icon, tag } = {}) { try { const opts = { body, icon: icon || APP_ICON, tag, requireInteraction: false, silent: false, } const reg = self.registration if (reg && typeof reg.showNotification === 'function') { return reg.showNotification(title, opts) } if (typeof Notification === 'function' || typeof Notification === 'object') { new Notification(title, opts).show() return true } } catch (e) { console.warn('[sw] notification failed:', e) } return false } self.addEventListener('message', (event) => { const data = event?.data || {} if (data.type === 'weather-notify') { showNotification(data) } }) self.addEventListener('push', (event) => { let payload = {} try { payload = event?.data?.json?.() ?? {} } catch { /* not JSON */ } event?.waitUntil?.( Promise.resolve(showNotification(payload)).then(async () => { const clients = self.clients if (clients) { for (const client of await clients.matchAll({ includeUncontrolled: true })) { client.postMessage({ type: 'weather-push-refresh' }) } } }) ) }) self.addEventListener('notificationclick', (event) => { event?.waitUntil?.( (async () => { const url = event?.notification?.data?.url || './' const clients = self.clients if (clients) { for (const client of await clients.matchAll({ includeUncontrolled: true })) { await client.navigate?.(url) } } await clients?.openWindow?.(url) })() ) }) self.addEventListener('fetch', () => { /* network-first */ }) console.log(`[sw] ${APP_NAME} ${VERSION} active`)