go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/milo/ui/src/common/hooks/legacy_prpc_query/use_prpc_queries.ts (about) 1 // Copyright 2023 The LUCI Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 import { UseQueryOptions, useQueries } from '@tanstack/react-query'; 16 17 import { 18 useAuthState, 19 useGetAccessToken, 20 } from '@/common/components/auth_state_provider'; 21 import { PrpcClientExt } from '@/generic_libs/tools/prpc_client_ext'; 22 23 import { 24 PrpcQueryBaseOptions, 25 PrpcMethod, 26 genPrpcQueryKey, 27 PrpcServiceMethodKeys, 28 PrpcMethodResponse, 29 PrpcMethodRequest, 30 } from './common'; 31 32 export interface UsePrpcQueriesOptions<S, MK, Req, Res, TError, TData> 33 extends Omit<PrpcQueryBaseOptions<S, MK, Req>, 'request'> { 34 readonly requests: readonly Req[]; 35 readonly options?: Omit< 36 UseQueryOptions<Res, TError, TData, readonly unknown[]>, 37 'queryKey' | 'queryFn' | 'context' 38 >; 39 readonly context?: UseQueryOptions['context']; 40 } 41 42 /** 43 * @deprecated use `usePrpcQueries` from `@common/hooks/prpc_query` instead. 44 * 45 * Call a pRPC method via `@tanstack/react-query`. 46 * 47 * This hook 48 * * reduces boilerplate, and 49 * * ensures the `queryKey` is populated correctly. 50 */ 51 export function usePrpcQueries< 52 S extends object, 53 MK extends PrpcServiceMethodKeys<S>, 54 TError = unknown, 55 TData = PrpcMethodResponse<S[MK]>, 56 >( 57 opts: UsePrpcQueriesOptions< 58 S, 59 MK, 60 PrpcMethodRequest<S[MK]>, 61 PrpcMethodResponse<S[MK]>, 62 TError, 63 TData 64 >, 65 ) { 66 const { host, insecure, Service, method, requests, options, context } = opts; 67 68 const { identity } = useAuthState(); 69 const getAccessToken = useGetAccessToken(); 70 const service = new Service( 71 new PrpcClientExt({ host, insecure }, getAccessToken), 72 ); 73 const m = 74 // `method` is constrained to be a key that has an associated property of 75 // type `PrpcMethod` in a `Service`. Therefore `service[method]` is 76 // guaranteed to be a `PrpcMethod`. TSC isn't smart enough to know that, 77 // so we need to use type casting. 78 ( 79 service[method] as PrpcMethod< 80 PrpcMethodRequest<S[MK]>, 81 PrpcMethodResponse<S[MK]> 82 > 83 ).bind(service); 84 85 type Query = Omit< 86 UseQueryOptions< 87 PrpcMethodResponse<S[MK]>, 88 TError, 89 TData, 90 ReadonlyArray<unknown> 91 >, 92 'context' 93 >; 94 95 return useQueries({ 96 queries: requests.map<Query>((request) => ({ 97 queryKey: genPrpcQueryKey(identity, { 98 host, 99 insecure, 100 Service, 101 method, 102 request, 103 }), 104 queryFn: async () => { 105 return await m( 106 request, 107 // Let react-query handle caching. 108 { 109 acceptCache: false, 110 skipUpdate: true, 111 }, 112 ); 113 }, 114 ...options, 115 })), 116 context, 117 }); 118 }