fix: don't flag stable NaN keys as volatile in each idempotency check

The dev-mode {#each} key-idempotency guard compared the two get_key
results with strict inequality. A key function that deterministically
returns NaN is idempotent, but NaN !== NaN is always true, so it was
wrongly reported as volatile and each_key_volatile was thrown. Use
Object.is so stable NaN keys compare equal while distinct fresh
references are still detected as volatile.
pull/18707/head
contactjawad 1 month ago
parent 15720b16a5
commit 70cd26f614

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: don't flag stable `NaN` keys as volatile in dev `{#each}` idempotency check

@ -306,7 +306,7 @@ export function each(node, flags, get_collection, get_key, render_fn, fallback_f
if (DEV) {
// Check that the key function is idempotent (returns the same value when called twice)
var key_again = get_key(value, index);
if (key !== key_again) {
if (!Object.is(key, key_again)) {
e.each_key_volatile(String(index), String(key), String(key_again));
}
}

@ -0,0 +1,13 @@
import { test } from '../../test';
// a deterministic `NaN` key is idempotent (`NaN !== NaN`, but `Object.is(NaN, NaN)`),
// so the dev-mode key-idempotency check must not throw `each_key_volatile`
export default test({
compileOptions: {
dev: true
},
mode: ['client'],
html: `<p>NaN</p>`
});

@ -0,0 +1,7 @@
<script>
let things = $state([{ id: NaN }]);
</script>
{#each things as thing (thing.id)}
<p>{thing.id}</p>
{/each}
Loading…
Cancel
Save