@syncable/core
Version:
111 lines • 3.58 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const rxjs_1 = require("rxjs");
const utils_1 = require("../utils");
const rpc_error_1 = require("./rpc-error");
class RPCPeer {
constructor(adapter) {
this.adapter = adapter;
this.requestHandlersMap = new Map();
this.incomingSubscription = new rxjs_1.Subscription();
this.onIncoming = (data) => {
switch (data.type) {
case 'request':
this.handleRequest(data);
break;
case 'response':
this.handleResponse(data);
break;
}
};
this.incomingSubscription.add(adapter.incoming$.subscribe(this.onIncoming));
}
async call(name, ...args) {
let id = utils_1.generateUniqueId();
let handlersMap = this.requestHandlersMap;
let handlers;
let request = {
type: 'request',
id,
name,
args,
};
let responsePromise = new Promise((resolve, reject) => {
handlers = { resolve, reject };
handlersMap.set(id, handlers);
});
this.adapter.send(request).catch(error => {
if (handlersMap.has(id)) {
handlersMap.delete(id);
handlers.reject(error);
}
});
return responsePromise;
}
dispose() {
this.incomingSubscription.unsubscribe();
}
handleRequest(request) {
this._handleRequest(request).catch(console.error);
}
async _handleRequest({ id, name, args }) {
let value;
let responseError;
try {
value = await this.callLocalMethod(name, args);
}
catch (error) {
if (error instanceof rpc_error_1.RPCError) {
responseError = {
code: error.code,
message: error.message,
};
console.error(error.message);
}
else {
responseError = {
code: 'UNKNOWN',
message: 'Unknown syncable PRC error',
};
console.error(error instanceof Error ? error.stack : error);
}
}
await this.adapter.send({
type: 'response',
id,
return: value,
throw: responseError,
});
}
handleResponse({ id, return: value, throw: responseError, }) {
let handlersMap = this.requestHandlersMap;
let handlers = handlersMap.get(id);
if (!handlers) {
console.error(`Cannot find RPC request handlers with ID "${id}"`);
return;
}
handlersMap.delete(id);
if (responseError) {
let error = new rpc_error_1.RPCError(responseError.code, responseError.message);
handlers.reject(error);
}
else {
handlers.resolve(value);
}
}
async callLocalMethod(name, args) {
let map = this.__methodMap;
let method = map && map.get(name);
if (!method) {
if (name in this) {
throw new Error(`RPC method "${name}" does not exist, are you missing \`@RPCMethod()\` decorator?`);
}
else {
throw new Error(`RPC method "${name}" does not exist`);
}
}
return method.apply(this, args);
}
}
exports.RPCPeer = RPCPeer;
//# sourceMappingURL=rpc-peer.js.map