5-way navigation for React and SolidJS
0

Configure Feed

Select the types of activity you want to include in your feed.

inspector: add reconnect

authored by

Pavel Hrách and committed by
Pavel Hrách
(Apr 29, 2026, 5:03 PM +0200) b36fbeac c7bcc7e8

+69 -25
+47 -23
packages/fiveway-inspector/assets/connect.js
··· 1 - const remoteUrl = new URL("/ws/client", document.currentScript.src); 2 - remoteUrl.protocol = "ws:"; 3 - remoteUrl.searchParams.set("title", document.title); 4 - remoteUrl.searchParams.set("url", window.location.href); 1 + (() => { 2 + const RETRY_INTERVAL = 5000; 3 + const remoteUrl = new URL("/ws/client", document.currentScript.src); 4 + remoteUrl.protocol = "ws:"; 5 5 6 - const ws = new WebSocket(remoteUrl); 6 + let ws; 7 7 8 - ws.addEventListener("message", (event) => { 9 - const data = JSON.parse(event.data); 10 - window.postMessage(data); 11 - }); 8 + function connect() { 9 + remoteUrl.searchParams.set("title", document.title); 10 + remoteUrl.searchParams.set("url", window.location.href); 12 11 13 - window.addEventListener("message", (event) => { 14 - if (ws.readyState !== WebSocket.OPEN) { 15 - return; 16 - } 12 + try { 13 + ws = new WebSocket(remoteUrl); 14 + } catch { 15 + setTimeout(() => { 16 + ws = null; 17 + connect(); 18 + }, RETRY_INTERVAL); 19 + } 17 20 18 - const message = event.data; 21 + ws.addEventListener("message", (event) => { 22 + const data = JSON.parse(event.data); 23 + window.postMessage(data); 24 + }); 19 25 20 - if ( 21 - typeof message === "object" && 22 - message != null && 23 - "type" in message && 24 - message.type.startsWith("fiveway:") && 25 - message.type !== "fiveway:command" 26 - ) { 27 - ws.send(JSON.stringify(message)); 26 + ws.addEventListener("close", () => { 27 + ws = null; 28 + setTimeout(() => { 29 + connect(); 30 + }, RETRY_INTERVAL); 31 + }); 28 32 } 29 - }); 33 + 34 + connect(); 35 + 36 + window.addEventListener("message", (event) => { 37 + if (ws == null || ws.readyState !== WebSocket.OPEN) { 38 + return; 39 + } 40 + 41 + const message = event.data; 42 + 43 + if ( 44 + typeof message === "object" && 45 + message != null && 46 + "type" in message && 47 + message.type.startsWith("fiveway:") && 48 + message.type !== "fiveway:command" 49 + ) { 50 + ws.send(JSON.stringify(message)); 51 + } 52 + }); 53 + })();
+19 -2
packages/fiveway-inspector/src/routes/inspect/[id].tsx
··· 1 1 import { type InspectorCommand, type InspectorMessage } from "@fiveway/core"; 2 2 import { useParams } from "@solidjs/router"; 3 + import { createSignal, Show } from "solid-js"; 3 4 4 5 import { devtoolsContext, createDevtoolsContext } from "../../inspector/context.ts"; 5 6 import { InspectorPanel } from "../../inspector/ui/InspectorPanel.tsx"; 6 7 7 8 export default function InspectorPage() { 8 9 const { id } = useParams(); 10 + const [isDisconnected, setDisconnected] = createSignal(false); 9 11 10 - const connection = createInspectorConnection(id!); 12 + const connection = createInspectorConnection(id!, () => setDisconnected(true)); 11 13 const context = createDevtoolsContext(connection); 12 14 13 15 return ( 14 16 <> 15 17 <main> 18 + <Show when={isDisconnected()}> 19 + <div class="absolute inset-0 flex flex-col items-center justify-center h-full"> 20 + <h1 class="text-2xl font-bold">Client disconnected</h1> 21 + <p class="text-gray-500">The client has disconnected from the inspector.</p> 22 + </div> 23 + </Show> 16 24 <devtoolsContext.Provider value={context}> 17 25 <InspectorPanel /> 18 26 </devtoolsContext.Provider> ··· 21 29 ); 22 30 } 23 31 24 - function createInspectorConnection(id: string) { 32 + function createInspectorConnection(id: string, onDisconnect: () => void) { 25 33 let ws: WebSocket; 26 34 27 35 const queue: string[] = []; ··· 38 46 }); 39 47 40 48 ws.addEventListener("message", (event) => { 49 + if (event.data === JSON.stringify({ type: "client-disconnected" })) { 50 + onDisconnect(); 51 + return; 52 + } 53 + 41 54 callback(JSON.parse(event.data)); 55 + }); 56 + 57 + ws.addEventListener("close", () => { 58 + onDisconnect(); 42 59 }); 43 60 44 61 return () => {
+3
packages/fiveway-inspector/src/routes/ws/client.ts
··· 20 20 }); 21 21 22 22 peer.subscribe("commands"); 23 + 24 + peer.send(JSON.stringify({ type: "setId", id: peer.namespace })); 23 25 }, 24 26 25 27 message(peer, message) { ··· 27 29 }, 28 30 29 31 close(peer) { 32 + peer.publish("updates", JSON.stringify({ type: "client-disconnected" })); 30 33 unregisterClient(peer.namespace); 31 34 }, 32 35 });