UNPKG

sg-socket-client

Version:
265 lines (226 loc) 15.8 kB
/** * Publish/Subscribe feature * @mixin PubsubExtension */ 'use strict'; var _regeneratorRuntime = require("@babel/runtime/regenerator"); var _Object$assign = require("@babel/runtime/core-js/object/assign"); var _asyncToGenerator = require("@babel/runtime/helpers/asyncToGenerator"); var _Object$freeze = require("@babel/runtime/core-js/object/freeze"); var _require = require('sg-socket-constants'), PubsubEvents = _require.PubsubEvents; var SUBSCRIBE = PubsubEvents.SUBSCRIBE, UNSUBSCRIBE = PubsubEvents.UNSUBSCRIBE, RAISE = PubsubEvents.RAISE, SHUT = PubsubEvents.SHUT, PUBLISH = PubsubEvents.PUBLISH, RECEIVE = PubsubEvents.RECEIVE, COUNT = PubsubEvents.COUNT; /** @lends PubsubExtension */ var PubsubExtension = _Object$freeze({ /** * Subscribe topic * @param {string} topic - Name of topic to subscribe * @param {function} handler - Event handler * @returns {Promise} */ subscribe: function () { var _subscribe = _asyncToGenerator( /*#__PURE__*/ _regeneratorRuntime.mark(function _callee(topic, handler) { var result, receiver; return _regeneratorRuntime.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: receiver = function _ref(data) { handler(data.payload); }; this._pubsubReceivers = this._pubsubReceivers || {}; _context.next = 4; return this.call(SUBSCRIBE, { topic: topic }); case 4: result = _context.sent; _Object$assign(receiver, { handler: handler }); this._pubsubReceivers[topic] = (this._pubsubReceivers[topic] || []).concat(receiver); this.on(RECEIVE, receiver); return _context.abrupt("return", result); case 9: case "end": return _context.stop(); } } }, _callee, this); })); return function subscribe(_x, _x2) { return _subscribe.apply(this, arguments); }; }(), /** * Unsubscribe topic * @param {string} topic - Name of topic to subscribe * @param {function} handler - Event handler * @returns {Promise} */ unsubscribe: function () { var _unsubscribe = _asyncToGenerator( /*#__PURE__*/ _regeneratorRuntime.mark(function _callee2(topic, handler) { var _this = this; var result; return _regeneratorRuntime.wrap(function _callee2$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: this._pubsubReceivers = this._pubsubReceivers || {}; _context2.next = 3; return this.call(UNSUBSCRIBE, { topic: topic }); case 3: result = _context2.sent; this._pubsubReceivers[topic] = (this._pubsubReceivers[topic] || []).filter(function (receiver) { var removing = !handler || receiver.handler === handler; if (removing) { _this.off(RECEIVE, receiver); } return !removing; }); return _context2.abrupt("return", result); case 6: case "end": return _context2.stop(); } } }, _callee2, this); })); return function unsubscribe(_x3, _x4) { return _unsubscribe.apply(this, arguments); }; }(), /** * Raise as a publisher * @param {string} topic - Name of topic * @returns {Promise} */ raiseAsPublisher: function () { var _raiseAsPublisher = _asyncToGenerator( /*#__PURE__*/ _regeneratorRuntime.mark(function _callee3(topic) { var call, result, sender; return _regeneratorRuntime.wrap(function _callee3$(_context3) { while (1) { switch (_context3.prev = _context3.next) { case 0: sender = function _ref2(payload) { return call(PUBLISH, { topic: topic, payload: payload }); }; call = this.call.bind(this); this._pubsubSenders = this._pubsubSenders || {}; _context3.next = 5; return call(RAISE, { topic: topic }); case 5: result = _context3.sent; _Object$assign(sender, { topic: topic, subCount: 0 }); this._pubsubSenders[topic] = sender; this.on(COUNT, function (counts) { sender.subCount = counts.sub; }); return _context3.abrupt("return", result); case 10: case "end": return _context3.stop(); } } }, _callee3, this); })); return function raiseAsPublisher(_x5) { return _raiseAsPublisher.apply(this, arguments); }; }(), /** * Shut as publisher * @param {Object} payload - Payload data * @returns {Promise} */ shutAsPublisher: function () { var _shutAsPublisher = _asyncToGenerator( /*#__PURE__*/ _regeneratorRuntime.mark(function _callee4(topic) { var result; return _regeneratorRuntime.wrap(function _callee4$(_context4) { while (1) { switch (_context4.prev = _context4.next) { case 0: this._pubsubSenders = this._pubsubSenders || {}; _context4.next = 3; return this.call(SHUT, { topic: topic }); case 3: result = _context4.sent; delete this._pubsubSenders[topic]; return _context4.abrupt("return", result); case 6: case "end": return _context4.stop(); } } }, _callee4, this); })); return function shutAsPublisher(_x6) { return _shutAsPublisher.apply(this, arguments); }; }(), /** * Publish topic * @param {string} topic - Name of topic to subscribe * @param {Object} payload - Payload data * @returns {Promise} */ publish: function () { var _publish = _asyncToGenerator( /*#__PURE__*/ _regeneratorRuntime.mark(function _callee5(topic, payload) { var sender; return _regeneratorRuntime.wrap(function _callee5$(_context5) { while (1) { switch (_context5.prev = _context5.next) { case 0: sender = (this._pubsubSenders || {})[topic]; if (sender) { _context5.next = 3; break; } throw new Error("Not ready to publish topic: ".concat(topic)); case 3: _context5.next = 5; return sender(payload); case 5: return _context5.abrupt("return", _context5.sent); case 6: case "end": return _context5.stop(); } } }, _callee5, this); })); return function publish(_x7, _x8) { return _publish.apply(this, arguments); }; }() }); module.exports = PubsubExtension; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImV4dGVuc2lvbnMvcHVic3ViX2V4dGVuc2lvbi5qcyJdLCJuYW1lcyI6WyJyZXF1aXJlIiwiUHVic3ViRXZlbnRzIiwiU1VCU0NSSUJFIiwiVU5TVUJTQ1JJQkUiLCJSQUlTRSIsIlNIVVQiLCJQVUJMSVNIIiwiUkVDRUlWRSIsIkNPVU5UIiwiUHVic3ViRXh0ZW5zaW9uIiwic3Vic2NyaWJlIiwidG9waWMiLCJoYW5kbGVyIiwicmVjZWl2ZXIiLCJkYXRhIiwicGF5bG9hZCIsIl9wdWJzdWJSZWNlaXZlcnMiLCJjYWxsIiwicmVzdWx0IiwiY29uY2F0Iiwib24iLCJ1bnN1YnNjcmliZSIsImZpbHRlciIsInJlbW92aW5nIiwib2ZmIiwicmFpc2VBc1B1Ymxpc2hlciIsInNlbmRlciIsImJpbmQiLCJfcHVic3ViU2VuZGVycyIsInN1YkNvdW50IiwiY291bnRzIiwic3ViIiwic2h1dEFzUHVibGlzaGVyIiwicHVibGlzaCIsIkVycm9yIiwibW9kdWxlIiwiZXhwb3J0cyJdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7QUFJQTs7Ozs7Ozs7OztlQUV1QkEsUUFBUSxxQkFBUixDO0lBQWhCQyxZLFlBQUFBLFk7O0lBR0xDLFMsR0FRRUQsWSxDQVJGQyxTO0lBQ0FDLFcsR0FPRUYsWSxDQVBGRSxXO0lBQ0FDLEssR0FNRUgsWSxDQU5GRyxLO0lBQ0FDLEksR0FLRUosWSxDQUxGSSxJO0lBQ0FDLE8sR0FJRUwsWSxDQUpGSyxPO0lBRUFDLE8sR0FFRU4sWSxDQUZGTSxPO0lBQ0FDLEssR0FDRVAsWSxDQURGTyxLO0FBR0Y7O0FBQ0EsSUFBTUMsa0JBQWtCLGVBQWM7QUFDcEM7Ozs7OztBQU1NQyxXQVA4QjtBQUFBO0FBQUE7QUFBQSw4Q0FPbkJDLEtBUG1CLEVBT1pDLE9BUFk7QUFBQSxrQkFXekJDLFFBWHlCO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFXekJBLHNCQVh5QixpQkFXZkMsSUFYZSxFQVdUO0FBQ3ZCRix3QkFBUUUsS0FBS0MsT0FBYjtBQUNELGVBYmlDOztB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S2lCLGNBQUwsR0FBc0IsS0FBS0EsY0FBTCxJQUF1QixFQUE3QztBQTVFa0M7QUFBQSxxQkE2RWYsS0FBS1gsSUFBTCxDQUFVWixJQUFWLEVBQWdCO0FBQUNNO0FBQUQsZUFBaEIsQ0E3RWU7O0FBQUE7QUE2RTlCTyxvQkE3RThCO0FBOEVsQyxxQkFBTyxLQUFLVSxjQUFMLENBQW9CakIsS0FBcEIsQ0FBUDtBQTlFa0MsZ0RBK0UzQk8sTUEvRTJCOztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOztBQUFBO0FBQUE7QUFBQTtBQUFBOztBQWtGcEM7Ozs7OztBQU1NZSxTQXhGOEI7QUFBQTtBQUFBO0FBQUEsK0NBd0ZyQnRCLEtBeEZxQixFQXdGZEksT0F4RmM7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBeUY1Qlcsb0JBekY0QixHQXlGbkIsQ0FBQyxLQUFLRSxjQUFMLElBQXVCLEVBQXhCLEVBQTRCakIsS0FBNUIsQ0F6Rm1COztBQUFBLGtCQTBGN0JlLE1BMUY2QjtBQUFBO0FBQUE7QUFBQTs7QUFBQSxvQkEyRjFCLElBQUlRLEtBQUosdUNBQXlDdkIsS0FBekMsRUEzRjBCOztBQUFBO0FBQUE7QUFBQSxxQkE2RnJCZSxPQUFPWCxPQUFQLENBN0ZxQjs7QUFBQTtBQUFBOztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsQ0FBZCxDQUF4Qjs7QUFpR0FvQixPQUFPQyxPQUFQLEdBQWlCM0IsZUFBakIiLCJmaWxlIjoiZXh0ZW5zaW9ucy9wdWJzdWJfZXh0ZW5zaW9uLmpzIiwic291cmNlUm9vdCI6Ii4uLy4uL2xpYiIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogUHVibGlzaC9TdWJzY3JpYmUgZmVhdHVyZVxuICogQG1peGluIFB1YnN1YkV4dGVuc2lvblxuICovXG4ndXNlIHN0cmljdCdcblxuY29uc3Qge1B1YnN1YkV2ZW50c30gPSByZXF1aXJlKCdzZy1zb2NrZXQtY29uc3RhbnRzJylcbmNvbnN0IHtcbiAgLy8gdG8gY2xvdWRcbiAgU1VCU0NSSUJFLFxuICBVTlNVQlNDUklCRSxcbiAgUkFJU0UsXG4gIFNIVVQsXG4gIFBVQkxJU0gsXG4gIC8vIEZyb20gY2xvdWRcbiAgUkVDRUlWRSxcbiAgQ09VTlRcbn0gPSBQdWJzdWJFdmVudHNcblxuLyoqIEBsZW5kcyBQdWJzdWJFeHRlbnNpb24gKi9cbmNvbnN0IFB1YnN1YkV4dGVuc2lvbiA9IE9iamVjdC5mcmVlemUoe1xuICAvKipcbiAgICogU3Vic2NyaWJlIHRvcGljXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0b3BpYyAtIE5hbWUgb2YgdG9waWMgdG8gc3Vic2NyaWJlXG4gICAqIEBwYXJhbSB7ZnVuY3Rpb259IGhhbmRsZXIgLSBFdmVudCBoYW5kbGVyXG4gICAqIEByZXR1cm5zIHtQcm9taXNlfVxuICAgKi9cbiAgYXN5bmMgc3Vic2NyaWJlICh0b3BpYywgaGFuZGxlcikge1xuICAgIHRoaXMuX3B1YnN1YlJlY2VpdmVycyA9IHRoaXMuX3B1YnN1YlJlY2VpdmVycyB8fCB7fVxuICAgIGxldCByZXN1bHQgPSBhd2FpdCB0aGlzLmNhbGwoU1VCU0NSSUJFLCB7dG9waWN9KVxuXG4gICAgZnVuY3Rpb24gcmVjZWl2ZXIgKGRhdGEpIHtcbiAgICAgIGhhbmRsZXIoZGF0YS5wYXlsb2FkKVxuICAgIH1cblxuICAgIE9iamVjdC5hc3NpZ24ocmVjZWl2ZXIsIHtcbiAgICAgIGhhbmRsZXJcbiAgICB9KVxuXG4gICAgdGhpcy5fcHVic3ViUmVjZWl2ZXJzW3RvcGljXSA9ICh0aGlzLl9wdWJzdWJSZWNlaXZlcnNbdG9waWNdIHx8IFtdKS5jb25jYXQocmVjZWl2ZXIpXG4gICAgdGhpcy5vbihSRUNFSVZFLCByZWNlaXZlcilcbiAgICByZXR1cm4gcmVzdWx0XG4gIH0sXG5cbiAgLyoqXG4gICAqIFVuc3Vic2NyaWJlIHRvcGljXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0b3BpYyAtIE5hbWUgb2YgdG9waWMgdG8gc3Vic2NyaWJlXG4gICAqIEBwYXJhbSB7ZnVuY3Rpb259IGhhbmRsZXIgLSBFdmVudCBoYW5kbGVyXG4gICAqIEByZXR1cm5zIHtQcm9taXNlfVxuICAgKi9cbiAgYXN5bmMgdW5zdWJzY3JpYmUgKHRvcGljLCBoYW5kbGVyKSB7XG4gICAgdGhpcy5fcHVic3ViUmVjZWl2ZXJzID0gdGhpcy5fcHVic3ViUmVjZWl2ZXJzIHx8IHt9XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5jYWxsKFVOU1VCU0NSSUJFLCB7dG9waWN9KVxuICAgIHRoaXMuX3B1YnN1YlJlY2VpdmVyc1t0b3BpY10gPSAodGhpcy5fcHVic3ViUmVjZWl2ZXJzW3RvcGljXSB8fCBbXSkuZmlsdGVyKChyZWNlaXZlcikgPT4ge1xuICAgICAgbGV0IHJlbW92aW5nID0gKCFoYW5kbGVyKSB8fCAocmVjZWl2ZXIuaGFuZGxlciA9PT0gaGFuZGxlcilcbiAgICAgIGlmIChyZW1vdmluZykge1xuICAgICAgICB0aGlzLm9mZihSRUNFSVZFLCByZWNlaXZlcilcbiAgICAgIH1cbiAgICAgIHJldHVybiAhcmVtb3ZpbmdcbiAgICB9KVxuICAgIHJldHVybiByZXN1bHRcbiAgfSxcblxuICAvKipcbiAgICogUmFpc2UgYXMgYSBwdWJsaXNoZXJcbiAgICogQHBhcmFtIHtzdHJpbmd9IHRvcGljIC0gTmFtZSBvZiB0b3BpY1xuICAgKiBAcmV0dXJucyB7UHJvbWlzZX1cbiAgICovXG4gIGFzeW5jIHJhaXNlQXNQdWJsaXNoZXIgKHRvcGljKSB7XG4gICAgY29uc3QgY2FsbCA9IHRoaXMuY2FsbC5iaW5kKHRoaXMpXG4gICAgdGhpcy5fcHVic3ViU2VuZGVycyA9IHRoaXMuX3B1YnN1YlNlbmRlcnMgfHwge31cbiAgICBsZXQgcmVzdWx0ID0gYXdhaXQgY2FsbChSQUlTRSwge3RvcGljfSlcblxuICAgIGZ1bmN0aW9uIHNlbmRlciAocGF5bG9hZCkge1xuICAgICAgcmV0dXJuIGNhbGwoUFVCTElTSCwge3RvcGljLCBwYXlsb2FkfSlcbiAgICB9XG5cbiAgICBPYmplY3QuYXNzaWduKHNlbmRlciwge1xuICAgICAgdG9waWMsXG4gICAgICBzdWJDb3VudDogMFxuICAgIH0pXG5cbiAgICB0aGlzLl9wdWJzdWJTZW5kZXJzW3RvcGljXSA9IHNlbmRlclxuXG4gICAgdGhpcy5vbihDT1VOVCwgKGNvdW50cykgPT4ge1xuICAgICAgc2VuZGVyLnN1YkNvdW50ID0gY291bnRzLnN1YlxuICAgIH0pXG4gICAgcmV0dXJuIHJlc3VsdFxuICB9LFxuXG4gIC8qKlxuICAgKiBTaHV0IGFzIHB1Ymxpc2hlclxuICAgKiBAcGFyYW0ge09iamVjdH0gcGF5bG9hZCAtIFBheWxvYWQgZGF0YVxuICAgKiBAcmV0dXJucyB7UHJvbWlzZX1cbiAgICovXG4gIGFzeW5jIHNodXRBc1B1Ymxpc2hlciAodG9waWMpIHtcbiAgICB0aGlzLl9wdWJzdWJTZW5kZXJzID0gdGhpcy5fcHVic3ViU2VuZGVycyB8fCB7fVxuICAgIGxldCByZXN1bHQgPSBhd2FpdCB0aGlzLmNhbGwoU0hVVCwge3RvcGljfSlcbiAgICBkZWxldGUgdGhpcy5fcHVic3ViU2VuZGVyc1t0b3BpY11cbiAgICByZXR1cm4gcmVzdWx0XG4gIH0sXG5cbiAgLyoqXG4gICAqIFB1Ymxpc2ggdG9waWNcbiAgICogQHBhcmFtIHtzdHJpbmd9IHRvcGljIC0gTmFtZSBvZiB0b3BpYyB0byBzdWJzY3JpYmVcbiAgICogQHBhcmFtIHtPYmplY3R9IHBheWxvYWQgLSBQYXlsb2FkIGRhdGFcbiAgICogQHJldHVybnMge1Byb21pc2V9XG4gICAqL1xuICBhc3luYyBwdWJsaXNoICh0b3BpYywgcGF5bG9hZCkge1xuICAgIGNvbnN0IHNlbmRlciA9ICh0aGlzLl9wdWJzdWJTZW5kZXJzIHx8IHt9KVt0b3BpY11cbiAgICBpZiAoIXNlbmRlcikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBOb3QgcmVhZHkgdG8gcHVibGlzaCB0b3BpYzogJHt0b3BpY31gKVxuICAgIH1cbiAgICByZXR1cm4gYXdhaXQgc2VuZGVyKHBheWxvYWQpXG4gIH1cbn0pXG5cbm1vZHVsZS5leHBvcnRzID0gUHVic3ViRXh0ZW5zaW9uXG4iXX0=