1- import { EventEmitter } from 'events' ;
21import WebSocket from 'ws' ;
32import { Message , MessageType } from './protocol' ;
43import { Stream } from './stream' ;
@@ -10,7 +9,7 @@ export interface ClientOptions {
109 maxRetries ?: number ;
1110}
1211
13- export class Client extends EventEmitter {
12+ export class Client {
1413 private ws : WebSocket | null = null ;
1514 private options : ClientOptions ;
1615 public streams : Map < string , Stream > = new Map ( ) ;
@@ -19,15 +18,30 @@ export class Client extends EventEmitter {
1918 private shouldReconnect : boolean = true ;
2019 private retryTimer : NodeJS . Timeout | null = null ;
2120
21+ private openCallbacks : ( ( ) => void ) [ ] = [ ] ;
22+ private closeCallbacks : ( ( ) => void ) [ ] = [ ] ;
23+ private errorCallbacks : ( ( error : Error ) => void ) [ ] = [ ] ;
24+
2225 constructor ( options : ClientOptions ) {
23- super ( ) ;
2426 this . options = {
2527 retryInterval : 1000 ,
2628 maxRetries : Infinity ,
2729 ...options
2830 } ;
2931 }
3032
33+ public onOpen ( cb : ( ) => void ) {
34+ this . openCallbacks . push ( cb ) ;
35+ }
36+
37+ public onClose ( cb : ( ) => void ) {
38+ this . closeCallbacks . push ( cb ) ;
39+ }
40+
41+ public onError ( cb : ( error : Error ) => void ) {
42+ this . errorCallbacks . push ( cb ) ;
43+ }
44+
3145 public connect ( ) : void {
3246 this . shouldReconnect = true ;
3347 this . initiateConnection ( ) ;
@@ -44,7 +58,7 @@ export class Client extends EventEmitter {
4458 this . ws . onopen = ( ) => {
4559 console . log ( 'Connected' ) ;
4660 this . isConnected = true ;
47- this . emit ( 'open' ) ;
61+ this . openCallbacks . forEach ( cb => cb ( ) ) ;
4862 this . flushQueue ( ) ;
4963
5064 // Clear any existing Retry timer
@@ -69,6 +83,7 @@ export class Client extends EventEmitter {
6983 this . ws . onerror = ( err ) => {
7084 console . error ( 'WebSocket Error:' , err ) ;
7185 // creating error usually triggers close, so cleanup logic runs there.
86+ this . errorCallbacks . forEach ( cb => cb ( new Error ( err . message ) ) ) ;
7287 } ;
7388 }
7489
@@ -129,7 +144,7 @@ export class Client extends EventEmitter {
129144 const stream = this . streams . get ( header . streamId ) ;
130145 if ( stream ) {
131146 if ( header . type === MessageType . CLOSE_STREAM ) {
132- stream . emit ( 'close' ) ;
147+ stream . dispatchClose ( ) ;
133148 this . streams . delete ( header . streamId ) ;
134149 } else if ( header . type === MessageType . DATA ) {
135150 stream . handleMessage ( payload ) ;
@@ -156,9 +171,9 @@ export class Client extends EventEmitter {
156171
157172 private cleanup ( ) : void {
158173 this . isConnected = false ;
159- this . emit ( 'close' ) ;
174+ this . closeCallbacks . forEach ( cb => cb ( ) ) ;
160175 // Close all streams
161- this . streams . forEach ( stream => stream . emit ( 'close' ) ) ;
176+ this . streams . forEach ( stream => stream . dispatchClose ( ) ) ;
162177 this . streams . clear ( ) ;
163178 }
164179
0 commit comments