From 2017af407d73c5e90f17c0cc2677893d8e90648e Mon Sep 17 00:00:00 2001 From: Dominic Gannaway Date: Mon, 4 Dec 2023 16:24:06 +0000 Subject: [PATCH] fix: ensure computed props are cached with derived (#9757) Fixes #9751 --- .changeset/selfish-tools-hide.md | 5 +++++ .../3-transform/client/visitors/template.js | 13 +++++++++++- .../samples/props-derived/Child.svelte | 7 +++++++ .../samples/props-derived/_config.js | 21 +++++++++++++++++++ .../samples/props-derived/main.svelte | 5 +++++ 5 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 .changeset/selfish-tools-hide.md create mode 100644 packages/svelte/tests/runtime-runes/samples/props-derived/Child.svelte create mode 100644 packages/svelte/tests/runtime-runes/samples/props-derived/_config.js create mode 100644 packages/svelte/tests/runtime-runes/samples/props-derived/main.svelte diff --git a/.changeset/selfish-tools-hide.md b/.changeset/selfish-tools-hide.md new file mode 100644 index 000000000..194a2439d --- /dev/null +++ b/.changeset/selfish-tools-hide.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: ensure computed props are cached with derived diff --git a/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js b/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js index dbde21e95..ef281d319 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js @@ -767,7 +767,18 @@ function serialize_inline_component(node, component_name, context) { const [, value] = serialize_attribute_value(attribute.value, context); if (attribute.metadata.dynamic) { - push_prop(b.get(attribute.name, [b.return(value)])); + const contains_call_expression = + Array.isArray(attribute.value) && + attribute.value.some((n) => { + return n.type === 'ExpressionTag' && n.metadata.contains_call_expression; + }); + if (contains_call_expression) { + const id = b.id(context.state.scope.generate(attribute.name)); + context.state.init.push(b.var(id, b.call('$.derived', b.thunk(value)))); + push_prop(b.get(attribute.name, [b.return(b.call('$.get', id))])); + } else { + push_prop(b.get(attribute.name, [b.return(value)])); + } } else { push_prop(b.init(attribute.name, value)); } diff --git a/packages/svelte/tests/runtime-runes/samples/props-derived/Child.svelte b/packages/svelte/tests/runtime-runes/samples/props-derived/Child.svelte new file mode 100644 index 000000000..f1914c86b --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/props-derived/Child.svelte @@ -0,0 +1,7 @@ + + +

{random}

+

{random}

+

{random}

diff --git a/packages/svelte/tests/runtime-runes/samples/props-derived/_config.js b/packages/svelte/tests/runtime-runes/samples/props-derived/_config.js new file mode 100644 index 000000000..53d312292 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/props-derived/_config.js @@ -0,0 +1,21 @@ +import { test } from '../../test'; + +let math_random = Math.random; +let calls = 0; + +export default test({ + skip_if_hydrate: 'permanent', + before_test() { + Math.random = function () { + calls++; + return math_random.call(this); + }; + }, + after_test() { + Math.random = math_random; + calls = 0; + }, + test({ assert }) { + assert.equal(calls, 1); + } +}); diff --git a/packages/svelte/tests/runtime-runes/samples/props-derived/main.svelte b/packages/svelte/tests/runtime-runes/samples/props-derived/main.svelte new file mode 100644 index 000000000..76bf2ba49 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/props-derived/main.svelte @@ -0,0 +1,5 @@ + + +