@@ -20,6 +20,71 @@ export type LocalPTY = {
2020const WORKSPACE_KEY = "__workspace__"
2121const MAX_TERMINAL_SESSIONS = 20
2222
23+ function record ( value : unknown ) : value is Record < string , unknown > {
24+ return typeof value === "object" && value !== null && ! Array . isArray ( value )
25+ }
26+
27+ function text ( value : unknown ) {
28+ return typeof value === "string" ? value : undefined
29+ }
30+
31+ function num ( value : unknown ) {
32+ return typeof value === "number" && Number . isFinite ( value ) ? value : undefined
33+ }
34+
35+ function numberFromTitle ( title : string ) {
36+ const match = title . match ( / ^ T e r m i n a l ( \d + ) $ / )
37+ if ( ! match ) return
38+ const value = Number ( match [ 1 ] )
39+ if ( ! Number . isFinite ( value ) || value <= 0 ) return
40+ return value
41+ }
42+
43+ function pty ( value : unknown ) : LocalPTY | undefined {
44+ if ( ! record ( value ) ) return
45+
46+ const id = text ( value . id )
47+ if ( ! id ) return
48+
49+ const title = text ( value . title ) ?? ""
50+ const number = num ( value . titleNumber )
51+ const rows = num ( value . rows )
52+ const cols = num ( value . cols )
53+ const buffer = text ( value . buffer )
54+ const scrollY = num ( value . scrollY )
55+ const cursor = num ( value . cursor )
56+
57+ return {
58+ id,
59+ title,
60+ titleNumber : number && number > 0 ? number : ( numberFromTitle ( title ) ?? 0 ) ,
61+ ...( rows !== undefined ? { rows } : { } ) ,
62+ ...( cols !== undefined ? { cols } : { } ) ,
63+ ...( buffer !== undefined ? { buffer } : { } ) ,
64+ ...( scrollY !== undefined ? { scrollY } : { } ) ,
65+ ...( cursor !== undefined ? { cursor } : { } ) ,
66+ }
67+ }
68+
69+ export function migrateTerminalState ( value : unknown ) {
70+ if ( ! record ( value ) ) return value
71+
72+ const seen = new Set < string > ( )
73+ const all = ( Array . isArray ( value . all ) ? value . all : [ ] ) . flatMap ( ( item ) => {
74+ const next = pty ( item )
75+ if ( ! next || seen . has ( next . id ) ) return [ ]
76+ seen . add ( next . id )
77+ return [ next ]
78+ } )
79+
80+ const active = text ( value . active )
81+
82+ return {
83+ active : active && seen . has ( active ) ? active : all [ 0 ] ?. id ,
84+ all,
85+ }
86+ }
87+
2388export function getWorkspaceTerminalCacheKey ( dir : string ) {
2489 return `${ dir } :${ WORKSPACE_KEY } `
2590}
@@ -71,16 +136,11 @@ export function clearWorkspaceTerminals(dir: string, sessionIDs?: string[], plat
71136function createWorkspaceTerminalSession ( sdk : ReturnType < typeof useSDK > , dir : string , legacySessionID ?: string ) {
72137 const legacy = getLegacyTerminalStorageKeys ( dir , legacySessionID )
73138
74- const numberFromTitle = ( title : string ) => {
75- const match = title . match ( / ^ T e r m i n a l ( \d + ) $ / )
76- if ( ! match ) return
77- const value = Number ( match [ 1 ] )
78- if ( ! Number . isFinite ( value ) || value <= 0 ) return
79- return value
80- }
81-
82139 const [ store , setStore , _ , ready ] = persisted (
83- Persist . workspace ( dir , "terminal" , legacy ) ,
140+ {
141+ ...Persist . workspace ( dir , "terminal" , legacy ) ,
142+ migrate : migrateTerminalState ,
143+ } ,
84144 createStore < {
85145 active ?: string
86146 all : LocalPTY [ ]
@@ -128,26 +188,6 @@ function createWorkspaceTerminalSession(sdk: ReturnType<typeof useSDK>, dir: str
128188 } )
129189 onCleanup ( unsub )
130190
131- const meta = { migrated : false }
132-
133- createEffect ( ( ) => {
134- if ( ! ready ( ) ) return
135- if ( meta . migrated ) return
136- meta . migrated = true
137-
138- setStore ( "all" , ( all ) => {
139- const next = all . map ( ( pty ) => {
140- const direct = Number . isFinite ( pty . titleNumber ) && pty . titleNumber > 0 ? pty . titleNumber : undefined
141- if ( direct !== undefined ) return pty
142- const parsed = numberFromTitle ( pty . title )
143- if ( parsed === undefined ) return pty
144- return { ...pty , titleNumber : parsed }
145- } )
146- if ( next . every ( ( pty , index ) => pty === all [ index ] ) ) return all
147- return next
148- } )
149- } )
150-
151191 return {
152192 ready,
153193 all : createMemo ( ( ) => store . all ) ,
0 commit comments