Skip to content

Commit 7d942c0

Browse files
committed
feat(react-chess): add Dockerfile, docker-compose, provider tests, docs
- Dockerfile: multi-stage Vite build → nginx serve - docker-compose.yml: frontend + rust/go/js backends with health checks - 90 new tests for LocalProvider, adapters, RemoteProvider, types (151 total) - Updated README with multi-backend docs, Docker section, env config - Updated CHANGELOG with provider system additions
1 parent 8c23c49 commit 7d942c0

File tree

10 files changed

+1426
-17
lines changed

10 files changed

+1426
-17
lines changed

.dockerignore

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Dependency directories
2+
node_modules/
3+
4+
# Build output (we COPY source and rebuild inside Docker)
5+
dist/
6+
dist-ssr/
7+
8+
# Test & coverage
9+
coverage/
10+
*.test.ts
11+
*.test.tsx
12+
*.spec.ts
13+
*.spec.tsx
14+
tests/
15+
16+
# Editor / OS
17+
.vscode/
18+
.idea/
19+
.DS_Store
20+
*.local
21+
22+
# Git
23+
.git/
24+
.gitignore
25+
26+
# Docs (not needed in image)
27+
*.md
28+
LICENSE*
29+
CHANGELOG*
30+
CONTRIBUTING*
31+
CODE_OF_CONDUCT*
32+
SECURITY*
33+
FUNDING*
34+
wiki/
35+
docs/
36+
37+
# CI config
38+
.github/
39+
.prettierrc
40+
.prettierignore
41+
eslint.config.js
42+
jest.config.ts
43+
tsconfig.jest.json
44+
.ai/

CHANGELOG.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
### Added
1111

12+
- **Multi-backend provider system** — switch between local (@rumenx/chess), rust-chess, go-chess, and js-chess backends
13+
- `ChessProvider` interface with unified types across all backends
14+
- `LocalProvider` — in-browser engine wrapper (zero latency, offline-capable)
15+
- `RemoteProvider` — HTTP-based provider with per-backend response adapters
16+
- Response normalizers for rust-chess (camelCase), go-chess (snake_case), js-chess (/api/v1/)
17+
- `BackendContext` — React context with health checking, localStorage persistence, env var support
18+
- `useChessBackendGame` hook — backend-aware game hook with optimistic local updates
19+
- **Backend picker UI** in settings panel
20+
- Engine selector dropdown (Local / Rust / Go / JS)
21+
- Custom URL input for remote backends
22+
- Live connection status indicator (checking / connected / error) with retry
23+
- Capability warnings (e.g. "Go backend does not support undo")
24+
- **Header connection indicator** — colored dot showing backend connection state
25+
- **Environment variable configuration**`VITE_CHESS_BACKEND`, `VITE_CHESS_RUST_URL`, `VITE_CHESS_GO_URL`, `VITE_CHESS_JS_URL`
26+
- **`.env.example`** with all configuration options documented
1227
- Game archival subsystem (in progress)
1328
- Replay mode UI (planned)
14-
- Comprehensive test suite (planned)
1529

1630
### Changed
1731

Dockerfile

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Stage 1: Build
2+
FROM node:22-alpine AS builder
3+
4+
WORKDIR /app
5+
6+
# Install dependencies first (layer caching)
7+
COPY package.json package-lock.json ./
8+
RUN npm ci --ignore-scripts
9+
10+
# Copy source and build
11+
COPY index.html vite.config.ts tsconfig*.json ./
12+
COPY public/ public/
13+
COPY src/ src/
14+
15+
RUN npm run build
16+
17+
# Stage 2: Serve with nginx
18+
FROM nginx:alpine
19+
20+
# Copy built assets
21+
COPY --from=builder /app/dist /usr/share/nginx/html
22+
23+
# Custom nginx config for SPA routing
24+
COPY nginx.conf /etc/nginx/conf.d/default.conf
25+
26+
EXPOSE 80
27+
28+
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s \
29+
CMD wget -qO- http://localhost/ || exit 1
30+
31+
CMD ["nginx", "-g", "daemon off;"]

README.md

Lines changed: 122 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,17 @@
55
[![Dependabot](https://github.com/RumenDamyanov/react-chess/actions/workflows/dependabot/dependabot-updates/badge.svg)](https://github.com/RumenDamyanov/react-chess/actions/workflows/dependabot/dependabot-updates)
66
[![TypeScript](https://img.shields.io/badge/TypeScript-5.x-3178C6?logo=typescript&logoColor=white)](https://www.typescriptlang.org/)
77

8-
Modern, fully client-side chess application built with **React + TypeScript + Vite**, powered by the custom engine [@rumenx/chess](https://www.npmjs.com/package/@rumenx/chess).
8+
Modern chess application built with **React + TypeScript + Vite**, powered by the custom engine [@rumenx/chess](https://www.npmjs.com/package/@rumenx/chess).
9+
10+
Supports **multiple backend engines** — play offline in the browser or connect to [rust-chess](https://github.com/RumenDamyanov/rust-chess), [go-chess](https://github.com/RumenDamyanov/go-chess), or [npm-chess](https://github.com/RumenDamyanov/npm-chess) REST APIs.
911

1012
---
1113

1214
## ✨ Features
1315

14-
- Legal move generation & game state via \`@rumenx/chess\`
16+
- Legal move generation & game state via `@rumenx/chess`
17+
- **Multi-backend support** — switch between Local (in-browser), Rust, Go, and JS engines
18+
- Backend picker with live connection status & health checking
1519
- Move history with time-travel (jump to any ply)
1620
- AI opponent with multiple difficulty tiers (random → depth 5 minimax w/ alpha-beta & capture ordering)
1721
- Hint system (on-demand best move preview)
@@ -53,21 +57,115 @@ npm run dev
5357

5458
Then open: [http://localhost:5173](http://localhost:5173)
5559

60+
## 🔀 Switching Backends
61+
62+
React Chess supports **four chess engines** — you can switch between them at any time without losing your current game position.
63+
64+
| Backend | Engine | Runs In | Default URL |
65+
|---------|--------|---------|-------------|
66+
| **Local** | `@rumenx/chess` | Browser (no server) ||
67+
| **Rust** | `rumenx-chess` | REST API | `http://localhost:8082` |
68+
| **Go** | `go-chess` | REST API | `http://localhost:8080` |
69+
| **JS** | `npm-chess` | REST API | `http://localhost:8081` |
70+
71+
### Method 1: Settings Panel (UI)
72+
73+
1. Open the app at [http://localhost:5173](http://localhost:5173)
74+
2. In the left sidebar, find the **Backend Engine** section
75+
3. Select an engine from the **Engine** dropdown (Local, Rust, Go, or JS)
76+
4. For remote backends, a **URL** field appears — edit it if your server runs on a different host/port
77+
5. A connection indicator shows the status:
78+
-**Checking…** — health check in progress
79+
-**Connected** — backend is reachable
80+
-**Disconnected** — server unreachable; click **🔄 Retry**
81+
6. Start playing — the game resets with the new engine
82+
83+
Your selection is persisted in `localStorage`, so it survives page reloads.
84+
85+
### Method 2: Environment Variables
86+
87+
Set the default backend before starting the dev server:
88+
89+
```bash
90+
cp .env.example .env
91+
```
92+
93+
Edit `.env`:
94+
95+
```env
96+
# Options: local | rust | go | js
97+
VITE_CHESS_BACKEND=rust
98+
99+
# Override default URLs (optional)
100+
VITE_CHESS_RUST_URL=http://localhost:8082
101+
VITE_CHESS_GO_URL=http://localhost:8080
102+
VITE_CHESS_JS_URL=http://localhost:8081
103+
```
104+
105+
Then run `npm run dev` — the app opens with the chosen backend pre-selected.
106+
107+
### Method 3: Docker Compose (all backends)
108+
109+
Start the frontend and all three remote backends together:
110+
111+
```bash
112+
docker compose up
113+
```
114+
115+
| Service | URL |
116+
|---------|-----|
117+
| Frontend | [http://localhost:3001](http://localhost:3001) |
118+
| Rust API | [http://localhost:8082](http://localhost:8082) |
119+
| Go API | [http://localhost:8080](http://localhost:8080) |
120+
| JS API | [http://localhost:8081](http://localhost:8081) |
121+
122+
Once running, switch freely between all four engines in the Settings panel.
123+
124+
### Backend Capabilities
125+
126+
Not every backend supports every feature:
127+
128+
| Capability | Local | Rust | Go | JS |
129+
|------------|:-----:|:----:|:--:|:--:|
130+
| AI opponent |||||
131+
| Hint |||||
132+
| Undo |||||
133+
| FEN load |||||
134+
| PGN export |||||
135+
| Analysis |||||
136+
| LLM Chat |||||
137+
| WebSocket |||||
138+
139+
The UI automatically warns when a feature is unavailable (e.g. "⚠️ This backend does not support undo").
140+
56141
## 🧩 Project Structure
57142

58-
\`\`\`text
143+
```text
59144
src/
60-
App.tsx # Composition + settings + clocks
145+
App.tsx # Composition + settings + backend picker
61146
hooks/
62-
useChessGame.ts # Core game + clocks + history logic
63-
... (future: useGameArchive.ts)
64-
services/ChessAI.ts # AI difficulty + search
65-
components/ChessBoard/ # Board + Square rendering
66-
components/MoveHistory # Move list & navigation
67-
utils/ # PGN, persistence helpers
68-
styles/ # SCSS tokens & theming
69-
tests/ # Jest tests (planned)
70-
\`\`\`
147+
useChessGame.ts # Core game + clocks + history logic
148+
useChessBackendGame.ts # Backend-aware game hook (delegates to provider)
149+
providers/
150+
types.ts # BackendId, presets, normalised game types
151+
LocalProvider.ts # In-browser provider via @rumenx/chess
152+
RemoteProvider.ts # HTTP provider for Rust/Go/JS APIs
153+
adapters.ts # Response normalisers per backend
154+
BackendContext.tsx # React context (selection, health, persistence)
155+
index.ts # Barrel export
156+
services/
157+
ChessAI.ts # AI difficulty + minimax search
158+
ChessEngine.ts # Engine wrapper for local play
159+
components/
160+
ChessBoard/ # Board + Square rendering
161+
MoveHistory/ # Move list & navigation
162+
utils/ # PGN, persistence, notation helpers
163+
styles/ # SCSS tokens & theming
164+
tests/
165+
providers/ # Provider & adapter tests
166+
services/ # ChessAI & ChessEngine tests
167+
utils/ # Notation utility tests
168+
```
71169

72170
## 🔧 Development Scripts
73171

@@ -88,7 +186,7 @@ tests/ # Jest tests (planned)
88186

89187
Comprehensive test coverage for core functionality:
90188

91-
- **61 passing tests** covering services and utilities
189+
- **151 passing tests** covering providers, services, and utilities
92190
- **85%+ coverage** on ChessAI service (difficulty levels, move selection, minimax)
93191
- **77%+ coverage** on ChessEngine wrapper (initialization, moves, game state)
94192
- **50%+ coverage** on chess notation utilities (SAN formatting, move chunking)
@@ -123,16 +221,22 @@ See the full [Contributing Guide](./CONTRIBUTING.md) for detailed guidelines.
123221

124222
## 📦 Future Enhancements
125223

224+
- WebSocket real-time game sync (rust-chess, go-chess)
225+
- AI chat panel (LLM integration via rust-chess, go-chess)
126226
- Opening explorer / book weighting
127227
- Engine benchmarking panel
128228
- Dark theme toggle
229+
- Save slots (3 game slots)
230+
- PGN import
129231
- Cloud sync (optional)
130232

131233
## 🛠 Tech Stack
132234

133-
- React + TypeScript + Vite
134-
- Custom chess engine: \`@rumenx/chess\`
235+
- React 19 + TypeScript 5 + Vite 7
236+
- Custom chess engine: `@rumenx/chess`
237+
- Multi-backend provider layer (Local / Rust / Go / JS)
135238
- SCSS modules (design tokens & utilities)
239+
- Docker + Docker Compose (optional)
136240

137241
## 🔗 Related Projects
138242

@@ -141,6 +245,8 @@ Explore other libraries and tools from the same developer:
141245
### NPM Packages
142246

143247
- **[@rumenx/chess](https://github.com/RumenDamyanov/npm-chess)** - TypeScript chess engine with legal move generation ([npm](https://www.npmjs.com/package/@rumenx/chess))
248+
- **[rust-chess](https://github.com/RumenDamyanov/rust-chess)** - Rust chess engine + REST API ([crates.io](https://crates.io/crates/rumenx-chess))
249+
- **[go-chess](https://github.com/RumenDamyanov/go-chess)** - Go chess engine + REST API
144250
- **[@rumenx/chatbot](https://github.com/RumenDamyanov/npm-chatbot)** - AI chatbot integration library ([npm](https://www.npmjs.com/package/@rumenx/chatbot))
145251
- **[@rumenx/seo](https://github.com/RumenDamyanov/npm-seo)** - SEO analysis and optimization toolkit ([npm](https://www.npmjs.com/package/@rumenx/seo))
146252
- **[@rumenx/sitemap](https://github.com/RumenDamyanov/npm-sitemap)** - Dynamic sitemap generator ([npm](https://www.npmjs.com/package/@rumenx/sitemap))

docker-compose.yml

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# Docker Compose — react-chess with all backend engines
2+
#
3+
# Usage:
4+
# docker compose up # start all services
5+
# docker compose up frontend # start frontend only (local mode)
6+
# docker compose up rust-backend # start a specific backend
7+
#
8+
# The frontend is served at http://localhost:3001
9+
# Switch backends from the Settings panel in the UI.
10+
11+
services:
12+
# ── Frontend ────────────────────────────────────────────
13+
frontend:
14+
build:
15+
context: .
16+
dockerfile: Dockerfile
17+
ports:
18+
- "3001:80"
19+
environment:
20+
- VITE_CHESS_BACKEND=local
21+
- VITE_CHESS_RUST_URL=http://localhost:8082
22+
- VITE_CHESS_GO_URL=http://localhost:8080
23+
- VITE_CHESS_JS_URL=http://localhost:8081
24+
depends_on:
25+
rust-backend:
26+
condition: service_healthy
27+
required: false
28+
go-backend:
29+
condition: service_healthy
30+
required: false
31+
js-backend:
32+
condition: service_healthy
33+
required: false
34+
restart: unless-stopped
35+
36+
# ── Rust Backend (rust-chess) ───────────────────────────
37+
rust-backend:
38+
build:
39+
context: ../rust-chess
40+
dockerfile: Dockerfile
41+
ports:
42+
- "8082:8082"
43+
environment:
44+
- PORT=8082
45+
- RUST_LOG=info
46+
healthcheck:
47+
test: ["/rust-chess", "--health-check"]
48+
interval: 15s
49+
timeout: 3s
50+
start_period: 5s
51+
retries: 3
52+
restart: unless-stopped
53+
54+
# ── Go Backend (go-chess) ───────────────────────────────
55+
go-backend:
56+
build:
57+
context: ../go-chess
58+
dockerfile: Dockerfile
59+
ports:
60+
- "8080:8080"
61+
environment:
62+
- CHESS_HOST=0.0.0.0
63+
- CHESS_PORT=8080
64+
healthcheck:
65+
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:8080/health"]
66+
interval: 15s
67+
timeout: 3s
68+
start_period: 5s
69+
retries: 3
70+
restart: unless-stopped
71+
72+
# ── JS Backend (npm-chess) ─────────────────────────────
73+
js-backend:
74+
build:
75+
context: ../npm-chess
76+
dockerfile: Dockerfile
77+
ports:
78+
- "8081:8081"
79+
environment:
80+
- PORT=8081
81+
healthcheck:
82+
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:8081/api/v1/health"]
83+
interval: 15s
84+
timeout: 3s
85+
start_period: 5s
86+
retries: 3
87+
restart: unless-stopped

0 commit comments

Comments
 (0)