mirror of https://github.com/sveltejs/svelte
fix: emit `each_key_duplicate` error in production (#16724)
* fix: emit `each_key_duplicate` error in production * fix: preserve key * Update packages/svelte/src/internal/client/dom/blocks/each.js Co-authored-by: Rich Harris <rich.harris@vercel.com> * Update packages/svelte/src/internal/client/dom/blocks/each.js Co-authored-by: Rich Harris <rich.harris@vercel.com> * fix: ensure keys are validated * fix silly test name * fix: cover other case of duplicate keys * emit error on hydration * ensure the error is handled * drop useless tests * unused * finish merge * add lost check back * chore: bump playwright (#17565) * chore: bump playwright * maybe this will help somehow? * err whatever * fix * chore: allow testing in production env 2 (#17590) * Revert "chore: allow testing in production env (#16840)" This reverts commitpull/17515/mergeffd65e90fe. * new approach * fix: handle renderer.run rejections (#17591) * fix: handle renderer run rejections * add test * changeset * simplify * explanatory comment --------- Co-authored-by: Antonio Bennett <abennett@mabelslabels.com> Co-authored-by: Rich Harris <rich.harris@vercel.com> * fix: only create async functions in SSR output when necessary (#17593) * fix: only create async functions in SSR output when necessary * actually... * simplify generated code a bit more * simplify * fix: merge consecutive text nodes during hydration for large text content (#17587) * fix: merge consecutive text nodes during hydration for large text content Fixes #17582 Browsers automatically split text nodes exceeding 65536 characters into multiple consecutive text nodes during HTML parsing. This causes hydration mismatches when Svelte expects a single text node. The fix merges consecutive text nodes during hydration by: - Detecting when the current node is a text node - Finding all consecutive text node siblings - Merging their content into the first text node - Removing the extra text nodes This restores correct hydration behavior for large text content. * add test, fix * fix * fix * changeset --------- Co-authored-by: Miner <miner@example.com> Co-authored-by: Rich Harris <rich.harris@vercel.com> * Version Packages (#17585) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * Revert "drop useless tests" This reverts commit65f77ef840. * update tests * fix test * we don't need to expose this function any more * figured it out... we cant have errors during reconcile * simplify * tweak * unused * revert no-longer-needed change * unused --------- Co-authored-by: Rich Harris <rich.harris@vercel.com> Co-authored-by: Antonio Bennett <31296212+Antonio-Bennett@users.noreply.github.com> Co-authored-by: Antonio Bennett <abennett@mabelslabels.com> Co-authored-by: FORMI <239411042+Richman018@users.noreply.github.com> Co-authored-by: Miner <miner@example.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
parent
4f41e816ba
commit
d7a8e3d130
@ -0,0 +1,5 @@
|
||||
---
|
||||
'svelte': patch
|
||||
---
|
||||
|
||||
fix: emit `each_key_duplicate` error in production
|
||||
@ -0,0 +1,12 @@
|
||||
import { flushSync } from 'svelte';
|
||||
import { test } from '../../test';
|
||||
|
||||
export default test({
|
||||
test({ assert, target }) {
|
||||
let button = target.querySelector('button');
|
||||
|
||||
button?.click();
|
||||
|
||||
assert.throws(flushSync, 'https://svelte.dev/e/each_key_duplicate');
|
||||
}
|
||||
});
|
||||
@ -0,0 +1,8 @@
|
||||
<script>
|
||||
let data = $state([1, 2, 3]);
|
||||
</script>
|
||||
|
||||
<button onclick={() => data = [1, 1, 1]}>add</button>
|
||||
{#each data as d (d)}
|
||||
{d}
|
||||
{/each}
|
||||
@ -0,0 +1,5 @@
|
||||
import { test } from '../../test';
|
||||
|
||||
export default test({
|
||||
error: 'each_key_duplicate'
|
||||
});
|
||||
@ -0,0 +1,7 @@
|
||||
<script>
|
||||
let data = [1, 1, 1];
|
||||
</script>
|
||||
|
||||
{#each data as d (d)}
|
||||
{d}
|
||||
{/each}
|
||||
@ -0,0 +1,12 @@
|
||||
import { flushSync } from 'svelte';
|
||||
import { test } from '../../test';
|
||||
|
||||
export default test({
|
||||
test({ assert, target }) {
|
||||
let button = target.querySelector('button');
|
||||
|
||||
button?.click();
|
||||
|
||||
assert.throws(flushSync, 'https://svelte.dev/e/each_key_duplicate');
|
||||
}
|
||||
});
|
||||
@ -0,0 +1,8 @@
|
||||
<script>
|
||||
let data = $state([1, 2, 3, 4, 5]);
|
||||
</script>
|
||||
|
||||
<button onclick={() => data = [1, 1, 3, 1]}>add</button>
|
||||
{#each data as d (d)}
|
||||
{d}
|
||||
{/each}
|
||||
Loading…
Reference in new issue