mirror of
https://github.com/streamyfin/streamyfin.git
synced 2026-01-15 15:48:05 +00:00
feat(search): lower debounce to 200ms and add AbortController using TanStack Pacer
This commit is contained in:
@@ -3,6 +3,7 @@ import type {
|
|||||||
BaseItemKind,
|
BaseItemKind,
|
||||||
} from "@jellyfin/sdk/lib/generated-client/models";
|
} from "@jellyfin/sdk/lib/generated-client/models";
|
||||||
import { getItemsApi } from "@jellyfin/sdk/lib/utils/api";
|
import { getItemsApi } from "@jellyfin/sdk/lib/utils/api";
|
||||||
|
import { useAsyncDebouncer } from "@tanstack/react-pacer";
|
||||||
import { useQuery } from "@tanstack/react-query";
|
import { useQuery } from "@tanstack/react-query";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import { Image } from "expo-image";
|
import { Image } from "expo-image";
|
||||||
@@ -20,7 +21,6 @@ import {
|
|||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { Platform, ScrollView, TouchableOpacity, View } from "react-native";
|
import { Platform, ScrollView, TouchableOpacity, View } from "react-native";
|
||||||
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
||||||
import { useDebounce } from "use-debounce";
|
|
||||||
import ContinueWatchingPoster from "@/components/ContinueWatchingPoster";
|
import ContinueWatchingPoster from "@/components/ContinueWatchingPoster";
|
||||||
import { Input } from "@/components/common/Input";
|
import { Input } from "@/components/common/Input";
|
||||||
import { Text } from "@/components/common/Text";
|
import { Text } from "@/components/common/Text";
|
||||||
@@ -70,7 +70,23 @@ export default function search() {
|
|||||||
const [searchType, setSearchType] = useState<SearchType>("Library");
|
const [searchType, setSearchType] = useState<SearchType>("Library");
|
||||||
const [search, setSearch] = useState<string>("");
|
const [search, setSearch] = useState<string>("");
|
||||||
|
|
||||||
const [debouncedSearch] = useDebounce(search, 500);
|
const [debouncedSearch, setDebouncedSearch] = useState("");
|
||||||
|
const abortControllerRef = useRef<AbortController | null>(null);
|
||||||
|
|
||||||
|
const searchDebouncer = useAsyncDebouncer(
|
||||||
|
async (query: string) => {
|
||||||
|
// Cancel previous in-flight requests
|
||||||
|
abortControllerRef.current?.abort();
|
||||||
|
abortControllerRef.current = new AbortController();
|
||||||
|
setDebouncedSearch(query);
|
||||||
|
return query;
|
||||||
|
},
|
||||||
|
{ wait: 200 },
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
searchDebouncer.maybeExecute(search);
|
||||||
|
}, [search]);
|
||||||
|
|
||||||
const [api] = useAtom(apiAtom);
|
const [api] = useAtom(apiAtom);
|
||||||
|
|
||||||
@@ -100,9 +116,11 @@ export default function search() {
|
|||||||
async ({
|
async ({
|
||||||
types,
|
types,
|
||||||
query,
|
query,
|
||||||
|
signal,
|
||||||
}: {
|
}: {
|
||||||
types: BaseItemKind[];
|
types: BaseItemKind[];
|
||||||
query: string;
|
query: string;
|
||||||
|
signal?: AbortSignal;
|
||||||
}): Promise<BaseItemDto[]> => {
|
}): Promise<BaseItemDto[]> => {
|
||||||
if (!api || !query) {
|
if (!api || !query) {
|
||||||
return [];
|
return [];
|
||||||
@@ -110,13 +128,16 @@ export default function search() {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
if (searchEngine === "Jellyfin") {
|
if (searchEngine === "Jellyfin") {
|
||||||
const searchApi = await getItemsApi(api).getItems({
|
const searchApi = await getItemsApi(api).getItems(
|
||||||
searchTerm: query,
|
{
|
||||||
limit: 10,
|
searchTerm: query,
|
||||||
includeItemTypes: types,
|
limit: 10,
|
||||||
recursive: true,
|
includeItemTypes: types,
|
||||||
userId: user?.Id,
|
recursive: true,
|
||||||
});
|
userId: user?.Id,
|
||||||
|
},
|
||||||
|
{ signal },
|
||||||
|
);
|
||||||
|
|
||||||
return (searchApi.data.Items as BaseItemDto[]) || [];
|
return (searchApi.data.Items as BaseItemDto[]) || [];
|
||||||
}
|
}
|
||||||
@@ -145,6 +166,7 @@ export default function search() {
|
|||||||
query,
|
query,
|
||||||
searchType as "movies" | "series" | "episodes" | "actors" | "media",
|
searchType as "movies" | "series" | "episodes" | "actors" | "media",
|
||||||
10,
|
10,
|
||||||
|
signal,
|
||||||
);
|
);
|
||||||
|
|
||||||
const allIds: string[] = [
|
const allIds: string[] = [
|
||||||
@@ -159,10 +181,13 @@ export default function search() {
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
const itemsResponse = await getItemsApi(api).getItems({
|
const itemsResponse = await getItemsApi(api).getItems(
|
||||||
ids: allIds,
|
{
|
||||||
enableImageTypes: ["Primary", "Backdrop", "Thumb"],
|
ids: allIds,
|
||||||
});
|
enableImageTypes: ["Primary", "Backdrop", "Thumb"],
|
||||||
|
},
|
||||||
|
{ signal },
|
||||||
|
);
|
||||||
|
|
||||||
return (itemsResponse.data.Items as BaseItemDto[]) || [];
|
return (itemsResponse.data.Items as BaseItemDto[]) || [];
|
||||||
}
|
}
|
||||||
@@ -178,7 +203,7 @@ export default function search() {
|
|||||||
.map((type) => encodeURIComponent(type))
|
.map((type) => encodeURIComponent(type))
|
||||||
.join("&includeItemTypes=")}`;
|
.join("&includeItemTypes=")}`;
|
||||||
|
|
||||||
const response1 = await axios.get(url);
|
const response1 = await axios.get(url, { signal });
|
||||||
|
|
||||||
const ids = response1.data.ids;
|
const ids = response1.data.ids;
|
||||||
|
|
||||||
@@ -186,13 +211,20 @@ export default function search() {
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
const response2 = await getItemsApi(api).getItems({
|
const response2 = await getItemsApi(api).getItems(
|
||||||
ids,
|
{
|
||||||
enableImageTypes: ["Primary", "Backdrop", "Thumb"],
|
ids,
|
||||||
});
|
enableImageTypes: ["Primary", "Backdrop", "Thumb"],
|
||||||
|
},
|
||||||
|
{ signal },
|
||||||
|
);
|
||||||
|
|
||||||
return (response2.data.Items as BaseItemDto[]) || [];
|
return (response2.data.Items as BaseItemDto[]) || [];
|
||||||
} catch (_error) {
|
} catch (error) {
|
||||||
|
// Silently handle aborted requests
|
||||||
|
if (error instanceof Error && error.name === "AbortError") {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -204,25 +236,34 @@ export default function search() {
|
|||||||
async ({
|
async ({
|
||||||
types,
|
types,
|
||||||
query,
|
query,
|
||||||
|
signal,
|
||||||
}: {
|
}: {
|
||||||
types: BaseItemKind[];
|
types: BaseItemKind[];
|
||||||
query: string;
|
query: string;
|
||||||
|
signal?: AbortSignal;
|
||||||
}): Promise<BaseItemDto[]> => {
|
}): Promise<BaseItemDto[]> => {
|
||||||
if (!api || !query) {
|
if (!api || !query) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const searchApi = await getItemsApi(api).getItems({
|
const searchApi = await getItemsApi(api).getItems(
|
||||||
searchTerm: query,
|
{
|
||||||
limit: 10,
|
searchTerm: query,
|
||||||
includeItemTypes: types,
|
limit: 10,
|
||||||
recursive: true,
|
includeItemTypes: types,
|
||||||
userId: user?.Id,
|
recursive: true,
|
||||||
});
|
userId: user?.Id,
|
||||||
|
},
|
||||||
|
{ signal },
|
||||||
|
);
|
||||||
|
|
||||||
return (searchApi.data.Items as BaseItemDto[]) || [];
|
return (searchApi.data.Items as BaseItemDto[]) || [];
|
||||||
} catch (_error) {
|
} catch (error) {
|
||||||
|
// Silently handle aborted requests
|
||||||
|
if (error instanceof Error && error.name === "AbortError") {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -275,6 +316,7 @@ export default function search() {
|
|||||||
searchFn({
|
searchFn({
|
||||||
query: debouncedSearch,
|
query: debouncedSearch,
|
||||||
types: ["Movie"],
|
types: ["Movie"],
|
||||||
|
signal: abortControllerRef.current?.signal,
|
||||||
}),
|
}),
|
||||||
enabled: searchType === "Library" && debouncedSearch.length > 0,
|
enabled: searchType === "Library" && debouncedSearch.length > 0,
|
||||||
});
|
});
|
||||||
@@ -285,6 +327,7 @@ export default function search() {
|
|||||||
searchFn({
|
searchFn({
|
||||||
query: debouncedSearch,
|
query: debouncedSearch,
|
||||||
types: ["Series"],
|
types: ["Series"],
|
||||||
|
signal: abortControllerRef.current?.signal,
|
||||||
}),
|
}),
|
||||||
enabled: searchType === "Library" && debouncedSearch.length > 0,
|
enabled: searchType === "Library" && debouncedSearch.length > 0,
|
||||||
});
|
});
|
||||||
@@ -295,6 +338,7 @@ export default function search() {
|
|||||||
searchFn({
|
searchFn({
|
||||||
query: debouncedSearch,
|
query: debouncedSearch,
|
||||||
types: ["Episode"],
|
types: ["Episode"],
|
||||||
|
signal: abortControllerRef.current?.signal,
|
||||||
}),
|
}),
|
||||||
enabled: searchType === "Library" && debouncedSearch.length > 0,
|
enabled: searchType === "Library" && debouncedSearch.length > 0,
|
||||||
});
|
});
|
||||||
@@ -305,6 +349,7 @@ export default function search() {
|
|||||||
searchFn({
|
searchFn({
|
||||||
query: debouncedSearch,
|
query: debouncedSearch,
|
||||||
types: ["BoxSet"],
|
types: ["BoxSet"],
|
||||||
|
signal: abortControllerRef.current?.signal,
|
||||||
}),
|
}),
|
||||||
enabled: searchType === "Library" && debouncedSearch.length > 0,
|
enabled: searchType === "Library" && debouncedSearch.length > 0,
|
||||||
});
|
});
|
||||||
@@ -315,6 +360,7 @@ export default function search() {
|
|||||||
searchFn({
|
searchFn({
|
||||||
query: debouncedSearch,
|
query: debouncedSearch,
|
||||||
types: ["Person"],
|
types: ["Person"],
|
||||||
|
signal: abortControllerRef.current?.signal,
|
||||||
}),
|
}),
|
||||||
enabled: searchType === "Library" && debouncedSearch.length > 0,
|
enabled: searchType === "Library" && debouncedSearch.length > 0,
|
||||||
});
|
});
|
||||||
@@ -326,6 +372,7 @@ export default function search() {
|
|||||||
jellyfinSearchFn({
|
jellyfinSearchFn({
|
||||||
query: debouncedSearch,
|
query: debouncedSearch,
|
||||||
types: ["MusicArtist"],
|
types: ["MusicArtist"],
|
||||||
|
signal: abortControllerRef.current?.signal,
|
||||||
}),
|
}),
|
||||||
enabled: searchType === "Library" && debouncedSearch.length > 0,
|
enabled: searchType === "Library" && debouncedSearch.length > 0,
|
||||||
});
|
});
|
||||||
@@ -336,6 +383,7 @@ export default function search() {
|
|||||||
jellyfinSearchFn({
|
jellyfinSearchFn({
|
||||||
query: debouncedSearch,
|
query: debouncedSearch,
|
||||||
types: ["MusicAlbum"],
|
types: ["MusicAlbum"],
|
||||||
|
signal: abortControllerRef.current?.signal,
|
||||||
}),
|
}),
|
||||||
enabled: searchType === "Library" && debouncedSearch.length > 0,
|
enabled: searchType === "Library" && debouncedSearch.length > 0,
|
||||||
});
|
});
|
||||||
@@ -346,6 +394,7 @@ export default function search() {
|
|||||||
jellyfinSearchFn({
|
jellyfinSearchFn({
|
||||||
query: debouncedSearch,
|
query: debouncedSearch,
|
||||||
types: ["Audio"],
|
types: ["Audio"],
|
||||||
|
signal: abortControllerRef.current?.signal,
|
||||||
}),
|
}),
|
||||||
enabled: searchType === "Library" && debouncedSearch.length > 0,
|
enabled: searchType === "Library" && debouncedSearch.length > 0,
|
||||||
});
|
});
|
||||||
@@ -356,6 +405,7 @@ export default function search() {
|
|||||||
jellyfinSearchFn({
|
jellyfinSearchFn({
|
||||||
query: debouncedSearch,
|
query: debouncedSearch,
|
||||||
types: ["Playlist"],
|
types: ["Playlist"],
|
||||||
|
signal: abortControllerRef.current?.signal,
|
||||||
}),
|
}),
|
||||||
enabled: searchType === "Library" && debouncedSearch.length > 0,
|
enabled: searchType === "Library" && debouncedSearch.length > 0,
|
||||||
});
|
});
|
||||||
|
|||||||
11
bun.lock
11
bun.lock
@@ -18,6 +18,7 @@
|
|||||||
"@react-navigation/native": "^7.0.14",
|
"@react-navigation/native": "^7.0.14",
|
||||||
"@shopify/flash-list": "2.0.2",
|
"@shopify/flash-list": "2.0.2",
|
||||||
"@tanstack/query-sync-storage-persister": "^5.90.18",
|
"@tanstack/query-sync-storage-persister": "^5.90.18",
|
||||||
|
"@tanstack/react-pacer": "^0.19.1",
|
||||||
"@tanstack/react-query": "5.90.12",
|
"@tanstack/react-query": "5.90.12",
|
||||||
"@tanstack/react-query-persist-client": "^5.90.18",
|
"@tanstack/react-query-persist-client": "^5.90.18",
|
||||||
"axios": "^1.7.9",
|
"axios": "^1.7.9",
|
||||||
@@ -589,16 +590,26 @@
|
|||||||
|
|
||||||
"@sinonjs/fake-timers": ["@sinonjs/fake-timers@10.3.0", "", { "dependencies": { "@sinonjs/commons": "^3.0.0" } }, "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA=="],
|
"@sinonjs/fake-timers": ["@sinonjs/fake-timers@10.3.0", "", { "dependencies": { "@sinonjs/commons": "^3.0.0" } }, "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA=="],
|
||||||
|
|
||||||
|
"@tanstack/devtools-event-client": ["@tanstack/devtools-event-client@0.4.0", "", {}, "sha512-RPfGuk2bDZgcu9bAJodvO2lnZeHuz4/71HjZ0bGb/SPg8+lyTA+RLSKQvo7fSmPSi8/vcH3aKQ8EM9ywf1olaw=="],
|
||||||
|
|
||||||
|
"@tanstack/pacer": ["@tanstack/pacer@0.17.1", "", { "dependencies": { "@tanstack/devtools-event-client": "^0.4.0", "@tanstack/store": "^0.8.0" } }, "sha512-52GytGu07L73lNCWB1N02NWBp/tzK2jZ20U8sFInXyiq2KHtHxbXaN1Qw/MR1REqFIKgEy5DOBNZRjuSy5zaRg=="],
|
||||||
|
|
||||||
"@tanstack/query-core": ["@tanstack/query-core@5.90.16", "", {}, "sha512-MvtWckSVufs/ja463/K4PyJeqT+HMlJWtw6PrCpywznd2NSgO3m4KwO9RqbFqGg6iDE8vVMFWMeQI4Io3eEYww=="],
|
"@tanstack/query-core": ["@tanstack/query-core@5.90.16", "", {}, "sha512-MvtWckSVufs/ja463/K4PyJeqT+HMlJWtw6PrCpywznd2NSgO3m4KwO9RqbFqGg6iDE8vVMFWMeQI4Io3eEYww=="],
|
||||||
|
|
||||||
"@tanstack/query-persist-client-core": ["@tanstack/query-persist-client-core@5.91.15", "", { "dependencies": { "@tanstack/query-core": "5.90.16" } }, "sha512-vnPSfQVo41EKJN8v20nkhWNZPyB1dMJIy5icOvCGzcCJzsmRefYY1owtr63ICOcjOiPPTuNEfPsdjdBhkzYnmA=="],
|
"@tanstack/query-persist-client-core": ["@tanstack/query-persist-client-core@5.91.15", "", { "dependencies": { "@tanstack/query-core": "5.90.16" } }, "sha512-vnPSfQVo41EKJN8v20nkhWNZPyB1dMJIy5icOvCGzcCJzsmRefYY1owtr63ICOcjOiPPTuNEfPsdjdBhkzYnmA=="],
|
||||||
|
|
||||||
"@tanstack/query-sync-storage-persister": ["@tanstack/query-sync-storage-persister@5.90.18", "", { "dependencies": { "@tanstack/query-core": "5.90.16", "@tanstack/query-persist-client-core": "5.91.15" } }, "sha512-tKngFopz/TuAe7LBDg7IOhWPh9blxdQ6QG/vVL2dFzRmlPNcSo4WdCSONqSDioJkcyTwh1YCSlcikmJ1WnSb3Q=="],
|
"@tanstack/query-sync-storage-persister": ["@tanstack/query-sync-storage-persister@5.90.18", "", { "dependencies": { "@tanstack/query-core": "5.90.16", "@tanstack/query-persist-client-core": "5.91.15" } }, "sha512-tKngFopz/TuAe7LBDg7IOhWPh9blxdQ6QG/vVL2dFzRmlPNcSo4WdCSONqSDioJkcyTwh1YCSlcikmJ1WnSb3Q=="],
|
||||||
|
|
||||||
|
"@tanstack/react-pacer": ["@tanstack/react-pacer@0.19.1", "", { "dependencies": { "@tanstack/pacer": "0.17.1", "@tanstack/react-store": "^0.8.0" }, "peerDependencies": { "react": ">=16.8", "react-dom": ">=16.8" } }, "sha512-wfGwKLo2gosKr5tsXico+jWJ8LsWsBC8MA1HVtUY/D6dhFduEVizKxRUcvP60I3dRvnoXDbN202g4feJHlivnA=="],
|
||||||
|
|
||||||
"@tanstack/react-query": ["@tanstack/react-query@5.90.12", "", { "dependencies": { "@tanstack/query-core": "5.90.12" }, "peerDependencies": { "react": "^18 || ^19" } }, "sha512-graRZspg7EoEaw0a8faiUASCyJrqjKPdqJ9EwuDRUF9mEYJ1YPczI9H+/agJ0mOJkPCJDk0lsz5QTrLZ/jQ2rg=="],
|
"@tanstack/react-query": ["@tanstack/react-query@5.90.12", "", { "dependencies": { "@tanstack/query-core": "5.90.12" }, "peerDependencies": { "react": "^18 || ^19" } }, "sha512-graRZspg7EoEaw0a8faiUASCyJrqjKPdqJ9EwuDRUF9mEYJ1YPczI9H+/agJ0mOJkPCJDk0lsz5QTrLZ/jQ2rg=="],
|
||||||
|
|
||||||
"@tanstack/react-query-persist-client": ["@tanstack/react-query-persist-client@5.90.18", "", { "dependencies": { "@tanstack/query-persist-client-core": "5.91.15" }, "peerDependencies": { "@tanstack/react-query": "^5.90.16", "react": "^18 || ^19" } }, "sha512-ToVRTVpjzTrd9S/p7JIvGdLs+Xtz9aDMM/7+TQGSV9notY8Jt64irfAAAkZ05syftLKS+3KPgyKAnHcVeKVbWQ=="],
|
"@tanstack/react-query-persist-client": ["@tanstack/react-query-persist-client@5.90.18", "", { "dependencies": { "@tanstack/query-persist-client-core": "5.91.15" }, "peerDependencies": { "@tanstack/react-query": "^5.90.16", "react": "^18 || ^19" } }, "sha512-ToVRTVpjzTrd9S/p7JIvGdLs+Xtz9aDMM/7+TQGSV9notY8Jt64irfAAAkZ05syftLKS+3KPgyKAnHcVeKVbWQ=="],
|
||||||
|
|
||||||
|
"@tanstack/react-store": ["@tanstack/react-store@0.8.0", "", { "dependencies": { "@tanstack/store": "0.8.0", "use-sync-external-store": "^1.6.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-1vG9beLIuB7q69skxK9r5xiLN3ztzIPfSQSs0GfeqWGO2tGIyInZx0x1COhpx97RKaONSoAb8C3dxacWksm1ow=="],
|
||||||
|
|
||||||
|
"@tanstack/store": ["@tanstack/store@0.8.0", "", {}, "sha512-Om+BO0YfMZe//X2z0uLF2j+75nQga6TpTJgLJQBiq85aOyZNIhkCgleNcud2KQg4k4v9Y9l+Uhru3qWMPGTOzQ=="],
|
||||||
|
|
||||||
"@tokenizer/token": ["@tokenizer/token@0.3.0", "", {}, "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A=="],
|
"@tokenizer/token": ["@tokenizer/token@0.3.0", "", {}, "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A=="],
|
||||||
|
|
||||||
"@types/babel__core": ["@types/babel__core@7.20.5", "", { "dependencies": { "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7", "@types/babel__generator": "*", "@types/babel__template": "*", "@types/babel__traverse": "*" } }, "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA=="],
|
"@types/babel__core": ["@types/babel__core@7.20.5", "", { "dependencies": { "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7", "@types/babel__generator": "*", "@types/babel__template": "*", "@types/babel__traverse": "*" } }, "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA=="],
|
||||||
|
|||||||
@@ -37,6 +37,7 @@
|
|||||||
"@react-navigation/native": "^7.0.14",
|
"@react-navigation/native": "^7.0.14",
|
||||||
"@shopify/flash-list": "2.0.2",
|
"@shopify/flash-list": "2.0.2",
|
||||||
"@tanstack/query-sync-storage-persister": "^5.90.18",
|
"@tanstack/query-sync-storage-persister": "^5.90.18",
|
||||||
|
"@tanstack/react-pacer": "^0.19.1",
|
||||||
"@tanstack/react-query": "5.90.12",
|
"@tanstack/react-query": "5.90.12",
|
||||||
"@tanstack/react-query-persist-client": "^5.90.18",
|
"@tanstack/react-query-persist-client": "^5.90.18",
|
||||||
"axios": "^1.7.9",
|
"axios": "^1.7.9",
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ export const createStreamystatsApi = (config: StreamystatsApiConfig) => {
|
|||||||
|
|
||||||
const search = async (
|
const search = async (
|
||||||
params: StreamystatsSearchParams,
|
params: StreamystatsSearchParams,
|
||||||
|
signal?: AbortSignal,
|
||||||
): Promise<
|
): Promise<
|
||||||
StreamystatsSearchIdsResponse | StreamystatsSearchFullResponse
|
StreamystatsSearchIdsResponse | StreamystatsSearchFullResponse
|
||||||
> => {
|
> => {
|
||||||
@@ -55,7 +56,7 @@ export const createStreamystatsApi = (config: StreamystatsApiConfig) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const url = `${baseUrl}/api/search?${queryParams.toString()}`;
|
const url = `${baseUrl}/api/search?${queryParams.toString()}`;
|
||||||
const response = await axios.get(url, { headers });
|
const response = await axios.get(url, { headers, signal });
|
||||||
|
|
||||||
return response.data;
|
return response.data;
|
||||||
};
|
};
|
||||||
@@ -64,13 +65,17 @@ export const createStreamystatsApi = (config: StreamystatsApiConfig) => {
|
|||||||
query: string,
|
query: string,
|
||||||
type?: StreamystatsSearchParams["type"],
|
type?: StreamystatsSearchParams["type"],
|
||||||
limit?: number,
|
limit?: number,
|
||||||
|
signal?: AbortSignal,
|
||||||
): Promise<StreamystatsSearchIdsResponse> => {
|
): Promise<StreamystatsSearchIdsResponse> => {
|
||||||
return search({
|
return search(
|
||||||
q: query,
|
{
|
||||||
format: "ids",
|
q: query,
|
||||||
type,
|
format: "ids",
|
||||||
limit,
|
type,
|
||||||
}) as Promise<StreamystatsSearchIdsResponse>;
|
limit,
|
||||||
|
},
|
||||||
|
signal,
|
||||||
|
) as Promise<StreamystatsSearchIdsResponse>;
|
||||||
};
|
};
|
||||||
|
|
||||||
const searchFull = async (
|
const searchFull = async (
|
||||||
|
|||||||
Reference in New Issue
Block a user