diff --git a/.changeset/odd-buckets-lie.md b/.changeset/odd-buckets-lie.md new file mode 100644 index 0000000000..240cf02d9a --- /dev/null +++ b/.changeset/odd-buckets-lie.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: improve code generation diff --git a/packages/svelte/src/compiler/phases/3-transform/client/utils.js b/packages/svelte/src/compiler/phases/3-transform/client/utils.js index 19fef4e5bd..d8e6008086 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/utils.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/utils.js @@ -217,9 +217,10 @@ function is_expression_async(expression) { * @param {import('estree').AssignmentExpression} node * @param {import('zimmerframe').Context} context * @param {() => any} fallback + * @param {{skip_proxy_and_freeze?: boolean}} [options] * @returns {import('estree').Expression} */ -export function serialize_set_binding(node, context, fallback) { +export function serialize_set_binding(node, context, fallback, options) { const { state, visit } = context; if ( @@ -242,7 +243,7 @@ export function serialize_set_binding(node, context, fallback) { const value = path.expression?.(b.id(tmp_id)); const assignment = b.assignment('=', path.node, value); original_assignments.push(assignment); - assignments.push(serialize_set_binding(assignment, context, () => assignment)); + assignments.push(serialize_set_binding(assignment, context, () => assignment, options)); } if (assignments.every((assignment, i) => assignment === original_assignments[i])) { @@ -288,7 +289,11 @@ export function serialize_set_binding(node, context, fallback) { if (private_state !== undefined) { if (state.in_constructor) { // See if we should wrap value in $.proxy - if (context.state.analysis.runes && should_proxy_or_freeze(value)) { + if ( + context.state.analysis.runes && + !options?.skip_proxy_and_freeze && + should_proxy_or_freeze(value) + ) { const assignment = fallback(); if (assignment.type === 'AssignmentExpression') { assignment.right = @@ -302,7 +307,9 @@ export function serialize_set_binding(node, context, fallback) { return b.call( '$.set', left, - context.state.analysis.runes && should_proxy_or_freeze(value) + context.state.analysis.runes && + !options?.skip_proxy_and_freeze && + should_proxy_or_freeze(value) ? private_state.kind === 'frozen_state' ? b.call('$.freeze', value) : b.call('$.proxy', value) @@ -321,6 +328,7 @@ export function serialize_set_binding(node, context, fallback) { if ( context.state.analysis.runes && public_state !== undefined && + !options?.skip_proxy_and_freeze && should_proxy_or_freeze(value) ) { const assignment = fallback(); @@ -387,7 +395,9 @@ export function serialize_set_binding(node, context, fallback) { return b.call( '$.set', b.id(left_name), - context.state.analysis.runes && should_proxy_or_freeze(value) + context.state.analysis.runes && + !options?.skip_proxy_and_freeze && + should_proxy_or_freeze(value) ? b.call('$.proxy', value) : value ); @@ -395,7 +405,9 @@ export function serialize_set_binding(node, context, fallback) { return b.call( '$.set', b.id(left_name), - context.state.analysis.runes && should_proxy_or_freeze(value) + context.state.analysis.runes && + !options?.skip_proxy_and_freeze && + should_proxy_or_freeze(value) ? b.call('$.freeze', value) : value ); @@ -624,6 +636,5 @@ export function should_proxy_or_freeze(node) { ) { return false; } - return true; } 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 b6708bc851..60c1d2fac2 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 @@ -2604,7 +2604,10 @@ export const template_visitors = { serialize_set_binding( assignment, context, - () => /** @type {import('estree').Expression} */ (context.visit(assignment)) + () => /** @type {import('estree').Expression} */ (context.visit(assignment)), + { + skip_proxy_and_freeze: true + } ) ); diff --git a/packages/svelte/tests/snapshot/samples/state-proxy-literal/_expected/client/index.svelte.js b/packages/svelte/tests/snapshot/samples/state-proxy-literal/_expected/client/index.svelte.js index f1a5a0ee42..321496e20b 100644 --- a/packages/svelte/tests/snapshot/samples/state-proxy-literal/_expected/client/index.svelte.js +++ b/packages/svelte/tests/snapshot/samples/state-proxy-literal/_expected/client/index.svelte.js @@ -29,8 +29,8 @@ export default function State_proxy_literal($$anchor, $$props) { var button = $.sibling($.sibling(input)); - $.bind_value(node, () => $.get(str), ($$value) => $.set(str, $.proxy($$value))); - $.bind_value(input, () => $.get(tpl), ($$value) => $.set(tpl, $.proxy($$value))); + $.bind_value(node, () => $.get(str), ($$value) => $.set(str, $$value)); + $.bind_value(input, () => $.get(tpl), ($$value) => $.set(tpl, $$value)); button.__click = [reset, str, tpl]; $.close_frag($$anchor, fragment); $.pop();