From 290dfa5ca7c14d5e893edf8b3c04b09bd31d6c05 Mon Sep 17 00:00:00 2001 From: paoloricciuti Date: Sat, 26 Oct 2024 15:00:27 +0200 Subject: [PATCH 1/3] fix: more exhaustive check during `SvelteMap.set` in deriveds --- .changeset/sweet-candles-poke.md | 5 +++++ packages/svelte/src/reactivity/map.js | 11 +++++------ .../runtime-runes/samples/derived-map/_config.js | 3 +++ .../runtime-runes/samples/derived-map/main.svelte | 4 ++++ 4 files changed, 17 insertions(+), 6 deletions(-) create mode 100644 .changeset/sweet-candles-poke.md diff --git a/.changeset/sweet-candles-poke.md b/.changeset/sweet-candles-poke.md new file mode 100644 index 000000000000..49ec3053994b --- /dev/null +++ b/.changeset/sweet-candles-poke.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: more exhaustive check during `SvelteMap.set` in deriveds diff --git a/packages/svelte/src/reactivity/map.js b/packages/svelte/src/reactivity/map.js index ddadad90e2fc..c581a2791406 100644 --- a/packages/svelte/src/reactivity/map.js +++ b/packages/svelte/src/reactivity/map.js @@ -3,6 +3,7 @@ import { DEV } from 'esm-env'; import { source, set } from '../internal/client/reactivity/sources.js'; import { get } from '../internal/client/runtime.js'; import { increment } from './utils.js'; +import { DERIVED } from '../internal/client/constants.js'; /** * @template K @@ -102,12 +103,10 @@ export class SvelteMap extends Map { 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) - ) { + + // if not every reaction of s is a reaction of version we need to also include version + const needs_version_increase = !s.reactions?.every((r) => version.reactions?.includes(r)); + if (needs_version_increase) { increment(version); } } diff --git a/packages/svelte/tests/runtime-runes/samples/derived-map/_config.js b/packages/svelte/tests/runtime-runes/samples/derived-map/_config.js index f3d115c62bfa..493d6a8bb4ef 100644 --- a/packages/svelte/tests/runtime-runes/samples/derived-map/_config.js +++ b/packages/svelte/tests/runtime-runes/samples/derived-map/_config.js @@ -3,6 +3,9 @@ import { test } from '../../test'; export default test({ html: `Loading`, + compileOptions: { + // dev: true + }, async test({ assert, target }) { await Promise.resolve(); diff --git a/packages/svelte/tests/runtime-runes/samples/derived-map/main.svelte b/packages/svelte/tests/runtime-runes/samples/derived-map/main.svelte index 6278af81589a..ea51f29dfb30 100644 --- a/packages/svelte/tests/runtime-runes/samples/derived-map/main.svelte +++ b/packages/svelte/tests/runtime-runes/samples/derived-map/main.svelte @@ -24,6 +24,10 @@ } const value = $derived(get_async(1)); + const value2 = $derived(get_async(1)); + // both values are read before the set + value; + value2; {#if value instanceof Promise} From 88a84fff816a1dbed385a2683a91709395228586 Mon Sep 17 00:00:00 2001 From: paoloricciuti Date: Sat, 26 Oct 2024 19:11:59 +0200 Subject: [PATCH 2/3] chore: use set for version reactions --- packages/svelte/src/reactivity/map.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/svelte/src/reactivity/map.js b/packages/svelte/src/reactivity/map.js index c581a2791406..5572a76d4277 100644 --- a/packages/svelte/src/reactivity/map.js +++ b/packages/svelte/src/reactivity/map.js @@ -105,7 +105,12 @@ export class SvelteMap extends Map { increment(s); // if not every reaction of s is a reaction of version we need to also include version - const needs_version_increase = !s.reactions?.every((r) => version.reactions?.includes(r)); + var v_reactions = version.reactions === null ? null : new Set(version.reactions); + var needs_version_increase = + v_reactions === null || + !s.reactions?.every((r) => + /** @type {NonNullable} */ (v_reactions).has(r) + ); if (needs_version_increase) { increment(version); } From 59435ac57bde387717c7a179be507620b520d638 Mon Sep 17 00:00:00 2001 From: paoloricciuti Date: Sat, 26 Oct 2024 19:13:09 +0200 Subject: [PATCH 3/3] chore: cleanup --- packages/svelte/src/reactivity/map.js | 3 +-- .../svelte/tests/runtime-runes/samples/derived-map/_config.js | 4 ---- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/packages/svelte/src/reactivity/map.js b/packages/svelte/src/reactivity/map.js index 5572a76d4277..ae1bf4777334 100644 --- a/packages/svelte/src/reactivity/map.js +++ b/packages/svelte/src/reactivity/map.js @@ -1,9 +1,8 @@ /** @import { Source } from '#client' */ import { DEV } from 'esm-env'; -import { source, set } from '../internal/client/reactivity/sources.js'; +import { set, source } from '../internal/client/reactivity/sources.js'; import { get } from '../internal/client/runtime.js'; import { increment } from './utils.js'; -import { DERIVED } from '../internal/client/constants.js'; /** * @template K diff --git a/packages/svelte/tests/runtime-runes/samples/derived-map/_config.js b/packages/svelte/tests/runtime-runes/samples/derived-map/_config.js index 493d6a8bb4ef..f933d0b2faaa 100644 --- a/packages/svelte/tests/runtime-runes/samples/derived-map/_config.js +++ b/packages/svelte/tests/runtime-runes/samples/derived-map/_config.js @@ -3,10 +3,6 @@ import { test } from '../../test'; export default test({ html: `Loading`, - compileOptions: { - // dev: true - }, - async test({ assert, target }) { await Promise.resolve(); flushSync();