import React from "react"; // Database connection is now handled by the centralized db module import { renderToString } from "react-dom/server"; import { AppShell } from "./src/frontend/AppShell"; import { Home } from "./src/frontend/pages/home"; import { NotFound } from "./src/frontend/pages/not-found"; import { Post } from "./src/frontend/pages/post"; import { dbConnection } from "./src/db"; function compressResponse(html: string, status?: number) { const compressed = Bun.gzipSync(Buffer.from(html)); return new Response(compressed, { status, headers: { "Content-Type": "text/html", "Content-Encoding": "gzip", "Vary": "Accept-Encoding" } }); } async function blogPosts(hmr: boolean) { const glob = new Bun.Glob("**/*.md"); const blogPosts: Record = {}; for await (const file of glob.scan("./content")) { const post = await import(`./content/${file}`, { with: { type: "html" } }); const route = `/${file.replace(/\.md$/, "")}`; dbConnection.getAllTags(); if (hmr) { // Use Bun Importer plugin for hot reloading in the browser blogPosts[`/hmr${route}`] = post.default; } else { // Use the Database for sending just the HTML or the HTML and AppShell blogPosts[route] = async (req: Request) => { const path = new URL(req.url).pathname; const post = dbConnection.getPost(path); if (!post) return compressResponse(renderToString(), 404); // Get adjacent posts for navigation const { previousPost, nextPost } = dbConnection.getAdjacentPosts(post.path); const data = { title: post.title, summary: post.summary, date: new Date(post.date), readingTime: post.reading_time, tags: post.tags || [], previousPost, nextPost, }; // AppShell is already loaded, just send the
content if (req.headers.get("shell-loaded") === "true") { return compressResponse( renderToString() ); } // AppShell is not loaded, send the with the
content inside return compressResponse( renderToString( , ) ); }; } } Object.keys(blogPosts).map((route) => { console.info(route); }); return blogPosts; } Bun.serve({ development: { hmr: true, console: true, }, routes: { // standard mounting of blog posts ...(await blogPosts(false)), // hot module replacement in development mode ...(process.env.NODE_ENV === "development" ? (await blogPosts(true)) : {}), // Home page "/": (req: Request) => { // Extract URL parameters from the request to pass to the component const searchParams = new URLSearchParams(req.url.split('?')[1]); if (req.headers.get("shell-loaded") === "true") { return compressResponse(renderToString()); } return compressResponse( renderToString( , ) ); }, "/profile-picture.webp": () => { return new Response(Bun.file("./src/public/profile-picture.webp"), { headers: { "Content-Type": "image/webp", }, }); }, "/*": (req) => { if(req.headers.get("shell-loaded") === "true") { return compressResponse(renderToString(), 404); } return compressResponse(renderToString(), 404); } }, });