Skip to content

Commit

Permalink
fix: improve member expression mutation logic (#9625)
Browse files Browse the repository at this point in the history
* fix: improve member expression mutation logic

* cleanup

* Update .changeset/moody-frogs-exist.md

---------

Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
  • Loading branch information
trueadm and dummdidumm committed Nov 23, 2023
1 parent 7825570 commit ef68b66
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 12 deletions.
5 changes: 5 additions & 0 deletions .changeset/moody-frogs-exist.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'svelte': patch
---

fix: improve member expression mutation logic
Original file line number Diff line number Diff line change
Expand Up @@ -2170,17 +2170,15 @@ export const template_visitors = {

/**
* @param {import('estree').Pattern} expression_for_id
* @param {import('estree').Expression} expression_for_other
* @returns {import('#compiler').Binding['mutation']}
*/
const create_mutation = (expression_for_id, expression_for_other) => {
const create_mutation = (expression_for_id) => {
return (assignment, context) => {
if (assignment.left.type !== 'Identifier' && assignment.left.type !== 'MemberExpression') {
// serialize_set_binding turns other patterns into IIFEs and separates the assignments
// into separate expressions, at which point this is called again with an identifier or member expression
return serialize_set_binding(assignment, context, () => assignment);
}

const left = object(assignment.left);
const value = get_assignment_value(assignment, context);
const invalidate = b.call(
Expand All @@ -2193,11 +2191,7 @@ export const template_visitors = {
return context.state.analysis.runes ? assign : b.sequence([assign, invalidate]);
} else {
const original_left = /** @type {import('estree').MemberExpression} */ (assignment.left);
const left = b.member(
expression_for_other,
context.visit(original_left).property,
original_left.computed
);
const left = context.visit(original_left);
const assign = b.assignment(assignment.operator, left, value);
return context.state.analysis.runes ? assign : b.sequence([assign, invalidate]);
}
Expand All @@ -2223,8 +2217,7 @@ export const template_visitors = {
each_node_meta.array_name ? b.call(each_node_meta.array_name) : collection,
index,
true
),
binding.expression
)
);
} else {
const unwrapped = binding.expression;
Expand Down Expand Up @@ -2252,8 +2245,7 @@ export const template_visitors = {

binding.expression = b.call(name);
binding.mutation = create_mutation(
/** @type {import('estree').Pattern} */ (path.update_expression(unwrapped)),
binding.expression
/** @type {import('estree').Pattern} */ (path.update_expression(unwrapped))
);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { flushSync } from 'svelte';
import { test } from '../../test';

export default test({
html: `<button>person.name.first = "dave"</button><h3>JSON output</h3><div>[{"name":{"first":"rob"}}]</div>`,

async test({ assert, target }) {
const button = target.querySelector('button');

flushSync(() => {
button?.click();
});

assert.htmlEqual(
target.innerHTML,
`<button>person.name.first = "dave"</button><h3>JSON output</h3><div>[{"name":{"first":"dave"}}]</div>`
);
}
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<script>
let people = $state([{name:{first:'rob'}}]);
</script>

{#each people as person}
<button on:click={()=>{
person.name.first = "dave";
people = people;
}}>person.name.first = "dave"</button>
{/each}

<h3>JSON output</h3>
{#each people as person}
<div>{JSON.stringify(people)}</div>
{/each}

1 comment on commit ef68b66

@vercel
Copy link

@vercel vercel bot commented on ef68b66 Nov 23, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

svelte-5-preview – ./sites/svelte-5-preview

svelte-octane.vercel.app
svelte-5-preview-svelte.vercel.app
svelte-5-preview.vercel.app
svelte-5-preview-git-main-svelte.vercel.app

Please sign in to comment.