Skip to content

Commit b8fd326

Browse files
feat: async SSR (#16748)
* feat: First pass at payload * first crack * snapshots * checkpoint * fix: cloning * add test option * big dumb * today's hard work; few tests left to fix * improve * tests passing no wayyyyy yo * lots of progress, couple of failing tests around selects * meh * solve async tree stuff * fix select/option stuff * whoop, tests * simplify * feat: hoisting * fix: `$effect.pending` sends updates to incorrect boundary * changeset * stuff from upstream * feat: first hydrationgaa * remove docs * snapshots * silly fix * checkpoint * meh * ALKASJDFALSKDFJ the test passes * chore: Update a bunch of tests for hydration markers * chore: remove snippet and is_async * naming * better errors for sync-in-async * test improvements * idk man * merge local branches (#16757) * use fragment as async hoist boundary * remove async_hoist_boundary * only dewaterfall when necessary * unused * simplify/fix * de-waterfall awaits in separate elements * update snapshots * remove unnecessary wrapper * fix * fix * remove suspends_without_fallback --------- Co-authored-by: Rich Harris <rich.harris@vercel.com> * Update payload.js Co-authored-by: Rich Harris <rich.harris@vercel.com> * checkpoint * got the extra children to go away * just gonna go ahead and merge this as the review comments take up too much space * chore: remove hoisted_promises (#16766) * chore: remove hoisted_promises * WIP optimise promises * WIP * fix <slot> with await in prop * tweak * fix type error * Update packages/svelte/src/compiler/phases/3-transform/server/visitors/SvelteHead.js * chore: fix hydration treeshaking (#16767) * chore: fix hydration treeshaking * fix * remove await_outside_boundary error (#16762) * chore: remove unused analysis.boundary (#16763) * chore: simplify slots (#16765) * chore: simplify slots * unused * Apply suggestions from code review * chore: remove metadata.pending (#16764) * Update packages/svelte/src/compiler/phases/3-transform/server/visitors/SnippetBlock.js * put this back where it was, keep the diff small * Update packages/svelte/src/compiler/phases/types.d.ts Co-authored-by: Rich Harris <rich.harris@vercel.com> * chore: remove analysis.state.title (#16771) * chore: remove analysis.state.title * unused * chore: remove is_async (#16769) * chore: remove is_async * unused * Apply suggestions from code review Co-authored-by: Rich Harris <rich.harris@vercel.com> * cleanup * lint * clean up payload a bit * compiler work * run ssr on sync and async * prettier * inline capture * Update packages/svelte/src/compiler/phases/3-transform/server/visitors/EachBlock.js * chore: simplify build_template (#16780) * small tweak to aid greppability * chore: fix SSR context (#16781) * at least passing * cleanup * fix * remove push/pop from exports, not needed with payload * I think this is better but tbh not sure * async SSR * qualification * errors: * I have lost the plot * finally * ugh * tweak error codes to better align with existing conventions, such as they are * tweak messages * remove unused args * DRY out a bit * unused * unused * unused * simplify - we can enforce readonly at a type level * unused * simplify * avoid magical accessors * simplify algorithm * unused * unused * reduce indirection * TreeState -> SSRState * mark deprecated methods * grab this.local from parent directly * rename render -> fn per conventions (fn indicates 'arbitrary code') * reduce indirection * Revert "reduce indirection" This reverts commit 3ec461b. * tweak * okay works this time * no way chat, it works * fix context stuff * tweak * make it chainable * lint * clean up * lint * Update packages/svelte/src/internal/server/types.d.ts Co-authored-by: Rich Harris <rich.harris@vercel.com> * sunset html for async * types * we use 'deprecated' in other messages * oops --------- Co-authored-by: Rich Harris <rich.harris@vercel.com>
1 parent 8c982f6 commit b8fd326

File tree

181 files changed

+2638
-901
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

181 files changed

+2638
-901
lines changed

.changeset/forty-insects-cheat.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': minor
3+
---
4+
5+
feat: experimental async SSR

.prettierignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ packages/svelte/src/internal/client/warnings.js
1515
packages/svelte/src/internal/shared/errors.js
1616
packages/svelte/src/internal/shared/warnings.js
1717
packages/svelte/src/internal/server/errors.js
18+
packages/svelte/src/internal/server/warnings.js
1819
packages/svelte/tests/migrate/samples/*/output.svelte
1920
packages/svelte/tests/**/*.svelte
2021
packages/svelte/tests/**/_expected*

documentation/docs/98-reference/.generated/server-errors.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,19 @@
11
<!-- This file is generated by scripts/process-messages/index.js. Do not edit! -->
22

3+
### await_invalid
4+
5+
```
6+
Encountered asynchronous work while rendering synchronously.
7+
```
8+
9+
You (or the framework you're using) called [`render(...)`](svelte-server#render) with a component containing an `await` expression. Either `await` the result of `render` or wrap the `await` (or the component containing it) in a [`<svelte:boundary>`](svelte-boundary) with a `pending` snippet.
10+
11+
### html_deprecated
12+
13+
```
14+
The `html` property of server render results has been deprecated. Use `body` instead.
15+
```
16+
317
### lifecycle_function_unavailable
418

519
```
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<!-- This file is generated by scripts/process-messages/index.js. Do not edit! -->
2+
3+
### experimental_async_ssr
4+
5+
```
6+
Attempted to use asynchronous rendering without `experimental.async` enabled
7+
```
8+
9+
Set `experimental.async: true` in your compiler options (usually in `svelte.config.js`) to use async server rendering. This render ran synchronously.

documentation/docs/98-reference/.generated/shared-errors.md

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,5 @@
11
<!-- This file is generated by scripts/process-messages/index.js. Do not edit! -->
22

3-
### await_outside_boundary
4-
5-
```
6-
Cannot await outside a `<svelte:boundary>` with a `pending` snippet
7-
```
8-
9-
The `await` keyword can only appear in a `$derived(...)` or template expression, or at the top level of a component's `<script>` block, if it is inside a [`<svelte:boundary>`](/docs/svelte/svelte-boundary) that has a `pending` snippet:
10-
11-
```svelte
12-
<svelte:boundary>
13-
<p>{await getData()}</p>
14-
15-
{#snippet pending()}
16-
<p>loading...</p>
17-
{/snippet}
18-
</svelte:boundary>
19-
```
20-
21-
This restriction may be lifted in a future version of Svelte.
22-
233
### invalid_default_snippet
244

255
```

eslint.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ export default [
9494
'packages/svelte/src/internal/client/errors.js',
9595
'packages/svelte/src/internal/client/warnings.js',
9696
'packages/svelte/src/internal/shared/warnings.js',
97+
'packages/svelte/src/internal/server/warnings.js',
9798
'packages/svelte/compiler/index.js',
9899
// stuff we don't want to lint
99100
'benchmarking/**',
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
## await_invalid
2+
3+
> Encountered asynchronous work while rendering synchronously.
4+
5+
You (or the framework you're using) called [`render(...)`](svelte-server#render) with a component containing an `await` expression. Either `await` the result of `render` or wrap the `await` (or the component containing it) in a [`<svelte:boundary>`](svelte-boundary) with a `pending` snippet.
6+
7+
## html_deprecated
8+
9+
> The `html` property of server render results has been deprecated. Use `body` instead.
10+
11+
## lifecycle_function_unavailable
12+
13+
> `%name%(...)` is not available on the server
14+
15+
Certain methods such as `mount` cannot be invoked while running in a server context. Avoid calling them eagerly, i.e. not during render.

packages/svelte/messages/server-errors/lifecycle.md

Lines changed: 0 additions & 5 deletions
This file was deleted.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
## experimental_async_ssr
2+
3+
> Attempted to use asynchronous rendering without `experimental.async` enabled
4+
5+
Set `experimental.async: true` in your compiler options (usually in `svelte.config.js`) to use async server rendering. This render ran synchronously.

packages/svelte/messages/shared-errors/errors.md

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,3 @@
1-
## await_outside_boundary
2-
3-
> Cannot await outside a `<svelte:boundary>` with a `pending` snippet
4-
5-
The `await` keyword can only appear in a `$derived(...)` or template expression, or at the top level of a component's `<script>` block, if it is inside a [`<svelte:boundary>`](/docs/svelte/svelte-boundary) that has a `pending` snippet:
6-
7-
```svelte
8-
<svelte:boundary>
9-
<p>{await getData()}</p>
10-
11-
{#snippet pending()}
12-
<p>loading...</p>
13-
{/snippet}
14-
</svelte:boundary>
15-
```
16-
17-
This restriction may be lifted in a future version of Svelte.
18-
191
## invalid_default_snippet
202

213
> Cannot use `{@render children(...)}` if the parent component uses `let:` directives. Consider using a named snippet instead

0 commit comments

Comments
 (0)