diff --git a/project-context.md b/project-context.md index 2b2b470..c395191 100644 --- a/project-context.md +++ b/project-context.md @@ -10,7 +10,7 @@ Havenllo (Haven + Trello) is a lightweight, single-user, no-authentication kanba - Go module `havenllo`, Go 1.24. - Backend: `modernc.org/sqlite`, pure Go and CGO-free. -- Frontend runtime: `preact`, `commonmark`, and `dompurify`; build tooling: `@preact/preset-vite`, `@types/commonmark`, `typescript`, and `vite`. +- Frontend runtime: `preact`, `commonmark`, and `dompurify`; build tooling: `@preact/preset-vite`, `@types/commonmark`, `@types/node`, `typescript`, and `vite`. - Card movement: custom Pointer Events interaction; no DnD library. - Static SPA assets are embedded with Go `embed` from `web/dist`. - Runtime port: `8080`; `HAVENLLO_LISTEN_ADDR` defaults to `:8080` and `HAVENLLO_DATABASE_PATH` defaults to `/data/havenllo.db`. @@ -52,7 +52,7 @@ Havenllo (Haven + Trello) is a lightweight, single-user, no-authentication kanba ### Embedding bridge -- `web/embed.go`: embeds `web/dist` and exports it as `web.Files` after stripping the `dist/` prefix. `web/dist` is generated and ignored; Docker rebuilds it. +- `web/embed.go`: embeds `web/dist` and exports it as `web.Files` after stripping the `dist/` prefix. `web/dist` is generated and ignored except for its tracked `.gitkeep` placeholder, which keeps Go embeds valid before Vite runs; `web/vite.config.ts` recreates that placeholder after every build. Docker rebuilds the real bundle. ## Backend Architecture diff --git a/web/dist/.gitkeep b/web/dist/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/web/package-lock.json b/web/package-lock.json index 83a1dd5..dd7aca3 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -15,6 +15,7 @@ "devDependencies": { "@preact/preset-vite": "^2.10.1", "@types/commonmark": "^0.27.10", + "@types/node": "^26.1.1", "typescript": "^5.8.3", "vite": "^6.3.5" } @@ -1344,6 +1345,16 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/node": { + "version": "26.1.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-26.1.1.tgz", + "integrity": "sha512-nxAkRSVkN1Y0JC1W8ky/fTfkGsMmcrRsbx+3XoZE+rMOX71kLYTV7fLXpqud1GpbpP5TuffXFqfX7fH2GgZREw==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~8.3.0" + } + }, "node_modules/@types/trusted-types": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", @@ -2048,6 +2059,13 @@ "node": ">=14.17" } }, + "node_modules/undici-types": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-8.3.0.tgz", + "integrity": "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==", + "dev": true, + "license": "MIT" + }, "node_modules/update-browserslist-db": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", diff --git a/web/package.json b/web/package.json index 8e63695..0952222 100644 --- a/web/package.json +++ b/web/package.json @@ -16,6 +16,7 @@ "devDependencies": { "@preact/preset-vite": "^2.10.1", "@types/commonmark": "^0.27.10", + "@types/node": "^26.1.1", "typescript": "^5.8.3", "vite": "^6.3.5" }, diff --git a/web/vite.config.ts b/web/vite.config.ts index cedf533..631cda3 100644 --- a/web/vite.config.ts +++ b/web/vite.config.ts @@ -1,11 +1,21 @@ +import { writeFileSync } from "node:fs"; import { defineConfig } from "vite"; import preact from "@preact/preset-vite"; +const embedPlaceholder = new URL("./dist/.gitkeep", import.meta.url); + export default defineConfig({ - plugins: [preact()], + plugins: [ + preact(), + { + name: "preserve-go-embed-placeholder", + closeBundle() { + writeFileSync(embedPlaceholder, ""); + } + } + ], build: { outDir: "dist", emptyOutDir: true } }); -