diff --git a/packages/svelte/src/internal/client/reactivity/effects.js b/packages/svelte/src/internal/client/reactivity/effects.js index 0a66d76466..3ffa558a08 100644 --- a/packages/svelte/src/internal/client/reactivity/effects.js +++ b/packages/svelte/src/internal/client/reactivity/effects.js @@ -12,7 +12,8 @@ import { set_is_destroying_effect, set_signal_status, untrack, - untracking + untracking, + flushSync } from '../runtime.js'; import { DIRTY, @@ -41,6 +42,7 @@ import { get_next_sibling } from '../dom/operations.js'; import { async_derived, derived } from './deriveds.js'; import { capture, suspend } from '../dom/blocks/boundary.js'; import { component_context, dev_current_component_function } from '../context.js'; +import { active_fork } from './forks.js'; /** * @param {'$effect' | '$effect.pre' | '$inspect'} rune @@ -338,19 +340,26 @@ export function render_effect(fn, flags = 0) { * @param {Array<() => Promise>} async */ export function template_effect(fn, sync = [], async = [], d = derived) { - let effect = /** @type {Effect} */ (active_effect); + var parent = /** @type {Effect} */ (active_effect); if (async.length > 0) { + var fork = active_fork; var restore = capture(); Promise.all(async.map((expression) => async_derived(expression))).then((result) => { restore(); - if ((effect.f & DESTROYED) !== 0) { + if ((parent.f & DESTROYED) !== 0) { return; } - create_template_effect(fn, [...sync.map(d), ...result]); + var effect = create_template_effect(fn, [...sync.map(d), ...result]); + + if (fork !== null) { + fork.run(() => { + schedule_effect(effect); + }); + } }); } else { create_template_effect(fn, sync.map(d)); @@ -370,7 +379,7 @@ function create_template_effect(fn, deriveds) { }); } - create_effect(RENDER_EFFECT, effect, true); + return create_effect(RENDER_EFFECT, effect, true); } /** diff --git a/packages/svelte/src/internal/client/runtime.js b/packages/svelte/src/internal/client/runtime.js index eef109b8a3..b8f05bb850 100644 --- a/packages/svelte/src/internal/client/runtime.js +++ b/packages/svelte/src/internal/client/runtime.js @@ -751,12 +751,20 @@ export function schedule_effect(signal) { var flags = effect.f; if ((flags & (ROOT_EFFECT | BRANCH_EFFECT)) !== 0) { - if ((flags & CLEAN) === 0) return; - effect.f ^= CLEAN; + // TODO reinstate this + // if ((flags & CLEAN) === 0) return; + // effect.f ^= CLEAN; + + if ((flags & CLEAN) !== 0) { + effect.f ^= CLEAN; + } } } - queued_root_effects.push(effect); + // TODO reinstate early bail-out when traversing up the graph + if (!queued_root_effects.includes(effect)) { + queued_root_effects.push(effect); + } } export function queue_flush() { @@ -827,7 +835,8 @@ function process_effects(effect, fork) { } } else if ((flags & RENDER_EFFECT) !== 0) { if (is_branch) { - current_effect.f ^= CLEAN; + // TODO clean branch later, if fork is settled + // current_effect.f ^= CLEAN; } else { render_effects.push(current_effect); } @@ -848,6 +857,7 @@ function process_effects(effect, fork) { while (parent !== null) { if (effect === parent) { + // TODO is this still necessary? break main_loop; }