From 5d2a92e95b29b5aed0313405f8d4d435026c39ba Mon Sep 17 00:00:00 2001 From: Andrey Kogut Date: Fri, 31 Mar 2017 03:24:53 +0300 Subject: [PATCH 1/3] Fix #916: new observed derivations bocomes stale --- src/core/derivation.ts | 11 +++++++++++ test/autorun.js | 19 ++++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/core/derivation.ts b/src/core/derivation.ts index 8ea56c692..b0830e9b3 100644 --- a/src/core/derivation.ts +++ b/src/core/derivation.ts @@ -148,6 +148,7 @@ function bindDependencies(derivation: IDerivation) { const prevObserving = derivation.observing; const observing = derivation.observing = derivation.newObserving!; + let lowestNewObservingDerivationState = IDerivationState.UP_TO_DATE; derivation.newObserving = null; // newObserving shouldn't be needed outside tracking @@ -162,6 +163,9 @@ function bindDependencies(derivation: IDerivation) { if (i0 !== i) observing[i0] = dep; i0++; } + if (dep['dependenciesState'] > lowestNewObservingDerivationState) { + lowestNewObservingDerivationState = dep['dependenciesState']; + } } observing.length = i0; @@ -187,6 +191,13 @@ function bindDependencies(derivation: IDerivation) { addObserver(dep, derivation); } } + + // Some new observed derivations might become stale during this derivation computation + // so say had no chance to propagate staleness (#916) + if (lowestNewObservingDerivationState !== IDerivationState.UP_TO_DATE) { + derivation.dependenciesState = lowestNewObservingDerivationState; + derivation.onBecomeStale(); + } } export function clearObserving(derivation: IDerivation) { diff --git a/test/autorun.js b/test/autorun.js index cd137d9da..bd4636698 100644 --- a/test/autorun.js +++ b/test/autorun.js @@ -84,4 +84,21 @@ test('autorun batches automatically', function(t) { d1() d2() t.end(); -}) \ No newline at end of file +}) + + +test('autorun tracks invalidation of unbound dependencies', function(t) { + var a = m.observable(0); + var b = m.observable(0); + var c = m.computed(() => a.get() + b.get()); + var values = []; + + m.autorun(() => { + values.push(c.get()); + b.set(100); + }); + + a.set(1); + t.deepEqual(values, [0, 100, 101]); + t.end(); +}) From 3d0876013d42a1fcc2bb1a7db36b35fcf4f01bc8 Mon Sep 17 00:00:00 2001 From: Michel Weststrate Date: Mon, 3 Apr 2017 09:39:33 +0200 Subject: [PATCH 2/3] Factored out string key access --- src/core/derivation.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/core/derivation.ts b/src/core/derivation.ts index b0830e9b3..c150965dc 100644 --- a/src/core/derivation.ts +++ b/src/core/derivation.ts @@ -163,8 +163,11 @@ function bindDependencies(derivation: IDerivation) { if (i0 !== i) observing[i0] = dep; i0++; } - if (dep['dependenciesState'] > lowestNewObservingDerivationState) { - lowestNewObservingDerivationState = dep['dependenciesState']; + + // Upcast is 'safe' here, because if dep is IObservable, `dependenciesState` will be undefined, + // not hitting the condition + if ((dep as any as IDerivation).dependenciesState > lowestNewObservingDerivationState) { + lowestNewObservingDerivationState = (dep as any as IDerivation).dependenciesState; } } observing.length = i0; From 1c79a51cee63d3cf2b20efa7983fda855f3eb1d8 Mon Sep 17 00:00:00 2001 From: Michel Weststrate Date: Mon, 3 Apr 2017 09:43:40 +0200 Subject: [PATCH 3/3] Updated changelog for fix #916 --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a698f2a2f..4f1c1d742 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 3.1.8 + +* Fixed edge case where `autorun` was not triggered again if a computed value was invalidated by the reaction itself, see [#916](https://github.com/mobxjs/mobx/issues/916) + # 3.1.7 * Reverted ES2015 module changes, as they broke with webpack 2 (will be re-released later)