@@ -604,31 +604,56 @@ export const {
604604 } ,
605605 async sync ( sessionID : string ) {
606606 if ( fullSyncedSessions . has ( sessionID ) ) return
607- const [ session , messages , todo , diff ] = await Promise . all ( [
608- sdk . client . session . get ( { sessionID } , { throwOnError : true } ) ,
609- sdk . client . session . messages ( { sessionID, limit : INITIAL_PAGE_SIZE } ) ,
610- sdk . client . session . todo ( { sessionID } ) ,
611- sdk . client . session . diff ( { sessionID } ) ,
612- ] )
613- const olderCursor = ( messages . response ?. headers . get ( "x-next-cursor" ) as string | null | undefined ) ?? null
614- setStore (
615- produce ( ( draft ) => {
616- const match = search ( draft . session , sessionID , ( s ) => s . id )
617- if ( match . found ) draft . session [ match . index ] = session . data !
618- if ( ! match . found ) draft . session . splice ( match . index , 0 , session . data ! )
619- draft . todo [ sessionID ] = todo . data ?? [ ]
620- const infos : ( typeof draft . message ) [ string ] = [ ]
621- for ( const message of messages . data ?? [ ] ) {
622- infos . push ( message . info )
623- draft . part [ message . info . id ] = message . parts
624- }
625- draft . message [ sessionID ] = infos
626- draft . session_diff [ sessionID ] = diff . data ?? [ ]
627- draft . messageOlderCursor [ sessionID ] = olderCursor
628- draft . messageNewerCursor [ sessionID ] = null
629- } ) ,
630- )
631- if ( ! olderCursor ) fullSyncedSessions . add ( sessionID )
607+ const hydration = { messages : new Set < string > ( ) , parts : new Set < string > ( ) }
608+ hydratingSessions . set ( sessionID , hydration )
609+ try {
610+ const [ session , messages , todo , diff ] = await Promise . all ( [
611+ sdk . client . session . get ( { sessionID } , { throwOnError : true } ) ,
612+ sdk . client . session . messages ( { sessionID, limit : INITIAL_PAGE_SIZE } ) ,
613+ sdk . client . session . todo ( { sessionID } ) ,
614+ sdk . client . session . diff ( { sessionID } ) ,
615+ ] )
616+ const olderCursor = ( messages . response ?. headers . get ( "x-next-cursor" ) as string | null | undefined ) ?? null
617+ setStore (
618+ produce ( ( draft ) => {
619+ const match = search ( draft . session , sessionID , ( s ) => s . id )
620+ if ( match . found ) draft . session [ match . index ] = session . data !
621+ if ( ! match . found ) draft . session . splice ( match . index , 0 , session . data ! )
622+ draft . todo [ sessionID ] = todo . data ?? [ ]
623+ if ( messages . data ) {
624+ const existing = draft . message [ sessionID ] ?? [ ]
625+ const infos : ( typeof draft . message ) [ string ] = [ ]
626+ const hydratedIDs = new Set < string > ( )
627+ for ( const message of messages . data ) {
628+ hydratedIDs . add ( message . info . id )
629+ const current = existing . find ( ( item ) => item . id === message . info . id )
630+ if ( current ) {
631+ infos . push ( current )
632+ continue
633+ }
634+ if ( hydration . messages . has ( message . info . id ) ) continue
635+ infos . push ( message . info )
636+ draft . part [ message . info . id ] = message . parts
637+ }
638+ for ( const message of existing ) {
639+ if ( hydratedIDs . has ( message . id ) ) continue
640+ infos . push ( message )
641+ }
642+ while ( infos . length > INITIAL_PAGE_SIZE ) {
643+ const evicted = infos . shift ( )
644+ if ( evicted ) delete draft . part [ evicted . id ]
645+ }
646+ draft . message [ sessionID ] = infos
647+ draft . messageOlderCursor [ sessionID ] = olderCursor
648+ draft . messageNewerCursor [ sessionID ] = null
649+ }
650+ draft . session_diff [ sessionID ] = diff . data ?? [ ]
651+ } ) ,
652+ )
653+ if ( ! olderCursor ) fullSyncedSessions . add ( sessionID )
654+ } finally {
655+ hydratingSessions . delete ( sessionID )
656+ }
632657 } ,
633658 async loadOlderMessages ( sessionID : string ) {
634659 const cursor = store . messageOlderCursor [ sessionID ]
0 commit comments