From 7e0a81d102180e72ad12b22e9c061bd5ea955b11 Mon Sep 17 00:00:00 2001 From: ComputerGuy <63362464+Ocean-OS@users.noreply.github.com> Date: Sat, 31 May 2025 15:52:18 -0700 Subject: [PATCH 1/3] fix: correctly transform reassignments to class fields in SSR mode --- .changeset/rude-drinks-relate.md | 5 +++++ .../3-transform/server/visitors/AssignmentExpression.js | 7 ++++++- 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 .changeset/rude-drinks-relate.md diff --git a/.changeset/rude-drinks-relate.md b/.changeset/rude-drinks-relate.md new file mode 100644 index 000000000000..d0eab6ba114c --- /dev/null +++ b/.changeset/rude-drinks-relate.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: correctly transform reassignments to class fields in SSR mode diff --git a/packages/svelte/src/compiler/phases/3-transform/server/visitors/AssignmentExpression.js b/packages/svelte/src/compiler/phases/3-transform/server/visitors/AssignmentExpression.js index 466682fb82b8..7a054fcbb414 100644 --- a/packages/svelte/src/compiler/phases/3-transform/server/visitors/AssignmentExpression.js +++ b/packages/svelte/src/compiler/phases/3-transform/server/visitors/AssignmentExpression.js @@ -24,7 +24,12 @@ export function AssignmentExpression(node, context) { * @returns {Expression | null} */ function build_assignment(operator, left, right, context) { - if (context.state.analysis.runes && left.type === 'MemberExpression') { + if ( + context.state.analysis.runes && + left.type === 'MemberExpression' && + left.object.type === 'ThisExpression' && + !left.computed + ) { const name = get_name(left.property); const field = name && context.state.state_fields.get(name); From 152fe5019b8414f2862df27b65bd6ef1f1b0d3a2 Mon Sep 17 00:00:00 2001 From: ComputerGuy <63362464+Ocean-OS@users.noreply.github.com> Date: Sat, 31 May 2025 16:10:47 -0700 Subject: [PATCH 2/3] add test, fix more stuff --- .../server/visitors/AssignmentExpression.js | 5 ---- .../_expected/client/index.svelte.js | 23 ++++++++++++++++++- .../_expected/server/index.svelte.js | 23 ++++++++++++++++++- .../index.svelte | 7 ++++-- 4 files changed, 49 insertions(+), 9 deletions(-) diff --git a/packages/svelte/src/compiler/phases/3-transform/server/visitors/AssignmentExpression.js b/packages/svelte/src/compiler/phases/3-transform/server/visitors/AssignmentExpression.js index 7a054fcbb414..fc660f89c951 100644 --- a/packages/svelte/src/compiler/phases/3-transform/server/visitors/AssignmentExpression.js +++ b/packages/svelte/src/compiler/phases/3-transform/server/visitors/AssignmentExpression.js @@ -49,11 +49,6 @@ function build_assignment(operator, left, right, context) { /** @type {Expression} */ (context.visit(right)) ); } - } else if (field && (field.type === '$derived' || field.type === '$derived.by')) { - let value = /** @type {Expression} */ ( - context.visit(build_assignment_value(operator, left, right)) - ); - return b.call(b.member(b.this, name), value); } } diff --git a/packages/svelte/tests/snapshot/samples/class-state-field-constructor-assignment/_expected/client/index.svelte.js b/packages/svelte/tests/snapshot/samples/class-state-field-constructor-assignment/_expected/client/index.svelte.js index 21339741761f..c9725d6718dd 100644 --- a/packages/svelte/tests/snapshot/samples/class-state-field-constructor-assignment/_expected/client/index.svelte.js +++ b/packages/svelte/tests/snapshot/samples/class-state-field-constructor-assignment/_expected/client/index.svelte.js @@ -5,7 +5,7 @@ export default function Class_state_field_constructor_assignment($$anchor, $$pro $.push($$props, true); class Foo { - #a = $.state(); + #a = $.state(0); get a() { return $.get(this.#a); @@ -16,10 +16,31 @@ export default function Class_state_field_constructor_assignment($$anchor, $$pro } #b = $.state(); + #foo = $.derived(() => ({ bar: this.a * 2 })); + + get foo() { + return $.get(this.#foo); + } + + set foo(value) { + $.set(this.#foo, value); + } + + #bar = $.derived(() => ({ baz: this.foo })); + + get bar() { + return $.get(this.#bar); + } + + set bar(value) { + $.set(this.#bar, value); + } constructor() { this.a = 1; $.set(this.#b, 2); + this.foo.bar = 3; + this.bar = 4; } } diff --git a/packages/svelte/tests/snapshot/samples/class-state-field-constructor-assignment/_expected/server/index.svelte.js b/packages/svelte/tests/snapshot/samples/class-state-field-constructor-assignment/_expected/server/index.svelte.js index 2a115a498373..abfc264fea0a 100644 --- a/packages/svelte/tests/snapshot/samples/class-state-field-constructor-assignment/_expected/server/index.svelte.js +++ b/packages/svelte/tests/snapshot/samples/class-state-field-constructor-assignment/_expected/server/index.svelte.js @@ -4,12 +4,33 @@ export default function Class_state_field_constructor_assignment($$payload, $$pr $.push(); class Foo { - a; + a = 0; #b; + #foo = $.derived(() => ({ bar: this.a * 2 })); + + get foo() { + return this.#foo(); + } + + set foo($$value) { + return this.#foo($$value); + } + + #bar = $.derived(() => ({ baz: this.foo })); + + get bar() { + return this.#bar(); + } + + set bar($$value) { + return this.#bar($$value); + } constructor() { this.a = 1; this.#b = 2; + this.foo.bar = 3; + this.bar = 4; } } diff --git a/packages/svelte/tests/snapshot/samples/class-state-field-constructor-assignment/index.svelte b/packages/svelte/tests/snapshot/samples/class-state-field-constructor-assignment/index.svelte index a3ff5917e77f..127cfd4d2a7d 100644 --- a/packages/svelte/tests/snapshot/samples/class-state-field-constructor-assignment/index.svelte +++ b/packages/svelte/tests/snapshot/samples/class-state-field-constructor-assignment/index.svelte @@ -1,11 +1,14 @@ From 513e4569f24776c8f0320955495c0497001618bd Mon Sep 17 00:00:00 2001 From: ComputerGuy <63362464+Ocean-OS@users.noreply.github.com> Date: Sat, 31 May 2025 16:25:05 -0700 Subject: [PATCH 3/3] fix --- .../3-transform/server/visitors/AssignmentExpression.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/packages/svelte/src/compiler/phases/3-transform/server/visitors/AssignmentExpression.js b/packages/svelte/src/compiler/phases/3-transform/server/visitors/AssignmentExpression.js index fc660f89c951..49a284d12bc9 100644 --- a/packages/svelte/src/compiler/phases/3-transform/server/visitors/AssignmentExpression.js +++ b/packages/svelte/src/compiler/phases/3-transform/server/visitors/AssignmentExpression.js @@ -49,6 +49,15 @@ function build_assignment(operator, left, right, context) { /** @type {Expression} */ (context.visit(right)) ); } + } else if ( + field && + (field.type === '$derived' || field.type === '$derived.by') && + left.property.type === 'PrivateIdentifier' + ) { + let value = /** @type {Expression} */ ( + context.visit(build_assignment_value(operator, left, right)) + ); + return b.call(b.member(b.this, name), value); } }