sg-socket-client
Version:
Web socket client for SUGOS
265 lines (226 loc) • 15.8 kB
JavaScript
/**
* 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=