diff --git a/.changeset/fn-blank-page-service-worker-assets.md b/.changeset/fn-blank-page-service-worker-assets.md new file mode 100644 index 0000000000..19dfd36ecf --- /dev/null +++ b/.changeset/fn-blank-page-service-worker-assets.md @@ -0,0 +1,5 @@ +--- +"@runfusion/fusion": patch +--- + +Revalidate dashboard service-worker assets before falling back to cache so rebuilt tabs cannot stay on stale bundles and render a blank page. diff --git a/packages/dashboard/app/__tests__/pwa.test.ts b/packages/dashboard/app/__tests__/pwa.test.ts index 45fe05fac2..09ce06fafb 100644 --- a/packages/dashboard/app/__tests__/pwa.test.ts +++ b/packages/dashboard/app/__tests__/pwa.test.ts @@ -194,7 +194,7 @@ describe("PWA configuration", () => { expect(swSource).toContain('addEventListener("install"'); expect(swSource).toContain('addEventListener("fetch"'); expect(swSource).toContain('addEventListener("activate"'); - expect(swSource).toContain('const CACHE_NAME = "fusion-cache-v4";'); + expect(swSource).toContain('const CACHE_NAME = "fusion-cache-v5";'); }); it("service worker bypasses SSE requests instead of trying to cache them", () => { @@ -316,7 +316,7 @@ describe("PWA configuration", () => { expect(indexHtml).toContain(''); expect(indexHtml).toContain(''); - expect(swSource).toContain('const CACHE_NAME = "fusion-cache-v4";'); + expect(swSource).toContain('const CACHE_NAME = "fusion-cache-v5";'); }); }); }); diff --git a/packages/dashboard/app/public/sw.js b/packages/dashboard/app/public/sw.js index 9f53c68c68..dbd20849e5 100644 --- a/packages/dashboard/app/public/sw.js +++ b/packages/dashboard/app/public/sw.js @@ -1,4 +1,4 @@ -const CACHE_NAME = "fusion-cache-v4"; +const CACHE_NAME = "fusion-cache-v5"; const APP_SHELL_URLS = [ "/", "/index.html", diff --git a/packages/dashboard/app/versionCheck.ts b/packages/dashboard/app/versionCheck.ts index 7676c3f031..794baa1ada 100644 --- a/packages/dashboard/app/versionCheck.ts +++ b/packages/dashboard/app/versionCheck.ts @@ -240,7 +240,8 @@ export async function checkVersion(trigger: VersionCheckTrigger = "initial"): Pr } catch { // ignore } - if (autoReloadEnabled) { + const alreadyAttempted = Boolean((() => { try { return sessionStorage.getItem(RELOAD_FLAG); } catch { return null; } })()); + if (autoReloadEnabled && !alreadyAttempted) { setReloadedRemoteVersion(remote); } reloadOnce(`build version changed: ${__BUILD_VERSION__} -> ${remote}`);