@sveltejs/kit 1.0.0-next.41 → 1.0.0-next.412

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 (129) hide show
  1. package/README.md +12 -9
  2. package/package.json +97 -63
  3. package/src/cli.js +119 -0
  4. package/src/core/adapt/builder.js +207 -0
  5. package/src/core/adapt/index.js +19 -0
  6. package/src/core/config/index.js +86 -0
  7. package/src/core/config/options.js +488 -0
  8. package/src/core/config/types.d.ts +1 -0
  9. package/src/core/constants.js +3 -0
  10. package/src/core/generate_manifest/index.js +99 -0
  11. package/src/core/prerender/crawl.js +194 -0
  12. package/src/core/prerender/prerender.js +378 -0
  13. package/src/core/prerender/queue.js +80 -0
  14. package/src/core/sync/create_manifest_data/index.js +496 -0
  15. package/src/core/sync/create_manifest_data/types.d.ts +40 -0
  16. package/src/core/sync/sync.js +59 -0
  17. package/src/core/sync/utils.js +97 -0
  18. package/src/core/sync/write_ambient.js +87 -0
  19. package/src/core/sync/write_client_manifest.js +82 -0
  20. package/src/core/sync/write_matchers.js +25 -0
  21. package/src/core/sync/write_root.js +88 -0
  22. package/src/core/sync/write_tsconfig.js +189 -0
  23. package/src/core/sync/write_types.js +727 -0
  24. package/src/core/utils.js +58 -0
  25. package/src/hooks.js +26 -0
  26. package/src/index/index.js +45 -0
  27. package/src/index/private.js +33 -0
  28. package/src/node/index.js +145 -0
  29. package/src/node/polyfills.js +40 -0
  30. package/src/packaging/index.js +218 -0
  31. package/src/packaging/types.d.ts +8 -0
  32. package/src/packaging/typescript.js +150 -0
  33. package/src/packaging/utils.js +143 -0
  34. package/src/runtime/app/env.js +11 -0
  35. package/src/runtime/app/navigation.js +22 -0
  36. package/src/runtime/app/paths.js +1 -0
  37. package/src/runtime/app/stores.js +94 -0
  38. package/src/runtime/client/ambient.d.ts +17 -0
  39. package/src/runtime/client/client.js +1281 -0
  40. package/src/runtime/client/fetcher.js +60 -0
  41. package/src/runtime/client/parse.js +36 -0
  42. package/src/runtime/client/singletons.js +11 -0
  43. package/src/runtime/client/start.js +48 -0
  44. package/src/runtime/client/types.d.ts +106 -0
  45. package/src/runtime/client/utils.js +113 -0
  46. package/src/runtime/components/error.svelte +16 -0
  47. package/{assets → src/runtime}/components/layout.svelte +0 -0
  48. package/src/runtime/env/dynamic/private.js +1 -0
  49. package/src/runtime/env/dynamic/public.js +1 -0
  50. package/src/runtime/env-private.js +7 -0
  51. package/src/runtime/env-public.js +7 -0
  52. package/src/runtime/env.js +6 -0
  53. package/src/runtime/hash.js +16 -0
  54. package/src/runtime/paths.js +11 -0
  55. package/src/runtime/server/endpoint.js +42 -0
  56. package/src/runtime/server/index.js +434 -0
  57. package/src/runtime/server/page/cookie.js +25 -0
  58. package/src/runtime/server/page/crypto.js +239 -0
  59. package/src/runtime/server/page/csp.js +249 -0
  60. package/src/runtime/server/page/fetch.js +266 -0
  61. package/src/runtime/server/page/index.js +418 -0
  62. package/src/runtime/server/page/load_data.js +94 -0
  63. package/src/runtime/server/page/render.js +363 -0
  64. package/src/runtime/server/page/respond_with_error.js +105 -0
  65. package/src/runtime/server/page/types.d.ts +44 -0
  66. package/src/runtime/server/utils.js +116 -0
  67. package/src/utils/error.js +22 -0
  68. package/src/utils/escape.js +104 -0
  69. package/src/utils/filesystem.js +108 -0
  70. package/src/utils/http.js +55 -0
  71. package/src/utils/misc.js +1 -0
  72. package/src/utils/routing.js +107 -0
  73. package/src/utils/url.js +97 -0
  74. package/src/vite/build/build_server.js +339 -0
  75. package/src/vite/build/build_service_worker.js +90 -0
  76. package/src/vite/build/utils.js +153 -0
  77. package/src/vite/dev/index.js +569 -0
  78. package/src/vite/index.js +540 -0
  79. package/src/vite/preview/index.js +186 -0
  80. package/src/vite/types.d.ts +3 -0
  81. package/src/vite/utils.js +335 -0
  82. package/svelte-kit.js +1 -1
  83. package/types/ambient.d.ts +368 -0
  84. package/types/index.d.ts +345 -0
  85. package/types/internal.d.ts +309 -0
  86. package/types/private.d.ts +236 -0
  87. package/CHANGELOG.md +0 -419
  88. package/assets/components/error.svelte +0 -13
  89. package/assets/runtime/app/env.js +0 -5
  90. package/assets/runtime/app/navigation.js +0 -41
  91. package/assets/runtime/app/paths.js +0 -1
  92. package/assets/runtime/app/stores.js +0 -93
  93. package/assets/runtime/chunks/utils.js +0 -19
  94. package/assets/runtime/internal/singletons.js +0 -23
  95. package/assets/runtime/internal/start.js +0 -770
  96. package/assets/runtime/paths.js +0 -12
  97. package/dist/api.js +0 -28
  98. package/dist/api.js.map +0 -1
  99. package/dist/chunks/index.js +0 -3519
  100. package/dist/chunks/index2.js +0 -587
  101. package/dist/chunks/index3.js +0 -246
  102. package/dist/chunks/index4.js +0 -524
  103. package/dist/chunks/index5.js +0 -761
  104. package/dist/chunks/index6.js +0 -322
  105. package/dist/chunks/standard.js +0 -99
  106. package/dist/chunks/utils.js +0 -83
  107. package/dist/cli.js +0 -546
  108. package/dist/cli.js.map +0 -1
  109. package/dist/create_app.js +0 -592
  110. package/dist/create_app.js.map +0 -1
  111. package/dist/index.js +0 -392
  112. package/dist/index.js.map +0 -1
  113. package/dist/index2.js +0 -3519
  114. package/dist/index2.js.map +0 -1
  115. package/dist/index3.js +0 -320
  116. package/dist/index3.js.map +0 -1
  117. package/dist/index4.js +0 -323
  118. package/dist/index4.js.map +0 -1
  119. package/dist/index5.js +0 -247
  120. package/dist/index5.js.map +0 -1
  121. package/dist/index6.js +0 -761
  122. package/dist/index6.js.map +0 -1
  123. package/dist/renderer.js +0 -2499
  124. package/dist/renderer.js.map +0 -1
  125. package/dist/ssr.js +0 -2581
  126. package/dist/standard.js +0 -100
  127. package/dist/standard.js.map +0 -1
  128. package/dist/utils.js +0 -84
  129. package/dist/utils.js.map +0 -1
@@ -0,0 +1,1281 @@
1
+ import { onMount, tick } from 'svelte';
2
+ import { writable } from 'svelte/store';
3
+ import { normalize_error } from '../../utils/error.js';
4
+ import { LoadURL, decode_params, normalize_path } from '../../utils/url.js';
5
+ import {
6
+ create_updated_store,
7
+ find_anchor,
8
+ get_base_uri,
9
+ get_href,
10
+ notifiable_store,
11
+ scroll_state
12
+ } from './utils.js';
13
+ import { lock_fetch, unlock_fetch, initial_fetch, native_fetch } from './fetcher.js';
14
+ import { parse } from './parse.js';
15
+ import { error } from '../../index/index.js';
16
+
17
+ import Root from '__GENERATED__/root.svelte';
18
+ import { nodes, dictionary, matchers } from '__GENERATED__/client-manifest.js';
19
+ import { HttpError, Redirect } from '../../index/private.js';
20
+
21
+ const SCROLL_KEY = 'sveltekit:scroll';
22
+ const INDEX_KEY = 'sveltekit:index';
23
+
24
+ const routes = parse(nodes, dictionary, matchers);
25
+
26
+ // we import the root layout/error nodes eagerly, so that
27
+ // connectivity errors after initialisation don't nuke the app
28
+ const default_layout = nodes[0]();
29
+ const default_error = nodes[1]();
30
+
31
+ // We track the scroll position associated with each history entry in sessionStorage,
32
+ // rather than on history.state itself, because when navigation is driven by
33
+ // popstate it's too late to update the scroll position associated with the
34
+ // state we're navigating from
35
+
36
+ /** @typedef {{ x: number, y: number }} ScrollPosition */
37
+ /** @type {Record<number, ScrollPosition>} */
38
+ let scroll_positions = {};
39
+ try {
40
+ scroll_positions = JSON.parse(sessionStorage[SCROLL_KEY]);
41
+ } catch {
42
+ // do nothing
43
+ }
44
+
45
+ /** @param {number} index */
46
+ function update_scroll_positions(index) {
47
+ scroll_positions[index] = scroll_state();
48
+ }
49
+
50
+ /**
51
+ * @param {{
52
+ * target: Element;
53
+ * session: App.Session;
54
+ * base: string;
55
+ * trailing_slash: import('types').TrailingSlash;
56
+ * }} opts
57
+ * @returns {import('./types').Client}
58
+ */
59
+ export function create_client({ target, session, base, trailing_slash }) {
60
+ /** @type {Array<((href: string) => boolean)>} */
61
+ const invalidated = [];
62
+
63
+ const stores = {
64
+ url: notifiable_store({}),
65
+ page: notifiable_store({}),
66
+ navigating: writable(/** @type {import('types').Navigation | null} */ (null)),
67
+ session: writable(session),
68
+ updated: create_updated_store()
69
+ };
70
+
71
+ /** @type {{id: string | null, promise: Promise<import('./types').NavigationResult | undefined> | null}} */
72
+ const load_cache = {
73
+ id: null,
74
+ promise: null
75
+ };
76
+
77
+ const callbacks = {
78
+ /** @type {Array<(opts: { from: URL, to: URL | null, cancel: () => void }) => void>} */
79
+ before_navigate: [],
80
+
81
+ /** @type {Array<(opts: { from: URL | null, to: URL }) => void>} */
82
+ after_navigate: []
83
+ };
84
+
85
+ /** @type {import('./types').NavigationState} */
86
+ let current = {
87
+ branch: [],
88
+ error: null,
89
+ session_id: 0,
90
+ // @ts-ignore - we need the initial value to be null
91
+ url: null
92
+ };
93
+
94
+ let started = false;
95
+ let autoscroll = true;
96
+ let updating = false;
97
+ let session_id = 1;
98
+
99
+ /** @type {Promise<void> | null} */
100
+ let invalidating = null;
101
+
102
+ /** @type {import('svelte').SvelteComponent} */
103
+ let root;
104
+
105
+ /** @type {App.Session} */
106
+ let $session;
107
+
108
+ let ready = false;
109
+ stores.session.subscribe(async (value) => {
110
+ $session = value;
111
+
112
+ if (!ready) return;
113
+ session_id += 1;
114
+
115
+ const current_load_uses_session = current.branch.some((node) => node?.uses.session);
116
+ if (!current_load_uses_session) return;
117
+
118
+ update(new URL(location.href), []);
119
+ });
120
+ ready = true;
121
+
122
+ let router_enabled = true;
123
+
124
+ // keeping track of the history index in order to prevent popstate navigation events if needed
125
+ let current_history_index = history.state?.[INDEX_KEY];
126
+
127
+ if (!current_history_index) {
128
+ // we use Date.now() as an offset so that cross-document navigations
129
+ // within the app don't result in data loss
130
+ current_history_index = Date.now();
131
+
132
+ // create initial history entry, so we can return here
133
+ history.replaceState(
134
+ { ...history.state, [INDEX_KEY]: current_history_index },
135
+ '',
136
+ location.href
137
+ );
138
+ }
139
+
140
+ // if we reload the page, or Cmd-Shift-T back to it,
141
+ // recover scroll position
142
+ const scroll = scroll_positions[current_history_index];
143
+ if (scroll) {
144
+ history.scrollRestoration = 'manual';
145
+ scrollTo(scroll.x, scroll.y);
146
+ }
147
+
148
+ let hash_navigating = false;
149
+
150
+ /** @type {import('types').Page} */
151
+ let page;
152
+
153
+ /** @type {{}} */
154
+ let token;
155
+
156
+ /**
157
+ * @param {string | URL} url
158
+ * @param {{ noscroll?: boolean; replaceState?: boolean; keepfocus?: boolean; state?: any }} opts
159
+ * @param {string[]} redirect_chain
160
+ */
161
+ async function goto(
162
+ url,
163
+ { noscroll = false, replaceState = false, keepfocus = false, state = {} },
164
+ redirect_chain
165
+ ) {
166
+ if (typeof url === 'string') {
167
+ url = new URL(url, get_base_uri(document));
168
+ }
169
+
170
+ if (router_enabled) {
171
+ return navigate({
172
+ url,
173
+ scroll: noscroll ? scroll_state() : null,
174
+ keepfocus,
175
+ redirect_chain,
176
+ details: {
177
+ state,
178
+ replaceState
179
+ },
180
+ accepted: () => {},
181
+ blocked: () => {}
182
+ });
183
+ }
184
+
185
+ await native_navigation(url);
186
+ }
187
+
188
+ /** @param {URL} url */
189
+ async function prefetch(url) {
190
+ const intent = get_navigation_intent(url);
191
+
192
+ if (!intent) {
193
+ throw new Error('Attempted to prefetch a URL that does not belong to this app');
194
+ }
195
+
196
+ load_cache.promise = load_route(intent);
197
+ load_cache.id = intent.id;
198
+
199
+ return load_cache.promise;
200
+ }
201
+
202
+ /**
203
+ * Returns `true` if update completes, `false` if it is aborted
204
+ * @param {URL} url
205
+ * @param {string[]} redirect_chain
206
+ * @param {{hash?: string, scroll: { x: number, y: number } | null, keepfocus: boolean, details: { replaceState: boolean, state: any } | null}} [opts]
207
+ * @param {() => void} [callback]
208
+ */
209
+ async function update(url, redirect_chain, opts, callback) {
210
+ const intent = get_navigation_intent(url);
211
+
212
+ const current_token = (token = {});
213
+ let navigation_result = intent && (await load_route(intent));
214
+
215
+ if (
216
+ !navigation_result &&
217
+ url.origin === location.origin &&
218
+ url.pathname === location.pathname
219
+ ) {
220
+ // this could happen in SPA fallback mode if the user navigated to
221
+ // `/non-existent-page`. if we fall back to reloading the page, it
222
+ // will create an infinite loop. so whereas we normally handle
223
+ // unknown routes by going to the server, in this special case
224
+ // we render a client-side error page instead
225
+ navigation_result = await load_root_error_page({
226
+ status: 404,
227
+ error: new Error(`Not found: ${url.pathname}`),
228
+ url,
229
+ routeId: null
230
+ });
231
+ }
232
+
233
+ if (!navigation_result) {
234
+ await native_navigation(url);
235
+ return false; // unnecessary, but TypeScript prefers it this way
236
+ }
237
+
238
+ // if this is an internal navigation intent, use the normalized
239
+ // URL for the rest of the function
240
+ url = intent?.url || url;
241
+
242
+ // abort if user navigated during update
243
+ if (token !== current_token) return false;
244
+
245
+ invalidated.length = 0;
246
+
247
+ if (navigation_result.type === 'redirect') {
248
+ if (redirect_chain.length > 10 || redirect_chain.includes(url.pathname)) {
249
+ navigation_result = await load_root_error_page({
250
+ status: 500,
251
+ error: new Error('Redirect loop'),
252
+ url,
253
+ routeId: null
254
+ });
255
+ } else {
256
+ if (router_enabled) {
257
+ goto(new URL(navigation_result.location, url).href, {}, [
258
+ ...redirect_chain,
259
+ url.pathname
260
+ ]);
261
+ } else {
262
+ await native_navigation(new URL(navigation_result.location, location.href));
263
+ }
264
+
265
+ return false;
266
+ }
267
+ } else if (navigation_result.props?.page?.status >= 400) {
268
+ const updated = await stores.updated.check();
269
+ if (updated) {
270
+ await native_navigation(url);
271
+ }
272
+ }
273
+
274
+ updating = true;
275
+
276
+ if (opts && opts.details) {
277
+ const { details } = opts;
278
+ const change = details.replaceState ? 0 : 1;
279
+ details.state[INDEX_KEY] = current_history_index += change;
280
+ history[details.replaceState ? 'replaceState' : 'pushState'](details.state, '', url);
281
+ }
282
+
283
+ if (started) {
284
+ current = navigation_result.state;
285
+
286
+ if (navigation_result.props.page) {
287
+ navigation_result.props.page.url = url;
288
+ }
289
+
290
+ root.$set(navigation_result.props);
291
+ } else {
292
+ initialize(navigation_result);
293
+ }
294
+
295
+ // opts must be passed if we're navigating
296
+ if (opts) {
297
+ const { scroll, keepfocus } = opts;
298
+
299
+ if (!keepfocus) {
300
+ // Reset page selection and focus
301
+ // We try to mimic browsers' behaviour as closely as possible by targeting the
302
+ // first scrollable region, but unfortunately it's not a perfect match — e.g.
303
+ // shift-tabbing won't immediately cycle up from the end of the page on Chromium
304
+ // See https://html.spec.whatwg.org/multipage/interaction.html#get-the-focusable-area
305
+ const root = document.body;
306
+ const tabindex = root.getAttribute('tabindex');
307
+
308
+ root.tabIndex = -1;
309
+ root.focus({ preventScroll: true });
310
+
311
+ setTimeout(() => {
312
+ getSelection()?.removeAllRanges();
313
+ });
314
+
315
+ // restore `tabindex` as to prevent `root` from stealing input from elements
316
+ if (tabindex !== null) {
317
+ root.setAttribute('tabindex', tabindex);
318
+ } else {
319
+ root.removeAttribute('tabindex');
320
+ }
321
+ }
322
+
323
+ // need to render the DOM before we can scroll to the rendered elements
324
+ await tick();
325
+
326
+ if (autoscroll) {
327
+ const deep_linked = url.hash && document.getElementById(url.hash.slice(1));
328
+ if (scroll) {
329
+ scrollTo(scroll.x, scroll.y);
330
+ } else if (deep_linked) {
331
+ // Here we use `scrollIntoView` on the element instead of `scrollTo`
332
+ // because it natively supports the `scroll-margin` and `scroll-behavior`
333
+ // CSS properties.
334
+ deep_linked.scrollIntoView();
335
+ } else {
336
+ scrollTo(0, 0);
337
+ }
338
+ }
339
+ } else {
340
+ // in this case we're simply invalidating
341
+ await tick();
342
+ }
343
+
344
+ load_cache.promise = null;
345
+ load_cache.id = null;
346
+ autoscroll = true;
347
+
348
+ if (navigation_result.props.page) {
349
+ page = navigation_result.props.page;
350
+ }
351
+
352
+ const leaf_node = navigation_result.state.branch.at(-1);
353
+ router_enabled = leaf_node?.node.shared?.router !== false;
354
+
355
+ if (callback) callback();
356
+
357
+ updating = false;
358
+ }
359
+
360
+ /** @param {import('./types').NavigationFinished} result */
361
+ function initialize(result) {
362
+ current = result.state;
363
+
364
+ const style = document.querySelector('style[data-sveltekit]');
365
+ if (style) style.remove();
366
+
367
+ page = result.props.page;
368
+
369
+ root = new Root({
370
+ target,
371
+ props: { ...result.props, stores },
372
+ hydrate: true
373
+ });
374
+
375
+ if (router_enabled) {
376
+ const navigation = { from: null, to: new URL(location.href) };
377
+ callbacks.after_navigate.forEach((fn) => fn(navigation));
378
+ }
379
+
380
+ started = true;
381
+ }
382
+
383
+ /**
384
+ *
385
+ * @param {{
386
+ * url: URL;
387
+ * params: Record<string, string>;
388
+ * branch: Array<import('./types').BranchNode | undefined>;
389
+ * status: number;
390
+ * error: HttpError | Error | null;
391
+ * routeId: string | null;
392
+ * validation_errors?: string | undefined;
393
+ * }} opts
394
+ */
395
+ async function get_navigation_result_from_branch({
396
+ url,
397
+ params,
398
+ branch,
399
+ status,
400
+ error,
401
+ routeId,
402
+ validation_errors
403
+ }) {
404
+ const filtered = /** @type {import('./types').BranchNode[] } */ (branch.filter(Boolean));
405
+
406
+ /** @type {import('./types').NavigationFinished} */
407
+ const result = {
408
+ type: 'loaded',
409
+ state: {
410
+ url,
411
+ params,
412
+ branch,
413
+ error,
414
+ session_id
415
+ },
416
+ props: {
417
+ components: filtered.map((branch_node) => branch_node.node.component),
418
+ errors: validation_errors
419
+ }
420
+ };
421
+
422
+ let data = {};
423
+ let data_changed = false;
424
+ for (let i = 0; i < filtered.length; i += 1) {
425
+ Object.assign(data, filtered[i].data);
426
+ // Only set props if the node actually updated. This prevents needless rerenders.
427
+ if (!current.branch.some((node) => node === filtered[i])) {
428
+ result.props[`data_${i}`] = filtered[i].data;
429
+ data_changed = true;
430
+ }
431
+ }
432
+
433
+ const page_changed =
434
+ !current.url || url.href !== current.url.href || current.error !== error || data_changed;
435
+
436
+ if (page_changed) {
437
+ result.props.page = { error, params, routeId, status, url, data };
438
+
439
+ // TODO remove this for 1.0
440
+ /**
441
+ * @param {string} property
442
+ * @param {string} replacement
443
+ */
444
+ const print_error = (property, replacement) => {
445
+ Object.defineProperty(result.props.page, property, {
446
+ get: () => {
447
+ throw new Error(`$page.${property} has been replaced by $page.url.${replacement}`);
448
+ }
449
+ });
450
+ };
451
+
452
+ print_error('origin', 'origin');
453
+ print_error('path', 'pathname');
454
+ print_error('query', 'searchParams');
455
+ }
456
+
457
+ return result;
458
+ }
459
+
460
+ /**
461
+ * Call the load function of the given node, if it exists.
462
+ * If `server_data` is passed, this is treated as the initial run and the page endpoint is not requested.
463
+ *
464
+ * @param {{
465
+ * node: import('types').CSRPageNode;
466
+ * parent: () => Promise<Record<string, any>>;
467
+ * url: URL;
468
+ * params: Record<string, string>;
469
+ * routeId: string | null;
470
+ * server_data: import('types').JSONObject | null;
471
+ * }} options
472
+ * @returns {Promise<import('./types').BranchNode>}
473
+ */
474
+ async function load_node({ node, parent, url, params, routeId, server_data }) {
475
+ const uses = {
476
+ params: new Set(),
477
+ url: false,
478
+ session: false,
479
+ dependencies: new Set(),
480
+ parent: false
481
+ };
482
+
483
+ /** @param {string[]} deps */
484
+ function depends(...deps) {
485
+ for (const dep of deps) {
486
+ const { href } = new URL(dep, url);
487
+ uses.dependencies.add(href);
488
+ }
489
+ }
490
+
491
+ /** @type {Record<string, any> | null} */
492
+ let data = null;
493
+
494
+ if (node.server) {
495
+ // +page|layout.server.js data means we need to mark this URL as a dependency of itself,
496
+ // unless we want to get clever with usage detection on the server, which could
497
+ // be returned to the client either as payload or custom headers
498
+ uses.dependencies.add(url.href);
499
+ uses.url = true;
500
+ }
501
+
502
+ /** @type {Record<string, string>} */
503
+ const uses_params = {};
504
+ for (const key in params) {
505
+ Object.defineProperty(uses_params, key, {
506
+ get() {
507
+ uses.params.add(key);
508
+ return params[key];
509
+ },
510
+ enumerable: true
511
+ });
512
+ }
513
+
514
+ const session = $session;
515
+ const load_url = new LoadURL(url);
516
+
517
+ if (node.shared?.load) {
518
+ /** @type {import('types').LoadEvent} */
519
+ const load_input = {
520
+ routeId,
521
+ params: uses_params,
522
+ data: server_data,
523
+ get url() {
524
+ uses.url = true;
525
+ return load_url;
526
+ },
527
+ get session() {
528
+ uses.session = true;
529
+ return session;
530
+ },
531
+ async fetch(resource, init) {
532
+ let requested;
533
+
534
+ if (typeof resource === 'string') {
535
+ requested = resource;
536
+ } else {
537
+ requested = resource.url;
538
+
539
+ // we're not allowed to modify the received `Request` object, so in order
540
+ // to fixup relative urls we create a new equivalent `init` object instead
541
+ init = {
542
+ // the request body must be consumed in memory until browsers
543
+ // implement streaming request bodies and/or the body getter
544
+ body:
545
+ resource.method === 'GET' || resource.method === 'HEAD'
546
+ ? undefined
547
+ : await resource.blob(),
548
+ cache: resource.cache,
549
+ credentials: resource.credentials,
550
+ headers: resource.headers,
551
+ integrity: resource.integrity,
552
+ keepalive: resource.keepalive,
553
+ method: resource.method,
554
+ mode: resource.mode,
555
+ redirect: resource.redirect,
556
+ referrer: resource.referrer,
557
+ referrerPolicy: resource.referrerPolicy,
558
+ signal: resource.signal,
559
+ ...init
560
+ };
561
+ }
562
+
563
+ // we must fixup relative urls so they are resolved from the target page
564
+ const normalized = new URL(requested, url).href;
565
+ depends(normalized);
566
+
567
+ // prerendered pages may be served from any origin, so `initial_fetch` urls shouldn't be normalized
568
+ return started ? native_fetch(normalized, init) : initial_fetch(requested, init);
569
+ },
570
+ setHeaders: () => {}, // noop
571
+ depends,
572
+ get parent() {
573
+ // uses.parent assignment here, not on method inokation, else we wouldn't notice when someone
574
+ // does await parent() inside an if branch which wasn't executed yet.
575
+ uses.parent = true;
576
+ return parent;
577
+ },
578
+ // @ts-expect-error
579
+ get props() {
580
+ throw new Error(
581
+ '@migration task: Replace `props` with `data` stuff https://github.com/sveltejs/kit/discussions/5774#discussioncomment-3292693'
582
+ );
583
+ },
584
+ get stuff() {
585
+ throw new Error(
586
+ '@migration task: Remove stuff https://github.com/sveltejs/kit/discussions/5774#discussioncomment-3292693'
587
+ );
588
+ }
589
+ };
590
+
591
+ if (import.meta.env.DEV) {
592
+ try {
593
+ lock_fetch();
594
+ data = (await node.shared.load.call(null, load_input)) ?? null;
595
+ } finally {
596
+ unlock_fetch();
597
+ }
598
+ } else {
599
+ data = (await node.shared.load.call(null, load_input)) ?? null;
600
+ }
601
+ }
602
+
603
+ return {
604
+ node,
605
+ data: data || server_data,
606
+ uses
607
+ };
608
+ }
609
+
610
+ /**
611
+ * @param {import('./types').NavigationIntent} intent
612
+ * @returns {Promise<import('./types').NavigationResult | undefined>}
613
+ */
614
+ async function load_route({ id, url, params, route }) {
615
+ if (load_cache.id === id && load_cache.promise) {
616
+ return load_cache.promise;
617
+ }
618
+
619
+ const { errors, layouts, leaf } = route;
620
+
621
+ const changed = current.url && {
622
+ url: id !== current.url.pathname + current.url.search,
623
+ params: Object.keys(params).filter((key) => current.params[key] !== params[key]),
624
+ session: session_id !== current.session_id
625
+ };
626
+
627
+ // preload modules to avoid waterfall, but handle rejections
628
+ // so they don't get reported to Sentry et al (we don't need
629
+ // to act on the failures at this point)
630
+ [...errors, ...layouts, leaf].forEach((loader) => loader?.().catch(() => {}));
631
+
632
+ const nodes = [...layouts, leaf];
633
+
634
+ // To avoid waterfalls when someone awaits a parent, compute as much as possible here already
635
+ /** @type {boolean[]} */
636
+ const nodes_changed_since_last_render = [];
637
+ for (let i = 0; i < nodes.length; i++) {
638
+ if (!nodes[i]) {
639
+ nodes_changed_since_last_render.push(false);
640
+ } else {
641
+ const previous = current.branch[i];
642
+ const changed_since_last_render =
643
+ !previous ||
644
+ (changed.url && previous.uses.url) ||
645
+ changed.params.some((param) => previous.uses.params.has(param)) ||
646
+ (changed.session && previous.uses.session) ||
647
+ Array.from(previous.uses.dependencies).some((dep) => invalidated.some((fn) => fn(dep))) ||
648
+ (previous.uses.parent && nodes_changed_since_last_render.includes(true));
649
+ nodes_changed_since_last_render.push(changed_since_last_render);
650
+ }
651
+ }
652
+
653
+ /** @type {import('./types').ServerDataPayload | null} */
654
+ let server_data_payload = null;
655
+
656
+ if (route.uses_server_data) {
657
+ try {
658
+ const res = await native_fetch(
659
+ `${url.pathname}${url.pathname.endsWith('/') ? '' : '/'}__data.json${url.search}`
660
+ );
661
+
662
+ server_data_payload = /** @type {import('./types').ServerDataPayload} */ (await res.json());
663
+
664
+ if (!res.ok) {
665
+ throw server_data_payload;
666
+ }
667
+ } catch (e) {
668
+ throw new Error('TODO render fallback error page');
669
+ }
670
+
671
+ if (server_data_payload.type === 'redirect') {
672
+ return server_data_payload;
673
+ }
674
+ }
675
+
676
+ const server_data_nodes = server_data_payload?.nodes;
677
+
678
+ const branch_promises = nodes.map(async (loader, i) => {
679
+ return Promise.resolve().then(async () => {
680
+ if (!loader) return;
681
+ const node = await loader();
682
+
683
+ /** @type {import('./types').BranchNode | undefined} */
684
+ const previous = current.branch[i];
685
+ const changed_since_last_render =
686
+ nodes_changed_since_last_render[i] || !previous || node !== previous.node;
687
+
688
+ if (changed_since_last_render) {
689
+ const payload = server_data_nodes?.[i];
690
+
691
+ if (payload?.status) {
692
+ throw error(payload.status, payload.message);
693
+ }
694
+
695
+ if (payload?.error) {
696
+ throw payload.error;
697
+ }
698
+
699
+ return await load_node({
700
+ node,
701
+ url,
702
+ params,
703
+ routeId: route.id,
704
+ parent: async () => {
705
+ const data = {};
706
+ for (let j = 0; j < i; j += 1) {
707
+ Object.assign(data, (await branch_promises[j])?.data);
708
+ }
709
+ return data;
710
+ },
711
+ server_data: payload?.data ?? null
712
+ });
713
+ } else {
714
+ return previous;
715
+ }
716
+ });
717
+ });
718
+
719
+ // if we don't do this, rejections will be unhandled
720
+ for (const p of branch_promises) p.catch(() => {});
721
+
722
+ /** @type {Array<import('./types').BranchNode | undefined>} */
723
+ const branch = [];
724
+
725
+ for (let i = 0; i < nodes.length; i += 1) {
726
+ if (nodes[i]) {
727
+ try {
728
+ branch.push(await branch_promises[i]);
729
+ } catch (e) {
730
+ const error = normalize_error(e);
731
+
732
+ if (error instanceof Redirect) {
733
+ return {
734
+ type: 'redirect',
735
+ location: error.location
736
+ };
737
+ }
738
+
739
+ const status = e instanceof HttpError ? e.status : 500;
740
+
741
+ while (i--) {
742
+ if (errors[i]) {
743
+ /** @type {import('./types').BranchNode | undefined} */
744
+ let error_loaded;
745
+
746
+ let j = i;
747
+ while (!branch[j]) j -= 1;
748
+
749
+ try {
750
+ error_loaded = {
751
+ node: await errors[i](),
752
+ data: {},
753
+ uses: {
754
+ params: new Set(),
755
+ url: false,
756
+ session: false,
757
+ dependencies: new Set(),
758
+ parent: false
759
+ }
760
+ };
761
+
762
+ return await get_navigation_result_from_branch({
763
+ url,
764
+ params,
765
+ branch: branch.slice(0, j + 1).concat(error_loaded),
766
+ status,
767
+ error,
768
+ routeId: route.id
769
+ });
770
+ } catch (e) {
771
+ continue;
772
+ }
773
+ }
774
+ }
775
+
776
+ return await load_root_error_page({
777
+ status,
778
+ error,
779
+ url,
780
+ routeId: route.id
781
+ });
782
+ }
783
+ } else {
784
+ // push an empty slot so we can rewind past gaps to the
785
+ // layout that corresponds with an +error.svelte page
786
+ branch.push(undefined);
787
+ }
788
+ }
789
+
790
+ return await get_navigation_result_from_branch({
791
+ url,
792
+ params,
793
+ branch,
794
+ status: 200,
795
+ error: null,
796
+ routeId: route.id
797
+ });
798
+ }
799
+
800
+ /**
801
+ * @param {{
802
+ * status: number;
803
+ * error: HttpError | Error;
804
+ * url: URL;
805
+ * routeId: string | null
806
+ * }} opts
807
+ */
808
+ async function load_root_error_page({ status, error, url, routeId }) {
809
+ /** @type {Record<string, string>} */
810
+ const params = {}; // error page does not have params
811
+
812
+ const root_layout = await load_node({
813
+ node: await default_layout,
814
+ url,
815
+ params,
816
+ routeId,
817
+ parent: () => Promise.resolve({}),
818
+ server_data: null // TODO!!!!!
819
+ });
820
+
821
+ const root_error = {
822
+ node: await default_error,
823
+ data: null,
824
+ // TODO make this unnecessary
825
+ uses: {
826
+ params: new Set(),
827
+ url: false,
828
+ session: false,
829
+ dependencies: new Set(),
830
+ parent: false
831
+ }
832
+ };
833
+
834
+ return await get_navigation_result_from_branch({
835
+ url,
836
+ params,
837
+ branch: [root_layout, root_error],
838
+ status,
839
+ error,
840
+ routeId
841
+ });
842
+ }
843
+
844
+ /** @param {URL} url */
845
+ function get_navigation_intent(url) {
846
+ if (url.origin !== location.origin || !url.pathname.startsWith(base)) return;
847
+
848
+ const path = decodeURI(url.pathname.slice(base.length) || '/');
849
+
850
+ for (const route of routes) {
851
+ const params = route.exec(path);
852
+
853
+ if (params) {
854
+ const normalized = new URL(
855
+ url.origin + normalize_path(url.pathname, trailing_slash) + url.search + url.hash
856
+ );
857
+ const id = normalized.pathname + normalized.search;
858
+ /** @type {import('./types').NavigationIntent} */
859
+ const intent = { id, route, params: decode_params(params), url: normalized };
860
+ return intent;
861
+ }
862
+ }
863
+ }
864
+
865
+ /**
866
+ * @param {{
867
+ * url: URL;
868
+ * scroll: { x: number, y: number } | null;
869
+ * keepfocus: boolean;
870
+ * redirect_chain: string[];
871
+ * details: {
872
+ * replaceState: boolean;
873
+ * state: any;
874
+ * } | null;
875
+ * accepted: () => void;
876
+ * blocked: () => void;
877
+ * }} opts
878
+ */
879
+ async function navigate({ url, scroll, keepfocus, redirect_chain, details, accepted, blocked }) {
880
+ const from = current.url;
881
+ let should_block = false;
882
+
883
+ const navigation = {
884
+ from,
885
+ to: url,
886
+ cancel: () => (should_block = true)
887
+ };
888
+
889
+ callbacks.before_navigate.forEach((fn) => fn(navigation));
890
+
891
+ if (should_block) {
892
+ blocked();
893
+ return;
894
+ }
895
+
896
+ update_scroll_positions(current_history_index);
897
+
898
+ accepted();
899
+
900
+ if (started) {
901
+ stores.navigating.set({
902
+ from: current.url,
903
+ to: url
904
+ });
905
+ }
906
+
907
+ await update(
908
+ url,
909
+ redirect_chain,
910
+ {
911
+ scroll,
912
+ keepfocus,
913
+ details
914
+ },
915
+ () => {
916
+ const navigation = { from, to: url };
917
+ callbacks.after_navigate.forEach((fn) => fn(navigation));
918
+
919
+ stores.navigating.set(null);
920
+ }
921
+ );
922
+ }
923
+
924
+ /**
925
+ * Loads `href` the old-fashioned way, with a full page reload.
926
+ * Returns a `Promise` that never resolves (to prevent any
927
+ * subsequent work, e.g. history manipulation, from happening)
928
+ * @param {URL} url
929
+ */
930
+ function native_navigation(url) {
931
+ location.href = url.href;
932
+ return new Promise(() => {});
933
+ }
934
+
935
+ if (import.meta.hot) {
936
+ import.meta.hot.on('vite:beforeUpdate', () => {
937
+ if (current.error) location.reload();
938
+ });
939
+ }
940
+
941
+ return {
942
+ after_navigate: (fn) => {
943
+ onMount(() => {
944
+ callbacks.after_navigate.push(fn);
945
+
946
+ return () => {
947
+ const i = callbacks.after_navigate.indexOf(fn);
948
+ callbacks.after_navigate.splice(i, 1);
949
+ };
950
+ });
951
+ },
952
+
953
+ before_navigate: (fn) => {
954
+ onMount(() => {
955
+ callbacks.before_navigate.push(fn);
956
+
957
+ return () => {
958
+ const i = callbacks.before_navigate.indexOf(fn);
959
+ callbacks.before_navigate.splice(i, 1);
960
+ };
961
+ });
962
+ },
963
+
964
+ disable_scroll_handling: () => {
965
+ if (import.meta.env.DEV && started && !updating) {
966
+ throw new Error('Can only disable scroll handling during navigation');
967
+ }
968
+
969
+ if (updating || !started) {
970
+ autoscroll = false;
971
+ }
972
+ },
973
+
974
+ goto: (href, opts = {}) => goto(href, opts, []),
975
+
976
+ invalidate: (resource) => {
977
+ if (resource === undefined) {
978
+ // Force rerun of all load functions, regardless of their dependencies
979
+ for (const node of current.branch) {
980
+ node?.uses.dependencies.add('');
981
+ }
982
+ invalidated.push(() => true);
983
+ } else if (typeof resource === 'function') {
984
+ invalidated.push(resource);
985
+ } else {
986
+ const { href } = new URL(resource, location.href);
987
+ invalidated.push((dep) => dep === href);
988
+ }
989
+
990
+ if (!invalidating) {
991
+ invalidating = Promise.resolve().then(async () => {
992
+ await update(new URL(location.href), []);
993
+
994
+ invalidating = null;
995
+ });
996
+ }
997
+
998
+ return invalidating;
999
+ },
1000
+
1001
+ prefetch: async (href) => {
1002
+ const url = new URL(href, get_base_uri(document));
1003
+ await prefetch(url);
1004
+ },
1005
+
1006
+ // TODO rethink this API
1007
+ prefetch_routes: async (pathnames) => {
1008
+ const matching = pathnames
1009
+ ? routes.filter((route) => pathnames.some((pathname) => route.exec(pathname)))
1010
+ : routes;
1011
+
1012
+ const promises = matching.map((r) => {
1013
+ return Promise.all([...r.layouts, r.leaf].map((load) => load?.()));
1014
+ });
1015
+
1016
+ await Promise.all(promises);
1017
+ },
1018
+
1019
+ _start_router: () => {
1020
+ history.scrollRestoration = 'manual';
1021
+
1022
+ // Adopted from Nuxt.js
1023
+ // Reset scrollRestoration to auto when leaving page, allowing page reload
1024
+ // and back-navigation from other pages to use the browser to restore the
1025
+ // scrolling position.
1026
+ addEventListener('beforeunload', (e) => {
1027
+ let should_block = false;
1028
+
1029
+ const navigation = {
1030
+ from: current.url,
1031
+ to: null,
1032
+ cancel: () => (should_block = true)
1033
+ };
1034
+
1035
+ callbacks.before_navigate.forEach((fn) => fn(navigation));
1036
+
1037
+ if (should_block) {
1038
+ e.preventDefault();
1039
+ e.returnValue = '';
1040
+ } else {
1041
+ history.scrollRestoration = 'auto';
1042
+ }
1043
+ });
1044
+
1045
+ addEventListener('visibilitychange', () => {
1046
+ if (document.visibilityState === 'hidden') {
1047
+ update_scroll_positions(current_history_index);
1048
+
1049
+ try {
1050
+ sessionStorage[SCROLL_KEY] = JSON.stringify(scroll_positions);
1051
+ } catch {
1052
+ // do nothing
1053
+ }
1054
+ }
1055
+ });
1056
+
1057
+ /** @param {Event} event */
1058
+ const trigger_prefetch = (event) => {
1059
+ const a = find_anchor(event);
1060
+ if (a && a.href && a.hasAttribute('sveltekit:prefetch')) {
1061
+ prefetch(get_href(a));
1062
+ }
1063
+ };
1064
+
1065
+ /** @type {NodeJS.Timeout} */
1066
+ let mousemove_timeout;
1067
+
1068
+ /** @param {MouseEvent|TouchEvent} event */
1069
+ const handle_mousemove = (event) => {
1070
+ clearTimeout(mousemove_timeout);
1071
+ mousemove_timeout = setTimeout(() => {
1072
+ // event.composedPath(), which is used in find_anchor, will be empty if the event is read in a timeout
1073
+ // add a layer of indirection to address that
1074
+ event.target?.dispatchEvent(
1075
+ new CustomEvent('sveltekit:trigger_prefetch', { bubbles: true })
1076
+ );
1077
+ }, 20);
1078
+ };
1079
+
1080
+ addEventListener('touchstart', trigger_prefetch);
1081
+ addEventListener('mousemove', handle_mousemove);
1082
+ addEventListener('sveltekit:trigger_prefetch', trigger_prefetch);
1083
+
1084
+ /** @param {MouseEvent} event */
1085
+ addEventListener('click', (event) => {
1086
+ if (!router_enabled) return;
1087
+
1088
+ // Adapted from https://github.com/visionmedia/page.js
1089
+ // MIT license https://github.com/visionmedia/page.js#license
1090
+ if (event.button || event.which !== 1) return;
1091
+ if (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return;
1092
+ if (event.defaultPrevented) return;
1093
+
1094
+ const a = find_anchor(event);
1095
+ if (!a) return;
1096
+
1097
+ if (!a.href) return;
1098
+
1099
+ const is_svg_a_element = a instanceof SVGAElement;
1100
+ const url = get_href(a);
1101
+
1102
+ // Ignore non-HTTP URL protocols (e.g. `mailto:`, `tel:`, `myapp:`, etc.)
1103
+ // MEMO: Without this condition, firefox will open mailer twice.
1104
+ // See:
1105
+ // - https://github.com/sveltejs/kit/issues/4045
1106
+ // - https://github.com/sveltejs/kit/issues/5725
1107
+ if (!is_svg_a_element && !(url.protocol === 'https:' || url.protocol === 'http:')) return;
1108
+
1109
+ // Ignore if tag has
1110
+ // 1. 'download' attribute
1111
+ // 2. 'rel' attribute includes external
1112
+ const rel = (a.getAttribute('rel') || '').split(/\s+/);
1113
+
1114
+ if (
1115
+ a.hasAttribute('download') ||
1116
+ rel.includes('external') ||
1117
+ a.hasAttribute('sveltekit:reload')
1118
+ ) {
1119
+ return;
1120
+ }
1121
+
1122
+ // Ignore if <a> has a target
1123
+ if (is_svg_a_element ? a.target.baseVal : a.target) return;
1124
+
1125
+ // Check if new url only differs by hash and use the browser default behavior in that case
1126
+ // This will ensure the `hashchange` event is fired
1127
+ // Removing the hash does a full page navigation in the browser, so make sure a hash is present
1128
+ const [base, hash] = url.href.split('#');
1129
+ if (hash !== undefined && base === location.href.split('#')[0]) {
1130
+ // set this flag to distinguish between navigations triggered by
1131
+ // clicking a hash link and those triggered by popstate
1132
+ hash_navigating = true;
1133
+
1134
+ update_scroll_positions(current_history_index);
1135
+
1136
+ stores.page.set({ ...page, url });
1137
+ stores.page.notify();
1138
+
1139
+ return;
1140
+ }
1141
+
1142
+ navigate({
1143
+ url,
1144
+ scroll: a.hasAttribute('sveltekit:noscroll') ? scroll_state() : null,
1145
+ keepfocus: false,
1146
+ redirect_chain: [],
1147
+ details: {
1148
+ state: {},
1149
+ replaceState: url.href === location.href
1150
+ },
1151
+ accepted: () => event.preventDefault(),
1152
+ blocked: () => event.preventDefault()
1153
+ });
1154
+ });
1155
+
1156
+ addEventListener('popstate', (event) => {
1157
+ if (event.state && router_enabled) {
1158
+ // if a popstate-driven navigation is cancelled, we need to counteract it
1159
+ // with history.go, which means we end up back here, hence this check
1160
+ if (event.state[INDEX_KEY] === current_history_index) return;
1161
+
1162
+ navigate({
1163
+ url: new URL(location.href),
1164
+ scroll: scroll_positions[event.state[INDEX_KEY]],
1165
+ keepfocus: false,
1166
+ redirect_chain: [],
1167
+ details: null,
1168
+ accepted: () => {
1169
+ current_history_index = event.state[INDEX_KEY];
1170
+ },
1171
+ blocked: () => {
1172
+ const delta = current_history_index - event.state[INDEX_KEY];
1173
+ history.go(delta);
1174
+ }
1175
+ });
1176
+ }
1177
+ });
1178
+
1179
+ addEventListener('hashchange', () => {
1180
+ // if the hashchange happened as a result of clicking on a link,
1181
+ // we need to update history, otherwise we have to leave it alone
1182
+ if (hash_navigating) {
1183
+ hash_navigating = false;
1184
+ history.replaceState(
1185
+ { ...history.state, [INDEX_KEY]: ++current_history_index },
1186
+ '',
1187
+ location.href
1188
+ );
1189
+ }
1190
+ });
1191
+
1192
+ // fix link[rel=icon], because browsers will occasionally try to load relative
1193
+ // URLs after a pushState/replaceState, resulting in a 404 — see
1194
+ // https://github.com/sveltejs/kit/issues/3748#issuecomment-1125980897
1195
+ for (const link of document.querySelectorAll('link')) {
1196
+ if (link.rel === 'icon') link.href = link.href;
1197
+ }
1198
+
1199
+ addEventListener('pageshow', (event) => {
1200
+ // If the user navigates to another site and then uses the back button and
1201
+ // bfcache hits, we need to set navigating to null, the site doesn't know
1202
+ // the navigation away from it was successful.
1203
+ // Info about bfcache here: https://web.dev/bfcache
1204
+ if (event.persisted) {
1205
+ stores.navigating.set(null);
1206
+ }
1207
+ });
1208
+ },
1209
+
1210
+ _hydrate: async ({ status, error, node_ids, params, routeId }) => {
1211
+ const url = new URL(location.href);
1212
+
1213
+ /** @type {import('./types').NavigationFinished | undefined} */
1214
+ let result;
1215
+
1216
+ try {
1217
+ /**
1218
+ * @param {string} type
1219
+ * @param {any} fallback
1220
+ */
1221
+ const parse = (type, fallback) => {
1222
+ const script = document.querySelector(`script[sveltekit\\:data-type="${type}"]`);
1223
+ return script?.textContent ? JSON.parse(script.textContent) : fallback;
1224
+ };
1225
+ const server_data = parse('server_data', []);
1226
+ const validation_errors = parse('validation_errors', undefined);
1227
+
1228
+ const branch_promises = node_ids.map(async (n, i) => {
1229
+ return load_node({
1230
+ node: await nodes[n](),
1231
+ url,
1232
+ params,
1233
+ routeId,
1234
+ parent: async () => {
1235
+ const data = {};
1236
+ for (let j = 0; j < i; j += 1) {
1237
+ Object.assign(data, (await branch_promises[j]).data);
1238
+ }
1239
+ return data;
1240
+ },
1241
+ server_data: server_data[i] ?? null
1242
+ });
1243
+ });
1244
+
1245
+ result = await get_navigation_result_from_branch({
1246
+ url,
1247
+ params,
1248
+ branch: await Promise.all(branch_promises),
1249
+ status,
1250
+ error: /** @type {import('../server/page/types').SerializedHttpError} */ (error)
1251
+ ?.__is_http_error
1252
+ ? new HttpError(
1253
+ /** @type {import('../server/page/types').SerializedHttpError} */ (error).status,
1254
+ error.message
1255
+ )
1256
+ : error,
1257
+ validation_errors,
1258
+ routeId
1259
+ });
1260
+ } catch (e) {
1261
+ const error = normalize_error(e);
1262
+
1263
+ if (error instanceof Redirect) {
1264
+ // this is a real edge case — `load` would need to return
1265
+ // a redirect but only in the browser
1266
+ await native_navigation(new URL(/** @type {Redirect} */ (e).location, location.href));
1267
+ return;
1268
+ }
1269
+
1270
+ result = await load_root_error_page({
1271
+ status: error instanceof HttpError ? error.status : 500,
1272
+ error,
1273
+ url,
1274
+ routeId
1275
+ });
1276
+ }
1277
+
1278
+ initialize(result);
1279
+ }
1280
+ };
1281
+ }