@sveltejs/kit 2.64.0 → 2.65.1

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 (35) hide show
  1. package/package.json +2 -2
  2. package/src/core/postbuild/analyse.js +0 -5
  3. package/src/core/postbuild/prerender.js +2 -0
  4. package/src/core/sync/write_client_manifest.js +5 -0
  5. package/src/exports/public.d.ts +1 -1
  6. package/src/exports/vite/build/build_server.js +43 -57
  7. package/src/exports/vite/build/build_service_worker.js +10 -0
  8. package/src/exports/vite/build/utils.js +0 -8
  9. package/src/exports/vite/index.js +237 -178
  10. package/src/runtime/app/server/remote/command.js +0 -3
  11. package/src/runtime/app/server/remote/form.js +18 -13
  12. package/src/runtime/app/server/remote/prerender.js +28 -34
  13. package/src/runtime/app/server/remote/query.js +105 -94
  14. package/src/runtime/app/server/remote/requested.js +14 -10
  15. package/src/runtime/app/server/remote/shared.js +25 -18
  16. package/src/runtime/client/client.js +25 -15
  17. package/src/runtime/client/remote-functions/command.svelte.js +5 -30
  18. package/src/runtime/client/remote-functions/form.svelte.js +62 -82
  19. package/src/runtime/client/remote-functions/prerender.svelte.js +14 -6
  20. package/src/runtime/client/remote-functions/query/index.js +6 -14
  21. package/src/runtime/client/remote-functions/query/instance.svelte.js +37 -8
  22. package/src/runtime/client/remote-functions/query/proxy.js +3 -3
  23. package/src/runtime/client/remote-functions/query-batch.svelte.js +59 -68
  24. package/src/runtime/client/remote-functions/query-live/instance.svelte.js +20 -6
  25. package/src/runtime/client/remote-functions/shared.svelte.js +76 -59
  26. package/src/runtime/server/page/render.js +20 -83
  27. package/src/runtime/server/page/server_routing.js +20 -15
  28. package/src/runtime/server/remote.js +296 -204
  29. package/src/runtime/server/respond.js +4 -2
  30. package/src/runtime/shared.js +0 -15
  31. package/src/types/global-private.d.ts +3 -3
  32. package/src/types/internal.d.ts +53 -34
  33. package/src/version.js +1 -1
  34. package/types/index.d.ts +4 -4
  35. package/types/index.d.ts.map +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sveltejs/kit",
3
- "version": "2.64.0",
3
+ "version": "2.65.1",
4
4
  "description": "SvelteKit is the fastest way to build Svelte apps",
5
5
  "keywords": [
6
6
  "framework",
@@ -41,7 +41,7 @@
41
41
  "dts-buddy": "^0.8.0",
42
42
  "jsdom": "^26.1.0",
43
43
  "rollup": "^4.59.0",
44
- "svelte": "^5.55.7",
44
+ "svelte": "^5.56.3",
45
45
  "typescript": "^5.3.3",
46
46
  "vite": "^6.4.2",
47
47
  "vitest": "^4.1.7"
@@ -11,7 +11,6 @@ import { has_server_load, resolve_route } from '../../utils/routing.js';
11
11
  import { check_feature } from '../../utils/features.js';
12
12
  import { createReadableStream } from '@sveltejs/kit/node';
13
13
  import { PageNodes } from '../../utils/page_nodes.js';
14
- import { build_server_nodes } from '../../exports/vite/build/build_server.js';
15
14
 
16
15
  export default forked(import.meta.url, analyse);
17
16
 
@@ -34,7 +33,6 @@ async function analyse({
34
33
  server_manifest,
35
34
  tracked_features,
36
35
  env,
37
- out,
38
36
  remotes
39
37
  }) {
40
38
  /** @type {import('@sveltejs/kit').SSRManifest} */
@@ -64,9 +62,6 @@ async function analyse({
64
62
  internal.set_manifest(manifest);
65
63
  internal.set_read_implementation((file) => createReadableStream(`${server_root}/server/${file}`));
66
64
 
67
- // first, build server nodes without the client manifest so we can analyse it
68
- build_server_nodes(out, config, manifest_data, server_manifest, null, null, null);
69
-
70
65
  /** @type {import('types').ServerMetadata} */
71
66
  const metadata = {
72
67
  nodes: [],
@@ -204,6 +204,8 @@ async function prerender({ hash, out, manifest_path, metadata, verbose, env }) {
204
204
 
205
205
  const seen = new Set();
206
206
  const written = new Set();
207
+
208
+ /** @type {Map<string, Promise<any>>} */
207
209
  const remote_responses = new Map();
208
210
 
209
211
  /** @type {Map<string, Set<string>>} */
@@ -140,6 +140,11 @@ export function write_client_manifest(kit, manifest_data, output, metadata) {
140
140
  write_if_changed(
141
141
  `${output}/app.js`,
142
142
  dedent`
143
+ // in dev, this makes Vite inject its client as this module's first dependency,
144
+ // so that global constant replacements are installed before any other module
145
+ // (including user hooks) evaluates. In build it's inert.
146
+ import.meta.hot;
147
+
143
148
  ${
144
149
  client_hooks_file
145
150
  ? `import * as client_hooks from '${relative_path(output, client_hooks_file)}';`
@@ -1696,7 +1696,7 @@ export interface SSRManifest {
1696
1696
 
1697
1697
  /** private fields */
1698
1698
  _: {
1699
- client: NonNullable<BuildData['client']>;
1699
+ client: BuildData['client'];
1700
1700
  nodes: SSRNodeLoader[];
1701
1701
  /** hashed filename -> import to that file */
1702
1702
  remotes: Record<string, () => Promise<any>>;
@@ -15,36 +15,14 @@ import { basename } from 'node:path';
15
15
  import { fix_css_urls } from '../../../utils/css.js';
16
16
  import { escape_for_interpolation } from '../../../utils/escape.js';
17
17
 
18
- /**
19
- * @overload Build without the client manifest so we can analyse the nodes.
20
- * @param {string} out
21
- * @param {ValidatedKitConfig} kit
22
- * @param {ManifestData} manifest_data
23
- * @param {Manifest} server_manifest
24
- * @param {null} client_manifest
25
- * @param {null} assets_path
26
- * @param {null} client_chunks
27
- * @returns {void}
28
- */
29
- /**
30
- * @overload Or build with the client manifest
31
- * @param {string} out
32
- * @param {ValidatedKitConfig} kit
33
- * @param {ManifestData} manifest_data
34
- * @param {Manifest} server_manifest
35
- * @param {Manifest} client_manifest
36
- * @param {string} assets_path
37
- * @param {Rollup.RollupOutput['output']} client_chunks
38
- * @returns {void}
39
- */
40
18
  /**
41
19
  * @param {string} out
42
20
  * @param {ValidatedKitConfig} kit
43
21
  * @param {ManifestData} manifest_data
44
22
  * @param {Manifest} server_manifest
45
23
  * @param {Manifest | null} client_manifest
46
- * @param {string | null} assets_path
47
- * @param {Rollup.RollupOutput['output'] | null} client_chunks
24
+ * @param {string} assets_path
25
+ * @param {(Rollup.OutputAsset | Rollup.OutputChunk)[]} chunks
48
26
  * @returns {void}
49
27
  */
50
28
  export function build_server_nodes(
@@ -54,7 +32,7 @@ export function build_server_nodes(
54
32
  server_manifest,
55
33
  client_manifest,
56
34
  assets_path,
57
- client_chunks
35
+ chunks
58
36
  ) {
59
37
  mkdirp(`${out}/server/nodes`);
60
38
  mkdirp(`${out}/server/stylesheets`);
@@ -72,8 +50,8 @@ export function build_server_nodes(
72
50
  */
73
51
  let prepare_css_for_inlining = (css) => s(css);
74
52
 
75
- if (client_chunks && kit.inlineStyleThreshold > 0 && kit.output.bundleStrategy === 'split') {
76
- for (const chunk of client_chunks) {
53
+ if (chunks && kit.inlineStyleThreshold > 0 && kit.output.bundleStrategy === 'split') {
54
+ for (const chunk of chunks) {
77
55
  if (chunk.type !== 'asset' || !chunk.fileName.endsWith('.css')) {
78
56
  continue;
79
57
  }
@@ -129,6 +107,9 @@ export function build_server_nodes(
129
107
  }
130
108
  }
131
109
 
110
+ /** path to the `.svelte-kit` directory */
111
+ const out_dir = normalizePath(kit.outDir);
112
+
132
113
  for (let i = 0; i < manifest_data.nodes.length; i++) {
133
114
  const node = manifest_data.nodes[i];
134
115
 
@@ -156,7 +137,7 @@ export function build_server_nodes(
156
137
  ? node.child_pages.some((child) => child.page_options?.ssr !== false)
157
138
  : node.page_options?.ssr !== false;
158
139
 
159
- if (node.component && client_manifest && uses_server_component) {
140
+ if (node.component && uses_server_component) {
160
141
  exports.push(
161
142
  'let component_cache;',
162
143
  `export const component = async () => component_cache ??= (await import('../${
@@ -186,18 +167,7 @@ export function build_server_nodes(
186
167
  exports.push(`export const server_id = ${s(node.server)};`);
187
168
  }
188
169
 
189
- if (
190
- client_manifest &&
191
- (node.universal || node.component) &&
192
- kit.output.bundleStrategy === 'split'
193
- ) {
194
- const entry_path = `${normalizePath(kit.outDir)}/generated/client-optimized/nodes/${i}.js`;
195
- const entry = find_deps(client_manifest, entry_path, true);
196
-
197
- // Eagerly load client stylesheets and fonts imported by the SSR-ed page to avoid FOUC.
198
- // However, if it is not used during SSR (not present in the server manifest),
199
- // then it can be lazily loaded in the browser.
200
-
170
+ if ((node.universal || node.component) && kit.output.bundleStrategy === 'split') {
201
171
  /** @type {AssetDependencies | undefined} */
202
172
  let component;
203
173
  if (node.component) {
@@ -210,25 +180,41 @@ export function build_server_nodes(
210
180
  universal = find_deps(server_manifest, node.universal, true);
211
181
  }
212
182
 
213
- /** @type {Set<string>} */
214
- const eager_css = new Set();
183
+ if (client_manifest) {
184
+ const entry_path = `${out_dir}/generated/client-optimized/nodes/${i}.js`;
185
+ const entry = find_deps(client_manifest, entry_path, true);
215
186
 
216
- entry.stylesheet_map.forEach((value, filepath) => {
217
- // pages and layouts are renamed to node indexes when optimised for the client
218
- // so we use the original filename instead to check against the server manifest
219
- if (filepath === entry_path) {
220
- filepath = node.component ?? filepath;
221
- }
187
+ // Eagerly load client stylesheets and fonts imported by the SSR-ed page to avoid FOUC.
188
+ // However, if it is not used during SSR (not present in the server manifest),
189
+ // then it can be lazily loaded in the browser.
222
190
 
223
- if (component?.stylesheet_map.has(filepath) || universal?.stylesheet_map.has(filepath)) {
224
- value.css.forEach((file) => eager_css.add(file));
225
- value.assets.forEach((file) => eager_assets.add(file));
226
- }
227
- });
191
+ /** @type {Set<string>} */
192
+ const eager_css = new Set();
193
+
194
+ entry.stylesheet_map.forEach((value, filepath) => {
195
+ // pages and layouts are renamed to node indexes when optimised for the client
196
+ // so we use the original filename instead to check against the server manifest
197
+ if (filepath === entry_path) {
198
+ filepath = node.component ?? filepath;
199
+ }
200
+
201
+ if (component?.stylesheet_map.has(filepath) || universal?.stylesheet_map.has(filepath)) {
202
+ value.css.forEach((file) => eager_css.add(file));
203
+ value.assets.forEach((file) => eager_assets.add(file));
204
+ }
205
+ });
228
206
 
229
- imported = entry.imports;
230
- stylesheets = Array.from(eager_css);
231
- fonts = filter_fonts(Array.from(eager_assets));
207
+ imported = entry.imports;
208
+ stylesheets = Array.from(eager_css);
209
+ fonts = filter_fonts(Array.from(eager_assets));
210
+ } else {
211
+ for (const entry of [component, universal]) {
212
+ if (!entry) continue;
213
+ imported.push(...entry.imports);
214
+ stylesheets.push(...entry.stylesheets);
215
+ fonts.push(...entry.fonts);
216
+ }
217
+ }
232
218
  }
233
219
 
234
220
  exports.push(
@@ -245,7 +231,7 @@ export function build_server_nodes(
245
231
 
246
232
  // Keep track of Vite asset filenames so that we avoid touching unrelated ones
247
233
  // when adjusting the inlined CSS
248
- if (stylesheets_to_inline.size && assets_path && eager_assets.size) {
234
+ if (stylesheets_to_inline.size && eager_assets.size) {
249
235
  vite_assets = new Set(
250
236
  Array.from(eager_assets).map((asset) => {
251
237
  return decodeURIComponent(asset.replace(`${assets_path}/`, ''));
@@ -39,6 +39,16 @@ export async function build_service_worker(
39
39
  assets.forEach((file) => build.add(file));
40
40
  }
41
41
 
42
+ if (kit.output.bundleStrategy === 'inline') {
43
+ // the bundle and stylesheet are inlined into the page and their files
44
+ // deleted, so they must not appear in the list of cacheable assets
45
+ for (const file of build) {
46
+ if (!fs.existsSync(`${out}/client/${file}`)) {
47
+ build.delete(file);
48
+ }
49
+ }
50
+ }
51
+
42
52
  // in a service worker, `location` is the location of the service worker itself,
43
53
  // which is guaranteed to be `<base>/service-worker.js`
44
54
  const base = "location.pathname.split('/').slice(0, -1).join('/')";
@@ -122,14 +122,6 @@ export function filter_fonts(assets) {
122
122
  return assets.filter((asset) => /\.(woff2?|ttf|otf)$/.test(asset));
123
123
  }
124
124
 
125
- /**
126
- * @param {import('types').ValidatedKitConfig} config
127
- * @returns {string}
128
- */
129
- export function assets_base(config) {
130
- return (config.paths.assets || config.paths.base || '.') + '/';
131
- }
132
-
133
125
  /**
134
126
  * Writes a function with arguments used by a template literal.
135
127
  * This helps us store strings in a module and inject values at runtime.