11import type { DisplayResult } from '../postMessage'
22import { childPort } from '../postMessage'
3- import {
4- useCallback ,
5- useDeferredValue ,
6- useMemo ,
7- useSyncExternalStore
8- } from 'react'
3+ import { useCallback , useDeferredValue , useSyncExternalStore } from 'react'
94import { useDebounce } from 'react-use'
105
116// id should not overflow, the MOD is large enough
@@ -14,16 +9,16 @@ const MOD = 1e9 + 7
149
1510// maintain the latest search task id and callback
1611let id = 0
17- let searchResult : DisplayResult [ ] = [ ]
12+ let grouped = [ ] as [ string , DisplayResult [ ] ] [ ]
1813let queryInFlight = ''
1914let searching = true
2015let notify = ( ) => { }
2116
2217function postSearch ( inputValue : string ) {
2318 id = ( id + 1 ) % MOD
2419 childPort . postMessage ( 'search' , { id, inputValue } )
25- searchResult = [ ]
2620 searching = true
21+ grouped = [ ]
2722 notify ( )
2823}
2924
@@ -32,7 +27,7 @@ childPort.onMessage('searchResultStreaming', event => {
3227 return
3328 }
3429 queryInFlight = event . inputValue
35- searchResult = searchResult . concat ( event . searchResult )
30+ grouped = merge ( groupBy ( event . searchResult ) )
3631 notify ( )
3732} )
3833
@@ -56,6 +51,16 @@ function groupBy(matches: DisplayResult[]) {
5651 return groups
5752}
5853
54+ function merge ( newEntries : Map < string , DisplayResult [ ] > ) {
55+ // first, clone the old map for react
56+ let temp = new Map ( grouped )
57+ for ( const [ file , newList ] of newEntries ) {
58+ const existing = temp . get ( file ) || [ ]
59+ temp . set ( file , existing . concat ( newList ) )
60+ }
61+ return [ ...temp . entries ( ) ]
62+ }
63+
5964// version is for react to update view
6065let version = 114514
6166function subscribe ( onChange : ( ) => void ) : ( ) => void {
@@ -81,9 +86,6 @@ export const useSearchResult = (inputValue: string) => {
8186 postSearch ( inputValue )
8287 } , [ inputValue ] )
8388
84- const grouped = useMemo ( ( ) => {
85- return [ ...groupBy ( searchResult ) . entries ( ) ]
86- } , [ searchResult ] )
8789 // rendering tree is too expensive, useDeferredValue
8890 const groupedByFileSearchResult = useDeferredValue ( grouped )
8991
@@ -92,8 +94,8 @@ export const useSearchResult = (inputValue: string) => {
9294 return {
9395 queryInFlight,
9496 searching,
95- searchResult,
9697 groupedByFileSearchResult,
98+ searchCount : grouped . reduce ( ( a , l ) => a + l [ 1 ] . length , 0 ) ,
9799 refreshSearchResult
98100 }
99101}
0 commit comments