Merge branch 'main' into simplify-source-ownership

pull/16333/head
Rich Harris 2 months ago
commit 38e6943ef5

@ -0,0 +1,5 @@
---
'svelte': patch
---
chore: simplify internal component `pop()`

@ -139,16 +139,14 @@ export function getAllContexts() {
* @returns {void}
*/
export function push(props, runes = false, fn) {
var ctx = (component_context = {
component_context = {
p: component_context,
c: null,
d: false,
e: null,
m: false,
s: props,
x: null,
l: null
});
};
if (legacy_mode_flag && !runes) {
component_context.l = {
@ -159,10 +157,6 @@ export function push(props, runes = false, fn) {
};
}
teardown(() => {
/** @type {ComponentContext} */ (ctx).d = true;
});
if (DEV) {
// component function
component_context.function = fn;
@ -176,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} */

@ -209,21 +209,14 @@ export function transition(flags, element, get_fn, get_params) {
var outro;
function get_options() {
var previous_reaction = active_reaction;
var previous_effect = active_effect;
set_active_reaction(null);
set_active_effect(null);
try {
return without_reactive_context(() => {
// If a transition is still ongoing, we use the existing options rather than generating
// new ones. This ensures that reversible transitions reverse smoothly, rather than
// jumping to a new spot because (for example) a different `duration` was used
return (current_options ??= get_fn()(element, get_params?.() ?? /** @type {P} */ ({}), {
direction
}));
} finally {
set_active_reaction(previous_reaction);
set_active_effect(previous_effect);
}
});
}
/** @type {TransitionManager} */

@ -8,7 +8,7 @@ import {
is_array,
object_prototype
} from '../shared/utils.js';
import { state as source, set } from './reactivity/sources.js';
import { state as source, set, increment } from './reactivity/sources.js';
import { PROXY_PATH_SYMBOL, STATE_SYMBOL } from '#client/constants';
import { UNINITIALIZED } from '../../constants.js';
import * as e from './errors.js';
@ -118,7 +118,7 @@ export function proxy(value) {
if (prop in target) {
const s = with_parent(() => source(UNINITIALIZED, stack));
sources.set(prop, s);
update_version(version);
increment(version);
if (DEV) {
tag(s, get_label(path, prop));
@ -136,7 +136,7 @@ export function proxy(value) {
}
}
set(s, UNINITIALIZED);
update_version(version);
increment(version);
}
return true;
@ -304,7 +304,7 @@ export function proxy(value) {
}
}
update_version(version);
increment(version);
}
return true;
@ -343,14 +343,6 @@ function get_label(path, prop) {
return /^\d+$/.test(prop) ? `${path}[${prop}]` : `${path}['${prop}']`;
}
/**
* @param {Source<number>} signal
* @param {1 | -1} [d]
*/
function update_version(signal, d = 1) {
set(signal, signal.v + d);
}
/**
* @param {any} value
*/

@ -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);
}
}

@ -268,14 +268,6 @@ export function spread_props(...props) {
return new Proxy({ props }, spread_props_handler);
}
/**
* @param {Derived} current_value
* @returns {boolean}
*/
function has_destroyed_component_ctx(current_value) {
return current_value.ctx?.d ?? false;
}
/**
* This function is responsible for synchronizing a possibly bound prop with the inner component state.
* It is used whenever the compiler sees that the component writes to the prop, or when it has a default prop_value.

@ -259,6 +259,14 @@ export function update_pre(source, d = 1) {
return set(source, d === 1 ? ++value : --value);
}
/**
* Silently (without using `get`) increment a source
* @param {Source<number>} source
*/
export function increment(source) {
set(source, source.v + 1);
}
/**
* @param {Value} signal
* @param {number} status should be DIRTY or MAYBE_DIRTY

@ -14,16 +14,8 @@ export type ComponentContext = {
p: null | ComponentContext;
/** context */
c: null | Map<unknown, unknown>;
/** 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

@ -1,8 +1,7 @@
import { get, tick, untrack } from '../internal/client/runtime.js';
import { effect_tracking, render_effect } from '../internal/client/reactivity/effects.js';
import { source } from '../internal/client/reactivity/sources.js';
import { source, increment } from '../internal/client/reactivity/sources.js';
import { tag } from '../internal/client/dev/tracing.js';
import { increment } from './utils.js';
import { DEV } from 'esm-env';
/**

@ -1,9 +1,8 @@
/** @import { Source } from '#client' */
import { DEV } from 'esm-env';
import { set, source, state } from '../internal/client/reactivity/sources.js';
import { set, source, state, increment } from '../internal/client/reactivity/sources.js';
import { label, tag } from '../internal/client/dev/tracing.js';
import { get, update_version } from '../internal/client/runtime.js';
import { increment } from './utils.js';
/**
* A reactive version of the built-in [`Map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) object.

@ -1,9 +1,8 @@
/** @import { Source } from '#client' */
import { DEV } from 'esm-env';
import { source, set, state } from '../internal/client/reactivity/sources.js';
import { source, set, state, increment } from '../internal/client/reactivity/sources.js';
import { label, tag } from '../internal/client/dev/tracing.js';
import { get, update_version } from '../internal/client/runtime.js';
import { increment } from './utils.js';
var read_methods = ['forEach', 'isDisjointFrom', 'isSubsetOf', 'isSupersetOf'];
var set_like_methods = ['difference', 'intersection', 'symmetricDifference', 'union'];

@ -1,9 +1,8 @@
import { DEV } from 'esm-env';
import { state } from '../internal/client/reactivity/sources.js';
import { state, increment } from '../internal/client/reactivity/sources.js';
import { tag } from '../internal/client/dev/tracing.js';
import { get } from '../internal/client/runtime.js';
import { get_current_url } from './url.js';
import { increment } from './utils.js';
export const REPLACE = Symbol();

@ -1,7 +0,0 @@
/** @import { Source } from '#client' */
import { set } from '../internal/client/reactivity/sources.js';
/** @param {Source<number>} source */
export function increment(source) {
set(source, source.v + 1);
}
Loading…
Cancel
Save