-
-
Notifications
You must be signed in to change notification settings - Fork 180
/
svelte.ts
67 lines (65 loc) · 1.49 KB
/
svelte.ts
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
type View = {
page: any
frames: any[]
layout: any
error?: any
client: string
}
// TODO:
// - Test custom layouts
// - Support frames
// - Support default errors
// - Support custom errors
export function createView(view: View) {
view.layout = view.layout || defaultLayout
return function ({ props, context }) {
const page = view.page.render(props)
let css = page.css.code
let html = page.html
let head = page.head
// Render the layout
const hydrate = JSON.stringify(props)
const layout = view.layout.render(props, {
head: function () {
return `
${head}
<style>#bud{}${css}</style>
<script id="bud_props" type="text/template" defer>${hydrate}</script>
<script type="module" src="${view.client}" defer></script>
`
},
default: function () {
return '<div id="bud_target">' + html + "</div>"
},
})
html = layout.html.replace("#bud{}", layout.css.code)
return {
status: 200,
headers: {
"Content-Type": "text/html",
},
body: html,
}
}
}
const defaultLayout = {
render(props, slots) {
return {
css: {
code: "",
},
head: "",
html: `
<!doctype html>
<html>
<head>
<meta charset="utf-8"/>
<link rel="stylesheet" href="/default.css" />
${slots.head(props)}
</head>
<body>${slots.default(props)}</body>
</html>
`,
}
},
}