svelte
svelte copied to clipboard
Svelte 5: Runes not tracking async dependencies
Describe the bug
A value is only considered a dependency of a rune if it is called in the same event loop tick.
Reproduction
This won't re-evaluate when chatId changes. REPL
let derivedId = $derived(Promise.resolve().then(() => chatId))
but using $: it does work. REPL
$: derivedId = Promise.resolve().then(() => id)
workaround is to e.g. do
let derivedId = $derived.by(() => {
chatId;
return Promise.resolve().then(() => chatId);
});
My real life example is that Dexie's liveQuery stopped reacting to changes
let chatMessages = $derived(
liveQuery(() =>
localDB.chatMessage
.where({
chatId,
})
.toArray(),
),
);
Logs
No response
System Info
-
Severity
annoyance
This is to be expected. Runes are designed to read dependencies sync only – and given the browser has no native way to track async context (yet), this isn't possible to do otherwise.
This is to be expected. Runes are designed to read dependencies sync only – and given the browser has no native way to track async context (yet), this isn't possible to do otherwise.
Thanks, that's what I assumed, but couldn't find any documentation/issue related to it.
I guess the compiler could traverse the inside of e.g. $derived and find all the dependencies though 🤔
@valterkraemer What if you call a function from a random npm module? The compiler is limited in context.
@valterkraemer What if you call a function from a random npm module? The compiler is limited in context.
I was thinking just the variables used inside of the $derived block, not calls to code outside of it. But yeah, that's probably not a good idea.
Then this would work
let derivedId = $derived.by(() => {
return Promise.resolve().then(() => chatId);
});
But not this
function myFunc() {
return Promise.resolve().then(() => chatId);
}
let derivedId = $derived.by(myFunc);
@valterkraemer That would break far too many cases as we now use runtime reactivity rather than compile time reactivity.
Sorry to bother you guys, but what is the idiomatic way to call async methods in new Svelte 5 runes?