@@ -191,7 +191,7 @@ function App() {
191191 const toSafeString = ( value ) =>
192192 typeof value === 'string' ? value : value == null ? '' : String ( value )
193193
194- // Filter sessions based on search query (memoized for performance)
194+ // Normalization utility for search
195195 const normalizeForSearch = ( value ) =>
196196 toSafeString ( value )
197197 . toLowerCase ( )
@@ -200,34 +200,32 @@ function App() {
200200 . replace ( / \s + / g, ' ' )
201201 . trim ( )
202202
203- const filteredSessions = useMemo ( ( ) => {
204- const query = normalizeForSearch ( debouncedQuery ) . trim ( )
205- // Always exclude items without a valid sessionId first
206- const validSessions = Array . isArray ( sessions )
207- ? sessions . filter ( ( s ) => Boolean ( s ?. sessionId ) )
208- : [ ]
209-
210- if ( ! query ) return validSessions
211-
212- return validSessions . filter ( ( session ) => {
213- // Search in session name
214- const sessionName = normalizeForSearch ( session . sessionName )
215- if ( sessionName . includes ( query ) ) {
216- return true
217- }
203+ // Precompute a normalized index for sessions to reduce per-keystroke work
204+ const normalizedIndex = useMemo ( ( ) => {
205+ if ( ! Array . isArray ( sessions ) ) return [ ]
206+ const SEP = '\n—\n'
207+ return sessions
208+ . filter ( ( s ) => Boolean ( s ?. sessionId ) )
209+ . map ( ( s ) => {
210+ const nameNorm = normalizeForSearch ( s . sessionName )
211+ let bodyNorm = ''
212+ if ( Array . isArray ( s . conversationRecords ) ) {
213+ bodyNorm = s . conversationRecords
214+ . map ( ( r ) => `${ normalizeForSearch ( r ?. question ) } ${ normalizeForSearch ( r ?. answer ) } ` )
215+ . join ( SEP )
216+ }
217+ return { session : s , nameNorm, bodyNorm }
218+ } )
219+ } , [ sessions ] )
218220
219- // Search in conversation records
220- if ( Array . isArray ( session . conversationRecords ) ) {
221- return session . conversationRecords . some ( ( record ) => {
222- const question = normalizeForSearch ( record ?. question )
223- const answer = normalizeForSearch ( record ?. answer )
224- return question . includes ( query ) || answer . includes ( query )
225- } )
226- }
227-
228- return false
229- } )
230- } , [ sessions , debouncedQuery ] )
221+ // Filter sessions based on search query using the precomputed index
222+ const filteredSessions = useMemo ( ( ) => {
223+ const q = normalizeForSearch ( debouncedQuery ) . trim ( )
224+ if ( ! q ) return normalizedIndex . map ( ( i ) => i . session )
225+ return normalizedIndex
226+ . filter ( ( i ) => i . nameNorm . includes ( q ) || i . bodyNorm . includes ( q ) )
227+ . map ( ( i ) => i . session )
228+ } , [ normalizedIndex , debouncedQuery ] )
231229
232230 return (
233231 < div className = "IndependentPanel" >
0 commit comments