diff --git a/packages/svelte/src/compiler/phases/3-transform/client/visitors/SlotElement.js b/packages/svelte/src/compiler/phases/3-transform/client/visitors/SlotElement.js index 401cfde42832..43393e5bdc5a 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/visitors/SlotElement.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/visitors/SlotElement.js @@ -54,8 +54,7 @@ export function SlotElement(node, context) { // Let bindings first, they can be used on attributes context.state.init.push(...lets); - const props_expression = - spreads.length === 0 ? b.object(props) : b.call('$.spread_props', b.object(props), ...spreads); + const props_expression = b.call('$.props', b.object(props), ...spreads); const fallback = node.fragment.nodes.length === 0 diff --git a/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/component.js b/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/component.js index a1c4025d6023..1d52e4ac7c82 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/component.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/component.js @@ -4,8 +4,8 @@ import { dev, is_ignored } from '../../../../../state.js'; import { get_attribute_chunks, object } from '../../../../../utils/ast.js'; import * as b from '#compiler/builders'; -import { build_bind_this, memoize_expression, validate_binding } from '../shared/utils.js'; -import { build_attribute_value } from '../shared/element.js'; +import { build_bind_this, memoize_expression, validate_binding } from './utils.js'; +import { build_attribute_value } from './element.js'; import { build_event_handler } from './events.js'; import { determine_slot } from '../../../../../utils/slot.js'; @@ -399,14 +399,10 @@ export function build_component(node, component_name, context) { push_prop(b.init('$$legacy', b.true)); } - const props_expression = - props_and_spreads.length === 0 || - (props_and_spreads.length === 1 && Array.isArray(props_and_spreads[0])) - ? b.object(/** @type {Property[]} */ (props_and_spreads[0]) || []) - : b.call( - '$.spread_props', - ...props_and_spreads.map((p) => (Array.isArray(p) ? b.object(p) : p)) - ); + const props_expression = b.call( + '$.props', + ...props_and_spreads.map((p) => (Array.isArray(p) ? b.object(p) : p)) + ); /** @param {Expression} node_id */ let fn = (node_id) => { diff --git a/packages/svelte/src/internal/client/context.js b/packages/svelte/src/internal/client/context.js index 7c7213b7a2de..f381c62d3a1f 100644 --- a/packages/svelte/src/internal/client/context.js +++ b/packages/svelte/src/internal/client/context.js @@ -101,16 +101,15 @@ 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 = { @@ -121,10 +120,6 @@ export function push(props, runes = false, fn) { }; } - teardown(() => { - /** @type {ComponentContext} */ (ctx).d = true; - }); - if (DEV) { // component function component_context.function = fn; diff --git a/packages/svelte/src/internal/client/index.js b/packages/svelte/src/internal/client/index.js index 60f9af912060..7a4b045f52d6 100644 --- a/packages/svelte/src/internal/client/index.js +++ b/packages/svelte/src/internal/client/index.js @@ -114,7 +114,7 @@ export { prop, rest_props, legacy_rest_props, - spread_props, + props, update_pre_prop, update_prop } from './reactivity/props.js'; diff --git a/packages/svelte/src/internal/client/reactivity/deriveds.js b/packages/svelte/src/internal/client/reactivity/deriveds.js index e9cea0df3e64..5fa3ffe1c041 100644 --- a/packages/svelte/src/internal/client/reactivity/deriveds.js +++ b/packages/svelte/src/internal/client/reactivity/deriveds.js @@ -116,7 +116,7 @@ let stack = []; * @param {Derived} derived * @returns {Effect | null} */ -function get_derived_parent_effect(derived) { +export function get_derived_parent_effect(derived) { var parent = derived.parent; while (parent !== null) { if ((parent.f & DERIVED) === 0) { diff --git a/packages/svelte/src/internal/client/reactivity/props.js b/packages/svelte/src/internal/client/reactivity/props.js index f3111361c051..937f60bf843b 100644 --- a/packages/svelte/src/internal/client/reactivity/props.js +++ b/packages/svelte/src/internal/client/reactivity/props.js @@ -9,11 +9,17 @@ import { } from '../../../constants.js'; import { get_descriptor, is_function } from '../../shared/utils.js'; import { mutable_source, set, source, update } from './sources.js'; -import { derived, derived_safe_equal } from './deriveds.js'; -import { get, captured_signals, untrack } from '../runtime.js'; +import { derived, derived_safe_equal, get_derived_parent_effect } from './deriveds.js'; +import { active_effect, captured_signals, get, untrack } from '../runtime.js'; import { safe_equals } from './equality.js'; import * as e from '../errors.js'; -import { LEGACY_DERIVED_PROP, LEGACY_PROPS, STATE_SYMBOL } from '#client/constants'; +import { + DESTROYED, + INERT, + LEGACY_DERIVED_PROP, + LEGACY_PROPS, + STATE_SYMBOL +} from '#client/constants'; import { proxy } from '../proxy.js'; import { capture_store_binding } from './store.js'; import { legacy_mode_flag } from '../../flags/index.js'; @@ -159,16 +165,17 @@ export function legacy_rest_props(props, exclude) { * The proxy handler for spread props. Handles the incoming array of props * that looks like `() => { dynamic: props }, { static: prop }, ..` and wraps * them so that the whole thing is passed to the component as the `$$props` argument. - * @template {Record} T - * @type {ProxyHandler<{ props: Array T)> }>}} + * @typedef {Record} AnyProps + * @type {ProxyHandler<{ props: Array AnyProps)>, old_props: AnyProps, destroyed: boolean }>}} */ const spread_props_handler = { get(target, key) { + if (target.destroyed && key in target.old_props) return target.old_props[key]; let i = target.props.length; while (i--) { let p = target.props[i]; if (is_function(p)) p = p(); - if (typeof p === 'object' && p !== null && key in p) return p[key]; + if (typeof p === 'object' && p !== null && key in p) return (target.old_props[key] = p[key]); } }, set(target, key, value) { @@ -178,7 +185,7 @@ const spread_props_handler = { if (is_function(p)) p = p(); const desc = get_descriptor(p, key); if (desc && desc.set) { - desc.set(value); + desc.set((target.old_props[key] = value)); return true; } } @@ -237,16 +244,34 @@ const spread_props_handler = { * @param {Array | (() => Record)>} props * @returns {any} */ -export function spread_props(...props) { - return new Proxy({ props }, spread_props_handler); +export function props(...props) { + const effect = active_effect; + return new Proxy( + { + props, + old_props: untrack(() => { + const old_props = {}; + for (let p of props) { + if (typeof p === 'function') p = p(); + Object.assign(old_props, p); + } + return old_props; + }), + get destroyed() { + return effect ? (effect.f & (DESTROYED | INERT)) !== 0 : false; + } + }, + spread_props_handler + ); } /** - * @param {Derived} current_value - * @returns {boolean} + * @param {Derived} derived */ -function has_destroyed_component_ctx(current_value) { - return current_value.ctx?.d ?? false; +function is_paused_or_destroyed(derived) { + const parent = get_derived_parent_effect(derived); + if (!parent) return false; + return (parent.f & (DESTROYED | INERT)) !== 0; } /** @@ -414,7 +439,7 @@ export function prop(props, key, flags, fallback) { fallback_value = new_value; } - if (has_destroyed_component_ctx(current_value)) { + if (is_paused_or_destroyed(current_value)) { return value; } @@ -424,7 +449,7 @@ export function prop(props, key, flags, fallback) { return value; } - if (has_destroyed_component_ctx(current_value)) { + if (is_paused_or_destroyed(current_value)) { return current_value.v; } diff --git a/packages/svelte/src/internal/client/reactivity/sources.js b/packages/svelte/src/internal/client/reactivity/sources.js index 40a3e4e77f14..111e8ca7a21d 100644 --- a/packages/svelte/src/internal/client/reactivity/sources.js +++ b/packages/svelte/src/internal/client/reactivity/sources.js @@ -14,7 +14,6 @@ import { reaction_sources, check_dirtiness, untracking, - is_destroying_effect, push_reaction_value } from '../runtime.js'; import { equals, safe_equals } from './equality.js'; @@ -38,9 +37,6 @@ import { execute_derived } from './deriveds.js'; export let inspect_effects = new Set(); -/** @type {Map} */ -export const old_values = new Map(); - /** * @param {Set} v */ @@ -160,14 +156,6 @@ export function set(source, value, should_proxy = false) { */ export function internal_set(source, value) { if (!source.equals(value)) { - var old_value = source.v; - - if (is_destroying_effect) { - old_values.set(source, value); - } else { - old_values.set(source, old_value); - } - source.v = value; if (DEV && tracing_mode_flag) { diff --git a/packages/svelte/src/internal/client/runtime.js b/packages/svelte/src/internal/client/runtime.js index 954406095904..237a7a3c994e 100644 --- a/packages/svelte/src/internal/client/runtime.js +++ b/packages/svelte/src/internal/client/runtime.js @@ -25,7 +25,7 @@ import { EFFECT_IS_UPDATING } from './constants.js'; import { flush_tasks } from './dom/task.js'; -import { internal_set, old_values } from './reactivity/sources.js'; +import { internal_set } from './reactivity/sources.js'; import { destroy_derived_effects, update_derived } from './reactivity/deriveds.js'; import * as e from './errors.js'; @@ -535,7 +535,6 @@ function flush_queued_root_effects() { var collected_effects = process_effects(root_effects[i]); flush_queued_effects(collected_effects); } - old_values.clear(); } } finally { is_flushing = false; @@ -800,10 +799,6 @@ export function get(signal) { } } - if (is_destroying_effect && old_values.has(signal)) { - return old_values.get(signal); - } - return signal.v; } diff --git a/packages/svelte/src/internal/client/types.d.ts b/packages/svelte/src/internal/client/types.d.ts index 9703c2aac198..a3156b14dd45 100644 --- a/packages/svelte/src/internal/client/types.d.ts +++ b/packages/svelte/src/internal/client/types.d.ts @@ -14,8 +14,6 @@ export type ComponentContext = { p: null | ComponentContext; /** context */ c: null | Map; - /** destroyed */ - d: boolean; /** deferred effects */ e: null | Array<{ fn: () => void | (() => void); diff --git a/packages/svelte/tests/runtime-runes/samples/effect-teardown-stale-value/_config.js b/packages/svelte/tests/runtime-runes/samples/effect-teardown-stale-value/_config.js index 1016ffb43e7e..349487883bf6 100644 --- a/packages/svelte/tests/runtime-runes/samples/effect-teardown-stale-value/_config.js +++ b/packages/svelte/tests/runtime-runes/samples/effect-teardown-stale-value/_config.js @@ -14,7 +14,8 @@ export default test({ 'up', { foo: false, bar: false }, 'down', - { foo: false, bar: false }, + // TODO the test should be deleted as there's no more concept of "teardown stale value" + { foo: true, bar: true }, 'up', { foo: true, bar: true } ]); diff --git a/packages/svelte/tests/runtime-runes/samples/nested-effect-conflict/_config.js b/packages/svelte/tests/runtime-runes/samples/nested-effect-conflict/_config.js index eb631bc9f4bc..a8c16b7008c9 100644 --- a/packages/svelte/tests/runtime-runes/samples/nested-effect-conflict/_config.js +++ b/packages/svelte/tests/runtime-runes/samples/nested-effect-conflict/_config.js @@ -10,6 +10,14 @@ export default test({ }); await Promise.resolve(); - assert.deepEqual(logs, ['top level', 'inner', 0, 'destroy inner', 0, 'destroy outer', 0]); + assert.deepEqual(logs, [ + 'top level', + 'inner', + 0, + 'destroy inner', + undefined, + 'destroy outer', + undefined + ]); } }); diff --git a/packages/svelte/tests/snapshot/samples/bind-component-snippet/_expected/client/index.svelte.js b/packages/svelte/tests/snapshot/samples/bind-component-snippet/_expected/client/index.svelte.js index ba3f4b155a31..a407c84a8ad2 100644 --- a/packages/svelte/tests/snapshot/samples/bind-component-snippet/_expected/client/index.svelte.js +++ b/packages/svelte/tests/snapshot/samples/bind-component-snippet/_expected/client/index.svelte.js @@ -18,17 +18,17 @@ export default function Bind_component_snippet($$anchor) { var fragment = root(); var node = $.first_child(fragment); - TextInput(node, { + TextInput(node, $.props({ get value() { return $.get(value); }, set value($$value) { $.set(value, $$value, true); } - }); + })); var text_1 = $.sibling(node); $.template_effect(() => $.set_text(text_1, ` value: ${$.get(value) ?? ''}`)); $.append($$anchor, fragment); -} \ No newline at end of file +} diff --git a/packages/svelte/tests/snapshot/samples/bind-this/_expected/client/index.svelte.js b/packages/svelte/tests/snapshot/samples/bind-this/_expected/client/index.svelte.js index dfd32a04e51d..7b9f6d0abfb0 100644 --- a/packages/svelte/tests/snapshot/samples/bind-this/_expected/client/index.svelte.js +++ b/packages/svelte/tests/snapshot/samples/bind-this/_expected/client/index.svelte.js @@ -3,5 +3,5 @@ import 'svelte/internal/flags/legacy'; import * as $ from 'svelte/internal/client'; export default function Bind_this($$anchor) { - $.bind_this(Foo($$anchor, { $$legacy: true }), ($$value) => foo = $$value, () => foo); -} \ No newline at end of file + $.bind_this(Foo($$anchor, $.props({ $$legacy: true })), ($$value) => foo = $$value, () => foo); +} diff --git a/packages/svelte/tests/snapshot/samples/function-prop-no-getter/_expected/client/index.svelte.js b/packages/svelte/tests/snapshot/samples/function-prop-no-getter/_expected/client/index.svelte.js index 762a23754c9b..4bf75eea50c0 100644 --- a/packages/svelte/tests/snapshot/samples/function-prop-no-getter/_expected/client/index.svelte.js +++ b/packages/svelte/tests/snapshot/samples/function-prop-no-getter/_expected/client/index.svelte.js @@ -10,7 +10,7 @@ export default function Function_prop_no_getter($$anchor) { const plusOne = (num) => num + 1; - Button($$anchor, { + Button($$anchor, $.props({ onmousedown: () => $.set(count, $.get(count) + 1), onmouseup, onmouseenter: () => $.set(count, plusOne($.get(count)), true), @@ -23,5 +23,5 @@ export default function Function_prop_no_getter($$anchor) { $.append($$anchor, text); }, $$slots: { default: true } - }); -} \ No newline at end of file + })); +} diff --git a/packages/svelte/tests/snapshot/samples/purity/_expected/client/index.svelte.js b/packages/svelte/tests/snapshot/samples/purity/_expected/client/index.svelte.js index a351851875ed..de315b019662 100644 --- a/packages/svelte/tests/snapshot/samples/purity/_expected/client/index.svelte.js +++ b/packages/svelte/tests/snapshot/samples/purity/_expected/client/index.svelte.js @@ -16,6 +16,6 @@ export default function Purity($$anchor) { var node = $.sibling(p_1, 2); - Child(node, { prop: encodeURIComponent('hello') }); + Child(node, $.props({ prop: encodeURIComponent('hello') })); $.append($$anchor, fragment); -} \ No newline at end of file +} pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy