fix: ensure reactions are kept dirty when marking them again (#11364)

previously a reaction could be marked as DIRTY and subsequently as MAYBE_DIRTY before running, resulting in false negatives. Ensure that DIRTY flag can never be lowered to MAYBE_DIRTY
fixes #11363
pull/11381/head
Simon H 1 year ago committed by GitHub
parent 7a3ee6d059
commit de315d84eb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
"svelte": patch
---
fix: ensure reactions are kept dirty when marking them again

@ -780,7 +780,7 @@ export function invalidate_inner_signals(fn) {
/**
* @param {import('#client').Value} signal
* @param {number} to_status
* @param {number} to_status should be DIRTY or MAYBE_DIRTY
* @param {boolean} force_schedule
* @returns {void}
*/
@ -793,15 +793,15 @@ export function mark_reactions(signal, to_status, force_schedule) {
for (var i = 0; i < length; i++) {
var reaction = reactions[i];
var flags = reaction.f;
// We skip any effects that are already dirty (but not unowned). Additionally, we also
// We skip any effects that are already dirty. Additionally, we also
// skip if the reaction is the same as the current effect (except if we're not in runes or we
// are in force schedule mode).
if ((!force_schedule || !runes) && reaction === current_effect) {
if ((flags & DIRTY) !== 0 || ((!force_schedule || !runes) && reaction === current_effect)) {
continue;
}
var flags = reaction.f;
set_signal_status(reaction, to_status);
// If the signal is not clean, then skip over it with the exception of unowned signals that

@ -0,0 +1,8 @@
import { test } from '../../test';
export default test({
async test({ assert, target }) {
await target.querySelector('button')?.click();
assert.htmlEqual(target.innerHTML, `<button>0</button>`);
}
});

@ -0,0 +1,13 @@
<script>
let x = $state(1);
let y = $state(1);
let z = $derived(x*y);
</script>
<button onclick={() => {
x = 0;
// reading a derived value and then setting another source contributing to the derived
// resulting in the same value should not prevent pending render effects from updating
z;
y = 0;
}}>{z}</button>
Loading…
Cancel
Save