rpcchannel
Version:
Easy RPC with permission controls
1,178 lines (942 loc) • 94.9 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.RpcAddress = RpcAddress;
exports.RemapArguments = RemapArguments;
exports.RpcChannel = exports.RpcState = exports.ForwardedError = exports.AccessDeniedError = exports.InvalidChannelError = exports.RpcHandlerRegistry = exports.RpcMessage = exports.RpcRemappedFunction = exports.RpcFunctionAddress = void 0;
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
var _wrapNativeSuper2 = _interopRequireDefault(require("@babel/runtime/helpers/wrapNativeSuper"));
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized"));
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _asyncIterator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncIterator"));
var _awaitAsyncGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/awaitAsyncGenerator"));
var _wrapAsyncGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/wrapAsyncGenerator"));
var _eventemitter = _interopRequireDefault(require("eventemitter3"));
var _addrmap = require("./addrmap");
var _accesscontrol = require("./accesscontrol");
var _serializer = require("./serializer");
var _utils = require("./utils");
function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2["default"])(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2["default"])(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2["default"])(this, result); }; }
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
var RpcFunctionAddress = Symbol('RpcFunctionAddress');
exports.RpcFunctionAddress = RpcFunctionAddress;
var RpcRemappedFunction = Symbol('RpcRemappedFunction');
exports.RpcRemappedFunction = RpcRemappedFunction;
function RpcAddress(address) {
return function ( // eslint-disable-next-line
target, propertyKey, descriptor) {
var func = descriptor.value;
if (typeof func !== 'function') {
throw new TypeError('Cannot mark non-function as RPC function');
}
func[RpcFunctionAddress] = address;
};
}
function RemapArguments(mapping) {
var key = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : RpcRemappedFunction;
return function ( // eslint-disable-next-line
target, propertyKey, descriptor) {
var func = descriptor.value;
if (typeof func !== 'function') {
throw new TypeError('Cannot remap arguments for non-function');
} // eslint-disable-next-line
descriptor.value[key] = function () {
var it = mapping[Symbol.iterator]();
var value = undefined;
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
return func.apply(this, args.flatMap(function (v) {
if (!value) {
;
var _it$next = it.next();
value = _it$next.value;
}
switch (value) {
default:
case 'pass':
value = undefined;
return [v];
case 'drop':
value = undefined;
return [];
case 'expand':
// eslint-disable-next-line
var array = [];
if (!v[Symbol.iterator]) {
throw new TypeError('Attempted to expand non-iterable');
}
var exp_it = v[Symbol.iterator]();
do {
var _it$next2;
var r = exp_it.next();
if (r.done) {
throw new TypeError('Expand reached end of array');
}
array.push(r.value);
} while ((_it$next2 = it.next(), value = _it$next2.value, _it$next2).value === 'expand');
return array;
}
}));
};
return descriptor;
};
}
/**
* Sent between threads/workers/tabs/domains/whatever to carry RPCs and
* associated data.
*/
var RpcMessage;
exports.RpcMessage = RpcMessage;
(function (_RpcMessage) {
var Schema = _RpcMessage.Schema = {
type: 'object',
properties: {
to: {
type: 'array',
items: {
type: 'string'
}
},
args: {
type: 'array'
},
return_addr: {
type: 'array',
items: {
type: 'string'
}
},
return_type: {
type: 'string',
"enum": ['promise', 'generator']
}
},
required: ['to', 'args']
};
})(RpcMessage || (exports.RpcMessage = RpcMessage = {}));
/**
* Where RPC handles are registered to a particular address. This can be
* re-used between different `RpcChannel`s.
*/
var RpcHandlerRegistry = /*#__PURE__*/function (_ChainedAccessControl) {
(0, _inherits2["default"])(RpcHandlerRegistry, _ChainedAccessControl);
var _super = _createSuper(RpcHandlerRegistry);
function RpcHandlerRegistry() {
var _this;
(0, _classCallCheck2["default"])(this, RpcHandlerRegistry);
_this = _super.call(this, undefined);
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "map", new _addrmap.AddressMap());
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "return_seq_id", 0);
return _this;
}
(0, _createClass2["default"])(RpcHandlerRegistry, [{
key: "register",
value: function register(address, func) {
while (func[RpcRemappedFunction]) {
func = func[RpcRemappedFunction];
}
this.map.put(address, func);
}
}, {
key: "unregister",
value: function unregister(address) {
this.map.put(address, undefined);
}
}, {
key: "registerAll",
value: function registerAll(base) {
var _this2 = this;
var obj = base; // Based on https://stackoverflow.com/a/31055217/7853604
do {
var _iterator2 = _createForOfIteratorHelper(Object.getOwnPropertyNames(obj)),
_step2;
try {
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
var k = _step2.value;
var _func = obj[k];
if (_func && _func[RpcFunctionAddress] && typeof _func === 'function') {
(function () {
var tgt = _func;
while (tgt[RpcRemappedFunction]) {
tgt = tgt[RpcRemappedFunction];
}
_this2.register(_func[RpcFunctionAddress], // eslint-disable-next-line
function () {
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
args[_key2] = arguments[_key2];
}
return tgt.apply(base, args);
});
})();
}
}
} catch (err) {
_iterator2.e(err);
} finally {
_iterator2.f();
}
} while (obj = Object.getPrototypeOf(obj));
}
}, {
key: "unregisterAll",
value: function unregisterAll(base) {
var obj = base; // Based on https://stackoverflow.com/a/31055217/7853604
do {
var _iterator3 = _createForOfIteratorHelper(Object.getOwnPropertyNames(obj)),
_step3;
try {
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
var k = _step3.value;
var _func2 = obj[k];
if (_func2 && _func2[RpcFunctionAddress] && typeof _func2 === 'function') {
this.unregister(_func2[RpcFunctionAddress]);
}
}
} catch (err) {
_iterator3.e(err);
} finally {
_iterator3.f();
}
} while (obj = Object.getPrototypeOf(obj));
}
}, {
key: "clear",
value: function clear() {
this.map.clear();
}
}, {
key: "nextSeqAddr",
value: function nextSeqAddr() {
return ['_', 'ret', "id".concat(this.return_seq_id++)];
}
}]);
return RpcHandlerRegistry;
}(_accesscontrol.ChainedAccessController);
exports.RpcHandlerRegistry = RpcHandlerRegistry;
/**
* Thrown when a return from a function call reaches a different RpcChannel
* than it was sent from. This **may** indicate a security issue due to re-used
* recieve callbacks.
*/
var InvalidChannelError = /*#__PURE__*/function (_Error) {
(0, _inherits2["default"])(InvalidChannelError, _Error);
var _super2 = _createSuper(InvalidChannelError);
function InvalidChannelError() {
var _this3;
(0, _classCallCheck2["default"])(this, InvalidChannelError);
for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
args[_key3] = arguments[_key3];
}
_this3 = _super2.call.apply(_super2, [this].concat(args));
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this3), "name", 'InvalidChannelError');
return _this3;
}
return InvalidChannelError;
}( /*#__PURE__*/(0, _wrapNativeSuper2["default"])(Error));
exports.InvalidChannelError = InvalidChannelError;
var AccessDeniedError = /*#__PURE__*/function (_Error2) {
(0, _inherits2["default"])(AccessDeniedError, _Error2);
var _super3 = _createSuper(AccessDeniedError);
function AccessDeniedError() {
var _this4;
(0, _classCallCheck2["default"])(this, AccessDeniedError);
for (var _len5 = arguments.length, args = new Array(_len5), _key5 = 0; _key5 < _len5; _key5++) {
args[_key5] = arguments[_key5];
}
_this4 = _super3.call.apply(_super3, [this].concat(args));
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this4), "name", 'AccessDeniedError');
return _this4;
}
return AccessDeniedError;
}( /*#__PURE__*/(0, _wrapNativeSuper2["default"])(Error));
exports.AccessDeniedError = AccessDeniedError;
var ForwardedError = /*#__PURE__*/function (_Error3) {
(0, _inherits2["default"])(ForwardedError, _Error3);
var _super4 = _createSuper(ForwardedError);
function ForwardedError() {
(0, _classCallCheck2["default"])(this, ForwardedError);
return _super4.apply(this, arguments);
}
return ForwardedError;
}( /*#__PURE__*/(0, _wrapNativeSuper2["default"])(Error));
exports.ForwardedError = ForwardedError;
var RpcState;
/**
* A wrapper class for functions to perform remote procedure calls.
*/
exports.RpcState = RpcState;
(function (RpcState) {
RpcState[RpcState["INACTIVE"] = 0] = "INACTIVE";
RpcState[RpcState["ACTIVE"] = 1] = "ACTIVE";
RpcState[RpcState["CLOSED"] = 2] = "CLOSED";
})(RpcState || (exports.RpcState = RpcState = {}));
var RpcChannel = /*#__PURE__*/function (_EventEmitter) {
(0, _inherits2["default"])(RpcChannel, _EventEmitter);
var _super5 = _createSuper(RpcChannel);
/**
* @param c_send The function to send over whatever transport is used.
* @param reg The handle registry. This can be changed later.
*/
function RpcChannel(c_send) {
var _this5;
var default_policy = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _accesscontrol.AccessPolicy.ALLOW;
var reg = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : new RpcHandlerRegistry();
var _opts = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
(0, _classCallCheck2["default"])(this, RpcChannel);
_this5 = _super5.call(this);
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this5), "_i_reg", new RpcHandlerRegistry());
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this5), "access_controller", new _accesscontrol.ChainedAccessController(undefined));
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this5), "active_timeout", void 0);
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this5), "active_keepalive", void 0);
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this5), "_state", RpcState.INACTIVE);
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this5), "stop", function () {
return _this5.close();
});
_this5.c_send = c_send;
_this5.default_policy = default_policy;
_this5.reg = reg;
_this5._opts = _opts;
_this5._i_reg.register(['_', 'close'], function () {
return _this5.close(false);
});
_this5.on('rawmessage', function () {
return _this5.resetTimeout();
}); // Keep alives start getting sent immediately
_this5.resetKeepAlive();
return _this5;
}
(0, _createClass2["default"])(RpcChannel, [{
key: "resetTimeout",
value: function resetTimeout() {
var _this6 = this;
if ((0, _utils.isDefined)(this.active_timeout)) {
clearTimeout(this.active_timeout);
delete this.active_timeout;
}
if (this.state !== RpcState.ACTIVE) {
return;
}
if (this.opts.timeout) {
this.active_timeout = setTimeout(function () {
_this6.close();
delete _this6.active_timeout;
}, this.opts.timeout);
}
}
}, {
key: "sendKeepAlive",
value: function sendKeepAlive() {
if (this.opts.keep_alive_interval) {
try {
this.send(['_', 'keepalive']);
} catch (e) {// TODO
}
}
}
}, {
key: "resetKeepAlive",
value: function resetKeepAlive() {
var _this7 = this;
this.sendKeepAlive();
if ((0, _utils.isDefined)(this.active_keepalive)) {
clearInterval(this.active_keepalive);
delete this.active_keepalive;
}
if (this.opts.keep_alive_interval) {
this.active_keepalive = setInterval(function () {
_this7.sendKeepAlive();
}, this.opts.keep_alive_interval);
}
}
}, {
key: "setTimeout",
value: function setTimeout(timeout, keep_alive_interval) {
Object.assign(this._opts, {
timeout: timeout,
keep_alive_interval: keep_alive_interval
});
this.resetTimeout();
this.resetKeepAlive();
}
}, {
key: "setAwaitFirstMsg",
value: function setAwaitFirstMsg(should) {
this._opts.await_first_msg = should;
}
}, {
key: "_stateChange",
value: function _stateChange(state) {
var old_state = this._state;
this._state = state;
this.emit('statechange', state, old_state);
switch (state) {
case RpcState.ACTIVE:
this.emit('active');
break;
case RpcState.CLOSED:
this.emit('close');
break;
}
}
}, {
key: "start",
value: function () {
var _start = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee() {
var _this8 = this;
return _regenerator["default"].wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
if (!(this._state !== RpcState.INACTIVE)) {
_context.next = 2;
break;
}
return _context.abrupt("return");
case 2:
if (!this.opts.await_first_msg) {
_context.next = 5;
break;
}
_context.next = 5;
return new Promise(function (r) {
var closefunc = function closefunc() {
r();
_this8.off('rawmessage', closefunc);
_this8.off('close', closefunc);
};
_this8.once('rawmessage', closefunc);
_this8.once('close', closefunc);
});
case 5:
if (!(this._state !== RpcState.INACTIVE)) {
_context.next = 7;
break;
}
return _context.abrupt("return");
case 7:
this._stateChange(RpcState.ACTIVE);
this.resetTimeout();
case 9:
case "end":
return _context.stop();
}
}
}, _callee, this);
}));
function start() {
return _start.apply(this, arguments);
}
return start;
}()
}, {
key: "close",
value: function close() {
var send = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
if (this.state === RpcState.CLOSED) {
return;
}
if (send) {
try {
this.send(['_', 'close']);
} catch (e) {// TODO
}
}
this._stateChange(RpcState.CLOSED);
this._i_reg.clear();
if (this.active_timeout) {
clearTimeout(this.active_timeout);
delete this.active_timeout;
}
if (this.active_keepalive) {
clearInterval(this.active_keepalive);
delete this.active_keepalive;
}
}
}, {
key: "register",
value: function register(address, func) {
this.reg.register(address, func);
}
}, {
key: "unregister",
value: function unregister(address) {
this.reg.unregister(address);
}
}, {
key: "registerAll",
value: function registerAll(obj) {
this.reg.registerAll(obj);
}
}, {
key: "unregisterAll",
value: function unregisterAll(obj) {
this.reg.unregisterAll(obj);
}
}, {
key: "can",
value: function can(addr, opts) {
var val = this.access_controller && this.access_controller.can(addr, opts);
if ((0, _utils.isDefined)(val)) {
return val;
}
val = this._i_reg.can(addr, opts);
if ((0, _utils.isDefined)(val)) {
return val;
}
return this.default_policy;
}
/**
* Sends data to a particular handle. Because there is no `await` for the
* other side to process this, the `send` function should be used for pushing
* data only since multiple messages may be sent before the other side gets
* around to processing them.
* @param to Address to send data to
* @param args Data to send
* @param return_addr The address of the return field. This is used for full
* transactions, such as function calls
*/
}, {
key: "send",
value: function send(to) {
var args = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
var return_addr = arguments.length > 2 ? arguments[2] : undefined;
var return_type = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 'promise';
var xfer = [];
var msg = {
to: to,
args: args.map(function (d) {
return (0, _serializer.rpcSerialize)(d, xfer);
}),
return_addr: return_addr,
return_type: return_type
};
this.c_send(msg, xfer);
}
/**
* Calls a handle and awaits the return value.
* @param to Handle to call
* @param args Arguments to pass through
* @returns A promise that will return when the call is completed. This will
* throw an error with the message `Channel closed` if the channel is closed
* before a response is received.
*/
}, {
key: "call",
value: function call(to) {
var _this9 = this;
var args = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
var return_addr = this._i_reg.nextSeqAddr();
return new Promise(function (resolve, reject) {
var onDone = function onDone() {
_this9.unregister(return_addr);
_this9.off('close', onChannelClose);
};
var onChannelClose = function onChannelClose() {
onDone();
reject(new Error('Channel closed'));
};
_this9._i_reg.register(return_addr, function (channel, wc, data, error) {
if (channel !== _this9) {
reject(new InvalidChannelError('Return value was sent through the wrong channel'));
} else if (error) {
if (error.name) {
reject(Object.assign(new ForwardedError(), error));
} else {
reject(error);
}
} else {
resolve(data);
}
onDone();
});
_this9.once('close', onChannelClose);
_this9.send(to, args, return_addr);
});
}
/**
* Returns an async generator. This supports only `yield`ing values: ATM,
* returned values and `yield`ed arguments are not supported. **You also must
* manually deallocate the generator once you're done!** Yes, manual memory
* management. If you don't manually deallocate, the listeners on both ends
* will remain allocated leading to memory leaks. To deallocate, call the
* `return` or `throw` functions on the generator.
*/
}, {
key: "generate",
value: function generate(to) {
var _this10 = this;
var args = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
var return_addr = this._i_reg.nextSeqAddr();
this.send(to, args, return_addr, 'generator'); // Now, create the generator. If this wasn't done, the above code would
// only be run when `next` was called
var buffer = [];
var onNewData;
var onDone = function onDone() {
_this10._i_reg.unregister(return_addr);
_this10.off('close', onChannelClose);
};
var onChannelClose = function onChannelClose() {
onDone();
buffer.push([undefined, undefined, true]);
};
this._i_reg.register(return_addr, function (channel, wc, data, error, done) {
if (channel !== _this10) {
onDone();
buffer.push([undefined, new InvalidChannelError('Yield value was sent through the wrong channel'), true]);
} else {
if (error) {
onDone();
}
if (error === null || error === void 0 ? void 0 : error.name) {
buffer.push([data, Object.assign(new ForwardedError(), error), Boolean(done)]);
} else {
buffer.push([data, error, Boolean(done)]);
}
}
if (onNewData) {
onNewData();
}
});
this.once('close', onChannelClose);
var getNext = /*#__PURE__*/function () {
var _ref2 = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee2() {
return _regenerator["default"].wrap(function _callee2$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
if (buffer.length) {
_context2.next = 4;
break;
}
_context2.next = 3;
return new Promise(function (res) {
return onNewData = res;
});
case 3:
onNewData = undefined;
case 4:
return _context2.abrupt("return", buffer.shift());
case 5:
case "end":
return _context2.stop();
}
}
}, _callee2);
}));
return function getNext() {
return _ref2.apply(this, arguments);
};
}();
var gen = (0, _wrapAsyncGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee3() {
var _yield$_awaitAsyncGen, _yield$_awaitAsyncGen2, d, e, c;
return _regenerator["default"].wrap(function _callee3$(_context3) {
while (1) {
switch (_context3.prev = _context3.next) {
case 0:
if (!true) {
_context3.next = 22;
break;
}
_context3.next = 3;
return (0, _awaitAsyncGenerator2["default"])(getNext());
case 3:
_yield$_awaitAsyncGen = _context3.sent;
_yield$_awaitAsyncGen2 = (0, _slicedToArray2["default"])(_yield$_awaitAsyncGen, 3);
d = _yield$_awaitAsyncGen2[0];
e = _yield$_awaitAsyncGen2[1];
c = _yield$_awaitAsyncGen2[2];
if (!e) {
_context3.next = 13;
break;
}
onDone();
throw e;
case 13:
if (!c) {
_context3.next = 18;
break;
}
onDone();
return _context3.abrupt("return");
case 18:
_context3.next = 20;
return d;
case 20:
_context3.next = 0;
break;
case 22:
case "end":
return _context3.stop();
}
}
}, _callee3);
}))();
var stop = function stop() {
_this10.send(['_', 'stopgen'].concat((0, _toConsumableArray2["default"])(return_addr)), []);
onDone();
};
var original_return = gen["return"];
var original_throw = gen["throw"];
return Object.assign(gen, {
"return": function _return() {
stop();
return original_return.apply(gen, [undefined]);
},
// eslint-disable-next-line
"throw": function _throw(e) {
stop();
return original_throw.apply(gen, [e]);
}
});
}
}, {
key: "receive",
/**
* Call this when a new message is recieved to process it.
* @param val Incoming message
*/
value: function receive(val) {
var _this11 = this;
if (this.state === RpcState.CLOSED) {
return;
}
this.emit('rawmessage', val);
var maybeReturn = function maybeReturn(data, error) {
// eslint-disable-next-line
var isGenerator = function isGenerator(data) {
return data && data[Symbol.asyncIterator] && typeof data.next === 'function';
};
if (val.return_addr) {
var addr = val.return_addr;
switch (val.return_type) {
case 'generator':
if (error) {
_this11.send(addr, [undefined, error, true]);
return;
}
var done = false;
var setDone = function setDone() {
done = true;
_this11.unregister(['_', 'stopgen'].concat((0, _toConsumableArray2["default"])(addr)));
};
var send = function send(a, d, e) {
var set_done = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
if (!done) {
_this11.send(a, [d, e, set_done || Boolean(e)]);
}
if (e || set_done) {
setDone();
}
};
var registerStopHandler = function registerStopHandler() {
_this11._i_reg.register(['_', 'stopgen'].concat((0, _toConsumableArray2["default"])(addr)), setDone);
};
if (data instanceof Promise) {
data.then(function (d) {
send(addr, d, undefined, false);
send(addr, undefined, undefined, true);
}, function (e) {
return send(addr, undefined, e);
});
} else if (isGenerator(data)) {
registerStopHandler();
(0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee4() {
var _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, _value, d;
return _regenerator["default"].wrap(function _callee4$(_context4) {
while (1) {
switch (_context4.prev = _context4.next) {
case 0:
_context4.prev = 0;
_iteratorNormalCompletion = true;
_didIteratorError = false;
_context4.prev = 3;
_iterator = (0, _asyncIterator2["default"])(data);
case 5:
_context4.next = 7;
return _iterator.next();
case 7:
_step = _context4.sent;
_iteratorNormalCompletion = _step.done;
_context4.next = 11;
return _step.value;
case 11:
_value = _context4.sent;
if (_iteratorNormalCompletion) {
_context4.next = 20;
break;
}
d = _value;
send(addr, d, undefined, false);
if (!done) {
_context4.next = 17;
break;
}
return _context4.abrupt("return");
case 17:
_iteratorNormalCompletion = true;
_context4.next = 5;
break;
case 20:
_context4.next = 26;
break;
case 22:
_context4.prev = 22;
_context4.t0 = _context4["catch"](3);
_didIteratorError = true;
_iteratorError = _context4.t0;
case 26:
_context4.prev = 26;
_context4.prev = 27;
if (!(!_iteratorNormalCompletion && _iterator["return"] != null)) {
_context4.next = 31;
break;
}
_context4.next = 31;
return _iterator["return"]();
case 31:
_context4.prev = 31;
if (!_didIteratorError) {
_context4.next = 34;
break;
}
throw _iteratorError;
case 34:
return _context4.finish(31);
case 35:
return _context4.finish(26);
case 36:
send(addr, undefined, undefined, true);
_context4.next = 42;
break;
case 39:
_context4.prev = 39;
_context4.t1 = _context4["catch"](0);
send(addr, undefined, _context4.t1);
case 42:
case "end":
return _context4.stop();
}
}
}, _callee4, null, [[0, 39], [3, 22, 26, 36], [27,, 31, 35]]);
}))();
} else {
send(addr, data, undefined, false);
send(addr, undefined, undefined, true);
}
return;
default:
case 'promise':
if (error) {
_this11.send(addr, [undefined, error]);
return;
}
var sendPromise = function sendPromise(data) {
data.then(function (d) {
return _this11.send(addr, [d, undefined]);
}, function (e) {
return _this11.send(addr, [undefined, e]);
});
};
if (data instanceof Promise) {
sendPromise(data);
} else if (isGenerator(data)) {
sendPromise(new Promise(function (res, rej) {
return data.next().then(function (_ref4) {
var value = _ref4.value;
return res(value);
}, function (err) {
return rej(err);
});
}));
} else {
_this11.send(addr, [data, undefined]);
}
return;
}
}
};
var wc = [];
var func = this._i_reg.map.get(val.to, wc) || this.reg.map.get(val.to, wc);
var security_policy = this.can(val.to, {
args: val.args,
wc: wc,
channel: this,
func: func
});
if ((0, _utils.isDefined)(security_policy) && security_policy === _accesscontrol.AccessPolicy.DENY) {
maybeReturn(undefined, new AccessDeniedError('Access denied'));
return;
}
if (!func) {
maybeReturn(undefined, new TypeError('Function at address is undefined'));
return;
}
var data;
try {
data = func.apply(void 0, [this, wc].concat((0, _toConsumableArray2["default"])(val.args)));
} catch (e) {
maybeReturn(undefined, e);
return;
}
maybeReturn(data);
}
}, {
key: "opts",
get: function get() {
var timeout = this._opts.timeout || 0;
return {
timeout: timeout,
keep_alive_interval: this._opts.keep_alive_interval || timeout / 2,
await_first_msg: Boolean(this._opts.await_first_msg)
};
}
}, {
key: "state",
get: function get() {
return this._state;
}
}, {
key: "call_obj",
get: function get() {
var _this12 = this;
function createRpcAccessor(addr, oncall) {
var dummyFunction = function dummyFunction() {
return new Promise(function (r) {
return r();
});
};
return new Proxy(dummyFunction, {
apply: function apply(func, target, args) {
return oncall(addr, args);
},
get: function get(target, prop) {
if (typeof prop !== 'string') {
return undefined;
}
return createRpcAccessor([].concat((0, _toConsumableArray2["default"])(addr), [prop]), oncall);
}
});
}
return createRpcAccessor([], function (addr, args) {
return _this12.call(addr, args);
});
}
}]);
return RpcChannel;
}(_eventemitter["default"]);
exports.RpcChannel = RpcChannel;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9yZWdpc3RyeS50cyJdLCJuYW1lcyI6WyJScGNGdW5jdGlvbkFkZHJlc3MiLCJTeW1ib2wiLCJScGNSZW1hcHBlZEZ1bmN0aW9uIiwiUnBjQWRkcmVzcyIsImFkZHJlc3MiLCJ0YXJnZXQiLCJwcm9wZXJ0eUtleSIsImRlc2NyaXB0b3IiLCJmdW5jIiwidmFsdWUiLCJUeXBlRXJyb3IiLCJSZW1hcEFyZ3VtZW50cyIsIm1hcHBpbmciLCJrZXkiLCJpdCIsIml0ZXJhdG9yIiwidW5kZWZpbmVkIiwiYXJncyIsImFwcGx5IiwiZmxhdE1hcCIsInYiLCJuZXh0IiwiYXJyYXkiLCJleHBfaXQiLCJyIiwiZG9uZSIsInB1c2giLCJTY2hlbWEiLCJ0eXBlIiwicHJvcGVydGllcyIsInRvIiwiaXRlbXMiLCJyZXR1cm5fYWRkciIsInJldHVybl90eXBlIiwicmVxdWlyZWQiLCJScGNNZXNzYWdlIiwiUnBjSGFuZGxlclJlZ2lzdHJ5IiwiQWRkcmVzc01hcCIsIm1hcCIsInB1dCIsImJhc2UiLCJvYmoiLCJPYmplY3QiLCJnZXRPd25Qcm9wZXJ0eU5hbWVzIiwiayIsInRndCIsInJlZ2lzdGVyIiwiZ2V0UHJvdG90eXBlT2YiLCJ1bnJlZ2lzdGVyIiwiY2xlYXIiLCJyZXR1cm5fc2VxX2lkIiwiQ2hhaW5lZEFjY2Vzc0NvbnRyb2xsZXIiLCJJbnZhbGlkQ2hhbm5lbEVycm9yIiwiRXJyb3IiLCJBY2Nlc3NEZW5pZWRFcnJvciIsIkZvcndhcmRlZEVycm9yIiwiUnBjU3RhdGUiLCJScGNDaGFubmVsIiwiY19zZW5kIiwiZGVmYXVsdF9wb2xpY3kiLCJBY2Nlc3NQb2xpY3kiLCJBTExPVyIsInJlZyIsIl9vcHRzIiwiSU5BQ1RJVkUiLCJjbG9zZSIsIl9pX3JlZyIsIm9uIiwicmVzZXRUaW1lb3V0IiwicmVzZXRLZWVwQWxpdmUiLCJhY3RpdmVfdGltZW91dCIsImNsZWFyVGltZW91dCIsInN0YXRlIiwiQUNUSVZFIiwib3B0cyIsInRpbWVvdXQiLCJzZXRUaW1lb3V0Iiwia2VlcF9hbGl2ZV9pbnRlcnZhbCIsInNlbmQiLCJlIiwic2VuZEtlZXBBbGl2ZSIsImFjdGl2ZV9rZWVwYWxpdmUiLCJjbGVhckludGVydmFsIiwic2V0SW50ZXJ2YWwiLCJhc3NpZ24iLCJzaG91bGQiLCJhd2FpdF9maXJzdF9tc2ciLCJvbGRfc3RhdGUiLCJfc3RhdGUiLCJlbWl0IiwiQ0xPU0VEIiwiUHJvbWlzZSIsImNsb3NlZnVuYyIsIm9mZiIsIm9uY2UiLCJfc3RhdGVDaGFuZ2UiLCJyZWdpc3RlckFsbCIsInVucmVnaXN0ZXJBbGwiLCJhZGRyIiwidmFsIiwiYWNjZXNzX2NvbnRyb2xsZXIiLCJjYW4iLCJ4ZmVyIiwibXNnIiwiZCIsIm5leHRTZXFBZGRyIiwicmVzb2x2ZSIsInJlamVjdCIsIm9uRG9uZSIsIm9uQ2hhbm5lbENsb3NlIiwiY2hhbm5lbCIsIndjIiwiZGF0YSIsImVycm9yIiwibmFtZSIsImJ1ZmZlciIsIm9uTmV3RGF0YSIsIkJvb2xlYW4iLCJnZXROZXh0IiwibGVuZ3RoIiwicmVzIiwic2hpZnQiLCJnZW4iLCJjIiwic3RvcCIsIm9yaWdpbmFsX3JldHVybiIsIm9yaWdpbmFsX3Rocm93IiwibWF5YmVSZXR1cm4iLCJpc0dlbmVyYXRvciIsImFzeW5jSXRlcmF0b3IiLCJzZXREb25lIiwiYSIsInNldF9kb25lIiwicmVnaXN0ZXJTdG9wSGFuZGxlciIsInRoZW4iLCJzZW5kUHJvbWlzZSIsInJlaiIsImVyciIsImdldCIsInNlY3VyaXR5X3BvbGljeSIsIkRFTlkiLCJjcmVhdGVScGNBY2Nlc3NvciIsIm9uY2FsbCIsImR1bW15RnVuY3Rpb24iLCJQcm94eSIsInByb3AiLCJjYWxsIiwiRXZlbnRFbWl0dGVyIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUtBOztBQUVBOztBQUtBOztBQVVBOztBQUNBOzs7Ozs7Ozs7Ozs7QUFFTyxJQUFNQSxrQkFBa0IsR0FBR0MsTUFBTSxDQUFDLG9CQUFELENB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