/* eslint-disable */ // Relay 서비스워커 — 웹 푸시(Level2): 사이트/탭을 닫아도 OS 토스트를 띄운다. // 푸시 페이로드는 백엔드 WebPushService 가 { title, body, url } 로 보낸다. self.addEventListener('install', () => { // 새 워커를 즉시 활성화 self.skipWaiting() }) self.addEventListener('activate', (event) => { event.waitUntil(self.clients.claim()) }) self.addEventListener('push', (event) => { if (!event.data) return let payload = {} try { payload = event.data.json() } catch (e) { payload = { title: 'Relay', body: '새 알림이 도착했습니다' } } const title = payload.title || 'Relay' const body = payload.body || '' const url = payload.url || null event.waitUntil( (async () => { // 열린 클라이언트(탭)가 있으면 페이지의 SSE 가 이미 토스트를 처리 → 중복 표시 생략 const clients = await self.clients.matchAll({ type: 'window', includeUncontrolled: true, }) if (clients.length > 0) return await self.registration.showNotification(title, { body, icon: '/relay-icon-256.png', badge: '/relay-icon-256.png', data: { url }, }) })(), ) }) self.addEventListener('notificationclick', (event) => { event.notification.close() const url = (event.notification.data && event.notification.data.url) || '/' event.waitUntil( (async () => { const clients = await self.clients.matchAll({ type: 'window', includeUncontrolled: true, }) // 이미 열린 창이 있으면 포커스 후 해당 경로로 이동 for (const client of clients) { if ('focus' in client) { await client.focus() if ('navigate' in client && url) { try { await client.navigate(url) } catch (e) { /* 이동 실패 무시 */ } } return } } // 열린 창이 없으면 새 창 if (self.clients.openWindow) await self.clients.openWindow(url) })(), ) })