Skip to content

fix: ensure custom element attribute/prop changes are in their own context #14016

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Oct 30, 2024

Conversation

trueadm
Copy link
Contributor

@trueadm trueadm commented Oct 29, 2024

Fixes #13848.

When we set custom element attributes/props, we should be doing so without the current effect/reaction active. Otherwise, the custom element lifecycle might attach effects/dependencies to the wrong reaction and all manner of things can incorrectly occur. I tried to create a test for this using our Playwright testing but I couldn't get it to load up multiple custom elements so I gave up.

Copy link

changeset-bot bot commented Oct 29, 2024

🦋 Changeset detected

Latest commit: 127d831

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
svelte Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Copy link

pkg-pr-new bot commented Oct 29, 2024

pnpm add https://pkg.pr.new/svelte@14016

commit: 999f805

@dummdidumm
Copy link
Member

Can you give an example of a life cycle method being invoked in a wrong way as a result of a prop change? The related bug only lists the mutation error, which isn't exactly a life cycle method to me.

@trueadm
Copy link
Contributor Author

trueadm commented Oct 30, 2024

@dummdidumm It's the fact that calling these properties on a custom element invokes code that is not in the runtime's context. So if that method or logic reads state or creates an effect it should be treated as needing it's own context, like we do for events.

@dummdidumm
Copy link
Member

Can you give a concrete example, ideally one that isn't related to the mutation error? Ideally a code example (just dump a REPL link; custom elements don't work in there but I can copy-paste it out of there to run locally) I can then try to add it to the test suite.

@trueadm
Copy link
Contributor Author

trueadm commented Oct 30, 2024

Sure my-foo.svelte.js:

class MyElem extends HTMLElement {
  static observedAttributes = ["foo"];
  
  attributeChangedCallback() {
    console.log($effect.tracking())
  }
}
  
customElements.define("my-foo", MyElem);

Foo.svelte:

<script>
  let foo = $state('');
</script>

<button onclick={() => foo = '!!!'}>change</button>

<my-foo foo={foo}></my-foo>

@dummdidumm
Copy link
Member

(trying to add a test, and trying to see if this is due to flushSync and if yes whether we should fix it somewhere in there instead)

@trueadm
Copy link
Contributor Author

trueadm commented Oct 30, 2024

attributeChangedCallback fires sync, that's the issue here. It's like the Chrome blur bug all over again.

@trueadm
Copy link
Contributor Author

trueadm commented Oct 30, 2024

Thanks for the test @dummdidumm

@dummdidumm dummdidumm merged commit cdec39a into main Oct 30, 2024
10 checks passed
@dummdidumm dummdidumm deleted the custom-element-reaction branch October 30, 2024 21:07
@github-actions github-actions bot mentioned this pull request Oct 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Uncaught Svelte error state_unsafe_mutation with a $state boolean variable
2 participants