wasmrs-js
Version:
A JavaScript implementation of the RSocket protocol over WebAssembly.
84 lines • 3.15 kB
JavaScript
import { Deferred, Flags, FrameTypes, serializeFrame, } from 'rsocket-core';
import DEBUG from 'debug';
export const debug = DEBUG('wasmrs:connection:worker');
export class WorkerDuplexConnection extends Deferred {
worker;
deserializer;
multiplexerDemultiplexer;
constructor(worker, deserializer, multiplexerDemultiplexerFactory) {
super();
this.worker = worker;
this.deserializer = deserializer;
worker.addEventListener('error', this.handleError);
worker.addEventListener('message', this.handleMessage);
worker.addEventListener('messageerror', this.handleMessageError);
this.multiplexerDemultiplexer = multiplexerDemultiplexerFactory(this);
}
get availability() {
return this.done ? 0 : 1;
}
close(error) {
debug('closing worker connection');
if (this.done) {
super.close(error);
return;
}
this.worker.removeEventListener('error', this.handleError);
this.worker.removeEventListener('message', this.handleMessage);
this.worker.removeEventListener('messageerror', this.handleMessageError);
this.worker.terminate();
super.close(error);
}
send(frame) {
// Only send frame types supported by WasmRS
switch (frame.type) {
case FrameTypes.REQUEST_RESPONSE:
case FrameTypes.REQUEST_CHANNEL:
case FrameTypes.REQUEST_FNF:
case FrameTypes.REQUEST_STREAM:
case FrameTypes.REQUEST_N:
case FrameTypes.CANCEL:
case FrameTypes.ERROR:
case FrameTypes.PAYLOAD:
break;
case FrameTypes.KEEPALIVE:
if ((frame.flags & Flags.RESPOND) == Flags.RESPOND) {
frame.flags ^= Flags.RESPOND;
this.multiplexerDemultiplexer.handle(frame);
}
return;
default:
debug(`ignoring frame`, JSON.stringify(frame));
return;
}
if (this.done) {
debug(`notice: got frame after connection complete`);
return;
}
const buffer = serializeFrame(frame);
debug(`sending frame`, JSON.stringify(frame));
this.worker.postMessage(buffer);
}
handleError = (e) => {
debug('error in worker: %o', e);
this.close(new Error(e.message));
};
handleMessageError = (e) => {
debug('error handling message from worker: %o', e);
this.close(e.data);
};
handleMessage = (message) => {
try {
const buffer = Buffer.from(message.data);
const frame = this.deserializer.deserializeFrame(buffer);
debug('got frame from worker %o', frame);
this.multiplexerDemultiplexer.handle(frame);
}
catch (error) {
debug('error handling message from worker: %s from: %o', error, message);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
this.close(error);
}
};
}
//# sourceMappingURL=worker-connection.js.map