From 9bc2347cfd41e8d14a008fbb243dc80bed71567f Mon Sep 17 00:00:00 2001 From: Vithorio Polten Date: Thu, 18 Jun 2026 22:51:50 -0300 Subject: [PATCH 01/92] Add Svelte 5 rewrite PoC (logs view) + migration proposal Proof-of-concept Svelte 5 port of the Settings -> Logs view, plus a PROPOSAL.md analyzing a full client-web rewrite and an optional Tauri desktop shell. The PoC (crates/client-web-svelte/) validates three claims that de-risk the larger proposal: - SvelteKit + adapter-static builds a static dist/ (132 KB) the Rust server could serve, with SPA fallback. - Routing parity for /settings/logs via file-based routes. - The data layer (api.ts + mockApi.ts) ports verbatim; the VITE_USE_MOCK_API toggle and dev:mock workflow carry over unchanged. What it deliberately does NOT cover: playbackController.ts, youtube.ts, home shelf virtualization, item/person views, and app.ts's auto-refresh polling -- those are the real work of a full migration, with playbackController.ts being the headline risk per PROPOSAL.md. Key finding from research: Koko's server already builds on tao + tray-icon + keyring -- the exact crates Tauri is made of -- so a Tauri desktop shell is lower-risk than typical. Recommended architecture keeps the HTTP-served SPA for remote clients and adds Tauri as an optional desktop shell loading the same frontend. Verified: npm run check (0 errors), npm run build (dist/ written), npm run dev:mock (serves at 127.0.0.1:4173 with mock data). --- PROPOSAL.md | 222 +++ crates/client-web-svelte/.env.mock | 3 + crates/client-web-svelte/.gitignore | 10 + crates/client-web-svelte/package-lock.json | 1673 +++++++++++++++++ crates/client-web-svelte/package.json | 23 + crates/client-web-svelte/src/app.css | 148 ++ crates/client-web-svelte/src/app.html | 12 + .../client-web-svelte/src/lib/activities.ts | 22 + crates/client-web-svelte/src/lib/api.ts | 175 ++ .../src/routes/+layout.svelte | 63 + .../client-web-svelte/src/routes/+layout.ts | 7 + .../client-web-svelte/src/routes/+page.svelte | 16 + .../src/routes/settings/logs/+page.svelte | 157 ++ crates/client-web-svelte/svelte.config.js | 27 + crates/client-web-svelte/tsconfig.json | 24 + crates/client-web-svelte/vite.config.ts | 17 + 16 files changed, 2599 insertions(+) create mode 100644 PROPOSAL.md create mode 100644 crates/client-web-svelte/.env.mock create mode 100644 crates/client-web-svelte/.gitignore create mode 100644 crates/client-web-svelte/package-lock.json create mode 100644 crates/client-web-svelte/package.json create mode 100644 crates/client-web-svelte/src/app.css create mode 100644 crates/client-web-svelte/src/app.html create mode 100644 crates/client-web-svelte/src/lib/activities.ts create mode 100644 crates/client-web-svelte/src/lib/api.ts create mode 100644 crates/client-web-svelte/src/routes/+layout.svelte create mode 100644 crates/client-web-svelte/src/routes/+layout.ts create mode 100644 crates/client-web-svelte/src/routes/+page.svelte create mode 100644 crates/client-web-svelte/src/routes/settings/logs/+page.svelte create mode 100644 crates/client-web-svelte/svelte.config.js create mode 100644 crates/client-web-svelte/tsconfig.json create mode 100644 crates/client-web-svelte/vite.config.ts diff --git a/PROPOSAL.md b/PROPOSAL.md new file mode 100644 index 0000000..232031f --- /dev/null +++ b/PROPOSAL.md @@ -0,0 +1,222 @@ +# Proposal: Rewrite the Koko web client in Svelte 5 (+ optional Tauri desktop shell) + +**Status:** Proof-of-concept / proposal — not a merged plan. Prepared for discussion. +**Scope:** `crates/client-web` (the web UI). No backend changes are required or proposed. +**Worktree:** `poc/svelte-rewrite` (companion PoC in `crates/client-web-svelte/`). + +--- + +## TL;DR + +1. **Rewrite `client-web` from vanilla TypeScript into Svelte 5**, shipped as a static SPA (SvelteKit with `adapter-static`, SSR disabled). The rewrite is well-supported, modest effort, and the single biggest win is **deleting the hand-rolled `domPatcher.ts`** (~290 lines) and most of `eventBindings.ts` (~1,395 lines) — Svelte's reactivity replaces them natively. +2. **A Tauri desktop shell is viable and lower-risk than typical** because Koko's server already builds on `tao` + `tray-icon` + `keyring` — the exact crates Tauri is made of. Tauri is an *optional follow-on*, not a prerequisite. The recommended architecture keeps the HTTP-served SPA for remote clients (phones, tablets, LAN TVs) **and** adds a Tauri shell that loads the same frontend for desktop. +3. **The real risk is `playbackController.ts`** (video/audio/YouTube trailers), not the framework swap. That file needs careful, incremental porting. The logs-view PoC in this worktree de-risks everything *except* playback. +4. **Recommendation:** pursue the Svelte rewrite incrementally (view-by-view, keeping the vanilla client buildable in parallel), and treat the Tauri shell as a separate, later decision once the rewrite has shipped. + +--- + +## 1. Why consider this at all + +The current client is a **vanilla TypeScript SPA** (~11,750 lines across `src/app/`) bundled with Vite. It has exactly one runtime dependency (`lucide`). It is genuinely lean, and that's worth preserving. + +However, it implements its own UI framework by hand: + +- **`domPatcher.ts`** — a custom DOM reconciler with keyed reordering, focus/scroll/selection snapshot+restore, form-control syncing, and a special-case guard so `