@@ -148,6 +148,14 @@ class Manager extends Base {
148148 ! Neo . insideWorker && me . createWorkers ( ) ;
149149
150150 if ( navigator . serviceWorker ) {
151+ // Bind the message handler globally to ensure even "unmanaged" apps (those not using the SW addon)
152+ // can receive critical recovery commands (like 'reloadWindow') from the Service Worker.
153+ //
154+ // CRITICAL: We must bind this even if Neo.config.useServiceWorker is false.
155+ // Scenario: User visits App A (uses SW), then navigates to App B (no SW). The SW from App A
156+ // *still controls* App B (if in scope). If App B hits a version mismatch (404), the SW will
157+ // send a 'reloadWindow' command. App B must be listening to execute this recovery command,
158+ // otherwise it will crash with a blank page.
151159 navigator . serviceWorker . onmessage = me . onWorkerMessage . bind ( me ) ;
152160 me . checkServiceWorkerVersion ( )
153161 }
@@ -183,6 +191,12 @@ class Manager extends Base {
183191 }
184192
185193 /**
194+ * Proactively checks if the controlling Service Worker's version matches the client's version.
195+ * This is the primary defense against "Zombie Apps" (stale client code running against a new Service Worker).
196+ *
197+ * If a mismatch is detected, it forces a hard reload to fetch fresh assets.
198+ * Includes a throttle mechanism (via sessionStorage) to prevent infinite reload loops in case of persistent mismatches.
199+ *
186200 * @returns {Promise<void> }
187201 */
188202 async checkServiceWorkerVersion ( ) {
@@ -192,6 +206,18 @@ class Manager extends Base {
192206 } ) ;
193207
194208 if ( swVersion ?. version && swVersion . version !== Neo . config . version ) {
209+ const
210+ key = 'neoVersionReload' ,
211+ lastReload = parseInt ( sessionStorage . getItem ( key ) || '0' ) ,
212+ now = Date . now ( ) ;
213+
214+ if ( now - lastReload < 5000 ) {
215+ console . error ( 'Reload loop detected. Aborting version enforcement.' ) ;
216+ return
217+ }
218+
219+ sessionStorage . setItem ( key , String ( now ) ) ;
220+
195221 console . error ( `Version Mismatch! Client: ${ Neo . config . version } , SW: ${ swVersion . version } . Reloading.` ) ;
196222 location . reload ( true )
197223 }
0 commit comments