-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
/
write_client_manifest.js
97 lines (82 loc) · 2.57 KB
/
write_client_manifest.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import { relative } from 'path';
import { s } from '../../utils/misc.js';
import { trim, write_if_changed } from './utils.js';
/**
* Writes the client manifest to disk. The manifest is used to power the router. It contains the
* list of routes and corresponding Svelte components (i.e. pages and layouts).
* @param {import('types').ManifestData} manifest_data
* @param {string} output
*/
export function write_client_manifest(manifest_data, output) {
/**
* Creates a module that exports a `CSRPageNode`
* @param {import('types').PageNode} node
*/
function generate_node(node) {
const declarations = [];
if (node.shared) {
declarations.push(
`import * as shared from ${s(relative(`${output}/nodes`, node.shared))};`,
`export { shared };`
);
}
if (node.component) {
declarations.push(
`export { default as component } from ${s(relative(`${output}/nodes`, node.component))};`
);
}
if (node.server) {
declarations.push(`export const server = true;`);
}
return declarations.join('\n');
}
const nodes = manifest_data.nodes
.map((node, i) => {
write_if_changed(`${output}/nodes/${i}.js`, generate_node(node));
return `() => import('./nodes/${i}')`;
})
.join(',\n\t');
const dictionary = `{
${manifest_data.routes
.map((route) => {
if (route.page) {
const errors = route.page.errors.slice(1).map((n) => n ?? '');
const layouts = route.page.layouts.slice(1).map((n) => {
if (n == undefined) {
return '';
}
return get_node_id(manifest_data.nodes, n);
});
while (layouts.at(-1) === '') layouts.pop();
while (errors.at(-1) === '') errors.pop();
const array = [get_node_id(manifest_data.nodes, route.page.leaf)];
// only include non-root layout/error nodes if they exist
if (layouts.length > 0 || errors.length > 0) array.push(`[${layouts.join(',')}]`);
if (errors.length > 0) array.push(`[${errors.join(',')}]`);
return `${s(route.id)}: [${array.join(',')}]`;
}
})
.filter(Boolean)
.join(',\n\t\t')}
}`.replace(/^\t/gm, '');
// String representation of __GENERATED__/client-manifest.js
write_if_changed(
`${output}/client-manifest.js`,
trim(`
export { matchers } from './client-matchers.js';
export const nodes = [
${nodes}
];
export const dictionary = ${dictionary};
`)
);
}
/**
* Encode whether or not the route uses the server data
* using the ones' complement, to save space
* @param {import('types').PageNode[]} nodes
* @param {number} id
*/
function get_node_id(nodes, id) {
return `${nodes[id].server ? '~' : ''}${id}`;
}