Skip to content

Commit 127b61a

Browse files
jrouleaudummdidumm
andauthored
fix: derived store restarting when unsubscribed from another store with a shared ancestor (#8368)
Fixes #8364 --------- Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
1 parent c99dd2e commit 127b61a

File tree

2 files changed

+26
-3
lines changed

2 files changed

+26
-3
lines changed

src/runtime/store/index.ts

+7-3
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ export function derived<T>(stores: Stores, fn: Function, initial_value?: T): Rea
164164
const auto = fn.length < 2;
165165

166166
return readable(initial_value, (set) => {
167-
let inited = false;
167+
let started = false;
168168
const values = [];
169169

170170
let pending = 0;
@@ -188,7 +188,7 @@ export function derived<T>(stores: Stores, fn: Function, initial_value?: T): Rea
188188
(value) => {
189189
values[i] = value;
190190
pending &= ~(1 << i);
191-
if (inited) {
191+
if (started) {
192192
sync();
193193
}
194194
},
@@ -197,12 +197,16 @@ export function derived<T>(stores: Stores, fn: Function, initial_value?: T): Rea
197197
})
198198
);
199199

200-
inited = true;
200+
started = true;
201201
sync();
202202

203203
return function stop() {
204204
run_all(unsubscribers);
205205
cleanup();
206+
// We need to set this to false because callbacks can still happen despite having unsubscribed:
207+
// Callbacks might already be placed in the queue which doesn't know it should no longer
208+
// invoke this derived store.
209+
started = false;
206210
};
207211
});
208212
}

test/store/index.ts

+19
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,25 @@ describe('store', () => {
407407
const d = derived(fake_observable, _ => _);
408408
assert.equal(get(d), 42);
409409
});
410+
411+
it('doesn\'t restart when unsubscribed from another store with a shared ancestor', () => {
412+
const a = writable(true);
413+
let b_started = false;
414+
const b = derived(a, (_, __) => {
415+
b_started = true;
416+
return () => {
417+
assert.equal(b_started, true);
418+
b_started = false;
419+
};
420+
});
421+
const c = derived(a, ($a, set) => {
422+
if ($a) return b.subscribe(set);
423+
});
424+
425+
c.subscribe(() => { });
426+
a.set(false);
427+
assert.equal(b_started, false);
428+
});
410429
});
411430

412431
describe('get', () => {

0 commit comments

Comments
 (0)