const isEqual = function(original, fn) {
  return function(val) {
    fn(val===original);
  }
};
const Store = function(cfg) {
  Observable.call(this);
  this._props = cfg || {};
};

Store.prototype = {
  set: function(key, val) {
    if(this._props[key] !== val){
      this._props[ key ] = val;
      this.fire( 'change', key, val );
      this.fire( key, val );
    }
  },
  get: function(key) {
    return this._props[key];
  },
  sub: function(key, fn) {
    if(Array.isArray(key)){
      var wrap = () => fn.apply(this, key.map(key=>this.get(key)));

      for( var i = 0, _i = key.length; i < _i; i++ ){
        this.on(key[i], wrap)
      }
      wrap();
    }else{
      this.on( key, fn )
      fn( this.get( key ) );
    }
    return this;
  },
  equal: function(key, val, fn) {
    const wrap = isEqual(val, fn);
    this.on(key, wrap);
    wrap(this.get(key));
    return this;
  }
};

Store.prototype = Object.assign(new Observable, Store.prototype);