Skip to content

Commit

Permalink
fix: improve signal consumer removal logic
Browse files Browse the repository at this point in the history
  • Loading branch information
trueadm committed Dec 7, 2023
1 parent b20b461 commit 2369f0c
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 7 deletions.
5 changes: 5 additions & 0 deletions .changeset/rich-tables-sing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'svelte': patch
---

fix: improve signal consumer removal logic
16 changes: 9 additions & 7 deletions packages/svelte/src/internal/client/runtime.js
Original file line number Diff line number Diff line change
Expand Up @@ -382,13 +382,15 @@ function remove_consumer(signal, start_index, remove_unowned) {
let consumers_length = 0;
if (consumers !== null) {
consumers_length = consumers.length - 1;
if (consumers_length === 0) {
dependency.c = null;
} else {
const index = consumers.indexOf(signal);
// Swap with last element and then remove.
consumers[index] = consumers[consumers_length];
consumers.pop();
const index = consumers.indexOf(signal);
if (index !== -1) {
if (consumers_length === 0) {
dependency.c = null;
} else {
// Swap with last element and then remove.
consumers[index] = consumers[consumers_length];
consumers.pop();
}
}
}
if (remove_unowned && consumers_length === 0 && (dependency.f & UNOWNED) !== 0) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { flushSync } from 'svelte';
import { test } from '../../test';

export default test({
async test({ assert, target }) {
const [b1, b2] = target.querySelectorAll('button');
flushSync(() => {
b1.click();
});

assert.htmlEqual(
target.innerHTML,
`<div><button>A</button><button>B</button></div><div>A</div>`
);

flushSync(() => {
b2.click();
});

assert.htmlEqual(
target.innerHTML,
`<div><button>A</button><button>B</button></div><div>B\n12</div>`
);

flushSync(() => {
b1.click();
});

assert.htmlEqual(
target.innerHTML,
`<div><button>A</button><button>B</button></div><div>A</div>`
);

flushSync(() => {
b2.click();
});

assert.htmlEqual(
target.innerHTML,
`<div><button>A</button><button>B</button></div><div>B\n12</div>`
);

flushSync(() => {
b1.click();
});

assert.htmlEqual(
target.innerHTML,
`<div><button>A</button><button>B</button></div><div>A</div>`
);
}
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<script context="module">
class Things {
tab = $state('A');
data = $state([{no: 1}, {no: 2}]);
list = $derived(this.filter());
filter() {
this.tab;
return this.data;
}
}
const things = new Things();
</script>

<div>
<button onclick={() => things.tab = 'A'} >A</button>
<button onclick={() => things.tab = 'B'} >B</button>
</div>

<div>
{#if things.tab === 'A'}
A
{:else}
B
{#each things.list as item}
{item.no}
{/each}
{/if}
</div>

0 comments on commit 2369f0c

Please sign in to comment.