Source: Reference.js

import beof from 'beof';
import Promise from 'bluebird';

class RefStateObserver {

    stateChanged() {

    }

}

/**
 * Reference acts as a handle for a Concern. Rather
 * than reaching the Concern's interface directly we restrict communication
 * via the Reference.
 *
 * This has the effect of enforcing message passing via a very specific interface.
 * @param {RefState} state
 * @implements {Observable}
 */
class Reference {

    constructor(state) {

        this._promise = Promise.resolve();
        this._state = state;
        this._observers = [];

    }

    _notify(old, neu) {

        this._observers.forEach(o => o.stateChanged(old, neu, this));

    }

    /**
     * path returns the full path (inclusive of protocol information) of this Reference.
     * @returns {string}
     */
    path() {

        return this._state.path();

    }

    observe(observer) {

        beof({observer}).interface(RefStateObserver);
        this._observers.push(observer);

    }

    accept(msg, sender) {

        var old;

        this._promise = this._promise.then(this._state.getState(msg).then(state => {

            if (state !== this._state) {
                old = this.state;
                this._state = state;
                this._notify(old, state);
            } else {
                this._state.accept(msg, sender);
            }

        }));

    }

    acceptAndPromise(msg, sender) {

        var old;

        return this._promise = this._promise.then(this._state.getState(msg).then(state => {

            if (state !== this._state) {
                old = this.state;
                this._state = state;
                this._notify(old, state);
                return Promise.resolve(null);
            } else {
                return this._state.acceptAndPromise(msg, sender);
            }

        }));

    }
}

export default Reference