@sveltejs/kit 3.0.0-next.23 → 3.0.0-next.24

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 (92) hide show
  1. package/package.json +40 -5
  2. package/src/cli.js +3 -3
  3. package/src/constants.js +13 -1
  4. package/src/core/adapt/builder.js +2 -3
  5. package/src/core/env.js +139 -181
  6. package/src/core/postbuild/analyse.js +9 -4
  7. package/src/core/postbuild/prerender.js +3 -4
  8. package/src/core/sync/create_manifest_data/index.js +29 -33
  9. package/src/core/sync/sync.js +23 -40
  10. package/src/core/sync/write_app_manifest.js +83 -0
  11. package/src/core/sync/write_client_manifest.js +6 -4
  12. package/src/core/sync/write_server.js +10 -6
  13. package/src/core/sync/write_types/index.js +2 -2
  14. package/src/core/utils.js +0 -28
  15. package/src/exports/hooks/public.d.ts +9 -1
  16. package/src/exports/node/index.js +77 -5
  17. package/src/exports/vite/build/build_server.js +3 -3
  18. package/src/exports/vite/build/utils.js +48 -4
  19. package/src/exports/vite/dev/index.js +11 -22
  20. package/src/exports/vite/index.js +62 -345
  21. package/src/exports/vite/module_ids.js +1 -11
  22. package/src/exports/vite/plugins/env-vars.js +117 -0
  23. package/src/exports/vite/preview/index.js +6 -4
  24. package/src/exports/vite/utils.js +2 -4
  25. package/src/runtime/app/env/{types.d.ts → client.js} +9 -4
  26. package/src/runtime/app/env/index.js +1 -2
  27. package/src/runtime/app/env/private/index.js +1 -0
  28. package/src/runtime/app/env/public/client.js +1 -1
  29. package/src/runtime/app/env/public/server.js +1 -1
  30. package/src/runtime/app/env/{internal.js → server.js} +4 -4
  31. package/src/runtime/app/forms/client.js +263 -0
  32. package/src/runtime/app/forms/index.js +1 -263
  33. package/src/runtime/app/forms/public.d.ts +1 -1
  34. package/src/runtime/app/forms/server.js +6 -0
  35. package/src/runtime/app/forms/shared.js +34 -0
  36. package/src/runtime/app/manifest/index.js +1 -1
  37. package/src/runtime/app/navigation/client.js +15 -0
  38. package/src/runtime/app/navigation/index.js +1 -15
  39. package/src/runtime/app/navigation/public.d.ts +1 -1
  40. package/src/runtime/app/navigation/server.js +15 -0
  41. package/src/runtime/app/paths/server.js +1 -1
  42. package/src/runtime/app/server/remote/form.js +11 -1
  43. package/src/runtime/app/server/remote/prerender.js +1 -2
  44. package/src/runtime/app/server/remote/query.js +1 -1
  45. package/src/runtime/app/state/client.svelte.js +207 -0
  46. package/src/runtime/app/state/index.js +1 -66
  47. package/src/runtime/app/state/public.d.ts +1 -1
  48. package/src/runtime/client/bundle.js +1 -1
  49. package/src/runtime/client/client.js +206 -274
  50. package/src/runtime/client/fetcher.js +18 -8
  51. package/src/runtime/client/remote-functions/form.svelte.js +9 -6
  52. package/src/runtime/client/remote-functions/prerender.svelte.js +1 -1
  53. package/src/runtime/client/remote-functions/query-live/iterator.js +1 -1
  54. package/src/runtime/client/remote-functions/shared.svelte.js +2 -2
  55. package/src/runtime/client/snapshots.js +1 -3
  56. package/src/runtime/client/stream.js +27 -20
  57. package/src/runtime/client/utils.js +7 -3
  58. package/src/runtime/components/root.svelte +5 -5
  59. package/src/runtime/env/dynamic/private.js +1 -1
  60. package/src/runtime/env/static/private.js +1 -1
  61. package/src/runtime/error-chain.js +54 -0
  62. package/src/runtime/form-utils.js +53 -77
  63. package/src/runtime/invalid-import.js +1 -0
  64. package/src/runtime/props.svelte.js +1 -1
  65. package/src/runtime/server/data/index.js +1 -1
  66. package/src/runtime/server/endpoint.js +8 -3
  67. package/src/runtime/server/env_module.js +1 -1
  68. package/src/runtime/server/errors.js +2 -2
  69. package/src/runtime/server/index.js +2 -2
  70. package/src/runtime/server/page/actions.js +77 -122
  71. package/src/runtime/server/page/index.js +37 -69
  72. package/src/runtime/server/page/render.js +18 -23
  73. package/src/runtime/server/remote-functions.js +14 -42
  74. package/src/runtime/server/respond.js +23 -3
  75. package/src/telemetry.js +1 -33
  76. package/src/types/ambient-private.d.ts +9 -17
  77. package/src/types/internal.d.ts +20 -4
  78. package/src/types/private.d.ts +1 -1
  79. package/src/utils/exports.js +1 -0
  80. package/src/utils/filesystem.js +9 -21
  81. package/src/utils/functions.js +10 -0
  82. package/src/utils/routing.js +0 -11
  83. package/src/utils/url.js +0 -11
  84. package/src/version.js +1 -1
  85. package/types/index.d.ts +34 -28
  86. package/types/index.d.ts.map +7 -5
  87. package/src/runtime/app/env/private.js +0 -1
  88. package/src/runtime/app/env/standard-schema.d.ts +0 -0
  89. package/src/runtime/app/state/client.js +0 -63
  90. package/src/runtime/client/state.svelte.js +0 -98
  91. package/src/runtime/server/ambient.d.ts +0 -4
  92. package/src/utils/path.js +0 -23
@@ -1,12 +1,10 @@
1
- import { BROWSER, DEV } from 'esm-env';
2
- import { noop } from '../../utils/functions.js';
1
+ import { DEV } from 'esm-env';
3
2
  import { hash_request } from '../../utils/hash.js';
4
3
  import { base64_decode } from '../utils.js';
5
4
 
6
5
  let loading = 0;
7
6
 
8
- /** @type {typeof fetch} */
9
- const native_fetch = BROWSER ? window.fetch : /** @type {any} */ (noop);
7
+ const native_fetch = window.fetch;
10
8
 
11
9
  export function lock_fetch() {
12
10
  loading += 1;
@@ -16,7 +14,7 @@ export function unlock_fetch() {
16
14
  loading -= 1;
17
15
  }
18
16
 
19
- if (DEV && BROWSER) {
17
+ if (DEV) {
20
18
  let can_inspect_stack_trace = false;
21
19
 
22
20
  // detect whether async stack traces work
@@ -61,17 +59,17 @@ if (DEV && BROWSER) {
61
59
  const method = input instanceof Request ? input.method : init?.method || 'GET';
62
60
 
63
61
  if (method !== 'GET') {
64
- cache.delete(build_selector(input));
62
+ cache.delete(build_selector(requested_url(input)));
65
63
  }
66
64
 
67
65
  return native_fetch(input, init);
68
66
  };
69
- } else if (BROWSER) {
67
+ } else {
70
68
  window.fetch = (input, init) => {
71
69
  const method = input instanceof Request ? input.method : init?.method || 'GET';
72
70
 
73
71
  if (method !== 'GET') {
74
- cache.delete(build_selector(input));
72
+ cache.delete(build_selector(requested_url(input)));
75
73
  }
76
74
 
77
75
  return native_fetch(input, init);
@@ -153,6 +151,18 @@ export function dev_fetch(resource, opts) {
153
151
  return window.fetch(resource, patched_opts);
154
152
  }
155
153
 
154
+ /**
155
+ * Mirror the url normalization in `resolve_fetch_url`, so that non-GET requests
156
+ * evict the cache entry regardless of how the url is spelled
157
+ * @param {RequestInfo | URL} input
158
+ */
159
+ function requested_url(input) {
160
+ const resolved = new URL(input instanceof Request ? input.url : input, location.href);
161
+ return resolved.origin === location.origin
162
+ ? resolved.href.slice(location.origin.length)
163
+ : resolved.href;
164
+ }
165
+
156
166
  /**
157
167
  * Build the cache key for a given request
158
168
  * @param {URL | RequestInfo} resource
@@ -11,7 +11,7 @@ import {
11
11
  handle_error,
12
12
  refreshAll
13
13
  } from '../client.js';
14
- import { page } from '../state.svelte.js';
14
+ import { page } from '#app/state/client';
15
15
  import { tick } from 'svelte';
16
16
  import { categorize_updates, remote_request } from './shared.svelte.js';
17
17
  import { createAttachmentKey } from 'svelte/attachments';
@@ -133,7 +133,9 @@ export function form(id) {
133
133
  if (await instance.submit()) {
134
134
  await tick();
135
135
  // We call reset from the prototype to avoid DOM clobbering
136
- HTMLFormElement.prototype.reset.call(instance.element);
136
+ if (instance.element.isConnected) {
137
+ HTMLFormElement.prototype.reset.call(instance.element);
138
+ }
137
139
  }
138
140
  };
139
141
 
@@ -263,7 +265,7 @@ export function form(id) {
263
265
 
264
266
  if (response.redirect) {
265
267
  // Use internal version to allow redirects to external URLs
266
- void _goto(response.redirect, {
268
+ await _goto(response.redirect, {
267
269
  refreshAll: should_refresh
268
270
  });
269
271
  return true;
@@ -273,7 +275,7 @@ export function form(id) {
273
275
 
274
276
  if (succeeded) {
275
277
  if (should_refresh) {
276
- void refreshAll();
278
+ await refreshAll();
277
279
  }
278
280
  } else {
279
281
  if (DEV) {
@@ -695,13 +697,14 @@ export function form(id) {
695
697
  validate: {
696
698
  /** @type {RemoteForm<any, any>['validate']} */
697
699
  value: async ({ all = false, preflightOnly = false } = {}) => {
698
- if (!element) return;
699
-
700
700
  const id = ++validate_id;
701
701
 
702
702
  // wait a tick in case the user is calling validate() right after set() which takes time to propagate
703
703
  await tick();
704
704
 
705
+ // the form may have been removed from the DOM while we were waiting
706
+ if (!element) return;
707
+
705
708
  const default_submitter = /** @type {HTMLElement | undefined} */ (
706
709
  element.querySelector('button:not([type]), [type="submit"]')
707
710
  );
@@ -100,7 +100,7 @@ export function prerender(id) {
100
100
 
101
101
  if (result.redirect) {
102
102
  // Use internal version to allow redirects to external URLs
103
- void _goto(result.redirect);
103
+ await _goto(result.redirect);
104
104
  return;
105
105
  }
106
106
 
@@ -1,7 +1,7 @@
1
1
  /** @import { RemoteFunctionResponse } from 'types' */
2
2
  import { app_dir, base } from '#app/paths';
3
3
  import { app } from '../../client.js';
4
- import { notify_version } from '../../state.svelte.js';
4
+ import { notify_version } from '#app/state/client';
5
5
  import { handle_side_channel_response } from '../shared.svelte.js';
6
6
  import * as devalue from 'devalue';
7
7
  import { HttpError, HandledHttpError } from '@sveltejs/kit/internal';
@@ -6,7 +6,7 @@ import { app, _goto, live_query_map, query_map, query_responses } from '../clien
6
6
  import { HttpError, Redirect, HandledHttpError } from '@sveltejs/kit/internal';
7
7
  import { untrack } from 'svelte';
8
8
  import { create_remote_key, split_remote_key } from '../../shared.js';
9
- import { navigating, page, notify_version } from '../state.svelte.js';
9
+ import { navigating, page, notify_version } from '#app/state/client';
10
10
 
11
11
  /** Indicates a query function, as opposed to a query instance */
12
12
  export const QUERY_FUNCTION_ID = Symbol('sveltekit.query_function_id');
@@ -97,7 +97,7 @@ export function get_remote_request_headers() {
97
97
  // even in forks because it's state-based - therefore not using window.location.
98
98
  // Use untrack(...) to Avoid accidental reactive dependency on pathname/search
99
99
  return untrack(() => {
100
- const url = navigating.current?.to?.url ?? page.url;
100
+ const url = navigating?.to?.url ?? page.url;
101
101
 
102
102
  return {
103
103
  'x-sveltekit-pathname': url.pathname,
@@ -1,4 +1,4 @@
1
- import { BROWSER, DEV } from 'esm-env';
1
+ import { DEV } from 'esm-env';
2
2
  import { onMount } from 'svelte';
3
3
  import * as storage from './session-storage.js';
4
4
  import { NAVIGATION_SNAPSHOT_KEY } from './constants.js';
@@ -105,8 +105,6 @@ function callsite_id(stack) {
105
105
  * @returns {void}
106
106
  */
107
107
  export function snapshot(options) {
108
- if (!BROWSER) return;
109
-
110
108
  let id = options.id;
111
109
  if (id === undefined) {
112
110
  // restore any lowered third-party limit, else every callsite collapses to one id
@@ -8,32 +8,39 @@
8
8
  */
9
9
  export async function* read_stream(reader, delimiter, options) {
10
10
  let done = false;
11
- let buffer = '';
11
+ /** @type {string[]} */
12
+ let parts = [];
13
+ let rest = '';
12
14
  const decoder = new TextDecoder(undefined, options);
15
+ const carry = delimiter.length - 1;
13
16
 
14
- while (true) {
15
- let split = buffer.indexOf(delimiter);
16
- while (split !== -1) {
17
- yield buffer.slice(0, split);
18
- buffer = buffer.slice(split + delimiter.length);
19
- split = buffer.indexOf(delimiter);
20
- }
17
+ while (!done) {
18
+ const chunk = await reader.read();
19
+ done = chunk.done;
20
+ let text = rest;
21
+ if (chunk.value) text += decoder.decode(chunk.value, { stream: true });
22
+ if (done) text += decoder.decode();
21
23
 
22
- if (done) {
23
- if (buffer) {
24
- yield buffer;
24
+ let start = 0;
25
+ let split = text.indexOf(delimiter);
26
+ while (split !== -1) {
27
+ if (parts.length > 0) {
28
+ parts.push(text.slice(start, split));
29
+ yield parts.join('');
30
+ parts = [];
31
+ } else {
32
+ yield text.slice(start, split);
25
33
  }
26
- return;
34
+ start = split + delimiter.length;
35
+ split = text.indexOf(delimiter, start);
27
36
  }
28
37
 
29
- const chunk = await reader.read();
30
- done = chunk.done;
31
- if (chunk.value) {
32
- buffer += decoder.decode(chunk.value, { stream: true });
33
- }
38
+ const keep = Math.max(start, text.length - carry);
39
+ if (keep > start) parts.push(text.slice(start, keep));
40
+ rest = text.slice(keep);
41
+ }
34
42
 
35
- if (done) {
36
- buffer += decoder.decode();
37
- }
43
+ if (parts.length > 0 || rest) {
44
+ yield parts.join('') + rest;
38
45
  }
39
46
  }
@@ -1,7 +1,7 @@
1
- import { BROWSER, DEV } from 'esm-env';
1
+ import { DEV } from 'esm-env';
2
2
  import { PRELOAD_PRIORITIES } from './constants.js';
3
3
 
4
- export const origin = BROWSER ? location.origin : '';
4
+ export const origin = location.origin;
5
5
 
6
6
  /** @param {string | URL} url */
7
7
  export function resolve_url(url) {
@@ -105,7 +105,11 @@ function parent_element(element) {
105
105
  */
106
106
  export function find_anchor(element, target) {
107
107
  while (element && element !== target) {
108
- if (element.nodeName.toUpperCase() === 'A' && element.hasAttribute('href')) {
108
+ // don't read `nodeName` a form control named `nodeName` shadows it on its form
109
+ if (
110
+ (element instanceof HTMLAnchorElement || element instanceof SVGAElement) &&
111
+ element.hasAttribute('href')
112
+ ) {
109
113
  return /** @type {HTMLAnchorElement | SVGAElement} */ (element);
110
114
  }
111
115
 
@@ -23,7 +23,11 @@
23
23
  {const Error = $derived(n.error)}
24
24
  {const data = $derived(n.data)}
25
25
 
26
- <svelte:boundary {onerror}>
26
+ {#snippet failed(error: unknown)}
27
+ <Error {error} />
28
+ {/snippet}
29
+
30
+ <svelte:boundary failed={Error ? failed : undefined} onerror={Error ? onerror : undefined}>
27
31
  {#if n.child}
28
32
  <!-- svelte-ignore binding_property_non_reactive -->
29
33
  <Component bind:this={components[depth]} {data} {form} params={page.params}>
@@ -33,10 +37,6 @@
33
37
  <!-- svelte-ignore binding_property_non_reactive -->
34
38
  <Component bind:this={components[depth]} {data} {form} params={page.params} {error} />
35
39
  {/if}
36
-
37
- {#snippet failed(error: unknown)}
38
- <Error {error} />
39
- {/snippet}
40
40
  </svelte:boundary>
41
41
  {/snippet}
42
42
 
@@ -1,5 +1,5 @@
1
1
  import { DEV } from 'esm-env';
2
- import * as env from '../../app/env/private.js';
2
+ import * as env from '../../app/env/private/index.js';
3
3
  export { env };
4
4
 
5
5
  if (DEV) {
@@ -1,5 +1,5 @@
1
1
  import { DEV } from 'esm-env';
2
- export * from '../../app/env/private.js';
2
+ export * from '../../app/env/private/index.js';
3
3
 
4
4
  if (DEV) {
5
5
  console.warn('`$env/static/private` is deprecated, use `$app/env/private` instead');
@@ -0,0 +1,54 @@
1
+ /** @import { Component } from 'svelte'; */
2
+
3
+ /**
4
+ * Resolves the `+error.svelte` component that guards each node of `branch`, aligned to the
5
+ * branch with its empty slots removed. A node is guarded by the closest error page declared
6
+ * at or above it, except the root layout, which wraps the root error component rather than
7
+ * being wrapped by it.
8
+ * @template T
9
+ * @param {Array<unknown>} branch
10
+ * @param {Array<T | undefined | null>} errors the error page declared at each depth, if any
11
+ * @param {(error: T) => Promise<Component | undefined> | undefined} load
12
+ * @returns {Promise<Array<Component | undefined>>}
13
+ */
14
+ export function build_error_chain(branch, errors, load) {
15
+ /** @type {Array<Promise<Component | undefined> | undefined>} */
16
+ const chain = [undefined];
17
+ let last_idx = -1;
18
+
19
+ for (let i = 1; i < branch.length; i += 1) {
20
+ if (!branch[i]) continue;
21
+
22
+ let j = i - 1;
23
+ while (j > last_idx + 1 && errors[j] == null) j -= 1;
24
+ last_idx = j;
25
+
26
+ const error = errors[j];
27
+ chain.push(error == null ? undefined : load(error)?.catch(() => undefined));
28
+ }
29
+
30
+ // depths with no error page contribute `undefined` rather than a promise
31
+ // eslint-disable-next-line @typescript-eslint/await-thenable
32
+ return Promise.all(chain);
33
+ }
34
+
35
+ /**
36
+ * Walks up from the node at index `i` through the `+error.svelte` pages declared strictly
37
+ * above it, nearest first. Yields each candidate with the branch depth it attaches at,
38
+ * rewound past empty branch slots, so callers can skip candidates that fail to load.
39
+ * @template T
40
+ * @param {number} i
41
+ * @param {Array<unknown>} branch
42
+ * @param {Array<T | undefined | null>} errors the error page declared at each depth, if any
43
+ * @returns {Generator<{ error: T; idx: number }>}
44
+ */
45
+ export function* nearest_error_pages(i, branch, errors) {
46
+ while (i--) {
47
+ const error = errors[i];
48
+ if (error != null) {
49
+ let j = i;
50
+ while (!branch[j]) j -= 1;
51
+ yield { error, idx: j + 1 };
52
+ }
53
+ }
54
+ }
@@ -198,7 +198,9 @@ export async function deserialize_binary_form(request, form_id) {
198
198
 
199
199
  let i = chunks.length;
200
200
  while (i <= index) {
201
- chunks[i] = reader.read().then((chunk) => chunk.value);
201
+ // chain reads so only one is ever pending — workerd forbids concurrent reads
202
+ const previous = chunks[i - 1] ?? Promise.resolve(undefined);
203
+ chunks[i] = previous.then(() => reader.read()).then((chunk) => chunk.value);
202
204
  i++;
203
205
  }
204
206
  return chunks[index];
@@ -210,47 +212,23 @@ export async function deserialize_binary_form(request, form_id) {
210
212
  * @returns {Promise<Uint8Array | null>}
211
213
  */
212
214
  async function get_buffer(offset, length) {
213
- /** @type {Uint8Array} */
214
- let start_chunk;
215
- let chunk_start = 0;
216
- /** @type {number} */
217
- let chunk_index;
218
- for (chunk_index = 0; ; chunk_index++) {
219
- const chunk = await get_chunk(chunk_index);
220
- if (!chunk) return null;
221
-
222
- const chunk_end = chunk_start + chunk.byteLength;
223
- // If this chunk contains the target offset
224
- if (offset >= chunk_start && offset < chunk_end) {
225
- start_chunk = chunk;
226
- break;
227
- }
228
- chunk_start = chunk_end;
229
- }
230
- // If the buffer is completely contained in one chunk, do a subarray
231
- if (offset + length <= chunk_start + start_chunk.byteLength) {
232
- return start_chunk.subarray(offset - chunk_start, offset + length - chunk_start);
233
- }
234
- // Otherwise, copy the data into a new buffer
235
- const chunks = [start_chunk.subarray(offset - chunk_start)];
236
- let cursor = start_chunk.byteLength - offset + chunk_start;
237
- while (cursor < length) {
238
- chunk_index++;
239
- let chunk = await get_chunk(chunk_index);
240
- if (!chunk) return null;
241
- if (chunk.byteLength > length - cursor) {
242
- chunk = chunk.subarray(0, length - cursor);
243
- }
244
- chunks.push(chunk);
245
- cursor += chunk.byteLength;
215
+ /** @type {Uint8Array<ArrayBuffer>[]} */
216
+ const parts = [];
217
+ let total = 0;
218
+ for await (const part of read_range(get_chunk, offset, length)) {
219
+ parts.push(part);
220
+ total += part.byteLength;
246
221
  }
222
+ if (total < length || parts.length === 0) return null;
223
+ // If the buffer is completely contained in one chunk, return the subarray as-is
224
+ if (parts.length === 1) return parts[0];
225
+
247
226
  const buffer = new Uint8Array(length);
248
- cursor = 0;
249
- for (const chunk of chunks) {
250
- buffer.set(chunk, cursor);
251
- cursor += chunk.byteLength;
227
+ let cursor = 0;
228
+ for (const part of parts) {
229
+ buffer.set(part, cursor);
230
+ cursor += part.byteLength;
252
231
  }
253
-
254
232
  return buffer;
255
233
  }
256
234
 
@@ -366,6 +344,32 @@ function deserialize_error(message) {
366
344
  return new SvelteKitError(400, 'Bad Request', `Could not deserialize binary form: ${message}`);
367
345
  }
368
346
 
347
+ /**
348
+ * Yields the chunks that make up the byte range `[offset, offset + length)`,
349
+ * trimmed to its boundaries. Ends early if the underlying data runs out.
350
+ * @param {(index: number) => Promise<Uint8Array<ArrayBuffer> | undefined>} get_chunk
351
+ * @param {number} offset
352
+ * @param {number} length
353
+ * @returns {AsyncGenerator<Uint8Array<ArrayBuffer>, void, void>}
354
+ */
355
+ async function* read_range(get_chunk, offset, length) {
356
+ let chunk_start = 0;
357
+ for (let index = 0; ; index++) {
358
+ const chunk = await get_chunk(index);
359
+ if (!chunk) return;
360
+
361
+ const chunk_end = chunk_start + chunk.byteLength;
362
+ if (chunk_end > offset) {
363
+ yield chunk.subarray(
364
+ Math.max(0, offset - chunk_start),
365
+ Math.min(chunk.byteLength, offset + length - chunk_start)
366
+ );
367
+ if (offset + length <= chunk_end) return;
368
+ }
369
+ chunk_start = chunk_end;
370
+ }
371
+ }
372
+
369
373
  /** @implements {File} */
370
374
  class LazyFile {
371
375
  /** @type {(index: number) => Promise<Uint8Array<ArrayBuffer> | undefined>} */
@@ -436,49 +440,21 @@ class LazyFile {
436
440
  return file;
437
441
  }
438
442
  stream() {
443
+ const range = read_range(this.#get_chunk, this.#offset, this.size);
439
444
  let cursor = 0;
440
- let chunk_index = 0;
441
445
  return new ReadableStream({
442
- start: async (controller) => {
443
- let chunk_start = 0;
444
- /** @type {Uint8Array} */
445
- let start_chunk;
446
- for (chunk_index = 0; ; chunk_index++) {
447
- const chunk = await this.#get_chunk(chunk_index);
448
- if (!chunk) return null;
449
-
450
- const chunk_end = chunk_start + chunk.byteLength;
451
- // If this chunk contains the target offset
452
- if (this.#offset >= chunk_start && this.#offset < chunk_end) {
453
- start_chunk = chunk;
454
- break;
455
- }
456
- chunk_start = chunk_end;
457
- }
458
- // If the buffer is completely contained in one chunk, do a subarray
459
- if (this.#offset + this.size <= chunk_start + start_chunk.byteLength) {
460
- controller.enqueue(
461
- start_chunk.subarray(this.#offset - chunk_start, this.#offset + this.size - chunk_start)
462
- );
463
- controller.close();
464
- } else {
465
- controller.enqueue(start_chunk.subarray(this.#offset - chunk_start));
466
- cursor = start_chunk.byteLength - this.#offset + chunk_start;
467
- }
468
- },
469
446
  pull: async (controller) => {
470
- chunk_index++;
471
- let chunk = await this.#get_chunk(chunk_index);
472
- if (!chunk) {
473
- controller.error('incomplete file data');
474
- controller.close();
447
+ const { value, done } = await range.next();
448
+ if (done) {
449
+ if (cursor < this.size) {
450
+ controller.error('incomplete file data');
451
+ } else {
452
+ controller.close();
453
+ }
475
454
  return;
476
455
  }
477
- if (chunk.byteLength > this.size - cursor) {
478
- chunk = chunk.subarray(0, this.size - cursor);
479
- }
480
- controller.enqueue(chunk);
481
- cursor += chunk.byteLength;
456
+ cursor += value.byteLength;
457
+ controller.enqueue(value);
482
458
  if (cursor >= this.size) {
483
459
  controller.close();
484
460
  }
@@ -0,0 +1 @@
1
+ throw new Error('invalid import');
@@ -63,7 +63,7 @@ export class RenderNode {
63
63
  /**
64
64
  *
65
65
  * @param {Component} component
66
- * @param {Component} error
66
+ * @param {Component | undefined} error
67
67
  */
68
68
  constructor(component, error) {
69
69
  this.component = component;
@@ -12,7 +12,7 @@ import { with_version_header } from '../utils.js';
12
12
  /**
13
13
  * @param {import('@sveltejs/kit').RequestEvent} event
14
14
  * @param {import('types').RequestState} state
15
- * @param {import('types').SSRRoute} route
15
+ * @param {{ page: Pick<import('types').PageNodeIndexes, 'layouts' | 'leaf'> | null }} route
16
16
  * @param {import('types').SSROptions} options
17
17
  * @param {import('@sveltejs/kit').SSRManifest} manifest
18
18
  * @param {boolean[] | undefined} invalidated_data_nodes
@@ -1,6 +1,6 @@
1
1
  import { Redirect } from '@sveltejs/kit/internal';
2
2
  import { with_request_store } from '@sveltejs/kit/internal/server';
3
- import { ENDPOINT_METHODS, PAGE_METHODS } from '../../constants.js';
3
+ import { BODY_DEPENDENT_METHODS, ENDPOINT_METHODS, PAGE_METHODS } from '../../constants.js';
4
4
  import { negotiate } from '../../utils/http.js';
5
5
  import { method_not_allowed } from './utils.js';
6
6
 
@@ -25,8 +25,13 @@ export async function render_endpoint(event, state, mod) {
25
25
 
26
26
  const prerender = mod.prerender ?? state.prerender_default;
27
27
 
28
- if (prerender && (mod.POST || mod.PATCH || mod.PUT || mod.DELETE)) {
29
- throw new Error('Cannot prerender endpoints that have mutative methods');
28
+ if (
29
+ prerender &&
30
+ /** @type {import('types').HttpMethod[]} */ (BODY_DEPENDENT_METHODS).some(
31
+ (method) => mod[method]
32
+ )
33
+ ) {
34
+ throw new Error('Cannot prerender endpoints with body-dependent methods');
30
35
  }
31
36
 
32
37
  if (state.prerendering && !state.prerendering.inside_reroute && !prerender) {
@@ -1,5 +1,5 @@
1
1
  import * as devalue from 'devalue';
2
- import { rendered_env } from '__sveltekit/env';
2
+ import { rendered_env } from '<sveltekit:generated>/env/config.js';
3
3
 
4
4
  /** @type {string} */
5
5
  let payload;
@@ -1,4 +1,4 @@
1
- import { json, text } from '@sveltejs/kit';
1
+ import { text } from '@sveltejs/kit';
2
2
  import {
3
3
  HandledHttpError,
4
4
  HttpError,
@@ -28,7 +28,7 @@ export async function handle_fatal_error(event, state, options, error) {
28
28
  ]);
29
29
 
30
30
  if (event.isDataRequest || type === 'application/json') {
31
- return json(body, {
31
+ return Response.json(body, {
32
32
  status
33
33
  });
34
34
  }
@@ -2,9 +2,9 @@ import { noop } from '../../utils/functions.js';
2
2
  import { IN_WEBCONTAINER } from '../../constants.js';
3
3
  import { respond } from './respond.js';
4
4
  import { create_request_state } from './state.js';
5
- import { options, get_hooks } from '__SERVER__/internal.js';
5
+ import { options, get_hooks } from '<sveltekit:generated>/server.js';
6
6
  import { set_read_implementation, set_manifest, fix_stack_trace } from './internal.js';
7
- import { set_env } from '__sveltekit/env';
7
+ import { set_env } from '<sveltekit:generated>/env/config.js';
8
8
  import { init_tracing } from '@sveltejs/kit/internal/server';
9
9
  import { DEV } from 'esm-env';
10
10
  import { init_transport } from '#app/internal/transport';