feat: initial Racecraft web client v0.1.0

Vue 3 + TypeScript + Vite web client for rusty-telemetry.

- Dashboard with system status, live feeds, quick actions
- Live telemetry view with real-time gauges (speed/RPM/gear)
- Session management (create, run, complete, analyze)
- Shift point analysis with Chart.js visualizations
- Track map with Canvas 2D boundary rendering
- Typed API client for all 19 REST endpoints
- Dark theme, network-accessible via Vite 0.0.0.0 bind
This commit is contained in:
Jan-Peter von Hunnius 2026-06-05 16:12:33 +02:00
commit cf9af73281
27 changed files with 5123 additions and 0 deletions

174
README.md Normal file
View file

@ -0,0 +1,174 @@
# Racecraft
Web-based sim racing telemetry analysis client. Connects to [rusty-telemetry](https://codeberg.org/jhunnius/rusty-telemetry) via its REST API and provides live telemetry visualization, session management, and data analysis.
## Architecture
```
┌─────────────────────────────────────────────────┐
│ Sim Machine │
│ │
│ ┌──────────────┐ ┌───────────────┐ │
│ │ Assetto │ │ rusty- │ │
│ │ Corsa │──│ telemetry │ │
│ │ (UDP out) │ │ :8080 (API) │ │
│ └──────────────┘ └───────────────┘ │
│ ┌───────────────┐ │
│ │ racecraft │ │
│ │ :5173 (Vite) │ │
│ └───────────────┘ │
└─────────────────────────────────────────────────┘
│
LAN / WiFi
│
┌──────────────────┐
│ Other machine │
│ Browser │
└──────────────────┘
```
- **rusty-telemetry** listens for UDP telemetry from sim games on ports 9996, 10101, 5606
- **racecraft** is a Vue.js SPA that talks to the rusty-telemetry REST API via a Vite dev proxy
- The Vite dev server binds to `0.0.0.0`, making it accessible from other machines on the LAN
- API calls (`/api/*`) are proxied to `http://127.0.0.1:8080`
## Features
### Dashboard
- System status overview: API server connectivity, sim connection state, active recording
- Live feed cards with health indicators, frequency, and telemetry snapshot
- Quick access to live telemetry and session management
- Recent sessions list
### Live Telemetry
- Real-time gauges: speed (km/h), RPM, gear indicator
- Throttle and brake input bars
- Lap time and track position (spline)
- Per-feed status cards with health, frequency, and packet stats
- Polling at 250ms for responsive updates
### Session Management
- Create analysis sessions with use case selection (Shift Points, Track Map, etc.)
- Start/stop runs within a session to capture telemetry data
- Complete sessions to trigger automatic analysis
- Session detail view with run history and status
### Shift Point Analysis
- Gear RPM range visualization (min/avg/max bar chart)
- Shift event timeline (RPM before/after each upshift)
- Recommended shift RPM from aggregated data
- Detailed shift event table
### Track Map
- Canvas-rendered track boundaries from coordinate data
- Center line computation from left/right boundary runs
- Boundary legend with point counts
- Responsive canvas that redraws on window resize
## Tech Stack
| Layer | Technology |
|-------|-----------|
| Framework | Vue 3.5 (Composition API, `<script setup>`) |
| Language | TypeScript 5.7 |
| Build | Vite 6 |
| Routing | Vue Router 4 |
| State | Pinia 3 |
| HTTP | Axios |
| Charts | Chart.js 4 + vue-chartjs 5 |
| Track Map | HTML Canvas 2D |
| Styling | CSS with custom properties (dark theme) |
## Getting Started
### Prerequisites
- Node.js 18+ and npm
- [rusty-telemetry](https://codeberg.org/jhunnius/rusty-telemetry) running on the same machine
### Install
```bash
cd ~/WebstormProjects/racecraft
npm install
```
### Run (Development)
Start both the backend and frontend:
```bash
# Terminal 1 — Backend (rusty-telemetry)
cd ~/RustroverProjects/rusty-telemetry
RUSTY_TELEMETRY_API_HOST=0.0.0.0 cargo run --release
# Terminal 2 — Frontend (racecraft)
cd ~/WebstormProjects/racecraft
npm run dev
```
Vite will output:
```
➜ Local: http://localhost:5173/
➜ Network: http://192.168.1.x:5173/
```
- **From the same machine**: open `http://localhost:5173`
- **From another machine**: open `http://192.168.1.x:5173` (the Network URL)
The `RUSTY_TELEMETRY_API_HOST=0.0.0.0` env var makes the backend API accessible from all network interfaces. In dev mode, the Vite proxy handles routing `/api/*` to the backend.
### Production Build
```bash
npm run build
```
Output is in `dist/`. Serve with any static file server, or configure axum in rusty-telemetry to serve the built files.
## Project Structure
```
racecraft/
├── index.html
├── package.json
├── vite.config.ts # host: 0.0.0.0, proxy /api → localhost:8080
├── tsconfig.json
├── src/
│ ├── main.ts # App bootstrap (Vue + Pinia + Router)
│ ├── App.vue # Root layout with navigation
│ ├── router/index.ts # 6 routes with lazy loading
│ ├── types/index.ts # TypeScript interfaces matching API JSON shapes
│ ├── api/client.ts # Typed Axios client (all API endpoints)
│ ├── stores/
│ │ ├── telemetry.ts # Live telemetry with polling + derived status
│ │ └── sessions.ts # Session CRUD, run management, analysis
│ ├── views/
│ │ ├── DashboardView.vue # System status, feeds, quick actions
│ │ ├── LiveView.vue # Real-time gauges and telemetry
│ │ ├── SessionsView.vue # Session list with create/delete
│ │ ├── SessionDetailView.vue # Run workflow, complete, analyze
│ │ ├── ShiftPointsView.vue # RPM charts and shift event table
│ │ └── TrackMapView.vue # Canvas track map renderer
│ ├── components/
│ │ └── FeedStatus.vue # Reusable feed card with health + telemetry
│ └── assets/
│ └── main.css # Dark theme, CSS variables, utilities
└── public/
└── favicon.ico
```
## API Contract
Racecraft consumes the rusty-telemetry REST API (19 endpoints). See the [rusty-telemetry README](https://codeberg.org/jhunnius/rusty-telemetry) for full endpoint documentation.
Key endpoints used:
- `GET /api/live` — polled every 250ms–1000ms for live telemetry
- `GET /api/sessions` / `POST /api/sessions` — session management
- `POST /api/sessions/{id}/runs` / `POST /api/sessions/{id}/runs/{run_id}/stop` — run capture
- `POST /api/sessions/{id}/complete` — complete session and trigger analysis
- `GET /api/sessions/{id}/analysis` — retrieve analysis results
## License
Private project — not yet licensed for distribution.