@@ -324,6 +324,11 @@ describe("WsTransport", () => {
324324 const secondSocket = getSocket ( ) ;
325325 expect ( secondSocket ) . not . toBe ( firstSocket ) ;
326326 expect ( firstSocket . readyState ) . toBe ( MockWebSocket . CLOSED ) ;
327+ expect ( getWsConnectionStatus ( ) ) . toMatchObject ( {
328+ closeCode : null ,
329+ closeReason : null ,
330+ phase : "connecting" ,
331+ } ) ;
327332
328333 const requestPromise = transport . request ( ( client ) =>
329334 client [ WS_METHODS . serverUpsertKeybinding ] ( {
@@ -361,6 +366,58 @@ describe("WsTransport", () => {
361366 await transport . dispose ( ) ;
362367 } ) ;
363368
369+ it ( "ignores stale socket lifecycle events after a reconnect starts a new session" , async ( ) => {
370+ const onClose = vi . fn ( ) ;
371+ const transport = createTransport ( "ws://localhost:3020" , { onClose } ) ;
372+
373+ await waitFor ( ( ) => {
374+ expect ( sockets ) . toHaveLength ( 1 ) ;
375+ } ) ;
376+
377+ const firstSocket = getSocket ( ) ;
378+ firstSocket . open ( ) ;
379+
380+ await waitFor ( ( ) => {
381+ expect ( getWsConnectionStatus ( ) ) . toMatchObject ( {
382+ hasConnected : true ,
383+ phase : "connected" ,
384+ } ) ;
385+ } ) ;
386+
387+ await transport . reconnect ( ) ;
388+
389+ await waitFor ( ( ) => {
390+ expect ( sockets ) . toHaveLength ( 2 ) ;
391+ } ) ;
392+
393+ expect ( onClose ) . not . toHaveBeenCalled ( ) ;
394+ expect ( getWsConnectionStatus ( ) ) . toMatchObject ( {
395+ closeCode : null ,
396+ closeReason : null ,
397+ phase : "connecting" ,
398+ } ) ;
399+
400+ const secondSocket = getSocket ( ) ;
401+ secondSocket . open ( ) ;
402+
403+ await waitFor ( ( ) => {
404+ expect ( getWsConnectionStatus ( ) ) . toMatchObject ( {
405+ phase : "connected" ,
406+ } ) ;
407+ } ) ;
408+
409+ firstSocket . close ( 1006 , "stale close" ) ;
410+
411+ expect ( onClose ) . not . toHaveBeenCalled ( ) ;
412+ expect ( getWsConnectionStatus ( ) ) . toMatchObject ( {
413+ closeCode : null ,
414+ closeReason : null ,
415+ phase : "connected" ,
416+ } ) ;
417+
418+ await transport . dispose ( ) ;
419+ } ) ;
420+
364421 it ( "marks unary requests as slow until the first server ack arrives" , async ( ) => {
365422 const slowAckThresholdMs = 25 ;
366423 setSlowRpcAckThresholdMsForTests ( slowAckThresholdMs ) ;
0 commit comments