@@ -304,6 +304,23 @@ const collectLeafPaneIds = (node: SessionPaneNode | undefined | null): string[]
304304 return [ ...collectLeafPaneIds ( node . first ) , ...collectLeafPaneIds ( node . second ) ] ;
305305} ;
306306
307+ const collectLeafSessionIds = ( node : SessionPaneNode | undefined | null ) : string [ ] => {
308+ if ( ! node ) return [ ] ;
309+ if ( node . type === "leaf" ) return [ node . sessionId ] ;
310+ return [ ...collectLeafSessionIds ( node . first ) , ...collectLeafSessionIds ( node . second ) ] ;
311+ } ;
312+
313+ const findPaneIdForSessionId = (
314+ node : SessionPaneNode | undefined | null ,
315+ sessionId : string ,
316+ ) : string | undefined => {
317+ if ( ! node ) return undefined ;
318+ if ( node . type === "leaf" ) {
319+ return node . sessionId === sessionId ? node . id : undefined ;
320+ }
321+ return findPaneIdForSessionId ( node . first , sessionId ) ?? findPaneIdForSessionId ( node . second , sessionId ) ;
322+ } ;
323+
307324const sanitizePaneLayout = (
308325 node : SessionPaneNode | undefined | null ,
309326 fallbackSessionId : string
@@ -330,6 +347,40 @@ const sanitizePaneLayout = (
330347 } ;
331348} ;
332349
350+ const prunePaneLayout = (
351+ node : SessionPaneNode | undefined | null ,
352+ validSessionIds : Set < string > ,
353+ seenSessionIds : Set < string > ,
354+ ) : SessionPaneNode | null => {
355+ if ( ! node ) return null ;
356+
357+ if ( node . type === "leaf" ) {
358+ if ( ! validSessionIds . has ( node . sessionId ) || seenSessionIds . has ( node . sessionId ) ) {
359+ return null ;
360+ }
361+ seenSessionIds . add ( node . sessionId ) ;
362+ return {
363+ type : "leaf" ,
364+ id : node . id || createId ( "pane" ) ,
365+ sessionId : node . sessionId ,
366+ } ;
367+ }
368+
369+ const first = prunePaneLayout ( node . first , validSessionIds , seenSessionIds ) ;
370+ const second = prunePaneLayout ( node . second , validSessionIds , seenSessionIds ) ;
371+ if ( ! first && ! second ) return null ;
372+ if ( ! first ) return second ;
373+ if ( ! second ) return first ;
374+ return {
375+ type : "split" ,
376+ id : node . id || createId ( "split" ) ,
377+ axis : node . axis === "vertical" ? "vertical" : "horizontal" ,
378+ ratio : Number . isFinite ( node . ratio ) ? Math . min ( 1 , Math . max ( 0 , node . ratio ) ) : 0.5 ,
379+ first,
380+ second,
381+ } ;
382+ } ;
383+
333384const sanitizeTabSessions = ( tab : Tab , locale : Locale ) : Tab => {
334385 const allSessions = ( tab . sessions ?? [ ] ) . filter ( Boolean ) ;
335386 const persistedSessions = allSessions . filter ( ( session ) => ! session . isDraft ) ;
@@ -340,24 +391,22 @@ const sanitizeTabSessions = (tab: Tab, locale: Locale): Tab => {
340391 : fallbackSessions [ 0 ] . id ;
341392 const validSessionIds = new Set ( fallbackSessions . map ( ( session ) => session . id ) ) ;
342393 const sanitizedLayout = sanitizePaneLayout ( tab . paneLayout , activeSessionId ) ;
343- const normalizedLayout = ( ( ) => {
344- const visit = ( node : SessionPaneNode ) : SessionPaneNode => {
345- if ( node . type === "leaf" ) {
346- return {
347- ...node ,
348- sessionId : validSessionIds . has ( node . sessionId ) ? node . sessionId : activeSessionId
349- } ;
350- }
351- return {
352- ...node ,
353- first : visit ( node . first ) ,
354- second : visit ( node . second )
355- } ;
356- } ;
357- return visit ( sanitizedLayout ) ;
358- } ) ( ) ;
394+ const normalizedBaseLayout = prunePaneLayout ( sanitizedLayout , validSessionIds , new Set ( ) ) ?? createPaneLayout ( activeSessionId ) ;
395+ const coveredSessionIds = new Set ( collectLeafSessionIds ( normalizedBaseLayout ) ) ;
396+ const missingSessionIds = fallbackSessions
397+ . map ( ( session ) => session . id )
398+ . filter ( ( sessionId ) => ! coveredSessionIds . has ( sessionId ) ) ;
399+ const normalizedLayout = missingSessionIds . reduce < SessionPaneNode > ( ( layout , sessionId ) => ( {
400+ type : "split" ,
401+ id : createId ( "split" ) ,
402+ axis : "vertical" ,
403+ ratio : 0.5 ,
404+ first : layout ,
405+ second : createPaneLeaf ( sessionId ) ,
406+ } ) , normalizedBaseLayout ) ;
359407 const leafIds = collectLeafPaneIds ( normalizedLayout ) ;
360- const activePaneId = leafIds . includes ( tab . activePaneId ) ? tab . activePaneId : leafIds [ 0 ] ;
408+ const activePaneId = findPaneIdForSessionId ( normalizedLayout , activeSessionId )
409+ ?? ( leafIds . includes ( tab . activePaneId ) ? tab . activePaneId : leafIds [ 0 ] ) ;
361410
362411 return {
363412 ...tab ,
0 commit comments