From 9d7d045310552a60f16c3ac077e392218f811875 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Thu, 13 Feb 2025 13:35:24 -0500 Subject: [PATCH] create separate effect type for async deriveds, as they are not blocks --- packages/svelte/src/internal/client/constants.js | 1 + packages/svelte/src/internal/client/dev/debug.js | 3 +++ .../svelte/src/internal/client/reactivity/deriveds.js | 8 ++++---- packages/svelte/src/internal/client/reactivity/effects.js | 4 ++-- packages/svelte/src/internal/client/reactivity/sources.js | 5 +++-- packages/svelte/src/internal/client/runtime.js | 5 +++-- 6 files changed, 16 insertions(+), 10 deletions(-) diff --git a/packages/svelte/src/internal/client/constants.js b/packages/svelte/src/internal/client/constants.js index 530f72b61c..cf9a18f3dd 100644 --- a/packages/svelte/src/internal/client/constants.js +++ b/packages/svelte/src/internal/client/constants.js @@ -23,6 +23,7 @@ export const EFFECT_PRESERVED = 1 << 21; // effects with this flag should not be // Flags used for async export const REACTION_IS_UPDATING = 1 << 22; +export const EFFECT_ASYNC = 1 << 23; export const STATE_SYMBOL = Symbol('$state'); export const STATE_SYMBOL_METADATA = Symbol('$state metadata'); diff --git a/packages/svelte/src/internal/client/dev/debug.js b/packages/svelte/src/internal/client/dev/debug.js index 2007f0066b..b65f79697c 100644 --- a/packages/svelte/src/internal/client/dev/debug.js +++ b/packages/svelte/src/internal/client/dev/debug.js @@ -7,6 +7,7 @@ import { CLEAN, DERIVED, EFFECT, + EFFECT_ASYNC, MAYBE_DIRTY, RENDER_EFFECT, ROOT_EFFECT @@ -39,6 +40,8 @@ export function log_effect_tree(effect) { label = 'boundary'; } else if ((flags & BLOCK_EFFECT) !== 0) { label = 'block'; + } else if ((flags & EFFECT_ASYNC) !== 0) { + label = 'async'; } else if ((flags & BRANCH_EFFECT) !== 0) { label = 'branch'; } else if ((flags & RENDER_EFFECT) !== 0) { diff --git a/packages/svelte/src/internal/client/reactivity/deriveds.js b/packages/svelte/src/internal/client/reactivity/deriveds.js index 6fd875c98f..8d1a0692d6 100644 --- a/packages/svelte/src/internal/client/reactivity/deriveds.js +++ b/packages/svelte/src/internal/client/reactivity/deriveds.js @@ -5,6 +5,7 @@ import { DERIVED, DESTROYED, DIRTY, + EFFECT_ASYNC, EFFECT_PRESERVED, MAYBE_DIRTY, UNOWNED @@ -22,7 +23,7 @@ import { import { equals, safe_equals } from './equality.js'; import * as e from '../errors.js'; import * as w from '../warnings.js'; -import { block, destroy_effect } from './effects.js'; +import { block, destroy_effect, render_effect } from './effects.js'; import { inspect_effects, internal_set, set_inspect_effects, source } from './sources.js'; import { get_stack } from '../dev/tracing.js'; import { tracing_mode_flag } from '../../flags/index.js'; @@ -107,8 +108,7 @@ export function async_derived(fn, location) { /** @type {(() => void) | null} */ var unsuspend = null; - // TODO this isn't a block - block(() => { + render_effect(() => { if (DEV) from_async_derived = active_effect; var current = (promise = fn()); if (DEV) from_async_derived = null; @@ -151,7 +151,7 @@ export function async_derived(fn, location) { } } ); - }, EFFECT_PRESERVED); + }, EFFECT_ASYNC | EFFECT_PRESERVED); return new Promise(async (fulfil) => { // if the effect re-runs before the initial promise diff --git a/packages/svelte/src/internal/client/reactivity/effects.js b/packages/svelte/src/internal/client/reactivity/effects.js index 554b3bce27..ab6ee71c4e 100644 --- a/packages/svelte/src/internal/client/reactivity/effects.js +++ b/packages/svelte/src/internal/client/reactivity/effects.js @@ -335,8 +335,8 @@ export function legacy_pre_effect_reset() { * @param {() => void | (() => void)} fn * @returns {Effect} */ -export function render_effect(fn) { - return create_effect(RENDER_EFFECT, fn, true); +export function render_effect(fn, flags = 0) { + return create_effect(RENDER_EFFECT | flags, fn, true); } /** diff --git a/packages/svelte/src/internal/client/reactivity/sources.js b/packages/svelte/src/internal/client/reactivity/sources.js index 0dc55f97ba..efc5aa20fe 100644 --- a/packages/svelte/src/internal/client/reactivity/sources.js +++ b/packages/svelte/src/internal/client/reactivity/sources.js @@ -28,7 +28,8 @@ import { UNOWNED, MAYBE_DIRTY, BLOCK_EFFECT, - ROOT_EFFECT + ROOT_EFFECT, + EFFECT_ASYNC } from '../constants.js'; import * as e from '../errors.js'; import { legacy_mode_flag, tracing_mode_flag } from '../../flags/index.js'; @@ -150,7 +151,7 @@ export function set(source, value) { active_reaction !== null && !untracking && is_runes() && - (active_reaction.f & (DERIVED | BLOCK_EFFECT)) !== 0 && + (active_reaction.f & (DERIVED | BLOCK_EFFECT | EFFECT_ASYNC)) !== 0 && // If the source was created locally within the current derived, then // we allow the mutation. (derived_sources === null || !derived_sources.includes(source)) diff --git a/packages/svelte/src/internal/client/runtime.js b/packages/svelte/src/internal/client/runtime.js index 0b9d22fa56..b352d1a75f 100644 --- a/packages/svelte/src/internal/client/runtime.js +++ b/packages/svelte/src/internal/client/runtime.js @@ -24,7 +24,8 @@ import { LEGACY_DERIVED_PROP, DISCONNECTED, BOUNDARY_EFFECT, - REACTION_IS_UPDATING + REACTION_IS_UPDATING, + EFFECT_ASYNC } from './constants.js'; import { flush_idle_tasks, @@ -820,7 +821,7 @@ function process_effects(effect, effects = [], boundary) { var sibling = current_effect.next; if (!is_skippable_branch && (flags & INERT) === 0) { - if (boundary !== undefined && (flags & (BLOCK_EFFECT | BRANCH_EFFECT)) === 0) { + if (boundary !== undefined && (flags & (BLOCK_EFFECT | BRANCH_EFFECT | EFFECT_ASYNC)) === 0) { // Inside a boundary, defer everything except block/branch effects boundary.add_effect(current_effect); } else if ((flags & BOUNDARY_EFFECT) !== 0) {