@@ -20,6 +20,13 @@ interface SearchParams {
2020 queries : AlgoliaMultipleQueriesQuery [ ]
2121}
2222
23+ interface HighlightMetadata {
24+ value : string
25+ fullyHighlighted : boolean
26+ matchLevel : 'none' | 'partial' | 'full'
27+ matchedWords : string [ ]
28+ }
29+
2330export function fetchMeilisearchResults < TRecord = Record < string , any > > ( {
2431 searchClient,
2532 queries,
@@ -42,7 +49,60 @@ export function fetchMeilisearchResults<TRecord = Record<string, any>>({
4249 )
4350 . then (
4451 ( response : Awaited < ReturnType < typeof searchClient . search < TRecord > > > ) => {
45- return response . results
52+ return response . results . map (
53+ ( result : AlgoliaSearchResponse < TRecord > ) => ( {
54+ ...result ,
55+ hits : result . hits . map (
56+ ( hit : AlgoliaSearchResponse < TRecord > [ 'hits' ] [ number ] ) => ( {
57+ ...hit ,
58+ _highlightResult : hit . _highlightResult
59+ ? Object . entries ( hit . _highlightResult ) . reduce (
60+ ( acc , [ key , value ] ) => ( {
61+ ...acc ,
62+ [ key ] : calculateHighlightMetadata ( value . value ) ,
63+ } ) ,
64+ { }
65+ )
66+ : { } ,
67+ } )
68+ ) ,
69+ } )
70+ )
4671 }
4772 )
4873}
74+
75+ function calculateHighlightMetadata (
76+ value : string ,
77+ preTag : string = HIGHLIGHT_PRE_TAG ,
78+ postTag : string = HIGHLIGHT_POST_TAG
79+ ) : HighlightMetadata {
80+ // Find all highlighted words
81+ const highlightRegex = new RegExp ( `${ preTag } (.*?)${ postTag } ` , 'g' )
82+ const matches : string [ ] = [ ]
83+ let match
84+ while ( ( match = highlightRegex . exec ( value ) ) !== null ) {
85+ matches . push ( match [ 1 ] )
86+ }
87+ const matchedWords = matches
88+
89+ // Remove highlight tags for comparison
90+ const cleanValue = value . replace ( new RegExp ( `${ preTag } |${ postTag } ` , 'g' ) , '' )
91+
92+ // Calculate if fully highlighted
93+ const highlightedText = matches . join ( '' )
94+ const fullyHighlighted = cleanValue === highlightedText
95+
96+ // Determine match level
97+ let matchLevel : 'none' | 'partial' | 'full' = 'none'
98+ if ( matches . length > 0 ) {
99+ matchLevel = fullyHighlighted ? 'full' : 'partial'
100+ }
101+
102+ return {
103+ value,
104+ fullyHighlighted,
105+ matchLevel,
106+ matchedWords,
107+ }
108+ }
0 commit comments