pull/17004/head
Rich Harris 1 week ago
parent 2664bb4162
commit cd4da0e77d

@ -135,6 +135,44 @@ If a `<svelte:boundary>` with a `pending` snippet is encountered during SSR, tha
> [!NOTE] In the future, we plan to add a streaming implementation that renders the content in the background.
## Forking
The [`fork(...)`](svelte#fork) API, added in 5.42, makes it possible to run `await` expressions that you _expect_ to happen in the near future. This is mainly intended for frameworks like SvelteKit to implement preloading when users signal an intent to navigate (for example).
```svelte
<script>
import { fork } from 'svelte';
import Menu from './Menu.svelte';
let open = $state(false);
/** @type {import('svelte').Fork | null} */
let pending = null;
</script>
<button
onpointerenter={() => {
pending ??= fork(() => {
open = true;
});
}}
onpointerleave={() => {
pending?.discard();
pending = null;
}}
onclick={() => {
pending?.commit();
open = true;
}}
>open menu</button>
{#if open}
<!-- any async work inside this component will start
as soon as the fork is created -->
<Menu onclose={() => open = false} />
{/if}
```
## Caveats
As an experimental feature, the details of how `await` is handled (and related APIs like `$effect.pending()`) are subject to breaking changes outside of a semver major release, though we intend to keep such changes to a bare minimum.

@ -352,4 +352,20 @@ export type MountOptions<Props extends Record<string, any> = Record<string, any>
props: Props;
});
/**
* Represents work that is happening off-screen, such as data being preloaded
* in anticipation of the user navigating
* @since 5.42
*/
export interface Fork {
/**
* Commit the fork. The promise will resolve once the state change has been applied
*/
commit(): Promise<void>;
/**
* Discard the fork
*/
discard(): void;
}
export * from './index-client.js';

@ -1,3 +1,4 @@
/** @import { Fork } from 'svelte' */
/** @import { Derived, Effect, Reaction, Source, Value } from '#client' */
import {
BLOCK_EFFECT,
@ -884,7 +885,8 @@ export function eager(fn) {
* user navigated elsewhere), it must be discarded to avoid leaking memory.
*
* @param {() => void} fn
* @returns {{ commit: () => void, discard: () => void }}
* @returns {Fork}
* @since 5.42
*/
export function fork(fn) {
if (!async_mode_flag) {

@ -463,7 +463,8 @@ declare module 'svelte' {
* When it becomes clear that a fork will _not_ be committed (e.g. because the
* user navigated elsewhere), it must be discarded to avoid leaking memory.
*
* */
* @since 5.42
*/
export function fork(fn: () => void): {
commit: () => void;
discard: () => void;

Loading…
Cancel
Save