From b2b3399419e42dd1646db1d28bfc8f8526e29f9c Mon Sep 17 00:00:00 2001 From: Dominic Gannaway Date: Wed, 9 Oct 2024 11:01:11 +0100 Subject: [PATCH] breaking: array proxy toPrimitive is no longer reactive --- .changeset/gorgeous-jokes-sit.md | 5 ++++ packages/svelte/src/internal/client/proxy.js | 8 ++++- .../samples/inspect-derived-2/main.svelte | 2 +- .../props-default-value-lazy/sub.svelte | 2 +- .../samples/proxy-to-primitive/_config.js | 30 +++++++++++++++++++ .../samples/proxy-to-primitive/main.svelte | 21 +++++++++++++ 6 files changed, 65 insertions(+), 3 deletions(-) create mode 100644 .changeset/gorgeous-jokes-sit.md create mode 100644 packages/svelte/tests/runtime-runes/samples/proxy-to-primitive/_config.js create mode 100644 packages/svelte/tests/runtime-runes/samples/proxy-to-primitive/main.svelte diff --git a/.changeset/gorgeous-jokes-sit.md b/.changeset/gorgeous-jokes-sit.md new file mode 100644 index 0000000000..09484f7131 --- /dev/null +++ b/.changeset/gorgeous-jokes-sit.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +breaking: array proxy toPrimitive is no longer reactive diff --git a/packages/svelte/src/internal/client/proxy.js b/packages/svelte/src/internal/client/proxy.js index 7454a22183..915b88c56f 100644 --- a/packages/svelte/src/internal/client/proxy.js +++ b/packages/svelte/src/internal/client/proxy.js @@ -1,6 +1,6 @@ /** @import { ProxyMetadata, ProxyStateObject, Source } from '#client' */ import { DEV } from 'esm-env'; -import { get, component_context, active_effect } from './runtime.js'; +import { get, component_context, active_effect, untrack } from './runtime.js'; import { array_prototype, get_descriptor, @@ -115,6 +115,12 @@ export function proxy(value, parent = null, prev) { if (DEV && prop === STATE_SYMBOL_METADATA) { return metadata; } + // We untrack Symbol.toPrimitive cases. If people want explicit reactivity, they should + // use toString() or some other coercion method instead + if (is_proxied_array && prop === Symbol.toPrimitive) { + return (/** @type {'string' | 'number' | 'default'} */ hint) => + untrack(() => (hint === 'number' ? Number(target) : String(target))); + } if (prop === STATE_SYMBOL) { return value; diff --git a/packages/svelte/tests/runtime-runes/samples/inspect-derived-2/main.svelte b/packages/svelte/tests/runtime-runes/samples/inspect-derived-2/main.svelte index 1071d37c39..14e9e7acc7 100644 --- a/packages/svelte/tests/runtime-runes/samples/inspect-derived-2/main.svelte +++ b/packages/svelte/tests/runtime-runes/samples/inspect-derived-2/main.svelte @@ -18,4 +18,4 @@ -{state.data.list} +{state.data.list.toString()} diff --git a/packages/svelte/tests/runtime-runes/samples/props-default-value-lazy/sub.svelte b/packages/svelte/tests/runtime-runes/samples/props-default-value-lazy/sub.svelte index fe2ac37bd3..ce2a5e5e2d 100644 --- a/packages/svelte/tests/runtime-runes/samples/props-default-value-lazy/sub.svelte +++ b/packages/svelte/tests/runtime-runes/samples/props-default-value-lazy/sub.svelte @@ -26,4 +26,4 @@

props: {p0} {p1} {p2} {p3} {p4} {p5} {p6} {p7}

-

log: {log}

+

log: {log.toString()}

diff --git a/packages/svelte/tests/runtime-runes/samples/proxy-to-primitive/_config.js b/packages/svelte/tests/runtime-runes/samples/proxy-to-primitive/_config.js new file mode 100644 index 0000000000..684e5870c1 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/proxy-to-primitive/_config.js @@ -0,0 +1,30 @@ +import { flushSync } from 'svelte'; +import { test } from '../../test'; + +export default test({ + html: ` + + `, + + ssrHtml: ` + + `, + + test({ assert, target }) { + const [btn1] = target.querySelectorAll('button'); + + flushSync(() => { + btn1?.click(); + }); + + assert.htmlEqual( + target.innerHTML, + ` + + ` + ); + } +}); diff --git a/packages/svelte/tests/runtime-runes/samples/proxy-to-primitive/main.svelte b/packages/svelte/tests/runtime-runes/samples/proxy-to-primitive/main.svelte new file mode 100644 index 0000000000..a02ab881c6 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/proxy-to-primitive/main.svelte @@ -0,0 +1,21 @@ + + + + +