diff --git a/.changeset/hungry-dogs-happen.md b/.changeset/hungry-dogs-happen.md new file mode 100644 index 000000000000..e041a94c24a7 --- /dev/null +++ b/.changeset/hungry-dogs-happen.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: ensure SvelteMap reactivity persists through deriveds diff --git a/packages/svelte/src/reactivity/map.js b/packages/svelte/src/reactivity/map.js index c732806cd0b6..ddadad90e2fc 100644 --- a/packages/svelte/src/reactivity/map.js +++ b/packages/svelte/src/reactivity/map.js @@ -94,13 +94,22 @@ export class SvelteMap extends Map { var s = sources.get(key); var prev_res = super.get(key); var res = super.set(key, value); + var version = this.#version; if (s === undefined) { sources.set(key, source(0)); set(this.#size, super.size); - increment(this.#version); + increment(version); } else if (prev_res !== value) { increment(s); + // If no one listening to this property and is listening to the version, or + // the inverse, then we should increment the version to be safe + if ( + (s.reactions === null && version.reactions !== null) || + (s.reactions !== null && version.reactions === null) + ) { + increment(version); + } } return res; diff --git a/packages/svelte/tests/runtime-runes/samples/derived-map/_config.js b/packages/svelte/tests/runtime-runes/samples/derived-map/_config.js new file mode 100644 index 000000000000..f3d115c62bfa --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/derived-map/_config.js @@ -0,0 +1,13 @@ +import { flushSync } from 'svelte'; +import { test } from '../../test'; + +export default test({ + html: `Loading`, + + async test({ assert, target }) { + await Promise.resolve(); + flushSync(); + + assert.htmlEqual(target.innerHTML, `1`); + } +}); diff --git a/packages/svelte/tests/runtime-runes/samples/derived-map/main.svelte b/packages/svelte/tests/runtime-runes/samples/derived-map/main.svelte new file mode 100644 index 000000000000..6278af81589a --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/derived-map/main.svelte @@ -0,0 +1,34 @@ + + +{#if value instanceof Promise} + Loading +{:else} + {value} +{/if} +