Skip to content

Commit 890399b

Browse files
Copilotdummdidumm
andcommitted
Fix: Don't wrap await inside @const async functions with save
The issue was that `is_reactive_expression` was returning true for all awaits inside @const tags because `in_derived` was set to true. This caused awaits inside async functions assigned to @const to be incorrectly pickled with $.save(), breaking reactivity. The fix checks if there's a function in the path between the await and any reactive context. If there's a reactive rune call ($derived, $effect, etc.) between the function and the await, it's still considered reactive. Otherwise, it's not. This preserves the correct behavior for $derived with await inside async functions while fixing the @const async function case. Co-authored-by: dummdidumm <[email protected]>
1 parent c996279 commit 890399b

File tree

1 file changed

+22
-5
lines changed

1 file changed

+22
-5
lines changed

packages/svelte/src/compiler/phases/2-analyze/visitors/AwaitExpression.js

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,6 @@ export function AwaitExpression(node, context) {
5353
* @param {boolean} in_derived
5454
*/
5555
export function is_reactive_expression(path, in_derived) {
56-
if (in_derived) {
57-
return true;
58-
}
59-
6056
let i = path.length;
6157

6258
while (i--) {
@@ -67,6 +63,27 @@ export function is_reactive_expression(path, in_derived) {
6763
parent.type === 'FunctionExpression' ||
6864
parent.type === 'FunctionDeclaration'
6965
) {
66+
// Check if there's a reactive rune call (like $derived) between this function and the await
67+
for (let j = i + 1; j < path.length; j++) {
68+
const node = path[j];
69+
// @ts-expect-error
70+
if (node.metadata) {
71+
// There's a reactive expression between the function and the await
72+
return true;
73+
}
74+
// Also check for $derived, $effect, etc. calls
75+
if (
76+
node.type === 'CallExpression' &&
77+
node.callee?.type === 'Identifier' &&
78+
(node.callee.name === '$derived' ||
79+
node.callee.name === '$effect' ||
80+
node.callee.name === '$inspect')
81+
) {
82+
// This is a reactive rune call
83+
return true;
84+
}
85+
}
86+
// No reactive expression found between function and await
7087
return false;
7188
}
7289

@@ -76,7 +93,7 @@ export function is_reactive_expression(path, in_derived) {
7693
}
7794
}
7895

79-
return false;
96+
return in_derived;
8097
}
8198

8299
/**

0 commit comments

Comments
 (0)