22 * WebSocket client for real-time event streaming
33 */
44
5- import WebSocket from 'ws' ;
65import { Event , ConversationCallbackType } from '../types/base' ;
76
7+ // Use native WebSocket in browser, ws library in Node.js
8+ const WebSocketImpl = ( ( ) => {
9+ if ( typeof window !== 'undefined' && window . WebSocket ) {
10+ // Browser environment
11+ return window . WebSocket ;
12+ } else {
13+ // Node.js environment
14+ try {
15+ const ws = require ( 'ws' ) ;
16+ return ws ;
17+ } catch ( e ) {
18+ throw new Error ( 'WebSocket implementation not available. Install ws package for Node.js environments.' ) ;
19+ }
20+ }
21+ } ) ( ) ;
22+
823export interface WebSocketClientOptions {
924 host : string ;
1025 conversationId : string ;
@@ -17,7 +32,7 @@ export class WebSocketCallbackClient {
1732 private conversationId : string ;
1833 private callback : ConversationCallbackType ;
1934 private apiKey ?: string ;
20- private ws ?: WebSocket ;
35+ private ws ?: any ; // WebSocket instance (browser or Node.js)
2136 private reconnectDelay = 1000 ;
2237 private maxReconnectDelay = 30000 ;
2338 private currentDelay = 1000 ;
@@ -64,38 +79,74 @@ export class WebSocketCallbackClient {
6479 // Add API key as query parameter if provided
6580 const finalUrl = this . apiKey ? `${ wsUrl } ?session_api_key=${ this . apiKey } ` : wsUrl ;
6681
67- this . ws = new WebSocket ( finalUrl ) ;
68-
69- this . ws . on ( 'open' , ( ) => {
70- console . debug ( `WebSocket connected to ${ finalUrl } ` ) ;
71- this . currentDelay = this . reconnectDelay ; // Reset delay on successful connection
72- } ) ;
73-
74- this . ws . on ( 'message' , ( data : WebSocket . Data ) => {
75- try {
76- const message = data . toString ( ) ;
77- const event : Event = JSON . parse ( message ) ;
78- this . callback ( event ) ;
79- } catch ( error ) {
80- console . error ( 'Error processing WebSocket message:' , error ) ;
81- }
82- } ) ;
83-
84- this . ws . on ( 'close' , ( code : number , reason : Buffer ) => {
85- console . debug ( `WebSocket closed: ${ code } ${ reason . toString ( ) } ` ) ;
86- this . ws = undefined ;
87-
88- if ( this . shouldReconnect ) {
89- this . scheduleReconnect ( ) ;
90- }
91- } ) ;
92-
93- this . ws . on ( 'error' , ( error : Error ) => {
94- console . debug ( 'WebSocket error:' , error ) ;
95- if ( this . shouldReconnect ) {
96- this . scheduleReconnect ( ) ;
97- }
98- } ) ;
82+ this . ws = new WebSocketImpl ( finalUrl ) ;
83+
84+ // Handle events differently for browser vs Node.js
85+ if ( typeof window !== 'undefined' ) {
86+ // Browser WebSocket API
87+ this . ws . onopen = ( ) => {
88+ console . debug ( `WebSocket connected to ${ finalUrl } ` ) ;
89+ this . currentDelay = this . reconnectDelay ; // Reset delay on successful connection
90+ } ;
91+
92+ this . ws . onmessage = ( event : MessageEvent ) => {
93+ try {
94+ const message = event . data ;
95+ const eventData : Event = JSON . parse ( message ) ;
96+ this . callback ( eventData ) ;
97+ } catch ( error ) {
98+ console . error ( 'Error processing WebSocket message:' , error ) ;
99+ }
100+ } ;
101+
102+ this . ws . onclose = ( event : CloseEvent ) => {
103+ console . debug ( `WebSocket closed: ${ event . code } ${ event . reason } ` ) ;
104+ this . ws = undefined ;
105+
106+ if ( this . shouldReconnect ) {
107+ this . scheduleReconnect ( ) ;
108+ }
109+ } ;
110+
111+ this . ws . onerror = ( error : Event ) => {
112+ console . debug ( 'WebSocket error:' , error ) ;
113+ if ( this . shouldReconnect ) {
114+ this . scheduleReconnect ( ) ;
115+ }
116+ } ;
117+ } else {
118+ // Node.js ws library API
119+ this . ws . on ( 'open' , ( ) => {
120+ console . debug ( `WebSocket connected to ${ finalUrl } ` ) ;
121+ this . currentDelay = this . reconnectDelay ; // Reset delay on successful connection
122+ } ) ;
123+
124+ this . ws . on ( 'message' , ( data : any ) => {
125+ try {
126+ const message = data . toString ( ) ;
127+ const event : Event = JSON . parse ( message ) ;
128+ this . callback ( event ) ;
129+ } catch ( error ) {
130+ console . error ( 'Error processing WebSocket message:' , error ) ;
131+ }
132+ } ) ;
133+
134+ this . ws . on ( 'close' , ( code : number , reason : any ) => {
135+ console . debug ( `WebSocket closed: ${ code } ${ reason ? reason . toString ( ) : '' } ` ) ;
136+ this . ws = undefined ;
137+
138+ if ( this . shouldReconnect ) {
139+ this . scheduleReconnect ( ) ;
140+ }
141+ } ) ;
142+
143+ this . ws . on ( 'error' , ( error : Error ) => {
144+ console . debug ( 'WebSocket error:' , error ) ;
145+ if ( this . shouldReconnect ) {
146+ this . scheduleReconnect ( ) ;
147+ }
148+ } ) ;
149+ }
99150 } catch ( error ) {
100151 console . error ( 'Failed to create WebSocket connection:' , error ) ;
101152 if ( this . shouldReconnect ) {
0 commit comments