milo-core

MessageSource

declaration
MessageSource

milo.classes.MessageSource
An abstract class (subclass of Mixin) for connecting Messenger to external sources of messages (like DOM events) and defining higher level messages.
An instance of MessageSource can either be passed to Messenger constructor or later using _setMessageSource method of Messenger. Once set, MessageSource of Messenger cannot be changed.

var MessageSource = _.createSubclass(Mixin, 'MessageSource', true);

module.exports = MessageSource;

MessageSource instance methods

  • init - initializes messageSource - called by Mixin superclass
  • setMessenger - connects Messenger to MessageSource, is called from init or _setMessageSource methods of Messenger.
  • onSubscriberAdded - called by Messenger to notify when the first subscriber for an internal message was added, so MessageSource can subscribe to source
  • onSubscriberRemoved - called by Messenger to notify when the last subscriber for an internal message was removed, so MessageSource can unsubscribe from source
  • dispatchMessage - dispatches source message. MessageSource subclass should implement mechanism when on actual source message this method is called.

Methods below should be implemented in subclass:

_.extendProto(MessageSource, {
    init: init,
    destroy: MessageSource$destroy,
    setMessenger: setMessenger,
    onSubscriberAdded: onSubscriberAdded,
    onSubscriberRemoved: onSubscriberRemoved, 
    dispatchMessage: dispatchMessage,
    postMessage: postMessage,
    _prepareMessengerAPI: _prepareMessengerAPI,

    // Methods below must be implemented in subclass
    trigger: toBeImplemented,
    addSourceSubscriber: toBeImplemented,
    removeSourceSubscriber: toBeImplemented
});

init

function
init()

Option name Type Description
hostObject Object

Optional object that stores the MessageSource on one of its properties. It is used to proxy methods of MessageSource.

proxyMethods

Optional map of method names; key - proxy method name, value - MessageSource's method name.

messengerAPI MessengerAPI

Optional instance of MessengerAPI.

MessageSource instance method.
Called by Mixin constructor.
MessageSource constructor should be passed the same parameters as this method signature.
If an instance of MessengerAPI is passed as the third parameter, it extends MessageSource functionality to allow it to define new messages, to filter messages based on their data and to change message data. See MessengerAPI.

function init(hostObject, proxyMethods, messengerAPI) {
    this._prepareMessengerAPI(messengerAPI);
}

MessageSource$destroy

function
MessageSource$destroy()

Destroys message source

function MessageSource$destroy() {
    if (this.messengerAPI)
        this.messengerAPI.destroy();
}

setMessenger

function
setMessenger()

Option name Type Description
messenger Messenger

reference to Messenger instance linked to this MessageSource

MessageSource instance method.
Sets reference to Messenger instance.

function setMessenger(messenger) {
    _.defineProperty(this, 'messenger', messenger);
}

onSubscriberAdded

function
onSubscriberAdded()

Option name Type Description
message String

internal Messenger message that has to be subscribed to at the external source of messages.

MessageSource instance method.
Subscribes to external source using addSourceSubscriber method that should be implemented in subclass.
This method is called by Messenger when the first subscriber to the message is added.
Delegates to supplied or default MessengerAPI for translation of message to sourceMessage. MessageAPI.prototype.addInternalMessage will return undefined if this sourceMessage was already subscribed to to prevent duplicate subscription.

function onSubscriberAdded(message) {
    var newSourceMessage = this.messengerAPI.addInternalMessage(message);
    if (typeof newSourceMessage != 'undefined')
        this.addSourceSubscriber(newSourceMessage);
}

onSubscriberRemoved

function
onSubscriberRemoved()

Option name Type Description
message String

internal Messenger message that has to be unsubscribed from at the external source of messages.

MessageSource instance method.
Unsubscribes from external source using removeSourceSubscriber method that should be implemented in subclass.
This method is called by Messenger when the last subscriber to the message is removed.
Delegates to supplied or default MessengerAPI for translation of message to sourceMessage. MessageAPI.prototype.removeInternalMessage will return undefined if this sourceMessage was not yet subscribed to to prevent unsubscription without previous subscription.

function onSubscriberRemoved(message) {
    var removedSourceMessage = this.messengerAPI.removeInternalMessage(message);
    if (typeof removedSourceMessage != 'undefined')
        this.removeSourceSubscriber(removedSourceMessage);
}

dispatchMessage

function
dispatchMessage()

Option name Type Description
sourceMessage String

source message received from external source

sourceData Object

data received from external source

MessageSource instance method.
Dispatches sourceMessage to Messenger.
Mechanism that calls this method when the source message is received should be implemented by subclass (see DOMEventsSource for example).
Delegates to supplied or default MessengerAPI to create internal message data (createInternalData) and to filter the message based on its data and/or message (filterSourceMessage).
Base MessengerAPI class implements these two methods in a trivial way (createInternalData simply returns external data, filterSourceMessage returns true), they are meant to be implemented by subclass.

function dispatchMessage(sourceMessage, sourceData) {
    var api = this.messengerAPI
        , internalMessages = api.getInternalMessages(sourceMessage);

    if (internalMessages) 
        internalMessages.forEach(function (message) {
            var internalData = api.createInternalData(sourceMessage, message, sourceData);

            var shouldDispatch = api.filterSourceMessage(sourceMessage, message, internalData);
            if (shouldDispatch) 
                this.postMessage(message, internalData);      
            
        }, this);
}

postMessage

function
postMessage()

Option name Type Description
message String
data Object

Posts message on the messenger. This method is separated so specific message sources can make message dispatch synchronous by using postMessageSync

function postMessage(message, data) {
    this.messenger.postMessage(message, data);
}


function toBeImplemented() {
    throw new Error('calling the method of an absctract class');
}