Skip to content

Commit

Permalink
fix: ensure disconnected deriveds correctly connect again (#14899)
Browse files Browse the repository at this point in the history
* fix: ensure disconnected deriveds correctly connect again

* fix: ensure disconnected deriveds correctly connect again
  • Loading branch information
trueadm authored Jan 5, 2025
1 parent a91308d commit 82db92f
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 1 deletion.
5 changes: 5 additions & 0 deletions .changeset/happy-plums-greet.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'svelte': patch
---

fix: ensure disconnected deriveds correctly connect again
4 changes: 3 additions & 1 deletion packages/svelte/src/internal/client/runtime.js
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,9 @@ export function check_dirtiness(reaction) {
for (i = 0; i < length; i++) {
dependency = dependencies[i];

if (!dependency?.reactions?.includes(reaction)) {
// We always re-add all reactions (even duplicates) if the derived was
// previously disconnected
if (is_disconnected || !dependency?.reactions?.includes(reaction)) {
(dependency.reactions ??= []).push(reaction);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import { flushSync } from 'svelte';
import { test } from '../../test';

export default test({
async test({ assert, target, logs }) {
let [b1, b2, b3, b4, b5] = target.querySelectorAll('button');

b1?.click();
flushSync();

assert.htmlEqual(
target.innerHTML,
`<main><div>Current ID: 1</div>
<div>Name: a</div><div><button>a</button></div><div><button>b</button></div><div><button>c</button></div><div><button>d</button></div><hr><div>
<button>Show / Hide</button></div></main>`
);

b2?.click();
flushSync();

assert.htmlEqual(
target.innerHTML,
`<main><div>Current ID: 2</div>
<div>Name: b</div><div><button>a</button></div><div><button>b</button></div><div><button>c</button></div><div><button>d</button></div><hr><div>
<button>Show / Hide</button></div></main>`
);

b3?.click();
flushSync();

assert.htmlEqual(
target.innerHTML,
`<main><div>Current ID: 3</div>
<div>Name: c</div><div><button>a</button></div><div><button>b</button></div><div><button>c</button></div><div><button>d</button></div><hr><div>
<button>Show / Hide</button></div></main>`
);

b4?.click();
flushSync();

assert.htmlEqual(
target.innerHTML,
`<main><div>Current ID: 4</div>
<div>Name: d</div><div><button>a</button></div><div><button>b</button></div><div><button>c</button></div><div><button>d</button></div><hr><div>
<button>Show / Hide</button></div></main>`
);

b5?.click();
flushSync();

b5?.click();
flushSync();

[b1, b2, b3, b4, b5] = target.querySelectorAll('button');

b1?.click();
flushSync();

assert.htmlEqual(
target.innerHTML,
`<main><div>Current ID: 1</div>
<div>Name: a</div><div><button>a</button></div><div><button>b</button></div><div><button>c</button></div><div><button>d</button></div><hr><div>
<button>Show / Hide</button></div></main>`
);

b2?.click();
flushSync();

assert.htmlEqual(
target.innerHTML,
`<main><div>Current ID: 2</div>
<div>Name: b</div><div><button>a</button></div><div><button>b</button></div><div><button>c</button></div><div><button>d</button></div><hr><div>
<button>Show / Hide</button></div></main>`
);

b3?.click();
flushSync();

assert.htmlEqual(
target.innerHTML,
`<main><div>Current ID: 3</div>
<div>Name: c</div><div><button>a</button></div><div><button>b</button></div><div><button>c</button></div><div><button>d</button></div><hr><div>
<button>Show / Hide</button></div></main>`
);

b4?.click();
flushSync();

assert.htmlEqual(
target.innerHTML,
`<main><div>Current ID: 4</div>
<div>Name: d</div><div><button>a</button></div><div><button>b</button></div><div><button>c</button></div><div><button>d</button></div><hr><div>
<button>Show / Hide</button></div></main>`
);
}
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<script>
const items = [
{ id: 1, name: "a" },
{ id: 2, name: "b" },
{ id: 3, name: "c" },
{ id: 4, name: "d" },
];
let currentId = $state(1);
let currentItem = $derived(items.find(item => item.id === currentId));
let visible = $state(true);
</script>

<main>
{#if visible}
<div>Current ID: {currentId}</div>
<div>Name: {currentItem.name}</div>
{#each items as item}
<div><button onclick={() => { currentId = item.id; }}>{item.name}</button></div>
{/each}
{/if}
<hr>
<div><button onclick={() => { visible = !visible; }}>Show / Hide</button></div>
</main>

0 comments on commit 82db92f

Please sign in to comment.