feat: static .html fragments

This commit is contained in:
Ayo 2023-10-19 12:07:43 +02:00
parent feea346f73
commit 655debf193
4 changed files with 60 additions and 16 deletions

View file

@ -28,15 +28,15 @@ We want a way to:
- use `<script server:setup>` to define logic that runs on the server, which then gets stripped away
**2. `src/components`**
- custom element constructor class files go here (only `.js` files for now)
- all components are automatically registered using their file names (e.g., a `hello-world.js` component can be used as `<hello-world>` element)
- the idea is, if it is a valid custom element constructor, just throw it in the `components` directory and it will work... vanilla, Lit, Stencil, or our own totally optional [Base Class](https://ayco.io/n/web-component-base) -- your choice!
- custom element constructor files (only `.js` files for now)
- all components are automatically registered using their file names; a `hello-world.js` component can be used as `<hello-world>`
- static `.html` fragments; a `my-header.html` fragment can be directly used as `<my-header>`
## Setting up
It's still very early in the project development and we have no packages published yet.
You can, however, experience the framework by cloning the project and play with the example files in the [special directories](#special-directories).
You can, however, experience the framework by cloning the project and play with the example files in the [special directories](#special-directories).
Do the following steps to get you started:

View file

@ -2,16 +2,23 @@
* McFly SSR logic
*/
import { ELEMENT_NODE, parse, render, renderSync, walkSync } from "ultrahtml";
import {
Node as UltraNode,
ELEMENT_NODE,
parse,
render,
renderSync,
walkSync,
} from "ultrahtml";
import { parseScript } from "esprima";
import config from "../mcfly.config";
const { components: componentType } = config();
export default eventHandler(async (event) => {
const { path } = event;
let html = await getHtml(path);
const { components: componentType } = config();
// transforms
const transforms = [doSetUp, deleteServerScripts];
if (html) {
@ -20,6 +27,8 @@ export default eventHandler(async (event) => {
}
}
html = await useFragments(html.toString());
if (!!componentType && !!html) {
html = await insertRegistry(html.toString(), componentType);
}
@ -48,9 +57,7 @@ async function insertRegistry(
type: "js" | "ts"
): Promise<string> {
const ast = parse(html);
const componentFiles = (await useStorage().getKeys("assets:components"))
.map((key) => key.replace("assets:components:", ""))
.filter((key) => key.includes(type));
const componentFiles = await getFiles(type);
const availableComponents = componentFiles.map((key) =>
key.replace(`.${type}`, "")
);
@ -193,3 +200,39 @@ function removeComments(script: string) {
});
return script;
}
async function useFragments(html: string) {
const fragmentFiles = await getFiles("html");
const availableFragments = fragmentFiles.map((key) => {
return {
key: key.replace(".html", ""),
text: "",
};
});
const ast = parse(html);
for (const fragment of availableFragments) {
fragment.text = await useStorage().getItem(
"assets:components:" + fragment.key + ".html"
);
}
walkSync(ast, (node) => {
const usedFragment = availableFragments.find(
(fragment) => fragment.key === node.name
);
if (node.type === ELEMENT_NODE && !!usedFragment) {
node.children.push(parse(usedFragment.text));
}
});
return render(ast);
}
async function getFiles(type: string) {
return (await useStorage().getKeys("assets:components"))
.map((key) => key.replace("assets:components:", ""))
.filter((key) => key.includes(type));
}

View file

@ -0,0 +1,6 @@
<header>
<a href="https://ayco.io/gh/mcfly">
<h1>McFly</h1>
</a>
<span>Back to the Basics. Into the Future.</span>
</header>

View file

@ -44,12 +44,7 @@
</style>
</head>
<body>
<header>
<a href="https://ayco.io/gh/mcfly">
<h1>McFly</h1>
</a>
<span>Back to the Basics. Into the Future.</span>
</header>
<awesome-header></awesome-header>
<main>
<p>
<strong>McFly</strong> is a full-stack no-framework framework that assists developers in leveraging the web platform.