mobx 4.12.0 → 4.14.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/api/autorun.d.ts +5 -0
- package/lib/api/configure.d.ts +10 -0
- package/lib/api/when.d.ts +5 -0
- package/lib/core/action.d.ts +13 -0
- package/lib/core/derivation.d.ts +7 -0
- package/lib/core/globalstate.d.ts +15 -0
- package/lib/core/reaction.d.ts +2 -1
- package/lib/mobx.d.ts +1 -1
- package/lib/mobx.es6.js +499 -394
- package/lib/mobx.js +498 -391
- package/lib/mobx.js.flow +20 -2
- package/lib/mobx.min.js +1 -1
- package/lib/mobx.module.js +498 -393
- package/lib/mobx.umd.js +498 -391
- package/lib/mobx.umd.min.js +1 -1
- package/lib/utils/comparer.d.ts +2 -0
- package/lib/utils/eq.d.ts +1 -1
- package/lib/utils/utils.d.ts +1 -0
- package/package.json +1 -1
package/lib/mobx.js
CHANGED
|
@@ -71,8 +71,15 @@ var EMPTY_ARRAY = [];
|
|
|
71
71
|
Object.freeze(EMPTY_ARRAY);
|
|
72
72
|
var EMPTY_OBJECT = {};
|
|
73
73
|
Object.freeze(EMPTY_OBJECT);
|
|
74
|
+
var mockGlobal = {};
|
|
74
75
|
function getGlobal() {
|
|
75
|
-
|
|
76
|
+
if (typeof window !== "undefined") {
|
|
77
|
+
return window;
|
|
78
|
+
}
|
|
79
|
+
if (typeof global !== "undefined") {
|
|
80
|
+
return global;
|
|
81
|
+
}
|
|
82
|
+
return mockGlobal;
|
|
76
83
|
}
|
|
77
84
|
function getNextId() {
|
|
78
85
|
return ++globalState.mobxGuid;
|
|
@@ -132,6 +139,20 @@ function isPlainObject(value) {
|
|
|
132
139
|
var proto = Object.getPrototypeOf(value);
|
|
133
140
|
return proto === Object.prototype || proto === null;
|
|
134
141
|
}
|
|
142
|
+
function convertToMap(dataStructure) {
|
|
143
|
+
if (isES6Map(dataStructure) || isObservableMap(dataStructure)) {
|
|
144
|
+
return dataStructure;
|
|
145
|
+
}
|
|
146
|
+
else if (Array.isArray(dataStructure)) {
|
|
147
|
+
return new Map(dataStructure);
|
|
148
|
+
}
|
|
149
|
+
else if (isPlainObject(dataStructure)) {
|
|
150
|
+
return new Map(Object.entries(dataStructure));
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
return fail("Cannot convert to map from '" + dataStructure + "'");
|
|
154
|
+
}
|
|
155
|
+
}
|
|
135
156
|
function makeNonEnumerable(object, propNames) {
|
|
136
157
|
for (var i = 0; i < propNames.length; i++) {
|
|
137
158
|
addHiddenProp(object, propNames[i], object[propNames[i]]);
|
|
@@ -185,18 +206,6 @@ function isES6Map(thing) {
|
|
|
185
206
|
function isES6Set(thing) {
|
|
186
207
|
return thing instanceof Set;
|
|
187
208
|
}
|
|
188
|
-
function getMapLikeKeys(map) {
|
|
189
|
-
if (isPlainObject(map))
|
|
190
|
-
return Object.keys(map);
|
|
191
|
-
if (Array.isArray(map))
|
|
192
|
-
return map.map(function (_a) {
|
|
193
|
-
var _b = __read(_a, 1), key = _b[0];
|
|
194
|
-
return key;
|
|
195
|
-
});
|
|
196
|
-
if (isES6Map(map) || isObservableMap(map))
|
|
197
|
-
return iteratorToArray(map.keys());
|
|
198
|
-
return fail("Cannot get keys from '" + map + "'");
|
|
199
|
-
}
|
|
200
209
|
// use Array.from in Mobx 5
|
|
201
210
|
function iteratorToArray(it) {
|
|
202
211
|
var res = [];
|
|
@@ -223,13 +232,13 @@ function declareIterator(prototType, iteratorFactory) {
|
|
|
223
232
|
addHiddenFinalProp(prototType, iteratorSymbol(), iteratorFactory);
|
|
224
233
|
}
|
|
225
234
|
function makeIterable(iterator) {
|
|
226
|
-
iterator[iteratorSymbol()] =
|
|
235
|
+
iterator[iteratorSymbol()] = getSelf;
|
|
227
236
|
return iterator;
|
|
228
237
|
}
|
|
229
238
|
function toStringTagSymbol() {
|
|
230
239
|
return (typeof Symbol === "function" && Symbol.toStringTag) || "@@toStringTag";
|
|
231
240
|
}
|
|
232
|
-
function
|
|
241
|
+
function getSelf() {
|
|
233
242
|
return this;
|
|
234
243
|
}
|
|
235
244
|
|
|
@@ -297,13 +306,17 @@ function identityComparer(a, b) {
|
|
|
297
306
|
function structuralComparer(a, b) {
|
|
298
307
|
return deepEqual(a, b);
|
|
299
308
|
}
|
|
309
|
+
function shallowComparer(a, b) {
|
|
310
|
+
return deepEqual(a, b, 1);
|
|
311
|
+
}
|
|
300
312
|
function defaultComparer(a, b) {
|
|
301
313
|
return areBothNaN(a, b) || identityComparer(a, b);
|
|
302
314
|
}
|
|
303
315
|
var comparer = {
|
|
304
316
|
identity: identityComparer,
|
|
305
317
|
structural: structuralComparer,
|
|
306
|
-
default: defaultComparer
|
|
318
|
+
default: defaultComparer,
|
|
319
|
+
shallow: shallowComparer
|
|
307
320
|
};
|
|
308
321
|
|
|
309
322
|
var enumerableDescriptorCache = {};
|
|
@@ -623,6 +636,275 @@ var computed = function computed(arg1, arg2, arg3) {
|
|
|
623
636
|
};
|
|
624
637
|
computed.struct = computedStructDecorator;
|
|
625
638
|
|
|
639
|
+
(function (IDerivationState) {
|
|
640
|
+
// before being run or (outside batch and not being observed)
|
|
641
|
+
// at this point derivation is not holding any data about dependency tree
|
|
642
|
+
IDerivationState[IDerivationState["NOT_TRACKING"] = -1] = "NOT_TRACKING";
|
|
643
|
+
// no shallow dependency changed since last computation
|
|
644
|
+
// won't recalculate derivation
|
|
645
|
+
// this is what makes mobx fast
|
|
646
|
+
IDerivationState[IDerivationState["UP_TO_DATE"] = 0] = "UP_TO_DATE";
|
|
647
|
+
// some deep dependency changed, but don't know if shallow dependency changed
|
|
648
|
+
// will require to check first if UP_TO_DATE or POSSIBLY_STALE
|
|
649
|
+
// currently only ComputedValue will propagate POSSIBLY_STALE
|
|
650
|
+
//
|
|
651
|
+
// having this state is second big optimization:
|
|
652
|
+
// don't have to recompute on every dependency change, but only when it's needed
|
|
653
|
+
IDerivationState[IDerivationState["POSSIBLY_STALE"] = 1] = "POSSIBLY_STALE";
|
|
654
|
+
// A shallow dependency has changed since last computation and the derivation
|
|
655
|
+
// will need to recompute when it's needed next.
|
|
656
|
+
IDerivationState[IDerivationState["STALE"] = 2] = "STALE";
|
|
657
|
+
})(exports.IDerivationState || (exports.IDerivationState = {}));
|
|
658
|
+
var TraceMode;
|
|
659
|
+
(function (TraceMode) {
|
|
660
|
+
TraceMode[TraceMode["NONE"] = 0] = "NONE";
|
|
661
|
+
TraceMode[TraceMode["LOG"] = 1] = "LOG";
|
|
662
|
+
TraceMode[TraceMode["BREAK"] = 2] = "BREAK";
|
|
663
|
+
})(TraceMode || (TraceMode = {}));
|
|
664
|
+
var CaughtException = /** @class */ (function () {
|
|
665
|
+
function CaughtException(cause) {
|
|
666
|
+
this.cause = cause;
|
|
667
|
+
// Empty
|
|
668
|
+
}
|
|
669
|
+
return CaughtException;
|
|
670
|
+
}());
|
|
671
|
+
function isCaughtException(e) {
|
|
672
|
+
return e instanceof CaughtException;
|
|
673
|
+
}
|
|
674
|
+
/**
|
|
675
|
+
* Finds out whether any dependency of the derivation has actually changed.
|
|
676
|
+
* If dependenciesState is 1 then it will recalculate dependencies,
|
|
677
|
+
* if any dependency changed it will propagate it by changing dependenciesState to 2.
|
|
678
|
+
*
|
|
679
|
+
* By iterating over the dependencies in the same order that they were reported and
|
|
680
|
+
* stopping on the first change, all the recalculations are only called for ComputedValues
|
|
681
|
+
* that will be tracked by derivation. That is because we assume that if the first x
|
|
682
|
+
* dependencies of the derivation doesn't change then the derivation should run the same way
|
|
683
|
+
* up until accessing x-th dependency.
|
|
684
|
+
*/
|
|
685
|
+
function shouldCompute(derivation) {
|
|
686
|
+
switch (derivation.dependenciesState) {
|
|
687
|
+
case exports.IDerivationState.UP_TO_DATE:
|
|
688
|
+
return false;
|
|
689
|
+
case exports.IDerivationState.NOT_TRACKING:
|
|
690
|
+
case exports.IDerivationState.STALE:
|
|
691
|
+
return true;
|
|
692
|
+
case exports.IDerivationState.POSSIBLY_STALE: {
|
|
693
|
+
var prevUntracked = untrackedStart(); // no need for those computeds to be reported, they will be picked up in trackDerivedFunction.
|
|
694
|
+
var obs = derivation.observing, l = obs.length;
|
|
695
|
+
for (var i = 0; i < l; i++) {
|
|
696
|
+
var obj = obs[i];
|
|
697
|
+
if (isComputedValue(obj)) {
|
|
698
|
+
if (globalState.disableErrorBoundaries) {
|
|
699
|
+
obj.get();
|
|
700
|
+
}
|
|
701
|
+
else {
|
|
702
|
+
try {
|
|
703
|
+
obj.get();
|
|
704
|
+
}
|
|
705
|
+
catch (e) {
|
|
706
|
+
// we are not interested in the value *or* exception at this moment, but if there is one, notify all
|
|
707
|
+
untrackedEnd(prevUntracked);
|
|
708
|
+
return true;
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
// if ComputedValue `obj` actually changed it will be computed and propagated to its observers.
|
|
712
|
+
// and `derivation` is an observer of `obj`
|
|
713
|
+
// invariantShouldCompute(derivation)
|
|
714
|
+
if (derivation.dependenciesState === exports.IDerivationState.STALE) {
|
|
715
|
+
untrackedEnd(prevUntracked);
|
|
716
|
+
return true;
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
changeDependenciesStateTo0(derivation);
|
|
721
|
+
untrackedEnd(prevUntracked);
|
|
722
|
+
return false;
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
// function invariantShouldCompute(derivation: IDerivation) {
|
|
727
|
+
// const newDepState = (derivation as any).dependenciesState
|
|
728
|
+
// if (
|
|
729
|
+
// process.env.NODE_ENV === "production" &&
|
|
730
|
+
// (newDepState === IDerivationState.POSSIBLY_STALE ||
|
|
731
|
+
// newDepState === IDerivationState.NOT_TRACKING)
|
|
732
|
+
// )
|
|
733
|
+
// fail("Illegal dependency state")
|
|
734
|
+
// }
|
|
735
|
+
function isComputingDerivation() {
|
|
736
|
+
return globalState.trackingDerivation !== null; // filter out actions inside computations
|
|
737
|
+
}
|
|
738
|
+
function checkIfStateModificationsAreAllowed(atom) {
|
|
739
|
+
var hasObservers = atom.observers.length > 0;
|
|
740
|
+
// Should never be possible to change an observed observable from inside computed, see #798
|
|
741
|
+
if (globalState.computationDepth > 0 && hasObservers)
|
|
742
|
+
fail(process.env.NODE_ENV !== "production" &&
|
|
743
|
+
"Computed values are not allowed to cause side effects by changing observables that are already being observed. Tried to modify: " + atom.name);
|
|
744
|
+
// Should not be possible to change observed state outside strict mode, except during initialization, see #563
|
|
745
|
+
if (!globalState.allowStateChanges && (hasObservers || globalState.enforceActions === "strict"))
|
|
746
|
+
fail(process.env.NODE_ENV !== "production" &&
|
|
747
|
+
(globalState.enforceActions
|
|
748
|
+
? "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: "
|
|
749
|
+
: "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: ") +
|
|
750
|
+
atom.name);
|
|
751
|
+
}
|
|
752
|
+
function checkIfStateReadsAreAllowed(observable) {
|
|
753
|
+
if (process.env.NODE_ENV !== "production" &&
|
|
754
|
+
!globalState.allowStateReads &&
|
|
755
|
+
globalState.observableRequiresReaction) {
|
|
756
|
+
console.warn("[mobx] Observable " + observable.name + " being read outside a reactive context");
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
/**
|
|
760
|
+
* Executes the provided function `f` and tracks which observables are being accessed.
|
|
761
|
+
* The tracking information is stored on the `derivation` object and the derivation is registered
|
|
762
|
+
* as observer of any of the accessed observables.
|
|
763
|
+
*/
|
|
764
|
+
function trackDerivedFunction(derivation, f, context) {
|
|
765
|
+
var prevAllowStateReads = allowStateReadsStart(true);
|
|
766
|
+
// pre allocate array allocation + room for variation in deps
|
|
767
|
+
// array will be trimmed by bindDependencies
|
|
768
|
+
changeDependenciesStateTo0(derivation);
|
|
769
|
+
derivation.newObserving = new Array(derivation.observing.length + 100);
|
|
770
|
+
derivation.unboundDepsCount = 0;
|
|
771
|
+
derivation.runId = ++globalState.runId;
|
|
772
|
+
var prevTracking = globalState.trackingDerivation;
|
|
773
|
+
globalState.trackingDerivation = derivation;
|
|
774
|
+
var result;
|
|
775
|
+
if (globalState.disableErrorBoundaries === true) {
|
|
776
|
+
result = f.call(context);
|
|
777
|
+
}
|
|
778
|
+
else {
|
|
779
|
+
try {
|
|
780
|
+
result = f.call(context);
|
|
781
|
+
}
|
|
782
|
+
catch (e) {
|
|
783
|
+
result = new CaughtException(e);
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
globalState.trackingDerivation = prevTracking;
|
|
787
|
+
bindDependencies(derivation);
|
|
788
|
+
if (derivation.observing.length === 0) {
|
|
789
|
+
warnAboutDerivationWithoutDependencies(derivation);
|
|
790
|
+
}
|
|
791
|
+
allowStateReadsEnd(prevAllowStateReads);
|
|
792
|
+
return result;
|
|
793
|
+
}
|
|
794
|
+
function warnAboutDerivationWithoutDependencies(derivation) {
|
|
795
|
+
if (process.env.NODE_ENV === "production")
|
|
796
|
+
return;
|
|
797
|
+
if (globalState.reactionRequiresObservable || derivation.requiresObservable) {
|
|
798
|
+
console.warn("[mobx] Derivation " + derivation.name + " is created/updated without reading any observable value");
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
/**
|
|
802
|
+
* diffs newObserving with observing.
|
|
803
|
+
* update observing to be newObserving with unique observables
|
|
804
|
+
* notify observers that become observed/unobserved
|
|
805
|
+
*/
|
|
806
|
+
function bindDependencies(derivation) {
|
|
807
|
+
// invariant(derivation.dependenciesState !== IDerivationState.NOT_TRACKING, "INTERNAL ERROR bindDependencies expects derivation.dependenciesState !== -1");
|
|
808
|
+
var prevObserving = derivation.observing;
|
|
809
|
+
var observing = (derivation.observing = derivation.newObserving);
|
|
810
|
+
var lowestNewObservingDerivationState = exports.IDerivationState.UP_TO_DATE;
|
|
811
|
+
// Go through all new observables and check diffValue: (this list can contain duplicates):
|
|
812
|
+
// 0: first occurrence, change to 1 and keep it
|
|
813
|
+
// 1: extra occurrence, drop it
|
|
814
|
+
var i0 = 0, l = derivation.unboundDepsCount;
|
|
815
|
+
for (var i = 0; i < l; i++) {
|
|
816
|
+
var dep = observing[i];
|
|
817
|
+
if (dep.diffValue === 0) {
|
|
818
|
+
dep.diffValue = 1;
|
|
819
|
+
if (i0 !== i)
|
|
820
|
+
observing[i0] = dep;
|
|
821
|
+
i0++;
|
|
822
|
+
}
|
|
823
|
+
// Upcast is 'safe' here, because if dep is IObservable, `dependenciesState` will be undefined,
|
|
824
|
+
// not hitting the condition
|
|
825
|
+
if (dep.dependenciesState > lowestNewObservingDerivationState) {
|
|
826
|
+
lowestNewObservingDerivationState = dep.dependenciesState;
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
observing.length = i0;
|
|
830
|
+
derivation.newObserving = null; // newObserving shouldn't be needed outside tracking (statement moved down to work around FF bug, see #614)
|
|
831
|
+
// Go through all old observables and check diffValue: (it is unique after last bindDependencies)
|
|
832
|
+
// 0: it's not in new observables, unobserve it
|
|
833
|
+
// 1: it keeps being observed, don't want to notify it. change to 0
|
|
834
|
+
l = prevObserving.length;
|
|
835
|
+
while (l--) {
|
|
836
|
+
var dep = prevObserving[l];
|
|
837
|
+
if (dep.diffValue === 0) {
|
|
838
|
+
removeObserver(dep, derivation);
|
|
839
|
+
}
|
|
840
|
+
dep.diffValue = 0;
|
|
841
|
+
}
|
|
842
|
+
// Go through all new observables and check diffValue: (now it should be unique)
|
|
843
|
+
// 0: it was set to 0 in last loop. don't need to do anything.
|
|
844
|
+
// 1: it wasn't observed, let's observe it. set back to 0
|
|
845
|
+
while (i0--) {
|
|
846
|
+
var dep = observing[i0];
|
|
847
|
+
if (dep.diffValue === 1) {
|
|
848
|
+
dep.diffValue = 0;
|
|
849
|
+
addObserver(dep, derivation);
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
// Some new observed derivations may become stale during this derivation computation
|
|
853
|
+
// so they have had no chance to propagate staleness (#916)
|
|
854
|
+
if (lowestNewObservingDerivationState !== exports.IDerivationState.UP_TO_DATE) {
|
|
855
|
+
derivation.dependenciesState = lowestNewObservingDerivationState;
|
|
856
|
+
derivation.onBecomeStale();
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
function clearObserving(derivation) {
|
|
860
|
+
// invariant(globalState.inBatch > 0, "INTERNAL ERROR clearObserving should be called only inside batch");
|
|
861
|
+
var obs = derivation.observing;
|
|
862
|
+
derivation.observing = [];
|
|
863
|
+
var i = obs.length;
|
|
864
|
+
while (i--)
|
|
865
|
+
removeObserver(obs[i], derivation);
|
|
866
|
+
derivation.dependenciesState = exports.IDerivationState.NOT_TRACKING;
|
|
867
|
+
}
|
|
868
|
+
function untracked(action) {
|
|
869
|
+
var prev = untrackedStart();
|
|
870
|
+
var res = action();
|
|
871
|
+
untrackedEnd(prev);
|
|
872
|
+
return res;
|
|
873
|
+
}
|
|
874
|
+
function untrackedStart() {
|
|
875
|
+
var prev = globalState.trackingDerivation;
|
|
876
|
+
globalState.trackingDerivation = null;
|
|
877
|
+
return prev;
|
|
878
|
+
}
|
|
879
|
+
function untrackedEnd(prev) {
|
|
880
|
+
globalState.trackingDerivation = prev;
|
|
881
|
+
}
|
|
882
|
+
function allowStateReadsStart(allowStateReads) {
|
|
883
|
+
var prev = globalState.allowStateReads;
|
|
884
|
+
globalState.allowStateReads = allowStateReads;
|
|
885
|
+
return prev;
|
|
886
|
+
}
|
|
887
|
+
function allowStateReadsEnd(prev) {
|
|
888
|
+
globalState.allowStateReads = prev;
|
|
889
|
+
}
|
|
890
|
+
/**
|
|
891
|
+
* needed to keep `lowestObserverState` correct. when changing from (2 or 1) to 0
|
|
892
|
+
*
|
|
893
|
+
*/
|
|
894
|
+
function changeDependenciesStateTo0(derivation) {
|
|
895
|
+
if (derivation.dependenciesState === exports.IDerivationState.UP_TO_DATE)
|
|
896
|
+
return;
|
|
897
|
+
derivation.dependenciesState = exports.IDerivationState.UP_TO_DATE;
|
|
898
|
+
var obs = derivation.observing;
|
|
899
|
+
var i = obs.length;
|
|
900
|
+
while (i--)
|
|
901
|
+
obs[i].lowestObserverState = exports.IDerivationState.UP_TO_DATE;
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
// we don't use globalState for these in order to avoid possible issues with multiple
|
|
905
|
+
// mobx versions
|
|
906
|
+
var currentActionId = 0;
|
|
907
|
+
var nextActionId = 1;
|
|
626
908
|
function createAction(actionName, fn) {
|
|
627
909
|
if (process.env.NODE_ENV !== "production") {
|
|
628
910
|
invariant(typeof fn === "function", "`action` can only be invoked on functions");
|
|
@@ -636,25 +918,19 @@ function createAction(actionName, fn) {
|
|
|
636
918
|
return res;
|
|
637
919
|
}
|
|
638
920
|
function executeAction(actionName, fn, scope, args) {
|
|
639
|
-
var runInfo =
|
|
640
|
-
var shouldSupressReactionError = true;
|
|
921
|
+
var runInfo = _startAction(actionName, scope, args);
|
|
641
922
|
try {
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
923
|
+
return fn.apply(scope, args);
|
|
924
|
+
}
|
|
925
|
+
catch (err) {
|
|
926
|
+
runInfo.error = err;
|
|
927
|
+
throw err;
|
|
645
928
|
}
|
|
646
929
|
finally {
|
|
647
|
-
|
|
648
|
-
globalState.suppressReactionErrors = shouldSupressReactionError;
|
|
649
|
-
endAction(runInfo);
|
|
650
|
-
globalState.suppressReactionErrors = false;
|
|
651
|
-
}
|
|
652
|
-
else {
|
|
653
|
-
endAction(runInfo);
|
|
654
|
-
}
|
|
930
|
+
_endAction(runInfo);
|
|
655
931
|
}
|
|
656
932
|
}
|
|
657
|
-
function
|
|
933
|
+
function _startAction(actionName, scope, args) {
|
|
658
934
|
var notifySpy = isSpyEnabled() && !!actionName;
|
|
659
935
|
var startTime = 0;
|
|
660
936
|
if (notifySpy) {
|
|
@@ -674,19 +950,35 @@ function startAction(actionName, fn, scope, args) {
|
|
|
674
950
|
var prevDerivation = untrackedStart();
|
|
675
951
|
startBatch();
|
|
676
952
|
var prevAllowStateChanges = allowStateChangesStart(true);
|
|
677
|
-
|
|
953
|
+
var prevAllowStateReads = allowStateReadsStart(true);
|
|
954
|
+
var runInfo = {
|
|
678
955
|
prevDerivation: prevDerivation,
|
|
679
956
|
prevAllowStateChanges: prevAllowStateChanges,
|
|
957
|
+
prevAllowStateReads: prevAllowStateReads,
|
|
680
958
|
notifySpy: notifySpy,
|
|
681
|
-
startTime: startTime
|
|
959
|
+
startTime: startTime,
|
|
960
|
+
actionId: nextActionId++,
|
|
961
|
+
parentActionId: currentActionId
|
|
682
962
|
};
|
|
963
|
+
currentActionId = runInfo.actionId;
|
|
964
|
+
return runInfo;
|
|
683
965
|
}
|
|
684
|
-
function
|
|
966
|
+
function _endAction(runInfo) {
|
|
967
|
+
if (currentActionId !== runInfo.actionId) {
|
|
968
|
+
fail("invalid action stack. did you forget to finish an action?");
|
|
969
|
+
}
|
|
970
|
+
currentActionId = runInfo.parentActionId;
|
|
971
|
+
if (runInfo.error !== undefined) {
|
|
972
|
+
globalState.suppressReactionErrors = true;
|
|
973
|
+
}
|
|
685
974
|
allowStateChangesEnd(runInfo.prevAllowStateChanges);
|
|
975
|
+
allowStateReadsEnd(runInfo.prevAllowStateReads);
|
|
686
976
|
endBatch();
|
|
687
977
|
untrackedEnd(runInfo.prevDerivation);
|
|
688
|
-
if (runInfo.notifySpy)
|
|
978
|
+
if (runInfo.notifySpy) {
|
|
689
979
|
spyReportEnd({ time: Date.now() - runInfo.startTime });
|
|
980
|
+
}
|
|
981
|
+
globalState.suppressReactionErrors = false;
|
|
690
982
|
}
|
|
691
983
|
function allowStateChanges(allowStateChanges, func) {
|
|
692
984
|
var prev = allowStateChangesStart(allowStateChanges);
|
|
@@ -942,337 +1234,99 @@ var ComputedValue = /** @class */ (function () {
|
|
|
942
1234
|
if (isSpyEnabled()) {
|
|
943
1235
|
spyReport({
|
|
944
1236
|
object: this.scope,
|
|
945
|
-
type: "compute",
|
|
946
|
-
name: this.name
|
|
947
|
-
});
|
|
948
|
-
}
|
|
949
|
-
var oldValue = this.value;
|
|
950
|
-
var wasSuspended =
|
|
951
|
-
/* see #1208 */ this.dependenciesState === exports.IDerivationState.NOT_TRACKING;
|
|
952
|
-
var newValue = this.computeValue(true);
|
|
953
|
-
var changed = wasSuspended ||
|
|
954
|
-
isCaughtException(oldValue) ||
|
|
955
|
-
isCaughtException(newValue) ||
|
|
956
|
-
!this.equals(oldValue, newValue);
|
|
957
|
-
if (changed) {
|
|
958
|
-
this.value = newValue;
|
|
959
|
-
}
|
|
960
|
-
return changed;
|
|
961
|
-
};
|
|
962
|
-
ComputedValue.prototype.computeValue = function (track) {
|
|
963
|
-
this.isComputing = true;
|
|
964
|
-
globalState.computationDepth++;
|
|
965
|
-
var res;
|
|
966
|
-
if (track) {
|
|
967
|
-
res = trackDerivedFunction(this, this.derivation, this.scope);
|
|
968
|
-
}
|
|
969
|
-
else {
|
|
970
|
-
if (globalState.disableErrorBoundaries === true) {
|
|
971
|
-
res = this.derivation.call(this.scope);
|
|
972
|
-
}
|
|
973
|
-
else {
|
|
974
|
-
try {
|
|
975
|
-
res = this.derivation.call(this.scope);
|
|
976
|
-
}
|
|
977
|
-
catch (e) {
|
|
978
|
-
res = new CaughtException(e);
|
|
979
|
-
}
|
|
980
|
-
}
|
|
981
|
-
}
|
|
982
|
-
globalState.computationDepth--;
|
|
983
|
-
this.isComputing = false;
|
|
984
|
-
return res;
|
|
985
|
-
};
|
|
986
|
-
ComputedValue.prototype.suspend = function () {
|
|
987
|
-
if (!this.keepAlive) {
|
|
988
|
-
clearObserving(this);
|
|
989
|
-
this.value = undefined; // don't hold on to computed value!
|
|
990
|
-
}
|
|
991
|
-
};
|
|
992
|
-
ComputedValue.prototype.observe = function (listener, fireImmediately) {
|
|
993
|
-
var _this = this;
|
|
994
|
-
var firstTime = true;
|
|
995
|
-
var prevValue = undefined;
|
|
996
|
-
return autorun(function () {
|
|
997
|
-
var newValue = _this.get();
|
|
998
|
-
if (!firstTime || fireImmediately) {
|
|
999
|
-
var prevU = untrackedStart();
|
|
1000
|
-
listener({
|
|
1001
|
-
type: "update",
|
|
1002
|
-
object: _this,
|
|
1003
|
-
newValue: newValue,
|
|
1004
|
-
oldValue: prevValue
|
|
1005
|
-
});
|
|
1006
|
-
untrackedEnd(prevU);
|
|
1007
|
-
}
|
|
1008
|
-
firstTime = false;
|
|
1009
|
-
prevValue = newValue;
|
|
1010
|
-
});
|
|
1011
|
-
};
|
|
1012
|
-
ComputedValue.prototype.warnAboutUntrackedRead = function () {
|
|
1013
|
-
if (process.env.NODE_ENV === "production")
|
|
1014
|
-
return;
|
|
1015
|
-
if (this.requiresReaction === true) {
|
|
1016
|
-
fail("[mobx] Computed value " + this.name + " is read outside a reactive context");
|
|
1017
|
-
}
|
|
1018
|
-
if (this.isTracing !== TraceMode.NONE) {
|
|
1019
|
-
console.log("[mobx.trace] '" + this.name + "' is being read outside a reactive context. Doing a full recompute");
|
|
1020
|
-
}
|
|
1021
|
-
if (globalState.computedRequiresReaction) {
|
|
1022
|
-
console.warn("[mobx] Computed value " + this.name + " is being read outside a reactive context. Doing a full recompute");
|
|
1023
|
-
}
|
|
1024
|
-
};
|
|
1025
|
-
ComputedValue.prototype.toJSON = function () {
|
|
1026
|
-
return this.get();
|
|
1027
|
-
};
|
|
1028
|
-
ComputedValue.prototype.toString = function () {
|
|
1029
|
-
return this.name + "[" + this.derivation.toString() + "]";
|
|
1030
|
-
};
|
|
1031
|
-
ComputedValue.prototype.valueOf = function () {
|
|
1032
|
-
return toPrimitive(this.get());
|
|
1033
|
-
};
|
|
1034
|
-
return ComputedValue;
|
|
1035
|
-
}());
|
|
1036
|
-
ComputedValue.prototype[primitiveSymbol()] = ComputedValue.prototype.valueOf;
|
|
1037
|
-
var isComputedValue = createInstanceofPredicate("ComputedValue", ComputedValue);
|
|
1038
|
-
|
|
1039
|
-
(function (IDerivationState) {
|
|
1040
|
-
// before being run or (outside batch and not being observed)
|
|
1041
|
-
// at this point derivation is not holding any data about dependency tree
|
|
1042
|
-
IDerivationState[IDerivationState["NOT_TRACKING"] = -1] = "NOT_TRACKING";
|
|
1043
|
-
// no shallow dependency changed since last computation
|
|
1044
|
-
// won't recalculate derivation
|
|
1045
|
-
// this is what makes mobx fast
|
|
1046
|
-
IDerivationState[IDerivationState["UP_TO_DATE"] = 0] = "UP_TO_DATE";
|
|
1047
|
-
// some deep dependency changed, but don't know if shallow dependency changed
|
|
1048
|
-
// will require to check first if UP_TO_DATE or POSSIBLY_STALE
|
|
1049
|
-
// currently only ComputedValue will propagate POSSIBLY_STALE
|
|
1050
|
-
//
|
|
1051
|
-
// having this state is second big optimization:
|
|
1052
|
-
// don't have to recompute on every dependency change, but only when it's needed
|
|
1053
|
-
IDerivationState[IDerivationState["POSSIBLY_STALE"] = 1] = "POSSIBLY_STALE";
|
|
1054
|
-
// A shallow dependency has changed since last computation and the derivation
|
|
1055
|
-
// will need to recompute when it's needed next.
|
|
1056
|
-
IDerivationState[IDerivationState["STALE"] = 2] = "STALE";
|
|
1057
|
-
})(exports.IDerivationState || (exports.IDerivationState = {}));
|
|
1058
|
-
var TraceMode;
|
|
1059
|
-
(function (TraceMode) {
|
|
1060
|
-
TraceMode[TraceMode["NONE"] = 0] = "NONE";
|
|
1061
|
-
TraceMode[TraceMode["LOG"] = 1] = "LOG";
|
|
1062
|
-
TraceMode[TraceMode["BREAK"] = 2] = "BREAK";
|
|
1063
|
-
})(TraceMode || (TraceMode = {}));
|
|
1064
|
-
var CaughtException = /** @class */ (function () {
|
|
1065
|
-
function CaughtException(cause) {
|
|
1066
|
-
this.cause = cause;
|
|
1067
|
-
// Empty
|
|
1068
|
-
}
|
|
1069
|
-
return CaughtException;
|
|
1070
|
-
}());
|
|
1071
|
-
function isCaughtException(e) {
|
|
1072
|
-
return e instanceof CaughtException;
|
|
1073
|
-
}
|
|
1074
|
-
/**
|
|
1075
|
-
* Finds out whether any dependency of the derivation has actually changed.
|
|
1076
|
-
* If dependenciesState is 1 then it will recalculate dependencies,
|
|
1077
|
-
* if any dependency changed it will propagate it by changing dependenciesState to 2.
|
|
1078
|
-
*
|
|
1079
|
-
* By iterating over the dependencies in the same order that they were reported and
|
|
1080
|
-
* stopping on the first change, all the recalculations are only called for ComputedValues
|
|
1081
|
-
* that will be tracked by derivation. That is because we assume that if the first x
|
|
1082
|
-
* dependencies of the derivation doesn't change then the derivation should run the same way
|
|
1083
|
-
* up until accessing x-th dependency.
|
|
1084
|
-
*/
|
|
1085
|
-
function shouldCompute(derivation) {
|
|
1086
|
-
switch (derivation.dependenciesState) {
|
|
1087
|
-
case exports.IDerivationState.UP_TO_DATE:
|
|
1088
|
-
return false;
|
|
1089
|
-
case exports.IDerivationState.NOT_TRACKING:
|
|
1090
|
-
case exports.IDerivationState.STALE:
|
|
1091
|
-
return true;
|
|
1092
|
-
case exports.IDerivationState.POSSIBLY_STALE: {
|
|
1093
|
-
var prevUntracked = untrackedStart(); // no need for those computeds to be reported, they will be picked up in trackDerivedFunction.
|
|
1094
|
-
var obs = derivation.observing, l = obs.length;
|
|
1095
|
-
for (var i = 0; i < l; i++) {
|
|
1096
|
-
var obj = obs[i];
|
|
1097
|
-
if (isComputedValue(obj)) {
|
|
1098
|
-
if (globalState.disableErrorBoundaries) {
|
|
1099
|
-
obj.get();
|
|
1100
|
-
}
|
|
1101
|
-
else {
|
|
1102
|
-
try {
|
|
1103
|
-
obj.get();
|
|
1104
|
-
}
|
|
1105
|
-
catch (e) {
|
|
1106
|
-
// we are not interested in the value *or* exception at this moment, but if there is one, notify all
|
|
1107
|
-
untrackedEnd(prevUntracked);
|
|
1108
|
-
return true;
|
|
1109
|
-
}
|
|
1110
|
-
}
|
|
1111
|
-
// if ComputedValue `obj` actually changed it will be computed and propagated to its observers.
|
|
1112
|
-
// and `derivation` is an observer of `obj`
|
|
1113
|
-
// invariantShouldCompute(derivation)
|
|
1114
|
-
if (derivation.dependenciesState === exports.IDerivationState.STALE) {
|
|
1115
|
-
untrackedEnd(prevUntracked);
|
|
1116
|
-
return true;
|
|
1117
|
-
}
|
|
1118
|
-
}
|
|
1119
|
-
}
|
|
1120
|
-
changeDependenciesStateTo0(derivation);
|
|
1121
|
-
untrackedEnd(prevUntracked);
|
|
1122
|
-
return false;
|
|
1237
|
+
type: "compute",
|
|
1238
|
+
name: this.name
|
|
1239
|
+
});
|
|
1123
1240
|
}
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
// }
|
|
1135
|
-
function isComputingDerivation() {
|
|
1136
|
-
return globalState.trackingDerivation !== null; // filter out actions inside computations
|
|
1137
|
-
}
|
|
1138
|
-
function checkIfStateModificationsAreAllowed(atom) {
|
|
1139
|
-
var hasObservers = atom.observers.length > 0;
|
|
1140
|
-
// Should never be possible to change an observed observable from inside computed, see #798
|
|
1141
|
-
if (globalState.computationDepth > 0 && hasObservers)
|
|
1142
|
-
fail(process.env.NODE_ENV !== "production" &&
|
|
1143
|
-
"Computed values are not allowed to cause side effects by changing observables that are already being observed. Tried to modify: " + atom.name);
|
|
1144
|
-
// Should not be possible to change observed state outside strict mode, except during initialization, see #563
|
|
1145
|
-
if (!globalState.allowStateChanges && (hasObservers || globalState.enforceActions === "strict"))
|
|
1146
|
-
fail(process.env.NODE_ENV !== "production" &&
|
|
1147
|
-
(globalState.enforceActions
|
|
1148
|
-
? "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: "
|
|
1149
|
-
: "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: ") +
|
|
1150
|
-
atom.name);
|
|
1151
|
-
}
|
|
1152
|
-
/**
|
|
1153
|
-
* Executes the provided function `f` and tracks which observables are being accessed.
|
|
1154
|
-
* The tracking information is stored on the `derivation` object and the derivation is registered
|
|
1155
|
-
* as observer of any of the accessed observables.
|
|
1156
|
-
*/
|
|
1157
|
-
function trackDerivedFunction(derivation, f, context) {
|
|
1158
|
-
// pre allocate array allocation + room for variation in deps
|
|
1159
|
-
// array will be trimmed by bindDependencies
|
|
1160
|
-
changeDependenciesStateTo0(derivation);
|
|
1161
|
-
derivation.newObserving = new Array(derivation.observing.length + 100);
|
|
1162
|
-
derivation.unboundDepsCount = 0;
|
|
1163
|
-
derivation.runId = ++globalState.runId;
|
|
1164
|
-
var prevTracking = globalState.trackingDerivation;
|
|
1165
|
-
globalState.trackingDerivation = derivation;
|
|
1166
|
-
var result;
|
|
1167
|
-
if (globalState.disableErrorBoundaries === true) {
|
|
1168
|
-
result = f.call(context);
|
|
1169
|
-
}
|
|
1170
|
-
else {
|
|
1171
|
-
try {
|
|
1172
|
-
result = f.call(context);
|
|
1241
|
+
var oldValue = this.value;
|
|
1242
|
+
var wasSuspended =
|
|
1243
|
+
/* see #1208 */ this.dependenciesState === exports.IDerivationState.NOT_TRACKING;
|
|
1244
|
+
var newValue = this.computeValue(true);
|
|
1245
|
+
var changed = wasSuspended ||
|
|
1246
|
+
isCaughtException(oldValue) ||
|
|
1247
|
+
isCaughtException(newValue) ||
|
|
1248
|
+
!this.equals(oldValue, newValue);
|
|
1249
|
+
if (changed) {
|
|
1250
|
+
this.value = newValue;
|
|
1173
1251
|
}
|
|
1174
|
-
|
|
1175
|
-
|
|
1252
|
+
return changed;
|
|
1253
|
+
};
|
|
1254
|
+
ComputedValue.prototype.computeValue = function (track) {
|
|
1255
|
+
this.isComputing = true;
|
|
1256
|
+
globalState.computationDepth++;
|
|
1257
|
+
var res;
|
|
1258
|
+
if (track) {
|
|
1259
|
+
res = trackDerivedFunction(this, this.derivation, this.scope);
|
|
1176
1260
|
}
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
var prevObserving = derivation.observing;
|
|
1190
|
-
var observing = (derivation.observing = derivation.newObserving);
|
|
1191
|
-
var lowestNewObservingDerivationState = exports.IDerivationState.UP_TO_DATE;
|
|
1192
|
-
// Go through all new observables and check diffValue: (this list can contain duplicates):
|
|
1193
|
-
// 0: first occurrence, change to 1 and keep it
|
|
1194
|
-
// 1: extra occurrence, drop it
|
|
1195
|
-
var i0 = 0, l = derivation.unboundDepsCount;
|
|
1196
|
-
for (var i = 0; i < l; i++) {
|
|
1197
|
-
var dep = observing[i];
|
|
1198
|
-
if (dep.diffValue === 0) {
|
|
1199
|
-
dep.diffValue = 1;
|
|
1200
|
-
if (i0 !== i)
|
|
1201
|
-
observing[i0] = dep;
|
|
1202
|
-
i0++;
|
|
1261
|
+
else {
|
|
1262
|
+
if (globalState.disableErrorBoundaries === true) {
|
|
1263
|
+
res = this.derivation.call(this.scope);
|
|
1264
|
+
}
|
|
1265
|
+
else {
|
|
1266
|
+
try {
|
|
1267
|
+
res = this.derivation.call(this.scope);
|
|
1268
|
+
}
|
|
1269
|
+
catch (e) {
|
|
1270
|
+
res = new CaughtException(e);
|
|
1271
|
+
}
|
|
1272
|
+
}
|
|
1203
1273
|
}
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1274
|
+
globalState.computationDepth--;
|
|
1275
|
+
this.isComputing = false;
|
|
1276
|
+
return res;
|
|
1277
|
+
};
|
|
1278
|
+
ComputedValue.prototype.suspend = function () {
|
|
1279
|
+
if (!this.keepAlive) {
|
|
1280
|
+
clearObserving(this);
|
|
1281
|
+
this.value = undefined; // don't hold on to computed value!
|
|
1208
1282
|
}
|
|
1209
|
-
}
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1283
|
+
};
|
|
1284
|
+
ComputedValue.prototype.observe = function (listener, fireImmediately) {
|
|
1285
|
+
var _this = this;
|
|
1286
|
+
var firstTime = true;
|
|
1287
|
+
var prevValue = undefined;
|
|
1288
|
+
return autorun(function () {
|
|
1289
|
+
var newValue = _this.get();
|
|
1290
|
+
if (!firstTime || fireImmediately) {
|
|
1291
|
+
var prevU = untrackedStart();
|
|
1292
|
+
listener({
|
|
1293
|
+
type: "update",
|
|
1294
|
+
object: _this,
|
|
1295
|
+
newValue: newValue,
|
|
1296
|
+
oldValue: prevValue
|
|
1297
|
+
});
|
|
1298
|
+
untrackedEnd(prevU);
|
|
1299
|
+
}
|
|
1300
|
+
firstTime = false;
|
|
1301
|
+
prevValue = newValue;
|
|
1302
|
+
});
|
|
1303
|
+
};
|
|
1304
|
+
ComputedValue.prototype.warnAboutUntrackedRead = function () {
|
|
1305
|
+
if (process.env.NODE_ENV === "production")
|
|
1306
|
+
return;
|
|
1307
|
+
if (this.requiresReaction === true) {
|
|
1308
|
+
fail("[mobx] Computed value " + this.name + " is read outside a reactive context");
|
|
1220
1309
|
}
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
// Go through all new observables and check diffValue: (now it should be unique)
|
|
1224
|
-
// 0: it was set to 0 in last loop. don't need to do anything.
|
|
1225
|
-
// 1: it wasn't observed, let's observe it. set back to 0
|
|
1226
|
-
while (i0--) {
|
|
1227
|
-
var dep = observing[i0];
|
|
1228
|
-
if (dep.diffValue === 1) {
|
|
1229
|
-
dep.diffValue = 0;
|
|
1230
|
-
addObserver(dep, derivation);
|
|
1310
|
+
if (this.isTracing !== TraceMode.NONE) {
|
|
1311
|
+
console.log("[mobx.trace] '" + this.name + "' is being read outside a reactive context. Doing a full recompute");
|
|
1231
1312
|
}
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
}
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
function untracked(action) {
|
|
1250
|
-
var prev = untrackedStart();
|
|
1251
|
-
var res = action();
|
|
1252
|
-
untrackedEnd(prev);
|
|
1253
|
-
return res;
|
|
1254
|
-
}
|
|
1255
|
-
function untrackedStart() {
|
|
1256
|
-
var prev = globalState.trackingDerivation;
|
|
1257
|
-
globalState.trackingDerivation = null;
|
|
1258
|
-
return prev;
|
|
1259
|
-
}
|
|
1260
|
-
function untrackedEnd(prev) {
|
|
1261
|
-
globalState.trackingDerivation = prev;
|
|
1262
|
-
}
|
|
1263
|
-
/**
|
|
1264
|
-
* needed to keep `lowestObserverState` correct. when changing from (2 or 1) to 0
|
|
1265
|
-
*
|
|
1266
|
-
*/
|
|
1267
|
-
function changeDependenciesStateTo0(derivation) {
|
|
1268
|
-
if (derivation.dependenciesState === exports.IDerivationState.UP_TO_DATE)
|
|
1269
|
-
return;
|
|
1270
|
-
derivation.dependenciesState = exports.IDerivationState.UP_TO_DATE;
|
|
1271
|
-
var obs = derivation.observing;
|
|
1272
|
-
var i = obs.length;
|
|
1273
|
-
while (i--)
|
|
1274
|
-
obs[i].lowestObserverState = exports.IDerivationState.UP_TO_DATE;
|
|
1275
|
-
}
|
|
1313
|
+
if (globalState.computedRequiresReaction) {
|
|
1314
|
+
console.warn("[mobx] Computed value " + this.name + " is being read outside a reactive context. Doing a full recompute");
|
|
1315
|
+
}
|
|
1316
|
+
};
|
|
1317
|
+
ComputedValue.prototype.toJSON = function () {
|
|
1318
|
+
return this.get();
|
|
1319
|
+
};
|
|
1320
|
+
ComputedValue.prototype.toString = function () {
|
|
1321
|
+
return this.name + "[" + this.derivation.toString() + "]";
|
|
1322
|
+
};
|
|
1323
|
+
ComputedValue.prototype.valueOf = function () {
|
|
1324
|
+
return toPrimitive(this.get());
|
|
1325
|
+
};
|
|
1326
|
+
return ComputedValue;
|
|
1327
|
+
}());
|
|
1328
|
+
ComputedValue.prototype[primitiveSymbol()] = ComputedValue.prototype.valueOf;
|
|
1329
|
+
var isComputedValue = createInstanceofPredicate("ComputedValue", ComputedValue);
|
|
1276
1330
|
|
|
1277
1331
|
/**
|
|
1278
1332
|
* These values will persist if global state is reset
|
|
@@ -1282,6 +1336,9 @@ var persistentKeys = [
|
|
|
1282
1336
|
"spyListeners",
|
|
1283
1337
|
"enforceActions",
|
|
1284
1338
|
"computedRequiresReaction",
|
|
1339
|
+
"reactionRequiresObservable",
|
|
1340
|
+
"observableRequiresReaction",
|
|
1341
|
+
"allowStateReads",
|
|
1285
1342
|
"disableErrorBoundaries",
|
|
1286
1343
|
"runId",
|
|
1287
1344
|
"UNCHANGED"
|
|
@@ -1342,6 +1399,11 @@ var MobXGlobals = /** @class */ (function () {
|
|
|
1342
1399
|
* To ensure that those functions stay pure.
|
|
1343
1400
|
*/
|
|
1344
1401
|
this.allowStateChanges = true;
|
|
1402
|
+
/**
|
|
1403
|
+
* Is it allowed to read observables at this point?
|
|
1404
|
+
* Used to hold the state needed for `observableRequiresReaction`
|
|
1405
|
+
*/
|
|
1406
|
+
this.allowStateReads = true;
|
|
1345
1407
|
/**
|
|
1346
1408
|
* If strict mode is enabled, state changes are by default not allowed
|
|
1347
1409
|
*/
|
|
@@ -1358,6 +1420,16 @@ var MobXGlobals = /** @class */ (function () {
|
|
|
1358
1420
|
* Warn if computed values are accessed outside a reactive context
|
|
1359
1421
|
*/
|
|
1360
1422
|
this.computedRequiresReaction = false;
|
|
1423
|
+
/**
|
|
1424
|
+
* (Experimental)
|
|
1425
|
+
* Warn if you try to create to derivation / reactive context without accessing any observable.
|
|
1426
|
+
*/
|
|
1427
|
+
this.reactionRequiresObservable = false;
|
|
1428
|
+
/**
|
|
1429
|
+
* (Experimental)
|
|
1430
|
+
* Warn if observables are accessed outside a reactive context
|
|
1431
|
+
*/
|
|
1432
|
+
this.observableRequiresReaction = false;
|
|
1361
1433
|
/**
|
|
1362
1434
|
* Allows overwriting of computed properties, useful in tests but not prod as it can cause
|
|
1363
1435
|
* memory leaks. See https://github.com/mobxjs/mobx/issues/1867
|
|
@@ -1539,6 +1611,7 @@ function endBatch() {
|
|
|
1539
1611
|
}
|
|
1540
1612
|
}
|
|
1541
1613
|
function reportObserved(observable) {
|
|
1614
|
+
checkIfStateReadsAreAllowed(observable);
|
|
1542
1615
|
var derivation = globalState.trackingDerivation;
|
|
1543
1616
|
if (derivation !== null) {
|
|
1544
1617
|
/**
|
|
@@ -1659,11 +1732,13 @@ function printDepTree(tree, lines, depth) {
|
|
|
1659
1732
|
}
|
|
1660
1733
|
|
|
1661
1734
|
var Reaction = /** @class */ (function () {
|
|
1662
|
-
function Reaction(name, onInvalidate, errorHandler) {
|
|
1735
|
+
function Reaction(name, onInvalidate, errorHandler, requiresObservable) {
|
|
1663
1736
|
if (name === void 0) { name = "Reaction@" + getNextId(); }
|
|
1737
|
+
if (requiresObservable === void 0) { requiresObservable = false; }
|
|
1664
1738
|
this.name = name;
|
|
1665
1739
|
this.onInvalidate = onInvalidate;
|
|
1666
1740
|
this.errorHandler = errorHandler;
|
|
1741
|
+
this.requiresObservable = requiresObservable;
|
|
1667
1742
|
this.observing = []; // nodes we are looking at. Our value depends on these nodes
|
|
1668
1743
|
this.newObserving = [];
|
|
1669
1744
|
this.dependenciesState = exports.IDerivationState.NOT_TRACKING;
|
|
@@ -2009,7 +2084,7 @@ function autorun(view, opts) {
|
|
|
2009
2084
|
// normal autorun
|
|
2010
2085
|
reaction = new Reaction(name, function () {
|
|
2011
2086
|
this.track(reactionRunner);
|
|
2012
|
-
}, opts.onError);
|
|
2087
|
+
}, opts.onError, opts.requiresObservable);
|
|
2013
2088
|
}
|
|
2014
2089
|
else {
|
|
2015
2090
|
var scheduler_1 = createSchedulerFromOptions(opts);
|
|
@@ -2024,7 +2099,7 @@ function autorun(view, opts) {
|
|
|
2024
2099
|
reaction.track(reactionRunner);
|
|
2025
2100
|
});
|
|
2026
2101
|
}
|
|
2027
|
-
}, opts.onError);
|
|
2102
|
+
}, opts.onError, opts.requiresObservable);
|
|
2028
2103
|
}
|
|
2029
2104
|
function reactionRunner() {
|
|
2030
2105
|
view(reaction);
|
|
@@ -2068,7 +2143,7 @@ function reaction(expression, effect, opts) {
|
|
|
2068
2143
|
isScheduled = true;
|
|
2069
2144
|
scheduler(reactionRunner);
|
|
2070
2145
|
}
|
|
2071
|
-
}, opts.onError);
|
|
2146
|
+
}, opts.onError, opts.requiresObservable);
|
|
2072
2147
|
function reactionRunner() {
|
|
2073
2148
|
isScheduled = false; // Q: move into reaction runner?
|
|
2074
2149
|
if (r.isDisposed)
|
|
@@ -2107,8 +2182,8 @@ function onBecomeUnobserved(thing, arg2, arg3) {
|
|
|
2107
2182
|
return interceptHook("onBecomeUnobserved", thing, arg2, arg3);
|
|
2108
2183
|
}
|
|
2109
2184
|
function interceptHook(hook, thing, arg2, arg3) {
|
|
2110
|
-
var atom = typeof
|
|
2111
|
-
var cb = typeof
|
|
2185
|
+
var atom = typeof arg3 === "function" ? getAtom(thing, arg2) : getAtom(thing);
|
|
2186
|
+
var cb = typeof arg3 === "function" ? arg3 : arg2;
|
|
2112
2187
|
var orig = atom[hook];
|
|
2113
2188
|
if (typeof orig !== "function")
|
|
2114
2189
|
return fail(process.env.NODE_ENV !== "production" && "Not an atom that can be (un)observed");
|
|
@@ -2122,7 +2197,7 @@ function interceptHook(hook, thing, arg2, arg3) {
|
|
|
2122
2197
|
}
|
|
2123
2198
|
|
|
2124
2199
|
function configure(options) {
|
|
2125
|
-
var enforceActions = options.enforceActions, computedRequiresReaction = options.computedRequiresReaction, computedConfigurable = options.computedConfigurable, disableErrorBoundaries = options.disableErrorBoundaries, arrayBuffer = options.arrayBuffer, reactionScheduler = options.reactionScheduler;
|
|
2200
|
+
var enforceActions = options.enforceActions, computedRequiresReaction = options.computedRequiresReaction, computedConfigurable = options.computedConfigurable, disableErrorBoundaries = options.disableErrorBoundaries, arrayBuffer = options.arrayBuffer, reactionScheduler = options.reactionScheduler, reactionRequiresObservable = options.reactionRequiresObservable, observableRequiresReaction = options.observableRequiresReaction;
|
|
2126
2201
|
if (options.isolateGlobalState === true) {
|
|
2127
2202
|
isolateGlobalState();
|
|
2128
2203
|
}
|
|
@@ -2152,6 +2227,13 @@ function configure(options) {
|
|
|
2152
2227
|
if (computedRequiresReaction !== undefined) {
|
|
2153
2228
|
globalState.computedRequiresReaction = !!computedRequiresReaction;
|
|
2154
2229
|
}
|
|
2230
|
+
if (reactionRequiresObservable !== undefined) {
|
|
2231
|
+
globalState.reactionRequiresObservable = !!reactionRequiresObservable;
|
|
2232
|
+
}
|
|
2233
|
+
if (observableRequiresReaction !== undefined) {
|
|
2234
|
+
globalState.observableRequiresReaction = !!observableRequiresReaction;
|
|
2235
|
+
globalState.allowStateReads = !globalState.observableRequiresReaction;
|
|
2236
|
+
}
|
|
2155
2237
|
if (computedConfigurable !== undefined) {
|
|
2156
2238
|
globalState.computedConfigurable = !!computedConfigurable;
|
|
2157
2239
|
}
|
|
@@ -3407,9 +3489,17 @@ var ObservableMap = /** @class */ (function () {
|
|
|
3407
3489
|
return this._data.has(key);
|
|
3408
3490
|
};
|
|
3409
3491
|
ObservableMap.prototype.has = function (key) {
|
|
3410
|
-
|
|
3411
|
-
|
|
3412
|
-
|
|
3492
|
+
var _this = this;
|
|
3493
|
+
if (!globalState.trackingDerivation)
|
|
3494
|
+
return this._has(key);
|
|
3495
|
+
var entry = this._hasMap.get(key);
|
|
3496
|
+
if (!entry) {
|
|
3497
|
+
// todo: replace with atom (breaking change)
|
|
3498
|
+
var newEntry = (entry = new ObservableValue(this._has(key), referenceEnhancer, this.name + "." + stringifyKey(key) + "?", false));
|
|
3499
|
+
this._hasMap.set(key, newEntry);
|
|
3500
|
+
onBecomeUnobserved(newEntry, function () { return _this._hasMap.delete(key); });
|
|
3501
|
+
}
|
|
3502
|
+
return entry.get();
|
|
3413
3503
|
};
|
|
3414
3504
|
ObservableMap.prototype.set = function (key, value) {
|
|
3415
3505
|
var hasKey = this._has(key);
|
|
@@ -3472,16 +3562,10 @@ var ObservableMap = /** @class */ (function () {
|
|
|
3472
3562
|
return false;
|
|
3473
3563
|
};
|
|
3474
3564
|
ObservableMap.prototype._updateHasMapEntry = function (key, value) {
|
|
3475
|
-
// optimization; don't fill the hasMap if we are not observing, or remove entry if there are no observers anymore
|
|
3476
3565
|
var entry = this._hasMap.get(key);
|
|
3477
3566
|
if (entry) {
|
|
3478
3567
|
entry.setNewValue(value);
|
|
3479
3568
|
}
|
|
3480
|
-
else {
|
|
3481
|
-
entry = new ObservableValue(value, referenceEnhancer, this.name + "." + stringifyKey(key) + "?", false);
|
|
3482
|
-
this._hasMap.set(key, entry);
|
|
3483
|
-
}
|
|
3484
|
-
return entry;
|
|
3485
3569
|
};
|
|
3486
3570
|
ObservableMap.prototype._updateValue = function (key, newValue) {
|
|
3487
3571
|
var observable = this._data.get(key);
|
|
@@ -3614,14 +3698,32 @@ var ObservableMap = /** @class */ (function () {
|
|
|
3614
3698
|
ObservableMap.prototype.replace = function (values) {
|
|
3615
3699
|
var _this = this;
|
|
3616
3700
|
transaction(function () {
|
|
3617
|
-
|
|
3618
|
-
// and delete them from the map, then merge the new map
|
|
3619
|
-
// this will cause reactions only on changed values
|
|
3620
|
-
var newKeys = getMapLikeKeys(values);
|
|
3701
|
+
var replacementMap = convertToMap(values);
|
|
3621
3702
|
var oldKeys = _this._keys;
|
|
3622
|
-
var
|
|
3623
|
-
|
|
3624
|
-
|
|
3703
|
+
var newKeys = Array.from(replacementMap.keys());
|
|
3704
|
+
var keysChanged = false;
|
|
3705
|
+
for (var i = 0; i < oldKeys.length; i++) {
|
|
3706
|
+
var oldKey = oldKeys[i];
|
|
3707
|
+
// key order change
|
|
3708
|
+
if (oldKeys.length === newKeys.length && oldKey !== newKeys[i]) {
|
|
3709
|
+
keysChanged = true;
|
|
3710
|
+
}
|
|
3711
|
+
// deleted key
|
|
3712
|
+
if (!replacementMap.has(oldKey)) {
|
|
3713
|
+
keysChanged = true;
|
|
3714
|
+
_this.delete(oldKey);
|
|
3715
|
+
}
|
|
3716
|
+
}
|
|
3717
|
+
replacementMap.forEach(function (value, key) {
|
|
3718
|
+
// new key
|
|
3719
|
+
if (!_this._data.has(key)) {
|
|
3720
|
+
keysChanged = true;
|
|
3721
|
+
}
|
|
3722
|
+
_this.set(key, value);
|
|
3723
|
+
});
|
|
3724
|
+
if (keysChanged) {
|
|
3725
|
+
_this._keys.replace(newKeys);
|
|
3726
|
+
}
|
|
3625
3727
|
});
|
|
3626
3728
|
return this;
|
|
3627
3729
|
};
|
|
@@ -4225,12 +4327,13 @@ function getDebugName(thing, property) {
|
|
|
4225
4327
|
}
|
|
4226
4328
|
|
|
4227
4329
|
var toString = Object.prototype.toString;
|
|
4228
|
-
function deepEqual(a, b) {
|
|
4229
|
-
|
|
4330
|
+
function deepEqual(a, b, depth) {
|
|
4331
|
+
if (depth === void 0) { depth = -1; }
|
|
4332
|
+
return eq(a, b, depth);
|
|
4230
4333
|
}
|
|
4231
4334
|
// Copied from https://github.com/jashkenas/underscore/blob/5c237a7c682fb68fd5378203f0bf22dce1624854/underscore.js#L1186-L1289
|
|
4232
4335
|
// Internal recursive comparison function for `isEqual`.
|
|
4233
|
-
function eq(a, b, aStack, bStack) {
|
|
4336
|
+
function eq(a, b, depth, aStack, bStack) {
|
|
4234
4337
|
// Identical objects are equal. `0 === -0`, but they aren't identical.
|
|
4235
4338
|
// See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).
|
|
4236
4339
|
if (a === b)
|
|
@@ -4245,10 +4348,6 @@ function eq(a, b, aStack, bStack) {
|
|
|
4245
4348
|
var type = typeof a;
|
|
4246
4349
|
if (type !== "function" && type !== "object" && typeof b != "object")
|
|
4247
4350
|
return false;
|
|
4248
|
-
return deepEq(a, b, aStack, bStack);
|
|
4249
|
-
}
|
|
4250
|
-
// Internal recursive comparison function for `isEqual`.
|
|
4251
|
-
function deepEq(a, b, aStack, bStack) {
|
|
4252
4351
|
// Unwrap any wrapped objects.
|
|
4253
4352
|
a = unwrap(a);
|
|
4254
4353
|
b = unwrap(b);
|
|
@@ -4298,6 +4397,12 @@ function deepEq(a, b, aStack, bStack) {
|
|
|
4298
4397
|
return false;
|
|
4299
4398
|
}
|
|
4300
4399
|
}
|
|
4400
|
+
if (depth === 0) {
|
|
4401
|
+
return false;
|
|
4402
|
+
}
|
|
4403
|
+
else if (depth < 0) {
|
|
4404
|
+
depth = -1;
|
|
4405
|
+
}
|
|
4301
4406
|
// Assume equality for cyclic structures. The algorithm for detecting cyclic
|
|
4302
4407
|
// structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
|
|
4303
4408
|
// Initializing stack of traversed objects.
|
|
@@ -4322,7 +4427,7 @@ function deepEq(a, b, aStack, bStack) {
|
|
|
4322
4427
|
return false;
|
|
4323
4428
|
// Deep compare the contents, ignoring non-numeric properties.
|
|
4324
4429
|
while (length--) {
|
|
4325
|
-
if (!eq(a[length], b[length], aStack, bStack))
|
|
4430
|
+
if (!eq(a[length], b[length], depth - 1, aStack, bStack))
|
|
4326
4431
|
return false;
|
|
4327
4432
|
}
|
|
4328
4433
|
}
|
|
@@ -4337,7 +4442,7 @@ function deepEq(a, b, aStack, bStack) {
|
|
|
4337
4442
|
while (length--) {
|
|
4338
4443
|
// Deep compare each member
|
|
4339
4444
|
key = keys[length];
|
|
4340
|
-
if (!(has$1(b, key) && eq(a[key], b[key], aStack, bStack)))
|
|
4445
|
+
if (!(has$1(b, key) && eq(a[key], b[key], depth - 1, aStack, bStack)))
|
|
4341
4446
|
return false;
|
|
4342
4447
|
}
|
|
4343
4448
|
}
|
|
@@ -4392,7 +4497,7 @@ try {
|
|
|
4392
4497
|
process.env.NODE_ENV;
|
|
4393
4498
|
}
|
|
4394
4499
|
catch (e) {
|
|
4395
|
-
var g =
|
|
4500
|
+
var g = getGlobal();
|
|
4396
4501
|
if (typeof process === "undefined")
|
|
4397
4502
|
g.process = {};
|
|
4398
4503
|
g.process.env = {};
|
|
@@ -4467,11 +4572,13 @@ exports.ObservableSet = ObservableSet;
|
|
|
4467
4572
|
exports.Reaction = Reaction;
|
|
4468
4573
|
exports._allowStateChanges = allowStateChanges;
|
|
4469
4574
|
exports._allowStateChangesInsideComputed = allowStateChangesInsideComputed;
|
|
4575
|
+
exports._endAction = _endAction;
|
|
4470
4576
|
exports._getAdministration = getAdministration;
|
|
4471
4577
|
exports._getGlobalState = getGlobalState;
|
|
4472
4578
|
exports._interceptReads = interceptReads;
|
|
4473
4579
|
exports._isComputingDerivation = isComputingDerivation;
|
|
4474
4580
|
exports._resetGlobalState = resetGlobalState;
|
|
4581
|
+
exports._startAction = _startAction;
|
|
4475
4582
|
exports.action = action;
|
|
4476
4583
|
exports.autorun = autorun;
|
|
4477
4584
|
exports.comparer = comparer;
|