fix(kiosk): no reload on first service-worker claim + patient boot health check
Two causes of the fresh-install 'loads, refreshes, loads again' jank: - The PWA autoUpdate service worker claims the page right after the very first load, firing controllerchange, which unconditionally reloaded the page. Now only a *replaced* controller (a real update) triggers reload. - A single 2s RPC echo decided server-down on first boot, flashing the BootScreen and then hard-reloading seconds later. A second, 6s attempt now runs before concluding the backend is down. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
fa91faa67c
commit
66fd121748
@ -32,8 +32,18 @@ let updateCallback: (() => Promise<void>) | null = null
|
||||
onMounted(() => {
|
||||
// Listen for service worker updates
|
||||
if ('serviceWorker' in navigator) {
|
||||
// On the very first visit the page loads with no controlling SW; the
|
||||
// freshly-installed worker then activates and claims the page
|
||||
// (autoUpdate → clientsClaim), firing controllerchange. Reloading on
|
||||
// that first claim caused the fresh-install "loads, then reloads"
|
||||
// jank (worst on kiosk). Only reload when an existing controller is
|
||||
// REPLACED — i.e. a genuine update.
|
||||
let hadController = !!navigator.serviceWorker.controller
|
||||
navigator.serviceWorker.addEventListener('controllerchange', () => {
|
||||
// Service worker updated, reload the page
|
||||
if (!hadController) {
|
||||
hadController = true
|
||||
return
|
||||
}
|
||||
window.location.reload()
|
||||
})
|
||||
|
||||
|
||||
@ -40,10 +40,10 @@ function log(msg: string, data?: unknown) {
|
||||
sessionStorage.setItem('archipelago_boot_log', prev + entry + '\n')
|
||||
}
|
||||
|
||||
async function quickHealthCheck(): Promise<boolean> {
|
||||
async function quickHealthCheck(timeoutMs = 2000): Promise<boolean> {
|
||||
try {
|
||||
const ac = new AbortController()
|
||||
const t = setTimeout(() => ac.abort(), 2000)
|
||||
const t = setTimeout(() => ac.abort(), timeoutMs)
|
||||
const res = await fetch('/rpc/v1', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
@ -132,7 +132,16 @@ onMounted(async () => {
|
||||
return
|
||||
}
|
||||
|
||||
const isUp = await quickHealthCheck()
|
||||
// First-boot backends can be up but slow (image loads, first-run podman
|
||||
// work), so a single 2s echo timing out used to flash the BootScreen and
|
||||
// then hard-reload seconds later ("loads, refreshes, loads again" on
|
||||
// kiosk). Give it a second, more patient attempt before concluding the
|
||||
// server is down.
|
||||
let isUp = await quickHealthCheck()
|
||||
if (!isUp) {
|
||||
log('healthCheck retry with longer timeout')
|
||||
isUp = await quickHealthCheck(6000)
|
||||
}
|
||||
log('production flow', { isUp })
|
||||
|
||||
if (isUp) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user