From ffa8cdebe80f9fe09d2688d069c6a2767119ffcd Mon Sep 17 00:00:00 2001 From: Nic <162764842+Nic-Polumeyv@users.noreply.github.com> Date: Fri, 10 Jul 2026 19:28:16 -0400 Subject: [PATCH] fix: don't notify SvelteMap key trackers when an existing key's value is set --- .changeset/major-maps-agree.md | 5 ++++ packages/svelte/src/reactivity/map.js | 18 ++++++++----- packages/svelte/src/reactivity/map.test.ts | 30 ++++++++++++++++++++++ 3 files changed, 46 insertions(+), 7 deletions(-) create mode 100644 .changeset/major-maps-agree.md diff --git a/.changeset/major-maps-agree.md b/.changeset/major-maps-agree.md new file mode 100644 index 0000000000..be414365ea --- /dev/null +++ b/.changeset/major-maps-agree.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: don't notify `SvelteMap` key trackers when an existing key's value is set diff --git a/packages/svelte/src/reactivity/map.js b/packages/svelte/src/reactivity/map.js index 48d06a05a7..fcfc4c2089 100644 --- a/packages/svelte/src/reactivity/map.js +++ b/packages/svelte/src/reactivity/map.js @@ -161,19 +161,23 @@ export class SvelteMap extends Map { var sources = this.#sources; var s = sources.get(key); var prev_res = super.get(key); + var existed = super.has(key); var res = super.set(key, value); var version = this.#version; if (s === undefined) { - s = this.#source(0); + // if the key existed but was never read individually, nothing tracks it and the key set is unchanged + if (!existed) { + s = this.#source(0); - if (DEV) { - tag(s, `SvelteMap get(${label(key)})`); - } + if (DEV) { + tag(s, `SvelteMap get(${label(key)})`); + } - sources.set(key, s); - set(this.#size, super.size); - increment(version); + sources.set(key, s); + set(this.#size, super.size); + increment(version); + } } else if (prev_res !== value) { increment(s); diff --git a/packages/svelte/src/reactivity/map.test.ts b/packages/svelte/src/reactivity/map.test.ts index 8bb6f72f7b..fd0779562e 100644 --- a/packages/svelte/src/reactivity/map.test.ts +++ b/packages/svelte/src/reactivity/map.test.ts @@ -307,3 +307,33 @@ test('not invoking reactivity when value is not in the map after changes', () => test('Map.instanceOf', () => { assert.equal(new SvelteMap() instanceof Map, true); }); + +test('map.keys() is not notified when an existing unread key is set to a new value', () => { + const map = new SvelteMap([ + [1, 'a'], + [2, 'b'] + ]); + + const log: any = []; + + const cleanup = effect_root(() => { + render_effect(() => { + log.push(Array.from(map.keys())); + }); + }); + + flushSync(() => { + map.set(1, 'c'); + }); + + flushSync(() => { + map.set(3, 'd'); + }); + + assert.deepEqual(log, [ + [1, 2], + [1, 2, 3] + ]); + + cleanup(); +});