@@ -8,93 +8,105 @@ import { routesInfo } from './common';
88import { APIError , clientSideErrorHandler , useClientSideFetcher } from '@/utils/fetcher' ;
99import { exponentialBackOff , retryWrapper } from '@/utils/util' ;
1010
11- function make < Options extends MakeOptions & { path : GettableRoutes } > ( { path , queryKey , params , query } : Options ) {
11+ function buildPath ( path : string , params ?: Record < string , string > , query ?: Record < string , any > ) {
1212 const substitutedParams = params
1313 ? ( Object . entries ( params ) as [ string , string ] [ ] ) . reduce < string > (
1414 ( acc , [ key , value ] ) => acc . replace ( `:${ key } ` , encodeURIComponent ( value ) ) ,
1515 path ,
1616 )
1717 : path ;
18- const finalPath = query ? `${ substitutedParams } ?${ new URLSearchParams ( query as any ) . toString ( ) } ` : substitutedParams ;
1918
20- function useQueryIt ( ) {
21- // TODO: Investigate wether this is a react compiler bug or not
22- // eslint-disable-next-line react-compiler/react-compiler
23- 'use no memo' ;
19+ return (
20+ query ? `${ substitutedParams } ?${ new URLSearchParams ( query as any ) . toString ( ) } ` : substitutedParams
21+ ) as `/${string } `;
22+ }
23+
24+ function useQueryIt < Options extends MakeOptions & { path : GettableRoutes } > (
25+ { path : initialPath , queryKey, params, query } : Options ,
26+ doForceFresh = false ,
27+ ) {
28+ const path = buildPath ( initialPath , params , query ) ;
29+ const fetcher = useClientSideFetcher ( { path, method : 'GET' } ) ;
30+ const queryClient = useQueryClient ( ) ;
2431
25- const fetcher = useClientSideFetcher ( { path : finalPath as `/${string } `, method : 'GET' } ) ;
26- return useQuery ( {
27- queryKey,
32+ const { data, isLoading, error, refetch } = useQuery ( {
33+ // Dirty method to make sure other queries that wanna pass in force_fresh don't overwrite the others'
34+ // queryFn (effectively causing everything to always pass it in HTTP)
35+ queryKey : doForceFresh ? [ ...queryKey , 'force_fresh' ] : queryKey ,
36+ queryFn : async ( ) => {
2837 // @ts -expect-error - This won't ever compile
29- queryFn : async ( ) => fetcher ( ) as Promise < InferAPIRouteResult < Options [ 'path' ] , 'GET' > | null > ,
30- throwOnError : clientSideErrorHandler ( { throwOverride : false } ) ,
31- refetchOnWindowFocus : false ,
32- retry : retryWrapper ( ( retries , error ) => {
33- if ( error instanceof APIError ) {
34- return retries < 5 && error . payload . statusCode !== 401 ;
35- }
38+ const data = ( await fetcher ( ) ) as Promise < InferAPIRouteResult < Options [ 'path' ] , 'GET' > | null > ;
39+ if ( doForceFresh ) {
40+ queryClient . setQueryData ( queryKey , data ) ;
41+ }
42+
43+ return data ;
44+ } ,
45+ throwOnError : clientSideErrorHandler ( { throwOverride : false } ) ,
46+ refetchOnWindowFocus : false ,
47+ retry : retryWrapper ( ( retries , error ) => {
48+ if ( error instanceof APIError ) {
49+ return retries < 5 && error . payload . statusCode !== 401 ;
50+ }
3651
37- return retries < 3 ;
38- } ) ,
39- retryDelay : exponentialBackOff ,
40- } ) ;
41- }
52+ return retries < 3 ;
53+ } ) ,
54+ // Prevents double requests when a refresh button of sorts exists that passes doForceFresh
55+ enabled : ! doForceFresh ,
56+ retryDelay : exponentialBackOff ,
57+ } ) ;
4258
43- return useQueryIt ;
59+ return { data , isLoading , error , refetch } ;
4460}
4561
46- function makeMutation < Options extends MakeOptions , Method extends 'DELETE' | 'PATCH' | 'POST' | 'PUT' > (
47- { path } : Options ,
62+ function useMutateIt < Options extends MakeOptions , Method extends 'DELETE' | 'PATCH' | 'POST' | 'PUT' > (
63+ { path : initialPath , params } : Options ,
4864 method : Method ,
4965 onSuccess ?: (
5066 queryClient : QueryClient ,
5167 // @ts -expect-error - We can't get it to compile on the Method
5268 data : InferAPIRouteResult < Options [ 'path' ] , Method > ,
5369 ) => Promise < unknown > ,
5470) {
55- function useMutateIt ( ) {
56- // TODO: Investigate wether this is a react compiler bug or not
57- // eslint-disable-next-line react-compiler/react-compiler
58- 'use no memo' ;
71+ const queryClient = useQueryClient ( ) ;
72+ const path = buildPath ( initialPath , params ) ;
73+ const fetcher = useClientSideFetcher ( { path, method } ) ;
5974
60- const queryClient = useQueryClient ( ) ;
61- const fetcher = useClientSideFetcher ( { path, method } ) ;
62-
63- return useMutation <
64- // @ts -expect-error - We can't get it to compile on the Method
65- InferAPIRouteResult < Options [ 'path' ] , Method > ,
66- APIError ,
67- // @ts -expect-error - We can't get it to compile on the Method
68- Path < Options [ 'path' ] , Method >
69- > ( {
70- mutationFn : fetcher ,
71- onSuccess : async ( data ) => onSuccess ?.( queryClient , data ) ,
72- } ) ;
73- }
74-
75- return useMutateIt ;
75+ return useMutation <
76+ // @ts -expect-error - We can't get it to compile on the Method
77+ InferAPIRouteResult < Options [ 'path' ] , Method > ,
78+ APIError ,
79+ // @ts -expect-error - We can't get it to compile on the Method
80+ Path < Options [ 'path' ] , Method >
81+ > ( {
82+ mutationFn : fetcher ,
83+ onSuccess : async ( data ) => onSuccess ?.( queryClient , data ) ,
84+ } ) ;
7685}
7786
7887export const client = {
7988 auth : {
80- useMe : ( query ?: GetAuthMeQuery ) => make ( routesInfo . auth . me ( query ?? { force_fresh : 'false' } ) ) ( ) ,
81- useLogout : makeMutation ( routesInfo . auth . logout , 'POST' , async ( queryClient ) => queryClient . invalidateQueries ( ) ) ,
89+ useMe : ( query ?: GetAuthMeQuery ) =>
90+ useQueryIt ( routesInfo . auth . me ( query ?? { force_fresh : 'false' } ) , query ?. force_fresh === 'true' ) ,
91+ useLogout : ( ) =>
92+ useMutateIt ( routesInfo . auth . logout , 'POST' , async ( queryClient ) => queryClient . invalidateQueries ( ) ) ,
8293 } ,
8394
8495 guilds : {
85- useInfo : ( guildId : string , query : GetGuildQuery ) => make ( routesInfo . guilds ( guildId ) . info ( query ) ) ( ) ,
96+ useInfo : ( guildId : string , query : GetGuildQuery ) =>
97+ useQueryIt ( routesInfo . guilds ( guildId ) . info ( query ) , query ?. force_fresh === 'true' ) ,
8698
8799 ama : {
88- createAMA : ( guildId : string ) =>
89- makeMutation ( routesInfo . guilds ( guildId ) . ama . amas ( ) , 'POST' , async ( queryClient ) => {
100+ useCreateAMA : ( guildId : string ) =>
101+ useMutateIt ( routesInfo . guilds ( guildId ) . ama . amas ( ) , 'POST' , async ( queryClient ) => {
90102 await queryClient . invalidateQueries ( {
91103 queryKey : [
92104 routesInfo . guilds ( guildId ) . ama . amas ( { include_ended : 'false' } ) . queryKey ,
93105 routesInfo . guilds ( guildId ) . ama . amas ( { include_ended : 'true' } ) . queryKey ,
94106 ] ,
95107 } ) ;
96- } ) ( ) ,
97- useAMAs : ( guildId : string , query : GetAMAsQuery ) => make ( routesInfo . guilds ( guildId ) . ama . amas ( query ) ) ( ) ,
108+ } ) ,
109+ useAMAs : ( guildId : string , query : GetAMAsQuery ) => useQueryIt ( routesInfo . guilds ( guildId ) . ama . amas ( query ) ) ,
98110 } ,
99111 } ,
100112} as const ;
0 commit comments