@@ -22,6 +22,7 @@ import AudioSharing from './AudioSharing';
2222interface CollaborationEditorProps {
2323 matchId : string | null ;
2424}
25+ type AwarenessStates = Map < number , AwarenessState > ;
2526
2627const CollaborationEditor = ( { matchId } : CollaborationEditorProps ) => {
2728 const { user } = useAuthStore ( ) ;
@@ -30,7 +31,6 @@ const CollaborationEditor = ({ matchId }: CollaborationEditorProps) => {
3031 Map < number , ConnectedClient >
3132 > ( new Map ( ) ) ;
3233
33- // Refs for persistent state
3434 const providerRef = useRef < WebsocketProvider | null > ( null ) ;
3535 const bindingRef = useRef < MonacoBinding | null > ( null ) ;
3636 const editorRef = useRef < MonacoEditor . IStandaloneCodeEditor | null > ( null ) ;
@@ -46,21 +46,20 @@ const CollaborationEditor = ({ matchId }: CollaborationEditorProps) => {
4646 const { clearLastMatchId } = useCollaborationStore ( ) ;
4747 const router = useRouter ( ) ;
4848
49- const TOAST_DEBOUNCE = 1000 ; // Minimum time between toasts
49+ const TOAST_DEBOUNCE = 1000 ;
5050
5151 const onLanguageChange = ( language : string ) => {
5252 setLanguage ( language ) ;
5353 } ;
5454
55- const handleClientStateChange = ( states : Map < any , any > ) => {
55+ const handleClientStateChange = ( states : AwarenessStates ) => {
5656 const now = Date . now ( ) ;
5757 if ( now - lastUpdateTimeRef . current < TOAST_DEBOUNCE ) {
5858 return ;
5959 }
6060
6161 const newClients = new Map < number , ConnectedClient > ( ) ;
62- states . forEach ( ( value : { [ x : string ] : any } ) => {
63- const state = value as AwarenessState ;
62+ states . forEach ( ( state : AwarenessState ) => {
6463 if ( state . client ) {
6564 newClients . set ( state . client , {
6665 id : state . client ,
@@ -69,15 +68,12 @@ const CollaborationEditor = ({ matchId }: CollaborationEditorProps) => {
6968 }
7069 } ) ;
7170
72- // Clear any pending timeout
7371 if ( clientChangeTimeoutRef . current ) {
7472 clearTimeout ( clientChangeTimeoutRef . current ) ;
7573 }
7674
77- // Set a new timeout to handle the change
7875 clientChangeTimeoutRef . current = setTimeout ( ( ) => {
7976 if ( newClients . size !== prevClientsRef . current . size ) {
80- // Check for new connections
8177 const newConnectedUsers = Array . from ( newClients . values ( ) )
8278 . filter (
8379 ( client ) =>
@@ -103,7 +99,6 @@ const CollaborationEditor = ({ matchId }: CollaborationEditorProps) => {
10399 } ) ;
104100 }
105101
106- // Check for disconnections
107102 Array . from ( prevClientsRef . current . values ( ) ) . forEach ( ( prevClient ) => {
108103 if (
109104 ! Array . from ( newClients . values ( ) ) . some (
@@ -123,7 +118,7 @@ const CollaborationEditor = ({ matchId }: CollaborationEditorProps) => {
123118
124119 prevClientsRef . current = newClients ;
125120 setConnectedClients ( newClients ) ;
126- } , 500 ) ; // Debounce time for client changes
121+ } , 500 ) ;
127122 } ;
128123
129124 const initializeWebSocket = ( editor : MonacoEditor . IStandaloneCodeEditor ) => {
@@ -132,30 +127,27 @@ const CollaborationEditor = ({ matchId }: CollaborationEditorProps) => {
132127 return ;
133128 }
134129
135- // If we already have a connection, don't reinitialize
136130 if ( providerRef . current ?. wsconnected ) {
137131 console . log ( 'Reusing existing WebSocket connection' ) ;
138132 return ;
139133 }
140134
141135 console . log ( 'Initializing new WebSocket connection' ) ;
142136
143- // Create new Y.Doc if it doesn't exist
144137 if ( ! docRef . current ) {
145138 docRef . current = new Y . Doc ( ) ;
146139 }
147140
148- // Create new WebSocket provider with valid configuration options
149141 providerRef . current = new WebsocketProvider (
150142 sockServerURI ,
151143 matchId ,
152144 docRef . current ,
153145 {
154146 connect : true ,
155- resyncInterval : 3000 , // Time between resync attempts
156- disableBc : true , // Disable broadcast channel to prevent duplicate connections
147+ resyncInterval : 3000 ,
148+ disableBc : true ,
157149 params : {
158- version : '1.0.0' , // Optional version parameter
150+ version : '1.0.0' ,
159151 } ,
160152 } ,
161153 ) ;
@@ -170,7 +162,6 @@ const CollaborationEditor = ({ matchId }: CollaborationEditorProps) => {
170162 } ,
171163 } ) ;
172164
173- // Add connection status handlers
174165 providerRef . current . on ( 'status' , ( { status } : { status : string } ) => {
175166 console . log ( 'WebSocket status:' , status ) ;
176167 } ) ;
@@ -179,19 +170,18 @@ const CollaborationEditor = ({ matchId }: CollaborationEditorProps) => {
179170 console . error ( 'WebSocket connection error:' , event ) ;
180171 } ) ;
181172
182- // Set up awareness change handler with debouncing
183173 let changeTimeout : NodeJS . Timeout ;
184174 providerRef . current . awareness . on ( 'change' , ( ) => {
185175 clearTimeout ( changeTimeout ) ;
186176 changeTimeout = setTimeout ( ( ) => {
187- const states = providerRef . current ?. awareness . getStates ( ) ;
177+ const states =
178+ providerRef . current ?. awareness . getStates ( ) as AwarenessStates ;
188179 if ( states ) {
189180 handleClientStateChange ( states ) ;
190181 }
191182 } , 100 ) ;
192183 } ) ;
193184
194- // Set up Monaco binding
195185 const model = editor . getModel ( ) ;
196186 if ( editor && model ) {
197187 bindingRef . current = new MonacoBinding (
@@ -208,7 +198,6 @@ const CollaborationEditor = ({ matchId }: CollaborationEditorProps) => {
208198 initializeWebSocket ( editor ) ;
209199 } ;
210200
211- // Cleanup function
212201 const cleanup = ( force = false ) => {
213202 if ( clientChangeTimeoutRef . current ) {
214203 clearTimeout ( clientChangeTimeoutRef . current ) ;
@@ -241,23 +230,19 @@ const CollaborationEditor = ({ matchId }: CollaborationEditorProps) => {
241230 }
242231 } ;
243232
244- // Mount/unmount handling
245233 useEffect ( ( ) => {
246- mountCountRef . current ++ ;
247- console . log ( `Editor component mounted (count: ${ mountCountRef . current } )` ) ;
234+ const currentMountCount = mountCountRef . current + 1 ;
235+ mountCountRef . current = currentMountCount ;
236+ console . log ( `Editor component mounted (count: ${ currentMountCount } )` ) ;
248237
249238 return ( ) => {
250- mountCountRef . current -- ;
251- console . log (
252- `Editor component unmounting (count: ${ mountCountRef . current } )` ,
253- ) ;
254-
255- // Only do full cleanup when last instance unmounts
256- cleanup ( mountCountRef . current === 0 ) ;
239+ const finalMountCount = currentMountCount - 1 ;
240+ mountCountRef . current = finalMountCount ;
241+ console . log ( `Editor component unmounting (count: ${ finalMountCount } )` ) ;
242+ cleanup ( finalMountCount === 0 ) ;
257243 } ;
258244 } , [ ] ) ;
259245
260- // Handle page unload
261246 useEffect ( ( ) => {
262247 const handleUnload = ( ) => {
263248 cleanup ( true ) ;
0 commit comments