fix: ensure props passed to components via mount are updateable

Fixes #14161
pull/14210/head
Simon Holthausen 2 years ago
parent ea0d80e195
commit 6219282402

@ -20,7 +20,7 @@ import {
} from '../runtime.js'; } from '../runtime.js';
import { safe_equals } from './equality.js'; import { safe_equals } from './equality.js';
import * as e from '../errors.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 { proxy } from '../proxy.js';
import { capture_store_binding } from './store.js'; import { capture_store_binding } from './store.js';
import { legacy_mode_flag } from '../../flags/index.js'; import { legacy_mode_flag } from '../../flags/index.js';
@ -282,7 +282,11 @@ export function prop(props, key, flags, fallback) {
} else { } else {
prop_value = /** @type {V} */ (props[key]); 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_value = /** @type {V} */ (fallback);
var fallback_dirty = true; var fallback_dirty = true;

@ -104,6 +104,20 @@ class Svelte4Component {
set(target, prop, value) { set(target, prop, value) {
set(sources.get(prop) ?? add_source(prop, value), value); set(sources.get(prop) ?? add_source(prop, value), value);
return Reflect.set(target, prop, 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
};
} }
} }
); );

Loading…
Cancel
Save