| 70 | * ACK/COK responses in the HTTP response body. |
| 71 | */ |
| 72 | export class HttpRelayTransport { |
| 73 | // relayUrl, clusterId, and timeoutMs are always populated (default |
| 74 | // applied below for timeoutMs); logger remains optional. |
| 75 | private readonly config: { |
| 76 | relayUrl: string; |
| 77 | clusterId: string; |
| 78 | timeoutMs: number; |
| 79 | logger?: Logger; |
| 80 | }; |
| 81 | private readonly eventHandlers: Map<TransportEvent, Set<EventHandler>> = new Map(); |
| 82 | private readonly log: Logger; |
| 83 | private connected = false; |
| 84 | |
| 85 | constructor(config: HttpRelayTransportConfig) { |
| 86 | if (!config.clusterId) { |
| 87 | // Fail loudly at construction time. A late 400 from the relay is |
| 88 | // harder to diagnose than an Error here pointing at the source. |
| 89 | throw new Error('[HttpRelayTransport] clusterId is required'); |
| 90 | } |
| 91 | this.config = { |
| 92 | timeoutMs: 10_000, |
| 93 | ...config, |
| 94 | }; |
| 95 | this.log = config.logger ?? noopLogger; |
| 96 | } |
| 97 | |
| 98 | // ─── Transport interface ────────────────────────────────────────────────── |
| 99 | |
| 100 | /** Always resolves immediately — no persistent connection needed. */ |
| 101 | async connect(): Promise<void> { |
| 102 | this.connected = true; |
| 103 | // Emit 'open' asynchronously so callers can attach handlers after connect(). |
| 104 | setTimeout(() => this.emit('open', undefined), 0); |
| 105 | } |
| 106 | |
| 107 | /** Marks the transport as disconnected. */ |
| 108 | disconnect(): void { |
| 109 | this.connected = false; |
| 110 | this.emit('close', undefined); |
| 111 | } |
| 112 | |
| 113 | /** Returns true if connect() has been called and disconnect() has not. */ |
| 114 | isConnected(): boolean { |
| 115 | return this.connected; |
| 116 | } |
| 117 | |
| 118 | /** |
| 119 | * Sends an NHP packet to the relay and delivers the response via the |
| 120 | * 'message' event. |
| 121 | * |
| 122 | * @throws Error if the relay returns a non-200 status or the request times |
| 123 | * out. |
| 124 | */ |
| 125 | async send(data: Uint8Array): Promise<void> { |
| 126 | if (!this.connected) { |
| 127 | throw new Error('[HttpRelayTransport] not connected'); |
| 128 | } |
| 129 |
nothing calls this directly
no outgoing calls
no test coverage detected