1/** 2 * Simple Service Worker Ping Script 3 * Sends periodic pings to keep the service worker alive 4 */ 5 6(function () { 7 'use strict'; 8 9 // Check if service worker is supported 10 if (!('serviceWorker' in navigator)) { 11 console.warn('Service Worker not supported'); 12 return; 13 } 14 15 let pingInterval = null; 16 let missedPongs = 0; 17 const maxMissedPongs = 3; 18 const pingIntervalMs = 20000; 19 20 function sendPing() { 21 if (!navigator.serviceWorker.controller) { 22 console.warn('[SW Ping] No active Service Worker to ping'); 23 missedPongs++; 24 return; 25 } 26 27 try { 28 const timestamp = Date.now(); 29 navigator.serviceWorker.controller.postMessage({ 30 action: 'ping', 31 timestamp: timestamp, 32 }); 33 34 // Only increment missedPongs if we don't get a response 35 // We'll reset this when we receive a pong 36 const currentMissedPongs = missedPongs + 1; 37 38 if (currentMissedPongs >= maxMissedPongs) { 39 console.warn('[SW Ping] Multiple pings missed, attempting to recover...'); 40 stopPing(); 41 setTimeout(() => { 42 startPing(); 43 }, 1000); 44 missedPongs = 0; 45 } else { 46 missedPongs = currentMissedPongs; 47 } 48 } catch (error) { 49 console.error('[SW Ping] Error sending ping:', error); 50 missedPongs++; 51 } 52 } 53 54 function startPing() { 55 if (pingInterval) { 56 return; 57 } 58 59 pingInterval = setInterval(sendPing, pingIntervalMs); 60 61 // Send initial ping 62 sendPing(); 63 } 64 65 function stopPing() { 66 if (pingInterval) { 67 clearInterval(pingInterval); 68 pingInterval = null; 69 } 70 } 71 72 function resetMissedPongs() { 73 missedPongs = 0; 74 } 75 76 // Listen for pong responses from service worker 77 navigator.serviceWorker.addEventListener('message', function (event) { 78 try { 79 const data = JSON.parse(event.data); 80 if (data && data.action === 'pong') { 81 missedPongs = 0; 82 } 83 } catch (error) { 84 console.error('[SW Ping] Error parsing message:', error); 85 } 86 }); 87 88 // Handle user interactions to reset missed pongs 89 function onUserInteraction() { 90 resetMissedPongs(); 91 } 92 93 const events = ['click', 'keydown', 'mousemove', 'scroll', 'touchstart']; 94 events.forEach((eventType) => { 95 document.addEventListener(eventType, onUserInteraction, {passive: true}); 96 }); 97 98 // Handle page visibility changes 99 document.addEventListener('visibilitychange', function () { 100 if (!document.hidden) { 101 resetMissedPongs(); 102 } 103 }); 104 105 if (document.readyState === 'loading') { 106 document.addEventListener('DOMContentLoaded', startPing); 107 } else { 108 startPing(); 109 } 110 111 window.swPing = { 112 start: startPing, 113 stop: stopPing, 114 reset: resetMissedPongs, 115 getStatus: () => ({ 116 isRunning: !!pingInterval, 117 missedPongs: missedPongs, 118 maxMissedPongs: maxMissedPongs, 119 interval: pingIntervalMs, 120 }), 121 }; 122})();
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.