fix: improve signal consumer removal logic (#9837)

pull/9841/head
Dominic Gannaway 1 year ago committed by GitHub
parent e2dcdc2887
commit 388e3e68fc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: improve signal consumer removal logic

@ -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) {

@ -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>`
);
}
});

@ -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>
Loading…
Cancel
Save