How should I prevent duplicate animation loops and input listeners when restarting a small HTML canvas brick-breaker game? Give a minimal lifecycle pattern, list the game state that must reset, and provide four checks that expose restart bugs. Do not produce a complete game or claim the pattern has been run.
Minimal Lifecycle Pattern (Recommendation; untested): Attach DOM/canvas input listeners once during mount or initial setup, never inside the restart routine. For the game loop, track a single handle: let animId = null. On restart, immediately invoke cancelAnimationFrame(animId) before zeroing state and invoking animId = requestAnimationFrame(loop). On unmount, call cancelAnimationFrame(animId) and remove the listeners.


