()
| 133 | } |
| 134 | |
| 135 | public async connect(): Promise<void> { |
| 136 | if (this.state !== 'idle' && this.state !== 'reconnecting') { |
| 137 | logForDebugging( |
| 138 | `WebSocketTransport: Cannot connect, current state is ${this.state}`, |
| 139 | { level: 'error' }, |
| 140 | ) |
| 141 | logForDiagnosticsNoPII('error', 'cli_websocket_connect_failed') |
| 142 | return |
| 143 | } |
| 144 | this.state = 'reconnecting' |
| 145 | |
| 146 | this.connectStartTime = Date.now() |
| 147 | logForDebugging(`WebSocketTransport: Opening ${this.url.href}`) |
| 148 | logForDiagnosticsNoPII('info', 'cli_websocket_connect_opening') |
| 149 | |
| 150 | // Start with provided headers and add runtime headers |
| 151 | const headers = { ...this.headers } |
| 152 | if (this.lastSentId) { |
| 153 | headers['X-Last-Request-Id'] = this.lastSentId |
| 154 | logForDebugging( |
| 155 | `WebSocketTransport: Adding X-Last-Request-Id header: ${this.lastSentId}`, |
| 156 | ) |
| 157 | } |
| 158 | |
| 159 | if (typeof Bun !== 'undefined') { |
| 160 | // Bun's WebSocket supports headers/proxy options but the DOM typings don't |
| 161 | // eslint-disable-next-line eslint-plugin-n/no-unsupported-features/node-builtins |
| 162 | const ws = new globalThis.WebSocket(this.url.href, { |
| 163 | headers, |
| 164 | proxy: getWebSocketProxyUrl(this.url.href), |
| 165 | tls: getWebSocketTLSOptions() || undefined, |
| 166 | } as unknown as string[]) |
| 167 | this.ws = ws |
| 168 | this.isBunWs = true |
| 169 | |
| 170 | ws.addEventListener('open', this.onBunOpen) |
| 171 | ws.addEventListener('message', this.onBunMessage) |
| 172 | ws.addEventListener('error', this.onBunError) |
| 173 | // eslint-disable-next-line eslint-plugin-n/no-unsupported-features/node-builtins |
| 174 | ws.addEventListener('close', this.onBunClose) |
| 175 | // 'pong' is Bun-specific — not in DOM typings. |
| 176 | ws.addEventListener('pong', this.onPong) |
| 177 | } else { |
| 178 | const { default: WS } = await import('ws') |
| 179 | const ws = new WS(this.url.href, { |
| 180 | headers, |
| 181 | agent: getWebSocketProxyAgent(this.url.href), |
| 182 | ...getWebSocketTLSOptions(), |
| 183 | }) |
| 184 | this.ws = ws |
| 185 | this.isBunWs = false |
| 186 | |
| 187 | ws.on('open', this.onNodeOpen) |
| 188 | ws.on('message', this.onNodeMessage) |
| 189 | ws.on('error', this.onNodeError) |
| 190 | ws.on('close', this.onNodeClose) |
| 191 | ws.on('pong', this.onPong) |
| 192 | } |
no test coverage detected