Files
mathew/frontend/src-tauri/README.md
Aran Roig e2c2c66d7f
Some checks failed
Build and Deploy Lean / build (push) Failing after 16m44s
Build and Deploy Nuxt / build (push) Failing after 48s
Vibecoded CI/CD
2026-10-06 00:23:17 +02:00

79 lines
4.7 KiB
Markdown

# src-tauri/ — the app window
Mathew as a **desktop app** (Tauri 2, Linux / Windows / macOS): the wiki in a
window of its own, no browser around it. The shell is deliberately thin — the
app *is* the same Nuxt bundle the website serves, written out as plain files
and embedded in the binary. Nothing in `frontend/app/` is desktop code; the
bundle asks at run time whether it happens to be sitting in a window
(`app/utils/desktop.ts`) and only then takes the window's habits: a link leads
out to the system's browser instead of replacing the wiki in the only view
there is, and the session token and interface language are mirrored into
`localStorage` because a webview is not everywhere obliged to keep cookies for
its own `tauri://localhost` address.
The wiki needs a wiki to talk to: the window holds no server and no database.
It calls the **public Mathew** over HTTPS by default — the API base is baked in
at build, see the table below.
## Build & run
From `frontend/` — these need [Rust](https://rustup.rs) (stable) and the
[Tauri prerequisites](https://v2.tauri.app/start/prerequisites/) for your OS;
on Linux that is the WebKitGTK stack:
`libwebkit2gtk-4.1-dev libgtk-3-dev libssl-dev libxdo-dev librsvg2-dev build-essential`.
| Script | What it does |
| --- | --- |
| `npm run desktop:dev` | `tauri dev` — opens the **Nuxt dev server** (`localhost:3000`, started for you) in the window, hot-reload included; `isDesktop()` is already true inside it |
| `npm run desktop:build` | `tauri build` — runs `desktop:generate` (below), compiles the shell, embeds the files, and leaves installers under `src-tauri/target/release/bundle/` (deb/rpm/AppImage on Linux, NSIS/MSI on Windows, .app/.dmg on macOS) |
| `npm run desktop:generate` | the bundle the window loads: `MATHEW_DESKTOP=1 nuxt generate` → `dist-desktop/public`, the `frontendDist` this config names (a desktop build never overwrites the web `.output/`) |
| `npm run desktop:icons` | re-cuts `src-tauri/icons/` from `desktop/icon-source.png` (redraw that one with `python3 desktop/make-icon.py`) |
The desktop shape lives in `nuxt.config.ts` under one flag
(`MATHEW_DESKTOP=1`, also implied by the `TAURI_ENV_*` the Tauri CLI passes to
its build hooks): `ssr: false`, no `/api` proxy route, and the pre-paint theme
script served from `public/preboot.js` instead of inline. The web build takes
none of it. Deep routes (`/wiki/en/bayes-theorem`, …) are not files in the
bundle — Tauri's own asset serving answers unknown paths with `index.html`, so
the client router takes over exactly as it does on a static host.
**Dev-server port**: `devUrl` is fixed to `3000`, and Nuxt falls back to `3001`
when `3000` is taken (see the main gotchas) — free the port before
`desktop:dev`, or the window loads whatever else answers there.
## Where the app reaches
| Build variable | Default (desktop) | Meaning |
| --- | --- | --- |
| `NUXT_PUBLIC_API_BASE` | `https://mathew.aranroig.com` | the wiki the app reads and writes; point it at `http://localhost:5000` to test against this machine |
| `NUXT_PUBLIC_LEAN_URL` | empty | the Lean server `/lean` talks to; empty leaves that page saying there is no server here, which is the honest answer on a random laptop. The API's default CORS (`*`) carries the window's `tauri://localhost` origin fine — it sends a bearer header, not cookies |
Set them in the environment before `npm run desktop:build`.
## What the shell owns
- **one window per launch** — `tauri-plugin-single-instance`: pressing the
icon again brings the open window forward instead of stacking a second wiki
behind it (`src/lib.rs`).
- **the way out** — `tauri-plugin-opener` is the door `app/utils/desktop.ts`
hands outward links to the system's browser; `capabilities/default.json` is
what grants it. That and `core:default` are the whole permission list:
reading and writing the wiki is the webview's own business.
- **no CSP** (`csp: null` in `tauri.conf.json`): the window loads no foreign
script and talks to one API over HTTPS, and `/lean`'s Monaco wants
`eval`-like tricks a strict `script-src` would have to excuse. The one
script the page writes itself (the pre-paint theme, `public/preboot.js`)
already lives in a **file**, so turning a policy on later is a config line —
keep it that way if one is ever set.
Nothing here is signed: bundles come out unsigned, and updating is
reinstalling. An updater, signing, and a per-machine "which wiki?" setting are
the obvious next steps if this ever ships for real.
## Versioning
The app's version lives in `tauri.conf.json` (`version`); it names the
installers and the platform bundle metadata. Commit `Cargo.lock` once a build
has produced one — for an application binary, a locked dependency set is what
makes a rebuild reproducible.