@sveltejs/kit 3.0.0-next.12 → 3.0.0-next.13

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 (46) hide show
  1. package/package.json +10 -10
  2. package/src/core/postbuild/prerender.js +3 -3
  3. package/src/core/sync/write_app_types.js +1 -2
  4. package/src/core/sync/write_tsconfig/index.js +13 -1
  5. package/src/exports/index.js +23 -12
  6. package/src/exports/internal/shared.js +4 -12
  7. package/src/exports/public.d.ts +59 -11
  8. package/src/exports/vite/build/remote.js +10 -12
  9. package/src/exports/vite/dev/index.js +32 -19
  10. package/src/exports/vite/index.js +118 -123
  11. package/src/runtime/app/server/remote/form.js +9 -1
  12. package/src/runtime/app/server/remote/prerender.js +13 -9
  13. package/src/runtime/app/server/remote/requested.js +4 -4
  14. package/src/runtime/app/state/client.js +3 -0
  15. package/src/runtime/app/state/index.js +2 -2
  16. package/src/runtime/app/state/server.js +3 -0
  17. package/src/runtime/client/client.js +584 -305
  18. package/src/runtime/client/constants.js +2 -6
  19. package/src/runtime/client/fetcher.js +27 -17
  20. package/src/runtime/client/remote-functions/form.svelte.js +39 -7
  21. package/src/runtime/client/remote-functions/prerender.svelte.js +1 -1
  22. package/src/runtime/client/remote-functions/query/instance.svelte.js +2 -2
  23. package/src/runtime/client/remote-functions/query-batch.svelte.js +1 -1
  24. package/src/runtime/client/remote-functions/query-live/instance.svelte.js +2 -2
  25. package/src/runtime/client/remote-functions/query-live/iterator.js +10 -8
  26. package/src/runtime/client/remote-functions/shared.svelte.js +11 -10
  27. package/src/runtime/client/state.svelte.js +10 -22
  28. package/src/runtime/client/types.d.ts +1 -2
  29. package/src/runtime/client/utils.js +21 -14
  30. package/src/runtime/components/root.svelte +4 -14
  31. package/src/runtime/props.svelte.js +71 -0
  32. package/src/runtime/server/fetch.js +4 -6
  33. package/src/runtime/server/page/csp.js +86 -103
  34. package/src/runtime/server/page/index.js +1 -2
  35. package/src/runtime/server/page/load_data.js +15 -5
  36. package/src/runtime/server/page/render.js +27 -24
  37. package/src/runtime/server/page/respond_with_error.js +1 -3
  38. package/src/runtime/server/respond.js +0 -2
  39. package/src/types/ambient-private.d.ts +1 -1
  40. package/src/types/ambient.d.ts +1 -1
  41. package/src/types/internal.d.ts +2 -7
  42. package/src/types/private.d.ts +3 -12
  43. package/src/version.js +1 -1
  44. package/types/index.d.ts +92 -57
  45. package/types/index.d.ts.map +2 -1
  46. package/src/runtime/types.d.ts +0 -8
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sveltejs/kit",
3
- "version": "3.0.0-next.12",
3
+ "version": "3.0.0-next.13",
4
4
  "description": "SvelteKit is the fastest way to build Svelte apps",
5
5
  "keywords": [
6
6
  "framework",
@@ -30,7 +30,7 @@
30
30
  },
31
31
  "devDependencies": {
32
32
  "@opentelemetry/api": "^1.9.0",
33
- "@playwright/test": "^1.61.1",
33
+ "@playwright/test": "~1.61.0",
34
34
  "@sveltejs/vite-plugin-svelte": "^7.0.0",
35
35
  "@types/connect": "^3.4.38",
36
36
  "@types/node": "^22.19.19",
@@ -40,7 +40,7 @@
40
40
  "svelte": "^5.56.3",
41
41
  "svelte-preprocess": "^6.0.5",
42
42
  "typescript": "~6.0.3",
43
- "valibot": "^1.2.0",
43
+ "valibot": "^1.4.2",
44
44
  "vite": "^8.1.5",
45
45
  "vitest": "^4.1.10"
46
46
  },
@@ -136,15 +136,15 @@
136
136
  "format": "prettier --config ../../.prettierrc --write .",
137
137
  "test": "pnpm test:unit && pnpm test:integration",
138
138
  "test:integration": "pnpm -r --workspace-concurrency 1 --filter=\"./test/**\" test",
139
- "test:cross-platform:dev": "pnpm -r --workspace-concurrency 1 --filter=\"./test/**\" test:cross-platform:dev",
140
- "test:cross-platform:build": "pnpm test:unit && pnpm -r --workspace-concurrency 1 --filter=\"./test/**\" test:cross-platform:build",
139
+ "test:dev": "pnpm -r --workspace-concurrency 1 --filter=\"./test/**\" test:dev",
140
+ "test:build": "pnpm -r --workspace-concurrency 1 --filter=\"./test/**\" test:build",
141
+ "test:cross-platform:dev": "pnpm test:unit && pnpm -r --workspace-concurrency 1 --filter=\"./test/**\" test:cross-platform:dev",
142
+ "test:cross-platform:build": "pnpm -r --workspace-concurrency 1 --filter=\"./test/**\" test:cross-platform:build",
141
143
  "test:server-side-route-resolution:dev": "pnpm -r --workspace-concurrency 1 --filter=\"./test/**\" test:server-side-route-resolution:dev",
142
- "test:server-side-route-resolution:build": "pnpm test:unit && pnpm -r --workspace-concurrency 1 --filter=\"./test/**\" test:server-side-route-resolution:build",
144
+ "test:server-side-route-resolution:build": "pnpm -r --workspace-concurrency 1 --filter=\"./test/**\" test:server-side-route-resolution:build",
143
145
  "test:svelte-async:dev": "pnpm -r --workspace-concurrency 1 --filter=\"./test/**\" test:svelte-async:dev",
144
- "test:svelte-async:build": "pnpm test:unit && pnpm -r --workspace-concurrency 1 --filter=\"./test/**\" test:svelte-async:build",
145
- "test:unit:dev": "vitest --config kit.vitest.config.js run",
146
- "test:unit:prod": "NODE_ENV=production vitest --config kit.vitest.config.js run csp.spec.js cookie.spec.js",
147
- "test:unit": "pnpm test:unit:dev && pnpm test:unit:prod",
146
+ "test:svelte-async:build": "pnpm -r --workspace-concurrency 1 --filter=\"./test/**\" test:svelte-async:build",
147
+ "test:unit": "vitest run ./",
148
148
  "generate:version": "node scripts/generate-version.js",
149
149
  "generate:types": "node scripts/generate-dts.js"
150
150
  }
@@ -265,7 +265,7 @@ async function prerender({ hash, out, manifest_path, metadata, verbose, env, vit
265
265
  /** @type {Map<string, Set<string>>} */
266
266
  const expected_hashlinks = new Map();
267
267
 
268
- /** @type {Map<string, string[]>} */
268
+ /** @type {Map<string, Set<string>>} */
269
269
  const actual_hashlinks = new Map();
270
270
 
271
271
  /**
@@ -394,7 +394,7 @@ async function prerender({ hash, out, manifest_path, metadata, verbose, env, vit
394
394
  handle_invalid_url({ href, referrer: decoded });
395
395
  }
396
396
 
397
- actual_hashlinks.set(decoded, ids);
397
+ actual_hashlinks.set(decoded, new Set(ids));
398
398
 
399
399
  /** @param {string} href */
400
400
  const removePrerenderOrigin = (href) => {
@@ -646,7 +646,7 @@ async function prerender({ hash, out, manifest_path, metadata, verbose, env, vit
646
646
  // ignore fragment links to pages that were not prerendered
647
647
  if (!hashlinks) continue;
648
648
 
649
- if (!hashlinks.includes(id) && !SPECIAL_HASHLINKS.has(id)) {
649
+ if (!hashlinks.has(id) && !SPECIAL_HASHLINKS.has(id)) {
650
650
  handle_missing_id({ id, path, referrers: Array.from(referrers) });
651
651
  }
652
652
  }
@@ -53,8 +53,6 @@ function get_pathnames_for_trailing_slash(pathname, route) {
53
53
  const template = `
54
54
  declare module "svelte/elements" {
55
55
  export interface HTMLAttributes<T> {
56
- 'data-sveltekit-keepfocus'?: true | false | '' | undefined | null;
57
- 'data-sveltekit-noscroll'?: true | false | '' | undefined | null;
58
56
  'data-sveltekit-preload-code'?:
59
57
  | true
60
58
  | false
@@ -68,6 +66,7 @@ declare module "svelte/elements" {
68
66
  'data-sveltekit-preload-data'?: true | false | '' | 'hover' | 'tap' | undefined | null;
69
67
  'data-sveltekit-reload'?: true | false | '' | undefined | null;
70
68
  'data-sveltekit-replacestate'?: true | false | '' | undefined | null;
69
+ 'data-sveltekit-reset'?: true | false | '' | undefined | null;
71
70
  }
72
71
  }
73
72
  `;
@@ -2,7 +2,6 @@
2
2
  import process from 'node:process';
3
3
  import fs from 'node:fs';
4
4
  import path from 'node:path';
5
- import ts from 'typescript';
6
5
  import { styleText } from 'node:util';
7
6
  import { write_if_changed } from '../utils.js';
8
7
  import {
@@ -15,6 +14,14 @@ import {
15
14
  validate_resolved_config
16
15
  } from './utils.js';
17
16
 
17
+ /** @type {import('typescript')} */
18
+ let ts;
19
+ try {
20
+ ts = await import('typescript');
21
+ } catch {
22
+ // The user has not installed TypeScript.
23
+ }
24
+
18
25
  /**
19
26
  * Generates the tsconfig that the user's tsconfig inherits from.
20
27
  * @param {import('types').ValidatedKitConfig} kit
@@ -85,6 +92,11 @@ function write_parent_tsconfig(root, dir, id, config, example, transform) {
85
92
 
86
93
  write_if_changed(out_file, JSON.stringify(normalized, null, '\t'));
87
94
 
95
+ if (!ts) {
96
+ // The user has not installed TypeScript. Skip validation of config.
97
+ return;
98
+ }
99
+
88
100
  const user_config = load_user_tsconfig(dir);
89
101
 
90
102
  if (user_config && modified_since_last_check(user_config.file)) {
@@ -27,10 +27,10 @@ export { defineParams } from './params.js';
27
27
  * return an error response without invoking `handleError`.
28
28
  * Make sure you're not catching the thrown error, which would prevent SvelteKit from handling it.
29
29
  * @param {number} status The [HTTP status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#client_error_responses). Must be in the range 400-599.
30
- * @param {Omit<App.Error, 'status'> & { status?: App.Error['status'] }} body An object that conforms to the App.Error type. If a string is passed, it will be used as the message property.
30
+ * @param {string} [message] The error message.
31
31
  * @overload
32
- * @param {number} status
33
- * @param {Omit<App.Error, 'status'> & { status?: App.Error['status'] }} body
32
+ * @param {{ status: number; message: string } extends App.Error ? number : never} status
33
+ * @param {{ status: number; message: string } extends App.Error ? string : never} [message]
34
34
  * @return {never}
35
35
  * @throws {import('./public.js').HttpError} This error instructs SvelteKit to initiate HTTP error handling.
36
36
  * @throws {Error} If the provided status is invalid (not between 400 and 599).
@@ -41,10 +41,12 @@ export { defineParams } from './params.js';
41
41
  * return an error response without invoking `handleError`.
42
42
  * Make sure you're not catching the thrown error, which would prevent SvelteKit from handling it.
43
43
  * @param {number} status The [HTTP status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#client_error_responses). Must be in the range 400-599.
44
- * @param {{ status: number; message: string } extends App.Error ? string | void | undefined : never} body The error message.
44
+ * @param {string} message The error message.
45
+ * @param {{ status: number; message: string } extends App.Error ? never : Omit<App.Error, 'status' | 'message'>} properties Additional properties of the App.Error type.
45
46
  * @overload
46
47
  * @param {number} status
47
- * @param {{ status: number; message: string } extends App.Error ? string | void | undefined : never} body
48
+ * @param {string} message
49
+ * @param {{ status: number; message: string } extends App.Error ? never : Omit<App.Error, 'status' | 'message'>} properties
48
50
  * @return {never}
49
51
  * @throws {import('./public.js').HttpError} This error instructs SvelteKit to initiate HTTP error handling.
50
52
  * @throws {Error} If the provided status is invalid (not between 400 and 599).
@@ -54,13 +56,12 @@ export { defineParams } from './params.js';
54
56
  * When called during request handling, this will cause SvelteKit to
55
57
  * return an error response without invoking `handleError`.
56
58
  * Make sure you're not catching the thrown error, which would prevent SvelteKit from handling it.
59
+ * @deprecated Passing an `App.Error` body as the second argument is deprecated — pass the `message` as the second argument, and any additional properties as the third
57
60
  * @param {number} status The [HTTP status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#client_error_responses). Must be in the range 400-599.
58
- * @param {string} body The error message.
59
- * @param {{ status: number; message: string } extends App.Error ? never : Omit<App.Error, 'status' | 'message'>} properties Additional properties of the App.Error type.
61
+ * @param {Omit<App.Error, 'status'> & { status?: App.Error['status'] }} body An object that conforms to the App.Error type. If a string is passed, it will be used as the message property.
60
62
  * @overload
61
63
  * @param {number} status
62
- * @param {string} body
63
- * @param {{ status: number; message: string } extends App.Error ? never : Omit<App.Error, 'status' | 'message'>} properties
64
+ * @param {Omit<App.Error, 'status'> & { status?: App.Error['status'] }} properties
64
65
  * @return {never}
65
66
  * @throws {import('./public.js').HttpError} This error instructs SvelteKit to initiate HTTP error handling.
66
67
  * @throws {Error} If the provided status is invalid (not between 400 and 599).
@@ -71,18 +72,28 @@ export { defineParams } from './params.js';
71
72
  * return an error response without invoking `handleError`.
72
73
  * Make sure you're not catching the thrown error, which would prevent SvelteKit from handling it.
73
74
  * @param {any} status The [HTTP status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#client_error_responses). Must be in the range 400-599.
74
- * @param {any} [body] An object that conforms to the App.Error type. If a string is passed, it will be used as the message property.
75
+ * @param {any} [message] A string, or (deprecated) a partial App.Error object
75
76
  * @param {any} [properties] Additional properties of the App.Error type when passing a string message.
76
77
  * @return {never}
77
78
  * @throws {import('./public.js').HttpError} This error instructs SvelteKit to initiate HTTP error handling.
78
79
  * @throws {Error} If the provided status is invalid (not between 400 and 599).
79
80
  */
80
- export function error(status, body, properties) {
81
+ export function error(status, message, properties) {
81
82
  if ((!BROWSER || DEV) && (isNaN(status) || status < 400 || status > 599)) {
82
83
  throw new Error(`HTTP error status codes must be between 400 and 599 — ${status} is invalid`);
83
84
  }
84
85
 
85
- throw new HttpError(status, body, properties);
86
+ if (message !== undefined && typeof message !== 'string') {
87
+ if (DEV) {
88
+ console.warn(
89
+ 'Passing an `App.Error` body as the second argument is deprecated — pass the `message` as the second argument, and any additional properties as the third'
90
+ );
91
+ }
92
+
93
+ ({ message, ...properties } = message);
94
+ }
95
+
96
+ throw new HttpError({ ...properties, status, message: message ?? `Error: ${status}` });
86
97
  }
87
98
 
88
99
  /**
@@ -2,19 +2,11 @@
2
2
 
3
3
  export class HttpError {
4
4
  /**
5
- * @param {number} status
6
- * @param {Omit<App.Error, 'status'> | string | undefined} body
7
- * @param {Omit<App.Error, 'status' | 'message'>} [properties]
5
+ * @param {App.Error} error
8
6
  */
9
- constructor(status, body, properties) {
10
- this.status = status;
11
- if (typeof body === 'string') {
12
- this.body = { ...properties, message: body, status };
13
- } else if (body) {
14
- this.body = { ...body, status };
15
- } else {
16
- this.body = { message: `Error: ${status}`, status };
17
- }
7
+ constructor(error) {
8
+ this.status = error.status;
9
+ this.body = error;
18
10
  }
19
11
 
20
12
  toString() {
@@ -862,7 +862,7 @@ export interface KitConfig {
862
862
  * A function that allows you to edit the generated `tsconfig.json`. You can mutate the config (recommended) or return a new one.
863
863
  * This is useful for extending a shared `tsconfig.json` in a monorepo root, for example.
864
864
  *
865
- * Note that any paths configured here should be relative to the generated config file, which is written to `.svelte-kit/tsconfig.json`.
865
+ * Note that any paths configured here should be relative to the generated config file, which is written to `node_modules/$app/tsconfig/tsconfig.json`.
866
866
  *
867
867
  * @default (config) => config
868
868
  * @since 1.3.0
@@ -1237,6 +1237,46 @@ export interface NavigationTarget<
1237
1237
  scroll: { x: number; y: number } | null;
1238
1238
  }
1239
1239
 
1240
+ export interface GotoOptions {
1241
+ /**
1242
+ * If `true`, replaces the current history entry rather than creating a new one.
1243
+ * @default false
1244
+ */
1245
+ replace?: boolean;
1246
+ /** @deprecated Use `replace` instead. */
1247
+ replaceState?: boolean;
1248
+ /**
1249
+ * If `true`, updates the URL and `page.state` without navigating.
1250
+ * @default false
1251
+ */
1252
+ shallow?: boolean;
1253
+ /**
1254
+ * If `true`, resets the scroll position (to the top of the page, or to the element
1255
+ * matching the URL's `#hash` if there is one) and resets focus (to the `<body>`, or the
1256
+ * `autofocus` element if there is one) once the navigation completes.
1257
+ *
1258
+ * If `false`, the current scroll position and focused element are left alone.
1259
+ * @default true, or false when `shallow` is true
1260
+ */
1261
+ reset?: boolean;
1262
+ /**
1263
+ * If `true`, reruns all `load` functions and queries of the page.
1264
+ * @default false
1265
+ */
1266
+ refreshAll?: boolean;
1267
+ /** Causes any `load` functions to rerun if they depend on one of the URLs. */
1268
+ invalidate?: Array<string | URL | ((url: URL) => boolean)>;
1269
+ /** @deprecated Use `refreshAll` instead. */
1270
+ invalidateAll?: boolean;
1271
+ /** An optional object that will be available as `page.state`. */
1272
+ state?: App.PageState;
1273
+ /**
1274
+ * If `true`, `page.state` will be restored after a full page reload.
1275
+ * @default false
1276
+ */
1277
+ persistState?: boolean;
1278
+ }
1279
+
1240
1280
  /**
1241
1281
  * - `enter`: The app has hydrated/started
1242
1282
  * - `form`: The user submitted a `<form method="GET">`
@@ -1258,6 +1298,8 @@ export interface NavigationBase {
1258
1298
  * - `popstate`: Navigation was triggered by back/forward navigation
1259
1299
  */
1260
1300
  type: NavigationType;
1301
+ /** Whether this is a shallow navigation. */
1302
+ shallow: boolean;
1261
1303
  /**
1262
1304
  * Where navigation was triggered from
1263
1305
  */
@@ -1352,10 +1394,7 @@ export interface NavigationLink extends NavigationBase {
1352
1394
  }
1353
1395
 
1354
1396
  export type Navigation =
1355
- | NavigationExternal
1356
- | NavigationFormSubmit
1357
- | NavigationPopState
1358
- | NavigationLink;
1397
+ NavigationExternal | NavigationFormSubmit | NavigationPopState | NavigationLink;
1359
1398
 
1360
1399
  /**
1361
1400
  * The argument passed to [`beforeNavigate`](https://svelte.dev/docs/kit/$app-navigation#beforeNavigate) callbacks.
@@ -1426,9 +1465,20 @@ export interface Page<
1426
1465
  */
1427
1466
  data: App.PageData & Record<string, any>;
1428
1467
  /**
1429
- * The page state, which can be manipulated using the [`pushState`](https://svelte.dev/docs/kit/$app-navigation#pushState) and [`replaceState`](https://svelte.dev/docs/kit/$app-navigation#replaceState) functions from `$app/navigation`.
1468
+ * The page state, which can be manipulated using [`goto`](https://svelte.dev/docs/kit/$app-navigation#goto) from `$app/navigation`.
1430
1469
  */
1431
1470
  state: App.PageState;
1471
+ /**
1472
+ * Information about the target of the current shallow navigation, or `null` if no shallow navigation has occurred.
1473
+ */
1474
+ shallow: {
1475
+ /** Parameters of the target route, or `null` if the URL does not resolve to a route. */
1476
+ params: AppLayoutParams<'/'> | null;
1477
+ /** Info about the target route, or `null` if the URL does not resolve to a route. */
1478
+ route: { id: AppRouteId } | null;
1479
+ /** The normalized URL passed to `goto(..., { shallow: true })`. */
1480
+ url: ReadonlyURL;
1481
+ } | null;
1432
1482
  /**
1433
1483
  * Filled only after a form submission. See [form actions](https://svelte.dev/docs/kit/form-actions) for more info.
1434
1484
  */
@@ -1449,8 +1499,7 @@ export type ParamValue = string | number | boolean | bigint;
1449
1499
  * A param matcher definition passed to [`defineParams`](https://svelte.dev/docs/kit/@sveltejs-kit#defineParams).
1450
1500
  */
1451
1501
  export type ParamDefinition =
1452
- | ((param: string) => ParamValue | undefined)
1453
- | StandardSchemaV1<string, ParamValue>;
1502
+ ((param: string) => ParamValue | undefined) | StandardSchemaV1<string, ParamValue>;
1454
1503
 
1455
1504
  /**
1456
1505
  * The return type of [`defineParams`](https://svelte.dev/docs/kit/@sveltejs-kit#defineParams).
@@ -1555,8 +1604,7 @@ export type LiveQueryRequestedResult<Validated, Output> = Iterable<
1555
1604
  };
1556
1605
 
1557
1606
  export type RequestedResult<Validated, Output> =
1558
- | QueryRequestedResult<Validated, Output>
1559
- | LiveQueryRequestedResult<Validated, Output>;
1607
+ QueryRequestedResult<Validated, Output> | LiveQueryRequestedResult<Validated, Output>;
1560
1608
 
1561
1609
  export interface RequestEvent<
1562
1610
  Params extends AppLayoutParams<'/'> = AppLayoutParams<'/'>,
@@ -1737,7 +1785,7 @@ export class Server {
1737
1785
 
1738
1786
  export interface ServerInitOptions {
1739
1787
  /** A map of environment variables. */
1740
- env: Record<string, string>;
1788
+ env: Record<string, string | undefined>;
1741
1789
  /** A function that turns an asset filename into a `ReadableStream`. Required for the `read` export from `$app/server` to work. */
1742
1790
  read?: (file: string) => MaybePromise<ReadableStream | null>;
1743
1791
  }
@@ -11,6 +11,7 @@ import { posixify } from '../../../utils/os.js';
11
11
  * @param {typeof import('vite')} vite
12
12
  * @param {string} out
13
13
  * @param {Array<{ hash: string, file: string }>} remotes
14
+ * @param {Map<string, string>} remote_original_by_hash
14
15
  * @param {ServerMetadata} metadata
15
16
  * @param {string} cwd
16
17
  * @param {(Rolldown.OutputAsset | Rolldown.OutputChunk)[]} server_chunks
@@ -20,6 +21,7 @@ export async function treeshake_prerendered_remotes(
20
21
  vite,
21
22
  out,
22
23
  remotes,
24
+ remote_original_by_hash,
23
25
  metadata,
24
26
  cwd,
25
27
  server_chunks,
@@ -45,11 +47,11 @@ export async function treeshake_prerendered_remotes(
45
47
 
46
48
  if (prerendered.length === 0) continue; // nothing to treeshake
47
49
 
48
- // remove file extension
49
- const remote_filename = path.basename(remote.file).split('.').slice(0, -1).join('.');
50
+ const original_id = remote_original_by_hash.get(remote.hash);
51
+ if (!original_id) continue;
50
52
 
51
53
  const remote_chunk = server_chunks.find((chunk) => {
52
- return chunk.name === remote_filename;
54
+ return chunk.type === 'chunk' && chunk.moduleIds.includes(original_id);
53
55
  });
54
56
 
55
57
  if (!remote_chunk) continue;
@@ -116,16 +118,12 @@ export async function treeshake_prerendered_remotes(
116
118
  })
117
119
  );
118
120
 
121
+ // the only possible outputs are the treeshaken chunk and, with sourcemaps, its map
119
122
  for (const output of bundle.output) {
120
- if (output.type !== 'chunk' || output.name !== 'treeshaken') return;
121
-
122
- fs.writeFileSync(chunk_path, output.code);
123
-
124
- const chunk_sourcemap = bundle.output.find(
125
- (o) => o.type === 'asset' && o.fileName === output.fileName + '.map'
126
- );
127
- if (chunk_sourcemap && chunk_sourcemap.type === 'asset') {
128
- fs.writeFileSync(chunk_path + '.map', chunk_sourcemap.source);
123
+ if (output.type === 'chunk') {
124
+ fs.writeFileSync(chunk_path, output.code);
125
+ } else {
126
+ fs.writeFileSync(chunk_path + '.map', output.source);
129
127
  }
130
128
  }
131
129
  }
@@ -1,5 +1,6 @@
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' */
3
4
  import process from 'node:process';
4
5
  import fs from 'node:fs';
5
6
  import path from 'node:path';
@@ -35,12 +36,12 @@ import { get_runner } from '../../../runner.js';
35
36
  const vite_css_query_regex = /(?:\?|&)(?:raw|url|inline)(?:&|$)/;
36
37
 
37
38
  /**
38
- * @param {import('vite').ViteDevServer} vite
39
- * @param {import('vite').ResolvedConfig} vite_config
40
- * @param {import('types').ValidatedConfig} svelte_config
41
- * @param {() => Array<{ hash: string, file: string }>} get_remotes
39
+ * @param {ViteDevServer} vite
40
+ * @param {ResolvedConfig} vite_config
41
+ * @param {ValidatedConfig} svelte_config
42
+ * @param {() => RemoteChunk[]} get_remotes
42
43
  * @param {string} root The project root directory
43
- * @param {(manifest_data: import('types').ManifestData) => void} set_manifest_data
44
+ * @param {(manifest_data: ManifestData) => void} set_manifest_data
44
45
  * @return {Promise<Promise<() => void>>}
45
46
  */
46
47
  export async function dev(vite, vite_config, svelte_config, get_remotes, root, set_manifest_data) {
@@ -72,9 +73,9 @@ export async function dev(vite, vite_config, svelte_config, get_remotes, root, s
72
73
 
73
74
  sync.init(svelte_config, root);
74
75
 
75
- /** @type {import('types').ManifestData} */
76
+ /** @type {ManifestData} */
76
77
  let manifest_data;
77
- /** @type {import('@sveltejs/kit').SSRManifest} */
78
+ /** @type {SSRManifest} */
78
79
  let manifest;
79
80
 
80
81
  /** @type {Error | null} */
@@ -104,7 +105,7 @@ export async function dev(vite, vite_config, svelte_config, get_remotes, root, s
104
105
  // we need a more considered approach
105
106
  vite.hot.send({
106
107
  type: 'error',
107
- err: /** @type {import('vite').ErrorPayload['err']} */ ({
108
+ err: /** @type {ErrorPayload['err']} */ ({
108
109
  ...err,
109
110
  // these properties are non-enumerable and will
110
111
  // not be serialized unless we explicitly include them
@@ -211,7 +212,7 @@ export async function dev(vite, vite_config, svelte_config, get_remotes, root, s
211
212
  ),
212
213
  nodes: manifest_data.nodes.map((node, index) => {
213
214
  return async () => {
214
- /** @type {import('types').SSRNode} */
215
+ /** @type {SSRNode} */
215
216
  const result = {};
216
217
  result.index = index;
217
218
  result.universal_id = node.universal;
@@ -222,7 +223,7 @@ export async function dev(vite, vite_config, svelte_config, get_remotes, root, s
222
223
  result.stylesheets = [];
223
224
  result.fonts = [];
224
225
 
225
- /** @type {import('vite').EnvironmentModuleNode[]} */
226
+ /** @type {EnvironmentModuleNode[]} */
226
227
  const module_nodes = [];
227
228
 
228
229
  if (node.component) {
@@ -256,7 +257,7 @@ export async function dev(vite, vite_config, svelte_config, get_remotes, root, s
256
257
  // in dev we inline all styles to avoid FOUC. this gets populated lazily so that
257
258
  // components/stylesheets loaded via import() during `load` are included
258
259
  result.inline_styles = async () => {
259
- /** @type {Set<import('vite').EnvironmentModuleNode>} */
260
+ /** @type {Set<EnvironmentModuleNode>} */
260
261
  const deps = new Set();
261
262
 
262
263
  for (const module_node of module_nodes) {
@@ -547,16 +548,27 @@ export async function dev(vite, vite_config, svelte_config, get_remotes, root, s
547
548
  return;
548
549
  }
549
550
 
551
+ // resolve the instrumentation file per request so that changes to it
552
+ // are picked up on new requests
550
553
  const resolved_instrumentation = resolve_entry(
551
554
  path.join(svelte_config.kit.files.src, 'instrumentation.server')
552
555
  );
553
556
 
554
557
  if (resolved_instrumentation) {
558
+ if (
559
+ svelte_config.kit.adapter &&
560
+ !svelte_config.kit.adapter.supports?.instrumentation?.()
561
+ ) {
562
+ throw new Error(
563
+ `${resolved_instrumentation} is unsupported in ${svelte_config.kit.adapter.name}.`
564
+ );
565
+ }
566
+
555
567
  await runner.import(resolved_instrumentation);
556
568
  }
557
569
 
558
570
  // we have to import `Server` before calling `set_assets`
559
- const { Server } = /** @type {import('types').ServerModule} */ (
571
+ const { Server } = /** @type {ServerModule} */ (
560
572
  await runner.import(`${get_runtime_base(root)}/server/index.js`)
561
573
  );
562
574
 
@@ -637,6 +649,7 @@ export async function dev(vite, vite_config, svelte_config, get_remotes, root, s
637
649
  const error = coalesce_to_error(e);
638
650
  res.statusCode = 500;
639
651
  fix_stack_trace(error);
652
+ console.error(styleText(['bold', 'red'], String(error)));
640
653
  res.end(error.stack || error.message); // handle `stackless` errors
641
654
  }
642
655
  });
@@ -657,9 +670,9 @@ function remove_static_middlewares(server) {
657
670
  }
658
671
 
659
672
  /**
660
- * @param {import('vite').ViteDevServer} vite
661
- * @param {import('vite').EnvironmentModuleNode} node
662
- * @param {Set<import('vite').EnvironmentModuleNode>} deps
673
+ * @param {ViteDevServer} vite
674
+ * @param {EnvironmentModuleNode} node
675
+ * @param {Set<EnvironmentModuleNode>} deps
663
676
  */
664
677
  async function find_deps(vite, node, deps) {
665
678
  // since `transformResult.deps` contains URLs instead of `ModuleNode`s, this process is asynchronous.
@@ -667,7 +680,7 @@ async function find_deps(vite, node, deps) {
667
680
  /** @type {Promise<void>[]} */
668
681
  const branches = [];
669
682
 
670
- /** @param {import('vite').EnvironmentModuleNode} node */
683
+ /** @param {EnvironmentModuleNode} node */
671
684
  async function add(node) {
672
685
  if (!deps.has(node)) {
673
686
  deps.add(node);
@@ -722,7 +735,7 @@ function has_correct_case(file, assets) {
722
735
 
723
736
  /**
724
737
  * Invalidates a module in all environments.
725
- * @param {import('vite').ViteDevServer} server
738
+ * @param {ViteDevServer} server
726
739
  * @param {string} id
727
740
  * @returns {void}
728
741
  */