Socket
Socket
Sign inDemoInstall

mobservable

Package Overview
Dependencies
0
Maintainers
1
Versions
79
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.6.4 to 0.6.5

5

CHANGELOG.md

@@ -0,1 +1,6 @@

# 0.6.5:
* It is no longer possible to create impure views; views that alter other reactive values.
* Update links to the new documentation.
# 0.6.4:

@@ -2,0 +7,0 @@

43

dist/mobservable.js

@@ -209,2 +209,6 @@ /**

_.stackDepth = stackDepth;
function isComputingView() {
return __mobservableTrackingStack.length > 0;
}
_.isComputingView = isComputingView;
})(_ = mobservable._ || (mobservable._ = {}));

@@ -501,2 +505,3 @@ })(mobservable || (mobservable = {}));

set: function (newLength) {
this.assertNotComputing("spliceWithArray");
if (typeof newLength !== "number" || newLength < 0)

@@ -528,2 +533,3 @@ throw new Error("Out of range: " + newLength);

var _this = this;
this.assertNotComputing("spliceWithArray");
var length = this.$mobservable.values.length;

@@ -625,3 +631,3 @@ if ((newItems === undefined || newItems.length === 0) && (deleteCount === 0 || length === 0))

}
this.sideEffectWarning("splice");
this.assertNotComputing("splice");
switch (arguments.length) {

@@ -642,3 +648,3 @@ case 0:

}
this.sideEffectWarning("push");
this.assertNotComputing("push");
this.spliceWithArray(this.$mobservable.values.length, 0, items);

@@ -648,7 +654,7 @@ return this.$mobservable.values.length;

ObservableArray.prototype.pop = function () {
this.sideEffectWarning("pop");
this.assertNotComputing("pop");
return this.splice(Math.max(this.$mobservable.values.length - 1, 0), 1)[0];
};
ObservableArray.prototype.shift = function () {
this.sideEffectWarning("shift");
this.assertNotComputing("shift");
return this.splice(0, 1)[0];

@@ -661,3 +667,3 @@ };

}
this.sideEffectWarning("unshift");
this.assertNotComputing("unshift");
this.spliceWithArray(0, 0, items);

@@ -667,11 +673,11 @@ return this.$mobservable.values.length;

ObservableArray.prototype.reverse = function () {
this.sideEffectWarning("reverse");
this.assertNotComputing("reverse");
return this.replace(this.$mobservable.values.reverse());
};
ObservableArray.prototype.sort = function (compareFn) {
this.sideEffectWarning("sort");
this.assertNotComputing("sort");
return this.replace(this.$mobservable.values.sort.apply(this.$mobservable.values, arguments));
};
ObservableArray.prototype.remove = function (value) {
this.sideEffectWarning("remove");
this.assertNotComputing("remove");
var idx = this.$mobservable.values.indexOf(value);

@@ -705,5 +711,9 @@ if (idx > -1) {

};
ObservableArray.prototype.sideEffectWarning = function (funcName) {
if (mobservable.debugLevel > 0 && __mobservableTrackingStack.length > 0)
_.warn("[Mobservable.Array] The method array." + funcName + " should probably not be used inside observable functions since it has side-effects");
ObservableArray.prototype.assertNotComputing = function (funcName) {
if (_.isComputingView()) {
var e = "[Mobservable.Array] The method array." + funcName + " is not allowed to be used inside reactive views since it alters the state.";
console.error(e);
console.trace();
throw new Error();
}
};

@@ -869,2 +879,3 @@ return ObservableArray;

(function (_) {
_.NON_PURE_VIEW_ERROR = "[Mobservable] It is not allowed to change the state during the computation of a reactive view.";
var ObservableValue = (function (_super) {

@@ -888,2 +899,7 @@ __extends(ObservableValue, _super);

ObservableValue.prototype.set = function (value) {
if (_.isComputingView()) {
console.error(_.NON_PURE_VIEW_ERROR);
console.trace();
throw new Error(_.NON_PURE_VIEW_ERROR);
}
if (value !== this._value) {

@@ -943,3 +959,3 @@ var oldValue = this._value;

if (this.isSleeping) {
if (__mobservableTrackingStack.length > 0) {
if (_.isComputingView()) {
this.wakeUp();

@@ -949,3 +965,4 @@ this.notifyObserved();

else {
this.compute();
this.wakeUp();
this.tryToSleep();
}

@@ -952,0 +969,0 @@ }

@@ -1,1 +0,1 @@

var __extends=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c},mobservable;!function(a){var b=function(){return this}();b.__mobservableTrackingStack=[];var c;!function(b){function c(){return __mobservableTrackingStack.length}var d=0;!function(a){a[a.STALE=0]="STALE",a[a.PENDING=1]="PENDING",a[a.READY=2]="READY"}(b.DNodeState||(b.DNodeState={}));var e=b.DNodeState,f=function(){function a(a){this.context=a,this.id=++d,this.state=e.READY,this.observers=[],this.isDisposed=!1,this.externalRefenceCount=0,a.name||(a.name="[m#"+this.id+"]")}return a.prototype.setRefCount=function(a){this.externalRefenceCount+=a},a.prototype.addObserver=function(a){this.observers[this.observers.length]=a},a.prototype.removeObserver=function(a){var b=this.observers,c=b.indexOf(a);-1!==c&&b.splice(c,1)},a.prototype.markStale=function(){this.state===e.READY&&(this.state=e.STALE,b.transitionTracker&&b.reportTransition(this,"STALE"),this.notifyObservers())},a.prototype.markReady=function(a){this.state!==e.READY&&(this.state=e.READY,b.transitionTracker&&b.reportTransition(this,"READY",!0,this._value),this.notifyObservers(a))},a.prototype.notifyObservers=function(a){void 0===a&&(a=!1);for(var b=this.observers.slice(),c=b.length,d=0;c>d;d++)b[d].notifyStateChange(this,a)},a.prototype.notifyObserved=function(){var a=__mobservableTrackingStack,b=a.length;if(b>0){var c=a[b-1],d=c.length;c[d-1]!==this&&c[d-2]!==this&&(c[d]=this)}},a.prototype.dispose=function(){if(this.observers.length)throw new Error("Cannot dispose DNode; it is still being observed");this.isDisposed=!0},a.prototype.toString=function(){return"DNode["+this.context.name+", state: "+this.state+", observers: "+this.observers.length+"]"},a}();b.RootDNode=f;var g=function(c){function d(){c.apply(this,arguments),this.isSleeping=!0,this.hasCycle=!1,this.observing=[],this.prevObserving=null,this.dependencyChangeCount=0,this.dependencyStaleCount=0}return __extends(d,c),d.prototype.setRefCount=function(a){var b=this.externalRefenceCount+=a;0===b?this.tryToSleep():b===a&&this.wakeUp()},d.prototype.removeObserver=function(a){c.prototype.removeObserver.call(this,a),this.tryToSleep()},d.prototype.tryToSleep=function(){if(!this.isSleeping&&0===this.observers.length&&0===this.externalRefenceCount){for(var a=0,b=this.observing.length;b>a;a++)this.observing[a].removeObserver(this);this.observing=[],this.isSleeping=!0}},d.prototype.wakeUp=function(){this.isSleeping&&(this.isSleeping=!1,this.state=e.PENDING,this.computeNextState())},d.prototype.notifyStateChange=function(a,c){var d=this;a.state===e.STALE?1===++this.dependencyStaleCount&&this.markStale():(c&&(this.dependencyChangeCount+=1),0===--this.dependencyStaleCount&&(this.state=e.PENDING,b.Scheduler.schedule(function(){d.dependencyChangeCount>0?d.computeNextState():d.markReady(!1),d.dependencyChangeCount=0})))},d.prototype.computeNextState=function(){this.trackDependencies(),b.transitionTracker&&b.reportTransition(this,"PENDING");var a=this.compute();this.bindDependencies(),this.markReady(a)},d.prototype.compute=function(){throw"Abstract!"},d.prototype.trackDependencies=function(){this.prevObserving=this.observing,__mobservableTrackingStack[__mobservableTrackingStack.length]=[]},d.prototype.bindDependencies=function(){this.observing=__mobservableTrackingStack.pop(),0===this.observing.length&&a.debugLevel>1&&!this.isDisposed&&(console.trace(),b.warn("You have created a function that doesn't observe any values, did you forget to make its dependencies observable?"));var c=b.quickDiff(this.observing,this.prevObserving),e=c[0],f=c[1];this.prevObserving=null;for(var g=0,h=f.length;h>g;g++)f[g].removeObserver(this);this.hasCycle=!1;for(var g=0,h=e.length;h>g;g++){var i=e[g];i instanceof d&&i.findCycle(this)?(this.hasCycle=!0,this.observing.splice(this.observing.indexOf(e[g]),1),i.hasCycle=!0):e[g].addObserver(this)}},d.prototype.findCycle=function(a){var b=this.observing;if(-1!==b.indexOf(a))return!0;for(var c=b.length,e=0;c>e;e++)if(b[e]instanceof d&&b[e].findCycle(a))return!0;return!1},d.prototype.dispose=function(){if(this.observing)for(var a=this.observing.length,b=0;a>b;b++)this.observing[b].removeObserver(this);this.observing=null,c.prototype.dispose.call(this)},d}(f);b.ObservingDNode=g,b.stackDepth=c}(c=a._||(a._={}))}(mobservable||(mobservable={}));var mobservable;!function(a){function b(a,b){if(d(a))return a;b=b||{},a instanceof k.AsReference&&(a=a.value,b.as="reference");var c=b.recurse!==!1,e="reference"===b.as?k.ValueType.Reference:k.getTypeOfValue(a),f={name:b.name,object:b.context||b.scope};switch(e){case k.ValueType.Reference:case k.ValueType.ComplexObject:return k.toGetterSetterFunction(new k.ObservableValue(a,!1,f));case k.ValueType.ComplexFunction:throw new Error("[mobservable:error] Creating reactive functions from functions with multiple arguments is currently not supported, see https://github.com/mweststrate/mobservable/issues/12");case k.ValueType.ViewFunction:return f.name||(f.name=a.name),k.toGetterSetterFunction(new k.ObservableView(a,b.scope||b.context,f));case k.ValueType.Array:return new k.ObservableArray(a,c,f);case k.ValueType.PlainObject:return k.extendReactive({},a,c,f)}throw"Illegal State"}function c(a){return new k.AsReference(a)}function d(a){return null===a||void 0===a?!1:!!a.$mobservable}function e(a,b){var c=new k.ObservableView(a,b,{object:b,name:a.name}),d=c.observe(k.noop);return 0===c.observing.length&&k.warn("mobservable.sideEffect: not a single observable was used inside the side-effect function. Side-effect would be a no-op."),d.$mobservable=c,d}function f(a,b,c){k.extendReactive(a,b,!0,c)}function g(a,b,c){var d=c?c.value:null;if("function"==typeof d)throw new Error("@observable functions are deprecated. Use @observable (getter) properties instead");if(c&&c.set)throw new Error("@observable properties cannot have a setter.");Object.defineProperty(a,b,{configurable:!0,enumberable:!0,get:function(){return k.ObservableObject.asReactive(this,null).set(b,void 0,!0),this[b]},set:function(a){k.ObservableObject.asReactive(this,null).set(b,a,!0)}})}function h(a){if(!a)return a;if(Array.isArray(a)||a instanceof k.ObservableArray)return a.map(h);if("object"==typeof a){var b={};for(var c in a)a.hasOwnProperty(c)&&(b[c]=h(a[c]));return b}return a}function i(a){return k.Scheduler.batch(a)}function j(a,b,c){var d=new k.WatchedExpression(a,b,c||a.name);return[d.value,function(){return d.dispose()},d]}a.makeReactive=b,a.asReference=c,a.isReactive=d,a.sideEffect=e,a.extendReactive=f,a.observable=g,a.toJson=h,a.transaction=i,a.observeUntilInvalid=j,a.debugLevel=0;var k;!function(a){function b(b){return null===b||void 0===b?e.Reference:"function"==typeof b?b.length?e.ComplexFunction:e.ViewFunction:Array.isArray(b)||b instanceof a.ObservableArray?e.Array:"object"==typeof b?a.isPlainObject(b)?e.PlainObject:e.ComplexObject:e.Reference}function c(b,c,d,e){var f=a.ObservableObject.asReactive(b,e);for(var g in c)c.hasOwnProperty(g)&&f.set(g,c[g],d);return b}function d(a){var b=function(b){return arguments.length>0?void a.set(b):a.get()};return b.$mobservable=a,b.observe=function(b,c){return a.observe(b,c)},b.toString=function(){return a.toString()},b}!function(a){a[a.Reference=0]="Reference",a[a.PlainObject=1]="PlainObject",a[a.ComplexObject=2]="ComplexObject",a[a.Array=3]="Array",a[a.ViewFunction=4]="ViewFunction",a[a.ComplexFunction=5]="ComplexFunction"}(a.ValueType||(a.ValueType={}));var e=a.ValueType;a.getTypeOfValue=b,a.extendReactive=c,a.toGetterSetterFunction=d;var f=function(){function a(a){this.value=a}return a}();a.AsReference=f}(k=a._||(a._={}))}(mobservable||(mobservable={}));var mobservable;!function(a){var b;!function(a){function b(a){console&&console.warn("[mobservable:warning] "+a)}function c(a){var b=!1;return function(){return b?void 0:(b=!0,a.apply(this,arguments))}}function d(){}function e(a){var b=[];return a.forEach(function(a){-1===b.indexOf(a)&&b.push(a)}),b}function f(a){return null!==a&&"object"==typeof a&&Object.getPrototypeOf(a)===Object.prototype}function g(a,b){if(!b||!b.length)return[a,[]];if(!a||!a.length)return[[],b];for(var c=[],d=[],e=0,f=0,g=a.length,h=!1,i=0,j=0,k=b.length,l=!1,m=!1;!m&&!h;){if(!l){if(g>e&&k>i&&a[e]===b[i]){if(e++,i++,e===g&&i===k)return[c,d];continue}f=e,j=i,l=!0}j+=1,f+=1,j>=k&&(m=!0),f>=g&&(h=!0),h||a[f]!==b[i]?m||b[j]!==a[e]||(d.push.apply(d,b.slice(i,j)),i=j+1,e++,l=!1):(c.push.apply(c,a.slice(e,f)),e=f+1,i++,l=!1)}return c.push.apply(c,a.slice(e)),d.push.apply(d,b.slice(i)),[c,d]}a.warn=b,a.once=c,a.noop=d,a.unique=e,a.isPlainObject=f,a.quickDiff=g}(b=a._||(a._={}))}(mobservable||(mobservable={}));var mobservable;!function(a){var b;!function(b){function c(a){var b={enumerable:!1,configurable:!1,set:function(b){if(a<this.$mobservable.values.length){var c=this.$mobservable.values[a];c!==b&&(this.$mobservable.values[a]=b,this.notifyChildUpdate(a,c))}else{if(a!==this.$mobservable.values.length)throw new Error("ObservableArray: Index out of bounds, "+a+" is larger than "+this.values.length);this.push(b)}},get:function(){return a<this.$mobservable.values.length?(this.$mobservable.notifyObserved(),this.$mobservable.values[a]):void 0}};Object.defineProperty(g.prototype,""+a,b),b.enumerable=!0,b.configurable=!0,i[a]=b}function d(a){for(var b=h;a>b;b++)c(b);h=a}var e=function(){function a(){}return a}();e.prototype=[];var f=function(a){function c(c,d,e){a.call(this,e),this.array=c,this.recurse=d,this.values=[],this.changeEvent=new b.SimpleEventEmitter,e.object||(e.object=c)}return __extends(c,a),c}(b.RootDNode);b.ObservableArrayAdministration=f;var g=function(c){function e(a,b,d){c.call(this),Object.defineProperty(this,"$mobservable",{enumerable:!1,configurable:!1,value:new f(this,b,d)}),a&&a.length&&this.replace(a)}return __extends(e,c),Object.defineProperty(e.prototype,"length",{get:function(){return this.$mobservable.notifyObserved(),this.$mobservable.values.length},set:function(a){if("number"!=typeof a||0>a)throw new Error("Out of range: "+a);var b=this.$mobservable.values.length;a!==b&&(a>b?this.spliceWithArray(b,0,new Array(a-b)):this.spliceWithArray(a,b-a))},enumerable:!0,configurable:!0}),e.prototype.updateLength=function(a,b){if(0>b)for(var c=a+b;a>c;c++)delete this[c];else if(b>0){a+b>h&&d(a+b);for(var c=a,e=a+b;e>c;c++)Object.defineProperty(this,""+c,i[c])}},e.prototype.spliceWithArray=function(a,b,c){var d=this,e=this.$mobservable.values.length;if(!(void 0!==c&&0!==c.length||0!==b&&0!==e))return[];void 0===a?a=0:a>e?a=e:0>a&&(a=Math.max(0,e+a)),b=1===arguments.length?e-a:void 0===b||null===b?0:Math.max(0,Math.min(b,e-a)),void 0===c?c=[]:this.$mobservable.recurse&&(c=c.map(function(a){return d.makeReactiveArrayItem(a)}));var f=c.length-b,g=(h=this.$mobservable.values).splice.apply(h,[a,b].concat(c));return this.updateLength(e,f),this.notifySplice(a,g,c),g;var h},e.prototype.makeReactiveArrayItem=function(c){if(a.isReactive(c))return c;if(c instanceof b.AsReference)return c=c.value;var d={object:this.$mobservable.context.object,name:this.$mobservable.context.name+"[x]"};return Array.isArray(c)?new b.ObservableArray(c,!0,d):b.isPlainObject(c)?b.extendReactive({},c,!0,d):c},e.prototype.notifyChildUpdate=function(a,b){this.notifyChanged(),this.$mobservable.changeEvent.emit({object:this,type:"update",index:a,oldValue:b})},e.prototype.notifySplice=function(a,b,c){(0!==b.length||0!==c.length)&&(this.notifyChanged(),this.$mobservable.changeEvent.emit({object:this,type:"splice",index:a,addedCount:c.length,removed:b}))},e.prototype.notifyChanged=function(){this.$mobservable.markStale(),this.$mobservable.markReady(!0)},e.prototype.observe=function(a,b){return void 0===b&&(b=!1),b&&a({object:this,type:"splice",index:0,addedCount:this.$mobservable.values.length,removed:[]}),this.$mobservable.changeEvent.on(a)},e.prototype.clear=function(){return this.splice(0)},e.prototype.replace=function(a){return this.spliceWithArray(0,this.$mobservable.values.length,a)},e.prototype.values=function(){return this.$mobservable.notifyObserved(),this.$mobservable.values.slice()},e.prototype.toJSON=function(){return this.$mobservable.notifyObserved(),this.$mobservable.values.slice()},e.prototype.clone=function(){return this.$mobservable.notifyObserved(),new e(this.$mobservable.values,this.$mobservable.recurse,{object:null,name:this.$mobservable.context.name+"[clone]"})},e.prototype.find=function(a,b,c){void 0===c&&(c=0),this.$mobservable.notifyObserved();for(var d=this.$mobservable.values,e=d.length,f=c;e>f;f++)if(a.call(b,d[f],f,this))return d[f];return null},e.prototype.splice=function(a,b){for(var c=[],d=2;d<arguments.length;d++)c[d-2]=arguments[d];switch(this.sideEffectWarning("splice"),arguments.length){case 0:return[];case 1:return this.spliceWithArray(a);case 2:return this.spliceWithArray(a,b)}return this.spliceWithArray(a,b,c)},e.prototype.push=function(){for(var a=[],b=0;b<arguments.length;b++)a[b-0]=arguments[b];return this.sideEffectWarning("push"),this.spliceWithArray(this.$mobservable.values.length,0,a),this.$mobservable.values.length},e.prototype.pop=function(){return this.sideEffectWarning("pop"),this.splice(Math.max(this.$mobservable.values.length-1,0),1)[0]},e.prototype.shift=function(){return this.sideEffectWarning("shift"),this.splice(0,1)[0]},e.prototype.unshift=function(){for(var a=[],b=0;b<arguments.length;b++)a[b-0]=arguments[b];return this.sideEffectWarning("unshift"),this.spliceWithArray(0,0,a),this.$mobservable.values.length},e.prototype.reverse=function(){return this.sideEffectWarning("reverse"),this.replace(this.$mobservable.values.reverse())},e.prototype.sort=function(a){return this.sideEffectWarning("sort"),this.replace(this.$mobservable.values.sort.apply(this.$mobservable.values,arguments))},e.prototype.remove=function(a){this.sideEffectWarning("remove");var b=this.$mobservable.values.indexOf(a);return b>-1?(this.splice(b,1),!0):!1},e.prototype.toString=function(){return this.wrapReadFunction("toString",arguments)},e.prototype.toLocaleString=function(){return this.wrapReadFunction("toLocaleString",arguments)},e.prototype.concat=function(){return this.wrapReadFunction("concat",arguments)},e.prototype.join=function(a){return this.wrapReadFunction("join",arguments)},e.prototype.slice=function(a,b){return this.wrapReadFunction("slice",arguments)},e.prototype.indexOf=function(a,b){return this.wrapReadFunction("indexOf",arguments)},e.prototype.lastIndexOf=function(a,b){return this.wrapReadFunction("lastIndexOf",arguments)},e.prototype.every=function(a,b){return this.wrapReadFunction("every",arguments)},e.prototype.some=function(a,b){return this.wrapReadFunction("some",arguments)},e.prototype.forEach=function(a,b){return this.wrapReadFunction("forEach",arguments)},e.prototype.map=function(a,b){return this.wrapReadFunction("map",arguments)},e.prototype.filter=function(a,b){return this.wrapReadFunction("filter",arguments)},e.prototype.reduce=function(a,b){return this.wrapReadFunction("reduce",arguments)},e.prototype.reduceRight=function(a,b){return this.wrapReadFunction("reduceRight",arguments)},e.prototype.wrapReadFunction=function(a,b){var c=Array.prototype[a];return(e.prototype[a]=function(){return this.$mobservable.notifyObserved(),c.apply(this.$mobservable.values,arguments)}).apply(this,b)},e.prototype.sideEffectWarning=function(c){a.debugLevel>0&&__mobservableTrackingStack.length>0&&b.warn("[Mobservable.Array] The method array."+c+" should probably not be used inside observable functions since it has side-effects")},e}(e);b.ObservableArray=g;var h=0,i=[];d(1e3)}(b=a._||(a._={}))}(mobservable||(mobservable={}));var mobservable;!function(a){var b;!function(b){function c(c,d){if(!a.isReactive(c))throw new Error("[mobservable.getDNode] "+c+" doesn't seem to be reactive");if(void 0!==d){__mobservableTrackingStack.push([]),c[d];var e=__mobservableTrackingStack.pop()[0];if(!e)throw new Error("[mobservable.getDNode] property '"+d+"' of '"+c+"' doesn't seem to be a reactive property");return e}if(c.$mobservable){if(c.$mobservable instanceof b.ObservableObject)throw new Error("[mobservable.getDNode] missing properties parameter. Please specify a property of '"+c+"'.");return c.$mobservable}throw new Error("[mobservable.getDNode] "+c+" doesn't seem to be reactive")}function d(a,c,d,e){void 0===d&&(d=!1),void 0===e&&(e=null),b.transitionTracker.emit({id:a.id,name:a.context.name,context:a.context.object,state:c,changed:d,newValue:e})}b.getDNode=c,b.reportTransition=d,b.transitionTracker=null}(b=a._||(a._={}));var c;!function(a){function c(a,c){return d(b.getDNode(a,c))}function d(a){var c={id:a.id,name:a.context.name,context:a.context.object||null};return a instanceof b.ObservingDNode&&a.observing.length&&(c.dependencies=b.unique(a.observing).map(d)),c}function e(a,c){return f(b.getDNode(a,c))}function f(a){var c={id:a.id,name:a.context.name,context:a.context.object||null};return a.observers.length&&(c.observers=b.unique(a.observers).map(f)),a.externalRefenceCount>0&&(c.listeners=a.externalRefenceCount),c}function g(a){var b=[],c=!1;return function(d){(a||d.changed)&&b.push(d),c||(c=!0,setTimeout(function(){console[console.table?"table":"dir"](b),b=[],c=!1},1))}}function h(a,c){void 0===a&&(a=!1),b.transitionTracker||(b.transitionTracker=new b.SimpleEventEmitter);var d=c?function(b){(a||b.changed)&&c(b)}:g(a),e=b.transitionTracker.on(d);return b.once(function(){e(),0===b.transitionTracker.listeners.length&&(b.transitionTracker=null)})}a.getDependencyTree=c,a.getObserverTree=e,a.trackTransitions=h}(c=a.extras||(a.extras={}))}(mobservable||(mobservable={}));var mobservable;!function(a){var b;!function(b){var c=function(c){function d(a,d,e){c.call(this,e),this.value=a,this.recurse=d,this.changeEvent=new b.SimpleEventEmitter,this._value=this.makeReferenceValueReactive(a)}return __extends(d,c),d.prototype.makeReferenceValueReactive=function(c){return this.recurse&&(Array.isArray(c)||b.isPlainObject(c))?a.makeReactive(c,{context:this.context.object,name:this.context.name}):c},d.prototype.set=function(a){if(a!==this._value){var b=this._value;this.markStale(),this._value=this.makeReferenceValueReactive(a),this.markReady(!0),this.changeEvent.emit(this._value,b)}},d.prototype.get=function(){return this.notifyObserved(),this._value},d.prototype.observe=function(a,b){return void 0===b&&(b=!1),b&&a(this.get(),void 0),this.changeEvent.on(a)},d.prototype.asPropertyDescriptor=function(){var a=this;return{configurable:!1,enumerable:!0,get:function(){return a.get()},set:function(b){return a.set(b)}}},d.prototype.toString=function(){return"Observable["+this.context.name+":"+this._value+"]"},d}(b.RootDNode);b.ObservableValue=c}(b=a._||(a._={}))}(mobservable||(mobservable={}));var mobservable;!function(a){var b;!function(b){function c(){throw new Error("View functions do not accept new values")}var d=function(d){function e(a,c,e){d.call(this,e),this.func=a,this.scope=c,this.isComputing=!1,this.hasError=!1,this.changeEvent=new b.SimpleEventEmitter}return __extends(e,d),e.prototype.get=function(){if(this.isComputing)throw new Error("Cycle detected");if(this.isSleeping?__mobservableTrackingStack.length>0?(this.wakeUp(),this.notifyObserved()):this.compute():this.notifyObserved(),this.hasCycle)throw new Error("Cycle detected");if(this.hasError)throw a.debugLevel&&(console.trace(),b.warn(this+": rethrowing caught exception to observer: "+this._value+(this._value.cause||""))),this._value;return this._value},e.prototype.set=function(){c()},e.prototype.compute=function(){var a;try{if(this.isComputing)throw new Error("Cycle detected");this.isComputing=!0,a=this.func.call(this.scope),this.hasError=!1}catch(b){this.hasError=!0,console.error(this+"Caught error during computation: ",b),b instanceof Error?a=b:(a=new Error("MobservableComputationError"),a.cause=b)}if(this.isComputing=!1,a!==this._value){var c=this._value;return this._value=a,this.changeEvent.emit(a,c),!0}return!1},e.prototype.observe=function(a,c){var d=this;void 0===c&&(c=!1),this.setRefCount(1),c&&a(this.get(),void 0);var e=this.changeEvent.on(a);return b.once(function(){d.setRefCount(-1),e()})},e.prototype.asPropertyDescriptor=function(){var a=this;return{configurable:!1,enumerable:!1,get:function(){return a.get()},set:c}},e.prototype.toString=function(){return"ComputedObservable["+this.context.name+":"+this._value+"]"},e}(b.ObservingDNode);b.ObservableView=d}(b=a._||(a._={}))}(mobservable||(mobservable={}));var mobservable;!function(a){var b;!function(a){var b=function(){function b(b,c){if(this.target=b,this.context=c,b.$mobservable)throw new Error("Illegal state: already an reactive object");c?c.object||(c.object=b):this.context={object:b,name:""},this.keys=new a.ObservableArray([],!1,{object:b,name:this.context.name+"[keys]"}),Object.defineProperty(b,"$mobservable",{enumerable:!1,configurable:!1,value:this})}return b.asReactive=function(a,c){return a.$mobservable?a.$mobservable:new b(a,c)},b.prototype.set=function(a,b,c){-1===this.keys.indexOf(a)?this.defineReactiveProperty(a,b,c):this.target[a]=b},b.prototype.defineReactiveProperty=function(b,c,d){c instanceof a.AsReference&&(c=c.value,d=!1);var e,f={object:this.context.object,name:(this.context.name||"")+"."+b};e="function"==typeof c&&0===c.length&&d?new a.ObservableView(c,this.target,f).asPropertyDescriptor():new a.ObservableValue(c,d,f).asPropertyDescriptor(),Object.defineProperty(this.target,b,e)},b}();a.ObservableObject=b}(b=a._||(a._={}))}(mobservable||(mobservable={}));var mobservable;!function(a){function b(b){console.warn("The use of mobservable.reactiveComponent and mobservable.reactiveMixin is deprecated, please use reactiveComponent from the mobservable-react package");var c=b.prototype||b,d=c.componentWillMount,e=c.componentWillUnmount;return c.componentWillMount=function(){a.reactiveMixin.componentWillMount.apply(this,arguments),d&&d.apply(this,arguments)},c.componentWillUnmount=function(){a.reactiveMixin.componentWillUnmount.apply(this,arguments),e&&e.apply(this,arguments)},c.shouldComponentUpdate||(c.shouldComponentUpdate=a.reactiveMixin.shouldComponentUpdate),b}var c=1;a.reactiveMixin={componentWillMount:function(){var b=(this.displayName||this.constructor.name||"ReactiveComponent")+c++,d=this.render;this.render=function(){var c=this;this._watchDisposer&&this._watchDisposer();var e=a.observeUntilInvalid(function(){return d.call(c)},function(){c.forceUpdate()},{object:this,name:b}),f=e[0],g=e[1],h=e[2];return this.$mobservable=h,this._watchDisposer=g,f}},componentWillUnmount:function(){this._watchDisposer&&this._watchDisposer(),delete this._mobservableDNode},shouldComponentUpdate:function(a,b){if(this.state!==b)return!0;var c,d=Object.keys(this.props);if(d.length!==Object.keys(a).length)return!0;for(var e=d.length-1;c=d[e];e--)if(a[c]!==this.props[c])return!0;return!1}},a.reactiveComponent=b}(mobservable||(mobservable={}));var mobservable;!function(a){var b;!function(a){var b=function(){function a(){}return a.schedule=function(b){a.inBatch<1?b():a.tasks[a.tasks.length]=b},a.runPostBatchActions=function(){for(var b=0;a.tasks.length;)try{for(;b<a.tasks.length;b++)a.tasks[b]();a.tasks=[]}catch(c){console.error("Failed to run scheduled action, the action has been dropped from the queue: "+c,c),a.tasks.splice(0,b+1)}},a.batch=function(b){a.inBatch+=1;try{return b()}finally{0===--a.inBatch&&(a.inBatch+=1,a.runPostBatchActions(),a.inBatch-=1)}},a.inBatch=0,a.tasks=[],a}();a.Scheduler=b}(b=a._||(a._={}))}(mobservable||(mobservable={}));var mobservable;!function(a){var b;!function(a){var b=function(){function b(){this.listeners=[]}return b.prototype.emit=function(){var a=this.listeners.slice(),b=a.length;switch(arguments.length){case 0:for(var c=0;b>c;c++)a[c]();break;case 1:for(var d=arguments[0],c=0;b>c;c++)a[c](d);break;default:for(var c=0;b>c;c++)a[c].apply(null,arguments)}},b.prototype.on=function(b){var c=this;return this.listeners.push(b),a.once(function(){var a=c.listeners.indexOf(b);-1!==a&&c.listeners.splice(a,1)})},b.prototype.once=function(a){var b=this.on(function(){b(),a.apply(this,arguments)});return b},b}();a.SimpleEventEmitter=b}(b=a._||(a._={}))}(mobservable||(mobservable={}));var mobservable;!function(a){var b;!function(a){var b=function(a){function b(b,c,d){a.call(this,d),this.expr=b,this.onInvalidate=c,this.didEvaluate=!1,this.computeNextState()}return __extends(b,a),b.prototype.compute=function(){return this.didEvaluate?(this.dispose(),this.onInvalidate()):(this.didEvaluate=!0,this.value=this.expr()),!1},b}(a.ObservingDNode);a.WatchedExpression=b}(b=a._||(a._={}))}(mobservable||(mobservable={}));var forCompilerVerificationOnly=mobservable;!function(a,b){"function"==typeof define&&define.amd?define("mobservable",[],function(){return b()}):"object"==typeof exports?module.exports=b():a.mobservable=b()}(this,function(){var a=mobservable.makeReactive;a["default"]=mobservable.makeReactive;for(var b in mobservable)mobservable.hasOwnProperty(b)&&(a[b]=mobservable[b]);return a});
var __extends=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);c.prototype=b.prototype,a.prototype=new c},mobservable;!function(a){var b=function(){return this}();b.__mobservableTrackingStack=[];var c;!function(b){function c(){return __mobservableTrackingStack.length}function d(){return __mobservableTrackingStack.length>0}var e=0;!function(a){a[a.STALE=0]="STALE",a[a.PENDING=1]="PENDING",a[a.READY=2]="READY"}(b.DNodeState||(b.DNodeState={}));var f=b.DNodeState,g=function(){function a(a){this.context=a,this.id=++e,this.state=f.READY,this.observers=[],this.isDisposed=!1,this.externalRefenceCount=0,a.name||(a.name="[m#"+this.id+"]")}return a.prototype.setRefCount=function(a){this.externalRefenceCount+=a},a.prototype.addObserver=function(a){this.observers[this.observers.length]=a},a.prototype.removeObserver=function(a){var b=this.observers,c=b.indexOf(a);-1!==c&&b.splice(c,1)},a.prototype.markStale=function(){this.state===f.READY&&(this.state=f.STALE,b.transitionTracker&&b.reportTransition(this,"STALE"),this.notifyObservers())},a.prototype.markReady=function(a){this.state!==f.READY&&(this.state=f.READY,b.transitionTracker&&b.reportTransition(this,"READY",!0,this._value),this.notifyObservers(a))},a.prototype.notifyObservers=function(a){void 0===a&&(a=!1);for(var b=this.observers.slice(),c=b.length,d=0;c>d;d++)b[d].notifyStateChange(this,a)},a.prototype.notifyObserved=function(){var a=__mobservableTrackingStack,b=a.length;if(b>0){var c=a[b-1],d=c.length;c[d-1]!==this&&c[d-2]!==this&&(c[d]=this)}},a.prototype.dispose=function(){if(this.observers.length)throw new Error("Cannot dispose DNode; it is still being observed");this.isDisposed=!0},a.prototype.toString=function(){return"DNode["+this.context.name+", state: "+this.state+", observers: "+this.observers.length+"]"},a}();b.RootDNode=g;var h=function(c){function d(){c.apply(this,arguments),this.isSleeping=!0,this.hasCycle=!1,this.observing=[],this.prevObserving=null,this.dependencyChangeCount=0,this.dependencyStaleCount=0}return __extends(d,c),d.prototype.setRefCount=function(a){var b=this.externalRefenceCount+=a;0===b?this.tryToSleep():b===a&&this.wakeUp()},d.prototype.removeObserver=function(a){c.prototype.removeObserver.call(this,a),this.tryToSleep()},d.prototype.tryToSleep=function(){if(!this.isSleeping&&0===this.observers.length&&0===this.externalRefenceCount){for(var a=0,b=this.observing.length;b>a;a++)this.observing[a].removeObserver(this);this.observing=[],this.isSleeping=!0}},d.prototype.wakeUp=function(){this.isSleeping&&(this.isSleeping=!1,this.state=f.PENDING,this.computeNextState())},d.prototype.notifyStateChange=function(a,c){var d=this;a.state===f.STALE?1===++this.dependencyStaleCount&&this.markStale():(c&&(this.dependencyChangeCount+=1),0===--this.dependencyStaleCount&&(this.state=f.PENDING,b.Scheduler.schedule(function(){d.dependencyChangeCount>0?d.computeNextState():d.markReady(!1),d.dependencyChangeCount=0})))},d.prototype.computeNextState=function(){this.trackDependencies(),b.transitionTracker&&b.reportTransition(this,"PENDING");var a=this.compute();this.bindDependencies(),this.markReady(a)},d.prototype.compute=function(){throw"Abstract!"},d.prototype.trackDependencies=function(){this.prevObserving=this.observing,__mobservableTrackingStack[__mobservableTrackingStack.length]=[]},d.prototype.bindDependencies=function(){this.observing=__mobservableTrackingStack.pop(),0===this.observing.length&&a.debugLevel>1&&!this.isDisposed&&(console.trace(),b.warn("You have created a function that doesn't observe any values, did you forget to make its dependencies observable?"));var c=b.quickDiff(this.observing,this.prevObserving),e=c[0],f=c[1];this.prevObserving=null;for(var g=0,h=f.length;h>g;g++)f[g].removeObserver(this);this.hasCycle=!1;for(var g=0,h=e.length;h>g;g++){var i=e[g];i instanceof d&&i.findCycle(this)?(this.hasCycle=!0,this.observing.splice(this.observing.indexOf(e[g]),1),i.hasCycle=!0):e[g].addObserver(this)}},d.prototype.findCycle=function(a){var b=this.observing;if(-1!==b.indexOf(a))return!0;for(var c=b.length,e=0;c>e;e++)if(b[e]instanceof d&&b[e].findCycle(a))return!0;return!1},d.prototype.dispose=function(){if(this.observing)for(var a=this.observing.length,b=0;a>b;b++)this.observing[b].removeObserver(this);this.observing=null,c.prototype.dispose.call(this)},d}(g);b.ObservingDNode=h,b.stackDepth=c,b.isComputingView=d}(c=a._||(a._={}))}(mobservable||(mobservable={}));var mobservable;!function(a){function b(a,b){if(d(a))return a;b=b||{},a instanceof k.AsReference&&(a=a.value,b.as="reference");var c=b.recurse!==!1,e="reference"===b.as?k.ValueType.Reference:k.getTypeOfValue(a),f={name:b.name,object:b.context||b.scope};switch(e){case k.ValueType.Reference:case k.ValueType.ComplexObject:return k.toGetterSetterFunction(new k.ObservableValue(a,!1,f));case k.ValueType.ComplexFunction:throw new Error("[mobservable:error] Creating reactive functions from functions with multiple arguments is currently not supported, see https://github.com/mweststrate/mobservable/issues/12");case k.ValueType.ViewFunction:return f.name||(f.name=a.name),k.toGetterSetterFunction(new k.ObservableView(a,b.scope||b.context,f));case k.ValueType.Array:return new k.ObservableArray(a,c,f);case k.ValueType.PlainObject:return k.extendReactive({},a,c,f)}throw"Illegal State"}function c(a){return new k.AsReference(a)}function d(a){return null===a||void 0===a?!1:!!a.$mobservable}function e(a,b){var c=new k.ObservableView(a,b,{object:b,name:a.name}),d=c.observe(k.noop);return 0===c.observing.length&&k.warn("mobservable.sideEffect: not a single observable was used inside the side-effect function. Side-effect would be a no-op."),d.$mobservable=c,d}function f(a,b,c){k.extendReactive(a,b,!0,c)}function g(a,b,c){var d=c?c.value:null;if("function"==typeof d)throw new Error("@observable functions are deprecated. Use @observable (getter) properties instead");if(c&&c.set)throw new Error("@observable properties cannot have a setter.");Object.defineProperty(a,b,{configurable:!0,enumberable:!0,get:function(){return k.ObservableObject.asReactive(this,null).set(b,void 0,!0),this[b]},set:function(a){k.ObservableObject.asReactive(this,null).set(b,a,!0)}})}function h(a){if(!a)return a;if(Array.isArray(a)||a instanceof k.ObservableArray)return a.map(h);if("object"==typeof a){var b={};for(var c in a)a.hasOwnProperty(c)&&(b[c]=h(a[c]));return b}return a}function i(a){return k.Scheduler.batch(a)}function j(a,b,c){var d=new k.WatchedExpression(a,b,c||a.name);return[d.value,function(){return d.dispose()},d]}a.makeReactive=b,a.asReference=c,a.isReactive=d,a.sideEffect=e,a.extendReactive=f,a.observable=g,a.toJson=h,a.transaction=i,a.observeUntilInvalid=j,a.debugLevel=0;var k;!function(a){function b(b){return null===b||void 0===b?e.Reference:"function"==typeof b?b.length?e.ComplexFunction:e.ViewFunction:Array.isArray(b)||b instanceof a.ObservableArray?e.Array:"object"==typeof b?a.isPlainObject(b)?e.PlainObject:e.ComplexObject:e.Reference}function c(b,c,d,e){var f=a.ObservableObject.asReactive(b,e);for(var g in c)c.hasOwnProperty(g)&&f.set(g,c[g],d);return b}function d(a){var b=function(b){return arguments.length>0?void a.set(b):a.get()};return b.$mobservable=a,b.observe=function(b,c){return a.observe(b,c)},b.toString=function(){return a.toString()},b}!function(a){a[a.Reference=0]="Reference",a[a.PlainObject=1]="PlainObject",a[a.ComplexObject=2]="ComplexObject",a[a.Array=3]="Array",a[a.ViewFunction=4]="ViewFunction",a[a.ComplexFunction=5]="ComplexFunction"}(a.ValueType||(a.ValueType={}));var e=a.ValueType;a.getTypeOfValue=b,a.extendReactive=c,a.toGetterSetterFunction=d;var f=function(){function a(a){this.value=a}return a}();a.AsReference=f}(k=a._||(a._={}))}(mobservable||(mobservable={}));var mobservable;!function(a){var b;!function(a){function b(a){console&&console.warn("[mobservable:warning] "+a)}function c(a){var b=!1;return function(){return b?void 0:(b=!0,a.apply(this,arguments))}}function d(){}function e(a){var b=[];return a.forEach(function(a){-1===b.indexOf(a)&&b.push(a)}),b}function f(a){return null!==a&&"object"==typeof a&&Object.getPrototypeOf(a)===Object.prototype}function g(a,b){if(!b||!b.length)return[a,[]];if(!a||!a.length)return[[],b];for(var c=[],d=[],e=0,f=0,g=a.length,h=!1,i=0,j=0,k=b.length,l=!1,m=!1;!m&&!h;){if(!l){if(g>e&&k>i&&a[e]===b[i]){if(e++,i++,e===g&&i===k)return[c,d];continue}f=e,j=i,l=!0}j+=1,f+=1,j>=k&&(m=!0),f>=g&&(h=!0),h||a[f]!==b[i]?m||b[j]!==a[e]||(d.push.apply(d,b.slice(i,j)),i=j+1,e++,l=!1):(c.push.apply(c,a.slice(e,f)),e=f+1,i++,l=!1)}return c.push.apply(c,a.slice(e)),d.push.apply(d,b.slice(i)),[c,d]}a.warn=b,a.once=c,a.noop=d,a.unique=e,a.isPlainObject=f,a.quickDiff=g}(b=a._||(a._={}))}(mobservable||(mobservable={}));var mobservable;!function(a){var b;!function(b){function c(a){var b={enumerable:!1,configurable:!1,set:function(b){if(a<this.$mobservable.values.length){var c=this.$mobservable.values[a];c!==b&&(this.$mobservable.values[a]=b,this.notifyChildUpdate(a,c))}else{if(a!==this.$mobservable.values.length)throw new Error("ObservableArray: Index out of bounds, "+a+" is larger than "+this.values.length);this.push(b)}},get:function(){return a<this.$mobservable.values.length?(this.$mobservable.notifyObserved(),this.$mobservable.values[a]):void 0}};Object.defineProperty(g.prototype,""+a,b),b.enumerable=!0,b.configurable=!0,i[a]=b}function d(a){for(var b=h;a>b;b++)c(b);h=a}var e=function(){function a(){}return a}();e.prototype=[];var f=function(a){function c(c,d,e){a.call(this,e),this.array=c,this.recurse=d,this.values=[],this.changeEvent=new b.SimpleEventEmitter,e.object||(e.object=c)}return __extends(c,a),c}(b.RootDNode);b.ObservableArrayAdministration=f;var g=function(c){function e(a,b,d){c.call(this),Object.defineProperty(this,"$mobservable",{enumerable:!1,configurable:!1,value:new f(this,b,d)}),a&&a.length&&this.replace(a)}return __extends(e,c),Object.defineProperty(e.prototype,"length",{get:function(){return this.$mobservable.notifyObserved(),this.$mobservable.values.length},set:function(a){if(this.assertNotComputing("spliceWithArray"),"number"!=typeof a||0>a)throw new Error("Out of range: "+a);var b=this.$mobservable.values.length;a!==b&&(a>b?this.spliceWithArray(b,0,new Array(a-b)):this.spliceWithArray(a,b-a))},enumerable:!0,configurable:!0}),e.prototype.updateLength=function(a,b){if(0>b)for(var c=a+b;a>c;c++)delete this[c];else if(b>0){a+b>h&&d(a+b);for(var c=a,e=a+b;e>c;c++)Object.defineProperty(this,""+c,i[c])}},e.prototype.spliceWithArray=function(a,b,c){var d=this;this.assertNotComputing("spliceWithArray");var e=this.$mobservable.values.length;if(!(void 0!==c&&0!==c.length||0!==b&&0!==e))return[];void 0===a?a=0:a>e?a=e:0>a&&(a=Math.max(0,e+a)),b=1===arguments.length?e-a:void 0===b||null===b?0:Math.max(0,Math.min(b,e-a)),void 0===c?c=[]:this.$mobservable.recurse&&(c=c.map(function(a){return d.makeReactiveArrayItem(a)}));var f=c.length-b,g=(h=this.$mobservable.values).splice.apply(h,[a,b].concat(c));return this.updateLength(e,f),this.notifySplice(a,g,c),g;var h},e.prototype.makeReactiveArrayItem=function(c){if(a.isReactive(c))return c;if(c instanceof b.AsReference)return c=c.value;var d={object:this.$mobservable.context.object,name:this.$mobservable.context.name+"[x]"};return Array.isArray(c)?new b.ObservableArray(c,!0,d):b.isPlainObject(c)?b.extendReactive({},c,!0,d):c},e.prototype.notifyChildUpdate=function(a,b){this.notifyChanged(),this.$mobservable.changeEvent.emit({object:this,type:"update",index:a,oldValue:b})},e.prototype.notifySplice=function(a,b,c){(0!==b.length||0!==c.length)&&(this.notifyChanged(),this.$mobservable.changeEvent.emit({object:this,type:"splice",index:a,addedCount:c.length,removed:b}))},e.prototype.notifyChanged=function(){this.$mobservable.markStale(),this.$mobservable.markReady(!0)},e.prototype.observe=function(a,b){return void 0===b&&(b=!1),b&&a({object:this,type:"splice",index:0,addedCount:this.$mobservable.values.length,removed:[]}),this.$mobservable.changeEvent.on(a)},e.prototype.clear=function(){return this.splice(0)},e.prototype.replace=function(a){return this.spliceWithArray(0,this.$mobservable.values.length,a)},e.prototype.values=function(){return this.$mobservable.notifyObserved(),this.$mobservable.values.slice()},e.prototype.toJSON=function(){return this.$mobservable.notifyObserved(),this.$mobservable.values.slice()},e.prototype.clone=function(){return this.$mobservable.notifyObserved(),new e(this.$mobservable.values,this.$mobservable.recurse,{object:null,name:this.$mobservable.context.name+"[clone]"})},e.prototype.find=function(a,b,c){void 0===c&&(c=0),this.$mobservable.notifyObserved();for(var d=this.$mobservable.values,e=d.length,f=c;e>f;f++)if(a.call(b,d[f],f,this))return d[f];return null},e.prototype.splice=function(a,b){for(var c=[],d=2;d<arguments.length;d++)c[d-2]=arguments[d];switch(this.assertNotComputing("splice"),arguments.length){case 0:return[];case 1:return this.spliceWithArray(a);case 2:return this.spliceWithArray(a,b)}return this.spliceWithArray(a,b,c)},e.prototype.push=function(){for(var a=[],b=0;b<arguments.length;b++)a[b-0]=arguments[b];return this.assertNotComputing("push"),this.spliceWithArray(this.$mobservable.values.length,0,a),this.$mobservable.values.length},e.prototype.pop=function(){return this.assertNotComputing("pop"),this.splice(Math.max(this.$mobservable.values.length-1,0),1)[0]},e.prototype.shift=function(){return this.assertNotComputing("shift"),this.splice(0,1)[0]},e.prototype.unshift=function(){for(var a=[],b=0;b<arguments.length;b++)a[b-0]=arguments[b];return this.assertNotComputing("unshift"),this.spliceWithArray(0,0,a),this.$mobservable.values.length},e.prototype.reverse=function(){return this.assertNotComputing("reverse"),this.replace(this.$mobservable.values.reverse())},e.prototype.sort=function(a){return this.assertNotComputing("sort"),this.replace(this.$mobservable.values.sort.apply(this.$mobservable.values,arguments))},e.prototype.remove=function(a){this.assertNotComputing("remove");var b=this.$mobservable.values.indexOf(a);return b>-1?(this.splice(b,1),!0):!1},e.prototype.toString=function(){return this.wrapReadFunction("toString",arguments)},e.prototype.toLocaleString=function(){return this.wrapReadFunction("toLocaleString",arguments)},e.prototype.concat=function(){return this.wrapReadFunction("concat",arguments)},e.prototype.join=function(a){return this.wrapReadFunction("join",arguments)},e.prototype.slice=function(a,b){return this.wrapReadFunction("slice",arguments)},e.prototype.indexOf=function(a,b){return this.wrapReadFunction("indexOf",arguments)},e.prototype.lastIndexOf=function(a,b){return this.wrapReadFunction("lastIndexOf",arguments)},e.prototype.every=function(a,b){return this.wrapReadFunction("every",arguments)},e.prototype.some=function(a,b){return this.wrapReadFunction("some",arguments)},e.prototype.forEach=function(a,b){return this.wrapReadFunction("forEach",arguments)},e.prototype.map=function(a,b){return this.wrapReadFunction("map",arguments)},e.prototype.filter=function(a,b){return this.wrapReadFunction("filter",arguments)},e.prototype.reduce=function(a,b){return this.wrapReadFunction("reduce",arguments)},e.prototype.reduceRight=function(a,b){return this.wrapReadFunction("reduceRight",arguments)},e.prototype.wrapReadFunction=function(a,b){var c=Array.prototype[a];return(e.prototype[a]=function(){return this.$mobservable.notifyObserved(),c.apply(this.$mobservable.values,arguments)}).apply(this,b)},e.prototype.assertNotComputing=function(a){if(b.isComputingView()){var c="[Mobservable.Array] The method array."+a+" is not allowed to be used inside reactive views since it alters the state.";throw console.error(c),console.trace(),new Error}},e}(e);b.ObservableArray=g;var h=0,i=[];d(1e3)}(b=a._||(a._={}))}(mobservable||(mobservable={}));var mobservable;!function(a){var b;!function(b){function c(c,d){if(!a.isReactive(c))throw new Error("[mobservable.getDNode] "+c+" doesn't seem to be reactive");if(void 0!==d){__mobservableTrackingStack.push([]),c[d];var e=__mobservableTrackingStack.pop()[0];if(!e)throw new Error("[mobservable.getDNode] property '"+d+"' of '"+c+"' doesn't seem to be a reactive property");return e}if(c.$mobservable){if(c.$mobservable instanceof b.ObservableObject)throw new Error("[mobservable.getDNode] missing properties parameter. Please specify a property of '"+c+"'.");return c.$mobservable}throw new Error("[mobservable.getDNode] "+c+" doesn't seem to be reactive")}function d(a,c,d,e){void 0===d&&(d=!1),void 0===e&&(e=null),b.transitionTracker.emit({id:a.id,name:a.context.name,context:a.context.object,state:c,changed:d,newValue:e})}b.getDNode=c,b.reportTransition=d,b.transitionTracker=null}(b=a._||(a._={}));var c;!function(a){function c(a,c){return d(b.getDNode(a,c))}function d(a){var c={id:a.id,name:a.context.name,context:a.context.object||null};return a instanceof b.ObservingDNode&&a.observing.length&&(c.dependencies=b.unique(a.observing).map(d)),c}function e(a,c){return f(b.getDNode(a,c))}function f(a){var c={id:a.id,name:a.context.name,context:a.context.object||null};return a.observers.length&&(c.observers=b.unique(a.observers).map(f)),a.externalRefenceCount>0&&(c.listeners=a.externalRefenceCount),c}function g(a){var b=[],c=!1;return function(d){(a||d.changed)&&b.push(d),c||(c=!0,setTimeout(function(){console[console.table?"table":"dir"](b),b=[],c=!1},1))}}function h(a,c){void 0===a&&(a=!1),b.transitionTracker||(b.transitionTracker=new b.SimpleEventEmitter);var d=c?function(b){(a||b.changed)&&c(b)}:g(a),e=b.transitionTracker.on(d);return b.once(function(){e(),0===b.transitionTracker.listeners.length&&(b.transitionTracker=null)})}a.getDependencyTree=c,a.getObserverTree=e,a.trackTransitions=h}(c=a.extras||(a.extras={}))}(mobservable||(mobservable={}));var mobservable;!function(a){var b;!function(b){b.NON_PURE_VIEW_ERROR="[Mobservable] It is not allowed to change the state during the computation of a reactive view.";var c=function(c){function d(a,d,e){c.call(this,e),this.value=a,this.recurse=d,this.changeEvent=new b.SimpleEventEmitter,this._value=this.makeReferenceValueReactive(a)}return __extends(d,c),d.prototype.makeReferenceValueReactive=function(c){return this.recurse&&(Array.isArray(c)||b.isPlainObject(c))?a.makeReactive(c,{context:this.context.object,name:this.context.name}):c},d.prototype.set=function(a){if(b.isComputingView())throw console.error(b.NON_PURE_VIEW_ERROR),console.trace(),new Error(b.NON_PURE_VIEW_ERROR);if(a!==this._value){var c=this._value;this.markStale(),this._value=this.makeReferenceValueReactive(a),this.markReady(!0),this.changeEvent.emit(this._value,c)}},d.prototype.get=function(){return this.notifyObserved(),this._value},d.prototype.observe=function(a,b){return void 0===b&&(b=!1),b&&a(this.get(),void 0),this.changeEvent.on(a)},d.prototype.asPropertyDescriptor=function(){var a=this;return{configurable:!1,enumerable:!0,get:function(){return a.get()},set:function(b){return a.set(b)}}},d.prototype.toString=function(){return"Observable["+this.context.name+":"+this._value+"]"},d}(b.RootDNode);b.ObservableValue=c}(b=a._||(a._={}))}(mobservable||(mobservable={}));var mobservable;!function(a){var b;!function(b){function c(){throw new Error("View functions do not accept new values")}var d=function(d){function e(a,c,e){d.call(this,e),this.func=a,this.scope=c,this.isComputing=!1,this.hasError=!1,this.changeEvent=new b.SimpleEventEmitter}return __extends(e,d),e.prototype.get=function(){if(this.isComputing)throw new Error("Cycle detected");if(this.isSleeping?b.isComputingView()?(this.wakeUp(),this.notifyObserved()):(this.wakeUp(),this.tryToSleep()):this.notifyObserved(),this.hasCycle)throw new Error("Cycle detected");if(this.hasError)throw a.debugLevel&&(console.trace(),b.warn(this+": rethrowing caught exception to observer: "+this._value+(this._value.cause||""))),this._value;return this._value},e.prototype.set=function(){c()},e.prototype.compute=function(){var a;try{if(this.isComputing)throw new Error("Cycle detected");this.isComputing=!0,a=this.func.call(this.scope),this.hasError=!1}catch(b){this.hasError=!0,console.error(this+"Caught error during computation: ",b),b instanceof Error?a=b:(a=new Error("MobservableComputationError"),a.cause=b)}if(this.isComputing=!1,a!==this._value){var c=this._value;return this._value=a,this.changeEvent.emit(a,c),!0}return!1},e.prototype.observe=function(a,c){var d=this;void 0===c&&(c=!1),this.setRefCount(1),c&&a(this.get(),void 0);var e=this.changeEvent.on(a);return b.once(function(){d.setRefCount(-1),e()})},e.prototype.asPropertyDescriptor=function(){var a=this;return{configurable:!1,enumerable:!1,get:function(){return a.get()},set:c}},e.prototype.toString=function(){return"ComputedObservable["+this.context.name+":"+this._value+"]"},e}(b.ObservingDNode);b.ObservableView=d}(b=a._||(a._={}))}(mobservable||(mobservable={}));var mobservable;!function(a){var b;!function(a){var b=function(){function b(b,c){if(this.target=b,this.context=c,b.$mobservable)throw new Error("Illegal state: already an reactive object");c?c.object||(c.object=b):this.context={object:b,name:""},this.keys=new a.ObservableArray([],!1,{object:b,name:this.context.name+"[keys]"}),Object.defineProperty(b,"$mobservable",{enumerable:!1,configurable:!1,value:this})}return b.asReactive=function(a,c){return a.$mobservable?a.$mobservable:new b(a,c)},b.prototype.set=function(a,b,c){-1===this.keys.indexOf(a)?this.defineReactiveProperty(a,b,c):this.target[a]=b},b.prototype.defineReactiveProperty=function(b,c,d){c instanceof a.AsReference&&(c=c.value,d=!1);var e,f={object:this.context.object,name:(this.context.name||"")+"."+b};e="function"==typeof c&&0===c.length&&d?new a.ObservableView(c,this.target,f).asPropertyDescriptor():new a.ObservableValue(c,d,f).asPropertyDescriptor(),Object.defineProperty(this.target,b,e)},b}();a.ObservableObject=b}(b=a._||(a._={}))}(mobservable||(mobservable={}));var mobservable;!function(a){function b(b){console.warn("The use of mobservable.reactiveComponent and mobservable.reactiveMixin is deprecated, please use reactiveComponent from the mobservable-react package");var c=b.prototype||b,d=c.componentWillMount,e=c.componentWillUnmount;return c.componentWillMount=function(){a.reactiveMixin.componentWillMount.apply(this,arguments),d&&d.apply(this,arguments)},c.componentWillUnmount=function(){a.reactiveMixin.componentWillUnmount.apply(this,arguments),e&&e.apply(this,arguments)},c.shouldComponentUpdate||(c.shouldComponentUpdate=a.reactiveMixin.shouldComponentUpdate),b}var c=1;a.reactiveMixin={componentWillMount:function(){var b=(this.displayName||this.constructor.name||"ReactiveComponent")+c++,d=this.render;this.render=function(){var c=this;this._watchDisposer&&this._watchDisposer();var e=a.observeUntilInvalid(function(){return d.call(c)},function(){c.forceUpdate()},{object:this,name:b}),f=e[0],g=e[1],h=e[2];return this.$mobservable=h,this._watchDisposer=g,f}},componentWillUnmount:function(){this._watchDisposer&&this._watchDisposer(),delete this._mobservableDNode},shouldComponentUpdate:function(a,b){if(this.state!==b)return!0;var c,d=Object.keys(this.props);if(d.length!==Object.keys(a).length)return!0;for(var e=d.length-1;c=d[e];e--)if(a[c]!==this.props[c])return!0;return!1}},a.reactiveComponent=b}(mobservable||(mobservable={}));var mobservable;!function(a){var b;!function(a){var b=function(){function a(){}return a.schedule=function(b){a.inBatch<1?b():a.tasks[a.tasks.length]=b},a.runPostBatchActions=function(){for(var b=0;a.tasks.length;)try{for(;b<a.tasks.length;b++)a.tasks[b]();a.tasks=[]}catch(c){console.error("Failed to run scheduled action, the action has been dropped from the queue: "+c,c),a.tasks.splice(0,b+1)}},a.batch=function(b){a.inBatch+=1;try{return b()}finally{0===--a.inBatch&&(a.inBatch+=1,a.runPostBatchActions(),a.inBatch-=1)}},a.inBatch=0,a.tasks=[],a}();a.Scheduler=b}(b=a._||(a._={}))}(mobservable||(mobservable={}));var mobservable;!function(a){var b;!function(a){var b=function(){function b(){this.listeners=[]}return b.prototype.emit=function(){var a=this.listeners.slice(),b=a.length;switch(arguments.length){case 0:for(var c=0;b>c;c++)a[c]();break;case 1:for(var d=arguments[0],c=0;b>c;c++)a[c](d);break;default:for(var c=0;b>c;c++)a[c].apply(null,arguments)}},b.prototype.on=function(b){var c=this;return this.listeners.push(b),a.once(function(){var a=c.listeners.indexOf(b);-1!==a&&c.listeners.splice(a,1)})},b.prototype.once=function(a){var b=this.on(function(){b(),a.apply(this,arguments)});return b},b}();a.SimpleEventEmitter=b}(b=a._||(a._={}))}(mobservable||(mobservable={}));var mobservable;!function(a){var b;!function(a){var b=function(a){function b(b,c,d){a.call(this,d),this.expr=b,this.onInvalidate=c,this.didEvaluate=!1,this.computeNextState()}return __extends(b,a),b.prototype.compute=function(){return this.didEvaluate?(this.dispose(),this.onInvalidate()):(this.didEvaluate=!0,this.value=this.expr()),!1},b}(a.ObservingDNode);a.WatchedExpression=b}(b=a._||(a._={}))}(mobservable||(mobservable={}));var forCompilerVerificationOnly=mobservable;!function(a,b){"function"==typeof define&&define.amd?define("mobservable",[],function(){return b()}):"object"==typeof exports?module.exports=b():a.mobservable=b()}(this,function(){var a=mobservable.makeReactive;a["default"]=mobservable.makeReactive;for(var b in mobservable)mobservable.hasOwnProperty(b)&&(a[b]=mobservable[b]);return a});

@@ -1,436 +0,1 @@

# API Documentation
Mobservable divides your application into three different concepts:
1. State
2. Views on your state
3. State management
_State_ is is all the factual information that lives inside your application.
This might be the profile of the user that is logged in, the tasks he needs to manage, or the fact that the sidebar currently collapsed.
With Mobservable you can make your state reactive. This means that all derived views based on your state are updated automatically.
The first section of this api documentation describes how to [make data reactive](#making-state-reactive).
_Views_ are all pieces of information that can be derived from the _State_ or its mutations.
For example; the amount of unfinished tasks, the user interface and the data mutations that need to be synced with the server.
Those are all forms of views.
The second section describes how to [react to data changes](#reacting-to-state-changes).
Finally your application has actions that _change state_.
Mobservable does not dictate how to change your state.
Instead of that, Mobservable tries to be as unobtrusive as possible.
You can use mutable objects and arrays, real references, classes and cyclic data structures to store your state.
With Mobservable you are free to mutate that state in any way you think is the best.
Different examples of storing state in ES5, ES6, or TypeScript, using plain objects, constructor functions or classes can be found in the [syntax documentation](syntax.md).
The third section describes some [utility functions](#utility-functions) that might come in convenient.
## Making state reactive
### makeReactive(data, options)
`makeReactive` is the swiss knife of `mobservable`. It converts `data` to something reactive.
The following types are distinguished, details are described below.
* `Primitive`: Any boolean, string, number, null, undefined, date, or regex.
* `PlainObject`: Any raw javascript object that wasn't created using a constructor function
* `ComplexObject`: A javascript object that was created by a constructor function (using the `new` keyword, with the sole exception of `new Object`).
* `Array`: A javascript array; anything which `Array.isArray` yields true.
* `ViewFuncion`: A function that takes no arguments but produces a value based on its scope / closure.
* `ComplexFunction`: A function that takes one or more arguments and might produce a value
#### Primitive values
If `data` is a primitive value, _complex_ object or function, a getter/setter function is returned:
a function that returns its current value if invoked without arguments, or updates its current value if invoked with exactly one argument.
If updated, it will notify all its _observers_.
New observers can be registered by invoking the _.observe(callback, invokeImmediately=false)_ method.
If the second parameter passed to `.observe` is true, the callback will be invoked with the current value immediately.
Otherwise the callback will be invoked on the first change.
Note that you might never use `.observe` yourself; as creating new [reactive functions or side-effects](#reacting-to-state-changes) is a more high-level approach to observe one or more values.
In practice you will hardly use `makeReactive` for primitives, as most primitive values will belong to some object.
```javascript
var temperature = makeReactive(25);
temperature.observe(function(newTemperature, oldTemperature) {
console.log('Temperature changed from ', oldTemperature, ' to ', newTemperature);
});
temperature(30);
// prints: 'Temperature changed from 25 to 30'
console.log(temperature());
// prints: '30'.
```
#### Plain objects
If `makeReactive` is invoked on a plain objects, a new plain object with reactive properties based on the original properties will be returned.
`makeReactive` will recurse into all property values of the original object.
Any values that will be assigned to these properties in the future, will be made reactive as well if needed.
View functions inside the object will become reactive properties of the object (see the next section for more info about reactive functions).
Their `this` will be bound to the object automatically.
Properties that will be added to the reactive object later on won't become reactive automatically.
This makes it easy to extend objects with, for example, functions that are not reactive themselves but instead mutate the object.
If you want to add a new reactive property to an existing object, just use `extendReactive`.
Example:
```javascript
var orderLine = makeReactive({
price: 10,
amount: 1,
total: function() {
return this.price * this.amount;
}
});
// sideEffect is explained below,
mobservable.sideEffect(function() {
console.log(orderline.total);
});
// prints: 10
orderLine.amount = 3;
// prints: 30
```
The recommended way to create reactive objects is to create a constructor function and use `extendReactive(this, properties)` inside the constructor;
this keeps the responsibility of making an object inside the object and makes it impossible to accidentally use a non-reactive version of the object.
However, some prefer to not use constructor functions at all in javascript applications.
So Mobservable will work just as fine when using `makeReactive(plainObject)`.
#### Complex objects
Passing non-plain objects to `makeReactive` will result in a reactive reference to the object, similar to creating reactive primitive values.
The constructor of such objects is considered responsible for creating reactive properties if needed.
#### Arrays
For arrays a new, reactive array will be returned.
Like with plain objects, reactiveness is a contagious thing; all values of the array,
now or in the future, will be made reactive as well if needed.
Arrays created using `makeReactive` provide a thin abstraction over native arrays.
The most notable difference between built-in arrays is that reactive arrays cannot be sparse;
values assigned to an index larger than `length` are considered to be out-of-bounds and will not become reactive.
Furthermore, `Array.isArray(reactiveArray)` and `typeof reactiveArray === "array"` will yield `false` for reactive arrays,
but `reactiveArray instanceof Array` will return `true`.
This has consequences when passing arrays to external methods or built-in functions, like `array.concat`, as they might not handle reactive arrays correctly.
(This might improve in the future).
***To avoid issues with other libraries, just make defensive copies before passing reactive arrays to external libraries using `array.slice()`.***
Reactive arrays support all available ES5 array methods. Besides those, the following methods are available as well:
* `observe(listener, fireImmediately? = false)` Listen to changes in this array. The callback will receive arguments that express an array splice or array change, conforming to [ES7 proposal](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/observe). It returns a disposer function to stop the listener.
* `clear()` Remove all current entries from the array.
* `replace(newItems)` Replaces all existing entries in the array with new ones.
* `clone()` Create a new observable array containing the same values.
* `find(predicate: (item, index, array) => boolean, thisArg?, fromIndex?)` Find implementation, basically the same as the ES7 Array.find proposal, but with added `fromIndex` parameter.
* `remove(value)` Remove a single item by value from the array. Returns true if the item was found and removed.
#### Functions
Those are explained in the next [section](#reacting-to-state-changes).
#### Further notes on `makeReactive`.
`makeReactive` will not recurse into non-plain objects, multi-argument functions and any value that is wrapped in `asReference`.
`makeReactive` will not recurse into objects that already have been processed by `makeReactive` or `extendReactive`.
The second `options` parameter object is optional but can define using following flags:
* `as` specifies what kind of reactive object should be made. Defaults to `"auto"`. Other valid values are `"reference"`, `"struct"` (in a later version see #8).
* `scope` defined the `this` of reactive functions. Will be set automatically in most cases
* `recurse` defaults `true`. If `false`, `makeActive` will not recurse into any child values.
* `name`: can be set to assign a name to this observable, used by the developers tools in the `extras` namespaces.
* `context` can be set to specify a certain context which is reported by the developers tools defined in the `extras`namespaces. Defaults to the object which caused this value to become reactive.
More flags will be made available in the feature.
`makeReactive` is the default export of the `mobservable` module, so you can use `mobservable(data, opts)` as a shorthand.
### extendReactive(target, properties)
`extendReactive` works similarly to `makeReactive`, but it extends an existing object instead of creating a new one. Similar to `Object.assign` or `jQuery.extend`.
This is especially useful inside constructor functions or to extend existing (possibly already reactive) objects.
In general, it is better to use `extendReactive(target, { property : value })` than `target.property = makeReactive(value)`.
The difference is that in the later only creates a reactive value, while `extendReactive` will make the property itself reactive as well,
so that you can safely assign new values to it later on.
### asReference(value)
See `makeReactive`, the given value will not be converted to a reactive structure if it is added to another reactive structure.
The reference to it will be observable nonetheless.
In the following example the properties of the dimensions object itself won't be reactive, but assigning a new object value to the `image.dimension` will be picked up:
```javascript
var image = makeReactive({
src: "/some/path",
dimension: asReference({
width: 100,
height: 200
})
});
```
### observable
Decorator (or annotation) that can be used on ES6 or TypeScript properties to make them reactive.
Note that in ES6 the annotation can only be used on getter functions, as ES6 doesn't support property initializers in class declarations.
See also the [syntax section](syntax.md) to see how `@observable` can be combined with different flavors of javascript code.
```javascript
/// <reference path="./node_modules/mobservable/dist/mobservable.d.ts"/>
import {observable, sideEffect} from "mobservable";
class Order {
@observable orderLines: OrderLine[] = [];
@observable get total() {
return this.orderLines.reduce((sum, orderLine) => sum + orderLine.total, 0)
}
}
class OrderLine {
@observable price:number = 0;
@observable amount:number = 1;
constructor(price) {
this.price = price;
}
@observable get total() {
return "Total: " + this.price * this.amount;
}
}
```
## Reacting to state changes
### makeReactive(function, options)
Responding to changes in your state is simply the matter of passing a `function` that takes no parameters to `makeReactive`.
Mobservable will track which reactive objects, array and other reactive functions are used by the provided function.
Mobservable will call `function` again when any of those values have changed.
This will happen in such a way one can never observe a stale output of `function`; updates are pushed synchronously.
Invocations of `function` will only happen when none of its dependencies is stale, so that updates are atomic.
This is a major difference with many other reactive frameworks.
This sounds complicated and expensive but in practice you won't notice any performance overhead in any reasonable scenario.
Reactive functions evaluate lazily; if nobody is observing the reactive function it will never evaluate.
For non-lazy reactive functions see `sideEffect`.
Invoking `makeReactive` directly on a function will result in a _getter function_, similar to invoking `makeReactive` on primitive values.
If `makeReactive` encounters a function inside an object passed through it,
it will introduce a new property on that object, that uses the function as getter function for that property.
The optional `options` parameter is an object.
The `scope` property of that object can be set to define the `this` value that will be used inside the reactive function.
```javascript
var greeter = makeReactive({
who: "world",
greeting: function() {
return "Hello, " + this.who + "!!!";
}
});
var upperCaseGreeter = makeReactive(function() {
return greeter.greeting; // greeting has become an reactive property
});
var disposer = upperCaseGreeter.observe(function(newGreeting) {
console.log(newGreeting)
});
greeter.who = "Universe";
// Prints: 'HELLO, UNIVERSE!!!'
disposer(); // stop observing
console.log(greeter.greeting); // prints the latest version of the reactive, derived property
console.log(upperCaseGreeter()); // prints the latest version of the reactive function
```
### sideEffect(function)
`sideEffect` can be used in those cases where you want to create a reactive function that will never have observers itself.
This is usually the case when you need to bridge from reactive to imperative code, for example for logging, persistence or UI-updating code.
When `sideEffect` is used, `function` will always be
triggered when one of its dependencies changes.
(In contrast, `makeReactive(function)` creates functions that only re-evaluate if it has
observers on its own, otherwise its value is considered to be irrelevant).
```javascript
var numbers = makeReactive([1,2,3]);
var sum = makeReactive(() => numbers.reduce((a, b) => a + b, 0);
var loggerDisposer = sideEffect(() => console.log(sum());
// prints '6'
numbers.push(4);
// prints '10'
loggerDisposer();
numbers.push(5);
// won't print anything, nor is `sum` re-evaluated
```
Fun fact: `sideEffect(func)` is actually an alias for `makeReactive(func).observe(function() { /* noop */ });`.
### reactiveComponent(component)
It turns a ReactJS component into a reactive one.
Making a component reactive means that it will automatically observe any reactive data it uses.
It is quite similar to `@connect` as found in several flux libraries, yet there are two important differences.
With `@reactiveComponent` you don't need to specify which store / data should be observed in order to re-render at the appropriate time.
Secondly, reactive components provide far more fine grained update semantics: Reactive components won't be observing a complete store or data tree, but only that data that is actually used during the rendering of the component. This might be a complete list, but also a single object or even a single property.
The consequence of this is that components won't re-render unless some data that is actually used in the rendering has changed. Large applications really benefit from this in terms of performance.
Rule of thumb is to use `reactiveComponent` on every component in your application that is specific for your application.
Its overhead is neglectable and it makes sure that whenever you start using reactive data the component will respond to it.
One exception are general purposes components that are not specific for your app. As these probably don't depend on the actual state of your application.
For that reason it doesn't make sense to add `reactiveComponent` to them (unless their own state is expressed using reactive data structures as well).
The `reactiveComponent` function / decorator supports both components that are constructed using `React.createClass` or using ES6 classes that extend `React.Component`. `reactiveComponent` is also available as mixin: `mobservable.reactiveMixin`.
`reactiveComponent` also prevents re-renderings when the *props* of the component have only shallowly changed, which makes a lot of sense if the data passed into the component is reactive.
This behavior is similar to [React PureRender mixin](https://facebook.github.io/react/docs/pure-render-mixin.html), except that *state* changes are still always processed.
If a component provides its own `shouldComponentUpdate`, that one takes precedence.
Since in practice you will see that most reactive components become stateless, they can easily be hot-reloaded.
_Note: when `reactiveComponent` needs to be combined with other decorators or higher-order-components, make sure that `reactiveComponent` is the most inner (first applied) decorator;
otherwise it might do nothing at all._
**ES6 class + decorator**
```javascript
@reactiveComponent class MyCompoment extends React.Component {
/* .. */
}
```
**ES6 class + function call**
```javascript
reactiveComponent(class MyCompoment extends React.Component {
/* .. */
});
```
**ES5 + React.createClass**
```javascript
reactiveComponent(React.createClass({
/* .. */
}))
```
Note: `reactiveComponent` is actually the only ReactJS specific thing in mobservable and should be easily portable to other frameworks.
`reactiveComponent` might move to its own package in the future.
### observeUntilInvalid(functionToObserve, onInvalidate)
`observeUntilInvalid` is quite similar to `sideEffect`, but instead of re-evaluating `functionToObserve` when one of its dependencies has changed,
the `onInvalidate` function is triggered instead.
So `functionToObserve` will be evaluated only once, and as soon as its value has become stale, the `onInvalidate` callback is triggered.
`observeUntilInvalid` returns a tuple consisting of the initial return value of `func` and an `unsubscriber` to be able to abort the observeUntilInvalid.
The `onInvalidate` function will be called only once, after that, the observeUntilInvalid has finished.
`observeUntilInvalid` is useful in functions where you want to have a function that responds to change, but where the function is actually invoked as side effect or as part of a bigger change flow or where unnecessary recalculations of `func` or either pointless or expensive.
It is for example used to implement `reactiveCompoenent`, which, in pseudo-code, does just: `component.render = () => observeUntilInvalid(originalRender, this.forceUpdate)[0]`;
## Utility functions
### isReactive(value)
Returns true if the given value was created or extended by mobservable. Note: this function cannot be used to tell whether a property is reactive; it will determine the reactiveness of its actual value.
### toJson(value)
Converts a non-cyclic tree of observable objects into a JSON structure that is not observable. It is kind of the inverse of `mobservable.makeReactive`
### transaction(workerFunction)
Transaction postpones the updates of computed properties until the (synchronous) `workerFunction` has completed.
This is useful if you want to apply a bunch of different updates throughout your model before needing the updated computed values, e.g. while refreshing data from the back-end.
In practice, you will probably never need `.transaction`, since observables typically update wickedly fast.
```javascript
var amount = mobservable(3);
var price = mobservable(2.5);
var total = mobservable(function() {
return amount() * price();
});
total.observe(console.log);
// without transaction:
amount(2); // Prints 5
price(3); // Prints 6
// with transaction:
mobservable.transaction(function() {
amount(3);
price(4);
});
// Prints 12, after completing the transaction
```
### extras.getDependencyTree(thing, property?)
Accepts something reactive and prints its current dependency tree; other reactive values it depends on. For sideEffects, this method can be invoked on its disposer.
Works for React components as well, but only if they are actually mounted (otherwise they won't be observing any data).
For object properties, pass in the property name as second argument. `id` is unique and generated by mobservable.
`name` and `context` are determined automatically, unless they were overriden in the options passed to `makeReactive`.
The returned dependency tree is a recursive structure with the following signature:
```javascript
interface IDependencyTree {
id: number;
name: string;
context: any;
dependencies?: IDependencyTree[];
}
```
### extras.getObserverTree(thing, property?)
Similar to `getDependencyTree`, but observer tree returns a tree of all objects that are depending on `thing`. It returns a tree structure with the following structure:
```javascript
interface IObserverTree {
id: number;
name: string;
context: any;
observers?: IObserverTree[];
listeners?: number;
}
```
`listeners` defines the amount of external observers, attached by using `.observe` of some reactive value. Side-effects will always report 1 listener.
### extras.trackTransitions(extensive, onReport)
Debugging tool that reports each change in a reactive value.
The optional `extensive` boolean indicates whether all control events should be reported, or only the events that changes a value. Defaults to `false`.
The `onReport` function is a callback that will be invoked for each transition. If omitted, the reports will be printed to the console.
`trackTransitions` returns a function that can be used to stop the tracker.
Each transition is reported as an object with the following signature. The `state` value is either `STALE`, `PENDING` or `READY`.
```javascript
interface ITransitionEvent {
id: number;
name: string;
context: Object;
state: string;
changed: boolean;
newValue: string;
}
```
The official API documentation has moved to [mweststrate.github.io/mobservable](https://mweststrate.github.io/mobservable/refguide/api.html)
{
"name": "mobservable",
"version": "0.6.4",
"version": "0.6.5",
"description": "Keeps views automatically in sync with state. Unobtrusively.",

@@ -5,0 +5,0 @@ "main": "dist/mobservable.js",

@@ -35,3 +35,3 @@ # mobservable

> _I was reluctant to abandon immutable data and the PureRenderMixin, but I no longer have any reservations. I can't think of any reason not to do things the simple, elegant way you have demonstrated._
>&dash;David Schalk, fpcomplete.com
> &dash;David Schalk, fpcomplete.com

@@ -75,8 +75,8 @@ ## The essentials

### mobservable.reactiveComponent
### mobservableReact.reactiveComponent
The second important function is `reactiveComponent`. It turns a Reactjs component into a reactive one, that responds automatically to changes in data that is used by its render method. It can be used to wrap any react component, either created by using ES6 classes or `createClass`. So to fix the example, just update the timer definition to:
The second important function is `reactiveComponent` from the `mobservable-react` package. It turns a Reactjs component into a reactive one, that responds automatically to changes in data that is used by its render method. It can be used to wrap any react component, either created by using ES6 classes or `createClass`. So to fix the example, just update the timer definition to:
```javascript
var Timer = mobservable.reactiveComponent(React.createClass{
var Timer = mobservableReact.reactiveComponent(React.createClass{
/** Omitted */

@@ -102,34 +102,32 @@ }));

Either:
* `npm install mobservable --save`
* [Edit](https://mweststrate.github.io/mobservable/getting-started.html#demo) a simple ToDo application online.
* Clone the boilerplate repository containing the above example from: https://github.com/mweststrate/react-mobservable-boilerplate.
* Or fork this [JSFiddle](https://jsfiddle.net/mweststrate/wgbe4guu/).
* `npm install mobservable --save`.
* For React apps `npm install mobservable-react --save` as well. You might also be interested in the [dev tools for React and Mobservable](https://github.com/mweststrate/mobservable-react-devtools).
## Resources
Fresh step-by-step documentation is [coming soon](https://github.com/mweststrate/mobservable/issues/7)!
* [Five minute interactive introducton to Mobservable and React](https://mweststrate.github.io/mobservable/getting-started.html)
* [API documentation](https://github.com/mweststrate/mobservable/blob/master/docs/api.md)
* [Tips & Tricks](https://github.com/mweststrate/mobservable/blob/master/docs/syntax.md)
* [API documentation](https://mweststrate.github.io/mobservable/refguide/api.html)
* [ES5, ES6, TypeScript syntax examples](https://github.com/mweststrate/mobservable/blob/master/docs/api.md)
* [TypeScript Typings](https://github.com/mweststrate/mobservable/blob/master/dist/mobservable.d.ts)
## More examples
## Examples
* The [ports of the _Notes_ and _Kanban_ examples](https://github.com/survivejs/mobservable-demo) from the book "SurviveJS - Webpack and React" to mobservable.
* A simple webshop using [React + mobservable](https://jsfiddle.net/mweststrate/46vL0phw) or [JQuery + mobservable](http://jsfiddle.net/mweststrate/vxn7qgdw).
* [Simple timer](https://jsfiddle.net/mweststrate/wgbe4guu/) application in JSFiddle.
* [TodoMVC](https://rawgit.com/mweststrate/todomvc/immutable-to-observable/examples/react-mobservable/index.html#/), based on the ReactJS TodoMVC.
* Online: Live edit the Todo example from the [introduction](https://mweststrate.github.io/mobservable/getting-started.html#demo).
* Online: Simple timer example on [JSFiddle](https://jsfiddle.net/mweststrate/wgbe4guu/).
* Repo: [Minimal boilerplate repostory](https://github.com/mweststrate/mobservable-react-boilerplate).
* Repo: [Full TodoMVC implementation](https://github.com/mweststrate/mobservable-react-todomvc).
* External example: The ports of the _Notes_ and _Kanban_ [examples of the "SurviveJS - Webpack and React"](https://github.com/survivejs/mobservable-demo).
## Philosophy
* [Official homepage introduction](http://mweststrate.github.io/mobservable/)
* [Making React reactive: the pursuit of high performing, easily maintainable React apps](https://www.mendix.com/tech-blog/making-react-reactive-pursuit-high-performing-easily-maintainable-react-apps/)
* [SurviveJS interview on Mobservable, React and Flux](http://survivejs.com/blog/mobservable-interview/)
* [Pure rendering in the light of time and state](https://medium.com/@mweststrate/pure-rendering-in-the-light-of-time-and-state-4b537d8d40b1)
* [Official homepage](http://mweststrate.github.io/mobservable/)
## Top level api
For the full api, see the [API documentation](https://github.com/mweststrate/mobservable/blob/master/docs/api.md).
For the full api, see the [API documentation](https://mweststrate.github.io/mobservable/refguide/api.html).
This is an overview of most important functions available in the `mobservable` namespace:

@@ -141,3 +139,3 @@

**reactiveComponent(reactJsComponent)**
Turns a ReactJS component into a reactive one, that automatically re-renders if any reactive data that it uses is changed.
Provided by the `mobservable-react` packaege, turns a ReactJS component into a reactive one, that automatically re-renders if any reactive data that it uses is changed.

@@ -162,41 +160,4 @@ **extendReactive(target, properties)**

* Split into two packages; `mobservable` and `mobservable-react`
* Write documentation, including how to organize projects
* Write blog about inner workings
* Write documentation, including how to organize projects
* Introduce options for asynchronous views and structurally compare view results
## FAQ
##### Which browsers are supported?
Mobservable runs on any ES5 environment. That means that all browsers except IE8, Node.js and Rhine are supported. See [caniuse.com](http://caniuse.com/#feat=es5)
##### Is mobservable a framework?
Mobservabe is *not* a framework. It does not tell you how to structure your code, where to store state or how to process events. Yet it might free you from frameworks that poses all kinds of restrictions on your code in the name of performance.
##### Can I combine flux with mobservable?
Flux implementations that do not work on the assumption that the data in their stores is immutable should work well with mobservable.
However, the need for flux is less when using mobservable.
Mobservable already optimizes rendering and since it works with most kinds of data, including cycles and classes.
So other programming paradigms like classic MVC are now can be easily applied in applications that combine ReactJS with mobservable.
##### Can I use mobservable together with framework X?
Probably.
Mobservable is framework agnostic and can be applied in any JS environment.
It just ships with a small function to transform Reactjs components into reactive view functions for convenience.
Mobservable works just as well server side, and is already combined with JQuery (see this [Fiddle](http://jsfiddle.net/mweststrate/vxn7qgdw)) and [Deku](https://gist.github.com/mattmccray/d8740ea97013c7505a9b).
##### Why should I use Mobservable instead of reactive library X?
See: https://github.com/mweststrate/mobservable/issues/18
##### Can I record states and re-hydrate them?
Yes, some examples are coming shortly!
##### Can you tell me how it works?
Sure, join the reactiflux channel our checkout [dnode.ts](lib/dnode.ts). Or, submit an issue to motivate me to make some nice drawings :).
* Introduce options for asynchronous views and structurally compare view results
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc