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.umd.js
CHANGED
|
@@ -113,7 +113,7 @@ var Atom = (function (_super) {
|
|
|
113
113
|
var isAtom = createInstanceofPredicate("Atom", BaseAtom);
|
|
114
114
|
|
|
115
115
|
function hasInterceptors(interceptable) {
|
|
116
|
-
return
|
|
116
|
+
return interceptable.interceptors && interceptable.interceptors.length > 0;
|
|
117
117
|
}
|
|
118
118
|
function registerInterceptor(interceptable, handler) {
|
|
119
119
|
var interceptors = interceptable.interceptors || (interceptable.interceptors = []);
|
|
@@ -225,7 +225,11 @@ var MAX_SPLICE_SIZE = 10000; // See e.g. https://github.com/mobxjs/mobx/issues/8
|
|
|
225
225
|
var safariPrototypeSetterInheritanceBug = (function () {
|
|
226
226
|
var v = false;
|
|
227
227
|
var p = {};
|
|
228
|
-
Object.defineProperty(p, "0", {
|
|
228
|
+
Object.defineProperty(p, "0", {
|
|
229
|
+
set: function () {
|
|
230
|
+
v = true;
|
|
231
|
+
}
|
|
232
|
+
});
|
|
229
233
|
Object.create(p)["0"] = 1;
|
|
230
234
|
return v === false;
|
|
231
235
|
})();
|
|
@@ -253,6 +257,32 @@ function inherit(ctor, proto) {
|
|
|
253
257
|
}
|
|
254
258
|
}
|
|
255
259
|
inherit(StubArray, Array.prototype);
|
|
260
|
+
// Weex freeze Array.prototype
|
|
261
|
+
// Make them writeable and configurable in prototype chain
|
|
262
|
+
// https://github.com/alibaba/weex/pull/1529
|
|
263
|
+
if (Object.isFrozen(Array)) {
|
|
264
|
+
|
|
265
|
+
[
|
|
266
|
+
"constructor",
|
|
267
|
+
"push",
|
|
268
|
+
"shift",
|
|
269
|
+
"concat",
|
|
270
|
+
"pop",
|
|
271
|
+
"unshift",
|
|
272
|
+
"replace",
|
|
273
|
+
"find",
|
|
274
|
+
"findIndex",
|
|
275
|
+
"splice",
|
|
276
|
+
"reverse",
|
|
277
|
+
"sort"
|
|
278
|
+
].forEach(function (key) {
|
|
279
|
+
Object.defineProperty(StubArray.prototype, key, {
|
|
280
|
+
configurable: true,
|
|
281
|
+
writable: true,
|
|
282
|
+
value: Array.prototype[key]
|
|
283
|
+
});
|
|
284
|
+
});
|
|
285
|
+
}
|
|
256
286
|
var ObservableArrayAdministration = (function () {
|
|
257
287
|
function ObservableArrayAdministration(name, enhancer, array, owned) {
|
|
258
288
|
this.array = array;
|
|
@@ -261,7 +291,7 @@ var ObservableArrayAdministration = (function () {
|
|
|
261
291
|
this.lastKnownLength = 0;
|
|
262
292
|
this.interceptors = null;
|
|
263
293
|
this.changeListeners = null;
|
|
264
|
-
this.atom = new BaseAtom(name ||
|
|
294
|
+
this.atom = new BaseAtom(name || "ObservableArray@" + getNextId());
|
|
265
295
|
this.enhancer = function (newV, oldV) { return enhancer(newV, oldV, name + "[..]"); };
|
|
266
296
|
}
|
|
267
297
|
ObservableArrayAdministration.prototype.dehanceValue = function (value) {
|
|
@@ -364,7 +394,9 @@ var ObservableArrayAdministration = (function () {
|
|
|
364
394
|
}
|
|
365
395
|
else {
|
|
366
396
|
var res = this.values.slice(index, index + deleteCount);
|
|
367
|
-
this.values = this.values
|
|
397
|
+
this.values = this.values
|
|
398
|
+
.slice(0, index)
|
|
399
|
+
.concat(newItems, this.values.slice(index + deleteCount));
|
|
368
400
|
return res;
|
|
369
401
|
}
|
|
370
402
|
var _a;
|
|
@@ -372,11 +404,15 @@ var ObservableArrayAdministration = (function () {
|
|
|
372
404
|
ObservableArrayAdministration.prototype.notifyArrayChildUpdate = function (index, newValue, oldValue) {
|
|
373
405
|
var notifySpy = !this.owned && isSpyEnabled();
|
|
374
406
|
var notify = hasListeners(this);
|
|
375
|
-
var change = notify || notifySpy
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
407
|
+
var change = notify || notifySpy
|
|
408
|
+
? {
|
|
409
|
+
object: this.array,
|
|
410
|
+
type: "update",
|
|
411
|
+
index: index,
|
|
412
|
+
newValue: newValue,
|
|
413
|
+
oldValue: oldValue
|
|
414
|
+
}
|
|
415
|
+
: null;
|
|
380
416
|
if (notifySpy)
|
|
381
417
|
spyReportStart(change);
|
|
382
418
|
this.atom.reportChanged();
|
|
@@ -388,13 +424,17 @@ var ObservableArrayAdministration = (function () {
|
|
|
388
424
|
ObservableArrayAdministration.prototype.notifyArraySplice = function (index, added, removed) {
|
|
389
425
|
var notifySpy = !this.owned && isSpyEnabled();
|
|
390
426
|
var notify = hasListeners(this);
|
|
391
|
-
var change = notify || notifySpy
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
427
|
+
var change = notify || notifySpy
|
|
428
|
+
? {
|
|
429
|
+
object: this.array,
|
|
430
|
+
type: "splice",
|
|
431
|
+
index: index,
|
|
432
|
+
removed: removed,
|
|
433
|
+
added: added,
|
|
434
|
+
removedCount: removed.length,
|
|
435
|
+
addedCount: added.length
|
|
436
|
+
}
|
|
437
|
+
: null;
|
|
398
438
|
if (notifySpy)
|
|
399
439
|
spyReportStart(change);
|
|
400
440
|
this.atom.reportChanged();
|
|
@@ -440,7 +480,7 @@ var ObservableArray = (function (_super) {
|
|
|
440
480
|
arrays[_i] = arguments[_i];
|
|
441
481
|
}
|
|
442
482
|
this.$mobx.atom.reportObserved();
|
|
443
|
-
return Array.prototype.concat.apply(this.peek(), arrays.map(function (a) { return isObservableArray(a) ? a.peek() : a; }));
|
|
483
|
+
return Array.prototype.concat.apply(this.peek(), arrays.map(function (a) { return (isObservableArray(a) ? a.peek() : a); }));
|
|
444
484
|
};
|
|
445
485
|
ObservableArray.prototype.replace = function (newItems) {
|
|
446
486
|
return this.$mobx.spliceWithArray(0, this.$mobx.values.length, newItems);
|
|
@@ -476,11 +516,11 @@ var ObservableArray = (function (_super) {
|
|
|
476
516
|
return -1;
|
|
477
517
|
};
|
|
478
518
|
/*
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
519
|
+
* functions that do alter the internal structure of the array, (based on lib.es6.d.ts)
|
|
520
|
+
* since these functions alter the inner structure of the array, the have side effects.
|
|
521
|
+
* Because the have side effects, they should not be used in computed function,
|
|
522
|
+
* and for that reason the do not call dependencyState.notifyObserved
|
|
523
|
+
*/
|
|
484
524
|
ObservableArray.prototype.splice = function (index, deleteCount) {
|
|
485
525
|
var newItems = [];
|
|
486
526
|
for (var _i = 2; _i < arguments.length; _i++) {
|
|
@@ -562,10 +602,15 @@ var ObservableArray = (function (_super) {
|
|
|
562
602
|
var oldItems = this.$mobx.values;
|
|
563
603
|
var newItems;
|
|
564
604
|
if (fromIndex < toIndex) {
|
|
565
|
-
newItems = oldItems.slice(0, fromIndex).concat(oldItems.slice(fromIndex + 1, toIndex + 1), [
|
|
605
|
+
newItems = oldItems.slice(0, fromIndex).concat(oldItems.slice(fromIndex + 1, toIndex + 1), [
|
|
606
|
+
oldItems[fromIndex]
|
|
607
|
+
], oldItems.slice(toIndex + 1));
|
|
566
608
|
}
|
|
567
609
|
else {
|
|
568
|
-
|
|
610
|
+
// toIndex < fromIndex
|
|
611
|
+
newItems = oldItems.slice(0, toIndex).concat([
|
|
612
|
+
oldItems[fromIndex]
|
|
613
|
+
], oldItems.slice(toIndex, fromIndex), oldItems.slice(fromIndex + 1));
|
|
569
614
|
}
|
|
570
615
|
this.replace(newItems);
|
|
571
616
|
};
|
|
@@ -577,7 +622,9 @@ var ObservableArray = (function (_super) {
|
|
|
577
622
|
impl.atom.reportObserved();
|
|
578
623
|
return impl.dehanceValue(impl.values[index]);
|
|
579
624
|
}
|
|
580
|
-
console.warn("[mobx.array] Attempt to read an array index (" + index + ") that is out of bounds (" + impl
|
|
625
|
+
console.warn("[mobx.array] Attempt to read an array index (" + index + ") that is out of bounds (" + impl
|
|
626
|
+
.values
|
|
627
|
+
.length + "). Please check length first. Out of bound indices will not be tracked by MobX");
|
|
581
628
|
}
|
|
582
629
|
return undefined;
|
|
583
630
|
};
|
|
@@ -593,7 +640,8 @@ var ObservableArray = (function (_super) {
|
|
|
593
640
|
var change = interceptChange(adm, {
|
|
594
641
|
type: "update",
|
|
595
642
|
object: this,
|
|
596
|
-
index: index,
|
|
643
|
+
index: index,
|
|
644
|
+
newValue: newValue
|
|
597
645
|
});
|
|
598
646
|
if (!change)
|
|
599
647
|
return;
|
|
@@ -630,9 +678,6 @@ Object.defineProperty(ObservableArray.prototype, "length", {
|
|
|
630
678
|
this.$mobx.setArrayLength(newLength);
|
|
631
679
|
}
|
|
632
680
|
});
|
|
633
|
-
/**
|
|
634
|
-
* Wrap function from prototype
|
|
635
|
-
*/
|
|
636
681
|
[
|
|
637
682
|
"every",
|
|
638
683
|
"filter",
|
|
@@ -744,7 +789,8 @@ var ObservableValue = (function (_super) {
|
|
|
744
789
|
spyReportStart({
|
|
745
790
|
type: "update",
|
|
746
791
|
object: this,
|
|
747
|
-
newValue: newValue,
|
|
792
|
+
newValue: newValue,
|
|
793
|
+
oldValue: oldValue
|
|
748
794
|
});
|
|
749
795
|
}
|
|
750
796
|
this.setNewValue(newValue);
|
|
@@ -755,16 +801,18 @@ var ObservableValue = (function (_super) {
|
|
|
755
801
|
ObservableValue.prototype.prepareNewValue = function (newValue) {
|
|
756
802
|
checkIfStateModificationsAreAllowed(this);
|
|
757
803
|
if (hasInterceptors(this)) {
|
|
758
|
-
var change = interceptChange(this, {
|
|
804
|
+
var change = interceptChange(this, {
|
|
805
|
+
object: this,
|
|
806
|
+
type: "update",
|
|
807
|
+
newValue: newValue
|
|
808
|
+
});
|
|
759
809
|
if (!change)
|
|
760
810
|
return UNCHANGED;
|
|
761
811
|
newValue = change.newValue;
|
|
762
812
|
}
|
|
763
813
|
// apply modifier
|
|
764
814
|
newValue = this.enhancer(newValue, this.value, this.name);
|
|
765
|
-
return this.value !== newValue
|
|
766
|
-
? newValue
|
|
767
|
-
: UNCHANGED;
|
|
815
|
+
return this.value !== newValue ? newValue : UNCHANGED;
|
|
768
816
|
};
|
|
769
817
|
ObservableValue.prototype.setNewValue = function (newValue) {
|
|
770
818
|
var oldValue = this.value;
|
|
@@ -774,7 +822,8 @@ var ObservableValue = (function (_super) {
|
|
|
774
822
|
notifyListeners(this, {
|
|
775
823
|
type: "update",
|
|
776
824
|
object: this,
|
|
777
|
-
newValue: newValue,
|
|
825
|
+
newValue: newValue,
|
|
826
|
+
oldValue: oldValue
|
|
778
827
|
});
|
|
779
828
|
}
|
|
780
829
|
};
|
|
@@ -810,44 +859,43 @@ ObservableValue.prototype[primitiveSymbol()] = ObservableValue.prototype.valueOf
|
|
|
810
859
|
var isObservableValue = createInstanceofPredicate("ObservableValue", ObservableValue);
|
|
811
860
|
|
|
812
861
|
var messages = {
|
|
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
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
"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"
|
|
862
|
+
m001: "It is not allowed to assign new values to @action fields",
|
|
863
|
+
m002: "`runInAction` expects a function",
|
|
864
|
+
m003: "`runInAction` expects a function without arguments",
|
|
865
|
+
m004: "autorun expects a function",
|
|
866
|
+
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.",
|
|
867
|
+
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.",
|
|
868
|
+
m007: "reaction only accepts 2 or 3 arguments. If migrating from MobX 2, please provide an options object",
|
|
869
|
+
m008: "wrapping reaction expression in `asReference` is no longer supported, use options object instead",
|
|
870
|
+
m009: "@computed can only be used on getter functions, like: '@computed get myProps() { return ...; }'. It looks like it was used on a property.",
|
|
871
|
+
m010: "@computed can only be used on getter functions, like: '@computed get myProps() { return ...; }'",
|
|
872
|
+
m011: "First argument to `computed` should be an expression. If using computed as decorator, don't pass it arguments",
|
|
873
|
+
m012: "computed takes one or two arguments if used as function",
|
|
874
|
+
m013: "[mobx.expr] 'expr' should only be used inside other reactive functions.",
|
|
875
|
+
m014: "extendObservable expected 2 or more arguments",
|
|
876
|
+
m015: "extendObservable expects an object as first argument",
|
|
877
|
+
m016: "extendObservable should not be used on maps, use map.merge instead",
|
|
878
|
+
m017: "all arguments of extendObservable should be objects",
|
|
879
|
+
m018: "extending an object with another observable (object) is not supported. Please construct an explicit propertymap, using `toJS` if need. See issue #540",
|
|
880
|
+
m019: "[mobx.isObservable] isObservable(object, propertyName) is not supported for arrays and maps. Use map.has or array.length instead.",
|
|
881
|
+
m020: "modifiers can only be used for individual object properties",
|
|
882
|
+
m021: "observable expects zero or one arguments",
|
|
883
|
+
m022: "@observable can not be used on getters, use @computed instead",
|
|
884
|
+
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.",
|
|
885
|
+
m025: "whyRun can only be used on reactions and computed values",
|
|
886
|
+
m026: "`action` can only be invoked on functions",
|
|
887
|
+
m028: "It is not allowed to set `useStrict` when a derivation is running",
|
|
888
|
+
m029: "INTERNAL ERROR only onBecomeUnobserved shouldn't be called twice in a row",
|
|
889
|
+
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: ",
|
|
890
|
+
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: ",
|
|
891
|
+
m031: "Computed values are not allowed to cause side effects by changing observables that are already being observed. Tried to modify: ",
|
|
892
|
+
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).",
|
|
893
|
+
m033: "`observe` doesn't support the fire immediately property for observable maps.",
|
|
894
|
+
m034: "`mobx.map` is deprecated, use `new ObservableMap` or `mobx.observable.map` instead",
|
|
895
|
+
m035: "Cannot make the designated object observable; it is not extensible",
|
|
896
|
+
m036: "It is not possible to get index atoms from arrays",
|
|
897
|
+
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",
|
|
898
|
+
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"
|
|
851
899
|
};
|
|
852
900
|
function getMessage(id) {
|
|
853
901
|
return messages[id];
|
|
@@ -986,7 +1034,7 @@ function createClassPropertyDecorator(
|
|
|
986
1034
|
}
|
|
987
1035
|
}
|
|
988
1036
|
};
|
|
989
|
-
if (arguments.length < 3 || arguments.length === 5 && argLen < 3) {
|
|
1037
|
+
if (arguments.length < 3 || (arguments.length === 5 && argLen < 3)) {
|
|
990
1038
|
// Typescript target is ES3, so it won't define property for us
|
|
991
1039
|
// or using Reflect.decorate polyfill, which will return no descriptor
|
|
992
1040
|
// (see https://github.com/mobxjs/mobx/issues/333)
|
|
@@ -1002,10 +1050,11 @@ function createClassPropertyDecorator(
|
|
|
1002
1050
|
}
|
|
1003
1051
|
var value_1 = descriptor.value, initializer_1 = descriptor.initializer;
|
|
1004
1052
|
target.__mobxLazyInitializers.push(function (instance) {
|
|
1005
|
-
onInitialize(instance, key,
|
|
1053
|
+
onInitialize(instance, key, initializer_1 ? initializer_1.call(instance) : value_1, customArgs, descriptor);
|
|
1006
1054
|
});
|
|
1007
1055
|
return {
|
|
1008
|
-
enumerable: enumerable,
|
|
1056
|
+
enumerable: enumerable,
|
|
1057
|
+
configurable: true,
|
|
1009
1058
|
get: function () {
|
|
1010
1059
|
if (this.__mobxDidRunLazyInitializers !== true)
|
|
1011
1060
|
runLazyInitializers(this);
|
|
@@ -1028,7 +1077,9 @@ function createClassPropertyDecorator(
|
|
|
1028
1077
|
/** Indirect invocation: @decorator(args) bla */
|
|
1029
1078
|
var outerArgs = arguments;
|
|
1030
1079
|
var argLen = arguments.length;
|
|
1031
|
-
return function (target, key, descriptor) {
|
|
1080
|
+
return function (target, key, descriptor) {
|
|
1081
|
+
return classPropertyDecorator(target, key, descriptor, outerArgs, argLen);
|
|
1082
|
+
};
|
|
1032
1083
|
};
|
|
1033
1084
|
}
|
|
1034
1085
|
return classPropertyDecorator;
|
|
@@ -1044,7 +1095,8 @@ function runLazyInitializers(instance) {
|
|
|
1044
1095
|
return;
|
|
1045
1096
|
if (instance.__mobxLazyInitializers) {
|
|
1046
1097
|
addHiddenProp(instance, "__mobxDidRunLazyInitializers", true);
|
|
1047
|
-
instance.__mobxDidRunLazyInitializers &&
|
|
1098
|
+
instance.__mobxDidRunLazyInitializers &&
|
|
1099
|
+
instance.__mobxLazyInitializers.forEach(function (initializer) { return initializer(instance); });
|
|
1048
1100
|
}
|
|
1049
1101
|
}
|
|
1050
1102
|
function quacksLikeADecorator(args) {
|
|
@@ -1052,7 +1104,7 @@ function quacksLikeADecorator(args) {
|
|
|
1052
1104
|
}
|
|
1053
1105
|
|
|
1054
1106
|
var actionFieldDecorator = createClassPropertyDecorator(function (target, key, value, args, originalDescriptor) {
|
|
1055
|
-
var actionName =
|
|
1107
|
+
var actionName = args && args.length === 1 ? args[0] : value.name || key || "<unnamed action>";
|
|
1056
1108
|
var wrappedAction = action(actionName, value);
|
|
1057
1109
|
addHiddenProp(target, key, wrappedAction);
|
|
1058
1110
|
}, function (key) {
|
|
@@ -1094,6 +1146,9 @@ function namedActionDecorator(name) {
|
|
|
1094
1146
|
descriptor.configurable = true;
|
|
1095
1147
|
return descriptor;
|
|
1096
1148
|
}
|
|
1149
|
+
if (descriptor !== undefined && descriptor.get !== undefined) {
|
|
1150
|
+
throw new Error("[mobx] action is not expected to be used with getters");
|
|
1151
|
+
}
|
|
1097
1152
|
// bound instance methods
|
|
1098
1153
|
return actionFieldDecorator(name).apply(this, arguments);
|
|
1099
1154
|
};
|
|
@@ -1118,6 +1173,27 @@ function defineBoundAction(target, propertyName, fn) {
|
|
|
1118
1173
|
addHiddenProp(target, propertyName, res);
|
|
1119
1174
|
}
|
|
1120
1175
|
|
|
1176
|
+
function identityComparer(a, b) {
|
|
1177
|
+
return a === b;
|
|
1178
|
+
}
|
|
1179
|
+
function structuralComparer(a, b) {
|
|
1180
|
+
if (typeof a === "number" && typeof b === "number" && isNaN(a) && isNaN(b)) {
|
|
1181
|
+
return true;
|
|
1182
|
+
}
|
|
1183
|
+
return deepEqual(a, b);
|
|
1184
|
+
}
|
|
1185
|
+
function defaultComparer(a, b) {
|
|
1186
|
+
if (typeof a === "number" && typeof b === "number" && isNaN(a) && isNaN(b)) {
|
|
1187
|
+
return true;
|
|
1188
|
+
}
|
|
1189
|
+
return identityComparer(a, b);
|
|
1190
|
+
}
|
|
1191
|
+
var comparer = {
|
|
1192
|
+
identity: identityComparer,
|
|
1193
|
+
structural: structuralComparer,
|
|
1194
|
+
default: defaultComparer
|
|
1195
|
+
};
|
|
1196
|
+
|
|
1121
1197
|
function autorun(arg1, arg2, arg3) {
|
|
1122
1198
|
var name, view, scope;
|
|
1123
1199
|
if (typeof arg1 === "string") {
|
|
@@ -1126,7 +1202,7 @@ function autorun(arg1, arg2, arg3) {
|
|
|
1126
1202
|
scope = arg3;
|
|
1127
1203
|
}
|
|
1128
1204
|
else {
|
|
1129
|
-
name = arg1.name ||
|
|
1205
|
+
name = arg1.name || "Autorun@" + getNextId();
|
|
1130
1206
|
view = arg1;
|
|
1131
1207
|
scope = arg2;
|
|
1132
1208
|
}
|
|
@@ -1152,7 +1228,7 @@ function when(arg1, arg2, arg3, arg4) {
|
|
|
1152
1228
|
scope = arg4;
|
|
1153
1229
|
}
|
|
1154
1230
|
else {
|
|
1155
|
-
name =
|
|
1231
|
+
name = "When@" + getNextId();
|
|
1156
1232
|
predicate = arg1;
|
|
1157
1233
|
effect = arg2;
|
|
1158
1234
|
scope = arg3;
|
|
@@ -1176,7 +1252,7 @@ function autorunAsync(arg1, arg2, arg3, arg4) {
|
|
|
1176
1252
|
scope = arg4;
|
|
1177
1253
|
}
|
|
1178
1254
|
else {
|
|
1179
|
-
name = arg1.name ||
|
|
1255
|
+
name = arg1.name || "AutorunAsync@" + getNextId();
|
|
1180
1256
|
func = arg1;
|
|
1181
1257
|
delay = arg2;
|
|
1182
1258
|
scope = arg3;
|
|
@@ -1197,7 +1273,9 @@ function autorunAsync(arg1, arg2, arg3, arg4) {
|
|
|
1197
1273
|
}, delay);
|
|
1198
1274
|
}
|
|
1199
1275
|
});
|
|
1200
|
-
function reactionRunner() {
|
|
1276
|
+
function reactionRunner() {
|
|
1277
|
+
func(r);
|
|
1278
|
+
}
|
|
1201
1279
|
r.schedule();
|
|
1202
1280
|
return r.getDisposer();
|
|
1203
1281
|
}
|
|
@@ -1215,17 +1293,22 @@ function reaction(expression, effect, arg3) {
|
|
|
1215
1293
|
else {
|
|
1216
1294
|
opts = {};
|
|
1217
1295
|
}
|
|
1218
|
-
opts.name =
|
|
1296
|
+
opts.name =
|
|
1297
|
+
opts.name || expression.name || effect.name || "Reaction@" + getNextId();
|
|
1219
1298
|
opts.fireImmediately = arg3 === true || opts.fireImmediately === true;
|
|
1220
1299
|
opts.delay = opts.delay || 0;
|
|
1221
1300
|
opts.compareStructural = opts.compareStructural || opts.struct || false;
|
|
1301
|
+
// TODO: creates ugly spy events, use `effect = (r) => runInAction(opts.name, () => effect(r))` instead
|
|
1222
1302
|
effect = action(opts.name, opts.context ? effect.bind(opts.context) : effect);
|
|
1223
1303
|
if (opts.context) {
|
|
1224
1304
|
expression = expression.bind(opts.context);
|
|
1225
1305
|
}
|
|
1226
1306
|
var firstTime = true;
|
|
1227
1307
|
var isScheduled = false;
|
|
1228
|
-
var
|
|
1308
|
+
var value;
|
|
1309
|
+
var equals = opts.equals
|
|
1310
|
+
? opts.equals
|
|
1311
|
+
: opts.compareStructural || opts.struct ? comparer.structural : comparer.default;
|
|
1229
1312
|
var r = new Reaction(opts.name, function () {
|
|
1230
1313
|
if (firstTime || opts.delay < 1) {
|
|
1231
1314
|
reactionRunner();
|
|
@@ -1243,14 +1326,14 @@ function reaction(expression, effect, arg3) {
|
|
|
1243
1326
|
return;
|
|
1244
1327
|
var changed = false;
|
|
1245
1328
|
r.track(function () {
|
|
1246
|
-
var
|
|
1247
|
-
changed =
|
|
1248
|
-
|
|
1329
|
+
var nextValue = expression(r);
|
|
1330
|
+
changed = firstTime || !equals(value, nextValue);
|
|
1331
|
+
value = nextValue;
|
|
1249
1332
|
});
|
|
1250
1333
|
if (firstTime && opts.fireImmediately)
|
|
1251
|
-
effect(
|
|
1334
|
+
effect(value, r);
|
|
1252
1335
|
if (!firstTime && changed === true)
|
|
1253
|
-
effect(
|
|
1336
|
+
effect(value, r);
|
|
1254
1337
|
if (firstTime)
|
|
1255
1338
|
firstTime = false;
|
|
1256
1339
|
}
|
|
@@ -1261,7 +1344,9 @@ function reaction(expression, effect, arg3) {
|
|
|
1261
1344
|
/**
|
|
1262
1345
|
* A node in the state dependency root that observes other nodes, and can be observed itself.
|
|
1263
1346
|
*
|
|
1264
|
-
* ComputedValue will remember result of the computation for duration of
|
|
1347
|
+
* ComputedValue will remember the result of the computation for the duration of the batch, or
|
|
1348
|
+
* while being observed.
|
|
1349
|
+
*
|
|
1265
1350
|
* During this time it will recompute only when one of its direct dependencies changed,
|
|
1266
1351
|
* but only when it is being accessed with `ComputedValue.get()`.
|
|
1267
1352
|
*
|
|
@@ -1281,15 +1366,17 @@ var ComputedValue = (function () {
|
|
|
1281
1366
|
*
|
|
1282
1367
|
* The `name` property is for debug purposes only.
|
|
1283
1368
|
*
|
|
1284
|
-
* The `
|
|
1285
|
-
*
|
|
1286
|
-
*
|
|
1369
|
+
* The `equals` property specifies the comparer function to use to determine if a newly produced
|
|
1370
|
+
* value differs from the previous value. Two comparers are provided in the library; `defaultComparer`
|
|
1371
|
+
* compares based on identity comparison (===), and `structualComparer` deeply compares the structure.
|
|
1372
|
+
* Structural comparison can be convenient if you always produce an new aggregated object and
|
|
1373
|
+
* don't want to notify observers if it is structurally the same.
|
|
1287
1374
|
* This is useful for working with vectors, mouse coordinates etc.
|
|
1288
1375
|
*/
|
|
1289
|
-
function ComputedValue(derivation, scope,
|
|
1376
|
+
function ComputedValue(derivation, scope, equals, name, setter) {
|
|
1290
1377
|
this.derivation = derivation;
|
|
1291
1378
|
this.scope = scope;
|
|
1292
|
-
this.
|
|
1379
|
+
this.equals = equals;
|
|
1293
1380
|
this.dependenciesState = exports.IDerivationState.NOT_TRACKING;
|
|
1294
1381
|
this.observing = []; // nodes we are looking at. Our value depends on these nodes
|
|
1295
1382
|
this.newObserving = null; // during tracking it's an array with new observed observers
|
|
@@ -1302,7 +1389,7 @@ var ComputedValue = (function () {
|
|
|
1302
1389
|
this.lowestObserverState = exports.IDerivationState.UP_TO_DATE;
|
|
1303
1390
|
this.unboundDepsCount = 0;
|
|
1304
1391
|
this.__mapid = "#" + getNextId();
|
|
1305
|
-
this.value =
|
|
1392
|
+
this.value = new CaughtException(null);
|
|
1306
1393
|
this.isComputing = false; // to check for cycles
|
|
1307
1394
|
this.isRunningSetter = false;
|
|
1308
1395
|
this.name = name || "ComputedValue@" + getNextId();
|
|
@@ -1323,9 +1410,9 @@ var ComputedValue = (function () {
|
|
|
1323
1410
|
ComputedValue.prototype.get = function () {
|
|
1324
1411
|
invariant(!this.isComputing, "Cycle detected in computation " + this.name, this.derivation);
|
|
1325
1412
|
if (globalState.inBatch === 0) {
|
|
1326
|
-
//
|
|
1327
|
-
//
|
|
1328
|
-
//
|
|
1413
|
+
// This is an minor optimization which could be omitted to simplify the code
|
|
1414
|
+
// The computedValue is accessed outside of any mobx stuff. Batch observing should be enough and don't need
|
|
1415
|
+
// tracking as it will never be called again inside this batch.
|
|
1329
1416
|
startBatch();
|
|
1330
1417
|
if (shouldCompute(this))
|
|
1331
1418
|
this.value = this.computeValue(false);
|
|
@@ -1350,7 +1437,8 @@ var ComputedValue = (function () {
|
|
|
1350
1437
|
};
|
|
1351
1438
|
ComputedValue.prototype.set = function (value) {
|
|
1352
1439
|
if (this.setter) {
|
|
1353
|
-
invariant(!this.isRunningSetter, "The setter of computed value '" + this
|
|
1440
|
+
invariant(!this.isRunningSetter, "The setter of computed value '" + this
|
|
1441
|
+
.name + "' is trying to update itself. Did you intend to update an _observable_ value, instead of the computed property?");
|
|
1354
1442
|
this.isRunningSetter = true;
|
|
1355
1443
|
try {
|
|
1356
1444
|
this.setter.call(this.scope, value);
|
|
@@ -1360,7 +1448,8 @@ var ComputedValue = (function () {
|
|
|
1360
1448
|
}
|
|
1361
1449
|
}
|
|
1362
1450
|
else
|
|
1363
|
-
invariant(false, "[ComputedValue '" + this
|
|
1451
|
+
invariant(false, "[ComputedValue '" + this
|
|
1452
|
+
.name + "'] It is not possible to assign a new value to a computed value.");
|
|
1364
1453
|
};
|
|
1365
1454
|
ComputedValue.prototype.trackAndCompute = function () {
|
|
1366
1455
|
if (isSpyEnabled()) {
|
|
@@ -1371,8 +1460,10 @@ var ComputedValue = (function () {
|
|
|
1371
1460
|
});
|
|
1372
1461
|
}
|
|
1373
1462
|
var oldValue = this.value;
|
|
1374
|
-
var newValue = this.value = this.computeValue(true);
|
|
1375
|
-
return isCaughtException(
|
|
1463
|
+
var newValue = (this.value = this.computeValue(true));
|
|
1464
|
+
return (isCaughtException(oldValue) ||
|
|
1465
|
+
isCaughtException(newValue) ||
|
|
1466
|
+
!this.equals(oldValue, newValue));
|
|
1376
1467
|
};
|
|
1377
1468
|
ComputedValue.prototype.computeValue = function (track) {
|
|
1378
1469
|
this.isComputing = true;
|
|
@@ -1393,7 +1484,6 @@ var ComputedValue = (function () {
|
|
|
1393
1484
|
this.isComputing = false;
|
|
1394
1485
|
return res;
|
|
1395
1486
|
};
|
|
1396
|
-
|
|
1397
1487
|
ComputedValue.prototype.observe = function (listener, fireImmediately) {
|
|
1398
1488
|
var _this = this;
|
|
1399
1489
|
var firstTime = true;
|
|
@@ -1423,14 +1513,20 @@ var ComputedValue = (function () {
|
|
|
1423
1513
|
ComputedValue.prototype.valueOf = function () {
|
|
1424
1514
|
return toPrimitive(this.get());
|
|
1425
1515
|
};
|
|
1426
|
-
|
|
1427
1516
|
ComputedValue.prototype.whyRun = function () {
|
|
1428
1517
|
var isTracking = Boolean(globalState.trackingDerivation);
|
|
1429
1518
|
var observing = unique(this.isComputing ? this.newObserving : this.observing).map(function (dep) { return dep.name; });
|
|
1430
1519
|
var observers = unique(getObservers(this).map(function (dep) { return dep.name; }));
|
|
1431
|
-
return ("\nWhyRun? computation '" + this.name + "':\n * Running because: " + (isTracking
|
|
1432
|
-
|
|
1433
|
-
|
|
1520
|
+
return ("\nWhyRun? computation '" + this.name + "':\n * Running because: " + (isTracking
|
|
1521
|
+
? "[active] the value of this computation is needed by a reaction"
|
|
1522
|
+
: this.isComputing
|
|
1523
|
+
? "[get] The value of this computed was requested outside a reaction"
|
|
1524
|
+
: "[idle] not running at the moment") + "\n" +
|
|
1525
|
+
(this.dependenciesState === exports.IDerivationState.NOT_TRACKING
|
|
1526
|
+
? getMessage("m032")
|
|
1527
|
+
: " * This computation will re-run if any of the following observables changes:\n " + joinStrings(observing) + "\n " + (this.isComputing && isTracking
|
|
1528
|
+
? " (... or any observable accessed during the remainder of the current run)"
|
|
1529
|
+
: "") + "\n\t" + getMessage("m038") + "\n\n * If the outcome of this computation changes, the following observers will be re-run:\n " + joinStrings(observers) + "\n"));
|
|
1434
1530
|
};
|
|
1435
1531
|
return ComputedValue;
|
|
1436
1532
|
}());
|
|
@@ -1446,10 +1542,10 @@ var ObservableObjectAdministration = (function () {
|
|
|
1446
1542
|
this.interceptors = null;
|
|
1447
1543
|
}
|
|
1448
1544
|
/**
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1545
|
+
* Observes this object. Triggers for the events 'add', 'update' and 'delete'.
|
|
1546
|
+
* See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/observe
|
|
1547
|
+
* for callback details
|
|
1548
|
+
*/
|
|
1453
1549
|
ObservableObjectAdministration.prototype.observe = function (callback, fireImmediately) {
|
|
1454
1550
|
invariant(fireImmediately !== true, "`observe` doesn't support the fire immediately property for observable objects.");
|
|
1455
1551
|
return registerListener(this, callback);
|
|
@@ -1460,7 +1556,7 @@ var ObservableObjectAdministration = (function () {
|
|
|
1460
1556
|
return ObservableObjectAdministration;
|
|
1461
1557
|
}());
|
|
1462
1558
|
function asObservableObject(target, name) {
|
|
1463
|
-
if (isObservableObject(target))
|
|
1559
|
+
if (isObservableObject(target) && target.hasOwnProperty("$mobx"))
|
|
1464
1560
|
return target.$mobx;
|
|
1465
1561
|
invariant(Object.isExtensible(target), getMessage("m035"));
|
|
1466
1562
|
if (!isPlainObject(target))
|
|
@@ -1472,7 +1568,7 @@ function asObservableObject(target, name) {
|
|
|
1472
1568
|
return adm;
|
|
1473
1569
|
}
|
|
1474
1570
|
function defineObservablePropertyFromDescriptor(adm, propName, descriptor, defaultEnhancer) {
|
|
1475
|
-
if (adm.values[propName]) {
|
|
1571
|
+
if (adm.values[propName] && !isComputedValue(adm.values[propName])) {
|
|
1476
1572
|
// already observable property
|
|
1477
1573
|
invariant("value" in descriptor, "The property " + propName + " in " + adm.name + " is already observable, cannot redefine it as computed property");
|
|
1478
1574
|
adm.target[propName] = descriptor.value; // the property setter will make 'value' reactive if needed.
|
|
@@ -1500,7 +1596,7 @@ function defineObservablePropertyFromDescriptor(adm, propName, descriptor, defau
|
|
|
1500
1596
|
}
|
|
1501
1597
|
else {
|
|
1502
1598
|
// get x() { return 3 } set x(v) { }
|
|
1503
|
-
defineComputedProperty(adm, propName, descriptor.get, descriptor.set,
|
|
1599
|
+
defineComputedProperty(adm, propName, descriptor.get, descriptor.set, comparer.default, true);
|
|
1504
1600
|
}
|
|
1505
1601
|
}
|
|
1506
1602
|
function defineObservableProperty(adm, propName, newValue, enhancer) {
|
|
@@ -1516,15 +1612,15 @@ function defineObservableProperty(adm, propName, newValue, enhancer) {
|
|
|
1516
1612
|
return;
|
|
1517
1613
|
newValue = change.newValue;
|
|
1518
1614
|
}
|
|
1519
|
-
var observable = adm.values[propName] = new ObservableValue(newValue, enhancer, adm.name + "." + propName, false);
|
|
1615
|
+
var observable = (adm.values[propName] = new ObservableValue(newValue, enhancer, adm.name + "." + propName, false));
|
|
1520
1616
|
newValue = observable.value; // observableValue might have changed it
|
|
1521
1617
|
Object.defineProperty(adm.target, propName, generateObservablePropConfig(propName));
|
|
1522
1618
|
notifyPropertyAddition(adm, adm.target, propName, newValue);
|
|
1523
1619
|
}
|
|
1524
|
-
function defineComputedProperty(adm, propName, getter, setter,
|
|
1620
|
+
function defineComputedProperty(adm, propName, getter, setter, equals, asInstanceProperty) {
|
|
1525
1621
|
if (asInstanceProperty)
|
|
1526
1622
|
assertPropertyConfigurable(adm.target, propName);
|
|
1527
|
-
adm.values[propName] = new ComputedValue(getter, adm.target,
|
|
1623
|
+
adm.values[propName] = new ComputedValue(getter, adm.target, equals, adm.name + "." + propName, setter);
|
|
1528
1624
|
if (asInstanceProperty) {
|
|
1529
1625
|
Object.defineProperty(adm.target, propName, generateComputedPropConfig(propName));
|
|
1530
1626
|
}
|
|
@@ -1540,28 +1636,30 @@ function defineComputedPropertyFromComputedValue(adm, propName, computedValue) {
|
|
|
1540
1636
|
var observablePropertyConfigs = {};
|
|
1541
1637
|
var computedPropertyConfigs = {};
|
|
1542
1638
|
function generateObservablePropConfig(propName) {
|
|
1543
|
-
return observablePropertyConfigs[propName] ||
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1639
|
+
return (observablePropertyConfigs[propName] ||
|
|
1640
|
+
(observablePropertyConfigs[propName] = {
|
|
1641
|
+
configurable: true,
|
|
1642
|
+
enumerable: true,
|
|
1643
|
+
get: function () {
|
|
1644
|
+
return this.$mobx.values[propName].get();
|
|
1645
|
+
},
|
|
1646
|
+
set: function (v) {
|
|
1647
|
+
setPropertyValue(this, propName, v);
|
|
1648
|
+
}
|
|
1649
|
+
}));
|
|
1553
1650
|
}
|
|
1554
1651
|
function generateComputedPropConfig(propName) {
|
|
1555
|
-
return computedPropertyConfigs[propName] ||
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1652
|
+
return (computedPropertyConfigs[propName] ||
|
|
1653
|
+
(computedPropertyConfigs[propName] = {
|
|
1654
|
+
configurable: true,
|
|
1655
|
+
enumerable: false,
|
|
1656
|
+
get: function () {
|
|
1657
|
+
return this.$mobx.values[propName].get();
|
|
1658
|
+
},
|
|
1659
|
+
set: function (v) {
|
|
1660
|
+
return this.$mobx.values[propName].set(v);
|
|
1661
|
+
}
|
|
1662
|
+
}));
|
|
1565
1663
|
}
|
|
1566
1664
|
function setPropertyValue(instance, name, newValue) {
|
|
1567
1665
|
var adm = instance.$mobx;
|
|
@@ -1571,7 +1669,8 @@ function setPropertyValue(instance, name, newValue) {
|
|
|
1571
1669
|
var change = interceptChange(adm, {
|
|
1572
1670
|
type: "update",
|
|
1573
1671
|
object: instance,
|
|
1574
|
-
name: name,
|
|
1672
|
+
name: name,
|
|
1673
|
+
newValue: newValue
|
|
1575
1674
|
});
|
|
1576
1675
|
if (!change)
|
|
1577
1676
|
return;
|
|
@@ -1582,12 +1681,15 @@ function setPropertyValue(instance, name, newValue) {
|
|
|
1582
1681
|
if (newValue !== UNCHANGED) {
|
|
1583
1682
|
var notify = hasListeners(adm);
|
|
1584
1683
|
var notifySpy = isSpyEnabled();
|
|
1585
|
-
var change = notify || notifySpy
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1684
|
+
var change = notify || notifySpy
|
|
1685
|
+
? {
|
|
1686
|
+
type: "update",
|
|
1687
|
+
object: instance,
|
|
1688
|
+
oldValue: observable.value,
|
|
1689
|
+
name: name,
|
|
1690
|
+
newValue: newValue
|
|
1691
|
+
}
|
|
1692
|
+
: null;
|
|
1591
1693
|
if (notifySpy)
|
|
1592
1694
|
spyReportStart(change);
|
|
1593
1695
|
observable.setNewValue(newValue);
|
|
@@ -1600,10 +1702,14 @@ function setPropertyValue(instance, name, newValue) {
|
|
|
1600
1702
|
function notifyPropertyAddition(adm, object, name, newValue) {
|
|
1601
1703
|
var notify = hasListeners(adm);
|
|
1602
1704
|
var notifySpy = isSpyEnabled();
|
|
1603
|
-
var change = notify || notifySpy
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1705
|
+
var change = notify || notifySpy
|
|
1706
|
+
? {
|
|
1707
|
+
type: "add",
|
|
1708
|
+
object: object,
|
|
1709
|
+
name: name,
|
|
1710
|
+
newValue: newValue
|
|
1711
|
+
}
|
|
1712
|
+
: null;
|
|
1607
1713
|
if (notifySpy)
|
|
1608
1714
|
spyReportStart(change);
|
|
1609
1715
|
if (notify)
|
|
@@ -1622,10 +1728,10 @@ function isObservableObject(thing) {
|
|
|
1622
1728
|
}
|
|
1623
1729
|
|
|
1624
1730
|
/**
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1731
|
+
* Returns true if the provided value is reactive.
|
|
1732
|
+
* @param value object, function or array
|
|
1733
|
+
* @param property if property is specified, checks whether value.property is reactive.
|
|
1734
|
+
*/
|
|
1629
1735
|
function isObservable(value, property) {
|
|
1630
1736
|
if (value === null || value === undefined)
|
|
1631
1737
|
return false;
|
|
@@ -1639,7 +1745,11 @@ function isObservable(value, property) {
|
|
|
1639
1745
|
return false;
|
|
1640
1746
|
}
|
|
1641
1747
|
// For first check, see #701
|
|
1642
|
-
return isObservableObject(value) ||
|
|
1748
|
+
return (isObservableObject(value) ||
|
|
1749
|
+
!!value.$mobx ||
|
|
1750
|
+
isAtom(value) ||
|
|
1751
|
+
isReaction(value) ||
|
|
1752
|
+
isComputedValue(value));
|
|
1643
1753
|
}
|
|
1644
1754
|
|
|
1645
1755
|
function createDecoratorForEnhancer(enhancer) {
|
|
@@ -1651,7 +1761,8 @@ function createDecoratorForEnhancer(enhancer) {
|
|
|
1651
1761
|
defineObservableProperty(adm, name, baseValue, enhancer);
|
|
1652
1762
|
}, function (name) {
|
|
1653
1763
|
var observable = this.$mobx.values[name];
|
|
1654
|
-
if (observable === undefined
|
|
1764
|
+
if (observable === undefined // See #505
|
|
1765
|
+
)
|
|
1655
1766
|
return undefined;
|
|
1656
1767
|
return observable.get();
|
|
1657
1768
|
}, function (name, value) {
|
|
@@ -1676,7 +1787,7 @@ function extendShallowObservable(target) {
|
|
|
1676
1787
|
function extendObservableHelper(target, defaultEnhancer, properties) {
|
|
1677
1788
|
invariant(arguments.length >= 2, getMessage("m014"));
|
|
1678
1789
|
invariant(typeof target === "object", getMessage("m015"));
|
|
1679
|
-
invariant(!
|
|
1790
|
+
invariant(!isObservableMap(target), getMessage("m016"));
|
|
1680
1791
|
properties.forEach(function (propSet) {
|
|
1681
1792
|
invariant(typeof propSet === "object", getMessage("m017"));
|
|
1682
1793
|
invariant(!isObservable(propSet), getMessage("m018"));
|
|
@@ -1705,7 +1816,7 @@ var deepStructDecorator = createDecoratorForEnhancer(deepStructEnhancer);
|
|
|
1705
1816
|
var refStructDecorator = createDecoratorForEnhancer(refStructEnhancer);
|
|
1706
1817
|
/**
|
|
1707
1818
|
* Turns an object, array or function into a reactive structure.
|
|
1708
|
-
* @param
|
|
1819
|
+
* @param v the value which should become observable.
|
|
1709
1820
|
*/
|
|
1710
1821
|
function createObservable(v) {
|
|
1711
1822
|
if (v === void 0) { v = undefined; }
|
|
@@ -1823,7 +1934,7 @@ var observable = createObservable;
|
|
|
1823
1934
|
// ES6 class methods aren't enumerable, can't use Object.keys
|
|
1824
1935
|
Object.getOwnPropertyNames(IObservableFactories.prototype)
|
|
1825
1936
|
.filter(function (name) { return name !== "constructor"; })
|
|
1826
|
-
.forEach(function (name) { return observable[name] = IObservableFactories.prototype[name]; });
|
|
1937
|
+
.forEach(function (name) { return (observable[name] = IObservableFactories.prototype[name]); });
|
|
1827
1938
|
observable.deep.struct = observable.struct;
|
|
1828
1939
|
observable.ref.struct = function () {
|
|
1829
1940
|
if (arguments.length < 2) {
|
|
@@ -1921,7 +2032,6 @@ function refStructEnhancer(v, oldValue, name) {
|
|
|
1921
2032
|
*/
|
|
1922
2033
|
function transaction(action, thisArg) {
|
|
1923
2034
|
if (thisArg === void 0) { thisArg = undefined; }
|
|
1924
|
-
deprecated(getMessage("m023"));
|
|
1925
2035
|
return runInTransaction.apply(undefined, arguments);
|
|
1926
2036
|
}
|
|
1927
2037
|
function runInTransaction(action, thisArg) {
|
|
@@ -1995,12 +2105,14 @@ var ObservableMap = (function () {
|
|
|
1995
2105
|
if (this._has(key)) {
|
|
1996
2106
|
var notifySpy = isSpyEnabled();
|
|
1997
2107
|
var notify = hasListeners(this);
|
|
1998
|
-
var change = notify || notifySpy
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2108
|
+
var change = notify || notifySpy
|
|
2109
|
+
? {
|
|
2110
|
+
type: "delete",
|
|
2111
|
+
object: this,
|
|
2112
|
+
oldValue: this._data[key].value,
|
|
2113
|
+
name: key
|
|
2114
|
+
}
|
|
2115
|
+
: null;
|
|
2004
2116
|
if (notifySpy)
|
|
2005
2117
|
spyReportStart(change);
|
|
2006
2118
|
runInTransaction(function () {
|
|
@@ -2035,12 +2147,15 @@ var ObservableMap = (function () {
|
|
|
2035
2147
|
if (newValue !== UNCHANGED) {
|
|
2036
2148
|
var notifySpy = isSpyEnabled();
|
|
2037
2149
|
var notify = hasListeners(this);
|
|
2038
|
-
var change = notify || notifySpy
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2150
|
+
var change = notify || notifySpy
|
|
2151
|
+
? {
|
|
2152
|
+
type: "update",
|
|
2153
|
+
object: this,
|
|
2154
|
+
oldValue: observable$$1.value,
|
|
2155
|
+
name: name,
|
|
2156
|
+
newValue: newValue
|
|
2157
|
+
}
|
|
2158
|
+
: null;
|
|
2044
2159
|
if (notifySpy)
|
|
2045
2160
|
spyReportStart(change);
|
|
2046
2161
|
observable$$1.setNewValue(newValue);
|
|
@@ -2053,19 +2168,21 @@ var ObservableMap = (function () {
|
|
|
2053
2168
|
ObservableMap.prototype._addValue = function (name, newValue) {
|
|
2054
2169
|
var _this = this;
|
|
2055
2170
|
runInTransaction(function () {
|
|
2056
|
-
var observable$$1 = _this._data[name] = new ObservableValue(newValue, _this.enhancer, _this.name + "." + name, false);
|
|
2171
|
+
var observable$$1 = (_this._data[name] = new ObservableValue(newValue, _this.enhancer, _this.name + "." + name, false));
|
|
2057
2172
|
newValue = observable$$1.value; // value might have been changed
|
|
2058
2173
|
_this._updateHasMapEntry(name, true);
|
|
2059
2174
|
_this._keys.push(name);
|
|
2060
2175
|
});
|
|
2061
2176
|
var notifySpy = isSpyEnabled();
|
|
2062
2177
|
var notify = hasListeners(this);
|
|
2063
|
-
var change = notify || notifySpy
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2178
|
+
var change = notify || notifySpy
|
|
2179
|
+
? {
|
|
2180
|
+
type: "add",
|
|
2181
|
+
object: this,
|
|
2182
|
+
name: name,
|
|
2183
|
+
newValue: newValue
|
|
2184
|
+
}
|
|
2185
|
+
: null;
|
|
2069
2186
|
if (notifySpy)
|
|
2070
2187
|
spyReportStart(change);
|
|
2071
2188
|
if (notify)
|
|
@@ -2145,12 +2262,12 @@ var ObservableMap = (function () {
|
|
|
2145
2262
|
});
|
|
2146
2263
|
/**
|
|
2147
2264
|
* Returns a shallow non observable object clone of this map.
|
|
2148
|
-
* Note that the values
|
|
2265
|
+
* Note that the values might still be observable. For a deep clone use mobx.toJS.
|
|
2149
2266
|
*/
|
|
2150
2267
|
ObservableMap.prototype.toJS = function () {
|
|
2151
2268
|
var _this = this;
|
|
2152
2269
|
var res = {};
|
|
2153
|
-
this.keys().forEach(function (key) { return res[key] = _this.get(key); });
|
|
2270
|
+
this.keys().forEach(function (key) { return (res[key] = _this.get(key)); });
|
|
2154
2271
|
return res;
|
|
2155
2272
|
};
|
|
2156
2273
|
ObservableMap.prototype.toJSON = function () {
|
|
@@ -2170,7 +2287,10 @@ var ObservableMap = (function () {
|
|
|
2170
2287
|
};
|
|
2171
2288
|
ObservableMap.prototype.toString = function () {
|
|
2172
2289
|
var _this = this;
|
|
2173
|
-
return this.name +
|
|
2290
|
+
return (this.name +
|
|
2291
|
+
"[{ " +
|
|
2292
|
+
this.keys().map(function (key) { return key + ": " + ("" + _this.get(key)); }).join(", ") +
|
|
2293
|
+
" }]");
|
|
2174
2294
|
};
|
|
2175
2295
|
/**
|
|
2176
2296
|
* Observes this object. Triggers for the events 'add', 'update' and 'delete'.
|
|
@@ -2199,7 +2319,7 @@ var isObservableMap = createInstanceofPredicate("ObservableMap", ObservableMap);
|
|
|
2199
2319
|
var EMPTY_ARRAY = [];
|
|
2200
2320
|
Object.freeze(EMPTY_ARRAY);
|
|
2201
2321
|
function getGlobal() {
|
|
2202
|
-
return global;
|
|
2322
|
+
return typeof window !== "undefined" ? window : global;
|
|
2203
2323
|
}
|
|
2204
2324
|
function getNextId() {
|
|
2205
2325
|
return ++globalState.mobxGuid;
|
|
@@ -2251,7 +2371,9 @@ function joinStrings(things, limit, separator) {
|
|
|
2251
2371
|
if (!things)
|
|
2252
2372
|
return "";
|
|
2253
2373
|
var sliced = things.slice(0, limit);
|
|
2254
|
-
return "" + sliced.join(separator) + (things.length > limit
|
|
2374
|
+
return "" + sliced.join(separator) + (things.length > limit
|
|
2375
|
+
? " (... and " + (things.length - limit) + "more)"
|
|
2376
|
+
: "");
|
|
2255
2377
|
}
|
|
2256
2378
|
function isObject(value) {
|
|
2257
2379
|
return value !== null && typeof value === "object";
|
|
@@ -2273,14 +2395,6 @@ function objectAssign() {
|
|
|
2273
2395
|
}
|
|
2274
2396
|
return res;
|
|
2275
2397
|
}
|
|
2276
|
-
function valueDidChange(compareStructural, oldValue, newValue) {
|
|
2277
|
-
if (typeof oldValue === 'number' && isNaN(oldValue)) {
|
|
2278
|
-
return typeof newValue !== 'number' || !isNaN(newValue);
|
|
2279
|
-
}
|
|
2280
|
-
return compareStructural
|
|
2281
|
-
? !deepEqual(oldValue, newValue)
|
|
2282
|
-
: oldValue !== newValue;
|
|
2283
|
-
}
|
|
2284
2398
|
var prototypeHasOwnProperty = Object.prototype.hasOwnProperty;
|
|
2285
2399
|
function hasOwnProperty(object, propName) {
|
|
2286
2400
|
return prototypeHasOwnProperty.call(object, propName);
|
|
@@ -2401,7 +2515,7 @@ function primitiveSymbol() {
|
|
|
2401
2515
|
return (typeof Symbol === "function" && Symbol.toPrimitive) || "@@toPrimitive";
|
|
2402
2516
|
}
|
|
2403
2517
|
function toPrimitive(value) {
|
|
2404
|
-
return value === null ? null : typeof value === "object" ?
|
|
2518
|
+
return value === null ? null : typeof value === "object" ? "" + value : value;
|
|
2405
2519
|
}
|
|
2406
2520
|
|
|
2407
2521
|
/**
|
|
@@ -2477,7 +2591,32 @@ var MobXGlobals = (function () {
|
|
|
2477
2591
|
return MobXGlobals;
|
|
2478
2592
|
}());
|
|
2479
2593
|
var globalState = new MobXGlobals();
|
|
2594
|
+
var shareGlobalStateCalled = false;
|
|
2595
|
+
var runInIsolationCalled = false;
|
|
2596
|
+
var warnedAboutMultipleInstances = false;
|
|
2597
|
+
{
|
|
2598
|
+
var global_1 = getGlobal();
|
|
2599
|
+
if (!global_1.__mobxInstanceCount) {
|
|
2600
|
+
global_1.__mobxInstanceCount = 1;
|
|
2601
|
+
}
|
|
2602
|
+
else {
|
|
2603
|
+
global_1.__mobxInstanceCount++;
|
|
2604
|
+
setTimeout(function () {
|
|
2605
|
+
if (!shareGlobalStateCalled && !runInIsolationCalled && !warnedAboutMultipleInstances) {
|
|
2606
|
+
warnedAboutMultipleInstances = true;
|
|
2607
|
+
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.");
|
|
2608
|
+
}
|
|
2609
|
+
});
|
|
2610
|
+
}
|
|
2611
|
+
}
|
|
2612
|
+
function isolateGlobalState() {
|
|
2613
|
+
runInIsolationCalled = true;
|
|
2614
|
+
getGlobal().__mobxInstanceCount--;
|
|
2615
|
+
}
|
|
2480
2616
|
function shareGlobalState() {
|
|
2617
|
+
// TODO: remove in 4.0; just use peer dependencies instead.
|
|
2618
|
+
deprecated("Using `shareGlobalState` is not recommended, use peer dependencies instead. See https://github.com/mobxjs/mobx/issues/1082 for details.");
|
|
2619
|
+
shareGlobalStateCalled = true;
|
|
2481
2620
|
var global = getGlobal();
|
|
2482
2621
|
var ownState = globalState;
|
|
2483
2622
|
/**
|
|
@@ -2521,13 +2660,14 @@ function addObserver(observable, node) {
|
|
|
2521
2660
|
// invariantObservers(observable);
|
|
2522
2661
|
var l = observable.observers.length;
|
|
2523
2662
|
if (l) {
|
|
2663
|
+
// because object assignment is relatively expensive, let's not store data about index 0.
|
|
2524
2664
|
observable.observersIndexes[node.__mapid] = l;
|
|
2525
2665
|
}
|
|
2526
2666
|
observable.observers[l] = node;
|
|
2527
2667
|
if (observable.lowestObserverState > node.dependenciesState)
|
|
2528
2668
|
observable.lowestObserverState = node.dependenciesState;
|
|
2529
2669
|
// invariantObservers(observable);
|
|
2530
|
-
// invariant(observable._observers.indexOf(node) !== -1, "INTERNAL ERROR
|
|
2670
|
+
// invariant(observable._observers.indexOf(node) !== -1, "INTERNAL ERROR didn't add node");
|
|
2531
2671
|
}
|
|
2532
2672
|
function removeObserver(observable, node) {
|
|
2533
2673
|
// invariant(globalState.inBatch > 0, "INTERNAL ERROR, remove should be called only inside batch");
|
|
@@ -2542,10 +2682,12 @@ function removeObserver(observable, node) {
|
|
|
2542
2682
|
// deleting from _observersIndexes is straight forward, to delete from _observers, let's swap `node` with last element
|
|
2543
2683
|
var list = observable.observers;
|
|
2544
2684
|
var map = observable.observersIndexes;
|
|
2545
|
-
var filler = list.pop(); // get last element, which should fill the place of `node`, so the array
|
|
2685
|
+
var filler = list.pop(); // get last element, which should fill the place of `node`, so the array doesn't have holes
|
|
2546
2686
|
if (filler !== node) {
|
|
2687
|
+
// otherwise node was the last element, which already got removed from array
|
|
2547
2688
|
var index = map[node.__mapid] || 0; // getting index of `node`. this is the only place we actually use map.
|
|
2548
2689
|
if (index) {
|
|
2690
|
+
// map store all indexes but 0, see comment in `addObserver`
|
|
2549
2691
|
map[filler.__mapid] = index;
|
|
2550
2692
|
}
|
|
2551
2693
|
else {
|
|
@@ -2561,7 +2703,7 @@ function removeObserver(observable, node) {
|
|
|
2561
2703
|
function queueForUnobservation(observable) {
|
|
2562
2704
|
if (!observable.isPendingUnobservation) {
|
|
2563
2705
|
// invariant(globalState.inBatch > 0, "INTERNAL ERROR, remove should be called only inside batch");
|
|
2564
|
-
// invariant(observable._observers.length === 0, "INTERNAL ERROR,
|
|
2706
|
+
// invariant(observable._observers.length === 0, "INTERNAL ERROR, should only queue for unobservation unobserved observables");
|
|
2565
2707
|
observable.isPendingUnobservation = true;
|
|
2566
2708
|
globalState.pendingUnobservations.push(observable);
|
|
2567
2709
|
}
|
|
@@ -2642,7 +2784,8 @@ function propagateChangeConfirmed(observable) {
|
|
|
2642
2784
|
var d = observers[i];
|
|
2643
2785
|
if (d.dependenciesState === exports.IDerivationState.POSSIBLY_STALE)
|
|
2644
2786
|
d.dependenciesState = exports.IDerivationState.STALE;
|
|
2645
|
-
else if (d.dependenciesState === exports.IDerivationState.UP_TO_DATE
|
|
2787
|
+
else if (d.dependenciesState === exports.IDerivationState.UP_TO_DATE // this happens during computing of `d`, just keep lowestObserverState up to date.
|
|
2788
|
+
)
|
|
2646
2789
|
observable.lowestObserverState = exports.IDerivationState.UP_TO_DATE;
|
|
2647
2790
|
}
|
|
2648
2791
|
// invariantLOS(observable, "confirmed end");
|
|
@@ -2680,8 +2823,8 @@ function propagateMaybeChanged(observable) {
|
|
|
2680
2823
|
// having this state is second big optimization:
|
|
2681
2824
|
// don't have to recompute on every dependency change, but only when it's needed
|
|
2682
2825
|
IDerivationState[IDerivationState["POSSIBLY_STALE"] = 1] = "POSSIBLY_STALE";
|
|
2683
|
-
// shallow dependency changed
|
|
2684
|
-
// will need to recompute when it's needed
|
|
2826
|
+
// A shallow dependency has changed since last computation and the derivation
|
|
2827
|
+
// will need to recompute when it's needed next.
|
|
2685
2828
|
IDerivationState[IDerivationState["STALE"] = 2] = "STALE";
|
|
2686
2829
|
})(exports.IDerivationState || (exports.IDerivationState = {}));
|
|
2687
2830
|
var CaughtException = (function () {
|
|
@@ -2695,20 +2838,23 @@ function isCaughtException(e) {
|
|
|
2695
2838
|
return e instanceof CaughtException;
|
|
2696
2839
|
}
|
|
2697
2840
|
/**
|
|
2698
|
-
* Finds out
|
|
2699
|
-
* If dependenciesState is 1 it will recalculate dependencies,
|
|
2841
|
+
* Finds out whether any dependency of the derivation has actually changed.
|
|
2842
|
+
* If dependenciesState is 1 then it will recalculate dependencies,
|
|
2700
2843
|
* if any dependency changed it will propagate it by changing dependenciesState to 2.
|
|
2701
2844
|
*
|
|
2702
|
-
* By iterating over dependencies in the same order they were reported and
|
|
2703
|
-
*
|
|
2704
|
-
* That is because we assume that if first x
|
|
2705
|
-
*
|
|
2845
|
+
* By iterating over the dependencies in the same order that they were reported and
|
|
2846
|
+
* stopping on the first change, all the recalculations are only called for ComputedValues
|
|
2847
|
+
* that will be tracked by derivation. That is because we assume that if the first x
|
|
2848
|
+
* dependencies of the derivation doesn't change then the derivation should run the same way
|
|
2849
|
+
* up until accessing x-th dependency.
|
|
2706
2850
|
*/
|
|
2707
2851
|
function shouldCompute(derivation) {
|
|
2708
2852
|
switch (derivation.dependenciesState) {
|
|
2709
|
-
case exports.IDerivationState.UP_TO_DATE:
|
|
2853
|
+
case exports.IDerivationState.UP_TO_DATE:
|
|
2854
|
+
return false;
|
|
2710
2855
|
case exports.IDerivationState.NOT_TRACKING:
|
|
2711
|
-
case exports.IDerivationState.STALE:
|
|
2856
|
+
case exports.IDerivationState.STALE:
|
|
2857
|
+
return true;
|
|
2712
2858
|
case exports.IDerivationState.POSSIBLY_STALE: {
|
|
2713
2859
|
var prevUntracked = untrackedStart(); // no need for those computeds to be reported, they will be picked up in trackDerivedFunction.
|
|
2714
2860
|
var obs = derivation.observing, l = obs.length;
|
|
@@ -2782,12 +2928,11 @@ function trackDerivedFunction(derivation, f, context) {
|
|
|
2782
2928
|
function bindDependencies(derivation) {
|
|
2783
2929
|
// invariant(derivation.dependenciesState !== IDerivationState.NOT_TRACKING, "INTERNAL ERROR bindDependencies expects derivation.dependenciesState !== -1");
|
|
2784
2930
|
var prevObserving = derivation.observing;
|
|
2785
|
-
var observing = derivation.observing = derivation.newObserving;
|
|
2931
|
+
var observing = (derivation.observing = derivation.newObserving);
|
|
2786
2932
|
var lowestNewObservingDerivationState = exports.IDerivationState.UP_TO_DATE;
|
|
2787
|
-
derivation.newObserving = null; // newObserving shouldn't be needed outside tracking
|
|
2788
2933
|
// Go through all new observables and check diffValue: (this list can contain duplicates):
|
|
2789
|
-
// 0: first
|
|
2790
|
-
// 1: extra
|
|
2934
|
+
// 0: first occurrence, change to 1 and keep it
|
|
2935
|
+
// 1: extra occurrence, drop it
|
|
2791
2936
|
var i0 = 0, l = derivation.unboundDepsCount;
|
|
2792
2937
|
for (var i = 0; i < l; i++) {
|
|
2793
2938
|
var dep = observing[i];
|
|
@@ -2804,6 +2949,7 @@ function bindDependencies(derivation) {
|
|
|
2804
2949
|
}
|
|
2805
2950
|
}
|
|
2806
2951
|
observing.length = i0;
|
|
2952
|
+
derivation.newObserving = null; // newObserving shouldn't be needed outside tracking (statement moved down to work around FF bug, see #614)
|
|
2807
2953
|
// Go through all old observables and check diffValue: (it is unique after last bindDependencies)
|
|
2808
2954
|
// 0: it's not in new observables, unobserve it
|
|
2809
2955
|
// 1: it keeps being observed, don't want to notify it. change to 0
|
|
@@ -2825,8 +2971,8 @@ function bindDependencies(derivation) {
|
|
|
2825
2971
|
addObserver(dep, derivation);
|
|
2826
2972
|
}
|
|
2827
2973
|
}
|
|
2828
|
-
// Some new observed derivations
|
|
2829
|
-
// so
|
|
2974
|
+
// Some new observed derivations may become stale during this derivation computation
|
|
2975
|
+
// so they have had no chance to propagate staleness (#916)
|
|
2830
2976
|
if (lowestNewObservingDerivationState !== exports.IDerivationState.UP_TO_DATE) {
|
|
2831
2977
|
derivation.dependenciesState = lowestNewObservingDerivationState;
|
|
2832
2978
|
derivation.onBecomeStale();
|
|
@@ -2958,7 +3104,7 @@ var Reaction = (function () {
|
|
|
2958
3104
|
var message = "[mobx] Encountered an uncaught exception that was thrown by a reaction or observer component, in: '" + this;
|
|
2959
3105
|
var messageToUser = getMessage("m037");
|
|
2960
3106
|
console.error(message || messageToUser /* latter will not be true, make sure uglify doesn't remove */, error);
|
|
2961
|
-
/** If debugging
|
|
3107
|
+
/** If debugging brought you here, please, read the above message :-). Tnx! */
|
|
2962
3108
|
if (isSpyEnabled()) {
|
|
2963
3109
|
spyReport({
|
|
2964
3110
|
type: "error",
|
|
@@ -2973,8 +3119,9 @@ var Reaction = (function () {
|
|
|
2973
3119
|
if (!this.isDisposed) {
|
|
2974
3120
|
this.isDisposed = true;
|
|
2975
3121
|
if (!this._isRunning) {
|
|
3122
|
+
// if disposed while running, clean up later. Maybe not optimal, but rare case
|
|
2976
3123
|
startBatch();
|
|
2977
|
-
clearObserving(this);
|
|
3124
|
+
clearObserving(this);
|
|
2978
3125
|
endBatch();
|
|
2979
3126
|
}
|
|
2980
3127
|
}
|
|
@@ -2990,7 +3137,11 @@ var Reaction = (function () {
|
|
|
2990
3137
|
};
|
|
2991
3138
|
Reaction.prototype.whyRun = function () {
|
|
2992
3139
|
var observing = unique(this._isRunning ? this.newObserving : this.observing).map(function (dep) { return dep.name; });
|
|
2993
|
-
return
|
|
3140
|
+
return "\nWhyRun? reaction '" + this.name + "':\n * Status: [" + (this.isDisposed
|
|
3141
|
+
? "stopped"
|
|
3142
|
+
: 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
|
|
3143
|
+
? " (... or any observable accessed during the remainder of the current run)"
|
|
3144
|
+
: "") + "\n\t" + getMessage("m038") + "\n";
|
|
2994
3145
|
};
|
|
2995
3146
|
return Reaction;
|
|
2996
3147
|
}());
|
|
@@ -3029,8 +3180,8 @@ function runReactionsHelper() {
|
|
|
3029
3180
|
// we converge to no remaining reactions after a while.
|
|
3030
3181
|
while (allReactions.length > 0) {
|
|
3031
3182
|
if (++iterations === MAX_REACTION_ITERATIONS) {
|
|
3032
|
-
console.error("Reaction doesn't converge to a stable state after " + MAX_REACTION_ITERATIONS + " iterations."
|
|
3033
|
-
|
|
3183
|
+
console.error("Reaction doesn't converge to a stable state after " + MAX_REACTION_ITERATIONS + " iterations." +
|
|
3184
|
+
(" Probably there is a cycle in the reactive function: " + allReactions[0]));
|
|
3034
3185
|
allReactions.splice(0); // clear reactions
|
|
3035
3186
|
}
|
|
3036
3187
|
var remainingReactions = allReactions.splice(0);
|
|
@@ -3062,28 +3213,29 @@ function asMap(data) {
|
|
|
3062
3213
|
return observable.map(data || {});
|
|
3063
3214
|
}
|
|
3064
3215
|
|
|
3065
|
-
function createComputedDecorator(
|
|
3216
|
+
function createComputedDecorator(equals) {
|
|
3066
3217
|
return createClassPropertyDecorator(function (target, name, _, __, originalDescriptor) {
|
|
3067
3218
|
invariant(typeof originalDescriptor !== "undefined", getMessage("m009"));
|
|
3068
3219
|
invariant(typeof originalDescriptor.get === "function", getMessage("m010"));
|
|
3069
3220
|
var adm = asObservableObject(target, "");
|
|
3070
|
-
defineComputedProperty(adm, name, originalDescriptor.get, originalDescriptor.set,
|
|
3221
|
+
defineComputedProperty(adm, name, originalDescriptor.get, originalDescriptor.set, equals, false);
|
|
3071
3222
|
}, function (name) {
|
|
3072
3223
|
var observable = this.$mobx.values[name];
|
|
3073
|
-
if (observable === undefined
|
|
3224
|
+
if (observable === undefined // See #505
|
|
3225
|
+
)
|
|
3074
3226
|
return undefined;
|
|
3075
3227
|
return observable.get();
|
|
3076
3228
|
}, function (name, value) {
|
|
3077
3229
|
this.$mobx.values[name].set(value);
|
|
3078
3230
|
}, false, false);
|
|
3079
3231
|
}
|
|
3080
|
-
var computedDecorator = createComputedDecorator(
|
|
3081
|
-
var computedStructDecorator = createComputedDecorator(
|
|
3232
|
+
var computedDecorator = createComputedDecorator(comparer.default);
|
|
3233
|
+
var computedStructDecorator = createComputedDecorator(comparer.structural);
|
|
3082
3234
|
/**
|
|
3083
3235
|
* Decorator for class properties: @computed get value() { return expr; }.
|
|
3084
3236
|
* For legacy purposes also invokable as ES5 observable created: `computed(() => expr)`;
|
|
3085
3237
|
*/
|
|
3086
|
-
var computed =
|
|
3238
|
+
var computed = function computed(arg1, arg2, arg3) {
|
|
3087
3239
|
if (typeof arg2 === "string") {
|
|
3088
3240
|
return computedDecorator.apply(null, arguments);
|
|
3089
3241
|
}
|
|
@@ -3091,9 +3243,13 @@ var computed = (function computed(arg1, arg2, arg3) {
|
|
|
3091
3243
|
invariant(arguments.length < 3, getMessage("m012"));
|
|
3092
3244
|
var opts = typeof arg2 === "object" ? arg2 : {};
|
|
3093
3245
|
opts.setter = typeof arg2 === "function" ? arg2 : opts.setter;
|
|
3094
|
-
|
|
3095
|
-
|
|
3246
|
+
var equals = opts.equals
|
|
3247
|
+
? opts.equals
|
|
3248
|
+
: opts.compareStructural || opts.struct ? comparer.structural : comparer.default;
|
|
3249
|
+
return new ComputedValue(arg1, opts.context, equals, opts.name || arg1.name || "", opts.setter);
|
|
3250
|
+
};
|
|
3096
3251
|
computed.struct = computedStructDecorator;
|
|
3252
|
+
computed.equals = createComputedDecorator;
|
|
3097
3253
|
|
|
3098
3254
|
function getAtom(thing, property) {
|
|
3099
3255
|
if (typeof thing === "object" && thing !== null) {
|
|
@@ -3196,19 +3352,19 @@ function interceptProperty(thing, property, handler) {
|
|
|
3196
3352
|
}
|
|
3197
3353
|
|
|
3198
3354
|
/**
|
|
3199
|
-
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
|
|
3206
|
-
|
|
3207
|
-
|
|
3208
|
-
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
|
|
3355
|
+
* expr can be used to create temporarily views inside views.
|
|
3356
|
+
* This can be improved to improve performance if a value changes often, but usually doesn't affect the outcome of an expression.
|
|
3357
|
+
*
|
|
3358
|
+
* In the following example the expression prevents that a component is rerender _each time_ the selection changes;
|
|
3359
|
+
* instead it will only rerenders when the current todo is (de)selected.
|
|
3360
|
+
*
|
|
3361
|
+
* reactiveComponent((props) => {
|
|
3362
|
+
* const todo = props.todo;
|
|
3363
|
+
* const isSelected = mobx.expr(() => props.viewState.selection === todo);
|
|
3364
|
+
* return <div className={isSelected ? "todo todo-selected" : "todo"}>{todo.title}</div>
|
|
3365
|
+
* });
|
|
3366
|
+
*
|
|
3367
|
+
*/
|
|
3212
3368
|
function expr(expr, scope) {
|
|
3213
3369
|
if (!isComputingDerivation())
|
|
3214
3370
|
console.warn(getMessage("m013"));
|
|
@@ -3250,7 +3406,7 @@ function toJS(source, detectCycles, __alreadySeen) {
|
|
|
3250
3406
|
}
|
|
3251
3407
|
if (isObservableMap(source)) {
|
|
3252
3408
|
var res_1 = cache({});
|
|
3253
|
-
source.forEach(function (value, key) { return res_1[key] = toJS(value, detectCycles, __alreadySeen); });
|
|
3409
|
+
source.forEach(function (value, key) { return (res_1[key] = toJS(value, detectCycles, __alreadySeen)); });
|
|
3254
3410
|
return res_1;
|
|
3255
3411
|
}
|
|
3256
3412
|
if (isObservableValue(source))
|
|
@@ -3270,7 +3426,7 @@ function createTransformer(transformer, onCleanup) {
|
|
|
3270
3426
|
var Transformer = (function (_super) {
|
|
3271
3427
|
__extends(Transformer, _super);
|
|
3272
3428
|
function Transformer(sourceIdentifier, sourceObject) {
|
|
3273
|
-
var _this = _super.call(this, function () { return transformer(sourceObject); }, undefined,
|
|
3429
|
+
var _this = _super.call(this, function () { return transformer(sourceObject); }, undefined, comparer.default, "Transformer-" + transformer.name + "-" + sourceIdentifier, undefined) || this;
|
|
3274
3430
|
_this.sourceIdentifier = sourceIdentifier;
|
|
3275
3431
|
_this.sourceObject = sourceObject;
|
|
3276
3432
|
return _this;
|
|
@@ -3299,7 +3455,7 @@ function createTransformer(transformer, onCleanup) {
|
|
|
3299
3455
|
};
|
|
3300
3456
|
}
|
|
3301
3457
|
function getMemoizationId(object) {
|
|
3302
|
-
if (typeof object ===
|
|
3458
|
+
if (typeof object === "string" || typeof object === "number")
|
|
3303
3459
|
return object;
|
|
3304
3460
|
if (object === null || typeof object !== "object")
|
|
3305
3461
|
throw new Error("[mobx] transform expected some kind of object or primitive value, got: " + object);
|
|
@@ -3410,6 +3566,7 @@ var extras = {
|
|
|
3410
3566
|
onReactionError: onReactionError,
|
|
3411
3567
|
reserveArrayBuffer: reserveArrayBuffer,
|
|
3412
3568
|
resetGlobalState: resetGlobalState,
|
|
3569
|
+
isolateGlobalState: isolateGlobalState,
|
|
3413
3570
|
shareGlobalState: shareGlobalState,
|
|
3414
3571
|
spyReport: spyReport,
|
|
3415
3572
|
spyReportEnd: spyReportEnd,
|
|
@@ -3419,31 +3576,45 @@ var extras = {
|
|
|
3419
3576
|
var everything = {
|
|
3420
3577
|
Reaction: Reaction,
|
|
3421
3578
|
untracked: untracked,
|
|
3422
|
-
Atom: Atom,
|
|
3423
|
-
|
|
3579
|
+
Atom: Atom,
|
|
3580
|
+
BaseAtom: BaseAtom,
|
|
3581
|
+
useStrict: useStrict,
|
|
3582
|
+
isStrictModeEnabled: isStrictModeEnabled,
|
|
3424
3583
|
spy: spy,
|
|
3425
|
-
|
|
3584
|
+
comparer: comparer,
|
|
3585
|
+
asReference: asReference,
|
|
3586
|
+
asFlat: asFlat,
|
|
3587
|
+
asStructure: asStructure,
|
|
3588
|
+
asMap: asMap,
|
|
3426
3589
|
isModifierDescriptor: isModifierDescriptor,
|
|
3427
3590
|
isObservableObject: isObservableObject,
|
|
3428
3591
|
isBoxedObservable: isObservableValue,
|
|
3429
3592
|
isObservableArray: isObservableArray,
|
|
3430
|
-
ObservableMap: ObservableMap,
|
|
3593
|
+
ObservableMap: ObservableMap,
|
|
3594
|
+
isObservableMap: isObservableMap,
|
|
3595
|
+
map: map,
|
|
3431
3596
|
transaction: transaction,
|
|
3432
3597
|
observable: observable,
|
|
3433
3598
|
computed: computed,
|
|
3434
3599
|
isObservable: isObservable,
|
|
3435
3600
|
isComputed: isComputed,
|
|
3436
|
-
extendObservable: extendObservable,
|
|
3601
|
+
extendObservable: extendObservable,
|
|
3602
|
+
extendShallowObservable: extendShallowObservable,
|
|
3437
3603
|
observe: observe,
|
|
3438
3604
|
intercept: intercept,
|
|
3439
|
-
autorun: autorun,
|
|
3440
|
-
|
|
3605
|
+
autorun: autorun,
|
|
3606
|
+
autorunAsync: autorunAsync,
|
|
3607
|
+
when: when,
|
|
3608
|
+
reaction: reaction,
|
|
3609
|
+
action: action,
|
|
3610
|
+
isAction: isAction,
|
|
3611
|
+
runInAction: runInAction,
|
|
3441
3612
|
expr: expr,
|
|
3442
3613
|
toJS: toJS,
|
|
3443
3614
|
createTransformer: createTransformer,
|
|
3444
3615
|
whyRun: whyRun,
|
|
3445
3616
|
isArrayLike: isArrayLike,
|
|
3446
|
-
extras: extras
|
|
3617
|
+
extras: extras
|
|
3447
3618
|
};
|
|
3448
3619
|
var warnedAboutDefaultExport = false;
|
|
3449
3620
|
var _loop_1 = function (p) {
|
|
@@ -3452,9 +3623,9 @@ var _loop_1 = function (p) {
|
|
|
3452
3623
|
get: function () {
|
|
3453
3624
|
if (!warnedAboutDefaultExport) {
|
|
3454
3625
|
warnedAboutDefaultExport = true;
|
|
3455
|
-
console.warn(
|
|
3456
|
-
|
|
3457
|
-
|
|
3626
|
+
console.warn("Using default export (`import mobx from 'mobx'`) is deprecated " +
|
|
3627
|
+
"and won’t work in mobx@4.0.0\n" +
|
|
3628
|
+
"Use `import * as mobx from 'mobx'` instead");
|
|
3458
3629
|
}
|
|
3459
3630
|
return val;
|
|
3460
3631
|
}
|
|
@@ -3476,6 +3647,7 @@ exports.BaseAtom = BaseAtom;
|
|
|
3476
3647
|
exports.useStrict = useStrict;
|
|
3477
3648
|
exports.isStrictModeEnabled = isStrictModeEnabled;
|
|
3478
3649
|
exports.spy = spy;
|
|
3650
|
+
exports.comparer = comparer;
|
|
3479
3651
|
exports.asReference = asReference;
|
|
3480
3652
|
exports.asFlat = asFlat;
|
|
3481
3653
|
exports.asStructure = asStructure;
|