@sveltejs/kit 2.30.1 → 2.31.0
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 +12 -1
- package/src/core/adapt/builder.js +122 -13
- package/src/core/config/options.js +6 -0
- package/src/exports/hooks/sequence.js +53 -31
- package/src/{runtime/app/server → exports/internal}/event.js +24 -9
- package/src/exports/internal/server.js +22 -0
- package/src/exports/public.d.ts +117 -5
- package/src/exports/vite/dev/index.js +8 -0
- package/src/exports/vite/index.js +30 -3
- package/src/exports/vite/utils.js +44 -0
- package/src/runtime/app/server/index.js +1 -1
- package/src/runtime/app/server/remote/command.js +4 -5
- package/src/runtime/app/server/remote/form.js +5 -7
- package/src/runtime/app/server/remote/prerender.js +5 -7
- package/src/runtime/app/server/remote/query.js +6 -8
- package/src/runtime/app/server/remote/shared.js +9 -13
- package/src/runtime/client/client.js +9 -14
- package/src/runtime/server/data/index.js +10 -5
- package/src/runtime/server/endpoint.js +4 -3
- package/src/runtime/server/page/actions.js +55 -24
- package/src/runtime/server/page/index.js +22 -5
- package/src/runtime/server/page/load_data.js +131 -121
- package/src/runtime/server/page/render.js +15 -7
- package/src/runtime/server/page/respond_with_error.js +7 -2
- package/src/runtime/server/remote.js +59 -13
- package/src/runtime/server/respond.js +110 -34
- package/src/runtime/server/utils.js +20 -5
- package/src/runtime/shared.js +20 -0
- package/src/runtime/telemetry/noop.js +81 -0
- package/src/runtime/telemetry/otel.js +21 -0
- package/src/runtime/telemetry/record_span.js +65 -0
- package/src/types/global-private.d.ts +2 -0
- package/src/types/internal.d.ts +28 -0
- package/src/types/synthetic/$env+dynamic+private.md +1 -1
- package/src/version.js +1 -1
- package/types/index.d.ts +117 -4
- package/types/index.d.ts.map +2 -2
- package/src/runtime/server/event-state.js +0 -40
|
@@ -16,7 +16,13 @@ import { build_service_worker } from './build/build_service_worker.js';
|
|
|
16
16
|
import { assets_base, find_deps, resolve_symlinks } from './build/utils.js';
|
|
17
17
|
import { dev } from './dev/index.js';
|
|
18
18
|
import { preview } from './preview/index.js';
|
|
19
|
-
import {
|
|
19
|
+
import {
|
|
20
|
+
error_for_missing_config,
|
|
21
|
+
get_config_aliases,
|
|
22
|
+
get_env,
|
|
23
|
+
normalize_id,
|
|
24
|
+
stackless
|
|
25
|
+
} from './utils.js';
|
|
20
26
|
import { write_client_manifest } from '../../core/sync/write_client_manifest.js';
|
|
21
27
|
import prerender from '../../core/postbuild/prerender.js';
|
|
22
28
|
import analyse from '../../core/postbuild/analyse.js';
|
|
@@ -332,7 +338,8 @@ async function kit({ svelte_config }) {
|
|
|
332
338
|
__SVELTEKIT_DEV__: 'false',
|
|
333
339
|
__SVELTEKIT_EMBEDDED__: s(kit.embedded),
|
|
334
340
|
__SVELTEKIT_EXPERIMENTAL__REMOTE_FUNCTIONS__: s(kit.experimental.remoteFunctions),
|
|
335
|
-
__SVELTEKIT_CLIENT_ROUTING__: kit.router.resolution === 'client'
|
|
341
|
+
__SVELTEKIT_CLIENT_ROUTING__: s(kit.router.resolution === 'client'),
|
|
342
|
+
__SVELTEKIT_SERVER_TRACING_ENABLED__: s(kit.experimental.instrumentation.server),
|
|
336
343
|
__SVELTEKIT_PAYLOAD__: new_config.build.ssr
|
|
337
344
|
? '{}'
|
|
338
345
|
: `globalThis.__sveltekit_${version_hash}`
|
|
@@ -347,7 +354,8 @@ async function kit({ svelte_config }) {
|
|
|
347
354
|
__SVELTEKIT_DEV__: 'true',
|
|
348
355
|
__SVELTEKIT_EMBEDDED__: s(kit.embedded),
|
|
349
356
|
__SVELTEKIT_EXPERIMENTAL__REMOTE_FUNCTIONS__: s(kit.experimental.remoteFunctions),
|
|
350
|
-
__SVELTEKIT_CLIENT_ROUTING__: kit.router.resolution === 'client'
|
|
357
|
+
__SVELTEKIT_CLIENT_ROUTING__: s(kit.router.resolution === 'client'),
|
|
358
|
+
__SVELTEKIT_SERVER_TRACING_ENABLED__: s(kit.experimental.instrumentation.server),
|
|
351
359
|
__SVELTEKIT_PAYLOAD__: 'globalThis.__sveltekit_dev'
|
|
352
360
|
};
|
|
353
361
|
|
|
@@ -775,6 +783,25 @@ async function kit({ svelte_config }) {
|
|
|
775
783
|
input[name] = path.resolve(file);
|
|
776
784
|
});
|
|
777
785
|
|
|
786
|
+
// ...and the server instrumentation file
|
|
787
|
+
const server_instrumentation = resolve_entry(
|
|
788
|
+
path.join(kit.files.src, 'instrumentation.server')
|
|
789
|
+
);
|
|
790
|
+
if (server_instrumentation) {
|
|
791
|
+
const { adapter } = kit;
|
|
792
|
+
if (adapter && !adapter.supports?.instrumentation?.()) {
|
|
793
|
+
throw new Error(`${server_instrumentation} is unsupported in ${adapter.name}.`);
|
|
794
|
+
}
|
|
795
|
+
if (!kit.experimental.instrumentation.server) {
|
|
796
|
+
error_for_missing_config(
|
|
797
|
+
'instrumentation.server.js',
|
|
798
|
+
'kit.experimental.instrumentation.server',
|
|
799
|
+
'true'
|
|
800
|
+
);
|
|
801
|
+
}
|
|
802
|
+
input['instrumentation.server'] = server_instrumentation;
|
|
803
|
+
}
|
|
804
|
+
|
|
778
805
|
// ...and every .remote file
|
|
779
806
|
for (const remote of manifest_data.remotes) {
|
|
780
807
|
input[`remote/${remote.hash}`] = path.resolve(remote.file);
|
|
@@ -4,6 +4,7 @@ import { posixify } from '../../utils/filesystem.js';
|
|
|
4
4
|
import { negotiate } from '../../utils/http.js';
|
|
5
5
|
import { filter_private_env, filter_public_env } from '../../utils/env.js';
|
|
6
6
|
import { escape_html } from '../../utils/escape.js';
|
|
7
|
+
import { dedent } from '../../core/sync/utils.js';
|
|
7
8
|
import {
|
|
8
9
|
app_server,
|
|
9
10
|
env_dynamic_private,
|
|
@@ -172,3 +173,46 @@ export function stackless(message) {
|
|
|
172
173
|
}
|
|
173
174
|
|
|
174
175
|
export const strip_virtual_prefix = /** @param {string} id */ (id) => id.replace('\0virtual:', '');
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* For `error_for_missing_config('instrumentation.server.js', 'kit.experimental.instrumentation.server', true)`,
|
|
179
|
+
* returns:
|
|
180
|
+
*
|
|
181
|
+
* ```
|
|
182
|
+
* To enable `instrumentation.server.js`, add the following to your `svelte.config.js`:
|
|
183
|
+
*
|
|
184
|
+
*\`\`\`js
|
|
185
|
+
* kit:
|
|
186
|
+
* experimental:
|
|
187
|
+
* instrumentation:
|
|
188
|
+
* server: true
|
|
189
|
+
* }
|
|
190
|
+
* }
|
|
191
|
+
* }
|
|
192
|
+
*\`\`\`
|
|
193
|
+
*```
|
|
194
|
+
* @param {string} feature_name
|
|
195
|
+
* @param {string} path
|
|
196
|
+
* @param {string} value
|
|
197
|
+
* @returns {never}
|
|
198
|
+
*/
|
|
199
|
+
export function error_for_missing_config(feature_name, path, value) {
|
|
200
|
+
const hole = '__HOLE__';
|
|
201
|
+
|
|
202
|
+
const result = path.split('.').reduce((acc, part, i, parts) => {
|
|
203
|
+
const indent = ' '.repeat(i);
|
|
204
|
+
const rhs = i === parts.length - 1 ? value : `{\n${hole}\n${indent}}`;
|
|
205
|
+
|
|
206
|
+
return acc.replace(hole, `${indent}${part}: ${rhs}`);
|
|
207
|
+
}, hole);
|
|
208
|
+
|
|
209
|
+
throw new Error(
|
|
210
|
+
dedent`\
|
|
211
|
+
To enable \`${feature_name}\`, add the following to your \`svelte.config.js\`:
|
|
212
|
+
|
|
213
|
+
\`\`\`js
|
|
214
|
+
${result}
|
|
215
|
+
\`\`\`
|
|
216
|
+
`
|
|
217
|
+
);
|
|
218
|
+
}
|
|
@@ -73,6 +73,6 @@ export function read(asset) {
|
|
|
73
73
|
throw new Error(`Asset does not exist: ${file}`);
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
export { getRequestEvent } from '
|
|
76
|
+
export { getRequestEvent } from '@sveltejs/kit/internal/server';
|
|
77
77
|
|
|
78
78
|
export { query, prerender, command, form } from './remote/index.js';
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
/** @import { RemoteCommand } from '@sveltejs/kit' */
|
|
2
2
|
/** @import { RemoteInfo, MaybePromise } from 'types' */
|
|
3
3
|
/** @import { StandardSchemaV1 } from '@standard-schema/spec' */
|
|
4
|
-
import {
|
|
4
|
+
import { get_request_store } from '@sveltejs/kit/internal/server';
|
|
5
5
|
import { check_experimental, create_validator, run_remote_function } from './shared.js';
|
|
6
|
-
import { get_event_state } from '../../../server/event-state.js';
|
|
7
6
|
|
|
8
7
|
/**
|
|
9
8
|
* Creates a remote command. When called from the browser, the function will be invoked on the server via a `fetch` call.
|
|
@@ -65,7 +64,7 @@ export function command(validate_or_fn, maybe_fn) {
|
|
|
65
64
|
|
|
66
65
|
/** @type {RemoteCommand<Input, Output> & { __: RemoteInfo }} */
|
|
67
66
|
const wrapper = (arg) => {
|
|
68
|
-
const event =
|
|
67
|
+
const { event, state } = get_request_store();
|
|
69
68
|
|
|
70
69
|
if (!event.isRemoteRequest) {
|
|
71
70
|
throw new Error(
|
|
@@ -73,9 +72,9 @@ export function command(validate_or_fn, maybe_fn) {
|
|
|
73
72
|
);
|
|
74
73
|
}
|
|
75
74
|
|
|
76
|
-
|
|
75
|
+
state.refreshes ??= {};
|
|
77
76
|
|
|
78
|
-
const promise = Promise.resolve(run_remote_function(event, true, arg, validate, fn));
|
|
77
|
+
const promise = Promise.resolve(run_remote_function(event, state, true, arg, validate, fn));
|
|
79
78
|
|
|
80
79
|
// @ts-expect-error
|
|
81
80
|
promise.updates = () => {
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
/** @import { RemoteForm } from '@sveltejs/kit' */
|
|
2
2
|
/** @import { RemoteInfo, MaybePromise } from 'types' */
|
|
3
|
-
import {
|
|
3
|
+
import { get_request_store } from '@sveltejs/kit/internal/server';
|
|
4
4
|
import { check_experimental, run_remote_function } from './shared.js';
|
|
5
|
-
import { get_event_state } from '../../../server/event-state.js';
|
|
6
5
|
|
|
7
6
|
/**
|
|
8
7
|
* Creates a form object that can be spread onto a `<form>` element.
|
|
@@ -57,12 +56,11 @@ export function form(fn) {
|
|
|
57
56
|
id: '',
|
|
58
57
|
/** @param {FormData} form_data */
|
|
59
58
|
fn: async (form_data) => {
|
|
60
|
-
const event =
|
|
61
|
-
const state = get_event_state(event);
|
|
59
|
+
const { event, state } = get_request_store();
|
|
62
60
|
|
|
63
61
|
state.refreshes ??= {};
|
|
64
62
|
|
|
65
|
-
const result = await run_remote_function(event, true, form_data, (d) => d, fn);
|
|
63
|
+
const result = await run_remote_function(event, state, true, form_data, (d) => d, fn);
|
|
66
64
|
|
|
67
65
|
// We don't need to care about args or deduplicating calls, because uneval results are only relevant in full page reloads
|
|
68
66
|
// where only one form submission is active at the same time
|
|
@@ -89,7 +87,7 @@ export function form(fn) {
|
|
|
89
87
|
Object.defineProperty(instance, 'result', {
|
|
90
88
|
get() {
|
|
91
89
|
try {
|
|
92
|
-
const { remote_data } =
|
|
90
|
+
const { remote_data } = get_request_store().state;
|
|
93
91
|
return remote_data?.[__.id];
|
|
94
92
|
} catch {
|
|
95
93
|
return undefined;
|
|
@@ -111,7 +109,7 @@ export function form(fn) {
|
|
|
111
109
|
Object.defineProperty(instance, 'for', {
|
|
112
110
|
/** @type {RemoteForm<any>['for']} */
|
|
113
111
|
value: (key) => {
|
|
114
|
-
const state =
|
|
112
|
+
const { state } = get_request_store();
|
|
115
113
|
let instance = (state.form_instances ??= new Map()).get(key);
|
|
116
114
|
|
|
117
115
|
if (!instance) {
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
/** @import { StandardSchemaV1 } from '@standard-schema/spec' */
|
|
4
4
|
import { error, json } from '@sveltejs/kit';
|
|
5
5
|
import { DEV } from 'esm-env';
|
|
6
|
-
import {
|
|
6
|
+
import { get_request_store } from '@sveltejs/kit/internal/server';
|
|
7
7
|
import { create_remote_cache_key, stringify, stringify_remote_arg } from '../../../shared.js';
|
|
8
8
|
import { app_dir, base } from '__sveltekit/paths';
|
|
9
9
|
import {
|
|
@@ -13,7 +13,6 @@ import {
|
|
|
13
13
|
parse_remote_response,
|
|
14
14
|
run_remote_function
|
|
15
15
|
} from './shared.js';
|
|
16
|
-
import { get_event_state } from '../../../server/event-state.js';
|
|
17
16
|
|
|
18
17
|
/**
|
|
19
18
|
* Creates a remote prerender function. When called from the browser, the function will be invoked on the server via a `fetch` call.
|
|
@@ -93,15 +92,14 @@ export function prerender(validate_or_fn, fn_or_options, maybe_options) {
|
|
|
93
92
|
const wrapper = (arg) => {
|
|
94
93
|
/** @type {Promise<Output> & Partial<RemoteResource<Output>>} */
|
|
95
94
|
const promise = (async () => {
|
|
96
|
-
const event =
|
|
97
|
-
const state = get_event_state(event);
|
|
95
|
+
const { event, state } = get_request_store();
|
|
98
96
|
const payload = stringify_remote_arg(arg, state.transport);
|
|
99
97
|
const id = __.id;
|
|
100
98
|
const url = `${base}/${app_dir}/remote/${id}${payload ? `/${payload}` : ''}`;
|
|
101
99
|
|
|
102
100
|
if (!state.prerendering && !DEV && !event.isRemoteRequest) {
|
|
103
101
|
try {
|
|
104
|
-
return await get_response(id, arg,
|
|
102
|
+
return await get_response(id, arg, state, async () => {
|
|
105
103
|
// TODO adapters can provide prerendered data more efficiently than
|
|
106
104
|
// fetching from the public internet
|
|
107
105
|
const response = await fetch(new URL(url, event.url.origin).href);
|
|
@@ -130,8 +128,8 @@ export function prerender(validate_or_fn, fn_or_options, maybe_options) {
|
|
|
130
128
|
return /** @type {Promise<any>} */ (state.prerendering.remote_responses.get(url));
|
|
131
129
|
}
|
|
132
130
|
|
|
133
|
-
const promise = get_response(id, arg,
|
|
134
|
-
run_remote_function(event, false, arg, validate, fn)
|
|
131
|
+
const promise = get_response(id, arg, state, () =>
|
|
132
|
+
run_remote_function(event, state, false, arg, validate, fn)
|
|
135
133
|
);
|
|
136
134
|
|
|
137
135
|
if (state.prerendering) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/** @import { RemoteQuery, RemoteQueryFunction } from '@sveltejs/kit' */
|
|
2
2
|
/** @import { RemoteInfo, MaybePromise } from 'types' */
|
|
3
3
|
/** @import { StandardSchemaV1 } from '@standard-schema/spec' */
|
|
4
|
-
import {
|
|
4
|
+
import { get_request_store } from '@sveltejs/kit/internal/server';
|
|
5
5
|
import { create_remote_cache_key, stringify_remote_arg } from '../../../shared.js';
|
|
6
6
|
import { prerendering } from '__sveltekit/environment';
|
|
7
7
|
import {
|
|
@@ -10,7 +10,6 @@ import {
|
|
|
10
10
|
get_response,
|
|
11
11
|
run_remote_function
|
|
12
12
|
} from './shared.js';
|
|
13
|
-
import { get_event_state } from '../../../server/event-state.js';
|
|
14
13
|
|
|
15
14
|
/**
|
|
16
15
|
* Creates a remote query. When called from the browser, the function will be invoked on the server via a `fetch` call.
|
|
@@ -78,19 +77,18 @@ export function query(validate_or_fn, maybe_fn) {
|
|
|
78
77
|
);
|
|
79
78
|
}
|
|
80
79
|
|
|
81
|
-
const event =
|
|
80
|
+
const { event, state } = get_request_store();
|
|
82
81
|
|
|
83
82
|
/** @type {Promise<any> & Partial<RemoteQuery<any>>} */
|
|
84
|
-
const promise = get_response(__.id, arg,
|
|
85
|
-
run_remote_function(event, false, arg, validate, fn)
|
|
83
|
+
const promise = get_response(__.id, arg, state, () =>
|
|
84
|
+
run_remote_function(event, state, false, arg, validate, fn)
|
|
86
85
|
);
|
|
87
86
|
|
|
88
87
|
promise.catch(() => {});
|
|
89
88
|
|
|
90
89
|
promise.refresh = async () => {
|
|
91
|
-
const
|
|
92
|
-
const
|
|
93
|
-
const refreshes = state?.refreshes;
|
|
90
|
+
const { state } = get_request_store();
|
|
91
|
+
const refreshes = state.refreshes;
|
|
94
92
|
|
|
95
93
|
if (!refreshes) {
|
|
96
94
|
throw new Error(
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
/** @import { RequestEvent } from '@sveltejs/kit' */
|
|
2
|
-
/** @import { ServerHooks, MaybePromise } from 'types' */
|
|
2
|
+
/** @import { ServerHooks, MaybePromise, RequestState } from 'types' */
|
|
3
3
|
import { parse } from 'devalue';
|
|
4
4
|
import { error } from '@sveltejs/kit';
|
|
5
|
-
import {
|
|
5
|
+
import { with_request_store, get_request_store } from '@sveltejs/kit/internal/server';
|
|
6
6
|
import { create_remote_cache_key, stringify_remote_arg } from '../../../shared.js';
|
|
7
|
-
import { EVENT_STATE, get_event_state } from '../../../server/event-state.js';
|
|
8
7
|
|
|
9
8
|
/**
|
|
10
9
|
* @param {any} validate_or_fn
|
|
@@ -30,8 +29,7 @@ export function create_validator(validate_or_fn, maybe_fn) {
|
|
|
30
29
|
if ('~standard' in validate_or_fn) {
|
|
31
30
|
return async (arg) => {
|
|
32
31
|
// Get event before async validation to ensure it's available in server environments without AsyncLocalStorage, too
|
|
33
|
-
const event =
|
|
34
|
-
const state = get_event_state(event);
|
|
32
|
+
const { event, state } = get_request_store();
|
|
35
33
|
const validate = validate_or_fn['~standard'].validate;
|
|
36
34
|
|
|
37
35
|
const result = await validate(arg);
|
|
@@ -66,12 +64,11 @@ export function create_validator(validate_or_fn, maybe_fn) {
|
|
|
66
64
|
* @template {MaybePromise<any>} T
|
|
67
65
|
* @param {string} id
|
|
68
66
|
* @param {any} arg
|
|
69
|
-
* @param {
|
|
67
|
+
* @param {RequestState} state
|
|
70
68
|
* @param {() => Promise<T>} get_result
|
|
71
69
|
* @returns {Promise<T>}
|
|
72
70
|
*/
|
|
73
|
-
export function get_response(id, arg,
|
|
74
|
-
const state = get_event_state(event);
|
|
71
|
+
export function get_response(id, arg, state, get_result) {
|
|
75
72
|
const cache_key = create_remote_cache_key(id, stringify_remote_arg(arg, state.transport));
|
|
76
73
|
|
|
77
74
|
return ((state.remote_data ??= {})[cache_key] ??= get_result());
|
|
@@ -104,17 +101,16 @@ export function parse_remote_response(data, transport) {
|
|
|
104
101
|
* Like `with_event` but removes things from `event` you cannot see/call in remote functions, such as `setHeaders`.
|
|
105
102
|
* @template T
|
|
106
103
|
* @param {RequestEvent} event
|
|
104
|
+
* @param {RequestState} state
|
|
107
105
|
* @param {boolean} allow_cookies
|
|
108
106
|
* @param {any} arg
|
|
109
107
|
* @param {(arg: any) => any} validate
|
|
110
108
|
* @param {(arg?: any) => T} fn
|
|
111
109
|
*/
|
|
112
|
-
export async function run_remote_function(event, allow_cookies, arg, validate, fn) {
|
|
110
|
+
export async function run_remote_function(event, state, allow_cookies, arg, validate, fn) {
|
|
113
111
|
/** @type {RequestEvent} */
|
|
114
112
|
const cleansed = {
|
|
115
113
|
...event,
|
|
116
|
-
// @ts-expect-error this isn't part of the public `RequestEvent` type
|
|
117
|
-
[EVENT_STATE]: event[EVENT_STATE],
|
|
118
114
|
setHeaders: () => {
|
|
119
115
|
throw new Error('setHeaders is not allowed in remote functions');
|
|
120
116
|
},
|
|
@@ -148,6 +144,6 @@ export async function run_remote_function(event, allow_cookies, arg, validate, f
|
|
|
148
144
|
};
|
|
149
145
|
|
|
150
146
|
// In two parts, each with_event, so that runtimes without async local storage can still get the event at the start of the function
|
|
151
|
-
const validated = await
|
|
152
|
-
return
|
|
147
|
+
const validated = await with_request_store({ event: cleansed, state }, () => validate(arg));
|
|
148
|
+
return with_request_store({ event: cleansed, state }, () => fn(validated));
|
|
153
149
|
}
|
|
@@ -39,11 +39,17 @@ import {
|
|
|
39
39
|
} from './constants.js';
|
|
40
40
|
import { validate_page_exports } from '../../utils/exports.js';
|
|
41
41
|
import { compact } from '../../utils/array.js';
|
|
42
|
-
import {
|
|
42
|
+
import {
|
|
43
|
+
INVALIDATED_PARAM,
|
|
44
|
+
TRAILING_SLASH_PARAM,
|
|
45
|
+
validate_depends,
|
|
46
|
+
validate_load_response
|
|
47
|
+
} from '../shared.js';
|
|
43
48
|
import { get_message, get_status } from '../../utils/error.js';
|
|
44
49
|
import { writable } from 'svelte/store';
|
|
45
50
|
import { page, update, navigating } from './state.svelte.js';
|
|
46
51
|
import { add_data_suffix, add_resolution_suffix } from '../pathname.js';
|
|
52
|
+
import { noop_span } from '../telemetry/noop.js';
|
|
47
53
|
import { text_decoder } from '../utils.js';
|
|
48
54
|
|
|
49
55
|
export { load_css };
|
|
@@ -715,6 +721,7 @@ async function load_node({ loader, parent, url, params, route, server_data_node
|
|
|
715
721
|
|
|
716
722
|
/** @type {import('@sveltejs/kit').LoadEvent} */
|
|
717
723
|
const load_input = {
|
|
724
|
+
tracing: { enabled: false, root: noop_span, current: noop_span },
|
|
718
725
|
route: new Proxy(route, {
|
|
719
726
|
get: (target, key) => {
|
|
720
727
|
if (is_tracking) {
|
|
@@ -807,19 +814,7 @@ async function load_node({ loader, parent, url, params, route, server_data_node
|
|
|
807
814
|
try {
|
|
808
815
|
lock_fetch();
|
|
809
816
|
data = (await node.universal.load.call(null, load_input)) ?? null;
|
|
810
|
-
|
|
811
|
-
throw new Error(
|
|
812
|
-
`a load function related to route '${route.id}' returned ${
|
|
813
|
-
typeof data !== 'object'
|
|
814
|
-
? `a ${typeof data}`
|
|
815
|
-
: data instanceof Response
|
|
816
|
-
? 'a Response object'
|
|
817
|
-
: Array.isArray(data)
|
|
818
|
-
? 'an array'
|
|
819
|
-
: 'a non-plain object'
|
|
820
|
-
}, but must return a plain object at the top level (i.e. \`return {...}\`)`
|
|
821
|
-
);
|
|
822
|
-
}
|
|
817
|
+
validate_load_response(data, `related to route '${route.id}'`);
|
|
823
818
|
} finally {
|
|
824
819
|
unlock_fetch();
|
|
825
820
|
}
|
|
@@ -11,6 +11,7 @@ import { text_encoder } from '../../utils.js';
|
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* @param {import('@sveltejs/kit').RequestEvent} event
|
|
14
|
+
* @param {import('types').RequestState} event_state
|
|
14
15
|
* @param {import('types').SSRRoute} route
|
|
15
16
|
* @param {import('types').SSROptions} options
|
|
16
17
|
* @param {import('@sveltejs/kit').SSRManifest} manifest
|
|
@@ -21,6 +22,7 @@ import { text_encoder } from '../../utils.js';
|
|
|
21
22
|
*/
|
|
22
23
|
export async function render_data(
|
|
23
24
|
event,
|
|
25
|
+
event_state,
|
|
24
26
|
route,
|
|
25
27
|
options,
|
|
26
28
|
manifest,
|
|
@@ -60,6 +62,7 @@ export async function render_data(
|
|
|
60
62
|
// load this. for the child, return as is. for the final result, stream things
|
|
61
63
|
return load_server_data({
|
|
62
64
|
event: new_event,
|
|
65
|
+
event_state,
|
|
63
66
|
state,
|
|
64
67
|
node,
|
|
65
68
|
parent: async () => {
|
|
@@ -107,7 +110,7 @@ export async function render_data(
|
|
|
107
110
|
|
|
108
111
|
return /** @type {import('types').ServerErrorNode} */ ({
|
|
109
112
|
type: 'error',
|
|
110
|
-
error: await handle_error_and_jsonify(event, options, error),
|
|
113
|
+
error: await handle_error_and_jsonify(event, event_state, options, error),
|
|
111
114
|
status:
|
|
112
115
|
error instanceof HttpError || error instanceof SvelteKitError
|
|
113
116
|
? error.status
|
|
@@ -117,7 +120,7 @@ export async function render_data(
|
|
|
117
120
|
)
|
|
118
121
|
);
|
|
119
122
|
|
|
120
|
-
const { data, chunks } = get_data_json(event, options, nodes);
|
|
123
|
+
const { data, chunks } = get_data_json(event, event_state, options, nodes);
|
|
121
124
|
|
|
122
125
|
if (!chunks) {
|
|
123
126
|
// use a normal JSON response where possible, so we get `content-length`
|
|
@@ -152,7 +155,7 @@ export async function render_data(
|
|
|
152
155
|
if (error instanceof Redirect) {
|
|
153
156
|
return redirect_json_response(error);
|
|
154
157
|
} else {
|
|
155
|
-
return json_response(await handle_error_and_jsonify(event, options, error), 500);
|
|
158
|
+
return json_response(await handle_error_and_jsonify(event, event_state, options, error), 500);
|
|
156
159
|
}
|
|
157
160
|
}
|
|
158
161
|
}
|
|
@@ -187,11 +190,12 @@ export function redirect_json_response(redirect) {
|
|
|
187
190
|
* If the serialized data contains promises, `chunks` will be an
|
|
188
191
|
* async iterable containing their resolutions
|
|
189
192
|
* @param {import('@sveltejs/kit').RequestEvent} event
|
|
193
|
+
* @param {import('types').RequestState} event_state
|
|
190
194
|
* @param {import('types').SSROptions} options
|
|
191
195
|
* @param {Array<import('types').ServerDataSkippedNode | import('types').ServerDataNode | import('types').ServerErrorNode | null | undefined>} nodes
|
|
192
196
|
* @returns {{ data: string, chunks: AsyncIterable<string> | null }}
|
|
193
197
|
*/
|
|
194
|
-
export function get_data_json(event, options, nodes) {
|
|
198
|
+
export function get_data_json(event, event_state, options, nodes) {
|
|
195
199
|
let promise_id = 1;
|
|
196
200
|
let count = 0;
|
|
197
201
|
|
|
@@ -214,7 +218,7 @@ export function get_data_json(event, options, nodes) {
|
|
|
214
218
|
.catch(
|
|
215
219
|
/** @param {any} e */ async (e) => {
|
|
216
220
|
key = 'error';
|
|
217
|
-
return handle_error_and_jsonify(event, options, /** @type {any} */ (e));
|
|
221
|
+
return handle_error_and_jsonify(event, event_state, options, /** @type {any} */ (e));
|
|
218
222
|
}
|
|
219
223
|
)
|
|
220
224
|
.then(
|
|
@@ -226,6 +230,7 @@ export function get_data_json(event, options, nodes) {
|
|
|
226
230
|
} catch {
|
|
227
231
|
const error = await handle_error_and_jsonify(
|
|
228
232
|
event,
|
|
233
|
+
event_state,
|
|
229
234
|
options,
|
|
230
235
|
new Error(`Failed to serialize promise while rendering ${event.route.id}`)
|
|
231
236
|
);
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import { Redirect } from '@sveltejs/kit/internal';
|
|
2
|
+
import { with_request_store } from '@sveltejs/kit/internal/server';
|
|
2
3
|
import { ENDPOINT_METHODS, PAGE_METHODS } from '../../constants.js';
|
|
3
4
|
import { negotiate } from '../../utils/http.js';
|
|
4
|
-
import { with_event } from '../app/server/event.js';
|
|
5
5
|
import { method_not_allowed } from './utils.js';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* @param {import('@sveltejs/kit').RequestEvent} event
|
|
9
|
+
* @param {import('types').RequestState} event_state
|
|
9
10
|
* @param {import('types').SSREndpoint} mod
|
|
10
11
|
* @param {import('types').SSRState} state
|
|
11
12
|
* @returns {Promise<Response>}
|
|
12
13
|
*/
|
|
13
|
-
export async function render_endpoint(event, mod, state) {
|
|
14
|
+
export async function render_endpoint(event, event_state, mod, state) {
|
|
14
15
|
const method = /** @type {import('types').HttpMethod} */ (event.request.method);
|
|
15
16
|
|
|
16
17
|
let handler = mod[method] || mod.fallback;
|
|
@@ -41,7 +42,7 @@ export async function render_endpoint(event, mod, state) {
|
|
|
41
42
|
}
|
|
42
43
|
|
|
43
44
|
try {
|
|
44
|
-
const response = await
|
|
45
|
+
const response = await with_request_store({ event, state: event_state }, () =>
|
|
45
46
|
handler(/** @type {import('@sveltejs/kit').RequestEvent<Record<string, any>>} */ (event))
|
|
46
47
|
);
|
|
47
48
|
|