95 updateSWSafe(registration, message, log, persistenceService).catch(
96 (error: unknown): void => {
97 // Rethrow error into React rendering stack
98 throw error 99 }
100 )
101 }
67 WrappedComponent: React.ComponentType<P & ServiceWorkerUpdaterProps>,
68 {
69 message = { type: 'SKIP_WAITING' },
70 log = () => console.log('Controller loaded'), 71 persistenceService = new NullPersistenceService()
72 }: WithServiceWorkerUpdaterOptions = {}
73) {
24 persistenceService: PersistenceService
25): Promise<void> => {
26 if (!registration) {
27 const { controller } = navigator.serviceWorker 28 if (controller) { 29 // If we have controller, use it's URL to re-register it 30 const registrationFromAPI = await navigator.serviceWorker.register( 31 controller.scriptURL 32 ) 33 34 // If we could register it and there is a waiting SW, use it 35 if (registrationFromAPI?.waiting) { 36 updateSW(registrationFromAPI, message, log, persistenceService) 37 } else { 38 throw new Error( 39 'ServiceWorkerRegistration not found and no waiting ServiceWorker found' 40 ) 41 } 42 } else { 43 throw new Error( 44 'ServiceWorkerRegistration not found and no ServiceWorker detected'
45 )
46 }
20 * Register an event to controllerchange, wich will be fired when the
21 * `waiting` SW executes `skipWaiting`
22 */
23 let preventDevToolsReloadLoop = false24 navigator.serviceWorker.addEventListener('controllerchange', () => {25 /*26 * Ensure refresh is only called once.27 * This works around a bug in "force update on reload".28 */29 if (preventDevToolsReloadLoop) {30 return31 }3233 preventDevToolsReloadLoop = true34 log()3536 // Clear the persisted state about service worker update being available37 persistenceService.clear()3839 // Finally, refresh the page40 global.location.reload()41 })4243 /*44 * Send a message to the new serviceWorker to activate itself45 * by executing its own `skipWaiting` method46 * The SW must register an event listener to messages which47 * identifies this `message` and runs its `skipWaiting` method48 */49 registration.waiting.postMessage(message)50 }
51}
52
3const onServiceWorkerUpdate = (
4 registration: ServiceWorkerRegistration
5): void => {
6 const event = new CustomEvent('onNewServiceWorker', { 7 detail: { registration } 8 }) 9 document.dispatchEvent(event)10}
11
12export default onServiceWorkerUpdate
A source line is considered covered when at least one instruction that is assigned to this line has been executed by a test case. These lines were not executed during any of the test cases.