@akala/json-rpc-ws
Version:
json-rpc websocket transport
85 lines • 3.11 kB
JavaScript
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