Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 2 additions & 9 deletions packages/kit/src/runtime/server/data/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,17 @@ import { handle_error_and_jsonify } from '../errors.js';
import { normalize_path } from '../../../utils/url.js';
import { stream_text } from '../../utils.js';
import { with_version_header } from '../utils.js';
import { manifest } from '../internal.js';

/**
* @param {import('@sveltejs/kit').RequestEvent} event
* @param {import('types').RequestState} state
* @param {{ page: Pick<import('types').PageNodeIndexes, 'layouts' | 'leaf'> | null }} route
* @param {import('types').SSRManifest} manifest
* @param {boolean[] | undefined} invalidated_data_nodes
* @param {import('types').TrailingSlash} trailing_slash
* @returns {Promise<Response>}
*/
export async function render_data(
event,
state,
route,
manifest,
invalidated_data_nodes,
trailing_slash
) {
export async function render_data(event, state, route, invalidated_data_nodes, trailing_slash) {
if (!route.page) {
// requesting /__data.json should fail for a +server.js
return with_version_header(new Response(undefined, { status: 404 }));
Expand Down
16 changes: 7 additions & 9 deletions packages/kit/src/runtime/server/fetch.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,20 @@ import { parseSetCookie } from 'cookie';
import { noop } from '../../utils/functions.js';
import { respond } from './respond.js';
import * as paths from '#app/paths';
import { hooks, read_implementation } from './internal.js';
import { hooks, manifest, read_implementation } from './internal.js';
import { has_prerendered_path } from './utils.js';
import { fork_state_for_subrequest } from './state.js';

/**
* @param {{
* event: import('@sveltejs/kit').RequestEvent;
* manifest: import('types').SSRManifest;
* state: import('types').RequestState;
* get_cookie_header: (url: URL, header: string | null) => string;
* set_internal: (name: string, value: string, opts: import('./page/types.js').Cookie['options']) => void;
* }} opts
* @returns {typeof fetch}
*/
export function create_fetch({ event, manifest, state, get_cookie_header, set_internal }) {
export function create_fetch({ event, state, get_cookie_header, set_internal }) {
/**
* @type {typeof fetch}
*/
Expand Down Expand Up @@ -117,7 +116,7 @@ export function create_fetch({ event, manifest, state, get_cookie_header, set_in
return await fetch(request);
}

if (has_prerendered_path(manifest, decoded)) {
if (has_prerendered_path(decoded)) {
// The path of something prerendered could match a different route
// that is still in the manifest, leading to the wrong route being loaded.
// We therefore bail early here. The prerendered logic is different for
Expand Down Expand Up @@ -147,7 +146,7 @@ export function create_fetch({ event, manifest, state, get_cookie_header, set_in
request.headers.set('accept-language', accept_language);
}

const response = await internal_fetch(request, manifest, state);
const response = await internal_fetch(request, state);

for (const str of response.headers.getSetCookie()) {
const { name, value, ...cookie_options } = parseSetCookie(str, { decode: (v) => v });
Expand Down Expand Up @@ -193,19 +192,18 @@ function normalize_fetch_input(info, init, url) {

/**
* @param {Request} request
* @param {import('types').SSRManifest} manifest
* @param {import('types').RequestState} state
* @returns {Promise<Response>}
*/
async function internal_fetch(request, manifest, state) {
async function internal_fetch(request, state) {
if (request.signal?.aborted) {
throw new DOMException('The operation was aborted.', 'AbortError');
}

const subrequest_state = fork_state_for_subrequest(state);

if (!request.signal) {
return await respond(request, manifest, subrequest_state);
return await respond(request, subrequest_state);
}

let remove_abort_listener = noop;
Expand All @@ -218,7 +216,7 @@ async function internal_fetch(request, manifest, state) {
remove_abort_listener = () => request.signal.removeEventListener('abort', on_abort);
});

return Promise.race([respond(request, manifest, subrequest_state), abort_promise]).finally(
return Promise.race([respond(request, subrequest_state), abort_promise]).finally(
remove_abort_listener
);
}
7 changes: 1 addition & 6 deletions packages/kit/src/runtime/server/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,8 @@ if (DEV) {
}

export class Server {
/** @type {import('types').SSRManifest} */
#manifest;

/** @param {import('types').SSRManifest} manifest */
constructor(manifest) {
this.#manifest = manifest;

// Since AsyncLocalStorage is not working in webcontainers, we don't reset `sync_store`
// in `src/exports/internal/server/event.js` and handle only one request at a time.
if (IN_WEBCONTAINER) {
Expand Down Expand Up @@ -187,7 +182,7 @@ export class Server {
async respond(request, options) {
const request_state = create_request_state(options);

const response = await respond(request, this.#manifest, request_state);
const response = await respond(request, request_state);

if (DEV) {
const error = decoded_responses.get(response);
Expand Down
19 changes: 7 additions & 12 deletions packages/kit/src/runtime/server/page/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/** @import { RequestEvent } from '@sveltejs/kit' */
/** @import { PageNodeIndexes, RequestState, RequiredResolveOptions, ServerDataNode, SSRNode, SSRManifest } from 'types' */
/** @import { PageNodeIndexes, RequestState, RequiredResolveOptions, ServerDataNode, SSRNode } from 'types' */
import { text } from '@sveltejs/kit';
import { Redirect } from '@sveltejs/kit/internal';
import { compact } from '../../../utils/array.js';
Expand All @@ -8,6 +8,7 @@ import { noop } from '../../../utils/functions.js';
import { add_data_suffix } from '../../pathname.js';
import { build_error_chain, nearest_error_pages } from '../../error-chain.js';
import { redirect_response } from '../utils.js';
import { manifest } from '../internal.js';
import { static_error_page, handle_error_and_jsonify } from '../errors.js';
import {
handle_action_json_request,
Expand All @@ -32,12 +33,11 @@ const MAX_DEPTH = 10;
* @param {RequestEvent} event
* @param {RequestState} state
* @param {PageNodeIndexes} page
* @param {SSRManifest} manifest
* @param {import('../../../utils/page_nodes.js').PageNodes} nodes
* @param {RequiredResolveOptions} resolve_opts
* @returns {Promise<Response>}
*/
export async function render_page(event, state, page, manifest, nodes, resolve_opts) {
export async function render_page(event, state, page, nodes, resolve_opts) {
if (state.depth > MAX_DEPTH) {
// infinite request cycle detected
return text(`Not found: ${event.url.pathname}`, {
Expand All @@ -61,7 +61,7 @@ export async function render_page(event, state, page, manifest, nodes, resolve_o
if (is_action_request(event)) {
const remote_id = get_remote_action(event.url);
if (remote_id) {
action_result = await handle_remote_form_post(event, state, manifest, remote_id);
action_result = await handle_remote_form_post(event, state, remote_id);
} else {
// for action requests, first call handler in +page.server.js
// (this also determines status code)
Expand Down Expand Up @@ -149,7 +149,6 @@ export async function render_page(event, state, page, manifest, nodes, resolve_o
error: null,
event,
state,
manifest,
resolve_opts,
data_serializer: server_data_serializer(event, state)
});
Expand Down Expand Up @@ -291,15 +290,14 @@ export async function render_page(event, state, page, manifest, nodes, resolve_o
return await render_response({
event,
state,
manifest,
resolve_opts,
page_config: {
ssr: nodes.ssr(),
csr: nodes.csr()
},
status,
error,
error_components: await load_error_components(ssr, error_branch, page, manifest),
error_components: await load_error_components(ssr, error_branch, page),
branch: error_branch,
fetched,
data_serializer
Expand Down Expand Up @@ -336,7 +334,6 @@ export async function render_page(event, state, page, manifest, nodes, resolve_o
return await render_response({
event,
state,
manifest,
resolve_opts,
page_config: {
csr,
Expand All @@ -348,7 +345,7 @@ export async function render_page(event, state, page, manifest, nodes, resolve_o
action_result,
fetched,
data_serializer: !ssr ? server_data_serializer(event, state) : data_serializer,
error_components: await load_error_components(ssr, branch, page, manifest)
error_components: await load_error_components(ssr, branch, page)
});
} catch (e) {
// a remote function could have thrown a redirect during render
Expand All @@ -361,7 +358,6 @@ export async function render_page(event, state, page, manifest, nodes, resolve_o
return await respond_with_error({
event,
state,
manifest,
error: e,
resolve_opts
});
Expand All @@ -372,9 +368,8 @@ export async function render_page(event, state, page, manifest, nodes, resolve_o
* @param {boolean} ssr
* @param {Array<import('./types.js').Loaded | null>} branch
* @param {PageNodeIndexes} page
* @param {SSRManifest} manifest
*/
function load_error_components(ssr, branch, page, manifest) {
function load_error_components(ssr, branch, page) {
if (!ssr) return undefined;

return build_error_chain(branch, page.errors, (idx) =>
Expand Down
7 changes: 5 additions & 2 deletions packages/kit/src/runtime/server/page/load_data.spec.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { assert, expect, test } from 'vitest';
import { create_universal_fetch } from './load_data.js';
import { assert, expect, test, vi } from 'vitest';

vi.stubGlobal('__SVELTEKIT_DEV__', undefined);

const { create_universal_fetch } = await import('./load_data.js');

/**
* @param {Partial<Pick<import('@sveltejs/kit').RequestEvent, 'fetch' | 'url' | 'request' | 'route'>>} event
Expand Down
4 changes: 1 addition & 3 deletions packages/kit/src/runtime/server/page/render.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import Root from '../../components/root.svelte';
import { render } from 'svelte/server';
import { Props, RenderNode } from '../../props.svelte.js';
import { has_custom_transporters, uneval } from '#app/internal/transport';
import { options } from '../internal.js';
import { manifest, options } from '../internal.js';

// TODO rename this function/module

Expand All @@ -36,7 +36,6 @@ import { options } from '../internal.js';
* @param {{
* branch: Array<import('./types.js').Loaded>;
* fetched: Array<import('./types.js').Fetched>;
* manifest: import('types').SSRManifest;
* page_config: { ssr: boolean; csr: boolean };
* status: number;
* error: App.Error | null;
Expand All @@ -51,7 +50,6 @@ import { options } from '../internal.js';
export async function render_response({
branch,
fetched,
manifest,
page_config,
status,
error = null,
Expand Down
5 changes: 2 additions & 3 deletions packages/kit/src/runtime/server/page/respond_with_error.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { redirect_response } from '../utils.js';
import { handle_error_and_jsonify, static_error_page } from '../errors.js';
import { PageNodes } from '../../../utils/page_nodes.js';
import { server_data_serializer } from './data_serializer.js';
import { manifest } from '../internal.js';

/**
* @typedef {import('./types.js').Loaded} Loaded
Expand All @@ -14,12 +15,11 @@ import { server_data_serializer } from './data_serializer.js';
* @param {{
* event: import('@sveltejs/kit').RequestEvent;
* state: import('types').RequestState;
* manifest: import('types').SSRManifest;
* error: unknown;
* resolve_opts: import('types').RequiredResolveOptions;
* }} opts
*/
export async function respond_with_error({ event, state, manifest, error, resolve_opts }) {
export async function respond_with_error({ event, state, error, resolve_opts }) {
// reroute to the fallback page to prevent an infinite chain of requests.
if (event.request.headers.get('x-sveltekit-error')) {
const transformed = await handle_error_and_jsonify(event, state, error);
Expand Down Expand Up @@ -79,7 +79,6 @@ export async function respond_with_error({ event, state, manifest, error, resolv
}

return await render_response({
manifest,
page_config: {
ssr,
csr
Expand Down
7 changes: 3 additions & 4 deletions packages/kit/src/runtime/server/page/server_routing.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { text } from '@sveltejs/kit';
import { s } from '../../../utils/misc.js';
import { find_route } from '../../../utils/routing.js';
import { get_relative_path } from '../../utils.js';
import { manifest } from '../internal.js';

/**
* @param {import('types').SSRClientRoute} route
Expand Down Expand Up @@ -62,10 +63,9 @@ function create_client_import(import_path, url) {
/**
* @param {string} resolved_path
* @param {URL} url
* @param {SSRManifest} manifest
* @returns {Promise<Response>}
*/
export async function resolve_route(resolved_path, url, manifest) {
export async function resolve_route(resolved_path, url) {
if (!manifest.client?.routes) {
return text('Server-side route resolution disabled', { status: 400 });
}
Expand Down Expand Up @@ -99,10 +99,9 @@ export async function resolve_route(resolved_path, url, manifest) {
*
* @param {string} route_id
* @param {URL} url
* @param {SSRManifest} manifest
* @returns {Response}
*/
export function resolve_route_by_id(route_id, url, manifest) {
export function resolve_route_by_id(route_id, url) {
if (!manifest.client?.routes) {
return text('Server-side route resolution disabled', { status: 400 });
}
Expand Down
17 changes: 8 additions & 9 deletions packages/kit/src/runtime/server/remote-functions.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/** @import { RequestEvent } from '@sveltejs/kit' */
/** @import { RemoteForm } from '$app/server' */
/** @import { RemoteFormInternals, RemoteFunctionData, RemoteFunctionResponse, RemoteInternals, RequestState, ServerActionResult, SSRManifest } from 'types' */
/** @import { RemoteFormInternals, RemoteFunctionData, RemoteFunctionResponse, RemoteInternals, RequestState, ServerActionResult } from 'types' */

import { error } from '@sveltejs/kit';
import { Redirect, SvelteKitError } from '@sveltejs/kit/internal';
Expand All @@ -18,6 +18,7 @@ import {
import { deserialize_binary_form } from '../form-utils.js';
import { text_encoder } from '../utils.js';
import { with_version_header } from './utils.js';
import { manifest } from './internal.js';

/**
* How long (in milliseconds) to wait after the last message was sent before
Expand Down Expand Up @@ -140,7 +141,7 @@ export function create_live_query_response(event, state, internals, arg) {
}

/** @type {typeof handle_remote_call_internal} */
export async function handle_remote_call(event, state, manifest, id) {
export async function handle_remote_call(event, state, id) {
return record_span({
name: 'sveltekit.remote.call',
attributes: {
Expand All @@ -149,7 +150,7 @@ export async function handle_remote_call(event, state, manifest, id) {
fn: async (current) => {
const traced_event = merge_tracing(event, current);
const response = await with_request_store({ event: traced_event, state }, () =>
handle_remote_call_internal(traced_event, state, manifest, id)
handle_remote_call_internal(traced_event, state, id)
);
return with_version_header(response);
}
Expand All @@ -159,10 +160,9 @@ export async function handle_remote_call(event, state, manifest, id) {
/**
* @param {RequestEvent} event
* @param {RequestState} state
* @param {SSRManifest} manifest
* @param {string} id
*/
async function handle_remote_call_internal(event, state, manifest, id) {
async function handle_remote_call_internal(event, state, id) {
const [hash, name, additional_args] = id.split('/');
const remotes = manifest.remotes;

Expand Down Expand Up @@ -513,7 +513,7 @@ function create_requested_map(refreshes) {
}

/** @type {typeof handle_remote_form_post_internal} */
export async function handle_remote_form_post(event, state, manifest, id) {
export async function handle_remote_form_post(event, state, id) {
return record_span({
name: 'sveltekit.remote.form.post',
attributes: {
Expand All @@ -522,7 +522,7 @@ export async function handle_remote_form_post(event, state, manifest, id) {
fn: (current) => {
const traced_event = merge_tracing(event, current);
return with_request_store({ event: traced_event, state }, () =>
handle_remote_form_post_internal(traced_event, state, manifest, id)
handle_remote_form_post_internal(traced_event, state, id)
);
}
});
Expand All @@ -531,11 +531,10 @@ export async function handle_remote_form_post(event, state, manifest, id) {
/**
* @param {RequestEvent} event
* @param {RequestState} state
* @param {SSRManifest} manifest
* @param {string} id
* @returns {Promise<ServerActionResult>}
*/
async function handle_remote_form_post_internal(event, state, manifest, id) {
async function handle_remote_form_post_internal(event, state, id) {
const location = get_action_location(event.url);
// `hash` and `name` can never contain a `/`, but the JSON-stringified key of a
// keyed (`form.for(key)`) instance can — rejoin the remaining segments
Expand Down
Loading
Loading