UNPKG

ws-rmi

Version:

A Remote Method Invocation implementation written in JavaScript utilising the WebSocket protocol

77 lines (76 loc) 3.33 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createRMIClient = void 0; const uuid_1 = require("uuid"); const RMIRemoteResponse_1 = require("./types/RMIRemoteResponse"); const RMIRequest_1 = require("./types/RMIRequest"); const Utils_1 = require("./Utils"); /** * Creates an RMI client that, when functions are called, will automatically message the server the given WebSocket * is a connected to. * * NOTE: The given WebSocket is assumed to be connected and in a readyState of 1. If this isn't the case, an Error * will be thrown! * * @param ws An open WebSocket connection that will be used to invoke functions on the remote. */ const createRMIClient = ({ ws, config: { logger: log } }) => { if (ws.readyState !== 1) throw new Error(`Attempted to create remote RMI instance, but the given WebSocket connection was not open. Ready state is ${ws.readyState}`); const activeRequests = new Map(); ws.addEventListener("message", ({ data }) => { log.debug(`Received message from remote: ${data}`); if (typeof data !== "string") return; let response; try { response = JSON.parse(data); } catch (e) { log.debug(`Remote message was not valid JSON! Cause: ${e}`); return; } log.debug(`Remote message parsed as ${response}`); if (!(0, RMIRemoteResponse_1.validateRMIRemoteResponse)(response)) { log.debug("Remote message was not a valid remote response!"); return; } const { rmi } = response; if (!(0, Utils_1.isEqualToAny)(rmi.type, "RESPONSE_RESULT", "RESPONSE_ERROR")) { log.debug(`Remote message had an invalid RMI type. Found "${rmi.type}"`); return; } const activeRequest = activeRequests.get(rmi.id); if (activeRequest === undefined) { log.debug(`No active requests were found matching ID "${rmi.id}"`); return; } const { resolve, reject } = activeRequest; log.debug(`Removing active request listener for ID ${rmi.id}`); activeRequests.delete(rmi.id); if ("error" in rmi.data) { log.info(`Received function invocation error from remote for request with ID "${rmi.id}". Error was: "${rmi.data.error}"`); reject(rmi.data.error); } else { log.info(`Received function invocation result from remote for request with ID "${rmi.id}". Result was: "${rmi.data.result}"`); resolve(rmi.data.result); } }); return new Proxy({}, { get: (target, property) => { return new Proxy(() => { }, { apply: (target, thisArg, args) => new Promise((resolve, reject) => { const id = (0, uuid_1.v4)(); activeRequests.set(id, { resolve, reject }); const request = JSON.stringify((0, RMIRequest_1.createRMIRequest)(id, property, args)); log.info(`Attempting to invoke remote function "${property}" with ID "${id}"...`); log.debug(`Sending ${request}`); ws.send(request); }) }); } }); }; exports.createRMIClient = createRMIClient;