File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change 1+ import { startPWAUpdatePolling } from './pwaUpdatePolling' ;
2+
3+ describe ( 'startPWAUpdatePolling' , ( ) => {
4+ beforeEach ( ( ) => {
5+ jest . useFakeTimers ( ) ;
6+ } ) ;
7+
8+ afterEach ( ( ) => {
9+ jest . useRealTimers ( ) ;
10+ } ) ;
11+
12+ it ( 'checks for updates immediately and on the polling interval while visible' , ( ) => {
13+ const registration = { update : jest . fn ( ) } ;
14+
15+ const stopPolling = startPWAUpdatePolling ( registration , {
16+ intervalMs : 1_000 ,
17+ isVisible : ( ) => true ,
18+ } ) ;
19+
20+ expect ( registration . update ) . toHaveBeenCalledTimes ( 1 ) ;
21+
22+ jest . advanceTimersByTime ( 2_000 ) ;
23+
24+ expect ( registration . update ) . toHaveBeenCalledTimes ( 3 ) ;
25+
26+ stopPolling ( ) ;
27+ jest . advanceTimersByTime ( 1_000 ) ;
28+
29+ expect ( registration . update ) . toHaveBeenCalledTimes ( 3 ) ;
30+ } ) ;
31+
32+ it ( 'skips update checks while the tab is hidden' , ( ) => {
33+ const registration = { update : jest . fn ( ) } ;
34+
35+ startPWAUpdatePolling ( registration , {
36+ intervalMs : 1_000 ,
37+ isVisible : ( ) => false ,
38+ } ) ;
39+
40+ jest . advanceTimersByTime ( 2_000 ) ;
41+
42+ expect ( registration . update ) . not . toHaveBeenCalled ( ) ;
43+ } ) ;
44+ } ) ;
Original file line number Diff line number Diff line change 1+ export const PWA_UPDATE_CHECK_INTERVAL_MS = 60_000 ;
2+
3+ type UpdateableServiceWorkerRegistration = Pick < ServiceWorkerRegistration , 'update' > ;
4+
5+ interface StartPWAUpdatePollingOptions {
6+ intervalMs ?: number ;
7+ isVisible ?: ( ) => boolean ;
8+ }
9+
10+ export function startPWAUpdatePolling (
11+ registration : UpdateableServiceWorkerRegistration ,
12+ {
13+ intervalMs = PWA_UPDATE_CHECK_INTERVAL_MS ,
14+ isVisible = ( ) => document . visibilityState === 'visible' ,
15+ } : StartPWAUpdatePollingOptions = { } ,
16+ ) {
17+ const checkForUpdate = ( ) => {
18+ if ( isVisible ( ) ) {
19+ void registration . update ( ) ;
20+ }
21+ } ;
22+
23+ checkForUpdate ( ) ;
24+
25+ const intervalId = window . setInterval ( checkForUpdate , intervalMs ) ;
26+
27+ return ( ) => window . clearInterval ( intervalId ) ;
28+ }
Original file line number Diff line number Diff line change 11import { registerSW } from 'virtual:pwa-register' ;
22import { useEffect , useRef , useState } from 'react' ;
3+ import { startPWAUpdatePolling } from './pwaUpdatePolling' ;
34
45export function usePWAUpdate ( ) {
56 const [ updateAvailable , setUpdateAvailable ] = useState ( false ) ;
67 const updateSWRef = useRef < ( reloadPage ?: boolean ) => Promise < void > > ( ) ;
8+ const stopUpdatePollingRef = useRef < ( ) => void > ( ) ;
79
810 useEffect ( ( ) => {
911 if ( ! import . meta. env . PROD ) {
1012 return ;
1113 }
1214
1315 updateSWRef . current = registerSW ( {
16+ immediate : true ,
1417 onNeedRefresh ( ) {
1518 setUpdateAvailable ( true ) ;
1619 } ,
20+ onRegisteredSW ( _swUrl , registration ) {
21+ if ( ! registration ) {
22+ return ;
23+ }
24+
25+ stopUpdatePollingRef . current ?.( ) ;
26+ stopUpdatePollingRef . current = startPWAUpdatePolling ( registration ) ;
27+ } ,
1728 onOfflineReady ( ) {
1829 // optionally notify
1930 } ,
2031 } ) ;
32+
33+ return ( ) => {
34+ stopUpdatePollingRef . current ?.( ) ;
35+ } ;
2136 } , [ ] ) ;
2237
2338 const updateSW = async ( reloadPage = true ) => {
Original file line number Diff line number Diff line change @@ -27,7 +27,7 @@ export default defineConfig({
2727 viteTsconfigPaths ( ) ,
2828 ViteYaml ( ) ,
2929 VitePWA ( {
30- registerType : 'autoUpdate ' ,
30+ registerType : 'prompt ' ,
3131 workbox : {
3232 importScripts : [ 'notification-sw.js' ] ,
3333 } ,
You can’t perform that action at this time.
0 commit comments