feedBack/static/js
Byron Gamatos 36cf77dc44
refactor(highway): carve the 2D drawing layer into highway-draw.js (R3c) (#917)
18 functions, 1,245 lines. highway.js 3,972 -> 2,727 (-31%). The biggest R3c slice: notes,
sustains, chords, strum groups, unison bends and lyrics — everything the default renderer
paints each frame.

━━━ MUTABILITY, NOT LOCATION, DECIDES WHERE A THING BELONGS ━━━

Three per-instance caches came out with this slice, and they are why it needed care:

    _frameMismatchWarned   a warn-once Set of chord ids     (feedBack#88)
    _chordRenderInfo       a WeakMap of chord -> chain info
    _lyricMeasureCache     Map<fontSize, Map<text, width>>

All three are MUTATED. Left at module scope they would be SHARED ACROSS PANELS — one
highway's lyric widths and chord chains stomping another's, silently, with nothing throwing.
createHighway() is a factory (the constitution publishes window.createHighway so a plugin can
build a second highway), so they are lifted onto hwState, which is exactly what hwState is for.

The shimmer LUT went the OTHER way — to MODULE scope in highway-geometry.js. It is a
deterministic xorshift table, byte-for-byte identical for every instance, so sharing it is not
merely safe but BETTER: built once for the page rather than once per panel.

Same slice, opposite directions, decided entirely by whether the thing mutates.

━━━ MY SCRIPT WAS WRONG TWICE. THE GATES CAUGHT BOTH. ━━━

1. HAND-LISTED THE MOVE SET. I listed 10 functions and missed six that drawChords needs
   (_ensureChordRenderCache, bsearchChords, getChordTemplateInfo, _computeChordBox,
   _updateFretLinePreview, _drawFretLineChordPreview). The no-undef gate named every one. The
   set is now DERIVED from the dependency closure — 18, not 10.

2. JUDGED PURITY TOO EARLY, and this one is subtle. I classified _computeChordBox as pure
   because its ORIGINAL body never mentions hwState. Then the call-site rewriter injected
   `fretX(hwState, …)` INTO it — fretX takes hwState now (#916) — leaving a function that
   references an hwState it was never given. Purity has to be judged from the body AS IT WILL
   BE, so the classifier iterates to a fixed point: a function needs hwState if it mentions it,
   OR calls anything that now takes it. That moved _computeChordBox to the stateful side.

VERIFIED. A/B against origin/main: IDENTICAL, zero page errors. The PLUGIN BUNDLE contract is
byte-identical (b.fretX arity 3, b.getNoteState arity 2, both stable references, both correct
under the old calling convention). PERF GATE PASSES AT 1.92ms against its 12ms budget — and
this is the slice that could really have cost something: the ENTIRE per-frame drawing path is
now cross-module. It costs nothing measurable.

TESTS. highway_teaching_marks follows strumGroupBuckets to the new module. The two source-shape
harnesses now read highway.js AND every static/js/highway-*.js, rather than being re-pinned at
whichever file currently holds a function — re-pinning breaks again next time, and a shape
assertion that silently stops finding its target is indistinguishable from one that passes.

node 1045, pytest 2416, ESLint 0, no-undef 0, Codex 0.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 13:00:29 +02:00
..
audio-el.js refactor(app): give the <audio> element a module of its own (R3a) (#886) 2026-07-11 20:44:01 +02:00
count-in.js refactor(highway): make the highway global explicit before the module flip (R3c) (#912) 2026-07-12 11:56:07 +02:00
diagnostics-export.js refactor(app): carve the diagnostics-bundle export out of app.js (R3a) (#881) 2026-07-11 18:52:47 +02:00
dom.js refactor(app): carve the DOM/modal primitives out of app.js (R3a) (#882) 2026-07-11 18:59:44 +02:00
format.js refactor(app): give formatTime a home — a leaf format.js, one fewer host hook (R3a) (#895) 2026-07-11 23:27:17 +02:00
highway-colors.js refactor(highway): make the highway global explicit before the module flip (R3c) (#912) 2026-07-12 11:56:07 +02:00
highway-constants.js refactor(highway): carve the constants into static/js/highway-constants.js (R3c) (#914) 2026-07-12 12:24:40 +02:00
highway-draw.js refactor(highway): carve the 2D drawing layer into highway-draw.js (R3c) (#917) 2026-07-12 13:00:29 +02:00
highway-geometry.js refactor(highway): carve the 2D drawing layer into highway-draw.js (R3c) (#917) 2026-07-12 13:00:29 +02:00
highway-state-primitives.js refactor(highway): carve the STATEFUL primitives, threading hwState explicitly (R3c) (#916) 2026-07-12 12:42:38 +02:00
host.js refactor(app): the host seam + carve section practice out of app.js (R3a) (#887) 2026-07-11 20:58:41 +02:00
juce-audio.js refactor(highway): make the highway global explicit before the module flip (R3c) (#912) 2026-07-12 11:56:07 +02:00
library-state.js refactor(app): carve the library out of app.js (R3a) (#896) 2026-07-11 23:30:30 +02:00
library.js refactor(app): carve the library out of app.js (R3a) (#896) 2026-07-11 23:30:30 +02:00
loops.js refactor(app): give formatTime a home — a leaf format.js, one fewer host hook (R3a) (#895) 2026-07-11 23:27:17 +02:00
player-controls.js refactor(highway): make the highway global explicit before the module flip (R3c) (#912) 2026-07-12 11:56:07 +02:00
player-state.js refactor(app): carve the JUCE/desktop audio shims out of app.js (R3a) (#893) 2026-07-11 22:44:03 +02:00
plugin-loader.js fix(plugins): make a module plugin actually re-evaluate on reload (#879) (#897) 2026-07-12 00:19:59 +02:00
resume-session.js refactor(highway): make the highway global explicit before the module flip (R3c) (#912) 2026-07-12 11:56:07 +02:00
section-practice.js refactor(highway): make the highway global explicit before the module flip (R3c) (#912) 2026-07-12 11:56:07 +02:00
settings-io.js refactor(app): carve settings backup + plugin updates out of app.js (R3a) (#885) 2026-07-11 19:42:54 +02:00
transport.js refactor(highway): make the highway global explicit before the module flip (R3c) (#912) 2026-07-12 11:56:07 +02:00
tuning-display.js refactor(app): carve the tuning-display helpers out of app.js (R3a) (#884) 2026-07-11 19:37:44 +02:00
viz.js refactor(highway): make the highway global explicit before the module flip (R3c) (#912) 2026-07-12 11:56:07 +02:00