Skip to content

Commit be81414

Browse files
committed
docs: update CLAUDE.md and README for recent refactoring
- Updated services list: removed CameraProxyService/RtspStreamService, added Go2rtcService, Go2rtcBinaryManager, DiscordNotificationService - Updated build system docs to reflect esbuild bundling via scripts/build-backend.ts - Added explanation for @yao-pkg/pkg usage (ARMv7 support for Raspberry Pi) - Updated dependencies: removed jsmpeg, added axios/form-data/video-rtc/esbuild/jest - Removed outdated CameraProxyPort from README config table - Updated gotchas with go2rtc binary and ARMv7 build notes - Updated testing notes to reflect current areas (go2rtc, Discord)
1 parent 1a98baa commit be81414

2 files changed

Lines changed: 52 additions & 25 deletions

File tree

CLAUDE.md

Lines changed: 52 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ npm run start:dev # Run with nodemon (watches for changes)
2020

2121
### Build Components
2222
```bash
23-
npm run build:backend # Compile TypeScript backend (tsc)
23+
npm run build:backend # Bundle backend with esbuild (scripts/build-backend.ts)
2424
npm run build:backend:watch # Watch backend files
2525
npm run build:webui # Compile frontend TS + copy static assets
2626
npm run build:webui:watch # Watch frontend files
@@ -44,8 +44,11 @@ npm run lint # Run Biome lint checks
4444
npm run lint:fix # Auto-fix Biome lint issues
4545
npm run format # Preview Biome formatting changes
4646
npm run format:fix # Apply Biome formatting changes
47+
npm run check # Run Biome check (lint + format combined)
48+
npm run check:fix # Auto-fix Biome check issues
4749
npm run type-check # TypeScript type checking without emit
48-
npm test # Tests (not yet implemented)
50+
npm test # Run Jest tests
51+
npm run test:watch # Run tests in watch mode
4952
npm run clean # Remove dist directory
5053
```
5154

@@ -110,7 +113,6 @@ src/index.ts # Entry point - initializes all singletons, conn
110113
- Backend instance (AD5XBackend, Adventurer5MBackend, GenericLegacyBackend, etc.)
111114
- Polling service instance
112115
- Connection state
113-
- Camera proxy port
114116
- Spoolman spool assignment
115117

116118
**Backends**: Abstraction layer over printer APIs (all extend `BasePrinterBackend`):
@@ -125,16 +127,18 @@ src/index.ts # Entry point - initializes all singletons, conn
125127
- `MultiContextPrintStateMonitor` - Track print progress, emit notifications
126128
- `MultiContextTemperatureMonitor` - Temperature anomaly detection
127129
- `MultiContextSpoolmanTracker` - Filament usage tracking
128-
- `CameraProxyService` - MJPEG camera proxying
129-
- `RtspStreamService` - RTSP stream management
130+
- `MultiContextNotificationCoordinator` - Coordinates Discord notifications across contexts
131+
- `Go2rtcService` - Unified camera streaming via go2rtc (WebRTC/MSE/MJPEG)
132+
- `Go2rtcBinaryManager` - Manages go2rtc binary lifecycle (download, start/stop)
133+
- `DiscordNotificationService` - Discord webhook notifications for print events
130134
- `SavedPrinterService` - Persistent printer storage (`data/printer_details.json`)
131135

132136
**WebUI**:
133137
- `WebUIManager` - Express HTTP server + static file serving
134138
- `WebSocketManager` - Real-time bidirectional communication with frontend
135139
- `AuthManager` - Optional password authentication
136140
- API routes organized by feature (printer-control, job, camera, spoolman, etc.)
137-
- Frontend uses GridStack for draggable dashboard, JSMpeg for video streaming
141+
- Frontend uses GridStack for draggable dashboard, go2rtc video-rtc player for camera streaming (WebRTC/MSE/MJPEG)
138142

139143
### Data Directory
140144

@@ -146,15 +150,33 @@ Default config values are in `ConfigManager.ts`.
146150

147151
### Build System
148152

149-
**Dual TypeScript Compilation**:
150-
1. **Backend** (`tsconfig.json`): Compiles `src/``dist/` as CommonJS (Node.js target)
151-
2. **Frontend** (`src/webui/static/tsconfig.json`): Compiles frontend TS → `dist/webui/static/` as ES modules (browser target)
153+
**Backend Bundling** (esbuild via `scripts/build-backend.ts`):
154+
- Bundles `src/index.ts``dist/index.js` as a single CommonJS file
155+
- Uses `packages: 'external'` to keep node_modules separate for pkg compatibility
156+
- tsc is still used for type checking (`npm run type-check`)
157+
158+
**Frontend Compilation** (`src/webui/static/tsconfig.json`):
159+
- Compiles frontend TS → `dist/webui/static/` as ES modules (browser target)
152160

153161
**Asset Pipeline** (`scripts/copy-webui-assets.js`):
154-
- Copies `index.html`, `webui.css`, `gridstack-extra.min.css` from `src/webui/static/`
155-
- Copies vendor libraries from `node_modules/` (jsmpeg, gridstack, lucide)
162+
- Copies `index.html`, `webui.css`, `gridstack-extra.min.css`, `favicon.png` from `src/webui/static/`
163+
- Copies vendor libraries from `node_modules/` (gridstack, lucide, video-rtc)
164+
165+
**go2rtc Binary** (`scripts/download-go2rtc.cjs`):
166+
- Runs at `npm install` time via postinstall hook
167+
- Downloads platform-specific go2rtc binary to `resources/bin/`
168+
169+
**pkg Bundling**: Production builds use `@yao-pkg/pkg` to create standalone executables with embedded assets (`dist/webui/**/*`, `resources/bin/**/*`)
170+
171+
**Why @yao-pkg/pkg instead of official pkg?** The official `pkg` package is no longer maintained and lacks support for newer Node.js versions and ARMv7 targets. We use `@yao-pkg/pkg` (a community-maintained fork) specifically because:
172+
- It supports `node20-linuxstatic-armv7` target for Raspberry Pi 4 (32-bit OS)
173+
- The original pkg dropped ARMv7 support, leaving no path for 32-bit Pi builds
174+
- It maintains API compatibility with the original pkg configuration
156175

157-
**pkg Bundling**: Production builds use `pkg` to create standalone executables with embedded assets (`dist/webui/**/*`)
176+
**Why esbuild instead of tsc for backend?** The build process bundles the backend with esbuild before pkg packaging because:
177+
- pkg requires CJS format and has issues with dynamic imports/ESM interop
178+
- esbuild produces a single bundled file that pkg can reliably package
179+
- The `packages: 'external'` option keeps node_modules outside the bundle so pkg can include them as bytecode
158180

159181
## Dependencies
160182

@@ -164,17 +186,21 @@ Default config values are in `ConfigManager.ts`.
164186
- `express` - HTTP server
165187
- `ws` - WebSocket server
166188
- `zod` - Schema validation
189+
- `axios` - HTTP client (for go2rtc API calls)
190+
- `form-data` - Multipart form handling
167191

168192
**Frontend**:
169193
- `gridstack` - Dashboard layout system
170-
- `@cycjimmy/jsmpeg-player` - Video streaming
171194
- `lucide` - Icon library
195+
- `video-rtc` - go2rtc video player (WebRTC/MSE/MJPEG) - bundled in static
172196

173197
**Dev**:
174198
- TypeScript 5.7, Biome 2 for linting and formatting
199+
- `esbuild` - Backend bundling
200+
- `jest`, `ts-jest`, `supertest` - Testing framework
175201
- `concurrently` - Parallel build tasks
176202
- `nodemon` - Dev server hot reload
177-
- `pkg` - Executable packaging
203+
- `@yao-pkg/pkg` - Executable packaging
178204

179205
## Printer API Integration
180206

@@ -200,7 +226,7 @@ Some printers support **both** (dual-API). The backend system abstracts these di
200226
- Initialize data directory
201227
- Parse CLI arguments
202228
- Load config
203-
- Initialize services (RTSP, Spoolman, monitoring)
229+
- Initialize services (go2rtc, Spoolman, Discord, monitoring)
204230
- Connect to printers (creates contexts + backends)
205231
- Start WebUI server
206232
- Setup event forwarding (polling data → WebUI)
@@ -269,14 +295,16 @@ class Service extends EventEmitter<EventMap> {
269295

270296
## Gotchas
271297

272-
1. **Dual Build System**: Backend and frontend have separate `tsconfig.json` files with different module systems (CommonJS vs ES modules)
298+
1. **Dual Build System**: Backend uses esbuild bundling, frontend uses tsc with separate tsconfig
273299
2. **Data Directory**: Not in git but can be manually accessed for debugging. Default location is `<project>/data/`
274-
3. **Camera Streams**: go2rtc manages camera streams per context; there is no user-facing global `CameraProxyPort` setting anymore
275-
4. **Polling Frequency**: All contexts poll at 3 seconds (changed from 30s for inactive contexts to prevent TCP keep-alive failures)
276-
5. **Context IDs**: UUID-based, generated during connection. Not tied to IP or serial number
277-
6. **Backend Lifecycle**: Backends are created per context, not shared. Each context has its own TCP connection
278-
7. **Graceful Shutdown**: SIGINT/SIGTERM handlers stop polling, disconnect contexts, and stop WebUI before exit
279-
8. **Windows Compatibility**: Special handling for Ctrl+C via readline interface (see `index.ts`)
300+
3. **Camera Streams**: go2rtc manages camera streams per context; there is no user-facing global `CameraProxyPort` setting
301+
4. **go2rtc Binary**: Downloaded at `npm install` time via postinstall script. The binary lives in `resources/bin/` and is platform-specific. If binary download fails, camera streaming won't work
302+
5. **Polling Frequency**: All contexts poll at 3 seconds (changed from 30s for inactive contexts to prevent TCP keep-alive failures)
303+
6. **Context IDs**: UUID-based, generated during connection. Not tied to IP or serial number
304+
7. **Backend Lifecycle**: Backends are created per context, not shared. Each context has its own TCP connection
305+
8. **Graceful Shutdown**: SIGINT/SIGTERM handlers stop polling, disconnect contexts, and stop WebUI before exit
306+
9. **Windows Compatibility**: Special handling for Ctrl+C via readline interface (see `index.ts`)
307+
10. **ARMv7 Builds**: Target `node20-linuxstatic-armv7` for Raspberry Pi 4 with 32-bit OS. This requires `@yao-pkg/pkg` as the official pkg lacks ARMv7 support.
280308

281309
## Testing Notes
282310

@@ -288,9 +316,9 @@ Core functionality has been tested and verified:
288316
- Static file serving in packaged binaries
289317

290318
Areas for continued testing:
291-
- Camera proxy stability under extended load
292-
- RTSP streaming for all supported printers
319+
- go2rtc binary download across all platforms
293320
- Temperature anomaly detection edge cases
321+
- Discord notification reliability
294322

295323
## Related Projects
296324

README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,6 @@ The application automatically creates a configuration file at `data/config.json`
180180
| **WebUIPasswordRequired** | `true` | Require password to access |
181181
| **SpoolmanEnabled** | `false` | Enable Spoolman integration |
182182
| **SpoolmanServerUrl** | `""` | Your Spoolman server URL (e.g., `http://192.168.1.100:7912`) |
183-
| **CameraProxyPort** | `8181` | Starting port for camera proxies |
184183

185184
</div>
186185

0 commit comments

Comments
 (0)