interface export interface TypeSocketOptions { /**
     * Maximum amount of retries until a successful connection gets established.
     * Set to 0 to keep retrying forever.
     * Default: 5
     */ maxRetries ? : number ; /**
     * When set to true the client will try to reconnect when the socket is intentionally closed by either party.
     * Default: false
     */ retryOnClose ? : boolean ; /**
     * Time between retries. (ms)
     * Default: 500
     */ retryTime ? : number ; } type WebSocketData = string | ArrayBuffer | Blob | ArrayBufferView ; type TypeSocketConnectionStateChangeEventListener < T > = ( this : TypeSocket < T > ) => void ; type TypeSocketMessageEventListener < T > = ( this : TypeSocket < T > , message : T ) => void ; type TypeSocketRawMessageEventListener < T > = ( this : TypeSocket < T > , message : WebSocketData ) => void ; interface TypeSocketEvents < T > { connected : Set < TypeSocketConnectionStateChangeEventListener < T > > ; disconnected : Set < TypeSocketConnectionStateChangeEventListener < T > > ; permanentlyDisconnected : Set < TypeSocketConnectionStateChangeEventListener < T > > ; message : Set < TypeSocketMessageEventListener < T > > ; invalidMessage : Set < TypeSocketRawMessageEventListener < T > > ; rawMessage : Set < TypeSocketRawMessageEventListener < T > > ; } export class TypeSocket < T > { private socket : WebSocket | null = null ; private retries = 0 ; private options : TypeSocketOptions = { maxRetries : 5 , retryOnClose : false , retryTime : 500 , } ; private events : TypeSocketEvents < T > = { connected : new Set ( ) , disconnected : new Set ( ) , permanentlyDisconnected : new Set ( ) , message : new Set ( ) , invalidMessage : new Set ( ) , rawMessage : new Set ( ) , } ; param url constructor ( private url , options ? ) { if ( options ) { this . options = { ... this . options , ... options , } ; } } /**
     * Connects to the server.
     *
     * Will automatically retry on failure.
     */ connect ( ) { if ( this . socket ) { try { this . socket . close ( ) ; this . disconnected ( ) ; } catch { } } this . socket = new WebSocket ( this . url ) ; this . socket . onopen = ( ) => { this . connected ( ) ; } ; this . socket . onclose = e => { if ( e . code === 1000 || ( this . options . retryOnClose && this . socket ) ) { this . reconnectAfterTime ( this . options . retryTime ) ; } else { this . disconnected ( ) ; this . permanentlyDisconnected ( ) ; } } ; this . socket . onmessage = e => { this . message ( e . data ) ; } ; this . socket . onerror = ( ) => { this . disconnected ( ) ; this . socket = null ; this . reconnectAfterTime ( this . options . retryTime ) ; } ; } /**
     * Disconnects the connection.
     *
     * When called, TypeSocket will stop retrying, the WebSocket will be closed and both disconnected and permanentlyDisconnected events will be called.
     */ disconnect ( ) { if ( this . socket ) { try { this . socket . onclose = null ; this . socket . onerror = null ; this . socket . close ( ) ; this . disconnected ( ) ; this . permanentlyDisconnected ( ) ; } catch { } } } param data send ( data ) { if ( ! this . socket ) return ; this . socket . send ( JSON . stringify ( data ) ) ; } param data sendRaw ( data ) { if ( ! this . socket ) return ; this . socket . send ( data ) ; } /**
     * Ready state of the socket.
     */ get readyState ( ) : number { return this . socket ? this . socket . readyState : 0 ; } param eventType param listener on ( eventType , listener ) ; param eventType param listener on ( eventType , listener ) ; param eventType param listener on ( eventType , listener ) ; param eventType param listener on ( eventType , listener ) { this . events [ eventType ] . add ( listener as any ) ; } param eventType param listener off ( eventType , listener ) ; param eventType param listener off ( eventType , listener ) ; param eventType param listener off ( eventType , listener ) ; param eventType param listener off ( eventType , listener ) { this . events [ eventType ] . delete ( listener as any ) ; } private emit ( eventType , ... args ) { for ( const listener of this . events [ eventType ] ) { ( listener as Function ) . apply ( this , args ) ; } } private reconnectAfterTime ( time = 500 ) { if ( this . socket ) { this . socket . close ( ) ; } this . socket = null ; this . disconnected ( ) ; setTimeout ( ( ) => { this . reconnect ( ) ; } , time ) ; } private reconnect ( ) { this . retries ++ ; if ( this . options . maxRetries && this . retries > this . options . maxRetries ) { this . disconnected ( ) ; this . permanentlyDisconnected ( ) ; return ; } this . connect ( ) ; } private connected ( ) { this . retries = 0 ; this . emit ( 'connected' ) ; } private disconnected ( ) { this . emit ( 'disconnected' ) ; } private permanentlyDisconnected ( ) { this . emit ( 'permanentlyDisconnected' ) ; } private message ( data ) { this . emit ( 'rawMessage' , data ) ; if ( typeof data === 'string' ) { try { const json = JSON . parse ( data ) ; if ( json ) { this . emit ( 'message' , json ) ; return ; } } catch { } } this . emit ( 'invalidMessage' , data ) ; } }