Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/new-candles-marry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'svelte': patch
---

chore: simplify internal component `pop()`
50 changes: 20 additions & 30 deletions packages/svelte/src/internal/client/context.js
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,6 @@ export function push(props, runes = false, fn) {
c: null,
d: false,
e: null,
m: false,
s: props,
x: null,
l: null
Expand Down Expand Up @@ -176,37 +175,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} */
Expand Down
18 changes: 4 additions & 14 deletions packages/svelte/src/internal/client/reactivity/effects.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Expand Down
8 changes: 1 addition & 7 deletions packages/svelte/src/internal/client/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,7 @@ export type ComponentContext = {
/** destroyed */
d: boolean;
/** 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
Expand Down