diff --git a/packages/assets/mcfly-ssr.ts b/packages/assets/mcfly-ssr.ts deleted file mode 100644 index 25b470b..0000000 --- a/packages/assets/mcfly-ssr.ts +++ /dev/null @@ -1,158 +0,0 @@ -/** - * McFly SSR logic - */ - -import { ELEMENT_NODE, parse, renderSync, walkSync } from "ultrahtml"; -import { parseScript } from "esprima"; - -export default eventHandler(async (event) => { - const { path } = event; - let html = await getHtml(path); - - // transforms - const transforms = [doSetUp, deleteServerScripts, insertRegistry]; - if (html) { - for (const transform of transforms) { - html = transform(html.toString()); - } - } - - return html ?? new Response("Not found", { status: 404 }); -}); - -const getHtml = async (path: string) => { - const rawPath = path[path.length - 1] === "/" ? path.slice(0, -1) : path; - const filename = rawPath === "" ? "/index.html" : `${rawPath}.html`; - const fallback = getPath(rawPath + "/index.html"); - const filePath = getPath(filename); - let html = await useStorage().getItem(filePath); - if (!html) html = await useStorage().getItem(fallback); - if (!html) html = await useStorage().getItem(getPath("/404.html")); - - return html; -}; - -function getPath(filename: string) { - return `assets/pages${filename}`; -} - -function insertRegistry(html: string): string { - // temporary; use ultrahtml later - const registryScript = - ''; - - const ast = parse(html); - - let hasCustomElements = false; - - walkSync(ast, (node) => { - if (node.type === ELEMENT_NODE && node.name.includes("-")) { - hasCustomElements = true; - } - }); - - // insert registry script to head - if (hasCustomElements) - walkSync(ast, (node) => { - if (node.type === ELEMENT_NODE && node.name === "head") { - node.children.push(parse(registryScript)); - } - }); - - return renderSync(ast); -} - -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:")); - if ( - node.type === ELEMENT_NODE && - node.name === "script" && - isServerScript - ) { - const scripts = node.children.map((child) => child.value); - const script = cleanScript(scripts); - serverScripts.push(script); - } - }); - - const setupMap = {}; - serverScripts.forEach((script: string) => { - const { body } = parseScript(script); - const keys = body - .filter((node) => node.type === "VariableDeclaration") - .map((node) => node.declarations[0].id.name); - const constructor = `(function(){}.constructor)(\`${script}; return {${keys.join( - "," - )}}\`);`; - const evalStore = eval(constructor); - Object.assign(setupMap, new evalStore()); - }); - - const regex = /{{(.*?)}}/g; - var match; - - while ((match = regex.exec(html))) { - let [key, value] = match; - value = value.replace(/\s/g, ""); - html = html.replace(key, setupMap[value]); - } - - return html; -} - -function deleteServerScripts(html: string): string { - const ast = parse(html); - walkSync(ast, (node) => { - const { attributes } = node; - const attributeKeys = Object.keys(attributes ?? {}); - const isServerScript = attributeKeys.some((key) => key.includes("server:")); - if (isServerScript) { - node.parent.children.splice(node.parent.children.indexOf(node), 1); - } - }); - - return renderSync(ast); -} - -function cleanScript(scripts: string[]): string { - let script = scripts.map((s) => s.trim()).join(" "); - - script = removeComments(script); - - return script.replace(/\n/g, "").replace(/\s+/g, " "); -} - -function isComment(node) { - return ( - node.type === "Line" || - node.type === "Block" || - node.type === "BlockComment" || - node.type === "LineComment" - ); -} - -function removeComments(script: string) { - const entries = []; - parseScript(script, { comment: true }, function (node, meta) { - if (isComment(node)) { - entries.push({ - start: meta.start.offset, - end: meta.end.offset, - }); - } - }); - - entries - .sort((a, b) => { - return b.end - a.end; - }) - .forEach((n) => { - script = script.slice(0, n.start) + script.slice(n.end); - }); - return script; -} diff --git a/src/pages/index.html b/src/pages/index.html index cd14dc3..d30b112 100644 --- a/src/pages/index.html +++ b/src/pages/index.html @@ -8,5 +8,6 @@