feat: really crude server:setup logic

This commit is contained in:
Ayo 2023-10-10 17:49:33 +02:00
parent 92db1c9059
commit 9608cb6f56
5 changed files with 66 additions and 13 deletions

8
package-lock.json generated
View file

@ -5,7 +5,8 @@
"packages": {
"": {
"dependencies": {
"nitropack": "latest"
"nitropack": "latest",
"ultrahtml": "^1.5.2"
}
},
"node_modules/@cloudflare/kv-asset-handler": {
@ -3624,6 +3625,11 @@
"resolved": "https://registry.npmjs.org/ufo/-/ufo-1.3.1.tgz",
"integrity": "sha512-uY/99gMLIOlJPwATcMVYfqDSxUR9//AUcgZMzwfSTJPDKzA1S8mX4VLqa+fiAtveraQUBCz4FFcwVZBGbwBXIw=="
},
"node_modules/ultrahtml": {
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/ultrahtml/-/ultrahtml-1.5.2.tgz",
"integrity": "sha512-qh4mBffhlkiXwDAOxvSGxhL0QEQsTbnP9BozOK3OYPEGvPvdWzvAUaXNtUSMdNsKDtuyjEbyVUPFZ52SSLhLqw=="
},
"node_modules/uncrypto": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/uncrypto/-/uncrypto-0.1.3.tgz",

View file

@ -9,6 +9,7 @@
"build:preview": "npm run build && npm run preview"
},
"dependencies": {
"nitropack": "latest"
"nitropack": "latest",
"ultrahtml": "^1.5.2"
}
}

View file

@ -1,3 +1,5 @@
import { ELEMENT_NODE, parse, walkSync } from "ultrahtml";
export default eventHandler(async (event) => {
const rawPath =
event.path[event.path.length - 1] === "/"
@ -10,14 +12,58 @@ export default eventHandler(async (event) => {
if (!html) html = await useStorage().getItem(fallback);
if (!html) html = await useStorage().getItem(getPath("/404.html"));
// temporary; use ultrahtml later
const registryScript =
'<script type="module" src="./.output/registry.js"></script>';
html = html.toString().replace("</head>", registryScript + "</head>");
// transforms
const transforms = [insertRegistry, doSetUp];
if (html) {
for (const transform of transforms) {
html = transform(html.toString());
}
}
return html ?? new Response("Not found", { status: 404 });
});
function getPath(filename: string) {
return `assets/pages${filename}`;
}
function insertRegistry(html: string): string {
// temporary; use ultrahtml later
const registryScript =
'<script type="module" src="./.output/registry.js"></script>';
return html.toString().replace("</head>", registryScript + "</head>");
}
function doSetUp(html: string) {
const ast = parse(html);
const serverScripts = [];
walkSync(ast, (node) => {
const { attributes } = node;
const attributeKeys = Object.keys(attributes ?? {});
const isServerScript = attributeKeys.some((key) => key.includes("server:"));
const isInHead = node.parent?.name === "head";
if (
node.type === ELEMENT_NODE &&
node.name === "script" &&
isServerScript &&
isInHead
) {
const scripts = node.children.map((child) => child.value);
serverScripts.push(scripts.join(" "));
}
});
const setupMap = {};
serverScripts.forEach((script: string) => {
console.log(script);
const constructor = `
new Function(\`${script}\`);
`;
const evalStore = eval(constructor);
Object.assign(setupMap, new evalStore());
console.log(">>> from server", setupMap);
});
return html.replace("{{name}}", setupMap["name"]);
}

View file

@ -9,7 +9,7 @@ export default class HelloWorld extends WebComponent {
let count = 0;
this.onclick = () => {
console.log("Clicked!");
this.setAttribute("name", `I was clicked ${++count} times`);
this.setAttribute("name", `I was clicked ${++count} times!`);
};
this.setAttribute("title", "Click me please");
}

View file

@ -4,9 +4,9 @@
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Hello Nitro</title>
<script setup>
// define logic that runs on the server
const name = "Ayo";
<script server:setup>
const name = "AYOs";
return { name };
</script>
</head>
<body>
@ -16,11 +16,11 @@
</div>
<span>some text</span>
<clickable-text></clickable-text>
<script>
<!-- <script>
const helloWorld = document.querySelector("hello-world");
setTimeout(() => {
helloWorld.setAttribute("name", "Nitro");
}, 2000);
</script>
</script> -->
</body>
</html>