@sveltejs/kit 2.60.0 → 2.61.0

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 +10 -11
  2. package/src/core/postbuild/analyse.js +1 -3
  3. package/src/core/sync/create_manifest_data/conflict.js +72 -0
  4. package/src/core/sync/create_manifest_data/index.js +1 -65
  5. package/src/core/sync/write_non_ambient.js +2 -2
  6. package/src/core/sync/write_types/index.js +1 -1
  7. package/src/exports/public.d.ts +23 -30
  8. package/src/exports/vite/build/build_server.js +36 -13
  9. package/src/exports/vite/dev/index.js +4 -2
  10. package/src/exports/vite/index.js +18 -16
  11. package/src/runtime/app/server/index.js +1 -2
  12. package/src/runtime/app/server/remote/form.js +10 -0
  13. package/src/runtime/app/server/remote/query.js +111 -44
  14. package/src/runtime/client/client.js +13 -8
  15. package/src/runtime/client/remote-functions/cache.svelte.js +157 -0
  16. package/src/runtime/client/remote-functions/form.svelte.js +235 -196
  17. package/src/runtime/client/remote-functions/index.js +2 -2
  18. package/src/runtime/client/remote-functions/prerender.svelte.js +1 -2
  19. package/src/runtime/client/remote-functions/query/cache.js +4 -0
  20. package/src/runtime/client/remote-functions/query/index.js +48 -0
  21. package/src/runtime/client/remote-functions/query/instance.svelte.js +249 -0
  22. package/src/runtime/client/remote-functions/query/proxy.js +156 -0
  23. package/src/runtime/client/remote-functions/query-batch.svelte.js +1 -1
  24. package/src/runtime/client/remote-functions/query-live/cache.js +4 -0
  25. package/src/runtime/client/remote-functions/query-live/index.js +31 -0
  26. package/src/runtime/client/remote-functions/{query-live.svelte.js → query-live/instance.svelte.js} +61 -310
  27. package/src/runtime/client/remote-functions/query-live/iterator.js +91 -0
  28. package/src/runtime/client/remote-functions/query-live/proxy.js +144 -0
  29. package/src/runtime/client/remote-functions/shared.svelte.js +53 -6
  30. package/src/runtime/client/utils.js +1 -1
  31. package/src/runtime/form-utils.js +7 -16
  32. package/src/runtime/server/index.js +2 -3
  33. package/src/runtime/server/page/actions.js +2 -9
  34. package/src/runtime/server/page/csp.js +3 -4
  35. package/src/runtime/server/page/render.js +13 -14
  36. package/src/runtime/server/respond.js +61 -38
  37. package/src/runtime/server/utils.js +23 -3
  38. package/src/types/global-private.d.ts +5 -0
  39. package/src/types/internal.d.ts +45 -8
  40. package/src/utils/routing.js +3 -1
  41. package/src/utils/shared-iterator.js +213 -0
  42. package/src/version.js +1 -1
  43. package/types/index.d.ts +28 -32
  44. package/types/index.d.ts.map +1 -1
  45. package/src/runtime/client/remote-functions/query.svelte.js +0 -512
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sveltejs/kit",
3
- "version": "2.60.0",
3
+ "version": "2.61.0",
4
4
  "description": "SvelteKit is the fastest way to build Svelte apps",
5
5
  "keywords": [
6
6
  "framework",
@@ -19,11 +19,11 @@
19
19
  "type": "module",
20
20
  "dependencies": {
21
21
  "@standard-schema/spec": "^1.0.0",
22
- "@sveltejs/acorn-typescript": "^1.0.5",
22
+ "@sveltejs/acorn-typescript": "^1.0.9",
23
23
  "@types/cookie": "^0.6.0",
24
- "acorn": "^8.14.1",
24
+ "acorn": "^8.16.0",
25
25
  "cookie": "^0.6.0",
26
- "devalue": "^5.6.4",
26
+ "devalue": "^5.8.1",
27
27
  "esm-env": "^1.2.2",
28
28
  "kleur": "^4.1.5",
29
29
  "magic-string": "^0.30.5",
@@ -38,16 +38,17 @@
38
38
  "@types/connect": "^3.4.38",
39
39
  "@types/node": "^18.19.119",
40
40
  "@types/set-cookie-parser": "^2.4.7",
41
- "dts-buddy": "^0.7.0",
41
+ "dts-buddy": "^0.8.0",
42
+ "jsdom": "^26.1.0",
42
43
  "rollup": "^4.59.0",
43
- "svelte": "^5.53.12",
44
+ "svelte": "^5.55.7",
44
45
  "typescript": "^5.3.3",
45
46
  "vite": "^6.4.2",
46
- "vitest": "^4.0.0"
47
+ "vitest": "^4.1.7"
47
48
  },
48
49
  "peerDependencies": {
49
- "@sveltejs/vite-plugin-svelte": "^3.0.0 || ^4.0.0-next.1 || ^5.0.0 || ^6.0.0-next.0 || ^7.0.0",
50
50
  "@opentelemetry/api": "^1.0.0",
51
+ "@sveltejs/vite-plugin-svelte": "^3.0.0 || ^4.0.0-next.1 || ^5.0.0 || ^6.0.0-next.0 || ^7.0.0",
51
52
  "svelte": "^4.0.0 || ^5.0.0-next.0",
52
53
  "typescript": "^5.3.3 || ^6.0.0",
53
54
  "vite": "^5.0.3 || ^6.0.0 || ^7.0.0-beta.0 || ^8.0.0"
@@ -125,9 +126,7 @@
125
126
  "test:server-side-route-resolution:build": "pnpm test:unit && pnpm -r --workspace-concurrency 1 --filter=\"./test/**\" test:server-side-route-resolution:build",
126
127
  "test:svelte-async:dev": "pnpm -r --workspace-concurrency 1 --filter=\"./test/**\" test:svelte-async:dev",
127
128
  "test:svelte-async:build": "pnpm test:unit && pnpm -r --workspace-concurrency 1 --filter=\"./test/**\" test:svelte-async:build",
128
- "test:unit:dev": "vitest --config kit.vitest.config.js run",
129
- "test:unit:prod": "NODE_ENV=production vitest --config kit.vitest.config.js run csp.spec.js cookie.spec.js",
130
- "test:unit": "pnpm test:unit:dev && pnpm test:unit:prod",
129
+ "test:unit": "vitest --config kit.vitest.config.js run",
131
130
  "generate:version": "node scripts/generate-version.js",
132
131
  "generate:types": "node scripts/generate-dts.js"
133
132
  }
@@ -24,7 +24,6 @@ export default forked(import.meta.url, analyse);
24
24
  * tracked_features: Record<string, string[]>;
25
25
  * env: Record<string, string>;
26
26
  * out: string;
27
- * output_config: import('types').RecursiveRequired<import('types').ValidatedConfig['kit']['output']>;
28
27
  * remotes: RemoteChunk[];
29
28
  * }} opts
30
29
  */
@@ -36,7 +35,6 @@ async function analyse({
36
35
  tracked_features,
37
36
  env,
38
37
  out,
39
- output_config,
40
38
  remotes
41
39
  }) {
42
40
  /** @type {import('@sveltejs/kit').SSRManifest} */
@@ -66,7 +64,7 @@ async function analyse({
66
64
  internal.set_read_implementation((file) => createReadableStream(`${server_root}/server/${file}`));
67
65
 
68
66
  // first, build server nodes without the client manifest so we can analyse it
69
- build_server_nodes(out, config, manifest_data, server_manifest, null, null, null, output_config);
67
+ build_server_nodes(out, config, manifest_data, server_manifest, null, null, null);
70
68
 
71
69
  /** @type {import('types').ServerMetadata} */
72
70
  const metadata = {
@@ -0,0 +1,72 @@
1
+ /** @param {import('types').RouteData[]} routes */
2
+ export function prevent_conflicts(routes) {
3
+ /** @type {Map<string, string>} */
4
+ const lookup = new Map();
5
+
6
+ for (const route of routes) {
7
+ if (!route.leaf && !route.endpoint) continue;
8
+
9
+ /** @type {string[]} */
10
+ let permutations;
11
+
12
+ const normalized = normalize_route_id(route.id);
13
+
14
+ const ends_with_optional = /<\?.+?>$/.test(normalized);
15
+ if (!ends_with_optional && Array.from(normalized.matchAll(/<\?.+?>/g)).length) {
16
+ // find all permutations created by optional parameters
17
+ const split = normalized.split(/<\?(.+?)>/g);
18
+
19
+ permutations = [/** @type {string} */ (split[0])];
20
+
21
+ // turn `x/[[optional]]/y` into `x/y` and `x/[required]/y`
22
+ for (let i = 1; i < split.length; i += 2) {
23
+ const matcher = split[i];
24
+ const next = split[i + 1];
25
+
26
+ permutations = permutations.reduce((a, b) => {
27
+ a.push(b + next);
28
+ if (!(matcher === '*' && b.endsWith('//'))) a.push(b + `<${matcher}>${next}`);
29
+ return a;
30
+ }, /** @type {string[]} */ ([]));
31
+ }
32
+ } else {
33
+ permutations = [normalized];
34
+ }
35
+
36
+ for (const permutation of permutations) {
37
+ // remove leading/trailing/duplicated slashes caused by prior
38
+ // manipulation of optional parameters and (groups)
39
+ const key = permutation
40
+ .replace(/\/{2,}/, '/')
41
+ .replace(/^\//, '')
42
+ .replace(/\/$/, '');
43
+
44
+ if (lookup.has(key)) {
45
+ throw new Error(
46
+ `The "${lookup.get(key)}" and "${route.id}" routes conflict with each other`
47
+ );
48
+ }
49
+
50
+ lookup.set(key, route.id);
51
+ }
52
+ }
53
+ }
54
+
55
+ /** @param {string} id */
56
+ function normalize_route_id(id) {
57
+ return (
58
+ id
59
+ // remove groups
60
+ .replace(/(?<=^|\/)\(.+?\)(?=$|\/)/g, '')
61
+
62
+ .replace(/\[[ux]\+([0-9a-f]+)\]/g, (_, x) =>
63
+ String.fromCharCode(parseInt(x, 16)).replace(/\//g, '%2f')
64
+ )
65
+
66
+ // replace `[param]` with `<*>`, `[param=x]` with `<x>`, and `[[param]]` with `<?*>`
67
+ .replace(
68
+ /\[(?:(\[)|(\.\.\.))?.+?(=.+?)?\]\]?/g,
69
+ (_, optional, rest, matcher) => `<${optional ? '?' : ''}${rest ?? ''}${matcher ?? '*'}>`
70
+ )
71
+ );
72
+ }
@@ -6,6 +6,7 @@ import { lookup } from 'mrmime';
6
6
  import { list_files, runtime_directory } from '../../utils.js';
7
7
  import { posixify, resolve_entry } from '../../../utils/filesystem.js';
8
8
  import { parse_route_id } from '../../../utils/routing.js';
9
+ import { prevent_conflicts } from './conflict.js';
9
10
  import { sort_routes } from './sort.js';
10
11
  import { isSvelte5Plus } from '../utils.js';
11
12
  import {
@@ -546,68 +547,3 @@ function count_occurrences(needle, haystack) {
546
547
  }
547
548
  return count;
548
549
  }
549
-
550
- /** @param {import('types').RouteData[]} routes */
551
- function prevent_conflicts(routes) {
552
- /** @type {Map<string, string>} */
553
- const lookup = new Map();
554
-
555
- for (const route of routes) {
556
- if (!route.leaf && !route.endpoint) continue;
557
-
558
- const normalized = normalize_route_id(route.id);
559
-
560
- // find all permutations created by optional parameters
561
- const split = normalized.split(/<\?(.+?)>/g);
562
-
563
- let permutations = [/** @type {string} */ (split[0])];
564
-
565
- // turn `x/[[optional]]/y` into `x/y` and `x/[required]/y`
566
- for (let i = 1; i < split.length; i += 2) {
567
- const matcher = split[i];
568
- const next = split[i + 1];
569
-
570
- permutations = permutations.reduce((a, b) => {
571
- a.push(b + next);
572
- if (!(matcher === '*' && b.endsWith('//'))) a.push(b + `<${matcher}>${next}`);
573
- return a;
574
- }, /** @type {string[]} */ ([]));
575
- }
576
-
577
- for (const permutation of permutations) {
578
- // remove leading/trailing/duplicated slashes caused by prior
579
- // manipulation of optional parameters and (groups)
580
- const key = permutation
581
- .replace(/\/{2,}/, '/')
582
- .replace(/^\//, '')
583
- .replace(/\/$/, '');
584
-
585
- if (lookup.has(key)) {
586
- throw new Error(
587
- `The "${lookup.get(key)}" and "${route.id}" routes conflict with each other`
588
- );
589
- }
590
-
591
- lookup.set(key, route.id);
592
- }
593
- }
594
- }
595
-
596
- /** @param {string} id */
597
- function normalize_route_id(id) {
598
- return (
599
- id
600
- // remove groups
601
- .replace(/(?<=^|\/)\(.+?\)(?=$|\/)/g, '')
602
-
603
- .replace(/\[[ux]\+([0-9a-f]+)\]/g, (_, x) =>
604
- String.fromCharCode(parseInt(x, 16)).replace(/\//g, '%2f')
605
- )
606
-
607
- // replace `[param]` with `<*>`, `[param=x]` with `<x>`, and `[[param]]` with `<?*>`
608
- .replace(
609
- /\[(?:(\[)|(\.\.\.))?.+?(=.+?)?\]\]?/g,
610
- (_, optional, rest, matcher) => `<${optional ? '?' : ''}${rest ?? ''}${matcher ?? '*'}>`
611
- )
612
- );
613
- }
@@ -204,7 +204,7 @@ function generate_app_types(manifest_data, config) {
204
204
  if (route.params.length > 0) {
205
205
  const params = route.params.map((p) => {
206
206
  const type = get_matcher_type(p.matcher);
207
- return `${p.name}${p.optional ? '?:' : ':'} ${type}`;
207
+ return `${p.name}${p.optional ? '?:' : ':'} ${type}${p.optional ? ' | undefined' : ''}`;
208
208
  });
209
209
  const route_type = `${s(route.id)}: { ${params.join('; ')} }`;
210
210
 
@@ -225,7 +225,7 @@ function generate_app_types(manifest_data, config) {
225
225
  const params = Array.from(layout_params)
226
226
  .map(([name, { optional, matchers }]) => {
227
227
  const type = get_matchers_type(matchers);
228
- return `${name}${optional ? '?:' : ':'} ${type}`;
228
+ return `${name}${optional ? '?:' : ':'} ${type}${optional ? ' | undefined' : ''}`;
229
229
  })
230
230
  .join('; ');
231
231
 
@@ -609,7 +609,7 @@ function generate_params_type(params, outdir, config) {
609
609
  param.matcher
610
610
  ? `MatcherParam<typeof import('${path_to_matcher(param.matcher)}').match>`
611
611
  : 'string'
612
- }`
612
+ }${param.optional ? ' | undefined' : ''}`
613
613
  )
614
614
  .join('; ')} }`;
615
615
  }
@@ -2145,15 +2145,19 @@ export type RemoteForm<Input extends RemoteFormInput | void, Output> = {
2145
2145
  method: 'POST';
2146
2146
  /** The URL to send the form to. */
2147
2147
  action: string;
2148
+ /** The `<form>` element this instance is currently attached to, if any. */
2149
+ get element(): HTMLFormElement | null;
2150
+ /** Submit the currently attached form programmatically. */
2151
+ submit(): Promise<boolean> & {
2152
+ updates: (...updates: RemoteQueryUpdate[]) => Promise<boolean>;
2153
+ };
2148
2154
  /** Use the `enhance` method to influence what happens when the form is submitted. */
2149
2155
  enhance(
2150
- callback: (opts: {
2151
- form: HTMLFormElement;
2152
- data: Input;
2153
- submit: () => Promise<boolean> & {
2154
- updates: (...updates: RemoteQueryUpdate[]) => Promise<boolean>;
2155
- };
2156
- }) => MaybePromise<void>
2156
+ callback: (
2157
+ form: Omit<RemoteForm<Input, Output>, 'enhance' | 'element'> & {
2158
+ readonly element: HTMLFormElement;
2159
+ }
2160
+ ) => MaybePromise<void>
2157
2161
  ): {
2158
2162
  method: 'POST';
2159
2163
  action: string;
@@ -2228,12 +2232,6 @@ export type RemoteResource<T> = Promise<T> & {
2228
2232
  );
2229
2233
 
2230
2234
  export type RemoteQuery<T> = RemoteResource<T> & {
2231
- /**
2232
- * Returns a plain promise with the result.
2233
- * Unlike awaiting the resource directly, this can only be used _outside_ render
2234
- * (i.e. in load functions, event handlers and so on)
2235
- */
2236
- run(): Promise<T>;
2237
2235
  /**
2238
2236
  * On the client, this function will update the value of the query without re-fetching it.
2239
2237
  *
@@ -2257,9 +2255,9 @@ export type RemoteQuery<T> = RemoteResource<T> & {
2257
2255
  * const todos = getTodos();
2258
2256
  * </script>
2259
2257
  *
2260
- * <form {...addTodo.enhance(async ({ data, submit }) => {
2261
- * await submit().updates(
2262
- * todos.withOverride((todos) => [...todos, { text: data.get('text') }])
2258
+ * <form {...addTodo.enhance(async (form) => {
2259
+ * await form.submit().updates(
2260
+ * todos.withOverride((todos) => [...todos, { text: form.fields.text.value() }])
2263
2261
  * );
2264
2262
  * })}>
2265
2263
  * <input type="text" name="text" />
@@ -2270,20 +2268,15 @@ export type RemoteQuery<T> = RemoteResource<T> & {
2270
2268
  withOverride(update: (current: T) => T): RemoteQueryOverride;
2271
2269
  };
2272
2270
 
2273
- export type RemoteLiveQuery<T> = RemoteResource<T> & {
2274
- /**
2275
- * Returns an async iterator with live updates.
2276
- * Unlike awaiting the resource directly, this can only be used _outside_ render
2277
- * (i.e. in load functions, event handlers and so on)
2278
- */
2279
- run(): AsyncGenerator<T>;
2280
- /** `true` if the live stream is currently connected. */
2281
- readonly connected: boolean;
2282
- /** `true` once the current live stream iterator is done. */
2283
- readonly done: boolean;
2284
- /** Reconnects the live stream immediately. */
2285
- reconnect(): Promise<void>;
2286
- };
2271
+ export type RemoteLiveQuery<T> = RemoteResource<T> &
2272
+ AsyncIterable<T> & {
2273
+ /** `true` if the live stream is currently connected. */
2274
+ readonly connected: boolean;
2275
+ /** `true` once the current live stream iterator is done. */
2276
+ readonly done: boolean;
2277
+ /** Reconnects the live stream immediately. */
2278
+ reconnect(): Promise<void>;
2279
+ };
2287
2280
 
2288
2281
  export type RemoteQueryOverride = () => void;
2289
2282
 
@@ -1,3 +1,5 @@
1
+ /** @import { AssetDependencies, ManifestData, SSRNode, ValidatedKitConfig } from 'types' */
2
+ /** @import { Manifest, Rollup } from 'vite' */
1
3
  import fs from 'node:fs';
2
4
  import { mkdirp } from '../../../utils/filesystem.js';
3
5
  import {
@@ -14,14 +16,36 @@ import { fix_css_urls } from '../../../utils/css.js';
14
16
  import { escape_for_interpolation } from '../../../utils/escape.js';
15
17
 
16
18
  /**
19
+ * @overload Build without the client manifest so we can analyse the nodes.
17
20
  * @param {string} out
18
- * @param {import('types').ValidatedKitConfig} kit
19
- * @param {import('types').ManifestData} manifest_data
20
- * @param {import('vite').Manifest} server_manifest
21
- * @param {import('vite').Manifest | null} client_manifest
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
+ /**
41
+ * @param {string} out
42
+ * @param {ValidatedKitConfig} kit
43
+ * @param {ManifestData} manifest_data
44
+ * @param {Manifest} server_manifest
45
+ * @param {Manifest | null} client_manifest
22
46
  * @param {string | null} assets_path
23
- * @param {import('vite').Rollup.RollupOutput['output'] | null} client_chunks
24
- * @param {import('types').RecursiveRequired<import('types').ValidatedConfig['kit']['output']>} output_config
47
+ * @param {Rollup.RollupOutput['output'] | null} client_chunks
48
+ * @returns {void}
25
49
  */
26
50
  export function build_server_nodes(
27
51
  out,
@@ -30,8 +54,7 @@ export function build_server_nodes(
30
54
  server_manifest,
31
55
  client_manifest,
32
56
  assets_path,
33
- client_chunks,
34
- output_config
57
+ client_chunks
35
58
  ) {
36
59
  mkdirp(`${out}/server/nodes`);
37
60
  mkdirp(`${out}/server/stylesheets`);
@@ -49,7 +72,7 @@ export function build_server_nodes(
49
72
  */
50
73
  let prepare_css_for_inlining = (css) => s(css);
51
74
 
52
- if (client_chunks && kit.inlineStyleThreshold > 0 && output_config.bundleStrategy === 'split') {
75
+ if (client_chunks && kit.inlineStyleThreshold > 0 && kit.output.bundleStrategy === 'split') {
53
76
  for (const chunk of client_chunks) {
54
77
  if (chunk.type !== 'asset' || !chunk.fileName.endsWith('.css')) {
55
78
  continue;
@@ -113,7 +136,7 @@ export function build_server_nodes(
113
136
  const imports = [];
114
137
 
115
138
  // String representation of
116
- /** @type {import('types').SSRNode} */
139
+ /** @type {SSRNode} */
117
140
  /** @type {string[]} */
118
141
  const exports = [`export const index = ${i};`];
119
142
 
@@ -162,7 +185,7 @@ export function build_server_nodes(
162
185
  if (
163
186
  client_manifest &&
164
187
  (node.universal || node.component) &&
165
- output_config.bundleStrategy === 'split'
188
+ kit.output.bundleStrategy === 'split'
166
189
  ) {
167
190
  const entry_path = `${normalizePath(kit.outDir)}/generated/client-optimized/nodes/${i}.js`;
168
191
  const entry = find_deps(client_manifest, entry_path, true);
@@ -171,13 +194,13 @@ export function build_server_nodes(
171
194
  // However, if it is not used during SSR (not present in the server manifest),
172
195
  // then it can be lazily loaded in the browser.
173
196
 
174
- /** @type {import('types').AssetDependencies | undefined} */
197
+ /** @type {AssetDependencies | undefined} */
175
198
  let component;
176
199
  if (node.component) {
177
200
  component = find_deps(server_manifest, node.component, true);
178
201
  }
179
202
 
180
- /** @type {import('types').AssetDependencies | undefined} */
203
+ /** @type {AssetDependencies | undefined} */
181
204
  let universal;
182
205
  if (node.universal) {
183
206
  universal = find_deps(server_manifest, node.universal, true);
@@ -568,8 +568,10 @@ export async function dev(vite, vite_config, svelte_config, get_remotes) {
568
568
 
569
569
  return fs.readFileSync(path.join(svelte_config.kit.files.assets, file));
570
570
  },
571
- before_handle: (event, config, prerender) => {
572
- async_local_storage.enterWith({ event, config, prerender });
571
+ before_handle: async (event, config, prerender, handle) => {
572
+ // we need to use .run because .enterWith() is not supported in Cloudflare Workers
573
+ // see https://blog.cloudflare.com/workers-node-js-asynclocalstorage/
574
+ return await async_local_storage.run({ event, config, prerender }, handle);
573
575
  },
574
576
  emulator
575
577
  });
@@ -198,7 +198,10 @@ async function kit({ svelte_config }) {
198
198
  const is_rolldown = !!vite.rolldownVersion;
199
199
 
200
200
  const { kit } = svelte_config;
201
- const out = `${kit.outDir}/output`;
201
+ /** `kit.outDir` but posix-ified */
202
+ const out_dir = posixify(kit.outDir);
203
+ /** The base directory for the Vite builds */
204
+ const out = `${out_dir}/output`;
202
205
 
203
206
  const version_hash = hash(kit.version.name);
204
207
 
@@ -268,7 +271,7 @@ async function kit({ svelte_config }) {
268
271
  const client_hooks = resolve_entry(kit.files.hooks.client);
269
272
  if (client_hooks) allow.add(path.dirname(client_hooks));
270
273
 
271
- const generated = path.posix.join(kit.outDir, 'generated');
274
+ const generated = path.posix.join(out_dir, 'generated');
272
275
 
273
276
  // dev and preview config can be shared
274
277
  /** @type {UserConfig} */
@@ -290,7 +293,7 @@ async function kit({ svelte_config }) {
290
293
  watch: {
291
294
  ignored: [
292
295
  // Ignore all siblings of config.kit.outDir/generated
293
- `${posixify(kit.outDir)}/!(generated)`
296
+ `${out_dir}/!(generated)`
294
297
  ]
295
298
  }
296
299
  },
@@ -373,7 +376,8 @@ async function kit({ svelte_config }) {
373
376
  __SVELTEKIT_CLIENT_ROUTING__: s(kit.router.resolution === 'client'),
374
377
  __SVELTEKIT_HASH_ROUTING__: s(kit.router.type === 'hash'),
375
378
  __SVELTEKIT_SERVER_TRACING_ENABLED__: s(kit.experimental.tracing.server),
376
- __SVELTEKIT_EXPERIMENTAL_USE_TRANSFORM_ERROR__: s(kit.experimental.handleRenderingErrors)
379
+ __SVELTEKIT_EXPERIMENTAL_USE_TRANSFORM_ERROR__: s(kit.experimental.handleRenderingErrors),
380
+ __SVELTEKIT_DEV__: s(!is_build)
377
381
  };
378
382
 
379
383
  if (is_build) {
@@ -447,7 +451,7 @@ async function kit({ svelte_config }) {
447
451
 
448
452
  resolveId(id, importer) {
449
453
  if (id === '__sveltekit/manifest') {
450
- return `${kit.outDir}/generated/client-optimized/app.js`;
454
+ return `${out_dir}/generated/client-optimized/app.js`;
451
455
  }
452
456
 
453
457
  // If importing from a service-worker, only allow $service-worker & $env/static/public, but none of the other virtual modules.
@@ -839,7 +843,7 @@ async function kit({ svelte_config }) {
839
843
 
840
844
  if (ssr) {
841
845
  input.index = `${runtime_directory}/server/index.js`;
842
- input.internal = `${kit.outDir}/generated/server/internal.js`;
846
+ input.internal = `${out_dir}/generated/server/internal.js`;
843
847
  input['remote-entry'] = `${runtime_directory}/app/server/remote/index.js`;
844
848
 
845
849
  // add entry points for every endpoint...
@@ -905,10 +909,10 @@ async function kit({ svelte_config }) {
905
909
  input['bundle'] = `${runtime_directory}/client/bundle.js`;
906
910
  } else {
907
911
  input['entry/start'] = `${runtime_directory}/client/entry.js`;
908
- input['entry/app'] = `${kit.outDir}/generated/client-optimized/app.js`;
912
+ input['entry/app'] = `${out_dir}/generated/client-optimized/app.js`;
909
913
  manifest_data.nodes.forEach((node, i) => {
910
914
  if (node.component || node.universal) {
911
- input[`nodes/${i}`] = `${kit.outDir}/generated/client-optimized/nodes/${i}.js`;
915
+ input[`nodes/${i}`] = `${out_dir}/generated/client-optimized/nodes/${i}.js`;
912
916
  }
913
917
  });
914
918
  }
@@ -953,7 +957,7 @@ async function kit({ svelte_config }) {
953
957
  (is_rolldown
954
958
  ? warning.code === 'IMPORT_IS_UNDEFINED'
955
959
  : warning.code === 'MISSING_EXPORT') &&
956
- warning.id === `${kit.outDir}/generated/client-optimized/app.js`
960
+ warning.id === `${out_dir}/generated/client-optimized/app.js`
957
961
  ) {
958
962
  // ignore e.g. undefined `handleError` hook when
959
963
  // referencing `client_hooks.handleError`
@@ -1109,7 +1113,6 @@ async function kit({ svelte_config }) {
1109
1113
  tracked_features,
1110
1114
  env: { ...env.private, ...env.public },
1111
1115
  out,
1112
- output_config: svelte_config.output,
1113
1116
  remotes
1114
1117
  });
1115
1118
 
@@ -1121,7 +1124,7 @@ async function kit({ svelte_config }) {
1121
1124
  write_client_manifest(
1122
1125
  kit,
1123
1126
  manifest_data,
1124
- `${kit.outDir}/generated/client-optimized`,
1127
+ `${out_dir}/generated/client-optimized`,
1125
1128
  metadata.nodes
1126
1129
  );
1127
1130
 
@@ -1209,7 +1212,7 @@ async function kit({ svelte_config }) {
1209
1212
 
1210
1213
  if (svelte_config.kit.output.bundleStrategy === 'split') {
1211
1214
  const start = deps_of(`${runtime_directory}/client/entry.js`);
1212
- const app = deps_of(`${kit.outDir}/generated/client-optimized/app.js`);
1215
+ const app = deps_of(`${out_dir}/generated/client-optimized/app.js`);
1213
1216
 
1214
1217
  build_data.client = {
1215
1218
  start: start.file,
@@ -1228,11 +1231,11 @@ async function kit({ svelte_config }) {
1228
1231
  if (svelte_config.kit.router.resolution === 'server') {
1229
1232
  const nodes = manifest_data.nodes.map((node, i) => {
1230
1233
  if (node.component || node.universal) {
1231
- const entry = `${kit.outDir}/generated/client-optimized/nodes/${i}.js`;
1234
+ const entry = `${out_dir}/generated/client-optimized/nodes/${i}.js`;
1232
1235
  const deps = deps_of(entry, true);
1233
1236
  const file = resolve_symlinks(
1234
1237
  client_manifest,
1235
- `${kit.outDir}/generated/client-optimized/nodes/${i}.js`
1238
+ `${out_dir}/generated/client-optimized/nodes/${i}.js`
1236
1239
  ).chunk.file;
1237
1240
 
1238
1241
  return { file, css: deps.stylesheets };
@@ -1308,8 +1311,7 @@ async function kit({ svelte_config }) {
1308
1311
  server_manifest,
1309
1312
  client_manifest,
1310
1313
  assets_path,
1311
- client_chunks,
1312
- svelte_config.kit.output
1314
+ client_chunks
1313
1315
  );
1314
1316
 
1315
1317
  // ...and prerender
@@ -1,6 +1,5 @@
1
1
  import { read_implementation, manifest } from '__sveltekit/server';
2
2
  import { base } from '$app/paths';
3
- import { DEV } from 'esm-env';
4
3
  import { base64_decode } from '../../utils.js';
5
4
 
6
5
  /**
@@ -55,7 +54,7 @@ export function read(asset) {
55
54
  }
56
55
 
57
56
  const file = decodeURIComponent(
58
- DEV && asset.startsWith('/@fs') ? asset : asset.slice(base.length + 1)
57
+ __SVELTEKIT_DEV__ && asset.startsWith('/@fs') ? asset : asset.slice(base.length + 1)
59
58
  );
60
59
 
61
60
  if (file in manifest._.server_assets) {
@@ -243,6 +243,16 @@ export function form(validate_or_fn, maybe_fn) {
243
243
  }
244
244
  });
245
245
 
246
+ Object.defineProperty(instance, 'submit', {
247
+ value: () => {
248
+ throw new Error('Cannot call submit() on the server');
249
+ }
250
+ });
251
+
252
+ Object.defineProperty(instance, 'element', {
253
+ get: () => null
254
+ });
255
+
246
256
  if (key == undefined) {
247
257
  Object.defineProperty(instance, 'for', {
248
258
  /** @type {RemoteForm<any, any>['for']} */