diff --git a/.changeset/new-candles-marry.md b/.changeset/new-candles-marry.md new file mode 100644 index 0000000000..4d55980c72 --- /dev/null +++ b/.changeset/new-candles-marry.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +chore: simplify internal component `pop()` diff --git a/packages/svelte/src/internal/client/context.js b/packages/svelte/src/internal/client/context.js index d79d827fee..6876a89f57 100644 --- a/packages/svelte/src/internal/client/context.js +++ b/packages/svelte/src/internal/client/context.js @@ -143,7 +143,6 @@ export function push(props, runes = false, fn) { p: component_context, c: null, e: null, - m: false, s: props, x: null, l: null @@ -171,37 +170,28 @@ export function push(props, runes = false, fn) { * @returns {T} */ export function pop(component) { - const context_stack_item = component_context; - if (context_stack_item !== null) { - if (component !== undefined) { - context_stack_item.x = component; - } - const component_effects = context_stack_item.e; - if (component_effects !== null) { - var previous_effect = active_effect; - var previous_reaction = active_reaction; - context_stack_item.e = null; - try { - for (var i = 0; i < component_effects.length; i++) { - var component_effect = component_effects[i]; - set_active_effect(component_effect.effect); - set_active_reaction(component_effect.reaction); - create_user_effect(component_effect.fn); - } - } finally { - set_active_effect(previous_effect); - set_active_reaction(previous_reaction); - } - } - component_context = context_stack_item.p; - if (DEV) { - dev_current_component_function = context_stack_item.p?.function ?? null; + var context = /** @type {ComponentContext} */ (component_context); + var effects = context.e; + + if (effects !== null) { + context.e = null; + + for (var fn of effects) { + create_user_effect(fn); } - context_stack_item.m = true; } - // Micro-optimization: Don't set .a above to the empty object - // so it can be garbage-collected when the return here is unused - return component || /** @type {T} */ ({}); + + if (component !== undefined) { + context.x = component; + } + + component_context = context.p; + + if (DEV) { + dev_current_component_function = component_context?.function ?? null; + } + + return component ?? /** @type {T} */ ({}); } /** @returns {boolean} */ diff --git a/packages/svelte/src/internal/client/reactivity/effects.js b/packages/svelte/src/internal/client/reactivity/effects.js index df2afd3e38..51c6805529 100644 --- a/packages/svelte/src/internal/client/reactivity/effects.js +++ b/packages/svelte/src/internal/client/reactivity/effects.js @@ -179,28 +179,18 @@ export function teardown(fn) { export function user_effect(fn) { validate_effect('$effect'); - // Non-nested `$effect(...)` in a component should be deferred - // until the component is mounted - var defer = - active_effect !== null && - (active_effect.f & BRANCH_EFFECT) !== 0 && - component_context !== null && - !component_context.m; - if (DEV) { define_property(fn, 'name', { value: '$effect' }); } - if (defer) { + if (!active_reaction && active_effect && (active_effect.f & BRANCH_EFFECT) !== 0) { + // Top-level `$effect(...)` in a component — defer until mount var context = /** @type {ComponentContext} */ (component_context); - (context.e ??= []).push({ - fn, - effect: active_effect, - reaction: active_reaction - }); + (context.e ??= []).push(fn); } else { + // Everything else — create immediately return create_user_effect(fn); } } diff --git a/packages/svelte/src/internal/client/types.d.ts b/packages/svelte/src/internal/client/types.d.ts index bcbd0ac8a3..a42f91343c 100644 --- a/packages/svelte/src/internal/client/types.d.ts +++ b/packages/svelte/src/internal/client/types.d.ts @@ -15,13 +15,7 @@ export type ComponentContext = { /** context */ c: null | Map; /** deferred effects */ - e: null | Array<{ - fn: () => void | (() => void); - effect: null | Effect; - reaction: null | Reaction; - }>; - /** mounted */ - m: boolean; + e: null | Array<() => void | (() => void)>; /** * props — needed for legacy mode lifecycle functions, and for `createEventDispatcher` * @deprecated remove in 6.0