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>
pull/8382/head
Jon Rouleau 1 year ago committed by GitHub
parent c99dd2e045
commit 127b61a465
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -164,7 +164,7 @@ export function derived<T>(stores: Stores, fn: Function, initial_value?: T): Rea
const auto = fn.length < 2;
return readable(initial_value, (set) => {
let inited = false;
let started = false;
const values = [];
let pending = 0;
@ -188,7 +188,7 @@ export function derived<T>(stores: Stores, fn: Function, initial_value?: T): Rea
(value) => {
values[i] = value;
pending &= ~(1 << i);
if (inited) {
if (started) {
sync();
}
},
@ -197,12 +197,16 @@ export function derived<T>(stores: Stores, fn: Function, initial_value?: T): Rea
})
);
inited = true;
started = true;
sync();
return function stop() {
run_all(unsubscribers);
cleanup();
// We need to set this to false because callbacks can still happen despite having unsubscribed:
// Callbacks might already be placed in the queue which doesn't know it should no longer
// invoke this derived store.
started = false;
};
});
}

@ -407,6 +407,25 @@ describe('store', () => {
const d = derived(fake_observable, _ => _);
assert.equal(get(d), 42);
});
it('doesn\'t restart when unsubscribed from another store with a shared ancestor', () => {
const a = writable(true);
let b_started = false;
const b = derived(a, (_, __) => {
b_started = true;
return () => {
assert.equal(b_started, true);
b_started = false;
};
});
const c = derived(a, ($a, set) => {
if ($a) return b.subscribe(set);
});
c.subscribe(() => { });
a.set(false);
assert.equal(b_started, false);
});
});
describe('get', () => {

Loading…
Cancel
Save