@sveltejs/kit 3.0.0-next.25 → 3.0.0-next.27
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 +5 -7
- package/src/core/adapt/builder.js +127 -31
- package/src/core/adapt/index.js +3 -0
- package/src/core/config/index.js +4 -7
- package/src/core/env.js +36 -8
- package/src/core/generate_manifest/index.js +42 -43
- package/src/core/postbuild/analyse.js +4 -4
- package/src/core/postbuild/fallback.js +1 -1
- package/src/core/postbuild/prerender.js +2 -2
- package/src/core/sync/create_manifest_data/index.js +0 -1
- package/src/core/sync/write_app_manifest.js +3 -2
- package/src/exports/public.d.ts +100 -48
- package/src/exports/vite/build/index.js +1173 -0
- package/src/exports/vite/build/remote.js +4 -4
- package/src/exports/vite/dev/generate_manifest.js +308 -0
- package/src/exports/vite/dev/index.js +28 -284
- package/src/exports/vite/index.js +117 -1308
- package/src/exports/vite/plugins/env-vars.js +11 -34
- package/src/exports/vite/plugins/guard.js +19 -7
- package/src/exports/vite/plugins/remote.js +237 -0
- package/src/exports/vite/preview/index.js +8 -8
- package/src/exports/vite/static_analysis/index.js +15 -15
- package/src/exports/vite/utils.js +1 -1
- package/src/runner.js +4 -3
- package/src/runtime/app/paths/server.js +2 -2
- package/src/runtime/app/server/index.js +3 -3
- package/src/runtime/app/server/public.d.ts +114 -57
- package/src/runtime/app/server/remote/requested.js +31 -15
- package/src/runtime/app/state/client.svelte.js +3 -1
- package/src/runtime/client/client.js +39 -194
- package/src/runtime/client/fetcher.js +6 -6
- package/src/runtime/client/focus.js +120 -0
- package/src/runtime/client/remote-functions/command.svelte.js +20 -9
- package/src/runtime/client/remote-functions/form.svelte.js +12 -7
- package/src/runtime/client/remote-functions/query/instance.svelte.js +19 -5
- package/src/runtime/client/remote-functions/shared.svelte.js +22 -1
- package/src/runtime/client/scroll.js +39 -0
- package/src/runtime/client/utils.js +28 -0
- package/src/runtime/form-utils.js +243 -245
- package/src/runtime/server/data/index.js +3 -10
- package/src/runtime/server/fetch.js +13 -15
- package/src/runtime/server/index.js +8 -7
- package/src/runtime/server/internal.js +1 -2
- package/src/runtime/server/page/index.js +10 -15
- package/src/runtime/server/page/load_data.js +2 -2
- package/src/runtime/server/page/render.js +8 -13
- package/src/runtime/server/page/respond_with_error.js +4 -5
- package/src/runtime/server/page/server_routing.js +21 -27
- package/src/runtime/server/remote-functions.js +14 -14
- package/src/runtime/server/respond.js +17 -40
- package/src/runtime/server/state.js +1 -0
- package/src/runtime/server/utils.js +4 -4
- package/src/runtime/shared.js +9 -0
- package/src/types/ambient-private.d.ts +1 -2
- package/src/types/internal.d.ts +49 -6
- package/src/utils/filesystem.js +43 -27
- package/src/version.js +1 -1
- package/types/index.d.ts +215 -92
- package/types/index.d.ts.map +6 -2
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
|
|
4
4
|
import fs from 'node:fs';
|
|
5
5
|
import path from 'node:path';
|
|
6
|
-
import { Parser } from 'acorn';
|
|
7
6
|
import MagicString from 'magic-string';
|
|
8
7
|
import { posixify } from '../../../utils/os.js';
|
|
9
8
|
|
|
@@ -59,11 +58,12 @@ export async function treeshake_prerendered_remotes(
|
|
|
59
58
|
const chunk_path = posixify(path.relative(cwd, `${out}/server/${remote_chunk.fileName}`));
|
|
60
59
|
|
|
61
60
|
const code = fs.readFileSync(chunk_path, 'utf-8');
|
|
62
|
-
const parsed =
|
|
61
|
+
const parsed = vite.parseSync(chunk_path, code);
|
|
62
|
+
if (parsed.errors.length) throw new Error(parsed.errors[0].message);
|
|
63
63
|
const modified_code = new MagicString(code);
|
|
64
64
|
|
|
65
65
|
for (const fn of prerendered) {
|
|
66
|
-
for (const node of parsed.body) {
|
|
66
|
+
for (const node of parsed.program.body) {
|
|
67
67
|
const declaration =
|
|
68
68
|
node.type === 'ExportNamedDeclaration'
|
|
69
69
|
? node.declaration
|
|
@@ -85,7 +85,7 @@ export async function treeshake_prerendered_remotes(
|
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
-
for (const node of parsed.body) {
|
|
88
|
+
for (const node of parsed.program.body) {
|
|
89
89
|
if (node.type === 'ExportDefaultDeclaration') {
|
|
90
90
|
modified_code.remove(node.start, node.end);
|
|
91
91
|
}
|
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
/** @import { EnvironmentModuleNode, ErrorPayload, ViteDevServer } from 'vite' */
|
|
2
|
+
/** @import { ModuleRunner } from 'vite/module-runner' */
|
|
3
|
+
/** @import { ManifestData, SSRManifest, SSRNode, RemoteChunk, UniversalNode, ValidatedConfig } from 'types' */
|
|
4
|
+
import fs from 'node:fs';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import { get_mime_lookup, get_runtime_base } from '../../../core/utils.js';
|
|
7
|
+
import { from_fs, to_fs } from '../../../utils/vite.js';
|
|
8
|
+
import { compact } from '../../../utils/array.js';
|
|
9
|
+
import { styleText } from 'node:util';
|
|
10
|
+
|
|
11
|
+
// vite-specifc queries that we should skip handling for css urls
|
|
12
|
+
const vite_css_query_regex = /(?:\?|&)(?:raw|url|inline)(?:&|$)/;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @param {typeof import('vite')} vite
|
|
16
|
+
* @param {ViteDevServer} vite_dev_server
|
|
17
|
+
* @param {ModuleRunner} runner
|
|
18
|
+
* @param {ValidatedConfig} svelte_config
|
|
19
|
+
* @param {ManifestData} manifest_data
|
|
20
|
+
* @param {string} root
|
|
21
|
+
* @param {() => RemoteChunk[]} get_remotes
|
|
22
|
+
* @returns {SSRManifest}
|
|
23
|
+
*/
|
|
24
|
+
export function generate_manifest(
|
|
25
|
+
vite,
|
|
26
|
+
vite_dev_server,
|
|
27
|
+
runner,
|
|
28
|
+
svelte_config,
|
|
29
|
+
manifest_data,
|
|
30
|
+
root,
|
|
31
|
+
get_remotes
|
|
32
|
+
) {
|
|
33
|
+
return {
|
|
34
|
+
app_dir: svelte_config.appDir,
|
|
35
|
+
app_path: svelte_config.appDir,
|
|
36
|
+
assets: new Set(manifest_data.assets.map((asset) => asset.file)),
|
|
37
|
+
mime_types: get_mime_lookup(manifest_data),
|
|
38
|
+
client: {
|
|
39
|
+
start: `${get_runtime_base(root)}/client/entry.js`,
|
|
40
|
+
app: `${to_fs(svelte_config.outDir)}/generated/dev/client/app.js`,
|
|
41
|
+
imports: [],
|
|
42
|
+
stylesheets: [],
|
|
43
|
+
fonts: [],
|
|
44
|
+
uses_env_dynamic_public: true,
|
|
45
|
+
nodes:
|
|
46
|
+
svelte_config.router.resolution === 'client'
|
|
47
|
+
? undefined
|
|
48
|
+
: manifest_data.nodes.map((node, i) => {
|
|
49
|
+
if (node.component || node.universal) {
|
|
50
|
+
return `${svelte_config.paths.base}${to_fs(svelte_config.outDir)}/generated/dev/client/nodes/${i}.js`;
|
|
51
|
+
}
|
|
52
|
+
}),
|
|
53
|
+
// `css` is not necessary in dev, as the JS file from `nodes` will reference the CSS file
|
|
54
|
+
routes:
|
|
55
|
+
svelte_config.router.resolution === 'client'
|
|
56
|
+
? undefined
|
|
57
|
+
: compact(
|
|
58
|
+
manifest_data.routes.map((route) => {
|
|
59
|
+
if (!route.page) return;
|
|
60
|
+
|
|
61
|
+
return {
|
|
62
|
+
id: route.id,
|
|
63
|
+
pattern: route.pattern,
|
|
64
|
+
params: route.params,
|
|
65
|
+
layouts: route.page.layouts.map((l) =>
|
|
66
|
+
l !== undefined ? [!!manifest_data.nodes[l].server, l] : undefined
|
|
67
|
+
),
|
|
68
|
+
errors: route.page.errors,
|
|
69
|
+
leaf: [!!manifest_data.nodes[route.page.leaf].server, route.page.leaf]
|
|
70
|
+
};
|
|
71
|
+
})
|
|
72
|
+
)
|
|
73
|
+
},
|
|
74
|
+
server_assets: new Proxy(
|
|
75
|
+
{},
|
|
76
|
+
{
|
|
77
|
+
has: (_, /** @type {string} */ file) => fs.existsSync(from_fs(file)),
|
|
78
|
+
get: (_, /** @type {string} */ file) => fs.statSync(from_fs(file)).size
|
|
79
|
+
}
|
|
80
|
+
),
|
|
81
|
+
nodes: manifest_data.nodes.map((node, index) => {
|
|
82
|
+
return async () => {
|
|
83
|
+
const result = /** @type {SSRNode} */ ({});
|
|
84
|
+
result.index = index;
|
|
85
|
+
result.universal_id = node.universal;
|
|
86
|
+
result.server_id = node.server;
|
|
87
|
+
|
|
88
|
+
// these are unused in dev, but it's easier to include them
|
|
89
|
+
result.imports = [];
|
|
90
|
+
result.stylesheets = [];
|
|
91
|
+
result.fonts = [];
|
|
92
|
+
|
|
93
|
+
/** @type {EnvironmentModuleNode[]} */
|
|
94
|
+
const module_nodes = [];
|
|
95
|
+
|
|
96
|
+
if (node.component) {
|
|
97
|
+
result.component = async () => {
|
|
98
|
+
const { module_node, module } = await resolve(
|
|
99
|
+
vite,
|
|
100
|
+
vite_dev_server,
|
|
101
|
+
runner,
|
|
102
|
+
/** @type {string} */ (node.component)
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
module_nodes.push(module_node);
|
|
106
|
+
|
|
107
|
+
return module.default;
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (node.universal) {
|
|
112
|
+
if (node.page_options?.ssr === false) {
|
|
113
|
+
result.universal = /** @type {UniversalNode} */ (node.page_options);
|
|
114
|
+
} else {
|
|
115
|
+
// TODO: explain why the file was loaded on the server if we fail to load it
|
|
116
|
+
const { module, module_node } = await resolve(
|
|
117
|
+
vite,
|
|
118
|
+
vite_dev_server,
|
|
119
|
+
runner,
|
|
120
|
+
node.universal
|
|
121
|
+
);
|
|
122
|
+
module_nodes.push(module_node);
|
|
123
|
+
result.universal = module;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (node.server) {
|
|
128
|
+
const { module } = await resolve(vite, vite_dev_server, runner, node.server);
|
|
129
|
+
result.server = module;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// in dev we inline all styles to avoid FOUC. this gets populated lazily so that
|
|
133
|
+
// components/stylesheets loaded via import() during `load` are included
|
|
134
|
+
result.inline_styles = async () => {
|
|
135
|
+
/** @type {Set<EnvironmentModuleNode>} */
|
|
136
|
+
const deps = new Set();
|
|
137
|
+
|
|
138
|
+
for (const module_node of module_nodes) {
|
|
139
|
+
await find_deps(vite_dev_server, module_node, deps);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/** @type {Record<string, string>} */
|
|
143
|
+
const styles = {};
|
|
144
|
+
|
|
145
|
+
for (const dep of deps) {
|
|
146
|
+
if (vite.isCSSRequest(dep.url) && !vite_css_query_regex.test(dep.url)) {
|
|
147
|
+
const inlineCssUrl = dep.url.includes('?')
|
|
148
|
+
? dep.url.replace('?', '?inline&')
|
|
149
|
+
: dep.url + '?inline';
|
|
150
|
+
try {
|
|
151
|
+
const mod = await runner.import(inlineCssUrl);
|
|
152
|
+
styles[dep.url] = mod.default;
|
|
153
|
+
} catch {
|
|
154
|
+
// this can happen with dynamically imported modules, I think
|
|
155
|
+
// because the Vite module graph doesn't distinguish between
|
|
156
|
+
// static and dynamic imports? TODO investigate, submit fix
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
return styles;
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
return result;
|
|
165
|
+
};
|
|
166
|
+
}),
|
|
167
|
+
prerendered_routes: new Set(),
|
|
168
|
+
get remotes() {
|
|
169
|
+
return Object.fromEntries(
|
|
170
|
+
get_remotes().map((remote) => [
|
|
171
|
+
remote.hash,
|
|
172
|
+
() => runner.import(remote.file).then((module) => ({ default: module }))
|
|
173
|
+
])
|
|
174
|
+
);
|
|
175
|
+
},
|
|
176
|
+
routes: compact(
|
|
177
|
+
manifest_data.routes.map((route) => {
|
|
178
|
+
if (!route.page && !route.endpoint) return null;
|
|
179
|
+
|
|
180
|
+
const endpoint = route.endpoint;
|
|
181
|
+
|
|
182
|
+
return {
|
|
183
|
+
id: route.id,
|
|
184
|
+
pattern: route.pattern,
|
|
185
|
+
params: route.params,
|
|
186
|
+
page: route.page,
|
|
187
|
+
endpoint: endpoint
|
|
188
|
+
? async () => {
|
|
189
|
+
const url = path.resolve(root, endpoint.file);
|
|
190
|
+
return await loud_ssr_load_module(vite, vite_dev_server, runner, url);
|
|
191
|
+
}
|
|
192
|
+
: null,
|
|
193
|
+
endpoint_id: endpoint?.file
|
|
194
|
+
};
|
|
195
|
+
})
|
|
196
|
+
),
|
|
197
|
+
matchers: async () => {
|
|
198
|
+
if (!manifest_data.params) return {};
|
|
199
|
+
|
|
200
|
+
const url = path.resolve(root, manifest_data.params);
|
|
201
|
+
const module = await runner.import(url);
|
|
202
|
+
|
|
203
|
+
if (!module.params) {
|
|
204
|
+
throw new Error(`${manifest_data.params} does not export \`params\` from \`defineParams\``);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
return module.params;
|
|
208
|
+
}
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* @param {typeof import('vite')} vite
|
|
214
|
+
* @param {ViteDevServer} vite_dev_server
|
|
215
|
+
* @param {ModuleRunner} runner
|
|
216
|
+
* @param {string} url
|
|
217
|
+
* @returns {Promise<Record<string, any>>}
|
|
218
|
+
*/
|
|
219
|
+
export async function loud_ssr_load_module(vite, vite_dev_server, runner, url) {
|
|
220
|
+
try {
|
|
221
|
+
return await runner.import(url);
|
|
222
|
+
} catch (/** @type {any} */ err) {
|
|
223
|
+
const msg = vite.buildErrorMessage(err, [
|
|
224
|
+
styleText('red', `Internal server error: ${err.message}`)
|
|
225
|
+
]);
|
|
226
|
+
|
|
227
|
+
if (!vite_dev_server.config.logger.hasErrorLogged(err)) {
|
|
228
|
+
vite_dev_server.config.logger.error(msg, { error: err });
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// TODO this is inadequate — it doesn't reliably show the overlay on every page load,
|
|
232
|
+
// and when it does appear it may immediately vanish. `hot.send` broadcasts
|
|
233
|
+
// to all connected clients, even ones that are unaffected by the error.
|
|
234
|
+
// we need a more considered approach
|
|
235
|
+
vite_dev_server.environments.client.hot.send({
|
|
236
|
+
type: 'error',
|
|
237
|
+
err: /** @type {ErrorPayload['err']} */ ({
|
|
238
|
+
...err,
|
|
239
|
+
// these properties are non-enumerable and will
|
|
240
|
+
// not be serialized unless we explicitly include them
|
|
241
|
+
message: err.message,
|
|
242
|
+
stack: err.stack ?? ''
|
|
243
|
+
})
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
throw err;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* @param {typeof import('vite')} vite
|
|
252
|
+
* @param {ViteDevServer} vite_dev_server
|
|
253
|
+
* @param {ModuleRunner} runner
|
|
254
|
+
* @param {string} id
|
|
255
|
+
*/
|
|
256
|
+
async function resolve(vite, vite_dev_server, runner, id) {
|
|
257
|
+
const url = id.startsWith('..') ? to_fs(path.resolve(id)) : `/${id}`;
|
|
258
|
+
|
|
259
|
+
const module = await loud_ssr_load_module(vite, vite_dev_server, runner, url);
|
|
260
|
+
|
|
261
|
+
const module_node = await vite_dev_server.environments.ssr.moduleGraph.getModuleByUrl(url);
|
|
262
|
+
if (!module_node) throw new Error(`Could not find node for ${url}`);
|
|
263
|
+
|
|
264
|
+
return { module, module_node, url };
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* @param {ViteDevServer} vite
|
|
269
|
+
* @param {EnvironmentModuleNode} node
|
|
270
|
+
* @param {Set<EnvironmentModuleNode>} deps
|
|
271
|
+
*/
|
|
272
|
+
async function find_deps(vite, node, deps) {
|
|
273
|
+
// since `transformResult.deps` contains URLs instead of `ModuleNode`s, this process is asynchronous.
|
|
274
|
+
// instead of using `await`, we resolve all branches in parallel.
|
|
275
|
+
/** @type {Promise<void>[]} */
|
|
276
|
+
const branches = [];
|
|
277
|
+
|
|
278
|
+
/** @param {EnvironmentModuleNode} node */
|
|
279
|
+
async function add(node) {
|
|
280
|
+
if (!deps.has(node)) {
|
|
281
|
+
deps.add(node);
|
|
282
|
+
await find_deps(vite, node, deps);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/** @param {string} url */
|
|
287
|
+
async function add_by_url(url) {
|
|
288
|
+
const node = await vite.environments.ssr.moduleGraph.getModuleByUrl(url);
|
|
289
|
+
|
|
290
|
+
if (node) {
|
|
291
|
+
await add(node);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
if (node.transformResult) {
|
|
296
|
+
if (node.transformResult.deps) {
|
|
297
|
+
node.transformResult.deps.forEach((url) => branches.push(add_by_url(url)));
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
if (node.transformResult.dynamicDeps) {
|
|
301
|
+
node.transformResult.dynamicDeps.forEach((url) => branches.push(add_by_url(url)));
|
|
302
|
+
}
|
|
303
|
+
} else {
|
|
304
|
+
node.importedModules.forEach((node) => branches.push(add(node)));
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
await Promise.all(branches);
|
|
308
|
+
}
|