mobx 3.1.17 → 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/CHANGELOG.md +26 -0
- package/README.md +2 -1
- package/lib/api/autorun.d.ts +2 -0
- package/lib/api/computed.d.ts +3 -0
- package/lib/api/expr.d.ts +13 -13
- package/lib/api/intercept-read.d.ts +4 -4
- package/lib/api/intercept.d.ts +1 -1
- package/lib/api/isobservable.d.ts +4 -4
- package/lib/api/tojs.d.ts +2 -2
- package/lib/core/action.d.ts +1 -1
- package/lib/core/computedvalue.d.ts +11 -6
- package/lib/core/derivation.d.ts +7 -6
- package/lib/core/globalstate.d.ts +1 -0
- package/lib/core/observable.d.ts +1 -1
- package/lib/mobx.d.ts +12 -4
- package/lib/mobx.js +425 -253
- package/lib/mobx.js.flow +487 -549
- package/lib/mobx.min.js +2 -2
- package/lib/mobx.min.js.map +1 -1
- package/lib/mobx.module.js +425 -254
- package/lib/mobx.umd.js +425 -253
- package/lib/mobx.umd.min.js +2 -2
- package/lib/mobx.umd.min.js.map +1 -1
- package/lib/types/comparer.d.ts +8 -0
- package/lib/types/modifiers-old.d.ts +1 -1
- package/lib/types/observablearray.d.ts +1 -1
- package/lib/types/observablemap.d.ts +1 -1
- package/lib/types/observableobject.d.ts +7 -6
- package/lib/types/observablevalue.d.ts +1 -1
- package/lib/utils/utils.d.ts +0 -1
- package/package.json +15 -3
package/lib/mobx.module.js
CHANGED
|
@@ -107,7 +107,7 @@ var Atom = (function (_super) {
|
|
|
107
107
|
var isAtom = createInstanceofPredicate("Atom", BaseAtom);
|
|
108
108
|
|
|
109
109
|
function hasInterceptors(interceptable) {
|
|
110
|
-
return
|
|
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", {
|
|
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 ||
|
|
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
|
|
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
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
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
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
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
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
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), [
|
|
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
|
-
|
|
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
|
|
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,
|
|
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,
|
|
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, {
|
|
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,
|
|
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
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
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,
|
|
1047
|
+
onInitialize(instance, key, initializer_1 ? initializer_1.call(instance) : value_1, customArgs, descriptor);
|
|
1000
1048
|
});
|
|
1001
1049
|
return {
|
|
1002
|
-
enumerable: enumerable,
|
|
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) {
|
|
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 &&
|
|
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 =
|
|
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
|
};
|
|
@@ -1112,6 +1167,27 @@ function defineBoundAction(target, propertyName, fn) {
|
|
|
1112
1167
|
addHiddenProp(target, propertyName, res);
|
|
1113
1168
|
}
|
|
1114
1169
|
|
|
1170
|
+
function identityComparer(a, b) {
|
|
1171
|
+
return a === b;
|
|
1172
|
+
}
|
|
1173
|
+
function structuralComparer(a, b) {
|
|
1174
|
+
if (typeof a === "number" && typeof b === "number" && isNaN(a) && isNaN(b)) {
|
|
1175
|
+
return true;
|
|
1176
|
+
}
|
|
1177
|
+
return deepEqual(a, b);
|
|
1178
|
+
}
|
|
1179
|
+
function defaultComparer(a, b) {
|
|
1180
|
+
if (typeof a === "number" && typeof b === "number" && isNaN(a) && isNaN(b)) {
|
|
1181
|
+
return true;
|
|
1182
|
+
}
|
|
1183
|
+
return identityComparer(a, b);
|
|
1184
|
+
}
|
|
1185
|
+
var comparer = {
|
|
1186
|
+
identity: identityComparer,
|
|
1187
|
+
structural: structuralComparer,
|
|
1188
|
+
default: defaultComparer
|
|
1189
|
+
};
|
|
1190
|
+
|
|
1115
1191
|
function autorun(arg1, arg2, arg3) {
|
|
1116
1192
|
var name, view, scope;
|
|
1117
1193
|
if (typeof arg1 === "string") {
|
|
@@ -1120,7 +1196,7 @@ function autorun(arg1, arg2, arg3) {
|
|
|
1120
1196
|
scope = arg3;
|
|
1121
1197
|
}
|
|
1122
1198
|
else {
|
|
1123
|
-
name = arg1.name ||
|
|
1199
|
+
name = arg1.name || "Autorun@" + getNextId();
|
|
1124
1200
|
view = arg1;
|
|
1125
1201
|
scope = arg2;
|
|
1126
1202
|
}
|
|
@@ -1146,7 +1222,7 @@ function when(arg1, arg2, arg3, arg4) {
|
|
|
1146
1222
|
scope = arg4;
|
|
1147
1223
|
}
|
|
1148
1224
|
else {
|
|
1149
|
-
name =
|
|
1225
|
+
name = "When@" + getNextId();
|
|
1150
1226
|
predicate = arg1;
|
|
1151
1227
|
effect = arg2;
|
|
1152
1228
|
scope = arg3;
|
|
@@ -1170,7 +1246,7 @@ function autorunAsync(arg1, arg2, arg3, arg4) {
|
|
|
1170
1246
|
scope = arg4;
|
|
1171
1247
|
}
|
|
1172
1248
|
else {
|
|
1173
|
-
name = arg1.name ||
|
|
1249
|
+
name = arg1.name || "AutorunAsync@" + getNextId();
|
|
1174
1250
|
func = arg1;
|
|
1175
1251
|
delay = arg2;
|
|
1176
1252
|
scope = arg3;
|
|
@@ -1191,7 +1267,9 @@ function autorunAsync(arg1, arg2, arg3, arg4) {
|
|
|
1191
1267
|
}, delay);
|
|
1192
1268
|
}
|
|
1193
1269
|
});
|
|
1194
|
-
function reactionRunner() {
|
|
1270
|
+
function reactionRunner() {
|
|
1271
|
+
func(r);
|
|
1272
|
+
}
|
|
1195
1273
|
r.schedule();
|
|
1196
1274
|
return r.getDisposer();
|
|
1197
1275
|
}
|
|
@@ -1209,17 +1287,22 @@ function reaction(expression, effect, arg3) {
|
|
|
1209
1287
|
else {
|
|
1210
1288
|
opts = {};
|
|
1211
1289
|
}
|
|
1212
|
-
opts.name =
|
|
1290
|
+
opts.name =
|
|
1291
|
+
opts.name || expression.name || effect.name || "Reaction@" + getNextId();
|
|
1213
1292
|
opts.fireImmediately = arg3 === true || opts.fireImmediately === true;
|
|
1214
1293
|
opts.delay = opts.delay || 0;
|
|
1215
1294
|
opts.compareStructural = opts.compareStructural || opts.struct || false;
|
|
1295
|
+
// TODO: creates ugly spy events, use `effect = (r) => runInAction(opts.name, () => effect(r))` instead
|
|
1216
1296
|
effect = action(opts.name, opts.context ? effect.bind(opts.context) : effect);
|
|
1217
1297
|
if (opts.context) {
|
|
1218
1298
|
expression = expression.bind(opts.context);
|
|
1219
1299
|
}
|
|
1220
1300
|
var firstTime = true;
|
|
1221
1301
|
var isScheduled = false;
|
|
1222
|
-
var
|
|
1302
|
+
var value;
|
|
1303
|
+
var equals = opts.equals
|
|
1304
|
+
? opts.equals
|
|
1305
|
+
: opts.compareStructural || opts.struct ? comparer.structural : comparer.default;
|
|
1223
1306
|
var r = new Reaction(opts.name, function () {
|
|
1224
1307
|
if (firstTime || opts.delay < 1) {
|
|
1225
1308
|
reactionRunner();
|
|
@@ -1237,14 +1320,14 @@ function reaction(expression, effect, arg3) {
|
|
|
1237
1320
|
return;
|
|
1238
1321
|
var changed = false;
|
|
1239
1322
|
r.track(function () {
|
|
1240
|
-
var
|
|
1241
|
-
changed =
|
|
1242
|
-
|
|
1323
|
+
var nextValue = expression(r);
|
|
1324
|
+
changed = firstTime || !equals(value, nextValue);
|
|
1325
|
+
value = nextValue;
|
|
1243
1326
|
});
|
|
1244
1327
|
if (firstTime && opts.fireImmediately)
|
|
1245
|
-
effect(
|
|
1328
|
+
effect(value, r);
|
|
1246
1329
|
if (!firstTime && changed === true)
|
|
1247
|
-
effect(
|
|
1330
|
+
effect(value, r);
|
|
1248
1331
|
if (firstTime)
|
|
1249
1332
|
firstTime = false;
|
|
1250
1333
|
}
|
|
@@ -1255,7 +1338,9 @@ function reaction(expression, effect, arg3) {
|
|
|
1255
1338
|
/**
|
|
1256
1339
|
* A node in the state dependency root that observes other nodes, and can be observed itself.
|
|
1257
1340
|
*
|
|
1258
|
-
* ComputedValue will remember result of the computation for duration of
|
|
1341
|
+
* ComputedValue will remember the result of the computation for the duration of the batch, or
|
|
1342
|
+
* while being observed.
|
|
1343
|
+
*
|
|
1259
1344
|
* During this time it will recompute only when one of its direct dependencies changed,
|
|
1260
1345
|
* but only when it is being accessed with `ComputedValue.get()`.
|
|
1261
1346
|
*
|
|
@@ -1275,15 +1360,17 @@ var ComputedValue = (function () {
|
|
|
1275
1360
|
*
|
|
1276
1361
|
* The `name` property is for debug purposes only.
|
|
1277
1362
|
*
|
|
1278
|
-
* The `
|
|
1279
|
-
*
|
|
1280
|
-
*
|
|
1363
|
+
* The `equals` property specifies the comparer function to use to determine if a newly produced
|
|
1364
|
+
* value differs from the previous value. Two comparers are provided in the library; `defaultComparer`
|
|
1365
|
+
* compares based on identity comparison (===), and `structualComparer` deeply compares the structure.
|
|
1366
|
+
* Structural comparison can be convenient if you always produce an new aggregated object and
|
|
1367
|
+
* don't want to notify observers if it is structurally the same.
|
|
1281
1368
|
* This is useful for working with vectors, mouse coordinates etc.
|
|
1282
1369
|
*/
|
|
1283
|
-
function ComputedValue(derivation, scope,
|
|
1370
|
+
function ComputedValue(derivation, scope, equals, name, setter) {
|
|
1284
1371
|
this.derivation = derivation;
|
|
1285
1372
|
this.scope = scope;
|
|
1286
|
-
this.
|
|
1373
|
+
this.equals = equals;
|
|
1287
1374
|
this.dependenciesState = IDerivationState.NOT_TRACKING;
|
|
1288
1375
|
this.observing = []; // nodes we are looking at. Our value depends on these nodes
|
|
1289
1376
|
this.newObserving = null; // during tracking it's an array with new observed observers
|
|
@@ -1296,7 +1383,7 @@ var ComputedValue = (function () {
|
|
|
1296
1383
|
this.lowestObserverState = IDerivationState.UP_TO_DATE;
|
|
1297
1384
|
this.unboundDepsCount = 0;
|
|
1298
1385
|
this.__mapid = "#" + getNextId();
|
|
1299
|
-
this.value =
|
|
1386
|
+
this.value = new CaughtException(null);
|
|
1300
1387
|
this.isComputing = false; // to check for cycles
|
|
1301
1388
|
this.isRunningSetter = false;
|
|
1302
1389
|
this.name = name || "ComputedValue@" + getNextId();
|
|
@@ -1317,9 +1404,9 @@ var ComputedValue = (function () {
|
|
|
1317
1404
|
ComputedValue.prototype.get = function () {
|
|
1318
1405
|
invariant(!this.isComputing, "Cycle detected in computation " + this.name, this.derivation);
|
|
1319
1406
|
if (globalState.inBatch === 0) {
|
|
1320
|
-
//
|
|
1321
|
-
//
|
|
1322
|
-
//
|
|
1407
|
+
// This is an minor optimization which could be omitted to simplify the code
|
|
1408
|
+
// The computedValue is accessed outside of any mobx stuff. Batch observing should be enough and don't need
|
|
1409
|
+
// tracking as it will never be called again inside this batch.
|
|
1323
1410
|
startBatch();
|
|
1324
1411
|
if (shouldCompute(this))
|
|
1325
1412
|
this.value = this.computeValue(false);
|
|
@@ -1344,7 +1431,8 @@ var ComputedValue = (function () {
|
|
|
1344
1431
|
};
|
|
1345
1432
|
ComputedValue.prototype.set = function (value) {
|
|
1346
1433
|
if (this.setter) {
|
|
1347
|
-
invariant(!this.isRunningSetter, "The setter of computed value '" + this
|
|
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?");
|
|
1348
1436
|
this.isRunningSetter = true;
|
|
1349
1437
|
try {
|
|
1350
1438
|
this.setter.call(this.scope, value);
|
|
@@ -1354,7 +1442,8 @@ var ComputedValue = (function () {
|
|
|
1354
1442
|
}
|
|
1355
1443
|
}
|
|
1356
1444
|
else
|
|
1357
|
-
invariant(false, "[ComputedValue '" + this
|
|
1445
|
+
invariant(false, "[ComputedValue '" + this
|
|
1446
|
+
.name + "'] It is not possible to assign a new value to a computed value.");
|
|
1358
1447
|
};
|
|
1359
1448
|
ComputedValue.prototype.trackAndCompute = function () {
|
|
1360
1449
|
if (isSpyEnabled()) {
|
|
@@ -1365,8 +1454,10 @@ var ComputedValue = (function () {
|
|
|
1365
1454
|
});
|
|
1366
1455
|
}
|
|
1367
1456
|
var oldValue = this.value;
|
|
1368
|
-
var newValue = this.value = this.computeValue(true);
|
|
1369
|
-
return isCaughtException(
|
|
1457
|
+
var newValue = (this.value = this.computeValue(true));
|
|
1458
|
+
return (isCaughtException(oldValue) ||
|
|
1459
|
+
isCaughtException(newValue) ||
|
|
1460
|
+
!this.equals(oldValue, newValue));
|
|
1370
1461
|
};
|
|
1371
1462
|
ComputedValue.prototype.computeValue = function (track) {
|
|
1372
1463
|
this.isComputing = true;
|
|
@@ -1387,7 +1478,6 @@ var ComputedValue = (function () {
|
|
|
1387
1478
|
this.isComputing = false;
|
|
1388
1479
|
return res;
|
|
1389
1480
|
};
|
|
1390
|
-
|
|
1391
1481
|
ComputedValue.prototype.observe = function (listener, fireImmediately) {
|
|
1392
1482
|
var _this = this;
|
|
1393
1483
|
var firstTime = true;
|
|
@@ -1417,14 +1507,20 @@ var ComputedValue = (function () {
|
|
|
1417
1507
|
ComputedValue.prototype.valueOf = function () {
|
|
1418
1508
|
return toPrimitive(this.get());
|
|
1419
1509
|
};
|
|
1420
|
-
|
|
1421
1510
|
ComputedValue.prototype.whyRun = function () {
|
|
1422
1511
|
var isTracking = Boolean(globalState.trackingDerivation);
|
|
1423
1512
|
var observing = unique(this.isComputing ? this.newObserving : this.observing).map(function (dep) { return dep.name; });
|
|
1424
1513
|
var observers = unique(getObservers(this).map(function (dep) { return dep.name; }));
|
|
1425
|
-
return ("\nWhyRun? computation '" + this.name + "':\n * Running because: " + (isTracking
|
|
1426
|
-
|
|
1427
|
-
|
|
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"));
|
|
1428
1524
|
};
|
|
1429
1525
|
return ComputedValue;
|
|
1430
1526
|
}());
|
|
@@ -1440,10 +1536,10 @@ var ObservableObjectAdministration = (function () {
|
|
|
1440
1536
|
this.interceptors = null;
|
|
1441
1537
|
}
|
|
1442
1538
|
/**
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
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
|
+
*/
|
|
1447
1543
|
ObservableObjectAdministration.prototype.observe = function (callback, fireImmediately) {
|
|
1448
1544
|
invariant(fireImmediately !== true, "`observe` doesn't support the fire immediately property for observable objects.");
|
|
1449
1545
|
return registerListener(this, callback);
|
|
@@ -1454,7 +1550,7 @@ var ObservableObjectAdministration = (function () {
|
|
|
1454
1550
|
return ObservableObjectAdministration;
|
|
1455
1551
|
}());
|
|
1456
1552
|
function asObservableObject(target, name) {
|
|
1457
|
-
if (isObservableObject(target))
|
|
1553
|
+
if (isObservableObject(target) && target.hasOwnProperty("$mobx"))
|
|
1458
1554
|
return target.$mobx;
|
|
1459
1555
|
invariant(Object.isExtensible(target), getMessage("m035"));
|
|
1460
1556
|
if (!isPlainObject(target))
|
|
@@ -1466,7 +1562,7 @@ function asObservableObject(target, name) {
|
|
|
1466
1562
|
return adm;
|
|
1467
1563
|
}
|
|
1468
1564
|
function defineObservablePropertyFromDescriptor(adm, propName, descriptor, defaultEnhancer) {
|
|
1469
|
-
if (adm.values[propName]) {
|
|
1565
|
+
if (adm.values[propName] && !isComputedValue(adm.values[propName])) {
|
|
1470
1566
|
// already observable property
|
|
1471
1567
|
invariant("value" in descriptor, "The property " + propName + " in " + adm.name + " is already observable, cannot redefine it as computed property");
|
|
1472
1568
|
adm.target[propName] = descriptor.value; // the property setter will make 'value' reactive if needed.
|
|
@@ -1494,7 +1590,7 @@ function defineObservablePropertyFromDescriptor(adm, propName, descriptor, defau
|
|
|
1494
1590
|
}
|
|
1495
1591
|
else {
|
|
1496
1592
|
// get x() { return 3 } set x(v) { }
|
|
1497
|
-
defineComputedProperty(adm, propName, descriptor.get, descriptor.set,
|
|
1593
|
+
defineComputedProperty(adm, propName, descriptor.get, descriptor.set, comparer.default, true);
|
|
1498
1594
|
}
|
|
1499
1595
|
}
|
|
1500
1596
|
function defineObservableProperty(adm, propName, newValue, enhancer) {
|
|
@@ -1510,15 +1606,15 @@ function defineObservableProperty(adm, propName, newValue, enhancer) {
|
|
|
1510
1606
|
return;
|
|
1511
1607
|
newValue = change.newValue;
|
|
1512
1608
|
}
|
|
1513
|
-
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));
|
|
1514
1610
|
newValue = observable.value; // observableValue might have changed it
|
|
1515
1611
|
Object.defineProperty(adm.target, propName, generateObservablePropConfig(propName));
|
|
1516
1612
|
notifyPropertyAddition(adm, adm.target, propName, newValue);
|
|
1517
1613
|
}
|
|
1518
|
-
function defineComputedProperty(adm, propName, getter, setter,
|
|
1614
|
+
function defineComputedProperty(adm, propName, getter, setter, equals, asInstanceProperty) {
|
|
1519
1615
|
if (asInstanceProperty)
|
|
1520
1616
|
assertPropertyConfigurable(adm.target, propName);
|
|
1521
|
-
adm.values[propName] = new ComputedValue(getter, adm.target,
|
|
1617
|
+
adm.values[propName] = new ComputedValue(getter, adm.target, equals, adm.name + "." + propName, setter);
|
|
1522
1618
|
if (asInstanceProperty) {
|
|
1523
1619
|
Object.defineProperty(adm.target, propName, generateComputedPropConfig(propName));
|
|
1524
1620
|
}
|
|
@@ -1534,28 +1630,30 @@ function defineComputedPropertyFromComputedValue(adm, propName, computedValue) {
|
|
|
1534
1630
|
var observablePropertyConfigs = {};
|
|
1535
1631
|
var computedPropertyConfigs = {};
|
|
1536
1632
|
function generateObservablePropConfig(propName) {
|
|
1537
|
-
return observablePropertyConfigs[propName] ||
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
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
|
+
}));
|
|
1547
1644
|
}
|
|
1548
1645
|
function generateComputedPropConfig(propName) {
|
|
1549
|
-
return computedPropertyConfigs[propName] ||
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
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
|
+
}));
|
|
1559
1657
|
}
|
|
1560
1658
|
function setPropertyValue(instance, name, newValue) {
|
|
1561
1659
|
var adm = instance.$mobx;
|
|
@@ -1565,7 +1663,8 @@ function setPropertyValue(instance, name, newValue) {
|
|
|
1565
1663
|
var change = interceptChange(adm, {
|
|
1566
1664
|
type: "update",
|
|
1567
1665
|
object: instance,
|
|
1568
|
-
name: name,
|
|
1666
|
+
name: name,
|
|
1667
|
+
newValue: newValue
|
|
1569
1668
|
});
|
|
1570
1669
|
if (!change)
|
|
1571
1670
|
return;
|
|
@@ -1576,12 +1675,15 @@ function setPropertyValue(instance, name, newValue) {
|
|
|
1576
1675
|
if (newValue !== UNCHANGED) {
|
|
1577
1676
|
var notify = hasListeners(adm);
|
|
1578
1677
|
var notifySpy = isSpyEnabled();
|
|
1579
|
-
var change = notify || notifySpy
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
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;
|
|
1585
1687
|
if (notifySpy)
|
|
1586
1688
|
spyReportStart(change);
|
|
1587
1689
|
observable.setNewValue(newValue);
|
|
@@ -1594,10 +1696,14 @@ function setPropertyValue(instance, name, newValue) {
|
|
|
1594
1696
|
function notifyPropertyAddition(adm, object, name, newValue) {
|
|
1595
1697
|
var notify = hasListeners(adm);
|
|
1596
1698
|
var notifySpy = isSpyEnabled();
|
|
1597
|
-
var change = notify || notifySpy
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1699
|
+
var change = notify || notifySpy
|
|
1700
|
+
? {
|
|
1701
|
+
type: "add",
|
|
1702
|
+
object: object,
|
|
1703
|
+
name: name,
|
|
1704
|
+
newValue: newValue
|
|
1705
|
+
}
|
|
1706
|
+
: null;
|
|
1601
1707
|
if (notifySpy)
|
|
1602
1708
|
spyReportStart(change);
|
|
1603
1709
|
if (notify)
|
|
@@ -1616,10 +1722,10 @@ function isObservableObject(thing) {
|
|
|
1616
1722
|
}
|
|
1617
1723
|
|
|
1618
1724
|
/**
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
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
|
+
*/
|
|
1623
1729
|
function isObservable(value, property) {
|
|
1624
1730
|
if (value === null || value === undefined)
|
|
1625
1731
|
return false;
|
|
@@ -1633,7 +1739,11 @@ function isObservable(value, property) {
|
|
|
1633
1739
|
return false;
|
|
1634
1740
|
}
|
|
1635
1741
|
// For first check, see #701
|
|
1636
|
-
return isObservableObject(value) ||
|
|
1742
|
+
return (isObservableObject(value) ||
|
|
1743
|
+
!!value.$mobx ||
|
|
1744
|
+
isAtom(value) ||
|
|
1745
|
+
isReaction(value) ||
|
|
1746
|
+
isComputedValue(value));
|
|
1637
1747
|
}
|
|
1638
1748
|
|
|
1639
1749
|
function createDecoratorForEnhancer(enhancer) {
|
|
@@ -1645,7 +1755,8 @@ function createDecoratorForEnhancer(enhancer) {
|
|
|
1645
1755
|
defineObservableProperty(adm, name, baseValue, enhancer);
|
|
1646
1756
|
}, function (name) {
|
|
1647
1757
|
var observable = this.$mobx.values[name];
|
|
1648
|
-
if (observable === undefined
|
|
1758
|
+
if (observable === undefined // See #505
|
|
1759
|
+
)
|
|
1649
1760
|
return undefined;
|
|
1650
1761
|
return observable.get();
|
|
1651
1762
|
}, function (name, value) {
|
|
@@ -1670,7 +1781,7 @@ function extendShallowObservable(target) {
|
|
|
1670
1781
|
function extendObservableHelper(target, defaultEnhancer, properties) {
|
|
1671
1782
|
invariant(arguments.length >= 2, getMessage("m014"));
|
|
1672
1783
|
invariant(typeof target === "object", getMessage("m015"));
|
|
1673
|
-
invariant(!
|
|
1784
|
+
invariant(!isObservableMap(target), getMessage("m016"));
|
|
1674
1785
|
properties.forEach(function (propSet) {
|
|
1675
1786
|
invariant(typeof propSet === "object", getMessage("m017"));
|
|
1676
1787
|
invariant(!isObservable(propSet), getMessage("m018"));
|
|
@@ -1699,7 +1810,7 @@ var deepStructDecorator = createDecoratorForEnhancer(deepStructEnhancer);
|
|
|
1699
1810
|
var refStructDecorator = createDecoratorForEnhancer(refStructEnhancer);
|
|
1700
1811
|
/**
|
|
1701
1812
|
* Turns an object, array or function into a reactive structure.
|
|
1702
|
-
* @param
|
|
1813
|
+
* @param v the value which should become observable.
|
|
1703
1814
|
*/
|
|
1704
1815
|
function createObservable(v) {
|
|
1705
1816
|
if (v === void 0) { v = undefined; }
|
|
@@ -1817,7 +1928,7 @@ var observable = createObservable;
|
|
|
1817
1928
|
// ES6 class methods aren't enumerable, can't use Object.keys
|
|
1818
1929
|
Object.getOwnPropertyNames(IObservableFactories.prototype)
|
|
1819
1930
|
.filter(function (name) { return name !== "constructor"; })
|
|
1820
|
-
.forEach(function (name) { return observable[name] = IObservableFactories.prototype[name]; });
|
|
1931
|
+
.forEach(function (name) { return (observable[name] = IObservableFactories.prototype[name]); });
|
|
1821
1932
|
observable.deep.struct = observable.struct;
|
|
1822
1933
|
observable.ref.struct = function () {
|
|
1823
1934
|
if (arguments.length < 2) {
|
|
@@ -1915,7 +2026,6 @@ function refStructEnhancer(v, oldValue, name) {
|
|
|
1915
2026
|
*/
|
|
1916
2027
|
function transaction(action, thisArg) {
|
|
1917
2028
|
if (thisArg === void 0) { thisArg = undefined; }
|
|
1918
|
-
deprecated(getMessage("m023"));
|
|
1919
2029
|
return runInTransaction.apply(undefined, arguments);
|
|
1920
2030
|
}
|
|
1921
2031
|
function runInTransaction(action, thisArg) {
|
|
@@ -1989,12 +2099,14 @@ var ObservableMap = (function () {
|
|
|
1989
2099
|
if (this._has(key)) {
|
|
1990
2100
|
var notifySpy = isSpyEnabled();
|
|
1991
2101
|
var notify = hasListeners(this);
|
|
1992
|
-
var change = notify || notifySpy
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
2102
|
+
var change = notify || notifySpy
|
|
2103
|
+
? {
|
|
2104
|
+
type: "delete",
|
|
2105
|
+
object: this,
|
|
2106
|
+
oldValue: this._data[key].value,
|
|
2107
|
+
name: key
|
|
2108
|
+
}
|
|
2109
|
+
: null;
|
|
1998
2110
|
if (notifySpy)
|
|
1999
2111
|
spyReportStart(change);
|
|
2000
2112
|
runInTransaction(function () {
|
|
@@ -2029,12 +2141,15 @@ var ObservableMap = (function () {
|
|
|
2029
2141
|
if (newValue !== UNCHANGED) {
|
|
2030
2142
|
var notifySpy = isSpyEnabled();
|
|
2031
2143
|
var notify = hasListeners(this);
|
|
2032
|
-
var change = notify || notifySpy
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
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;
|
|
2038
2153
|
if (notifySpy)
|
|
2039
2154
|
spyReportStart(change);
|
|
2040
2155
|
observable$$1.setNewValue(newValue);
|
|
@@ -2047,19 +2162,21 @@ var ObservableMap = (function () {
|
|
|
2047
2162
|
ObservableMap.prototype._addValue = function (name, newValue) {
|
|
2048
2163
|
var _this = this;
|
|
2049
2164
|
runInTransaction(function () {
|
|
2050
|
-
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));
|
|
2051
2166
|
newValue = observable$$1.value; // value might have been changed
|
|
2052
2167
|
_this._updateHasMapEntry(name, true);
|
|
2053
2168
|
_this._keys.push(name);
|
|
2054
2169
|
});
|
|
2055
2170
|
var notifySpy = isSpyEnabled();
|
|
2056
2171
|
var notify = hasListeners(this);
|
|
2057
|
-
var change = notify || notifySpy
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2172
|
+
var change = notify || notifySpy
|
|
2173
|
+
? {
|
|
2174
|
+
type: "add",
|
|
2175
|
+
object: this,
|
|
2176
|
+
name: name,
|
|
2177
|
+
newValue: newValue
|
|
2178
|
+
}
|
|
2179
|
+
: null;
|
|
2063
2180
|
if (notifySpy)
|
|
2064
2181
|
spyReportStart(change);
|
|
2065
2182
|
if (notify)
|
|
@@ -2139,12 +2256,12 @@ var ObservableMap = (function () {
|
|
|
2139
2256
|
});
|
|
2140
2257
|
/**
|
|
2141
2258
|
* Returns a shallow non observable object clone of this map.
|
|
2142
|
-
* Note that the values
|
|
2259
|
+
* Note that the values might still be observable. For a deep clone use mobx.toJS.
|
|
2143
2260
|
*/
|
|
2144
2261
|
ObservableMap.prototype.toJS = function () {
|
|
2145
2262
|
var _this = this;
|
|
2146
2263
|
var res = {};
|
|
2147
|
-
this.keys().forEach(function (key) { return res[key] = _this.get(key); });
|
|
2264
|
+
this.keys().forEach(function (key) { return (res[key] = _this.get(key)); });
|
|
2148
2265
|
return res;
|
|
2149
2266
|
};
|
|
2150
2267
|
ObservableMap.prototype.toJSON = function () {
|
|
@@ -2164,7 +2281,10 @@ var ObservableMap = (function () {
|
|
|
2164
2281
|
};
|
|
2165
2282
|
ObservableMap.prototype.toString = function () {
|
|
2166
2283
|
var _this = this;
|
|
2167
|
-
return this.name +
|
|
2284
|
+
return (this.name +
|
|
2285
|
+
"[{ " +
|
|
2286
|
+
this.keys().map(function (key) { return key + ": " + ("" + _this.get(key)); }).join(", ") +
|
|
2287
|
+
" }]");
|
|
2168
2288
|
};
|
|
2169
2289
|
/**
|
|
2170
2290
|
* Observes this object. Triggers for the events 'add', 'update' and 'delete'.
|
|
@@ -2193,7 +2313,7 @@ var isObservableMap = createInstanceofPredicate("ObservableMap", ObservableMap);
|
|
|
2193
2313
|
var EMPTY_ARRAY = [];
|
|
2194
2314
|
Object.freeze(EMPTY_ARRAY);
|
|
2195
2315
|
function getGlobal() {
|
|
2196
|
-
return global;
|
|
2316
|
+
return typeof window !== "undefined" ? window : global;
|
|
2197
2317
|
}
|
|
2198
2318
|
function getNextId() {
|
|
2199
2319
|
return ++globalState.mobxGuid;
|
|
@@ -2245,7 +2365,9 @@ function joinStrings(things, limit, separator) {
|
|
|
2245
2365
|
if (!things)
|
|
2246
2366
|
return "";
|
|
2247
2367
|
var sliced = things.slice(0, limit);
|
|
2248
|
-
return "" + sliced.join(separator) + (things.length > limit
|
|
2368
|
+
return "" + sliced.join(separator) + (things.length > limit
|
|
2369
|
+
? " (... and " + (things.length - limit) + "more)"
|
|
2370
|
+
: "");
|
|
2249
2371
|
}
|
|
2250
2372
|
function isObject(value) {
|
|
2251
2373
|
return value !== null && typeof value === "object";
|
|
@@ -2267,14 +2389,6 @@ function objectAssign() {
|
|
|
2267
2389
|
}
|
|
2268
2390
|
return res;
|
|
2269
2391
|
}
|
|
2270
|
-
function valueDidChange(compareStructural, oldValue, newValue) {
|
|
2271
|
-
if (typeof oldValue === 'number' && isNaN(oldValue)) {
|
|
2272
|
-
return typeof newValue !== 'number' || !isNaN(newValue);
|
|
2273
|
-
}
|
|
2274
|
-
return compareStructural
|
|
2275
|
-
? !deepEqual(oldValue, newValue)
|
|
2276
|
-
: oldValue !== newValue;
|
|
2277
|
-
}
|
|
2278
2392
|
var prototypeHasOwnProperty = Object.prototype.hasOwnProperty;
|
|
2279
2393
|
function hasOwnProperty(object, propName) {
|
|
2280
2394
|
return prototypeHasOwnProperty.call(object, propName);
|
|
@@ -2395,7 +2509,7 @@ function primitiveSymbol() {
|
|
|
2395
2509
|
return (typeof Symbol === "function" && Symbol.toPrimitive) || "@@toPrimitive";
|
|
2396
2510
|
}
|
|
2397
2511
|
function toPrimitive(value) {
|
|
2398
|
-
return value === null ? null : typeof value === "object" ?
|
|
2512
|
+
return value === null ? null : typeof value === "object" ? "" + value : value;
|
|
2399
2513
|
}
|
|
2400
2514
|
|
|
2401
2515
|
/**
|
|
@@ -2471,7 +2585,32 @@ var MobXGlobals = (function () {
|
|
|
2471
2585
|
return MobXGlobals;
|
|
2472
2586
|
}());
|
|
2473
2587
|
var globalState = new MobXGlobals();
|
|
2588
|
+
var shareGlobalStateCalled = false;
|
|
2589
|
+
var runInIsolationCalled = false;
|
|
2590
|
+
var warnedAboutMultipleInstances = false;
|
|
2591
|
+
{
|
|
2592
|
+
var global_1 = getGlobal();
|
|
2593
|
+
if (!global_1.__mobxInstanceCount) {
|
|
2594
|
+
global_1.__mobxInstanceCount = 1;
|
|
2595
|
+
}
|
|
2596
|
+
else {
|
|
2597
|
+
global_1.__mobxInstanceCount++;
|
|
2598
|
+
setTimeout(function () {
|
|
2599
|
+
if (!shareGlobalStateCalled && !runInIsolationCalled && !warnedAboutMultipleInstances) {
|
|
2600
|
+
warnedAboutMultipleInstances = true;
|
|
2601
|
+
console.warn("[mobx] Warning: there are multiple mobx instances active. This might lead to unexpected results. See https://github.com/mobxjs/mobx/issues/1082 for details.");
|
|
2602
|
+
}
|
|
2603
|
+
});
|
|
2604
|
+
}
|
|
2605
|
+
}
|
|
2606
|
+
function isolateGlobalState() {
|
|
2607
|
+
runInIsolationCalled = true;
|
|
2608
|
+
getGlobal().__mobxInstanceCount--;
|
|
2609
|
+
}
|
|
2474
2610
|
function shareGlobalState() {
|
|
2611
|
+
// TODO: remove in 4.0; just use peer dependencies instead.
|
|
2612
|
+
deprecated("Using `shareGlobalState` is not recommended, use peer dependencies instead. See https://github.com/mobxjs/mobx/issues/1082 for details.");
|
|
2613
|
+
shareGlobalStateCalled = true;
|
|
2475
2614
|
var global = getGlobal();
|
|
2476
2615
|
var ownState = globalState;
|
|
2477
2616
|
/**
|
|
@@ -2515,13 +2654,14 @@ function addObserver(observable, node) {
|
|
|
2515
2654
|
// invariantObservers(observable);
|
|
2516
2655
|
var l = observable.observers.length;
|
|
2517
2656
|
if (l) {
|
|
2657
|
+
// because object assignment is relatively expensive, let's not store data about index 0.
|
|
2518
2658
|
observable.observersIndexes[node.__mapid] = l;
|
|
2519
2659
|
}
|
|
2520
2660
|
observable.observers[l] = node;
|
|
2521
2661
|
if (observable.lowestObserverState > node.dependenciesState)
|
|
2522
2662
|
observable.lowestObserverState = node.dependenciesState;
|
|
2523
2663
|
// invariantObservers(observable);
|
|
2524
|
-
// invariant(observable._observers.indexOf(node) !== -1, "INTERNAL ERROR
|
|
2664
|
+
// invariant(observable._observers.indexOf(node) !== -1, "INTERNAL ERROR didn't add node");
|
|
2525
2665
|
}
|
|
2526
2666
|
function removeObserver(observable, node) {
|
|
2527
2667
|
// invariant(globalState.inBatch > 0, "INTERNAL ERROR, remove should be called only inside batch");
|
|
@@ -2536,10 +2676,12 @@ function removeObserver(observable, node) {
|
|
|
2536
2676
|
// deleting from _observersIndexes is straight forward, to delete from _observers, let's swap `node` with last element
|
|
2537
2677
|
var list = observable.observers;
|
|
2538
2678
|
var map = observable.observersIndexes;
|
|
2539
|
-
var filler = list.pop(); // get last element, which should fill the place of `node`, so the array
|
|
2679
|
+
var filler = list.pop(); // get last element, which should fill the place of `node`, so the array doesn't have holes
|
|
2540
2680
|
if (filler !== node) {
|
|
2681
|
+
// otherwise node was the last element, which already got removed from array
|
|
2541
2682
|
var index = map[node.__mapid] || 0; // getting index of `node`. this is the only place we actually use map.
|
|
2542
2683
|
if (index) {
|
|
2684
|
+
// map store all indexes but 0, see comment in `addObserver`
|
|
2543
2685
|
map[filler.__mapid] = index;
|
|
2544
2686
|
}
|
|
2545
2687
|
else {
|
|
@@ -2555,7 +2697,7 @@ function removeObserver(observable, node) {
|
|
|
2555
2697
|
function queueForUnobservation(observable) {
|
|
2556
2698
|
if (!observable.isPendingUnobservation) {
|
|
2557
2699
|
// invariant(globalState.inBatch > 0, "INTERNAL ERROR, remove should be called only inside batch");
|
|
2558
|
-
// invariant(observable._observers.length === 0, "INTERNAL ERROR,
|
|
2700
|
+
// invariant(observable._observers.length === 0, "INTERNAL ERROR, should only queue for unobservation unobserved observables");
|
|
2559
2701
|
observable.isPendingUnobservation = true;
|
|
2560
2702
|
globalState.pendingUnobservations.push(observable);
|
|
2561
2703
|
}
|
|
@@ -2636,7 +2778,8 @@ function propagateChangeConfirmed(observable) {
|
|
|
2636
2778
|
var d = observers[i];
|
|
2637
2779
|
if (d.dependenciesState === IDerivationState.POSSIBLY_STALE)
|
|
2638
2780
|
d.dependenciesState = IDerivationState.STALE;
|
|
2639
|
-
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
|
+
)
|
|
2640
2783
|
observable.lowestObserverState = IDerivationState.UP_TO_DATE;
|
|
2641
2784
|
}
|
|
2642
2785
|
// invariantLOS(observable, "confirmed end");
|
|
@@ -2675,8 +2818,8 @@ var IDerivationState;
|
|
|
2675
2818
|
// having this state is second big optimization:
|
|
2676
2819
|
// don't have to recompute on every dependency change, but only when it's needed
|
|
2677
2820
|
IDerivationState[IDerivationState["POSSIBLY_STALE"] = 1] = "POSSIBLY_STALE";
|
|
2678
|
-
// shallow dependency changed
|
|
2679
|
-
// will need to recompute when it's needed
|
|
2821
|
+
// A shallow dependency has changed since last computation and the derivation
|
|
2822
|
+
// will need to recompute when it's needed next.
|
|
2680
2823
|
IDerivationState[IDerivationState["STALE"] = 2] = "STALE";
|
|
2681
2824
|
})(IDerivationState || (IDerivationState = {}));
|
|
2682
2825
|
var CaughtException = (function () {
|
|
@@ -2690,20 +2833,23 @@ function isCaughtException(e) {
|
|
|
2690
2833
|
return e instanceof CaughtException;
|
|
2691
2834
|
}
|
|
2692
2835
|
/**
|
|
2693
|
-
* Finds out
|
|
2694
|
-
* If dependenciesState is 1 it will recalculate dependencies,
|
|
2836
|
+
* Finds out whether any dependency of the derivation has actually changed.
|
|
2837
|
+
* If dependenciesState is 1 then it will recalculate dependencies,
|
|
2695
2838
|
* if any dependency changed it will propagate it by changing dependenciesState to 2.
|
|
2696
2839
|
*
|
|
2697
|
-
* By iterating over dependencies in the same order they were reported and
|
|
2698
|
-
*
|
|
2699
|
-
* That is because we assume that if first x
|
|
2700
|
-
*
|
|
2840
|
+
* By iterating over the dependencies in the same order that they were reported and
|
|
2841
|
+
* stopping on the first change, all the recalculations are only called for ComputedValues
|
|
2842
|
+
* that will be tracked by derivation. That is because we assume that if the first x
|
|
2843
|
+
* dependencies of the derivation doesn't change then the derivation should run the same way
|
|
2844
|
+
* up until accessing x-th dependency.
|
|
2701
2845
|
*/
|
|
2702
2846
|
function shouldCompute(derivation) {
|
|
2703
2847
|
switch (derivation.dependenciesState) {
|
|
2704
|
-
case IDerivationState.UP_TO_DATE:
|
|
2848
|
+
case IDerivationState.UP_TO_DATE:
|
|
2849
|
+
return false;
|
|
2705
2850
|
case IDerivationState.NOT_TRACKING:
|
|
2706
|
-
case IDerivationState.STALE:
|
|
2851
|
+
case IDerivationState.STALE:
|
|
2852
|
+
return true;
|
|
2707
2853
|
case IDerivationState.POSSIBLY_STALE: {
|
|
2708
2854
|
var prevUntracked = untrackedStart(); // no need for those computeds to be reported, they will be picked up in trackDerivedFunction.
|
|
2709
2855
|
var obs = derivation.observing, l = obs.length;
|
|
@@ -2777,12 +2923,11 @@ function trackDerivedFunction(derivation, f, context) {
|
|
|
2777
2923
|
function bindDependencies(derivation) {
|
|
2778
2924
|
// invariant(derivation.dependenciesState !== IDerivationState.NOT_TRACKING, "INTERNAL ERROR bindDependencies expects derivation.dependenciesState !== -1");
|
|
2779
2925
|
var prevObserving = derivation.observing;
|
|
2780
|
-
var observing = derivation.observing = derivation.newObserving;
|
|
2926
|
+
var observing = (derivation.observing = derivation.newObserving);
|
|
2781
2927
|
var lowestNewObservingDerivationState = IDerivationState.UP_TO_DATE;
|
|
2782
|
-
derivation.newObserving = null; // newObserving shouldn't be needed outside tracking
|
|
2783
2928
|
// Go through all new observables and check diffValue: (this list can contain duplicates):
|
|
2784
|
-
// 0: first
|
|
2785
|
-
// 1: extra
|
|
2929
|
+
// 0: first occurrence, change to 1 and keep it
|
|
2930
|
+
// 1: extra occurrence, drop it
|
|
2786
2931
|
var i0 = 0, l = derivation.unboundDepsCount;
|
|
2787
2932
|
for (var i = 0; i < l; i++) {
|
|
2788
2933
|
var dep = observing[i];
|
|
@@ -2799,6 +2944,7 @@ function bindDependencies(derivation) {
|
|
|
2799
2944
|
}
|
|
2800
2945
|
}
|
|
2801
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)
|
|
2802
2948
|
// Go through all old observables and check diffValue: (it is unique after last bindDependencies)
|
|
2803
2949
|
// 0: it's not in new observables, unobserve it
|
|
2804
2950
|
// 1: it keeps being observed, don't want to notify it. change to 0
|
|
@@ -2820,8 +2966,8 @@ function bindDependencies(derivation) {
|
|
|
2820
2966
|
addObserver(dep, derivation);
|
|
2821
2967
|
}
|
|
2822
2968
|
}
|
|
2823
|
-
// Some new observed derivations
|
|
2824
|
-
// so
|
|
2969
|
+
// Some new observed derivations may become stale during this derivation computation
|
|
2970
|
+
// so they have had no chance to propagate staleness (#916)
|
|
2825
2971
|
if (lowestNewObservingDerivationState !== IDerivationState.UP_TO_DATE) {
|
|
2826
2972
|
derivation.dependenciesState = lowestNewObservingDerivationState;
|
|
2827
2973
|
derivation.onBecomeStale();
|
|
@@ -2953,7 +3099,7 @@ var Reaction = (function () {
|
|
|
2953
3099
|
var message = "[mobx] Encountered an uncaught exception that was thrown by a reaction or observer component, in: '" + this;
|
|
2954
3100
|
var messageToUser = getMessage("m037");
|
|
2955
3101
|
console.error(message || messageToUser /* latter will not be true, make sure uglify doesn't remove */, error);
|
|
2956
|
-
/** If debugging
|
|
3102
|
+
/** If debugging brought you here, please, read the above message :-). Tnx! */
|
|
2957
3103
|
if (isSpyEnabled()) {
|
|
2958
3104
|
spyReport({
|
|
2959
3105
|
type: "error",
|
|
@@ -2968,8 +3114,9 @@ var Reaction = (function () {
|
|
|
2968
3114
|
if (!this.isDisposed) {
|
|
2969
3115
|
this.isDisposed = true;
|
|
2970
3116
|
if (!this._isRunning) {
|
|
3117
|
+
// if disposed while running, clean up later. Maybe not optimal, but rare case
|
|
2971
3118
|
startBatch();
|
|
2972
|
-
clearObserving(this);
|
|
3119
|
+
clearObserving(this);
|
|
2973
3120
|
endBatch();
|
|
2974
3121
|
}
|
|
2975
3122
|
}
|
|
@@ -2985,7 +3132,11 @@ var Reaction = (function () {
|
|
|
2985
3132
|
};
|
|
2986
3133
|
Reaction.prototype.whyRun = function () {
|
|
2987
3134
|
var observing = unique(this._isRunning ? this.newObserving : this.observing).map(function (dep) { return dep.name; });
|
|
2988
|
-
return
|
|
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";
|
|
2989
3140
|
};
|
|
2990
3141
|
return Reaction;
|
|
2991
3142
|
}());
|
|
@@ -3024,8 +3175,8 @@ function runReactionsHelper() {
|
|
|
3024
3175
|
// we converge to no remaining reactions after a while.
|
|
3025
3176
|
while (allReactions.length > 0) {
|
|
3026
3177
|
if (++iterations === MAX_REACTION_ITERATIONS) {
|
|
3027
|
-
console.error("Reaction doesn't converge to a stable state after " + MAX_REACTION_ITERATIONS + " iterations."
|
|
3028
|
-
|
|
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]));
|
|
3029
3180
|
allReactions.splice(0); // clear reactions
|
|
3030
3181
|
}
|
|
3031
3182
|
var remainingReactions = allReactions.splice(0);
|
|
@@ -3057,28 +3208,29 @@ function asMap(data) {
|
|
|
3057
3208
|
return observable.map(data || {});
|
|
3058
3209
|
}
|
|
3059
3210
|
|
|
3060
|
-
function createComputedDecorator(
|
|
3211
|
+
function createComputedDecorator(equals) {
|
|
3061
3212
|
return createClassPropertyDecorator(function (target, name, _, __, originalDescriptor) {
|
|
3062
3213
|
invariant(typeof originalDescriptor !== "undefined", getMessage("m009"));
|
|
3063
3214
|
invariant(typeof originalDescriptor.get === "function", getMessage("m010"));
|
|
3064
3215
|
var adm = asObservableObject(target, "");
|
|
3065
|
-
defineComputedProperty(adm, name, originalDescriptor.get, originalDescriptor.set,
|
|
3216
|
+
defineComputedProperty(adm, name, originalDescriptor.get, originalDescriptor.set, equals, false);
|
|
3066
3217
|
}, function (name) {
|
|
3067
3218
|
var observable = this.$mobx.values[name];
|
|
3068
|
-
if (observable === undefined
|
|
3219
|
+
if (observable === undefined // See #505
|
|
3220
|
+
)
|
|
3069
3221
|
return undefined;
|
|
3070
3222
|
return observable.get();
|
|
3071
3223
|
}, function (name, value) {
|
|
3072
3224
|
this.$mobx.values[name].set(value);
|
|
3073
3225
|
}, false, false);
|
|
3074
3226
|
}
|
|
3075
|
-
var computedDecorator = createComputedDecorator(
|
|
3076
|
-
var computedStructDecorator = createComputedDecorator(
|
|
3227
|
+
var computedDecorator = createComputedDecorator(comparer.default);
|
|
3228
|
+
var computedStructDecorator = createComputedDecorator(comparer.structural);
|
|
3077
3229
|
/**
|
|
3078
3230
|
* Decorator for class properties: @computed get value() { return expr; }.
|
|
3079
3231
|
* For legacy purposes also invokable as ES5 observable created: `computed(() => expr)`;
|
|
3080
3232
|
*/
|
|
3081
|
-
var computed =
|
|
3233
|
+
var computed = function computed(arg1, arg2, arg3) {
|
|
3082
3234
|
if (typeof arg2 === "string") {
|
|
3083
3235
|
return computedDecorator.apply(null, arguments);
|
|
3084
3236
|
}
|
|
@@ -3086,9 +3238,13 @@ var computed = (function computed(arg1, arg2, arg3) {
|
|
|
3086
3238
|
invariant(arguments.length < 3, getMessage("m012"));
|
|
3087
3239
|
var opts = typeof arg2 === "object" ? arg2 : {};
|
|
3088
3240
|
opts.setter = typeof arg2 === "function" ? arg2 : opts.setter;
|
|
3089
|
-
|
|
3090
|
-
|
|
3241
|
+
var equals = opts.equals
|
|
3242
|
+
? opts.equals
|
|
3243
|
+
: opts.compareStructural || opts.struct ? comparer.structural : comparer.default;
|
|
3244
|
+
return new ComputedValue(arg1, opts.context, equals, opts.name || arg1.name || "", opts.setter);
|
|
3245
|
+
};
|
|
3091
3246
|
computed.struct = computedStructDecorator;
|
|
3247
|
+
computed.equals = createComputedDecorator;
|
|
3092
3248
|
|
|
3093
3249
|
function getAtom(thing, property) {
|
|
3094
3250
|
if (typeof thing === "object" && thing !== null) {
|
|
@@ -3191,19 +3347,19 @@ function interceptProperty(thing, property, handler) {
|
|
|
3191
3347
|
}
|
|
3192
3348
|
|
|
3193
3349
|
/**
|
|
3194
|
-
|
|
3195
|
-
|
|
3196
|
-
|
|
3197
|
-
|
|
3198
|
-
|
|
3199
|
-
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
|
|
3206
|
-
|
|
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
|
+
*/
|
|
3207
3363
|
function expr(expr, scope) {
|
|
3208
3364
|
if (!isComputingDerivation())
|
|
3209
3365
|
console.warn(getMessage("m013"));
|
|
@@ -3245,7 +3401,7 @@ function toJS(source, detectCycles, __alreadySeen) {
|
|
|
3245
3401
|
}
|
|
3246
3402
|
if (isObservableMap(source)) {
|
|
3247
3403
|
var res_1 = cache({});
|
|
3248
|
-
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)); });
|
|
3249
3405
|
return res_1;
|
|
3250
3406
|
}
|
|
3251
3407
|
if (isObservableValue(source))
|
|
@@ -3265,7 +3421,7 @@ function createTransformer(transformer, onCleanup) {
|
|
|
3265
3421
|
var Transformer = (function (_super) {
|
|
3266
3422
|
__extends(Transformer, _super);
|
|
3267
3423
|
function Transformer(sourceIdentifier, sourceObject) {
|
|
3268
|
-
var _this = _super.call(this, function () { return transformer(sourceObject); }, undefined,
|
|
3424
|
+
var _this = _super.call(this, function () { return transformer(sourceObject); }, undefined, comparer.default, "Transformer-" + transformer.name + "-" + sourceIdentifier, undefined) || this;
|
|
3269
3425
|
_this.sourceIdentifier = sourceIdentifier;
|
|
3270
3426
|
_this.sourceObject = sourceObject;
|
|
3271
3427
|
return _this;
|
|
@@ -3294,7 +3450,7 @@ function createTransformer(transformer, onCleanup) {
|
|
|
3294
3450
|
};
|
|
3295
3451
|
}
|
|
3296
3452
|
function getMemoizationId(object) {
|
|
3297
|
-
if (typeof object ===
|
|
3453
|
+
if (typeof object === "string" || typeof object === "number")
|
|
3298
3454
|
return object;
|
|
3299
3455
|
if (object === null || typeof object !== "object")
|
|
3300
3456
|
throw new Error("[mobx] transform expected some kind of object or primitive value, got: " + object);
|
|
@@ -3405,6 +3561,7 @@ var extras = {
|
|
|
3405
3561
|
onReactionError: onReactionError,
|
|
3406
3562
|
reserveArrayBuffer: reserveArrayBuffer,
|
|
3407
3563
|
resetGlobalState: resetGlobalState,
|
|
3564
|
+
isolateGlobalState: isolateGlobalState,
|
|
3408
3565
|
shareGlobalState: shareGlobalState,
|
|
3409
3566
|
spyReport: spyReport,
|
|
3410
3567
|
spyReportEnd: spyReportEnd,
|
|
@@ -3414,31 +3571,45 @@ var extras = {
|
|
|
3414
3571
|
var everything = {
|
|
3415
3572
|
Reaction: Reaction,
|
|
3416
3573
|
untracked: untracked,
|
|
3417
|
-
Atom: Atom,
|
|
3418
|
-
|
|
3574
|
+
Atom: Atom,
|
|
3575
|
+
BaseAtom: BaseAtom,
|
|
3576
|
+
useStrict: useStrict,
|
|
3577
|
+
isStrictModeEnabled: isStrictModeEnabled,
|
|
3419
3578
|
spy: spy,
|
|
3420
|
-
|
|
3579
|
+
comparer: comparer,
|
|
3580
|
+
asReference: asReference,
|
|
3581
|
+
asFlat: asFlat,
|
|
3582
|
+
asStructure: asStructure,
|
|
3583
|
+
asMap: asMap,
|
|
3421
3584
|
isModifierDescriptor: isModifierDescriptor,
|
|
3422
3585
|
isObservableObject: isObservableObject,
|
|
3423
3586
|
isBoxedObservable: isObservableValue,
|
|
3424
3587
|
isObservableArray: isObservableArray,
|
|
3425
|
-
ObservableMap: ObservableMap,
|
|
3588
|
+
ObservableMap: ObservableMap,
|
|
3589
|
+
isObservableMap: isObservableMap,
|
|
3590
|
+
map: map,
|
|
3426
3591
|
transaction: transaction,
|
|
3427
3592
|
observable: observable,
|
|
3428
3593
|
computed: computed,
|
|
3429
3594
|
isObservable: isObservable,
|
|
3430
3595
|
isComputed: isComputed,
|
|
3431
|
-
extendObservable: extendObservable,
|
|
3596
|
+
extendObservable: extendObservable,
|
|
3597
|
+
extendShallowObservable: extendShallowObservable,
|
|
3432
3598
|
observe: observe,
|
|
3433
3599
|
intercept: intercept,
|
|
3434
|
-
autorun: autorun,
|
|
3435
|
-
|
|
3600
|
+
autorun: autorun,
|
|
3601
|
+
autorunAsync: autorunAsync,
|
|
3602
|
+
when: when,
|
|
3603
|
+
reaction: reaction,
|
|
3604
|
+
action: action,
|
|
3605
|
+
isAction: isAction,
|
|
3606
|
+
runInAction: runInAction,
|
|
3436
3607
|
expr: expr,
|
|
3437
3608
|
toJS: toJS,
|
|
3438
3609
|
createTransformer: createTransformer,
|
|
3439
3610
|
whyRun: whyRun,
|
|
3440
3611
|
isArrayLike: isArrayLike,
|
|
3441
|
-
extras: extras
|
|
3612
|
+
extras: extras
|
|
3442
3613
|
};
|
|
3443
3614
|
var warnedAboutDefaultExport = false;
|
|
3444
3615
|
var _loop_1 = function (p) {
|
|
@@ -3447,9 +3618,9 @@ var _loop_1 = function (p) {
|
|
|
3447
3618
|
get: function () {
|
|
3448
3619
|
if (!warnedAboutDefaultExport) {
|
|
3449
3620
|
warnedAboutDefaultExport = true;
|
|
3450
|
-
console.warn(
|
|
3451
|
-
|
|
3452
|
-
|
|
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");
|
|
3453
3624
|
}
|
|
3454
3625
|
return val;
|
|
3455
3626
|
}
|
|
@@ -3462,4 +3633,4 @@ if (typeof __MOBX_DEVTOOLS_GLOBAL_HOOK__ === "object") {
|
|
|
3462
3633
|
__MOBX_DEVTOOLS_GLOBAL_HOOK__.injectMobx({ spy: spy, extras: extras });
|
|
3463
3634
|
}
|
|
3464
3635
|
|
|
3465
|
-
export { extras, Reaction, untracked, IDerivationState, Atom, BaseAtom, useStrict, isStrictModeEnabled, spy, asReference, asFlat, asStructure, asMap, isModifierDescriptor, isObservableObject, isObservableValue as isBoxedObservable, isObservableArray, ObservableMap, isObservableMap, map, transaction, observable, IObservableFactories, computed, isObservable, isComputed, extendObservable, extendShallowObservable, observe, intercept, autorun, autorunAsync, when, reaction, action, isAction, runInAction, expr, toJS, createTransformer, whyRun, isArrayLike };export default everything;
|
|
3636
|
+
export { extras, Reaction, untracked, IDerivationState, Atom, BaseAtom, useStrict, isStrictModeEnabled, spy, comparer, asReference, asFlat, asStructure, asMap, isModifierDescriptor, isObservableObject, isObservableValue as isBoxedObservable, isObservableArray, ObservableMap, isObservableMap, map, transaction, observable, IObservableFactories, computed, isObservable, isComputed, extendObservable, extendShallowObservable, observe, intercept, autorun, autorunAsync, when, reaction, action, isAction, runInAction, expr, toJS, createTransformer, whyRun, isArrayLike };export default everything;
|