@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.
Files changed (59) hide show
  1. package/package.json +5 -7
  2. package/src/core/adapt/builder.js +127 -31
  3. package/src/core/adapt/index.js +3 -0
  4. package/src/core/config/index.js +4 -7
  5. package/src/core/env.js +36 -8
  6. package/src/core/generate_manifest/index.js +42 -43
  7. package/src/core/postbuild/analyse.js +4 -4
  8. package/src/core/postbuild/fallback.js +1 -1
  9. package/src/core/postbuild/prerender.js +2 -2
  10. package/src/core/sync/create_manifest_data/index.js +0 -1
  11. package/src/core/sync/write_app_manifest.js +3 -2
  12. package/src/exports/public.d.ts +100 -48
  13. package/src/exports/vite/build/index.js +1173 -0
  14. package/src/exports/vite/build/remote.js +4 -4
  15. package/src/exports/vite/dev/generate_manifest.js +308 -0
  16. package/src/exports/vite/dev/index.js +28 -284
  17. package/src/exports/vite/index.js +117 -1308
  18. package/src/exports/vite/plugins/env-vars.js +11 -34
  19. package/src/exports/vite/plugins/guard.js +19 -7
  20. package/src/exports/vite/plugins/remote.js +237 -0
  21. package/src/exports/vite/preview/index.js +8 -8
  22. package/src/exports/vite/static_analysis/index.js +15 -15
  23. package/src/exports/vite/utils.js +1 -1
  24. package/src/runner.js +4 -3
  25. package/src/runtime/app/paths/server.js +2 -2
  26. package/src/runtime/app/server/index.js +3 -3
  27. package/src/runtime/app/server/public.d.ts +114 -57
  28. package/src/runtime/app/server/remote/requested.js +31 -15
  29. package/src/runtime/app/state/client.svelte.js +3 -1
  30. package/src/runtime/client/client.js +39 -194
  31. package/src/runtime/client/fetcher.js +6 -6
  32. package/src/runtime/client/focus.js +120 -0
  33. package/src/runtime/client/remote-functions/command.svelte.js +20 -9
  34. package/src/runtime/client/remote-functions/form.svelte.js +12 -7
  35. package/src/runtime/client/remote-functions/query/instance.svelte.js +19 -5
  36. package/src/runtime/client/remote-functions/shared.svelte.js +22 -1
  37. package/src/runtime/client/scroll.js +39 -0
  38. package/src/runtime/client/utils.js +28 -0
  39. package/src/runtime/form-utils.js +243 -245
  40. package/src/runtime/server/data/index.js +3 -10
  41. package/src/runtime/server/fetch.js +13 -15
  42. package/src/runtime/server/index.js +8 -7
  43. package/src/runtime/server/internal.js +1 -2
  44. package/src/runtime/server/page/index.js +10 -15
  45. package/src/runtime/server/page/load_data.js +2 -2
  46. package/src/runtime/server/page/render.js +8 -13
  47. package/src/runtime/server/page/respond_with_error.js +4 -5
  48. package/src/runtime/server/page/server_routing.js +21 -27
  49. package/src/runtime/server/remote-functions.js +14 -14
  50. package/src/runtime/server/respond.js +17 -40
  51. package/src/runtime/server/state.js +1 -0
  52. package/src/runtime/server/utils.js +4 -4
  53. package/src/runtime/shared.js +9 -0
  54. package/src/types/ambient-private.d.ts +1 -2
  55. package/src/types/internal.d.ts +49 -6
  56. package/src/utils/filesystem.js +43 -27
  57. package/src/version.js +1 -1
  58. package/types/index.d.ts +215 -92
  59. package/types/index.d.ts.map +6 -2
@@ -45,7 +45,7 @@ import {
45
45
  } from '../pathname.js';
46
46
  import { server_data_serializer } from './page/data_serializer.js';
47
47
  import { get_remote_id, handle_remote_call } from './remote-functions.js';
48
- import { hooks, options } from './internal.js';
48
+ import { hooks, manifest, options } from './internal.js';
49
49
 
50
50
  /** @type {import('types').RequiredResolveOptions['transformPageChunk']} */
51
51
  const default_transform = ({ html }) => html;
@@ -86,11 +86,10 @@ export const respond = propagate_context(internal_respond);
86
86
 
87
87
  /**
88
88
  * @param {Request} request
89
- * @param {import('@sveltejs/kit').SSRManifest} manifest
90
89
  * @param {import('types').RequestState} state
91
90
  * @returns {Promise<Response>}
92
91
  */
93
- export async function internal_respond(request, manifest, state) {
92
+ export async function internal_respond(request, state) {
94
93
  /** URL but stripped from the potential `/__data.json` suffix and its search param */
95
94
  const url = new URL(request.url);
96
95
 
@@ -243,7 +242,6 @@ export async function internal_respond(request, manifest, state) {
243
242
  // @ts-expect-error this has to be assigned lazily
244
243
  event.fetch = create_fetch({
245
244
  event,
246
- manifest,
247
245
  state,
248
246
  get_cookie_header,
249
247
  set_internal
@@ -264,7 +262,7 @@ export async function internal_respond(request, manifest, state) {
264
262
  resolved_path =
265
263
  (await hooks.reroute({ url: new URL(url), fetch: event.fetch })) ?? url.pathname;
266
264
 
267
- if (!manifest._.routes.length && resolved_path !== url.pathname) {
265
+ if (!manifest.routes.length && resolved_path !== url.pathname) {
268
266
  state.rerouted_url = denormalise_url({
269
267
  request_url: request.url,
270
268
  resolved_path,
@@ -306,7 +304,7 @@ export async function internal_respond(request, manifest, state) {
306
304
  // the resolved path has been decoded so it should be compared to the decoded url pathname
307
305
  resolved_path !== decode_pathname(url.pathname) &&
308
306
  !state.prerendering?.fallback &&
309
- has_prerendered_path(manifest, resolved_path)
307
+ has_prerendered_path(resolved_path)
310
308
  ) {
311
309
  const url = denormalise_url({
312
310
  request_url: request.url,
@@ -347,10 +345,10 @@ export async function internal_respond(request, manifest, state) {
347
345
 
348
346
  if (is_route_resolution_request) {
349
347
  if (is_route_id_resolution_request) {
350
- return resolve_route_by_id(extract_route_id(resolved_path), new URL(request.url), manifest);
348
+ return resolve_route_by_id(extract_route_id(resolved_path), new URL(request.url));
351
349
  }
352
350
 
353
- return resolve_route(resolved_path, new URL(request.url), manifest);
351
+ return resolve_route(resolved_path, new URL(request.url));
354
352
  }
355
353
 
356
354
  if (resolved_path === `/${app_dir}/env.js`) {
@@ -366,8 +364,8 @@ export async function internal_respond(request, manifest, state) {
366
364
 
367
365
  if (!state.prerendering?.fallback && !skip_route_resolution) {
368
366
  try {
369
- const matchers = await manifest._.matchers();
370
- const result = find_route(resolved_path, manifest._.routes, matchers);
367
+ const matchers = await manifest.matchers();
368
+ const result = find_route(resolved_path, manifest.routes, matchers);
371
369
 
372
370
  if (result) {
373
371
  route = result.route;
@@ -382,9 +380,7 @@ export async function internal_respond(request, manifest, state) {
382
380
  }
383
381
 
384
382
  try {
385
- page_nodes = route?.page
386
- ? new PageNodes(await load_page_nodes(route.page, manifest))
387
- : undefined;
383
+ page_nodes = route?.page ? new PageNodes(await load_page_nodes(route.page)) : undefined;
388
384
 
389
385
  // determine whether we need to redirect to add/remove a trailing slash
390
386
  if (route && !remote_id) {
@@ -600,7 +596,6 @@ export async function internal_respond(request, manifest, state) {
600
596
  return await respond_with_error({
601
597
  event,
602
598
  state,
603
- manifest,
604
599
  error: new SvelteKitError(
605
600
  400,
606
601
  'Malformed URI',
@@ -614,14 +609,13 @@ export async function internal_respond(request, manifest, state) {
614
609
  return await render_response({
615
610
  event,
616
611
  state,
617
- manifest,
618
612
  page_config: { ssr: false, csr: true },
619
613
  status: 200,
620
614
  error: null,
621
615
  branch: [
622
616
  // include the root layout because it applies to every page
623
617
  {
624
- node: /** @type {SSRNode} */ (await manifest._.nodes[0]()),
618
+ node: /** @type {SSRNode} */ (await manifest.nodes[0]()),
625
619
  data: null,
626
620
  server_data: null
627
621
  }
@@ -633,7 +627,7 @@ export async function internal_respond(request, manifest, state) {
633
627
  }
634
628
 
635
629
  if (remote_id) {
636
- return await handle_remote_call(event, state, manifest, remote_id);
630
+ return await handle_remote_call(event, state, remote_id);
637
631
  }
638
632
 
639
633
  if (route) {
@@ -643,14 +637,7 @@ export async function internal_respond(request, manifest, state) {
643
637
  let response;
644
638
 
645
639
  if (is_data_request) {
646
- response = await render_data(
647
- event,
648
- state,
649
- route,
650
- manifest,
651
- invalidated_data_nodes,
652
- trailing_slash
653
- );
640
+ response = await render_data(event, state, route, invalidated_data_nodes, trailing_slash);
654
641
  } else {
655
642
  let endpoint;
656
643
  if (
@@ -677,17 +664,10 @@ export async function internal_respond(request, manifest, state) {
677
664
  if (!page_nodes) {
678
665
  throw new Error('page_nodes not found. This should never happen');
679
666
  } else if (page_methods.has(method)) {
680
- response = await render_page(
681
- event,
682
- state,
683
- route.page,
684
- manifest,
685
- page_nodes,
686
- resolve_opts
687
- );
667
+ response = await render_page(event, state, route.page, page_nodes, resolve_opts);
688
668
  } else {
689
669
  const allowed_methods = new Set(allowed_page_methods);
690
- const node = await manifest._.nodes[route.page.leaf]();
670
+ const node = await manifest.nodes[route.page.leaf]();
691
671
  if (node?.server?.actions) {
692
672
  allowed_methods.add('POST');
693
673
  }
@@ -769,7 +749,6 @@ export async function internal_respond(request, manifest, state) {
769
749
  event,
770
750
  state,
771
751
  { page: { layouts: [], leaf: 0 } },
772
- manifest,
773
752
  invalidated_data_nodes,
774
753
  // there is no route to take a trailing slash option from, and the
775
754
  // SSR'd error page sees the pathname as-is
@@ -787,7 +766,6 @@ export async function internal_respond(request, manifest, state) {
787
766
  return await respond_with_error({
788
767
  event,
789
768
  state,
790
- manifest,
791
769
  error: new SvelteKitError(404, 'Not Found', `Not found: ${event.url.pathname}`),
792
770
  resolve_opts
793
771
  });
@@ -824,13 +802,12 @@ export async function internal_respond(request, manifest, state) {
824
802
 
825
803
  /**
826
804
  * @param {import('types').PageNodeIndexes} page
827
- * @param {import('@sveltejs/kit').SSRManifest} manifest
828
805
  */
829
- export function load_page_nodes(page, manifest) {
806
+ export function load_page_nodes(page) {
830
807
  return Promise.all([
831
808
  // we use == here rather than === because [undefined] serializes as "[null]"
832
- ...page.layouts.map((n) => (n == undefined ? n : manifest._.nodes[n]())),
833
- manifest._.nodes[page.leaf]()
809
+ ...page.layouts.map((n) => (n == undefined ? n : manifest.nodes[n]())),
810
+ manifest.nodes[page.leaf]()
834
811
  ]);
835
812
  }
836
813
 
@@ -9,6 +9,7 @@ function transient_fields() {
9
9
  implicit: null,
10
10
  forms: null,
11
11
  requested: null,
12
+ ignored: null,
12
13
  batches: null,
13
14
  live_iterators: null
14
15
  },
@@ -1,5 +1,6 @@
1
1
  import { text } from '@sveltejs/kit';
2
2
  import { ENDPOINT_METHODS } from '../../constants.js';
3
+ import { manifest } from './internal.js';
3
4
 
4
5
  /**
5
6
  * @param {Partial<Record<import('types').HttpMethod, any>>} mod
@@ -98,13 +99,12 @@ export function serialize_uses(node) {
98
99
 
99
100
  /**
100
101
  * Returns `true` if the given path was prerendered
101
- * @param {import('@sveltejs/kit').SSRManifest} manifest
102
102
  * @param {string} pathname Should include the base and be decoded
103
103
  */
104
- export function has_prerendered_path(manifest, pathname) {
104
+ export function has_prerendered_path(pathname) {
105
105
  return (
106
- manifest._.prerendered_routes.has(pathname) ||
107
- (pathname.at(-1) === '/' && manifest._.prerendered_routes.has(pathname.slice(0, -1)))
106
+ manifest.prerendered_routes.has(pathname) ||
107
+ (pathname.at(-1) === '/' && manifest.prerendered_routes.has(pathname.slice(0, -1)))
108
108
  );
109
109
  }
110
110
 
@@ -15,6 +15,15 @@ export function validate_depends(route_id, dep) {
15
15
  }
16
16
  }
17
17
 
18
+ /**
19
+ * Same-origin urls are keyed by path, so prerendered pages can be served from any origin
20
+ * @param {URL} url
21
+ * @param {{ origin: string }} page
22
+ */
23
+ export function fetch_cache_url(url, page) {
24
+ return url.origin === page.origin ? url.href.slice(page.origin.length) : url.href;
25
+ }
26
+
18
27
  export const INVALIDATED_PARAM = 'x-sveltekit-invalidated';
19
28
 
20
29
  export const TRAILING_SLASH_PARAM = 'x-sveltekit-trailing-slash';
@@ -1,7 +1,6 @@
1
1
  /** Internal version of $app/server */
2
2
  declare module '<sveltekit:generated>/server.js' {
3
- import { SSRManifest } from '@sveltejs/kit';
4
- import { SSROptions, ServerHooks } from 'types';
3
+ import { SSROptions, ServerHooks, SSRManifest } from 'types';
5
4
 
6
5
  export const options: SSROptions;
7
6
  export const get_hooks: () => Promise<Partial<ServerHooks>>;
@@ -7,12 +7,14 @@ import {
7
7
  ServerInitOptions,
8
8
  Actions,
9
9
  RequestEvent,
10
- SSRManifest,
11
10
  Emulator,
12
- HttpError
11
+ HttpError,
12
+ Adapter,
13
+ AdapterViteConfig
13
14
  } from '@sveltejs/kit';
14
15
  import { RemoteFormIssue, RemoteQuery, RemoteLiveQuery } from '$app/server';
15
16
  import { Config } from '@sveltejs/kit/vite';
17
+ import { ParamMatcher } from '@sveltejs/kit/params';
16
18
  import {
17
19
  ClientInit,
18
20
  Handle,
@@ -53,7 +55,6 @@ export interface ServerInternalModule {
53
55
 
54
56
  export interface Asset {
55
57
  file: string;
56
- size: number;
57
58
  type: string | null;
58
59
  }
59
60
 
@@ -194,7 +195,8 @@ export interface InternalRequestOptions extends RequestOptions {
194
195
  emulator?: Emulator;
195
196
  }
196
197
 
197
- export class InternalServer extends Server {
198
+ export class InternalServer implements Server {
199
+ constructor(manifest: SSRManifest);
198
200
  init(options: ServerInitOptions): Promise<void>;
199
201
  respond(request: Request, options: InternalRequestOptions): Promise<Response>;
200
202
  }
@@ -342,6 +344,8 @@ export type RemoteFunctionData = {
342
344
  f?: Record<string, RemoteFunctionDataNode>;
343
345
  /** Whether there were any refreshes/reconnects during the request */
344
346
  r?: true;
347
+ /** Client-requested updates that the server intentionally ignored */
348
+ i?: string[];
345
349
  /** The redirect location, if any */
346
350
  redirect?: string;
347
351
  };
@@ -457,6 +461,42 @@ export interface ServerNode {
457
461
  entries?: PrerenderEntryGenerator;
458
462
  }
459
463
 
464
+ /**
465
+ * Information required to instantiate a new `Server` instance.
466
+ */
467
+ export interface SSRManifest {
468
+ /**
469
+ * The directory where SvelteKit keeps its stuff, including static assets
470
+ * (such as JS and CSS) and internally-used routes.
471
+ */
472
+ app_dir: string;
473
+ /**
474
+ * The `base` and `appDir` settings combined without a leading slash.
475
+ */
476
+ app_path: string;
477
+ /**
478
+ * Static files from `config.files.assets` and the service worker (if any).
479
+ */
480
+ assets: Set<string>;
481
+ /**
482
+ * Map of file extensions to MIME types
483
+ */
484
+ mime_types: Record<string, string>;
485
+ client: BuildData['client'];
486
+ nodes: SSRNodeLoader[];
487
+ /**
488
+ * hashed filename -> import to that file
489
+ */
490
+ remotes: Record<string, () => Promise<{ default: Record<string, any> }>>;
491
+ routes: SSRRoute[];
492
+ prerendered_routes: Set<string>;
493
+ matchers: () => Promise<Record<string, ParamMatcher>>;
494
+ /**
495
+ * A `[file]: size` map of all assets imported by server code.
496
+ */
497
+ server_assets: Record<string, number>;
498
+ }
499
+
460
500
  export interface SSRNode {
461
501
  /** index into the `nodes` array in the generated `client/app.js`. */
462
502
  index: number;
@@ -553,7 +593,8 @@ export interface Uses {
553
593
  search_params: Set<string>;
554
594
  }
555
595
 
556
- export type ValidatedConfig = RecursiveRequired<Omit<Config, 'preprocess'>> & {
596
+ export type ValidatedConfig = RecursiveRequired<Omit<Config, 'preprocess' | 'adapter'>> & {
597
+ adapter: Adapter & { vite?: AdapterViteConfig };
557
598
  preprocess: Config['preprocess'];
558
599
  };
559
600
 
@@ -716,7 +757,9 @@ export interface RequestState {
716
757
  /** Instances created via `myForm.for(...)` */
717
758
  forms: null | Map<string, any>;
718
759
  /** A map of remote function ID to payloads requested for refreshing by the client */
719
- requested: null | Map<string, string[]>;
760
+ requested: null | Map<string, Set<string>>;
761
+ /** Client-requested updates intentionally ignored by `requested(...).ignoreAll()` or `ignore` */
762
+ ignored: null | Set<string>;
720
763
  /** A map of query.batch ID to payloads requested for that batch within the same macrotask */
721
764
  batches: null | Map<
722
765
  string,
@@ -16,46 +16,58 @@ export function copy(source, target, opts = {}) {
16
16
  /** @type {string[]} */
17
17
  const files = [];
18
18
 
19
- const prefix = posixify(target) + '/';
20
-
21
19
  const regex = opts.replace
22
20
  ? new RegExp(`\\b(${Object.keys(opts.replace).join('|')})\\b`, 'g')
23
21
  : null;
24
22
 
23
+ /** @type {string | undefined} */
24
+ let created;
25
+
25
26
  /**
26
27
  * @param {string} from
27
28
  * @param {string} to
29
+ * @param {string} file posix path of `to` relative to `target`, empty when copying a single file
30
+ * @param {boolean} is_directory
28
31
  */
29
- function go(from, to) {
32
+ function go(from, to, file, is_directory) {
30
33
  if (opts.filter && !opts.filter(path.basename(from))) return;
31
34
 
32
- const stats = fs.statSync(from);
33
-
34
- if (stats.isDirectory()) {
35
- fs.readdirSync(from).forEach((file) => {
36
- go(path.join(from, file), path.join(to, file));
37
- });
38
- } else {
39
- fs.mkdirSync(path.dirname(to), { recursive: true });
40
-
41
- if (opts.replace) {
42
- const data = fs.readFileSync(from, 'utf-8');
43
- fs.writeFileSync(
44
- to,
45
- data.replace(
46
- /** @type {RegExp} */ (regex),
47
- (_match, key) => /** @type {Record<string, string>} */ (opts.replace)[key]
48
- )
35
+ if (is_directory) {
36
+ for (const entry of fs.readdirSync(from, { withFileTypes: true })) {
37
+ const child = path.join(from, entry.name);
38
+ go(
39
+ child,
40
+ path.join(to, entry.name),
41
+ file ? `${file}/${entry.name}` : entry.name,
42
+ entry.isSymbolicLink() ? fs.statSync(child).isDirectory() : entry.isDirectory()
49
43
  );
50
- } else {
51
- fs.copyFileSync(from, to);
52
44
  }
45
+ return;
46
+ }
53
47
 
54
- files.push(to === target ? posixify(path.basename(to)) : posixify(to).replace(prefix, ''));
48
+ const dir = path.dirname(to);
49
+ if (dir !== created) {
50
+ fs.mkdirSync(dir, { recursive: true });
51
+ created = dir;
55
52
  }
53
+
54
+ if (opts.replace) {
55
+ const data = fs.readFileSync(from, 'utf-8');
56
+ fs.writeFileSync(
57
+ to,
58
+ data.replace(
59
+ /** @type {RegExp} */ (regex),
60
+ (_match, key) => /** @type {Record<string, string>} */ (opts.replace)[key]
61
+ )
62
+ );
63
+ } else {
64
+ fs.copyFileSync(from, to);
65
+ }
66
+
67
+ files.push(file || posixify(path.basename(to)));
56
68
  }
57
69
 
58
- go(source, target);
70
+ go(source, target, '', fs.statSync(source).isDirectory());
59
71
 
60
72
  return files;
61
73
  }
@@ -67,9 +79,13 @@ export function copy(source, target, opts = {}) {
67
79
  * @returns {Generator<string>} the posix paths of all found files, relative to `cwd`
68
80
  */
69
81
  export function* walk(cwd, dir = '') {
70
- for (const file of fs.readdirSync(path.join(cwd, dir))) {
71
- const joined = dir ? `${dir}/${file}` : file;
72
- if (fs.statSync(path.join(cwd, joined)).isDirectory()) {
82
+ for (const entry of fs.readdirSync(path.join(cwd, dir), { withFileTypes: true })) {
83
+ const joined = dir ? `${dir}/${entry.name}` : entry.name;
84
+ const is_directory = entry.isSymbolicLink()
85
+ ? fs.statSync(path.join(cwd, joined)).isDirectory()
86
+ : entry.isDirectory();
87
+
88
+ if (is_directory) {
73
89
  yield* walk(cwd, joined);
74
90
  } else {
75
91
  yield joined;
package/src/version.js CHANGED
@@ -1,4 +1,4 @@
1
1
  // generated during release, do not modify
2
2
 
3
3
  /** @type {string} */
4
- export const VERSION = '3.0.0-next.25';
4
+ export const VERSION = '3.0.0-next.27';