44 lines
2.7 KiB
Markdown
44 lines
2.7 KiB
Markdown
# Handoff notes
|
||||
|
|
|
|||
|
|
For whoever picks this up: what is solid, what is held together with care, and what a refactor should and should not
|
|||
|
|
do. Read ARCHITECTURE.md first.
|
|||
|
|
|
|||
|
|
## Where the seams are
|
|||
|
|
|
|||
|
|
- `index.html` is ~1,900 lines in one script. It grew feature by feature in one long session. The sections are
|
|||
|
|
commented and ordered sensibly, but state is one global `state` object and functions reach into each other freely.
|
|||
|
|
- brain.js **overrides** page functions by assignment (`djPrompt = …`, `openStation = …`, `makeJob = …`,
|
|||
|
|
`react = …`) so it can be loaded after the page. A refactor should turn these into explicit hooks.
|
|||
|
|
- Playback has three overlapping mechanisms layered over time: the ordinary `playJob/advance` path, the synchronous
|
|||
|
|
`ended` swap (`swapNow`) for locked screens, and the crackle hold with `pendingJob`. They work together (the
|
|||
|
|
harness proves the paths) but they should be one small state machine: `idle → cooking → holding → playing → ended`.
|
|||
|
|
- The crackle exists twice: as the side element (room tone) and as the player's own source (the hold). That is
|
|||
|
|
deliberate (iOS needs the hold in the same element) but easy to misread.
|
|||
|
|
- `db.all()` is used in many places where `db.get` or a filtered index would do; it loads every blob.
|
|||
|
|
- Several things are computed from the sheet in more than one place (section-at-time, mmss, kind chips).
|
|||
|
|
|
|||
|
|
## Known rough edges
|
|||
|
|
|
|||
|
|
- iOS volume sliders are inert (platform); the welcome/ident may fall back to Venice if Runware times out on a
|
|||
|
|
spoken-tag render (now avoided: spoken breaks are TTS).
|
|||
|
|
- The mashup reference uses OfflineAudioContext; untested headlessly.
|
|||
|
|
- The quota is per-person-per-day only; KV free tier caps total writes at ~1,000/day.
|
|||
|
|
- Share links made before the render seed was included re-roll the song.
|
|||
|
|
- `KEEP_UNKEPT = 40` unkept tracks roll off; nothing warns.
|
|||
|
|
- Light theme: a few hard-coded colours may remain in rarely-seen sheets.
|
|||
|
|
|
|||
|
|
## What a refactor should keep
|
|||
|
|
|
|||
|
|
- Every invariant in ARCHITECTURE.md › Playback invariants, and the harness green before and after.
|
|||
|
|
- The sheet as the unit (everything derives from `spec`), covers as a pure function of it.
|
|||
|
|
- One static page, no build step, no framework, no keys in the page.
|
|||
|
|
- STORAGE.md's contract (chai's DB adapter targets it).
|
|||
|
|
|
|||
|
|
## What's next (agreed directions, not started)
|
|||
|
|
|
|||
|
|
- Text embeddings for every sheet, audio embeddings (Gemini Embedding 2) for kept/reacted tracks; the taste map
|
|||
|
|
laid out in embedding space; segment-level vectors with the timed reactions (`spec.hits`).
|
|||
|
|
- Free tier = shared allowance on the worker (the key box is parked); pro = longer tracks, XL renders, sync.
|
|||
|
|
- Room-tone picker (vinyl / rain / tape / brown / drone in key).
|
|||
|
|
- Butterchurn (Milkdrop) as a fourth look.
|
|||
|
|
- Taste file export/import.
|