Repository navigation
Improve client side search logic - #58
Conversation
✅ Deploy Preview for device-database-preview ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
Side note: While validating this with AI it suggested a dependency-free version (~300 lines of logic): split labels into words, strip accents, and compare each typed word against each label word by exact match, prefix, one edit (counting swapped letters as a single edit), or shared stem. Measured on the live manufacturer list it was noticeably more precise: swapped-letter typos like "ikae" found IKEA directly, "aeotech" returned only Aeotec instead of 32 hits, highlights were always whole words or clean prefixes, and wrong category extractions on manufacturer names dropped from 21 to 7 in German and 59 to 20 in Spanish. I went with fuse.js anyway, since the custom code is harder to read and maintain for anyone not familiar with edit distances, and the fuse.js version is already a big improvement. To keep in mind if any of the quirks mentioned above start bothering us/the users. |
| export const highlight = ( | ||
| text: string, | ||
| term: string, | ||
| ): (string | TemplateResult)[] => { | ||
| const ranges = tokens(term) | ||
| .flatMap((token) => { | ||
| const { isMatch, indices } = Fuse.match(token, text, OPTIONS); | ||
| return isMatch ? (indices ?? []) : []; | ||
| }) | ||
| .toSorted(([a], [b]) => a - b); | ||
|
|
||
| const parts: (string | TemplateResult)[] = []; | ||
| let at = 0; | ||
| for (const [start, end] of ranges) { | ||
| if (end < at) { | ||
| continue; | ||
| } | ||
| const from = Math.max(start, at); | ||
| parts.push( | ||
| text.slice(at, from), | ||
| html`<mark>${text.slice(from, end + 1)}</mark>`, | ||
| ); | ||
| at = end + 1; | ||
| } | ||
| parts.push(text.slice(at)); | ||
|
|
||
| return parts; | ||
| }; |
There was a problem hiding this comment.
This is connected to the minMatchCharLength issue but I updated the highlighter logic to stop on first occurrence or longest segment of typo tolerance check
| // avoids single-character highlight fragments on fuzzy matches | ||
| minMatchCharLength: 2, |
There was a problem hiding this comment.
Removed minMatchCharLength. I wanted to use it to tidy highlights but it also filtered out results
|
the search box already feels much nicer to use 🙌 |
… the tolerance match


Closes OHF-Device-Database/backlog-items#166
Replaces the plain
includes()filtering in the global search popover and the category/manufacturer filter modal and sheet with fuzzy search via fuse.js.What we get
<mark>.Trade offs
Category extraction is strict, because a wrong category silently hides results. Short words must match exactly and only one typo is forgiven, so "printer" does not become Printing (but "print" and "printing" do), and manufacturer names that contain a category word ("Philips Lighting", "Victron Energy") are narrowed to that category.