@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
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
/** @import { Component } from 'svelte'; */
|
|
1
2
|
import * as devalue from 'devalue';
|
|
2
|
-
import { readable, writable } from 'svelte/store';
|
|
3
3
|
import { DEV } from 'esm-env';
|
|
4
4
|
import { isRedirect, text } from '@sveltejs/kit';
|
|
5
|
-
import * as paths from '
|
|
5
|
+
import * as paths from '#app/paths';
|
|
6
|
+
import { relative } from '$app/paths/internal/server';
|
|
6
7
|
import { hash } from '../../../utils/hash.js';
|
|
7
8
|
import { serialize_data } from './serialize_data.js';
|
|
8
9
|
import { s } from '../../../utils/misc.js';
|
|
@@ -11,26 +12,24 @@ import { uneval_action_response } from './actions.js';
|
|
|
11
12
|
import { SVELTE_KIT_ASSETS } from '../../../constants.js';
|
|
12
13
|
import { SCHEME } from '../../../utils/url.js';
|
|
13
14
|
import { create_server_routing_response, generate_route_object } from './server_routing.js';
|
|
14
|
-
import {
|
|
15
|
+
import {
|
|
16
|
+
add_data_suffix,
|
|
17
|
+
add_resolution_suffix,
|
|
18
|
+
route_id_resolution_pathname
|
|
19
|
+
} from '../../pathname.js';
|
|
15
20
|
import { try_get_request_store, with_request_store } from '@sveltejs/kit/internal/server';
|
|
16
21
|
import { text_encoder } from '../../utils.js';
|
|
17
|
-
import {
|
|
18
|
-
|
|
19
|
-
create_replacer,
|
|
20
|
-
get_global_name,
|
|
21
|
-
handle_error_and_jsonify
|
|
22
|
-
} from '../utils.js';
|
|
23
|
-
import { create_remote_key } from '../../shared.js';
|
|
24
|
-
import { get_status } from '../../../utils/error.js';
|
|
22
|
+
import { count_non_ssi_comments, get_global_name } from '../utils.js';
|
|
23
|
+
import { handle_error_and_jsonify } from '../errors.js';
|
|
25
24
|
import * as env from '__sveltekit/env';
|
|
25
|
+
import { collect_remote_data } from '../remote-functions.js';
|
|
26
|
+
import Root from '../../components/root.svelte';
|
|
27
|
+
import { render } from 'svelte/server';
|
|
28
|
+
import { Props, RenderNode } from '../../props.svelte.js';
|
|
29
|
+
import { has_custom_transporters, uneval } from '#app/internal/transport';
|
|
26
30
|
|
|
27
31
|
// TODO rename this function/module
|
|
28
32
|
|
|
29
|
-
const updated = {
|
|
30
|
-
...readable(false),
|
|
31
|
-
check: () => false
|
|
32
|
-
};
|
|
33
|
-
|
|
34
33
|
/**
|
|
35
34
|
* Creates the HTML response.
|
|
36
35
|
* @param {{
|
|
@@ -38,16 +37,15 @@ const updated = {
|
|
|
38
37
|
* fetched: Array<import('./types.js').Fetched>;
|
|
39
38
|
* options: import('types').SSROptions;
|
|
40
39
|
* manifest: import('@sveltejs/kit').SSRManifest;
|
|
41
|
-
* state: import('types').SSRState;
|
|
42
40
|
* page_config: { ssr: boolean; csr: boolean };
|
|
43
41
|
* status: number;
|
|
44
42
|
* error: App.Error | null;
|
|
45
|
-
* event: import('
|
|
46
|
-
*
|
|
43
|
+
* event: import('$app/server').RequestEvent;
|
|
44
|
+
* state: import('types').RequestState;
|
|
47
45
|
* resolve_opts: import('types').RequiredResolveOptions;
|
|
48
|
-
* action_result?: import('
|
|
46
|
+
* action_result?: import('$app/forms').ActionResult;
|
|
49
47
|
* data_serializer: import('./types.js').ServerDataSerializer;
|
|
50
|
-
* error_components?: Array<import('
|
|
48
|
+
* error_components?: Array<import('svelte').Component | undefined>
|
|
51
49
|
* }} opts
|
|
52
50
|
*/
|
|
53
51
|
export async function render_response({
|
|
@@ -55,20 +53,19 @@ export async function render_response({
|
|
|
55
53
|
fetched,
|
|
56
54
|
options,
|
|
57
55
|
manifest,
|
|
58
|
-
state,
|
|
59
56
|
page_config,
|
|
60
57
|
status,
|
|
61
58
|
error = null,
|
|
62
59
|
event,
|
|
63
|
-
|
|
60
|
+
state,
|
|
64
61
|
resolve_opts,
|
|
65
62
|
action_result,
|
|
66
63
|
data_serializer,
|
|
67
64
|
error_components
|
|
68
65
|
}) {
|
|
69
|
-
if (state.prerendering) {
|
|
66
|
+
if (state.prerendering || state.prerender_default === true) {
|
|
70
67
|
if (options.csp.mode === 'nonce') {
|
|
71
|
-
throw new Error('Cannot use prerendering if config.
|
|
68
|
+
throw new Error('Cannot use prerendering if config.csp.mode === "nonce"');
|
|
72
69
|
}
|
|
73
70
|
|
|
74
71
|
if (options.app_template_contains_nonce) {
|
|
@@ -78,9 +75,9 @@ export async function render_response({
|
|
|
78
75
|
|
|
79
76
|
const { client } = manifest._;
|
|
80
77
|
|
|
81
|
-
const modulepreloads = new Set(client
|
|
82
|
-
const stylesheets = new Set(client
|
|
83
|
-
const fonts = new Set(client
|
|
78
|
+
const modulepreloads = new Set(client?.imports);
|
|
79
|
+
const stylesheets = new Set(client?.stylesheets);
|
|
80
|
+
const fonts = new Set(client?.fonts);
|
|
84
81
|
|
|
85
82
|
/**
|
|
86
83
|
* The value of the Link header that is added to the response when not prerendering
|
|
@@ -92,7 +89,8 @@ export async function render_response({
|
|
|
92
89
|
// TODO if we add a client entry point one day, we will need to include inline_styles with the entry, otherwise stylesheets will be linked even if they are below inlineStyleThreshold
|
|
93
90
|
const inline_styles = new Map();
|
|
94
91
|
|
|
95
|
-
|
|
92
|
+
// TODO `svelte/server` should expose `RenderOutput`
|
|
93
|
+
/** @type {{ head: string, body: string, hashes: { script: string[] } }} */
|
|
96
94
|
let rendered;
|
|
97
95
|
|
|
98
96
|
const form_value =
|
|
@@ -113,13 +111,18 @@ export async function render_response({
|
|
|
113
111
|
let base_expression = s(paths.base);
|
|
114
112
|
|
|
115
113
|
const csp = new Csp(options.csp, {
|
|
116
|
-
prerender: !!state.prerendering
|
|
114
|
+
prerender: !!(state.prerendering || state.prerender_default === true)
|
|
117
115
|
});
|
|
118
116
|
|
|
119
117
|
// if appropriate, use relative paths for greater portability
|
|
120
|
-
if (
|
|
118
|
+
if (relative) {
|
|
121
119
|
if (!state.prerendering?.fallback) {
|
|
122
|
-
|
|
120
|
+
// the relative path depth must reflect the URL the browser is actually at, which
|
|
121
|
+
// for a data request includes the `__data.json` suffix that was stripped during routing
|
|
122
|
+
const pathname = event.isDataRequest
|
|
123
|
+
? add_data_suffix(event.url.pathname)
|
|
124
|
+
: event.url.pathname;
|
|
125
|
+
const segments = pathname.slice(paths.base.length).split('/').slice(2);
|
|
123
126
|
|
|
124
127
|
base = segments.map(() => '..').join('/') || '.';
|
|
125
128
|
|
|
@@ -136,52 +139,52 @@ export async function render_response({
|
|
|
136
139
|
}
|
|
137
140
|
|
|
138
141
|
if (page_config.ssr) {
|
|
139
|
-
|
|
140
|
-
const props = {
|
|
141
|
-
stores: {
|
|
142
|
-
page: writable(null),
|
|
143
|
-
navigating: writable(null),
|
|
144
|
-
updated
|
|
145
|
-
},
|
|
146
|
-
constructors: await Promise.all(
|
|
147
|
-
branch.map(({ node }) => {
|
|
148
|
-
if (!node.component) {
|
|
149
|
-
// Can only be the leaf, layouts have a fallback component generated
|
|
150
|
-
throw new Error(`Missing +page.svelte component for route ${event.route.id}`);
|
|
151
|
-
}
|
|
152
|
-
return node.component();
|
|
153
|
-
})
|
|
154
|
-
),
|
|
155
|
-
form: form_value
|
|
156
|
-
};
|
|
157
|
-
|
|
158
|
-
if (error_components) {
|
|
159
|
-
if (error) {
|
|
160
|
-
props.error = error;
|
|
161
|
-
}
|
|
162
|
-
props.errors = error_components;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
let data = {};
|
|
166
|
-
|
|
167
|
-
// props_n (instead of props[n]) makes it easy to avoid
|
|
168
|
-
// unnecessary updates for layout components
|
|
169
|
-
for (let i = 0; i < branch.length; i += 1) {
|
|
170
|
-
data = { ...data, ...branch[i].data };
|
|
171
|
-
props[`data_${i}`] = data;
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
props.page = {
|
|
142
|
+
const page = {
|
|
175
143
|
error,
|
|
176
144
|
params: /** @type {Record<string, any>} */ (event.params),
|
|
177
145
|
route: event.route,
|
|
178
146
|
status,
|
|
179
147
|
url: event.url,
|
|
180
|
-
data,
|
|
148
|
+
data: {},
|
|
181
149
|
form: form_value,
|
|
150
|
+
shallow: null,
|
|
182
151
|
state: {}
|
|
183
152
|
};
|
|
184
153
|
|
|
154
|
+
const props = new Props({
|
|
155
|
+
page,
|
|
156
|
+
tree: new RenderNode(
|
|
157
|
+
// TODO tidy up
|
|
158
|
+
/** @type {Component} */ (await branch[0].node.component?.()),
|
|
159
|
+
/** @type {Component} */ (error_components?.[1])
|
|
160
|
+
),
|
|
161
|
+
form: form_value,
|
|
162
|
+
error: error ?? undefined
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
let current_node = props.tree;
|
|
166
|
+
let data = props.page.data;
|
|
167
|
+
|
|
168
|
+
for (let i = 0; i < branch.length; i += 1) {
|
|
169
|
+
const node = branch[i];
|
|
170
|
+
|
|
171
|
+
data = { ...data, ...node.data };
|
|
172
|
+
|
|
173
|
+
current_node.data = data;
|
|
174
|
+
|
|
175
|
+
if (i < branch.length - 1) {
|
|
176
|
+
current_node = current_node.child = new RenderNode(
|
|
177
|
+
// TODO tidy up
|
|
178
|
+
/** @type {Component} */ (await branch[i + 1].node.component?.()),
|
|
179
|
+
/** @type {Component} */ (error_components?.slice(0, i + 2).findLast((x) => x))
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
props.page.data = data;
|
|
185
|
+
|
|
186
|
+
const render_state = { ...state, is_in_render: true };
|
|
187
|
+
|
|
185
188
|
const render_opts = {
|
|
186
189
|
context: new Map([
|
|
187
190
|
[
|
|
@@ -193,15 +196,28 @@ export async function render_response({
|
|
|
193
196
|
]),
|
|
194
197
|
csp: csp.script_needs_nonce ? { nonce: csp.nonce } : { hash: csp.script_needs_hash },
|
|
195
198
|
transformError: error_components
|
|
196
|
-
? /** @param {unknown} e */
|
|
199
|
+
? /** @param {unknown} e */ (e) => {
|
|
197
200
|
if (isRedirect(e)) {
|
|
198
201
|
throw e;
|
|
199
202
|
}
|
|
200
203
|
|
|
201
|
-
const
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
204
|
+
const handled = handle_error_and_jsonify(event, render_state, options, e);
|
|
205
|
+
|
|
206
|
+
// TODO 4.0 make this an async function and await `handled`
|
|
207
|
+
if (handled instanceof Promise) {
|
|
208
|
+
return handled.then((e) => {
|
|
209
|
+
error = e;
|
|
210
|
+
props.page.error = error;
|
|
211
|
+
props.page.status = status = error.status;
|
|
212
|
+
return error;
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
error = handled;
|
|
217
|
+
props.page.error = error;
|
|
218
|
+
props.page.status = status = error.status;
|
|
219
|
+
|
|
220
|
+
return error;
|
|
205
221
|
}
|
|
206
222
|
: undefined
|
|
207
223
|
};
|
|
@@ -227,53 +243,27 @@ export async function render_response({
|
|
|
227
243
|
};
|
|
228
244
|
}
|
|
229
245
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
rendered = await with_request_store({ event, state }, async () => {
|
|
233
|
-
// use relative paths during rendering, so that the resulting HTML is as
|
|
234
|
-
// portable as possible, but reset afterwards
|
|
235
|
-
if (paths.relative) paths.override({ base, assets });
|
|
236
|
-
|
|
237
|
-
const maybe_promise = options.root.render(props, render_opts);
|
|
246
|
+
rendered = await with_request_store({ event, state: render_state }, async () => {
|
|
238
247
|
// We have to invoke .then eagerly here in order to kick off rendering: it's only starting on access,
|
|
239
248
|
// and `await maybe_promise` would eagerly access the .then property but call its function only after a tick, which is too late
|
|
240
249
|
// for the paths.reset() below and for any eager getRequestEvent() calls during rendering without AsyncLocalStorage available.
|
|
241
|
-
const rendered =
|
|
242
|
-
options.async && 'then' in maybe_promise
|
|
243
|
-
? /** @type {ReturnType<typeof options.root.render> & Promise<any>} */ (
|
|
244
|
-
maybe_promise
|
|
245
|
-
).then((r) => r)
|
|
246
|
-
: maybe_promise;
|
|
247
|
-
|
|
248
|
-
// TODO 3.0 remove options.async
|
|
249
|
-
if (options.async) {
|
|
250
|
-
// we reset this synchronously, rather than after async rendering is complete,
|
|
251
|
-
// to avoid cross-talk between requests. This is a breaking change for
|
|
252
|
-
// anyone who opts into async SSR, since `base` and `assets` will no
|
|
253
|
-
// longer be relative to the current pathname.
|
|
254
|
-
// TODO 3.0 remove `base` and `assets` in favour of `resolve(...)` and `asset(...)`
|
|
255
|
-
paths.reset();
|
|
256
|
-
}
|
|
250
|
+
const rendered = render(Root, { ...render_opts, props });
|
|
257
251
|
|
|
258
|
-
const { head,
|
|
259
|
-
options.async ? await rendered : rendered
|
|
260
|
-
);
|
|
252
|
+
const { head, body, hashes } = await rendered;
|
|
261
253
|
|
|
262
254
|
if (hashes) {
|
|
263
255
|
csp.add_script_hashes(hashes.script);
|
|
264
256
|
}
|
|
265
257
|
|
|
266
|
-
return { head,
|
|
258
|
+
return { head, body, hashes };
|
|
267
259
|
});
|
|
268
260
|
} finally {
|
|
269
261
|
if (DEV) {
|
|
270
262
|
globalThis.fetch = fetch;
|
|
271
263
|
}
|
|
272
|
-
|
|
273
|
-
paths.reset(); // just in case `options.root.render(...)` failed
|
|
274
264
|
}
|
|
275
265
|
} else {
|
|
276
|
-
rendered = { head: '',
|
|
266
|
+
rendered = { head: '', body: '', hashes: { script: [] } };
|
|
277
267
|
}
|
|
278
268
|
|
|
279
269
|
for (const { node } of branch) {
|
|
@@ -281,7 +271,7 @@ export async function render_response({
|
|
|
281
271
|
for (const url of node.stylesheets) stylesheets.add(url);
|
|
282
272
|
for (const url of node.fonts) fonts.add(url);
|
|
283
273
|
|
|
284
|
-
if (node.inline_styles && !client
|
|
274
|
+
if (node.inline_styles && !client?.inline) {
|
|
285
275
|
Object.entries(await node.inline_styles()).forEach(([filename, css]) => {
|
|
286
276
|
if (typeof css === 'string') {
|
|
287
277
|
inline_styles.set(filename, css);
|
|
@@ -294,7 +284,7 @@ export async function render_response({
|
|
|
294
284
|
}
|
|
295
285
|
|
|
296
286
|
const head = new Head(rendered.head);
|
|
297
|
-
let body = rendered.
|
|
287
|
+
let body = rendered.body;
|
|
298
288
|
|
|
299
289
|
/** @param {string} path */
|
|
300
290
|
const prefixed = (path) => {
|
|
@@ -307,7 +297,7 @@ export async function render_response({
|
|
|
307
297
|
return `${assets}/${path}`;
|
|
308
298
|
};
|
|
309
299
|
|
|
310
|
-
const style = client
|
|
300
|
+
const style = client?.inline
|
|
311
301
|
? client.inline?.style
|
|
312
302
|
: Array.from(inline_styles.values()).join('\n');
|
|
313
303
|
|
|
@@ -321,6 +311,19 @@ export async function render_response({
|
|
|
321
311
|
head.add_style(style, attributes);
|
|
322
312
|
}
|
|
323
313
|
|
|
314
|
+
/**
|
|
315
|
+
* see the `output.linkHeaderPreload` option for details on why we have multiple options here
|
|
316
|
+
* @param {string} path
|
|
317
|
+
* @param {string[]} attributes
|
|
318
|
+
*/
|
|
319
|
+
const add_preload = (path, attributes) => {
|
|
320
|
+
if (options.link_header_preload && !(state.prerendering || state.prerender_default === true)) {
|
|
321
|
+
link_headers.add(`<${encodeURI(path)}>; ${attributes.join('; ')}; nopush`);
|
|
322
|
+
} else {
|
|
323
|
+
head.add_link_tag(path, attributes);
|
|
324
|
+
}
|
|
325
|
+
};
|
|
326
|
+
|
|
324
327
|
for (const dep of stylesheets) {
|
|
325
328
|
const path = prefixed(dep);
|
|
326
329
|
|
|
@@ -345,18 +348,7 @@ export async function render_response({
|
|
|
345
348
|
if (resolve_opts.preload({ type: 'font', path })) {
|
|
346
349
|
const ext = dep.slice(dep.lastIndexOf('.') + 1);
|
|
347
350
|
|
|
348
|
-
|
|
349
|
-
link_headers.add(
|
|
350
|
-
`<${encodeURI(path)}>; rel="preload"; as="font"; type="font/${ext}"; crossorigin; nopush`
|
|
351
|
-
);
|
|
352
|
-
} else {
|
|
353
|
-
head.add_link_tag(path, [
|
|
354
|
-
'rel="preload"',
|
|
355
|
-
'as="font"',
|
|
356
|
-
`type="font/${ext}"`,
|
|
357
|
-
'crossorigin'
|
|
358
|
-
]);
|
|
359
|
-
}
|
|
351
|
+
add_preload(path, ['rel="preload"', 'as="font"', `type="font/${ext}"`, 'crossorigin']);
|
|
360
352
|
}
|
|
361
353
|
}
|
|
362
354
|
|
|
@@ -366,58 +358,66 @@ export async function render_response({
|
|
|
366
358
|
if (page_config.ssr && page_config.csr) {
|
|
367
359
|
body += `\n\t\t\t${fetched
|
|
368
360
|
.map((item) =>
|
|
369
|
-
serialize_data(
|
|
361
|
+
serialize_data(
|
|
362
|
+
item,
|
|
363
|
+
resolve_opts.filterSerializedResponseHeaders,
|
|
364
|
+
!!(state.prerendering || state.prerender_default === true)
|
|
365
|
+
)
|
|
370
366
|
)
|
|
371
367
|
.join('\n\t\t\t')}`;
|
|
372
368
|
}
|
|
373
369
|
|
|
374
|
-
if (page_config.csr) {
|
|
375
|
-
const route =
|
|
370
|
+
if (page_config.csr && client) {
|
|
371
|
+
const route = client.routes?.find((r) => r.id === event.route.id) ?? null;
|
|
372
|
+
|
|
373
|
+
// when serving a prerendered page in an app that uses runtime public env vars, we must
|
|
374
|
+
// import the env.js module so that it evaluates before any user code can evaluate.
|
|
375
|
+
// TODO revert to using top-level await once https://bugs.webkit.org/show_bug.cgi?id=242740 is fixed
|
|
376
|
+
// https://github.com/sveltejs/kit/pull/11601
|
|
377
|
+
const load_env_eagerly =
|
|
378
|
+
client.uses_env_dynamic_public && (state.prerendering || state.prerender_default === true);
|
|
376
379
|
|
|
377
|
-
if (
|
|
380
|
+
if (load_env_eagerly) {
|
|
378
381
|
modulepreloads.add(`${paths.app_dir}/env.js`);
|
|
379
382
|
}
|
|
380
383
|
|
|
381
384
|
if (!client.inline) {
|
|
382
|
-
const
|
|
383
|
-
|
|
384
|
-
);
|
|
385
|
+
for (const dep of modulepreloads) {
|
|
386
|
+
const path = prefixed(dep);
|
|
385
387
|
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
// see the kit.output.preloadStrategy option for details on why we have multiple options here
|
|
390
|
-
if (options.link_header_preload && !state.prerendering) {
|
|
391
|
-
add_preload = (path) =>
|
|
392
|
-
link_headers.add(`<${encodeURI(path)}>; rel="modulepreload"; nopush`);
|
|
393
|
-
} else {
|
|
394
|
-
add_preload = (path) => head.add_link_tag(path, ['rel="modulepreload"']);
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
for (const path of included_modulepreloads) {
|
|
398
|
-
add_preload(path);
|
|
388
|
+
if (resolve_opts.preload({ type: 'js', path })) {
|
|
389
|
+
add_preload(path, ['rel="modulepreload"']);
|
|
390
|
+
}
|
|
399
391
|
}
|
|
400
392
|
}
|
|
401
393
|
|
|
402
394
|
// prerender a `/path/to/page/__route.js` module
|
|
403
|
-
if (
|
|
395
|
+
if (client.routes && state.prerendering && !state.prerendering.fallback) {
|
|
404
396
|
const pathname = add_resolution_suffix(event.url.pathname);
|
|
405
397
|
|
|
406
398
|
state.prerendering.dependencies.set(
|
|
407
399
|
pathname,
|
|
408
|
-
create_server_routing_response(route, event.params, new URL(pathname, event.url),
|
|
400
|
+
create_server_routing_response(route, event.params, new URL(pathname, event.url), client)
|
|
409
401
|
);
|
|
402
|
+
|
|
403
|
+
// Prerender a route-ID-keyed `/_app/routes/<id>/__route.js` module alongside the
|
|
404
|
+
// pathname-keyed one above, so that `preloadCode(id)` can resolve a route ID without
|
|
405
|
+
// hitting the server.
|
|
406
|
+
if (route && !state.prerendering.resolved_route_ids.has(route.id)) {
|
|
407
|
+
state.prerendering.resolved_route_ids.add(route.id);
|
|
408
|
+
|
|
409
|
+
const id_pathname = paths.base + route_id_resolution_pathname(route.id);
|
|
410
|
+
|
|
411
|
+
state.prerendering.dependencies.set(
|
|
412
|
+
id_pathname,
|
|
413
|
+
create_server_routing_response(route, null, new URL(id_pathname, event.url), client)
|
|
414
|
+
);
|
|
415
|
+
}
|
|
410
416
|
}
|
|
411
417
|
|
|
412
418
|
const blocks = [];
|
|
413
419
|
|
|
414
|
-
|
|
415
|
-
// import the env.js module so that it evaluates before any user code can evaluate.
|
|
416
|
-
// TODO revert to using top-level await once https://bugs.webkit.org/show_bug.cgi?id=242740 is fixed
|
|
417
|
-
// https://github.com/sveltejs/kit/pull/11601
|
|
418
|
-
const load_env_eagerly = client.uses_env_dynamic_public && state.prerendering; // TODO implement uses_env_dynamic_public
|
|
419
|
-
|
|
420
|
-
const properties = [`base: ${base_expression}`];
|
|
420
|
+
const properties = [`base: ${base_expression}`, `version: ${s(__SVELTEKIT_APP_VERSION__)}`];
|
|
421
421
|
|
|
422
422
|
if (paths.assets) {
|
|
423
423
|
properties.push(`assets: ${s(paths.assets)}`);
|
|
@@ -436,11 +436,13 @@ export async function render_response({
|
|
|
436
436
|
|
|
437
437
|
let app_declaration = '';
|
|
438
438
|
|
|
439
|
-
if (
|
|
439
|
+
if (has_custom_transporters) {
|
|
440
440
|
if (client.inline) {
|
|
441
|
-
app_declaration = `const app =
|
|
441
|
+
app_declaration = `const app = ${global}.app.app;`;
|
|
442
442
|
} else if (client.app) {
|
|
443
|
-
app_declaration = `const
|
|
443
|
+
app_declaration = `const kit = await import(${s(prefixed(client.start))});
|
|
444
|
+
kit.init(${global});
|
|
445
|
+
const app = await import(${s(prefixed(client.app))});`;
|
|
444
446
|
} else {
|
|
445
447
|
app_declaration = `const { app } = await import(${s(prefixed(client.start))});`;
|
|
446
448
|
}
|
|
@@ -485,8 +487,7 @@ export async function render_response({
|
|
|
485
487
|
if (form_value) {
|
|
486
488
|
serialized.form = uneval_action_response(
|
|
487
489
|
form_value,
|
|
488
|
-
/** @type {string} */ (event.route.id)
|
|
489
|
-
options.hooks.transport
|
|
490
|
+
/** @type {string} */ (event.route.id)
|
|
490
491
|
);
|
|
491
492
|
}
|
|
492
493
|
|
|
@@ -501,13 +502,13 @@ export async function render_response({
|
|
|
501
502
|
`error: ${serialized.error}`
|
|
502
503
|
];
|
|
503
504
|
|
|
504
|
-
if (status !== 200) {
|
|
505
|
+
if (status !== 200 && !error) {
|
|
505
506
|
hydrate.push(`status: ${status}`);
|
|
506
507
|
}
|
|
507
508
|
|
|
508
|
-
if (
|
|
509
|
+
if (client.routes) {
|
|
509
510
|
if (route) {
|
|
510
|
-
const stringified = generate_route_object(route, event.url,
|
|
511
|
+
const stringified = generate_route_object(route, event.url, client).replaceAll(
|
|
511
512
|
'\n',
|
|
512
513
|
'\n\t\t\t\t\t\t\t'
|
|
513
514
|
); // make output after it's put together with the rest more readable
|
|
@@ -521,87 +522,26 @@ export async function render_response({
|
|
|
521
522
|
args.push(`{\n${indent}\t${hydrate.join(`,\n${indent}\t`)}\n${indent}}`);
|
|
522
523
|
}
|
|
523
524
|
|
|
524
|
-
const
|
|
525
|
-
|
|
526
|
-
let serialized_query_data = '';
|
|
527
|
-
let serialized_prerender_data = '';
|
|
528
|
-
|
|
529
|
-
if (remote.data) {
|
|
530
|
-
/** @type {Record<string, any>} */
|
|
531
|
-
const query = {};
|
|
532
|
-
|
|
533
|
-
/** @type {Record<string, any>} */
|
|
534
|
-
const prerender = {};
|
|
535
|
-
|
|
536
|
-
for (const [internals, cache] of remote.data) {
|
|
537
|
-
// remote functions without an `id` aren't exported, and thus
|
|
538
|
-
// cannot be called from the client
|
|
539
|
-
if (!internals.id) continue;
|
|
540
|
-
|
|
541
|
-
for (const key in cache) {
|
|
542
|
-
const entry = cache[key];
|
|
543
|
-
|
|
544
|
-
if (!entry.serialize) continue;
|
|
545
|
-
|
|
546
|
-
const remote_key = create_remote_key(internals.id, key);
|
|
547
|
-
|
|
548
|
-
const store = internals.type === 'prerender' ? prerender : query;
|
|
549
|
-
|
|
550
|
-
if (
|
|
551
|
-
event_state.remote.refreshes?.has(remote_key) ||
|
|
552
|
-
event_state.remote.reconnects?.has(remote_key)
|
|
553
|
-
) {
|
|
554
|
-
// This entry was refreshed/set by a command or form action.
|
|
555
|
-
// Always await it so the mutation result is serialized.
|
|
556
|
-
store[remote_key] = await entry.data;
|
|
557
|
-
} else {
|
|
558
|
-
// Don't block the response on pending remote data - if a query
|
|
559
|
-
// hasn't settled yet, it wasn't awaited in the template (or is behind a pending boundary).
|
|
560
|
-
const result = await Promise.race([
|
|
561
|
-
Promise.resolve(entry.data).then(
|
|
562
|
-
(v) => /** @type {const} */ ({ settled: true, value: v }),
|
|
563
|
-
(e) => /** @type {const} */ ({ settled: true, error: e })
|
|
564
|
-
),
|
|
565
|
-
new Promise((resolve) => {
|
|
566
|
-
queueMicrotask(() => resolve(/** @type {const} */ ({ settled: false })));
|
|
567
|
-
})
|
|
568
|
-
]);
|
|
569
|
-
|
|
570
|
-
if (result.settled) {
|
|
571
|
-
if ('error' in result) throw result.error;
|
|
572
|
-
store[remote_key] = result.value;
|
|
573
|
-
}
|
|
574
|
-
}
|
|
575
|
-
}
|
|
576
|
-
}
|
|
525
|
+
const remote_data = await collect_remote_data({}, event, state, options);
|
|
577
526
|
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
}
|
|
583
|
-
|
|
584
|
-
if (Object.keys(prerender).length > 0) {
|
|
585
|
-
serialized_prerender_data = `${global}.prerender = ${devalue.uneval(prerender, replacer)};\n\n\t\t\t\t\t\t`;
|
|
586
|
-
}
|
|
587
|
-
}
|
|
588
|
-
|
|
589
|
-
const serialized_remote_data = `${serialized_query_data}${serialized_prerender_data}`;
|
|
527
|
+
const serialized_data =
|
|
528
|
+
Object.keys(remote_data).length > 0
|
|
529
|
+
? `${global}.data = ${uneval(remote_data)};\n\n\t\t\t\t\t\t`
|
|
530
|
+
: '';
|
|
590
531
|
|
|
591
532
|
// `client.app` is a proxy for `bundleStrategy === 'split'`
|
|
592
533
|
const boot = client.inline
|
|
593
534
|
? `${client.inline.script}
|
|
594
535
|
|
|
595
|
-
${
|
|
536
|
+
${serialized_data}${global}.app.start(${args.join(', ')});`
|
|
596
537
|
: client.app
|
|
597
|
-
? `
|
|
598
|
-
|
|
599
|
-
import(${s(prefixed(client.app))})
|
|
600
|
-
|
|
601
|
-
${serialized_remote_data}kit.start(app, ${args.join(', ')});
|
|
538
|
+
? `import(${s(prefixed(client.start))}).then(async (kit) => {
|
|
539
|
+
kit.init(${global});
|
|
540
|
+
const app = await import(${s(prefixed(client.app))});
|
|
541
|
+
${serialized_data}kit.start(app, ${args.join(', ')});
|
|
602
542
|
});`
|
|
603
543
|
: `import(${s(prefixed(client.start))}).then((app) => {
|
|
604
|
-
${
|
|
544
|
+
${serialized_data}app.start(${args.join(', ')})
|
|
605
545
|
});`;
|
|
606
546
|
|
|
607
547
|
if (load_env_eagerly) {
|
|
@@ -615,12 +555,9 @@ export async function render_response({
|
|
|
615
555
|
}
|
|
616
556
|
|
|
617
557
|
if (options.service_worker) {
|
|
618
|
-
let opts =
|
|
558
|
+
let opts = ", { type: 'module' }";
|
|
619
559
|
if (options.service_worker_options != null) {
|
|
620
|
-
const service_worker_options = { ...options.service_worker_options };
|
|
621
|
-
if (__SVELTEKIT_DEV__) {
|
|
622
|
-
service_worker_options.type = 'module';
|
|
623
|
-
}
|
|
560
|
+
const service_worker_options = { ...options.service_worker_options, type: 'module' };
|
|
624
561
|
opts = `, ${s(service_worker_options)}`;
|
|
625
562
|
}
|
|
626
563
|
|
|
@@ -639,11 +576,8 @@ export async function render_response({
|
|
|
639
576
|
}`);
|
|
640
577
|
}
|
|
641
578
|
|
|
642
|
-
// we need to eagerly import the Vite client module in development to ensure
|
|
643
|
-
// that Vite global constant replacements are initialised before our code runs
|
|
644
579
|
const init_app = `
|
|
645
580
|
{
|
|
646
|
-
${DEV ? `import('${paths.base}/@vite/client')` : ''}
|
|
647
581
|
${blocks.join('\n\n\t\t\t\t\t')}
|
|
648
582
|
}
|
|
649
583
|
`;
|
|
@@ -659,14 +593,14 @@ export async function render_response({
|
|
|
659
593
|
'content-type': 'text/html'
|
|
660
594
|
});
|
|
661
595
|
|
|
662
|
-
if (state.prerendering) {
|
|
596
|
+
if (state.prerendering || state.prerender_default === true) {
|
|
663
597
|
// TODO read headers set with setHeaders and convert into http-equiv where possible
|
|
664
598
|
const csp_headers = csp.csp_provider.get_meta();
|
|
665
599
|
if (csp_headers) {
|
|
666
600
|
head.add_http_equiv(csp_headers);
|
|
667
601
|
}
|
|
668
602
|
|
|
669
|
-
if (state.prerendering
|
|
603
|
+
if (state.prerendering?.cache) {
|
|
670
604
|
head.add_http_equiv(
|
|
671
605
|
`<meta http-equiv="cache-control" content="${state.prerendering.cache}">`
|
|
672
606
|
);
|