UNPKG

@akala/json-rpc-ws

Version:

json-rpc websocket transport

109 lines 3.75 kB
'use strict'; import { default as ClientBase } from './shared-client.js'; import { Connection } from '../browser.js'; import { EventEmitter, StatefulSubscription } from '@akala/core'; import debug from 'debug'; /** * json-rpc-ws connection * * @constructor * @param {Socket} socket - web socket for this connection * @param {Object} parent - parent that controls this connection */ export class WebSocketAdapter extends EventEmitter { socket; constructor(socket) { super(); this.socket = socket; } pipe(socket) { this.on('message', (message) => socket.send(message)); this.on('close', () => socket.close()); } get open() { return this.socket.readyState == WebSocket.OPEN; } close() { this.socket.close(); } send(data) { this.socket.send(data); } messageListeners = []; off(event, handler) { switch (event) { case 'message': { let listeners = this.messageListeners; if (handler) listeners = listeners.filter(f => f[0] == handler); listeners.forEach(l => this.socket.removeEventListener('message', l[1])); } break; case 'close': case 'error': case 'open': //eslint-disable-next-line @typescript-eslint/no-explicit-any this.socket.removeEventListener(event, handler); break; default: throw new Error(`Unsupported event ${String(event)}`); } return true; } on(event, handler, options) { switch (event) { case 'message': { const x = function (ev) { return handler.call(this, ev.data); }; this.messageListeners.push([handler, x]); this.socket.addEventListener('message', x, options); return new StatefulSubscription(() => { this.messageListeners.splice(this.messageListeners.findIndex(x => x[0] === handler), 1); this.socket.removeEventListener('message', x); }).unsubscribe; } break; case 'close': case 'error': case 'open': //eslint-disable-next-line @typescript-eslint/no-explicit-any this.socket.addEventListener(event, handler); return new StatefulSubscription(() => { this.socket.removeEventListener(event, handler); }).unsubscribe; default: throw new Error(`Unsupported event ${String(event)}`); } } once(event, handler) { switch (event) { case 'message': return this.on(event, handler, { once: true }); case 'close': case 'error': case 'open': return this.on(event, handler, { once: true }); default: throw new Error(`Unsupported event ${event?.toString()}`); } } } export default class Client extends ClientBase { connection(socket) { return new Connection(socket, this); } constructor(options) { super(Client.connect, options); } static connect(address, options) { return new WebSocketAdapter(new WebSocket(address.replace(/^http/, 'ws'), options?.protocols)); } } const logger = debug('akala:json-rpc-ws'); export function createClient(options) { logger('create ws client'); return new Client(options); } export const connect = Client.connect; //# sourceMappingURL=websocket.js.map