Commit Graph

8331 Commits

Author SHA1 Message Date
Nuwan de5b331e07 feat(32-01): consolidate track sync to single debounced call
- Replace triple setTimeout pattern (1s, 1.4s, 6s) with single 1.5s debounced call
- Eliminates redundant API calls on session join (STATE-01)
- Uses useMemo to create stable debounced function
- Debounce delay of 1.5s covers mixer initialization window
- Cleanup via cancel() on unmount
2026-03-05 19:36:27 +05:30
Nuwan f7f6f10d6d feat(32-02): add prevCategoriesRef to track dispatched values
- Add useRef to track previous category values
- Prevents circular updates by using ref instead of selectors
- Stores last dispatched values for comparison
2026-03-05 19:36:17 +05:30
Nuwan 10a1eb6577 feat(32-02): add mixer array comparison helper
- Add mixerArraysEqual helper to compare mixer arrays by ID
- Compares master.id + personal.id to create unique pair key
- Used to prevent unnecessary Redux dispatches when categorizing mixers
2026-03-05 19:36:04 +05:30
Nuwan 1a42be980c feat(32-01): create useDebounceCallback hook
- Implements ref-based debounce pattern for stable timers
- Solves stale closure problem with debounced callbacks
- useRef stores latest callback, useMemo creates debounce once
- Cleanup on unmount via useEffect return
- Exports both named and default for flexibility
2026-03-05 19:35:23 +05:30
Nuwan 173cf5e94d docs(32): create phase plan
Phase 32: State Update Optimization
- 4 plan(s) in 2 wave(s)
- 3 parallel in wave 1, 1 sequential in wave 2
- Ready for execution

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-05 19:28:11 +05:30
Nuwan ae583e7bc7 docs(32): research state update optimization phase domain
Phase 32: State Update Optimization
- Debounce patterns for track sync consolidation documented
- Ref-based closure pattern for stable debounce identified
- State colocation principles for button loading states
- Content comparison before Redux dispatch patterns

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-05 19:22:50 +05:30
Nuwan af9b467546 docs(31): complete selector-optimization phase
- Phase 31 verified: 3/3 must-haves passed
- SEL-01, SEL-02, SEL-03 requirements marked complete
- 13/19 v1.7 requirements now complete (68%)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-05 19:15:38 +05:30
Nuwan 20ab1fd86a docs(31-01): complete selector optimization plan
Tasks completed: 2/2
- Create composed selectors in mixersSlice.js
- Refactor useMixerHelper to use composed selectors

SUMMARY: .planning/phases/31-selector-optimization/31-01-SUMMARY.md
2026-03-05 19:12:03 +05:30
Nuwan 43b99c549d feat(31-01): refactor useMixerHelper to use composed selectors
- Replace 21 individual useSelector calls with 6 composed selectors
- Import shallowEqual from react-redux for object comparison
- Import composed selectors (selectCoreMixerState, selectTrackMixerState, etc.)
- Remove 16 individual selector imports no longer needed
- Destructure composed results for backward compatibility
- Total useSelector calls reduced from 28 to 13

Performance: Single mixer field change now triggers 6 selector runs
instead of 21, with shallowEqual preventing unnecessary re-renders
when composed object contents haven't changed.
2026-03-05 19:10:24 +05:30
Nuwan 0630ebdd3f 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.
2026-03-05 19:08:46 +05:30
Nuwan 3a9df2bef8 fix(31): revise plan based on checker feedback
- Updated must_haves.truths to clarify that grouping state IS derived data
- Made Task 2 verification precise: exactly 13 useSelector calls expected
- Added verification that old individual selectors (lines 72-92) are removed
- Changed vague 'around 9-12' to exact count verification
2026-03-05 18:59:34 +05:30
Nuwan 249cf75ec6 docs(31): create phase plan
Phase 31: Selector Optimization
- 1 plan in 1 wave
- Fully autonomous (no checkpoints)
- Ready for execution
2026-03-05 18:56:14 +05:30
Nuwan bb0019c941 docs(31): research selector optimization phase domain
Phase 31: Selector Optimization
- Standard stack identified (createSelector, shallowEqual in Redux Toolkit)
- Architecture patterns documented (composed selectors, memoization)
- Pitfalls catalogued (reference equality, over-subscription, cache thrashing)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-05 18:53:42 +05:30
Nuwan 773382d4f7 docs(30): complete component memoization phase
- JKSessionAudioInputs wrapped with React.memo
- JKSessionRemoteTracks wrapped with React.memo
- MEMO-01 through MEMO-04 requirements satisfied
- Phase goal verified: child components skip re-renders when props unchanged

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-05 18:44:15 +05:30
Nuwan 2a06f8bc1e docs(30-01): complete memoize container components plan
Tasks completed: 2/2
- Task 1: Wrap JKSessionAudioInputs with React.memo
- Task 2: Wrap JKSessionRemoteTracks with React.memo

SUMMARY: .planning/phases/30-component-memoization/30-01-SUMMARY.md
2026-03-05 18:40:31 +05:30
Nuwan a26f755912 refactor(30-01): wrap JKSessionRemoteTracks with React.memo
- Add memo to React imports (with useMemo)
- Wrap component with memo(function JKSessionRemoteTracks)
- Add displayName for React DevTools
- Prevents unnecessary re-renders when mixerHelper and sessionModel props unchanged
2026-03-05 18:39:02 +05:30
Nuwan 4dea95e855 refactor(30-01): wrap JKSessionAudioInputs with React.memo
- Add memo to React import
- Wrap component with memo(function JKSessionAudioInputs)
- Add displayName for React DevTools
- Prevents unnecessary re-renders when parent re-renders with same props
2026-03-05 18:38:32 +05:30
Nuwan 35997b407a fix(29): correct memo syntax in JKSessionBackingTrack and JKSessionMyTrack
Remove invalid arrow function syntax from memo-wrapped named functions.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-05 18:34:06 +05:30
Nuwan 4fb81ea93e docs(30): create phase plan
Phase 30: Component Memoization
- 1 plan in 1 wave
- Wrap JKSessionAudioInputs with React.memo
- Wrap JKSessionRemoteTracks with React.memo
- Ready for execution

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-05 18:27:26 +05:30
Nuwan 125a7cdcc2 docs(30): research component memoization phase domain
Phase 30: Component Memoization
- React.memo API and patterns for React 16.13.1
- Prop stability requirements documented
- Integration with Phase 29 context memoization
- Common pitfalls: inline props, children, context
- Verification with React DevTools Profiler
- DisplayName for debugging best practices

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-05 18:25:04 +05:30
Nuwan cb73b3dcdd fix(29): correct memo syntax in JKSessionMetronome
Remove invalid arrow function syntax from memo-wrapped named function.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-05 18:11:16 +05:30
Nuwan af1c06302a docs(29): complete Context Optimization phase
Phase 29 verified and complete:
- MixersContext.Provider value memoized with useMemo
- VuContext separated from MixerConfigContext (Phase 28)
- 6 context consumers wrapped with React.memo
- useMixerHelper.getMixer stabilized with useCallback

Requirements satisfied: CTX-01, CTX-02, CTX-03

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-05 17:59:02 +05:30
Nuwan db1033a5c6 docs(29-01): complete context optimization plan 01
Tasks completed: 4/4
- Task 1a: Stabilize useMixerHelper function references
- Task 1b: Memoize MixersContext provider value
- Task 2: Memoize VuContext and GlobalContext provider values
- Task 3: Wrap context consumers with React.memo

SUMMARY: .planning/phases/29-context-optimization/29-01-SUMMARY.md

Accomplishments:
- Memoized all 3 context providers (MixersContext, VuContext, GlobalContext)
- Stabilized getMixer and dependent function references
- Wrapped 6 consumer components with React.memo
- Eliminated cascading re-renders from context value changes

Requirements completed:
- CTX-00: useMixerHelper.getMixer wrapped with useCallback
- CTX-01: MixersContext.Provider value is memoized
- CTX-03: Context consumers only re-render when data changes

Performance impact:
- Volume slider changes no longer re-render VU meters
- VU updates no longer re-render volume sliders
- Context consumers only re-render when their specific data changes
2026-03-05 17:54:56 +05:30
Nuwan b27ea854f4 refactor(29-01): wrap context consumers with React.memo
Components wrapped:
- SessionTrackGain: volume slider
- JKSessionMyTrack: local track display
- JKSessionVolumeModal: volume popup
- JKSessionPanModal: pan control popup
- JKSessionBackingTrack: backing track display
- JKSessionMetronome: metronome controls

Each component:
- Wrapped with memo(function ComponentName(...))
- Added displayName for debugging
- Preserved PropTypes

React.memo prevents re-renders when props haven't changed.
Combined with memoized context values, this eliminates
unnecessary re-renders across the component tree.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-05 17:53:34 +05:30
Nuwan 566a53fb2b refactor(29-01): memoize VuContext and GlobalContext provider values
VuContext:
- Wrap combined value object with useMemo
- vuStore is stable module reference (not a dependency)
- Depends on vuHelpers

GlobalContext:
- Wrap provider value with useMemo
- Dependencies: all state and callback values
- useState setters are stable (not dependencies)

Both contexts now only update consumers when actual data changes,
preventing unnecessary re-renders across the component tree.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-05 17:52:15 +05:30
Nuwan 6b5b0990bb refactor(29-01): memoize MixersContext provider value
- Add useMemo wrapper around mixerHelper value
- Prevents new object creation on every render
- Depends on stable mixerHelper (from Task 1a)
- Context consumers now only re-render when data actually changes

This eliminates cascading re-renders when unrelated state updates occur.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-05 17:51:46 +05:30
Nuwan d008fe977c refactor(29-01): stabilize useMixerHelper function references
- Wrap getMixer with useCallback to ensure stable reference
- Prevents cascade of function recreations on every render
- Dependencies: mixMode (selector value)
- Uses allMixersRef.current (ref, not dependency)

This stabilization is prerequisite for effective context memoization.
All dependent functions (fillTrackVolumeObject, mute, faderChanged, etc.)
now automatically stabilize because their getMixer dependency is stable.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-05 17:51:31 +05:30
Nuwan 468860d54f fix(29): revise plan based on checker feedback
- Split Task 1 into Task 1a (stabilize useMixerHelper) and Task 1b (memoize MixersContext)
- Add useMixerHelper.js to files_modified
- Add getMixer useCallback wrapping as prerequisite for context memoization
- Add key_link verifying useMixerHelper -> MixersContext wiring
- Add CTX-00 success criterion for getMixer stabilization

Issues addressed:
- task_completeness: Task 1 now includes getMixer useCallback wrapping
- key_links_planned: Added verification for useMixerHelper stabilization
2026-03-05 17:22:30 +05:30
Nuwan c595d5334e docs(29): create phase plan
Phase 29: Context Optimization
- 1 plan in 1 wave
- Memoize MixersContext, VuContext, GlobalContext providers
- Wrap 6 consumer components with React.memo
- Ready for execution
2026-03-05 17:18:20 +05:30
Nuwan ceec2342fe docs(29): research context optimization phase domain
Phase 29: Context Optimization
- Standard stack identified (useMemo, useCallback, memo built-ins)
- Architecture patterns documented (memoized provider values)
- Pitfalls catalogued (stale closures, missing dependencies)
2026-03-05 17:15:44 +05:30
Nuwan 393bdfe057 docs(28): complete VU Meter Optimization phase
Phase 28 verified and approved:
- VU data flows through external store (vuStore.js)
- VU components use refs for direct DOM updates
- React DevTools shows 0 re-renders from VU updates
- Session screen remains responsive

Requirements satisfied: VU-01, VU-02, VU-03

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-05 16:53:43 +05:30
Nuwan 6b6aeb1017 docs(28-02): complete Wire Components to External Store plan
Tasks completed: 4/4
- Update useMixerStore to route VU data to external store
- Simplify useVuHelpers and VuContext
- Rewrite SessionTrackVU with direct DOM updates
- Human verification (approved)

Additional fix:
- getLevelSnapshot now checks pendingUpdates for immediate access

SUMMARY: .planning/phases/28-vu-meter-optimization/28-02-SUMMARY.md
2026-03-05 15:18:31 +05:30
Nuwan a1d24fe385 fix(28-02): check pendingUpdates in getLevelSnapshot
The vuStore RAF loop only runs with subscribers, but SessionTrackVU
uses direct polling without subscribing. Changed getLevelSnapshot to
check pendingUpdates first for immediate access to latest VU data.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-05 15:03:28 +05:30
Nuwan a020e27260 refactor(28-02): rewrite SessionTrackVU with direct DOM updates
- Remove useVuContext - directly import vuStore
- Remove VuMeter component usage - render lights directly
- Add RAF loop polling vuStore.getLevelSnapshot at ~60fps
- Store light element refs for direct className assignment
- Wrap with React.memo to prevent parent re-renders
- Zero React re-renders for VU visual updates

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-03 20:26:16 +05:30
Nuwan f8214854d9 refactor(28-02): simplify VU helpers to use external store
- Remove useState from useVuHelpers (no React state for VU data)
- Remove updateVuState, removeVuState, updateVU3 functions
- Remove VuMeterComponent (replaced by direct DOM in SessionTrackVU)
- Expose vuStore methods via return object
- VuContext provides vuStore reference to consumers
- Keep legacy renderVU/updateVU for backward compatibility

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-03 20:25:48 +05:30
Nuwan 96d8f97175 refactor(28-02): route VU data to external store
- Import vuStore in useMixerStore.js
- Replace mixerHelper.updateVU call with vuStore.updateLevel
- VU data now flows to external store instead of React state
- Native bridge still calls at 50-70/sec but updates are buffered

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-03 20:25:08 +05:30
Nuwan 344ef27ae0 docs(28-01): complete External VU Store Infrastructure plan
Tasks completed: 2/2
- Install useSyncExternalStore shim and create external VU store
- Create useVuStore React hooks

SUMMARY: .planning/phases/28-vu-meter-optimization/28-01-SUMMARY.md

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-03 20:22:13 +05:30
Nuwan 834472127d feat(28-01): create useVuStore React hooks
- Add useAllVuLevels hook for subscribing to all VU levels
- Add useVuLevel hook for efficient single-mixer subscription
- Use useSyncExternalStore shim for React 16 compatibility
- Memoize getSnapshot callback to avoid unnecessary resubscription

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-03 20:20:26 +05:30
Nuwan 5da85c1e79 feat(28-01): create external VU store with RAF batching
- Install use-sync-external-store shim for React 16 compatibility
- Create vuStore.js with external state management
- Implement RAF batching loop to limit updates to 60fps
- Add updateLevel, removeLevel, getSnapshot, getLevelSnapshot, subscribe, reset methods
- Store VU data outside React to avoid reconciliation overhead

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-03 20:19:41 +05:30
Nuwan 9c9e118a6e docs(28): create phase plan
Phase 28: VU Meter Optimization
- 2 plan(s) in 2 wave(s)
- 1 parallel (wave 1), 1 sequential (wave 2)
- Ready for execution

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-03 20:09:26 +05:30
Nuwan e8c5a213c6 docs(28): research VU meter optimization phase domain
Phase 28: VU Meter Optimization
- Standard stack identified (use-sync-external-store shim, requestAnimationFrame)
- Architecture patterns documented (external store, direct DOM updates with refs)
- Pitfalls catalogued (getSnapshot object creation, rAF cleanup, layout thrashing)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-03 20:05:08 +05:30
Nuwan 9174d161c6 docs: start milestone v1.7 Performance Optimization
Goals:
- Eliminate page freezes from excessive React re-renders
- Optimize VU meter updates (50-70/sec → batched RAF)
- Prevent cascading re-renders with memoization
- Apply React best practices for granular updates

Phases:
28. VU Meter Optimization
29. Context Optimization
30. Component Memoization
31. Selector Optimization
32. State Update Optimization

19 requirements across 5 phases.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-03 19:57:32 +05:30
Nuwan 4c4ee9253b chore: complete v1.6 milestone
Archived:
- milestones/v1.6-ROADMAP.md
- milestones/v1.6-REQUIREMENTS.md

Deleted (fresh for next milestone):
- ROADMAP.md
- REQUIREMENTS.md

Updated:
- MILESTONES.md (new entry)
- PROJECT.md (requirements → Validated)
- STATE.md (reset for next milestone)

v1.6 Media Features Polish shipped:
- JamTrack loading sequence, sizing, navigation fixed
- Backing track sync to session screen
- Prevent multiple media players simultaneously
- 2 phases, 5 plans, 7 days

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-03 16:33:44 +05:30
Nuwan 51f7cb105a docs(v1.6): descope Phase 28 - metronome responsiveness satisfactory
Removed Phase 28 (Metronome Responsiveness) from v1.6 milestone.
Metronome responsiveness is satisfactory after Phase 26-27 improvements.

MET-01, MET-02 requirements moved to Out of Scope.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-03 16:31:17 +05:30
Nuwan 388dfe16f8 fix: prevent opening multiple media players simultaneously
- Add media state tracking to JKSessionOpenMenu component
- Disable menu items when any media (JamTrack, Backing Track, Metronome) is open
- Show warning toast when user attempts to open another media type
- Update backing track and metronome track styling and icons
- Adjust close button styling in session screen media sections
- Handle cancelled file selection dialog for backing tracks

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-03 16:08:41 +05:30
Nuwan fd8900c15b media players related updates 2026-03-03 09:47:59 +05:30
Nuwan eb65785e3d fix(27): restore stylesheet copying to popup windows
The stylesheet copying code was accidentally removed in aa731c96d,
causing popup windows (metronome, backing track) to render without
CSS styles. This restores the code that copies all <link> and <style>
elements from the parent window to the popup.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-02 19:17:26 +05:30
Nuwan 3da5f8938e docs(27): add debug notes and verification documentation
- Add jamtrack stems debug notes
- Add phase 26 verification v2 documentation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-02 19:04:42 +05:30
Nuwan b674a7e1b8 style(27): update media player icons and popup dimensions
- Change play/stop icon colors from black (#000000) to blue (#2c7be5)
- Adjust JamTrack player dimensions to 420x220px
- Reduce backing track popup height from 400 to 250px

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-02 19:03:31 +05:30
Nuwan 5349dc0d63 fix(27): fix backing track player end detection, loop, and close
- Detect track end via position reset (>80% to <20%) since native client
  auto-loops without updating isSessionTrackPlaying state
- Implement manual looping: Stop → Seek to 0 → Play when loop enabled
- Fix Close button to use onClose callback for proper WindowPortal cleanup
- Add boolean conversion for isSessionTrackPlaying (handles string/number)
- Clean up debug console.log statements

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-02 19:01:47 +05:30