From 0c58b32dcfbed9bb5db78e9c08f6a557ec2f640b Mon Sep 17 00:00:00 2001 From: Tim Date: Thu, 22 Feb 2024 07:38:37 +0100 Subject: [PATCH] add convenience client constructors to /rpc-http (#2198) --- .changeset/red-lobsters-call.md | 6 ++++ packages/rpc-http/src/HttpResolver.ts | 51 ++++++++++++++++++++++++++- packages/rpc/src/Resolver.ts | 20 ++++++++--- 3 files changed, 71 insertions(+), 6 deletions(-) create mode 100644 .changeset/red-lobsters-call.md diff --git a/.changeset/red-lobsters-call.md b/.changeset/red-lobsters-call.md new file mode 100644 index 00000000000..4f61ea0b72f --- /dev/null +++ b/.changeset/red-lobsters-call.md @@ -0,0 +1,6 @@ +--- +"@effect/rpc-http": patch +"@effect/rpc": patch +--- + +add convenience client constructors to /rpc-http diff --git a/packages/rpc-http/src/HttpResolver.ts b/packages/rpc-http/src/HttpResolver.ts index a77c9d85c53..135f1ad0db3 100644 --- a/packages/rpc-http/src/HttpResolver.ts +++ b/packages/rpc-http/src/HttpResolver.ts @@ -2,7 +2,7 @@ * @since 1.0.0 */ import * as Body from "@effect/platform/Http/Body" -import type * as Client from "@effect/platform/Http/Client" +import * as Client from "@effect/platform/Http/Client" import * as ClientRequest from "@effect/platform/Http/ClientRequest" import * as Resolver from "@effect/rpc/Resolver" import type * as Router from "@effect/rpc/Router" @@ -11,6 +11,7 @@ import type * as Serializable from "@effect/schema/Serializable" import * as Chunk from "effect/Chunk" import * as Effect from "effect/Effect" import type * as RequestResolver from "effect/RequestResolver" +import * as Schedule from "effect/Schedule" import * as Stream from "effect/Stream" /** @@ -57,3 +58,51 @@ export const makeEffect = >( Effect.scoped ) )() + +/** + * @category constructors + * @since 1.0.0 + */ +export const makeClient = >( + baseUrl: string +): Serializable.SerializableWithResult.Context> extends never ? + "HttpResolver.makeClient: request context is not `never`" + : Resolver.Client< + RequestResolver.RequestResolver< + Rpc.Request> + > + > => + Resolver.toClient(make( + Client.fetchOk().pipe( + Client.mapRequest(ClientRequest.prependUrl(baseUrl)), + Client.retry( + Schedule.exponential(50).pipe( + Schedule.intersect(Schedule.recurs(5)) + ) + ) + ) + ) as any) as any + +/** + * @category constructors + * @since 1.0.0 + */ +export const makeClientEffect = >( + baseUrl: string +): Serializable.SerializableWithResult.Context> extends never ? + "HttpResolver.makeClientEffect: request context is not `never`" + : Resolver.Client< + RequestResolver.RequestResolver< + Rpc.Request> + > + > => + Resolver.toClient(makeEffect( + Client.fetchOk().pipe( + Client.mapRequest(ClientRequest.prependUrl(baseUrl)), + Client.retry( + Schedule.exponential(50).pipe( + Schedule.intersect(Schedule.recurs(5)) + ) + ) + ) + ) as any) as any diff --git a/packages/rpc/src/Resolver.ts b/packages/rpc/src/Resolver.ts index a4fad2811d0..597eda3b4d2 100644 --- a/packages/rpc/src/Resolver.ts +++ b/packages/rpc/src/Resolver.ts @@ -246,6 +246,20 @@ export const annotateHeadersEffect: { ) )) +/** + * @since 1.0.0 + * @category models + */ +export type Client< + R extends + | RequestResolver.RequestResolver, never> + | Effect.Effect, never>, never, any> +> = R extends Effect.Effect>, infer _E, infer R> ? + ((request: Req) => Rpc.Rpc.Result) + : R extends RequestResolver.RequestResolver, never> ? + ((request: Req) => Rpc.Rpc.Result) + : never + /** * @since 1.0.0 * @category combinators @@ -259,8 +273,4 @@ export const toClient = < options?: { readonly spanPrefix?: string } -): R extends Effect.Effect>, infer _E, infer R> ? - ((request: Req) => Rpc.Rpc.Result) - : R extends RequestResolver.RequestResolver, never> ? - ((request: Req) => Rpc.Rpc.Result) - : never => ((request: Schema.TaggedRequest.Any) => Rpc.call(request, resolver, options)) as any +): Client => ((request: Schema.TaggedRequest.Any) => Rpc.call(request, resolver, options)) as any