- TypeScript 73.3%
- JavaScript 15.7%
- CSS 10.5%
- Dockerfile 0.5%
|
|
||
|---|---|---|
| .forgejo/workflows | ||
| app | ||
| components | ||
| lib | ||
| public | ||
| scripts | ||
| tests | ||
| .dockerignore | ||
| .gitignore | ||
| .npmrc | ||
| AGENTS.md | ||
| CLAUDE.md | ||
| components.json | ||
| detlef-runtime.json | ||
| Dockerfile | ||
| eslint.config.mjs | ||
| LICENSE | ||
| next.config.ts | ||
| package-lock.json | ||
| package.json | ||
| postcss.config.mjs | ||
| README.md | ||
| tsconfig.json | ||
Personal Website
Personal portfolio website built with:
- Next.js
- TypeScript
- Tailwind CSS
- shadcn/ui
Includes:
- portfolio/projects
- blog/articles
- chatbot integration
- multilingual support
Development
Install dependencies:
npm install
Start development server:
npm run dev
Environment Variables
NEXT_PUBLIC_CHAT_API_URL=/api/chat
NEXT_PUBLIC_TURNSTILE_SITE_KEY=...
Production
The site is deployed as a Docker container behind Nginx.
Detlef playground
/projects/detlef runs the release-built Wasm interpreter in a browser worker. The console
supports print() and read_line(), including empty lines and EOF. Each run starts
a fresh interpreter instance while reusing the worker and loaded Wasm module.
The worker starts loading when the playground mounts, before the first run.
Program output comes only from explicit print() calls; expression
results are not echoed. Programs can run until they finish or Stop is pressed.
Stop terminates the worker and immediately preloads a replacement.
Worker failures and Wasm traps terminate it; the next run loads a replacement.
Normal completion and ordinary language errors reuse it.
detlef-runtime.json pins the Forgejo release archive and its SHA-256 checksum.
npm run dev, npm run build, and npm run test:detlef prepare the runtime
automatically through their npm pre-scripts. It can also be prepared explicitly:
npm run prepare:detlef
Preparation requires Node.js and tar (available on Windows, macOS, and in the
Alpine Docker image). The first run downloads the pinned SDK over HTTPS and verifies
its checksum before extracting only the JavaScript modules, browser bindings, Wasm
binary, and license into public/detlef/runtime/. That directory and the archive
cache in .cache/detlef/ are generated and ignored by Git. Verified installed files
are reused offline; missing or modified files are restored from the verified cache.
Download, checksum, and extraction failures stop preparation instead of falling
back to another release. A corrupt cached archive can be removed from .cache/detlef/
before retrying.
To update Detlef, change the version, archive URL, and SHA-256 in
detlef-runtime.json, using the matching entry from that release's SHA256SUMS.
Then run npm run test:detlef and npm run build before committing the new pin.
The Docker build performs the same preparation and ships the generated runtime
in the final image; SDK files and downloads are not needed at container startup.
The worker, website integrations, logos, and favicons remain website source assets.
The worker uses shared memory so the synchronous read_line() can wait without
blocking React. Cross-origin isolation headers are configured only for this project
page and its runtime files. They must also be retained by the production proxy.
The project card uses a full navigation because client routing alone does not apply
new document headers. Cross-origin embeds on this page must support its isolation
policy. The Wasm build remains experimental.
The playground also exposes these site functions:
| Function | Behavior |
|---|---|
set_design("light" / "dark" / "aero") |
Change the site theme. |
get_design() |
Read the active theme (including the resolved system theme). |
set_language("de" / "en") |
Change the site language. |
get_language() |
Read the site language. |
set_font("comic" / "impact" / "mono" / "wingdings" / "reset") |
Set or reset the bonus font. |
clear_console() |
Clear the output, including text buffered in the worker. |
barrel_roll() |
Spin the page, at most once per second. |
retro(true) / retro(false) |
Enable or disable the playground's Windows 95 look. |
Setters return none on success or a descriptive error string for invalid values;
use optional(string) and is_none() to handle the result without stopping the
program. Wrong argument types or arity still use normal Detlef diagnostics.
Settings persist through the existing website controls. Site changes are limited
to 128 per run. A separate shared-memory channel lets these synchronous functions
wait for the browser's response while keeping the page responsive.
Retro mode affects only the playground and lasts across runs until the page is
left or reloaded. Use retro(true) to enable it and retro(false) to restore the
current site design. Repeating the same call keeps the requested state. Like the
other setters, it returns none on success.