publisher-subscriber-pattern
Version:
Publisher subscriber pattern that can be used with different event emitters including browser window
147 lines (111 loc) • 5.06 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.Publisher = void 0;
var _types = require("./_types");
var _subscriber = require("./subscriber");
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
var Publisher =
/*#__PURE__*/
function () {
function Publisher() {
var _this = this;
_classCallCheck(this, Publisher);
_defineProperty(this, "eventData", void 0);
_defineProperty(this, "addEventListener", void 0);
_defineProperty(this, "removeEventListener", void 0);
_defineProperty(this, "subscribe", function (eventName, eventCallback, subscriberInstance) {
var subscriber = new _subscriber.Subscriber(eventCallback, subscriberInstance);
var eventData = _this.getEventData(eventName);
if (!eventData) {
eventData = _this.eventData.set(eventName, [_this.buildInformSubscribers(eventName), []]).get(eventName);
_this.observeEvent(eventName, eventData);
}
eventData[1].push(subscriber);
return _this.unsubscribe(eventName, subscriber);
});
_defineProperty(this, "unsubscribeAll", function () {
Array.from(_this.eventData.keys()).forEach(function (eventName) {
_this.unobserveEvent(eventName);
});
});
_defineProperty(this, "eventSubscribersCount", function (eventName) {
return (_this.getSubscribers(eventName) || []).length;
});
_defineProperty(this, "subscribersCount", function () {
return Array.from(_this.eventData.values()).reduce(function () {
var count = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
var eventData = arguments.length > 1 ? arguments[1] : undefined;
count += eventData[1].length;
return count;
}, 0);
});
_defineProperty(this, "buildInformSubscribers", function (eventName) {
return function (event) {
(_this.getSubscribers(eventName) || []).forEach(function (subscriber) {
return subscriber.eventCallback(event);
});
};
});
_defineProperty(this, "unsubscribe", function (eventName, subscriber) {
return function () {
var subscribersArray = (_this.getEventData(eventName) || [])[1];
if (subscribersArray) {
subscribersArray.splice(subscribersArray.findIndex(function (item) {
return item === subscriber;
}), 1);
if (!subscribersArray.length) {
_this.unobserveEvent(eventName);
}
}
return;
};
});
_defineProperty(this, "observeEvent", function (eventName, eventData) {
var eventCallback = eventData ? eventData[0] : _this.getEventCallback(eventName);
if (eventCallback) {
_this.addEventListener(eventName, eventCallback);
}
});
_defineProperty(this, "unobserveEvent", function (eventName) {
_this.removeEventListener(eventName, _this.getEventCallback(eventName));
_this.eventData["delete"](eventName);
});
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
var emitterInstance = args[0],
addListenerMethodName = args[1],
removeListenerMethodName = args[2];
if (!(0, _types.isValidEmitter)(emitterInstance, addListenerMethodName, removeListenerMethodName)) {
throw new Error('Publisher received incorrect arguments');
}
this.eventData = new Map([]);
this.addEventListener = // @ts-ignore
emitterInstance[addListenerMethodName].bind(emitterInstance);
this.removeEventListener = // @ts-ignore
emitterInstance[removeListenerMethodName].bind(emitterInstance);
}
_createClass(Publisher, [{
key: "getEventData",
value: function getEventData(eventName) {
return this.eventData.get(eventName);
}
}, {
key: "getEventCallback",
value: function getEventCallback(eventName) {
return (this.getEventData(eventName) || [])[0];
}
}, {
key: "getSubscribers",
value: function getSubscribers(eventName) {
return (this.getEventData(eventName) || [])[1];
}
}]);
return Publisher;
}();
exports.Publisher = Publisher;