Faster search with minisearch
This commit is contained in:
parent
8d3b801aab
commit
716900a397
@ -1,7 +1,7 @@
|
|||||||
import React, { useEffect, useState, useRef } from "react";
|
import React, { useEffect, useState, useRef } from "react";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import type mapboxgl from "mapbox-gl";
|
import type mapboxgl from "mapbox-gl";
|
||||||
import Fuse from "fuse.js";
|
import MiniSearch, { SearchResult } from "minisearch";
|
||||||
import useSWRImmutable from "swr/immutable";
|
import useSWRImmutable from "swr/immutable";
|
||||||
|
|
||||||
import styles from "../styles/SearchBar.module.css";
|
import styles from "../styles/SearchBar.module.css";
|
||||||
@ -17,11 +17,6 @@ interface Mod {
|
|||||||
id: number;
|
id: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface SearchResult {
|
|
||||||
item: Mod;
|
|
||||||
refIndex: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
const jsonFetcher = async (url: string): Promise<Mod | null> => {
|
const jsonFetcher = async (url: string): Promise<Mod | null> => {
|
||||||
const res = await fetch(url);
|
const res = await fetch(url);
|
||||||
|
|
||||||
@ -38,9 +33,9 @@ const jsonFetcher = async (url: string): Promise<Mod | null> => {
|
|||||||
const SearchBar: React.FC<Props> = ({ clearSelectedCell, map }) => {
|
const SearchBar: React.FC<Props> = ({ clearSelectedCell, map }) => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
const fuse = useRef<Fuse<Mod> | null>(null) as React.MutableRefObject<
|
const searchEngine = useRef<MiniSearch<Mod> | null>(
|
||||||
Fuse<Mod>
|
null
|
||||||
>;
|
) as React.MutableRefObject<MiniSearch<Mod>>;
|
||||||
|
|
||||||
const { data, error } = useSWRImmutable(
|
const { data, error } = useSWRImmutable(
|
||||||
`https://mods.modmapper.com/mod_search_index.json`,
|
`https://mods.modmapper.com/mod_search_index.json`,
|
||||||
@ -48,8 +43,16 @@ const SearchBar: React.FC<Props> = ({ clearSelectedCell, map }) => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (data && !fuse.current) {
|
if (data && !searchEngine.current) {
|
||||||
fuse.current = new Fuse(data as unknown as Mod[], { keys: ["name"] });
|
searchEngine.current = new MiniSearch({
|
||||||
|
fields: ["name"],
|
||||||
|
storeFields: ["name", "id"],
|
||||||
|
searchOptions: {
|
||||||
|
fields: ["name"],
|
||||||
|
fuzzy: 0.2,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
searchEngine.current.addAll(data as unknown as Mod[]);
|
||||||
}
|
}
|
||||||
}, [data]);
|
}, [data]);
|
||||||
|
|
||||||
@ -77,8 +80,8 @@ const SearchBar: React.FC<Props> = ({ clearSelectedCell, map }) => {
|
|||||||
|
|
||||||
const onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
const onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
setSearch(e.target.value);
|
setSearch(e.target.value);
|
||||||
if (fuse.current) {
|
if (searchEngine.current) {
|
||||||
const results: { item: Mod; refIndex: number }[] = fuse.current.search(
|
const results: SearchResult[] = searchEngine.current.search(
|
||||||
e.target.value
|
e.target.value
|
||||||
);
|
);
|
||||||
setResults(results);
|
setResults(results);
|
||||||
@ -122,12 +125,12 @@ const SearchBar: React.FC<Props> = ({ clearSelectedCell, map }) => {
|
|||||||
<ul className={styles["search-results"]}>
|
<ul className={styles["search-results"]}>
|
||||||
{results.map((result) => (
|
{results.map((result) => (
|
||||||
<li
|
<li
|
||||||
key={result.item.id}
|
key={result.id}
|
||||||
onClick={onChooseResult(result.item)}
|
onClick={onChooseResult({ id: result.id, name: result.name })}
|
||||||
onTouchStart={() => setClickingResult(true)}
|
onTouchStart={() => setClickingResult(true)}
|
||||||
onMouseDown={() => setClickingResult(true)}
|
onMouseDown={() => setClickingResult(true)}
|
||||||
>
|
>
|
||||||
{result.item.name}
|
{result.name}
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
|
10
package-lock.json
generated
10
package-lock.json
generated
@ -1210,11 +1210,6 @@
|
|||||||
"integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
|
"integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"fuse.js": {
|
|
||||||
"version": "6.5.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/fuse.js/-/fuse.js-6.5.3.tgz",
|
|
||||||
"integrity": "sha512-sA5etGE7yD/pOqivZRBvUBd/NaL2sjAu6QuSaFoe1H2BrJSkH/T/UXAJ8CdXdw7DvY3Hs8CXKYkDWX7RiP5KOg=="
|
|
||||||
},
|
|
||||||
"geojson-vt": {
|
"geojson-vt": {
|
||||||
"version": "3.2.1",
|
"version": "3.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/geojson-vt/-/geojson-vt-3.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/geojson-vt/-/geojson-vt-3.2.1.tgz",
|
||||||
@ -1716,6 +1711,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
||||||
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
|
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
|
||||||
},
|
},
|
||||||
|
"minisearch": {
|
||||||
|
"version": "3.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/minisearch/-/minisearch-3.2.0.tgz",
|
||||||
|
"integrity": "sha512-Nq3o/a9mhvokHXKCS9zxAd0t1z/eSjdtmvfBfvGI2D0/Fx8xUjrOdpjqbU7DXRyH8obowhELR1+L+i3TV7Y21g=="
|
||||||
|
},
|
||||||
"ms": {
|
"ms": {
|
||||||
"version": "2.1.2",
|
"version": "2.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||||
|
@ -11,9 +11,9 @@
|
|||||||
"@types/javascript-color-gradient": "^1.3.0",
|
"@types/javascript-color-gradient": "^1.3.0",
|
||||||
"@types/mapbox-gl": "^2.6.0",
|
"@types/mapbox-gl": "^2.6.0",
|
||||||
"date-fns": "^2.28.0",
|
"date-fns": "^2.28.0",
|
||||||
"fuse.js": "^6.5.3",
|
|
||||||
"javascript-color-gradient": "^1.3.2",
|
"javascript-color-gradient": "^1.3.2",
|
||||||
"mapbox-gl": "^2.6.1",
|
"mapbox-gl": "^2.6.1",
|
||||||
|
"minisearch": "^3.2.0",
|
||||||
"next": "12.0.8",
|
"next": "12.0.8",
|
||||||
"react": "17.0.2",
|
"react": "17.0.2",
|
||||||
"react-dom": "17.0.2",
|
"react-dom": "17.0.2",
|
||||||
|
Loading…
Reference in New Issue
Block a user