Neale Pickett
·
2024-12-20
update-reload.mjs
1import {Toast} from "./toast.mjs"
2
3/** Reload the page when there's an update.
4 *
5 * The server provides Server-Sourced Events (SSEs) to notify clients that some resource has changed.
6 * Currently this is a coarse "something has changed" signal,
7 * which seems to be good enough.
8 *
9 * In addition, this will detect when the server has stopped,
10 * and reload the page once the server becomes available again.
11 */
12
13const Millisecond = 1
14const Second = 1000 * Millisecond
15const UpdateURL = new URL("../-/state/updates", import.meta.url)
16
17function MonitorUpdates(reload=false) {
18 let evtSource = new EventSource(UpdateURL)
19 evtSource.addEventListener("error", event => {
20 evtSource.close()
21 setTimeout(() => MonitorUpdates(true), 5 * Second)
22 })
23 evtSource.addEventListener("open", event => {
24 if (reload) {
25 // Give the server 2s to finish building.
26 // if it does finish before the 2s ends, it will send us an update message.
27 Toast("Server restarted - reloading...")
28 setTimeout(() => location.reload(), 2 * Second)
29 }
30 })
31 evtSource.addEventListener("update", event => {
32 let errors = false
33 for (let line of event.data.split("\n")) {
34 Toast(line)
35 if (line.startsWith("error:")) {
36 errors = true
37 }
38 }
39 if (!errors) {
40 location.reload()
41 }
42 })
43}
44
45MonitorUpdates()