Describe the Bug
In src/components/Bot.tsx, the cleanupTTSStreaming function attempts to remove event listeners from the audio and mediaSource elements to prevent memory leaks. However, removeEventListener is currently being called with brand-new anonymous arrow functions.
Because removeEventListener requires the exact same function reference in memory that was passed to addEventListener, these calls fail silently. The original event listeners are never removed.
Code Snippet
Current Implementation (src/components/Bot.tsx):
// These do not remove the original handlers
currentState.audio.removeEventListener('playing', () => console.log('Playing'));
currentState.audio.removeEventListener('ended', () => console.log('Ended'));
// ...
currentState.mediaSource.removeEventListener('sourceopen', () => console.log('removed source open event listener'));
Impact
Memory Leak: Every time a user plays a Text-to-Speech message and the stream is cleaned up, orphaned event listeners remain permanently attached to the DOM elements.
Race Conditions: If the audio elements are reused, multiple handlers will fire simultaneously, leading to unpredictable UI state changes and console errors.
Proposed Solution
Instead of using addEventListener, we should use the direct DOM event properties (e.g., audio.onplaying, audio.onended, mediaSource.onsourceopen). This guarantees that only one listener is ever attached at a time, and makes cleanup as simple as setting the properties to null inside cleanupTTSStreaming().
I would be happy to submit a PR to fix this if the maintainers agree with the proposed solution!
Describe the Bug
In
src/components/Bot.tsx, thecleanupTTSStreamingfunction attempts to remove event listeners from theaudioandmediaSourceelements to prevent memory leaks. However,removeEventListeneris currently being called with brand-new anonymous arrow functions.Because
removeEventListenerrequires the exact same function reference in memory that was passed toaddEventListener, these calls fail silently. The original event listeners are never removed.Code Snippet
Current Implementation (
src/components/Bot.tsx):Impact
Memory Leak: Every time a user plays a Text-to-Speech message and the stream is cleaned up, orphaned event listeners remain permanently attached to the DOM elements.
Race Conditions: If the audio elements are reused, multiple handlers will fire simultaneously, leading to unpredictable UI state changes and console errors.
Proposed Solution
Instead of using addEventListener, we should use the direct DOM event properties (e.g., audio.onplaying, audio.onended, mediaSource.onsourceopen). This guarantees that only one listener is ever attached at a time, and makes cleanup as simple as setting the properties to null inside cleanupTTSStreaming().
I would be happy to submit a PR to fix this if the maintainers agree with the proposed solution!