@sveltejs/kit 1.0.0-next.441 → 1.0.0-next.444
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 +6 -6
- package/src/core/prerender/prerender.js +1 -1
- package/src/core/sync/write_ambient.js +1 -1
- package/src/core/sync/write_client_manifest.js +18 -13
- package/src/core/sync/write_root.js +1 -1
- package/src/core/sync/write_types/index.js +28 -9
- package/src/core/sync/write_types/test/layout-advanced/_expected/(main)/sub/$types.d.ts +5 -4
- package/src/core/sync/write_types/test/slugs-layout-not-all-pages-have-load/_expected/nested/[...rest]/$types.d.ts +5 -4
- package/src/exports/hooks/index.js +1 -0
- package/src/{hooks.js → exports/hooks/sequence.js} +0 -0
- package/src/{index → exports}/index.js +1 -1
- package/src/{node → exports/node}/index.js +0 -0
- package/src/{node → exports/node}/polyfills.js +0 -0
- package/src/{vite → exports/vite}/build/build_server.js +4 -4
- package/src/{vite → exports/vite}/build/build_service_worker.js +1 -1
- package/src/{vite → exports/vite}/build/utils.js +0 -0
- package/src/{vite → exports/vite}/dev/index.js +9 -9
- package/src/{vite → exports/vite}/index.js +8 -8
- package/src/{vite → exports/vite}/preview/index.js +3 -3
- package/src/{vite → exports/vite}/types.d.ts +0 -0
- package/src/{vite → exports/vite}/utils.js +2 -2
- package/src/runtime/client/ambient.d.ts +3 -3
- package/src/runtime/client/client.js +40 -23
- package/src/runtime/client/parse.js +14 -8
- package/src/runtime/client/types.d.ts +2 -2
- package/src/{index/private.js → runtime/control.js} +0 -0
- package/src/runtime/server/endpoint.js +1 -1
- package/src/runtime/server/index.js +7 -4
- package/src/runtime/server/page/index.js +2 -2
- package/src/runtime/server/page/render.js +1 -1
- package/src/runtime/server/page/types.d.ts +1 -1
- package/src/runtime/server/utils.js +1 -1
- package/src/utils/error.js +1 -1
- package/types/index.d.ts +1 -1
- package/types/internal.d.ts +10 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sveltejs/kit",
|
|
3
|
-
"version": "1.0.0-next.
|
|
3
|
+
"version": "1.0.0-next.444",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/sveltejs/kit",
|
|
@@ -60,20 +60,20 @@
|
|
|
60
60
|
"exports": {
|
|
61
61
|
"./package.json": "./package.json",
|
|
62
62
|
".": {
|
|
63
|
-
"import": "./src/
|
|
63
|
+
"import": "./src/exports/index.js",
|
|
64
64
|
"types": "./types/index.d.ts"
|
|
65
65
|
},
|
|
66
66
|
"./node": {
|
|
67
|
-
"import": "./src/node/index.js"
|
|
67
|
+
"import": "./src/exports/node/index.js"
|
|
68
68
|
},
|
|
69
69
|
"./node/polyfills": {
|
|
70
|
-
"import": "./src/node/polyfills.js"
|
|
70
|
+
"import": "./src/exports/node/polyfills.js"
|
|
71
71
|
},
|
|
72
72
|
"./hooks": {
|
|
73
|
-
"import": "./src/hooks.js"
|
|
73
|
+
"import": "./src/exports/hooks/index.js"
|
|
74
74
|
},
|
|
75
75
|
"./vite": {
|
|
76
|
-
"import": "./src/vite/index.js"
|
|
76
|
+
"import": "./src/exports/vite/index.js"
|
|
77
77
|
}
|
|
78
78
|
},
|
|
79
79
|
"types": "types/index.d.ts",
|
|
@@ -2,7 +2,7 @@ import { readFileSync, writeFileSync } from 'fs';
|
|
|
2
2
|
import { dirname, join } from 'path';
|
|
3
3
|
import { pathToFileURL, URL } from 'url';
|
|
4
4
|
import { mkdirp, posixify, walk } from '../../utils/filesystem.js';
|
|
5
|
-
import { installPolyfills } from '../../node/polyfills.js';
|
|
5
|
+
import { installPolyfills } from '../../exports/node/polyfills.js';
|
|
6
6
|
import { is_root_relative, resolve } from '../../utils/url.js';
|
|
7
7
|
import { queue } from './queue.js';
|
|
8
8
|
import { crawl } from './crawl.js';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import path from 'path';
|
|
2
|
-
import { get_env } from '../../vite/utils.js';
|
|
2
|
+
import { get_env } from '../../exports/vite/utils.js';
|
|
3
3
|
import { GENERATED_COMMENT } from '../constants.js';
|
|
4
4
|
import { create_types } from '../env.js';
|
|
5
5
|
import { write_if_changed } from './utils.js';
|
|
@@ -48,23 +48,17 @@ export function write_client_manifest(manifest_data, output) {
|
|
|
48
48
|
.map((route) => {
|
|
49
49
|
if (route.page) {
|
|
50
50
|
const errors = route.page.errors.slice(1).map((n) => n ?? '');
|
|
51
|
-
const layouts = route.page.layouts.slice(1).map((n) =>
|
|
51
|
+
const layouts = route.page.layouts.slice(1).map((n) => {
|
|
52
|
+
if (n == undefined) {
|
|
53
|
+
return '';
|
|
54
|
+
}
|
|
55
|
+
return get_node_id(manifest_data.nodes, n);
|
|
56
|
+
});
|
|
52
57
|
|
|
53
58
|
while (layouts.at(-1) === '') layouts.pop();
|
|
54
59
|
while (errors.at(-1) === '') errors.pop();
|
|
55
60
|
|
|
56
|
-
|
|
57
|
-
let current_node = route.leaf;
|
|
58
|
-
|
|
59
|
-
let uses_server_data = false;
|
|
60
|
-
while (current_node && !uses_server_data) {
|
|
61
|
-
uses_server_data = !!current_node?.server;
|
|
62
|
-
current_node = current_node?.parent ?? null;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
// encode whether or not the route uses the server data
|
|
66
|
-
// using the ones' complement, to save space
|
|
67
|
-
const array = [`${uses_server_data ? '~' : ''}${route.page.leaf}`];
|
|
61
|
+
const array = [get_node_id(manifest_data.nodes, route.page.leaf)];
|
|
68
62
|
|
|
69
63
|
// only include non-root layout/error nodes if they exist
|
|
70
64
|
if (layouts.length > 0 || errors.length > 0) array.push(`[${layouts.join(',')}]`);
|
|
@@ -77,6 +71,7 @@ export function write_client_manifest(manifest_data, output) {
|
|
|
77
71
|
.join(',\n\t\t')}
|
|
78
72
|
}`.replace(/^\t/gm, '');
|
|
79
73
|
|
|
74
|
+
// String representation of __GENERATED__/client-manifest.js
|
|
80
75
|
write_if_changed(
|
|
81
76
|
`${output}/client-manifest.js`,
|
|
82
77
|
trim(`
|
|
@@ -90,3 +85,13 @@ export function write_client_manifest(manifest_data, output) {
|
|
|
90
85
|
`)
|
|
91
86
|
);
|
|
92
87
|
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Encode whether or not the route uses the server data
|
|
91
|
+
* using the ones' complement, to save space
|
|
92
|
+
* @param {import('types').PageNode[]} nodes
|
|
93
|
+
* @param {number} id
|
|
94
|
+
*/
|
|
95
|
+
function get_node_id(nodes, id) {
|
|
96
|
+
return `${nodes[id].server ? '~' : ''}${id}`;
|
|
97
|
+
}
|
|
@@ -21,7 +21,7 @@ export function write_root(manifest_data, output) {
|
|
|
21
21
|
|
|
22
22
|
let l = max_depth;
|
|
23
23
|
|
|
24
|
-
let pyramid = `<svelte:component this={components[${l}]} data={data_${l}}/>`;
|
|
24
|
+
let pyramid = `<svelte:component this={components[${l}]} data={data_${l}} {errors}/>`;
|
|
25
25
|
|
|
26
26
|
while (l--) {
|
|
27
27
|
pyramid = `
|
|
@@ -167,15 +167,20 @@ function update_types(config, routes, route) {
|
|
|
167
167
|
`type RouteParams = { ${route.names.map((param) => `${param}: string`).join('; ')} }`
|
|
168
168
|
);
|
|
169
169
|
|
|
170
|
+
// These could also be placed in our public types, but it would bloat them unnecessarily and we may want to change these in the future
|
|
170
171
|
if (route.layout || route.leaf) {
|
|
171
|
-
//
|
|
172
|
+
// If T extends the empty object, void is also allowed as a return type
|
|
172
173
|
declarations.push(`type MaybeWithVoid<T> = {} extends T ? T | void : T;`);
|
|
174
|
+
// Returns the key of the object whose values are required.
|
|
173
175
|
declarations.push(
|
|
174
176
|
`export type RequiredKeys<T> = { [K in keyof T]-?: {} extends { [P in K]: T[K] } ? never : K; }[keyof T];`
|
|
175
177
|
);
|
|
178
|
+
// Helper type to get the correct output type for load functions. It should be passed the parent type to check what types from App.PageData are still required.
|
|
179
|
+
// If none, void is also allowed as a return type.
|
|
176
180
|
declarations.push(
|
|
177
181
|
`type OutputDataShape<T> = MaybeWithVoid<Omit<App.PageData, RequiredKeys<T>> & Partial<Pick<App.PageData, keyof T & keyof App.PageData>> & Record<string, any>>`
|
|
178
182
|
);
|
|
183
|
+
// null & {} == null, we need to prevent that in some situations
|
|
179
184
|
declarations.push(`type EnsureParentData<T> = NonNullable<T> extends never ? {} : T;`);
|
|
180
185
|
}
|
|
181
186
|
|
|
@@ -277,9 +282,7 @@ function process_node(node, outdir, is_page, all_pages_have_load = true) {
|
|
|
277
282
|
|
|
278
283
|
const parent_type = `${prefix}ServerParentData`;
|
|
279
284
|
|
|
280
|
-
declarations.push(
|
|
281
|
-
`type ${parent_type} = EnsureParentData<${get_parent_type(node, 'LayoutServerData')}>;`
|
|
282
|
-
);
|
|
285
|
+
declarations.push(`type ${parent_type} = ${get_parent_type(node, 'LayoutServerData')};`);
|
|
283
286
|
|
|
284
287
|
// +page.js load present -> server can return all-optional data
|
|
285
288
|
const output_data_shape =
|
|
@@ -317,9 +320,7 @@ function process_node(node, outdir, is_page, all_pages_have_load = true) {
|
|
|
317
320
|
exports.push(`export type ${prefix}ServerData = ${server_data};`);
|
|
318
321
|
|
|
319
322
|
const parent_type = `${prefix}ParentData`;
|
|
320
|
-
declarations.push(
|
|
321
|
-
`type ${parent_type} = EnsureParentData<${get_parent_type(node, 'LayoutData')}>;`
|
|
322
|
-
);
|
|
323
|
+
declarations.push(`type ${parent_type} = ${get_parent_type(node, 'LayoutData')};`);
|
|
323
324
|
|
|
324
325
|
if (node.shared) {
|
|
325
326
|
const content = fs.readFileSync(node.shared, 'utf8');
|
|
@@ -394,12 +395,14 @@ function get_parent_type(node, type) {
|
|
|
394
395
|
parent = parent.parent;
|
|
395
396
|
}
|
|
396
397
|
|
|
397
|
-
let parent_str = parent_imports[0] || '{}'
|
|
398
|
+
let parent_str = `EnsureParentData<${parent_imports[0] || '{}'}>`;
|
|
398
399
|
for (let i = 1; i < parent_imports.length; i++) {
|
|
399
400
|
// Omit is necessary because a parent could have a property with the same key which would
|
|
400
401
|
// cause a type conflict. At runtime the child overwrites the parent property in this case,
|
|
401
402
|
// so reflect that in the type definition.
|
|
402
|
-
|
|
403
|
+
// EnsureParentData is necessary because {something: string} & null becomes null.
|
|
404
|
+
// Output types of server loads can be null but when passed in through the `parent` parameter they are the empty object instead.
|
|
405
|
+
parent_str = `Omit<${parent_str}, keyof ${parent_imports[i]}> & EnsureParentData<${parent_imports[i]}>`;
|
|
403
406
|
}
|
|
404
407
|
return parent_str;
|
|
405
408
|
}
|
|
@@ -556,7 +559,13 @@ export function tweak_types(content, names) {
|
|
|
556
559
|
arg.name.end,
|
|
557
560
|
`: Parameters<${type}>[0]` + (add_parens ? ')' : '')
|
|
558
561
|
);
|
|
562
|
+
} else {
|
|
563
|
+
// prevent "type X is imported but not used" (isn't silenced by @ts-nocheck) when svelte-check runs
|
|
564
|
+
code.append(`;${type};`);
|
|
559
565
|
}
|
|
566
|
+
} else {
|
|
567
|
+
// prevent "type X is imported but not used" (isn't silenced by @ts-nocheck) when svelte-check runs
|
|
568
|
+
code.append(`;${type};`);
|
|
560
569
|
}
|
|
561
570
|
|
|
562
571
|
modified = true;
|
|
@@ -566,6 +575,16 @@ export function tweak_types(content, names) {
|
|
|
566
575
|
}
|
|
567
576
|
});
|
|
568
577
|
|
|
578
|
+
if (modified) {
|
|
579
|
+
// Ignore all type errors so they don't show up twice when svelte-check runs
|
|
580
|
+
// Account for possible @ts-check which would overwrite @ts-nocheck
|
|
581
|
+
if (code.original.startsWith('// @ts-check')) {
|
|
582
|
+
code.prependLeft('// @ts-check'.length, '\n// @ts-nocheck\n');
|
|
583
|
+
} else {
|
|
584
|
+
code.prepend('// @ts-nocheck\n');
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
|
|
569
588
|
return {
|
|
570
589
|
modified,
|
|
571
590
|
code: code.toString(),
|
|
@@ -11,10 +11,11 @@ type OutputDataShape<T> = MaybeWithVoid<
|
|
|
11
11
|
Record<string, any>
|
|
12
12
|
>;
|
|
13
13
|
type EnsureParentData<T> = NonNullable<T> extends never ? {} : T;
|
|
14
|
-
type PageParentData =
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
type PageParentData = Omit<
|
|
15
|
+
EnsureParentData<import('../../$types.js').LayoutData>,
|
|
16
|
+
keyof import('../$types.js').LayoutData
|
|
17
|
+
> &
|
|
18
|
+
EnsureParentData<import('../$types.js').LayoutData>;
|
|
18
19
|
|
|
19
20
|
export type PageServerData = null;
|
|
20
21
|
export type PageLoad<
|
|
@@ -11,10 +11,11 @@ type OutputDataShape<T> = MaybeWithVoid<
|
|
|
11
11
|
Record<string, any>
|
|
12
12
|
>;
|
|
13
13
|
type EnsureParentData<T> = NonNullable<T> extends never ? {} : T;
|
|
14
|
-
type PageParentData =
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
type PageParentData = Omit<
|
|
15
|
+
EnsureParentData<import('../../$types.js').LayoutData>,
|
|
16
|
+
keyof import('../$types.js').LayoutData
|
|
17
|
+
> &
|
|
18
|
+
EnsureParentData<import('../$types.js').LayoutData>;
|
|
18
19
|
|
|
19
20
|
export type PageServerData = null;
|
|
20
21
|
export type PageLoad<
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { sequence } from './sequence.js';
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
|
-
import { mkdirp, posixify } from '
|
|
3
|
+
import { mkdirp, posixify } from '../../../utils/filesystem.js';
|
|
4
4
|
import { get_vite_config, merge_vite_configs, resolve_entry } from '../utils.js';
|
|
5
|
-
import { load_template } from '
|
|
6
|
-
import { runtime_directory } from '
|
|
5
|
+
import { load_template } from '../../../core/config/index.js';
|
|
6
|
+
import { runtime_directory } from '../../../core/utils.js';
|
|
7
7
|
import { create_build, find_deps, get_default_build_config, is_http_method } from './utils.js';
|
|
8
|
-
import { s } from '
|
|
8
|
+
import { s } from '../../../utils/misc.js';
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* @param {{
|
|
File without changes
|
|
@@ -3,16 +3,16 @@ import colors from 'kleur';
|
|
|
3
3
|
import path from 'path';
|
|
4
4
|
import sirv from 'sirv';
|
|
5
5
|
import { URL } from 'url';
|
|
6
|
-
import { getRequest, setResponse } from '
|
|
7
|
-
import { installPolyfills } from '
|
|
8
|
-
import { coalesce_to_error } from '
|
|
9
|
-
import { posixify } from '
|
|
10
|
-
import { load_template } from '
|
|
11
|
-
import { SVELTE_KIT_ASSETS } from '
|
|
12
|
-
import * as sync from '
|
|
13
|
-
import { get_mime_lookup, runtime_base, runtime_prefix } from '
|
|
6
|
+
import { getRequest, setResponse } from '../../../exports/node/index.js';
|
|
7
|
+
import { installPolyfills } from '../../../exports/node/polyfills.js';
|
|
8
|
+
import { coalesce_to_error } from '../../../utils/error.js';
|
|
9
|
+
import { posixify } from '../../../utils/filesystem.js';
|
|
10
|
+
import { load_template } from '../../../core/config/index.js';
|
|
11
|
+
import { SVELTE_KIT_ASSETS } from '../../../core/constants.js';
|
|
12
|
+
import * as sync from '../../../core/sync/sync.js';
|
|
13
|
+
import { get_mime_lookup, runtime_base, runtime_prefix } from '../../../core/utils.js';
|
|
14
14
|
import { get_env, prevent_illegal_vite_imports, resolve_entry } from '../utils.js';
|
|
15
|
-
import { compact } from '
|
|
15
|
+
import { compact } from '../../../utils/array.js';
|
|
16
16
|
|
|
17
17
|
// Vite doesn't expose this so we just copy the list for now
|
|
18
18
|
// https://github.com/vitejs/vite/blob/3edd1af56e980aef56641a5a51cf2932bb580d41/packages/vite/src/node/plugins/css.ts#L96
|
|
@@ -4,19 +4,19 @@ import path from 'node:path';
|
|
|
4
4
|
import colors from 'kleur';
|
|
5
5
|
import { svelte } from '@sveltejs/vite-plugin-svelte';
|
|
6
6
|
import * as vite from 'vite';
|
|
7
|
-
import { mkdirp, posixify, rimraf } from '
|
|
8
|
-
import * as sync from '
|
|
7
|
+
import { mkdirp, posixify, rimraf } from '../../utils/filesystem.js';
|
|
8
|
+
import * as sync from '../../core/sync/sync.js';
|
|
9
9
|
import { build_server } from './build/build_server.js';
|
|
10
10
|
import { build_service_worker } from './build/build_service_worker.js';
|
|
11
|
-
import { load_config } from '
|
|
11
|
+
import { load_config } from '../../core/config/index.js';
|
|
12
12
|
import { dev } from './dev/index.js';
|
|
13
|
-
import { generate_manifest } from '
|
|
14
|
-
import { runtime_directory, logger } from '
|
|
13
|
+
import { generate_manifest } from '../../core/generate_manifest/index.js';
|
|
14
|
+
import { runtime_directory, logger } from '../../core/utils.js';
|
|
15
15
|
import { find_deps, get_default_build_config } from './build/utils.js';
|
|
16
16
|
import { preview } from './preview/index.js';
|
|
17
17
|
import { get_aliases, resolve_entry, prevent_illegal_rollup_imports, get_env } from './utils.js';
|
|
18
18
|
import { fileURLToPath } from 'node:url';
|
|
19
|
-
import { create_static_module, create_dynamic_module } from '
|
|
19
|
+
import { create_static_module, create_dynamic_module } from '../../core/env.js';
|
|
20
20
|
|
|
21
21
|
const cwd = process.cwd();
|
|
22
22
|
|
|
@@ -405,7 +405,7 @@ function kit() {
|
|
|
405
405
|
const results_path = `${svelte_config.kit.outDir}/generated/prerendered.json`;
|
|
406
406
|
|
|
407
407
|
// do prerendering in a subprocess so any dangling stuff gets killed upon completion
|
|
408
|
-
const script = fileURLToPath(new URL('
|
|
408
|
+
const script = fileURLToPath(new URL('../../core/prerender/prerender.js', import.meta.url));
|
|
409
409
|
|
|
410
410
|
const child = fork(
|
|
411
411
|
script,
|
|
@@ -465,7 +465,7 @@ function kit() {
|
|
|
465
465
|
}
|
|
466
466
|
|
|
467
467
|
if (svelte_config.kit.adapter) {
|
|
468
|
-
const { adapt } = await import('
|
|
468
|
+
const { adapt } = await import('../../core/adapt/index.js');
|
|
469
469
|
await adapt(svelte_config, build_data, prerendered, { log });
|
|
470
470
|
} else {
|
|
471
471
|
console.log(colors.bold().yellow('\nNo adapter specified'));
|
|
@@ -2,9 +2,9 @@ import fs from 'fs';
|
|
|
2
2
|
import { join } from 'path';
|
|
3
3
|
import sirv from 'sirv';
|
|
4
4
|
import { pathToFileURL } from 'url';
|
|
5
|
-
import { getRequest, setResponse } from '
|
|
6
|
-
import { installPolyfills } from '
|
|
7
|
-
import { SVELTE_KIT_ASSETS } from '
|
|
5
|
+
import { getRequest, setResponse } from '../../../exports/node/index.js';
|
|
6
|
+
import { installPolyfills } from '../../../exports/node/polyfills.js';
|
|
7
|
+
import { SVELTE_KIT_ASSETS } from '../../../core/constants.js';
|
|
8
8
|
import { loadEnv } from 'vite';
|
|
9
9
|
|
|
10
10
|
/** @typedef {import('http').IncomingMessage} Req */
|
|
File without changes
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import { loadConfigFromFile, loadEnv, normalizePath } from 'vite';
|
|
4
|
-
import { runtime_directory } from '
|
|
5
|
-
import { posixify } from '
|
|
4
|
+
import { runtime_directory } from '../../core/utils.js';
|
|
5
|
+
import { posixify } from '../../utils/filesystem.js';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* @param {import('vite').ResolvedConfig} config
|
|
@@ -8,9 +8,9 @@ declare module '__GENERATED__/client-manifest.js' {
|
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* A map of `[routeId: string]: [leaf, layouts, errors]` tuples, which
|
|
11
|
-
* is parsed into an array of routes on startup. The numbers refer to the
|
|
12
|
-
*
|
|
13
|
-
* they are always number 0 and 1 and always apply.
|
|
11
|
+
* is parsed into an array of routes on startup. The numbers refer to the indices in `nodes`.
|
|
12
|
+
* If the number is negative, it means it does use a server load function and the complement is the node index.
|
|
13
|
+
* The route layout and error nodes are not referenced, they are always number 0 and 1 and always apply.
|
|
14
14
|
*/
|
|
15
15
|
export const dictionary: Record<string, [leaf: number, layouts?: number[], errors?: number[]]>;
|
|
16
16
|
|
|
@@ -4,11 +4,11 @@ import { make_trackable, decode_params, normalize_path } from '../../utils/url.j
|
|
|
4
4
|
import { find_anchor, get_base_uri, get_href, scroll_state } from './utils.js';
|
|
5
5
|
import { lock_fetch, unlock_fetch, initial_fetch, native_fetch } from './fetcher.js';
|
|
6
6
|
import { parse } from './parse.js';
|
|
7
|
-
import { error } from '../../
|
|
7
|
+
import { error } from '../../exports/index.js';
|
|
8
8
|
|
|
9
9
|
import Root from '__GENERATED__/root.svelte';
|
|
10
10
|
import { nodes, dictionary, matchers } from '__GENERATED__/client-manifest.js';
|
|
11
|
-
import { HttpError, Redirect } from '
|
|
11
|
+
import { HttpError, Redirect } from '../control.js';
|
|
12
12
|
import { stores } from './singletons.js';
|
|
13
13
|
|
|
14
14
|
const SCROLL_KEY = 'sveltekit:scroll';
|
|
@@ -424,21 +424,37 @@ export function create_client({ target, base, trailing_slash }) {
|
|
|
424
424
|
};
|
|
425
425
|
|
|
426
426
|
let data = {};
|
|
427
|
-
let data_changed =
|
|
427
|
+
let data_changed = !page;
|
|
428
428
|
for (let i = 0; i < filtered.length; i += 1) {
|
|
429
|
-
|
|
429
|
+
const node = filtered[i];
|
|
430
|
+
data = { ...data, ...node.data };
|
|
431
|
+
|
|
430
432
|
// Only set props if the node actually updated. This prevents needless rerenders.
|
|
431
|
-
if (data_changed || !current.branch.some((
|
|
433
|
+
if (data_changed || !current.branch.some((previous) => previous === node)) {
|
|
432
434
|
result.props[`data_${i}`] = data;
|
|
433
|
-
data_changed =
|
|
435
|
+
data_changed = data_changed || Object.keys(node.data ?? {}).length > 0;
|
|
434
436
|
}
|
|
435
437
|
}
|
|
438
|
+
if (!data_changed) {
|
|
439
|
+
// If nothing was added, and the object entries are the same length, this means
|
|
440
|
+
// that nothing was removed either and therefore the data is the same as the previous one.
|
|
441
|
+
// This would be more readable with a separate boolean but that would cost us some bytes.
|
|
442
|
+
data_changed = Object.keys(page.data).length !== Object.keys(data).length;
|
|
443
|
+
}
|
|
436
444
|
|
|
437
445
|
const page_changed =
|
|
438
446
|
!current.url || url.href !== current.url.href || current.error !== error || data_changed;
|
|
439
447
|
|
|
440
448
|
if (page_changed) {
|
|
441
|
-
result.props.page = {
|
|
449
|
+
result.props.page = {
|
|
450
|
+
error,
|
|
451
|
+
params,
|
|
452
|
+
routeId,
|
|
453
|
+
status,
|
|
454
|
+
url,
|
|
455
|
+
// The whole page store is updated, but this way the object reference stays the same
|
|
456
|
+
data: data_changed ? data : page.data
|
|
457
|
+
};
|
|
442
458
|
|
|
443
459
|
// TODO remove this for 1.0
|
|
444
460
|
/**
|
|
@@ -638,9 +654,10 @@ export function create_client({ target, base, trailing_slash }) {
|
|
|
638
654
|
|
|
639
655
|
/**
|
|
640
656
|
* @param {import('types').ServerDataNode | import('types').ServerDataSkippedNode | null} node
|
|
657
|
+
* @param {import('./types').DataNode | null} [previous]
|
|
641
658
|
* @returns {import('./types').DataNode | null}
|
|
642
659
|
*/
|
|
643
|
-
function create_data_node(node) {
|
|
660
|
+
function create_data_node(node, previous) {
|
|
644
661
|
if (node?.type === 'data') {
|
|
645
662
|
return {
|
|
646
663
|
type: 'data',
|
|
@@ -652,6 +669,8 @@ export function create_client({ target, base, trailing_slash }) {
|
|
|
652
669
|
url: !!node.uses.url
|
|
653
670
|
}
|
|
654
671
|
};
|
|
672
|
+
} else if (node?.type === 'skip') {
|
|
673
|
+
return previous ?? null;
|
|
655
674
|
}
|
|
656
675
|
return null;
|
|
657
676
|
}
|
|
@@ -672,14 +691,13 @@ export function create_client({ target, base, trailing_slash }) {
|
|
|
672
691
|
params: Object.keys(params).filter((key) => current.params[key] !== params[key])
|
|
673
692
|
};
|
|
674
693
|
|
|
694
|
+
const loaders = [...layouts, leaf];
|
|
695
|
+
|
|
675
696
|
// preload modules to avoid waterfall, but handle rejections
|
|
676
697
|
// so they don't get reported to Sentry et al (we don't need
|
|
677
698
|
// to act on the failures at this point)
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
const loaders = [...layouts, leaf];
|
|
681
|
-
|
|
682
|
-
// To avoid waterfalls when someone awaits a parent, compute as much as possible here already
|
|
699
|
+
errors.forEach((loader) => loader?.().catch(() => {}));
|
|
700
|
+
loaders.forEach((loader) => loader?.[1]().catch(() => {}));
|
|
683
701
|
|
|
684
702
|
/** @type {import('types').ServerData | null} */
|
|
685
703
|
let server_data = null;
|
|
@@ -687,15 +705,15 @@ export function create_client({ target, base, trailing_slash }) {
|
|
|
687
705
|
const invalid_server_nodes = loaders.reduce((acc, loader, i) => {
|
|
688
706
|
const previous = current.branch[i];
|
|
689
707
|
const invalid =
|
|
690
|
-
loader &&
|
|
691
|
-
(previous?.loader !== loader ||
|
|
708
|
+
!!loader?.[0] &&
|
|
709
|
+
(previous?.loader !== loader[1] ||
|
|
692
710
|
has_changed(changed, acc.some(Boolean), previous.server?.uses));
|
|
693
711
|
|
|
694
712
|
acc.push(invalid);
|
|
695
713
|
return acc;
|
|
696
714
|
}, /** @type {boolean[]} */ ([]));
|
|
697
715
|
|
|
698
|
-
if (
|
|
716
|
+
if (invalid_server_nodes.some(Boolean)) {
|
|
699
717
|
try {
|
|
700
718
|
const res = await native_fetch(
|
|
701
719
|
`${url.pathname}${url.pathname.endsWith('/') ? '' : '/'}__data.json${url.search}`,
|
|
@@ -738,7 +756,7 @@ export function create_client({ target, base, trailing_slash }) {
|
|
|
738
756
|
// re-use data from previous load if it's still valid
|
|
739
757
|
const valid =
|
|
740
758
|
can_reuse_server_data &&
|
|
741
|
-
loader === previous?.loader &&
|
|
759
|
+
loader[1] === previous?.loader &&
|
|
742
760
|
!has_changed(changed, parent_changed, previous.shared?.uses);
|
|
743
761
|
if (valid) return previous;
|
|
744
762
|
|
|
@@ -754,7 +772,7 @@ export function create_client({ target, base, trailing_slash }) {
|
|
|
754
772
|
}
|
|
755
773
|
|
|
756
774
|
return load_node({
|
|
757
|
-
loader,
|
|
775
|
+
loader: loader[1],
|
|
758
776
|
url,
|
|
759
777
|
params,
|
|
760
778
|
routeId: route.id,
|
|
@@ -765,7 +783,7 @@ export function create_client({ target, base, trailing_slash }) {
|
|
|
765
783
|
}
|
|
766
784
|
return data;
|
|
767
785
|
},
|
|
768
|
-
server_data_node: create_data_node(server_data_node
|
|
786
|
+
server_data_node: create_data_node(server_data_node, previous?.server)
|
|
769
787
|
});
|
|
770
788
|
});
|
|
771
789
|
|
|
@@ -798,11 +816,10 @@ export function create_client({ target, base, trailing_slash }) {
|
|
|
798
816
|
|
|
799
817
|
let j = i;
|
|
800
818
|
while (!branch[j]) j -= 1;
|
|
801
|
-
|
|
802
819
|
try {
|
|
803
820
|
error_loaded = {
|
|
804
|
-
node: await errors[i](),
|
|
805
|
-
loader: errors[i],
|
|
821
|
+
node: await /** @type {import('types').CSRPageNodeLoader } */ (errors[i])(),
|
|
822
|
+
loader: /** @type {import('types').CSRPageNodeLoader } */ (errors[i]),
|
|
806
823
|
data: {},
|
|
807
824
|
server: null,
|
|
808
825
|
shared: null
|
|
@@ -1084,7 +1101,7 @@ export function create_client({ target, base, trailing_slash }) {
|
|
|
1084
1101
|
: routes;
|
|
1085
1102
|
|
|
1086
1103
|
const promises = matching.map((r) => {
|
|
1087
|
-
return Promise.all([...r.layouts, r.leaf].map((load) => load?.()));
|
|
1104
|
+
return Promise.all([...r.layouts, r.leaf].map((load) => load?.[1]()));
|
|
1088
1105
|
});
|
|
1089
1106
|
|
|
1090
1107
|
await Promise.all(promises);
|
|
@@ -10,11 +10,6 @@ export function parse(nodes, dictionary, matchers) {
|
|
|
10
10
|
return Object.entries(dictionary).map(([id, [leaf, layouts, errors]]) => {
|
|
11
11
|
const { pattern, names, types } = parse_route_id(id);
|
|
12
12
|
|
|
13
|
-
// whether or not the route uses the server data is
|
|
14
|
-
// encoded using the ones' complement, to save space
|
|
15
|
-
const uses_server_data = leaf < 0;
|
|
16
|
-
if (uses_server_data) leaf = ~leaf;
|
|
17
|
-
|
|
18
13
|
const route = {
|
|
19
14
|
id,
|
|
20
15
|
/** @param {string} path */
|
|
@@ -23,9 +18,8 @@ export function parse(nodes, dictionary, matchers) {
|
|
|
23
18
|
if (match) return exec(match, names, types, matchers);
|
|
24
19
|
},
|
|
25
20
|
errors: [1, ...(errors || [])].map((n) => nodes[n]),
|
|
26
|
-
layouts: [0, ...(layouts || [])].map(
|
|
27
|
-
leaf:
|
|
28
|
-
uses_server_data
|
|
21
|
+
layouts: [0, ...(layouts || [])].map(create_loader),
|
|
22
|
+
leaf: create_loader(leaf)
|
|
29
23
|
};
|
|
30
24
|
|
|
31
25
|
// bit of a hack, but ensures that layout/error node lists are the same
|
|
@@ -38,4 +32,16 @@ export function parse(nodes, dictionary, matchers) {
|
|
|
38
32
|
|
|
39
33
|
return route;
|
|
40
34
|
});
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* @param {number} id
|
|
38
|
+
* @returns {[boolean, import('types').CSRPageNodeLoader]}
|
|
39
|
+
*/
|
|
40
|
+
function create_loader(id) {
|
|
41
|
+
// whether or not the route uses the server data is
|
|
42
|
+
// encoded using the ones' complement, to save space
|
|
43
|
+
const uses_server_data = id < 0;
|
|
44
|
+
if (uses_server_data) id = ~id;
|
|
45
|
+
return [uses_server_data, nodes[id]];
|
|
46
|
+
}
|
|
41
47
|
}
|
|
@@ -6,8 +6,8 @@ import {
|
|
|
6
6
|
prefetch,
|
|
7
7
|
prefetchRoutes
|
|
8
8
|
} from '$app/navigation';
|
|
9
|
-
import { CSRPageNode, CSRPageNodeLoader, CSRRoute,
|
|
10
|
-
import { HttpError } from '
|
|
9
|
+
import { CSRPageNode, CSRPageNodeLoader, CSRRoute, Uses } from 'types';
|
|
10
|
+
import { HttpError } from '../control.js';
|
|
11
11
|
import { SerializedHttpError } from '../server/page/types.js';
|
|
12
12
|
|
|
13
13
|
export interface Client {
|
|
File without changes
|
|
@@ -7,9 +7,9 @@ import { serialize_error, GENERIC_ERROR, error_to_pojo } from './utils.js';
|
|
|
7
7
|
import { decode_params, disable_search, normalize_path } from '../../utils/url.js';
|
|
8
8
|
import { exec } from '../../utils/routing.js';
|
|
9
9
|
import { negotiate } from '../../utils/http.js';
|
|
10
|
-
import { HttpError, Redirect } from '
|
|
10
|
+
import { HttpError, Redirect } from '../control.js';
|
|
11
11
|
import { load_server_data } from './page/load_data.js';
|
|
12
|
-
import { json } from '../../
|
|
12
|
+
import { json } from '../../exports/index.js';
|
|
13
13
|
import { once } from '../../utils/functions.js';
|
|
14
14
|
|
|
15
15
|
/* global __SVELTEKIT_ADAPTER_NAME__ */
|
|
@@ -280,10 +280,13 @@ export async function respond(request, options, state) {
|
|
|
280
280
|
/** @type {Record<string, any>} */
|
|
281
281
|
const data = {};
|
|
282
282
|
for (let j = 0; j < i; j += 1) {
|
|
283
|
-
const parent = /** @type {import('types').ServerDataNode} */ (
|
|
283
|
+
const parent = /** @type {import('types').ServerDataNode | null} */ (
|
|
284
284
|
await functions[j]()
|
|
285
285
|
);
|
|
286
|
-
|
|
286
|
+
|
|
287
|
+
if (parent) {
|
|
288
|
+
Object.assign(data, parent.data);
|
|
289
|
+
}
|
|
287
290
|
}
|
|
288
291
|
return data;
|
|
289
292
|
}
|
|
@@ -3,8 +3,8 @@ import { render_response } from './render.js';
|
|
|
3
3
|
import { respond_with_error } from './respond_with_error.js';
|
|
4
4
|
import { method_not_allowed, error_to_pojo, allowed_methods } from '../utils.js';
|
|
5
5
|
import { create_fetch } from './fetch.js';
|
|
6
|
-
import { HttpError, Redirect } from '
|
|
7
|
-
import { error, json } from '../../../
|
|
6
|
+
import { HttpError, Redirect } from '../../control.js';
|
|
7
|
+
import { error, json } from '../../../exports/index.js';
|
|
8
8
|
import { compact } from '../../../utils/array.js';
|
|
9
9
|
import { normalize_error } from '../../../utils/error.js';
|
|
10
10
|
import { load_data, load_server_data } from './load_data.js';
|
|
@@ -6,7 +6,7 @@ import { render_json_payload_script } from '../../../utils/escape.js';
|
|
|
6
6
|
import { s } from '../../../utils/misc.js';
|
|
7
7
|
import { Csp } from './csp.js';
|
|
8
8
|
import { serialize_error } from '../utils.js';
|
|
9
|
-
import { HttpError } from '
|
|
9
|
+
import { HttpError } from '../../control.js';
|
|
10
10
|
|
|
11
11
|
// TODO rename this function/module
|
|
12
12
|
|
package/src/utils/error.js
CHANGED
package/types/index.d.ts
CHANGED
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
TrailingSlash
|
|
18
18
|
} from './private.js';
|
|
19
19
|
import { SSRNodeLoader, SSRRoute, ValidatedConfig } from './internal.js';
|
|
20
|
-
import { HttpError, Redirect } from '../src/
|
|
20
|
+
import { HttpError, Redirect } from '../src/runtime/control.js';
|
|
21
21
|
|
|
22
22
|
export interface Adapter {
|
|
23
23
|
name: string;
|
package/types/internal.d.ts
CHANGED
|
@@ -71,13 +71,16 @@ export interface CSRPageNode {
|
|
|
71
71
|
|
|
72
72
|
export type CSRPageNodeLoader = () => Promise<CSRPageNode>;
|
|
73
73
|
|
|
74
|
+
/**
|
|
75
|
+
* Definition of a client side route.
|
|
76
|
+
* The boolean in the tuples indicates whether the route has a server load.
|
|
77
|
+
*/
|
|
74
78
|
export type CSRRoute = {
|
|
75
79
|
id: string;
|
|
76
80
|
exec: (path: string) => undefined | Record<string, string>;
|
|
77
|
-
errors: CSRPageNodeLoader
|
|
78
|
-
layouts: CSRPageNodeLoader
|
|
79
|
-
leaf: CSRPageNodeLoader;
|
|
80
|
-
uses_server_data: boolean;
|
|
81
|
+
errors: Array<CSRPageNodeLoader | undefined>;
|
|
82
|
+
layouts: Array<[boolean, CSRPageNodeLoader] | undefined>;
|
|
83
|
+
leaf: [boolean, CSRPageNodeLoader];
|
|
81
84
|
};
|
|
82
85
|
|
|
83
86
|
export type GetParams = (match: RegExpExecArray) => Record<string, string>;
|
|
@@ -194,6 +197,9 @@ export type ServerData =
|
|
|
194
197
|
}
|
|
195
198
|
| {
|
|
196
199
|
type: 'data';
|
|
200
|
+
/**
|
|
201
|
+
* If `null`, then there was no load function
|
|
202
|
+
*/
|
|
197
203
|
nodes: Array<ServerDataNode | ServerDataSkippedNode | ServerErrorNode | null>;
|
|
198
204
|
};
|
|
199
205
|
|