feat: really crude server:setup logic
This commit is contained in:
parent
92db1c9059
commit
9608cb6f56
5 changed files with 66 additions and 13 deletions
8
package-lock.json
generated
8
package-lock.json
generated
|
@ -5,7 +5,8 @@
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"nitropack": "latest"
|
"nitropack": "latest",
|
||||||
|
"ultrahtml": "^1.5.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@cloudflare/kv-asset-handler": {
|
"node_modules/@cloudflare/kv-asset-handler": {
|
||||||
|
@ -3624,6 +3625,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/ufo/-/ufo-1.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/ufo/-/ufo-1.3.1.tgz",
|
||||||
"integrity": "sha512-uY/99gMLIOlJPwATcMVYfqDSxUR9//AUcgZMzwfSTJPDKzA1S8mX4VLqa+fiAtveraQUBCz4FFcwVZBGbwBXIw=="
|
"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": {
|
"node_modules/uncrypto": {
|
||||||
"version": "0.1.3",
|
"version": "0.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/uncrypto/-/uncrypto-0.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/uncrypto/-/uncrypto-0.1.3.tgz",
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
"build:preview": "npm run build && npm run preview"
|
"build:preview": "npm run build && npm run preview"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"nitropack": "latest"
|
"nitropack": "latest",
|
||||||
|
"ultrahtml": "^1.5.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import { ELEMENT_NODE, parse, walkSync } from "ultrahtml";
|
||||||
|
|
||||||
export default eventHandler(async (event) => {
|
export default eventHandler(async (event) => {
|
||||||
const rawPath =
|
const rawPath =
|
||||||
event.path[event.path.length - 1] === "/"
|
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(fallback);
|
||||||
if (!html) html = await useStorage().getItem(getPath("/404.html"));
|
if (!html) html = await useStorage().getItem(getPath("/404.html"));
|
||||||
|
|
||||||
// temporary; use ultrahtml later
|
// transforms
|
||||||
const registryScript =
|
const transforms = [insertRegistry, doSetUp];
|
||||||
'<script type="module" src="./.output/registry.js"></script>';
|
if (html) {
|
||||||
html = html.toString().replace("</head>", registryScript + "</head>");
|
for (const transform of transforms) {
|
||||||
|
html = transform(html.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
return html ?? new Response("Not found", { status: 404 });
|
return html ?? new Response("Not found", { status: 404 });
|
||||||
});
|
});
|
||||||
|
|
||||||
function getPath(filename: string) {
|
function getPath(filename: string) {
|
||||||
return `assets/pages${filename}`;
|
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"]);
|
||||||
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ export default class HelloWorld extends WebComponent {
|
||||||
let count = 0;
|
let count = 0;
|
||||||
this.onclick = () => {
|
this.onclick = () => {
|
||||||
console.log("Clicked!");
|
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");
|
this.setAttribute("title", "Click me please");
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,9 +4,9 @@
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>Hello Nitro</title>
|
<title>Hello Nitro</title>
|
||||||
<script setup>
|
<script server:setup>
|
||||||
// define logic that runs on the server
|
const name = "AYOs";
|
||||||
const name = "Ayo";
|
return { name };
|
||||||
</script>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
@ -16,11 +16,11 @@
|
||||||
</div>
|
</div>
|
||||||
<span>some text</span>
|
<span>some text</span>
|
||||||
<clickable-text></clickable-text>
|
<clickable-text></clickable-text>
|
||||||
<script>
|
<!-- <script>
|
||||||
const helloWorld = document.querySelector("hello-world");
|
const helloWorld = document.querySelector("hello-world");
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
helloWorld.setAttribute("name", "Nitro");
|
helloWorld.setAttribute("name", "Nitro");
|
||||||
}, 2000);
|
}, 2000);
|
||||||
</script>
|
</script> -->
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
Loading…
Reference in a new issue