diff --git a/packages/svelte/src/internal/client/reactivity/props.js b/packages/svelte/src/internal/client/reactivity/props.js index ae934c01a5..41809e4f73 100644 --- a/packages/svelte/src/internal/client/reactivity/props.js +++ b/packages/svelte/src/internal/client/reactivity/props.js @@ -20,7 +20,7 @@ import { } from '../runtime.js'; import { safe_equals } from './equality.js'; import * as e from '../errors.js'; -import { BRANCH_EFFECT, LEGACY_DERIVED_PROP, ROOT_EFFECT } from '../constants.js'; +import { BRANCH_EFFECT, LEGACY_DERIVED_PROP, ROOT_EFFECT, STATE_SYMBOL } from '../constants.js'; import { proxy } from '../proxy.js'; import { capture_store_binding } from './store.js'; import { legacy_mode_flag } from '../../flags/index.js'; @@ -282,7 +282,11 @@ export function prop(props, key, flags, fallback) { } else { prop_value = /** @type {V} */ (props[key]); } - var setter = get_descriptor(props, key)?.set; + + var setter = + get_descriptor(props, key)?.set ?? + // Can be the case when someone does `mount(Component, props)` with `let props = $state({...})` + (STATE_SYMBOL in props ? (v) => (props[key] = v) : undefined); var fallback_value = /** @type {V} */ (fallback); var fallback_dirty = true; diff --git a/packages/svelte/src/legacy/legacy-client.js b/packages/svelte/src/legacy/legacy-client.js index c7684570bb..30f2161b77 100644 --- a/packages/svelte/src/legacy/legacy-client.js +++ b/packages/svelte/src/legacy/legacy-client.js @@ -104,6 +104,20 @@ class Svelte4Component { set(target, prop, value) { set(sources.get(prop) ?? add_source(prop, value), value); return Reflect.set(target, prop, value); + }, + getOwnPropertyDescriptor(target, prop) { + // TODO this throws "invalid binding" errors on the component side + const desc = Reflect.getOwnPropertyDescriptor(target, prop); + if (!desc?.configurable) return desc; + return { + get: () => get(sources.get(prop) ?? add_source(prop, Reflect.get(target, prop))), + set: (value) => { + set(sources.get(prop) ?? add_source(prop, value), value); + return Reflect.set(target, prop, value); + }, + enumerable: desc.enumerable, + configurable: desc.configurable + }; } } );