@@ -50,6 +50,12 @@ const WORD_MATCH_BOOST = 4;
50
50
const NEAR_MATCH_BOOST = 2 ;
51
51
const BREADCRUMB_LENGTH_BOOST = 0.2 ;
52
52
53
+ interface Entry {
54
+ block : Block ;
55
+ score : number ;
56
+ rank : number ;
57
+ }
58
+
53
59
/**
54
60
* Search for a given query in the existing index
55
61
*/
@@ -65,7 +71,7 @@ export function search(query: string, path: string): BlockGroup[] {
65
71
. flatMap ( ( index ) => index . search ( query ) )
66
72
// @ts -expect-error flexsearch types are wrong i think?
67
73
. map ( lookup )
68
- . map ( ( block ) => {
74
+ . map ( ( block , rank ) => {
69
75
const block_parts = block . href . split ( '/' ) ;
70
76
71
77
// prioritise current section
@@ -85,25 +91,39 @@ export function search(query: string, path: string): BlockGroup[] {
85
91
// prioritise branches over leaves
86
92
score -= block . breadcrumbs . length * BREADCRUMB_LENGTH_BOOST ;
87
93
88
- return { block, score } ;
89
- } ) ;
94
+ const entry : Entry = { block, score, rank } ;
90
95
91
- const groups : Record < string , BlockGroup > = { } ;
96
+ return entry ;
97
+ } ) ;
92
98
93
- for ( const { score, block } of blocks ) {
94
- const breadcrumbs = block . breadcrumbs . slice ( 0 , 2 ) ;
99
+ const grouped : Record < string , { breadcrumbs : string [ ] ; entries : Entry [ ] } > = { } ;
95
100
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 ( '::' ) ] ??= {
97
104
breadcrumbs,
98
- blocks : [ ] ,
99
- score : 0
105
+ entries : [ ]
100
106
} ) ;
101
107
102
- group . score = Math . max ( score , group . score ) ;
103
- group . blocks . push ( block ) ;
108
+ group . entries . push ( entry ) ;
104
109
}
105
110
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
+ } ) ;
107
127
}
108
128
109
129
/**
0 commit comments