From 1e653ef4d8cccf57dff1e43cbfacce0415cafe57 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Wed, 13 Mar 2024 11:36:45 -0400 Subject: [PATCH] fix: make `set.has(...)` granular for existing properties (#10793) * fix: make set.has(...) granular * changeset --------- Co-authored-by: Rich Harris --- .changeset/orange-yaks-protect.md | 5 +++ packages/svelte/src/reactivity/set.js | 7 ++-- packages/svelte/src/reactivity/set.test.ts | 45 +++++++++++++++++++++- 3 files changed, 53 insertions(+), 4 deletions(-) create mode 100644 .changeset/orange-yaks-protect.md diff --git a/.changeset/orange-yaks-protect.md b/.changeset/orange-yaks-protect.md new file mode 100644 index 0000000000..9742c90936 --- /dev/null +++ b/.changeset/orange-yaks-protect.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: make `set.has(...)` granular for existing properties' diff --git a/packages/svelte/src/reactivity/set.js b/packages/svelte/src/reactivity/set.js index dcd544671d..173c0095a0 100644 --- a/packages/svelte/src/reactivity/set.js +++ b/packages/svelte/src/reactivity/set.js @@ -82,11 +82,12 @@ export class ReactiveSet extends Set { /** @param {T} value */ has(value) { var source = this.#sources.get(value); - // We should always track the version in case - // the Set ever gets this value in the future. - get(this.#version); if (source === undefined) { + // We should always track the version in case + // the Set ever gets this value in the future. + get(this.#version); + return false; } diff --git a/packages/svelte/src/reactivity/set.test.ts b/packages/svelte/src/reactivity/set.test.ts index cea7221060..aff076fc39 100644 --- a/packages/svelte/src/reactivity/set.test.ts +++ b/packages/svelte/src/reactivity/set.test.ts @@ -30,7 +30,50 @@ test('set.values()', () => { set.clear(); }); - assert.deepEqual(log, [5, true, [1, 2, 3, 4, 5], 4, false, [1, 2, 4, 5], 0, false, []]); + assert.deepEqual(log, [5, true, [1, 2, 3, 4, 5], 4, false, [1, 2, 4, 5], 0, [], false]); // TODO update when we fix effect ordering bug + + cleanup(); +}); + +test('set.has(...)', () => { + const set = new ReactiveSet([1, 2, 3]); + + const log: any = []; + + const cleanup = user_root_effect(() => { + pre_effect(() => { + log.push('has 1', set.has(1)); + }); + + pre_effect(() => { + log.push('has 2', set.has(2)); + }); + + pre_effect(() => { + log.push('has 3', set.has(3)); + }); + }); + + flushSync(() => { + set.delete(2); + }); + + flushSync(() => { + set.add(2); + }); + + assert.deepEqual(log, [ + 'has 1', + true, + 'has 2', + true, + 'has 3', + true, + 'has 2', + false, + 'has 2', + true + ]); cleanup(); });