-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Move the hydration code to a file (#26)
- Loading branch information
Showing
2 changed files
with
52 additions
and
28 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,6 +12,7 @@ | |
"editor.defaultFormatter": "denoland.vscode-deno" | ||
}, | ||
"cSpell.words": [ | ||
"hydrator", | ||
"mononykus" | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,58 @@ | ||
import { normalize } from "https://deno.land/[email protected]/path/mod.ts"; | ||
import { format } from "npm:prettier"; | ||
|
||
// dummy value to put the var name in scope | ||
const component_path = ""; | ||
|
||
// this function is stringified inline in the page | ||
// putting it here gives us type safety etc | ||
export const hydrate_island = async (target: Element) => { | ||
try { | ||
const name = target.getAttribute("name"); | ||
const props = JSON.parse(target.getAttribute("props") ?? "{}"); | ||
const load = performance.now(); | ||
|
||
const Component = | ||
(await import(component_path + name + ".island.js")).default; | ||
console.group(name); | ||
console.info( | ||
`Loaded in %c${Math.round((performance.now() - load) * 1000) / 1000}ms`, | ||
"color: orange", | ||
); | ||
|
||
const hydrate = performance.now(); | ||
new Component({ target, props, hydrate: true }); | ||
target.setAttribute("foraged", ""); | ||
|
||
console.info( | ||
`Hydrated in %c${ | ||
Math.round((performance.now() - hydrate) * 1000) / 1000 | ||
}ms%c with`, | ||
"color: orange", | ||
"color: reset", | ||
props, | ||
); | ||
console.groupEnd(); | ||
} catch (_) { | ||
console.error(_); | ||
} | ||
}; | ||
|
||
interface TemplateOptions { | ||
css: string; | ||
head: string; | ||
html: string; | ||
hydrate: string; | ||
hydrator: string; | ||
} | ||
const template = ({ css, head, html, hydrate }: TemplateOptions) => ` | ||
const template = ({ css, head, html, hydrator }: TemplateOptions) => ` | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8" /> | ||
<meta http-equiv="X-UA-Compatible" content="IE=edge" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
${head} | ||
<script type="module">${hydrate}</script> | ||
<script type="module">${hydrator}</script> | ||
<style>${css}</style> | ||
</head> | ||
<body> | ||
|
@@ -24,38 +61,24 @@ const template = ({ css, head, html, hydrate }: TemplateOptions) => ` | |
</html> | ||
`; | ||
|
||
const islands = (base = "") => ` | ||
const hydrate = async (target) => { | ||
try { | ||
const name = target.getAttribute("name"); | ||
const props = JSON.parse(target.getAttribute("props") ?? "{}"); | ||
const load = performance.now(); | ||
const Component = (await import('${ | ||
normalize(`/${base}/components/`) | ||
}' + name + '.island.js')).default; | ||
console.group(name); | ||
console.info(\`Loaded in %c\${Math.round((performance.now() - load) * 1000) / 1000}ms\`, "color: orange"); | ||
const hydrate = performance.now(); | ||
new Component({ target, props, hydrate: true }); | ||
target.setAttribute("foraged", ""); | ||
console.info(\`Hydrated in %c\${Math.round((performance.now() - hydrate) * 1000) / 1000}ms%c with\`, "color: orange", "color: reset", props); | ||
console.groupEnd(); | ||
} catch (_) { | ||
console.error(_) | ||
} | ||
}; | ||
document.querySelectorAll("one-claw[name]").forEach(hydrate);`; | ||
const island_hydrator = (base = "") => ` | ||
const component_path = "${base}"; | ||
const hydrate_island = ${hydrate_island.toString()}; | ||
document.querySelectorAll("one-claw[name]").forEach(hydrate_island); | ||
`; | ||
|
||
export const get_route_html = ({ html, css, head, base_path }: { | ||
html: string; | ||
css: string; | ||
head: string; | ||
base_path?: string; | ||
}) => { | ||
const page = template({ css, head, html, hydrate: islands(base_path) }); | ||
const page = template({ | ||
css, | ||
head, | ||
html, | ||
hydrator: island_hydrator(normalize(`/${base_path}/components/`)), | ||
}); | ||
|
||
try { | ||
return format( | ||
|