From 0630ebdd3fb84145b4c81a0efcb86830ed727557 Mon Sep 17 00:00:00 2001 From: Nuwan Date: Thu, 5 Mar 2026 19:08:46 +0530 Subject: [PATCH] feat(31-01): add composed memoized selectors to mixersSlice - Add createSelector import from @reduxjs/toolkit - Add selectCoreMixerState (chatMixer, broadcastMixer, recordingMixer) - Add selectTrackMixerState (5 track mixer arrays) - Add selectMixerLookupTables (allMixers, mixersByResourceId, mixersByTrackId) - Add selectMasterPersonalMixers (masterMixers, personalMixers) - Add selectMixerMetadata (metronome, settings, mediaSummary, noAudioUsers, etc) - Add selectSimulatedCategoryMixers (simulatedMusic, simulatedChat) These composed selectors memoize grouped state objects, reducing selector overhead from 18+ individual subscriptions to 6 memoized selectors. --- jam-ui/src/store/features/mixersSlice.js | 68 +++++++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) diff --git a/jam-ui/src/store/features/mixersSlice.js b/jam-ui/src/store/features/mixersSlice.js index 149f5d122..bc624e7ce 100644 --- a/jam-ui/src/store/features/mixersSlice.js +++ b/jam-ui/src/store/features/mixersSlice.js @@ -1,4 +1,4 @@ -import { createSlice } from '@reduxjs/toolkit'; +import { createSlice, createSelector } from '@reduxjs/toolkit'; const initialState = { // Core mixer collections @@ -313,3 +313,69 @@ export const selectMixerPairByResourceId = (resourceId) => (state) => { export const selectMixerPairByTrackId = (trackId) => (state) => { return state.mixers.mixersByTrackId[trackId]; }; + +// Composed memoized selectors for useMixerHelper optimization +// These group related data that's typically used together + +export const selectCoreMixerState = createSelector( + [selectChatMixer, selectBroadcastMixer, selectRecordingMixer], + (chatMixer, broadcastMixer, recordingMixer) => ({ + chatMixer, + broadcastMixer, + recordingMixer + }) +); + +export const selectTrackMixerState = createSelector( + [ + selectRecordingTrackMixers, + selectBackingTrackMixers, + selectJamTrackMixers, + selectMetronomeTrackMixers, + selectAdhocTrackMixers + ], + (recordingTrackMixers, backingTrackMixers, jamTrackMixers, metronomeTrackMixers, adhocTrackMixers) => ({ + recordingTrackMixers, + backingTrackMixers, + jamTrackMixers, + metronomeTrackMixers, + adhocTrackMixers + }) +); + +export const selectMixerLookupTables = createSelector( + [selectAllMixers, selectMixersByResourceId, selectMixersByTrackId], + (allMixers, mixersByResourceId, mixersByTrackId) => ({ + allMixers, + mixersByResourceId, + mixersByTrackId + }) +); + +export const selectMasterPersonalMixers = createSelector( + [selectMasterMixers, selectPersonalMixers], + (masterMixers, personalMixers) => ({ + masterMixers, + personalMixers + }) +); + +export const selectMixerMetadata = createSelector( + [selectMetronome, selectMetronomeSettings, selectMediaSummary, selectNoAudioUsers, selectClientsWithAudioOverride, selectMixersReady], + (metronome, metronomeSettings, mediaSummary, noAudioUsers, clientsWithAudioOverride, isReady) => ({ + metronome, + metronomeSettings, + mediaSummary, + noAudioUsers, + clientsWithAudioOverride, + isReady + }) +); + +export const selectSimulatedCategoryMixers = createSelector( + [selectSimulatedMusicCategoryMixers, selectSimulatedChatCategoryMixers], + (simulatedMusicCategoryMixers, simulatedChatCategoryMixers) => ({ + simulatedMusicCategoryMixers, + simulatedChatCategoryMixers + }) +);