UNPKG

@akala/json-rpc-ws

Version:

json-rpc websocket transport

85 lines 3.11 kB
import ws from 'ws'; import { ErrorWithStatus, HttpStatusCode, StatefulSubscription, AsyncTeardownManager, IsomorphicBuffer, Deferred } from '@akala/core'; /** * json-rpc-ws connection * * @constructor * @param {Socket} socket - web socket for this connection * @param {Object} parent - parent that controls this connection */ export default class WsSocketAdapter extends AsyncTeardownManager { socket; constructor(socket) { super(); this.socket = socket; } hasListener(name) { return !!this.socket.listenerCount(name); } get definedEvents() { return ['message', 'close', 'error', 'open'].filter(k => this.socket.listenerCount(k)); } emit(event, ...args) { throw new ErrorWithStatus(HttpStatusCode.NotImplemented, 'Method not implemented.'); } pipe(socket) { this.on('message', (message) => socket.send(message)); this.on('close', () => socket.close()); } get open() { return this.socket.readyState == ws.OPEN; } close() { const deferred = new Deferred(); this.socket.addEventListener('close', () => deferred.resolve()); this.socket.close(); return deferred; } send(data) { return new Promise((resolve, reject) => this.socket.send(data instanceof IsomorphicBuffer ? data.toArray() : data, { binary: data instanceof IsomorphicBuffer }, err => err ? reject(err) : resolve())); } off(event, handler) { if (event === 'message') { this.socket.removeAllListeners(event); } else this.socket.off(event, handler); return true; } messageListeners = []; on(event, handler, options) { if (event === 'message') { function x(data, isBinary) { if (!isBinary) { if (Buffer.isBuffer(data)) handler.call(this, data.toString('utf8')); else if (typeof data === 'string') handler.call(this, data); else if (Array.isArray(data)) data.forEach(data => handler.call(this, IsomorphicBuffer.fromBuffer(data))); else handler.call(this, IsomorphicBuffer.fromArrayBuffer(data)); } else handler.call(this, data); } this.messageListeners.push([handler, x]); if (options?.once) this.socket.once(event, x); else this.socket.on(event, x); return new StatefulSubscription(() => this.socket.off(event, x)).unsubscribe; } else { if (options?.once) this.socket.once(event, handler); else this.socket.on(event, handler); return new StatefulSubscription(() => this.socket.off(event, handler)).unsubscribe; } } once(event, handler) { return this.on(event, handler, { once: true }); } } //# sourceMappingURL=ws-socket-adapter.js.map