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

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 (77) hide show
  1. package/package.json +11 -11
  2. package/src/cli.js +2 -2
  3. package/src/core/adapt/builder.js +8 -5
  4. package/src/core/generate_manifest/index.js +6 -0
  5. package/src/core/postbuild/entities.js +8 -2
  6. package/src/core/postbuild/fallback.js +2 -1
  7. package/src/core/postbuild/prerender.js +15 -6
  8. package/src/core/sync/create_manifest_data/conflict.js +1 -1
  9. package/src/core/sync/create_manifest_data/index.js +33 -2
  10. package/src/core/sync/write_app_types.js +73 -29
  11. package/src/core/sync/write_tsconfig/index.js +15 -2
  12. package/src/core/sync/write_types/index.js +5 -2
  13. package/src/exports/index.js +23 -12
  14. package/src/exports/internal/shared.js +4 -12
  15. package/src/exports/node/index.js +2 -7
  16. package/src/exports/public.d.ts +61 -12
  17. package/src/exports/vite/build/remote.js +10 -12
  18. package/src/exports/vite/dev/index.js +32 -19
  19. package/src/exports/vite/index.js +162 -133
  20. package/src/exports/vite/utils.js +1 -7
  21. package/src/runtime/app/server/remote/form.js +9 -1
  22. package/src/runtime/app/server/remote/prerender.js +13 -9
  23. package/src/runtime/app/server/remote/query.js +0 -6
  24. package/src/runtime/app/server/remote/requested.js +4 -4
  25. package/src/runtime/app/state/client.js +3 -0
  26. package/src/runtime/app/state/index.js +2 -2
  27. package/src/runtime/app/state/server.js +3 -0
  28. package/src/runtime/client/client.js +731 -342
  29. package/src/runtime/client/constants.js +2 -6
  30. package/src/runtime/client/fetcher.js +24 -25
  31. package/src/runtime/client/remote-functions/form.svelte.js +42 -14
  32. package/src/runtime/client/remote-functions/prerender.svelte.js +2 -2
  33. package/src/runtime/client/remote-functions/query/index.js +1 -1
  34. package/src/runtime/client/remote-functions/query/instance.svelte.js +2 -2
  35. package/src/runtime/client/remote-functions/query-batch.svelte.js +2 -2
  36. package/src/runtime/client/remote-functions/query-live/instance.svelte.js +2 -2
  37. package/src/runtime/client/remote-functions/query-live/iterator.js +10 -8
  38. package/src/runtime/client/remote-functions/query-live/proxy.js +0 -10
  39. package/src/runtime/client/remote-functions/shared.svelte.js +12 -11
  40. package/src/runtime/client/state.svelte.js +10 -22
  41. package/src/runtime/client/types.d.ts +1 -2
  42. package/src/runtime/client/utils.js +22 -14
  43. package/src/runtime/components/root.svelte +4 -14
  44. package/src/runtime/form-utils.js +4 -6
  45. package/src/runtime/pathname.js +37 -0
  46. package/src/runtime/props.svelte.js +71 -0
  47. package/src/runtime/server/fetch.js +9 -14
  48. package/src/runtime/server/index.js +10 -24
  49. package/src/runtime/server/page/crypto.js +2 -2
  50. package/src/runtime/server/page/csp.js +88 -104
  51. package/src/runtime/server/page/index.js +1 -2
  52. package/src/runtime/server/page/load_data.js +16 -33
  53. package/src/runtime/server/page/render.js +46 -25
  54. package/src/runtime/server/page/respond_with_error.js +1 -3
  55. package/src/runtime/server/page/serialize_data.js +2 -13
  56. package/src/runtime/server/page/server_routing.js +58 -9
  57. package/src/runtime/server/respond.js +20 -29
  58. package/src/runtime/server/state.js +43 -0
  59. package/src/runtime/shared.js +4 -2
  60. package/src/runtime/utils.js +3 -0
  61. package/src/types/ambient-private.d.ts +2 -2
  62. package/src/types/ambient.d.ts +59 -8
  63. package/src/types/global-private.d.ts +1 -1
  64. package/src/types/internal.d.ts +4 -8
  65. package/src/types/private.d.ts +3 -12
  66. package/src/utils/hash.js +21 -0
  67. package/src/utils/http.js +8 -7
  68. package/src/utils/import.js +2 -1
  69. package/src/utils/params.js +1 -1
  70. package/src/utils/regex.js +9 -0
  71. package/src/utils/routing.js +52 -27
  72. package/src/utils/url.js +1 -0
  73. package/src/version.js +1 -1
  74. package/types/index.d.ts +165 -66
  75. package/types/index.d.ts.map +2 -1
  76. package/src/exports/node/polyfills.js +0 -30
  77. package/src/runtime/types.d.ts +0 -8
@@ -253,8 +253,9 @@ export interface Builder {
253
253
  /**
254
254
  * Compress files in `directory` with gzip and brotli, where appropriate. Generates `.gz` and `.br` files alongside the originals.
255
255
  * @param {string} directory The directory containing the files to be compressed
256
+ * @returns an array of the files in `directory` that were compressed
256
257
  */
257
- compress: (directory: string) => Promise<void>;
258
+ compress: (directory: string) => Promise<string[]>;
258
259
  }
259
260
 
260
261
  /**
@@ -862,7 +863,7 @@ export interface KitConfig {
862
863
  * A function that allows you to edit the generated `tsconfig.json`. You can mutate the config (recommended) or return a new one.
863
864
  * This is useful for extending a shared `tsconfig.json` in a monorepo root, for example.
864
865
  *
865
- * Note that any paths configured here should be relative to the generated config file, which is written to `.svelte-kit/tsconfig.json`.
866
+ * Note that any paths configured here should be relative to the generated config file, which is written to `node_modules/$app/tsconfig.json`.
866
867
  *
867
868
  * @default (config) => config
868
869
  * @since 1.3.0
@@ -1237,6 +1238,46 @@ export interface NavigationTarget<
1237
1238
  scroll: { x: number; y: number } | null;
1238
1239
  }
1239
1240
 
1241
+ export interface GotoOptions {
1242
+ /**
1243
+ * If `true`, replaces the current history entry rather than creating a new one.
1244
+ * @default false
1245
+ */
1246
+ replace?: boolean;
1247
+ /** @deprecated Use `replace` instead. */
1248
+ replaceState?: boolean;
1249
+ /**
1250
+ * If `true`, updates the URL and `page.state` without navigating.
1251
+ * @default false
1252
+ */
1253
+ shallow?: boolean;
1254
+ /**
1255
+ * If `true`, resets the scroll position (to the top of the page, or to the element
1256
+ * matching the URL's `#hash` if there is one) and resets focus (to the `<body>`, or the
1257
+ * `autofocus` element if there is one) once the navigation completes.
1258
+ *
1259
+ * If `false`, the current scroll position and focused element are left alone.
1260
+ * @default true, or false when `shallow` is true
1261
+ */
1262
+ reset?: boolean;
1263
+ /**
1264
+ * If `true`, reruns all `load` functions and queries of the page.
1265
+ * @default false
1266
+ */
1267
+ refreshAll?: boolean;
1268
+ /** Causes any `load` functions to rerun if they depend on one of the URLs. */
1269
+ invalidate?: Array<string | URL | ((url: URL) => boolean)>;
1270
+ /** @deprecated Use `refreshAll` instead. */
1271
+ invalidateAll?: boolean;
1272
+ /** An optional object that will be available as `page.state`. */
1273
+ state?: App.PageState;
1274
+ /**
1275
+ * If `true`, `page.state` will be restored after a full page reload.
1276
+ * @default false
1277
+ */
1278
+ persistState?: boolean;
1279
+ }
1280
+
1240
1281
  /**
1241
1282
  * - `enter`: The app has hydrated/started
1242
1283
  * - `form`: The user submitted a `<form method="GET">`
@@ -1258,6 +1299,8 @@ export interface NavigationBase {
1258
1299
  * - `popstate`: Navigation was triggered by back/forward navigation
1259
1300
  */
1260
1301
  type: NavigationType;
1302
+ /** Whether this is a shallow navigation. */
1303
+ shallow: boolean;
1261
1304
  /**
1262
1305
  * Where navigation was triggered from
1263
1306
  */
@@ -1352,10 +1395,7 @@ export interface NavigationLink extends NavigationBase {
1352
1395
  }
1353
1396
 
1354
1397
  export type Navigation =
1355
- | NavigationExternal
1356
- | NavigationFormSubmit
1357
- | NavigationPopState
1358
- | NavigationLink;
1398
+ NavigationExternal | NavigationFormSubmit | NavigationPopState | NavigationLink;
1359
1399
 
1360
1400
  /**
1361
1401
  * The argument passed to [`beforeNavigate`](https://svelte.dev/docs/kit/$app-navigation#beforeNavigate) callbacks.
@@ -1426,9 +1466,20 @@ export interface Page<
1426
1466
  */
1427
1467
  data: App.PageData & Record<string, any>;
1428
1468
  /**
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`.
1469
+ * The page state, which can be manipulated using [`goto`](https://svelte.dev/docs/kit/$app-navigation#goto) from `$app/navigation`.
1430
1470
  */
1431
1471
  state: App.PageState;
1472
+ /**
1473
+ * Information about the target of the current shallow navigation, or `null` if no shallow navigation has occurred.
1474
+ */
1475
+ shallow: {
1476
+ /** Parameters of the target route, or `null` if the URL does not resolve to a route. */
1477
+ params: AppLayoutParams<'/'> | null;
1478
+ /** Info about the target route, or `null` if the URL does not resolve to a route. */
1479
+ route: { id: AppRouteId } | null;
1480
+ /** The normalized URL passed to `goto(..., { shallow: true })`. */
1481
+ url: ReadonlyURL;
1482
+ } | null;
1432
1483
  /**
1433
1484
  * Filled only after a form submission. See [form actions](https://svelte.dev/docs/kit/form-actions) for more info.
1434
1485
  */
@@ -1449,8 +1500,7 @@ export type ParamValue = string | number | boolean | bigint;
1449
1500
  * A param matcher definition passed to [`defineParams`](https://svelte.dev/docs/kit/@sveltejs-kit#defineParams).
1450
1501
  */
1451
1502
  export type ParamDefinition =
1452
- | ((param: string) => ParamValue | undefined)
1453
- | StandardSchemaV1<string, ParamValue>;
1503
+ ((param: string) => ParamValue | undefined) | StandardSchemaV1<string, ParamValue>;
1454
1504
 
1455
1505
  /**
1456
1506
  * The return type of [`defineParams`](https://svelte.dev/docs/kit/@sveltejs-kit#defineParams).
@@ -1555,8 +1605,7 @@ export type LiveQueryRequestedResult<Validated, Output> = Iterable<
1555
1605
  };
1556
1606
 
1557
1607
  export type RequestedResult<Validated, Output> =
1558
- | QueryRequestedResult<Validated, Output>
1559
- | LiveQueryRequestedResult<Validated, Output>;
1608
+ QueryRequestedResult<Validated, Output> | LiveQueryRequestedResult<Validated, Output>;
1560
1609
 
1561
1610
  export interface RequestEvent<
1562
1611
  Params extends AppLayoutParams<'/'> = AppLayoutParams<'/'>,
@@ -1737,7 +1786,7 @@ export class Server {
1737
1786
 
1738
1787
  export interface ServerInitOptions {
1739
1788
  /** A map of environment variables. */
1740
- env: Record<string, string>;
1789
+ env: Record<string, string | undefined>;
1741
1790
  /** A function that turns an asset filename into a `ReadableStream`. Required for the `read` export from `$app/server` to work. */
1742
1791
  read?: (file: string) => MaybePromise<ReadableStream | null>;
1743
1792
  }
@@ -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
  */