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