From 66a184689b2ea25b012cc0df1ea9010f12511637 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Mon, 8 Jul 2024 14:19:54 -0700 Subject: [PATCH] chore: simplify legacy props (#12353) * chore: simplify legacy props * add test --- packages/svelte/src/legacy/legacy-client.js | 44 +++++++------------ .../samples/component-props-added/_config.js | 15 +++++++ .../samples/component-props-added/main.svelte | 3 ++ 3 files changed, 34 insertions(+), 28 deletions(-) create mode 100644 packages/svelte/tests/runtime-legacy/samples/component-props-added/_config.js create mode 100644 packages/svelte/tests/runtime-legacy/samples/component-props-added/main.svelte diff --git a/packages/svelte/src/legacy/legacy-client.js b/packages/svelte/src/legacy/legacy-client.js index 35108b83a9..334fe34e14 100644 --- a/packages/svelte/src/legacy/legacy-client.js +++ b/packages/svelte/src/legacy/legacy-client.js @@ -71,50 +71,37 @@ class Svelte4Component { */ constructor(options) { var sources = new Map(); - var add_source = (/** @type {string | symbol} */ key) => { - var s = mutable_source(0); + + /** + * @param {string | symbol} key + * @param {unknown} value + */ + var add_source = (key, value) => { + var s = mutable_source(value); sources.set(key, s); return s; }; + // Replicate coarse-grained props through a proxy that has a version source for // each property, which is increment on updates to the property itself. Do not // use our $state proxy because that one has fine-grained reactivity. const props = new Proxy( { ...(options.props || {}), $$events: {} }, { - get(target, prop, receiver) { - var value = Reflect.get(target, prop, receiver); - var s = sources.get(prop); - if (s === undefined) { - s = add_source(prop); - } - get(s); - return value; + get(target, prop) { + return get(sources.get(prop) ?? add_source(prop, Reflect.get(target, prop))); }, has(target, prop) { - var value = Reflect.has(target, prop); - var s = sources.get(prop); - if (s !== undefined) { - get(s); - } - return value; + get(sources.get(prop) ?? add_source(prop, Reflect.get(target, prop))); + return Reflect.has(target, prop); }, set(target, prop, value) { - var s = sources.get(prop); - // @ts-ignore - var prev_value = target[prop]; - if (s === undefined) { - s = add_source(prop); - } else if (safe_not_equal(prev_value, value)) { - // Increment version - set(s, s.v + 1); - } - // @ts-ignore - target[prop] = value; - return true; + set(sources.get(prop) ?? add_source(prop, value), value); + return Reflect.set(target, prop, value); } } ); + this.#instance = (options.hydrate ? hydrate : mount)(options.component, { target: options.target, props, @@ -142,6 +129,7 @@ class Svelte4Component { this.#instance.$set = /** @param {Record} next */ (next) => { Object.assign(props, next); }; + this.#instance.$destroy = () => { unmount(this.#instance); }; diff --git a/packages/svelte/tests/runtime-legacy/samples/component-props-added/_config.js b/packages/svelte/tests/runtime-legacy/samples/component-props-added/_config.js new file mode 100644 index 0000000000..bed8824577 --- /dev/null +++ b/packages/svelte/tests/runtime-legacy/samples/component-props-added/_config.js @@ -0,0 +1,15 @@ +import { test } from '../../test'; + +export default test({ + get props() { + return {}; + }, + + html: '', + + async test({ assert, component, target }) { + await component.$set({ message: 'goodbye' }); + + assert.htmlEqual(target.innerHTML, '

goodbye

'); + } +}); diff --git a/packages/svelte/tests/runtime-legacy/samples/component-props-added/main.svelte b/packages/svelte/tests/runtime-legacy/samples/component-props-added/main.svelte new file mode 100644 index 0000000000..8ee7f80adf --- /dev/null +++ b/packages/svelte/tests/runtime-legacy/samples/component-props-added/main.svelte @@ -0,0 +1,3 @@ +{#if 'message' in $$props} +

{$$props.message}

+{/if}