@@ -805,48 +805,60 @@ function Picker:_flush_direct()
805805 self ._state .matching = {}
806806 end
807807 local match_state = self ._state .matching
808- if match_state .debounced == nil then
809- match_state .debounced = utils .debounce_callback (
810- self ._options .match_debounce ,
811- function (mode , list , match_query , total )
812- local current = self .select :query ()
813- if current ~= match_query or current == " " then
814- return
815- end
816- self .match :match (list , match_query , function (matching )
817- if matching == nil then
818- if not self .match :isvalid () or self .match :isempty () then
819- local current_state = self ._state .matching
820- local accum = current_state and current_state .accum
821- if not accum or # accum [1 ] == 0 then
822- self .select :list (
823- utils .EMPTY_TABLE ,
824- utils .EMPTY_TABLE
825- )
826- self .select :status (" 0/0" )
827- self .select :list (nil , nil )
828- end
808+ if match_state .worker == nil then
809+ match_state .worker = function (list , match_query , total )
810+ -- since this call is sometimes debounced we want to minimize the chance of doing extra work, in case the query has
811+ -- changed in between the call of this callback and it actually execting, we can skip it, the finalization above
812+ -- will ensure that the check should_match will trigger the final matching if needed.
813+ local current = assert (self .select :query ())
814+ if # current == 0 or current ~= match_query then
815+ return
816+ end
817+ -- start a new matcher with a non-empty query, against the target list that list will either be the entire stream
818+ -- accumulated so far, or just the latest chunk from the stream,
819+ self .match :match (list , match_query , function (matching )
820+ if matching == nil then
821+ if not self .match :isvalid () or self .match :isempty () then
822+ local matching_state = self ._state .matching or {}
823+ local accum = matching_state and matching_state .accum
824+ if not accum or # accum [1 ] == 0 then
825+ self .select :list (
826+ utils .EMPTY_TABLE ,
827+ utils .EMPTY_TABLE
828+ )
829+ self .select :status (" 0/0" )
830+ self .select :list (nil , nil )
829831 end
830- else
831- if mode == " all" then self :_running_match () end
832- matching = self :_running_match (matching , match_query )
833- self .select :list (matching [1 ], matching [2 ])
834- self .select :status (string.format (
835- " %d/%d" , # matching [1 ], total
836- ))
837832 end
838- end , self ._state .display )
839- end
840- )
833+ else
834+ -- the running match will ensure to reset the state internally in case the query was any different than
835+ -- it is currently stored with the matching state, the matching argument here will either be all results
836+ -- or the current streaming buffer based on the call site of this callback
837+ matching = self :_running_match (matching , match_query )
838+ self .select :list (matching [1 ], matching [2 ])
839+ self .select :status (string.format (
840+ " %d/%d" , # matching [1 ], total
841+ ))
842+ end
843+ end , self ._state .display )
844+ end
845+ match_state .workerd = utils .debounce_callback (
846+ self ._options .match_debounce , match_state .worker )
841847 end
842848
843849 -- If the query changed we have to do a match on all stream entries thus far, to reflect the matching state of these entries
844- -- while the stream is still emitting
845- local query_changed = not match_state or match_state .query ~= query
846- if query_changed and # all > 0 then
847- match_state .debounced (" all" , all , query , # all )
850+ -- while the stream is still emitting. We have two options here the query changed and we have to match on the entire set of
851+ -- results, or keep matching the incoming chunks of the stream and merge with current running match results, since the query
852+ -- never changed
853+ local match_all = not match_state or match_state .query ~= query
854+ if match_all and # all > 0 then
855+ -- debounce match onto all stream results, it is safe to debounce this call because we always have access to the latest
856+ -- accumulated results
857+ match_state .workerd (all , query , # all )
848858 elseif buf and # buf > 0 then
849- match_state .debounced (" buf" , buf , query , # all )
859+ -- directly call non-debounced accumulate match worker for the current buffer, it is not safe to debounce this call as
860+ -- the buffer we receive here will no longer be available and and we can not afford to skip it
861+ match_state .worker (buf , query , # all )
850862 end
851863 else
852864 -- No query, render all of the results as-is and reset any running accumulator, as it will have become
0 commit comments