UNPKG

blinx

Version:

The Scalable JavaScript Application Framework

245 lines (208 loc) 8.29 kB
var _createClass = 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } import Utils from '../helpers/utils'; import { moduleS, subscriptions, eventQ } from './store.js'; var subscribeLogger = function subscribeLogger(eventName, subscription) { console.group('Event Subscribed'); console.info(eventName); console.dirxml(subscription); console.groupEnd(); }; var publishLogger = function publishLogger(eventName, publishData) { console.group('Event Published'); console.info(eventName); console.dirxml(publishData); console.groupEnd(); }; var unsubscribeLogger = function unsubscribeLogger(eventName, subscription) { console.group('Event UnSubscribed'); console.info(eventName); console.dirxml(subscription); console.groupEnd(); }; /** * Check if the module is rendered * @param moduleContext {Object} the moduleContext object */ var isModuleRendered = function isModuleRendered(moduleContext) { return moduleContext && moduleContext.lifeCycleFlags && moduleContext.lifeCycleFlags.rendered == true; }; /** * Check if the module has initOn * @param moduleContext {Object} the moduleContext object * @param EventName {String} */ var checkIfModuleHasInitOn = function checkIfModuleHasInitOn(moduleContext, eventName) { // Should also remove from the eventQ maintained return moduleContext && moduleContext.instanceConfig && moduleContext.instanceConfig.initOn && moduleContext.instanceConfig.initOn.eventName == eventName; }; /** * Check if the event is subscribed or published using global pubsub * @param instance {Object} the instance object using which the pub sub is handled */ var isGlobalPubsub = function isGlobalPubsub(instance) { return instance && instance.getInstanceName() == 'PUBSUB'; }; /** * @class * PubSub * The publisher subscriber module for Blinx. * It is responsible for the communication between the modules through events */ var PubSub = function () { function PubSub() { _classCallCheck(this, PubSub); } _createClass(PubSub, [{ key: 'subscribe', /** * Subscribes to the blinx event * @method * @public * @param subscription {Object} the subscription object * @param [eventName = subscription.eventName] */ value: function subscribe(subscription) { var eventName = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : subscription.eventName; if (!subscriptions[eventName]) subscriptions[eventName] = []; var subscriptionData = Utils.pick(subscription, ['callback', 'context', 'eventSubscriber', 'eventPublisher', 'once', 'type']); subscriptionData.moduleContext = this; subscriptions[eventName].push(subscriptionData); subscribeLogger(eventName, subscription); } /** * Publishes a blinx event * @method * @public * @param eventName {string} * @param message {string} */ }, { key: 'publish', value: function publish(eventName, message) { var publisher = ''; if (arguments.length === 3) { publisher = arguments[0] || ''; eventName = arguments[1]; message = arguments[2]; } else { publisher = Utils.getCSSSelector(this); } var subscriptionsForEvent = subscriptions[eventName], remainingSubscriptions = []; publishLogger(eventName, { eventName: eventName, message: message, publisher: publisher, subscription: subscriptionsForEvent }); if (!subscriptionsForEvent) { return; } // If any of the subscription is of type Replay // Push the message to eventQ var replaySubscriptions = subscriptionsForEvent.filter(function (subs) { if (subs.type === 'RE_PLAY') return subs; }); if (replaySubscriptions.length) { eventQ.store.push({ eventName: eventName, message: message, publisher: publisher }); } subscriptionsForEvent && subscriptionsForEvent.length && subscriptionsForEvent.forEach(function (subscription) { var callback = subscription.callback, context = subscription.context, subscribeOnce = subscription.once, moduleContext = subscription.moduleContext, subscriptionMatched = false; if (!callback || typeof callback !== 'function') { console.error('The callback for the event is invalid'); return; } if (subscription.eventPublisher) { var regex = new RegExp(subscription.eventPublisher + '$'); if (regex.test(publisher)) { subscriptionMatched = true; } else { var actualPublisherHierarchy = publisher.split(' '), subscriptionPublisherHierarhcy = subscription.eventPublisher.split(' '), actualPublisherHierarchyLength = actualPublisherHierarchy.length, subscriptionPublisherHierarhcyLength = subscriptionPublisherHierarhcy.length; while (actualPublisherHierarchy.length && subscriptionPublisherHierarhcy.length) { actualPublisherHierarchyLength = actualPublisherHierarchy.length; subscriptionPublisherHierarhcyLength = subscriptionPublisherHierarhcy.length; if (actualPublisherHierarchy[actualPublisherHierarchyLength - 1] === subscriptionPublisherHierarhcy[subscriptionPublisherHierarhcyLength - 1]) { actualPublisherHierarchy.pop(); subscriptionPublisherHierarhcy.pop(); } else { actualPublisherHierarchy.pop(); } } if (!subscriptionPublisherHierarhcy.length) { subscriptionMatched = true; } } } if (!subscription.eventPublisher || subscriptionMatched) { // If replay event: publish only after render is complete // If replay event: publish all the data matched from event queue var publishData = message; if (isModuleRendered(moduleContext) || checkIfModuleHasInitOn(moduleContext, eventName) || isGlobalPubsub(moduleContext) || subscription.type == 'KEEP_ON') { callback.call(context || null, publishData); } if (subscribeOnce) { subscriptions[eventName] = subscriptions[eventName].filter(function (sub) { return sub.eventSubscriber !== subscription.eventSubscriber && sub.eventName !== subscription.eventName; }); } } }); } /** * unsubscribes a blinx event * @public * @param subscriber {Object} the reference of the module which had subscribed the event earlier * @param eventName {string} * @param callback {function} the callback method to be unsubscribed */ }, { key: 'unsubscribe', value: function unsubscribe(subscriber, eventName, callback) { var subscriptionsForEvent = subscriptions[eventName]; if (!subscriptionsForEvent) { return; } // Check if any RE_PLAY event is there and all the event context is of is same as // destroy its data from eventQ var replaySubscriptions = subscriptionsForEvent.filter(function (subscription) { if (subscription.type === 'RE_PLAY') return subscription; }); subscriptions[eventName] = subscriptionsForEvent.filter(function (subscription) { return !(subscription.callback === callback && subscription.eventSubscriber === subscriber); }); unsubscribeLogger(eventName, subscriptionsForEvent); if (replaySubscriptions.length) { if (!subscriptions[eventName].length) { // Remove all the items from eventQ with eventName eventQ.store = eventQ.store.filter(function (evt) { if (evt.eventName !== eventName) return evt; }); } } } /** * For internal use * This method is currently used to check is the event occured via Pub sub or a module * @returns {string} */ }, { key: 'getInstanceName', value: function getInstanceName() { return 'PUBSUB'; } }]); return PubSub; }(); export default PubSub;