open-swe/ui/src/client.tsx

43 lines
1.3 KiB
TypeScript
Raw Normal View History

import { StartClient } from "@tanstack/react-start/client"
import { StrictMode, useEffect, useState } from "react"
import { hydrateRoot } from "react-dom/client"
import { registerSW } from "virtual:pwa-register"
import { PwaUpdateToast } from "@/components/PwaUpdateToast"
// Prompt-mode PWA: vite-plugin-pwa still generates a SW that precaches the
// production bundle, but it does not force skipWaiting/clientsClaim. Instead,
// the new SW waits until the user accepts the update, so open dashboard tabs
// are not reloaded mid-session. This protects in-flight agent runs and any
// unsaved text in the compose box. Skip in dev — the SW precaches production-only
// build artifacts that 404 against the dev server.
function PwaUpdateProvider() {
const [needRefresh, setNeedRefresh] = useState(false)
const [updateSW, setUpdateSW] = useState<(() => Promise<void>) | undefined>(undefined)
useEffect(() => {
if (!import.meta.env.PROD) return
const updateSWRef = registerSW({
onNeedRefresh() {
setNeedRefresh(true)
},
})
setUpdateSW(() => updateSWRef)
}, [])
return (
<PwaUpdateToast
needRefresh={needRefresh}
updateServiceWorker={updateSW}
/>
)
}
hydrateRoot(
document,
<StrictMode>
<StartClient />
<PwaUpdateProvider />
</StrictMode>
)