|
1 |
| -import Fuse, { type FuseResultMatch, type FuseSortFunctionArg, type IFuseOptions } from 'fuse.js'; |
2 |
| - |
3 | 1 | import { defineComponent, markRaw, ref } from 'vue';
|
4 | 2 | import interfacesJson from '../api.json';
|
5 | 3 | import ApiParameter from './ApiParameter.vue';
|
6 | 4 | import type { ApiInterface, ApiMethod, ApiMethodParameter, ApiServices, SidebarGroupData } from './interfaces';
|
| 5 | +import { ApiSearcher } from './search'; |
7 | 6 |
|
8 | 7 | interface FuseSearchType {
|
9 | 8 | interface: string;
|
@@ -81,7 +80,7 @@ export default defineComponent({
|
81 | 80 | accessTokenVisible: false,
|
82 | 81 | currentFilter: '',
|
83 | 82 | currentInterface: '',
|
84 |
| - fuzzy: new Object() as Fuse<FuseSearchType>, |
| 83 | + search: markRaw(new ApiSearcher(interfaces)), |
85 | 84 | interfaces,
|
86 | 85 | groupsMap,
|
87 | 86 | groupsData,
|
@@ -230,26 +229,6 @@ export default defineComponent({
|
230 | 229 | false,
|
231 | 230 | );
|
232 | 231 |
|
233 |
| - const fuseOptions: IFuseOptions<FuseSearchType> = { |
234 |
| - shouldSort: true, |
235 |
| - useExtendedSearch: true, |
236 |
| - includeMatches: true, |
237 |
| - minMatchCharLength: 3, |
238 |
| - threshold: 0.3, |
239 |
| - keys: [ |
240 |
| - { |
241 |
| - name: 'interface', |
242 |
| - weight: 0.3, |
243 |
| - }, |
244 |
| - { |
245 |
| - name: 'method', |
246 |
| - weight: 0.7, |
247 |
| - }, |
248 |
| - ], |
249 |
| - }; |
250 |
| - const fuse = new Fuse<FuseSearchType>(flattenedMethods, fuseOptions); |
251 |
| - this.fuzzy = markRaw(fuse); |
252 |
| - |
253 | 232 | this.bindGlobalKeybind();
|
254 | 233 | },
|
255 | 234 | computed: {
|
@@ -285,26 +264,16 @@ export default defineComponent({
|
285 | 264 | return this.interfaces;
|
286 | 265 | }
|
287 | 266 |
|
288 |
| - const matches = this.fuzzy.search(this.currentFilter.replace('/', '|')); |
289 | 267 | const matchedInterfaces: ApiServices = {};
|
| 268 | + const hits = this.search.search(this.currentFilter); |
290 | 269 |
|
291 |
| - for (const searchResult of matches) { |
292 |
| - const match = searchResult.item; |
293 |
| - |
| 270 | + for (const match of hits) { |
294 | 271 | if (!matchedInterfaces[match.interface]) {
|
295 | 272 | matchedInterfaces[match.interface] = {};
|
296 | 273 | }
|
297 | 274 |
|
298 |
| - let highlight: string | undefined; |
299 |
| - for (const m of searchResult.matches!) { |
300 |
| - if (m.key === 'method') { |
301 |
| - highlight = this.highlightMatches(m); |
302 |
| - break; |
303 |
| - } |
304 |
| - } |
305 |
| - |
306 | 275 | const method = this.interfaces[match.interface][match.method];
|
307 |
| - method.highlight = highlight; |
| 276 | + method.highlight = match.highlight; |
308 | 277 | matchedInterfaces[match.interface][match.method] = method;
|
309 | 278 | }
|
310 | 279 |
|
@@ -660,38 +629,6 @@ export default defineComponent({
|
660 | 629 | this.currentFilter = (e.target as HTMLInputElement).value;
|
661 | 630 | });
|
662 | 631 | },
|
663 |
| - highlightMatches(match: FuseResultMatch) { |
664 |
| - let lastIndex = 0; |
665 |
| - const result: string[] = []; |
666 |
| - const sortedMatches = match.indices.toSorted((a, b) => a[0] - b[0]); |
667 |
| - const value = match.value!; |
668 |
| - |
669 |
| - for (let [start, end] of sortedMatches) { |
670 |
| - if (end <= lastIndex) { |
671 |
| - continue; |
672 |
| - } |
673 |
| - |
674 |
| - if (start < lastIndex) { |
675 |
| - start = lastIndex; |
676 |
| - } |
677 |
| - |
678 |
| - if (lastIndex < start) { |
679 |
| - result.push(value.slice(lastIndex, start)); |
680 |
| - } |
681 |
| - |
682 |
| - end++; |
683 |
| - |
684 |
| - result.push('<b>', value.slice(start, end), '</b>'); |
685 |
| - |
686 |
| - lastIndex = end; |
687 |
| - } |
688 |
| - |
689 |
| - if (lastIndex !== value.length) { |
690 |
| - result.push(value.slice(lastIndex)); |
691 |
| - } |
692 |
| - |
693 |
| - return result.join(''); |
694 |
| - }, |
695 | 632 | bindGlobalKeybind() {
|
696 | 633 | document.addEventListener('keydown', (e: KeyboardEvent) => {
|
697 | 634 | if (e.ctrlKey || e.metaKey) {
|
|
0 commit comments