@sveltejs/kit 3.0.0-next.1 → 3.0.0-next.3

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 (45) hide show
  1. package/package.json +2 -2
  2. package/src/core/postbuild/analyse.js +0 -8
  3. package/src/core/postbuild/prerender.js +2 -0
  4. package/src/core/sync/create_manifest_data/index.js +24 -1
  5. package/src/core/sync/write_env.js +2 -1
  6. package/src/exports/internal/env.js +1 -1
  7. package/src/exports/public.d.ts +1 -1
  8. package/src/exports/vite/build/build_server.js +47 -58
  9. package/src/exports/vite/build/remote.js +18 -11
  10. package/src/exports/vite/build/utils.js +0 -8
  11. package/src/exports/vite/index.js +221 -217
  12. package/src/exports/vite/static_analysis/index.js +2 -4
  13. package/src/exports/vite/static_analysis/types.d.ts +14 -0
  14. package/src/exports/vite/utils.js +1 -12
  15. package/src/runtime/app/server/remote/command.js +0 -3
  16. package/src/runtime/app/server/remote/form.js +18 -13
  17. package/src/runtime/app/server/remote/prerender.js +28 -34
  18. package/src/runtime/app/server/remote/query.js +105 -94
  19. package/src/runtime/app/server/remote/requested.js +14 -10
  20. package/src/runtime/app/server/remote/shared.js +25 -19
  21. package/src/runtime/client/client.js +19 -13
  22. package/src/runtime/client/ndjson.js +6 -33
  23. package/src/runtime/client/remote-functions/command.svelte.js +7 -32
  24. package/src/runtime/client/remote-functions/form.svelte.js +62 -82
  25. package/src/runtime/client/remote-functions/prerender.svelte.js +14 -6
  26. package/src/runtime/client/remote-functions/query/index.js +6 -14
  27. package/src/runtime/client/remote-functions/query/instance.svelte.js +20 -0
  28. package/src/runtime/client/remote-functions/query/proxy.js +3 -3
  29. package/src/runtime/client/remote-functions/query-batch.svelte.js +59 -68
  30. package/src/runtime/client/remote-functions/query-live/instance.svelte.js +21 -6
  31. package/src/runtime/client/remote-functions/query-live/iterator.js +36 -55
  32. package/src/runtime/client/remote-functions/shared.svelte.js +76 -59
  33. package/src/runtime/client/sse.js +32 -0
  34. package/src/runtime/client/stream.js +38 -0
  35. package/src/runtime/server/page/render.js +23 -80
  36. package/src/runtime/server/page/server_routing.js +20 -15
  37. package/src/runtime/server/remote.js +296 -204
  38. package/src/runtime/server/respond.js +4 -2
  39. package/src/runtime/shared.js +83 -13
  40. package/src/types/global-private.d.ts +3 -3
  41. package/src/types/internal.d.ts +54 -35
  42. package/src/utils/error.js +12 -0
  43. package/src/version.js +1 -1
  44. package/types/index.d.ts +17 -7
  45. package/types/index.d.ts.map +5 -3
@@ -20,9 +20,9 @@ import {
20
20
  get_global_name,
21
21
  handle_error_and_jsonify
22
22
  } from '../utils.js';
23
- import { create_remote_key } from '../../shared.js';
24
23
  import { get_status } from '../../../utils/error.js';
25
24
  import * as env from '__sveltekit/env';
25
+ import { collect_remote_data } from '../remote.js';
26
26
 
27
27
  // TODO rename this function/module
28
28
 
@@ -78,9 +78,9 @@ export async function render_response({
78
78
 
79
79
  const { client } = manifest._;
80
80
 
81
- const modulepreloads = new Set(client.imports);
82
- const stylesheets = new Set(client.stylesheets);
83
- const fonts = new Set(client.fonts);
81
+ const modulepreloads = new Set(client?.imports);
82
+ const stylesheets = new Set(client?.stylesheets);
83
+ const fonts = new Set(client?.fonts);
84
84
 
85
85
  /**
86
86
  * The value of the Link header that is added to the response when not prerendering
@@ -281,7 +281,7 @@ export async function render_response({
281
281
  for (const url of node.stylesheets) stylesheets.add(url);
282
282
  for (const url of node.fonts) fonts.add(url);
283
283
 
284
- if (node.inline_styles && !client.inline) {
284
+ if (node.inline_styles && !client?.inline) {
285
285
  Object.entries(await node.inline_styles()).forEach(([filename, css]) => {
286
286
  if (typeof css === 'string') {
287
287
  inline_styles.set(filename, css);
@@ -307,7 +307,7 @@ export async function render_response({
307
307
  return `${assets}/${path}`;
308
308
  };
309
309
 
310
- const style = client.inline
310
+ const style = client?.inline
311
311
  ? client.inline?.style
312
312
  : Array.from(inline_styles.values()).join('\n');
313
313
 
@@ -371,8 +371,8 @@ export async function render_response({
371
371
  .join('\n\t\t\t')}`;
372
372
  }
373
373
 
374
- if (page_config.csr) {
375
- const route = manifest._.client.routes?.find((r) => r.id === event.route.id) ?? null;
374
+ if (page_config.csr && client) {
375
+ const route = client.routes?.find((r) => r.id === event.route.id) ?? null;
376
376
 
377
377
  if (client.uses_env_dynamic_public && state.prerendering) {
378
378
  modulepreloads.add(`${paths.app_dir}/env.js`);
@@ -400,12 +400,12 @@ export async function render_response({
400
400
  }
401
401
 
402
402
  // prerender a `/path/to/page/__route.js` module
403
- if (manifest._.client.routes && state.prerendering && !state.prerendering.fallback) {
403
+ if (client.routes && state.prerendering && !state.prerendering.fallback) {
404
404
  const pathname = add_resolution_suffix(event.url.pathname);
405
405
 
406
406
  state.prerendering.dependencies.set(
407
407
  pathname,
408
- create_server_routing_response(route, event.params, new URL(pathname, event.url), manifest)
408
+ create_server_routing_response(route, event.params, new URL(pathname, event.url), client)
409
409
  );
410
410
  }
411
411
 
@@ -505,9 +505,9 @@ export async function render_response({
505
505
  hydrate.push(`status: ${status}`);
506
506
  }
507
507
 
508
- if (manifest._.client.routes) {
508
+ if (client.routes) {
509
509
  if (route) {
510
- const stringified = generate_route_object(route, event.url, manifest).replaceAll(
510
+ const stringified = generate_route_object(route, event.url, client).replaceAll(
511
511
  '\n',
512
512
  '\n\t\t\t\t\t\t\t'
513
513
  ); // make output after it's put together with the rest more readable
@@ -521,87 +521,27 @@ export async function render_response({
521
521
  args.push(`{\n${indent}\t${hydrate.join(`,\n${indent}\t`)}\n${indent}}`);
522
522
  }
523
523
 
524
- const { remote } = event_state;
525
-
526
- let serialized_query_data = '';
527
- let serialized_prerender_data = '';
528
-
529
- if (remote.data) {
530
- /** @type {Record<string, any>} */
531
- const query = {};
532
-
533
- /** @type {Record<string, any>} */
534
- const prerender = {};
535
-
536
- for (const [internals, cache] of remote.data) {
537
- // remote functions without an `id` aren't exported, and thus
538
- // cannot be called from the client
539
- if (!internals.id) continue;
540
-
541
- for (const key in cache) {
542
- const entry = cache[key];
543
-
544
- if (!entry.serialize) continue;
545
-
546
- const remote_key = create_remote_key(internals.id, key);
547
-
548
- const store = internals.type === 'prerender' ? prerender : query;
549
-
550
- if (
551
- event_state.remote.refreshes?.has(remote_key) ||
552
- event_state.remote.reconnects?.has(remote_key)
553
- ) {
554
- // This entry was refreshed/set by a command or form action.
555
- // Always await it so the mutation result is serialized.
556
- store[remote_key] = await entry.data;
557
- } else {
558
- // Don't block the response on pending remote data - if a query
559
- // hasn't settled yet, it wasn't awaited in the template (or is behind a pending boundary).
560
- const result = await Promise.race([
561
- Promise.resolve(entry.data).then(
562
- (v) => /** @type {const} */ ({ settled: true, value: v }),
563
- (e) => /** @type {const} */ ({ settled: true, error: e })
564
- ),
565
- new Promise((resolve) => {
566
- queueMicrotask(() => resolve(/** @type {const} */ ({ settled: false })));
567
- })
568
- ]);
569
-
570
- if (result.settled) {
571
- if ('error' in result) throw result.error;
572
- store[remote_key] = result.value;
573
- }
574
- }
575
- }
576
- }
577
-
578
- const replacer = create_replacer(options.hooks.transport);
579
-
580
- if (Object.keys(query).length > 0) {
581
- serialized_query_data = `${global}.query = ${devalue.uneval(query, replacer)};\n\n\t\t\t\t\t\t`;
582
- }
583
-
584
- if (Object.keys(prerender).length > 0) {
585
- serialized_prerender_data = `${global}.prerender = ${devalue.uneval(prerender, replacer)};\n\n\t\t\t\t\t\t`;
586
- }
587
- }
524
+ const remote_data = await collect_remote_data({}, event, event_state, options);
588
525
 
589
- const serialized_remote_data = `${serialized_query_data}${serialized_prerender_data}`;
526
+ const serialized_data =
527
+ Object.keys(remote_data).length > 0
528
+ ? `${global}.data = ${devalue.uneval(remote_data, create_replacer(options.hooks.transport))};\n\n\t\t\t\t\t\t`
529
+ : '';
590
530
 
591
531
  // `client.app` is a proxy for `bundleStrategy === 'split'`
592
532
  const boot = client.inline
593
533
  ? `${client.inline.script}
594
534
 
595
- ${serialized_remote_data}${global}.app.start(${args.join(', ')});`
535
+ ${serialized_data}${global}.app.start(${args.join(', ')});`
596
536
  : client.app
597
537
  ? `Promise.all([
598
538
  import(${s(prefixed(client.start))}),
599
539
  import(${s(prefixed(client.app))})
600
540
  ]).then(([kit, app]) => {
601
- ${serialized_remote_data}kit.start(app, ${args.join(', ')});
541
+ ${serialized_data}kit.start(app, ${args.join(', ')});
602
542
  });`
603
543
  : `import(${s(prefixed(client.start))}).then((app) => {
604
- ${serialized_remote_data}app.start(${args.join(', ')})
544
+ ${serialized_data}app.start(${args.join(', ')})
605
545
  });`;
606
546
 
607
547
  if (load_env_eagerly) {
@@ -639,8 +579,11 @@ export async function render_response({
639
579
  }`);
640
580
  }
641
581
 
582
+ // we need to eagerly import the Vite client module in development to ensure
583
+ // that Vite global constant replacements are initialised before our code runs
642
584
  const init_app = `
643
585
  {
586
+ ${DEV ? `import('${paths.base}/@vite/client')` : ''}
644
587
  ${blocks.join('\n\n\t\t\t\t\t')}
645
588
  }
646
589
  `;
@@ -1,3 +1,4 @@
1
+ /** @import { SSRManifest } from '@sveltejs/kit' */
1
2
  import { base, assets, relative } from '$app/paths/internal/server';
2
3
  import { text } from '@sveltejs/kit';
3
4
  import { s } from '../../../utils/misc.js';
@@ -7,15 +8,15 @@ import { get_relative_path } from '../../utils.js';
7
8
  /**
8
9
  * @param {import('types').SSRClientRoute} route
9
10
  * @param {URL} url
10
- * @param {import('@sveltejs/kit').SSRManifest} manifest
11
+ * @param {NonNullable<SSRManifest['_']['client']>} client
11
12
  * @returns {string}
12
13
  */
13
- export function generate_route_object(route, url, manifest) {
14
+ export function generate_route_object(route, url, client) {
14
15
  const { errors, layouts, leaf } = route;
15
16
 
16
17
  const nodes = [...errors, ...layouts.map((l) => l?.[1]), leaf[1]]
17
18
  .filter((n) => typeof n === 'number')
18
- .map((n) => `'${n}': () => ${create_client_import(manifest._.client.nodes?.[n], url)}`)
19
+ .map((n) => `'${n}': () => ${create_client_import(client.nodes?.[n], url)}`)
19
20
  .join(',\n\t\t');
20
21
 
21
22
  // stringified version of
@@ -60,36 +61,40 @@ function create_client_import(import_path, url) {
60
61
  /**
61
62
  * @param {string} resolved_path
62
63
  * @param {URL} url
63
- * @param {import('@sveltejs/kit').SSRManifest} manifest
64
+ * @param {SSRManifest} manifest
64
65
  * @returns {Promise<Response>}
65
66
  */
66
67
  export async function resolve_route(resolved_path, url, manifest) {
67
- if (!manifest._.client.routes) {
68
+ if (!manifest._.client?.routes) {
68
69
  return text('Server-side route resolution disabled', { status: 400 });
69
70
  }
70
71
 
71
72
  const matchers = await manifest._.matchers();
72
73
  const result = find_route(resolved_path, manifest._.client.routes, matchers);
73
74
 
74
- return create_server_routing_response(result?.route ?? null, result?.params ?? {}, url, manifest)
75
- .response;
75
+ return create_server_routing_response(
76
+ result?.route ?? null,
77
+ result?.params ?? {},
78
+ url,
79
+ manifest._.client
80
+ ).response;
76
81
  }
77
82
 
78
83
  /**
79
84
  * @param {import('types').SSRClientRoute | null} route
80
85
  * @param {Partial<Record<string, string>>} params
81
86
  * @param {URL} url
82
- * @param {import('@sveltejs/kit').SSRManifest} manifest
87
+ * @param {NonNullable<SSRManifest['_']['client']>} client
83
88
  * @returns {{response: Response, body: string}}
84
89
  */
85
- export function create_server_routing_response(route, params, url, manifest) {
90
+ export function create_server_routing_response(route, params, url, client) {
86
91
  const headers = new Headers({
87
92
  'content-type': 'application/javascript; charset=utf-8'
88
93
  });
89
94
 
90
95
  if (route) {
91
- const csr_route = generate_route_object(route, url, manifest);
92
- const body = `${create_css_import(route, url, manifest)}\nexport const route = ${csr_route}; export const params = ${JSON.stringify(params)};`;
96
+ const csr_route = generate_route_object(route, url, client);
97
+ const body = `${create_css_import(route, url, client)}\nexport const route = ${csr_route}; export const params = ${JSON.stringify(params)};`;
93
98
 
94
99
  return { response: text(body, { headers }), body };
95
100
  } else {
@@ -105,17 +110,17 @@ export function create_server_routing_response(route, params, url, manifest) {
105
110
  *
106
111
  * @param {import('types').SSRClientRoute} route
107
112
  * @param {URL} url
108
- * @param {import('@sveltejs/kit').SSRManifest} manifest
113
+ * @param {NonNullable<SSRManifest['_']['client']>} client
109
114
  * @returns {string}
110
115
  */
111
- function create_css_import(route, url, manifest) {
116
+ function create_css_import(route, url, client) {
112
117
  const { errors, layouts, leaf } = route;
113
118
 
114
119
  let css = '';
115
120
 
116
121
  for (const node of [...errors, ...layouts.map((l) => l?.[1]), leaf[1]]) {
117
122
  if (typeof node !== 'number') continue;
118
- const node_css = manifest._.client.css?.[node];
123
+ const node_css = client.css?.[node];
119
124
  for (const css_path of node_css ?? []) {
120
125
  css += `'${assets || base}/${css_path}',`;
121
126
  }
@@ -123,5 +128,5 @@ function create_css_import(route, url, manifest) {
123
128
 
124
129
  if (!css) return '';
125
130
 
126
- return `${create_client_import(/** @type {string} */ (manifest._.client.start), url)}.then(x => x.load_css([${css}]));`;
131
+ return `${create_client_import(client.start, url)}.then(x => x.load_css([${css}]));`;
127
132
  }