mobx 3.2.2 → 3.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -107,7 +107,7 @@ var Atom = (function (_super) {
107
107
  var isAtom = createInstanceofPredicate("Atom", BaseAtom);
108
108
 
109
109
  function hasInterceptors(interceptable) {
110
- return (interceptable.interceptors && interceptable.interceptors.length > 0);
110
+ return interceptable.interceptors && interceptable.interceptors.length > 0;
111
111
  }
112
112
  function registerInterceptor(interceptable, handler) {
113
113
  var interceptors = interceptable.interceptors || (interceptable.interceptors = []);
@@ -219,7 +219,11 @@ var MAX_SPLICE_SIZE = 10000; // See e.g. https://github.com/mobxjs/mobx/issues/8
219
219
  var safariPrototypeSetterInheritanceBug = (function () {
220
220
  var v = false;
221
221
  var p = {};
222
- Object.defineProperty(p, "0", { set: function () { v = true; } });
222
+ Object.defineProperty(p, "0", {
223
+ set: function () {
224
+ v = true;
225
+ }
226
+ });
223
227
  Object.create(p)["0"] = 1;
224
228
  return v === false;
225
229
  })();
@@ -247,6 +251,32 @@ function inherit(ctor, proto) {
247
251
  }
248
252
  }
249
253
  inherit(StubArray, Array.prototype);
254
+ // Weex freeze Array.prototype
255
+ // Make them writeable and configurable in prototype chain
256
+ // https://github.com/alibaba/weex/pull/1529
257
+ if (Object.isFrozen(Array)) {
258
+
259
+ [
260
+ "constructor",
261
+ "push",
262
+ "shift",
263
+ "concat",
264
+ "pop",
265
+ "unshift",
266
+ "replace",
267
+ "find",
268
+ "findIndex",
269
+ "splice",
270
+ "reverse",
271
+ "sort"
272
+ ].forEach(function (key) {
273
+ Object.defineProperty(StubArray.prototype, key, {
274
+ configurable: true,
275
+ writable: true,
276
+ value: Array.prototype[key]
277
+ });
278
+ });
279
+ }
250
280
  var ObservableArrayAdministration = (function () {
251
281
  function ObservableArrayAdministration(name, enhancer, array, owned) {
252
282
  this.array = array;
@@ -255,7 +285,7 @@ var ObservableArrayAdministration = (function () {
255
285
  this.lastKnownLength = 0;
256
286
  this.interceptors = null;
257
287
  this.changeListeners = null;
258
- this.atom = new BaseAtom(name || ("ObservableArray@" + getNextId()));
288
+ this.atom = new BaseAtom(name || "ObservableArray@" + getNextId());
259
289
  this.enhancer = function (newV, oldV) { return enhancer(newV, oldV, name + "[..]"); };
260
290
  }
261
291
  ObservableArrayAdministration.prototype.dehanceValue = function (value) {
@@ -358,7 +388,9 @@ var ObservableArrayAdministration = (function () {
358
388
  }
359
389
  else {
360
390
  var res = this.values.slice(index, index + deleteCount);
361
- this.values = this.values.slice(0, index).concat(newItems, this.values.slice(index + deleteCount));
391
+ this.values = this.values
392
+ .slice(0, index)
393
+ .concat(newItems, this.values.slice(index + deleteCount));
362
394
  return res;
363
395
  }
364
396
  var _a;
@@ -366,11 +398,15 @@ var ObservableArrayAdministration = (function () {
366
398
  ObservableArrayAdministration.prototype.notifyArrayChildUpdate = function (index, newValue, oldValue) {
367
399
  var notifySpy = !this.owned && isSpyEnabled();
368
400
  var notify = hasListeners(this);
369
- var change = notify || notifySpy ? {
370
- object: this.array,
371
- type: "update",
372
- index: index, newValue: newValue, oldValue: oldValue
373
- } : null;
401
+ var change = notify || notifySpy
402
+ ? {
403
+ object: this.array,
404
+ type: "update",
405
+ index: index,
406
+ newValue: newValue,
407
+ oldValue: oldValue
408
+ }
409
+ : null;
374
410
  if (notifySpy)
375
411
  spyReportStart(change);
376
412
  this.atom.reportChanged();
@@ -382,13 +418,17 @@ var ObservableArrayAdministration = (function () {
382
418
  ObservableArrayAdministration.prototype.notifyArraySplice = function (index, added, removed) {
383
419
  var notifySpy = !this.owned && isSpyEnabled();
384
420
  var notify = hasListeners(this);
385
- var change = notify || notifySpy ? {
386
- object: this.array,
387
- type: "splice",
388
- index: index, removed: removed, added: added,
389
- removedCount: removed.length,
390
- addedCount: added.length
391
- } : null;
421
+ var change = notify || notifySpy
422
+ ? {
423
+ object: this.array,
424
+ type: "splice",
425
+ index: index,
426
+ removed: removed,
427
+ added: added,
428
+ removedCount: removed.length,
429
+ addedCount: added.length
430
+ }
431
+ : null;
392
432
  if (notifySpy)
393
433
  spyReportStart(change);
394
434
  this.atom.reportChanged();
@@ -434,7 +474,7 @@ var ObservableArray = (function (_super) {
434
474
  arrays[_i] = arguments[_i];
435
475
  }
436
476
  this.$mobx.atom.reportObserved();
437
- return Array.prototype.concat.apply(this.peek(), arrays.map(function (a) { return isObservableArray(a) ? a.peek() : a; }));
477
+ return Array.prototype.concat.apply(this.peek(), arrays.map(function (a) { return (isObservableArray(a) ? a.peek() : a); }));
438
478
  };
439
479
  ObservableArray.prototype.replace = function (newItems) {
440
480
  return this.$mobx.spliceWithArray(0, this.$mobx.values.length, newItems);
@@ -470,11 +510,11 @@ var ObservableArray = (function (_super) {
470
510
  return -1;
471
511
  };
472
512
  /*
473
- functions that do alter the internal structure of the array, (based on lib.es6.d.ts)
474
- since these functions alter the inner structure of the array, the have side effects.
475
- Because the have side effects, they should not be used in computed function,
476
- and for that reason the do not call dependencyState.notifyObserved
477
- */
513
+ * functions that do alter the internal structure of the array, (based on lib.es6.d.ts)
514
+ * since these functions alter the inner structure of the array, the have side effects.
515
+ * Because the have side effects, they should not be used in computed function,
516
+ * and for that reason the do not call dependencyState.notifyObserved
517
+ */
478
518
  ObservableArray.prototype.splice = function (index, deleteCount) {
479
519
  var newItems = [];
480
520
  for (var _i = 2; _i < arguments.length; _i++) {
@@ -556,10 +596,15 @@ var ObservableArray = (function (_super) {
556
596
  var oldItems = this.$mobx.values;
557
597
  var newItems;
558
598
  if (fromIndex < toIndex) {
559
- newItems = oldItems.slice(0, fromIndex).concat(oldItems.slice(fromIndex + 1, toIndex + 1), [oldItems[fromIndex]], oldItems.slice(toIndex + 1));
599
+ newItems = oldItems.slice(0, fromIndex).concat(oldItems.slice(fromIndex + 1, toIndex + 1), [
600
+ oldItems[fromIndex]
601
+ ], oldItems.slice(toIndex + 1));
560
602
  }
561
603
  else {
562
- newItems = oldItems.slice(0, toIndex).concat([oldItems[fromIndex]], oldItems.slice(toIndex, fromIndex), oldItems.slice(fromIndex + 1));
604
+ // toIndex < fromIndex
605
+ newItems = oldItems.slice(0, toIndex).concat([
606
+ oldItems[fromIndex]
607
+ ], oldItems.slice(toIndex, fromIndex), oldItems.slice(fromIndex + 1));
563
608
  }
564
609
  this.replace(newItems);
565
610
  };
@@ -571,7 +616,9 @@ var ObservableArray = (function (_super) {
571
616
  impl.atom.reportObserved();
572
617
  return impl.dehanceValue(impl.values[index]);
573
618
  }
574
- console.warn("[mobx.array] Attempt to read an array index (" + index + ") that is out of bounds (" + impl.values.length + "). Please check length first. Out of bound indices will not be tracked by MobX");
619
+ console.warn("[mobx.array] Attempt to read an array index (" + index + ") that is out of bounds (" + impl
620
+ .values
621
+ .length + "). Please check length first. Out of bound indices will not be tracked by MobX");
575
622
  }
576
623
  return undefined;
577
624
  };
@@ -587,7 +634,8 @@ var ObservableArray = (function (_super) {
587
634
  var change = interceptChange(adm, {
588
635
  type: "update",
589
636
  object: this,
590
- index: index, newValue: newValue
637
+ index: index,
638
+ newValue: newValue
591
639
  });
592
640
  if (!change)
593
641
  return;
@@ -624,9 +672,6 @@ Object.defineProperty(ObservableArray.prototype, "length", {
624
672
  this.$mobx.setArrayLength(newLength);
625
673
  }
626
674
  });
627
- /**
628
- * Wrap function from prototype
629
- */
630
675
  [
631
676
  "every",
632
677
  "filter",
@@ -738,7 +783,8 @@ var ObservableValue = (function (_super) {
738
783
  spyReportStart({
739
784
  type: "update",
740
785
  object: this,
741
- newValue: newValue, oldValue: oldValue
786
+ newValue: newValue,
787
+ oldValue: oldValue
742
788
  });
743
789
  }
744
790
  this.setNewValue(newValue);
@@ -749,16 +795,18 @@ var ObservableValue = (function (_super) {
749
795
  ObservableValue.prototype.prepareNewValue = function (newValue) {
750
796
  checkIfStateModificationsAreAllowed(this);
751
797
  if (hasInterceptors(this)) {
752
- var change = interceptChange(this, { object: this, type: "update", newValue: newValue });
798
+ var change = interceptChange(this, {
799
+ object: this,
800
+ type: "update",
801
+ newValue: newValue
802
+ });
753
803
  if (!change)
754
804
  return UNCHANGED;
755
805
  newValue = change.newValue;
756
806
  }
757
807
  // apply modifier
758
808
  newValue = this.enhancer(newValue, this.value, this.name);
759
- return this.value !== newValue
760
- ? newValue
761
- : UNCHANGED;
809
+ return this.value !== newValue ? newValue : UNCHANGED;
762
810
  };
763
811
  ObservableValue.prototype.setNewValue = function (newValue) {
764
812
  var oldValue = this.value;
@@ -768,7 +816,8 @@ var ObservableValue = (function (_super) {
768
816
  notifyListeners(this, {
769
817
  type: "update",
770
818
  object: this,
771
- newValue: newValue, oldValue: oldValue
819
+ newValue: newValue,
820
+ oldValue: oldValue
772
821
  });
773
822
  }
774
823
  };
@@ -804,44 +853,43 @@ ObservableValue.prototype[primitiveSymbol()] = ObservableValue.prototype.valueOf
804
853
  var isObservableValue = createInstanceofPredicate("ObservableValue", ObservableValue);
805
854
 
806
855
  var messages = {
807
- "m001": "It is not allowed to assign new values to @action fields",
808
- "m002": "`runInAction` expects a function",
809
- "m003": "`runInAction` expects a function without arguments",
810
- "m004": "autorun expects a function",
811
- "m005": "Warning: attempted to pass an action to autorun. Actions are untracked and will not trigger on state changes. Use `reaction` or wrap only your state modification code in an action.",
812
- "m006": "Warning: attempted to pass an action to autorunAsync. Actions are untracked and will not trigger on state changes. Use `reaction` or wrap only your state modification code in an action.",
813
- "m007": "reaction only accepts 2 or 3 arguments. If migrating from MobX 2, please provide an options object",
814
- "m008": "wrapping reaction expression in `asReference` is no longer supported, use options object instead",
815
- "m009": "@computed can only be used on getter functions, like: '@computed get myProps() { return ...; }'. It looks like it was used on a property.",
816
- "m010": "@computed can only be used on getter functions, like: '@computed get myProps() { return ...; }'",
817
- "m011": "First argument to `computed` should be an expression. If using computed as decorator, don't pass it arguments",
818
- "m012": "computed takes one or two arguments if used as function",
819
- "m013": "[mobx.expr] 'expr' should only be used inside other reactive functions.",
820
- "m014": "extendObservable expected 2 or more arguments",
821
- "m015": "extendObservable expects an object as first argument",
822
- "m016": "extendObservable should not be used on maps, use map.merge instead",
823
- "m017": "all arguments of extendObservable should be objects",
824
- "m018": "extending an object with another observable (object) is not supported. Please construct an explicit propertymap, using `toJS` if need. See issue #540",
825
- "m019": "[mobx.isObservable] isObservable(object, propertyName) is not supported for arrays and maps. Use map.has or array.length instead.",
826
- "m020": "modifiers can only be used for individual object properties",
827
- "m021": "observable expects zero or one arguments",
828
- "m022": "@observable can not be used on getters, use @computed instead",
829
- "m023": "Using `transaction` is deprecated, use `runInAction` or `(@)action` instead.",
830
- "m024": "whyRun() can only be used if a derivation is active, or by passing an computed value / reaction explicitly. If you invoked whyRun from inside a computation; the computation is currently suspended but re-evaluating because somebody requested its value.",
831
- "m025": "whyRun can only be used on reactions and computed values",
832
- "m026": "`action` can only be invoked on functions",
833
- "m028": "It is not allowed to set `useStrict` when a derivation is running",
834
- "m029": "INTERNAL ERROR only onBecomeUnobserved shouldn't be called twice in a row",
835
- "m030a": "Since strict-mode is enabled, changing observed observable values outside actions is not allowed. Please wrap the code in an `action` if this change is intended. Tried to modify: ",
836
- "m030b": "Side effects like changing state are not allowed at this point. Are you trying to modify state from, for example, the render function of a React component? Tried to modify: ",
837
- "m031": "Computed values are not allowed to cause side effects by changing observables that are already being observed. Tried to modify: ",
838
- "m032": "* This computation is suspended (not in use by any reaction) and won't run automatically.\n Didn't expect this computation to be suspended at this point?\n 1. Make sure this computation is used by a reaction (reaction, autorun, observer).\n 2. Check whether you are using this computation synchronously (in the same stack as they reaction that needs it).",
839
- "m033": "`observe` doesn't support the fire immediately property for observable maps.",
840
- "m034": "`mobx.map` is deprecated, use `new ObservableMap` or `mobx.observable.map` instead",
841
- "m035": "Cannot make the designated object observable; it is not extensible",
842
- "m036": "It is not possible to get index atoms from arrays",
843
- "m037": "Hi there! I'm sorry you have just run into an exception.\nIf your debugger ends up here, know that some reaction (like the render() of an observer component, autorun or reaction)\nthrew an exception and that mobx caught it, to avoid that it brings the rest of your application down.\nThe original cause of the exception (the code that caused this reaction to run (again)), is still in the stack.\n\nHowever, more interesting is the actual stack trace of the error itself.\nHopefully the error is an instanceof Error, because in that case you can inspect the original stack of the error from where it was thrown.\nSee `error.stack` property, or press the very subtle \"(...)\" link you see near the console.error message that probably brought you here.\nThat stack is more interesting than the stack of this console.error itself.\n\nIf the exception you see is an exception you created yourself, make sure to use `throw new Error(\"Oops\")` instead of `throw \"Oops\"`,\nbecause the javascript environment will only preserve the original stack trace in the first form.\n\nYou can also make sure the debugger pauses the next time this very same exception is thrown by enabling \"Pause on caught exception\".\n(Note that it might pause on many other, unrelated exception as well).\n\nIf that all doesn't help you out, feel free to open an issue https://github.com/mobxjs/mobx/issues!\n",
844
- "m038": "Missing items in this list?\n 1. Check whether all used values are properly marked as observable (use isObservable to verify)\n 2. Make sure you didn't dereference values too early. MobX observes props, not primitives. E.g: use 'person.name' instead of 'name' in your computation.\n"
856
+ m001: "It is not allowed to assign new values to @action fields",
857
+ m002: "`runInAction` expects a function",
858
+ m003: "`runInAction` expects a function without arguments",
859
+ m004: "autorun expects a function",
860
+ m005: "Warning: attempted to pass an action to autorun. Actions are untracked and will not trigger on state changes. Use `reaction` or wrap only your state modification code in an action.",
861
+ m006: "Warning: attempted to pass an action to autorunAsync. Actions are untracked and will not trigger on state changes. Use `reaction` or wrap only your state modification code in an action.",
862
+ m007: "reaction only accepts 2 or 3 arguments. If migrating from MobX 2, please provide an options object",
863
+ m008: "wrapping reaction expression in `asReference` is no longer supported, use options object instead",
864
+ m009: "@computed can only be used on getter functions, like: '@computed get myProps() { return ...; }'. It looks like it was used on a property.",
865
+ m010: "@computed can only be used on getter functions, like: '@computed get myProps() { return ...; }'",
866
+ m011: "First argument to `computed` should be an expression. If using computed as decorator, don't pass it arguments",
867
+ m012: "computed takes one or two arguments if used as function",
868
+ m013: "[mobx.expr] 'expr' should only be used inside other reactive functions.",
869
+ m014: "extendObservable expected 2 or more arguments",
870
+ m015: "extendObservable expects an object as first argument",
871
+ m016: "extendObservable should not be used on maps, use map.merge instead",
872
+ m017: "all arguments of extendObservable should be objects",
873
+ m018: "extending an object with another observable (object) is not supported. Please construct an explicit propertymap, using `toJS` if need. See issue #540",
874
+ m019: "[mobx.isObservable] isObservable(object, propertyName) is not supported for arrays and maps. Use map.has or array.length instead.",
875
+ m020: "modifiers can only be used for individual object properties",
876
+ m021: "observable expects zero or one arguments",
877
+ m022: "@observable can not be used on getters, use @computed instead",
878
+ m024: "whyRun() can only be used if a derivation is active, or by passing an computed value / reaction explicitly. If you invoked whyRun from inside a computation; the computation is currently suspended but re-evaluating because somebody requested its value.",
879
+ m025: "whyRun can only be used on reactions and computed values",
880
+ m026: "`action` can only be invoked on functions",
881
+ m028: "It is not allowed to set `useStrict` when a derivation is running",
882
+ m029: "INTERNAL ERROR only onBecomeUnobserved shouldn't be called twice in a row",
883
+ m030a: "Since strict-mode is enabled, changing observed observable values outside actions is not allowed. Please wrap the code in an `action` if this change is intended. Tried to modify: ",
884
+ m030b: "Side effects like changing state are not allowed at this point. Are you trying to modify state from, for example, the render function of a React component? Tried to modify: ",
885
+ m031: "Computed values are not allowed to cause side effects by changing observables that are already being observed. Tried to modify: ",
886
+ m032: "* This computation is suspended (not in use by any reaction) and won't run automatically.\n Didn't expect this computation to be suspended at this point?\n 1. Make sure this computation is used by a reaction (reaction, autorun, observer).\n 2. Check whether you are using this computation synchronously (in the same stack as they reaction that needs it).",
887
+ m033: "`observe` doesn't support the fire immediately property for observable maps.",
888
+ m034: "`mobx.map` is deprecated, use `new ObservableMap` or `mobx.observable.map` instead",
889
+ m035: "Cannot make the designated object observable; it is not extensible",
890
+ m036: "It is not possible to get index atoms from arrays",
891
+ m037: "Hi there! I'm sorry you have just run into an exception.\nIf your debugger ends up here, know that some reaction (like the render() of an observer component, autorun or reaction)\nthrew an exception and that mobx caught it, to avoid that it brings the rest of your application down.\nThe original cause of the exception (the code that caused this reaction to run (again)), is still in the stack.\n\nHowever, more interesting is the actual stack trace of the error itself.\nHopefully the error is an instanceof Error, because in that case you can inspect the original stack of the error from where it was thrown.\nSee `error.stack` property, or press the very subtle \"(...)\" link you see near the console.error message that probably brought you here.\nThat stack is more interesting than the stack of this console.error itself.\n\nIf the exception you see is an exception you created yourself, make sure to use `throw new Error(\"Oops\")` instead of `throw \"Oops\"`,\nbecause the javascript environment will only preserve the original stack trace in the first form.\n\nYou can also make sure the debugger pauses the next time this very same exception is thrown by enabling \"Pause on caught exception\".\n(Note that it might pause on many other, unrelated exception as well).\n\nIf that all doesn't help you out, feel free to open an issue https://github.com/mobxjs/mobx/issues!\n",
892
+ m038: "Missing items in this list?\n 1. Check whether all used values are properly marked as observable (use isObservable to verify)\n 2. Make sure you didn't dereference values too early. MobX observes props, not primitives. E.g: use 'person.name' instead of 'name' in your computation.\n"
845
893
  };
846
894
  function getMessage(id) {
847
895
  return messages[id];
@@ -980,7 +1028,7 @@ function createClassPropertyDecorator(
980
1028
  }
981
1029
  }
982
1030
  };
983
- if (arguments.length < 3 || arguments.length === 5 && argLen < 3) {
1031
+ if (arguments.length < 3 || (arguments.length === 5 && argLen < 3)) {
984
1032
  // Typescript target is ES3, so it won't define property for us
985
1033
  // or using Reflect.decorate polyfill, which will return no descriptor
986
1034
  // (see https://github.com/mobxjs/mobx/issues/333)
@@ -996,10 +1044,11 @@ function createClassPropertyDecorator(
996
1044
  }
997
1045
  var value_1 = descriptor.value, initializer_1 = descriptor.initializer;
998
1046
  target.__mobxLazyInitializers.push(function (instance) {
999
- onInitialize(instance, key, (initializer_1 ? initializer_1.call(instance) : value_1), customArgs, descriptor);
1047
+ onInitialize(instance, key, initializer_1 ? initializer_1.call(instance) : value_1, customArgs, descriptor);
1000
1048
  });
1001
1049
  return {
1002
- enumerable: enumerable, configurable: true,
1050
+ enumerable: enumerable,
1051
+ configurable: true,
1003
1052
  get: function () {
1004
1053
  if (this.__mobxDidRunLazyInitializers !== true)
1005
1054
  runLazyInitializers(this);
@@ -1022,7 +1071,9 @@ function createClassPropertyDecorator(
1022
1071
  /** Indirect invocation: @decorator(args) bla */
1023
1072
  var outerArgs = arguments;
1024
1073
  var argLen = arguments.length;
1025
- return function (target, key, descriptor) { return classPropertyDecorator(target, key, descriptor, outerArgs, argLen); };
1074
+ return function (target, key, descriptor) {
1075
+ return classPropertyDecorator(target, key, descriptor, outerArgs, argLen);
1076
+ };
1026
1077
  };
1027
1078
  }
1028
1079
  return classPropertyDecorator;
@@ -1038,7 +1089,8 @@ function runLazyInitializers(instance) {
1038
1089
  return;
1039
1090
  if (instance.__mobxLazyInitializers) {
1040
1091
  addHiddenProp(instance, "__mobxDidRunLazyInitializers", true);
1041
- instance.__mobxDidRunLazyInitializers && instance.__mobxLazyInitializers.forEach(function (initializer) { return initializer(instance); });
1092
+ instance.__mobxDidRunLazyInitializers &&
1093
+ instance.__mobxLazyInitializers.forEach(function (initializer) { return initializer(instance); });
1042
1094
  }
1043
1095
  }
1044
1096
  function quacksLikeADecorator(args) {
@@ -1046,7 +1098,7 @@ function quacksLikeADecorator(args) {
1046
1098
  }
1047
1099
 
1048
1100
  var actionFieldDecorator = createClassPropertyDecorator(function (target, key, value, args, originalDescriptor) {
1049
- var actionName = (args && args.length === 1) ? args[0] : (value.name || key || "<unnamed action>");
1101
+ var actionName = args && args.length === 1 ? args[0] : value.name || key || "<unnamed action>";
1050
1102
  var wrappedAction = action(actionName, value);
1051
1103
  addHiddenProp(target, key, wrappedAction);
1052
1104
  }, function (key) {
@@ -1088,6 +1140,9 @@ function namedActionDecorator(name) {
1088
1140
  descriptor.configurable = true;
1089
1141
  return descriptor;
1090
1142
  }
1143
+ if (descriptor !== undefined && descriptor.get !== undefined) {
1144
+ throw new Error("[mobx] action is not expected to be used with getters");
1145
+ }
1091
1146
  // bound instance methods
1092
1147
  return actionFieldDecorator(name).apply(this, arguments);
1093
1148
  };
@@ -1116,13 +1171,13 @@ function identityComparer(a, b) {
1116
1171
  return a === b;
1117
1172
  }
1118
1173
  function structuralComparer(a, b) {
1119
- if (typeof a === 'number' && typeof b === 'number' && isNaN(a) && isNaN(b)) {
1174
+ if (typeof a === "number" && typeof b === "number" && isNaN(a) && isNaN(b)) {
1120
1175
  return true;
1121
1176
  }
1122
1177
  return deepEqual(a, b);
1123
1178
  }
1124
1179
  function defaultComparer(a, b) {
1125
- if (typeof a === 'number' && typeof b === 'number' && isNaN(a) && isNaN(b)) {
1180
+ if (typeof a === "number" && typeof b === "number" && isNaN(a) && isNaN(b)) {
1126
1181
  return true;
1127
1182
  }
1128
1183
  return identityComparer(a, b);
@@ -1141,7 +1196,7 @@ function autorun(arg1, arg2, arg3) {
1141
1196
  scope = arg3;
1142
1197
  }
1143
1198
  else {
1144
- name = arg1.name || ("Autorun@" + getNextId());
1199
+ name = arg1.name || "Autorun@" + getNextId();
1145
1200
  view = arg1;
1146
1201
  scope = arg2;
1147
1202
  }
@@ -1167,7 +1222,7 @@ function when(arg1, arg2, arg3, arg4) {
1167
1222
  scope = arg4;
1168
1223
  }
1169
1224
  else {
1170
- name = ("When@" + getNextId());
1225
+ name = "When@" + getNextId();
1171
1226
  predicate = arg1;
1172
1227
  effect = arg2;
1173
1228
  scope = arg3;
@@ -1191,7 +1246,7 @@ function autorunAsync(arg1, arg2, arg3, arg4) {
1191
1246
  scope = arg4;
1192
1247
  }
1193
1248
  else {
1194
- name = arg1.name || ("AutorunAsync@" + getNextId());
1249
+ name = arg1.name || "AutorunAsync@" + getNextId();
1195
1250
  func = arg1;
1196
1251
  delay = arg2;
1197
1252
  scope = arg3;
@@ -1212,7 +1267,9 @@ function autorunAsync(arg1, arg2, arg3, arg4) {
1212
1267
  }, delay);
1213
1268
  }
1214
1269
  });
1215
- function reactionRunner() { func(r); }
1270
+ function reactionRunner() {
1271
+ func(r);
1272
+ }
1216
1273
  r.schedule();
1217
1274
  return r.getDisposer();
1218
1275
  }
@@ -1230,7 +1287,8 @@ function reaction(expression, effect, arg3) {
1230
1287
  else {
1231
1288
  opts = {};
1232
1289
  }
1233
- opts.name = opts.name || expression.name || effect.name || ("Reaction@" + getNextId());
1290
+ opts.name =
1291
+ opts.name || expression.name || effect.name || "Reaction@" + getNextId();
1234
1292
  opts.fireImmediately = arg3 === true || opts.fireImmediately === true;
1235
1293
  opts.delay = opts.delay || 0;
1236
1294
  opts.compareStructural = opts.compareStructural || opts.struct || false;
@@ -1244,9 +1302,7 @@ function reaction(expression, effect, arg3) {
1244
1302
  var value;
1245
1303
  var equals = opts.equals
1246
1304
  ? opts.equals
1247
- : (opts.compareStructural || opts.struct)
1248
- ? comparer.structural
1249
- : comparer.default;
1305
+ : opts.compareStructural || opts.struct ? comparer.structural : comparer.default;
1250
1306
  var r = new Reaction(opts.name, function () {
1251
1307
  if (firstTime || opts.delay < 1) {
1252
1308
  reactionRunner();
@@ -1282,7 +1338,9 @@ function reaction(expression, effect, arg3) {
1282
1338
  /**
1283
1339
  * A node in the state dependency root that observes other nodes, and can be observed itself.
1284
1340
  *
1285
- * ComputedValue will remember result of the computation for duration of a batch, or being observed
1341
+ * ComputedValue will remember the result of the computation for the duration of the batch, or
1342
+ * while being observed.
1343
+ *
1286
1344
  * During this time it will recompute only when one of its direct dependencies changed,
1287
1345
  * but only when it is being accessed with `ComputedValue.get()`.
1288
1346
  *
@@ -1373,7 +1431,8 @@ var ComputedValue = (function () {
1373
1431
  };
1374
1432
  ComputedValue.prototype.set = function (value) {
1375
1433
  if (this.setter) {
1376
- invariant(!this.isRunningSetter, "The setter of computed value '" + this.name + "' is trying to update itself. Did you intend to update an _observable_ value, instead of the computed property?");
1434
+ invariant(!this.isRunningSetter, "The setter of computed value '" + this
1435
+ .name + "' is trying to update itself. Did you intend to update an _observable_ value, instead of the computed property?");
1377
1436
  this.isRunningSetter = true;
1378
1437
  try {
1379
1438
  this.setter.call(this.scope, value);
@@ -1383,7 +1442,8 @@ var ComputedValue = (function () {
1383
1442
  }
1384
1443
  }
1385
1444
  else
1386
- invariant(false, "[ComputedValue '" + this.name + "'] It is not possible to assign a new value to a computed value.");
1445
+ invariant(false, "[ComputedValue '" + this
1446
+ .name + "'] It is not possible to assign a new value to a computed value.");
1387
1447
  };
1388
1448
  ComputedValue.prototype.trackAndCompute = function () {
1389
1449
  if (isSpyEnabled()) {
@@ -1394,7 +1454,7 @@ var ComputedValue = (function () {
1394
1454
  });
1395
1455
  }
1396
1456
  var oldValue = this.value;
1397
- var newValue = this.value = this.computeValue(true);
1457
+ var newValue = (this.value = this.computeValue(true));
1398
1458
  return (isCaughtException(oldValue) ||
1399
1459
  isCaughtException(newValue) ||
1400
1460
  !this.equals(oldValue, newValue));
@@ -1418,7 +1478,6 @@ var ComputedValue = (function () {
1418
1478
  this.isComputing = false;
1419
1479
  return res;
1420
1480
  };
1421
-
1422
1481
  ComputedValue.prototype.observe = function (listener, fireImmediately) {
1423
1482
  var _this = this;
1424
1483
  var firstTime = true;
@@ -1448,14 +1507,20 @@ var ComputedValue = (function () {
1448
1507
  ComputedValue.prototype.valueOf = function () {
1449
1508
  return toPrimitive(this.get());
1450
1509
  };
1451
-
1452
1510
  ComputedValue.prototype.whyRun = function () {
1453
1511
  var isTracking = Boolean(globalState.trackingDerivation);
1454
1512
  var observing = unique(this.isComputing ? this.newObserving : this.observing).map(function (dep) { return dep.name; });
1455
1513
  var observers = unique(getObservers(this).map(function (dep) { return dep.name; }));
1456
- return ("\nWhyRun? computation '" + this.name + "':\n * Running because: " + (isTracking ? "[active] the value of this computation is needed by a reaction" : this.isComputing ? "[get] The value of this computed was requested outside a reaction" : "[idle] not running at the moment") + "\n" +
1457
- (this.dependenciesState === IDerivationState.NOT_TRACKING ? getMessage("m032") :
1458
- " * This computation will re-run if any of the following observables changes:\n " + joinStrings(observing) + "\n " + ((this.isComputing && isTracking) ? " (... or any observable accessed during the remainder of the current run)" : "") + "\n\t" + getMessage("m038") + "\n\n * If the outcome of this computation changes, the following observers will be re-run:\n " + joinStrings(observers) + "\n"));
1514
+ return ("\nWhyRun? computation '" + this.name + "':\n * Running because: " + (isTracking
1515
+ ? "[active] the value of this computation is needed by a reaction"
1516
+ : this.isComputing
1517
+ ? "[get] The value of this computed was requested outside a reaction"
1518
+ : "[idle] not running at the moment") + "\n" +
1519
+ (this.dependenciesState === IDerivationState.NOT_TRACKING
1520
+ ? getMessage("m032")
1521
+ : " * This computation will re-run if any of the following observables changes:\n " + joinStrings(observing) + "\n " + (this.isComputing && isTracking
1522
+ ? " (... or any observable accessed during the remainder of the current run)"
1523
+ : "") + "\n\t" + getMessage("m038") + "\n\n * If the outcome of this computation changes, the following observers will be re-run:\n " + joinStrings(observers) + "\n"));
1459
1524
  };
1460
1525
  return ComputedValue;
1461
1526
  }());
@@ -1471,10 +1536,10 @@ var ObservableObjectAdministration = (function () {
1471
1536
  this.interceptors = null;
1472
1537
  }
1473
1538
  /**
1474
- * Observes this object. Triggers for the events 'add', 'update' and 'delete'.
1475
- * See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/observe
1476
- * for callback details
1477
- */
1539
+ * Observes this object. Triggers for the events 'add', 'update' and 'delete'.
1540
+ * See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/observe
1541
+ * for callback details
1542
+ */
1478
1543
  ObservableObjectAdministration.prototype.observe = function (callback, fireImmediately) {
1479
1544
  invariant(fireImmediately !== true, "`observe` doesn't support the fire immediately property for observable objects.");
1480
1545
  return registerListener(this, callback);
@@ -1485,7 +1550,7 @@ var ObservableObjectAdministration = (function () {
1485
1550
  return ObservableObjectAdministration;
1486
1551
  }());
1487
1552
  function asObservableObject(target, name) {
1488
- if (isObservableObject(target) && target.hasOwnProperty('$mobx'))
1553
+ if (isObservableObject(target) && target.hasOwnProperty("$mobx"))
1489
1554
  return target.$mobx;
1490
1555
  invariant(Object.isExtensible(target), getMessage("m035"));
1491
1556
  if (!isPlainObject(target))
@@ -1497,7 +1562,7 @@ function asObservableObject(target, name) {
1497
1562
  return adm;
1498
1563
  }
1499
1564
  function defineObservablePropertyFromDescriptor(adm, propName, descriptor, defaultEnhancer) {
1500
- if (adm.values[propName]) {
1565
+ if (adm.values[propName] && !isComputedValue(adm.values[propName])) {
1501
1566
  // already observable property
1502
1567
  invariant("value" in descriptor, "The property " + propName + " in " + adm.name + " is already observable, cannot redefine it as computed property");
1503
1568
  adm.target[propName] = descriptor.value; // the property setter will make 'value' reactive if needed.
@@ -1541,7 +1606,7 @@ function defineObservableProperty(adm, propName, newValue, enhancer) {
1541
1606
  return;
1542
1607
  newValue = change.newValue;
1543
1608
  }
1544
- var observable = adm.values[propName] = new ObservableValue(newValue, enhancer, adm.name + "." + propName, false);
1609
+ var observable = (adm.values[propName] = new ObservableValue(newValue, enhancer, adm.name + "." + propName, false));
1545
1610
  newValue = observable.value; // observableValue might have changed it
1546
1611
  Object.defineProperty(adm.target, propName, generateObservablePropConfig(propName));
1547
1612
  notifyPropertyAddition(adm, adm.target, propName, newValue);
@@ -1565,28 +1630,30 @@ function defineComputedPropertyFromComputedValue(adm, propName, computedValue) {
1565
1630
  var observablePropertyConfigs = {};
1566
1631
  var computedPropertyConfigs = {};
1567
1632
  function generateObservablePropConfig(propName) {
1568
- return observablePropertyConfigs[propName] || (observablePropertyConfigs[propName] = {
1569
- configurable: true,
1570
- enumerable: true,
1571
- get: function () {
1572
- return this.$mobx.values[propName].get();
1573
- },
1574
- set: function (v) {
1575
- setPropertyValue(this, propName, v);
1576
- }
1577
- });
1633
+ return (observablePropertyConfigs[propName] ||
1634
+ (observablePropertyConfigs[propName] = {
1635
+ configurable: true,
1636
+ enumerable: true,
1637
+ get: function () {
1638
+ return this.$mobx.values[propName].get();
1639
+ },
1640
+ set: function (v) {
1641
+ setPropertyValue(this, propName, v);
1642
+ }
1643
+ }));
1578
1644
  }
1579
1645
  function generateComputedPropConfig(propName) {
1580
- return computedPropertyConfigs[propName] || (computedPropertyConfigs[propName] = {
1581
- configurable: true,
1582
- enumerable: false,
1583
- get: function () {
1584
- return this.$mobx.values[propName].get();
1585
- },
1586
- set: function (v) {
1587
- return this.$mobx.values[propName].set(v);
1588
- }
1589
- });
1646
+ return (computedPropertyConfigs[propName] ||
1647
+ (computedPropertyConfigs[propName] = {
1648
+ configurable: true,
1649
+ enumerable: false,
1650
+ get: function () {
1651
+ return this.$mobx.values[propName].get();
1652
+ },
1653
+ set: function (v) {
1654
+ return this.$mobx.values[propName].set(v);
1655
+ }
1656
+ }));
1590
1657
  }
1591
1658
  function setPropertyValue(instance, name, newValue) {
1592
1659
  var adm = instance.$mobx;
@@ -1596,7 +1663,8 @@ function setPropertyValue(instance, name, newValue) {
1596
1663
  var change = interceptChange(adm, {
1597
1664
  type: "update",
1598
1665
  object: instance,
1599
- name: name, newValue: newValue
1666
+ name: name,
1667
+ newValue: newValue
1600
1668
  });
1601
1669
  if (!change)
1602
1670
  return;
@@ -1607,12 +1675,15 @@ function setPropertyValue(instance, name, newValue) {
1607
1675
  if (newValue !== UNCHANGED) {
1608
1676
  var notify = hasListeners(adm);
1609
1677
  var notifySpy = isSpyEnabled();
1610
- var change = notify || notifySpy ? {
1611
- type: "update",
1612
- object: instance,
1613
- oldValue: observable.value,
1614
- name: name, newValue: newValue
1615
- } : null;
1678
+ var change = notify || notifySpy
1679
+ ? {
1680
+ type: "update",
1681
+ object: instance,
1682
+ oldValue: observable.value,
1683
+ name: name,
1684
+ newValue: newValue
1685
+ }
1686
+ : null;
1616
1687
  if (notifySpy)
1617
1688
  spyReportStart(change);
1618
1689
  observable.setNewValue(newValue);
@@ -1625,10 +1696,14 @@ function setPropertyValue(instance, name, newValue) {
1625
1696
  function notifyPropertyAddition(adm, object, name, newValue) {
1626
1697
  var notify = hasListeners(adm);
1627
1698
  var notifySpy = isSpyEnabled();
1628
- var change = notify || notifySpy ? {
1629
- type: "add",
1630
- object: object, name: name, newValue: newValue
1631
- } : null;
1699
+ var change = notify || notifySpy
1700
+ ? {
1701
+ type: "add",
1702
+ object: object,
1703
+ name: name,
1704
+ newValue: newValue
1705
+ }
1706
+ : null;
1632
1707
  if (notifySpy)
1633
1708
  spyReportStart(change);
1634
1709
  if (notify)
@@ -1647,10 +1722,10 @@ function isObservableObject(thing) {
1647
1722
  }
1648
1723
 
1649
1724
  /**
1650
- * Returns true if the provided value is reactive.
1651
- * @param value object, function or array
1652
- * @param property if property is specified, checks whether value.property is reactive.
1653
- */
1725
+ * Returns true if the provided value is reactive.
1726
+ * @param value object, function or array
1727
+ * @param property if property is specified, checks whether value.property is reactive.
1728
+ */
1654
1729
  function isObservable(value, property) {
1655
1730
  if (value === null || value === undefined)
1656
1731
  return false;
@@ -1664,7 +1739,11 @@ function isObservable(value, property) {
1664
1739
  return false;
1665
1740
  }
1666
1741
  // For first check, see #701
1667
- return isObservableObject(value) || !!value.$mobx || isAtom(value) || isReaction(value) || isComputedValue(value);
1742
+ return (isObservableObject(value) ||
1743
+ !!value.$mobx ||
1744
+ isAtom(value) ||
1745
+ isReaction(value) ||
1746
+ isComputedValue(value));
1668
1747
  }
1669
1748
 
1670
1749
  function createDecoratorForEnhancer(enhancer) {
@@ -1676,7 +1755,8 @@ function createDecoratorForEnhancer(enhancer) {
1676
1755
  defineObservableProperty(adm, name, baseValue, enhancer);
1677
1756
  }, function (name) {
1678
1757
  var observable = this.$mobx.values[name];
1679
- if (observable === undefined)
1758
+ if (observable === undefined // See #505
1759
+ )
1680
1760
  return undefined;
1681
1761
  return observable.get();
1682
1762
  }, function (name, value) {
@@ -1701,7 +1781,7 @@ function extendShallowObservable(target) {
1701
1781
  function extendObservableHelper(target, defaultEnhancer, properties) {
1702
1782
  invariant(arguments.length >= 2, getMessage("m014"));
1703
1783
  invariant(typeof target === "object", getMessage("m015"));
1704
- invariant(!(isObservableMap(target)), getMessage("m016"));
1784
+ invariant(!isObservableMap(target), getMessage("m016"));
1705
1785
  properties.forEach(function (propSet) {
1706
1786
  invariant(typeof propSet === "object", getMessage("m017"));
1707
1787
  invariant(!isObservable(propSet), getMessage("m018"));
@@ -1848,7 +1928,7 @@ var observable = createObservable;
1848
1928
  // ES6 class methods aren't enumerable, can't use Object.keys
1849
1929
  Object.getOwnPropertyNames(IObservableFactories.prototype)
1850
1930
  .filter(function (name) { return name !== "constructor"; })
1851
- .forEach(function (name) { return observable[name] = IObservableFactories.prototype[name]; });
1931
+ .forEach(function (name) { return (observable[name] = IObservableFactories.prototype[name]); });
1852
1932
  observable.deep.struct = observable.struct;
1853
1933
  observable.ref.struct = function () {
1854
1934
  if (arguments.length < 2) {
@@ -1946,7 +2026,6 @@ function refStructEnhancer(v, oldValue, name) {
1946
2026
  */
1947
2027
  function transaction(action, thisArg) {
1948
2028
  if (thisArg === void 0) { thisArg = undefined; }
1949
- deprecated(getMessage("m023"));
1950
2029
  return runInTransaction.apply(undefined, arguments);
1951
2030
  }
1952
2031
  function runInTransaction(action, thisArg) {
@@ -2020,12 +2099,14 @@ var ObservableMap = (function () {
2020
2099
  if (this._has(key)) {
2021
2100
  var notifySpy = isSpyEnabled();
2022
2101
  var notify = hasListeners(this);
2023
- var change = notify || notifySpy ? {
2024
- type: "delete",
2025
- object: this,
2026
- oldValue: this._data[key].value,
2027
- name: key
2028
- } : null;
2102
+ var change = notify || notifySpy
2103
+ ? {
2104
+ type: "delete",
2105
+ object: this,
2106
+ oldValue: this._data[key].value,
2107
+ name: key
2108
+ }
2109
+ : null;
2029
2110
  if (notifySpy)
2030
2111
  spyReportStart(change);
2031
2112
  runInTransaction(function () {
@@ -2060,12 +2141,15 @@ var ObservableMap = (function () {
2060
2141
  if (newValue !== UNCHANGED) {
2061
2142
  var notifySpy = isSpyEnabled();
2062
2143
  var notify = hasListeners(this);
2063
- var change = notify || notifySpy ? {
2064
- type: "update",
2065
- object: this,
2066
- oldValue: observable$$1.value,
2067
- name: name, newValue: newValue
2068
- } : null;
2144
+ var change = notify || notifySpy
2145
+ ? {
2146
+ type: "update",
2147
+ object: this,
2148
+ oldValue: observable$$1.value,
2149
+ name: name,
2150
+ newValue: newValue
2151
+ }
2152
+ : null;
2069
2153
  if (notifySpy)
2070
2154
  spyReportStart(change);
2071
2155
  observable$$1.setNewValue(newValue);
@@ -2078,19 +2162,21 @@ var ObservableMap = (function () {
2078
2162
  ObservableMap.prototype._addValue = function (name, newValue) {
2079
2163
  var _this = this;
2080
2164
  runInTransaction(function () {
2081
- var observable$$1 = _this._data[name] = new ObservableValue(newValue, _this.enhancer, _this.name + "." + name, false);
2165
+ var observable$$1 = (_this._data[name] = new ObservableValue(newValue, _this.enhancer, _this.name + "." + name, false));
2082
2166
  newValue = observable$$1.value; // value might have been changed
2083
2167
  _this._updateHasMapEntry(name, true);
2084
2168
  _this._keys.push(name);
2085
2169
  });
2086
2170
  var notifySpy = isSpyEnabled();
2087
2171
  var notify = hasListeners(this);
2088
- var change = notify || notifySpy ? {
2089
- type: "add",
2090
- object: this,
2091
- name: name,
2092
- newValue: newValue
2093
- } : null;
2172
+ var change = notify || notifySpy
2173
+ ? {
2174
+ type: "add",
2175
+ object: this,
2176
+ name: name,
2177
+ newValue: newValue
2178
+ }
2179
+ : null;
2094
2180
  if (notifySpy)
2095
2181
  spyReportStart(change);
2096
2182
  if (notify)
@@ -2175,7 +2261,7 @@ var ObservableMap = (function () {
2175
2261
  ObservableMap.prototype.toJS = function () {
2176
2262
  var _this = this;
2177
2263
  var res = {};
2178
- this.keys().forEach(function (key) { return res[key] = _this.get(key); });
2264
+ this.keys().forEach(function (key) { return (res[key] = _this.get(key)); });
2179
2265
  return res;
2180
2266
  };
2181
2267
  ObservableMap.prototype.toJSON = function () {
@@ -2195,7 +2281,10 @@ var ObservableMap = (function () {
2195
2281
  };
2196
2282
  ObservableMap.prototype.toString = function () {
2197
2283
  var _this = this;
2198
- return this.name + "[{ " + this.keys().map(function (key) { return key + ": " + ("" + _this.get(key)); }).join(", ") + " }]";
2284
+ return (this.name +
2285
+ "[{ " +
2286
+ this.keys().map(function (key) { return key + ": " + ("" + _this.get(key)); }).join(", ") +
2287
+ " }]");
2199
2288
  };
2200
2289
  /**
2201
2290
  * Observes this object. Triggers for the events 'add', 'update' and 'delete'.
@@ -2224,7 +2313,7 @@ var isObservableMap = createInstanceofPredicate("ObservableMap", ObservableMap);
2224
2313
  var EMPTY_ARRAY = [];
2225
2314
  Object.freeze(EMPTY_ARRAY);
2226
2315
  function getGlobal() {
2227
- return typeof window !== 'undefined' ? window : global;
2316
+ return typeof window !== "undefined" ? window : global;
2228
2317
  }
2229
2318
  function getNextId() {
2230
2319
  return ++globalState.mobxGuid;
@@ -2276,7 +2365,9 @@ function joinStrings(things, limit, separator) {
2276
2365
  if (!things)
2277
2366
  return "";
2278
2367
  var sliced = things.slice(0, limit);
2279
- return "" + sliced.join(separator) + (things.length > limit ? " (... and " + (things.length - limit) + "more)" : "");
2368
+ return "" + sliced.join(separator) + (things.length > limit
2369
+ ? " (... and " + (things.length - limit) + "more)"
2370
+ : "");
2280
2371
  }
2281
2372
  function isObject(value) {
2282
2373
  return value !== null && typeof value === "object";
@@ -2418,7 +2509,7 @@ function primitiveSymbol() {
2418
2509
  return (typeof Symbol === "function" && Symbol.toPrimitive) || "@@toPrimitive";
2419
2510
  }
2420
2511
  function toPrimitive(value) {
2421
- return value === null ? null : typeof value === "object" ? ("" + value) : value;
2512
+ return value === null ? null : typeof value === "object" ? "" + value : value;
2422
2513
  }
2423
2514
 
2424
2515
  /**
@@ -2563,6 +2654,7 @@ function addObserver(observable, node) {
2563
2654
  // invariantObservers(observable);
2564
2655
  var l = observable.observers.length;
2565
2656
  if (l) {
2657
+ // because object assignment is relatively expensive, let's not store data about index 0.
2566
2658
  observable.observersIndexes[node.__mapid] = l;
2567
2659
  }
2568
2660
  observable.observers[l] = node;
@@ -2586,8 +2678,10 @@ function removeObserver(observable, node) {
2586
2678
  var map = observable.observersIndexes;
2587
2679
  var filler = list.pop(); // get last element, which should fill the place of `node`, so the array doesn't have holes
2588
2680
  if (filler !== node) {
2681
+ // otherwise node was the last element, which already got removed from array
2589
2682
  var index = map[node.__mapid] || 0; // getting index of `node`. this is the only place we actually use map.
2590
2683
  if (index) {
2684
+ // map store all indexes but 0, see comment in `addObserver`
2591
2685
  map[filler.__mapid] = index;
2592
2686
  }
2593
2687
  else {
@@ -2684,7 +2778,8 @@ function propagateChangeConfirmed(observable) {
2684
2778
  var d = observers[i];
2685
2779
  if (d.dependenciesState === IDerivationState.POSSIBLY_STALE)
2686
2780
  d.dependenciesState = IDerivationState.STALE;
2687
- else if (d.dependenciesState === IDerivationState.UP_TO_DATE)
2781
+ else if (d.dependenciesState === IDerivationState.UP_TO_DATE // this happens during computing of `d`, just keep lowestObserverState up to date.
2782
+ )
2688
2783
  observable.lowestObserverState = IDerivationState.UP_TO_DATE;
2689
2784
  }
2690
2785
  // invariantLOS(observable, "confirmed end");
@@ -2750,9 +2845,11 @@ function isCaughtException(e) {
2750
2845
  */
2751
2846
  function shouldCompute(derivation) {
2752
2847
  switch (derivation.dependenciesState) {
2753
- case IDerivationState.UP_TO_DATE: return false;
2848
+ case IDerivationState.UP_TO_DATE:
2849
+ return false;
2754
2850
  case IDerivationState.NOT_TRACKING:
2755
- case IDerivationState.STALE: return true;
2851
+ case IDerivationState.STALE:
2852
+ return true;
2756
2853
  case IDerivationState.POSSIBLY_STALE: {
2757
2854
  var prevUntracked = untrackedStart(); // no need for those computeds to be reported, they will be picked up in trackDerivedFunction.
2758
2855
  var obs = derivation.observing, l = obs.length;
@@ -2826,9 +2923,8 @@ function trackDerivedFunction(derivation, f, context) {
2826
2923
  function bindDependencies(derivation) {
2827
2924
  // invariant(derivation.dependenciesState !== IDerivationState.NOT_TRACKING, "INTERNAL ERROR bindDependencies expects derivation.dependenciesState !== -1");
2828
2925
  var prevObserving = derivation.observing;
2829
- var observing = derivation.observing = derivation.newObserving;
2926
+ var observing = (derivation.observing = derivation.newObserving);
2830
2927
  var lowestNewObservingDerivationState = IDerivationState.UP_TO_DATE;
2831
- derivation.newObserving = null; // newObserving shouldn't be needed outside tracking
2832
2928
  // Go through all new observables and check diffValue: (this list can contain duplicates):
2833
2929
  // 0: first occurrence, change to 1 and keep it
2834
2930
  // 1: extra occurrence, drop it
@@ -2848,6 +2944,7 @@ function bindDependencies(derivation) {
2848
2944
  }
2849
2945
  }
2850
2946
  observing.length = i0;
2947
+ derivation.newObserving = null; // newObserving shouldn't be needed outside tracking (statement moved down to work around FF bug, see #614)
2851
2948
  // Go through all old observables and check diffValue: (it is unique after last bindDependencies)
2852
2949
  // 0: it's not in new observables, unobserve it
2853
2950
  // 1: it keeps being observed, don't want to notify it. change to 0
@@ -2869,8 +2966,8 @@ function bindDependencies(derivation) {
2869
2966
  addObserver(dep, derivation);
2870
2967
  }
2871
2968
  }
2872
- // Some new observed derivations might become stale during this derivation computation
2873
- // so say had no chance to propagate staleness (#916)
2969
+ // Some new observed derivations may become stale during this derivation computation
2970
+ // so they have had no chance to propagate staleness (#916)
2874
2971
  if (lowestNewObservingDerivationState !== IDerivationState.UP_TO_DATE) {
2875
2972
  derivation.dependenciesState = lowestNewObservingDerivationState;
2876
2973
  derivation.onBecomeStale();
@@ -3035,7 +3132,11 @@ var Reaction = (function () {
3035
3132
  };
3036
3133
  Reaction.prototype.whyRun = function () {
3037
3134
  var observing = unique(this._isRunning ? this.newObserving : this.observing).map(function (dep) { return dep.name; });
3038
- return ("\nWhyRun? reaction '" + this.name + "':\n * Status: [" + (this.isDisposed ? "stopped" : this._isRunning ? "running" : this.isScheduled() ? "scheduled" : "idle") + "]\n * This reaction will re-run if any of the following observables changes:\n " + joinStrings(observing) + "\n " + ((this._isRunning) ? " (... or any observable accessed during the remainder of the current run)" : "") + "\n\t" + getMessage("m038") + "\n");
3135
+ return "\nWhyRun? reaction '" + this.name + "':\n * Status: [" + (this.isDisposed
3136
+ ? "stopped"
3137
+ : this._isRunning ? "running" : this.isScheduled() ? "scheduled" : "idle") + "]\n * This reaction will re-run if any of the following observables changes:\n " + joinStrings(observing) + "\n " + (this._isRunning
3138
+ ? " (... or any observable accessed during the remainder of the current run)"
3139
+ : "") + "\n\t" + getMessage("m038") + "\n";
3039
3140
  };
3040
3141
  return Reaction;
3041
3142
  }());
@@ -3074,8 +3175,8 @@ function runReactionsHelper() {
3074
3175
  // we converge to no remaining reactions after a while.
3075
3176
  while (allReactions.length > 0) {
3076
3177
  if (++iterations === MAX_REACTION_ITERATIONS) {
3077
- console.error("Reaction doesn't converge to a stable state after " + MAX_REACTION_ITERATIONS + " iterations."
3078
- + (" Probably there is a cycle in the reactive function: " + allReactions[0]));
3178
+ console.error("Reaction doesn't converge to a stable state after " + MAX_REACTION_ITERATIONS + " iterations." +
3179
+ (" Probably there is a cycle in the reactive function: " + allReactions[0]));
3079
3180
  allReactions.splice(0); // clear reactions
3080
3181
  }
3081
3182
  var remainingReactions = allReactions.splice(0);
@@ -3115,7 +3216,8 @@ function createComputedDecorator(equals) {
3115
3216
  defineComputedProperty(adm, name, originalDescriptor.get, originalDescriptor.set, equals, false);
3116
3217
  }, function (name) {
3117
3218
  var observable = this.$mobx.values[name];
3118
- if (observable === undefined)
3219
+ if (observable === undefined // See #505
3220
+ )
3119
3221
  return undefined;
3120
3222
  return observable.get();
3121
3223
  }, function (name, value) {
@@ -3128,7 +3230,7 @@ var computedStructDecorator = createComputedDecorator(comparer.structural);
3128
3230
  * Decorator for class properties: @computed get value() { return expr; }.
3129
3231
  * For legacy purposes also invokable as ES5 observable created: `computed(() => expr)`;
3130
3232
  */
3131
- var computed = (function computed(arg1, arg2, arg3) {
3233
+ var computed = function computed(arg1, arg2, arg3) {
3132
3234
  if (typeof arg2 === "string") {
3133
3235
  return computedDecorator.apply(null, arguments);
3134
3236
  }
@@ -3138,11 +3240,9 @@ var computed = (function computed(arg1, arg2, arg3) {
3138
3240
  opts.setter = typeof arg2 === "function" ? arg2 : opts.setter;
3139
3241
  var equals = opts.equals
3140
3242
  ? opts.equals
3141
- : (opts.compareStructural || opts.struct)
3142
- ? comparer.structural
3143
- : comparer.default;
3243
+ : opts.compareStructural || opts.struct ? comparer.structural : comparer.default;
3144
3244
  return new ComputedValue(arg1, opts.context, equals, opts.name || arg1.name || "", opts.setter);
3145
- });
3245
+ };
3146
3246
  computed.struct = computedStructDecorator;
3147
3247
  computed.equals = createComputedDecorator;
3148
3248
 
@@ -3247,19 +3347,19 @@ function interceptProperty(thing, property, handler) {
3247
3347
  }
3248
3348
 
3249
3349
  /**
3250
- * expr can be used to create temporarily views inside views.
3251
- * This can be improved to improve performance if a value changes often, but usually doesn't affect the outcome of an expression.
3252
- *
3253
- * In the following example the expression prevents that a component is rerender _each time_ the selection changes;
3254
- * instead it will only rerenders when the current todo is (de)selected.
3255
- *
3256
- * reactiveComponent((props) => {
3257
- * const todo = props.todo;
3258
- * const isSelected = mobx.expr(() => props.viewState.selection === todo);
3259
- * return <div className={isSelected ? "todo todo-selected" : "todo"}>{todo.title}</div>
3260
- * });
3261
- *
3262
- */
3350
+ * expr can be used to create temporarily views inside views.
3351
+ * This can be improved to improve performance if a value changes often, but usually doesn't affect the outcome of an expression.
3352
+ *
3353
+ * In the following example the expression prevents that a component is rerender _each time_ the selection changes;
3354
+ * instead it will only rerenders when the current todo is (de)selected.
3355
+ *
3356
+ * reactiveComponent((props) => {
3357
+ * const todo = props.todo;
3358
+ * const isSelected = mobx.expr(() => props.viewState.selection === todo);
3359
+ * return <div className={isSelected ? "todo todo-selected" : "todo"}>{todo.title}</div>
3360
+ * });
3361
+ *
3362
+ */
3263
3363
  function expr(expr, scope) {
3264
3364
  if (!isComputingDerivation())
3265
3365
  console.warn(getMessage("m013"));
@@ -3301,7 +3401,7 @@ function toJS(source, detectCycles, __alreadySeen) {
3301
3401
  }
3302
3402
  if (isObservableMap(source)) {
3303
3403
  var res_1 = cache({});
3304
- source.forEach(function (value, key) { return res_1[key] = toJS(value, detectCycles, __alreadySeen); });
3404
+ source.forEach(function (value, key) { return (res_1[key] = toJS(value, detectCycles, __alreadySeen)); });
3305
3405
  return res_1;
3306
3406
  }
3307
3407
  if (isObservableValue(source))
@@ -3350,7 +3450,7 @@ function createTransformer(transformer, onCleanup) {
3350
3450
  };
3351
3451
  }
3352
3452
  function getMemoizationId(object) {
3353
- if (typeof object === 'string' || typeof object === 'number')
3453
+ if (typeof object === "string" || typeof object === "number")
3354
3454
  return object;
3355
3455
  if (object === null || typeof object !== "object")
3356
3456
  throw new Error("[mobx] transform expected some kind of object or primitive value, got: " + object);
@@ -3471,32 +3571,45 @@ var extras = {
3471
3571
  var everything = {
3472
3572
  Reaction: Reaction,
3473
3573
  untracked: untracked,
3474
- Atom: Atom, BaseAtom: BaseAtom,
3475
- useStrict: useStrict, isStrictModeEnabled: isStrictModeEnabled,
3574
+ Atom: Atom,
3575
+ BaseAtom: BaseAtom,
3576
+ useStrict: useStrict,
3577
+ isStrictModeEnabled: isStrictModeEnabled,
3476
3578
  spy: spy,
3477
3579
  comparer: comparer,
3478
- asReference: asReference, asFlat: asFlat, asStructure: asStructure, asMap: asMap,
3580
+ asReference: asReference,
3581
+ asFlat: asFlat,
3582
+ asStructure: asStructure,
3583
+ asMap: asMap,
3479
3584
  isModifierDescriptor: isModifierDescriptor,
3480
3585
  isObservableObject: isObservableObject,
3481
3586
  isBoxedObservable: isObservableValue,
3482
3587
  isObservableArray: isObservableArray,
3483
- ObservableMap: ObservableMap, isObservableMap: isObservableMap, map: map,
3588
+ ObservableMap: ObservableMap,
3589
+ isObservableMap: isObservableMap,
3590
+ map: map,
3484
3591
  transaction: transaction,
3485
3592
  observable: observable,
3486
3593
  computed: computed,
3487
3594
  isObservable: isObservable,
3488
3595
  isComputed: isComputed,
3489
- extendObservable: extendObservable, extendShallowObservable: extendShallowObservable,
3596
+ extendObservable: extendObservable,
3597
+ extendShallowObservable: extendShallowObservable,
3490
3598
  observe: observe,
3491
3599
  intercept: intercept,
3492
- autorun: autorun, autorunAsync: autorunAsync, when: when, reaction: reaction,
3493
- action: action, isAction: isAction, runInAction: runInAction,
3600
+ autorun: autorun,
3601
+ autorunAsync: autorunAsync,
3602
+ when: when,
3603
+ reaction: reaction,
3604
+ action: action,
3605
+ isAction: isAction,
3606
+ runInAction: runInAction,
3494
3607
  expr: expr,
3495
3608
  toJS: toJS,
3496
3609
  createTransformer: createTransformer,
3497
3610
  whyRun: whyRun,
3498
3611
  isArrayLike: isArrayLike,
3499
- extras: extras,
3612
+ extras: extras
3500
3613
  };
3501
3614
  var warnedAboutDefaultExport = false;
3502
3615
  var _loop_1 = function (p) {
@@ -3505,9 +3618,9 @@ var _loop_1 = function (p) {
3505
3618
  get: function () {
3506
3619
  if (!warnedAboutDefaultExport) {
3507
3620
  warnedAboutDefaultExport = true;
3508
- console.warn('Using default export (`import mobx from \'mobx\'`) is deprecated ' +
3509
- 'and won’t work in mobx@4.0.0\n' +
3510
- 'Use `import * as mobx from \'mobx\'` instead');
3621
+ console.warn("Using default export (`import mobx from 'mobx'`) is deprecated " +
3622
+ "and won’t work in mobx@4.0.0\n" +
3623
+ "Use `import * as mobx from 'mobx'` instead");
3511
3624
  }
3512
3625
  return val;
3513
3626
  }