Compare commits

...
Sign in to create a new pull request.

1 commit

Author SHA1 Message Date
bf85b4d81c
init preact testing
All checks were successful
Code quality checks / biome (push) Successful in 10s
2025-04-13 10:57:52 -04:00
8 changed files with 92 additions and 2 deletions

2
.gitignore vendored
View file

@ -3,3 +3,5 @@ bun.lock
.env .env
/uploads /uploads
.idea .idea
temp
.vscode/settings.json

View file

@ -32,6 +32,7 @@
"fluent-ffmpeg": "^2.1.3", "fluent-ffmpeg": "^2.1.3",
"image-thumbnail": "^1.0.17", "image-thumbnail": "^1.0.17",
"luxon": "^3.6.1", "luxon": "^3.6.1",
"preact-render-to-string": "^6.5.13",
"redis": "^4.7.0" "redis": "^4.7.0"
} }
} }

42
src/components/head.tsx Normal file
View file

@ -0,0 +1,42 @@
import type { FunctionalComponent, JSX } from "preact";
export const Head: FunctionalComponent<Props> = ({
title,
styles,
scripts,
}): JSX.Element => (
<>
<meta charSet="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="color-scheme" content="dark" />
{title && <title>{title}</title>}
<link rel="stylesheet" href="/public/css/global.css" />
{styles?.map(
(style): JSX.Element => (
<link key={style} rel="stylesheet" href={`/public/css/${style}.css`} />
),
)}
{scripts?.map(
(script: string | [string, boolean]): JSX.Element | undefined => {
if (typeof script === "string") {
return <script src={`/public/js/${script}.js`} defer />;
}
if (Array.isArray(script)) {
return (
<script
src={`/public/js/${script[0]}.js`}
{...(script[1] ? { defer: true } : {})}
/>
);
}
},
)}
<script src="/public/js/global.js" />
</>
);

26
src/routes/test.tsx Normal file
View file

@ -0,0 +1,26 @@
import { HtmlShell } from "@/templates/shell";
import { render } from "preact-render-to-string";
import type { JSX } from "preact/jsx-runtime";
const routeDef = {
method: "GET",
accepts: "*/*",
returns: "text/html",
};
async function handler(request: ExtendedRequest): Promise<Response> {
const name = "test";
const page: JSX.Element = (
<HtmlShell title="Test Page" styles={[]} scripts={[]}>
<div class="foo">test {name}</div>
</HtmlShell>
);
return new Response(`<!DOCTYPE html>${render(page)}`, {
headers: {
"Content-Type": "text/html",
},
});
}
export { handler, routeDef };

View file

@ -23,7 +23,7 @@ class ServerHandler {
this.router = new FileSystemRouter({ this.router = new FileSystemRouter({
style: "nextjs", style: "nextjs",
dir: "./src/routes", dir: "./src/routes",
fileExtensions: [".ts"], fileExtensions: [".ts", ".tsx"],
origin: `http://${this.host}:${this.port}`, origin: `http://${this.host}:${this.port}`,
}); });
} }

12
src/templates/shell.tsx Normal file
View file

@ -0,0 +1,12 @@
import { Head } from "@/components/head";
export function HtmlShell({ title, styles, scripts, children }: Props) {
return (
<html lang="en">
<head>
<Head title={title} styles={styles} scripts={scripts} />
</head>
<body>{children}</body>
</html>
);
}

View file

@ -14,7 +14,8 @@
"module": "ESNext", "module": "ESNext",
"moduleDetection": "force", "moduleDetection": "force",
"jsx": "react-jsx", "jsx": "react-jsx",
"allowJs": true, "jsxImportSource": "preact",
"allowJs": false,
// Bundler mode // Bundler mode
"moduleResolution": "bundler", "moduleResolution": "bundler",
"allowImportingTsExtensions": true, "allowImportingTsExtensions": true,

6
types/preact.d.ts vendored Normal file
View file

@ -0,0 +1,6 @@
type Props = {
title?: string;
styles?: string[];
scripts?: (string | [string, boolean])[];
children?: preact.ComponentChildren;
};