1/**
2 * In-memory test harness for RPC groups.
3 *
4 * `RpcTest` connects a generated client directly to `RpcServer` handlers for
5 * the same `RpcGroup`. It uses the no-serialization path, so requests,
6 * responses, stream chunks, acknowledgements, interrupts, headers, and
7 * middleware metadata travel through the normal client/server machinery without
8 * opening HTTP, socket, worker, or serializer infrastructure.
9 *
10 * @stability unstable
11 * @since 4.0.0
12 */
13import * as Effect from "../Effect.ts"
14import type * as Scope from "../Scope.ts"
15import type * as Rpc from "./Rpc.ts"
16import * as RpcClient from "./RpcClient.ts"
17import type * as RpcGroup from "./RpcGroup.ts"
18import * as RpcServer from "./RpcServer.ts"
19
20/**
21 * Creates an in-memory RPC client for a group, backed by the group's handlers
22 * from the environment and using the no-serialization test transport.
23 *
24 * @stability unstable
25 * @category constructors
26 * @since 4.0.0
27 */
28export const makeClient: <Rpcs extends Rpc.Any, const Flatten extends boolean = false>(
29 group: RpcGroup.RpcGroup<Rpcs>,
30 options?: {
31 readonly flatten?: Flatten | undefined
32 }
33) => Effect.Effect<
34 Flatten extends true ? RpcClient.RpcClient.Flat<Rpcs> : RpcClient.RpcClient<Rpcs>,
35 never,
36 Scope.Scope | Rpc.ToHandler<Rpcs> | Rpc.Middleware<Rpcs> | Rpc.MiddlewareClient<Rpcs>
37> = Effect.fnUntraced(function*<Rpcs extends Rpc.Any, const Flatten extends boolean = false>(
38 group: RpcGroup.RpcGroup<Rpcs>,
39 options?: {
40 readonly flatten?: Flatten | undefined
41 }
42) {
43 // oxlint-disable-next-line prefer-const
44 let client!: Effect.Success<ReturnType<typeof RpcClient.makeNoSerialization<Rpcs, never, Flatten>>>
45 const server = yield* RpcServer.makeNoSerialization(group, {
46 onFromServer(response) {
47 return client.write(response)
48 }
49 })
50 client = yield* RpcClient.makeNoSerialization(group, {
51 supportsAck: true,
52 flatten: options?.flatten,
53 onFromClient({ message }) {
54 return server.write(0, message)
55 }
56 })
57 return client.client
58})