- 
          
- 
                Notifications
    You must be signed in to change notification settings 
- Fork 2.1k
feat: async SSR #14447
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
          
     Merged
      
      
    
  
     Merged
                    feat: async SSR #14447
Changes from 19 commits
      Commits
    
    
            Show all changes
          
          
            21 commits
          
        
        Select commit
          Hold shift + click to select a range
      
      7aa184a
              
                chore: use catalog version for svelte dev dependency
              
              
                Rich-Harris 08157ea
              
                WIP async SSR
              
              
                Rich-Harris aa0c5c7
              
                bump
              
              
                Rich-Harris 425eeec
              
                partial fix
              
              
                Rich-Harris 2eb87ab
              
                bump
              
              
                Rich-Harris 2ac2fe0
              
                catalog version
              
              
                Rich-Harris 79c5470
              
                merge/fix
              
              
                Rich-Harris ca9003d
              
                WIP
              
              
                Rich-Harris 3056f54
              
                tidy up
              
              
                Rich-Harris d887138
              
                WIP
              
              
                Rich-Harris 7328f9a
              
                construct relative paths from event store
              
              
                Rich-Harris 8d348e2
              
                Merge branch 'main' into async-ssr
              
              
                Rich-Harris c311aee
              
                Merge branch 'main' into async-ssr
              
              
                Rich-Harris 81857f5
              
                wait really typescript?
              
              
                Rich-Harris 156536f
              
                update lockfile
              
              
                Rich-Harris a4d4e2b
              
                revert
              
              
                Rich-Harris 6649a61
              
                fix
              
              
                Rich-Harris cbb3acd
              
                changeset
              
              
                Rich-Harris 9790e40
              
                fix
              
              
                Rich-Harris 00d6b8a
              
                merge
              
              
                Rich-Harris 18051e1
              
                use pkg.imports
              
              
                Rich-Harris File filter
Filter by extension
Conversations
          Failed to load comments.   
        
        
          
      Loading
        
  Jump to
        
          Jump to file
        
      
      
          Failed to load files.   
        
        
          
      Loading
        
  Diff view
Diff view
There are no files selected for viewing
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| '@sveltejs/kit': minor | ||
| --- | ||
|  | ||
| feat: experimental async SSR | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              
              
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              
              
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              
              
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,57 @@ | ||
| /** @import { Asset, RouteId, Pathname, ResolvedPathname } from '$app/types' */ | ||
| /** @import { ResolveArgs } from './types.js' */ | ||
| import { base, assets } from './internal/client.js'; | ||
| import { resolve_route } from '../../../utils/routing.js'; | ||
|  | ||
| /** | ||
| * Resolve the URL of an asset in your `static` directory, by prefixing it with [`config.kit.paths.assets`](https://svelte.dev/docs/kit/configuration#paths) if configured, or otherwise by prefixing it with the base path. | ||
| * | ||
| * During server rendering, the base path is relative and depends on the page currently being rendered. | ||
| * | ||
| * @example | ||
| * ```svelte | ||
| * <script> | ||
| * import { asset } from '$app/paths'; | ||
| * </script> | ||
| * | ||
| * <img alt="a potato" src={asset('/potato.jpg')} /> | ||
| * ``` | ||
| * @since 2.26 | ||
| * | ||
| * @param {Asset} file | ||
| * @returns {string} | ||
| */ | ||
| export function asset(file) { | ||
| return (assets || base) + file; | ||
| } | ||
|  | ||
| /** | ||
| * Resolve a pathname by prefixing it with the base path, if any, or resolve a route ID by populating dynamic segments with parameters. | ||
| * | ||
| * During server rendering, the base path is relative and depends on the page currently being rendered. | ||
| * | ||
| * @example | ||
| * ```js | ||
| * import { resolve } from '$app/paths'; | ||
| * | ||
| * // using a pathname | ||
| * const resolved = resolve(`/blog/hello-world`); | ||
| * | ||
| * // using a route ID plus parameters | ||
| * const resolved = resolve('/blog/[slug]', { | ||
| * slug: 'hello-world' | ||
| * }); | ||
| * ``` | ||
| * @since 2.26 | ||
| * | ||
| * @template {RouteId | Pathname} T | ||
| * @param {ResolveArgs<T>} args | ||
| * @returns {ResolvedPathname} | ||
| */ | ||
| export function resolve(...args) { | ||
| // The type error is correct here, and if someone doesn't pass params when they should there's a runtime error, | ||
| // but we don't want to adjust the internal resolve_route function to accept `undefined`, hence the type cast. | ||
| return base + resolve_route(args[0], /** @type {Record<string, string>} */ (args[1])); | ||
| } | ||
|  | ||
| export { base, assets, resolve as resolveRoute }; | 
This file was deleted.
      
      Oops, something went wrong.
      
    
  
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| export const base = __SVELTEKIT_PAYLOAD__?.base ?? __SVELTEKIT_PATHS_BASE__; | ||
| export const assets = __SVELTEKIT_PAYLOAD__?.assets ?? base ?? __SVELTEKIT_PATHS_ASSETS__; | ||
| export const app_dir = __SVELTEKIT_APP_DIR__; | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| export let base = __SVELTEKIT_PATHS_BASE__; | ||
| export let assets = __SVELTEKIT_PATHS_ASSETS__ || base; | ||
| export const app_dir = __SVELTEKIT_APP_DIR__; | ||
| export const relative = __SVELTEKIT_PATHS_RELATIVE__; | ||
|  | ||
| const initial = { base, assets }; | ||
|  | ||
| /** | ||
| * @param {{ base: string, assets: string }} paths | ||
| */ | ||
| export function override(paths) { | ||
| base = paths.base; | ||
| assets = paths.assets; | ||
| } | ||
|  | ||
| export function reset() { | ||
| base = initial.base; | ||
| assets = initial.assets; | ||
| } | ||
|  | ||
| /** @param {string} path */ | ||
| export function set_assets(path) { | ||
| assets = initial.assets = path; | ||
| } | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| { | ||
|         
                  Rich-Harris marked this conversation as resolved.
              Outdated
          
            Show resolved
            Hide resolved | ||
| "type": "module", | ||
| "exports": { | ||
| ".": { | ||
| "browser": "./client.js", | ||
| "default": "./server.js" | ||
| }, | ||
| "./internal": { | ||
| "browser": "./internal/client.js", | ||
| "default": "./internal/server.js" | ||
| } | ||
| } | ||
| } | ||
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| import { RouteId, Pathname, ResolvedPathname } from '$app/types'; | ||
| import { ResolveArgs } from './types.js'; | ||
|  | ||
| export { resolve, asset } from './client.js'; | ||
|  | ||
| /** | ||
| * A string that matches [`config.kit.paths.base`](https://svelte.dev/docs/kit/configuration#paths). | ||
| * | ||
| * Example usage: `<a href="{base}/your-page">Link</a>` | ||
| * | ||
| * @deprecated Use [`resolve(...)`](https://svelte.dev/docs/kit/$app-paths#resolve) instead | ||
| */ | ||
| export let base: '' | `/${string}`; | ||
|  | ||
| /** | ||
| * An absolute path that matches [`config.kit.paths.assets`](https://svelte.dev/docs/kit/configuration#paths). | ||
| * | ||
| * > [!NOTE] If a value for `config.kit.paths.assets` is specified, it will be replaced with `'/_svelte_kit_assets'` during `vite dev` or `vite preview`, since the assets don't yet live at their eventual URL. | ||
| * | ||
| * @deprecated Use [`asset(...)`](https://svelte.dev/docs/kit/$app-paths#asset) instead | ||
| */ | ||
| export let assets: '' | `https://${string}` | `http://${string}` | '/_svelte_kit_assets'; | ||
|  | ||
| /** | ||
| * @deprecated Use [`resolve(...)`](https://svelte.dev/docs/kit/$app-paths#resolve) instead | ||
| */ | ||
| export function resolveRoute<T extends RouteId | Pathname>( | ||
| ...args: ResolveArgs<T> | ||
| ): ResolvedPathname; | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| import { base, assets, relative } from './internal/server.js'; | ||
| import { resolve_route } from '../../../utils/routing.js'; | ||
| import { get_request_store } from '../../../exports/internal/server.js'; // TODO not sure why we can't use `@sveltejs/kit/internal/server` here | ||
|  | ||
| /** @type {import('./client.js').asset} */ | ||
| export function asset(file) { | ||
| // @ts-expect-error we use the `resolve` mechanism, but with the 'wrong' input | ||
| return assets ? assets + file : resolve(file); | ||
| } | ||
|  | ||
| /** @type {import('./client.js').resolve} */ | ||
| export function resolve(id, params) { | ||
| const resolved = resolve_route(id, /** @type {Record<string, string>} */ (params)); | ||
|  | ||
| if (relative) { | ||
| const { event, state } = get_request_store(); | ||
|  | ||
| if (state.prerendering?.fallback) { | ||
| return resolved; | ||
| } | ||
|  | ||
| const segments = event.url.pathname.slice(base.length).split('/').slice(2); | ||
| const prefix = segments.map(() => '..').join('/') || '.'; | ||
|  | ||
| return prefix + resolved; | ||
| } | ||
|  | ||
| return resolved; | ||
| } | ||
|  | ||
| export { base, assets, resolve as resolveRoute }; | 
      
      Oops, something went wrong.
        
    
  
      
      Oops, something went wrong.
        
    
  
  Add this suggestion to a batch that can be applied as a single commit.
  This suggestion is invalid because no changes were made to the code.
  Suggestions cannot be applied while the pull request is closed.
  Suggestions cannot be applied while viewing a subset of changes.
  Only one suggestion per line can be applied in a batch.
  Add this suggestion to a batch that can be applied as a single commit.
  Applying suggestions on deleted lines is not supported.
  You must change the existing code in this line in order to create a valid suggestion.
  Outdated suggestions cannot be applied.
  This suggestion has been applied or marked resolved.
  Suggestions cannot be applied from pending reviews.
  Suggestions cannot be applied on multi-line comments.
  Suggestions cannot be applied while the pull request is queued to merge.
  Suggestion cannot be applied right now. Please check back later.
  
    
  
    
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this seems pretty close
$app/pathsand i'm getting flashbacks from libraries messing with svelte runtime internals.Do we have to prevent users from accessing internal somehow? maybe $internal would be one more step away from $app to make it clearer? Or is there a case for import maps here?
I do like the replacement of __sveltekit which struck me as odd before
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's the same as
svelte/internal— accessible, but disallowed by types. I don't believe it's possible to not make it publicly accessible to someone who really wants to shoot themselves in the foot, but I also don't think that's a real problem. It won't show up as an auto-import option, and if you do import*/internalin user code you'll be rewarded with a red squiggly