diff --git a/.changeset/afraid-badgers-behave.md b/.changeset/afraid-badgers-behave.md new file mode 100644 index 000000000..8110ee086 --- /dev/null +++ b/.changeset/afraid-badgers-behave.md @@ -0,0 +1,5 @@ +--- +"nostrudel": patch +--- + +Fixed search results not being cached diff --git a/package.json b/package.json index e69f75b3b..d10b829e8 100644 --- a/package.json +++ b/package.json @@ -93,6 +93,7 @@ "three": "^0.160.0", "three-spritetext": "^1.8.2", "three-stdlib": "^2.29.11", + "tiny-lru": "^11.2.11", "webln": "^0.3.2", "workbox-core": "7.0.0", "workbox-precaching": "7.0.0", diff --git a/src/views/search/components/search-results.tsx b/src/views/search/components/search-results.tsx index 5bd2b9aa7..5b9eb9672 100644 --- a/src/views/search/components/search-results.tsx +++ b/src/views/search/components/search-results.tsx @@ -2,6 +2,7 @@ import { useEffect, useMemo, useState } from "react"; import { Filter, kinds, NostrEvent } from "nostr-tools"; import { AbstractRelay, Subscription, SubscriptionParams } from "nostr-tools/abstract-relay"; import { Alert, AlertDescription, AlertIcon, AlertTitle, Heading, Spinner, Text } from "@chakra-ui/react"; +import { LRU } from "tiny-lru"; import relayPoolService from "../../../services/relay-pool"; import ProfileSearchResults from "./profile-results"; @@ -35,6 +36,8 @@ function createSearchAction(url: string | AbstractRelay) { return { search, cancel }; } +const searchCache = new LRU(10); + export default function SearchResults({ query, relay }: { query: string; relay: string | AbstractRelay }) { const [results, setResults] = useState([]); @@ -44,17 +47,32 @@ export default function SearchResults({ query, relay }: { query: string; relay: useEffect(() => { if (query.length < 3) return; - setResults([]); - setError(undefined); - setSearching(true); - search - .search([{ search: query, kinds: [kinds.Metadata, kinds.ShortTextNote, kinds.LongFormArticle], limit: 200 }], { - onevent: (event) => setResults((arr) => [...arr, event]), - oneose: () => setSearching(false), - }) - .catch((err) => setError(err)); - return () => search.cancel(); + setError(undefined); + if (searchCache.has(query + relay)) { + // restore search from cache + const events = searchCache.get(query + relay)!; + setResults(events); + setSearching(false); + } else { + // run a new search + setResults([]); + setSearching(true); + search + .search([{ search: query, kinds: [kinds.Metadata, kinds.ShortTextNote, kinds.LongFormArticle], limit: 200 }], { + onevent: (event) => { + setResults((arr) => { + const newArr = [...arr, event]; + searchCache.set(query + relay, newArr); + return newArr; + }); + }, + oneose: () => setSearching(false), + }) + .catch((err) => setError(err)); + + return () => search.cancel(); + } }, [query, search]); const profiles = results.filter((e) => e.kind === kinds.Metadata); diff --git a/src/views/search/index.tsx b/src/views/search/index.tsx index ea093041e..14bd7fc98 100644 --- a/src/views/search/index.tsx +++ b/src/views/search/index.tsx @@ -1,6 +1,7 @@ import { useCallback, useEffect } from "react"; import { ButtonGroup, Flex, IconButton, Input, Select } from "@chakra-ui/react"; import { useNavigate, useSearchParams, Link as RouterLink } from "react-router-dom"; +import { useForm } from "react-hook-form"; import { safeDecode } from "../../helpers/nip19"; import { getMatchHashtag } from "../../helpers/regexp"; @@ -9,7 +10,6 @@ import VerticalPageLayout from "../../components/vertical-page-layout"; import PeopleListProvider from "../../providers/local/people-list-provider"; import { useBreakpointValue } from "../../providers/global/breakpoint-provider"; import QRCodeScannerButton from "../../components/qr-code/qr-code-scanner-button"; -import { useForm } from "react-hook-form"; import SearchResults from "./components/search-results"; import useSearchRelays from "../../hooks/use-search-relays"; diff --git a/yarn.lock b/yarn.lock index c1438f1a5..7fe76c196 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7640,6 +7640,11 @@ tiny-invariant@^1.0.6: resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.3.1.tgz#8560808c916ef02ecfd55e66090df23a4b7aa642" integrity sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw== +tiny-lru@^11.2.11: + version "11.2.11" + resolved "https://registry.yarnpkg.com/tiny-lru/-/tiny-lru-11.2.11.tgz#5089a6a4a157f5a97b82aa930b44d550ac5c4778" + integrity sha512-27BIW0dIWTYYoWNnqSmoNMKe5WIbkXsc0xaCQHd3/3xT2XMuMJrzHdrO9QBFR14emBz1Bu0dOAs2sCBBrvgPQA== + tinycolor2@1, tinycolor2@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/tinycolor2/-/tinycolor2-1.6.0.tgz#f98007460169b0263b97072c5ae92484ce02d09e"