Files
xahau.js/packages/xrpl/src/client/WSWrapper.ts
2023-02-03 17:03:07 -06:00

107 lines
2.6 KiB
TypeScript

/* eslint-disable max-classes-per-file -- Needs to be a wrapper for ws */
import { EventEmitter } from 'events'
// Define the global WebSocket class found on the native browser
declare class WebSocket {
public onclose?: (closeEvent: CloseEvent) => void
public onopen?: (openEvent: Event) => void
public onerror?: (error: Error) => void
public onmessage?: (message: MessageEvent) => void
public readyState: number
public constructor(url: string)
public close(code?: number, reason?: Buffer): void
public send(message: string): void
}
interface WSWrapperOptions {
perMessageDeflate: boolean
handshakeTimeout: number
protocolVersion: number
origin: string
maxPayload: number
followRedirects: boolean
maxRedirects: number
}
/**
* Provides `EventEmitter` interface for native browser `WebSocket`,
* same, as `ws` package provides.
*/
export default class WSWrapper extends EventEmitter {
public static CONNECTING = 0
public static OPEN = 1
public static CLOSING = 2
// eslint-disable-next-line @typescript-eslint/no-magic-numbers -- magic number is being defined here
public static CLOSED = 3
private readonly ws: WebSocket
/**
* Constructs a browser-safe websocket.
*
* @param url - URL to connect to.
* @param _protocols - Not used.
* @param _websocketOptions - Not used.
*/
public constructor(
url: string,
_protocols: string | string[] | WSWrapperOptions | undefined,
_websocketOptions: WSWrapperOptions,
) {
super()
this.setMaxListeners(Infinity)
this.ws = new WebSocket(url)
this.ws.onclose = (closeEvent: CloseEvent): void => {
let reason: Uint8Array | undefined
if (closeEvent.reason) {
const enc = new TextEncoder()
reason = enc.encode(closeEvent.reason)
}
this.emit('close', closeEvent.code, reason)
}
this.ws.onopen = (): void => {
this.emit('open')
}
this.ws.onerror = (error): void => {
this.emit('error', error)
}
this.ws.onmessage = (message: MessageEvent): void => {
this.emit('message', message.data)
}
}
/**
* Closes the websocket.
*
* @param code - Close code.
* @param reason - Close reason.
*/
public close(code?: number, reason?: Buffer): void {
if (this.readyState === 1) {
this.ws.close(code, reason)
}
}
/**
* Sends a message over the Websocket connection.
*
* @param message - Message to send.
*/
public send(message: string): void {
this.ws.send(message)
}
/**
* Get the ready state of the websocket.
*
* @returns The Websocket's ready state.
*/
public get readyState(): number {
return this.ws.readyState
}
}