Skip to content
Open
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
5 changes: 2 additions & 3 deletions packages/kit/src/core/postbuild/analyse.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,9 @@ async function analyse({
const config = extract_svelte_config(vite_config);
const server_root = join(config.outDir, 'output');

/** @type {import('types').ServerInternalModule} */
const { configure } = await import(pathToFileURL(`${server_root}/server/internal.js`).href);
/** @type {import('types').ServerModule} */
const { configure } = await import(pathToFileURL(`${server_root}/server/index.js`).href);

// everything user modules may read at their top level, before any of them are analysed
await configure({
building: true,
manifest,
Expand Down
9 changes: 3 additions & 6 deletions packages/kit/src/core/postbuild/fallback.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,14 @@ export default forked(import.meta.url, generate_fallback);
async function generate_fallback({ manifest_path, env, out_dir, origin, assets }) {
const server_root = join(out_dir, 'output');

/** @type {import('types').ServerInternalModule} */
const { configure } = await import(pathToFileURL(`${server_root}/server/internal.js`).href);
await configure({ building: true });

/** @type {import('types').ServerModule} */
const { init, respond } = await import(pathToFileURL(`${server_root}/server/index.js`).href);
const { configure } = await import(pathToFileURL(`${server_root}/server/index.js`).href);

/** @type {import('types').SSRManifest} */
const manifest = (await import(pathToFileURL(manifest_path).href)).manifest;

await init({ manifest, env });
const { init, respond } = await configure({ building: true, manifest, env });
await init();

const response = await respond(new Request(origin + '/[fallback]'), {
getClientAddress: () => {
Expand Down
25 changes: 10 additions & 15 deletions packages/kit/src/core/postbuild/prerender.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,16 +51,16 @@ async function prerender({
/** @type {import('types').SSRManifest} */
const manifest = (await import(pathToFileURL(manifest_path).href)).manifest;

/** @type {import('types').ServerInternalModule} */
const { configure, format_response } = await import(
pathToFileURL(`${out}/server/internal.js`).href
);

// `building` and `prerendering` have to be set before the server module evaluates the user's env config
await configure({ building: true, prerendering: true, env });

/** @type {import('types').ServerModule} */
const { init, respond } = await import(pathToFileURL(`${out}/server/index.js`).href);
const { configure, format_response } = await import(pathToFileURL(`${out}/server/index.js`).href);

const { init, respond } = await configure({
building: true,
prerendering: true,
env,
manifest,
read: (file) => createReadableStream(`${out}/server/${file}`)
Comment thread
elliott-with-the-longest-name-on-github marked this conversation as resolved.
});

const throw_handled = () => {
throw new Error('__handled__');
Expand Down Expand Up @@ -644,11 +644,6 @@ async function prerender({
}
}

// the user's remote function modules may reference `read` or the `manifest` at the top-level
// so we need to set them before evaluating those modules to avoid potential runtime errors
const read = (/** @type {string} */ file) => createReadableStream(`${out}/server/${file}`);
await configure({ manifest, read });

/** @type {Array<import('types').RemotePrerenderInternals>} */
const prerender_functions = [];

Expand All @@ -669,7 +664,7 @@ async function prerender({

// only run the server after the `should_prerender` check so that we
// don't run the user's init hook unnecessarily
await init({ manifest, env, read });
await init();

log.info('Prerendering');

Expand Down
53 changes: 1 addition & 52 deletions packages/kit/src/core/sync/write_server.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,16 @@ import { s } from '../../utils/misc.js';
import { load_error_page, load_template } from '../config/index.js';
import { check_spelling, write_if_changed } from './utils.js';
import { escape_html } from '../../utils/escape.js';
import { runtime_directory } from '../utils.js';

/**
* @param {{
* server_hooks: string | null;
* universal_hooks: string | null;
* config: import('types').ValidatedConfig;
* template: string;
* runtime_directory: string;
* }} opts
*/
const server_template = ({
config,
server_hooks,
universal_hooks,
template,
runtime_directory
}) => `
import { set_building, set_prerendering } from '$app/env/server';
import { set_assets } from '$app/paths/internal/server';
import { set_fix_stack_trace, set_manifest, set_read_implementation, format_response } from '${runtime_directory}/server/internal.js';
import { stream_from_iterable } from '${runtime_directory}/utils.js';
const server_template = ({ config, server_hooks, universal_hooks, template }) => `
import error from './shared/error-template.js';

export const options = {
Expand Down Expand Up @@ -69,44 +57,6 @@ export async function get_hooks() {
transport
};
}

/**
* Sets the module-level state the server runtime reads, in the order it has to happen:
* \`building\` and \`prerendering\` before the env module evaluates the user's \`src/env\` config,
* which may read them, and everything else before user modules run
* @param {import('types').ServerConfigureOptions} opts
*/
export async function configure({ building, prerendering, env, manifest, read, assets, fix_stack_trace }) {
if (building) set_building();
if (prerendering) set_prerendering();

if (manifest) set_manifest(manifest);
if (assets !== undefined) set_assets(assets);
if (fix_stack_trace) set_fix_stack_trace(fix_stack_trace);

if (read) {
// the public \`read\` may return a promise, the runtime expects a stream
set_read_implementation((file) => {
const result = read(file);
if (result instanceof ReadableStream) return result;

return stream_from_iterable(
(async function* () {
const stream = await result;
if (stream) yield* stream;
})()
);
});
}

// evaluates the user's \`src/env\` config, which may read any of the above
if (env) {
const { set_env } = await import('<sveltekit:generated>/env/config.js');
set_env(env);
}
}

export { format_response };
`;

/**
Expand Down Expand Up @@ -147,7 +97,6 @@ export function write_server(config, output, root) {
`${output}/server.js`,
server_template({
config,
runtime_directory: relative(runtime_directory),
server_hooks: server_hooks_file ? relative(server_hooks_file) : null,
universal_hooks: universal_hooks_file ? relative(universal_hooks_file) : null,
template: load_template(root, config)
Expand Down
1 change: 0 additions & 1 deletion packages/kit/src/exports/vite/build/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,6 @@ export function plugin_compile(
/** @type {Record<string, string>} */
const server_input = {
index: `${runtime_directory}/server/index.js`,
internal: `<sveltekit:generated>/server.js`,
env: '<sveltekit:generated>/env/config.js',
['remote-entry']: `${runtime_directory}/app/server/remote/index.js`
};
Expand Down
10 changes: 4 additions & 6 deletions packages/kit/src/exports/vite/dev/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -376,22 +376,20 @@ export async function dev(
await runner.import(resolved_instrumentation);
}

const { init, respond } = /** @type {ServerModule} */ (
const { configure, format_response } = /** @type {ServerModule} */ (
await runner.import(`${get_runtime_base(root)}/server/index.js`)
);

const { format_response } = await runner.import(
`${get_runtime_base(root)}/server/internal.js`
);

await init({
const { init, respond } = await configure({
manifest,
env,
read: (file) => createReadableStream(from_fs(file)),
assets,
fix_stack_trace
});

await init();

const request = (svelte_config.adapter?.vite?.getRequest ?? getRequest)({
base,
request: req,
Expand Down
11 changes: 8 additions & 3 deletions packages/kit/src/exports/vite/preview/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,23 @@ export async function preview(vite, svelte_config) {
}

/** @type {ServerModule} */
const { init, respond } = await import(pathToFileURL(join(dir, 'index.js')).href);
const { configure } = await import(pathToFileURL(join(dir, 'index.js')).href);

/** @type {{ manifest: import('types').SSRManifest }} */
const { manifest } = await import(pathToFileURL(join(dir, 'manifest.js')).href);

/** @type {import('types').ServerInstance} */
let server;

try {
await init({
server = await configure({
manifest,
env: loadEnv(vite.config.mode, svelte_config.env.dir, ''),
read: (file) => createReadableStream(`${dir}/${file}`),
assets
});

await server.init();
} catch (error) {
// Vite erases the error message when starting the preview server so we store
// it in the stack instead. This ensures errors thrown using `stackless`
Expand Down Expand Up @@ -208,7 +213,7 @@ export async function preview(vite, svelte_config) {

(svelte_config.adapter?.vite?.setResponse ?? setResponse)(
res,
await respond(request, {
await server.respond(request, {
getClientAddress: () => {
const { remoteAddress } = req.socket;
if (remoteAddress) return remoteAddress;
Expand Down
50 changes: 2 additions & 48 deletions packages/kit/src/runtime/server/errors.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { text } from '@sveltejs/kit';
import {
HandledHttpError,
HttpError,
Expand All @@ -7,33 +6,8 @@ import {
} from '@sveltejs/kit/internal';
import { with_request_store } from '@sveltejs/kit/internal/server';
import { add_deprecated_handle_error_properties, coalesce_to_error } from '../../utils/error.js';
import { negotiate } from '../../utils/http.js';
import { fix_stack_trace, hooks, options } from './internal.js';
import { escape_html } from '../../utils/escape.js';

/**
* @param {import('@sveltejs/kit').RequestEvent} event
* @param {import('types').RequestState} state
* @param {unknown} error
*/
export async function handle_fatal_error(event, state, error) {
const body = await handle_error_and_jsonify(event, state, error);
const status = body.status;

// sec-fetch-dest would be nicer, but non-browser clients and plain HTTP hosts don't send it
const type = negotiate(event.request.headers.get('accept') || 'text/html', [
'application/json',
'text/html'
]);

if (event.isDataRequest || type === 'application/json') {
return Response.json(body, {
status
});
}

return static_error_page(status, body.message);
}
// `$app/server` reaches this module, so it must not import anything generated
import { fix_stack_trace, hooks } from './internal.js';

/**
* @param {import('@sveltejs/kit').RequestEvent} event
Expand Down Expand Up @@ -135,23 +109,3 @@ function log_handle_error_hook_failure(error, hook_error) {
console.error('Original error:', error);
}
}

/**
* Return as a response that renders the error.html
*
* @param {number} status
* @param {string} message
*/
export function static_error_page(status, message) {
let page = options.templates.error({ status, message: escape_html(message) });

if (__SVELTEKIT_DEV__) {
// inject Vite HMR client, for easier debugging
page = page.replace('</head>', '<script type="module" src="/@vite/client"></script></head>');
}

return text(page, {
headers: { 'content-type': 'text/html; charset=utf-8' },
status
});
}
Loading
Loading