1/* OverSkill Web Push Service Worker. 2 * 3 * Companion to the SDK's `overskill.push.subscribe()`. Receives `push` 4 * events from the platform's push relay and shows a system notification. 5 * 6 * Lives at /sw-push.js so it has root scope (can show notifications 7 * for any URL on the app's origin). Vite's PWA plugin generates ITS OWN 8 * service worker for offline asset caching â that one lives at /sw.js 9 * by default. We don't want to merge the two: precaching has very 10 * different lifecycle semantics from push, and Workbox's auto-update 11 * model would clobber our push handlers on every deploy. 12 * 13 * If your generated app needs both PWA precaching AND push, both SWs 14 * coexist fine â each owns its own scope. Browsers allow multiple 15 * service workers per origin. 16 */ 17 18self.addEventListener('install', () => { 19 // Activate immediately on first install so the user gets push reception 20 // without needing to refresh after subscribe. 21 self.skipWaiting(); 22}); 23 24self.addEventListener('activate', (event) => { 25 event.waitUntil(self.clients.claim()); 26}); 27 28self.addEventListener('push', (event) => { 29 if (!event.data) return; 30 31 let payload; 32 try { 33 payload = event.data.json(); 34 } catch (err) { 35 payload = { title: 'Notification', body: event.data.text() }; 36 } 37 38 const title = payload.title || 'Notification'; 39 const options = { 40 body: payload.body, 41 icon: payload.icon || '/icon-192.png', 42 badge: payload.badge || payload.icon || '/icon-192.png', 43 data: { 44 url: payload.url || '/', 45 ...(payload.data || {}) 46 } 47 }; 48 49 event.waitUntil(self.registration.showNotification(title, options)); 50}); 51 52self.addEventListener('notificationclick', (event) => { 53 event.notification.close(); 54 const targetUrl = event.notification.data?.url || '/'; 55 56 // Focus an existing window with the same URL if possible; otherwise 57 // open a new one. Standard "click to deep-link" UX. 58 event.waitUntil( 59 self.clients.matchAll({ type: 'window', includeUncontrolled: true }).then((clientList) => { 60 for (const client of clientList) { 61 if (client.url.endsWith(targetUrl) && 'focus' in client) { 62 return client.focus(); 63 } 64 } 65 if (self.clients.openWindow) { 66 return self.clients.openWindow(targetUrl); 67 } 68 }) 69 ); 70}); 71 72; 73// ---- OverSkill push capability ping (#3705) ------------------------- 74// The page cannot introspect a service worker's listeners, so a worker 75// that handles push says so out loud. overskill-runtime-sdk's push scope 76// guard uses this to tell "the worker that owns / can receive push" from 77// "the worker that owns / is a bare precache worker" â without it the 78// guard could hand a caller a registration whose push events go nowhere, 79// which is the #3705 bug wearing a different hat. 80self.__overskillPushSw = 1; 81self.addEventListener('message', function (event) { 82 var data = event.data; 83 if (!data || data.type !== 'OVERSKILL_PUSH_SW_PING') return; 84 var reply = { type: 'OVERSKILL_PUSH_SW_PONG', pushSw: self.__overskillPushSw }; 85 try { 86 if (event.ports && event.ports[0]) { 87 event.ports[0].postMessage(reply); 88 return; 89 } 90 } catch (err) { 91 // Fall through to the client channel below. 92 } 93 try { 94 if (event.source && typeof event.source.postMessage === 'function') { 95 event.source.postMessage(reply); 96 } 97 } catch (err) { 98 // A page we cannot answer simply times out and treats us as 99 // push-incapable â the safe direction (it registers its own worker). 100 } 101});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.