MCPcopy Create free account
hub / github.com/block/buzz / RelayClient

Class RelayClient

desktop/src/shared/api/relayClientSession.ts:53–1016  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

51const STALL_IDLE_TIMEOUT_MS = 60_000;
52
53export class RelayClient {
54 private wsId: number | null = null;
55 private relayUrl: string | null = null;
56 private connectPromise: Promise<void> | null = null;
57 private reconnectTimeout: number | null = null;
58 private reconnectDelayMs = RECONNECT_BASE_DELAY_MS;
59 private keepAliveRequested = false;
60 private authRequest: {
61 pendingEventId: string;
62 resolve: () => void;
63 reject: (error: Error) => void;
64 timeout: number;
65 } | null = null;
66 private subscriptions = new Map<string, RelaySubscription>();
67 private pendingEvents = new Map<string, PendingEvent>();
68 private eventBuffer: Array<{ subId: string; event: RelayEvent }> = [];
69 private flushTimeout: number | null = null;
70 private reconnectListeners = new Set<() => void>();
71 private hasConnectedOnce = false;
72 private notifyReconnectListeners = false;
73 private onMessageChannel: Channel<unknown> | null = null;
74 private connectionGeneration = 0;
75
76 /**
77 * Sticky terminal flag. Set when `resetConnection` is called with
78 * `reconnect: false` (today: auth rejection). Acts as a hard guard against
79 * the reconnect-timer / retry-wrapper paths racing back to "reconnecting"
80 * after we've already declared the session dead.
81 *
82 * Cleared only on explicit user re-engagement: `disconnect()` (workspace
83 * switch — the singleton is being reused for a different workspace) and
84 * `preconnect()` (caller is asking us to come back up).
85 */
86 private terminal = false;
87
88 private connectionStateEmitter = new RelayConnectionStateEmitter("idle");
89 private stallWatchdog = new RelayStallWatchdog({
90 intervalMs: STALL_CHECK_INTERVAL_MS,
91 idleTimeoutMs: STALL_IDLE_TIMEOUT_MS,
92 onStall: (error) => {
93 this.connectionStateEmitter.set("stalled");
94 this.resetConnection(error);
95 },
96 });
97
98 /**
99 * Cleanly tear down the connection without scheduling a reconnect.
100 * Used during workspace switches to reset the singleton before the
101 * new workspace applies.
102 */
103 disconnect() {
104 const error = new Error("Relay disconnected for workspace switch.");
105
106 if (this.reconnectTimeout) {
107 window.clearTimeout(this.reconnectTimeout);
108 this.reconnectTimeout = null;
109 }
110 this.stallWatchdog.stop();

Callers

nothing calls this directly

Calls 2

resetConnectionMethod · 0.95
setMethod · 0.80

Tested by

no test coverage detected