diff --git a/.changeset/sharp-rings-march.md b/.changeset/sharp-rings-march.md new file mode 100644 index 0000000000..1fb3ec0796 --- /dev/null +++ b/.changeset/sharp-rings-march.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +feat: allow `$state` in return statements diff --git a/packages/svelte/src/compiler/phases/2-analyze/visitors/CallExpression.js b/packages/svelte/src/compiler/phases/2-analyze/visitors/CallExpression.js index 6ef323725b..9f713c5d06 100644 --- a/packages/svelte/src/compiler/phases/2-analyze/visitors/CallExpression.js +++ b/packages/svelte/src/compiler/phases/2-analyze/visitors/CallExpression.js @@ -104,6 +104,15 @@ export function CallExpression(node, context) { } case '$state': + if ( + (!(parent.type === 'VariableDeclarator' || parent.type === 'ReturnStatement') || + get_parent(context.path, -3).type === 'ConstTag') && + !(parent.type === 'PropertyDefinition' && !parent.static && !parent.computed) + ) { + e.state_invalid_placement(node, rune); + } + + break; case '$state.raw': case '$derived': case '$derived.by': diff --git a/packages/svelte/src/compiler/phases/3-transform/client/visitors/CallExpression.js b/packages/svelte/src/compiler/phases/3-transform/client/visitors/CallExpression.js index fda43ad791..1cd35e2ec0 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/visitors/CallExpression.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/visitors/CallExpression.js @@ -4,6 +4,7 @@ import { dev, is_ignored } from '../../../../state.js'; import * as b from '../../../../utils/builders.js'; import { get_rune } from '../../../scope.js'; import { transform_inspect_rune } from '../../utils.js'; +import { should_proxy } from '../utils.js'; /** * @param {CallExpression} node @@ -33,6 +34,20 @@ export function CallExpression(node, context) { case '$inspect': case '$inspect().with': return transform_inspect_rune(node, context); + case '$state': + if (context.path.at(-1)?.type === 'ReturnStatement') { + if ( + node.arguments[0] && + should_proxy( + /** @type {Expression} */ (context.visit(node.arguments[0])), + context.state.scope + ) + ) { + return b.call('$.proxy', node.arguments[0]); + } else { + return node.arguments[0] ?? b.void0; + } + } } if (