Files
arsam f3d2eee2ec Import documentation: AGENTS.md
Import the existing local project snapshot. This commit organizes existing files; it does not represent newly developed functionality.
2026-09-18 23:21:00 +03:30

2.2 KiB
Raw Permalink Blame History

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 consts 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.