DocsRoid RunnerHub & Commands

Hub & Commands

RoidHubWS — the WebSocket client singleton that connects to the backend Roid Hub, handles reconnection, and routes inbound messages to registered callbacks. RoidHubCommand — stateless helper functions that send typed commands to the hub.

RoidHubWS

A class-based WebSocket wrapper exported as a module-level singleton via getRoidHubWS(). The singleton pattern ensures that all parts of the application share the same connection. Calling resetRoidHubWS() destroys the current instance and creates a fresh one — used by the disconnect flow to guarantee a clean state.

Constructor Config

OptionDefaultDescription
wsUrlVITE_HUB_WS_URL env varWebSocket server URL. Query params user_id and ticket are appended when non-empty.
reconnectInterval3 000 msBase delay between reconnect attempts. Each attempt doubles the delay (exponential backoff), capped at 30 000 ms.
maxReconnectAttemptsInfinityMaximum number of consecutive reconnect attempts. When reached, reconnection stops silently.
connectionTimeout10 000 msHow long to wait for the WebSocket open event before aborting and attempting a reconnect.

Public API

connect(): void

Creates the WebSocket connection. Noop if already OPEN or CONNECTING. Sets isIntentionallyClosed = false so auto-reconnect is active.

disconnect(): void

Closes the socket and clears timers. Sets isIntentionallyClosed = true so the onclose handler does NOT trigger a reconnect. Also clears the message callback to prevent stale deliveries.

isConnected(): boolean

Returns true when readyState === WebSocket.OPEN.

sendCommand(command: object): void

JSON-serialises the command object and sends it over the socket. Logs an error and returns silently if not connected.

setMessageCallback(cb): void

Registers the inbound message handler. Called with a parsed HubMessage on every text or Blob frame received. Blob frames are converted to text asynchronously before parsing.

setConnectionStatusCallback(cb): void

Called with (true) on successful open; called with (false, reason) on close or timeout.

getUserId(): string

Returns the current authenticated user id (used to populate the from field on outbound commands).

Singleton helpers

getRoidHubWS()

Returns the current singleton, creating it with default config on first call.

resetRoidHubWS()

Calls disconnect() on the current singleton, then replaces it with a fresh instance. Used by handleDisconnect in RoidRunnerPanel.

Reconnect Strategy

1

Connection fails (onclose fires while isIntentionallyClosed = false) or connection timeout fires.

2

handleReconnect() is called. reconnectAttempts is incremented.

3

Delay = min(reconnectInterval × 2^(attempts-1), 30 000 ms). A setTimeout schedules createConnection().

4

On success, reconnectAttempts resets to 0 and connectionStatusCallback(true) fires.

5

If maxReconnectAttempts is reached, reconnection stops. Panel shows disconnected status.

HubMessage type

export interface HubMessage {
  cmd: string;           // Command identifier (run_roid, kill_roid, roid_output, …)
  [key: string]: unknown; // Additional payload fields vary by cmd
}

// Common outbound command shape:
{
  cmd:  string,   // e.g. "run_roid" | "kill_roid" | "get_roids" | "get_bars"
  from: string,   // user_id
  to?:  string,   // roid_id (when targeting a specific process)
  data?: unknown  // payload (e.g. slang source string for run_roid)
}

RoidHubCommand

Pure functions that call hub.sendCommand() with the correct payload shape. All accept the hub instance and userId as their first two arguments, keeping the command module stateless and independently testable.

Functioncmd sentExtra payloadPurpose
sendRunSlang(hub, slang, userId)run_roiddata: slang stringDispatch the current graph's decompiled Slang to the hub to start a new roid process.
sendKillRoid(hub, userId, roidId)kill_roidto: roidIdTerminate a running roid process by ID.
sendGetRoids(hub, userId)get_roids(none)Request the current list of running roid processes for this user.
sendGetBars(hub, userId, roidId)get_barsto: roidIdRequest the full cached bar and output history for a roid.
sendGetNodes(hub, userId, roidId)get_nodesto: roidIdRequest the output node name list for a roid.
sendGetSlang(hub, userId, roidId)get_slangto: roidIdRequest the Slang source code for a roid (to display in SlangViewerModal).

RoidRunnerHeader

A 36 px toolbar bar that shows the Roid Runner label with a live connection dot, and four action buttons. It also owns the Run flow: decompile → validate → send.

Props

PropTypeDescription
theme'light' | 'dark'Controls button colours and border tones.
connectedbooleanDrives the green/red status dot and enables/disables buttons.
hubRoidHubWSThe hub singleton; used to send commands from the header.
onLog(entry: LogEntry) => voidAppend a log entry to the panel logger.
onConnect() => voidCalled when the Connect button is clicked.
onDisconnect() => voidCalled when the Disconnect button is clicked.
onGetRoids() => voidCalled when the Refresh button is clicked.

Run Flow

1

decompile({ excludeConfig: true }) is called. If the result is empty, an error is logged and the flow aborts.

2

The decompiled Slang source is logged line-by-line as "request" entries (blue in the logger).

3

validateSlang(slang) is called. Any validation errors are logged and the flow aborts.

4

sendRunSlang(hub, slang, userId) sends the cmd: "run_roid" message to the hub.

5

The hub responds with a run_roid message; the panel appends the new roid and auto-selects it.

Button states

ButtonEnabled whenActive colour
Connect!connected#3b82f6 (blue)
Run ▶connected#22c55e (green)
Refresh ⟳connected#6366f1 (indigo)
Disconnectconnected#ef4444 (red)