4.5 KiB
4.5 KiB
Tasks: enterprise-react-audio-player
Change ID: enterprise-react-audio-player
Package: @suaveplan/react-audio-player
Target path: packages/ui/react/react-audio-player
Prerequisite packages on Verdaccio: @suaveplan/react-audio, @suaveplan/audio-fx-plugin-base, @suaveplan/audio-transport, @suaveplan/error, @suaveplan/types, @suaveplan/opentelemetry, @suaveplan/events
1. Scaffold
- 1.1 Directory tree per proposal.
- 1.2
package.jsonat0.1.0,"sideEffects": false, full subpath exports map (root + provider + components + hooks + stores + karaoke + optional screensavers + optional sync). React 19 peer.@react-three/fiber,three,react-audio-streamas optional peers gated by subpath. - 1.3
tsconfig.json,vitest.config.ts(happy-dom).
2. Error codes
- 2.1
src/error-codes.ts—defineCodes("REACT_AUDIO_PLAYER", [...]),ReactAudioPlayerError extends AudioError. - 2.2
error-codes.test.ts— every code reachable.
3. Provider + stores
- 3.1
src/provider/audio-player-provider.tsx— nests<AudioProvider>, owns three Zustand stores, constructs source plugin inplayer-trackchain, wires'ended'to playlist advance, disposal on unmount. - 3.2
src/stores/use-audio-player-store.ts— volume / mute / loading-state / chain-visibility. - 3.3
src/stores/use-playlist-store.ts— tracks / position / repeat / shuffle. - 3.4
src/stores/use-lyrics-store.ts— parsed lyrics + active index cache. - 3.5
audio-player-provider.test.tsxcovering: per-id source plugin uniqueness, ended → playlist advance, persistence restore, injected store supersedes default, strict-mode safe.
4. Hooks
- 4.1
use-audio-player— combined controls (play/pause/seek/setVolume/load). - 4.2
use-playlist-controls— next/previous/select/add/remove/clear, repeat/shuffle toggles. - 4.3
use-lyrics— exposes parsed lyrics and active index sampled at 100 ms. - 4.4
use-eq-band— bind a single band (low/mid/high) to the chain's EQ plugin parameters.
5. Karaoke
- 5.1
src/karaoke/lrc-parser/lrc-parser.ts— sorted, validated parse; ignores metadata tags; skips malformed lines. - 5.2
lrc-parser.test.ts— sort, skip, malformed, large file (10 k lines) under 50 ms. - 5.3
src/karaoke/lyrics-display/lyrics-display.tsx— 100 ms re-bind binary-search active line;aria-livetoggle.
6. Components (each: .tsx, .md, .test.tsx, .stories.tsx)
- 6.1
play-pause-button/. - 6.2
volume-control/. - 6.3
progress-bar/— keyboard seek, ARIA per spec. - 6.4
queue/— listbox semantics, keyboard CRUD per spec. - 6.5
eq-panel/— 3-band specialised renderer overEQPlugin. - 6.6
preset-selector-3band/. - 6.7
waveform-visualizer/—<canvas>overuseAnalyser. - 6.8
spectrum-analyzer/. - 6.9
basic-player/. - 6.10
audio-player/. - 6.11
premium-player/— composes everything, optional chain UI, optional lyrics, optional multi-peer.
7. Optional subpaths
- 7.1
screensavers/glb-viewer/— R3F-gated component. - 7.2
screensavers/shader-background/— R3F-gated component. - 7.3
sync/use-multi-peer-sync/— WebRTC-gated hook overreact-audio-stream.
8. Benchmarks
- 8.1
src/__benchmarks__/lrc-parse.bench.ts— parse a 10 k-line LRC. - 8.2
src/__benchmarks__/visualizer.bench.ts—<SpectrumAnalyzer>frame render.
9. Tests
- 9.1
tests/integration.test.tsx— load playlist, play, advance on ended, EQ change persists across remount. - 9.2
tests/purity.test.ts— builtdist/references no audio context. - 9.3
tests/exports.test.ts— every surface has subpath; every component has 3 story types. - 9.4
tests/bundle-size/{root-only,basic-only,premium-only}.size.test.ts— gating proof. - 9.5
e2e/play.spec.ts— Playwright play/pause/seek under a real browser. - 9.6
e2e/karaoke.spec.ts— Playwright lyric advancement.
10. Docs + verify
- 10.1 All co-located
.md(≥200 words). - 10.2
README.mdat package root with quick-start for each variant + karaoke example + screensaver example. - 10.3
bunx turbo lint typecheck test --filter=@suaveplan/react-audio-playergreen; coverage 100/100/100/100; banned-pattern sweeps empty.
11. Spec reconciliation + archive
- 11.1 Walk every
### Requirementand**Verified by:**. - 11.2 Fold spec delta into
openspec/specs/react-audio-player/spec.md. - 11.3 Move change folder to archive.