mobx 5.10.1 → 5.14.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 +29 -1
- package/LICENSE +0 -0
- package/README.md +66 -52
- package/lib/api/action.d.ts +0 -0
- package/lib/api/actiondecorator.d.ts +0 -0
- package/lib/api/autorun.d.ts +5 -0
- package/lib/api/become-observed.d.ts +0 -0
- package/lib/api/computed.d.ts +0 -0
- package/lib/api/configure.d.ts +11 -0
- package/lib/api/decorate.d.ts +0 -0
- package/lib/api/extendobservable.d.ts +0 -0
- package/lib/api/extras.d.ts +0 -0
- package/lib/api/flow.d.ts +0 -0
- package/lib/api/intercept-read.d.ts +0 -0
- package/lib/api/intercept.d.ts +0 -0
- package/lib/api/iscomputed.d.ts +0 -0
- package/lib/api/isobservable.d.ts +0 -0
- package/lib/api/object-api.d.ts +2 -2
- package/lib/api/observable.d.ts +0 -0
- package/lib/api/observabledecorator.d.ts +0 -0
- package/lib/api/observe.d.ts +0 -0
- package/lib/api/tojs.d.ts +0 -0
- package/lib/api/trace.d.ts +0 -0
- package/lib/api/transaction.d.ts +0 -0
- package/lib/api/when.d.ts +5 -0
- package/lib/core/action.d.ts +13 -0
- package/lib/core/atom.d.ts +2 -2
- package/lib/core/computedvalue.d.ts +0 -0
- package/lib/core/derivation.d.ts +7 -0
- package/lib/core/globalstate.d.ts +22 -0
- package/lib/core/observable.d.ts +0 -0
- package/lib/core/reaction.d.ts +2 -1
- package/lib/core/spy.d.ts +0 -0
- package/lib/internal.d.ts +0 -0
- package/lib/mobx.d.ts +1 -1
- package/lib/mobx.es6.js +471 -382
- package/lib/mobx.js +485 -371
- package/lib/mobx.js.flow +20 -2
- package/lib/mobx.min.js +1 -1
- package/lib/mobx.module.js +485 -373
- package/lib/mobx.umd.js +485 -371
- package/lib/mobx.umd.min.js +1 -1
- package/lib/types/dynamicobject.d.ts +0 -0
- package/lib/types/intercept-utils.d.ts +0 -0
- package/lib/types/listen-utils.d.ts +0 -0
- package/lib/types/modifiers.d.ts +0 -0
- package/lib/types/observablearray.d.ts +0 -0
- package/lib/types/observablemap.d.ts +0 -0
- package/lib/types/observableobject.d.ts +0 -0
- package/lib/types/observableset.d.ts +0 -0
- package/lib/types/observablevalue.d.ts +0 -0
- package/lib/types/type-utils.d.ts +0 -0
- package/lib/utils/comparer.d.ts +0 -0
- package/lib/utils/decorators.d.ts +0 -0
- package/lib/utils/eq.d.ts +0 -0
- package/lib/utils/iterable.d.ts +0 -0
- package/lib/utils/utils.d.ts +0 -0
- package/package.json +7 -6
package/lib/mobx.module.js
CHANGED
|
@@ -593,6 +593,275 @@ var computed = function computed(arg1, arg2, arg3) {
|
|
|
593
593
|
};
|
|
594
594
|
computed.struct = computedStructDecorator;
|
|
595
595
|
|
|
596
|
+
var IDerivationState;
|
|
597
|
+
(function (IDerivationState) {
|
|
598
|
+
// before being run or (outside batch and not being observed)
|
|
599
|
+
// at this point derivation is not holding any data about dependency tree
|
|
600
|
+
IDerivationState[IDerivationState["NOT_TRACKING"] = -1] = "NOT_TRACKING";
|
|
601
|
+
// no shallow dependency changed since last computation
|
|
602
|
+
// won't recalculate derivation
|
|
603
|
+
// this is what makes mobx fast
|
|
604
|
+
IDerivationState[IDerivationState["UP_TO_DATE"] = 0] = "UP_TO_DATE";
|
|
605
|
+
// some deep dependency changed, but don't know if shallow dependency changed
|
|
606
|
+
// will require to check first if UP_TO_DATE or POSSIBLY_STALE
|
|
607
|
+
// currently only ComputedValue will propagate POSSIBLY_STALE
|
|
608
|
+
//
|
|
609
|
+
// having this state is second big optimization:
|
|
610
|
+
// don't have to recompute on every dependency change, but only when it's needed
|
|
611
|
+
IDerivationState[IDerivationState["POSSIBLY_STALE"] = 1] = "POSSIBLY_STALE";
|
|
612
|
+
// A shallow dependency has changed since last computation and the derivation
|
|
613
|
+
// will need to recompute when it's needed next.
|
|
614
|
+
IDerivationState[IDerivationState["STALE"] = 2] = "STALE";
|
|
615
|
+
})(IDerivationState || (IDerivationState = {}));
|
|
616
|
+
var TraceMode;
|
|
617
|
+
(function (TraceMode) {
|
|
618
|
+
TraceMode[TraceMode["NONE"] = 0] = "NONE";
|
|
619
|
+
TraceMode[TraceMode["LOG"] = 1] = "LOG";
|
|
620
|
+
TraceMode[TraceMode["BREAK"] = 2] = "BREAK";
|
|
621
|
+
})(TraceMode || (TraceMode = {}));
|
|
622
|
+
var CaughtException = /** @class */ (function () {
|
|
623
|
+
function CaughtException(cause) {
|
|
624
|
+
this.cause = cause;
|
|
625
|
+
// Empty
|
|
626
|
+
}
|
|
627
|
+
return CaughtException;
|
|
628
|
+
}());
|
|
629
|
+
function isCaughtException(e) {
|
|
630
|
+
return e instanceof CaughtException;
|
|
631
|
+
}
|
|
632
|
+
/**
|
|
633
|
+
* Finds out whether any dependency of the derivation has actually changed.
|
|
634
|
+
* If dependenciesState is 1 then it will recalculate dependencies,
|
|
635
|
+
* if any dependency changed it will propagate it by changing dependenciesState to 2.
|
|
636
|
+
*
|
|
637
|
+
* By iterating over the dependencies in the same order that they were reported and
|
|
638
|
+
* stopping on the first change, all the recalculations are only called for ComputedValues
|
|
639
|
+
* that will be tracked by derivation. That is because we assume that if the first x
|
|
640
|
+
* dependencies of the derivation doesn't change then the derivation should run the same way
|
|
641
|
+
* up until accessing x-th dependency.
|
|
642
|
+
*/
|
|
643
|
+
function shouldCompute(derivation) {
|
|
644
|
+
switch (derivation.dependenciesState) {
|
|
645
|
+
case IDerivationState.UP_TO_DATE:
|
|
646
|
+
return false;
|
|
647
|
+
case IDerivationState.NOT_TRACKING:
|
|
648
|
+
case IDerivationState.STALE:
|
|
649
|
+
return true;
|
|
650
|
+
case IDerivationState.POSSIBLY_STALE: {
|
|
651
|
+
var prevUntracked = untrackedStart(); // no need for those computeds to be reported, they will be picked up in trackDerivedFunction.
|
|
652
|
+
var obs = derivation.observing, l = obs.length;
|
|
653
|
+
for (var i = 0; i < l; i++) {
|
|
654
|
+
var obj = obs[i];
|
|
655
|
+
if (isComputedValue(obj)) {
|
|
656
|
+
if (globalState.disableErrorBoundaries) {
|
|
657
|
+
obj.get();
|
|
658
|
+
}
|
|
659
|
+
else {
|
|
660
|
+
try {
|
|
661
|
+
obj.get();
|
|
662
|
+
}
|
|
663
|
+
catch (e) {
|
|
664
|
+
// we are not interested in the value *or* exception at this moment, but if there is one, notify all
|
|
665
|
+
untrackedEnd(prevUntracked);
|
|
666
|
+
return true;
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
// if ComputedValue `obj` actually changed it will be computed and propagated to its observers.
|
|
670
|
+
// and `derivation` is an observer of `obj`
|
|
671
|
+
// invariantShouldCompute(derivation)
|
|
672
|
+
if (derivation.dependenciesState === IDerivationState.STALE) {
|
|
673
|
+
untrackedEnd(prevUntracked);
|
|
674
|
+
return true;
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
changeDependenciesStateTo0(derivation);
|
|
679
|
+
untrackedEnd(prevUntracked);
|
|
680
|
+
return false;
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
// function invariantShouldCompute(derivation: IDerivation) {
|
|
685
|
+
// const newDepState = (derivation as any).dependenciesState
|
|
686
|
+
// if (
|
|
687
|
+
// process.env.NODE_ENV === "production" &&
|
|
688
|
+
// (newDepState === IDerivationState.POSSIBLY_STALE ||
|
|
689
|
+
// newDepState === IDerivationState.NOT_TRACKING)
|
|
690
|
+
// )
|
|
691
|
+
// fail("Illegal dependency state")
|
|
692
|
+
// }
|
|
693
|
+
function isComputingDerivation() {
|
|
694
|
+
return globalState.trackingDerivation !== null; // filter out actions inside computations
|
|
695
|
+
}
|
|
696
|
+
function checkIfStateModificationsAreAllowed(atom) {
|
|
697
|
+
var hasObservers = atom.observers.size > 0;
|
|
698
|
+
// Should never be possible to change an observed observable from inside computed, see #798
|
|
699
|
+
if (globalState.computationDepth > 0 && hasObservers)
|
|
700
|
+
fail(process.env.NODE_ENV !== "production" &&
|
|
701
|
+
"Computed values are not allowed to cause side effects by changing observables that are already being observed. Tried to modify: " + atom.name);
|
|
702
|
+
// Should not be possible to change observed state outside strict mode, except during initialization, see #563
|
|
703
|
+
if (!globalState.allowStateChanges && (hasObservers || globalState.enforceActions === "strict"))
|
|
704
|
+
fail(process.env.NODE_ENV !== "production" &&
|
|
705
|
+
(globalState.enforceActions
|
|
706
|
+
? "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: "
|
|
707
|
+
: "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: ") +
|
|
708
|
+
atom.name);
|
|
709
|
+
}
|
|
710
|
+
function checkIfStateReadsAreAllowed(observable) {
|
|
711
|
+
if (process.env.NODE_ENV !== "production" &&
|
|
712
|
+
!globalState.allowStateReads &&
|
|
713
|
+
globalState.observableRequiresReaction) {
|
|
714
|
+
console.warn("[mobx] Observable " + observable.name + " being read outside a reactive context");
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
/**
|
|
718
|
+
* Executes the provided function `f` and tracks which observables are being accessed.
|
|
719
|
+
* The tracking information is stored on the `derivation` object and the derivation is registered
|
|
720
|
+
* as observer of any of the accessed observables.
|
|
721
|
+
*/
|
|
722
|
+
function trackDerivedFunction(derivation, f, context) {
|
|
723
|
+
var prevAllowStateReads = allowStateReadsStart(true);
|
|
724
|
+
// pre allocate array allocation + room for variation in deps
|
|
725
|
+
// array will be trimmed by bindDependencies
|
|
726
|
+
changeDependenciesStateTo0(derivation);
|
|
727
|
+
derivation.newObserving = new Array(derivation.observing.length + 100);
|
|
728
|
+
derivation.unboundDepsCount = 0;
|
|
729
|
+
derivation.runId = ++globalState.runId;
|
|
730
|
+
var prevTracking = globalState.trackingDerivation;
|
|
731
|
+
globalState.trackingDerivation = derivation;
|
|
732
|
+
var result;
|
|
733
|
+
if (globalState.disableErrorBoundaries === true) {
|
|
734
|
+
result = f.call(context);
|
|
735
|
+
}
|
|
736
|
+
else {
|
|
737
|
+
try {
|
|
738
|
+
result = f.call(context);
|
|
739
|
+
}
|
|
740
|
+
catch (e) {
|
|
741
|
+
result = new CaughtException(e);
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
globalState.trackingDerivation = prevTracking;
|
|
745
|
+
bindDependencies(derivation);
|
|
746
|
+
warnAboutDerivationWithoutDependencies(derivation);
|
|
747
|
+
allowStateReadsEnd(prevAllowStateReads);
|
|
748
|
+
return result;
|
|
749
|
+
}
|
|
750
|
+
function warnAboutDerivationWithoutDependencies(derivation) {
|
|
751
|
+
if (process.env.NODE_ENV === "production")
|
|
752
|
+
return;
|
|
753
|
+
if (derivation.observing.length !== 0)
|
|
754
|
+
return;
|
|
755
|
+
if (globalState.reactionRequiresObservable || derivation.requiresObservable) {
|
|
756
|
+
console.warn("[mobx] Derivation " + derivation.name + " is created/updated without reading any observable value");
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
/**
|
|
760
|
+
* diffs newObserving with observing.
|
|
761
|
+
* update observing to be newObserving with unique observables
|
|
762
|
+
* notify observers that become observed/unobserved
|
|
763
|
+
*/
|
|
764
|
+
function bindDependencies(derivation) {
|
|
765
|
+
// invariant(derivation.dependenciesState !== IDerivationState.NOT_TRACKING, "INTERNAL ERROR bindDependencies expects derivation.dependenciesState !== -1");
|
|
766
|
+
var prevObserving = derivation.observing;
|
|
767
|
+
var observing = (derivation.observing = derivation.newObserving);
|
|
768
|
+
var lowestNewObservingDerivationState = IDerivationState.UP_TO_DATE;
|
|
769
|
+
// Go through all new observables and check diffValue: (this list can contain duplicates):
|
|
770
|
+
// 0: first occurrence, change to 1 and keep it
|
|
771
|
+
// 1: extra occurrence, drop it
|
|
772
|
+
var i0 = 0, l = derivation.unboundDepsCount;
|
|
773
|
+
for (var i = 0; i < l; i++) {
|
|
774
|
+
var dep = observing[i];
|
|
775
|
+
if (dep.diffValue === 0) {
|
|
776
|
+
dep.diffValue = 1;
|
|
777
|
+
if (i0 !== i)
|
|
778
|
+
observing[i0] = dep;
|
|
779
|
+
i0++;
|
|
780
|
+
}
|
|
781
|
+
// Upcast is 'safe' here, because if dep is IObservable, `dependenciesState` will be undefined,
|
|
782
|
+
// not hitting the condition
|
|
783
|
+
if (dep.dependenciesState > lowestNewObservingDerivationState) {
|
|
784
|
+
lowestNewObservingDerivationState = dep.dependenciesState;
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
observing.length = i0;
|
|
788
|
+
derivation.newObserving = null; // newObserving shouldn't be needed outside tracking (statement moved down to work around FF bug, see #614)
|
|
789
|
+
// Go through all old observables and check diffValue: (it is unique after last bindDependencies)
|
|
790
|
+
// 0: it's not in new observables, unobserve it
|
|
791
|
+
// 1: it keeps being observed, don't want to notify it. change to 0
|
|
792
|
+
l = prevObserving.length;
|
|
793
|
+
while (l--) {
|
|
794
|
+
var dep = prevObserving[l];
|
|
795
|
+
if (dep.diffValue === 0) {
|
|
796
|
+
removeObserver(dep, derivation);
|
|
797
|
+
}
|
|
798
|
+
dep.diffValue = 0;
|
|
799
|
+
}
|
|
800
|
+
// Go through all new observables and check diffValue: (now it should be unique)
|
|
801
|
+
// 0: it was set to 0 in last loop. don't need to do anything.
|
|
802
|
+
// 1: it wasn't observed, let's observe it. set back to 0
|
|
803
|
+
while (i0--) {
|
|
804
|
+
var dep = observing[i0];
|
|
805
|
+
if (dep.diffValue === 1) {
|
|
806
|
+
dep.diffValue = 0;
|
|
807
|
+
addObserver(dep, derivation);
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
// Some new observed derivations may become stale during this derivation computation
|
|
811
|
+
// so they have had no chance to propagate staleness (#916)
|
|
812
|
+
if (lowestNewObservingDerivationState !== IDerivationState.UP_TO_DATE) {
|
|
813
|
+
derivation.dependenciesState = lowestNewObservingDerivationState;
|
|
814
|
+
derivation.onBecomeStale();
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
function clearObserving(derivation) {
|
|
818
|
+
// invariant(globalState.inBatch > 0, "INTERNAL ERROR clearObserving should be called only inside batch");
|
|
819
|
+
var obs = derivation.observing;
|
|
820
|
+
derivation.observing = [];
|
|
821
|
+
var i = obs.length;
|
|
822
|
+
while (i--)
|
|
823
|
+
removeObserver(obs[i], derivation);
|
|
824
|
+
derivation.dependenciesState = IDerivationState.NOT_TRACKING;
|
|
825
|
+
}
|
|
826
|
+
function untracked(action) {
|
|
827
|
+
var prev = untrackedStart();
|
|
828
|
+
try {
|
|
829
|
+
return action();
|
|
830
|
+
}
|
|
831
|
+
finally {
|
|
832
|
+
untrackedEnd(prev);
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
function untrackedStart() {
|
|
836
|
+
var prev = globalState.trackingDerivation;
|
|
837
|
+
globalState.trackingDerivation = null;
|
|
838
|
+
return prev;
|
|
839
|
+
}
|
|
840
|
+
function untrackedEnd(prev) {
|
|
841
|
+
globalState.trackingDerivation = prev;
|
|
842
|
+
}
|
|
843
|
+
function allowStateReadsStart(allowStateReads) {
|
|
844
|
+
var prev = globalState.allowStateReads;
|
|
845
|
+
globalState.allowStateReads = allowStateReads;
|
|
846
|
+
return prev;
|
|
847
|
+
}
|
|
848
|
+
function allowStateReadsEnd(prev) {
|
|
849
|
+
globalState.allowStateReads = prev;
|
|
850
|
+
}
|
|
851
|
+
/**
|
|
852
|
+
* needed to keep `lowestObserverState` correct. when changing from (2 or 1) to 0
|
|
853
|
+
*
|
|
854
|
+
*/
|
|
855
|
+
function changeDependenciesStateTo0(derivation) {
|
|
856
|
+
if (derivation.dependenciesState === IDerivationState.UP_TO_DATE)
|
|
857
|
+
return;
|
|
858
|
+
derivation.dependenciesState = IDerivationState.UP_TO_DATE;
|
|
859
|
+
var obs = derivation.observing;
|
|
860
|
+
var i = obs.length;
|
|
861
|
+
while (i--)
|
|
862
|
+
obs[i].lowestObserverState = IDerivationState.UP_TO_DATE;
|
|
863
|
+
}
|
|
864
|
+
|
|
596
865
|
function createAction(actionName, fn, ref) {
|
|
597
866
|
if (process.env.NODE_ENV !== "production") {
|
|
598
867
|
invariant(typeof fn === "function", "`action` can only be invoked on functions");
|
|
@@ -606,25 +875,19 @@ function createAction(actionName, fn, ref) {
|
|
|
606
875
|
return res;
|
|
607
876
|
}
|
|
608
877
|
function executeAction(actionName, fn, scope, args) {
|
|
609
|
-
var runInfo =
|
|
610
|
-
var shouldSupressReactionError = true;
|
|
878
|
+
var runInfo = _startAction(actionName, scope, args);
|
|
611
879
|
try {
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
880
|
+
return fn.apply(scope, args);
|
|
881
|
+
}
|
|
882
|
+
catch (err) {
|
|
883
|
+
runInfo.error = err;
|
|
884
|
+
throw err;
|
|
615
885
|
}
|
|
616
886
|
finally {
|
|
617
|
-
|
|
618
|
-
globalState.suppressReactionErrors = shouldSupressReactionError;
|
|
619
|
-
endAction(runInfo);
|
|
620
|
-
globalState.suppressReactionErrors = false;
|
|
621
|
-
}
|
|
622
|
-
else {
|
|
623
|
-
endAction(runInfo);
|
|
624
|
-
}
|
|
887
|
+
_endAction(runInfo);
|
|
625
888
|
}
|
|
626
889
|
}
|
|
627
|
-
function
|
|
890
|
+
function _startAction(actionName, scope, args) {
|
|
628
891
|
var notifySpy = isSpyEnabled() && !!actionName;
|
|
629
892
|
var startTime = 0;
|
|
630
893
|
if (notifySpy && process.env.NODE_ENV !== "production") {
|
|
@@ -644,19 +907,35 @@ function startAction(actionName, fn, scope, args) {
|
|
|
644
907
|
var prevDerivation = untrackedStart();
|
|
645
908
|
startBatch();
|
|
646
909
|
var prevAllowStateChanges = allowStateChangesStart(true);
|
|
647
|
-
|
|
910
|
+
var prevAllowStateReads = allowStateReadsStart(true);
|
|
911
|
+
var runInfo = {
|
|
648
912
|
prevDerivation: prevDerivation,
|
|
649
913
|
prevAllowStateChanges: prevAllowStateChanges,
|
|
914
|
+
prevAllowStateReads: prevAllowStateReads,
|
|
650
915
|
notifySpy: notifySpy,
|
|
651
|
-
startTime: startTime
|
|
916
|
+
startTime: startTime,
|
|
917
|
+
actionId: globalState.nextActionId++,
|
|
918
|
+
parentActionId: globalState.currentActionId
|
|
652
919
|
};
|
|
920
|
+
globalState.currentActionId = runInfo.actionId;
|
|
921
|
+
return runInfo;
|
|
653
922
|
}
|
|
654
|
-
function
|
|
923
|
+
function _endAction(runInfo) {
|
|
924
|
+
if (globalState.currentActionId !== runInfo.actionId) {
|
|
925
|
+
fail("invalid action stack. did you forget to finish an action?");
|
|
926
|
+
}
|
|
927
|
+
globalState.currentActionId = runInfo.parentActionId;
|
|
928
|
+
if (runInfo.error !== undefined) {
|
|
929
|
+
globalState.suppressReactionErrors = true;
|
|
930
|
+
}
|
|
655
931
|
allowStateChangesEnd(runInfo.prevAllowStateChanges);
|
|
932
|
+
allowStateReadsEnd(runInfo.prevAllowStateReads);
|
|
656
933
|
endBatch();
|
|
657
934
|
untrackedEnd(runInfo.prevDerivation);
|
|
658
|
-
if (runInfo.notifySpy && process.env.NODE_ENV !== "production")
|
|
935
|
+
if (runInfo.notifySpy && process.env.NODE_ENV !== "production") {
|
|
659
936
|
spyReportEnd({ time: Date.now() - runInfo.startTime });
|
|
937
|
+
}
|
|
938
|
+
globalState.suppressReactionErrors = false;
|
|
660
939
|
}
|
|
661
940
|
function allowStateChanges(allowStateChanges, func) {
|
|
662
941
|
var prev = allowStateChangesStart(allowStateChanges);
|
|
@@ -950,314 +1229,72 @@ var ComputedValue = /** @class */ (function () {
|
|
|
950
1229
|
res = this.derivation.call(this.scope);
|
|
951
1230
|
}
|
|
952
1231
|
else {
|
|
953
|
-
try {
|
|
954
|
-
res = this.derivation.call(this.scope);
|
|
955
|
-
}
|
|
956
|
-
catch (e) {
|
|
957
|
-
res = new CaughtException(e);
|
|
958
|
-
}
|
|
959
|
-
}
|
|
960
|
-
}
|
|
961
|
-
globalState.computationDepth--;
|
|
962
|
-
this.isComputing = false;
|
|
963
|
-
return res;
|
|
964
|
-
};
|
|
965
|
-
ComputedValue.prototype.suspend = function () {
|
|
966
|
-
if (!this.keepAlive) {
|
|
967
|
-
clearObserving(this);
|
|
968
|
-
this.value = undefined; // don't hold on to computed value!
|
|
969
|
-
}
|
|
970
|
-
};
|
|
971
|
-
ComputedValue.prototype.observe = function (listener, fireImmediately) {
|
|
972
|
-
var _this = this;
|
|
973
|
-
var firstTime = true;
|
|
974
|
-
var prevValue = undefined;
|
|
975
|
-
return autorun(function () {
|
|
976
|
-
var newValue = _this.get();
|
|
977
|
-
if (!firstTime || fireImmediately) {
|
|
978
|
-
var prevU = untrackedStart();
|
|
979
|
-
listener({
|
|
980
|
-
type: "update",
|
|
981
|
-
object: _this,
|
|
982
|
-
newValue: newValue,
|
|
983
|
-
oldValue: prevValue
|
|
984
|
-
});
|
|
985
|
-
untrackedEnd(prevU);
|
|
986
|
-
}
|
|
987
|
-
firstTime = false;
|
|
988
|
-
prevValue = newValue;
|
|
989
|
-
});
|
|
990
|
-
};
|
|
991
|
-
ComputedValue.prototype.warnAboutUntrackedRead = function () {
|
|
992
|
-
if (process.env.NODE_ENV === "production")
|
|
993
|
-
return;
|
|
994
|
-
if (this.requiresReaction === true) {
|
|
995
|
-
fail("[mobx] Computed value " + this.name + " is read outside a reactive context");
|
|
996
|
-
}
|
|
997
|
-
if (this.isTracing !== TraceMode.NONE) {
|
|
998
|
-
console.log("[mobx.trace] '" + this.name + "' is being read outside a reactive context. Doing a full recompute");
|
|
999
|
-
}
|
|
1000
|
-
if (globalState.computedRequiresReaction) {
|
|
1001
|
-
console.warn("[mobx] Computed value " + this.name + " is being read outside a reactive context. Doing a full recompute");
|
|
1002
|
-
}
|
|
1003
|
-
};
|
|
1004
|
-
ComputedValue.prototype.toJSON = function () {
|
|
1005
|
-
return this.get();
|
|
1006
|
-
};
|
|
1007
|
-
ComputedValue.prototype.toString = function () {
|
|
1008
|
-
return this.name + "[" + this.derivation.toString() + "]";
|
|
1009
|
-
};
|
|
1010
|
-
ComputedValue.prototype.valueOf = function () {
|
|
1011
|
-
return toPrimitive(this.get());
|
|
1012
|
-
};
|
|
1013
|
-
ComputedValue.prototype[Symbol.toPrimitive] = function () {
|
|
1014
|
-
return this.valueOf();
|
|
1015
|
-
};
|
|
1016
|
-
return ComputedValue;
|
|
1017
|
-
}());
|
|
1018
|
-
var isComputedValue = createInstanceofPredicate("ComputedValue", ComputedValue);
|
|
1019
|
-
|
|
1020
|
-
var IDerivationState;
|
|
1021
|
-
(function (IDerivationState) {
|
|
1022
|
-
// before being run or (outside batch and not being observed)
|
|
1023
|
-
// at this point derivation is not holding any data about dependency tree
|
|
1024
|
-
IDerivationState[IDerivationState["NOT_TRACKING"] = -1] = "NOT_TRACKING";
|
|
1025
|
-
// no shallow dependency changed since last computation
|
|
1026
|
-
// won't recalculate derivation
|
|
1027
|
-
// this is what makes mobx fast
|
|
1028
|
-
IDerivationState[IDerivationState["UP_TO_DATE"] = 0] = "UP_TO_DATE";
|
|
1029
|
-
// some deep dependency changed, but don't know if shallow dependency changed
|
|
1030
|
-
// will require to check first if UP_TO_DATE or POSSIBLY_STALE
|
|
1031
|
-
// currently only ComputedValue will propagate POSSIBLY_STALE
|
|
1032
|
-
//
|
|
1033
|
-
// having this state is second big optimization:
|
|
1034
|
-
// don't have to recompute on every dependency change, but only when it's needed
|
|
1035
|
-
IDerivationState[IDerivationState["POSSIBLY_STALE"] = 1] = "POSSIBLY_STALE";
|
|
1036
|
-
// A shallow dependency has changed since last computation and the derivation
|
|
1037
|
-
// will need to recompute when it's needed next.
|
|
1038
|
-
IDerivationState[IDerivationState["STALE"] = 2] = "STALE";
|
|
1039
|
-
})(IDerivationState || (IDerivationState = {}));
|
|
1040
|
-
var TraceMode;
|
|
1041
|
-
(function (TraceMode) {
|
|
1042
|
-
TraceMode[TraceMode["NONE"] = 0] = "NONE";
|
|
1043
|
-
TraceMode[TraceMode["LOG"] = 1] = "LOG";
|
|
1044
|
-
TraceMode[TraceMode["BREAK"] = 2] = "BREAK";
|
|
1045
|
-
})(TraceMode || (TraceMode = {}));
|
|
1046
|
-
var CaughtException = /** @class */ (function () {
|
|
1047
|
-
function CaughtException(cause) {
|
|
1048
|
-
this.cause = cause;
|
|
1049
|
-
// Empty
|
|
1050
|
-
}
|
|
1051
|
-
return CaughtException;
|
|
1052
|
-
}());
|
|
1053
|
-
function isCaughtException(e) {
|
|
1054
|
-
return e instanceof CaughtException;
|
|
1055
|
-
}
|
|
1056
|
-
/**
|
|
1057
|
-
* Finds out whether any dependency of the derivation has actually changed.
|
|
1058
|
-
* If dependenciesState is 1 then it will recalculate dependencies,
|
|
1059
|
-
* if any dependency changed it will propagate it by changing dependenciesState to 2.
|
|
1060
|
-
*
|
|
1061
|
-
* By iterating over the dependencies in the same order that they were reported and
|
|
1062
|
-
* stopping on the first change, all the recalculations are only called for ComputedValues
|
|
1063
|
-
* that will be tracked by derivation. That is because we assume that if the first x
|
|
1064
|
-
* dependencies of the derivation doesn't change then the derivation should run the same way
|
|
1065
|
-
* up until accessing x-th dependency.
|
|
1066
|
-
*/
|
|
1067
|
-
function shouldCompute(derivation) {
|
|
1068
|
-
switch (derivation.dependenciesState) {
|
|
1069
|
-
case IDerivationState.UP_TO_DATE:
|
|
1070
|
-
return false;
|
|
1071
|
-
case IDerivationState.NOT_TRACKING:
|
|
1072
|
-
case IDerivationState.STALE:
|
|
1073
|
-
return true;
|
|
1074
|
-
case IDerivationState.POSSIBLY_STALE: {
|
|
1075
|
-
var prevUntracked = untrackedStart(); // no need for those computeds to be reported, they will be picked up in trackDerivedFunction.
|
|
1076
|
-
var obs = derivation.observing, l = obs.length;
|
|
1077
|
-
for (var i = 0; i < l; i++) {
|
|
1078
|
-
var obj = obs[i];
|
|
1079
|
-
if (isComputedValue(obj)) {
|
|
1080
|
-
if (globalState.disableErrorBoundaries) {
|
|
1081
|
-
obj.get();
|
|
1082
|
-
}
|
|
1083
|
-
else {
|
|
1084
|
-
try {
|
|
1085
|
-
obj.get();
|
|
1086
|
-
}
|
|
1087
|
-
catch (e) {
|
|
1088
|
-
// we are not interested in the value *or* exception at this moment, but if there is one, notify all
|
|
1089
|
-
untrackedEnd(prevUntracked);
|
|
1090
|
-
return true;
|
|
1091
|
-
}
|
|
1092
|
-
}
|
|
1093
|
-
// if ComputedValue `obj` actually changed it will be computed and propagated to its observers.
|
|
1094
|
-
// and `derivation` is an observer of `obj`
|
|
1095
|
-
// invariantShouldCompute(derivation)
|
|
1096
|
-
if (derivation.dependenciesState === IDerivationState.STALE) {
|
|
1097
|
-
untrackedEnd(prevUntracked);
|
|
1098
|
-
return true;
|
|
1099
|
-
}
|
|
1232
|
+
try {
|
|
1233
|
+
res = this.derivation.call(this.scope);
|
|
1234
|
+
}
|
|
1235
|
+
catch (e) {
|
|
1236
|
+
res = new CaughtException(e);
|
|
1100
1237
|
}
|
|
1101
1238
|
}
|
|
1102
|
-
changeDependenciesStateTo0(derivation);
|
|
1103
|
-
untrackedEnd(prevUntracked);
|
|
1104
|
-
return false;
|
|
1105
|
-
}
|
|
1106
|
-
}
|
|
1107
|
-
}
|
|
1108
|
-
// function invariantShouldCompute(derivation: IDerivation) {
|
|
1109
|
-
// const newDepState = (derivation as any).dependenciesState
|
|
1110
|
-
// if (
|
|
1111
|
-
// process.env.NODE_ENV === "production" &&
|
|
1112
|
-
// (newDepState === IDerivationState.POSSIBLY_STALE ||
|
|
1113
|
-
// newDepState === IDerivationState.NOT_TRACKING)
|
|
1114
|
-
// )
|
|
1115
|
-
// fail("Illegal dependency state")
|
|
1116
|
-
// }
|
|
1117
|
-
function isComputingDerivation() {
|
|
1118
|
-
return globalState.trackingDerivation !== null; // filter out actions inside computations
|
|
1119
|
-
}
|
|
1120
|
-
function checkIfStateModificationsAreAllowed(atom) {
|
|
1121
|
-
var hasObservers = atom.observers.size > 0;
|
|
1122
|
-
// Should never be possible to change an observed observable from inside computed, see #798
|
|
1123
|
-
if (globalState.computationDepth > 0 && hasObservers)
|
|
1124
|
-
fail(process.env.NODE_ENV !== "production" &&
|
|
1125
|
-
"Computed values are not allowed to cause side effects by changing observables that are already being observed. Tried to modify: " + atom.name);
|
|
1126
|
-
// Should not be possible to change observed state outside strict mode, except during initialization, see #563
|
|
1127
|
-
if (!globalState.allowStateChanges && (hasObservers || globalState.enforceActions === "strict"))
|
|
1128
|
-
fail(process.env.NODE_ENV !== "production" &&
|
|
1129
|
-
(globalState.enforceActions
|
|
1130
|
-
? "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: "
|
|
1131
|
-
: "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: ") +
|
|
1132
|
-
atom.name);
|
|
1133
|
-
}
|
|
1134
|
-
/**
|
|
1135
|
-
* Executes the provided function `f` and tracks which observables are being accessed.
|
|
1136
|
-
* The tracking information is stored on the `derivation` object and the derivation is registered
|
|
1137
|
-
* as observer of any of the accessed observables.
|
|
1138
|
-
*/
|
|
1139
|
-
function trackDerivedFunction(derivation, f, context) {
|
|
1140
|
-
// pre allocate array allocation + room for variation in deps
|
|
1141
|
-
// array will be trimmed by bindDependencies
|
|
1142
|
-
changeDependenciesStateTo0(derivation);
|
|
1143
|
-
derivation.newObserving = new Array(derivation.observing.length + 100);
|
|
1144
|
-
derivation.unboundDepsCount = 0;
|
|
1145
|
-
derivation.runId = ++globalState.runId;
|
|
1146
|
-
var prevTracking = globalState.trackingDerivation;
|
|
1147
|
-
globalState.trackingDerivation = derivation;
|
|
1148
|
-
var result;
|
|
1149
|
-
if (globalState.disableErrorBoundaries === true) {
|
|
1150
|
-
result = f.call(context);
|
|
1151
|
-
}
|
|
1152
|
-
else {
|
|
1153
|
-
try {
|
|
1154
|
-
result = f.call(context);
|
|
1155
|
-
}
|
|
1156
|
-
catch (e) {
|
|
1157
|
-
result = new CaughtException(e);
|
|
1158
1239
|
}
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
* notify observers that become observed/unobserved
|
|
1168
|
-
*/
|
|
1169
|
-
function bindDependencies(derivation) {
|
|
1170
|
-
// invariant(derivation.dependenciesState !== IDerivationState.NOT_TRACKING, "INTERNAL ERROR bindDependencies expects derivation.dependenciesState !== -1");
|
|
1171
|
-
var prevObserving = derivation.observing;
|
|
1172
|
-
var observing = (derivation.observing = derivation.newObserving);
|
|
1173
|
-
var lowestNewObservingDerivationState = IDerivationState.UP_TO_DATE;
|
|
1174
|
-
// Go through all new observables and check diffValue: (this list can contain duplicates):
|
|
1175
|
-
// 0: first occurrence, change to 1 and keep it
|
|
1176
|
-
// 1: extra occurrence, drop it
|
|
1177
|
-
var i0 = 0, l = derivation.unboundDepsCount;
|
|
1178
|
-
for (var i = 0; i < l; i++) {
|
|
1179
|
-
var dep = observing[i];
|
|
1180
|
-
if (dep.diffValue === 0) {
|
|
1181
|
-
dep.diffValue = 1;
|
|
1182
|
-
if (i0 !== i)
|
|
1183
|
-
observing[i0] = dep;
|
|
1184
|
-
i0++;
|
|
1240
|
+
globalState.computationDepth--;
|
|
1241
|
+
this.isComputing = false;
|
|
1242
|
+
return res;
|
|
1243
|
+
};
|
|
1244
|
+
ComputedValue.prototype.suspend = function () {
|
|
1245
|
+
if (!this.keepAlive) {
|
|
1246
|
+
clearObserving(this);
|
|
1247
|
+
this.value = undefined; // don't hold on to computed value!
|
|
1185
1248
|
}
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1249
|
+
};
|
|
1250
|
+
ComputedValue.prototype.observe = function (listener, fireImmediately) {
|
|
1251
|
+
var _this = this;
|
|
1252
|
+
var firstTime = true;
|
|
1253
|
+
var prevValue = undefined;
|
|
1254
|
+
return autorun(function () {
|
|
1255
|
+
var newValue = _this.get();
|
|
1256
|
+
if (!firstTime || fireImmediately) {
|
|
1257
|
+
var prevU = untrackedStart();
|
|
1258
|
+
listener({
|
|
1259
|
+
type: "update",
|
|
1260
|
+
object: _this,
|
|
1261
|
+
newValue: newValue,
|
|
1262
|
+
oldValue: prevValue
|
|
1263
|
+
});
|
|
1264
|
+
untrackedEnd(prevU);
|
|
1265
|
+
}
|
|
1266
|
+
firstTime = false;
|
|
1267
|
+
prevValue = newValue;
|
|
1268
|
+
});
|
|
1269
|
+
};
|
|
1270
|
+
ComputedValue.prototype.warnAboutUntrackedRead = function () {
|
|
1271
|
+
if (process.env.NODE_ENV === "production")
|
|
1272
|
+
return;
|
|
1273
|
+
if (this.requiresReaction === true) {
|
|
1274
|
+
fail("[mobx] Computed value " + this.name + " is read outside a reactive context");
|
|
1190
1275
|
}
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
derivation.newObserving = null; // newObserving shouldn't be needed outside tracking (statement moved down to work around FF bug, see #614)
|
|
1194
|
-
// Go through all old observables and check diffValue: (it is unique after last bindDependencies)
|
|
1195
|
-
// 0: it's not in new observables, unobserve it
|
|
1196
|
-
// 1: it keeps being observed, don't want to notify it. change to 0
|
|
1197
|
-
l = prevObserving.length;
|
|
1198
|
-
while (l--) {
|
|
1199
|
-
var dep = prevObserving[l];
|
|
1200
|
-
if (dep.diffValue === 0) {
|
|
1201
|
-
removeObserver(dep, derivation);
|
|
1276
|
+
if (this.isTracing !== TraceMode.NONE) {
|
|
1277
|
+
console.log("[mobx.trace] '" + this.name + "' is being read outside a reactive context. Doing a full recompute");
|
|
1202
1278
|
}
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
// Go through all new observables and check diffValue: (now it should be unique)
|
|
1206
|
-
// 0: it was set to 0 in last loop. don't need to do anything.
|
|
1207
|
-
// 1: it wasn't observed, let's observe it. set back to 0
|
|
1208
|
-
while (i0--) {
|
|
1209
|
-
var dep = observing[i0];
|
|
1210
|
-
if (dep.diffValue === 1) {
|
|
1211
|
-
dep.diffValue = 0;
|
|
1212
|
-
addObserver(dep, derivation);
|
|
1279
|
+
if (globalState.computedRequiresReaction) {
|
|
1280
|
+
console.warn("[mobx] Computed value " + this.name + " is being read outside a reactive context. Doing a full recompute");
|
|
1213
1281
|
}
|
|
1214
|
-
}
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
derivation.
|
|
1220
|
-
}
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
}
|
|
1231
|
-
function untracked(action) {
|
|
1232
|
-
var prev = untrackedStart();
|
|
1233
|
-
try {
|
|
1234
|
-
return action();
|
|
1235
|
-
}
|
|
1236
|
-
finally {
|
|
1237
|
-
untrackedEnd(prev);
|
|
1238
|
-
}
|
|
1239
|
-
}
|
|
1240
|
-
function untrackedStart() {
|
|
1241
|
-
var prev = globalState.trackingDerivation;
|
|
1242
|
-
globalState.trackingDerivation = null;
|
|
1243
|
-
return prev;
|
|
1244
|
-
}
|
|
1245
|
-
function untrackedEnd(prev) {
|
|
1246
|
-
globalState.trackingDerivation = prev;
|
|
1247
|
-
}
|
|
1248
|
-
/**
|
|
1249
|
-
* needed to keep `lowestObserverState` correct. when changing from (2 or 1) to 0
|
|
1250
|
-
*
|
|
1251
|
-
*/
|
|
1252
|
-
function changeDependenciesStateTo0(derivation) {
|
|
1253
|
-
if (derivation.dependenciesState === IDerivationState.UP_TO_DATE)
|
|
1254
|
-
return;
|
|
1255
|
-
derivation.dependenciesState = IDerivationState.UP_TO_DATE;
|
|
1256
|
-
var obs = derivation.observing;
|
|
1257
|
-
var i = obs.length;
|
|
1258
|
-
while (i--)
|
|
1259
|
-
obs[i].lowestObserverState = IDerivationState.UP_TO_DATE;
|
|
1260
|
-
}
|
|
1282
|
+
};
|
|
1283
|
+
ComputedValue.prototype.toJSON = function () {
|
|
1284
|
+
return this.get();
|
|
1285
|
+
};
|
|
1286
|
+
ComputedValue.prototype.toString = function () {
|
|
1287
|
+
return this.name + "[" + this.derivation.toString() + "]";
|
|
1288
|
+
};
|
|
1289
|
+
ComputedValue.prototype.valueOf = function () {
|
|
1290
|
+
return toPrimitive(this.get());
|
|
1291
|
+
};
|
|
1292
|
+
ComputedValue.prototype[Symbol.toPrimitive] = function () {
|
|
1293
|
+
return this.valueOf();
|
|
1294
|
+
};
|
|
1295
|
+
return ComputedValue;
|
|
1296
|
+
}());
|
|
1297
|
+
var isComputedValue = createInstanceofPredicate("ComputedValue", ComputedValue);
|
|
1261
1298
|
|
|
1262
1299
|
/**
|
|
1263
1300
|
* These values will persist if global state is reset
|
|
@@ -1267,6 +1304,9 @@ var persistentKeys = [
|
|
|
1267
1304
|
"spyListeners",
|
|
1268
1305
|
"enforceActions",
|
|
1269
1306
|
"computedRequiresReaction",
|
|
1307
|
+
"reactionRequiresObservable",
|
|
1308
|
+
"observableRequiresReaction",
|
|
1309
|
+
"allowStateReads",
|
|
1270
1310
|
"disableErrorBoundaries",
|
|
1271
1311
|
"runId",
|
|
1272
1312
|
"UNCHANGED"
|
|
@@ -1327,6 +1367,11 @@ var MobXGlobals = /** @class */ (function () {
|
|
|
1327
1367
|
* To ensure that those functions stay pure.
|
|
1328
1368
|
*/
|
|
1329
1369
|
this.allowStateChanges = true;
|
|
1370
|
+
/**
|
|
1371
|
+
* Is it allowed to read observables at this point?
|
|
1372
|
+
* Used to hold the state needed for `observableRequiresReaction`
|
|
1373
|
+
*/
|
|
1374
|
+
this.allowStateReads = true;
|
|
1330
1375
|
/**
|
|
1331
1376
|
* If strict mode is enabled, state changes are by default not allowed
|
|
1332
1377
|
*/
|
|
@@ -1343,16 +1388,39 @@ var MobXGlobals = /** @class */ (function () {
|
|
|
1343
1388
|
* Warn if computed values are accessed outside a reactive context
|
|
1344
1389
|
*/
|
|
1345
1390
|
this.computedRequiresReaction = false;
|
|
1391
|
+
/**
|
|
1392
|
+
* (Experimental)
|
|
1393
|
+
* Warn if you try to create to derivation / reactive context without accessing any observable.
|
|
1394
|
+
*/
|
|
1395
|
+
this.reactionRequiresObservable = false;
|
|
1396
|
+
/**
|
|
1397
|
+
* (Experimental)
|
|
1398
|
+
* Warn if observables are accessed outside a reactive context
|
|
1399
|
+
*/
|
|
1400
|
+
this.observableRequiresReaction = false;
|
|
1401
|
+
/**
|
|
1402
|
+
* Allows overwriting of computed properties, useful in tests but not prod as it can cause
|
|
1403
|
+
* memory leaks. See https://github.com/mobxjs/mobx/issues/1867
|
|
1404
|
+
*/
|
|
1405
|
+
this.computedConfigurable = false;
|
|
1346
1406
|
/*
|
|
1347
1407
|
* Don't catch and rethrow exceptions. This is useful for inspecting the state of
|
|
1348
1408
|
* the stack when an exception occurs while debugging.
|
|
1349
1409
|
*/
|
|
1350
1410
|
this.disableErrorBoundaries = false;
|
|
1351
1411
|
/*
|
|
1352
|
-
* If true, we are already handling an exception in an action. Any errors in reactions should be
|
|
1412
|
+
* If true, we are already handling an exception in an action. Any errors in reactions should be suppressed, as
|
|
1353
1413
|
* they are not the cause, see: https://github.com/mobxjs/mobx/issues/1836
|
|
1354
1414
|
*/
|
|
1355
1415
|
this.suppressReactionErrors = false;
|
|
1416
|
+
/*
|
|
1417
|
+
* Current action id.
|
|
1418
|
+
*/
|
|
1419
|
+
this.currentActionId = 0;
|
|
1420
|
+
/*
|
|
1421
|
+
* Next action id.
|
|
1422
|
+
*/
|
|
1423
|
+
this.nextActionId = 1;
|
|
1356
1424
|
}
|
|
1357
1425
|
return MobXGlobals;
|
|
1358
1426
|
}());
|
|
@@ -1409,8 +1477,15 @@ function resetGlobalState() {
|
|
|
1409
1477
|
globalState[key] = defaultGlobals[key];
|
|
1410
1478
|
globalState.allowStateChanges = !globalState.enforceActions;
|
|
1411
1479
|
}
|
|
1480
|
+
var mockGlobal = {};
|
|
1412
1481
|
function getGlobal() {
|
|
1413
|
-
|
|
1482
|
+
if (typeof window !== "undefined") {
|
|
1483
|
+
return window;
|
|
1484
|
+
}
|
|
1485
|
+
if (typeof global !== "undefined") {
|
|
1486
|
+
return global;
|
|
1487
|
+
}
|
|
1488
|
+
return mockGlobal;
|
|
1414
1489
|
}
|
|
1415
1490
|
|
|
1416
1491
|
function hasObservers(observable) {
|
|
@@ -1498,6 +1573,7 @@ function endBatch() {
|
|
|
1498
1573
|
}
|
|
1499
1574
|
}
|
|
1500
1575
|
function reportObserved(observable) {
|
|
1576
|
+
checkIfStateReadsAreAllowed(observable);
|
|
1501
1577
|
var derivation = globalState.trackingDerivation;
|
|
1502
1578
|
if (derivation !== null) {
|
|
1503
1579
|
/**
|
|
@@ -1611,11 +1687,13 @@ function printDepTree(tree, lines, depth) {
|
|
|
1611
1687
|
}
|
|
1612
1688
|
|
|
1613
1689
|
var Reaction = /** @class */ (function () {
|
|
1614
|
-
function Reaction(name, onInvalidate, errorHandler) {
|
|
1690
|
+
function Reaction(name, onInvalidate, errorHandler, requiresObservable) {
|
|
1615
1691
|
if (name === void 0) { name = "Reaction@" + getNextId(); }
|
|
1692
|
+
if (requiresObservable === void 0) { requiresObservable = false; }
|
|
1616
1693
|
this.name = name;
|
|
1617
1694
|
this.onInvalidate = onInvalidate;
|
|
1618
1695
|
this.errorHandler = errorHandler;
|
|
1696
|
+
this.requiresObservable = requiresObservable;
|
|
1619
1697
|
this.observing = []; // nodes we are looking at. Our value depends on these nodes
|
|
1620
1698
|
this.newObserving = [];
|
|
1621
1699
|
this.dependenciesState = IDerivationState.NOT_TRACKING;
|
|
@@ -1978,7 +2056,7 @@ function autorun(view, opts) {
|
|
|
1978
2056
|
// normal autorun
|
|
1979
2057
|
reaction = new Reaction(name, function () {
|
|
1980
2058
|
this.track(reactionRunner);
|
|
1981
|
-
}, opts.onError);
|
|
2059
|
+
}, opts.onError, opts.requiresObservable);
|
|
1982
2060
|
}
|
|
1983
2061
|
else {
|
|
1984
2062
|
var scheduler_1 = createSchedulerFromOptions(opts);
|
|
@@ -1993,7 +2071,7 @@ function autorun(view, opts) {
|
|
|
1993
2071
|
reaction.track(reactionRunner);
|
|
1994
2072
|
});
|
|
1995
2073
|
}
|
|
1996
|
-
}, opts.onError);
|
|
2074
|
+
}, opts.onError, opts.requiresObservable);
|
|
1997
2075
|
}
|
|
1998
2076
|
function reactionRunner() {
|
|
1999
2077
|
view(reaction);
|
|
@@ -2033,7 +2111,7 @@ function reaction(expression, effect, opts) {
|
|
|
2033
2111
|
isScheduled = true;
|
|
2034
2112
|
scheduler(reactionRunner);
|
|
2035
2113
|
}
|
|
2036
|
-
}, opts.onError);
|
|
2114
|
+
}, opts.onError, opts.requiresObservable);
|
|
2037
2115
|
function reactionRunner() {
|
|
2038
2116
|
isScheduled = false; // Q: move into reaction runner?
|
|
2039
2117
|
if (r.isDisposed)
|
|
@@ -2072,8 +2150,8 @@ function onBecomeUnobserved(thing, arg2, arg3) {
|
|
|
2072
2150
|
return interceptHook("onBecomeUnobserved", thing, arg2, arg3);
|
|
2073
2151
|
}
|
|
2074
2152
|
function interceptHook(hook, thing, arg2, arg3) {
|
|
2075
|
-
var atom = typeof
|
|
2076
|
-
var cb = typeof
|
|
2153
|
+
var atom = typeof arg3 === "function" ? getAtom(thing, arg2) : getAtom(thing);
|
|
2154
|
+
var cb = typeof arg3 === "function" ? arg3 : arg2;
|
|
2077
2155
|
var listenersKey = hook + "Listeners";
|
|
2078
2156
|
if (atom[listenersKey]) {
|
|
2079
2157
|
atom[listenersKey].add(cb);
|
|
@@ -2096,7 +2174,7 @@ function interceptHook(hook, thing, arg2, arg3) {
|
|
|
2096
2174
|
}
|
|
2097
2175
|
|
|
2098
2176
|
function configure(options) {
|
|
2099
|
-
var enforceActions = options.enforceActions, computedRequiresReaction = options.computedRequiresReaction, disableErrorBoundaries = options.disableErrorBoundaries, reactionScheduler = options.reactionScheduler;
|
|
2177
|
+
var enforceActions = options.enforceActions, computedRequiresReaction = options.computedRequiresReaction, computedConfigurable = options.computedConfigurable, disableErrorBoundaries = options.disableErrorBoundaries, reactionScheduler = options.reactionScheduler, reactionRequiresObservable = options.reactionRequiresObservable, observableRequiresReaction = options.observableRequiresReaction;
|
|
2100
2178
|
if (options.isolateGlobalState === true) {
|
|
2101
2179
|
isolateGlobalState();
|
|
2102
2180
|
}
|
|
@@ -2126,6 +2204,16 @@ function configure(options) {
|
|
|
2126
2204
|
if (computedRequiresReaction !== undefined) {
|
|
2127
2205
|
globalState.computedRequiresReaction = !!computedRequiresReaction;
|
|
2128
2206
|
}
|
|
2207
|
+
if (reactionRequiresObservable !== undefined) {
|
|
2208
|
+
globalState.reactionRequiresObservable = !!reactionRequiresObservable;
|
|
2209
|
+
}
|
|
2210
|
+
if (observableRequiresReaction !== undefined) {
|
|
2211
|
+
globalState.observableRequiresReaction = !!observableRequiresReaction;
|
|
2212
|
+
globalState.allowStateReads = !globalState.observableRequiresReaction;
|
|
2213
|
+
}
|
|
2214
|
+
if (computedConfigurable !== undefined) {
|
|
2215
|
+
globalState.computedConfigurable = !!computedConfigurable;
|
|
2216
|
+
}
|
|
2129
2217
|
if (disableErrorBoundaries !== undefined) {
|
|
2130
2218
|
if (disableErrorBoundaries === true)
|
|
2131
2219
|
console.warn("WARNING: Debug feature only. MobX will NOT recover from errors when `disableErrorBoundaries` is enabled.");
|
|
@@ -2176,40 +2264,61 @@ function getDefaultDecoratorFromObjectOptions(options) {
|
|
|
2176
2264
|
return options.defaultDecorator || (options.deep === false ? refDecorator : deepDecorator);
|
|
2177
2265
|
}
|
|
2178
2266
|
function extendObservableObjectWithProperties(target, properties, decorators, defaultDecorator) {
|
|
2267
|
+
var e_1, _a, e_2, _b;
|
|
2179
2268
|
if (process.env.NODE_ENV !== "production") {
|
|
2180
2269
|
invariant(!isObservable(properties), "Extending an object with another observable (object) is not supported. Please construct an explicit propertymap, using `toJS` if need. See issue #540");
|
|
2181
2270
|
if (decorators) {
|
|
2182
2271
|
var keys = getPlainObjectKeys(decorators);
|
|
2183
|
-
|
|
2184
|
-
var
|
|
2185
|
-
|
|
2186
|
-
|
|
2272
|
+
try {
|
|
2273
|
+
for (var keys_1 = __values(keys), keys_1_1 = keys_1.next(); !keys_1_1.done; keys_1_1 = keys_1.next()) {
|
|
2274
|
+
var key = keys_1_1.value;
|
|
2275
|
+
if (!(key in properties))
|
|
2276
|
+
fail("Trying to declare a decorator for unspecified property '" + stringifyKey(key) + "'");
|
|
2277
|
+
}
|
|
2278
|
+
}
|
|
2279
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
2280
|
+
finally {
|
|
2281
|
+
try {
|
|
2282
|
+
if (keys_1_1 && !keys_1_1.done && (_a = keys_1.return)) _a.call(keys_1);
|
|
2283
|
+
}
|
|
2284
|
+
finally { if (e_1) throw e_1.error; }
|
|
2187
2285
|
}
|
|
2188
2286
|
}
|
|
2189
2287
|
}
|
|
2190
2288
|
startBatch();
|
|
2191
2289
|
try {
|
|
2192
2290
|
var keys = getPlainObjectKeys(properties);
|
|
2193
|
-
|
|
2194
|
-
var
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
if (
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2291
|
+
try {
|
|
2292
|
+
for (var keys_2 = __values(keys), keys_2_1 = keys_2.next(); !keys_2_1.done; keys_2_1 = keys_2.next()) {
|
|
2293
|
+
var key = keys_2_1.value;
|
|
2294
|
+
var descriptor = Object.getOwnPropertyDescriptor(properties, key);
|
|
2295
|
+
if (process.env.NODE_ENV !== "production") {
|
|
2296
|
+
if (!isPlainObject(properties))
|
|
2297
|
+
fail("'extendObservabe' only accepts plain objects as second argument");
|
|
2298
|
+
if (Object.getOwnPropertyDescriptor(target, key))
|
|
2299
|
+
fail("'extendObservable' can only be used to introduce new properties. Use 'set' or 'decorate' instead. The property '" + stringifyKey(key) + "' already exists on '" + target + "'");
|
|
2300
|
+
if (isComputed(descriptor.value))
|
|
2301
|
+
fail("Passing a 'computed' as initial property value is no longer supported by extendObservable. Use a getter or decorator instead");
|
|
2302
|
+
}
|
|
2303
|
+
var decorator = decorators && key in decorators
|
|
2304
|
+
? decorators[key]
|
|
2305
|
+
: descriptor.get
|
|
2306
|
+
? computedDecorator
|
|
2307
|
+
: defaultDecorator;
|
|
2308
|
+
if (process.env.NODE_ENV !== "production" && typeof decorator !== "function")
|
|
2309
|
+
fail("Not a valid decorator for '" + stringifyKey(key) + "', got: " + decorator);
|
|
2310
|
+
var resultDescriptor = decorator(target, key, descriptor, true);
|
|
2311
|
+
if (resultDescriptor // otherwise, assume already applied, due to `applyToInstance`
|
|
2312
|
+
)
|
|
2313
|
+
Object.defineProperty(target, key, resultDescriptor);
|
|
2314
|
+
}
|
|
2315
|
+
}
|
|
2316
|
+
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
|
2317
|
+
finally {
|
|
2318
|
+
try {
|
|
2319
|
+
if (keys_2_1 && !keys_2_1.done && (_b = keys_2.return)) _b.call(keys_2);
|
|
2201
2320
|
}
|
|
2202
|
-
|
|
2203
|
-
? decorators[key]
|
|
2204
|
-
: descriptor.get
|
|
2205
|
-
? computedDecorator
|
|
2206
|
-
: defaultDecorator;
|
|
2207
|
-
if (process.env.NODE_ENV !== "production" && typeof decorator !== "function")
|
|
2208
|
-
fail("Not a valid decorator for '" + stringifyKey(key) + "', got: " + decorator);
|
|
2209
|
-
var resultDescriptor = decorator(target, key, descriptor, true);
|
|
2210
|
-
if (resultDescriptor // otherwise, assume already applied, due to `applyToInstance`
|
|
2211
|
-
)
|
|
2212
|
-
Object.defineProperty(target, key, resultDescriptor);
|
|
2321
|
+
finally { if (e_2) throw e_2.error; }
|
|
2213
2322
|
}
|
|
2214
2323
|
}
|
|
2215
2324
|
finally {
|
|
@@ -2904,17 +3013,18 @@ var arrayTraps = {
|
|
|
2904
3013
|
set: function (target, name, value) {
|
|
2905
3014
|
if (name === "length") {
|
|
2906
3015
|
target[$mobx].setArrayLength(value);
|
|
2907
|
-
return true;
|
|
2908
3016
|
}
|
|
2909
3017
|
if (typeof name === "number") {
|
|
2910
3018
|
arrayExtensions.set.call(target, name, value);
|
|
2911
|
-
return true;
|
|
2912
3019
|
}
|
|
2913
|
-
if (
|
|
3020
|
+
if (typeof name === "symbol" || isNaN(name)) {
|
|
3021
|
+
target[name] = value;
|
|
3022
|
+
}
|
|
3023
|
+
else {
|
|
3024
|
+
// numeric string
|
|
2914
3025
|
arrayExtensions.set.call(target, parseInt(name), value);
|
|
2915
|
-
return true;
|
|
2916
3026
|
}
|
|
2917
|
-
return
|
|
3027
|
+
return true;
|
|
2918
3028
|
},
|
|
2919
3029
|
preventExtensions: function (target) {
|
|
2920
3030
|
fail("Observable arrays cannot be frozen");
|
|
@@ -3179,7 +3289,7 @@ var arrayExtensions = {
|
|
|
3179
3289
|
// which makes it both a 'derivation' and a 'mutation'.
|
|
3180
3290
|
// so we deviate from the default and just make it an dervitation
|
|
3181
3291
|
if (process.env.NODE_ENV !== "production") {
|
|
3182
|
-
console.warn("[mobx] `observableArray.reverse()` will not update the array in place. Use `observableArray.slice().reverse()` to
|
|
3292
|
+
console.warn("[mobx] `observableArray.reverse()` will not update the array in place. Use `observableArray.slice().reverse()` to suppress this warning and perform the operation on a copy, or `observableArray.replace(observableArray.slice().reverse())` to reverse & update in place");
|
|
3183
3293
|
}
|
|
3184
3294
|
var clone = this.slice();
|
|
3185
3295
|
return clone.reverse.apply(clone, arguments);
|
|
@@ -3188,7 +3298,7 @@ var arrayExtensions = {
|
|
|
3188
3298
|
// sort by default mutates in place before returning the result
|
|
3189
3299
|
// which goes against all good practices. Let's not change the array in place!
|
|
3190
3300
|
if (process.env.NODE_ENV !== "production") {
|
|
3191
|
-
console.warn("[mobx] `observableArray.sort()` will not update the array in place. Use `observableArray.slice().sort()` to
|
|
3301
|
+
console.warn("[mobx] `observableArray.sort()` will not update the array in place. Use `observableArray.slice().sort()` to suppress this warning and perform the operation on a copy, or `observableArray.replace(observableArray.slice().sort())` to sort & update in place");
|
|
3192
3302
|
}
|
|
3193
3303
|
var clone = this.slice();
|
|
3194
3304
|
return clone.sort.apply(clone, arguments);
|
|
@@ -3300,9 +3410,17 @@ var ObservableMap = /** @class */ (function () {
|
|
|
3300
3410
|
return this._data.has(key);
|
|
3301
3411
|
};
|
|
3302
3412
|
ObservableMap.prototype.has = function (key) {
|
|
3303
|
-
|
|
3304
|
-
|
|
3305
|
-
|
|
3413
|
+
var _this = this;
|
|
3414
|
+
if (!globalState.trackingDerivation)
|
|
3415
|
+
return this._has(key);
|
|
3416
|
+
var entry = this._hasMap.get(key);
|
|
3417
|
+
if (!entry) {
|
|
3418
|
+
// todo: replace with atom (breaking change)
|
|
3419
|
+
var newEntry = (entry = new ObservableValue(this._has(key), referenceEnhancer, this.name + "." + stringifyKey(key) + "?", false));
|
|
3420
|
+
this._hasMap.set(key, newEntry);
|
|
3421
|
+
onBecomeUnobserved(newEntry, function () { return _this._hasMap.delete(key); });
|
|
3422
|
+
}
|
|
3423
|
+
return entry.get();
|
|
3306
3424
|
};
|
|
3307
3425
|
ObservableMap.prototype.set = function (key, value) {
|
|
3308
3426
|
var hasKey = this._has(key);
|
|
@@ -3365,16 +3483,10 @@ var ObservableMap = /** @class */ (function () {
|
|
|
3365
3483
|
return false;
|
|
3366
3484
|
};
|
|
3367
3485
|
ObservableMap.prototype._updateHasMapEntry = function (key, value) {
|
|
3368
|
-
// optimization; don't fill the hasMap if we are not observing, or remove entry if there are no observers anymore
|
|
3369
3486
|
var entry = this._hasMap.get(key);
|
|
3370
3487
|
if (entry) {
|
|
3371
3488
|
entry.setNewValue(value);
|
|
3372
3489
|
}
|
|
3373
|
-
else {
|
|
3374
|
-
entry = new ObservableValue(value, referenceEnhancer, this.name + "." + stringifyKey(key) + "?", false);
|
|
3375
|
-
this._hasMap.set(key, entry);
|
|
3376
|
-
}
|
|
3377
|
-
return entry;
|
|
3378
3490
|
};
|
|
3379
3491
|
ObservableMap.prototype._updateValue = function (key, newValue) {
|
|
3380
3492
|
var observable = this._data.get(key);
|
|
@@ -4108,7 +4220,7 @@ function getAdministrationForComputedPropOwner(owner) {
|
|
|
4108
4220
|
function generateComputedPropConfig(propName) {
|
|
4109
4221
|
return (computedPropertyConfigs[propName] ||
|
|
4110
4222
|
(computedPropertyConfigs[propName] = {
|
|
4111
|
-
configurable:
|
|
4223
|
+
configurable: globalState.computedConfigurable,
|
|
4112
4224
|
enumerable: false,
|
|
4113
4225
|
get: function () {
|
|
4114
4226
|
return getAdministrationForComputedPropOwner(this).read(propName);
|
|
@@ -4334,17 +4446,17 @@ function has$1(a, key) {
|
|
|
4334
4446
|
}
|
|
4335
4447
|
|
|
4336
4448
|
function makeIterable(iterator) {
|
|
4337
|
-
iterator[Symbol.iterator] =
|
|
4449
|
+
iterator[Symbol.iterator] = getSelf;
|
|
4338
4450
|
return iterator;
|
|
4339
4451
|
}
|
|
4340
|
-
function
|
|
4452
|
+
function getSelf() {
|
|
4341
4453
|
return this;
|
|
4342
4454
|
}
|
|
4343
4455
|
|
|
4344
4456
|
/*
|
|
4345
4457
|
The only reason for this file to exist is pure horror:
|
|
4346
4458
|
Without it rollup can make the bundling fail at any point in time; when it rolls up the files in the wrong order
|
|
4347
|
-
it will cause undefined errors (for example because super classes or local variables not being
|
|
4459
|
+
it will cause undefined errors (for example because super classes or local variables not being hoisted).
|
|
4348
4460
|
With this file that will still happen,
|
|
4349
4461
|
but at least in this file we can magically reorder the imports with trial and error until the build succeeds again.
|
|
4350
4462
|
*/
|
|
@@ -4376,7 +4488,7 @@ try {
|
|
|
4376
4488
|
process.env.NODE_ENV;
|
|
4377
4489
|
}
|
|
4378
4490
|
catch (e) {
|
|
4379
|
-
var g =
|
|
4491
|
+
var g = getGlobal();
|
|
4380
4492
|
if (typeof process === "undefined")
|
|
4381
4493
|
g.process = {};
|
|
4382
4494
|
g.process.env = {};
|
|
@@ -4402,4 +4514,4 @@ if (typeof __MOBX_DEVTOOLS_GLOBAL_HOOK__ === "object") {
|
|
|
4402
4514
|
});
|
|
4403
4515
|
}
|
|
4404
4516
|
|
|
4405
|
-
export { $mobx, IDerivationState, ObservableMap, ObservableSet, Reaction, allowStateChanges as _allowStateChanges, allowStateChangesInsideComputed as _allowStateChangesInsideComputed, getAdministration as _getAdministration, getGlobalState as _getGlobalState, interceptReads as _interceptReads, isComputingDerivation as _isComputingDerivation, resetGlobalState as _resetGlobalState, action, autorun, comparer, computed, configure, createAtom, decorate, entries, extendObservable, flow, get, getAtom, getDebugName, getDependencyTree, getObserverTree, has, intercept, isAction, isArrayLike, isObservableValue as isBoxedObservable, isComputed, isComputedProp, isObservable, isObservableArray, isObservableMap, isObservableObject, isObservableProp, isObservableSet, keys, observable, observe, onBecomeObserved, onBecomeUnobserved, onReactionError, reaction, remove, runInAction, set, spy, toJS, trace, transaction, untracked, values, when };
|
|
4517
|
+
export { $mobx, IDerivationState, ObservableMap, ObservableSet, Reaction, allowStateChanges as _allowStateChanges, allowStateChangesInsideComputed as _allowStateChangesInsideComputed, _endAction, getAdministration as _getAdministration, getGlobalState as _getGlobalState, interceptReads as _interceptReads, isComputingDerivation as _isComputingDerivation, resetGlobalState as _resetGlobalState, _startAction, action, autorun, comparer, computed, configure, createAtom, decorate, entries, extendObservable, flow, get, getAtom, getDebugName, getDependencyTree, getObserverTree, has, intercept, isAction, isArrayLike, isObservableValue as isBoxedObservable, isComputed, isComputedProp, isObservable, isObservableArray, isObservableMap, isObservableObject, isObservableProp, isObservableSet, keys, observable, observe, onBecomeObserved, onBecomeUnobserved, onReactionError, reaction, remove, runInAction, set, spy, toJS, trace, transaction, untracked, values, when };
|