go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/milo/ui/src/common/hooks/legacy_prpc_query/use_prpc_query.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 {
    16    UseQueryOptions,
    17    UseQueryResult,
    18    useQuery,
    19  } from '@tanstack/react-query';
    20  
    21  import {
    22    useAuthState,
    23    useGetAccessToken,
    24  } from '@/common/components/auth_state_provider';
    25  import { PrpcClientExt } from '@/generic_libs/tools/prpc_client_ext';
    26  
    27  import {
    28    PrpcMethod,
    29    PrpcMethodRequest,
    30    PrpcMethodResponse,
    31    PrpcQueryBaseOptions,
    32    PrpcServiceMethodKeys,
    33    genPrpcQueryKey,
    34  } from './common';
    35  
    36  export interface UsePrpcQueryOptions<S, MK, Req, Res, TError, TData>
    37    extends PrpcQueryBaseOptions<S, MK, Req> {
    38    /**
    39     * options will be passed to `useQuery` from `@tanstack/react-query`.
    40     */
    41    readonly options?: Omit<
    42      UseQueryOptions<
    43        Res,
    44        TError,
    45        TData,
    46        readonly [string, string, string, MK, Req]
    47      >,
    48      'queryKey' | 'queryFn'
    49    >;
    50  }
    51  
    52  /**
    53   * @deprecated use `usePrpcQuery` from `@common/hooks/prpc_query` instead.
    54   *
    55   * Call a pRPC method via `@tanstack/react-query`.
    56   *
    57   * This hook
    58   *  * reduces boilerplate, and
    59   *  * ensures the `queryKey` is populated correctly.
    60   */
    61  export function usePrpcQuery<
    62    S extends object,
    63    MK extends PrpcServiceMethodKeys<S>,
    64    TError = unknown,
    65    TData = PrpcMethodResponse<S[MK]>,
    66  >(
    67    opts: UsePrpcQueryOptions<
    68      S,
    69      MK,
    70      PrpcMethodRequest<S[MK]>,
    71      PrpcMethodResponse<S[MK]>,
    72      TError,
    73      TData
    74    >,
    75  ): UseQueryResult<TData, TError> {
    76    const { host, insecure, Service, method, request, options } = opts;
    77  
    78    const { identity } = useAuthState();
    79    const getAccessToken = useGetAccessToken();
    80    const queryKey = genPrpcQueryKey(identity, opts);
    81    return useQuery({
    82      queryKey,
    83      queryFn: async () => {
    84        const service = new Service(
    85          new PrpcClientExt({ host, insecure }, getAccessToken),
    86        );
    87        // `method` is constrained to be a key that has an associated property of
    88        // type `PrpcMethod` in a `Service`. Therefore `service[method]` is
    89        // guaranteed to be a `PrpcMethod`. TSC isn't smart enough to know that,
    90        // so we need to use type casting.
    91        return await (
    92          service[method] as PrpcMethod<
    93            PrpcMethodRequest<S[MK]>,
    94            PrpcMethodResponse<S[MK]>
    95          >
    96        )(
    97          request,
    98          // Let react-query handle caching.
    99          {
   100            acceptCache: false,
   101            skipUpdate: true,
   102          },
   103        );
   104      },
   105      ...options,
   106    });
   107  }