Skip to content

Commit

Permalink
fix: ensure reactions are correctly attached for unowned deriveds (#1…
Browse files Browse the repository at this point in the history
…5158)

* fix: ensure reactions are correctly attached for unowned deriveds

* tune
  • Loading branch information
trueadm authored Jan 30, 2025
1 parent 970aa7c commit 7bef596
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 4 deletions.
5 changes: 5 additions & 0 deletions .changeset/loud-cars-scream.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'svelte': patch
---

fix: ensure reactions are correctly attached for unowned deriveds
13 changes: 9 additions & 4 deletions packages/svelte/src/internal/client/runtime.js
Original file line number Diff line number Diff line change
Expand Up @@ -802,12 +802,19 @@ function process_effects(effect, collected_effects) {
if (is_branch) {
current_effect.f ^= CLEAN;
} else {
// Ensure we set the effect to be the active reaction
// to ensure that unowned deriveds are correctly tracked
// because we're flushing the current effect
var previous_active_reaction = active_reaction;
try {
active_reaction = current_effect;
if (check_dirtiness(current_effect)) {
update_effect(current_effect);
}
} catch (error) {
handle_error(error, current_effect, null, current_effect.ctx);
} finally {
active_reaction = previous_active_reaction;
}
}

Expand Down Expand Up @@ -952,13 +959,11 @@ export function get(signal) {
var derived = /** @type {Derived} */ (signal);
var parent = derived.parent;

if (parent !== null) {
if (parent !== null && (parent.f & UNOWNED) === 0) {
// If the derived is owned by another derived then mark it as unowned
// as the derived value might have been referenced in a different context
// since and thus its parent might not be its true owner anymore
if ((parent.f & UNOWNED) === 0) {
derived.f ^= UNOWNED;
}
derived.f ^= UNOWNED;
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<script>
let { value = $bindable() } = $props()
</script>

<button onclick={() => value = 'a'}>change</button>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<script>
let {disabled = false} = $props()
</script>

{disabled}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { flushSync } from 'svelte';
import { test } from '../../test';

export default test({
async test({ assert, target }) {
let [btn1, btn2] = target.querySelectorAll('button');

btn1?.click();
flushSync();

btn2?.click();
flushSync();

assert.htmlEqual(target.innerHTML, `<button>change</button><button>change</button>\nfalse`);
}
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<script>
import Child2 from './Child2.svelte'
import Child from './Child.svelte'
let loginname = $state('')
let password = $state('')
</script>

<Child bind:value={loginname} />
<Child bind:value={password} />
<Child2 disabled={!loginname || !password} />

0 comments on commit 7bef596

Please sign in to comment.