From eedb59355f7c0051223272e9c3b2249433e0f473 Mon Sep 17 00:00:00 2001 From: Dominic Gannaway Date: Tue, 5 Mar 2024 12:51:02 +0000 Subject: [PATCH] fix: adjust keyed each block equality handling (#10699) Fixes #10685 --- .changeset/seven-masks-end.md | 5 +++++ .../src/internal/client/dom/blocks/each.js | 8 +++++-- .../samples/each-updates-4/_config.js | 21 +++++++++++++++++++ .../samples/each-updates-4/main.svelte | 13 ++++++++++++ 4 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 .changeset/seven-masks-end.md create mode 100644 packages/svelte/tests/runtime-runes/samples/each-updates-4/_config.js create mode 100644 packages/svelte/tests/runtime-runes/samples/each-updates-4/main.svelte diff --git a/.changeset/seven-masks-end.md b/.changeset/seven-masks-end.md new file mode 100644 index 0000000000..342091267d --- /dev/null +++ b/.changeset/seven-masks-end.md @@ -0,0 +1,5 @@ +--- +"svelte": patch +--- + +fix: adjust keyed each block equality handling diff --git a/packages/svelte/src/internal/client/dom/blocks/each.js b/packages/svelte/src/internal/client/dom/blocks/each.js index f84d2a7d02..c50f959406 100644 --- a/packages/svelte/src/internal/client/dom/blocks/each.js +++ b/packages/svelte/src/internal/client/dom/blocks/each.js @@ -20,8 +20,8 @@ import { current_block, destroy_signal, execute_effect, push_destroy_fn } from ' import { render_effect } from '../../reactivity/effects.js'; import { source, mutable_source, set } from '../../reactivity/sources.js'; import { trigger_transitions } from '../../transitions.js'; -import { is_array } from '../../utils.js'; -import { EACH_BLOCK, EACH_ITEM_BLOCK } from '../../constants.js'; +import { is_array, is_frozen } from '../../utils.js'; +import { EACH_BLOCK, EACH_ITEM_BLOCK, STATE_SYMBOL } from '../../constants.js'; const NEW_BLOCK = -1; const MOVED_BLOCK = 99999999; @@ -449,6 +449,10 @@ function reconcile_tracked_array( apply_transitions, keys ) { + // If we are working with an array that isn't proxied or frozen, then remove strict equality. + if ((flags & EACH_IS_STRICT_EQUALS) !== 0 && !is_frozen(array) && !(STATE_SYMBOL in array)) { + flags ^= EACH_IS_STRICT_EQUALS; + } var a_blocks = each_block.v; const is_computed_key = keys !== null; var active_transitions = each_block.s; diff --git a/packages/svelte/tests/runtime-runes/samples/each-updates-4/_config.js b/packages/svelte/tests/runtime-runes/samples/each-updates-4/_config.js new file mode 100644 index 0000000000..284f036dc4 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/each-updates-4/_config.js @@ -0,0 +1,21 @@ +import { flushSync } from 'svelte'; +import { test } from '../../test'; + +export default test({ + html: `100\n`, + + async test({ assert, target }) { + /** + * @type {{ click: () => void; }} + */ + let btn1; + + [btn1] = target.querySelectorAll('button'); + + flushSync(() => { + btn1.click(); + }); + + assert.htmlEqual(target.innerHTML, `1000\n`); + } +}); diff --git a/packages/svelte/tests/runtime-runes/samples/each-updates-4/main.svelte b/packages/svelte/tests/runtime-runes/samples/each-updates-4/main.svelte new file mode 100644 index 0000000000..f48f711976 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/each-updates-4/main.svelte @@ -0,0 +1,13 @@ + + +{#each Object.values($roomState.users) as user (user.name)} + {user.value} +{/each} + +