@sveltejs/kit 3.0.0-next.2 → 3.0.0-next.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +62 -36
- package/src/cli.js +15 -12
- package/src/constants.js +6 -1
- package/src/core/adapt/builder.js +66 -72
- package/src/core/adapt/index.js +17 -6
- package/src/core/config/index.js +134 -80
- package/src/core/config/options.js +295 -273
- package/src/core/config/types.d.ts +1 -1
- package/src/core/env.js +146 -16
- package/src/core/generate_manifest/index.js +18 -15
- package/src/core/postbuild/analyse.js +8 -20
- package/src/core/postbuild/crawl.js +22 -6
- package/src/core/postbuild/entities.js +8 -2
- package/src/core/postbuild/fallback.js +4 -2
- package/src/core/postbuild/prerender.js +222 -70
- package/src/core/postbuild/queue.js +2 -1
- package/src/core/sync/create_manifest_data/conflict.js +1 -1
- package/src/core/sync/create_manifest_data/index.js +82 -62
- package/src/core/sync/sync.js +40 -31
- package/src/core/sync/ts.js +1 -1
- package/src/core/sync/utils.js +22 -2
- package/src/core/sync/{write_non_ambient.js → write_app_types.js} +107 -58
- package/src/core/sync/write_client_manifest.js +14 -29
- package/src/core/sync/write_env.js +7 -5
- package/src/core/sync/write_server.js +37 -45
- package/src/core/sync/write_tsconfig/index.js +274 -0
- package/src/core/sync/write_tsconfig/test-app/package.json +7 -0
- package/src/core/sync/write_tsconfig/utils.js +77 -0
- package/src/core/sync/write_tsconfig/validate.js +128 -0
- package/src/core/sync/write_types/index.js +127 -123
- package/src/core/utils.js +30 -5
- package/src/exports/env/index.js +77 -0
- package/src/exports/env/public.d.ts +55 -0
- package/src/exports/hooks/index.js +3 -9
- package/src/exports/hooks/public.d.ts +195 -0
- package/src/exports/hooks/sequence.js +9 -6
- package/src/exports/index.js +52 -29
- package/src/exports/internal/client.js +5 -0
- package/src/exports/internal/env.js +8 -5
- package/src/exports/internal/index.js +1 -90
- package/src/exports/internal/{event.js → server/event.js} +2 -3
- package/src/exports/internal/server/index.js +37 -0
- package/src/exports/internal/server/telemetry.js +95 -0
- package/src/exports/internal/shared.js +90 -0
- package/src/exports/node/index.js +64 -22
- package/src/exports/params/index.js +70 -0
- package/src/exports/params/public.d.ts +63 -0
- package/src/exports/public.d.ts +50 -1733
- package/src/exports/remote/index.js +11 -0
- package/src/exports/remote/public.d.ts +519 -0
- package/src/exports/url.js +86 -0
- package/src/exports/vite/build/build_server.js +54 -65
- package/src/exports/vite/build/remote.js +24 -19
- package/src/exports/vite/build/utils.js +0 -8
- package/src/exports/vite/dev/index.js +218 -146
- package/src/exports/vite/index.js +1590 -858
- package/src/exports/vite/module_ids.js +2 -2
- package/src/exports/vite/preview/index.js +40 -32
- package/src/exports/vite/public.d.ts +588 -0
- package/src/exports/vite/utils.js +84 -46
- package/src/pathname.js +55 -0
- package/src/runner.js +15 -0
- package/src/runtime/app/env/internal.js +4 -4
- package/src/runtime/app/env/types.d.ts +1 -1
- package/src/runtime/app/environment/index.js +3 -3
- package/src/runtime/app/{forms.js → forms/index.js} +73 -42
- package/src/runtime/app/forms/public.d.ts +2 -0
- package/src/runtime/app/forms/types.d.ts +56 -0
- package/src/runtime/app/internal/transport.js +53 -0
- package/src/runtime/app/manifest/index.js +1 -0
- package/src/runtime/app/{navigation.js → navigation/index.js} +2 -1
- package/src/runtime/app/navigation/public.d.ts +237 -0
- package/src/runtime/app/paths/client.js +37 -37
- package/src/runtime/app/paths/index.js +1 -1
- package/src/runtime/app/paths/internal/client.js +34 -2
- package/src/runtime/app/paths/internal/server.js +6 -23
- package/src/runtime/app/paths/internal.d.ts +3 -0
- package/src/runtime/app/paths/public.d.ts +1 -29
- package/src/runtime/app/paths/server.js +36 -17
- package/src/runtime/app/paths/types.d.ts +11 -19
- package/src/runtime/app/server/index.js +2 -2
- package/src/runtime/app/server/public.d.ts +201 -0
- package/src/runtime/app/server/remote/command.js +13 -11
- package/src/runtime/app/server/remote/form.js +61 -39
- package/src/runtime/app/server/remote/prerender.js +45 -45
- package/src/runtime/app/server/remote/query.js +106 -108
- package/src/runtime/app/server/remote/requested.js +27 -19
- package/src/runtime/app/server/remote/shared.js +76 -76
- package/src/runtime/app/service-worker/index.js +24 -0
- package/src/runtime/app/state/client.js +4 -2
- package/src/runtime/app/state/index.js +7 -5
- package/src/runtime/app/state/public.d.ts +72 -0
- package/src/runtime/app/state/server.js +3 -0
- package/src/runtime/app/stores.js +15 -78
- package/src/runtime/client/bundle.js +1 -1
- package/src/runtime/client/client-entry.js +3 -0
- package/src/runtime/client/client.js +1336 -648
- package/src/runtime/client/constants.js +3 -6
- package/src/runtime/client/entry.js +24 -3
- package/src/runtime/client/fetcher.js +25 -25
- package/src/runtime/client/ndjson.js +1 -1
- package/src/runtime/client/parse.js +1 -1
- package/src/runtime/client/payload.js +17 -0
- package/src/runtime/client/remote-functions/cache.svelte.js +3 -1
- package/src/runtime/client/remote-functions/command.svelte.js +37 -61
- package/src/runtime/client/remote-functions/form.svelte.js +267 -178
- package/src/runtime/client/remote-functions/prerender.svelte.js +32 -11
- package/src/runtime/client/remote-functions/query/index.js +10 -17
- package/src/runtime/client/remote-functions/query/instance.svelte.js +64 -18
- package/src/runtime/client/remote-functions/query/proxy.js +5 -5
- package/src/runtime/client/remote-functions/query-batch.svelte.js +61 -70
- package/src/runtime/client/remote-functions/query-live/index.js +1 -1
- package/src/runtime/client/remote-functions/query-live/instance.svelte.js +63 -21
- package/src/runtime/client/remote-functions/query-live/iterator.js +15 -12
- package/src/runtime/client/remote-functions/query-live/proxy.js +2 -12
- package/src/runtime/client/remote-functions/shared.svelte.js +90 -65
- package/src/runtime/client/snapshots.js +147 -0
- package/src/runtime/client/state.svelte.js +94 -55
- package/src/runtime/client/stream.js +3 -2
- package/src/runtime/client/types.d.ts +13 -9
- package/src/runtime/client/utils.js +22 -110
- package/src/runtime/components/root.svelte +56 -0
- package/src/runtime/env/dynamic/private.js +7 -0
- package/src/runtime/env/dynamic/public.js +7 -0
- package/src/runtime/env/static/private.js +6 -0
- package/src/runtime/env/static/public.js +6 -0
- package/src/runtime/form-utils.js +172 -61
- package/src/runtime/pathname.js +20 -32
- package/src/runtime/props.svelte.js +72 -0
- package/src/runtime/server/constants.js +0 -3
- package/src/runtime/server/cookie.js +72 -55
- package/src/runtime/server/csrf.js +65 -0
- package/src/runtime/server/data/index.js +49 -53
- package/src/runtime/server/dev.js +22 -0
- package/src/runtime/server/endpoint.js +6 -7
- package/src/runtime/server/env_module.js +0 -5
- package/src/runtime/server/errors.js +160 -0
- package/src/runtime/server/fetch.js +32 -39
- package/src/runtime/server/index.js +90 -64
- package/src/runtime/server/internal.js +71 -0
- package/src/runtime/server/page/actions.js +85 -64
- package/src/runtime/server/page/crypto.js +2 -2
- package/src/runtime/server/page/csp.js +88 -104
- package/src/runtime/server/page/data_serializer.js +24 -25
- package/src/runtime/server/page/index.js +36 -53
- package/src/runtime/server/page/load_data.js +50 -57
- package/src/runtime/server/page/render.js +173 -239
- package/src/runtime/server/page/respond_with_error.js +17 -31
- package/src/runtime/server/page/serialize_data.js +2 -13
- package/src/runtime/server/page/server_routing.js +85 -26
- package/src/runtime/server/remote-functions.js +640 -0
- package/src/runtime/server/respond.js +190 -131
- package/src/runtime/server/sourcemaps.js +183 -0
- package/src/runtime/server/state.js +53 -0
- package/src/runtime/server/utils.js +13 -155
- package/src/runtime/shared.js +20 -40
- package/src/runtime/utils.js +3 -0
- package/src/types/ambient-private.d.ts +11 -1
- package/src/types/ambient.d.ts +87 -36
- package/src/types/global-private.d.ts +25 -25
- package/src/types/internal.d.ts +163 -157
- package/src/types/private.d.ts +41 -1
- package/src/utils/error.js +28 -4
- package/src/utils/escape.js +9 -25
- package/src/utils/features.js +1 -1
- package/src/utils/filesystem.js +1 -23
- package/src/utils/fork.js +7 -2
- package/src/utils/hash.js +21 -0
- package/src/utils/http.js +8 -7
- package/src/utils/import.js +9 -2
- package/src/utils/imports.js +83 -0
- package/src/utils/mime.js +9 -0
- package/src/utils/page_nodes.js +6 -7
- package/src/utils/params.js +67 -0
- package/src/utils/regex.js +9 -0
- package/src/utils/routing.js +145 -73
- package/src/utils/shared-iterator.js +5 -0
- package/src/utils/streaming.js +14 -4
- package/src/utils/url.js +33 -2
- package/src/version.js +1 -1
- package/types/index.d.ts +2616 -2433
- package/types/index.d.ts.map +120 -106
- package/src/core/sync/write_ambient.js +0 -18
- package/src/core/sync/write_root.js +0 -148
- package/src/core/sync/write_tsconfig.js +0 -250
- package/src/exports/internal/server.js +0 -22
- package/src/exports/node/polyfills.js +0 -30
- package/src/runtime/server/app.js +0 -9
- package/src/runtime/server/remote.js +0 -457
- package/src/runtime/shared-server.js +0 -7
- package/src/runtime/telemetry/otel.js +0 -21
- package/src/runtime/telemetry/record_span.js +0 -65
- package/src/types/synthetic/$lib.md +0 -5
- /package/src/exports/internal/{remote-functions.js → server/remote-functions.js} +0 -0
- /package/src/{runtime/telemetry/noop.js → telemetry.js} +0 -0
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { json, text } from '@sveltejs/kit';
|
|
2
|
+
import {
|
|
3
|
+
HandledHttpError,
|
|
4
|
+
HttpError,
|
|
5
|
+
SvelteKitError,
|
|
6
|
+
ValidationError
|
|
7
|
+
} from '@sveltejs/kit/internal';
|
|
8
|
+
import { with_request_store } from '@sveltejs/kit/internal/server';
|
|
9
|
+
import { add_deprecated_handle_error_properties, coalesce_to_error } from '../../utils/error.js';
|
|
10
|
+
import { negotiate } from '../../utils/http.js';
|
|
11
|
+
import { fix_stack_trace } from './internal.js';
|
|
12
|
+
import { escape_html } from '../../utils/escape.js';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @param {import('$app/server').RequestEvent} event
|
|
16
|
+
* @param {import('types').RequestState} state
|
|
17
|
+
* @param {import('types').SSROptions} options
|
|
18
|
+
* @param {unknown} error
|
|
19
|
+
*/
|
|
20
|
+
export async function handle_fatal_error(event, state, options, error) {
|
|
21
|
+
const body = await handle_error_and_jsonify(event, state, options, error);
|
|
22
|
+
const status = body.status;
|
|
23
|
+
|
|
24
|
+
// sec-fetch-dest would be nicer, but non-browser clients and plain HTTP hosts don't send it
|
|
25
|
+
const type = negotiate(event.request.headers.get('accept') || 'text/html', [
|
|
26
|
+
'application/json',
|
|
27
|
+
'text/html'
|
|
28
|
+
]);
|
|
29
|
+
|
|
30
|
+
if (event.isDataRequest || type === 'application/json') {
|
|
31
|
+
return json(body, {
|
|
32
|
+
status
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return static_error_page(options, status, body.message);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* @param {import('$app/server').RequestEvent} event
|
|
41
|
+
* @param {import('types').RequestState} state
|
|
42
|
+
* @param {import('types').SSROptions} options
|
|
43
|
+
* @param {any} error
|
|
44
|
+
* @returns {App.Error | Promise<App.Error>}
|
|
45
|
+
*/
|
|
46
|
+
export function handle_error_and_jsonify(event, state, options, error) {
|
|
47
|
+
if (error instanceof HandledHttpError) {
|
|
48
|
+
return error.body;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/** @type {import('@sveltejs/kit/hooks').CaughtError} */
|
|
52
|
+
let caught;
|
|
53
|
+
|
|
54
|
+
if (error instanceof HttpError) {
|
|
55
|
+
caught = { kind: 'app', error: error.body };
|
|
56
|
+
} else if (error instanceof SvelteKitError) {
|
|
57
|
+
caught = { kind: 'framework', error: { status: error.status, message: error.text } };
|
|
58
|
+
} else if (error instanceof ValidationError) {
|
|
59
|
+
caught = {
|
|
60
|
+
kind: 'validation',
|
|
61
|
+
error: { status: 400, message: 'Bad Request' },
|
|
62
|
+
issues: error.issues
|
|
63
|
+
};
|
|
64
|
+
} else {
|
|
65
|
+
caught = { kind: 'unknown', error };
|
|
66
|
+
|
|
67
|
+
let e = error;
|
|
68
|
+
while (e instanceof Error) {
|
|
69
|
+
fix_stack_trace(e);
|
|
70
|
+
e = e.cause;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const fallback =
|
|
75
|
+
caught.kind === 'unknown' ? { status: 500, message: 'Internal Error' } : caught.error;
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* The hook returns only the properties it wants to override; anything it omits
|
|
79
|
+
* (including by returning nothing at all) is inherited from the caught error.
|
|
80
|
+
* @param {Awaited<ReturnType<import('@sveltejs/kit/hooks').HandleServerError>>} body
|
|
81
|
+
* @returns {App.Error}
|
|
82
|
+
*/
|
|
83
|
+
function merge(body) {
|
|
84
|
+
return { ...fallback, ...body };
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// TODO 4.0 await this, rather than handling the non-Promise case
|
|
88
|
+
let result;
|
|
89
|
+
try {
|
|
90
|
+
const input = { ...caught, event };
|
|
91
|
+
if (__SVELTEKIT_DEV__) add_deprecated_handle_error_properties(input, fallback);
|
|
92
|
+
|
|
93
|
+
result = with_request_store({ event, state }, () => options.hooks.handleError(input));
|
|
94
|
+
} catch (hook_error) {
|
|
95
|
+
log_handle_error_hook_failure(error, hook_error);
|
|
96
|
+
return { status: fallback.status, message: 'Internal Error' };
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (result instanceof Promise) {
|
|
100
|
+
if (!__SVELTEKIT_SUPPORTS_ASYNC__ && state.is_in_render) {
|
|
101
|
+
console.warn(
|
|
102
|
+
`To use an async \`handleError\` hook to handle errors that occur during rendering, you must enable \`compilerOptions.experimental.async\` in the SvelteKit plugin of your Vite config. The returned error has been replaced with a generic object`
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
// we're discarding the result, but we still need to prevent an unhandled
|
|
106
|
+
// rejection if the user's async `handleError` hook rejects
|
|
107
|
+
result.catch((hook_error) => log_handle_error_hook_failure(error, hook_error));
|
|
108
|
+
|
|
109
|
+
return {
|
|
110
|
+
status: fallback.status,
|
|
111
|
+
message: 'Internal Error'
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return result.then(merge, (hook_error) => {
|
|
116
|
+
log_handle_error_hook_failure(error, hook_error);
|
|
117
|
+
return { status: fallback.status, message: 'Internal Error' };
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return merge(result);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* @param {unknown} error
|
|
126
|
+
* @param {unknown} hook_error
|
|
127
|
+
*/
|
|
128
|
+
function log_handle_error_hook_failure(error, hook_error) {
|
|
129
|
+
const failure = new Error('The `handleError` hook failed', {
|
|
130
|
+
cause: coalesce_to_error(hook_error)
|
|
131
|
+
});
|
|
132
|
+
failure.stack = failure.message;
|
|
133
|
+
console.error(failure);
|
|
134
|
+
if (error instanceof SvelteKitError) {
|
|
135
|
+
console.error(`Original error: ${error.status} ${error.text}: ${error.message}`);
|
|
136
|
+
} else {
|
|
137
|
+
console.error('Original error:', error);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Return as a response that renders the error.html
|
|
143
|
+
*
|
|
144
|
+
* @param {import('types').SSROptions} options
|
|
145
|
+
* @param {number} status
|
|
146
|
+
* @param {string} message
|
|
147
|
+
*/
|
|
148
|
+
export function static_error_page(options, status, message) {
|
|
149
|
+
let page = options.templates.error({ status, message: escape_html(message) });
|
|
150
|
+
|
|
151
|
+
if (__SVELTEKIT_DEV__) {
|
|
152
|
+
// inject Vite HMR client, for easier debugging
|
|
153
|
+
page = page.replace('</head>', '<script type="module" src="/@vite/client"></script></head>');
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
return text(page, {
|
|
157
|
+
headers: { 'content-type': 'text/html; charset=utf-8' },
|
|
158
|
+
status
|
|
159
|
+
});
|
|
160
|
+
}
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import { parseSetCookie } from 'cookie';
|
|
2
2
|
import { noop } from '../../utils/functions.js';
|
|
3
3
|
import { respond } from './respond.js';
|
|
4
|
-
import * as paths from '
|
|
5
|
-
import { read_implementation } from '
|
|
4
|
+
import * as paths from '#app/paths';
|
|
5
|
+
import { read_implementation } from './internal.js';
|
|
6
6
|
import { has_prerendered_path } from './utils.js';
|
|
7
|
+
import { fork_state_for_subrequest } from './state.js';
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* @param {{
|
|
10
|
-
* event: import('
|
|
11
|
+
* event: import('$app/server').RequestEvent;
|
|
11
12
|
* options: import('types').SSROptions;
|
|
12
13
|
* manifest: import('@sveltejs/kit').SSRManifest;
|
|
13
|
-
* state: import('types').
|
|
14
|
+
* state: import('types').RequestState;
|
|
14
15
|
* get_cookie_header: (url: URL, header: string | null) => string;
|
|
15
16
|
* set_internal: (name: string, value: string, opts: import('./page/types.js').Cookie['options']) => void;
|
|
16
17
|
* }} opts
|
|
@@ -117,7 +118,7 @@ export function create_fetch({ event, options, manifest, state, get_cookie_heade
|
|
|
117
118
|
return await fetch(request);
|
|
118
119
|
}
|
|
119
120
|
|
|
120
|
-
if (has_prerendered_path(manifest,
|
|
121
|
+
if (has_prerendered_path(manifest, decoded)) {
|
|
121
122
|
// The path of something prerendered could match a different route
|
|
122
123
|
// that is still in the manifest, leading to the wrong route being loaded.
|
|
123
124
|
// We therefore bail early here. The prerendered logic is different for
|
|
@@ -142,11 +143,9 @@ export function create_fetch({ event, options, manifest, state, get_cookie_heade
|
|
|
142
143
|
request.headers.set('accept', '*/*');
|
|
143
144
|
}
|
|
144
145
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
/** @type {string} */ (event.request.headers.get('accept-language'))
|
|
149
|
-
);
|
|
146
|
+
const accept_language = event.request.headers.get('accept-language');
|
|
147
|
+
if (accept_language && !request.headers.has('accept-language')) {
|
|
148
|
+
request.headers.set('accept-language', accept_language);
|
|
150
149
|
}
|
|
151
150
|
|
|
152
151
|
const response = await internal_fetch(request, options, manifest, state);
|
|
@@ -196,38 +195,32 @@ function normalize_fetch_input(info, init, url) {
|
|
|
196
195
|
* @param {Request} request
|
|
197
196
|
* @param {import('types').SSROptions} options
|
|
198
197
|
* @param {import('@sveltejs/kit').SSRManifest} manifest
|
|
199
|
-
* @param {import('types').
|
|
198
|
+
* @param {import('types').RequestState} state
|
|
200
199
|
* @returns {Promise<Response>}
|
|
201
200
|
*/
|
|
202
201
|
async function internal_fetch(request, options, manifest, state) {
|
|
203
|
-
if (request.signal) {
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
let remove_abort_listener = noop;
|
|
209
|
-
/** @type {Promise<never>} */
|
|
210
|
-
const abort_promise = new Promise((_, reject) => {
|
|
211
|
-
const on_abort = () => {
|
|
212
|
-
reject(new DOMException('The operation was aborted.', 'AbortError'));
|
|
213
|
-
};
|
|
214
|
-
request.signal.addEventListener('abort', on_abort, { once: true });
|
|
215
|
-
remove_abort_listener = () => request.signal.removeEventListener('abort', on_abort);
|
|
216
|
-
});
|
|
202
|
+
if (request.signal?.aborted) {
|
|
203
|
+
throw new DOMException('The operation was aborted.', 'AbortError');
|
|
204
|
+
}
|
|
217
205
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
}),
|
|
223
|
-
abort_promise
|
|
224
|
-
]);
|
|
225
|
-
remove_abort_listener();
|
|
226
|
-
return result;
|
|
227
|
-
} else {
|
|
228
|
-
return await respond(request, options, manifest, {
|
|
229
|
-
...state,
|
|
230
|
-
depth: state.depth + 1
|
|
231
|
-
});
|
|
206
|
+
const subrequest_state = fork_state_for_subrequest(state);
|
|
207
|
+
|
|
208
|
+
if (!request.signal) {
|
|
209
|
+
return await respond(request, options, manifest, subrequest_state);
|
|
232
210
|
}
|
|
211
|
+
|
|
212
|
+
let remove_abort_listener = noop;
|
|
213
|
+
/** @type {Promise<never>} */
|
|
214
|
+
const abort_promise = new Promise((_, reject) => {
|
|
215
|
+
const on_abort = () => {
|
|
216
|
+
reject(new DOMException('The operation was aborted.', 'AbortError'));
|
|
217
|
+
};
|
|
218
|
+
request.signal.addEventListener('abort', on_abort, { once: true });
|
|
219
|
+
remove_abort_listener = () => request.signal.removeEventListener('abort', on_abort);
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
return Promise.race([
|
|
223
|
+
respond(request, options, manifest, subrequest_state),
|
|
224
|
+
abort_promise
|
|
225
|
+
]).finally(remove_abort_listener);
|
|
233
226
|
}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { noop } from '../../utils/functions.js';
|
|
2
|
-
import { IN_WEBCONTAINER } from '
|
|
2
|
+
import { IN_WEBCONTAINER } from '../../constants.js';
|
|
3
3
|
import { respond } from './respond.js';
|
|
4
|
+
import { create_request_state } from './state.js';
|
|
4
5
|
import { options, get_hooks } from '__SERVER__/internal.js';
|
|
5
|
-
import {
|
|
6
|
-
import { set_read_implementation, set_manifest } from '__sveltekit/server';
|
|
6
|
+
import { set_read_implementation, set_manifest, fix_stack_trace } from './internal.js';
|
|
7
7
|
import { set_env } from '__sveltekit/env';
|
|
8
|
-
import {
|
|
8
|
+
import { init_tracing } from '@sveltejs/kit/internal/server';
|
|
9
|
+
import { DEV } from 'esm-env';
|
|
10
|
+
import { init_transport } from '#app/internal/transport';
|
|
9
11
|
|
|
10
12
|
/** @type {Promise<any>} */
|
|
11
13
|
let init_promise;
|
|
@@ -13,6 +15,38 @@ let init_promise;
|
|
|
13
15
|
/** @type {Promise<void> | null} */
|
|
14
16
|
let current = null;
|
|
15
17
|
|
|
18
|
+
/**
|
|
19
|
+
* Responses that were created with our monkey-patched `fetch`, which may need
|
|
20
|
+
* to have their `content-encoding` and `content-length` headers removed
|
|
21
|
+
* if returned directly (i.e. `fetch` is being used to proxy a request)
|
|
22
|
+
* @type {WeakMap<Response, Error>}
|
|
23
|
+
*/
|
|
24
|
+
const decoded_responses = new WeakMap();
|
|
25
|
+
|
|
26
|
+
if (DEV) {
|
|
27
|
+
const fetch = globalThis.fetch;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @param {RequestInfo | URL} info
|
|
31
|
+
* @param {RequestInit} [init]
|
|
32
|
+
*/
|
|
33
|
+
globalThis.fetch = async (info, init) => {
|
|
34
|
+
const response = await fetch(info, init);
|
|
35
|
+
const encoding = response.headers.get('content-encoding');
|
|
36
|
+
|
|
37
|
+
if (encoding) {
|
|
38
|
+
decoded_responses.set(
|
|
39
|
+
response,
|
|
40
|
+
new Error(
|
|
41
|
+
`Cannot return \`fetch(...)\` directly from a handler if the response has a \`Content-Encoding: ${encoding}\` header. The body has already been decoded`
|
|
42
|
+
)
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return response;
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
16
50
|
export class Server {
|
|
17
51
|
/** @type {import('types').SSROptions} */
|
|
18
52
|
#options;
|
|
@@ -27,7 +61,7 @@ export class Server {
|
|
|
27
61
|
this.#manifest = manifest;
|
|
28
62
|
|
|
29
63
|
// Since AsyncLocalStorage is not working in webcontainers, we don't reset `sync_store`
|
|
30
|
-
// in `src/exports/internal/event.js` and handle only one request at a time.
|
|
64
|
+
// in `src/exports/internal/server/event.js` and handle only one request at a time.
|
|
31
65
|
if (IN_WEBCONTAINER) {
|
|
32
66
|
const respond = this.respond.bind(this);
|
|
33
67
|
|
|
@@ -56,6 +90,8 @@ export class Server {
|
|
|
56
90
|
// so anything that shouldn't be rerun should be wrapped in an `if` block to make sure it hasn't
|
|
57
91
|
// been done already.
|
|
58
92
|
|
|
93
|
+
if (__SVELTEKIT_SERVER_TRACING_ENABLED__) init_tracing(import('@opentelemetry/api'));
|
|
94
|
+
|
|
59
95
|
// set env, in case it's used in initialisation
|
|
60
96
|
set_env(env);
|
|
61
97
|
|
|
@@ -67,31 +103,17 @@ export class Server {
|
|
|
67
103
|
const result = read(file);
|
|
68
104
|
if (result instanceof ReadableStream) {
|
|
69
105
|
return result;
|
|
70
|
-
} else {
|
|
71
|
-
return new ReadableStream({
|
|
72
|
-
async start(controller) {
|
|
73
|
-
try {
|
|
74
|
-
const stream = await Promise.resolve(result);
|
|
75
|
-
if (!stream) {
|
|
76
|
-
controller.close();
|
|
77
|
-
return;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
const reader = stream.getReader();
|
|
81
|
-
|
|
82
|
-
while (true) {
|
|
83
|
-
const { done, value } = await reader.read();
|
|
84
|
-
if (done) break;
|
|
85
|
-
controller.enqueue(value);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
controller.close();
|
|
89
|
-
} catch (error) {
|
|
90
|
-
controller.error(error);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
});
|
|
94
106
|
}
|
|
107
|
+
|
|
108
|
+
// TODO remove the cast once TypeScript's lib includes `ReadableStream.from`
|
|
109
|
+
return /** @type {ReadableStream} */ (
|
|
110
|
+
/** @type {any} */ (ReadableStream).from(
|
|
111
|
+
(async function* () {
|
|
112
|
+
const stream = await result;
|
|
113
|
+
if (stream) yield* stream;
|
|
114
|
+
})()
|
|
115
|
+
)
|
|
116
|
+
);
|
|
95
117
|
};
|
|
96
118
|
|
|
97
119
|
set_read_implementation(wrapped_read);
|
|
@@ -107,30 +129,34 @@ export class Server {
|
|
|
107
129
|
handle: module.handle || (({ event, resolve }) => resolve(event)),
|
|
108
130
|
handleError:
|
|
109
131
|
module.handleError ||
|
|
110
|
-
(({
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
132
|
+
(({ kind, error, issues }) => {
|
|
133
|
+
if (kind === 'validation') {
|
|
134
|
+
console.error('Remote function schema validation failed:', issues);
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (kind !== 'unknown') {
|
|
139
|
+
// don't log stack traces for 404s etc, it's all internal gubbins
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
let e = error;
|
|
144
|
+
while (e instanceof Error) {
|
|
145
|
+
if (e.stack) {
|
|
146
|
+
console.error(e.stack);
|
|
147
|
+
}
|
|
148
|
+
e = e.cause;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (e) {
|
|
152
|
+
console.error(String(e));
|
|
153
|
+
}
|
|
117
154
|
}),
|
|
118
155
|
handleFetch: module.handleFetch || (({ request, fetch }) => fetch(request)),
|
|
119
|
-
|
|
120
|
-
module.handleValidationError ||
|
|
121
|
-
(({ issues }) => {
|
|
122
|
-
console.error('Remote function schema validation failed:', issues);
|
|
123
|
-
return { message: 'Bad Request' };
|
|
124
|
-
}),
|
|
125
|
-
reroute: module.reroute || noop,
|
|
126
|
-
transport: module.transport || {}
|
|
156
|
+
reroute: module.reroute || noop
|
|
127
157
|
};
|
|
128
158
|
|
|
129
|
-
|
|
130
|
-
decoders: module.transport
|
|
131
|
-
? Object.fromEntries(Object.entries(module.transport).map(([k, v]) => [k, v.decode]))
|
|
132
|
-
: {}
|
|
133
|
-
});
|
|
159
|
+
init_transport(module.transport ?? {});
|
|
134
160
|
|
|
135
161
|
if (module.init) {
|
|
136
162
|
await module.init();
|
|
@@ -143,16 +169,8 @@ export class Server {
|
|
|
143
169
|
},
|
|
144
170
|
handleError: ({ error }) => console.error(error),
|
|
145
171
|
handleFetch: ({ request, fetch }) => fetch(request),
|
|
146
|
-
|
|
147
|
-
return { message: 'Bad Request' };
|
|
148
|
-
},
|
|
149
|
-
reroute: noop,
|
|
150
|
-
transport: {}
|
|
172
|
+
reroute: noop
|
|
151
173
|
};
|
|
152
|
-
|
|
153
|
-
set_app({
|
|
154
|
-
decoders: {}
|
|
155
|
-
});
|
|
156
174
|
} else {
|
|
157
175
|
throw e;
|
|
158
176
|
}
|
|
@@ -162,13 +180,21 @@ export class Server {
|
|
|
162
180
|
|
|
163
181
|
/**
|
|
164
182
|
* @param {Request} request
|
|
165
|
-
* @param {import('types').
|
|
183
|
+
* @param {import('types').InternalRequestOptions} options
|
|
166
184
|
*/
|
|
167
185
|
async respond(request, options) {
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
186
|
+
const response = await respond(
|
|
187
|
+
request,
|
|
188
|
+
this.#options,
|
|
189
|
+
this.#manifest,
|
|
190
|
+
create_request_state(options)
|
|
191
|
+
);
|
|
192
|
+
|
|
193
|
+
if (DEV) {
|
|
194
|
+
const error = decoded_responses.get(response);
|
|
195
|
+
if (error) console.error(fix_stack_trace(error));
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
return response;
|
|
173
199
|
}
|
|
174
200
|
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/** @import { SSRManifest } from '@sveltejs/kit'; */
|
|
2
|
+
import { restore, save } from './dev.js';
|
|
3
|
+
import {
|
|
4
|
+
has_data_suffix,
|
|
5
|
+
has_resolution_suffix,
|
|
6
|
+
strip_data_suffix,
|
|
7
|
+
strip_resolution_suffix
|
|
8
|
+
} from '../../pathname.js';
|
|
9
|
+
import { has_remote_prefix, strip_remote_prefix } from '../../runtime/server/remote-functions.js';
|
|
10
|
+
|
|
11
|
+
// using `getBuiltinModule` rather than `import` makes this safe to run in non-Node-compatible environments
|
|
12
|
+
const styleText =
|
|
13
|
+
// eslint-disable-next-line n/prefer-global/process
|
|
14
|
+
globalThis.process?.getBuiltinModule?.('node:util')?.styleText ??
|
|
15
|
+
/** @type {(format: unknown, text: string) => string} */ ((_format, text) => text);
|
|
16
|
+
|
|
17
|
+
const read_implementation_key = Symbol.for('sveltekit.read_implementation');
|
|
18
|
+
const manifest_key = Symbol.for('sveltekit.manifest');
|
|
19
|
+
|
|
20
|
+
export let read_implementation = /** @type {((path: string) => ReadableStream<any>) | null} */ (
|
|
21
|
+
(__SVELTEKIT_DEV__ && restore(read_implementation_key)) ?? null
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
export let manifest = /** @type {SSRManifest} */ (
|
|
25
|
+
(__SVELTEKIT_DEV__ && restore(manifest_key)) ?? null
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* @param {(path: string) => ReadableStream<any>} fn
|
|
30
|
+
*/
|
|
31
|
+
export function set_read_implementation(fn) {
|
|
32
|
+
read_implementation = fn;
|
|
33
|
+
if (__SVELTEKIT_DEV__) save(read_implementation_key, fn);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
*
|
|
38
|
+
* @param {SSRManifest} value
|
|
39
|
+
*/
|
|
40
|
+
export function set_manifest(value) {
|
|
41
|
+
manifest = value;
|
|
42
|
+
if (__SVELTEKIT_DEV__) save(manifest_key, value);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* @param {number} status
|
|
47
|
+
* @param {Request} request
|
|
48
|
+
*/
|
|
49
|
+
export function log_response(status, request) {
|
|
50
|
+
const url = new URL(request.url);
|
|
51
|
+
const requested = url.href.replace(url.origin, '');
|
|
52
|
+
|
|
53
|
+
let log = `${styleText(status < 400 ? ['cyan'] : ['bold', 'red'], `${status}`)} ${request.method} `;
|
|
54
|
+
|
|
55
|
+
if (has_data_suffix(url.pathname)) {
|
|
56
|
+
const pathname = strip_data_suffix(url.pathname) || '/';
|
|
57
|
+
log += pathname + styleText('dim', requested.slice(pathname.length));
|
|
58
|
+
} else if (has_resolution_suffix(url.pathname)) {
|
|
59
|
+
const pathname = strip_resolution_suffix(url.pathname) || '/';
|
|
60
|
+
log += pathname + styleText('dim', requested.slice(pathname.length));
|
|
61
|
+
} else if (has_remote_prefix(url)) {
|
|
62
|
+
const id = /** @type {string} */ (strip_remote_prefix(url).split('/').pop());
|
|
63
|
+
log += styleText('dim', url.pathname.slice(0, -id.length)) + id + styleText('dim', url.search);
|
|
64
|
+
} else {
|
|
65
|
+
log += requested;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
console.log(log);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export { fix_stack_trace, set_fix_stack_trace } from './sourcemaps.js';
|