@sveltejs/kit 1.0.0-next.405 → 1.0.0-next.406
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.
- package/package.json +23 -25
- package/{dist → src}/cli.js +19 -18
- package/{dist/chunks/index3.js → src/core/adapt/builder.js} +6 -59
- package/src/core/adapt/index.js +19 -0
- package/src/core/config/index.js +86 -0
- package/{dist/chunks/index.js → src/core/config/options.js} +7 -194
- package/src/core/config/types.d.ts +1 -0
- package/src/core/constants.js +3 -0
- package/src/core/generate_manifest/index.js +99 -0
- package/src/core/prerender/crawl.js +194 -0
- package/src/core/prerender/prerender.js +378 -0
- package/src/core/prerender/queue.js +80 -0
- package/src/core/sync/create_manifest_data/index.js +492 -0
- package/src/core/sync/create_manifest_data/types.d.ts +40 -0
- package/src/core/sync/sync.js +59 -0
- package/src/core/sync/utils.js +97 -0
- package/src/core/sync/write_ambient.js +87 -0
- package/src/core/sync/write_client_manifest.js +82 -0
- package/src/core/sync/write_matchers.js +25 -0
- package/src/core/sync/write_root.js +88 -0
- package/{dist/chunks → src/core/sync}/write_tsconfig.js +24 -108
- package/src/core/sync/write_types.js +738 -0
- package/src/core/utils.js +58 -0
- package/{dist → src}/hooks.js +1 -3
- package/src/index/index.js +45 -0
- package/src/index/private.js +31 -0
- package/src/node/index.js +145 -0
- package/src/node/polyfills.js +40 -0
- package/src/packaging/index.js +218 -0
- package/src/packaging/types.d.ts +8 -0
- package/src/packaging/typescript.js +150 -0
- package/src/packaging/utils.js +138 -0
- package/{assets → src/runtime}/app/env.js +3 -5
- package/src/runtime/app/navigation.js +22 -0
- package/src/runtime/app/paths.js +1 -0
- package/{assets → src/runtime}/app/stores.js +6 -9
- package/src/runtime/client/ambient.d.ts +17 -0
- package/{assets/client/start.js → src/runtime/client/client.js} +302 -878
- package/src/runtime/client/fetcher.js +60 -0
- package/src/runtime/client/parse.js +36 -0
- package/{assets → src/runtime}/client/singletons.js +2 -4
- package/src/runtime/client/start.js +48 -0
- package/src/runtime/client/types.d.ts +106 -0
- package/src/runtime/client/utils.js +113 -0
- package/src/runtime/components/error.svelte +16 -0
- package/{assets → src/runtime}/components/layout.svelte +0 -0
- package/{assets → src/runtime}/env/dynamic/private.js +0 -0
- package/{assets → src/runtime}/env/dynamic/public.js +0 -0
- package/{assets → src/runtime}/env-private.js +2 -4
- package/{assets → src/runtime}/env-public.js +2 -4
- package/src/runtime/env.js +6 -0
- package/src/runtime/hash.js +16 -0
- package/{assets → src/runtime}/paths.js +3 -5
- package/src/runtime/server/endpoint.js +42 -0
- package/src/runtime/server/index.js +434 -0
- package/src/runtime/server/page/cookie.js +25 -0
- package/src/runtime/server/page/crypto.js +239 -0
- package/src/runtime/server/page/csp.js +249 -0
- package/src/runtime/server/page/fetch.js +265 -0
- package/src/runtime/server/page/index.js +423 -0
- package/src/runtime/server/page/load_data.js +94 -0
- package/src/runtime/server/page/render.js +357 -0
- package/src/runtime/server/page/respond_with_error.js +105 -0
- package/src/runtime/server/page/types.d.ts +44 -0
- package/src/runtime/server/utils.js +116 -0
- package/src/utils/error.js +22 -0
- package/src/utils/escape.js +104 -0
- package/{dist/chunks → src/utils}/filesystem.js +22 -24
- package/src/utils/http.js +55 -0
- package/src/utils/misc.js +1 -0
- package/src/utils/routing.js +107 -0
- package/src/utils/url.js +97 -0
- package/src/vite/build/build_server.js +333 -0
- package/src/vite/build/build_service_worker.js +90 -0
- package/src/vite/build/utils.js +152 -0
- package/src/vite/dev/index.js +565 -0
- package/src/vite/index.js +536 -0
- package/src/vite/preview/index.js +186 -0
- package/src/vite/types.d.ts +3 -0
- package/src/vite/utils.js +335 -0
- package/svelte-kit.js +1 -10
- package/types/ambient.d.ts +5 -12
- package/types/index.d.ts +86 -44
- package/types/internal.d.ts +50 -72
- package/types/private.d.ts +2 -1
- package/assets/app/navigation.js +0 -24
- package/assets/app/paths.js +0 -1
- package/assets/components/error.svelte +0 -29
- package/assets/env.js +0 -8
- package/assets/server/index.js +0 -3589
- package/dist/chunks/error.js +0 -12
- package/dist/chunks/index2.js +0 -15745
- package/dist/chunks/multipart-parser.js +0 -458
- package/dist/chunks/sync.js +0 -1366
- package/dist/chunks/utils.js +0 -66
- package/dist/node/polyfills.js +0 -17928
- package/dist/node.js +0 -348
- package/dist/prerender.js +0 -788
- package/dist/vite.js +0 -2513
|
@@ -1,486 +1,32 @@
|
|
|
1
1
|
import { onMount, tick } from 'svelte';
|
|
2
2
|
import { writable } from 'svelte/store';
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
? /** @type {Error} */ (err)
|
|
17
|
-
: new Error(JSON.stringify(err));
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* @param {import('types').LoadOutput | void} loaded
|
|
22
|
-
* @returns {import('types').NormalizedLoadOutput}
|
|
23
|
-
*/
|
|
24
|
-
function normalize(loaded) {
|
|
25
|
-
if (!loaded) {
|
|
26
|
-
return {};
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// TODO remove for 1.0
|
|
30
|
-
// @ts-expect-error
|
|
31
|
-
if (loaded.fallthrough) {
|
|
32
|
-
throw new Error(
|
|
33
|
-
'fallthrough is no longer supported. Use matchers instead: https://kit.svelte.dev/docs/routing#advanced-routing-matching'
|
|
34
|
-
);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
// TODO remove for 1.0
|
|
38
|
-
if ('maxage' in loaded) {
|
|
39
|
-
throw new Error('maxage should be replaced with cache: { maxage }');
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
const has_error_status =
|
|
43
|
-
loaded.status && loaded.status >= 400 && loaded.status <= 599 && !loaded.redirect;
|
|
44
|
-
if (loaded.error || has_error_status) {
|
|
45
|
-
const status = loaded.status;
|
|
46
|
-
|
|
47
|
-
if (!loaded.error && has_error_status) {
|
|
48
|
-
return {
|
|
49
|
-
status: status || 500,
|
|
50
|
-
error: new Error(`${status}`)
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const error = typeof loaded.error === 'string' ? new Error(loaded.error) : loaded.error;
|
|
55
|
-
|
|
56
|
-
if (!(error instanceof Error)) {
|
|
57
|
-
return {
|
|
58
|
-
status: 500,
|
|
59
|
-
error: new Error(
|
|
60
|
-
`"error" property returned from load() must be a string or instance of Error, received type "${typeof error}"`
|
|
61
|
-
)
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
if (!status || status < 400 || status > 599) {
|
|
66
|
-
console.warn('"error" returned from load() without a valid status code — defaulting to 500');
|
|
67
|
-
return { status: 500, error };
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
return { status, error };
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
if (loaded.redirect) {
|
|
74
|
-
if (!loaded.status || Math.floor(loaded.status / 100) !== 3) {
|
|
75
|
-
throw new Error(
|
|
76
|
-
'"redirect" property returned from load() must be accompanied by a 3xx status code'
|
|
77
|
-
);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
if (typeof loaded.redirect !== 'string') {
|
|
81
|
-
throw new Error('"redirect" property returned from load() must be a string');
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
if (loaded.dependencies) {
|
|
86
|
-
if (
|
|
87
|
-
!Array.isArray(loaded.dependencies) ||
|
|
88
|
-
loaded.dependencies.some((dep) => typeof dep !== 'string')
|
|
89
|
-
) {
|
|
90
|
-
throw new Error('"dependencies" property returned from load() must be of type string[]');
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
// TODO remove before 1.0
|
|
95
|
-
if (/** @type {any} */ (loaded).context) {
|
|
96
|
-
throw new Error(
|
|
97
|
-
'You are returning "context" from a load function. ' +
|
|
98
|
-
'"context" was renamed to "stuff", please adjust your code accordingly.'
|
|
99
|
-
);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
return /** @type {import('types').NormalizedLoadOutput} */ (loaded);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* @param {string} path
|
|
107
|
-
* @param {import('types').TrailingSlash} trailing_slash
|
|
108
|
-
*/
|
|
109
|
-
function normalize_path(path, trailing_slash) {
|
|
110
|
-
if (path === '/' || trailing_slash === 'ignore') return path;
|
|
111
|
-
|
|
112
|
-
if (trailing_slash === 'never') {
|
|
113
|
-
return path.endsWith('/') ? path.slice(0, -1) : path;
|
|
114
|
-
} else if (trailing_slash === 'always' && !path.endsWith('/')) {
|
|
115
|
-
return path + '/';
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
return path;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
/** @param {Record<string, string>} params */
|
|
122
|
-
function decode_params(params) {
|
|
123
|
-
for (const key in params) {
|
|
124
|
-
// input has already been decoded by decodeURI
|
|
125
|
-
// now handle the rest that decodeURIComponent would do
|
|
126
|
-
params[key] = params[key]
|
|
127
|
-
.replace(/%23/g, '#')
|
|
128
|
-
.replace(/%3[Bb]/g, ';')
|
|
129
|
-
.replace(/%2[Cc]/g, ',')
|
|
130
|
-
.replace(/%2[Ff]/g, '/')
|
|
131
|
-
.replace(/%3[Ff]/g, '?')
|
|
132
|
-
.replace(/%3[Aa]/g, ':')
|
|
133
|
-
.replace(/%40/g, '@')
|
|
134
|
-
.replace(/%26/g, '&')
|
|
135
|
-
.replace(/%3[Dd]/g, '=')
|
|
136
|
-
.replace(/%2[Bb]/g, '+')
|
|
137
|
-
.replace(/%24/g, '$');
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
return params;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
class LoadURL extends URL {
|
|
144
|
-
/** @returns {string} */
|
|
145
|
-
get hash() {
|
|
146
|
-
throw new Error(
|
|
147
|
-
'url.hash is inaccessible from load. Consider accessing hash from the page store within the script tag of your component.'
|
|
148
|
-
);
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
/* global __SVELTEKIT_APP_VERSION__, __SVELTEKIT_APP_VERSION_FILE__, __SVELTEKIT_APP_VERSION_POLL_INTERVAL__ */
|
|
153
|
-
|
|
154
|
-
/** @param {HTMLDocument} doc */
|
|
155
|
-
function get_base_uri(doc) {
|
|
156
|
-
let baseURI = doc.baseURI;
|
|
157
|
-
|
|
158
|
-
if (!baseURI) {
|
|
159
|
-
const baseTags = doc.getElementsByTagName('base');
|
|
160
|
-
baseURI = baseTags.length ? baseTags[0].href : doc.URL;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
return baseURI;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
function scroll_state() {
|
|
167
|
-
return {
|
|
168
|
-
x: pageXOffset,
|
|
169
|
-
y: pageYOffset
|
|
170
|
-
};
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
/** @param {Event} event */
|
|
174
|
-
function find_anchor(event) {
|
|
175
|
-
const node = event
|
|
176
|
-
.composedPath()
|
|
177
|
-
.find((e) => e instanceof Node && e.nodeName.toUpperCase() === 'A'); // SVG <a> elements have a lowercase name
|
|
178
|
-
return /** @type {HTMLAnchorElement | SVGAElement | undefined} */ (node);
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
/** @param {HTMLAnchorElement | SVGAElement} node */
|
|
182
|
-
function get_href(node) {
|
|
183
|
-
return node instanceof SVGAElement
|
|
184
|
-
? new URL(node.href.baseVal, document.baseURI)
|
|
185
|
-
: new URL(node.href);
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
/** @param {any} value */
|
|
189
|
-
function notifiable_store(value) {
|
|
190
|
-
const store = writable(value);
|
|
191
|
-
let ready = true;
|
|
192
|
-
|
|
193
|
-
function notify() {
|
|
194
|
-
ready = true;
|
|
195
|
-
store.update((val) => val);
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
/** @param {any} new_value */
|
|
199
|
-
function set(new_value) {
|
|
200
|
-
ready = false;
|
|
201
|
-
store.set(new_value);
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
/** @param {(value: any) => void} run */
|
|
205
|
-
function subscribe(run) {
|
|
206
|
-
/** @type {any} */
|
|
207
|
-
let old_value;
|
|
208
|
-
return store.subscribe((new_value) => {
|
|
209
|
-
if (old_value === undefined || (ready && new_value !== old_value)) {
|
|
210
|
-
run((old_value = new_value));
|
|
211
|
-
}
|
|
212
|
-
});
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
return { notify, set, subscribe };
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
function create_updated_store() {
|
|
219
|
-
const { set, subscribe } = writable(false);
|
|
220
|
-
|
|
221
|
-
const interval = __SVELTEKIT_APP_VERSION_POLL_INTERVAL__;
|
|
222
|
-
|
|
223
|
-
/** @type {NodeJS.Timeout} */
|
|
224
|
-
let timeout;
|
|
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';
|
|
225
16
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
clearTimeout(timeout);
|
|
230
|
-
|
|
231
|
-
if (interval) timeout = setTimeout(check, interval);
|
|
232
|
-
|
|
233
|
-
const res = await fetch(`${assets}/${__SVELTEKIT_APP_VERSION_FILE__}`, {
|
|
234
|
-
headers: {
|
|
235
|
-
pragma: 'no-cache',
|
|
236
|
-
'cache-control': 'no-cache'
|
|
237
|
-
}
|
|
238
|
-
});
|
|
239
|
-
|
|
240
|
-
if (res.ok) {
|
|
241
|
-
const { version } = await res.json();
|
|
242
|
-
const updated = version !== __SVELTEKIT_APP_VERSION__;
|
|
243
|
-
|
|
244
|
-
if (updated) {
|
|
245
|
-
set(true);
|
|
246
|
-
clearTimeout(timeout);
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
return updated;
|
|
250
|
-
} else {
|
|
251
|
-
throw new Error(`Version check failed: ${res.status}`);
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
if (interval) timeout = setTimeout(check, interval);
|
|
256
|
-
|
|
257
|
-
return {
|
|
258
|
-
subscribe,
|
|
259
|
-
check
|
|
260
|
-
};
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
/**
|
|
264
|
-
* Hash using djb2
|
|
265
|
-
* @param {import('types').StrictBody} value
|
|
266
|
-
*/
|
|
267
|
-
function hash(value) {
|
|
268
|
-
let hash = 5381;
|
|
269
|
-
let i = value.length;
|
|
270
|
-
|
|
271
|
-
if (typeof value === 'string') {
|
|
272
|
-
while (i) hash = (hash * 33) ^ value.charCodeAt(--i);
|
|
273
|
-
} else {
|
|
274
|
-
while (i) hash = (hash * 33) ^ value[--i];
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
return (hash >>> 0).toString(36);
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
let loading = 0;
|
|
281
|
-
|
|
282
|
-
const native_fetch = window.fetch;
|
|
283
|
-
|
|
284
|
-
function lock_fetch() {
|
|
285
|
-
loading += 1;
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
function unlock_fetch() {
|
|
289
|
-
loading -= 1;
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
if (import.meta.env.DEV) {
|
|
293
|
-
let can_inspect_stack_trace = false;
|
|
294
|
-
|
|
295
|
-
const check_stack_trace = async () => {
|
|
296
|
-
const stack = /** @type {string} */ (new Error().stack);
|
|
297
|
-
can_inspect_stack_trace = stack.includes('check_stack_trace');
|
|
298
|
-
};
|
|
299
|
-
|
|
300
|
-
check_stack_trace();
|
|
301
|
-
|
|
302
|
-
window.fetch = (input, init) => {
|
|
303
|
-
const url = input instanceof Request ? input.url : input.toString();
|
|
304
|
-
const stack = /** @type {string} */ (new Error().stack);
|
|
305
|
-
|
|
306
|
-
const heuristic = can_inspect_stack_trace ? stack.includes('load_node') : loading;
|
|
307
|
-
if (heuristic) {
|
|
308
|
-
console.warn(
|
|
309
|
-
`Loading ${url} using \`window.fetch\`. For best results, use the \`fetch\` that is passed to your \`load\` function: https://kit.svelte.dev/docs/loading#input-fetch`
|
|
310
|
-
);
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
return native_fetch(input, init);
|
|
314
|
-
};
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
/**
|
|
318
|
-
* @param {RequestInfo} resource
|
|
319
|
-
* @param {RequestInit} [opts]
|
|
320
|
-
*/
|
|
321
|
-
function initial_fetch(resource, opts) {
|
|
322
|
-
const url = JSON.stringify(typeof resource === 'string' ? resource : resource.url);
|
|
323
|
-
|
|
324
|
-
let selector = `script[sveltekit\\:data-type="data"][sveltekit\\:data-url=${url}]`;
|
|
325
|
-
|
|
326
|
-
if (opts && typeof opts.body === 'string') {
|
|
327
|
-
selector += `[sveltekit\\:data-body="${hash(opts.body)}"]`;
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
const script = document.querySelector(selector);
|
|
331
|
-
if (script && script.textContent) {
|
|
332
|
-
const { body, ...init } = JSON.parse(script.textContent);
|
|
333
|
-
return Promise.resolve(new Response(body, init));
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
return native_fetch(resource, opts);
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
const param_pattern = /^(\.\.\.)?(\w+)(?:=(\w+))?$/;
|
|
340
|
-
|
|
341
|
-
/** @param {string} id */
|
|
342
|
-
function parse_route_id(id) {
|
|
343
|
-
/** @type {string[]} */
|
|
344
|
-
const names = [];
|
|
345
|
-
|
|
346
|
-
/** @type {string[]} */
|
|
347
|
-
const types = [];
|
|
348
|
-
|
|
349
|
-
// `/foo` should get an optional trailing slash, `/foo.json` should not
|
|
350
|
-
// const add_trailing_slash = !/\.[a-z]+$/.test(key);
|
|
351
|
-
let add_trailing_slash = true;
|
|
352
|
-
|
|
353
|
-
const pattern =
|
|
354
|
-
id === ''
|
|
355
|
-
? /^\/$/
|
|
356
|
-
: new RegExp(
|
|
357
|
-
`^${decodeURIComponent(id)
|
|
358
|
-
.split(/(?:@[a-zA-Z0-9_-]+)?(?:\/|$)/)
|
|
359
|
-
.map((segment, i, segments) => {
|
|
360
|
-
// special case — /[...rest]/ could contain zero segments
|
|
361
|
-
const match = /^\[\.\.\.(\w+)(?:=(\w+))?\]$/.exec(segment);
|
|
362
|
-
if (match) {
|
|
363
|
-
names.push(match[1]);
|
|
364
|
-
types.push(match[2]);
|
|
365
|
-
return '(?:/(.*))?';
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
const is_last = i === segments.length - 1;
|
|
369
|
-
|
|
370
|
-
return (
|
|
371
|
-
segment &&
|
|
372
|
-
'/' +
|
|
373
|
-
segment
|
|
374
|
-
.split(/\[(.+?)\]/)
|
|
375
|
-
.map((content, i) => {
|
|
376
|
-
if (i % 2) {
|
|
377
|
-
const match = param_pattern.exec(content);
|
|
378
|
-
if (!match) {
|
|
379
|
-
throw new Error(
|
|
380
|
-
`Invalid param: ${content}. Params and matcher names can only have underscores and alphanumeric characters.`
|
|
381
|
-
);
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
const [, rest, name, type] = match;
|
|
385
|
-
names.push(name);
|
|
386
|
-
types.push(type);
|
|
387
|
-
return rest ? '(.*?)' : '([^/]+?)';
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
if (is_last && content.includes('.')) add_trailing_slash = false;
|
|
391
|
-
|
|
392
|
-
return (
|
|
393
|
-
content // allow users to specify characters on the file system in an encoded manner
|
|
394
|
-
.normalize()
|
|
395
|
-
// We use [ and ] to denote parameters, so users must encode these on the file
|
|
396
|
-
// system to match against them. We don't decode all characters since others
|
|
397
|
-
// can already be epressed and so that '%' can be easily used directly in filenames
|
|
398
|
-
.replace(/%5[Bb]/g, '[')
|
|
399
|
-
.replace(/%5[Dd]/g, ']')
|
|
400
|
-
// '#', '/', and '?' can only appear in URL path segments in an encoded manner.
|
|
401
|
-
// They will not be touched by decodeURI so need to be encoded here, so
|
|
402
|
-
// that we can match against them.
|
|
403
|
-
// We skip '/' since you can't create a file with it on any OS
|
|
404
|
-
.replace(/#/g, '%23')
|
|
405
|
-
.replace(/\?/g, '%3F')
|
|
406
|
-
// escape characters that have special meaning in regex
|
|
407
|
-
.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
|
|
408
|
-
); // TODO handle encoding
|
|
409
|
-
})
|
|
410
|
-
.join('')
|
|
411
|
-
);
|
|
412
|
-
})
|
|
413
|
-
.join('')}${add_trailing_slash ? '/?' : ''}$`
|
|
414
|
-
);
|
|
415
|
-
|
|
416
|
-
return { pattern, names, types };
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
/**
|
|
420
|
-
* @param {RegExpMatchArray} match
|
|
421
|
-
* @param {string[]} names
|
|
422
|
-
* @param {string[]} types
|
|
423
|
-
* @param {Record<string, import('types').ParamMatcher>} matchers
|
|
424
|
-
*/
|
|
425
|
-
function exec(match, names, types, matchers) {
|
|
426
|
-
/** @type {Record<string, string>} */
|
|
427
|
-
const params = {};
|
|
428
|
-
|
|
429
|
-
for (let i = 0; i < names.length; i += 1) {
|
|
430
|
-
const name = names[i];
|
|
431
|
-
const type = types[i];
|
|
432
|
-
const value = match[i + 1] || '';
|
|
433
|
-
|
|
434
|
-
if (type) {
|
|
435
|
-
const matcher = matchers[type];
|
|
436
|
-
if (!matcher) throw new Error(`Missing "${type}" param matcher`); // TODO do this ahead of time?
|
|
437
|
-
|
|
438
|
-
if (!matcher(value)) return;
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
params[name] = value;
|
|
442
|
-
}
|
|
443
|
-
|
|
444
|
-
return params;
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
/**
|
|
448
|
-
* @param {import('types').CSRComponentLoader[]} components
|
|
449
|
-
* @param {Record<string, [number[], number[], 1?]>} dictionary
|
|
450
|
-
* @param {Record<string, (param: string) => boolean>} matchers
|
|
451
|
-
* @returns {import('types').CSRRoute[]}
|
|
452
|
-
*/
|
|
453
|
-
function parse(components, dictionary, matchers) {
|
|
454
|
-
const routes = Object.entries(dictionary).map(([id, [a, b, has_shadow]]) => {
|
|
455
|
-
const { pattern, names, types } = parse_route_id(id);
|
|
456
|
-
|
|
457
|
-
return {
|
|
458
|
-
id,
|
|
459
|
-
/** @param {string} path */
|
|
460
|
-
exec: (path) => {
|
|
461
|
-
const match = pattern.exec(path);
|
|
462
|
-
if (match) return exec(match, names, types, matchers);
|
|
463
|
-
},
|
|
464
|
-
a: a.map((n) => components[n]),
|
|
465
|
-
b: b.map((n) => components[n]),
|
|
466
|
-
has_shadow: !!has_shadow
|
|
467
|
-
};
|
|
468
|
-
});
|
|
469
|
-
|
|
470
|
-
return routes;
|
|
471
|
-
}
|
|
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';
|
|
472
20
|
|
|
473
21
|
const SCROLL_KEY = 'sveltekit:scroll';
|
|
474
22
|
const INDEX_KEY = 'sveltekit:index';
|
|
475
23
|
|
|
476
|
-
const routes = parse(
|
|
24
|
+
const routes = parse(nodes, dictionary, matchers);
|
|
477
25
|
|
|
478
|
-
// we import the root layout/error
|
|
26
|
+
// we import the root layout/error nodes eagerly, so that
|
|
479
27
|
// connectivity errors after initialisation don't nuke the app
|
|
480
|
-
const default_layout =
|
|
481
|
-
const default_error =
|
|
482
|
-
|
|
483
|
-
const root_stuff = {};
|
|
28
|
+
const default_layout = nodes[0]();
|
|
29
|
+
const default_error = nodes[1]();
|
|
484
30
|
|
|
485
31
|
// We track the scroll position associated with each history entry in sessionStorage,
|
|
486
32
|
// rather than on history.state itself, because when navigation is driven by
|
|
@@ -510,10 +56,7 @@ function update_scroll_positions(index) {
|
|
|
510
56
|
* }} opts
|
|
511
57
|
* @returns {import('./types').Client}
|
|
512
58
|
*/
|
|
513
|
-
function create_client({ target, session, base, trailing_slash }) {
|
|
514
|
-
/** @type {Map<string, import('./types').NavigationResult>} */
|
|
515
|
-
const cache = new Map();
|
|
516
|
-
|
|
59
|
+
export function create_client({ target, session, base, trailing_slash }) {
|
|
517
60
|
/** @type {Array<((href: string) => boolean)>} */
|
|
518
61
|
const invalidated = [];
|
|
519
62
|
|
|
@@ -544,7 +87,6 @@ function create_client({ target, session, base, trailing_slash }) {
|
|
|
544
87
|
branch: [],
|
|
545
88
|
error: null,
|
|
546
89
|
session_id: 0,
|
|
547
|
-
stuff: root_stuff,
|
|
548
90
|
// @ts-ignore - we need the initial value to be null
|
|
549
91
|
url: null
|
|
550
92
|
};
|
|
@@ -573,7 +115,7 @@ function create_client({ target, session, base, trailing_slash }) {
|
|
|
573
115
|
const current_load_uses_session = current.branch.some((node) => node?.uses.session);
|
|
574
116
|
if (!current_load_uses_session) return;
|
|
575
117
|
|
|
576
|
-
update(new URL(location.href), []
|
|
118
|
+
update(new URL(location.href), []);
|
|
577
119
|
});
|
|
578
120
|
ready = true;
|
|
579
121
|
|
|
@@ -651,7 +193,7 @@ function create_client({ target, session, base, trailing_slash }) {
|
|
|
651
193
|
throw new Error('Attempted to prefetch a URL that does not belong to this app');
|
|
652
194
|
}
|
|
653
195
|
|
|
654
|
-
load_cache.promise = load_route(intent
|
|
196
|
+
load_cache.promise = load_route(intent);
|
|
655
197
|
load_cache.id = intent.id;
|
|
656
198
|
|
|
657
199
|
return load_cache.promise;
|
|
@@ -661,15 +203,14 @@ function create_client({ target, session, base, trailing_slash }) {
|
|
|
661
203
|
* Returns `true` if update completes, `false` if it is aborted
|
|
662
204
|
* @param {URL} url
|
|
663
205
|
* @param {string[]} redirect_chain
|
|
664
|
-
* @param {boolean} no_cache
|
|
665
206
|
* @param {{hash?: string, scroll: { x: number, y: number } | null, keepfocus: boolean, details: { replaceState: boolean, state: any } | null}} [opts]
|
|
666
207
|
* @param {() => void} [callback]
|
|
667
208
|
*/
|
|
668
|
-
async function update(url, redirect_chain,
|
|
209
|
+
async function update(url, redirect_chain, opts, callback) {
|
|
669
210
|
const intent = get_navigation_intent(url);
|
|
670
211
|
|
|
671
212
|
const current_token = (token = {});
|
|
672
|
-
let navigation_result = intent && (await load_route(intent
|
|
213
|
+
let navigation_result = intent && (await load_route(intent));
|
|
673
214
|
|
|
674
215
|
if (
|
|
675
216
|
!navigation_result &&
|
|
@@ -703,7 +244,7 @@ function create_client({ target, session, base, trailing_slash }) {
|
|
|
703
244
|
|
|
704
245
|
invalidated.length = 0;
|
|
705
246
|
|
|
706
|
-
if (navigation_result.redirect) {
|
|
247
|
+
if (navigation_result.type === 'redirect') {
|
|
707
248
|
if (redirect_chain.length > 10 || redirect_chain.includes(url.pathname)) {
|
|
708
249
|
navigation_result = await load_root_error_page({
|
|
709
250
|
status: 500,
|
|
@@ -713,12 +254,12 @@ function create_client({ target, session, base, trailing_slash }) {
|
|
|
713
254
|
});
|
|
714
255
|
} else {
|
|
715
256
|
if (router_enabled) {
|
|
716
|
-
goto(new URL(navigation_result.
|
|
257
|
+
goto(new URL(navigation_result.location, url).href, {}, [
|
|
717
258
|
...redirect_chain,
|
|
718
259
|
url.pathname
|
|
719
260
|
]);
|
|
720
261
|
} else {
|
|
721
|
-
await native_navigation(new URL(navigation_result.
|
|
262
|
+
await native_navigation(new URL(navigation_result.location, location.href));
|
|
722
263
|
}
|
|
723
264
|
|
|
724
265
|
return false;
|
|
@@ -808,15 +349,15 @@ function create_client({ target, session, base, trailing_slash }) {
|
|
|
808
349
|
page = navigation_result.props.page;
|
|
809
350
|
}
|
|
810
351
|
|
|
811
|
-
const leaf_node = navigation_result.state.branch
|
|
812
|
-
router_enabled = leaf_node?.
|
|
352
|
+
const leaf_node = navigation_result.state.branch.at(-1);
|
|
353
|
+
router_enabled = leaf_node?.node.shared?.router !== false;
|
|
813
354
|
|
|
814
355
|
if (callback) callback();
|
|
815
356
|
|
|
816
357
|
updating = false;
|
|
817
358
|
}
|
|
818
359
|
|
|
819
|
-
/** @param {import('./types').
|
|
360
|
+
/** @param {import('./types').NavigationFinished} result */
|
|
820
361
|
function initialize(result) {
|
|
821
362
|
current = result.state;
|
|
822
363
|
|
|
@@ -844,57 +385,53 @@ function create_client({ target, session, base, trailing_slash }) {
|
|
|
844
385
|
* @param {{
|
|
845
386
|
* url: URL;
|
|
846
387
|
* params: Record<string, string>;
|
|
847
|
-
* stuff: Record<string, any>;
|
|
848
388
|
* branch: Array<import('./types').BranchNode | undefined>;
|
|
849
389
|
* status: number;
|
|
850
|
-
* error: Error | null;
|
|
390
|
+
* error: HttpError | Error | null;
|
|
851
391
|
* routeId: string | null;
|
|
852
392
|
* }} opts
|
|
853
393
|
*/
|
|
854
394
|
async function get_navigation_result_from_branch({
|
|
855
395
|
url,
|
|
856
396
|
params,
|
|
857
|
-
stuff,
|
|
858
397
|
branch,
|
|
859
398
|
status,
|
|
860
399
|
error,
|
|
861
400
|
routeId
|
|
862
401
|
}) {
|
|
863
402
|
const filtered = /** @type {import('./types').BranchNode[] } */ (branch.filter(Boolean));
|
|
864
|
-
const redirect = filtered.find((f) => f.loaded?.redirect);
|
|
865
403
|
|
|
866
|
-
/** @type {import('./types').
|
|
404
|
+
/** @type {import('./types').NavigationFinished} */
|
|
867
405
|
const result = {
|
|
868
|
-
|
|
406
|
+
type: 'loaded',
|
|
869
407
|
state: {
|
|
870
408
|
url,
|
|
871
409
|
params,
|
|
872
410
|
branch,
|
|
873
411
|
error,
|
|
874
|
-
stuff,
|
|
875
412
|
session_id
|
|
876
413
|
},
|
|
877
414
|
props: {
|
|
878
|
-
components: filtered.map((
|
|
415
|
+
components: filtered.map((branch_node) => branch_node.node.component)
|
|
879
416
|
}
|
|
880
417
|
};
|
|
881
418
|
|
|
419
|
+
let data = {};
|
|
420
|
+
let data_changed = false;
|
|
882
421
|
for (let i = 0; i < filtered.length; i += 1) {
|
|
422
|
+
Object.assign(data, filtered[i].data);
|
|
883
423
|
// Only set props if the node actually updated. This prevents needless rerenders.
|
|
884
424
|
if (!current.branch.some((node) => node === filtered[i])) {
|
|
885
|
-
|
|
886
|
-
|
|
425
|
+
result.props[`data_${i}`] = filtered[i].data;
|
|
426
|
+
data_changed = true;
|
|
887
427
|
}
|
|
888
428
|
}
|
|
889
429
|
|
|
890
430
|
const page_changed =
|
|
891
|
-
!current.url ||
|
|
892
|
-
url.href !== current.url.href ||
|
|
893
|
-
current.error !== error ||
|
|
894
|
-
current.stuff !== stuff;
|
|
431
|
+
!current.url || url.href !== current.url.href || current.error !== error || data_changed;
|
|
895
432
|
|
|
896
433
|
if (page_changed) {
|
|
897
|
-
result.props.page = { error, params, routeId, status,
|
|
434
|
+
result.props.page = { error, params, routeId, status, url, data };
|
|
898
435
|
|
|
899
436
|
// TODO remove this for 1.0
|
|
900
437
|
/**
|
|
@@ -914,72 +451,49 @@ function create_client({ target, session, base, trailing_slash }) {
|
|
|
914
451
|
print_error('query', 'searchParams');
|
|
915
452
|
}
|
|
916
453
|
|
|
917
|
-
const leaf = filtered[filtered.length - 1];
|
|
918
|
-
const load_cache = leaf?.loaded?.cache;
|
|
919
|
-
|
|
920
|
-
if (load_cache) {
|
|
921
|
-
const key = url.pathname + url.search; // omit hash
|
|
922
|
-
let ready = false;
|
|
923
|
-
|
|
924
|
-
const clear = () => {
|
|
925
|
-
if (cache.get(key) === result) {
|
|
926
|
-
cache.delete(key);
|
|
927
|
-
}
|
|
928
|
-
|
|
929
|
-
unsubscribe();
|
|
930
|
-
clearTimeout(timeout);
|
|
931
|
-
};
|
|
932
|
-
|
|
933
|
-
const timeout = setTimeout(clear, load_cache.maxage * 1000);
|
|
934
|
-
|
|
935
|
-
const unsubscribe = stores.session.subscribe(() => {
|
|
936
|
-
if (ready) clear();
|
|
937
|
-
});
|
|
938
|
-
|
|
939
|
-
ready = true;
|
|
940
|
-
|
|
941
|
-
cache.set(key, result);
|
|
942
|
-
}
|
|
943
|
-
|
|
944
454
|
return result;
|
|
945
455
|
}
|
|
946
456
|
|
|
947
457
|
/**
|
|
458
|
+
* Call the load function of the given node, if it exists.
|
|
459
|
+
* If `server_data` is passed, this is treated as the initial run and the page endpoint is not requested.
|
|
460
|
+
*
|
|
948
461
|
* @param {{
|
|
949
|
-
*
|
|
950
|
-
*
|
|
951
|
-
* module: import('types').CSRComponent;
|
|
462
|
+
* node: import('types').CSRPageNode;
|
|
463
|
+
* parent: () => Promise<Record<string, any>>;
|
|
952
464
|
* url: URL;
|
|
953
465
|
* params: Record<string, string>;
|
|
954
|
-
* stuff: Record<string, any>;
|
|
955
|
-
* props?: Record<string, any>;
|
|
956
466
|
* routeId: string | null;
|
|
467
|
+
* server_data: import('types').JSONObject | null;
|
|
957
468
|
* }} options
|
|
469
|
+
* @returns {Promise<import('./types').BranchNode>}
|
|
958
470
|
*/
|
|
959
|
-
async function load_node({
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
session: false,
|
|
967
|
-
stuff: false,
|
|
968
|
-
dependencies: new Set()
|
|
969
|
-
},
|
|
970
|
-
loaded: null,
|
|
971
|
-
stuff
|
|
471
|
+
async function load_node({ node, parent, url, params, routeId, server_data }) {
|
|
472
|
+
const uses = {
|
|
473
|
+
params: new Set(),
|
|
474
|
+
url: false,
|
|
475
|
+
session: false,
|
|
476
|
+
dependencies: new Set(),
|
|
477
|
+
parent: false
|
|
972
478
|
};
|
|
973
479
|
|
|
974
|
-
/** @param
|
|
975
|
-
function
|
|
976
|
-
const
|
|
977
|
-
|
|
480
|
+
/** @param {string[]} deps */
|
|
481
|
+
function depends(...deps) {
|
|
482
|
+
for (const dep of deps) {
|
|
483
|
+
const { href } = new URL(dep, url);
|
|
484
|
+
uses.dependencies.add(href);
|
|
485
|
+
}
|
|
978
486
|
}
|
|
979
487
|
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
488
|
+
/** @type {Record<string, any> | null} */
|
|
489
|
+
let data = null;
|
|
490
|
+
|
|
491
|
+
if (node.server) {
|
|
492
|
+
// +page|layout.server.js data means we need to mark this URL as a dependency of itself,
|
|
493
|
+
// unless we want to get clever with usage detection on the server, which could
|
|
494
|
+
// be returned to the client either as payload or custom headers
|
|
495
|
+
uses.dependencies.add(url.href);
|
|
496
|
+
uses.url = true;
|
|
983
497
|
}
|
|
984
498
|
|
|
985
499
|
/** @type {Record<string, string>} */
|
|
@@ -987,7 +501,7 @@ function create_client({ target, session, base, trailing_slash }) {
|
|
|
987
501
|
for (const key in params) {
|
|
988
502
|
Object.defineProperty(uses_params, key, {
|
|
989
503
|
get() {
|
|
990
|
-
|
|
504
|
+
uses.params.add(key);
|
|
991
505
|
return params[key];
|
|
992
506
|
},
|
|
993
507
|
enumerable: true
|
|
@@ -997,24 +511,20 @@ function create_client({ target, session, base, trailing_slash }) {
|
|
|
997
511
|
const session = $session;
|
|
998
512
|
const load_url = new LoadURL(url);
|
|
999
513
|
|
|
1000
|
-
if (
|
|
514
|
+
if (node.shared?.load) {
|
|
1001
515
|
/** @type {import('types').LoadEvent} */
|
|
1002
516
|
const load_input = {
|
|
1003
517
|
routeId,
|
|
1004
518
|
params: uses_params,
|
|
1005
|
-
|
|
519
|
+
data: server_data,
|
|
1006
520
|
get url() {
|
|
1007
|
-
|
|
521
|
+
uses.url = true;
|
|
1008
522
|
return load_url;
|
|
1009
523
|
},
|
|
1010
524
|
get session() {
|
|
1011
|
-
|
|
525
|
+
uses.session = true;
|
|
1012
526
|
return session;
|
|
1013
527
|
},
|
|
1014
|
-
get stuff() {
|
|
1015
|
-
node.uses.stuff = true;
|
|
1016
|
-
return { ...stuff };
|
|
1017
|
-
},
|
|
1018
528
|
async fetch(resource, init) {
|
|
1019
529
|
let requested;
|
|
1020
530
|
|
|
@@ -1049,61 +559,61 @@ function create_client({ target, session, base, trailing_slash }) {
|
|
|
1049
559
|
|
|
1050
560
|
// we must fixup relative urls so they are resolved from the target page
|
|
1051
561
|
const normalized = new URL(requested, url).href;
|
|
1052
|
-
|
|
562
|
+
depends(normalized);
|
|
1053
563
|
|
|
1054
564
|
// prerendered pages may be served from any origin, so `initial_fetch` urls shouldn't be normalized
|
|
1055
565
|
return started ? native_fetch(normalized, init) : initial_fetch(requested, init);
|
|
1056
566
|
},
|
|
1057
|
-
|
|
1058
|
-
|
|
567
|
+
setHeaders: () => {}, // noop
|
|
568
|
+
depends,
|
|
569
|
+
get parent() {
|
|
570
|
+
// uses.parent assignment here, not on method inokation, else we wouldn't notice when someone
|
|
571
|
+
// does await parent() inside an if branch which wasn't executed yet.
|
|
572
|
+
uses.parent = true;
|
|
573
|
+
return parent;
|
|
574
|
+
},
|
|
575
|
+
// @ts-expect-error
|
|
576
|
+
get props() {
|
|
577
|
+
throw new Error(
|
|
578
|
+
'@migration task: Replace `props` with `data` stuff https://github.com/sveltejs/kit/discussions/5774#discussioncomment-3292693'
|
|
579
|
+
);
|
|
580
|
+
},
|
|
581
|
+
get stuff() {
|
|
582
|
+
throw new Error(
|
|
583
|
+
'@migration task: Remove stuff https://github.com/sveltejs/kit/discussions/5774#discussioncomment-3292693'
|
|
584
|
+
);
|
|
585
|
+
}
|
|
1059
586
|
};
|
|
1060
587
|
|
|
1061
|
-
if (import.meta.env.DEV) {
|
|
1062
|
-
// TODO remove this for 1.0
|
|
1063
|
-
Object.defineProperty(load_input, 'page', {
|
|
1064
|
-
get: () => {
|
|
1065
|
-
throw new Error('`page` in `load` functions has been replaced by `url` and `params`');
|
|
1066
|
-
}
|
|
1067
|
-
});
|
|
1068
|
-
}
|
|
1069
|
-
|
|
1070
588
|
if (import.meta.env.DEV) {
|
|
1071
589
|
try {
|
|
1072
590
|
lock_fetch();
|
|
1073
|
-
|
|
591
|
+
data = (await node.shared.load.call(null, load_input)) ?? null;
|
|
1074
592
|
} finally {
|
|
1075
593
|
unlock_fetch();
|
|
1076
594
|
}
|
|
1077
595
|
} else {
|
|
1078
|
-
|
|
1079
|
-
}
|
|
1080
|
-
|
|
1081
|
-
if (node.loaded.stuff) node.stuff = node.loaded.stuff;
|
|
1082
|
-
if (node.loaded.dependencies) {
|
|
1083
|
-
node.loaded.dependencies.forEach(add_dependency);
|
|
596
|
+
data = (await node.shared.load.call(null, load_input)) ?? null;
|
|
1084
597
|
}
|
|
1085
|
-
} else if (props) {
|
|
1086
|
-
node.loaded = normalize({ props });
|
|
1087
598
|
}
|
|
1088
599
|
|
|
1089
|
-
return
|
|
600
|
+
return {
|
|
601
|
+
node,
|
|
602
|
+
data: data || server_data,
|
|
603
|
+
uses
|
|
604
|
+
};
|
|
1090
605
|
}
|
|
1091
606
|
|
|
1092
607
|
/**
|
|
1093
608
|
* @param {import('./types').NavigationIntent} intent
|
|
1094
|
-
* @
|
|
609
|
+
* @returns {Promise<import('./types').NavigationResult | undefined>}
|
|
1095
610
|
*/
|
|
1096
|
-
async function load_route({ id, url, params, route }
|
|
611
|
+
async function load_route({ id, url, params, route }) {
|
|
1097
612
|
if (load_cache.id === id && load_cache.promise) {
|
|
1098
613
|
return load_cache.promise;
|
|
1099
614
|
}
|
|
1100
615
|
|
|
1101
|
-
|
|
1102
|
-
const cached = cache.get(id);
|
|
1103
|
-
if (cached) return cached;
|
|
1104
|
-
}
|
|
1105
|
-
|
|
1106
|
-
const { a, b, has_shadow } = route;
|
|
616
|
+
const { errors, layouts, leaf } = route;
|
|
1107
617
|
|
|
1108
618
|
const changed = current.url && {
|
|
1109
619
|
url: id !== current.url.pathname + current.url.search,
|
|
@@ -1111,191 +621,175 @@ function create_client({ target, session, base, trailing_slash }) {
|
|
|
1111
621
|
session: session_id !== current.session_id
|
|
1112
622
|
};
|
|
1113
623
|
|
|
1114
|
-
/** @type {Array<import('./types').BranchNode | undefined>} */
|
|
1115
|
-
let branch = [];
|
|
1116
|
-
|
|
1117
|
-
/** @type {Record<string, any>} */
|
|
1118
|
-
let stuff = root_stuff;
|
|
1119
|
-
let stuff_changed = false;
|
|
1120
|
-
|
|
1121
|
-
/** @type {number} */
|
|
1122
|
-
let status = 200;
|
|
1123
|
-
|
|
1124
|
-
/** @type {Error | null} */
|
|
1125
|
-
let error = null;
|
|
1126
|
-
|
|
1127
624
|
// preload modules to avoid waterfall, but handle rejections
|
|
1128
625
|
// so they don't get reported to Sentry et al (we don't need
|
|
1129
626
|
// to act on the failures at this point)
|
|
1130
|
-
|
|
627
|
+
[...errors, ...layouts, leaf].forEach((loader) => loader?.().catch(() => {}));
|
|
1131
628
|
|
|
1132
|
-
|
|
1133
|
-
/** @type {import('./types').BranchNode | undefined} */
|
|
1134
|
-
let node;
|
|
629
|
+
const nodes = [...layouts, leaf];
|
|
1135
630
|
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
631
|
+
// To avoid waterfalls when someone awaits a parent, compute as much as possible here already
|
|
632
|
+
/** @type {boolean[]} */
|
|
633
|
+
const nodes_changed_since_last_render = [];
|
|
634
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
635
|
+
if (!nodes[i]) {
|
|
636
|
+
nodes_changed_since_last_render.push(false);
|
|
637
|
+
} else {
|
|
1140
638
|
const previous = current.branch[i];
|
|
1141
|
-
|
|
1142
639
|
const changed_since_last_render =
|
|
1143
640
|
!previous ||
|
|
1144
|
-
module !== previous.module ||
|
|
1145
641
|
(changed.url && previous.uses.url) ||
|
|
1146
642
|
changed.params.some((param) => previous.uses.params.has(param)) ||
|
|
1147
643
|
(changed.session && previous.uses.session) ||
|
|
1148
644
|
Array.from(previous.uses.dependencies).some((dep) => invalidated.some((fn) => fn(dep))) ||
|
|
1149
|
-
(
|
|
645
|
+
(previous.uses.parent && nodes_changed_since_last_render.includes(true));
|
|
646
|
+
nodes_changed_since_last_render.push(changed_since_last_render);
|
|
647
|
+
}
|
|
648
|
+
}
|
|
1150
649
|
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
let props = {};
|
|
1154
|
-
|
|
1155
|
-
const is_shadow_page = has_shadow && i === a.length - 1;
|
|
1156
|
-
|
|
1157
|
-
if (is_shadow_page) {
|
|
1158
|
-
const res = await native_fetch(
|
|
1159
|
-
`${url.pathname}${url.pathname.endsWith('/') ? '' : '/'}__data.json${url.search}`,
|
|
1160
|
-
{
|
|
1161
|
-
headers: {
|
|
1162
|
-
'x-sveltekit-load': 'true'
|
|
1163
|
-
}
|
|
1164
|
-
}
|
|
1165
|
-
);
|
|
650
|
+
/** @type {import('./types').ServerDataPayload | null} */
|
|
651
|
+
let server_data_payload = null;
|
|
1166
652
|
|
|
1167
|
-
|
|
1168
|
-
|
|
653
|
+
if (route.uses_server_data) {
|
|
654
|
+
try {
|
|
655
|
+
const res = await native_fetch(
|
|
656
|
+
`${url.pathname}${url.pathname.endsWith('/') ? '' : '/'}__data.json${url.search}`
|
|
657
|
+
);
|
|
1169
658
|
|
|
1170
|
-
|
|
1171
|
-
return {
|
|
1172
|
-
redirect,
|
|
1173
|
-
props: {},
|
|
1174
|
-
state: current
|
|
1175
|
-
};
|
|
1176
|
-
}
|
|
659
|
+
server_data_payload = /** @type {import('./types').ServerDataPayload} */ (await res.json());
|
|
1177
660
|
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
error = new Error('Failed to load data');
|
|
1185
|
-
}
|
|
1186
|
-
}
|
|
1187
|
-
}
|
|
661
|
+
if (!res.ok) {
|
|
662
|
+
throw server_data_payload;
|
|
663
|
+
}
|
|
664
|
+
} catch (e) {
|
|
665
|
+
throw new Error('TODO render fallback error page');
|
|
666
|
+
}
|
|
1188
667
|
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
params,
|
|
1194
|
-
props,
|
|
1195
|
-
stuff,
|
|
1196
|
-
routeId: route.id
|
|
1197
|
-
});
|
|
1198
|
-
}
|
|
668
|
+
if (server_data_payload.type === 'redirect') {
|
|
669
|
+
return server_data_payload;
|
|
670
|
+
}
|
|
671
|
+
}
|
|
1199
672
|
|
|
1200
|
-
|
|
1201
|
-
if (is_shadow_page) {
|
|
1202
|
-
node.uses.url = true;
|
|
1203
|
-
}
|
|
673
|
+
const server_data_nodes = server_data_payload?.nodes;
|
|
1204
674
|
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
}
|
|
675
|
+
const branch_promises = nodes.map(async (loader, i) => {
|
|
676
|
+
return Promise.resolve().then(async () => {
|
|
677
|
+
if (!loader) return;
|
|
678
|
+
const node = await loader();
|
|
1210
679
|
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
state: current
|
|
1216
|
-
};
|
|
1217
|
-
}
|
|
680
|
+
/** @type {import('./types').BranchNode | undefined} */
|
|
681
|
+
const previous = current.branch[i];
|
|
682
|
+
const changed_since_last_render =
|
|
683
|
+
nodes_changed_since_last_render[i] || !previous || node !== previous.node;
|
|
1218
684
|
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
685
|
+
if (changed_since_last_render) {
|
|
686
|
+
const payload = server_data_nodes?.[i];
|
|
687
|
+
|
|
688
|
+
if (payload?.status) {
|
|
689
|
+
throw error(payload.status, payload.message);
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
if (payload?.error) {
|
|
693
|
+
throw payload.error;
|
|
1223
694
|
}
|
|
695
|
+
|
|
696
|
+
return await load_node({
|
|
697
|
+
node,
|
|
698
|
+
url,
|
|
699
|
+
params,
|
|
700
|
+
routeId: route.id,
|
|
701
|
+
parent: async () => {
|
|
702
|
+
const data = {};
|
|
703
|
+
for (let j = 0; j < i; j += 1) {
|
|
704
|
+
Object.assign(data, (await branch_promises[j])?.data);
|
|
705
|
+
}
|
|
706
|
+
return data;
|
|
707
|
+
},
|
|
708
|
+
server_data: payload?.data ?? null
|
|
709
|
+
});
|
|
1224
710
|
} else {
|
|
1225
|
-
|
|
711
|
+
return previous;
|
|
1226
712
|
}
|
|
1227
|
-
}
|
|
1228
|
-
|
|
1229
|
-
error = coalesce_to_error(e);
|
|
1230
|
-
}
|
|
713
|
+
});
|
|
714
|
+
});
|
|
1231
715
|
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
if (b[i]) {
|
|
1235
|
-
let error_loaded;
|
|
716
|
+
// if we don't do this, rejections will be unhandled
|
|
717
|
+
for (const p of branch_promises) p.catch(() => {});
|
|
1236
718
|
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
let j = i;
|
|
1240
|
-
while (!(node_loaded = branch[j])) {
|
|
1241
|
-
j -= 1;
|
|
1242
|
-
}
|
|
719
|
+
/** @type {Array<import('./types').BranchNode | undefined>} */
|
|
720
|
+
const branch = [];
|
|
1243
721
|
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
722
|
+
for (let i = 0; i < nodes.length; i += 1) {
|
|
723
|
+
if (nodes[i]) {
|
|
724
|
+
try {
|
|
725
|
+
branch.push(await branch_promises[i]);
|
|
726
|
+
} catch (e) {
|
|
727
|
+
const error = normalize_error(e);
|
|
728
|
+
|
|
729
|
+
if (error instanceof Redirect) {
|
|
730
|
+
return {
|
|
731
|
+
type: 'redirect',
|
|
732
|
+
location: error.location
|
|
733
|
+
};
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
const status = e instanceof HttpError ? e.status : 500;
|
|
737
|
+
|
|
738
|
+
while (i--) {
|
|
739
|
+
if (errors[i]) {
|
|
740
|
+
/** @type {import('./types').BranchNode | undefined} */
|
|
741
|
+
let error_loaded;
|
|
1258
742
|
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
743
|
+
let j = i;
|
|
744
|
+
while (!branch[j]) j -= 1;
|
|
745
|
+
|
|
746
|
+
try {
|
|
747
|
+
error_loaded = {
|
|
748
|
+
node: await errors[i](),
|
|
749
|
+
data: {},
|
|
750
|
+
uses: {
|
|
751
|
+
params: new Set(),
|
|
752
|
+
url: false,
|
|
753
|
+
session: false,
|
|
754
|
+
dependencies: new Set(),
|
|
755
|
+
parent: false
|
|
756
|
+
}
|
|
1263
757
|
};
|
|
1264
|
-
}
|
|
1265
758
|
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
759
|
+
return await get_navigation_result_from_branch({
|
|
760
|
+
url,
|
|
761
|
+
params,
|
|
762
|
+
branch: branch.slice(0, j + 1).concat(error_loaded),
|
|
763
|
+
status,
|
|
764
|
+
error,
|
|
765
|
+
routeId: route.id
|
|
766
|
+
});
|
|
767
|
+
} catch (e) {
|
|
768
|
+
continue;
|
|
769
|
+
}
|
|
1270
770
|
}
|
|
1271
771
|
}
|
|
1272
|
-
}
|
|
1273
772
|
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
} else {
|
|
1281
|
-
if (node?.loaded?.stuff) {
|
|
1282
|
-
stuff = {
|
|
1283
|
-
...stuff,
|
|
1284
|
-
...node.loaded.stuff
|
|
1285
|
-
};
|
|
773
|
+
return await load_root_error_page({
|
|
774
|
+
status,
|
|
775
|
+
error,
|
|
776
|
+
url,
|
|
777
|
+
routeId: route.id
|
|
778
|
+
});
|
|
1286
779
|
}
|
|
1287
|
-
|
|
1288
|
-
|
|
780
|
+
} else {
|
|
781
|
+
// push an empty slot so we can rewind past gaps to the
|
|
782
|
+
// layout that corresponds with an +error.svelte page
|
|
783
|
+
branch.push(undefined);
|
|
1289
784
|
}
|
|
1290
785
|
}
|
|
1291
786
|
|
|
1292
787
|
return await get_navigation_result_from_branch({
|
|
1293
788
|
url,
|
|
1294
789
|
params,
|
|
1295
|
-
stuff,
|
|
1296
790
|
branch,
|
|
1297
|
-
status,
|
|
1298
|
-
error,
|
|
791
|
+
status: 200,
|
|
792
|
+
error: null,
|
|
1299
793
|
routeId: route.id
|
|
1300
794
|
});
|
|
1301
795
|
}
|
|
@@ -1303,7 +797,7 @@ function create_client({ target, session, base, trailing_slash }) {
|
|
|
1303
797
|
/**
|
|
1304
798
|
* @param {{
|
|
1305
799
|
* status: number;
|
|
1306
|
-
* error: Error;
|
|
800
|
+
* error: HttpError | Error;
|
|
1307
801
|
* url: URL;
|
|
1308
802
|
* routeId: string | null
|
|
1309
803
|
* }} opts
|
|
@@ -1313,30 +807,30 @@ function create_client({ target, session, base, trailing_slash }) {
|
|
|
1313
807
|
const params = {}; // error page does not have params
|
|
1314
808
|
|
|
1315
809
|
const root_layout = await load_node({
|
|
1316
|
-
|
|
810
|
+
node: await default_layout,
|
|
1317
811
|
url,
|
|
1318
812
|
params,
|
|
1319
|
-
|
|
1320
|
-
|
|
813
|
+
routeId,
|
|
814
|
+
parent: () => Promise.resolve({}),
|
|
815
|
+
server_data: null // TODO!!!!!
|
|
1321
816
|
});
|
|
1322
817
|
|
|
1323
|
-
const root_error =
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
818
|
+
const root_error = {
|
|
819
|
+
node: await default_error,
|
|
820
|
+
data: null,
|
|
821
|
+
// TODO make this unnecessary
|
|
822
|
+
uses: {
|
|
823
|
+
params: new Set(),
|
|
824
|
+
url: false,
|
|
825
|
+
session: false,
|
|
826
|
+
dependencies: new Set(),
|
|
827
|
+
parent: false
|
|
828
|
+
}
|
|
829
|
+
};
|
|
1332
830
|
|
|
1333
831
|
return await get_navigation_result_from_branch({
|
|
1334
832
|
url,
|
|
1335
833
|
params,
|
|
1336
|
-
stuff: {
|
|
1337
|
-
...root_layout?.loaded?.stuff,
|
|
1338
|
-
...root_error?.loaded?.stuff
|
|
1339
|
-
},
|
|
1340
834
|
branch: [root_layout, root_error],
|
|
1341
835
|
status,
|
|
1342
836
|
error,
|
|
@@ -1410,7 +904,6 @@ function create_client({ target, session, base, trailing_slash }) {
|
|
|
1410
904
|
await update(
|
|
1411
905
|
url,
|
|
1412
906
|
redirect_chain,
|
|
1413
|
-
false,
|
|
1414
907
|
{
|
|
1415
908
|
scroll,
|
|
1416
909
|
keepfocus,
|
|
@@ -1478,7 +971,13 @@ function create_client({ target, session, base, trailing_slash }) {
|
|
|
1478
971
|
goto: (href, opts = {}) => goto(href, opts, []),
|
|
1479
972
|
|
|
1480
973
|
invalidate: (resource) => {
|
|
1481
|
-
if (
|
|
974
|
+
if (resource === undefined) {
|
|
975
|
+
// Force rerun of all load functions, regardless of their dependencies
|
|
976
|
+
for (const node of current.branch) {
|
|
977
|
+
node?.uses.dependencies.add('');
|
|
978
|
+
}
|
|
979
|
+
invalidated.push(() => true);
|
|
980
|
+
} else if (typeof resource === 'function') {
|
|
1482
981
|
invalidated.push(resource);
|
|
1483
982
|
} else {
|
|
1484
983
|
const { href } = new URL(resource, location.href);
|
|
@@ -1487,7 +986,7 @@ function create_client({ target, session, base, trailing_slash }) {
|
|
|
1487
986
|
|
|
1488
987
|
if (!invalidating) {
|
|
1489
988
|
invalidating = Promise.resolve().then(async () => {
|
|
1490
|
-
await update(new URL(location.href), []
|
|
989
|
+
await update(new URL(location.href), []);
|
|
1491
990
|
|
|
1492
991
|
invalidating = null;
|
|
1493
992
|
});
|
|
@@ -1507,7 +1006,9 @@ function create_client({ target, session, base, trailing_slash }) {
|
|
|
1507
1006
|
? routes.filter((route) => pathnames.some((pathname) => route.exec(pathname)))
|
|
1508
1007
|
: routes;
|
|
1509
1008
|
|
|
1510
|
-
const promises = matching.map((r) =>
|
|
1009
|
+
const promises = matching.map((r) => {
|
|
1010
|
+
return Promise.all([...r.layouts, r.leaf].map((load) => load?.()));
|
|
1011
|
+
});
|
|
1511
1012
|
|
|
1512
1013
|
await Promise.all(promises);
|
|
1513
1014
|
},
|
|
@@ -1703,143 +1204,66 @@ function create_client({ target, session, base, trailing_slash }) {
|
|
|
1703
1204
|
});
|
|
1704
1205
|
},
|
|
1705
1206
|
|
|
1706
|
-
_hydrate: async ({ status, error,
|
|
1207
|
+
_hydrate: async ({ status, error, node_ids, params, routeId }) => {
|
|
1707
1208
|
const url = new URL(location.href);
|
|
1708
1209
|
|
|
1709
|
-
/** @type {
|
|
1710
|
-
const branch = [];
|
|
1711
|
-
|
|
1712
|
-
/** @type {Record<string, any>} */
|
|
1713
|
-
let stuff = {};
|
|
1714
|
-
|
|
1715
|
-
/** @type {import('./types').NavigationResult | undefined} */
|
|
1210
|
+
/** @type {import('./types').NavigationFinished | undefined} */
|
|
1716
1211
|
let result;
|
|
1717
1212
|
|
|
1718
|
-
let error_args;
|
|
1719
|
-
|
|
1720
1213
|
try {
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
let props;
|
|
1214
|
+
const script = document.querySelector(`script[sveltekit\\:data-type="server_data"]`);
|
|
1215
|
+
const server_data = script?.textContent ? JSON.parse(script.textContent) : [];
|
|
1725
1216
|
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
props = JSON.parse(/** @type {string} */ (serialized.textContent));
|
|
1730
|
-
}
|
|
1731
|
-
}
|
|
1732
|
-
|
|
1733
|
-
const node = await load_node({
|
|
1734
|
-
module: await components[nodes[i]](),
|
|
1217
|
+
const branch_promises = node_ids.map(async (n, i) => {
|
|
1218
|
+
return load_node({
|
|
1219
|
+
node: await nodes[n](),
|
|
1735
1220
|
url,
|
|
1736
1221
|
params,
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1222
|
+
routeId,
|
|
1223
|
+
parent: async () => {
|
|
1224
|
+
const data = {};
|
|
1225
|
+
for (let j = 0; j < i; j += 1) {
|
|
1226
|
+
Object.assign(data, (await branch_promises[j]).data);
|
|
1227
|
+
}
|
|
1228
|
+
return data;
|
|
1229
|
+
},
|
|
1230
|
+
server_data: server_data[i] ?? null
|
|
1742
1231
|
});
|
|
1232
|
+
});
|
|
1743
1233
|
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1234
|
+
result = await get_navigation_result_from_branch({
|
|
1235
|
+
url,
|
|
1236
|
+
params,
|
|
1237
|
+
branch: await Promise.all(branch_promises),
|
|
1238
|
+
status,
|
|
1239
|
+
error: /** @type {import('../server/page/types').SerializedHttpError} */ (error)
|
|
1240
|
+
?.__is_http_error
|
|
1241
|
+
? new HttpError(
|
|
1242
|
+
/** @type {import('../server/page/types').SerializedHttpError} */ (error).status,
|
|
1243
|
+
error.message
|
|
1244
|
+
)
|
|
1245
|
+
: error,
|
|
1246
|
+
routeId
|
|
1247
|
+
});
|
|
1248
|
+
} catch (e) {
|
|
1249
|
+
const error = normalize_error(e);
|
|
1748
1250
|
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
error_args = {
|
|
1755
|
-
status: node.loaded.status ?? 500,
|
|
1756
|
-
error: node.loaded.error,
|
|
1757
|
-
url,
|
|
1758
|
-
routeId
|
|
1759
|
-
};
|
|
1760
|
-
} else if (node.loaded.stuff) {
|
|
1761
|
-
stuff = {
|
|
1762
|
-
...stuff,
|
|
1763
|
-
...node.loaded.stuff
|
|
1764
|
-
};
|
|
1765
|
-
}
|
|
1766
|
-
}
|
|
1251
|
+
if (error instanceof Redirect) {
|
|
1252
|
+
// this is a real edge case — `load` would need to return
|
|
1253
|
+
// a redirect but only in the browser
|
|
1254
|
+
await native_navigation(new URL(/** @type {Redirect} */ (e).location, location.href));
|
|
1255
|
+
return;
|
|
1767
1256
|
}
|
|
1768
1257
|
|
|
1769
|
-
result = error_args
|
|
1770
|
-
? await load_root_error_page(error_args)
|
|
1771
|
-
: await get_navigation_result_from_branch({
|
|
1772
|
-
url,
|
|
1773
|
-
params,
|
|
1774
|
-
stuff,
|
|
1775
|
-
branch,
|
|
1776
|
-
status,
|
|
1777
|
-
error,
|
|
1778
|
-
routeId
|
|
1779
|
-
});
|
|
1780
|
-
} catch (e) {
|
|
1781
|
-
if (error) throw e;
|
|
1782
|
-
|
|
1783
1258
|
result = await load_root_error_page({
|
|
1784
|
-
status: 500,
|
|
1785
|
-
error
|
|
1259
|
+
status: error instanceof HttpError ? error.status : 500,
|
|
1260
|
+
error,
|
|
1786
1261
|
url,
|
|
1787
1262
|
routeId
|
|
1788
1263
|
});
|
|
1789
1264
|
}
|
|
1790
1265
|
|
|
1791
|
-
if (result.redirect) {
|
|
1792
|
-
// this is a real edge case — `load` would need to return
|
|
1793
|
-
// a redirect but only in the browser
|
|
1794
|
-
await native_navigation(new URL(result.redirect, location.href));
|
|
1795
|
-
}
|
|
1796
|
-
|
|
1797
1266
|
initialize(result);
|
|
1798
1267
|
}
|
|
1799
1268
|
};
|
|
1800
1269
|
}
|
|
1801
|
-
|
|
1802
|
-
/**
|
|
1803
|
-
* @param {{
|
|
1804
|
-
* paths: {
|
|
1805
|
-
* assets: string;
|
|
1806
|
-
* base: string;
|
|
1807
|
-
* },
|
|
1808
|
-
* target: Element;
|
|
1809
|
-
* session: any;
|
|
1810
|
-
* route: boolean;
|
|
1811
|
-
* spa: boolean;
|
|
1812
|
-
* trailing_slash: import('types').TrailingSlash;
|
|
1813
|
-
* hydrate: {
|
|
1814
|
-
* status: number;
|
|
1815
|
-
* error: Error;
|
|
1816
|
-
* nodes: number[];
|
|
1817
|
-
* params: Record<string, string>;
|
|
1818
|
-
* routeId: string | null;
|
|
1819
|
-
* };
|
|
1820
|
-
* }} opts
|
|
1821
|
-
*/
|
|
1822
|
-
async function start({ paths, target, session, route, spa, trailing_slash, hydrate }) {
|
|
1823
|
-
const client = create_client({
|
|
1824
|
-
target,
|
|
1825
|
-
session,
|
|
1826
|
-
base: paths.base,
|
|
1827
|
-
trailing_slash
|
|
1828
|
-
});
|
|
1829
|
-
|
|
1830
|
-
init({ client });
|
|
1831
|
-
set_paths(paths);
|
|
1832
|
-
|
|
1833
|
-
if (hydrate) {
|
|
1834
|
-
await client._hydrate(hydrate);
|
|
1835
|
-
}
|
|
1836
|
-
|
|
1837
|
-
if (route) {
|
|
1838
|
-
if (spa) client.goto(location.href, { replaceState: true });
|
|
1839
|
-
client._start_router();
|
|
1840
|
-
}
|
|
1841
|
-
|
|
1842
|
-
dispatchEvent(new CustomEvent('sveltekit:start'));
|
|
1843
|
-
}
|
|
1844
|
-
|
|
1845
|
-
export { start };
|