@sveltejs/kit 3.0.0-next.2 → 3.0.0-next.20

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.
Files changed (192) hide show
  1. package/package.json +58 -36
  2. package/src/cli.js +14 -11
  3. package/src/constants.js +6 -1
  4. package/src/core/adapt/builder.js +54 -60
  5. package/src/core/adapt/index.js +2 -5
  6. package/src/core/config/index.js +141 -76
  7. package/src/core/config/options.js +260 -260
  8. package/src/core/config/types.d.ts +1 -1
  9. package/src/core/env.js +143 -13
  10. package/src/core/generate_manifest/index.js +18 -15
  11. package/src/core/postbuild/analyse.js +7 -19
  12. package/src/core/postbuild/crawl.js +22 -6
  13. package/src/core/postbuild/entities.js +8 -2
  14. package/src/core/postbuild/fallback.js +4 -2
  15. package/src/core/postbuild/prerender.js +193 -69
  16. package/src/core/postbuild/queue.js +2 -1
  17. package/src/core/sync/create_manifest_data/conflict.js +1 -1
  18. package/src/core/sync/create_manifest_data/index.js +72 -52
  19. package/src/core/sync/sync.js +35 -26
  20. package/src/core/sync/ts.js +1 -1
  21. package/src/core/sync/utils.js +22 -2
  22. package/src/core/sync/{write_non_ambient.js → write_app_types.js} +105 -56
  23. package/src/core/sync/write_client_manifest.js +13 -28
  24. package/src/core/sync/write_env.js +7 -5
  25. package/src/core/sync/write_server.js +25 -33
  26. package/src/core/sync/write_tsconfig/index.js +274 -0
  27. package/src/core/sync/write_tsconfig/test-app/package.json +7 -0
  28. package/src/core/sync/write_tsconfig/utils.js +77 -0
  29. package/src/core/sync/write_tsconfig/validate.js +128 -0
  30. package/src/core/sync/write_types/index.js +119 -116
  31. package/src/core/utils.js +30 -5
  32. package/src/exports/env/index.js +77 -0
  33. package/src/exports/env/public.d.ts +55 -0
  34. package/src/exports/hooks/index.js +3 -9
  35. package/src/exports/hooks/public.d.ts +194 -0
  36. package/src/exports/hooks/sequence.js +9 -6
  37. package/src/exports/index.js +53 -20
  38. package/src/exports/internal/client.js +5 -0
  39. package/src/exports/internal/env.js +8 -5
  40. package/src/exports/internal/index.js +1 -90
  41. package/src/exports/internal/{event.js → server/event.js} +1 -2
  42. package/src/exports/internal/server/index.js +37 -0
  43. package/src/exports/internal/server/telemetry.js +95 -0
  44. package/src/exports/internal/shared.js +90 -0
  45. package/src/exports/node/index.js +64 -22
  46. package/src/exports/params/index.js +70 -0
  47. package/src/exports/params/public.d.ts +63 -0
  48. package/src/exports/public.d.ts +219 -1118
  49. package/src/exports/url.js +86 -0
  50. package/src/exports/vite/build/build_server.js +53 -64
  51. package/src/exports/vite/build/remote.js +24 -19
  52. package/src/exports/vite/build/utils.js +0 -8
  53. package/src/exports/vite/dev/index.js +199 -125
  54. package/src/exports/vite/index.js +1514 -833
  55. package/src/exports/vite/module_ids.js +2 -2
  56. package/src/exports/vite/preview/index.js +32 -24
  57. package/src/exports/vite/utils.js +83 -45
  58. package/src/pathname.js +55 -0
  59. package/src/runner.js +15 -0
  60. package/src/runtime/app/env/internal.js +4 -4
  61. package/src/runtime/app/env/types.d.ts +1 -1
  62. package/src/runtime/app/environment/index.js +3 -3
  63. package/src/runtime/app/{forms.js → forms/index.js} +73 -42
  64. package/src/runtime/app/forms/public.d.ts +2 -0
  65. package/src/runtime/app/forms/types.d.ts +56 -0
  66. package/src/runtime/app/internal/transport.js +53 -0
  67. package/src/runtime/app/manifest/index.js +1 -0
  68. package/src/runtime/app/{navigation.js → navigation/index.js} +2 -1
  69. package/src/runtime/app/navigation/public.d.ts +237 -0
  70. package/src/runtime/app/paths/client.js +37 -37
  71. package/src/runtime/app/paths/index.js +1 -1
  72. package/src/runtime/app/paths/internal/client.js +34 -2
  73. package/src/runtime/app/paths/internal/server.js +6 -23
  74. package/src/runtime/app/paths/internal.d.ts +3 -0
  75. package/src/runtime/app/paths/public.d.ts +1 -29
  76. package/src/runtime/app/paths/server.js +36 -17
  77. package/src/runtime/app/paths/types.d.ts +11 -19
  78. package/src/runtime/app/server/index.js +2 -2
  79. package/src/runtime/app/server/public.d.ts +519 -0
  80. package/src/runtime/app/server/remote/command.js +13 -11
  81. package/src/runtime/app/server/remote/form.js +61 -39
  82. package/src/runtime/app/server/remote/prerender.js +45 -45
  83. package/src/runtime/app/server/remote/query.js +106 -108
  84. package/src/runtime/app/server/remote/requested.js +27 -19
  85. package/src/runtime/app/server/remote/shared.js +75 -75
  86. package/src/runtime/app/service-worker/index.js +24 -0
  87. package/src/runtime/app/state/client.js +4 -2
  88. package/src/runtime/app/state/index.js +7 -5
  89. package/src/runtime/app/state/public.d.ts +72 -0
  90. package/src/runtime/app/state/server.js +3 -0
  91. package/src/runtime/app/stores.js +15 -78
  92. package/src/runtime/client/bundle.js +1 -1
  93. package/src/runtime/client/client-entry.js +3 -0
  94. package/src/runtime/client/client.js +1336 -648
  95. package/src/runtime/client/constants.js +3 -6
  96. package/src/runtime/client/entry.js +24 -3
  97. package/src/runtime/client/fetcher.js +25 -25
  98. package/src/runtime/client/ndjson.js +1 -1
  99. package/src/runtime/client/parse.js +1 -1
  100. package/src/runtime/client/payload.js +17 -0
  101. package/src/runtime/client/remote-functions/cache.svelte.js +3 -1
  102. package/src/runtime/client/remote-functions/command.svelte.js +37 -61
  103. package/src/runtime/client/remote-functions/form.svelte.js +267 -178
  104. package/src/runtime/client/remote-functions/prerender.svelte.js +32 -11
  105. package/src/runtime/client/remote-functions/query/index.js +10 -17
  106. package/src/runtime/client/remote-functions/query/instance.svelte.js +64 -18
  107. package/src/runtime/client/remote-functions/query/proxy.js +5 -5
  108. package/src/runtime/client/remote-functions/query-batch.svelte.js +61 -70
  109. package/src/runtime/client/remote-functions/query-live/index.js +1 -1
  110. package/src/runtime/client/remote-functions/query-live/instance.svelte.js +63 -21
  111. package/src/runtime/client/remote-functions/query-live/iterator.js +15 -12
  112. package/src/runtime/client/remote-functions/query-live/proxy.js +2 -12
  113. package/src/runtime/client/remote-functions/shared.svelte.js +90 -65
  114. package/src/runtime/client/snapshots.js +147 -0
  115. package/src/runtime/client/state.svelte.js +94 -55
  116. package/src/runtime/client/stream.js +3 -2
  117. package/src/runtime/client/types.d.ts +13 -9
  118. package/src/runtime/client/utils.js +22 -110
  119. package/src/runtime/components/root.svelte +56 -0
  120. package/src/runtime/env/dynamic/private.js +7 -0
  121. package/src/runtime/env/dynamic/public.js +7 -0
  122. package/src/runtime/env/static/private.js +6 -0
  123. package/src/runtime/env/static/public.js +6 -0
  124. package/src/runtime/form-utils.js +172 -61
  125. package/src/runtime/pathname.js +20 -32
  126. package/src/runtime/props.svelte.js +72 -0
  127. package/src/runtime/server/constants.js +0 -3
  128. package/src/runtime/server/cookie.js +70 -53
  129. package/src/runtime/server/csrf.js +65 -0
  130. package/src/runtime/server/data/index.js +48 -52
  131. package/src/runtime/server/dev.js +22 -0
  132. package/src/runtime/server/endpoint.js +3 -4
  133. package/src/runtime/server/env_module.js +0 -5
  134. package/src/runtime/server/errors.js +160 -0
  135. package/src/runtime/server/fetch.js +31 -38
  136. package/src/runtime/server/index.js +90 -64
  137. package/src/runtime/server/internal.js +71 -0
  138. package/src/runtime/server/page/actions.js +84 -64
  139. package/src/runtime/server/page/crypto.js +2 -2
  140. package/src/runtime/server/page/csp.js +88 -104
  141. package/src/runtime/server/page/data_serializer.js +22 -23
  142. package/src/runtime/server/page/index.js +35 -53
  143. package/src/runtime/server/page/load_data.js +47 -54
  144. package/src/runtime/server/page/render.js +172 -238
  145. package/src/runtime/server/page/respond_with_error.js +16 -30
  146. package/src/runtime/server/page/serialize_data.js +2 -13
  147. package/src/runtime/server/page/server_routing.js +85 -26
  148. package/src/runtime/server/remote-functions.js +639 -0
  149. package/src/runtime/server/respond.js +188 -129
  150. package/src/runtime/server/sourcemaps.js +183 -0
  151. package/src/runtime/server/state.js +53 -0
  152. package/src/runtime/server/utils.js +12 -154
  153. package/src/runtime/shared.js +20 -40
  154. package/src/runtime/utils.js +3 -0
  155. package/src/types/ambient-private.d.ts +11 -1
  156. package/src/types/ambient.d.ts +87 -36
  157. package/src/types/global-private.d.ts +25 -25
  158. package/src/types/internal.d.ts +160 -150
  159. package/src/types/private.d.ts +41 -1
  160. package/src/utils/error.js +28 -4
  161. package/src/utils/escape.js +9 -25
  162. package/src/utils/features.js +1 -1
  163. package/src/utils/filesystem.js +1 -23
  164. package/src/utils/fork.js +7 -2
  165. package/src/utils/hash.js +21 -0
  166. package/src/utils/http.js +8 -7
  167. package/src/utils/import.js +9 -2
  168. package/src/utils/imports.js +83 -0
  169. package/src/utils/mime.js +9 -0
  170. package/src/utils/page_nodes.js +6 -7
  171. package/src/utils/params.js +67 -0
  172. package/src/utils/regex.js +9 -0
  173. package/src/utils/routing.js +145 -73
  174. package/src/utils/shared-iterator.js +5 -0
  175. package/src/utils/streaming.js +14 -4
  176. package/src/utils/url.js +33 -2
  177. package/src/version.js +1 -1
  178. package/types/index.d.ts +2291 -2135
  179. package/types/index.d.ts.map +116 -108
  180. package/src/core/sync/write_ambient.js +0 -18
  181. package/src/core/sync/write_root.js +0 -148
  182. package/src/core/sync/write_tsconfig.js +0 -250
  183. package/src/exports/internal/server.js +0 -22
  184. package/src/exports/node/polyfills.js +0 -30
  185. package/src/runtime/server/app.js +0 -9
  186. package/src/runtime/server/remote.js +0 -457
  187. package/src/runtime/shared-server.js +0 -7
  188. package/src/runtime/telemetry/otel.js +0 -21
  189. package/src/runtime/telemetry/record_span.js +0 -65
  190. package/src/types/synthetic/$lib.md +0 -5
  191. /package/src/exports/internal/{remote-functions.js → server/remote-functions.js} +0 -0
  192. /package/src/{runtime/telemetry/noop.js → telemetry.js} +0 -0
@@ -1,40 +1,53 @@
1
- /** @import { RequestEvent } from '@sveltejs/kit' */
2
- /** @import { PrerenderOption, UniversalNode } from 'types' */
1
+ /** @import { RequestEvent, SSRManifest } from '@sveltejs/kit' */
2
+ /** @import { EnvironmentModuleNode, ErrorPayload, ResolvedConfig, ViteDevServer } from 'vite' */
3
+ /** @import { ManifestData, PrerenderOption, RemoteChunk, ServerModule, SSRNode, UniversalNode, ValidatedConfig } from 'types' */
4
+ import process from 'node:process';
3
5
  import fs from 'node:fs';
4
6
  import path from 'node:path';
5
7
  import { URL } from 'node:url';
6
8
  import { AsyncLocalStorage } from 'node:async_hooks';
7
9
  import { styleText } from 'node:util';
8
10
  import sirv from 'sirv';
9
- import { isCSSRequest, loadEnv, buildErrorMessage } from 'vite';
10
11
  import { createReadableStream, getRequest, setResponse } from '../../../exports/node/index.js';
11
12
  import { coalesce_to_error } from '../../../utils/error.js';
12
13
  import { resolve_entry } from '../../../utils/filesystem.js';
14
+ import { load_and_validate_params } from '../../../utils/params.js';
13
15
  import { from_fs, to_fs } from '../../../utils/vite.js';
14
16
  import { posixify } from '../../../utils/os.js';
15
17
  import { load_error_page } from '../../../core/config/index.js';
16
- import { SVELTE_KIT_ASSETS } from '../../../constants.js';
18
+ import { SRC_ROOT, SVELTE_KIT_ASSETS } from '../../../constants.js';
17
19
  import * as sync from '../../../core/sync/sync.js';
18
20
  import { get_mime_lookup, get_runtime_base } from '../../../core/utils.js';
21
+ import '../../../utils/mime.js'; // extend mrmime with additional types (affects sirv too)
19
22
  import { compact } from '../../../utils/array.js';
20
- import { is_chrome_devtools_request, not_found } from '../utils.js';
23
+ import { is_chrome_devtools_request, is_remote_module, not_found } from '../utils.js';
21
24
  import { SCHEME } from '../../../utils/url.js';
22
25
  import { check_feature } from '../../../utils/features.js';
23
26
  import { escape_html } from '../../../utils/escape.js';
27
+ import { get_runner } from '../../../runner.js';
24
28
 
25
29
  // vite-specifc queries that we should skip handling for css urls
26
30
  const vite_css_query_regex = /(?:\?|&)(?:raw|url|inline)(?:&|$)/;
27
31
 
28
32
  /**
29
- * @param {import('vite').ViteDevServer} vite
30
- * @param {import('vite').ResolvedConfig} vite_config
31
- * @param {import('types').ValidatedConfig} svelte_config
32
- * @param {() => Array<{ hash: string, file: string }>} get_remotes
33
+ * @param {typeof import('vite')} vite the peer resolved vite module
34
+ * @param {ViteDevServer} vite_dev_server
35
+ * @param {ResolvedConfig} vite_config
36
+ * @param {ValidatedConfig} svelte_config
37
+ * @param {() => RemoteChunk[]} get_remotes
33
38
  * @param {string} root The project root directory
34
- * @param {import('@sveltejs/kit').Adapter | undefined} adapter
39
+ * @param {(manifest_data: ManifestData) => void} set_manifest_data
35
40
  * @return {Promise<Promise<() => void>>}
36
41
  */
37
- export async function dev(vite, vite_config, svelte_config, get_remotes, root, adapter) {
42
+ export async function dev(
43
+ vite,
44
+ vite_dev_server,
45
+ vite_config,
46
+ svelte_config,
47
+ get_remotes,
48
+ root,
49
+ set_manifest_data
50
+ ) {
38
51
  /** @type {AsyncLocalStorage<{ event: RequestEvent, config: any, prerender: PrerenderOption }>} */
39
52
  const async_local_storage = new AsyncLocalStorage();
40
53
 
@@ -42,7 +55,12 @@ export async function dev(vite, vite_config, svelte_config, get_remotes, root, a
42
55
  const context = async_local_storage.getStore();
43
56
  if (!context || context.prerender === true) return;
44
57
 
45
- check_feature(/** @type {string} */ (context.event.route.id), context.config, label, adapter);
58
+ check_feature(
59
+ /** @type {string} */ (context.event.route.id),
60
+ context.config,
61
+ label,
62
+ svelte_config.kit.adapter
63
+ );
46
64
  };
47
65
 
48
66
  const fetch = globalThis.fetch;
@@ -58,30 +76,39 @@ export async function dev(vite, vite_config, svelte_config, get_remotes, root, a
58
76
 
59
77
  sync.init(svelte_config, root);
60
78
 
61
- /** @type {import('types').ManifestData} */
79
+ /** @type {ManifestData} */
62
80
  let manifest_data;
63
- /** @type {import('@sveltejs/kit').SSRManifest} */
81
+ /** @type {SSRManifest} */
64
82
  let manifest;
65
83
 
66
84
  /** @type {Error | null} */
67
85
  let manifest_error = null;
68
86
 
69
- /** @param {string} url */
87
+ const runner = get_runner(vite, vite_dev_server);
88
+
89
+ /**
90
+ * @param {string} url
91
+ * @returns {Promise<Record<string, any>>}
92
+ */
70
93
  async function loud_ssr_load_module(url) {
71
94
  try {
72
- return await vite.ssrLoadModule(url, { fixStacktrace: true });
95
+ return await runner.import(url);
73
96
  } catch (/** @type {any} */ err) {
74
- const msg = buildErrorMessage(err, [
97
+ const msg = vite.buildErrorMessage(err, [
75
98
  styleText('red', `Internal server error: ${err.message}`)
76
99
  ]);
77
100
 
78
- if (!vite.config.logger.hasErrorLogged(err)) {
79
- vite.config.logger.error(msg, { error: err });
101
+ if (!vite_dev_server.config.logger.hasErrorLogged(err)) {
102
+ vite_dev_server.config.logger.error(msg, { error: err });
80
103
  }
81
104
 
82
- vite.ws.send({
105
+ // TODO this is inadequate — it doesn't reliably show the overlay on every page load,
106
+ // and when it does appear it may immediately vanish. `vite.hot.send` broadcasts
107
+ // to all connected clients, even ones that are unaffected by the error.
108
+ // we need a more considered approach
109
+ vite_dev_server.hot.send({
83
110
  type: 'error',
84
- err: /** @type {import('vite').ErrorPayload['err']} */ ({
111
+ err: /** @type {ErrorPayload['err']} */ ({
85
112
  ...err,
86
113
  // these properties are non-enumerable and will
87
114
  // not be serialized unless we explicitly include them
@@ -100,25 +127,33 @@ export async function dev(vite, vite_config, svelte_config, get_remotes, root, a
100
127
 
101
128
  const module = await loud_ssr_load_module(url);
102
129
 
103
- const module_node = await vite.moduleGraph.getModuleByUrl(url);
130
+ const module_node = await vite_dev_server.environments.ssr.moduleGraph.getModuleByUrl(url);
104
131
  if (!module_node) throw new Error(`Could not find node for ${url}`);
105
132
 
106
133
  return { module, module_node, url };
107
134
  }
108
135
 
109
- function update_manifest() {
136
+ async function update_manifest() {
110
137
  try {
111
138
  ({ manifest_data } = sync.create(svelte_config, root));
139
+ set_manifest_data(manifest_data);
140
+
141
+ await load_and_validate_params({
142
+ routes: manifest_data.routes,
143
+ params_path: manifest_data.params,
144
+ root,
145
+ load: (file) => loud_ssr_load_module(file)
146
+ });
112
147
 
113
148
  if (manifest_error) {
114
149
  manifest_error = null;
115
- vite.ws.send({ type: 'full-reload' });
150
+ vite_dev_server.hot.send({ type: 'full-reload' });
116
151
  }
117
152
  } catch (error) {
118
153
  manifest_error = /** @type {Error} */ (error);
119
154
 
120
155
  console.error(styleText(['bold', 'red'], manifest_error.message));
121
- vite.ws.send({
156
+ vite_dev_server.hot.send({
122
157
  type: 'error',
123
158
  err: {
124
159
  message: manifest_error.message ?? 'Invalid routes',
@@ -180,8 +215,7 @@ export async function dev(vite, vite_config, svelte_config, get_remotes, root, a
180
215
  ),
181
216
  nodes: manifest_data.nodes.map((node, index) => {
182
217
  return async () => {
183
- /** @type {import('types').SSRNode} */
184
- const result = {};
218
+ const result = /** @type {SSRNode} */ ({});
185
219
  result.index = index;
186
220
  result.universal_id = node.universal;
187
221
  result.server_id = node.server;
@@ -191,7 +225,7 @@ export async function dev(vite, vite_config, svelte_config, get_remotes, root, a
191
225
  result.stylesheets = [];
192
226
  result.fonts = [];
193
227
 
194
- /** @type {import('vite').ModuleNode[]} */
228
+ /** @type {EnvironmentModuleNode[]} */
195
229
  const module_nodes = [];
196
230
 
197
231
  if (node.component) {
@@ -225,23 +259,23 @@ export async function dev(vite, vite_config, svelte_config, get_remotes, root, a
225
259
  // in dev we inline all styles to avoid FOUC. this gets populated lazily so that
226
260
  // components/stylesheets loaded via import() during `load` are included
227
261
  result.inline_styles = async () => {
228
- /** @type {Set<import('vite').ModuleNode | import('vite').EnvironmentModuleNode>} */
262
+ /** @type {Set<EnvironmentModuleNode>} */
229
263
  const deps = new Set();
230
264
 
231
265
  for (const module_node of module_nodes) {
232
- await find_deps(vite, module_node, deps);
266
+ await find_deps(vite_dev_server, module_node, deps);
233
267
  }
234
268
 
235
269
  /** @type {Record<string, string>} */
236
270
  const styles = {};
237
271
 
238
272
  for (const dep of deps) {
239
- if (isCSSRequest(dep.url) && !vite_css_query_regex.test(dep.url)) {
273
+ if (vite.isCSSRequest(dep.url) && !vite_css_query_regex.test(dep.url)) {
240
274
  const inlineCssUrl = dep.url.includes('?')
241
275
  ? dep.url.replace('?', '?inline&')
242
276
  : dep.url + '?inline';
243
277
  try {
244
- const mod = await vite.ssrLoadModule(inlineCssUrl);
278
+ const mod = await runner.import(inlineCssUrl);
245
279
  styles[dep.url] = mod.default;
246
280
  } catch {
247
281
  // this can happen with dynamically imported modules, I think
@@ -262,7 +296,7 @@ export async function dev(vite, vite_config, svelte_config, get_remotes, root, a
262
296
  return Object.fromEntries(
263
297
  get_remotes().map((remote) => [
264
298
  remote.hash,
265
- () => vite.ssrLoadModule(remote.file).then((module) => ({ default: module }))
299
+ () => runner.import(remote.file).then((module) => ({ default: module }))
266
300
  ])
267
301
  );
268
302
  },
@@ -288,22 +322,18 @@ export async function dev(vite, vite_config, svelte_config, get_remotes, root, a
288
322
  })
289
323
  ),
290
324
  matchers: async () => {
291
- /** @type {Record<string, import('@sveltejs/kit').ParamMatcher>} */
292
- const matchers = {};
293
-
294
- for (const key in manifest_data.matchers) {
295
- const file = manifest_data.matchers[key];
296
- const url = path.resolve(root, file);
297
- const module = await vite.ssrLoadModule(url, { fixStacktrace: true });
298
-
299
- if (module.match) {
300
- matchers[key] = module.match;
301
- } else {
302
- throw new Error(`${file} does not export a \`match\` function`);
303
- }
325
+ if (!manifest_data.params) return {};
326
+
327
+ const url = path.resolve(root, manifest_data.params);
328
+ const module = await runner.import(url);
329
+
330
+ if (!module.params) {
331
+ throw new Error(
332
+ `${manifest_data.params} does not export \`params\` from \`defineParams\``
333
+ );
304
334
  }
305
335
 
306
- return matchers;
336
+ return module.params;
307
337
  }
308
338
  }
309
339
  };
@@ -311,27 +341,59 @@ export async function dev(vite, vite_config, svelte_config, get_remotes, root, a
311
341
 
312
342
  /** @param {Error} error */
313
343
  function fix_stack_trace(error) {
314
- try {
315
- vite.ssrFixStacktrace(error);
316
- } catch {
317
- // ssrFixStacktrace can fail on StackBlitz web containers and we don't know why
318
- // by ignoring it the line numbers are wrong, but at least we can show the error
344
+ if (!error.stack) {
345
+ return;
319
346
  }
320
- return error.stack?.replaceAll('\0', ''); // remove null bytes from e.g. virtual module IDs, or the response will fail
347
+
348
+ let prelude = '';
349
+ let start = -1;
350
+ let end = 0;
351
+
352
+ const lines = error.stack
353
+ .replaceAll('\0', '') // remove null bytes from e.g. virtual module IDs, or the response will fail
354
+ .split('\n')
355
+ .map((line, i) => {
356
+ const match = /^ {4}at (?:[^(]+ \((.+)\)|(.+))$/.exec(line);
357
+ if (!match) {
358
+ prelude += line + '\n';
359
+ end = i + 1;
360
+ return line;
361
+ }
362
+
363
+ const loc = match[1] ?? match[2];
364
+ const file = loc.replace(/:\d+:\d+$/, '');
365
+
366
+ if (fs.existsSync(file)) {
367
+ if (!file.includes('node_modules') && !file.includes(SRC_ROOT)) {
368
+ if (start === -1) start = i;
369
+ end = i + 1;
370
+ }
371
+
372
+ return line.replace(file, path.relative(process.cwd(), file));
373
+ }
374
+
375
+ return line;
376
+ })
377
+ // if no user-code frame was found, keep only the prelude (message/header)
378
+ // lines and drop everything else so the message isn't duplicated
379
+ .slice(start === -1 ? end : start, end);
380
+
381
+ return (error.stack = prelude + lines.join('\n'));
321
382
  }
322
383
 
323
- update_manifest();
384
+ const params_file = resolve_entry(svelte_config.kit.files.params);
324
385
 
325
386
  /**
326
387
  * @param {string} event
327
388
  * @param {(file: string) => void} cb
328
389
  */
329
390
  const watch = (event, cb) => {
330
- vite.watcher.on(event, (file) => {
391
+ vite_dev_server.watcher.on(event, (file) => {
331
392
  if (
332
393
  file.startsWith(svelte_config.kit.files.routes + path.sep) ||
333
- file.startsWith(svelte_config.kit.files.params + path.sep) ||
334
- svelte_config.kit.moduleExtensions.some((ext) => file.endsWith(`.remote${ext}`)) ||
394
+ file.startsWith(svelte_config.kit.files.assets + path.sep) ||
395
+ (params_file && file === params_file) ||
396
+ is_remote_module(file) ||
335
397
  // in contrast to server hooks, client hooks are written to the client manifest
336
398
  // and therefore need rebuilding when they are added/removed
337
399
  file.startsWith(svelte_config.kit.files.hooks.client)
@@ -351,19 +413,21 @@ export async function dev(vite, vite_config, svelte_config, get_remotes, root, a
351
413
  }, 100);
352
414
  };
353
415
 
354
- // flag to skip watchers if server is already restarting
355
- let restarting = false;
356
-
357
416
  // Debounce add/unlink events because in case of folder deletion or moves
358
417
  // they fire in rapid succession, causing needless invocations.
359
418
  // These watchers only run for routes, param matchers, and client hooks.
360
419
  watch('add', () => debounce(update_manifest));
361
420
  watch('unlink', () => debounce(update_manifest));
362
421
  watch('change', (file) => {
422
+ // `manifest_data` is populated lazily on the first request (see `update_manifest`
423
+ // call in the middleware below), so it may still be undefined if a file changes
424
+ // before the dev server has served a request. In that case there's nothing to
425
+ // update — the manifest will be created from scratch on the first request.
426
+ if (!manifest_data) return;
363
427
  // Don't run for a single file if the whole manifest is about to get updated
364
428
  // Unless it's a file where the trailing slash page option might have changed
365
- if (timeout || restarting || !/\+(page|layout|server).*$/.test(file)) return;
366
- sync.update(svelte_config, manifest_data, file, root);
429
+ if (timeout || !/\+(page|layout|server).*$/.test(file)) return;
430
+ if (!sync.update(svelte_config, manifest_data, file, root)) debounce(update_manifest);
367
431
  });
368
432
 
369
433
  const { appTemplate, errorTemplate, serviceWorker, hooks } = svelte_config.kit.files;
@@ -372,14 +436,14 @@ export async function dev(vite, vite_config, svelte_config, get_remotes, root, a
372
436
  // kit defaults to src/app.html, so unless user changed that to index.html
373
437
  // send the vite client a full-reload event without path being set
374
438
  if (appTemplate !== 'index.html') {
375
- vite.watcher.on('change', (file) => {
376
- if (file === appTemplate && !restarting) {
377
- vite.ws.send({ type: 'full-reload' });
439
+ vite_dev_server.watcher.on('change', (file) => {
440
+ if (file === appTemplate) {
441
+ vite_dev_server.hot.send({ type: 'full-reload' });
378
442
  }
379
443
  });
380
444
  }
381
445
 
382
- vite.watcher.on('all', (_, file) => {
446
+ vite_dev_server.watcher.on('all', (_, file) => {
383
447
  if (
384
448
  file === appTemplate ||
385
449
  file === errorTemplate ||
@@ -390,30 +454,16 @@ export async function dev(vite, vite_config, svelte_config, get_remotes, root, a
390
454
  }
391
455
  });
392
456
 
393
- vite.watcher.on('change', async (file) => {
394
- // changing the svelte config requires restarting the dev server
395
- // the config is only read on start and passed on to vite-plugin-svelte
396
- // which needs up-to-date values to operate correctly
397
- if (file.match(/[/\\]svelte\.config\.[jt]s$/)) {
398
- console.log(`svelte config changed, restarting vite dev-server. changed file: ${file}`);
399
- restarting = true;
400
- await vite.restart();
401
- }
402
- });
403
-
404
457
  const assets = svelte_config.kit.paths.assets ? SVELTE_KIT_ASSETS : svelte_config.kit.paths.base;
405
458
  const asset_server = sirv(svelte_config.kit.files.assets, {
406
459
  dev: true,
407
460
  etag: true,
408
461
  maxAge: 0,
409
- extensions: [],
410
- setHeaders: (res) => {
411
- res.setHeader('access-control-allow-origin', '*');
412
- }
462
+ extensions: []
413
463
  });
414
464
 
415
- vite.middlewares.use((req, res, next) => {
416
- const base = `${vite.config.server.https ? 'https' : 'http'}://${
465
+ vite_dev_server.middlewares.use((req, res, next) => {
466
+ const base = `${vite_dev_server.config.server.https ? 'https' : 'http'}://${
417
467
  req.headers[':authority'] || req.headers.host
418
468
  }`;
419
469
 
@@ -435,25 +485,33 @@ export async function dev(vite, vite_config, svelte_config, get_remotes, root, a
435
485
  next();
436
486
  });
437
487
 
438
- const env = loadEnv(vite_config.mode, svelte_config.kit.env.dir, '');
439
- const emulator = await adapter?.emulate?.();
488
+ const env = vite.loadEnv(vite_config.mode, svelte_config.kit.env.dir, '');
489
+ const emulator = await svelte_config.kit.adapter?.emulate?.();
490
+
491
+ /** @type {Promise<void> | undefined} */
492
+ let init_manifest;
440
493
 
441
494
  return () => {
442
- const serve_static_middleware = vite.middlewares.stack.find(
495
+ const serve_static_middleware = vite_dev_server.middlewares.stack.find(
443
496
  (middleware) =>
444
497
  /** @type {Function} */ (middleware.handle).name === 'viteServeStaticMiddleware'
445
498
  );
446
499
 
447
500
  // Vite will give a 403 on URLs like /test, /static, and /package.json preventing us from
448
501
  // serving routes with those names. See https://github.com/vitejs/vite/issues/7363
449
- remove_static_middlewares(vite.middlewares);
502
+ remove_static_middlewares(vite_dev_server.middlewares);
503
+
504
+ vite_dev_server.middlewares.use(async (req, res) => {
505
+ // Vite throws a Cannot read properties of undefined (reading 'wrapDynamicImport')
506
+ // if you try to run ssr.runner.import before the server has started so
507
+ // we do it inside here to avoid that
508
+ await (init_manifest ??= update_manifest());
450
509
 
451
- vite.middlewares.use(async (req, res) => {
452
510
  // Vite's base middleware strips out the base path. Restore it
453
511
  const original_url = req.url;
454
512
  req.url = req.originalUrl;
455
513
  try {
456
- const base = `${vite.config.server.https ? 'https' : 'http'}://${
514
+ const base = `${vite_dev_server.config.server.https ? 'https' : 'http'}://${
457
515
  req.headers[':authority'] || req.headers.host
458
516
  }`;
459
517
 
@@ -497,27 +555,36 @@ export async function dev(vite, vite_config, svelte_config, get_remotes, root, a
497
555
  return;
498
556
  }
499
557
 
558
+ // resolve the instrumentation file per request so that changes to it
559
+ // are picked up on new requests
500
560
  const resolved_instrumentation = resolve_entry(
501
561
  path.join(svelte_config.kit.files.src, 'instrumentation.server')
502
562
  );
503
563
 
504
564
  if (resolved_instrumentation) {
505
- await vite.ssrLoadModule(resolved_instrumentation);
565
+ if (
566
+ svelte_config.kit.adapter &&
567
+ !svelte_config.kit.adapter.supports?.instrumentation?.()
568
+ ) {
569
+ throw new Error(
570
+ `${resolved_instrumentation} is unsupported in ${svelte_config.kit.adapter.name}.`
571
+ );
572
+ }
573
+
574
+ await runner.import(resolved_instrumentation);
506
575
  }
507
576
 
508
577
  // we have to import `Server` before calling `set_assets`
509
- const { Server } = /** @type {import('types').ServerModule} */ (
510
- await vite.ssrLoadModule(`${get_runtime_base(root)}/server/index.js`, {
511
- fixStacktrace: true
512
- })
578
+ const { Server } = /** @type {ServerModule} */ (
579
+ await runner.import(`${get_runtime_base(root)}/server/index.js`)
513
580
  );
514
581
 
515
- const { set_fix_stack_trace } = await vite.ssrLoadModule(
516
- `${get_runtime_base(root)}/shared-server.js`
582
+ const { set_fix_stack_trace, log_response } = await runner.import(
583
+ `${get_runtime_base(root)}/server/internal.js`
517
584
  );
518
585
  set_fix_stack_trace(fix_stack_trace);
519
586
 
520
- const { set_assets } = await vite.ssrLoadModule('$app/paths/internal/server');
587
+ const { set_assets } = await runner.import('$app/paths/internal/server');
521
588
  set_assets(assets);
522
589
 
523
590
  const server = new Server(manifest);
@@ -527,7 +594,7 @@ export async function dev(vite, vite_config, svelte_config, get_remotes, root, a
527
594
  read: (file) => createReadableStream(from_fs(file))
528
595
  });
529
596
 
530
- const request = await getRequest({
597
+ const request = getRequest({
531
598
  base,
532
599
  request: req
533
600
  });
@@ -578,15 +645,19 @@ export async function dev(vite, vite_config, svelte_config, get_remotes, root, a
578
645
  if (rendered.status === 404) {
579
646
  // @ts-expect-error
580
647
  serve_static_middleware.handle(req, res, () => {
581
- void setResponse(res, rendered);
648
+ log_response(rendered.status, request);
649
+ setResponse(res, rendered);
582
650
  });
583
651
  } else {
584
- void setResponse(res, rendered);
652
+ log_response(rendered.status, request);
653
+ setResponse(res, rendered);
585
654
  }
586
655
  } catch (e) {
587
656
  const error = coalesce_to_error(e);
588
657
  res.statusCode = 500;
589
- res.end(fix_stack_trace(error) || error.message); // handle `stackless` errors
658
+ fix_stack_trace(error);
659
+ console.error(styleText(['bold', 'red'], String(error)));
660
+ res.end(error.stack || error.message); // handle `stackless` errors
590
661
  }
591
662
  });
592
663
  };
@@ -606,17 +677,17 @@ function remove_static_middlewares(server) {
606
677
  }
607
678
 
608
679
  /**
609
- * @param {import('vite').ViteDevServer} vite
610
- * @param {import('vite').ModuleNode | import('vite').EnvironmentModuleNode} node
611
- * @param {Set<import('vite').ModuleNode | import('vite').EnvironmentModuleNode>} deps
680
+ * @param {ViteDevServer} vite
681
+ * @param {EnvironmentModuleNode} node
682
+ * @param {Set<EnvironmentModuleNode>} deps
612
683
  */
613
684
  async function find_deps(vite, node, deps) {
614
- // since `ssrTransformResult.deps` contains URLs instead of `ModuleNode`s, this process is asynchronous.
685
+ // since `transformResult.deps` contains URLs instead of `ModuleNode`s, this process is asynchronous.
615
686
  // instead of using `await`, we resolve all branches in parallel.
616
687
  /** @type {Promise<void>[]} */
617
688
  const branches = [];
618
689
 
619
- /** @param {import('vite').ModuleNode | import('vite').EnvironmentModuleNode} node */
690
+ /** @param {EnvironmentModuleNode} node */
620
691
  async function add(node) {
621
692
  if (!deps.has(node)) {
622
693
  deps.add(node);
@@ -626,23 +697,20 @@ async function find_deps(vite, node, deps) {
626
697
 
627
698
  /** @param {string} url */
628
699
  async function add_by_url(url) {
629
- const node = await get_server_module_by_url(vite, url);
700
+ const node = await vite.environments.ssr.moduleGraph.getModuleByUrl(url);
630
701
 
631
702
  if (node) {
632
703
  await add(node);
633
704
  }
634
705
  }
635
706
 
636
- const transform_result =
637
- /** @type {import('vite').ModuleNode} */ (node).ssrTransformResult || node.transformResult;
638
-
639
- if (transform_result) {
640
- if (transform_result.deps) {
641
- transform_result.deps.forEach((url) => branches.push(add_by_url(url)));
707
+ if (node.transformResult) {
708
+ if (node.transformResult.deps) {
709
+ node.transformResult.deps.forEach((url) => branches.push(add_by_url(url)));
642
710
  }
643
711
 
644
- if (transform_result.dynamicDeps) {
645
- transform_result.dynamicDeps.forEach((url) => branches.push(add_by_url(url)));
712
+ if (node.transformResult.dynamicDeps) {
713
+ node.transformResult.dynamicDeps.forEach((url) => branches.push(add_by_url(url)));
646
714
  }
647
715
  } else {
648
716
  node.importedModules.forEach((node) => branches.push(add(node)));
@@ -651,16 +719,6 @@ async function find_deps(vite, node, deps) {
651
719
  await Promise.all(branches);
652
720
  }
653
721
 
654
- /**
655
- * @param {import('vite').ViteDevServer} vite
656
- * @param {string} url
657
- */
658
- function get_server_module_by_url(vite, url) {
659
- return vite.environments
660
- ? vite.environments.ssr.moduleGraph.getModuleByUrl(url)
661
- : vite.moduleGraph.getModuleByUrl(url, true);
662
- }
663
-
664
722
  /**
665
723
  * Determine if a file is being requested with the correct case,
666
724
  * to ensure consistent behaviour between dev and prod and across
@@ -681,3 +739,19 @@ function has_correct_case(file, assets) {
681
739
 
682
740
  return false;
683
741
  }
742
+
743
+ /**
744
+ * Invalidates a module in all environments.
745
+ * @param {ViteDevServer} server
746
+ * @param {string} id
747
+ * @returns {void}
748
+ */
749
+ export function invalidate_module(server, id) {
750
+ for (const environment in server.environments) {
751
+ const module = server.environments[environment].moduleGraph.getModuleById(id);
752
+ if (module) {
753
+ server.environments[environment].moduleGraph.invalidateModule(module);
754
+ void server.environments[environment].reloadModule(module);
755
+ }
756
+ }
757
+ }