interface WebSocketEvent { type : string ; reason ? : string ; message ? : string ; data ? : string | ArrayBufferLike ; source ? : any ; } interface WebSocketEventListener { ( evt ) : void ; } class WebSocketEventTarget { events : { [ type ] : WebSocketEventListener [ ] ; } = { } ; dispatchEvent ( event ) { const list = this . events [ event . type ] ; if ( ! list ) { return ; } for ( const l of list ) { l ( event ) ; } } addEventListener ( type , f ) { let list = this . events [ type ] ; if ( ! list ) { list = this . events [ type ] = [ ] ; } list . push ( f ) ; } removeEventListener ( type , f ) { const list = this . events [ type ] ; if ( ! list ) { return ; } const index = list . indexOf ( f ) ; if ( index > - 1 ) { list . splice ( index , 1 ) ; } } } function defineEventAttribute ( p , type ) { Object . defineProperty ( p , 'on' + type , { get : function ( ) { throw new Error ( `${ type } is write only` ) ; } , set : function ( f ) { this . events [ type ] = [ f ] ; } } ) ; } export interface WebSocketConnectCallbacks { connect ( e , ws ) : void ; end ( ) : void ; error ( e ) : void ; data ( data ) : void ; } export interface WebSocketConnect { ( url , protocols , callbacks ) : void ; } export interface WebSocketMethods { send ( message ) : void ; close ( message ) : void ; } export function createWebSocketClass ( __websocketConnect ) { class WebSocket extends WebSocketEventTarget { _url : string ; _protocols : string [ ] ; readyState : number ; _ws : WebSocketMethods ; constructor ( url , protocols ? ) { super ( ) ; this . _url = url ; this . _protocols = protocols ; this . readyState = 0 ; __websocketConnect ( url , protocols , { connect : ( e , ws ) => { if ( e != null ) { this . dispatchEvent ( { type : 'error' , message : e . toString ( ) , } ) ; return ; } this . _ws = ws ; this . readyState = 1 ; this . dispatchEvent ( { type : 'open' , } ) ; } , end : ( ) => { this . readyState = 3 ; this . dispatchEvent ( { type : 'close' , reason : 'closed' , } ) ; } , error : ( e ) => { this . readyState = 3 ; this . dispatchEvent ( { type : 'error' , message : e . toString ( ) , } ) ; } , data : ( data ) => { this . dispatchEvent ( { type : 'message' , data : data , source : this , } ) ; } } ) ; } send ( message ) { this . _ws . send ( message ) ; } get url ( ) { return this . _url ; } get extensions ( ) { return "" ; } close ( reason ) { this . _ws . close ( reason ) ; } } defineEventAttribute ( WebSocket . prototype , "close" ) ; defineEventAttribute ( WebSocket . prototype , "error" ) ; defineEventAttribute ( WebSocket . prototype , "message" ) ; defineEventAttribute ( WebSocket . prototype , "open" ) ; return WebSocket ; }