go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/milo/ui/src/common/hooks/legacy_prpc_query/common.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 { CacheOption } from '@/generic_libs/tools/cached_fn';
    16  import { PrpcClientExt } from '@/generic_libs/tools/prpc_client_ext';
    17  
    18  export type PrpcMethod<Req, Ret> = (
    19    req: Req,
    20    opt?: CacheOption,
    21  ) => Promise<Ret>;
    22  
    23  export type PrpcMethodRequest<T> = T extends PrpcMethod<infer Req, infer _Res>
    24    ? Req
    25    : never;
    26  
    27  export type PrpcMethodResponse<T> = T extends PrpcMethod<infer _Req, infer Res>
    28    ? Res
    29    : never;
    30  
    31  export type PrpcServiceMethodKeys<S> = keyof {
    32    // The request type has to be `any` because the argument type must be contra-
    33    // variant when sub-typing a function.
    34    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    35    [MK in keyof S as S[MK] extends PrpcMethod<any, object> ? MK : never]: S[MK];
    36  };
    37  
    38  export interface PrpcQueryBaseOptions<S, MK, Req> {
    39    readonly host: string;
    40    readonly insecure?: boolean;
    41    readonly Service: Constructor<S, [PrpcClientExt]> & { SERVICE: string };
    42    readonly method: MK;
    43    readonly request: Req;
    44  }
    45  
    46  /**
    47   * Generate a key to match a pRPC query call.
    48   *
    49   * Note that this function is not a hook and can be used in non-React
    50   * environment.
    51   */
    52  export function genPrpcQueryKey<S, MK, Req>(
    53    identity: string,
    54    opts: PrpcQueryBaseOptions<S, MK, Req>,
    55  ) {
    56    const { host, Service, method, request } = opts;
    57  
    58    return [
    59      // The query response is tied to the user identity (ACL). The user
    60      // identity may change after a auth state refresh after user logs in/out
    61      // in another browser tab.
    62      identity,
    63      // Some pRPC services may get hosted on multiple hosts (e.g. swarming).
    64      // Ensure the query to one host is not reused by query to another host.
    65      host,
    66      // Ensure methods sharing the same name from different services won't
    67      // cause collision.
    68      Service.SERVICE,
    69      // Obviously query to one method shall not be reused by query to another
    70      // method.
    71      method,
    72      // Include the whole request so whenever the request is changed, a new
    73      // RPC call is triggered.
    74      request,
    75    ] as const;
    76  }