Source: msg/MailDispatcher.js

import Promise from 'bluebird';

const keyify = function(msg) {

    switch (typeof msg) {

        case 'function':
            return msg.name;

        case 'object':
            return msg.constructor.name;

        default:
            return '' + msg;

    }

}

/**
 * MailDispatcher handles the actual delivery of messages to
 * Concerns from their MailBox.
 * @param {Concern} concern
 * @implements {EnqueueListener}
 */
class MailDispatcher {

    constructor(concern) {

        this._concern = concern;

    }

    onEnqueue(box) {

        var next = function(box) {

            var _next = box.dequeue();

            if (_next === null)
                return;

            Promise.resolve(_next.to.accept(_next.message, _next.sender)).
            then(actions => {

                var action = null;

                if (!actions)
                    return null;

                else if (typeof actions === 'object')
                    action = actions[keyify(msg)];

                else if (typeof actions === 'function')
                    action = actions;

                if (typeof action === 'function')
                    return Promise.resolve(action);

            }).
            catch(e => {

                return _next.to.parent();

            })
        }

    }
}

export default MailDispatcher