update
This commit is contained in:
71
main.ts
71
main.ts
@@ -13,20 +13,23 @@ const utf8Decoder = new TextDecoder("utf-8");
|
||||
|
||||
const parser = new DOMParser();
|
||||
|
||||
function appHeaderScript(params: { appstate: Record<string, unknown>; entryPath: string }) {
|
||||
function appHeaderScript(params: { ssrContext: DJSSRContext, entryPath: string }) {
|
||||
return `<script type="importmap">
|
||||
{
|
||||
"imports": {
|
||||
"vue": "/deps/vue/dist/vue.esm-browser.prod.js",
|
||||
"vue-router": "/deps/vue-router/dist/vue-router.esm-browser.js",
|
||||
"vue/jsx-runtime": "/deps/vue/jsx-runtime/index.mjs",
|
||||
"@vue/devtools-api": "/deps/@vue/devtools-api/lib/esm/index.js",
|
||||
"@vue/devtools-api": "/app/devtools-shim.ts",
|
||||
"@/": "/app/"
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
${ Object.values(params.ssrContext.styles).join('\n') }
|
||||
</style>
|
||||
<script type="module">
|
||||
window.appstate = ${JSON.stringify(params.appstate)};
|
||||
window.appstate = ${JSON.stringify(params.ssrContext.registry)};
|
||||
import('${params.entryPath}');
|
||||
</script>`;
|
||||
}
|
||||
@@ -47,7 +50,7 @@ for await (const path of publicFiles) {
|
||||
sites.push(path);
|
||||
}
|
||||
|
||||
function getAPIResponse(apiReq: Request): Response {
|
||||
async function getAPIResponse(apiReq: Request): Promise<Response> {
|
||||
let jsonResponse: DJAPIResult | { error: string } | null = null;
|
||||
let status = 200;
|
||||
|
||||
@@ -62,22 +65,42 @@ function getAPIResponse(apiReq: Request): Response {
|
||||
const apiPath = pathname.split("/api")[1];
|
||||
|
||||
if (apiPath === "/rp-articles") {
|
||||
jsonResponse = [
|
||||
{ name: "Koffein: ein vitamin-ähnlicher Nährstoff, oder Adaptogen", slug: "caffeine" },
|
||||
{
|
||||
name: "TSH, Temperatur, Puls, und andere Indikatoren bei einer Schilddrüsenunterfunktion",
|
||||
slug: "hypothyroidism",
|
||||
},
|
||||
] satisfies DJAPIResultMap["/rp-articles"];
|
||||
}
|
||||
const paths: string[] = [];
|
||||
const contentDir = './public/generative-energy/content/';
|
||||
for await (const dirEnt of Deno.readDir(contentDir)) {
|
||||
if (dirEnt.isFile && dirEnt.name.endsWith('.html')) {
|
||||
paths.push(`${contentDir}${dirEnt.name}`);
|
||||
}
|
||||
}
|
||||
const result: DJAPIResultMap['/rp-articles'] = [];
|
||||
for (const filePath of paths) {
|
||||
const content = await Deno.readTextFile(filePath);
|
||||
const dom = parser.parseFromString(content, 'text/html');
|
||||
const metadata = { title: '', tags: [] as string[], slug: '' };
|
||||
const metaTags = dom.querySelectorAll('meta') as unknown as NodeListOf<HTMLMetaElement>;
|
||||
for (const metaTag of metaTags) {
|
||||
const name = metaTag.attributes.getNamedItem('name')?.value ?? '';
|
||||
const content = metaTag.attributes.getNamedItem('content')?.value ?? '';
|
||||
if (name === 'title') {
|
||||
metadata.title = content;
|
||||
} else if (name === 'tags') {
|
||||
metadata.tags = content ? content.split(",") : [];
|
||||
} else if (name === 'slug') {
|
||||
metadata.slug = content;
|
||||
}
|
||||
}
|
||||
result.push(metadata);
|
||||
}
|
||||
jsonResponse = result;
|
||||
console.log(result);
|
||||
}
|
||||
}
|
||||
|
||||
if (!jsonResponse) {
|
||||
jsonResponse = { error: `API route ${ apiPath } not found.` };
|
||||
status = 404;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const headers = new Headers();
|
||||
headers.set("Content-Type", "application/json");
|
||||
return new Response(JSON.stringify(jsonResponse), {
|
||||
@@ -93,13 +116,17 @@ Deno.serve({
|
||||
console.log(`Listening on port http://${hostname}:${port}/`);
|
||||
},
|
||||
}, async (req, _conn) => {
|
||||
const timeStart = new Date().getTime();
|
||||
|
||||
let response: Response | null = null;
|
||||
|
||||
const url = URL.parse(req.url);
|
||||
|
||||
if (req.method === "GET") {
|
||||
const pathname = URL.parse(req.url)?.pathname ?? "/";
|
||||
const pathname = url?.pathname ?? "/";
|
||||
|
||||
if (pathname.startsWith("/api/")) {
|
||||
response = getAPIResponse(req);
|
||||
response = await getAPIResponse(req);
|
||||
}
|
||||
|
||||
// Public/static files
|
||||
@@ -144,7 +171,7 @@ Deno.serve({
|
||||
app.provide("dom-parse", (innerHTML: string) => {
|
||||
return parser.parseFromString(innerHTML, "text/html").documentElement;
|
||||
});
|
||||
const ssrContext: DJSSRContext = { registry: {}, head: { title: "" } };
|
||||
const ssrContext: DJSSRContext = { styles: {}, registry: {}, head: { title: "" } };
|
||||
if (router) {
|
||||
await router.replace(pathname.split("/generative-energy")[1]);
|
||||
await router.isReady();
|
||||
@@ -155,7 +182,7 @@ Deno.serve({
|
||||
.replaceAll("%TITLE%", toValue(ssrContext.head?.title) ?? "Site")
|
||||
.replace(
|
||||
`<!-- SSR HEAD OUTLET -->`,
|
||||
appHeaderScript({ appstate: ssrContext.registry, entryPath: clientEntry }),
|
||||
appHeaderScript({ ssrContext, entryPath: clientEntry }),
|
||||
);
|
||||
response = new Response(content, { headers: { "Content-Type": "text/html" } });
|
||||
}
|
||||
@@ -164,7 +191,13 @@ Deno.serve({
|
||||
response = new Response("Only GET allowed.", { status: 500 });
|
||||
}
|
||||
|
||||
return response ?? new Response("Not found.", { status: 404 });
|
||||
response ??= new Response("Not found.", { status: 404 })
|
||||
|
||||
const timeEnd = new Date().getTime();
|
||||
|
||||
console.log(`Request ${ url?.pathname ?? 'malformed' }\tStatus ${ response.status }, Duration ${ timeEnd - timeStart }ms`);
|
||||
|
||||
return response;
|
||||
});
|
||||
|
||||
Deno.addSignalListener("SIGINT", () => {
|
||||
|
||||
Reference in New Issue
Block a user