fix: prevent derived connection leak in untracked contexts (#18517)

Fixes #18501.

Problem is that is_updating_effect was also set to true for branch/root effects which are not reactive

---------

Co-authored-by: Simon Holthausen <simon.holthausen@vercel.com>
pull/18527/head
Rabindra Kumar Meher 5 days ago committed by GitHub
parent bfbb026f2f
commit 08a9e9e7e4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -61,6 +61,9 @@ import { without_reactive_context } from './dom/elements/bindings/shared.js';
import { set_signal_status, update_derived_status } from './reactivity/status.js';
import * as w from './warnings.js';
/**
* True if updating in an effect context that is reactive (i.e. not branch/root effects)
*/
let is_updating_effect = false;
export let is_destroying_effect = false;
@ -444,7 +447,7 @@ export function update_effect(effect) {
var was_updating_effect = is_updating_effect;
active_effect = effect;
is_updating_effect = true;
is_updating_effect = (flags & (BRANCH_EFFECT | ROOT_EFFECT)) === 0; // Branch/root effects are not reactive contexts
if (DEV) {
var previous_component_fn = dev_current_component_function;

@ -1503,4 +1503,22 @@ describe('signals', () => {
assert.deepEqual(log, ['inner destroyed', 'inner destroyed']);
};
});
test('derived read in an untracked context should not leak in deps reactions', () => {
return () => {
let s = state('hello');
let a = derived(() => $.get(s));
let b = derived(() => $.get(a));
let destroy = effect_root(() => {
$.get(b);
});
destroy();
// a was spuriously added to s.reactions via is_updating_effect
// even though the entire derived chain was read in an untracked context
assert.equal(s.reactions, null);
};
});
});

Loading…
Cancel
Save