--- /dev/null
+---
+'@sveltejs/kit': patch
+---
+
+fix: wait an extra microtask in dev before calling `$$_init_$$`
remotes.push(remote);
if (opts?.ssr) {
+ // we need to add an `await Promise.resolve()` because if the user imports this function
+ // on the client AND in a load function when loading the client module we will trigger
+ // an ssrLoadModule during dev. During a link preload, the module can be mistakenly
+ // loaded and transformed twice and the first time all its exports would be undefined
+ // triggering a dev server error. By adding a microtask we ensure that the module is fully loaded
+
// Extra newlines to prevent syntax errors around missing semicolons or comments
code +=
'\n\n' +
import * as $$_self_$$ from './${path.basename(id)}';
import { init_remote_functions as $$_init_$$ } from '@sveltejs/kit/internal';
+ ${dev_server ? 'await Promise.resolve()' : ''}
+
$$_init_$$($$_self_$$, ${s(file)}, ${s(remote.hash)});
for (const [name, fn] of Object.entries($$_self_$$)) {
--- /dev/null
+<script lang="ts">
+ import { resolve } from '$app/paths';
+</script>
+
+<a href={resolve('/remote/dev/preload')} data-sveltekit-preload-data="hover">preload</a>
--- /dev/null
+import { example } from './example.remote';
+
+export const load = async () => {
+ return {
+ example: await example('bar')
+ };
+};
--- /dev/null
+<script>
+ import { example } from './example.remote';
+
+ export let data;
+</script>
+
+<p>{data.example}</p>
+<button onclick={async () => (data.example = await example('baz'))}>Refresh</button>
--- /dev/null
+import { query } from '$app/server';
+import { schema } from './schema';
+
+export const example = query(schema, async (param) => {
+ await new Promise((resolve) => setTimeout(resolve, 1000));
+ return 'foo' + param;
+});
--- /dev/null
+import * as v from 'valibot';
+
+export const schema = v.string();
});
});
-// have to run in serial because commands mutate in-memory data on the server
test.describe('remote functions', () => {
+ test('preloading data works when the page component and server load both import a remote function', async ({
+ page
+ }) => {
+ test.skip(!process.env.DEV, 'remote functions are only analysed in dev mode');
+ await page.goto('/remote/dev');
+ await page.locator('a[href="/remote/dev/preload"]').hover();
+ await Promise.all([
+ page.waitForTimeout(100), // wait for preloading to start
+ page.waitForLoadState('networkidle') // wait for preloading to finish
+ ]);
+ await page.click('a[href="/remote/dev/preload"]');
+ await expect(page.locator('p')).toHaveText('foobar');
+ });
+});
+
+// have to run in serial because commands mutate in-memory data on the server
+test.describe('remote function mutations', () => {
test.describe.configure({ mode: 'default' });
test.afterEach(async ({ page }) => {
if (page.url().endsWith('/remote')) {