@sveltejs/kit 3.0.0-next.2 → 3.0.0-next.21

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 (195) hide show
  1. package/package.json +62 -36
  2. package/src/cli.js +15 -12
  3. package/src/constants.js +6 -1
  4. package/src/core/adapt/builder.js +66 -72
  5. package/src/core/adapt/index.js +17 -6
  6. package/src/core/config/index.js +134 -80
  7. package/src/core/config/options.js +295 -273
  8. package/src/core/config/types.d.ts +1 -1
  9. package/src/core/env.js +146 -16
  10. package/src/core/generate_manifest/index.js +18 -15
  11. package/src/core/postbuild/analyse.js +8 -20
  12. package/src/core/postbuild/crawl.js +22 -6
  13. package/src/core/postbuild/entities.js +8 -2
  14. package/src/core/postbuild/fallback.js +4 -2
  15. package/src/core/postbuild/prerender.js +222 -70
  16. package/src/core/postbuild/queue.js +2 -1
  17. package/src/core/sync/create_manifest_data/conflict.js +1 -1
  18. package/src/core/sync/create_manifest_data/index.js +82 -62
  19. package/src/core/sync/sync.js +40 -31
  20. package/src/core/sync/ts.js +1 -1
  21. package/src/core/sync/utils.js +22 -2
  22. package/src/core/sync/{write_non_ambient.js → write_app_types.js} +107 -58
  23. package/src/core/sync/write_client_manifest.js +14 -29
  24. package/src/core/sync/write_env.js +7 -5
  25. package/src/core/sync/write_server.js +37 -45
  26. package/src/core/sync/write_tsconfig/index.js +274 -0
  27. package/src/core/sync/write_tsconfig/test-app/package.json +7 -0
  28. package/src/core/sync/write_tsconfig/utils.js +77 -0
  29. package/src/core/sync/write_tsconfig/validate.js +128 -0
  30. package/src/core/sync/write_types/index.js +127 -123
  31. package/src/core/utils.js +30 -5
  32. package/src/exports/env/index.js +77 -0
  33. package/src/exports/env/public.d.ts +55 -0
  34. package/src/exports/hooks/index.js +3 -9
  35. package/src/exports/hooks/public.d.ts +195 -0
  36. package/src/exports/hooks/sequence.js +9 -6
  37. package/src/exports/index.js +52 -29
  38. package/src/exports/internal/client.js +5 -0
  39. package/src/exports/internal/env.js +8 -5
  40. package/src/exports/internal/index.js +1 -90
  41. package/src/exports/internal/{event.js → server/event.js} +2 -3
  42. package/src/exports/internal/server/index.js +37 -0
  43. package/src/exports/internal/server/telemetry.js +95 -0
  44. package/src/exports/internal/shared.js +90 -0
  45. package/src/exports/node/index.js +64 -22
  46. package/src/exports/params/index.js +70 -0
  47. package/src/exports/params/public.d.ts +63 -0
  48. package/src/exports/public.d.ts +50 -1733
  49. package/src/exports/remote/index.js +11 -0
  50. package/src/exports/remote/public.d.ts +519 -0
  51. package/src/exports/url.js +86 -0
  52. package/src/exports/vite/build/build_server.js +54 -65
  53. package/src/exports/vite/build/remote.js +24 -19
  54. package/src/exports/vite/build/utils.js +0 -8
  55. package/src/exports/vite/dev/index.js +218 -146
  56. package/src/exports/vite/index.js +1590 -858
  57. package/src/exports/vite/module_ids.js +2 -2
  58. package/src/exports/vite/preview/index.js +40 -32
  59. package/src/exports/vite/public.d.ts +588 -0
  60. package/src/exports/vite/utils.js +84 -46
  61. package/src/pathname.js +55 -0
  62. package/src/runner.js +15 -0
  63. package/src/runtime/app/env/internal.js +4 -4
  64. package/src/runtime/app/env/types.d.ts +1 -1
  65. package/src/runtime/app/environment/index.js +3 -3
  66. package/src/runtime/app/{forms.js → forms/index.js} +73 -42
  67. package/src/runtime/app/forms/public.d.ts +2 -0
  68. package/src/runtime/app/forms/types.d.ts +56 -0
  69. package/src/runtime/app/internal/transport.js +53 -0
  70. package/src/runtime/app/manifest/index.js +1 -0
  71. package/src/runtime/app/{navigation.js → navigation/index.js} +2 -1
  72. package/src/runtime/app/navigation/public.d.ts +237 -0
  73. package/src/runtime/app/paths/client.js +37 -37
  74. package/src/runtime/app/paths/index.js +1 -1
  75. package/src/runtime/app/paths/internal/client.js +34 -2
  76. package/src/runtime/app/paths/internal/server.js +6 -23
  77. package/src/runtime/app/paths/internal.d.ts +3 -0
  78. package/src/runtime/app/paths/public.d.ts +1 -29
  79. package/src/runtime/app/paths/server.js +36 -17
  80. package/src/runtime/app/paths/types.d.ts +11 -19
  81. package/src/runtime/app/server/index.js +2 -2
  82. package/src/runtime/app/server/public.d.ts +201 -0
  83. package/src/runtime/app/server/remote/command.js +13 -11
  84. package/src/runtime/app/server/remote/form.js +61 -39
  85. package/src/runtime/app/server/remote/prerender.js +45 -45
  86. package/src/runtime/app/server/remote/query.js +106 -108
  87. package/src/runtime/app/server/remote/requested.js +27 -19
  88. package/src/runtime/app/server/remote/shared.js +76 -76
  89. package/src/runtime/app/service-worker/index.js +24 -0
  90. package/src/runtime/app/state/client.js +4 -2
  91. package/src/runtime/app/state/index.js +7 -5
  92. package/src/runtime/app/state/public.d.ts +72 -0
  93. package/src/runtime/app/state/server.js +3 -0
  94. package/src/runtime/app/stores.js +15 -78
  95. package/src/runtime/client/bundle.js +1 -1
  96. package/src/runtime/client/client-entry.js +3 -0
  97. package/src/runtime/client/client.js +1336 -648
  98. package/src/runtime/client/constants.js +3 -6
  99. package/src/runtime/client/entry.js +24 -3
  100. package/src/runtime/client/fetcher.js +25 -25
  101. package/src/runtime/client/ndjson.js +1 -1
  102. package/src/runtime/client/parse.js +1 -1
  103. package/src/runtime/client/payload.js +17 -0
  104. package/src/runtime/client/remote-functions/cache.svelte.js +3 -1
  105. package/src/runtime/client/remote-functions/command.svelte.js +37 -61
  106. package/src/runtime/client/remote-functions/form.svelte.js +267 -178
  107. package/src/runtime/client/remote-functions/prerender.svelte.js +32 -11
  108. package/src/runtime/client/remote-functions/query/index.js +10 -17
  109. package/src/runtime/client/remote-functions/query/instance.svelte.js +64 -18
  110. package/src/runtime/client/remote-functions/query/proxy.js +5 -5
  111. package/src/runtime/client/remote-functions/query-batch.svelte.js +61 -70
  112. package/src/runtime/client/remote-functions/query-live/index.js +1 -1
  113. package/src/runtime/client/remote-functions/query-live/instance.svelte.js +63 -21
  114. package/src/runtime/client/remote-functions/query-live/iterator.js +15 -12
  115. package/src/runtime/client/remote-functions/query-live/proxy.js +2 -12
  116. package/src/runtime/client/remote-functions/shared.svelte.js +90 -65
  117. package/src/runtime/client/snapshots.js +147 -0
  118. package/src/runtime/client/state.svelte.js +94 -55
  119. package/src/runtime/client/stream.js +3 -2
  120. package/src/runtime/client/types.d.ts +13 -9
  121. package/src/runtime/client/utils.js +22 -110
  122. package/src/runtime/components/root.svelte +56 -0
  123. package/src/runtime/env/dynamic/private.js +7 -0
  124. package/src/runtime/env/dynamic/public.js +7 -0
  125. package/src/runtime/env/static/private.js +6 -0
  126. package/src/runtime/env/static/public.js +6 -0
  127. package/src/runtime/form-utils.js +172 -61
  128. package/src/runtime/pathname.js +20 -32
  129. package/src/runtime/props.svelte.js +72 -0
  130. package/src/runtime/server/constants.js +0 -3
  131. package/src/runtime/server/cookie.js +72 -55
  132. package/src/runtime/server/csrf.js +65 -0
  133. package/src/runtime/server/data/index.js +49 -53
  134. package/src/runtime/server/dev.js +22 -0
  135. package/src/runtime/server/endpoint.js +6 -7
  136. package/src/runtime/server/env_module.js +0 -5
  137. package/src/runtime/server/errors.js +160 -0
  138. package/src/runtime/server/fetch.js +32 -39
  139. package/src/runtime/server/index.js +90 -64
  140. package/src/runtime/server/internal.js +71 -0
  141. package/src/runtime/server/page/actions.js +85 -64
  142. package/src/runtime/server/page/crypto.js +2 -2
  143. package/src/runtime/server/page/csp.js +88 -104
  144. package/src/runtime/server/page/data_serializer.js +24 -25
  145. package/src/runtime/server/page/index.js +36 -53
  146. package/src/runtime/server/page/load_data.js +50 -57
  147. package/src/runtime/server/page/render.js +173 -239
  148. package/src/runtime/server/page/respond_with_error.js +17 -31
  149. package/src/runtime/server/page/serialize_data.js +2 -13
  150. package/src/runtime/server/page/server_routing.js +85 -26
  151. package/src/runtime/server/remote-functions.js +640 -0
  152. package/src/runtime/server/respond.js +190 -131
  153. package/src/runtime/server/sourcemaps.js +183 -0
  154. package/src/runtime/server/state.js +53 -0
  155. package/src/runtime/server/utils.js +13 -155
  156. package/src/runtime/shared.js +20 -40
  157. package/src/runtime/utils.js +3 -0
  158. package/src/types/ambient-private.d.ts +11 -1
  159. package/src/types/ambient.d.ts +87 -36
  160. package/src/types/global-private.d.ts +25 -25
  161. package/src/types/internal.d.ts +163 -157
  162. package/src/types/private.d.ts +41 -1
  163. package/src/utils/error.js +28 -4
  164. package/src/utils/escape.js +9 -25
  165. package/src/utils/features.js +1 -1
  166. package/src/utils/filesystem.js +1 -23
  167. package/src/utils/fork.js +7 -2
  168. package/src/utils/hash.js +21 -0
  169. package/src/utils/http.js +8 -7
  170. package/src/utils/import.js +9 -2
  171. package/src/utils/imports.js +83 -0
  172. package/src/utils/mime.js +9 -0
  173. package/src/utils/page_nodes.js +6 -7
  174. package/src/utils/params.js +67 -0
  175. package/src/utils/regex.js +9 -0
  176. package/src/utils/routing.js +145 -73
  177. package/src/utils/shared-iterator.js +5 -0
  178. package/src/utils/streaming.js +14 -4
  179. package/src/utils/url.js +33 -2
  180. package/src/version.js +1 -1
  181. package/types/index.d.ts +2616 -2433
  182. package/types/index.d.ts.map +120 -106
  183. package/src/core/sync/write_ambient.js +0 -18
  184. package/src/core/sync/write_root.js +0 -148
  185. package/src/core/sync/write_tsconfig.js +0 -250
  186. package/src/exports/internal/server.js +0 -22
  187. package/src/exports/node/polyfills.js +0 -30
  188. package/src/runtime/server/app.js +0 -9
  189. package/src/runtime/server/remote.js +0 -457
  190. package/src/runtime/shared-server.js +0 -7
  191. package/src/runtime/telemetry/otel.js +0 -21
  192. package/src/runtime/telemetry/record_span.js +0 -65
  193. package/src/types/synthetic/$lib.md +0 -5
  194. /package/src/exports/internal/{remote-functions.js → server/remote-functions.js} +0 -0
  195. /package/src/{runtime/telemetry/noop.js → telemetry.js} +0 -0
@@ -0,0 +1,160 @@
1
+ import { json, text } from '@sveltejs/kit';
2
+ import {
3
+ HandledHttpError,
4
+ HttpError,
5
+ SvelteKitError,
6
+ ValidationError
7
+ } from '@sveltejs/kit/internal';
8
+ import { with_request_store } from '@sveltejs/kit/internal/server';
9
+ import { add_deprecated_handle_error_properties, coalesce_to_error } from '../../utils/error.js';
10
+ import { negotiate } from '../../utils/http.js';
11
+ import { fix_stack_trace } from './internal.js';
12
+ import { escape_html } from '../../utils/escape.js';
13
+
14
+ /**
15
+ * @param {import('$app/server').RequestEvent} event
16
+ * @param {import('types').RequestState} state
17
+ * @param {import('types').SSROptions} options
18
+ * @param {unknown} error
19
+ */
20
+ export async function handle_fatal_error(event, state, options, error) {
21
+ const body = await handle_error_and_jsonify(event, state, options, error);
22
+ const status = body.status;
23
+
24
+ // sec-fetch-dest would be nicer, but non-browser clients and plain HTTP hosts don't send it
25
+ const type = negotiate(event.request.headers.get('accept') || 'text/html', [
26
+ 'application/json',
27
+ 'text/html'
28
+ ]);
29
+
30
+ if (event.isDataRequest || type === 'application/json') {
31
+ return json(body, {
32
+ status
33
+ });
34
+ }
35
+
36
+ return static_error_page(options, status, body.message);
37
+ }
38
+
39
+ /**
40
+ * @param {import('$app/server').RequestEvent} event
41
+ * @param {import('types').RequestState} state
42
+ * @param {import('types').SSROptions} options
43
+ * @param {any} error
44
+ * @returns {App.Error | Promise<App.Error>}
45
+ */
46
+ export function handle_error_and_jsonify(event, state, options, error) {
47
+ if (error instanceof HandledHttpError) {
48
+ return error.body;
49
+ }
50
+
51
+ /** @type {import('@sveltejs/kit/hooks').CaughtError} */
52
+ let caught;
53
+
54
+ if (error instanceof HttpError) {
55
+ caught = { kind: 'app', error: error.body };
56
+ } else if (error instanceof SvelteKitError) {
57
+ caught = { kind: 'framework', error: { status: error.status, message: error.text } };
58
+ } else if (error instanceof ValidationError) {
59
+ caught = {
60
+ kind: 'validation',
61
+ error: { status: 400, message: 'Bad Request' },
62
+ issues: error.issues
63
+ };
64
+ } else {
65
+ caught = { kind: 'unknown', error };
66
+
67
+ let e = error;
68
+ while (e instanceof Error) {
69
+ fix_stack_trace(e);
70
+ e = e.cause;
71
+ }
72
+ }
73
+
74
+ const fallback =
75
+ caught.kind === 'unknown' ? { status: 500, message: 'Internal Error' } : caught.error;
76
+
77
+ /**
78
+ * The hook returns only the properties it wants to override; anything it omits
79
+ * (including by returning nothing at all) is inherited from the caught error.
80
+ * @param {Awaited<ReturnType<import('@sveltejs/kit/hooks').HandleServerError>>} body
81
+ * @returns {App.Error}
82
+ */
83
+ function merge(body) {
84
+ return { ...fallback, ...body };
85
+ }
86
+
87
+ // TODO 4.0 await this, rather than handling the non-Promise case
88
+ let result;
89
+ try {
90
+ const input = { ...caught, event };
91
+ if (__SVELTEKIT_DEV__) add_deprecated_handle_error_properties(input, fallback);
92
+
93
+ result = with_request_store({ event, state }, () => options.hooks.handleError(input));
94
+ } catch (hook_error) {
95
+ log_handle_error_hook_failure(error, hook_error);
96
+ return { status: fallback.status, message: 'Internal Error' };
97
+ }
98
+
99
+ if (result instanceof Promise) {
100
+ if (!__SVELTEKIT_SUPPORTS_ASYNC__ && state.is_in_render) {
101
+ console.warn(
102
+ `To use an async \`handleError\` hook to handle errors that occur during rendering, you must enable \`compilerOptions.experimental.async\` in the SvelteKit plugin of your Vite config. The returned error has been replaced with a generic object`
103
+ );
104
+
105
+ // we're discarding the result, but we still need to prevent an unhandled
106
+ // rejection if the user's async `handleError` hook rejects
107
+ result.catch((hook_error) => log_handle_error_hook_failure(error, hook_error));
108
+
109
+ return {
110
+ status: fallback.status,
111
+ message: 'Internal Error'
112
+ };
113
+ }
114
+
115
+ return result.then(merge, (hook_error) => {
116
+ log_handle_error_hook_failure(error, hook_error);
117
+ return { status: fallback.status, message: 'Internal Error' };
118
+ });
119
+ }
120
+
121
+ return merge(result);
122
+ }
123
+
124
+ /**
125
+ * @param {unknown} error
126
+ * @param {unknown} hook_error
127
+ */
128
+ function log_handle_error_hook_failure(error, hook_error) {
129
+ const failure = new Error('The `handleError` hook failed', {
130
+ cause: coalesce_to_error(hook_error)
131
+ });
132
+ failure.stack = failure.message;
133
+ console.error(failure);
134
+ if (error instanceof SvelteKitError) {
135
+ console.error(`Original error: ${error.status} ${error.text}: ${error.message}`);
136
+ } else {
137
+ console.error('Original error:', error);
138
+ }
139
+ }
140
+
141
+ /**
142
+ * Return as a response that renders the error.html
143
+ *
144
+ * @param {import('types').SSROptions} options
145
+ * @param {number} status
146
+ * @param {string} message
147
+ */
148
+ export function static_error_page(options, status, message) {
149
+ let page = options.templates.error({ status, message: escape_html(message) });
150
+
151
+ if (__SVELTEKIT_DEV__) {
152
+ // inject Vite HMR client, for easier debugging
153
+ page = page.replace('</head>', '<script type="module" src="/@vite/client"></script></head>');
154
+ }
155
+
156
+ return text(page, {
157
+ headers: { 'content-type': 'text/html; charset=utf-8' },
158
+ status
159
+ });
160
+ }
@@ -1,16 +1,17 @@
1
1
  import { parseSetCookie } from 'cookie';
2
2
  import { noop } from '../../utils/functions.js';
3
3
  import { respond } from './respond.js';
4
- import * as paths from '$app/paths/internal/server';
5
- import { read_implementation } from '__sveltekit/server';
4
+ import * as paths from '#app/paths';
5
+ import { read_implementation } from './internal.js';
6
6
  import { has_prerendered_path } from './utils.js';
7
+ import { fork_state_for_subrequest } from './state.js';
7
8
 
8
9
  /**
9
10
  * @param {{
10
- * event: import('@sveltejs/kit').RequestEvent;
11
+ * event: import('$app/server').RequestEvent;
11
12
  * options: import('types').SSROptions;
12
13
  * manifest: import('@sveltejs/kit').SSRManifest;
13
- * state: import('types').SSRState;
14
+ * state: import('types').RequestState;
14
15
  * get_cookie_header: (url: URL, header: string | null) => string;
15
16
  * set_internal: (name: string, value: string, opts: import('./page/types.js').Cookie['options']) => void;
16
17
  * }} opts
@@ -117,7 +118,7 @@ export function create_fetch({ event, options, manifest, state, get_cookie_heade
117
118
  return await fetch(request);
118
119
  }
119
120
 
120
- if (has_prerendered_path(manifest, paths.base + decoded)) {
121
+ if (has_prerendered_path(manifest, decoded)) {
121
122
  // The path of something prerendered could match a different route
122
123
  // that is still in the manifest, leading to the wrong route being loaded.
123
124
  // We therefore bail early here. The prerendered logic is different for
@@ -142,11 +143,9 @@ export function create_fetch({ event, options, manifest, state, get_cookie_heade
142
143
  request.headers.set('accept', '*/*');
143
144
  }
144
145
 
145
- if (!request.headers.has('accept-language')) {
146
- request.headers.set(
147
- 'accept-language',
148
- /** @type {string} */ (event.request.headers.get('accept-language'))
149
- );
146
+ const accept_language = event.request.headers.get('accept-language');
147
+ if (accept_language && !request.headers.has('accept-language')) {
148
+ request.headers.set('accept-language', accept_language);
150
149
  }
151
150
 
152
151
  const response = await internal_fetch(request, options, manifest, state);
@@ -196,38 +195,32 @@ function normalize_fetch_input(info, init, url) {
196
195
  * @param {Request} request
197
196
  * @param {import('types').SSROptions} options
198
197
  * @param {import('@sveltejs/kit').SSRManifest} manifest
199
- * @param {import('types').SSRState} state
198
+ * @param {import('types').RequestState} state
200
199
  * @returns {Promise<Response>}
201
200
  */
202
201
  async function internal_fetch(request, options, manifest, state) {
203
- if (request.signal) {
204
- if (request.signal.aborted) {
205
- throw new DOMException('The operation was aborted.', 'AbortError');
206
- }
207
-
208
- let remove_abort_listener = noop;
209
- /** @type {Promise<never>} */
210
- const abort_promise = new Promise((_, reject) => {
211
- const on_abort = () => {
212
- reject(new DOMException('The operation was aborted.', 'AbortError'));
213
- };
214
- request.signal.addEventListener('abort', on_abort, { once: true });
215
- remove_abort_listener = () => request.signal.removeEventListener('abort', on_abort);
216
- });
202
+ if (request.signal?.aborted) {
203
+ throw new DOMException('The operation was aborted.', 'AbortError');
204
+ }
217
205
 
218
- const result = await Promise.race([
219
- respond(request, options, manifest, {
220
- ...state,
221
- depth: state.depth + 1
222
- }),
223
- abort_promise
224
- ]);
225
- remove_abort_listener();
226
- return result;
227
- } else {
228
- return await respond(request, options, manifest, {
229
- ...state,
230
- depth: state.depth + 1
231
- });
206
+ const subrequest_state = fork_state_for_subrequest(state);
207
+
208
+ if (!request.signal) {
209
+ return await respond(request, options, manifest, subrequest_state);
232
210
  }
211
+
212
+ let remove_abort_listener = noop;
213
+ /** @type {Promise<never>} */
214
+ const abort_promise = new Promise((_, reject) => {
215
+ const on_abort = () => {
216
+ reject(new DOMException('The operation was aborted.', 'AbortError'));
217
+ };
218
+ request.signal.addEventListener('abort', on_abort, { once: true });
219
+ remove_abort_listener = () => request.signal.removeEventListener('abort', on_abort);
220
+ });
221
+
222
+ return Promise.race([
223
+ respond(request, options, manifest, subrequest_state),
224
+ abort_promise
225
+ ]).finally(remove_abort_listener);
233
226
  }
@@ -1,11 +1,13 @@
1
1
  import { noop } from '../../utils/functions.js';
2
- import { IN_WEBCONTAINER } from './constants.js';
2
+ import { IN_WEBCONTAINER } from '../../constants.js';
3
3
  import { respond } from './respond.js';
4
+ import { create_request_state } from './state.js';
4
5
  import { options, get_hooks } from '__SERVER__/internal.js';
5
- import { format_server_error } from './utils.js';
6
- import { set_read_implementation, set_manifest } from '__sveltekit/server';
6
+ import { set_read_implementation, set_manifest, fix_stack_trace } from './internal.js';
7
7
  import { set_env } from '__sveltekit/env';
8
- import { set_app } from './app.js';
8
+ import { init_tracing } from '@sveltejs/kit/internal/server';
9
+ import { DEV } from 'esm-env';
10
+ import { init_transport } from '#app/internal/transport';
9
11
 
10
12
  /** @type {Promise<any>} */
11
13
  let init_promise;
@@ -13,6 +15,38 @@ let init_promise;
13
15
  /** @type {Promise<void> | null} */
14
16
  let current = null;
15
17
 
18
+ /**
19
+ * Responses that were created with our monkey-patched `fetch`, which may need
20
+ * to have their `content-encoding` and `content-length` headers removed
21
+ * if returned directly (i.e. `fetch` is being used to proxy a request)
22
+ * @type {WeakMap<Response, Error>}
23
+ */
24
+ const decoded_responses = new WeakMap();
25
+
26
+ if (DEV) {
27
+ const fetch = globalThis.fetch;
28
+
29
+ /**
30
+ * @param {RequestInfo | URL} info
31
+ * @param {RequestInit} [init]
32
+ */
33
+ globalThis.fetch = async (info, init) => {
34
+ const response = await fetch(info, init);
35
+ const encoding = response.headers.get('content-encoding');
36
+
37
+ if (encoding) {
38
+ decoded_responses.set(
39
+ response,
40
+ new Error(
41
+ `Cannot return \`fetch(...)\` directly from a handler if the response has a \`Content-Encoding: ${encoding}\` header. The body has already been decoded`
42
+ )
43
+ );
44
+ }
45
+
46
+ return response;
47
+ };
48
+ }
49
+
16
50
  export class Server {
17
51
  /** @type {import('types').SSROptions} */
18
52
  #options;
@@ -27,7 +61,7 @@ export class Server {
27
61
  this.#manifest = manifest;
28
62
 
29
63
  // Since AsyncLocalStorage is not working in webcontainers, we don't reset `sync_store`
30
- // in `src/exports/internal/event.js` and handle only one request at a time.
64
+ // in `src/exports/internal/server/event.js` and handle only one request at a time.
31
65
  if (IN_WEBCONTAINER) {
32
66
  const respond = this.respond.bind(this);
33
67
 
@@ -56,6 +90,8 @@ export class Server {
56
90
  // so anything that shouldn't be rerun should be wrapped in an `if` block to make sure it hasn't
57
91
  // been done already.
58
92
 
93
+ if (__SVELTEKIT_SERVER_TRACING_ENABLED__) init_tracing(import('@opentelemetry/api'));
94
+
59
95
  // set env, in case it's used in initialisation
60
96
  set_env(env);
61
97
 
@@ -67,31 +103,17 @@ export class Server {
67
103
  const result = read(file);
68
104
  if (result instanceof ReadableStream) {
69
105
  return result;
70
- } else {
71
- return new ReadableStream({
72
- async start(controller) {
73
- try {
74
- const stream = await Promise.resolve(result);
75
- if (!stream) {
76
- controller.close();
77
- return;
78
- }
79
-
80
- const reader = stream.getReader();
81
-
82
- while (true) {
83
- const { done, value } = await reader.read();
84
- if (done) break;
85
- controller.enqueue(value);
86
- }
87
-
88
- controller.close();
89
- } catch (error) {
90
- controller.error(error);
91
- }
92
- }
93
- });
94
106
  }
107
+
108
+ // TODO remove the cast once TypeScript's lib includes `ReadableStream.from`
109
+ return /** @type {ReadableStream} */ (
110
+ /** @type {any} */ (ReadableStream).from(
111
+ (async function* () {
112
+ const stream = await result;
113
+ if (stream) yield* stream;
114
+ })()
115
+ )
116
+ );
95
117
  };
96
118
 
97
119
  set_read_implementation(wrapped_read);
@@ -107,30 +129,34 @@ export class Server {
107
129
  handle: module.handle || (({ event, resolve }) => resolve(event)),
108
130
  handleError:
109
131
  module.handleError ||
110
- (({ status, error, event }) => {
111
- const error_message = format_server_error(
112
- status,
113
- /** @type {Error} */ (error),
114
- event
115
- );
116
- console.error(error_message);
132
+ (({ kind, error, issues }) => {
133
+ if (kind === 'validation') {
134
+ console.error('Remote function schema validation failed:', issues);
135
+ return;
136
+ }
137
+
138
+ if (kind !== 'unknown') {
139
+ // don't log stack traces for 404s etc, it's all internal gubbins
140
+ return;
141
+ }
142
+
143
+ let e = error;
144
+ while (e instanceof Error) {
145
+ if (e.stack) {
146
+ console.error(e.stack);
147
+ }
148
+ e = e.cause;
149
+ }
150
+
151
+ if (e) {
152
+ console.error(String(e));
153
+ }
117
154
  }),
118
155
  handleFetch: module.handleFetch || (({ request, fetch }) => fetch(request)),
119
- handleValidationError:
120
- module.handleValidationError ||
121
- (({ issues }) => {
122
- console.error('Remote function schema validation failed:', issues);
123
- return { message: 'Bad Request' };
124
- }),
125
- reroute: module.reroute || noop,
126
- transport: module.transport || {}
156
+ reroute: module.reroute || noop
127
157
  };
128
158
 
129
- set_app({
130
- decoders: module.transport
131
- ? Object.fromEntries(Object.entries(module.transport).map(([k, v]) => [k, v.decode]))
132
- : {}
133
- });
159
+ init_transport(module.transport ?? {});
134
160
 
135
161
  if (module.init) {
136
162
  await module.init();
@@ -143,16 +169,8 @@ export class Server {
143
169
  },
144
170
  handleError: ({ error }) => console.error(error),
145
171
  handleFetch: ({ request, fetch }) => fetch(request),
146
- handleValidationError: () => {
147
- return { message: 'Bad Request' };
148
- },
149
- reroute: noop,
150
- transport: {}
172
+ reroute: noop
151
173
  };
152
-
153
- set_app({
154
- decoders: {}
155
- });
156
174
  } else {
157
175
  throw e;
158
176
  }
@@ -162,13 +180,21 @@ export class Server {
162
180
 
163
181
  /**
164
182
  * @param {Request} request
165
- * @param {import('types').RequestOptions} options
183
+ * @param {import('types').InternalRequestOptions} options
166
184
  */
167
185
  async respond(request, options) {
168
- return respond(request, this.#options, this.#manifest, {
169
- ...options,
170
- error: false,
171
- depth: 0
172
- });
186
+ const response = await respond(
187
+ request,
188
+ this.#options,
189
+ this.#manifest,
190
+ create_request_state(options)
191
+ );
192
+
193
+ if (DEV) {
194
+ const error = decoded_responses.get(response);
195
+ if (error) console.error(fix_stack_trace(error));
196
+ }
197
+
198
+ return response;
173
199
  }
174
200
  }
@@ -0,0 +1,71 @@
1
+ /** @import { SSRManifest } from '@sveltejs/kit'; */
2
+ import { restore, save } from './dev.js';
3
+ import {
4
+ has_data_suffix,
5
+ has_resolution_suffix,
6
+ strip_data_suffix,
7
+ strip_resolution_suffix
8
+ } from '../../pathname.js';
9
+ import { has_remote_prefix, strip_remote_prefix } from '../../runtime/server/remote-functions.js';
10
+
11
+ // using `getBuiltinModule` rather than `import` makes this safe to run in non-Node-compatible environments
12
+ const styleText =
13
+ // eslint-disable-next-line n/prefer-global/process
14
+ globalThis.process?.getBuiltinModule?.('node:util')?.styleText ??
15
+ /** @type {(format: unknown, text: string) => string} */ ((_format, text) => text);
16
+
17
+ const read_implementation_key = Symbol.for('sveltekit.read_implementation');
18
+ const manifest_key = Symbol.for('sveltekit.manifest');
19
+
20
+ export let read_implementation = /** @type {((path: string) => ReadableStream<any>) | null} */ (
21
+ (__SVELTEKIT_DEV__ && restore(read_implementation_key)) ?? null
22
+ );
23
+
24
+ export let manifest = /** @type {SSRManifest} */ (
25
+ (__SVELTEKIT_DEV__ && restore(manifest_key)) ?? null
26
+ );
27
+
28
+ /**
29
+ * @param {(path: string) => ReadableStream<any>} fn
30
+ */
31
+ export function set_read_implementation(fn) {
32
+ read_implementation = fn;
33
+ if (__SVELTEKIT_DEV__) save(read_implementation_key, fn);
34
+ }
35
+
36
+ /**
37
+ *
38
+ * @param {SSRManifest} value
39
+ */
40
+ export function set_manifest(value) {
41
+ manifest = value;
42
+ if (__SVELTEKIT_DEV__) save(manifest_key, value);
43
+ }
44
+
45
+ /**
46
+ * @param {number} status
47
+ * @param {Request} request
48
+ */
49
+ export function log_response(status, request) {
50
+ const url = new URL(request.url);
51
+ const requested = url.href.replace(url.origin, '');
52
+
53
+ let log = `${styleText(status < 400 ? ['cyan'] : ['bold', 'red'], `${status}`)} ${request.method} `;
54
+
55
+ if (has_data_suffix(url.pathname)) {
56
+ const pathname = strip_data_suffix(url.pathname) || '/';
57
+ log += pathname + styleText('dim', requested.slice(pathname.length));
58
+ } else if (has_resolution_suffix(url.pathname)) {
59
+ const pathname = strip_resolution_suffix(url.pathname) || '/';
60
+ log += pathname + styleText('dim', requested.slice(pathname.length));
61
+ } else if (has_remote_prefix(url)) {
62
+ const id = /** @type {string} */ (strip_remote_prefix(url).split('/').pop());
63
+ log += styleText('dim', url.pathname.slice(0, -id.length)) + id + styleText('dim', url.search);
64
+ } else {
65
+ log += requested;
66
+ }
67
+
68
+ console.log(log);
69
+ }
70
+
71
+ export { fix_stack_trace, set_fix_stack_trace } from './sourcemaps.js';