diff --git a/src/runtime/store/index.ts b/src/runtime/store/index.ts index c85163003f..c5bbb052cf 100644 --- a/src/runtime/store/index.ts +++ b/src/runtime/store/index.ts @@ -67,16 +67,15 @@ export function writable(value: T, start: StartStopNotifier = noop): Writa function set(new_value: T): void { if (safe_not_equal(value, new_value)) { value = new_value; - if (!stop) { - return; // not ready + if (stop) { // store is ready + subscribers.forEach((s) => s[1]()); + subscribers.forEach((s) => s[0](value)); } - subscribers.forEach((s) => s[1]()); - subscribers.forEach((s) => s[0](value)); } } function update(fn: Updater): void { - set(fn(value)); + return set(fn(value)); } function subscribe(run: Subscriber, invalidate: Invalidator = noop): Unsubscriber { @@ -129,7 +128,9 @@ export function derived( const auto = fn.length < 2; + const subscribers: Array> = []; const invalidators: Array> = []; + let value: T = initial_value; const store = readable(initial_value, (set) => { let inited = false; @@ -146,6 +147,11 @@ export function derived( const result = fn(single ? values[0] : values, set); if (auto) { set(result as T); + const dirty = safe_not_equal(value, result); + value = result as T; + if (!dirty) { + subscribers.forEach(s => s(value)); + } } else { cleanup = is_function(result) ? result as Unsubscriber : noop; } @@ -176,6 +182,7 @@ export function derived( return { subscribe(run: Subscriber, invalidate: Invalidator = noop): Unsubscriber { + subscribers.push(run); invalidators.push(invalidate); const unsubscribe = store.subscribe(run, invalidate); @@ -189,4 +196,4 @@ export function derived( }; } }; -} \ No newline at end of file +} diff --git a/test/js/samples/bind-open/expected.js b/test/js/samples/bind-open/expected.js index 7f739aec8b..7c73c8ddac 100644 --- a/test/js/samples/bind-open/expected.js +++ b/test/js/samples/bind-open/expected.js @@ -66,4 +66,4 @@ class Component extends SvelteComponent { } } -export default Component; \ No newline at end of file +export default Component; diff --git a/test/store/index.ts b/test/store/index.ts index 6f5ef6abdd..a39fab86e6 100644 --- a/test/store/index.ts +++ b/test/store/index.ts @@ -233,6 +233,30 @@ describe('store', () => { unsubscribe(); }); + it('derived dependency does not update and shared ancestor updates', () => { + const root = writable({ a: 0, b:0 }); + const values = []; + + const a = derived(root, $root => { + return 'a' + $root.a; + }); + + const b = derived([a, root], ([$a, $root]) => { + return 'b' + $root.b + $a; + }); + + const unsubscribe = b.subscribe(v => { + values.push(v); + }); + + assert.deepEqual(values, ['b0a0']); + + root.set({ a: 0, b: 1 }); + assert.deepEqual(values, ['b0a0', 'b1a0']); + + unsubscribe(); + }); + it('is updated with safe_not_equal logic', () => { const arr = [0];