From 8d0e27034567792395b1cd2e2b8fbf187bb0bd71 Mon Sep 17 00:00:00 2001 From: Byron Gamatos Date: Sat, 11 Jul 2026 22:44:03 +0200 Subject: [PATCH] refactor(app): carve the JUCE/desktop audio shims out of app.js (R3a) (#893) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor(app): carve resume-session out of app.js (R3a) static/js/resume-session.js (157) — the snapshot taken when you leave a song and the pill that offers it back. Bodies VERBATIM. app.js 7,727 → 7,601. Fifth slice out of the strongly-connected core. ONE hook (playSong) + a currentFilename getter. S.pendingResume JOINS THE CONTAINER — on demand, exactly as intended. app.js WRITES it (playSong({ resume }) arms it; the song:ready listener consumes it) while this module reads it, so it cannot be a plain export: an imported binding is read-only. Same reason isPlaying is there. The container grows one field per carve that needs it, never speculatively. THE CONTRACT TEST CAUGHT THE MISSING HOOK, again on a path nothing executes: "playSong is read by a module but never wired by app.js — it would throw at runtime". Second time it has caught a real wiring gap the moment it appeared. A REAL TRAP, worth remembering: I first did the S.pendingResume rewrite by feeding acorn's identifier RANGES from node into python, and it corrupted the file (`_pS.pendingResume null;`). **Acorn's offsets are UTF-16 code units; Python's string indices are code points.** static/app.js contains emoji, so every offset past one drifts. Do an AST-driven rewrite in the SAME language that produced the offsets. `node --check` caught it; a silent version of that bug is very easy to imagine. VERIFIED. A/B against origin/main in two browsers, real song: the window API (resumeLastSession / _snapshotResumeSession / _readResumeSession / _clearResumeSession), snapshot, read-back, and clear — IDENTICAL, zero page errors. HONEST LIMIT: my probe never got the snapshot to actually PERSIST (there is a guard beyond the 3s minimum position that a scripted playSong does not satisfy), so that path is verified only as identical-to-main, not as observed-working. The real coverage is tests/browser/resume-session.spec.ts, which drives the flow properly. Zero harnesses broke. pytest 2396, node 1040/1040, ESLint 0 (no-cycle clean), tailwind clean, Codex 0. Co-Authored-By: Claude Opus 4.8 (1M context) * refactor(app): carve the JUCE/desktop audio shims out of app.js (R3a) static/js/juce-audio.js (994) — bodies VERBATIM. app.js 7,603 → 6,643. THE LARGEST SINGLE SLICE of the whole carve phase: 960 lines, ~13% of what was left. Three self-installing IIFEs: _installJuceEngineRoutingWatcher (444) routes a song to the JUCE engine or HTML5 as the desktop output enters/leaves exclusive/ASIO _installRendererBusFeeder (337) feeds the highway renderer bus from whichever transport is actually running _installJuceAudioElementShim (156) patches audio.play/pause so the rest of the app keeps talking to the