(
entries: NoteSearchEntry[],
query: string,
options: {
limit: number
defaultOrder?: NoteSearchDefaultOrder
}
)
| 142 | } |
| 143 | |
| 144 | export function searchNoteIndex( |
| 145 | entries: NoteSearchEntry[], |
| 146 | query: string, |
| 147 | options: { |
| 148 | limit: number |
| 149 | defaultOrder?: NoteSearchDefaultOrder |
| 150 | } |
| 151 | ): NoteMeta[] { |
| 152 | const { freeText, tagTokens } = parseNoteSearchQuery(query) |
| 153 | const limit = Math.max(0, options.limit) |
| 154 | if (limit === 0) return [] |
| 155 | |
| 156 | if (!freeText) { |
| 157 | const live = entries.filter( |
| 158 | (entry) => entry.note.folder !== 'trash' && matchesTags(entry, tagTokens) |
| 159 | ) |
| 160 | return defaultSort(live, options.defaultOrder ?? 'current') |
| 161 | .slice(0, limit) |
| 162 | .map((entry) => entry.note) |
| 163 | } |
| 164 | |
| 165 | const preparedQuery = freeText.toLowerCase() |
| 166 | const matches: Array<{ entry: NoteSearchEntry; score: number }> = [] |
| 167 | if (preparedQuery.length >= LONG_QUERY_EXACT_FIRST_CHARS) { |
| 168 | for (const entry of entries) { |
| 169 | if (entry.note.folder === 'trash' || !matchesTags(entry, tagTokens)) continue |
| 170 | const score = scoreNote(entry, preparedQuery, false) |
| 171 | if (score <= 0) continue |
| 172 | insertTopMatch(matches, { entry, score }, limit) |
| 173 | } |
| 174 | |
| 175 | if (matches.length > 0) { |
| 176 | return matches |
| 177 | .sort((a, b) => { |
| 178 | if (b.score !== a.score) return b.score - a.score |
| 179 | return b.entry.note.updatedAt - a.entry.note.updatedAt |
| 180 | }) |
| 181 | .map((match) => match.entry.note) |
| 182 | } |
| 183 | } |
| 184 | |
| 185 | for (const entry of entries) { |
| 186 | if (entry.note.folder === 'trash' || !matchesTags(entry, tagTokens)) continue |
| 187 | const score = scoreNote(entry, preparedQuery) |
| 188 | if (score <= 0) continue |
| 189 | insertTopMatch(matches, { entry, score }, limit) |
| 190 | } |
| 191 | |
| 192 | return matches |
| 193 | .sort((a, b) => { |
| 194 | if (b.score !== a.score) return b.score - a.score |
| 195 | return b.entry.note.updatedAt - a.entry.note.updatedAt |
| 196 | }) |
| 197 | .map((match) => match.entry.note) |
| 198 | } |
no test coverage detected