-
-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
fix: make untrack behave correctly in relation to mutations #14784
base: main
Are you sure you want to change the base?
Conversation
🦋 Changeset detectedLatest commit: 89780e3 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
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 |
preview: https://svelte-dev-git-preview-svelte-14784-svelte.vercel.app/ this is an automated message |
|
@trueadm just for clarity:
|
@Leonidaz
Yep
Yes. |
@trueadm since we are using We are heavily using read-through cache idea, which in simplified version looks as follows.
From your description I assume we need to swap |
@@ -484,6 +484,12 @@ declare module 'svelte' { | |||
* ``` | |||
* */ | |||
export function untrack<T>(fn: () => T): T; | |||
/** | |||
* When used inside a [`$derived`](https://svelte.dev/docs/svelte/$derived), | |||
* any state updates to state is allowed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's called unsafe
and this explanation leaves me wondering how to ensure that my usages of it are safe in practice. Maybe the idea is that if you use it, you should already understand it. However maybe there could be a bit lengthier explanation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There'd probably be a more detailed description in the online documentation, perhaps in the $derived
page.
this shouldn't affect this unless this instance was called from the template effect or inside a derived. basically, here you don't want getLazy to subscribe to the signal which is the correct usage of untrack. The bug with untrack was that it allowed mutations inside or if called from derived or template effect - this is a super discouraged practice but some people were using it as hack, which now they'd have to also use |
@Leonidaz I've updated original example. In our case |
created a repl with this pr I don't see it being affected as there'd be a mutation warning / error from svelte. I'm not sure how exactly this works since technically it is called from the template effect. maybe because of await or how SvelteMap works. But basically, if you apply this pr to your code base, you may start getting mutation errors, if you don't, then you're ok. |
@gyzerok I think you should be able to safely switch to |
The repl was not in @gyzerok so with the runes mode 🤦♂️ indeed you get the unsafe mutation warning So, yeah, if this lands, you're going to have to use Here's a repl with using I think since you're directly calling Despite having to make some adjustments, I'm glad that that this functionality would be split up as the purpose untrack is ambiguous otherwise. |
@trueadm I've tried to install version from this PR and swapped |
@gyzerok Looks like you'll need an |
For a while
untrack
has been a bit wonky/buggy. It's designed to prevent reads of reactive signals being tracked, but due to its buggy implementation it also causes three quite nasty unintended problems that this PR fixes:active_reaction
tonull
, causing all mayhem in doing so when it comes to connecting things to their parentsunsafe
ensures graph consistency is kept for effects, something that was previously not true with usinguntrack
this wayThis PR fixes that, by making sure
untrack
only stops reactive signals from being tracked. However, there might be genuine cases where someone knows that they can mutate state inside a derived or template and know it can occur, even if it's somewhat unsafe.So I've also exposed an
unsafe
API fromsvelte
that allows these use-cases. This also allows us to fix a few tests that made use of the previous behaviour ofuntrack
and also the store logic that needs this too (although that is internal).unsafe
could also be useful to unblock those who incorrectly have been misusinguntrack
today to emulate the same behaviour. Furthermore,unsafe
actually resolves the reactive graph for effects, by ensuring the re-schedule and correctly sync up and ensure UI consistency – somethinguntrack
never did before. This PR usesunsafe
to fix all of that.