node-apparatus
Version:
A mix of common components needed for awesome node experience
54 lines • 2.6 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.StatefulRecipient = void 0;
const node_worker_threads_1 = require("node:worker_threads");
const i_proxy_method_js_1 = require("./i-proxy-method.js");
/**
* Abstract class representing a recipient that can handle method invocations
* received via StatefulProxyManager. This class is designed to work with Node.js
* worker threads.
*
* @abstract StatefulRecipient
*/
class StatefulRecipient {
constructor(shouldActivateMessagePort = !node_worker_threads_1.isMainThread, messagePort = node_worker_threads_1.parentPort) {
this.shouldActivateMessagePort = shouldActivateMessagePort;
this.messagePort = messagePort;
this.methodNameSet = new Set();
const methodNames = Object.getOwnPropertyNames(Object.getPrototypeOf(this))
.filter(prop => typeof this[prop] === 'function' && prop !== 'constructor');
this.methodNameSet = new Set(methodNames);
if (shouldActivateMessagePort === true) {
this.messagePort.on('message', this.receiveCommands.bind(this));
this.messagePort.on('error', this[Symbol.asyncDispose].bind(this));
}
}
async receiveCommands(workMessage) {
let methodInvocation;
try {
methodInvocation = (0, i_proxy_method_js_1.deserialize)(workMessage);
if (methodInvocation.methodName === i_proxy_method_js_1.DisposeMethodPayload.methodName) {
await this[Symbol.asyncDispose]();
return;
}
if (this.methodNameSet.has(methodInvocation.methodName) === false) {
throw new Error(`Unknown method: ${methodInvocation.methodName}`);
}
methodInvocation.returnValue = await this[methodInvocation.methodName](...methodInvocation.methodArguments);
this.messagePort.postMessage((0, i_proxy_method_js_1.serialize)(methodInvocation));
}
catch (error) {
const errorPayload = methodInvocation || { workerId: Number.NaN, invocationId: Number.NaN, methodName: "", methodArguments: [], returnValue: null };
errorPayload.error = error.message;
this.messagePort.postMessage((0, i_proxy_method_js_1.serialize)(errorPayload));
}
}
async [Symbol.asyncDispose]() {
if (this.shouldActivateMessagePort === true) {
this.messagePort.removeAllListeners();
this.messagePort.close();
}
}
}
exports.StatefulRecipient = StatefulRecipient;
//# sourceMappingURL=stateful-recipient.js.map