All checks were successful
Build & Test WASM / build-and-test (push) Successful in 2m45s
5.0 KiB
5.0 KiB
Kobopatch Web UI - Architecture
Overview
Fully client-side web app. No backend server needed — can be hosted as a static site. kobopatch is compiled from Go to WebAssembly and runs entirely in the browser.
Browser
├── index.html + CSS + JS
├── patch-worker.js (Web Worker for off-thread patching)
├── kobopatch.wasm (Go compiled to WASM, loaded by worker)
├── Patch config zips (in src/public/patches/)
├── Firmware auto-download (fetched from ereaderfiles.kobo.com)
└── File System Access API (read/write Kobo USB drive, Chromium only)
User Flow
Auto mode (Chromium)
- Connect Kobo via USB
- Click "Select Kobo Drive" → browser reads
.kobo/version - App detects model + firmware version from serial prefix
- App shows available patches with toggles, grouped by target binary
- User configures patches (enable/disable)
- Click "Build" → firmware downloaded from Kobo CDN → WASM patches in Web Worker
- App writes resulting
KoboRoot.tgzto.kobo/on device (or download) - User ejects device and reboots Kobo
Manual mode (all browsers)
- Select firmware version from dropdown
- Select Kobo model from dropdown (determines firmware download URL)
- Configure patches, click "Build"
- Download
KoboRoot.tgzand manually copy to.kobo/on device
Components
kobo-device.js — Device Access & Firmware URLs
- File System Access API for reading
.kobo/version - Serial prefix → model name mapping (
KOBO_MODELS) - Firmware download URLs per version and device prefix (
FIRMWARE_DOWNLOADS) - Writing
KoboRoot.tgzback to.kobo/
patch-ui.js — Patch Configuration
- Parses patch YAML files from zip archives (handles CRLF line endings)
- Renders patch list with toggles grouped by target file
- Enforces PatchGroup mutual exclusion (radio buttons)
- Generates kobopatch.yaml config with overrides from UI state
patch-worker.js — Web Worker (in progress)
- Loads
wasm_exec.jsandkobopatch.wasmoff the main thread - Receives patch config + firmware via
postMessage - Sends progress updates back to main thread for live UI rendering
- Returns
KoboRoot.tgzbytes via transferable buffer
kobopatch.wasm — Patching Engine
- Go source in
kobopatch-wasm/, compiled withGOOS=js GOARCH=wasm - Custom WASM wrapper accepts in-memory inputs:
- Config YAML (generated from UI state)
- Firmware zip (auto-downloaded from Kobo CDN)
- Patch YAML files (from bundled zip)
- Optional progress callback (4th argument) for real-time status
- Returns
{ tgz: Uint8Array, log: string } - No filesystem or exec calls — everything in-memory
kobopatch.js — Runner Interface
- Abstracts WASM loading and invocation
- Will be updated to communicate with Web Worker
Static Assets
- Patch config zips in
src/public/patches/withindex.jsonindex wasm_exec.js(Go's WASM support JS)- The WASM binary itself
File Structure
src/
public/ # Webroot (static hosting)
index.html # Single page app
style.css # Styling
app.js # Main controller / flow orchestration
kobo-device.js # File System Access API + device identification + firmware URLs
patch-ui.js # Patch list rendering + toggle logic
kobopatch.js # WASM runner interface
patch-worker.js # Web Worker for off-thread patching
wasm_exec.js # Go WASM support (from Go SDK, gitignored)
kobopatch.wasm # Compiled WASM binary (gitignored)
patches/
index.json # Available patch versions
patches_*.zip # Patch config zips (kobopatch.yaml + src/*.yaml)
kobopatch-wasm/
main.go # WASM entry point + patching pipeline
go.mod # Go module (replaces for kobopatch + yaml fork)
setup.sh # Clones kobopatch source, copies wasm_exec.js
build.sh # Compiles WASM, copies artifacts to src/public/
kobopatch-src/ # Cloned kobopatch Go source (gitignored)
wip/ # Planning docs
.github/workflows/ # CI (GitHub Actions / Gitea compatible)
Key Constraints
- Chromium-only for auto mode: File System Access API not in Firefox/Safari
- Manual mode fallback: select model + firmware version from dropdowns
- Firmware auto-download: fetched from
ereaderfiles.kobo.com(CORS allows*)- URLs hardcoded per device prefix in
FIRMWARE_DOWNLOADS - Download URL displayed to user for verification
- URLs hardcoded per device prefix in
- WASM binary size: ~9.9MB uncompressed
- Mitigated by gzip compression on static hosting (~3-4MB)
- Memory usage: firmware zips are ~150-300MB, patching happens in-memory
- Should be fine on modern desktops (USB implies desktop use)
Running
Any static file server, e.g.: python3 -m http.server -d src/public/ 8888