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.
package/lib/mobx.js CHANGED
@@ -111,7 +111,7 @@ var Atom = (function (_super) {
111
111
  var isAtom = createInstanceofPredicate("Atom", BaseAtom);
112
112
 
113
113
  function hasInterceptors(interceptable) {
114
- return (interceptable.interceptors && interceptable.interceptors.length > 0);
114
+ return interceptable.interceptors && interceptable.interceptors.length > 0;
115
115
  }
116
116
  function registerInterceptor(interceptable, handler) {
117
117
  var interceptors = interceptable.interceptors || (interceptable.interceptors = []);
@@ -223,7 +223,11 @@ var MAX_SPLICE_SIZE = 10000; // See e.g. https://github.com/mobxjs/mobx/issues/8
223
223
  var safariPrototypeSetterInheritanceBug = (function () {
224
224
  var v = false;
225
225
  var p = {};
226
- Object.defineProperty(p, "0", { set: function () { v = true; } });
226
+ Object.defineProperty(p, "0", {
227
+ set: function () {
228
+ v = true;
229
+ }
230
+ });
227
231
  Object.create(p)["0"] = 1;
228
232
  return v === false;
229
233
  })();
@@ -251,6 +255,32 @@ function inherit(ctor, proto) {
251
255
  }
252
256
  }
253
257
  inherit(StubArray, Array.prototype);
258
+ // Weex freeze Array.prototype
259
+ // Make them writeable and configurable in prototype chain
260
+ // https://github.com/alibaba/weex/pull/1529
261
+ if (Object.isFrozen(Array)) {
262
+
263
+ [
264
+ "constructor",
265
+ "push",
266
+ "shift",
267
+ "concat",
268
+ "pop",
269
+ "unshift",
270
+ "replace",
271
+ "find",
272
+ "findIndex",
273
+ "splice",
274
+ "reverse",
275
+ "sort"
276
+ ].forEach(function (key) {
277
+ Object.defineProperty(StubArray.prototype, key, {
278
+ configurable: true,
279
+ writable: true,
280
+ value: Array.prototype[key]
281
+ });
282
+ });
283
+ }
254
284
  var ObservableArrayAdministration = (function () {
255
285
  function ObservableArrayAdministration(name, enhancer, array, owned) {
256
286
  this.array = array;
@@ -259,7 +289,7 @@ var ObservableArrayAdministration = (function () {
259
289
  this.lastKnownLength = 0;
260
290
  this.interceptors = null;
261
291
  this.changeListeners = null;
262
- this.atom = new BaseAtom(name || ("ObservableArray@" + getNextId()));
292
+ this.atom = new BaseAtom(name || "ObservableArray@" + getNextId());
263
293
  this.enhancer = function (newV, oldV) { return enhancer(newV, oldV, name + "[..]"); };
264
294
  }
265
295
  ObservableArrayAdministration.prototype.dehanceValue = function (value) {
@@ -362,7 +392,9 @@ var ObservableArrayAdministration = (function () {
362
392
  }
363
393
  else {
364
394
  var res = this.values.slice(index, index + deleteCount);
365
- this.values = this.values.slice(0, index).concat(newItems, this.values.slice(index + deleteCount));
395
+ this.values = this.values
396
+ .slice(0, index)
397
+ .concat(newItems, this.values.slice(index + deleteCount));
366
398
  return res;
367
399
  }
368
400
  var _a;
@@ -370,11 +402,15 @@ var ObservableArrayAdministration = (function () {
370
402
  ObservableArrayAdministration.prototype.notifyArrayChildUpdate = function (index, newValue, oldValue) {
371
403
  var notifySpy = !this.owned && isSpyEnabled();
372
404
  var notify = hasListeners(this);
373
- var change = notify || notifySpy ? {
374
- object: this.array,
375
- type: "update",
376
- index: index, newValue: newValue, oldValue: oldValue
377
- } : null;
405
+ var change = notify || notifySpy
406
+ ? {
407
+ object: this.array,
408
+ type: "update",
409
+ index: index,
410
+ newValue: newValue,
411
+ oldValue: oldValue
412
+ }
413
+ : null;
378
414
  if (notifySpy)
379
415
  spyReportStart(change);
380
416
  this.atom.reportChanged();
@@ -386,13 +422,17 @@ var ObservableArrayAdministration = (function () {
386
422
  ObservableArrayAdministration.prototype.notifyArraySplice = function (index, added, removed) {
387
423
  var notifySpy = !this.owned && isSpyEnabled();
388
424
  var notify = hasListeners(this);
389
- var change = notify || notifySpy ? {
390
- object: this.array,
391
- type: "splice",
392
- index: index, removed: removed, added: added,
393
- removedCount: removed.length,
394
- addedCount: added.length
395
- } : null;
425
+ var change = notify || notifySpy
426
+ ? {
427
+ object: this.array,
428
+ type: "splice",
429
+ index: index,
430
+ removed: removed,
431
+ added: added,
432
+ removedCount: removed.length,
433
+ addedCount: added.length
434
+ }
435
+ : null;
396
436
  if (notifySpy)
397
437
  spyReportStart(change);
398
438
  this.atom.reportChanged();
@@ -438,7 +478,7 @@ var ObservableArray = (function (_super) {
438
478
  arrays[_i] = arguments[_i];
439
479
  }
440
480
  this.$mobx.atom.reportObserved();
441
- return Array.prototype.concat.apply(this.peek(), arrays.map(function (a) { return isObservableArray(a) ? a.peek() : a; }));
481
+ return Array.prototype.concat.apply(this.peek(), arrays.map(function (a) { return (isObservableArray(a) ? a.peek() : a); }));
442
482
  };
443
483
  ObservableArray.prototype.replace = function (newItems) {
444
484
  return this.$mobx.spliceWithArray(0, this.$mobx.values.length, newItems);
@@ -474,11 +514,11 @@ var ObservableArray = (function (_super) {
474
514
  return -1;
475
515
  };
476
516
  /*
477
- functions that do alter the internal structure of the array, (based on lib.es6.d.ts)
478
- since these functions alter the inner structure of the array, the have side effects.
479
- Because the have side effects, they should not be used in computed function,
480
- and for that reason the do not call dependencyState.notifyObserved
481
- */
517
+ * functions that do alter the internal structure of the array, (based on lib.es6.d.ts)
518
+ * since these functions alter the inner structure of the array, the have side effects.
519
+ * Because the have side effects, they should not be used in computed function,
520
+ * and for that reason the do not call dependencyState.notifyObserved
521
+ */
482
522
  ObservableArray.prototype.splice = function (index, deleteCount) {
483
523
  var newItems = [];
484
524
  for (var _i = 2; _i < arguments.length; _i++) {
@@ -560,10 +600,15 @@ var ObservableArray = (function (_super) {
560
600
  var oldItems = this.$mobx.values;
561
601
  var newItems;
562
602
  if (fromIndex < toIndex) {
563
- newItems = oldItems.slice(0, fromIndex).concat(oldItems.slice(fromIndex + 1, toIndex + 1), [oldItems[fromIndex]], oldItems.slice(toIndex + 1));
603
+ newItems = oldItems.slice(0, fromIndex).concat(oldItems.slice(fromIndex + 1, toIndex + 1), [
604
+ oldItems[fromIndex]
605
+ ], oldItems.slice(toIndex + 1));
564
606
  }
565
607
  else {
566
- newItems = oldItems.slice(0, toIndex).concat([oldItems[fromIndex]], oldItems.slice(toIndex, fromIndex), oldItems.slice(fromIndex + 1));
608
+ // toIndex < fromIndex
609
+ newItems = oldItems.slice(0, toIndex).concat([
610
+ oldItems[fromIndex]
611
+ ], oldItems.slice(toIndex, fromIndex), oldItems.slice(fromIndex + 1));
567
612
  }
568
613
  this.replace(newItems);
569
614
  };
@@ -575,7 +620,9 @@ var ObservableArray = (function (_super) {
575
620
  impl.atom.reportObserved();
576
621
  return impl.dehanceValue(impl.values[index]);
577
622
  }
578
- 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");
623
+ console.warn("[mobx.array] Attempt to read an array index (" + index + ") that is out of bounds (" + impl
624
+ .values
625
+ .length + "). Please check length first. Out of bound indices will not be tracked by MobX");
579
626
  }
580
627
  return undefined;
581
628
  };
@@ -591,7 +638,8 @@ var ObservableArray = (function (_super) {
591
638
  var change = interceptChange(adm, {
592
639
  type: "update",
593
640
  object: this,
594
- index: index, newValue: newValue
641
+ index: index,
642
+ newValue: newValue
595
643
  });
596
644
  if (!change)
597
645
  return;
@@ -628,9 +676,6 @@ Object.defineProperty(ObservableArray.prototype, "length", {
628
676
  this.$mobx.setArrayLength(newLength);
629
677
  }
630
678
  });
631
- /**
632
- * Wrap function from prototype
633
- */
634
679
  [
635
680
  "every",
636
681
  "filter",
@@ -742,7 +787,8 @@ var ObservableValue = (function (_super) {
742
787
  spyReportStart({
743
788
  type: "update",
744
789
  object: this,
745
- newValue: newValue, oldValue: oldValue
790
+ newValue: newValue,
791
+ oldValue: oldValue
746
792
  });
747
793
  }
748
794
  this.setNewValue(newValue);
@@ -753,16 +799,18 @@ var ObservableValue = (function (_super) {
753
799
  ObservableValue.prototype.prepareNewValue = function (newValue) {
754
800
  checkIfStateModificationsAreAllowed(this);
755
801
  if (hasInterceptors(this)) {
756
- var change = interceptChange(this, { object: this, type: "update", newValue: newValue });
802
+ var change = interceptChange(this, {
803
+ object: this,
804
+ type: "update",
805
+ newValue: newValue
806
+ });
757
807
  if (!change)
758
808
  return UNCHANGED;
759
809
  newValue = change.newValue;
760
810
  }
761
811
  // apply modifier
762
812
  newValue = this.enhancer(newValue, this.value, this.name);
763
- return this.value !== newValue
764
- ? newValue
765
- : UNCHANGED;
813
+ return this.value !== newValue ? newValue : UNCHANGED;
766
814
  };
767
815
  ObservableValue.prototype.setNewValue = function (newValue) {
768
816
  var oldValue = this.value;
@@ -772,7 +820,8 @@ var ObservableValue = (function (_super) {
772
820
  notifyListeners(this, {
773
821
  type: "update",
774
822
  object: this,
775
- newValue: newValue, oldValue: oldValue
823
+ newValue: newValue,
824
+ oldValue: oldValue
776
825
  });
777
826
  }
778
827
  };
@@ -808,44 +857,43 @@ ObservableValue.prototype[primitiveSymbol()] = ObservableValue.prototype.valueOf
808
857
  var isObservableValue = createInstanceofPredicate("ObservableValue", ObservableValue);
809
858
 
810
859
  var messages = {
811
- "m001": "It is not allowed to assign new values to @action fields",
812
- "m002": "`runInAction` expects a function",
813
- "m003": "`runInAction` expects a function without arguments",
814
- "m004": "autorun expects a function",
815
- "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.",
816
- "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.",
817
- "m007": "reaction only accepts 2 or 3 arguments. If migrating from MobX 2, please provide an options object",
818
- "m008": "wrapping reaction expression in `asReference` is no longer supported, use options object instead",
819
- "m009": "@computed can only be used on getter functions, like: '@computed get myProps() { return ...; }'. It looks like it was used on a property.",
820
- "m010": "@computed can only be used on getter functions, like: '@computed get myProps() { return ...; }'",
821
- "m011": "First argument to `computed` should be an expression. If using computed as decorator, don't pass it arguments",
822
- "m012": "computed takes one or two arguments if used as function",
823
- "m013": "[mobx.expr] 'expr' should only be used inside other reactive functions.",
824
- "m014": "extendObservable expected 2 or more arguments",
825
- "m015": "extendObservable expects an object as first argument",
826
- "m016": "extendObservable should not be used on maps, use map.merge instead",
827
- "m017": "all arguments of extendObservable should be objects",
828
- "m018": "extending an object with another observable (object) is not supported. Please construct an explicit propertymap, using `toJS` if need. See issue #540",
829
- "m019": "[mobx.isObservable] isObservable(object, propertyName) is not supported for arrays and maps. Use map.has or array.length instead.",
830
- "m020": "modifiers can only be used for individual object properties",
831
- "m021": "observable expects zero or one arguments",
832
- "m022": "@observable can not be used on getters, use @computed instead",
833
- "m023": "Using `transaction` is deprecated, use `runInAction` or `(@)action` instead.",
834
- "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.",
835
- "m025": "whyRun can only be used on reactions and computed values",
836
- "m026": "`action` can only be invoked on functions",
837
- "m028": "It is not allowed to set `useStrict` when a derivation is running",
838
- "m029": "INTERNAL ERROR only onBecomeUnobserved shouldn't be called twice in a row",
839
- "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: ",
840
- "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: ",
841
- "m031": "Computed values are not allowed to cause side effects by changing observables that are already being observed. Tried to modify: ",
842
- "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).",
843
- "m033": "`observe` doesn't support the fire immediately property for observable maps.",
844
- "m034": "`mobx.map` is deprecated, use `new ObservableMap` or `mobx.observable.map` instead",
845
- "m035": "Cannot make the designated object observable; it is not extensible",
846
- "m036": "It is not possible to get index atoms from arrays",
847
- "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",
848
- "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"
860
+ m001: "It is not allowed to assign new values to @action fields",
861
+ m002: "`runInAction` expects a function",
862
+ m003: "`runInAction` expects a function without arguments",
863
+ m004: "autorun expects a function",
864
+ 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.",
865
+ 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.",
866
+ m007: "reaction only accepts 2 or 3 arguments. If migrating from MobX 2, please provide an options object",
867
+ m008: "wrapping reaction expression in `asReference` is no longer supported, use options object instead",
868
+ m009: "@computed can only be used on getter functions, like: '@computed get myProps() { return ...; }'. It looks like it was used on a property.",
869
+ m010: "@computed can only be used on getter functions, like: '@computed get myProps() { return ...; }'",
870
+ m011: "First argument to `computed` should be an expression. If using computed as decorator, don't pass it arguments",
871
+ m012: "computed takes one or two arguments if used as function",
872
+ m013: "[mobx.expr] 'expr' should only be used inside other reactive functions.",
873
+ m014: "extendObservable expected 2 or more arguments",
874
+ m015: "extendObservable expects an object as first argument",
875
+ m016: "extendObservable should not be used on maps, use map.merge instead",
876
+ m017: "all arguments of extendObservable should be objects",
877
+ m018: "extending an object with another observable (object) is not supported. Please construct an explicit propertymap, using `toJS` if need. See issue #540",
878
+ m019: "[mobx.isObservable] isObservable(object, propertyName) is not supported for arrays and maps. Use map.has or array.length instead.",
879
+ m020: "modifiers can only be used for individual object properties",
880
+ m021: "observable expects zero or one arguments",
881
+ m022: "@observable can not be used on getters, use @computed instead",
882
+ 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.",
883
+ m025: "whyRun can only be used on reactions and computed values",
884
+ m026: "`action` can only be invoked on functions",
885
+ m028: "It is not allowed to set `useStrict` when a derivation is running",
886
+ m029: "INTERNAL ERROR only onBecomeUnobserved shouldn't be called twice in a row",
887
+ 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: ",
888
+ 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: ",
889
+ m031: "Computed values are not allowed to cause side effects by changing observables that are already being observed. Tried to modify: ",
890
+ 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).",
891
+ m033: "`observe` doesn't support the fire immediately property for observable maps.",
892
+ m034: "`mobx.map` is deprecated, use `new ObservableMap` or `mobx.observable.map` instead",
893
+ m035: "Cannot make the designated object observable; it is not extensible",
894
+ m036: "It is not possible to get index atoms from arrays",
895
+ 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",
896
+ 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"
849
897
  };
850
898
  function getMessage(id) {
851
899
  return messages[id];
@@ -984,7 +1032,7 @@ function createClassPropertyDecorator(
984
1032
  }
985
1033
  }
986
1034
  };
987
- if (arguments.length < 3 || arguments.length === 5 && argLen < 3) {
1035
+ if (arguments.length < 3 || (arguments.length === 5 && argLen < 3)) {
988
1036
  // Typescript target is ES3, so it won't define property for us
989
1037
  // or using Reflect.decorate polyfill, which will return no descriptor
990
1038
  // (see https://github.com/mobxjs/mobx/issues/333)
@@ -1000,10 +1048,11 @@ function createClassPropertyDecorator(
1000
1048
  }
1001
1049
  var value_1 = descriptor.value, initializer_1 = descriptor.initializer;
1002
1050
  target.__mobxLazyInitializers.push(function (instance) {
1003
- onInitialize(instance, key, (initializer_1 ? initializer_1.call(instance) : value_1), customArgs, descriptor);
1051
+ onInitialize(instance, key, initializer_1 ? initializer_1.call(instance) : value_1, customArgs, descriptor);
1004
1052
  });
1005
1053
  return {
1006
- enumerable: enumerable, configurable: true,
1054
+ enumerable: enumerable,
1055
+ configurable: true,
1007
1056
  get: function () {
1008
1057
  if (this.__mobxDidRunLazyInitializers !== true)
1009
1058
  runLazyInitializers(this);
@@ -1026,7 +1075,9 @@ function createClassPropertyDecorator(
1026
1075
  /** Indirect invocation: @decorator(args) bla */
1027
1076
  var outerArgs = arguments;
1028
1077
  var argLen = arguments.length;
1029
- return function (target, key, descriptor) { return classPropertyDecorator(target, key, descriptor, outerArgs, argLen); };
1078
+ return function (target, key, descriptor) {
1079
+ return classPropertyDecorator(target, key, descriptor, outerArgs, argLen);
1080
+ };
1030
1081
  };
1031
1082
  }
1032
1083
  return classPropertyDecorator;
@@ -1042,7 +1093,8 @@ function runLazyInitializers(instance) {
1042
1093
  return;
1043
1094
  if (instance.__mobxLazyInitializers) {
1044
1095
  addHiddenProp(instance, "__mobxDidRunLazyInitializers", true);
1045
- instance.__mobxDidRunLazyInitializers && instance.__mobxLazyInitializers.forEach(function (initializer) { return initializer(instance); });
1096
+ instance.__mobxDidRunLazyInitializers &&
1097
+ instance.__mobxLazyInitializers.forEach(function (initializer) { return initializer(instance); });
1046
1098
  }
1047
1099
  }
1048
1100
  function quacksLikeADecorator(args) {
@@ -1050,7 +1102,7 @@ function quacksLikeADecorator(args) {
1050
1102
  }
1051
1103
 
1052
1104
  var actionFieldDecorator = createClassPropertyDecorator(function (target, key, value, args, originalDescriptor) {
1053
- var actionName = (args && args.length === 1) ? args[0] : (value.name || key || "<unnamed action>");
1105
+ var actionName = args && args.length === 1 ? args[0] : value.name || key || "<unnamed action>";
1054
1106
  var wrappedAction = action(actionName, value);
1055
1107
  addHiddenProp(target, key, wrappedAction);
1056
1108
  }, function (key) {
@@ -1092,6 +1144,9 @@ function namedActionDecorator(name) {
1092
1144
  descriptor.configurable = true;
1093
1145
  return descriptor;
1094
1146
  }
1147
+ if (descriptor !== undefined && descriptor.get !== undefined) {
1148
+ throw new Error("[mobx] action is not expected to be used with getters");
1149
+ }
1095
1150
  // bound instance methods
1096
1151
  return actionFieldDecorator(name).apply(this, arguments);
1097
1152
  };
@@ -1120,13 +1175,13 @@ function identityComparer(a, b) {
1120
1175
  return a === b;
1121
1176
  }
1122
1177
  function structuralComparer(a, b) {
1123
- if (typeof a === 'number' && typeof b === 'number' && isNaN(a) && isNaN(b)) {
1178
+ if (typeof a === "number" && typeof b === "number" && isNaN(a) && isNaN(b)) {
1124
1179
  return true;
1125
1180
  }
1126
1181
  return deepEqual(a, b);
1127
1182
  }
1128
1183
  function defaultComparer(a, b) {
1129
- if (typeof a === 'number' && typeof b === 'number' && isNaN(a) && isNaN(b)) {
1184
+ if (typeof a === "number" && typeof b === "number" && isNaN(a) && isNaN(b)) {
1130
1185
  return true;
1131
1186
  }
1132
1187
  return identityComparer(a, b);
@@ -1145,7 +1200,7 @@ function autorun(arg1, arg2, arg3) {
1145
1200
  scope = arg3;
1146
1201
  }
1147
1202
  else {
1148
- name = arg1.name || ("Autorun@" + getNextId());
1203
+ name = arg1.name || "Autorun@" + getNextId();
1149
1204
  view = arg1;
1150
1205
  scope = arg2;
1151
1206
  }
@@ -1171,7 +1226,7 @@ function when(arg1, arg2, arg3, arg4) {
1171
1226
  scope = arg4;
1172
1227
  }
1173
1228
  else {
1174
- name = ("When@" + getNextId());
1229
+ name = "When@" + getNextId();
1175
1230
  predicate = arg1;
1176
1231
  effect = arg2;
1177
1232
  scope = arg3;
@@ -1195,7 +1250,7 @@ function autorunAsync(arg1, arg2, arg3, arg4) {
1195
1250
  scope = arg4;
1196
1251
  }
1197
1252
  else {
1198
- name = arg1.name || ("AutorunAsync@" + getNextId());
1253
+ name = arg1.name || "AutorunAsync@" + getNextId();
1199
1254
  func = arg1;
1200
1255
  delay = arg2;
1201
1256
  scope = arg3;
@@ -1216,7 +1271,9 @@ function autorunAsync(arg1, arg2, arg3, arg4) {
1216
1271
  }, delay);
1217
1272
  }
1218
1273
  });
1219
- function reactionRunner() { func(r); }
1274
+ function reactionRunner() {
1275
+ func(r);
1276
+ }
1220
1277
  r.schedule();
1221
1278
  return r.getDisposer();
1222
1279
  }
@@ -1234,7 +1291,8 @@ function reaction(expression, effect, arg3) {
1234
1291
  else {
1235
1292
  opts = {};
1236
1293
  }
1237
- opts.name = opts.name || expression.name || effect.name || ("Reaction@" + getNextId());
1294
+ opts.name =
1295
+ opts.name || expression.name || effect.name || "Reaction@" + getNextId();
1238
1296
  opts.fireImmediately = arg3 === true || opts.fireImmediately === true;
1239
1297
  opts.delay = opts.delay || 0;
1240
1298
  opts.compareStructural = opts.compareStructural || opts.struct || false;
@@ -1248,9 +1306,7 @@ function reaction(expression, effect, arg3) {
1248
1306
  var value;
1249
1307
  var equals = opts.equals
1250
1308
  ? opts.equals
1251
- : (opts.compareStructural || opts.struct)
1252
- ? comparer.structural
1253
- : comparer.default;
1309
+ : opts.compareStructural || opts.struct ? comparer.structural : comparer.default;
1254
1310
  var r = new Reaction(opts.name, function () {
1255
1311
  if (firstTime || opts.delay < 1) {
1256
1312
  reactionRunner();
@@ -1286,7 +1342,9 @@ function reaction(expression, effect, arg3) {
1286
1342
  /**
1287
1343
  * A node in the state dependency root that observes other nodes, and can be observed itself.
1288
1344
  *
1289
- * ComputedValue will remember result of the computation for duration of a batch, or being observed
1345
+ * ComputedValue will remember the result of the computation for the duration of the batch, or
1346
+ * while being observed.
1347
+ *
1290
1348
  * During this time it will recompute only when one of its direct dependencies changed,
1291
1349
  * but only when it is being accessed with `ComputedValue.get()`.
1292
1350
  *
@@ -1377,7 +1435,8 @@ var ComputedValue = (function () {
1377
1435
  };
1378
1436
  ComputedValue.prototype.set = function (value) {
1379
1437
  if (this.setter) {
1380
- 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?");
1438
+ invariant(!this.isRunningSetter, "The setter of computed value '" + this
1439
+ .name + "' is trying to update itself. Did you intend to update an _observable_ value, instead of the computed property?");
1381
1440
  this.isRunningSetter = true;
1382
1441
  try {
1383
1442
  this.setter.call(this.scope, value);
@@ -1387,7 +1446,8 @@ var ComputedValue = (function () {
1387
1446
  }
1388
1447
  }
1389
1448
  else
1390
- invariant(false, "[ComputedValue '" + this.name + "'] It is not possible to assign a new value to a computed value.");
1449
+ invariant(false, "[ComputedValue '" + this
1450
+ .name + "'] It is not possible to assign a new value to a computed value.");
1391
1451
  };
1392
1452
  ComputedValue.prototype.trackAndCompute = function () {
1393
1453
  if (isSpyEnabled()) {
@@ -1398,7 +1458,7 @@ var ComputedValue = (function () {
1398
1458
  });
1399
1459
  }
1400
1460
  var oldValue = this.value;
1401
- var newValue = this.value = this.computeValue(true);
1461
+ var newValue = (this.value = this.computeValue(true));
1402
1462
  return (isCaughtException(oldValue) ||
1403
1463
  isCaughtException(newValue) ||
1404
1464
  !this.equals(oldValue, newValue));
@@ -1422,7 +1482,6 @@ var ComputedValue = (function () {
1422
1482
  this.isComputing = false;
1423
1483
  return res;
1424
1484
  };
1425
-
1426
1485
  ComputedValue.prototype.observe = function (listener, fireImmediately) {
1427
1486
  var _this = this;
1428
1487
  var firstTime = true;
@@ -1452,14 +1511,20 @@ var ComputedValue = (function () {
1452
1511
  ComputedValue.prototype.valueOf = function () {
1453
1512
  return toPrimitive(this.get());
1454
1513
  };
1455
-
1456
1514
  ComputedValue.prototype.whyRun = function () {
1457
1515
  var isTracking = Boolean(globalState.trackingDerivation);
1458
1516
  var observing = unique(this.isComputing ? this.newObserving : this.observing).map(function (dep) { return dep.name; });
1459
1517
  var observers = unique(getObservers(this).map(function (dep) { return dep.name; }));
1460
- 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" +
1461
- (this.dependenciesState === exports.IDerivationState.NOT_TRACKING ? getMessage("m032") :
1462
- " * 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"));
1518
+ return ("\nWhyRun? computation '" + this.name + "':\n * Running because: " + (isTracking
1519
+ ? "[active] the value of this computation is needed by a reaction"
1520
+ : this.isComputing
1521
+ ? "[get] The value of this computed was requested outside a reaction"
1522
+ : "[idle] not running at the moment") + "\n" +
1523
+ (this.dependenciesState === exports.IDerivationState.NOT_TRACKING
1524
+ ? getMessage("m032")
1525
+ : " * This computation will re-run if any of the following observables changes:\n " + joinStrings(observing) + "\n " + (this.isComputing && isTracking
1526
+ ? " (... or any observable accessed during the remainder of the current run)"
1527
+ : "") + "\n\t" + getMessage("m038") + "\n\n * If the outcome of this computation changes, the following observers will be re-run:\n " + joinStrings(observers) + "\n"));
1463
1528
  };
1464
1529
  return ComputedValue;
1465
1530
  }());
@@ -1475,10 +1540,10 @@ var ObservableObjectAdministration = (function () {
1475
1540
  this.interceptors = null;
1476
1541
  }
1477
1542
  /**
1478
- * Observes this object. Triggers for the events 'add', 'update' and 'delete'.
1479
- * See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/observe
1480
- * for callback details
1481
- */
1543
+ * Observes this object. Triggers for the events 'add', 'update' and 'delete'.
1544
+ * See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/observe
1545
+ * for callback details
1546
+ */
1482
1547
  ObservableObjectAdministration.prototype.observe = function (callback, fireImmediately) {
1483
1548
  invariant(fireImmediately !== true, "`observe` doesn't support the fire immediately property for observable objects.");
1484
1549
  return registerListener(this, callback);
@@ -1489,7 +1554,7 @@ var ObservableObjectAdministration = (function () {
1489
1554
  return ObservableObjectAdministration;
1490
1555
  }());
1491
1556
  function asObservableObject(target, name) {
1492
- if (isObservableObject(target) && target.hasOwnProperty('$mobx'))
1557
+ if (isObservableObject(target) && target.hasOwnProperty("$mobx"))
1493
1558
  return target.$mobx;
1494
1559
  invariant(Object.isExtensible(target), getMessage("m035"));
1495
1560
  if (!isPlainObject(target))
@@ -1501,7 +1566,7 @@ function asObservableObject(target, name) {
1501
1566
  return adm;
1502
1567
  }
1503
1568
  function defineObservablePropertyFromDescriptor(adm, propName, descriptor, defaultEnhancer) {
1504
- if (adm.values[propName]) {
1569
+ if (adm.values[propName] && !isComputedValue(adm.values[propName])) {
1505
1570
  // already observable property
1506
1571
  invariant("value" in descriptor, "The property " + propName + " in " + adm.name + " is already observable, cannot redefine it as computed property");
1507
1572
  adm.target[propName] = descriptor.value; // the property setter will make 'value' reactive if needed.
@@ -1545,7 +1610,7 @@ function defineObservableProperty(adm, propName, newValue, enhancer) {
1545
1610
  return;
1546
1611
  newValue = change.newValue;
1547
1612
  }
1548
- var observable = adm.values[propName] = new ObservableValue(newValue, enhancer, adm.name + "." + propName, false);
1613
+ var observable = (adm.values[propName] = new ObservableValue(newValue, enhancer, adm.name + "." + propName, false));
1549
1614
  newValue = observable.value; // observableValue might have changed it
1550
1615
  Object.defineProperty(adm.target, propName, generateObservablePropConfig(propName));
1551
1616
  notifyPropertyAddition(adm, adm.target, propName, newValue);
@@ -1569,28 +1634,30 @@ function defineComputedPropertyFromComputedValue(adm, propName, computedValue) {
1569
1634
  var observablePropertyConfigs = {};
1570
1635
  var computedPropertyConfigs = {};
1571
1636
  function generateObservablePropConfig(propName) {
1572
- return observablePropertyConfigs[propName] || (observablePropertyConfigs[propName] = {
1573
- configurable: true,
1574
- enumerable: true,
1575
- get: function () {
1576
- return this.$mobx.values[propName].get();
1577
- },
1578
- set: function (v) {
1579
- setPropertyValue(this, propName, v);
1580
- }
1581
- });
1637
+ return (observablePropertyConfigs[propName] ||
1638
+ (observablePropertyConfigs[propName] = {
1639
+ configurable: true,
1640
+ enumerable: true,
1641
+ get: function () {
1642
+ return this.$mobx.values[propName].get();
1643
+ },
1644
+ set: function (v) {
1645
+ setPropertyValue(this, propName, v);
1646
+ }
1647
+ }));
1582
1648
  }
1583
1649
  function generateComputedPropConfig(propName) {
1584
- return computedPropertyConfigs[propName] || (computedPropertyConfigs[propName] = {
1585
- configurable: true,
1586
- enumerable: false,
1587
- get: function () {
1588
- return this.$mobx.values[propName].get();
1589
- },
1590
- set: function (v) {
1591
- return this.$mobx.values[propName].set(v);
1592
- }
1593
- });
1650
+ return (computedPropertyConfigs[propName] ||
1651
+ (computedPropertyConfigs[propName] = {
1652
+ configurable: true,
1653
+ enumerable: false,
1654
+ get: function () {
1655
+ return this.$mobx.values[propName].get();
1656
+ },
1657
+ set: function (v) {
1658
+ return this.$mobx.values[propName].set(v);
1659
+ }
1660
+ }));
1594
1661
  }
1595
1662
  function setPropertyValue(instance, name, newValue) {
1596
1663
  var adm = instance.$mobx;
@@ -1600,7 +1667,8 @@ function setPropertyValue(instance, name, newValue) {
1600
1667
  var change = interceptChange(adm, {
1601
1668
  type: "update",
1602
1669
  object: instance,
1603
- name: name, newValue: newValue
1670
+ name: name,
1671
+ newValue: newValue
1604
1672
  });
1605
1673
  if (!change)
1606
1674
  return;
@@ -1611,12 +1679,15 @@ function setPropertyValue(instance, name, newValue) {
1611
1679
  if (newValue !== UNCHANGED) {
1612
1680
  var notify = hasListeners(adm);
1613
1681
  var notifySpy = isSpyEnabled();
1614
- var change = notify || notifySpy ? {
1615
- type: "update",
1616
- object: instance,
1617
- oldValue: observable.value,
1618
- name: name, newValue: newValue
1619
- } : null;
1682
+ var change = notify || notifySpy
1683
+ ? {
1684
+ type: "update",
1685
+ object: instance,
1686
+ oldValue: observable.value,
1687
+ name: name,
1688
+ newValue: newValue
1689
+ }
1690
+ : null;
1620
1691
  if (notifySpy)
1621
1692
  spyReportStart(change);
1622
1693
  observable.setNewValue(newValue);
@@ -1629,10 +1700,14 @@ function setPropertyValue(instance, name, newValue) {
1629
1700
  function notifyPropertyAddition(adm, object, name, newValue) {
1630
1701
  var notify = hasListeners(adm);
1631
1702
  var notifySpy = isSpyEnabled();
1632
- var change = notify || notifySpy ? {
1633
- type: "add",
1634
- object: object, name: name, newValue: newValue
1635
- } : null;
1703
+ var change = notify || notifySpy
1704
+ ? {
1705
+ type: "add",
1706
+ object: object,
1707
+ name: name,
1708
+ newValue: newValue
1709
+ }
1710
+ : null;
1636
1711
  if (notifySpy)
1637
1712
  spyReportStart(change);
1638
1713
  if (notify)
@@ -1651,10 +1726,10 @@ function isObservableObject(thing) {
1651
1726
  }
1652
1727
 
1653
1728
  /**
1654
- * Returns true if the provided value is reactive.
1655
- * @param value object, function or array
1656
- * @param property if property is specified, checks whether value.property is reactive.
1657
- */
1729
+ * Returns true if the provided value is reactive.
1730
+ * @param value object, function or array
1731
+ * @param property if property is specified, checks whether value.property is reactive.
1732
+ */
1658
1733
  function isObservable(value, property) {
1659
1734
  if (value === null || value === undefined)
1660
1735
  return false;
@@ -1668,7 +1743,11 @@ function isObservable(value, property) {
1668
1743
  return false;
1669
1744
  }
1670
1745
  // For first check, see #701
1671
- return isObservableObject(value) || !!value.$mobx || isAtom(value) || isReaction(value) || isComputedValue(value);
1746
+ return (isObservableObject(value) ||
1747
+ !!value.$mobx ||
1748
+ isAtom(value) ||
1749
+ isReaction(value) ||
1750
+ isComputedValue(value));
1672
1751
  }
1673
1752
 
1674
1753
  function createDecoratorForEnhancer(enhancer) {
@@ -1680,7 +1759,8 @@ function createDecoratorForEnhancer(enhancer) {
1680
1759
  defineObservableProperty(adm, name, baseValue, enhancer);
1681
1760
  }, function (name) {
1682
1761
  var observable = this.$mobx.values[name];
1683
- if (observable === undefined)
1762
+ if (observable === undefined // See #505
1763
+ )
1684
1764
  return undefined;
1685
1765
  return observable.get();
1686
1766
  }, function (name, value) {
@@ -1705,7 +1785,7 @@ function extendShallowObservable(target) {
1705
1785
  function extendObservableHelper(target, defaultEnhancer, properties) {
1706
1786
  invariant(arguments.length >= 2, getMessage("m014"));
1707
1787
  invariant(typeof target === "object", getMessage("m015"));
1708
- invariant(!(isObservableMap(target)), getMessage("m016"));
1788
+ invariant(!isObservableMap(target), getMessage("m016"));
1709
1789
  properties.forEach(function (propSet) {
1710
1790
  invariant(typeof propSet === "object", getMessage("m017"));
1711
1791
  invariant(!isObservable(propSet), getMessage("m018"));
@@ -1852,7 +1932,7 @@ var observable = createObservable;
1852
1932
  // ES6 class methods aren't enumerable, can't use Object.keys
1853
1933
  Object.getOwnPropertyNames(IObservableFactories.prototype)
1854
1934
  .filter(function (name) { return name !== "constructor"; })
1855
- .forEach(function (name) { return observable[name] = IObservableFactories.prototype[name]; });
1935
+ .forEach(function (name) { return (observable[name] = IObservableFactories.prototype[name]); });
1856
1936
  observable.deep.struct = observable.struct;
1857
1937
  observable.ref.struct = function () {
1858
1938
  if (arguments.length < 2) {
@@ -1950,7 +2030,6 @@ function refStructEnhancer(v, oldValue, name) {
1950
2030
  */
1951
2031
  function transaction(action, thisArg) {
1952
2032
  if (thisArg === void 0) { thisArg = undefined; }
1953
- deprecated(getMessage("m023"));
1954
2033
  return runInTransaction.apply(undefined, arguments);
1955
2034
  }
1956
2035
  function runInTransaction(action, thisArg) {
@@ -2024,12 +2103,14 @@ var ObservableMap = (function () {
2024
2103
  if (this._has(key)) {
2025
2104
  var notifySpy = isSpyEnabled();
2026
2105
  var notify = hasListeners(this);
2027
- var change = notify || notifySpy ? {
2028
- type: "delete",
2029
- object: this,
2030
- oldValue: this._data[key].value,
2031
- name: key
2032
- } : null;
2106
+ var change = notify || notifySpy
2107
+ ? {
2108
+ type: "delete",
2109
+ object: this,
2110
+ oldValue: this._data[key].value,
2111
+ name: key
2112
+ }
2113
+ : null;
2033
2114
  if (notifySpy)
2034
2115
  spyReportStart(change);
2035
2116
  runInTransaction(function () {
@@ -2064,12 +2145,15 @@ var ObservableMap = (function () {
2064
2145
  if (newValue !== UNCHANGED) {
2065
2146
  var notifySpy = isSpyEnabled();
2066
2147
  var notify = hasListeners(this);
2067
- var change = notify || notifySpy ? {
2068
- type: "update",
2069
- object: this,
2070
- oldValue: observable$$1.value,
2071
- name: name, newValue: newValue
2072
- } : null;
2148
+ var change = notify || notifySpy
2149
+ ? {
2150
+ type: "update",
2151
+ object: this,
2152
+ oldValue: observable$$1.value,
2153
+ name: name,
2154
+ newValue: newValue
2155
+ }
2156
+ : null;
2073
2157
  if (notifySpy)
2074
2158
  spyReportStart(change);
2075
2159
  observable$$1.setNewValue(newValue);
@@ -2082,19 +2166,21 @@ var ObservableMap = (function () {
2082
2166
  ObservableMap.prototype._addValue = function (name, newValue) {
2083
2167
  var _this = this;
2084
2168
  runInTransaction(function () {
2085
- var observable$$1 = _this._data[name] = new ObservableValue(newValue, _this.enhancer, _this.name + "." + name, false);
2169
+ var observable$$1 = (_this._data[name] = new ObservableValue(newValue, _this.enhancer, _this.name + "." + name, false));
2086
2170
  newValue = observable$$1.value; // value might have been changed
2087
2171
  _this._updateHasMapEntry(name, true);
2088
2172
  _this._keys.push(name);
2089
2173
  });
2090
2174
  var notifySpy = isSpyEnabled();
2091
2175
  var notify = hasListeners(this);
2092
- var change = notify || notifySpy ? {
2093
- type: "add",
2094
- object: this,
2095
- name: name,
2096
- newValue: newValue
2097
- } : null;
2176
+ var change = notify || notifySpy
2177
+ ? {
2178
+ type: "add",
2179
+ object: this,
2180
+ name: name,
2181
+ newValue: newValue
2182
+ }
2183
+ : null;
2098
2184
  if (notifySpy)
2099
2185
  spyReportStart(change);
2100
2186
  if (notify)
@@ -2179,7 +2265,7 @@ var ObservableMap = (function () {
2179
2265
  ObservableMap.prototype.toJS = function () {
2180
2266
  var _this = this;
2181
2267
  var res = {};
2182
- this.keys().forEach(function (key) { return res[key] = _this.get(key); });
2268
+ this.keys().forEach(function (key) { return (res[key] = _this.get(key)); });
2183
2269
  return res;
2184
2270
  };
2185
2271
  ObservableMap.prototype.toJSON = function () {
@@ -2199,7 +2285,10 @@ var ObservableMap = (function () {
2199
2285
  };
2200
2286
  ObservableMap.prototype.toString = function () {
2201
2287
  var _this = this;
2202
- return this.name + "[{ " + this.keys().map(function (key) { return key + ": " + ("" + _this.get(key)); }).join(", ") + " }]";
2288
+ return (this.name +
2289
+ "[{ " +
2290
+ this.keys().map(function (key) { return key + ": " + ("" + _this.get(key)); }).join(", ") +
2291
+ " }]");
2203
2292
  };
2204
2293
  /**
2205
2294
  * Observes this object. Triggers for the events 'add', 'update' and 'delete'.
@@ -2228,7 +2317,7 @@ var isObservableMap = createInstanceofPredicate("ObservableMap", ObservableMap);
2228
2317
  var EMPTY_ARRAY = [];
2229
2318
  Object.freeze(EMPTY_ARRAY);
2230
2319
  function getGlobal() {
2231
- return typeof window !== 'undefined' ? window : global;
2320
+ return typeof window !== "undefined" ? window : global;
2232
2321
  }
2233
2322
  function getNextId() {
2234
2323
  return ++globalState.mobxGuid;
@@ -2280,7 +2369,9 @@ function joinStrings(things, limit, separator) {
2280
2369
  if (!things)
2281
2370
  return "";
2282
2371
  var sliced = things.slice(0, limit);
2283
- return "" + sliced.join(separator) + (things.length > limit ? " (... and " + (things.length - limit) + "more)" : "");
2372
+ return "" + sliced.join(separator) + (things.length > limit
2373
+ ? " (... and " + (things.length - limit) + "more)"
2374
+ : "");
2284
2375
  }
2285
2376
  function isObject(value) {
2286
2377
  return value !== null && typeof value === "object";
@@ -2422,7 +2513,7 @@ function primitiveSymbol() {
2422
2513
  return (typeof Symbol === "function" && Symbol.toPrimitive) || "@@toPrimitive";
2423
2514
  }
2424
2515
  function toPrimitive(value) {
2425
- return value === null ? null : typeof value === "object" ? ("" + value) : value;
2516
+ return value === null ? null : typeof value === "object" ? "" + value : value;
2426
2517
  }
2427
2518
 
2428
2519
  /**
@@ -2567,6 +2658,7 @@ function addObserver(observable, node) {
2567
2658
  // invariantObservers(observable);
2568
2659
  var l = observable.observers.length;
2569
2660
  if (l) {
2661
+ // because object assignment is relatively expensive, let's not store data about index 0.
2570
2662
  observable.observersIndexes[node.__mapid] = l;
2571
2663
  }
2572
2664
  observable.observers[l] = node;
@@ -2590,8 +2682,10 @@ function removeObserver(observable, node) {
2590
2682
  var map = observable.observersIndexes;
2591
2683
  var filler = list.pop(); // get last element, which should fill the place of `node`, so the array doesn't have holes
2592
2684
  if (filler !== node) {
2685
+ // otherwise node was the last element, which already got removed from array
2593
2686
  var index = map[node.__mapid] || 0; // getting index of `node`. this is the only place we actually use map.
2594
2687
  if (index) {
2688
+ // map store all indexes but 0, see comment in `addObserver`
2595
2689
  map[filler.__mapid] = index;
2596
2690
  }
2597
2691
  else {
@@ -2688,7 +2782,8 @@ function propagateChangeConfirmed(observable) {
2688
2782
  var d = observers[i];
2689
2783
  if (d.dependenciesState === exports.IDerivationState.POSSIBLY_STALE)
2690
2784
  d.dependenciesState = exports.IDerivationState.STALE;
2691
- else if (d.dependenciesState === exports.IDerivationState.UP_TO_DATE)
2785
+ else if (d.dependenciesState === exports.IDerivationState.UP_TO_DATE // this happens during computing of `d`, just keep lowestObserverState up to date.
2786
+ )
2692
2787
  observable.lowestObserverState = exports.IDerivationState.UP_TO_DATE;
2693
2788
  }
2694
2789
  // invariantLOS(observable, "confirmed end");
@@ -2753,9 +2848,11 @@ function isCaughtException(e) {
2753
2848
  */
2754
2849
  function shouldCompute(derivation) {
2755
2850
  switch (derivation.dependenciesState) {
2756
- case exports.IDerivationState.UP_TO_DATE: return false;
2851
+ case exports.IDerivationState.UP_TO_DATE:
2852
+ return false;
2757
2853
  case exports.IDerivationState.NOT_TRACKING:
2758
- case exports.IDerivationState.STALE: return true;
2854
+ case exports.IDerivationState.STALE:
2855
+ return true;
2759
2856
  case exports.IDerivationState.POSSIBLY_STALE: {
2760
2857
  var prevUntracked = untrackedStart(); // no need for those computeds to be reported, they will be picked up in trackDerivedFunction.
2761
2858
  var obs = derivation.observing, l = obs.length;
@@ -2829,9 +2926,8 @@ function trackDerivedFunction(derivation, f, context) {
2829
2926
  function bindDependencies(derivation) {
2830
2927
  // invariant(derivation.dependenciesState !== IDerivationState.NOT_TRACKING, "INTERNAL ERROR bindDependencies expects derivation.dependenciesState !== -1");
2831
2928
  var prevObserving = derivation.observing;
2832
- var observing = derivation.observing = derivation.newObserving;
2929
+ var observing = (derivation.observing = derivation.newObserving);
2833
2930
  var lowestNewObservingDerivationState = exports.IDerivationState.UP_TO_DATE;
2834
- derivation.newObserving = null; // newObserving shouldn't be needed outside tracking
2835
2931
  // Go through all new observables and check diffValue: (this list can contain duplicates):
2836
2932
  // 0: first occurrence, change to 1 and keep it
2837
2933
  // 1: extra occurrence, drop it
@@ -2851,6 +2947,7 @@ function bindDependencies(derivation) {
2851
2947
  }
2852
2948
  }
2853
2949
  observing.length = i0;
2950
+ derivation.newObserving = null; // newObserving shouldn't be needed outside tracking (statement moved down to work around FF bug, see #614)
2854
2951
  // Go through all old observables and check diffValue: (it is unique after last bindDependencies)
2855
2952
  // 0: it's not in new observables, unobserve it
2856
2953
  // 1: it keeps being observed, don't want to notify it. change to 0
@@ -2872,8 +2969,8 @@ function bindDependencies(derivation) {
2872
2969
  addObserver(dep, derivation);
2873
2970
  }
2874
2971
  }
2875
- // Some new observed derivations might become stale during this derivation computation
2876
- // so say had no chance to propagate staleness (#916)
2972
+ // Some new observed derivations may become stale during this derivation computation
2973
+ // so they have had no chance to propagate staleness (#916)
2877
2974
  if (lowestNewObservingDerivationState !== exports.IDerivationState.UP_TO_DATE) {
2878
2975
  derivation.dependenciesState = lowestNewObservingDerivationState;
2879
2976
  derivation.onBecomeStale();
@@ -3038,7 +3135,11 @@ var Reaction = (function () {
3038
3135
  };
3039
3136
  Reaction.prototype.whyRun = function () {
3040
3137
  var observing = unique(this._isRunning ? this.newObserving : this.observing).map(function (dep) { return dep.name; });
3041
- 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");
3138
+ return "\nWhyRun? reaction '" + this.name + "':\n * Status: [" + (this.isDisposed
3139
+ ? "stopped"
3140
+ : 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
3141
+ ? " (... or any observable accessed during the remainder of the current run)"
3142
+ : "") + "\n\t" + getMessage("m038") + "\n";
3042
3143
  };
3043
3144
  return Reaction;
3044
3145
  }());
@@ -3077,8 +3178,8 @@ function runReactionsHelper() {
3077
3178
  // we converge to no remaining reactions after a while.
3078
3179
  while (allReactions.length > 0) {
3079
3180
  if (++iterations === MAX_REACTION_ITERATIONS) {
3080
- console.error("Reaction doesn't converge to a stable state after " + MAX_REACTION_ITERATIONS + " iterations."
3081
- + (" Probably there is a cycle in the reactive function: " + allReactions[0]));
3181
+ console.error("Reaction doesn't converge to a stable state after " + MAX_REACTION_ITERATIONS + " iterations." +
3182
+ (" Probably there is a cycle in the reactive function: " + allReactions[0]));
3082
3183
  allReactions.splice(0); // clear reactions
3083
3184
  }
3084
3185
  var remainingReactions = allReactions.splice(0);
@@ -3118,7 +3219,8 @@ function createComputedDecorator(equals) {
3118
3219
  defineComputedProperty(adm, name, originalDescriptor.get, originalDescriptor.set, equals, false);
3119
3220
  }, function (name) {
3120
3221
  var observable = this.$mobx.values[name];
3121
- if (observable === undefined)
3222
+ if (observable === undefined // See #505
3223
+ )
3122
3224
  return undefined;
3123
3225
  return observable.get();
3124
3226
  }, function (name, value) {
@@ -3131,7 +3233,7 @@ var computedStructDecorator = createComputedDecorator(comparer.structural);
3131
3233
  * Decorator for class properties: @computed get value() { return expr; }.
3132
3234
  * For legacy purposes also invokable as ES5 observable created: `computed(() => expr)`;
3133
3235
  */
3134
- var computed = (function computed(arg1, arg2, arg3) {
3236
+ var computed = function computed(arg1, arg2, arg3) {
3135
3237
  if (typeof arg2 === "string") {
3136
3238
  return computedDecorator.apply(null, arguments);
3137
3239
  }
@@ -3141,11 +3243,9 @@ var computed = (function computed(arg1, arg2, arg3) {
3141
3243
  opts.setter = typeof arg2 === "function" ? arg2 : opts.setter;
3142
3244
  var equals = opts.equals
3143
3245
  ? opts.equals
3144
- : (opts.compareStructural || opts.struct)
3145
- ? comparer.structural
3146
- : comparer.default;
3246
+ : opts.compareStructural || opts.struct ? comparer.structural : comparer.default;
3147
3247
  return new ComputedValue(arg1, opts.context, equals, opts.name || arg1.name || "", opts.setter);
3148
- });
3248
+ };
3149
3249
  computed.struct = computedStructDecorator;
3150
3250
  computed.equals = createComputedDecorator;
3151
3251
 
@@ -3250,19 +3350,19 @@ function interceptProperty(thing, property, handler) {
3250
3350
  }
3251
3351
 
3252
3352
  /**
3253
- * expr can be used to create temporarily views inside views.
3254
- * This can be improved to improve performance if a value changes often, but usually doesn't affect the outcome of an expression.
3255
- *
3256
- * In the following example the expression prevents that a component is rerender _each time_ the selection changes;
3257
- * instead it will only rerenders when the current todo is (de)selected.
3258
- *
3259
- * reactiveComponent((props) => {
3260
- * const todo = props.todo;
3261
- * const isSelected = mobx.expr(() => props.viewState.selection === todo);
3262
- * return <div className={isSelected ? "todo todo-selected" : "todo"}>{todo.title}</div>
3263
- * });
3264
- *
3265
- */
3353
+ * expr can be used to create temporarily views inside views.
3354
+ * This can be improved to improve performance if a value changes often, but usually doesn't affect the outcome of an expression.
3355
+ *
3356
+ * In the following example the expression prevents that a component is rerender _each time_ the selection changes;
3357
+ * instead it will only rerenders when the current todo is (de)selected.
3358
+ *
3359
+ * reactiveComponent((props) => {
3360
+ * const todo = props.todo;
3361
+ * const isSelected = mobx.expr(() => props.viewState.selection === todo);
3362
+ * return <div className={isSelected ? "todo todo-selected" : "todo"}>{todo.title}</div>
3363
+ * });
3364
+ *
3365
+ */
3266
3366
  function expr(expr, scope) {
3267
3367
  if (!isComputingDerivation())
3268
3368
  console.warn(getMessage("m013"));
@@ -3304,7 +3404,7 @@ function toJS(source, detectCycles, __alreadySeen) {
3304
3404
  }
3305
3405
  if (isObservableMap(source)) {
3306
3406
  var res_1 = cache({});
3307
- source.forEach(function (value, key) { return res_1[key] = toJS(value, detectCycles, __alreadySeen); });
3407
+ source.forEach(function (value, key) { return (res_1[key] = toJS(value, detectCycles, __alreadySeen)); });
3308
3408
  return res_1;
3309
3409
  }
3310
3410
  if (isObservableValue(source))
@@ -3353,7 +3453,7 @@ function createTransformer(transformer, onCleanup) {
3353
3453
  };
3354
3454
  }
3355
3455
  function getMemoizationId(object) {
3356
- if (typeof object === 'string' || typeof object === 'number')
3456
+ if (typeof object === "string" || typeof object === "number")
3357
3457
  return object;
3358
3458
  if (object === null || typeof object !== "object")
3359
3459
  throw new Error("[mobx] transform expected some kind of object or primitive value, got: " + object);
@@ -3474,32 +3574,45 @@ var extras = {
3474
3574
  var everything = {
3475
3575
  Reaction: Reaction,
3476
3576
  untracked: untracked,
3477
- Atom: Atom, BaseAtom: BaseAtom,
3478
- useStrict: useStrict, isStrictModeEnabled: isStrictModeEnabled,
3577
+ Atom: Atom,
3578
+ BaseAtom: BaseAtom,
3579
+ useStrict: useStrict,
3580
+ isStrictModeEnabled: isStrictModeEnabled,
3479
3581
  spy: spy,
3480
3582
  comparer: comparer,
3481
- asReference: asReference, asFlat: asFlat, asStructure: asStructure, asMap: asMap,
3583
+ asReference: asReference,
3584
+ asFlat: asFlat,
3585
+ asStructure: asStructure,
3586
+ asMap: asMap,
3482
3587
  isModifierDescriptor: isModifierDescriptor,
3483
3588
  isObservableObject: isObservableObject,
3484
3589
  isBoxedObservable: isObservableValue,
3485
3590
  isObservableArray: isObservableArray,
3486
- ObservableMap: ObservableMap, isObservableMap: isObservableMap, map: map,
3591
+ ObservableMap: ObservableMap,
3592
+ isObservableMap: isObservableMap,
3593
+ map: map,
3487
3594
  transaction: transaction,
3488
3595
  observable: observable,
3489
3596
  computed: computed,
3490
3597
  isObservable: isObservable,
3491
3598
  isComputed: isComputed,
3492
- extendObservable: extendObservable, extendShallowObservable: extendShallowObservable,
3599
+ extendObservable: extendObservable,
3600
+ extendShallowObservable: extendShallowObservable,
3493
3601
  observe: observe,
3494
3602
  intercept: intercept,
3495
- autorun: autorun, autorunAsync: autorunAsync, when: when, reaction: reaction,
3496
- action: action, isAction: isAction, runInAction: runInAction,
3603
+ autorun: autorun,
3604
+ autorunAsync: autorunAsync,
3605
+ when: when,
3606
+ reaction: reaction,
3607
+ action: action,
3608
+ isAction: isAction,
3609
+ runInAction: runInAction,
3497
3610
  expr: expr,
3498
3611
  toJS: toJS,
3499
3612
  createTransformer: createTransformer,
3500
3613
  whyRun: whyRun,
3501
3614
  isArrayLike: isArrayLike,
3502
- extras: extras,
3615
+ extras: extras
3503
3616
  };
3504
3617
  var warnedAboutDefaultExport = false;
3505
3618
  var _loop_1 = function (p) {
@@ -3508,9 +3621,9 @@ var _loop_1 = function (p) {
3508
3621
  get: function () {
3509
3622
  if (!warnedAboutDefaultExport) {
3510
3623
  warnedAboutDefaultExport = true;
3511
- console.warn('Using default export (`import mobx from \'mobx\'`) is deprecated ' +
3512
- 'and won’t work in mobx@4.0.0\n' +
3513
- 'Use `import * as mobx from \'mobx\'` instead');
3624
+ console.warn("Using default export (`import mobx from 'mobx'`) is deprecated " +
3625
+ "and won’t work in mobx@4.0.0\n" +
3626
+ "Use `import * as mobx from 'mobx'` instead");
3514
3627
  }
3515
3628
  return val;
3516
3629
  }