@sveltejs/kit 1.0.0-next.46 → 1.0.0-next.460
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/README.md +12 -9
- package/package.json +93 -65
- package/scripts/special-types/$env+dynamic+private.md +8 -0
- package/scripts/special-types/$env+dynamic+public.md +8 -0
- package/scripts/special-types/$env+static+private.md +19 -0
- package/scripts/special-types/$env+static+public.md +7 -0
- package/scripts/special-types/$lib.md +1 -0
- package/src/cli.js +112 -0
- package/src/constants.js +7 -0
- package/src/core/adapt/builder.js +207 -0
- package/src/core/adapt/index.js +31 -0
- package/src/core/config/default-error.html +56 -0
- package/src/core/config/index.js +105 -0
- package/src/core/config/options.js +498 -0
- package/src/core/config/types.d.ts +1 -0
- package/src/core/env.js +112 -0
- package/src/core/generate_manifest/index.js +78 -0
- package/src/core/prerender/crawl.js +194 -0
- package/src/core/prerender/prerender.js +425 -0
- package/src/core/prerender/queue.js +80 -0
- package/src/core/sync/create_manifest_data/index.js +452 -0
- package/src/core/sync/create_manifest_data/types.d.ts +37 -0
- package/src/core/sync/sync.js +59 -0
- package/src/core/sync/utils.js +33 -0
- package/src/core/sync/write_ambient.js +53 -0
- package/src/core/sync/write_client_manifest.js +94 -0
- package/src/core/sync/write_matchers.js +25 -0
- package/src/core/sync/write_root.js +91 -0
- package/src/core/sync/write_tsconfig.js +195 -0
- package/src/core/sync/write_types/index.js +595 -0
- package/src/core/utils.js +70 -0
- package/src/exports/hooks/index.js +1 -0
- package/src/exports/hooks/sequence.js +44 -0
- package/src/exports/index.js +45 -0
- package/src/exports/node/index.js +145 -0
- package/src/exports/node/polyfills.js +40 -0
- package/src/exports/vite/build/build_server.js +349 -0
- package/src/exports/vite/build/build_service_worker.js +90 -0
- package/src/exports/vite/build/utils.js +160 -0
- package/src/exports/vite/dev/index.js +543 -0
- package/src/exports/vite/index.js +595 -0
- package/src/exports/vite/preview/index.js +186 -0
- package/src/exports/vite/types.d.ts +3 -0
- package/src/exports/vite/utils.js +345 -0
- package/src/runtime/app/env.js +1 -0
- package/src/runtime/app/environment.js +11 -0
- package/src/runtime/app/navigation.js +22 -0
- package/src/runtime/app/paths.js +1 -0
- package/src/runtime/app/stores.js +102 -0
- package/src/runtime/client/ambient.d.ts +24 -0
- package/src/runtime/client/client.js +1387 -0
- package/src/runtime/client/fetcher.js +60 -0
- package/src/runtime/client/parse.js +60 -0
- package/src/runtime/client/singletons.js +21 -0
- package/src/runtime/client/start.js +45 -0
- package/src/runtime/client/types.d.ts +88 -0
- package/src/runtime/client/utils.js +140 -0
- package/src/runtime/components/error.svelte +16 -0
- package/{assets → src/runtime}/components/layout.svelte +0 -0
- package/src/runtime/control.js +33 -0
- package/src/runtime/env/dynamic/private.js +1 -0
- package/src/runtime/env/dynamic/public.js +1 -0
- package/src/runtime/env-private.js +6 -0
- package/src/runtime/env-public.js +6 -0
- package/src/runtime/env.js +6 -0
- package/src/runtime/hash.js +16 -0
- package/src/runtime/paths.js +11 -0
- package/src/runtime/server/data/index.js +146 -0
- package/src/runtime/server/endpoint.js +63 -0
- package/src/runtime/server/index.js +339 -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 +269 -0
- package/src/runtime/server/page/index.js +404 -0
- package/src/runtime/server/page/load_data.js +124 -0
- package/src/runtime/server/page/render.js +358 -0
- package/src/runtime/server/page/respond_with_error.js +92 -0
- package/src/runtime/server/page/serialize_data.js +58 -0
- package/src/runtime/server/page/types.d.ts +44 -0
- package/src/runtime/server/utils.js +209 -0
- package/src/utils/array.js +9 -0
- package/src/utils/error.js +22 -0
- package/src/utils/escape.js +46 -0
- package/src/utils/filesystem.js +108 -0
- package/src/utils/functions.js +16 -0
- package/src/utils/http.js +55 -0
- package/src/utils/misc.js +1 -0
- package/src/utils/routing.js +137 -0
- package/src/utils/url.js +142 -0
- package/svelte-kit.js +1 -1
- package/types/ambient.d.ts +332 -0
- package/types/index.d.ts +343 -0
- package/types/internal.d.ts +383 -0
- package/types/private.d.ts +213 -0
- package/CHANGELOG.md +0 -456
- package/assets/components/error.svelte +0 -13
- package/assets/runtime/app/env.js +0 -5
- package/assets/runtime/app/navigation.js +0 -44
- package/assets/runtime/app/paths.js +0 -1
- package/assets/runtime/app/stores.js +0 -93
- package/assets/runtime/chunks/utils.js +0 -22
- package/assets/runtime/internal/singletons.js +0 -23
- package/assets/runtime/internal/start.js +0 -771
- package/assets/runtime/paths.js +0 -12
- package/dist/chunks/index.js +0 -3522
- package/dist/chunks/index2.js +0 -587
- package/dist/chunks/index3.js +0 -246
- package/dist/chunks/index4.js +0 -539
- package/dist/chunks/index5.js +0 -763
- package/dist/chunks/index6.js +0 -322
- package/dist/chunks/standard.js +0 -99
- package/dist/chunks/utils.js +0 -83
- package/dist/cli.js +0 -546
- package/dist/ssr.js +0 -2581
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { hash } from '../hash.js';
|
|
2
|
+
|
|
3
|
+
let loading = 0;
|
|
4
|
+
|
|
5
|
+
export const native_fetch = window.fetch;
|
|
6
|
+
|
|
7
|
+
export function lock_fetch() {
|
|
8
|
+
loading += 1;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function unlock_fetch() {
|
|
12
|
+
loading -= 1;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
if (import.meta.env.DEV) {
|
|
16
|
+
let can_inspect_stack_trace = false;
|
|
17
|
+
|
|
18
|
+
const check_stack_trace = async () => {
|
|
19
|
+
const stack = /** @type {string} */ (new Error().stack);
|
|
20
|
+
can_inspect_stack_trace = stack.includes('check_stack_trace');
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
check_stack_trace();
|
|
24
|
+
|
|
25
|
+
window.fetch = (input, init) => {
|
|
26
|
+
const url = input instanceof Request ? input.url : input.toString();
|
|
27
|
+
const stack = /** @type {string} */ (new Error().stack);
|
|
28
|
+
|
|
29
|
+
const heuristic = can_inspect_stack_trace ? stack.includes('load_node') : loading;
|
|
30
|
+
if (heuristic) {
|
|
31
|
+
console.warn(
|
|
32
|
+
`Loading ${url} using \`window.fetch\`. For best results, use the \`fetch\` that is passed to your \`load\` function: https://kit.svelte.dev/docs/load#input-fetch`
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return native_fetch(input, init);
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* @param {RequestInfo} resource
|
|
42
|
+
* @param {RequestInit} [opts]
|
|
43
|
+
*/
|
|
44
|
+
export function initial_fetch(resource, opts) {
|
|
45
|
+
const url = JSON.stringify(typeof resource === 'string' ? resource : resource.url);
|
|
46
|
+
|
|
47
|
+
let selector = `script[data-sveltekit-fetched][data-url=${url}]`;
|
|
48
|
+
|
|
49
|
+
if (opts && typeof opts.body === 'string') {
|
|
50
|
+
selector += `[data-hash="${hash(opts.body)}"]`;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const script = document.querySelector(selector);
|
|
54
|
+
if (script && script.textContent) {
|
|
55
|
+
const { body, ...init } = JSON.parse(script.textContent);
|
|
56
|
+
return Promise.resolve(new Response(body, init));
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return native_fetch(resource, opts);
|
|
60
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { exec, parse_route_id } from '../../utils/routing.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @param {import('types').CSRPageNodeLoader[]} nodes
|
|
5
|
+
* @param {number[]} server_loads
|
|
6
|
+
* @param {typeof import('__GENERATED__/client-manifest.js').dictionary} dictionary
|
|
7
|
+
* @param {Record<string, (param: string) => boolean>} matchers
|
|
8
|
+
* @returns {import('types').CSRRoute[]}
|
|
9
|
+
*/
|
|
10
|
+
export function parse(nodes, server_loads, dictionary, matchers) {
|
|
11
|
+
const layouts_with_server_load = new Set(server_loads);
|
|
12
|
+
|
|
13
|
+
return Object.entries(dictionary).map(([id, [leaf, layouts, errors]]) => {
|
|
14
|
+
const { pattern, names, types } = parse_route_id(id);
|
|
15
|
+
|
|
16
|
+
const route = {
|
|
17
|
+
id,
|
|
18
|
+
/** @param {string} path */
|
|
19
|
+
exec: (path) => {
|
|
20
|
+
const match = pattern.exec(path);
|
|
21
|
+
if (match) return exec(match, names, types, matchers);
|
|
22
|
+
},
|
|
23
|
+
errors: [1, ...(errors || [])].map((n) => nodes[n]),
|
|
24
|
+
layouts: [0, ...(layouts || [])].map(create_layout_loader),
|
|
25
|
+
leaf: create_leaf_loader(leaf)
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
// bit of a hack, but ensures that layout/error node lists are the same
|
|
29
|
+
// length, without which the wrong data will be applied if the route
|
|
30
|
+
// manifest looks like `[[a, b], [c,], d]`
|
|
31
|
+
route.errors.length = route.layouts.length = Math.max(
|
|
32
|
+
route.errors.length,
|
|
33
|
+
route.layouts.length
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
return route;
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* @param {number} id
|
|
41
|
+
* @returns {[boolean, import('types').CSRPageNodeLoader]}
|
|
42
|
+
*/
|
|
43
|
+
function create_leaf_loader(id) {
|
|
44
|
+
// whether or not the route uses the server data is
|
|
45
|
+
// encoded using the ones' complement, to save space
|
|
46
|
+
const uses_server_data = id < 0;
|
|
47
|
+
if (uses_server_data) id = ~id;
|
|
48
|
+
return [uses_server_data, nodes[id]];
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* @param {number | undefined} id
|
|
53
|
+
* @returns {[boolean, import('types').CSRPageNodeLoader] | undefined}
|
|
54
|
+
*/
|
|
55
|
+
function create_layout_loader(id) {
|
|
56
|
+
// whether or not the layout uses the server data is
|
|
57
|
+
// encoded in the layouts array, to save space
|
|
58
|
+
return id === undefined ? id : [layouts_with_server_load.has(id), nodes[id]];
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { writable } from 'svelte/store';
|
|
2
|
+
import { create_updated_store, notifiable_store } from './utils.js';
|
|
3
|
+
|
|
4
|
+
/** @type {import('./types').Client} */
|
|
5
|
+
export let client;
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @param {{
|
|
9
|
+
* client: import('./types').Client;
|
|
10
|
+
* }} opts
|
|
11
|
+
*/
|
|
12
|
+
export function init(opts) {
|
|
13
|
+
client = opts.client;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const stores = {
|
|
17
|
+
url: notifiable_store({}),
|
|
18
|
+
page: notifiable_store({}),
|
|
19
|
+
navigating: writable(/** @type {import('types').Navigation | null} */ (null)),
|
|
20
|
+
updated: create_updated_store()
|
|
21
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { create_client } from './client.js';
|
|
2
|
+
import { init } from './singletons.js';
|
|
3
|
+
import { set_paths } from '../paths.js';
|
|
4
|
+
import { set_public_env } from '../env-public.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @param {{
|
|
8
|
+
* env: Record<string, string>;
|
|
9
|
+
* hydrate: {
|
|
10
|
+
* status: number;
|
|
11
|
+
* error: Error | (import('../server/page/types').SerializedHttpError);
|
|
12
|
+
* node_ids: number[];
|
|
13
|
+
* params: Record<string, string>;
|
|
14
|
+
* routeId: string | null;
|
|
15
|
+
* data: Array<import('types').ServerDataNode | null>;
|
|
16
|
+
* errors: Record<string, any> | null;
|
|
17
|
+
* };
|
|
18
|
+
* paths: {
|
|
19
|
+
* assets: string;
|
|
20
|
+
* base: string;
|
|
21
|
+
* },
|
|
22
|
+
* target: Element;
|
|
23
|
+
* trailing_slash: import('types').TrailingSlash;
|
|
24
|
+
* }} opts
|
|
25
|
+
*/
|
|
26
|
+
export async function start({ env, hydrate, paths, target, trailing_slash }) {
|
|
27
|
+
set_public_env(env);
|
|
28
|
+
set_paths(paths);
|
|
29
|
+
|
|
30
|
+
const client = create_client({
|
|
31
|
+
target,
|
|
32
|
+
base: paths.base,
|
|
33
|
+
trailing_slash
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
init({ client });
|
|
37
|
+
|
|
38
|
+
if (hydrate) {
|
|
39
|
+
await client._hydrate(hydrate);
|
|
40
|
+
} else {
|
|
41
|
+
client.goto(location.href, { replaceState: true });
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
client._start_router();
|
|
45
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import {
|
|
2
|
+
afterNavigate,
|
|
3
|
+
beforeNavigate,
|
|
4
|
+
goto,
|
|
5
|
+
invalidate,
|
|
6
|
+
prefetch,
|
|
7
|
+
prefetchRoutes
|
|
8
|
+
} from '$app/navigation';
|
|
9
|
+
import { CSRPageNode, CSRPageNodeLoader, CSRRoute, Uses } from 'types';
|
|
10
|
+
import { HttpError } from '../control.js';
|
|
11
|
+
import { SerializedHttpError } from '../server/page/types.js';
|
|
12
|
+
|
|
13
|
+
export interface Client {
|
|
14
|
+
// public API, exposed via $app/navigation
|
|
15
|
+
after_navigate: typeof afterNavigate;
|
|
16
|
+
before_navigate: typeof beforeNavigate;
|
|
17
|
+
disable_scroll_handling: () => void;
|
|
18
|
+
goto: typeof goto;
|
|
19
|
+
invalidate: typeof invalidate;
|
|
20
|
+
prefetch: typeof prefetch;
|
|
21
|
+
prefetch_routes: typeof prefetchRoutes;
|
|
22
|
+
|
|
23
|
+
// private API
|
|
24
|
+
_hydrate: (opts: {
|
|
25
|
+
status: number;
|
|
26
|
+
error: Error | SerializedHttpError;
|
|
27
|
+
node_ids: number[];
|
|
28
|
+
params: Record<string, string>;
|
|
29
|
+
routeId: string | null;
|
|
30
|
+
data: Array<import('types').ServerDataNode | null>;
|
|
31
|
+
errors: Record<string, any> | null;
|
|
32
|
+
}) => Promise<void>;
|
|
33
|
+
_start_router: () => void;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export type NavigationIntent = {
|
|
37
|
+
/**
|
|
38
|
+
* `url.pathname + url.search`
|
|
39
|
+
*/
|
|
40
|
+
id: string;
|
|
41
|
+
/**
|
|
42
|
+
* The route parameters
|
|
43
|
+
*/
|
|
44
|
+
params: Record<string, string>;
|
|
45
|
+
/**
|
|
46
|
+
* The route that matches `path`
|
|
47
|
+
*/
|
|
48
|
+
route: CSRRoute;
|
|
49
|
+
/**
|
|
50
|
+
* The destination URL
|
|
51
|
+
*/
|
|
52
|
+
url: URL;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export type NavigationResult = NavigationRedirect | NavigationFinished;
|
|
56
|
+
|
|
57
|
+
export type NavigationRedirect = {
|
|
58
|
+
type: 'redirect';
|
|
59
|
+
location: string;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
export type NavigationFinished = {
|
|
63
|
+
type: 'loaded';
|
|
64
|
+
state: NavigationState;
|
|
65
|
+
props: Record<string, any>;
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
export type BranchNode = {
|
|
69
|
+
node: CSRPageNode;
|
|
70
|
+
loader: CSRPageNodeLoader;
|
|
71
|
+
server: DataNode | null;
|
|
72
|
+
shared: DataNode | null;
|
|
73
|
+
data: Record<string, any> | null;
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
export interface DataNode {
|
|
77
|
+
type: 'data';
|
|
78
|
+
data: Record<string, any> | null;
|
|
79
|
+
uses: Uses;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export type NavigationState = {
|
|
83
|
+
branch: Array<BranchNode | undefined>;
|
|
84
|
+
error: HttpError | Error | null;
|
|
85
|
+
params: Record<string, string>;
|
|
86
|
+
session_id: number;
|
|
87
|
+
url: URL;
|
|
88
|
+
};
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { writable } from 'svelte/store';
|
|
2
|
+
import { assets } from '../paths.js';
|
|
3
|
+
|
|
4
|
+
/* global __SVELTEKIT_APP_VERSION__, __SVELTEKIT_APP_VERSION_FILE__, __SVELTEKIT_APP_VERSION_POLL_INTERVAL__ */
|
|
5
|
+
|
|
6
|
+
/** @param {HTMLDocument} doc */
|
|
7
|
+
export function get_base_uri(doc) {
|
|
8
|
+
let baseURI = doc.baseURI;
|
|
9
|
+
|
|
10
|
+
if (!baseURI) {
|
|
11
|
+
const baseTags = doc.getElementsByTagName('base');
|
|
12
|
+
baseURI = baseTags.length ? baseTags[0].href : doc.URL;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
return baseURI;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function scroll_state() {
|
|
19
|
+
return {
|
|
20
|
+
x: pageXOffset,
|
|
21
|
+
y: pageYOffset
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** @param {Event} event */
|
|
26
|
+
export function find_anchor(event) {
|
|
27
|
+
/** @type {HTMLAnchorElement | SVGAElement | undefined} */
|
|
28
|
+
let a;
|
|
29
|
+
|
|
30
|
+
const options = {
|
|
31
|
+
/** @type {string | null} */
|
|
32
|
+
noscroll: null,
|
|
33
|
+
|
|
34
|
+
/** @type {string | null} */
|
|
35
|
+
prefetch: null,
|
|
36
|
+
|
|
37
|
+
/** @type {string | null} */
|
|
38
|
+
reload: null
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
for (const element of event.composedPath()) {
|
|
42
|
+
if (!(element instanceof Element)) continue;
|
|
43
|
+
|
|
44
|
+
if (!a && element.nodeName.toUpperCase() === 'A') {
|
|
45
|
+
// SVG <a> elements have a lowercase name
|
|
46
|
+
a = /** @type {HTMLAnchorElement | SVGAElement} */ (element);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (options.noscroll === null) {
|
|
50
|
+
options.noscroll = element.getAttribute('data-sveltekit-noscroll');
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (options.prefetch === null) {
|
|
54
|
+
options.prefetch = element.getAttribute('data-sveltekit-prefetch');
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (options.reload === null) {
|
|
58
|
+
options.reload = element.getAttribute('data-sveltekit-reload');
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const url = a && new URL(a instanceof SVGAElement ? a.href.baseVal : a.href, document.baseURI);
|
|
63
|
+
|
|
64
|
+
return { a, url, options };
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** @param {any} value */
|
|
68
|
+
export function notifiable_store(value) {
|
|
69
|
+
const store = writable(value);
|
|
70
|
+
let ready = true;
|
|
71
|
+
|
|
72
|
+
function notify() {
|
|
73
|
+
ready = true;
|
|
74
|
+
store.update((val) => val);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** @param {any} new_value */
|
|
78
|
+
function set(new_value) {
|
|
79
|
+
ready = false;
|
|
80
|
+
store.set(new_value);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/** @param {(value: any) => void} run */
|
|
84
|
+
function subscribe(run) {
|
|
85
|
+
/** @type {any} */
|
|
86
|
+
let old_value;
|
|
87
|
+
return store.subscribe((new_value) => {
|
|
88
|
+
if (old_value === undefined || (ready && new_value !== old_value)) {
|
|
89
|
+
run((old_value = new_value));
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return { notify, set, subscribe };
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export function create_updated_store() {
|
|
98
|
+
const { set, subscribe } = writable(false);
|
|
99
|
+
|
|
100
|
+
const interval = __SVELTEKIT_APP_VERSION_POLL_INTERVAL__;
|
|
101
|
+
|
|
102
|
+
/** @type {NodeJS.Timeout} */
|
|
103
|
+
let timeout;
|
|
104
|
+
|
|
105
|
+
async function check() {
|
|
106
|
+
if (import.meta.env.DEV || import.meta.env.SSR) return false;
|
|
107
|
+
|
|
108
|
+
clearTimeout(timeout);
|
|
109
|
+
|
|
110
|
+
if (interval) timeout = setTimeout(check, interval);
|
|
111
|
+
|
|
112
|
+
const res = await fetch(`${assets}/${__SVELTEKIT_APP_VERSION_FILE__}`, {
|
|
113
|
+
headers: {
|
|
114
|
+
pragma: 'no-cache',
|
|
115
|
+
'cache-control': 'no-cache'
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
if (res.ok) {
|
|
120
|
+
const { version } = await res.json();
|
|
121
|
+
const updated = version !== __SVELTEKIT_APP_VERSION__;
|
|
122
|
+
|
|
123
|
+
if (updated) {
|
|
124
|
+
set(true);
|
|
125
|
+
clearTimeout(timeout);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return updated;
|
|
129
|
+
} else {
|
|
130
|
+
throw new Error(`Version check failed: ${res.status}`);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (interval) timeout = setTimeout(check, interval);
|
|
135
|
+
|
|
136
|
+
return {
|
|
137
|
+
subscribe,
|
|
138
|
+
check
|
|
139
|
+
};
|
|
140
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import { page } from '$app/stores';
|
|
3
|
+
</script>
|
|
4
|
+
|
|
5
|
+
<h1>{$page.status}</h1>
|
|
6
|
+
|
|
7
|
+
<pre>{$page.error.message}</pre>
|
|
8
|
+
|
|
9
|
+
<!-- TODO figure out what to do with frames/stacktraces in prod -->
|
|
10
|
+
<!-- frame is populated by Svelte in its CompileError and is a Rollup/Vite convention -->
|
|
11
|
+
{#if $page.error.frame}
|
|
12
|
+
<pre>{$page.error.frame}</pre>
|
|
13
|
+
{/if}
|
|
14
|
+
{#if $page.error.stack}
|
|
15
|
+
<pre>{$page.error.stack}</pre>
|
|
16
|
+
{/if}
|
|
File without changes
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export class HttpError {
|
|
2
|
+
// without these, things like `$page.error.stack` will error. we don't want to
|
|
3
|
+
// include a stack for these sorts of errors, but we also don't want red
|
|
4
|
+
// squigglies everywhere, so this feels like a not-terribile compromise
|
|
5
|
+
name = 'HttpError';
|
|
6
|
+
|
|
7
|
+
/** @type {void} */
|
|
8
|
+
stack = undefined;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @param {number} status
|
|
12
|
+
* @param {string | undefined} message
|
|
13
|
+
*/
|
|
14
|
+
constructor(status, message) {
|
|
15
|
+
this.status = status;
|
|
16
|
+
this.message = message ?? `Error: ${status}`;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
toString() {
|
|
20
|
+
return this.message;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export class Redirect {
|
|
25
|
+
/**
|
|
26
|
+
* @param {number} status
|
|
27
|
+
* @param {string} location
|
|
28
|
+
*/
|
|
29
|
+
constructor(status, location) {
|
|
30
|
+
this.status = status;
|
|
31
|
+
this.location = location;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { env } from '../../env-private.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { env } from '../../env-public.js';
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hash using djb2
|
|
3
|
+
* @param {import('types').StrictBody} value
|
|
4
|
+
*/
|
|
5
|
+
export function hash(value) {
|
|
6
|
+
let hash = 5381;
|
|
7
|
+
let i = value.length;
|
|
8
|
+
|
|
9
|
+
if (typeof value === 'string') {
|
|
10
|
+
while (i) hash = (hash * 33) ^ value.charCodeAt(--i);
|
|
11
|
+
} else {
|
|
12
|
+
while (i) hash = (hash * 33) ^ value[--i];
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
return (hash >>> 0).toString(36);
|
|
16
|
+
}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { HttpError, Redirect } from '../../control.js';
|
|
2
|
+
import { normalize_error } from '../../../utils/error.js';
|
|
3
|
+
import { once } from '../../../utils/functions.js';
|
|
4
|
+
import { load_server_data } from '../page/load_data.js';
|
|
5
|
+
import { data_response, error_to_pojo } from '../utils.js';
|
|
6
|
+
import { normalize_path } from '../../../utils/url.js';
|
|
7
|
+
import { DATA_SUFFIX } from '../../../constants.js';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @param {import('types').RequestEvent} event
|
|
11
|
+
* @param {import('types').SSRRoute} route
|
|
12
|
+
* @param {import('types').SSROptions} options
|
|
13
|
+
* @param {import('types').SSRState} state
|
|
14
|
+
* @returns {Promise<Response>}
|
|
15
|
+
*/
|
|
16
|
+
export async function render_data(event, route, options, state) {
|
|
17
|
+
if (!route.page) {
|
|
18
|
+
// requesting /__data.js should fail for a +server.js
|
|
19
|
+
return new Response(undefined, {
|
|
20
|
+
status: 404
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
try {
|
|
25
|
+
const node_ids = [...route.page.layouts, route.page.leaf];
|
|
26
|
+
|
|
27
|
+
const invalidated =
|
|
28
|
+
event.url.searchParams
|
|
29
|
+
.get('__invalid')
|
|
30
|
+
?.split('')
|
|
31
|
+
.map((x) => x === 'y') ?? node_ids.map(() => true);
|
|
32
|
+
|
|
33
|
+
let aborted = false;
|
|
34
|
+
|
|
35
|
+
const url = new URL(event.url);
|
|
36
|
+
url.pathname = normalize_path(
|
|
37
|
+
url.pathname.slice(0, -DATA_SUFFIX.length),
|
|
38
|
+
options.trailing_slash
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
url.searchParams.delete('__invalid');
|
|
42
|
+
url.searchParams.delete('__id');
|
|
43
|
+
|
|
44
|
+
const new_event = { ...event, url };
|
|
45
|
+
|
|
46
|
+
const functions = node_ids.map((n, i) => {
|
|
47
|
+
return once(async () => {
|
|
48
|
+
try {
|
|
49
|
+
if (aborted) {
|
|
50
|
+
return /** @type {import('types').ServerDataSkippedNode} */ ({
|
|
51
|
+
type: 'skip'
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// == because it could be undefined (in dev) or null (in build, because of JSON.stringify)
|
|
56
|
+
const node = n == undefined ? n : await options.manifest._.nodes[n]();
|
|
57
|
+
return load_server_data({
|
|
58
|
+
event: new_event,
|
|
59
|
+
state,
|
|
60
|
+
node,
|
|
61
|
+
parent: async () => {
|
|
62
|
+
/** @type {Record<string, any>} */
|
|
63
|
+
const data = {};
|
|
64
|
+
for (let j = 0; j < i; j += 1) {
|
|
65
|
+
const parent = /** @type {import('types').ServerDataNode | null} */ (
|
|
66
|
+
await functions[j]()
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
if (parent) {
|
|
70
|
+
Object.assign(data, parent.data);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return data;
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
} catch (e) {
|
|
77
|
+
aborted = true;
|
|
78
|
+
throw e;
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
const promises = functions.map(async (fn, i) => {
|
|
84
|
+
if (!invalidated[i]) {
|
|
85
|
+
return /** @type {import('types').ServerDataSkippedNode} */ ({
|
|
86
|
+
type: 'skip'
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return fn();
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
let length = promises.length;
|
|
94
|
+
const nodes = await Promise.all(
|
|
95
|
+
promises.map((p, i) =>
|
|
96
|
+
p.catch((e) => {
|
|
97
|
+
const error = normalize_error(e);
|
|
98
|
+
|
|
99
|
+
if (error instanceof Redirect) {
|
|
100
|
+
throw error;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Math.min because array isn't guaranteed to resolve in order
|
|
104
|
+
length = Math.min(length, i + 1);
|
|
105
|
+
|
|
106
|
+
if (error instanceof HttpError) {
|
|
107
|
+
return /** @type {import('types').ServerErrorNode} */ ({
|
|
108
|
+
type: 'error',
|
|
109
|
+
httperror: { ...error }
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
options.handle_error(error, event);
|
|
114
|
+
|
|
115
|
+
return /** @type {import('types').ServerErrorNode} */ ({
|
|
116
|
+
type: 'error',
|
|
117
|
+
error: error_to_pojo(error, options.get_stack)
|
|
118
|
+
});
|
|
119
|
+
})
|
|
120
|
+
)
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
/** @type {import('types').ServerData} */
|
|
124
|
+
const server_data = {
|
|
125
|
+
type: 'data',
|
|
126
|
+
nodes: nodes.slice(0, length)
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
return data_response(server_data);
|
|
130
|
+
} catch (e) {
|
|
131
|
+
const error = normalize_error(e);
|
|
132
|
+
|
|
133
|
+
if (error instanceof Redirect) {
|
|
134
|
+
/** @type {import('types').ServerData} */
|
|
135
|
+
const server_data = {
|
|
136
|
+
type: 'redirect',
|
|
137
|
+
location: error.location
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
return data_response(server_data);
|
|
141
|
+
} else {
|
|
142
|
+
// TODO make it clearer that this was an unexpected error
|
|
143
|
+
return data_response(error_to_pojo(error, options.get_stack));
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|