@sveltejs/kit 3.0.0-next.6 → 3.0.0-next.8

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 (80) hide show
  1. package/package.json +8 -3
  2. package/src/core/adapt/builder.js +11 -39
  3. package/src/core/config/index.js +76 -71
  4. package/src/core/config/options.js +280 -285
  5. package/src/core/config/types.d.ts +1 -1
  6. package/src/core/env.js +86 -1
  7. package/src/core/generate_manifest/index.js +12 -15
  8. package/src/core/sync/create_manifest_data/index.js +7 -45
  9. package/src/core/sync/sync.js +0 -2
  10. package/src/core/sync/write_client_manifest.js +7 -21
  11. package/src/core/sync/write_non_ambient.js +12 -9
  12. package/src/core/sync/write_server.js +0 -4
  13. package/src/core/sync/write_types/index.js +28 -24
  14. package/src/core/utils.js +2 -2
  15. package/src/exports/index.js +3 -3
  16. package/src/exports/internal/client.js +5 -0
  17. package/src/exports/internal/index.js +1 -91
  18. package/src/exports/internal/{event.js → server/event.js} +1 -2
  19. package/src/exports/internal/server/index.js +33 -0
  20. package/src/exports/internal/shared.js +89 -0
  21. package/src/exports/node/index.js +5 -9
  22. package/src/exports/params.js +63 -0
  23. package/src/exports/public.d.ts +103 -46
  24. package/src/exports/url.js +84 -0
  25. package/src/exports/vite/dev/index.js +31 -20
  26. package/src/exports/vite/index.js +280 -199
  27. package/src/exports/vite/preview/index.js +14 -15
  28. package/src/exports/vite/utils.js +8 -10
  29. package/src/runtime/app/env/internal.js +4 -4
  30. package/src/runtime/app/forms.js +2 -2
  31. package/src/runtime/app/paths/client.js +3 -7
  32. package/src/runtime/app/paths/internal/client.js +4 -2
  33. package/src/runtime/app/paths/internal/server.js +2 -23
  34. package/src/runtime/app/paths/server.js +3 -3
  35. package/src/runtime/app/server/remote/query.js +6 -12
  36. package/src/runtime/app/state/client.js +1 -2
  37. package/src/runtime/app/stores.js +13 -76
  38. package/src/runtime/client/bundle.js +1 -1
  39. package/src/runtime/client/client-entry.js +3 -0
  40. package/src/runtime/client/client.js +230 -238
  41. package/src/runtime/client/entry.js +24 -3
  42. package/src/runtime/client/payload.js +17 -0
  43. package/src/runtime/client/remote-functions/cache.svelte.js +3 -1
  44. package/src/runtime/client/remote-functions/form.svelte.js +11 -30
  45. package/src/runtime/client/remote-functions/prerender.svelte.js +10 -3
  46. package/src/runtime/client/remote-functions/query/instance.svelte.js +18 -9
  47. package/src/runtime/client/remote-functions/query-live/instance.svelte.js +16 -6
  48. package/src/runtime/client/remote-functions/shared.svelte.js +1 -2
  49. package/src/runtime/client/state.svelte.js +66 -49
  50. package/src/runtime/client/types.d.ts +3 -7
  51. package/src/runtime/client/utils.js +0 -96
  52. package/src/runtime/components/root.svelte +66 -0
  53. package/src/runtime/form-utils.js +16 -6
  54. package/src/runtime/server/cookie.js +17 -7
  55. package/src/runtime/server/index.js +1 -1
  56. package/src/runtime/server/page/index.js +7 -14
  57. package/src/runtime/server/page/load_data.js +1 -1
  58. package/src/runtime/server/page/render.js +72 -88
  59. package/src/runtime/server/page/server_routing.js +13 -9
  60. package/src/runtime/server/remote.js +23 -13
  61. package/src/runtime/server/respond.js +11 -8
  62. package/src/runtime/server/utils.js +28 -5
  63. package/src/runtime/telemetry/otel.js +1 -1
  64. package/src/runtime/types.d.ts +8 -0
  65. package/src/types/ambient.d.ts +5 -1
  66. package/src/types/global-private.d.ts +11 -18
  67. package/src/types/internal.d.ts +25 -30
  68. package/src/utils/error.js +1 -1
  69. package/src/utils/import.js +6 -1
  70. package/src/utils/mime.js +9 -0
  71. package/src/utils/params.js +66 -0
  72. package/src/utils/routing.js +90 -44
  73. package/src/utils/streaming.js +14 -4
  74. package/src/utils/url.js +0 -79
  75. package/src/version.js +1 -1
  76. package/types/index.d.ts +127 -125
  77. package/types/index.d.ts.map +12 -8
  78. package/src/core/sync/write_root.js +0 -148
  79. package/src/exports/internal/server.js +0 -22
  80. /package/src/exports/internal/{remote-functions.js → server/remote-functions.js} +0 -0
@@ -1,21 +1,20 @@
1
+ /** @import { NextHandleFunction } from 'connect' */
2
+ /** @import { PreviewServer, ResolvedConfig } from 'vite' */
3
+ /** @import { ValidatedConfig, ServerInternalModule, ServerModule } from 'types' */
1
4
  import fs from 'node:fs';
2
5
  import { join } from 'node:path';
3
6
  import { pathToFileURL } from 'node:url';
4
- import { lookup } from 'mrmime';
7
+ import { lookup } from '../../../utils/mime.js';
5
8
  import sirv from 'sirv';
6
9
  import { loadEnv, normalizePath } from 'vite';
7
10
  import { createReadableStream, getRequest, setResponse } from '../../../exports/node/index.js';
8
11
  import { SVELTE_KIT_ASSETS } from '../../../constants.js';
9
12
  import { is_chrome_devtools_request, not_found } from '../utils.js';
10
13
 
11
- /** @typedef {import('http').IncomingMessage} Req */
12
- /** @typedef {import('http').ServerResponse} Res */
13
- /** @typedef {(req: Req, res: Res, next: () => void) => void} Handler */
14
-
15
14
  /**
16
- * @param {import('vite').PreviewServer} vite
17
- * @param {import('vite').ResolvedConfig} vite_config
18
- * @param {import('types').ValidatedConfig} svelte_config
15
+ * @param {PreviewServer} vite
16
+ * @param {ResolvedConfig} vite_config
17
+ * @param {ValidatedConfig} svelte_config
19
18
  */
20
19
  export async function preview(vite, vite_config, svelte_config) {
21
20
  const { paths } = svelte_config.kit;
@@ -37,10 +36,10 @@ export async function preview(vite, vite_config, svelte_config) {
37
36
  await import(pathToFileURL(instrumentation).href);
38
37
  }
39
38
 
40
- /** @type {import('types').ServerInternalModule} */
39
+ /** @type {ServerInternalModule} */
41
40
  const { set_assets } = await import(pathToFileURL(join(dir, 'internal.js')).href);
42
41
 
43
- /** @type {import('types').ServerModule} */
42
+ /** @type {ServerModule} */
44
43
  const { Server } = await import(pathToFileURL(join(dir, 'index.js')).href);
45
44
 
46
45
  const { manifest } = await import(pathToFileURL(join(dir, 'manifest.js')).href);
@@ -204,12 +203,12 @@ export async function preview(vite, vite_config, svelte_config) {
204
203
  vite.middlewares.use(async (req, res) => {
205
204
  const host = req.headers[':authority'] || req.headers.host;
206
205
 
207
- const request = await getRequest({
206
+ const request = getRequest({
208
207
  base: `${protocol}://${host}`,
209
208
  request: req
210
209
  });
211
210
 
212
- await setResponse(
211
+ setResponse(
213
212
  res,
214
213
  await server.respond(request, {
215
214
  getClientAddress: () => {
@@ -233,7 +232,7 @@ export async function preview(vite, vite_config, svelte_config) {
233
232
 
234
233
  /**
235
234
  * @param {string} dir
236
- * @returns {Handler}
235
+ * @returns {NextHandleFunction}
237
236
  */
238
237
  const mutable = (dir) =>
239
238
  fs.existsSync(dir)
@@ -245,8 +244,8 @@ const mutable = (dir) =>
245
244
 
246
245
  /**
247
246
  * @param {string} scope
248
- * @param {Handler} handler
249
- * @returns {Handler}
247
+ * @param {NextHandleFunction} handler
248
+ * @returns {NextHandleFunction}
250
249
  */
251
250
  function scoped(scope, handler) {
252
251
  if (scope === '') return handler;
@@ -18,13 +18,13 @@ import {
18
18
  *
19
19
  * @param {import('types').ValidatedKitConfig} config
20
20
  * @param {string} root
21
- * */
21
+ */
22
22
  export function get_config_aliases(config, root) {
23
23
  /** @type {import('vite').Alias[]} */
24
24
  const alias = [
25
25
  // For now, we handle `$lib` specially here rather than make it a default value for
26
26
  // `config.alias` since it has special meaning for packaging, etc.
27
- { find: '$lib', replacement: config.files.lib }
27
+ { find: '$lib', replacement: posixify(config.files.lib) }
28
28
  ];
29
29
 
30
30
  for (let [key, value] of Object.entries(config.alias)) {
@@ -36,16 +36,16 @@ export function get_config_aliases(config, root) {
36
36
  // Doing just `{ find: key.slice(0, -2) ,..}` would mean `import .. from "key"` would also be matched, which we don't want
37
37
  alias.push({
38
38
  find: new RegExp(`^${escape_for_regexp(key.slice(0, -2))}\\/(.+)$`),
39
- replacement: `${path.resolve(root, value)}/$1`
39
+ replacement: `${posixify(path.resolve(root, value))}/$1`
40
40
  });
41
41
  } else if (key + '/*' in config.alias) {
42
42
  // key and key/* both exist -> the replacement for key needs to happen _only_ on import .. from "key"
43
43
  alias.push({
44
44
  find: new RegExp(`^${escape_for_regexp(key)}$`),
45
- replacement: path.resolve(root, value)
45
+ replacement: posixify(path.resolve(root, value))
46
46
  });
47
47
  } else {
48
- alias.push({ find: key, replacement: path.resolve(root, value) });
48
+ alias.push({ find: key, replacement: posixify(path.resolve(root, value)) });
49
49
  }
50
50
  }
51
51
 
@@ -152,17 +152,15 @@ export function normalize_id(id, lib, cwd) {
152
152
  export const strip_virtual_prefix = /** @param {string} id */ (id) => id.replace('\0virtual:', '');
153
153
 
154
154
  /**
155
- * For `error_for_missing_config('instrumentation.server.js', 'experimental.instrumentation.server', true)`,
155
+ * For `error_for_missing_config('remote functions', 'experimental.remoteFunctions', 'true')`,
156
156
  * returns:
157
157
  *
158
158
  * ```
159
- * To enable `instrumentation.server.js`, add the following to the SvelteKit plugin in your `vite.config.js`:
159
+ * To enable remote functions, add the following to the SvelteKit plugin in your `vite.config.js`:
160
160
  *
161
161
  *\`\`\`js
162
162
  * experimental: {
163
- * instrumentation: {
164
- * server: true
165
- * }
163
+ * remoteFunctions: true
166
164
  * }
167
165
  *\`\`\`
168
166
  *```
@@ -1,4 +1,7 @@
1
- export const version = __SVELTEKIT_APP_VERSION__;
1
+ import { BROWSER } from 'esm-env';
2
+ import { payload } from '../../client/payload.js';
3
+
4
+ export const version = BROWSER ? payload.version : __SVELTEKIT_APP_VERSION__;
2
5
  export let building = false;
3
6
  export let prerendering = false;
4
7
 
@@ -9,6 +12,3 @@ export function set_building() {
9
12
  export function set_prerendering() {
10
13
  prerendering = true;
11
14
  }
12
-
13
- // force /@vite/client to be injected
14
- import.meta.hot;
@@ -1,7 +1,7 @@
1
1
  import * as devalue from 'devalue';
2
2
  import { BROWSER, DEV } from 'esm-env';
3
3
  import { noop } from '../../utils/functions.js';
4
- import { invalidateAll } from './navigation.js';
4
+ import { refreshAll } from './navigation.js';
5
5
  import { app as client_app, applyAction, handle_error } from '../client/client.js';
6
6
  import { app as server_app } from '../server/app.js';
7
7
 
@@ -106,7 +106,7 @@ export function enhance(form_element, submit = noop) {
106
106
  HTMLFormElement.prototype.reset.call(form_element);
107
107
  }
108
108
  if (shouldInvalidateAll) {
109
- await invalidateAll();
109
+ await refreshAll();
110
110
  }
111
111
  }
112
112
 
@@ -1,4 +1,4 @@
1
- /** @import { Asset, RouteId, RouteIdWithSearchOrHash, Pathname, PathnameWithSearchOrHash, ResolvedPathname } from '$app/types' */
1
+ /** @import { Asset, RouteId, RouteIdWithSearchOrHash, Pathname, PathnameWithSearchOrHash, ResolvedPathname, RouteParams } from '$app/types' */
2
2
  /** @import { ResolveArgs } from './types.js' */
3
3
  import { base, assets, hash_routing } from './internal/client.js';
4
4
  import { resolve_route } from '../../../utils/routing.js';
@@ -59,11 +59,7 @@ export function resolve(...args) {
59
59
  );
60
60
  }
61
61
 
62
- // The type error is correct here, and if someone doesn't pass params when they should there's a runtime error,
63
- // but we don't want to adjust the internal resolve_route function to accept `undefined`, hence the type cast.
64
- return (
65
- base + pathname_prefix + resolve_route(args[0], /** @type {Record<string, string>} */ (args[1]))
66
- );
62
+ return base + pathname_prefix + resolve_route(args[0], args[1] ?? {});
67
63
  }
68
64
 
69
65
  /**
@@ -84,7 +80,7 @@ export function resolve(...args) {
84
80
  * @since 2.52.0
85
81
  *
86
82
  * @param {Pathname | URL | (string & {})} url
87
- * @returns {Promise<{ id: RouteId, params: Record<string, string> } | null>}
83
+ * @returns {Promise<{ [K in RouteId]: { id: K; params: RouteParams<K>; } }[RouteId] | null>}
88
84
  */
89
85
  export async function match(url) {
90
86
  if (typeof url === 'string') {
@@ -1,4 +1,6 @@
1
- export const base = __SVELTEKIT_PAYLOAD__?.base ?? __SVELTEKIT_PATHS_BASE__;
2
- export const assets = __SVELTEKIT_PAYLOAD__?.assets ?? base ?? __SVELTEKIT_PATHS_ASSETS__;
1
+ import { payload } from '../../../client/payload.js';
2
+
3
+ export const base = payload.base ?? __SVELTEKIT_PATHS_BASE__;
4
+ export const assets = payload.assets ?? base ?? __SVELTEKIT_PATHS_ASSETS__;
3
5
  export const app_dir = __SVELTEKIT_APP_DIR__;
4
6
  export const hash_routing = __SVELTEKIT_HASH_ROUTING__;
@@ -1,30 +1,9 @@
1
- export let base = __SVELTEKIT_PATHS_BASE__;
1
+ export const base = __SVELTEKIT_PATHS_BASE__;
2
2
  export let assets = __SVELTEKIT_PATHS_ASSETS__ || base;
3
3
  export const app_dir = __SVELTEKIT_APP_DIR__;
4
4
  export const relative = __SVELTEKIT_PATHS_RELATIVE__;
5
5
 
6
- const initial = { base, assets };
7
-
8
- /**
9
- * `base` could be overridden during rendering to be relative;
10
- * this one's the original non-relative base path
11
- */
12
- export const initial_base = initial.base;
13
-
14
- /**
15
- * @param {{ base: string, assets: string }} paths
16
- */
17
- export function override(paths) {
18
- base = paths.base;
19
- assets = paths.assets;
20
- }
21
-
22
- export function reset() {
23
- base = initial.base;
24
- assets = initial.assets;
25
- }
26
-
27
6
  /** @param {string} path */
28
7
  export function set_assets(path) {
29
- assets = initial.assets = path;
8
+ assets = path;
30
9
  }
@@ -1,4 +1,4 @@
1
- import { base, assets, relative, initial_base } from './internal/server.js';
1
+ import { base, assets, relative } from './internal/server.js';
2
2
  import { resolve_route, find_route } from '../../../utils/routing.js';
3
3
  import { decode_pathname } from '../../../utils/url.js';
4
4
  import { add_data_suffix } from '../../pathname.js';
@@ -21,7 +21,7 @@ export function resolve(id, params) {
21
21
  );
22
22
  }
23
23
 
24
- const resolved = resolve_route(id, /** @type {Record<string, string>} */ (params));
24
+ const resolved = resolve_route(id, params ?? {});
25
25
 
26
26
  if (relative) {
27
27
  const store = try_get_request_store();
@@ -32,7 +32,7 @@ export function resolve(id, params) {
32
32
  const pathname = store.event.isDataRequest
33
33
  ? add_data_suffix(store.event.url.pathname)
34
34
  : store.event.url.pathname;
35
- const after_base = pathname.slice(initial_base.length);
35
+ const after_base = pathname.slice(base.length);
36
36
  const segments = after_base.split('/').slice(2);
37
37
  const prefix = segments.map(() => '..').join('/') || '.';
38
38
 
@@ -411,20 +411,14 @@ export function refresh(event, state, internals, payload, fn) {
411
411
 
412
412
  const key = create_remote_key(internals.id, payload);
413
413
 
414
- // `fn()` is invoked eagerly here, which starts running the query immediately.
415
- // The resulting promise is normally awaited (and its rejection handled) in
416
- // `collect_remote_data`, but some code paths (e.g. a command throwing a
417
- // non-redirect error) never reach that point. Attach a no-op `catch` to the
418
- // promise so a rejection is always considered handled and can never become an
419
- // unhandled promise rejection (which crashes the process on modern Node).
420
- // We still store the original promise so `collect_remote_data` can serialize
421
- // either its value or its error as before.
422
- const promise = fn();
423
- promise.catch(() => {});
424
-
414
+ // `fn` is stored rather than invoked eagerly. The query is run at the end of
415
+ // the command/form (in `collect_remote_data`), so that it observes any state
416
+ // mutations that happen after `refresh()` is called. If the developer re-awaits
417
+ // the query before the command finishes, the cache entry created by that await
418
+ // is reused instead of re-running the query.
425
419
  (state.remote.explicit ??= new Map()).set(key, {
426
420
  internals,
427
- promise
421
+ fn
428
422
  });
429
423
  }
430
424
 
@@ -3,7 +3,6 @@ import {
3
3
  navigating as _navigating,
4
4
  updated as _updated
5
5
  } from '../../client/state.svelte.js';
6
- import { stores } from '../../client/client.js';
7
6
 
8
7
  export const page = {
9
8
  get data() {
@@ -57,5 +56,5 @@ export const updated = {
57
56
  get current() {
58
57
  return _updated.current;
59
58
  },
60
- check: stores.updated.check
59
+ check: _updated.check
61
60
  };
@@ -1,101 +1,38 @@
1
- import { getContext } from 'svelte';
2
- import { BROWSER, DEV } from 'esm-env';
3
- import { stores as browser_stores } from '../client/client.js';
1
+ // TODO: remove this file when enough people have migrated to Kit 3
2
+
3
+ /** @returns {never} */
4
+ function removed() {
5
+ throw new Error(
6
+ '`$app/stores` has been removed in favour of `$app/state`. See https://svelte.dev/docs/kit/migrating-to-sveltekit-2#SvelteKit-2.12:-$app-stores-deprecated'
7
+ );
8
+ }
4
9
 
5
10
  /**
6
- * A function that returns all of the contextual stores. On the server, this must be called during component initialization.
7
- * Only use this if you need to defer store subscription until after the component has mounted, for some reason.
8
- *
9
11
  * @deprecated Use `$app/state` instead (requires Svelte 5, [see docs for more info](https://svelte.dev/docs/kit/migrating-to-sveltekit-2#SvelteKit-2.12:-$app-stores-deprecated))
10
12
  */
11
- export const getStores = () => {
12
- const stores = BROWSER ? browser_stores : getContext('__svelte__');
13
-
14
- return {
15
- /** @type {typeof page} */
16
- page: {
17
- subscribe: stores.page.subscribe
18
- },
19
- /** @type {typeof navigating} */
20
- navigating: {
21
- subscribe: stores.navigating.subscribe
22
- },
23
- /** @type {typeof updated} */
24
- updated: stores.updated
25
- };
26
- };
13
+ export const getStores = removed;
27
14
 
28
15
  /**
29
- * A readable store whose value contains page data.
30
- *
31
- * On the server, this store can only be subscribed to during component initialization. In the browser, it can be subscribed to at any time.
32
- *
33
16
  * @deprecated Use `page` from `$app/state` instead (requires Svelte 5, [see docs for more info](https://svelte.dev/docs/kit/migrating-to-sveltekit-2#SvelteKit-2.12:-$app-stores-deprecated))
34
17
  * @type {import('svelte/store').Readable<import('@sveltejs/kit').Page>}
35
18
  */
36
19
  export const page = {
37
- subscribe(fn) {
38
- const store = DEV ? get_store('page') : getStores().page;
39
- return store.subscribe(fn);
40
- }
20
+ subscribe: removed
41
21
  };
42
22
 
43
23
  /**
44
- * A readable store.
45
- * When navigating starts, its value is a `Navigation` object with `from`, `to`, `type` and (if `type === 'popstate'`) `delta` properties.
46
- * When navigating finishes, its value reverts to `null`.
47
- *
48
- * On the server, this store can only be subscribed to during component initialization. In the browser, it can be subscribed to at any time.
49
- *
50
24
  * @deprecated Use `navigating` from `$app/state` instead (requires Svelte 5, [see docs for more info](https://svelte.dev/docs/kit/migrating-to-sveltekit-2#SvelteKit-2.12:-$app-stores-deprecated))
51
25
  * @type {import('svelte/store').Readable<import('@sveltejs/kit').Navigation | null>}
52
26
  */
53
27
  export const navigating = {
54
- subscribe(fn) {
55
- const store = DEV ? get_store('navigating') : getStores().navigating;
56
- return store.subscribe(fn);
57
- }
28
+ subscribe: removed
58
29
  };
59
30
 
60
31
  /**
61
- * A readable store whose initial value is `false`. If [`version.pollInterval`](https://svelte.dev/docs/kit/configuration#version) is a non-zero value, SvelteKit will poll for new versions of the app and update the store value to `true` when it detects one. `updated.check()` will force an immediate check, regardless of polling.
62
- *
63
- * On the server, this store can only be subscribed to during component initialization. In the browser, it can be subscribed to at any time.
64
- *
65
32
  * @deprecated Use `updated` from `$app/state` instead (requires Svelte 5, [see docs for more info](https://svelte.dev/docs/kit/migrating-to-sveltekit-2#SvelteKit-2.12:-$app-stores-deprecated))
66
33
  * @type {import('svelte/store').Readable<boolean> & { check(): Promise<boolean> }}
67
34
  */
68
35
  export const updated = {
69
- subscribe(fn) {
70
- const store = DEV ? get_store('updated') : getStores().updated;
71
-
72
- if (BROWSER) {
73
- updated.check = store.check;
74
- }
75
-
76
- return store.subscribe(fn);
77
- },
78
- check: () => {
79
- throw new Error(
80
- BROWSER
81
- ? 'Cannot check updated store before subscribing'
82
- : 'Can only check updated store in browser'
83
- );
84
- }
36
+ subscribe: removed,
37
+ check: removed
85
38
  };
86
-
87
- /**
88
- * @template {keyof ReturnType<typeof getStores>} Name
89
- * @param {Name} name
90
- * @returns {ReturnType<typeof getStores>[Name]}
91
- */
92
- function get_store(name) {
93
- try {
94
- return getStores()[name];
95
- } catch {
96
- throw new Error(
97
- `Cannot subscribe to '${name}' store on the server outside of a Svelte component, as it is bound to the current request via component context. This prevents state from leaking between users.` +
98
- 'For more information, see https://svelte.dev/docs/kit/state-management#avoid-shared-state-on-the-server'
99
- );
100
- }
101
- }
@@ -1,6 +1,6 @@
1
1
  /* if `bundleStrategy` is 'single' or 'inline', this file is used as the entry point */
2
2
 
3
- import * as kit from './entry.js';
3
+ import * as kit from './client-entry.js';
4
4
 
5
5
  // @ts-expect-error
6
6
  import * as app from '__sveltekit/manifest';
@@ -0,0 +1,3 @@
1
+ // we expose this as a separate entry point (rather than treating client.js as the entry point)
2
+ // so that everything other than `start`/`load_css` can be treeshaken
3
+ export { start, load_css } from './client.js';