Skip to content

WebSocketConnector

Defined in: packages/client/src/lib/connection-manager/connectors/web-socket-connector.ts:131

WebSocket connector for real-time bidirectional communication.

This connector is a thin wrapper around the WebSocket API. It:

  • Opens/closes WebSocket connections
  • Sends/receives messages with request/response correlation
  • Reports transport events via subscribe()

State management, retry logic, and circuit breaker patterns are handled by ConnectionManager which consumes the transport events.

import { ConnectionManager, WebSocketConnector } from '@maelstrom-co/client';
const connector = new WebSocketConnector({
url: 'wss://api.example.com/ws',
});
const manager = new ConnectionManager(store, connector);
await manager.connect(); // ConnectionManager handles state & retries

new WebSocketConnector(options): WebSocketConnector

Defined in: packages/client/src/lib/connection-manager/connectors/web-socket-connector.ts:174

WebSocketConnectorOptions

WebSocketConnector

readonly capabilities: ConnectorCapabilities

Defined in: packages/client/src/lib/connection-manager/connectors/web-socket-connector.ts:141

Connector capabilities. Metadata for consumers — the ConnectionManager does not use these for flow control.

AcknowledgedAssistantConnector.capabilities

addAssistantMessage(message): Promise<void>

Defined in: packages/client/src/lib/connection-manager/connectors/web-socket-connector.ts:416

Sends an assistant message to the server. Fire-and-forget: sends the legacy assistant_message envelope, for which the server sends no result frame, and resolves after the socket accepts the send. Use addAssistantMessageAcknowledged when persistence must be confirmed before a dependent side effect. Throws if the WebSocket is not connected, construction rejects malformed content, or the socket cannot accept the send. Later Engine insertion failures are intentionally unobservable on this legacy path.

Translates the connector-facing AssistantMessage into the real assistant_message envelope via AssistantInjectionMessage so the frame goes through the same codec as every other send. The smart constructor stamps a Date.now() epoch timestamp — the previous bespoke frame used performance.now() (a monotonic clock offset from an arbitrary origin), which is not a wall-clock time. A compatible server sends no frame for insertion success or failure, so this method cannot observe either.

AssistantMessage

Promise<void>

AcknowledgedAssistantConnector.addAssistantMessage


addAssistantMessageAcknowledged(message): Promise<AssistantMessageOutcome>

Defined in: packages/client/src/lib/connection-manager/connectors/web-socket-connector.ts:343

Insert an assistant message and wait for the correlated AssistantMessageOutcome from engine.assistant_message.result.

Unlike addAssistantMessage, this sends the opt-in client.assistant_message.acknowledged envelope. A server that predates that envelope may reject it with a correlated engine.error or stay silent; those paths reject promptly or at the bounded timeout rather than being mistaken for successful persistence.

Correlation uses message.id as requestId and times out after the connector timeout (default 30s).

AssistantMessage

Promise<AssistantMessageOutcome>

If the WebSocket is disconnected or the session is not yet established, or if construction rejects malformed message content.

If WebSocket.send fails while enqueueing the frame; the pending correlator is cleared before the returned promise rejects.

If the engine reports a correlated engine.error.

If the socket closes before the result arrives, or if the acknowledgement times out.

AcknowledgedAssistantConnector.addAssistantMessageAcknowledged


connect(sessionId): Promise<void>

Defined in: packages/client/src/lib/connection-manager/connectors/web-socket-connector.ts:214

Establishes WebSocket connection. Throws on failure — ConnectionManager will handle retries.

Idempotent only for the SAME sessionId: a second call for that session while a socket is already open or connecting is a no-op (open) or joins the in-flight attempt (connecting) instead of constructing another WebSocket, since the underlying socket assignment below does not itself guard against overwriting a live one. A call with a DIFFERENT sessionId is never idempotent — it always reassigns #sessionId and dials a fresh socket, even over one that is open or connecting, because silently keeping the old session would leave #sessionId (embedded in outbound envelopes such as assistant_message) pointing at a session this call was explicitly asked to move away from.

SessionId

Promise<void>

AcknowledgedAssistantConnector.connect


disconnect(): Promise<void>

Defined in: packages/client/src/lib/connection-manager/connectors/web-socket-connector.ts:303

Closes the WebSocket connection and rejects all pending requests.

Promise<void>

AcknowledgedAssistantConnector.disconnect


getHistory(sessionId): Promise<readonly SessionHistoryEntry[]>

Defined in: packages/client/src/lib/connection-manager/connectors/web-socket-connector.ts:444

Sends a client.history.get request and waits for the correlated engine.history.response. Correlation goes through #historyCorrelator (typed for SessionHistoryEntry[]) so the response can’t be misrouted to process()’s MaelstromResponse correlator even if the freshly generated request id happens to collide with an in-flight chart request.

SessionId

Promise<readonly SessionHistoryEntry[]>

AcknowledgedAssistantConnector.getHistory


process(message): Promise<MaelstromResponse>

Defined in: packages/client/src/lib/connection-manager/connectors/web-socket-connector.ts:388

Sends a chart_request envelope and waits for the correlated response.

ChartRequestMessage

Promise<MaelstromResponse>

AcknowledgedAssistantConnector.process


subscribe(handler): Unsubscribe

Defined in: packages/client/src/lib/connection-manager/connectors/web-socket-connector.ts:378

Subscribe to transport-level events (disconnected, error).

(event) => void

Unsubscribe

AcknowledgedAssistantConnector.subscribe