-
-
Notifications
You must be signed in to change notification settings - Fork 4.6k
fix: use state
instead of source
in reactive classes
#16239
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
base: main
Are you sure you want to change the base?
Conversation
|
|
New idea I'll try to implement: store the active reaction in the constructor of the Map/Set and use a |
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.
Great work!
@@ -56,13 +56,17 @@ export class SvelteMap extends Map { | |||
#sources = new Map(); | |||
#version = state(0); | |||
#size = state(0); | |||
/**@type {Reaction | null} */ | |||
#initial_reaction = null; |
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.
Wondering if there are cases when map still lives, while the reaction could have been GCed and this would prevent it?
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.
Yeah I was wondering about that too...technically it shouldn't be the case because either there's no active reaction (it's outside of a derived/effect) or it's inside it but this means that when the derived/effect is no longer used the function should be GCd and everything inside it too...but I need to do a better check
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.
Maybe this can become initial_reaction = WeakSet(active_reaction)
and we can check with this.initial_reaction.has(active_reaction)
?
Also tried installing this version locally, enabling runes mode forcefully and clicking through the interface. Looks like not hitting |
Closes #16237
So the problem with using
source
is that:$effect
/$derived
that reads asource
created in itself will also depend on it...since normally state created in a reaction doesn't depend on itself this is counter intuitiveThis is a bit problematic in some cases because we create the sources lazily...in the case of
Map
for example we don't create asource
unless youget
orhas
orset
that first. However this means that if you create a newMap
in a derived ask if ithas
something, then you try to write to it in the same derived the newly createdsource
throws the error.For
set
it was as simple as changing source tostate
...however withget
andhas
it's a bit different: the effect needs to have a dependency on thesource
sostate
is out of question but then you don't want writes to it to throw. For that my solution was to add the source to thereaction_values
after theget
(only if the sources was newly created). For#read_all
it was a bit more complex and i had to create aWeakSet
for the newly created signals (not sure about memory/performance impact of this tho).I also changed the
source
's tostate
's inTweened
andSpring
since that also could've been problematic in cases like thissource
is also used insidecreateSubscriber
and I think it could have a problem there too but i need to check to be sure.It's also used inside
await
,each
and other blocks that "create" a value but i think for that it's probably fine.As I've said in the issue I'm not satisfied with this solution since it feels a bit hack-ish to add the dependency and still allow the user to write to it.
I also need to add a bunch of tests for this but wanted to give the code to @gyzerok
Before submitting the PR, please make sure you do the following
feat:
,fix:
,chore:
, ordocs:
.packages/svelte/src
, add a changeset (npx changeset
).Tests and linting
pnpm test
and lint the project withpnpm lint