* Recover from a stale build after boot (lazy-chunk 404s)
When the app stays open across a Home Assistant upgrade, the previous
build's content-hashed lazy chunks are deleted, so opening a dialog,
more-info, card, or panel that was not yet loaded 404s. Today that
dead-ends: dialogs fail silently, panels show a Back-only error screen.
Add a shared recovery authority (recover-stale-build.ts): detect a stale
hashed-chunk load failure and either reload onto the current build (drop
the service worker + caches, cache-busting nav, one-shot cooldown guard)
or, when an editor has unsaved changes, show a non-dismissable toast that
reloads once the dirty state clears. Hook it into the global
error/unhandledrejection handlers, the router's swallowed load error, and
give hass-error-screen a reload action. Chunk-error patterns come from a
JSON single source shared with the boot guard.
Part of home-assistant/epics#113.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* Wire stale-build recovery into more paths, add tests
- make-dialog-manager: don't cache a rejected dialog import, so a stale
chunk 404 (or transient failure) no longer permanently breaks that
dialog until a full page reload — a later open re-imports.
- home-assistant: _checkUpdate now uses reloadFresh() instead of the
no-longer-effective location.reload(true) (forceGet is ignored by
modern browsers).
- connection-mixin: drop the dead reload(true) forceGet arg on the
safe_mode reload.
- Add unit tests for isStaleBuildError and the recoverFromStaleBuild
clean / dirty / dev-demo / non-stale / loop-guard branches.
Part of home-assistant/epics#113.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* Recover in the companion app via the reload_and_clear_cache command
The iOS/Android companion app (WKWebView) has no service worker, and its
document HTTP cache is not cleared by the Cache API, so the web-level
reload path is ineffective there. When an external bus is present,
reloadFresh() now fires the native `frontend/reload_and_clear_cache`
command (shipped in home-assistant/iOS#5190) so the app purges its cache
and reloads; browsers still take the web path.
Adds the outgoing message type and extracts the bus transport into an
exported fireExternalBusMessage() so it can be sent without a hass/bus
reference.
Closes#53405. Part of home-assistant/epics#113.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* Address Copilot review feedback
- reloadFresh: only send frontend/reload_and_clear_cache to the WebKit
(iOS) bridge; Android and browsers take the service-worker + cache-clear
path (Android's WebView has a service worker). Fail closed when the
sessionStorage cooldown marker can't be persisted so it can't loop. Return
whether a reload was actually started, so a guard-blocked failure is still
surfaced/logged instead of silently swallowed.
- Add a dirty-aware reloadForUpdate() and route _checkUpdate and the error
screen's Refresh button through it; drop the dirty toast's immediate
action (it auto-reloads once changes are saved/discarded).
- Set showReload on the error-screen element at the call site so router
overrides (e.g. ToolsRouter) can't drop it.
- Tests: exercise the WebKit bridge and the SW/cache-clear branch; assert
the dirty toast has no reload action.
Part of home-assistant/epics#113.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
* Save default panel in user data
* Change logic for default panel
* Fix types
* Fix typings
* Fix user and local storage
* Use user data and system data
* Update url path and update dashboard settings
* Fix tests
* Wait for panels and user/system data to be loaded
* Update comment
* Update comment
* Set empty object instead of null
* Update comment
* Feedbacks
* Apply suggestions from code review
* format
---------
Co-authored-by: Petar Petrov <MindFreeze@users.noreply.github.com>