Import documentation: AGENTS.md

Import the existing local project snapshot. This commit organizes existing files; it does not represent newly developed functionality.
This commit is contained in:
arsam
2026-09-18 23:21:00 +03:30
parent fc408c8d87
commit f3d2eee2ec
+22
View File
@@ -0,0 +1,22 @@
# AGENTS.md
Apple Music–style music streaming frontend. Vanilla HTML/CSS/JS, zero dependencies, no build step, no backend/database by design.
## Run / verify
- No package.json, no lint/test setup. Verification = `node --check js/*.js` plus a headless smoke test (load all scripts in a `vm` context with stubbed `document`/`localStorage`/`Audio`, exercise all routes + player ops).
- Serve locally: `python -m http.server 5173` (or open `index.html` directly from file:// — everything works offline; audio streams from SoundHelix).
## Architecture (non-obvious)
- Script order in `index.html` is load-bearing: `data.js` → `artwork.js` → `store.js` → `player.js` → `app.js`. Top-level `const`s share global scope across files (classic scripts, NOT ES modules — don't convert to modules, file:// would break).
- `js/data.js` builds the 111-song catalog at load time from `ARTISTS`/`ALBUMS` with a seeded RNG (`seeded()`). Keep it deterministic — durations, plays, artwork patterns and `D.topCharts()` order all derive from seeds.
- `js/app.js` routing: hash-based, no router lib. Views register play contexts in `ctxMap[ctx]` (ctx string → song id array) BEFORE rendering rows that reference them via `data-ctx`/`data-index`. All clicks go through one delegated `[data-action]` handler.
- `Player.queue` stores enriched song objects (via `D.song`), not ids — `playContext()` normalizes either form.
- Persistence: `Store` (js/store.js) writes everything (likes, playlists, history, volume, shuffle, repeat) to one `localStorage` key `aumusic-v1`; `Store.load()` is called at file load. Changing the key or shape silently loses user data.
## Gotchas
- Audio is SoundHelix MP3s. They send NO CORS headers: do NOT add `crossorigin` to the audio element (playback breaks). Consequence: WebAudio analyser data is tainted/zeroed, so `vizLoop` in app.js has a synthetic-wave fallback — the zero-sum detection is intentional, not a bug.
- `js/artwork.js` generates artwork as inline SVG data URIs; each is ~2–44 KB. Don't swap in external images — the site is meant to be fully offline-capable.
- Card artwork click buttons (`.card-play`) are nested inside `data-action` rows — the delegated handler relies on `closest()` picking the innermost element.