@@ -181,7 +181,7 @@ export class LoroWebsocketClient {
181181 private roomAuth : Map < string , AuthOption | undefined > = new Map ( ) ;
182182 private roomStatusListeners : Map <
183183 string ,
184- Set < ( s : RoomJoinStatusValue ) => void >
184+ Set < ( s : RoomJoinStatusValue , messageType ?: MessageType , messageCode ?: number ) => void >
185185 > = new Map ( ) ;
186186 private socketListeners = new WeakMap < WebSocket , SocketListeners > ( ) ;
187187
@@ -625,7 +625,7 @@ export class LoroWebsocketClient {
625625 } )
626626 . finally ( ( ) => {
627627 this . pendingRooms . delete ( id ) ;
628- this . emitRoomStatus ( id , RoomJoinStatus . Joined ) ;
628+ this . emitRoomStatus ( id , RoomJoinStatus . Joined , MessageType . JoinResponseOk ) ;
629629 } ) ;
630630 } ,
631631 reject : ( error : Error ) => {
@@ -718,7 +718,7 @@ export class LoroWebsocketClient {
718718 } else {
719719 // Remove local room state so client does not auto-retry unless requested
720720 this . cleanupRoom ( msg . roomId , msg . crdt ) ;
721- this . emitRoomStatus ( roomId , RoomJoinStatus . Error ) ;
721+ this . emitRoomStatus ( roomId , RoomJoinStatus . Error , MessageType . RoomError , msg . code ) ;
722722 }
723723 break ;
724724 }
@@ -840,7 +840,7 @@ export class LoroWebsocketClient {
840840 }
841841
842842 this . pendingRooms . delete ( id ) ;
843- this . emitRoomStatus ( id , RoomJoinStatus . Joined ) ;
843+ this . emitRoomStatus ( id , RoomJoinStatus . Joined , MessageType . JoinResponseOk ) ;
844844 }
845845
846846 private async handleJoinError (
@@ -857,7 +857,9 @@ export class LoroWebsocketClient {
857857 this . pendingRooms . delete ( roomId ) ;
858858 this . emitRoomStatus (
859859 pending . adaptor . crdtType + pending . roomId ,
860- RoomJoinStatus . Error
860+ RoomJoinStatus . Error ,
861+ MessageType . JoinError ,
862+ msg . code
861863 ) ;
862864 return ;
863865 }
@@ -895,7 +897,9 @@ export class LoroWebsocketClient {
895897 const err = new Error ( `Join failed: ${ msg . code } - ${ msg . message } ` ) ;
896898 this . emitRoomStatus (
897899 pending . adaptor . crdtType + pending . roomId ,
898- RoomJoinStatus . Error
900+ RoomJoinStatus . Error ,
901+ MessageType . JoinError ,
902+ msg . code
899903 ) ;
900904 // Remove active room references so caller can rejoin manually if this was a rejoin
901905 if ( pending . isRejoin ) {
@@ -913,7 +917,9 @@ export class LoroWebsocketClient {
913917 this . roomAdaptors . delete ( id ) ;
914918 this . roomIds . delete ( id ) ;
915919 this . roomAuth . delete ( id ) ;
916- this . roomStatusListeners . delete ( id ) ;
920+ // Status listeners are intentionally kept so any emitRoomStatus call
921+ // made immediately after cleanupRoom (e.g. RoomJoinStatus.Error) still
922+ // reaches subscribers. They are cleared when the client is destroyed.
917923 }
918924
919925 waitConnected ( ) {
@@ -983,7 +989,7 @@ export class LoroWebsocketClient {
983989 roomId : string ;
984990 crdtAdaptor : CrdtDocAdaptor ;
985991 auth ?: AuthOption ;
986- onStatusChange ?: ( s : RoomJoinStatusValue ) => void ;
992+ onStatusChange ?: ( s : RoomJoinStatusValue , messageType ?: MessageType , messageCode ?: number ) => void ;
987993 } ) : Promise < LoroWebsocketClientRoom > {
988994 const id = crdtAdaptor . crdtType + roomId ;
989995 // Check if already joining or joined
@@ -1561,12 +1567,12 @@ export class LoroWebsocketClient {
15611567 }
15621568 }
15631569
1564- private emitRoomStatus ( roomKey : string , status : RoomJoinStatusValue ) {
1570+ private emitRoomStatus ( roomKey : string , status : RoomJoinStatusValue , messageType ?: MessageType , messageCode ?: number ) {
15651571 const set = this . roomStatusListeners . get ( roomKey ) ;
15661572 if ( ! set || set . size === 0 ) return ;
15671573 for ( const cb of Array . from ( set ) ) {
15681574 try {
1569- cb ( status ) ;
1575+ cb ( status , messageType , messageCode ) ;
15701576 } catch ( err ) {
15711577 this . logCbError ( "onRoomStatusChange" , err ) ;
15721578 }
0 commit comments