@@ -50,6 +50,12 @@ const WORD_MATCH_BOOST = 4;
5050const NEAR_MATCH_BOOST = 2 ;
5151const BREADCRUMB_LENGTH_BOOST = 0.2 ;
5252
53+ interface Entry {
54+ block : Block ;
55+ score : number ;
56+ rank : number ;
57+ }
58+
5359/**
5460 * Search for a given query in the existing index
5561 */
@@ -65,7 +71,7 @@ export function search(query: string, path: string): BlockGroup[] {
6571 . flatMap ( ( index ) => index . search ( query ) )
6672 // @ts -expect-error flexsearch types are wrong i think?
6773 . map ( lookup )
68- . map ( ( block ) => {
74+ . map ( ( block , rank ) => {
6975 const block_parts = block . href . split ( '/' ) ;
7076
7177 // prioritise current section
@@ -85,25 +91,39 @@ export function search(query: string, path: string): BlockGroup[] {
8591 // prioritise branches over leaves
8692 score -= block . breadcrumbs . length * BREADCRUMB_LENGTH_BOOST ;
8793
88- return { block, score } ;
89- } ) ;
94+ const entry : Entry = { block, score, rank } ;
9095
91- const groups : Record < string , BlockGroup > = { } ;
96+ return entry ;
97+ } ) ;
9298
93- for ( const { score, block } of blocks ) {
94- const breadcrumbs = block . breadcrumbs . slice ( 0 , 2 ) ;
99+ const grouped : Record < string , { breadcrumbs : string [ ] ; entries : Entry [ ] } > = { } ;
95100
96- const group = ( groups [ breadcrumbs . join ( '::' ) ] ??= {
101+ for ( const entry of blocks ) {
102+ const breadcrumbs = entry . block . breadcrumbs . slice ( 0 , 2 ) ;
103+ const group = ( grouped [ breadcrumbs . join ( '::' ) ] ??= {
97104 breadcrumbs,
98- blocks : [ ] ,
99- score : 0
105+ entries : [ ]
100106 } ) ;
101107
102- group . score = Math . max ( score , group . score ) ;
103- group . blocks . push ( block ) ;
108+ group . entries . push ( entry ) ;
104109 }
105110
106- return Object . values ( groups ) . sort ( ( a , b ) => b . score - a . score ) ;
111+ const sorted = Object . values ( grouped ) ;
112+
113+ // sort blocks within groups...
114+ for ( const group of sorted ) {
115+ group . entries . sort ( ( a , b ) => b . score - a . score || a . rank - b . rank ) ;
116+ }
117+
118+ // ...then sort groups
119+ sorted . sort ( ( a , b ) => b . entries [ 0 ] . score - a . entries [ 0 ] . score ) ;
120+
121+ return sorted . map ( ( group ) => {
122+ return {
123+ breadcrumbs : group . breadcrumbs ,
124+ blocks : group . entries . map ( ( entry ) => entry . block )
125+ } ;
126+ } ) ;
107127}
108128
109129/**
0 commit comments