Skip to content

Commit 7d20738

Browse files
committed
feat: react-query-utils
1 parent 3b0900c commit 7d20738

File tree

2 files changed

+50
-16
lines changed

2 files changed

+50
-16
lines changed

src/hooks/useSse.ts

+6-16
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import { useEffect } from "react";
22
import { useLocation } from "react-router-dom";
3-
import { Query, useQueryClient } from "@tanstack/react-query";
4-
import { OpenApiTsReactQueryKey } from "@/types/openapi-ts";
3+
import { useQueryClient } from "@tanstack/react-query";
54
import {
65
v1GetWorkspaceAlertsQueryKey,
76
v1GetWorkspaceMessagesQueryKey,
87
} from "@/api/generated/@tanstack/react-query.gen";
8+
import { invalidateQueries } from "@/lib/react-query-utils";
99

1010
const BASE_URL = import.meta.env.VITE_BASE_API_URL;
1111

@@ -20,20 +20,10 @@ export function useSse() {
2020

2121
eventSource.onmessage = function (event) {
2222
if (event.data.toLowerCase().includes("new alert detected")) {
23-
queryClient.invalidateQueries({
24-
refetchType: "all",
25-
predicate: (
26-
query: Query<unknown, Error, unknown, OpenApiTsReactQueryKey>,
27-
) =>
28-
query.queryKey[0]._id ===
29-
v1GetWorkspaceAlertsQueryKey({
30-
path: { workspace_name: "default" }, // NOTE: Just supplying "default" to satisfy the type-checker, because we are just using the `_id`, this invalidates for any workspace
31-
})[0]?._id ||
32-
query.queryKey[0]._id ===
33-
v1GetWorkspaceMessagesQueryKey({
34-
path: { workspace_name: "default" }, // NOTE: Just supplying "default" to satisfy the type-checker, because we are just using the `_id`, this invalidates for any workspace
35-
})[0]?._id,
36-
});
23+
invalidateQueries(queryClient, [
24+
v1GetWorkspaceAlertsQueryKey,
25+
v1GetWorkspaceMessagesQueryKey,
26+
]);
3727
}
3828
};
3929

src/lib/react-query-utils.ts

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import { OpenApiTsReactQueryKey } from "@/types/openapi-ts";
2+
import { OptionsLegacyParser } from "@hey-api/client-fetch";
3+
import { Query, QueryClient } from "@tanstack/react-query";
4+
5+
// NOTE: This is copy/pasted from @/api/generated/@tanstack/react-query.gen
6+
type QueryKey<TOptions extends OptionsLegacyParser = OptionsLegacyParser> = [
7+
Pick<TOptions, "baseUrl" | "body" | "headers" | "path" | "query"> & {
8+
_id: string;
9+
_infinite?: boolean;
10+
},
11+
];
12+
13+
// A generic type that describes the possible permutations of openapi-ts
14+
// react-query queryKey functions. The use of `any` is required to make it
15+
// generic enough for use with any openapi-ts queryKey fn. The return type
16+
// constraint is sufficiently strict that it is still safe to use.
17+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
18+
type QueryKeyFn = (options: any) => QueryKey[0][];
19+
20+
// NOTE: The type constraints on `queryKeyFn` are sufficiently strict that we
21+
// can use type assertion for the return type with relative safety.
22+
const getQueryKeyFnId = <T extends OptionsLegacyParser>(
23+
queryKeyFn: QueryKeyFn,
24+
) => queryKeyFn({} as T)[0]?._id as string;
25+
26+
/**
27+
* Takes a queryClient, and an array of queryKeyFns, and invalidates all queries
28+
* in the cache with matching query keys.
29+
*/
30+
export function invalidateQueries(
31+
queryClient: QueryClient,
32+
queryKeyFns: QueryKeyFn[],
33+
) {
34+
return queryClient.invalidateQueries({
35+
refetchType: "all",
36+
predicate: (
37+
query: Query<unknown, Error, unknown, OpenApiTsReactQueryKey>,
38+
) => {
39+
return queryKeyFns.some(
40+
(fn) => query.queryKey[0]._id === getQueryKeyFnId(fn),
41+
);
42+
},
43+
});
44+
}

0 commit comments

Comments
 (0)