|
1 | 1 | import "preact/debug"; |
2 | 2 | export * from "./mod.ts"; |
3 | | -import { IS_BROWSER } from "../shared.ts"; |
4 | | - |
5 | | -let ws: WebSocket; |
6 | | -let revision = 0; |
7 | | - |
8 | | -let reconnectTimer: number; |
9 | | -const backoff = [ |
10 | | - // Wait 100ms initially, because we could also be |
11 | | - // disconnected because of a form submit. |
12 | | - 100, |
13 | | - 150, |
14 | | - 200, |
15 | | - 250, |
16 | | - 300, |
17 | | - 350, |
18 | | - 400, |
19 | | - 450, |
20 | | - 500, |
21 | | - 500, |
22 | | - 605, |
23 | | - 750, |
24 | | - 1000, |
25 | | - 1250, |
26 | | - 1500, |
27 | | - 1750, |
28 | | - 2000, |
29 | | -]; |
30 | | -let backoffIdx = 0; |
31 | | -function reconnect() { |
32 | | - if (ws.readyState !== ws.CLOSED) return; |
33 | | - |
34 | | - reconnectTimer = setTimeout(() => { |
35 | | - if (backoffIdx === 0) { |
36 | | - // deno-lint-ignore no-console |
37 | | - console.log( |
38 | | - `%c Fresh %c Connection closed. Trying to reconnect...`, |
39 | | - "background-color: #86efac; color: black", |
40 | | - "color: inherit", |
41 | | - ); |
42 | | - } |
43 | | - backoffIdx++; |
44 | | - |
45 | | - try { |
46 | | - connect(); |
47 | | - clearTimeout(reconnectTimer); |
48 | | - } catch (_err) { |
49 | | - reconnect(); |
50 | | - } |
51 | | - }, backoff[Math.min(backoffIdx, backoff.length - 1)]); |
52 | | -} |
53 | | - |
54 | | -function onOpenWs() { |
55 | | - backoffIdx = 0; |
56 | | -} |
57 | | - |
58 | | -function onCloseWs() { |
59 | | - disconnect(); |
60 | | - reconnect(); |
61 | | -} |
62 | | - |
63 | | -function connect() { |
64 | | - const url = new URL("/_frsh/alive", location.origin.replace("http", "ws")); |
65 | | - ws = new WebSocket( |
66 | | - url, |
67 | | - ); |
68 | | - |
69 | | - ws.addEventListener("open", onOpenWs); |
70 | | - ws.addEventListener("close", onCloseWs); |
71 | | - ws.addEventListener("message", handleMessage); |
72 | | - ws.addEventListener("error", handleError); |
73 | | -} |
74 | | - |
75 | | -function disconnect() { |
76 | | - ws.removeEventListener("open", onOpenWs); |
77 | | - ws.removeEventListener("close", onCloseWs); |
78 | | - ws.removeEventListener("message", handleMessage); |
79 | | - ws.removeEventListener("error", handleError); |
80 | | - ws.close(); |
81 | | -} |
82 | | - |
83 | | -function handleMessage(e: MessageEvent) { |
84 | | - const data = JSON.parse(e.data); |
85 | | - switch (data.type) { |
86 | | - case "initial-state": { |
87 | | - if (revision === 0) { |
88 | | - // deno-lint-ignore no-console |
89 | | - console.log( |
90 | | - `%c Fresh %c Connected to development server.`, |
91 | | - "background-color: #86efac; color: black", |
92 | | - "color: inherit", |
93 | | - ); |
94 | | - } |
95 | | - |
96 | | - if (revision === 0) { |
97 | | - revision = data.revision; |
98 | | - } else if (revision < data.revision) { |
99 | | - disconnect(); |
100 | | - // Needs reload |
101 | | - location.reload(); |
102 | | - } |
103 | | - } |
104 | | - } |
105 | | -} |
106 | | - |
107 | | -function handleError(e: Event) { |
108 | | - // TODO |
109 | | - // deno-lint-ignore no-explicit-any |
110 | | - if (e && (e as any).code === "ECONNREFUSED") { |
111 | | - setTimeout(connect, 1000); |
112 | | - } |
113 | | -} |
114 | | - |
115 | | -if (IS_BROWSER) { |
116 | | - connect(); |
117 | | - |
118 | | - addEventListener("message", (ev) => { |
119 | | - if (ev.origin !== location.origin) return; |
120 | | - if (typeof ev.data !== "string" || ev.data !== "close-error-overlay") { |
121 | | - return; |
122 | | - } |
123 | | - |
124 | | - document.querySelector("#fresh-error-overlay")?.remove(); |
125 | | - }); |
126 | | - |
127 | | - // Disconnect when the tab becomes inactive and re-connect when it |
128 | | - // becomes active again |
129 | | - addEventListener("visibilitychange", () => { |
130 | | - if (document.hidden) { |
131 | | - disconnect(); |
132 | | - } else { |
133 | | - connect(); |
134 | | - } |
135 | | - }); |
136 | | -} |
| 3 | +export * from "./dev_hmr.ts"; |
0 commit comments