mobx 7.0.0 → 7.0.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/CHANGELOG.md +14 -0
- package/dist/core/atom.d.ts +1 -1
- package/dist/core/computedvalue.d.ts +1 -1
- package/dist/core/globalstate.d.ts +7 -0
- package/dist/core/observable.d.ts +9 -1
- package/dist/mobx.cjs.development.js +93 -56
- package/dist/mobx.cjs.development.js.map +1 -1
- package/dist/mobx.cjs.production.min.js +1 -1
- package/dist/mobx.cjs.production.min.js.map +1 -1
- package/dist/mobx.esm.development.js +93 -56
- package/dist/mobx.esm.development.js.map +1 -1
- package/dist/mobx.esm.js +93 -56
- package/dist/mobx.esm.js.map +1 -1
- package/dist/mobx.esm.production.min.js +1 -1
- package/dist/mobx.esm.production.min.js.map +1 -1
- package/dist/mobx.mjs +93 -56
- package/dist/mobx.mjs.map +1 -1
- package/dist/mobx.umd.development.js +93 -56
- package/dist/mobx.umd.development.js.map +1 -1
- package/dist/mobx.umd.production.min.js +1 -1
- package/dist/mobx.umd.production.min.js.map +1 -1
- package/package.json +1 -1
- package/src/core/atom.ts +2 -1
- package/src/core/computedvalue.ts +9 -2
- package/src/core/derivation.ts +1 -1
- package/src/core/globalstate.ts +8 -0
- package/src/core/observable.ts +65 -25
- package/src/types/modifiers.ts +5 -0
- package/src/types/observableset.ts +4 -24
package/dist/mobx.mjs
CHANGED
|
@@ -260,7 +260,8 @@ class Atom {
|
|
|
260
260
|
constructor(name_ = process.env.NODE_ENV !== "production" ? "Atom@" + getNextId() : "Atom") {
|
|
261
261
|
this.name_ = void 0;
|
|
262
262
|
this.flags_ = 0b000;
|
|
263
|
-
|
|
263
|
+
// Allocated lazily on first observer to save memory.
|
|
264
|
+
this.observers_ = null;
|
|
264
265
|
this.lastAccessedBy_ = 0;
|
|
265
266
|
this.lowestObserverState_ = -1 /* IDerivationState_.NOT_TRACKING_ */;
|
|
266
267
|
// onBecomeObservedListeners
|
|
@@ -342,6 +343,10 @@ function compareShallow(a, b) {
|
|
|
342
343
|
const compareDefault = Object.is;
|
|
343
344
|
|
|
344
345
|
function deepEnhancer(v, _, name) {
|
|
346
|
+
// primitives can never be made observable; skip the type checks below
|
|
347
|
+
if (v === null || typeof v !== "object" && typeof v !== "function") {
|
|
348
|
+
return v;
|
|
349
|
+
}
|
|
345
350
|
// it is an observable already, done
|
|
346
351
|
if (isObservable(v)) {
|
|
347
352
|
return v;
|
|
@@ -1282,7 +1287,8 @@ class ComputedValue {
|
|
|
1282
1287
|
// nodes we are looking at. Our value depends on these nodes
|
|
1283
1288
|
this.newObserving_ = null;
|
|
1284
1289
|
// during tracking it's an array with new observed observers
|
|
1285
|
-
|
|
1290
|
+
// Lazily allocated on first observer - see Atom.observers_.
|
|
1291
|
+
this.observers_ = null;
|
|
1286
1292
|
this.runId_ = 0;
|
|
1287
1293
|
this.lastAccessedBy_ = 0;
|
|
1288
1294
|
this.lowestObserverState_ = 0 /* IDerivationState_.UP_TO_DATE_ */;
|
|
@@ -1365,9 +1371,9 @@ class ComputedValue {
|
|
|
1365
1371
|
if (this.isComputing) {
|
|
1366
1372
|
die(32, this.name_, this.derivation);
|
|
1367
1373
|
}
|
|
1368
|
-
if (globalState.inBatch === 0 &&
|
|
1374
|
+
if (globalState.inBatch === 0 && (
|
|
1369
1375
|
// !globalState.trackingDerivatpion &&
|
|
1370
|
-
this.observers_.size === 0 && !this.keepAlive_) {
|
|
1376
|
+
!this.observers_ || this.observers_.size === 0) && !this.keepAlive_) {
|
|
1371
1377
|
if (shouldCompute(this)) {
|
|
1372
1378
|
this.warnAboutUntrackedRead_();
|
|
1373
1379
|
startBatch(); // See perf test 'computed memoization'
|
|
@@ -1375,6 +1381,7 @@ class ComputedValue {
|
|
|
1375
1381
|
endBatch();
|
|
1376
1382
|
}
|
|
1377
1383
|
} else {
|
|
1384
|
+
const wasBeingObserved = this.isBeingObserved;
|
|
1378
1385
|
reportObserved(this);
|
|
1379
1386
|
if (shouldCompute(this)) {
|
|
1380
1387
|
let prevTrackingContext = globalState.trackingContext;
|
|
@@ -1385,6 +1392,10 @@ class ComputedValue {
|
|
|
1385
1392
|
propagateChangeConfirmed(this);
|
|
1386
1393
|
}
|
|
1387
1394
|
globalState.trackingContext = prevTrackingContext;
|
|
1395
|
+
} else if (!wasBeingObserved && this.isBeingObserved) {
|
|
1396
|
+
// We just became observed while serving a cached value, so the getter
|
|
1397
|
+
// won't run and won't re-report our dependencies. Cascade to them. #4547
|
|
1398
|
+
this.observing_.forEach(markObserved);
|
|
1388
1399
|
}
|
|
1389
1400
|
}
|
|
1390
1401
|
const result = this.value_;
|
|
@@ -1559,7 +1570,7 @@ function checkIfStateModificationsAreAllowed(atom) {
|
|
|
1559
1570
|
if (!(process.env.NODE_ENV !== "production")) {
|
|
1560
1571
|
return;
|
|
1561
1572
|
}
|
|
1562
|
-
const hasObservers = atom.observers_.size > 0;
|
|
1573
|
+
const hasObservers = !!atom.observers_ && atom.observers_.size > 0;
|
|
1563
1574
|
// Should not be possible to change observed state outside strict mode, except during initialization, see #563
|
|
1564
1575
|
if (!globalState.allowStateChanges && (hasObservers || globalState.enforceActions === "always")) {
|
|
1565
1576
|
console.warn("[MobX] " + (globalState.enforceActions ? "Since strict-mode is enabled, changing (observed) observable values without using an action is not allowed. Tried to modify: " : "Side effects like changing state are not allowed at this point. Are you trying to modify state from, for example, a computed value or the render function of a React component? You can wrap side effects in 'runInAction' (or decorate functions with 'action') if needed. Tried to modify: ") + atom.name_);
|
|
@@ -1785,6 +1796,13 @@ class MobXGlobals {
|
|
|
1785
1796
|
* Are we currently processing reactions?
|
|
1786
1797
|
*/
|
|
1787
1798
|
this.isRunningReactions = false;
|
|
1799
|
+
/**
|
|
1800
|
+
* Are we currently draining pendingUnobservations in endBatch?
|
|
1801
|
+
* An onBecomeUnobserved handler can dispose a Reaction, which calls
|
|
1802
|
+
* startBatch/endBatch again; this guards against re-entering the same
|
|
1803
|
+
* drain loop recursively (see endBatch in observable.ts).
|
|
1804
|
+
*/
|
|
1805
|
+
this.isRunningUnobservations = false;
|
|
1788
1806
|
/**
|
|
1789
1807
|
* Is it allowed to change observables at this point?
|
|
1790
1808
|
* In general, MobX doesn't allow that when running computations and React.render.
|
|
@@ -1901,10 +1919,11 @@ function resetGlobalState() {
|
|
|
1901
1919
|
}
|
|
1902
1920
|
|
|
1903
1921
|
function hasObservers(observable) {
|
|
1904
|
-
return observable.observers_ && observable.observers_.size > 0;
|
|
1922
|
+
return !!observable.observers_ && observable.observers_.size > 0;
|
|
1905
1923
|
}
|
|
1906
1924
|
function getObservers(observable) {
|
|
1907
|
-
|
|
1925
|
+
var _observable$observers;
|
|
1926
|
+
return (_observable$observers = observable.observers_) != null ? _observable$observers : new Set();
|
|
1908
1927
|
}
|
|
1909
1928
|
// function invariantObservers(observable: IObservable) {
|
|
1910
1929
|
// const list = observable.observers
|
|
@@ -1924,10 +1943,8 @@ function getObservers(observable) {
|
|
|
1924
1943
|
// )
|
|
1925
1944
|
// }
|
|
1926
1945
|
function addObserver(observable, node) {
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
// invariantObservers(observable);
|
|
1930
|
-
observable.observers_.add(node);
|
|
1946
|
+
var _observable$observers2;
|
|
1947
|
+
((_observable$observers2 = observable.observers_) != null ? _observable$observers2 : observable.observers_ = new Set()).add(node);
|
|
1931
1948
|
if (observable.lowestObserverState_ > node.dependenciesState_) {
|
|
1932
1949
|
observable.lowestObserverState_ = node.dependenciesState_;
|
|
1933
1950
|
}
|
|
@@ -1938,8 +1955,12 @@ function removeObserver(observable, node) {
|
|
|
1938
1955
|
// invariant(globalState.inBatch > 0, "INTERNAL ERROR, remove should be called only inside batch");
|
|
1939
1956
|
// invariant(observable._observers.indexOf(node) !== -1, "INTERNAL ERROR remove already removed node");
|
|
1940
1957
|
// invariantObservers(observable);
|
|
1941
|
-
observable.observers_
|
|
1942
|
-
if (
|
|
1958
|
+
const observers = observable.observers_;
|
|
1959
|
+
if (!observers) {
|
|
1960
|
+
return;
|
|
1961
|
+
}
|
|
1962
|
+
observers.delete(node);
|
|
1963
|
+
if (observers.size === 0) {
|
|
1943
1964
|
// deleting last observer
|
|
1944
1965
|
queueForUnobservation(observable);
|
|
1945
1966
|
}
|
|
@@ -1965,26 +1986,59 @@ function endBatch() {
|
|
|
1965
1986
|
if (--globalState.inBatch === 0) {
|
|
1966
1987
|
runReactions();
|
|
1967
1988
|
// the batch is actually about to finish, all unobserving should happen here.
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1989
|
+
// Guard against re-entering this loop: an onBUO handler can dispose a Reaction,
|
|
1990
|
+
// which calls startBatch/endBatch again while we're still iterating. Bail out of
|
|
1991
|
+
// the nested call instead of recursing; the outer loop re-reads list.length on
|
|
1992
|
+
// every iteration, so it picks up anything the nested dispose() pushes onto the
|
|
1993
|
+
// same pendingUnobservations array.
|
|
1994
|
+
if (!globalState.isRunningUnobservations) {
|
|
1995
|
+
globalState.isRunningUnobservations = true;
|
|
1996
|
+
try {
|
|
1997
|
+
const list = globalState.pendingUnobservations;
|
|
1998
|
+
for (let i = 0; i < list.length; i++) {
|
|
1999
|
+
const observable = list[i];
|
|
2000
|
+
observable.isPendingUnobservation = false;
|
|
2001
|
+
if (!observable.observers_ || observable.observers_.size === 0) {
|
|
2002
|
+
if (observable.isBeingObserved) {
|
|
2003
|
+
// if this observable had reactive observers, trigger the hooks
|
|
2004
|
+
observable.isBeingObserved = false;
|
|
2005
|
+
observable.onBUO();
|
|
2006
|
+
}
|
|
2007
|
+
if (observable instanceof ComputedValue) {
|
|
2008
|
+
// computed values are automatically teared down when the last observer leaves
|
|
2009
|
+
// this process happens recursively, this computed might be the last observabe of another, etc..
|
|
2010
|
+
observable.suspend_();
|
|
2011
|
+
}
|
|
2012
|
+
}
|
|
1982
2013
|
}
|
|
2014
|
+
globalState.pendingUnobservations = [];
|
|
2015
|
+
} finally {
|
|
2016
|
+
// Always release the guard, even if an onBUO handler (user code) threw,
|
|
2017
|
+
// otherwise every future endBatch() would see isRunningUnobservations
|
|
2018
|
+
// stuck true and silently stop draining pendingUnobservations forever.
|
|
2019
|
+
globalState.isRunningUnobservations = false;
|
|
1983
2020
|
}
|
|
1984
2021
|
}
|
|
1985
|
-
globalState.pendingUnobservations = [];
|
|
1986
2022
|
}
|
|
1987
2023
|
}
|
|
2024
|
+
/**
|
|
2025
|
+
* Marks an observable as observed, cascading into the dependencies of a ComputedValue.
|
|
2026
|
+
* Unobservation already cascades (`suspend_` -> `clearObserving`), observation normally
|
|
2027
|
+
* only does so by accident: a newly observed computed usually recomputes and re-reports
|
|
2028
|
+
* its dependencies. When it serves a cached value instead nothing re-reports them, so the
|
|
2029
|
+
* transition has to be propagated by hand. See #4547.
|
|
2030
|
+
*/
|
|
2031
|
+
function markObserved(observable) {
|
|
2032
|
+
var _observable$observing;
|
|
2033
|
+
if (observable.isBeingObserved) {
|
|
2034
|
+
return;
|
|
2035
|
+
}
|
|
2036
|
+
observable.isBeingObserved = true;
|
|
2037
|
+
observable.onBO();
|
|
2038
|
+
// No queueForUnobservation here: the observer links already exist, so the regular
|
|
2039
|
+
// suspend_ -> clearObserving -> removeObserver teardown still delivers the onBUO.
|
|
2040
|
+
(_observable$observing = observable.observing_) == null || _observable$observing.forEach(markObserved);
|
|
2041
|
+
}
|
|
1988
2042
|
function reportObserved(observable) {
|
|
1989
2043
|
checkIfStateReadsAreAllowed(observable);
|
|
1990
2044
|
const derivation = globalState.trackingDerivation;
|
|
@@ -2004,7 +2058,7 @@ function reportObserved(observable) {
|
|
|
2004
2058
|
}
|
|
2005
2059
|
}
|
|
2006
2060
|
return observable.isBeingObserved;
|
|
2007
|
-
} else if (observable.observers_.size === 0 && globalState.inBatch > 0) {
|
|
2061
|
+
} else if ((!observable.observers_ || observable.observers_.size === 0) && globalState.inBatch > 0) {
|
|
2008
2062
|
queueForUnobservation(observable);
|
|
2009
2063
|
}
|
|
2010
2064
|
return false;
|
|
@@ -2031,13 +2085,14 @@ function reportObserved(observable) {
|
|
|
2031
2085
|
*/
|
|
2032
2086
|
// Called by Atom when its value changes
|
|
2033
2087
|
function propagateChanged(observable) {
|
|
2088
|
+
var _observable$observers3;
|
|
2034
2089
|
// invariantLOS(observable, "changed start");
|
|
2035
2090
|
if (observable.lowestObserverState_ === 2 /* IDerivationState_.STALE_ */) {
|
|
2036
2091
|
return;
|
|
2037
2092
|
}
|
|
2038
2093
|
observable.lowestObserverState_ = 2 /* IDerivationState_.STALE_ */;
|
|
2039
2094
|
// Ideally we use for..of here, but the downcompiled version is really slow...
|
|
2040
|
-
observable.observers_.forEach(d => {
|
|
2095
|
+
(_observable$observers3 = observable.observers_) == null || _observable$observers3.forEach(d => {
|
|
2041
2096
|
if (d.dependenciesState_ === 0 /* IDerivationState_.UP_TO_DATE_ */) {
|
|
2042
2097
|
d.onBecomeStale_();
|
|
2043
2098
|
}
|
|
@@ -2047,12 +2102,13 @@ function propagateChanged(observable) {
|
|
|
2047
2102
|
}
|
|
2048
2103
|
// Called by ComputedValue when it recalculate and its value changed
|
|
2049
2104
|
function propagateChangeConfirmed(observable) {
|
|
2105
|
+
var _observable$observers4;
|
|
2050
2106
|
// invariantLOS(observable, "confirmed start");
|
|
2051
2107
|
if (observable.lowestObserverState_ === 2 /* IDerivationState_.STALE_ */) {
|
|
2052
2108
|
return;
|
|
2053
2109
|
}
|
|
2054
2110
|
observable.lowestObserverState_ = 2 /* IDerivationState_.STALE_ */;
|
|
2055
|
-
observable.observers_.forEach(d => {
|
|
2111
|
+
(_observable$observers4 = observable.observers_) == null || _observable$observers4.forEach(d => {
|
|
2056
2112
|
if (d.dependenciesState_ === 1 /* IDerivationState_.POSSIBLY_STALE_ */) {
|
|
2057
2113
|
d.dependenciesState_ = 2 /* IDerivationState_.STALE_ */;
|
|
2058
2114
|
} else if (d.dependenciesState_ === 0 /* IDerivationState_.UP_TO_DATE_ */ // this happens during computing of `d`, just keep lowestObserverState up to date.
|
|
@@ -2064,12 +2120,13 @@ function propagateChangeConfirmed(observable) {
|
|
|
2064
2120
|
}
|
|
2065
2121
|
// Used by computed when its dependency changed, but we don't wan't to immediately recompute.
|
|
2066
2122
|
function propagateMaybeChanged(observable) {
|
|
2123
|
+
var _observable$observers5;
|
|
2067
2124
|
// invariantLOS(observable, "maybe start");
|
|
2068
2125
|
if (observable.lowestObserverState_ !== 0 /* IDerivationState_.UP_TO_DATE_ */) {
|
|
2069
2126
|
return;
|
|
2070
2127
|
}
|
|
2071
2128
|
observable.lowestObserverState_ = 1 /* IDerivationState_.POSSIBLY_STALE_ */;
|
|
2072
|
-
observable.observers_.forEach(d => {
|
|
2129
|
+
(_observable$observers5 = observable.observers_) == null || _observable$observers5.forEach(d => {
|
|
2073
2130
|
if (d.dependenciesState_ === 0 /* IDerivationState_.UP_TO_DATE_ */) {
|
|
2074
2131
|
d.dependenciesState_ = 1 /* IDerivationState_.POSSIBLY_STALE_ */;
|
|
2075
2132
|
d.onBecomeStale_();
|
|
@@ -4336,31 +4393,16 @@ class ObservableSet {
|
|
|
4336
4393
|
});
|
|
4337
4394
|
}
|
|
4338
4395
|
intersection(otherSet) {
|
|
4339
|
-
|
|
4340
|
-
return otherSet.intersection(this);
|
|
4341
|
-
} else {
|
|
4342
|
-
const dehancedSet = new Set(this);
|
|
4343
|
-
return dehancedSet.intersection(otherSet);
|
|
4344
|
-
}
|
|
4396
|
+
return new Set(this).intersection(otherSet);
|
|
4345
4397
|
}
|
|
4346
4398
|
union(otherSet) {
|
|
4347
|
-
|
|
4348
|
-
return otherSet.union(this);
|
|
4349
|
-
} else {
|
|
4350
|
-
const dehancedSet = new Set(this);
|
|
4351
|
-
return dehancedSet.union(otherSet);
|
|
4352
|
-
}
|
|
4399
|
+
return new Set(this).union(otherSet);
|
|
4353
4400
|
}
|
|
4354
4401
|
difference(otherSet) {
|
|
4355
4402
|
return new Set(this).difference(otherSet);
|
|
4356
4403
|
}
|
|
4357
4404
|
symmetricDifference(otherSet) {
|
|
4358
|
-
|
|
4359
|
-
return otherSet.symmetricDifference(this);
|
|
4360
|
-
} else {
|
|
4361
|
-
const dehancedSet = new Set(this);
|
|
4362
|
-
return dehancedSet.symmetricDifference(otherSet);
|
|
4363
|
-
}
|
|
4405
|
+
return new Set(this).symmetricDifference(otherSet);
|
|
4364
4406
|
}
|
|
4365
4407
|
isSubsetOf(otherSet) {
|
|
4366
4408
|
return new Set(this).isSubsetOf(otherSet);
|
|
@@ -4369,12 +4411,7 @@ class ObservableSet {
|
|
|
4369
4411
|
return new Set(this).isSupersetOf(otherSet);
|
|
4370
4412
|
}
|
|
4371
4413
|
isDisjointFrom(otherSet) {
|
|
4372
|
-
|
|
4373
|
-
return otherSet.isDisjointFrom(this);
|
|
4374
|
-
} else {
|
|
4375
|
-
const dehancedSet = new Set(this);
|
|
4376
|
-
return dehancedSet.isDisjointFrom(otherSet);
|
|
4377
|
-
}
|
|
4414
|
+
return new Set(this).isDisjointFrom(otherSet);
|
|
4378
4415
|
}
|
|
4379
4416
|
replace(other) {
|
|
4380
4417
|
if (isObservableSet(other)) {
|