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
|
@@ -265,7 +265,8 @@
|
|
|
265
265
|
constructor(name_ = "Atom@" + getNextId() ) {
|
|
266
266
|
this.name_ = void 0;
|
|
267
267
|
this.flags_ = 0b000;
|
|
268
|
-
|
|
268
|
+
// Allocated lazily on first observer to save memory.
|
|
269
|
+
this.observers_ = null;
|
|
269
270
|
this.lastAccessedBy_ = 0;
|
|
270
271
|
this.lowestObserverState_ = -1 /* IDerivationState_.NOT_TRACKING_ */;
|
|
271
272
|
// onBecomeObservedListeners
|
|
@@ -347,6 +348,10 @@
|
|
|
347
348
|
const compareDefault = Object.is;
|
|
348
349
|
|
|
349
350
|
function deepEnhancer(v, _, name) {
|
|
351
|
+
// primitives can never be made observable; skip the type checks below
|
|
352
|
+
if (v === null || typeof v !== "object" && typeof v !== "function") {
|
|
353
|
+
return v;
|
|
354
|
+
}
|
|
350
355
|
// it is an observable already, done
|
|
351
356
|
if (isObservable(v)) {
|
|
352
357
|
return v;
|
|
@@ -1287,7 +1292,8 @@
|
|
|
1287
1292
|
// nodes we are looking at. Our value depends on these nodes
|
|
1288
1293
|
this.newObserving_ = null;
|
|
1289
1294
|
// during tracking it's an array with new observed observers
|
|
1290
|
-
|
|
1295
|
+
// Lazily allocated on first observer - see Atom.observers_.
|
|
1296
|
+
this.observers_ = null;
|
|
1291
1297
|
this.runId_ = 0;
|
|
1292
1298
|
this.lastAccessedBy_ = 0;
|
|
1293
1299
|
this.lowestObserverState_ = 0 /* IDerivationState_.UP_TO_DATE_ */;
|
|
@@ -1370,9 +1376,9 @@
|
|
|
1370
1376
|
if (this.isComputing) {
|
|
1371
1377
|
die(32, this.name_, this.derivation);
|
|
1372
1378
|
}
|
|
1373
|
-
if (globalState.inBatch === 0 &&
|
|
1379
|
+
if (globalState.inBatch === 0 && (
|
|
1374
1380
|
// !globalState.trackingDerivatpion &&
|
|
1375
|
-
this.observers_.size === 0 && !this.keepAlive_) {
|
|
1381
|
+
!this.observers_ || this.observers_.size === 0) && !this.keepAlive_) {
|
|
1376
1382
|
if (shouldCompute(this)) {
|
|
1377
1383
|
this.warnAboutUntrackedRead_();
|
|
1378
1384
|
startBatch(); // See perf test 'computed memoization'
|
|
@@ -1380,6 +1386,7 @@
|
|
|
1380
1386
|
endBatch();
|
|
1381
1387
|
}
|
|
1382
1388
|
} else {
|
|
1389
|
+
const wasBeingObserved = this.isBeingObserved;
|
|
1383
1390
|
reportObserved(this);
|
|
1384
1391
|
if (shouldCompute(this)) {
|
|
1385
1392
|
let prevTrackingContext = globalState.trackingContext;
|
|
@@ -1390,6 +1397,10 @@
|
|
|
1390
1397
|
propagateChangeConfirmed(this);
|
|
1391
1398
|
}
|
|
1392
1399
|
globalState.trackingContext = prevTrackingContext;
|
|
1400
|
+
} else if (!wasBeingObserved && this.isBeingObserved) {
|
|
1401
|
+
// We just became observed while serving a cached value, so the getter
|
|
1402
|
+
// won't run and won't re-report our dependencies. Cascade to them. #4547
|
|
1403
|
+
this.observing_.forEach(markObserved);
|
|
1393
1404
|
}
|
|
1394
1405
|
}
|
|
1395
1406
|
const result = this.value_;
|
|
@@ -1558,7 +1569,7 @@
|
|
|
1558
1569
|
return globalState.trackingDerivation !== null; // filter out actions inside computations
|
|
1559
1570
|
}
|
|
1560
1571
|
function checkIfStateModificationsAreAllowed(atom) {
|
|
1561
|
-
const hasObservers = atom.observers_.size > 0;
|
|
1572
|
+
const hasObservers = !!atom.observers_ && atom.observers_.size > 0;
|
|
1562
1573
|
// Should not be possible to change observed state outside strict mode, except during initialization, see #563
|
|
1563
1574
|
if (!globalState.allowStateChanges && (hasObservers || globalState.enforceActions === "always")) {
|
|
1564
1575
|
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_);
|
|
@@ -1781,6 +1792,13 @@
|
|
|
1781
1792
|
* Are we currently processing reactions?
|
|
1782
1793
|
*/
|
|
1783
1794
|
this.isRunningReactions = false;
|
|
1795
|
+
/**
|
|
1796
|
+
* Are we currently draining pendingUnobservations in endBatch?
|
|
1797
|
+
* An onBecomeUnobserved handler can dispose a Reaction, which calls
|
|
1798
|
+
* startBatch/endBatch again; this guards against re-entering the same
|
|
1799
|
+
* drain loop recursively (see endBatch in observable.ts).
|
|
1800
|
+
*/
|
|
1801
|
+
this.isRunningUnobservations = false;
|
|
1784
1802
|
/**
|
|
1785
1803
|
* Is it allowed to change observables at this point?
|
|
1786
1804
|
* In general, MobX doesn't allow that when running computations and React.render.
|
|
@@ -1897,10 +1915,11 @@
|
|
|
1897
1915
|
}
|
|
1898
1916
|
|
|
1899
1917
|
function hasObservers(observable) {
|
|
1900
|
-
return observable.observers_ && observable.observers_.size > 0;
|
|
1918
|
+
return !!observable.observers_ && observable.observers_.size > 0;
|
|
1901
1919
|
}
|
|
1902
1920
|
function getObservers(observable) {
|
|
1903
|
-
|
|
1921
|
+
var _observable$observers;
|
|
1922
|
+
return (_observable$observers = observable.observers_) != null ? _observable$observers : new Set();
|
|
1904
1923
|
}
|
|
1905
1924
|
// function invariantObservers(observable: IObservable) {
|
|
1906
1925
|
// const list = observable.observers
|
|
@@ -1920,10 +1939,8 @@
|
|
|
1920
1939
|
// )
|
|
1921
1940
|
// }
|
|
1922
1941
|
function addObserver(observable, node) {
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
// invariantObservers(observable);
|
|
1926
|
-
observable.observers_.add(node);
|
|
1942
|
+
var _observable$observers2;
|
|
1943
|
+
((_observable$observers2 = observable.observers_) != null ? _observable$observers2 : observable.observers_ = new Set()).add(node);
|
|
1927
1944
|
if (observable.lowestObserverState_ > node.dependenciesState_) {
|
|
1928
1945
|
observable.lowestObserverState_ = node.dependenciesState_;
|
|
1929
1946
|
}
|
|
@@ -1934,8 +1951,12 @@
|
|
|
1934
1951
|
// invariant(globalState.inBatch > 0, "INTERNAL ERROR, remove should be called only inside batch");
|
|
1935
1952
|
// invariant(observable._observers.indexOf(node) !== -1, "INTERNAL ERROR remove already removed node");
|
|
1936
1953
|
// invariantObservers(observable);
|
|
1937
|
-
observable.observers_
|
|
1938
|
-
if (
|
|
1954
|
+
const observers = observable.observers_;
|
|
1955
|
+
if (!observers) {
|
|
1956
|
+
return;
|
|
1957
|
+
}
|
|
1958
|
+
observers.delete(node);
|
|
1959
|
+
if (observers.size === 0) {
|
|
1939
1960
|
// deleting last observer
|
|
1940
1961
|
queueForUnobservation(observable);
|
|
1941
1962
|
}
|
|
@@ -1961,26 +1982,59 @@
|
|
|
1961
1982
|
if (--globalState.inBatch === 0) {
|
|
1962
1983
|
runReactions();
|
|
1963
1984
|
// the batch is actually about to finish, all unobserving should happen here.
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1985
|
+
// Guard against re-entering this loop: an onBUO handler can dispose a Reaction,
|
|
1986
|
+
// which calls startBatch/endBatch again while we're still iterating. Bail out of
|
|
1987
|
+
// the nested call instead of recursing; the outer loop re-reads list.length on
|
|
1988
|
+
// every iteration, so it picks up anything the nested dispose() pushes onto the
|
|
1989
|
+
// same pendingUnobservations array.
|
|
1990
|
+
if (!globalState.isRunningUnobservations) {
|
|
1991
|
+
globalState.isRunningUnobservations = true;
|
|
1992
|
+
try {
|
|
1993
|
+
const list = globalState.pendingUnobservations;
|
|
1994
|
+
for (let i = 0; i < list.length; i++) {
|
|
1995
|
+
const observable = list[i];
|
|
1996
|
+
observable.isPendingUnobservation = false;
|
|
1997
|
+
if (!observable.observers_ || observable.observers_.size === 0) {
|
|
1998
|
+
if (observable.isBeingObserved) {
|
|
1999
|
+
// if this observable had reactive observers, trigger the hooks
|
|
2000
|
+
observable.isBeingObserved = false;
|
|
2001
|
+
observable.onBUO();
|
|
2002
|
+
}
|
|
2003
|
+
if (observable instanceof ComputedValue) {
|
|
2004
|
+
// computed values are automatically teared down when the last observer leaves
|
|
2005
|
+
// this process happens recursively, this computed might be the last observabe of another, etc..
|
|
2006
|
+
observable.suspend_();
|
|
2007
|
+
}
|
|
2008
|
+
}
|
|
1978
2009
|
}
|
|
2010
|
+
globalState.pendingUnobservations = [];
|
|
2011
|
+
} finally {
|
|
2012
|
+
// Always release the guard, even if an onBUO handler (user code) threw,
|
|
2013
|
+
// otherwise every future endBatch() would see isRunningUnobservations
|
|
2014
|
+
// stuck true and silently stop draining pendingUnobservations forever.
|
|
2015
|
+
globalState.isRunningUnobservations = false;
|
|
1979
2016
|
}
|
|
1980
2017
|
}
|
|
1981
|
-
globalState.pendingUnobservations = [];
|
|
1982
2018
|
}
|
|
1983
2019
|
}
|
|
2020
|
+
/**
|
|
2021
|
+
* Marks an observable as observed, cascading into the dependencies of a ComputedValue.
|
|
2022
|
+
* Unobservation already cascades (`suspend_` -> `clearObserving`), observation normally
|
|
2023
|
+
* only does so by accident: a newly observed computed usually recomputes and re-reports
|
|
2024
|
+
* its dependencies. When it serves a cached value instead nothing re-reports them, so the
|
|
2025
|
+
* transition has to be propagated by hand. See #4547.
|
|
2026
|
+
*/
|
|
2027
|
+
function markObserved(observable) {
|
|
2028
|
+
var _observable$observing;
|
|
2029
|
+
if (observable.isBeingObserved) {
|
|
2030
|
+
return;
|
|
2031
|
+
}
|
|
2032
|
+
observable.isBeingObserved = true;
|
|
2033
|
+
observable.onBO();
|
|
2034
|
+
// No queueForUnobservation here: the observer links already exist, so the regular
|
|
2035
|
+
// suspend_ -> clearObserving -> removeObserver teardown still delivers the onBUO.
|
|
2036
|
+
(_observable$observing = observable.observing_) == null || _observable$observing.forEach(markObserved);
|
|
2037
|
+
}
|
|
1984
2038
|
function reportObserved(observable) {
|
|
1985
2039
|
checkIfStateReadsAreAllowed(observable);
|
|
1986
2040
|
const derivation = globalState.trackingDerivation;
|
|
@@ -2000,7 +2054,7 @@
|
|
|
2000
2054
|
}
|
|
2001
2055
|
}
|
|
2002
2056
|
return observable.isBeingObserved;
|
|
2003
|
-
} else if (observable.observers_.size === 0 && globalState.inBatch > 0) {
|
|
2057
|
+
} else if ((!observable.observers_ || observable.observers_.size === 0) && globalState.inBatch > 0) {
|
|
2004
2058
|
queueForUnobservation(observable);
|
|
2005
2059
|
}
|
|
2006
2060
|
return false;
|
|
@@ -2027,13 +2081,14 @@
|
|
|
2027
2081
|
*/
|
|
2028
2082
|
// Called by Atom when its value changes
|
|
2029
2083
|
function propagateChanged(observable) {
|
|
2084
|
+
var _observable$observers3;
|
|
2030
2085
|
// invariantLOS(observable, "changed start");
|
|
2031
2086
|
if (observable.lowestObserverState_ === 2 /* IDerivationState_.STALE_ */) {
|
|
2032
2087
|
return;
|
|
2033
2088
|
}
|
|
2034
2089
|
observable.lowestObserverState_ = 2 /* IDerivationState_.STALE_ */;
|
|
2035
2090
|
// Ideally we use for..of here, but the downcompiled version is really slow...
|
|
2036
|
-
observable.observers_.forEach(d => {
|
|
2091
|
+
(_observable$observers3 = observable.observers_) == null || _observable$observers3.forEach(d => {
|
|
2037
2092
|
if (d.dependenciesState_ === 0 /* IDerivationState_.UP_TO_DATE_ */) {
|
|
2038
2093
|
d.onBecomeStale_();
|
|
2039
2094
|
}
|
|
@@ -2043,12 +2098,13 @@
|
|
|
2043
2098
|
}
|
|
2044
2099
|
// Called by ComputedValue when it recalculate and its value changed
|
|
2045
2100
|
function propagateChangeConfirmed(observable) {
|
|
2101
|
+
var _observable$observers4;
|
|
2046
2102
|
// invariantLOS(observable, "confirmed start");
|
|
2047
2103
|
if (observable.lowestObserverState_ === 2 /* IDerivationState_.STALE_ */) {
|
|
2048
2104
|
return;
|
|
2049
2105
|
}
|
|
2050
2106
|
observable.lowestObserverState_ = 2 /* IDerivationState_.STALE_ */;
|
|
2051
|
-
observable.observers_.forEach(d => {
|
|
2107
|
+
(_observable$observers4 = observable.observers_) == null || _observable$observers4.forEach(d => {
|
|
2052
2108
|
if (d.dependenciesState_ === 1 /* IDerivationState_.POSSIBLY_STALE_ */) {
|
|
2053
2109
|
d.dependenciesState_ = 2 /* IDerivationState_.STALE_ */;
|
|
2054
2110
|
} else if (d.dependenciesState_ === 0 /* IDerivationState_.UP_TO_DATE_ */ // this happens during computing of `d`, just keep lowestObserverState up to date.
|
|
@@ -2060,12 +2116,13 @@
|
|
|
2060
2116
|
}
|
|
2061
2117
|
// Used by computed when its dependency changed, but we don't wan't to immediately recompute.
|
|
2062
2118
|
function propagateMaybeChanged(observable) {
|
|
2119
|
+
var _observable$observers5;
|
|
2063
2120
|
// invariantLOS(observable, "maybe start");
|
|
2064
2121
|
if (observable.lowestObserverState_ !== 0 /* IDerivationState_.UP_TO_DATE_ */) {
|
|
2065
2122
|
return;
|
|
2066
2123
|
}
|
|
2067
2124
|
observable.lowestObserverState_ = 1 /* IDerivationState_.POSSIBLY_STALE_ */;
|
|
2068
|
-
observable.observers_.forEach(d => {
|
|
2125
|
+
(_observable$observers5 = observable.observers_) == null || _observable$observers5.forEach(d => {
|
|
2069
2126
|
if (d.dependenciesState_ === 0 /* IDerivationState_.UP_TO_DATE_ */) {
|
|
2070
2127
|
d.dependenciesState_ = 1 /* IDerivationState_.POSSIBLY_STALE_ */;
|
|
2071
2128
|
d.onBecomeStale_();
|
|
@@ -4320,31 +4377,16 @@
|
|
|
4320
4377
|
});
|
|
4321
4378
|
}
|
|
4322
4379
|
intersection(otherSet) {
|
|
4323
|
-
|
|
4324
|
-
return otherSet.intersection(this);
|
|
4325
|
-
} else {
|
|
4326
|
-
const dehancedSet = new Set(this);
|
|
4327
|
-
return dehancedSet.intersection(otherSet);
|
|
4328
|
-
}
|
|
4380
|
+
return new Set(this).intersection(otherSet);
|
|
4329
4381
|
}
|
|
4330
4382
|
union(otherSet) {
|
|
4331
|
-
|
|
4332
|
-
return otherSet.union(this);
|
|
4333
|
-
} else {
|
|
4334
|
-
const dehancedSet = new Set(this);
|
|
4335
|
-
return dehancedSet.union(otherSet);
|
|
4336
|
-
}
|
|
4383
|
+
return new Set(this).union(otherSet);
|
|
4337
4384
|
}
|
|
4338
4385
|
difference(otherSet) {
|
|
4339
4386
|
return new Set(this).difference(otherSet);
|
|
4340
4387
|
}
|
|
4341
4388
|
symmetricDifference(otherSet) {
|
|
4342
|
-
|
|
4343
|
-
return otherSet.symmetricDifference(this);
|
|
4344
|
-
} else {
|
|
4345
|
-
const dehancedSet = new Set(this);
|
|
4346
|
-
return dehancedSet.symmetricDifference(otherSet);
|
|
4347
|
-
}
|
|
4389
|
+
return new Set(this).symmetricDifference(otherSet);
|
|
4348
4390
|
}
|
|
4349
4391
|
isSubsetOf(otherSet) {
|
|
4350
4392
|
return new Set(this).isSubsetOf(otherSet);
|
|
@@ -4353,12 +4395,7 @@
|
|
|
4353
4395
|
return new Set(this).isSupersetOf(otherSet);
|
|
4354
4396
|
}
|
|
4355
4397
|
isDisjointFrom(otherSet) {
|
|
4356
|
-
|
|
4357
|
-
return otherSet.isDisjointFrom(this);
|
|
4358
|
-
} else {
|
|
4359
|
-
const dehancedSet = new Set(this);
|
|
4360
|
-
return dehancedSet.isDisjointFrom(otherSet);
|
|
4361
|
-
}
|
|
4398
|
+
return new Set(this).isDisjointFrom(otherSet);
|
|
4362
4399
|
}
|
|
4363
4400
|
replace(other) {
|
|
4364
4401
|
if (isObservableSet(other)) {
|