UNPKG

rpcchannel

Version:

Easy RPC with permission controls

1,178 lines (942 loc) 94.9 kB
"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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