feat(20-01): integrate removeVuState with mixer lifecycle

- Destructure removeVuState from useVuContext alongside updateVU3
- Add previousMixerIdsRef to track mixer IDs between renders
- Add cleanup useEffect that detects removed mixers
- Call removeVuState when mixer is removed from allMixers
- Only run cleanup when mixers are ready (isReadyRedux is true)

This prevents unbounded growth of vuStates object as tracks join/leave.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Nuwan 2026-02-08 19:27:48 +05:30
parent 3624c09102
commit 6a7ee474d2
1 changed files with 29 additions and 1 deletions

View File

@ -66,6 +66,7 @@ const useMixerHelper = () => {
const dispatch = useDispatch(); const dispatch = useDispatch();
const allMixersRef = useRef({}); const allMixersRef = useRef({});
const previousMyTracksRef = useRef([]); const previousMyTracksRef = useRef([]);
const previousMixerIdsRef = useRef(null);
// Redux selectors - replace all useState calls // Redux selectors - replace all useState calls
const chatMixer = useSelector(selectChatMixer); const chatMixer = useSelector(selectChatMixer);
@ -108,7 +109,7 @@ const useMixerHelper = () => {
const currentSession = useSelector(selectActiveSession); const currentSession = useSelector(selectActiveSession);
const inSession = useSelector(selectInSession); const inSession = useSelector(selectInSession);
const { jamClient, isConnected, server } = useJamServerContext(); const { jamClient, isConnected, server } = useJamServerContext();
const { updateVU3 } = useVuContext(); const { updateVU3, removeVuState } = useVuContext();
const { getParticipant } = useSessionHelper(); const { getParticipant } = useSessionHelper();
const { trackVolumeObject, setTrackVolumeObject } = useGlobalContext(); const { trackVolumeObject, setTrackVolumeObject } = useGlobalContext();
const faderHelpers = useFaderHelpers(); const faderHelpers = useFaderHelpers();
@ -316,6 +317,33 @@ const useMixerHelper = () => {
} }
}, [isReadyRedux]); }, [isReadyRedux]);
// Cleanup VU state when mixers are removed
useEffect(() => {
// Skip if not ready or no previous mixers to compare
if (!isReadyRedux) return;
// Get current mixer IDs from allMixers
const currentMixerIds = new Set(Object.keys(allMixers));
// Track previous mixer IDs using a ref
if (!previousMixerIdsRef.current) {
previousMixerIdsRef.current = currentMixerIds;
return;
}
// Find removed mixers (in previous but not in current)
for (const mixerId of previousMixerIdsRef.current) {
if (!currentMixerIds.has(mixerId)) {
// Mixer was removed - clean up its VU state
removeVuState(mixerId);
console.debug('[useMixerHelper] Cleaned up VU state for removed mixer:', mixerId);
}
}
// Update previous for next comparison
previousMixerIdsRef.current = currentMixerIds;
}, [allMixers, isReadyRedux, removeVuState]);
const getMixerByTrackId = useCallback((trackId, mode) => { const getMixerByTrackId = useCallback((trackId, mode) => {
const mixerPair = mixersByTrackId[trackId]; const mixerPair = mixersByTrackId[trackId];