Skip to content

Commit a0fbe2a

Browse files
fix: allow using multiple remote functions within one async derived (#15561)
Fixes #15247 --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
1 parent 9de9b2c commit a0fbe2a

5 files changed

Lines changed: 45 additions & 8 deletions

File tree

.changeset/famous-kiwis-buy.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@sveltejs/kit': patch
3+
---
4+
5+
fix: allow using multiple remote functions within one async derived

packages/kit/src/runtime/client/remote-functions/query.svelte.js

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -240,21 +240,27 @@ export class Query {
240240
const idx = this.#latest.indexOf(resolve);
241241
if (idx === -1) return;
242242

243-
this.#latest.splice(0, idx).forEach((r) => r(undefined));
244-
this.#ready = true;
245-
this.#loading = false;
246-
this.#raw = value;
247-
this.#error = undefined;
243+
// Untrack this to not trigger mutation validation errors which can occur if you do e.g. $derived({ a: await queryA(), b: await queryB() })
244+
untrack(() => {
245+
this.#latest.splice(0, idx).forEach((r) => r(undefined));
246+
this.#ready = true;
247+
this.#loading = false;
248+
this.#raw = value;
249+
this.#error = undefined;
250+
});
248251

249252
resolve(undefined);
250253
})
251254
.catch((e) => {
252255
const idx = this.#latest.indexOf(resolve);
253256
if (idx === -1) return;
254257

255-
this.#latest.splice(0, idx).forEach((r) => r(undefined));
256-
this.#error = e;
257-
this.#loading = false;
258+
untrack(() => {
259+
this.#latest.splice(0, idx).forEach((r) => r(undefined));
260+
this.#error = e;
261+
this.#loading = false;
262+
});
263+
258264
reject(e);
259265
});
260266

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<script>
2+
import { get_a, get_b } from './data.remote.js';
3+
4+
const values = $derived({
5+
a: await get_a(),
6+
b: await get_b()
7+
});
8+
</script>
9+
10+
<p id="result">{values.a + values.b}</p>
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { query } from '$app/server';
2+
3+
export const get_a = query(() => 1);
4+
5+
export const get_b = query(async () => {
6+
await new Promise((resolve) => setTimeout(resolve, 10));
7+
return 2;
8+
});

packages/kit/test/apps/async/test/test.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -633,6 +633,14 @@ test.describe('remote functions', () => {
633633
}
634634
});
635635

636+
test('awaiting multiple queries inside $derived does not fail mutation validation', async ({
637+
page
638+
}) => {
639+
await page.goto('/remote/query-derived-awaits');
640+
641+
await expect(page.locator('#result')).toHaveText('3');
642+
});
643+
636644
test('.as(type, value) renders correct values', async ({ page }) => {
637645
await page.goto('/remote/form/as-value');
638646

0 commit comments

Comments
 (0)