diff --git a/README.md b/README.md new file mode 100644 index 0000000..0a63ead --- /dev/null +++ b/README.md @@ -0,0 +1,72 @@ +# vu + +A static, offline-first PWA for praying the Divine Office — Matins, Lauds, Prime, Terce, Sext, +None, Vespers, and Compline — in bilingual Latin/English, for any given date. + +This isn't a reconstruction of any single historical breviary. It's a personal design that +draws on several historical sources without reproducing any one of them exactly: hour +structure chiefly from the Monastic Tridentinum (1617), precedence/rubrics from Divino +Afflatu, and a calendar merged from both the Tridentine 1906 and Divino Afflatu calendars, +with more generous handling of commemorations and octaves than any one historical rite used. +See `CLAUDE.md` (gitignored, not shipped in this repo) or the project's own notes for the full +rationale if you're extending it. + +There's no backend and no database — everything is a pre-built static bundle, and the app is +designed to keep working fully offline once it's been loaded once. + +## Development + +Requires Node.js (developed against Node 20+). + +```sh +npm install +npm run dev # start the Vite dev server +npm run build # type-check (tsc --noEmit) and produce a production build in dist/ +npm run preview # serve the production build locally +npm test # run the test suite (vitest) +``` + +Run a single test file or a subset by name: + +```sh +npx vitest run tests/hours/vespers.test.ts +npx vitest run -t "some test name" +``` + +## Running in production + +The app is entirely static once built, so "running it" just means serving `dist/` — any static +file host works, as long as it falls back to `index.html` for unknown paths (the app does its +own client-side routing for URLs like `/2026-08-09/prime`). + +### Docker + +A `Dockerfile` builds the static bundle with Node and serves it with Caddy: + +```sh +docker build -t vu . +docker run -p 8080:80 vu +``` + +Or with Docker Compose (`docker-compose.yml` is included): + +```sh +docker compose up -d --build +``` + +This serves the app on `http://localhost:8080`. Put a reverse proxy/TLS terminator in front of +it for a real deployment; the container itself just listens on port 80 internally and has no +configuration, secrets, or external dependencies. + +### Without Docker + +Any static file server works — build the app, then serve `dist/` with SPA-style fallback +routing. For example, with Caddy directly: + +```sh +npm run build +caddy file-server --root dist --listen :8080 +``` + +(For a real deployment you'll want a fallback rule so unknown paths resolve to `index.html` — +see the `Caddyfile` in this repo for the pattern.)