| /** | |
| * Serves the proxy APIs generated from clustered entities. | |
| * | |
| * Proxy handlers read the target `entityId`, call the entity client, and | |
| * forward the payload to the matching entity RPC method. This module provides | |
| * handlers for HTTP API groups created by `EntityProxy.toHttpApiGroup` and RPC | |
| * handler services for RPC groups created by `EntityProxy.toRpcGroup`. Both | |
| * normal requests and discard requests are forwarded to the underlying entity | |
| * client. | |
| * | |
| * @since 4.0.0 | |
| */ | |
| import * as Context from "../../Context.ts" | |
| import * as Effect from "../../Effect.ts" | |
| import * as Layer from "../../Layer.ts" | |
| import type * as HttpApi from "../httpapi/HttpApi.ts" | |
| import * as HttpApiBuilder from "../httpapi/HttpApiBuilder.ts" | |
| import type * as HttpApiGroup from "../httpapi/HttpApiGroup.ts" | |
| import type * as Rpc from "../rpc/Rpc.ts" | |
| import type * as Entity from "./Entity.ts" | |
| import type { Sharding } from "./Sharding.ts" | |
| /** | |
| * Creates HTTP API handlers for an entity proxy group. | |
| * | |
| * **Details** | |
| * | |
| * Each generated endpoint reads the `entityId` path parameter and forwards the | |
| * request payload to the corresponding entity client method, including discard | |
| * endpoints. | |
| * | |
| * @category layers | |
| * @since 4.0.0 | |
| */ | |
| export const layerHttpApi = < | |
| ApiId extends string, | |
| Groups extends HttpApiGroup.Any, | |
| Name extends HttpApiGroup.Name<Groups>, | |
| Type extends string, | |
| Rpcs extends Rpc.Any | |
| >( | |
| api: HttpApi.HttpApi<ApiId, Groups>, | |
| name: Name, | |
| entity: Entity.Entity<Type, Rpcs> | |
| ): Layer.Layer<HttpApiGroup.ApiGroup<ApiId, Name>, never, Sharding | Rpc.ServicesServer<Rpcs>> => | |
| HttpApiBuilder.group( | |
| api, | |
| name, | |
| Effect.fnUntraced(function*(handlers_) { | |
| const client = yield* entity.client | |
| let handlers = handlers_ | |
| for (const parentRpc_ of entity.protocol.requests.values()) { | |
| const parentRpc = parentRpc_ as any as Rpc.AnyWithProps | |
| handlers = handlers | |
| .handle( | |
| parentRpc._tag as any, | |
| (({ params, payload }: { params: { entityId: string }; payload: any }) => | |
| (client(params.entityId) as any as Record<string, (p: any) => Effect.Effect<any>>)[parentRpc._tag]( | |
| payload | |
| ).pipe( | |
| Effect.tapDefect(Effect.logError), | |
| Effect.annotateLogs({ | |
| module: "EntityProxyServer", | |
| entity: entity.type, | |
| entityId: params.entityId, | |
| method: parentRpc._tag | |
| }) | |
| )) as any | |
| ) | |
| .handle( | |
| `${parentRpc._tag}Discard` as any, | |
| (({ params, payload }: { params: { entityId: string }; payload: any }) => | |
| (client(params.entityId) as any as Record<string, (p: any, o: {}) => Effect.Effect<any>>)[parentRpc._tag]( | |
| payload, | |
| { discard: true } | |
| ).pipe( | |
| Effect.tapDefect(Effect.logError), | |
| Effect.annotateLogs({ | |
| module: "EntityProxyServer", | |
| entity: entity.type, | |
| entityId: params.entityId, | |
| method: `${parentRpc._tag}Discard` | |
| }) | |
| )) as any | |
| ) as any | |
| } | |
| return handlers as HttpApiBuilder.Handlers<never, never> | |
| }) | |
| ) | |
| /** | |
| * Creates RPC handlers for the group produced by `EntityProxy.toRpcGroup`. | |
| * | |
| * **Details** | |
| * | |
| * The handlers forward each prefixed proxy RPC to the target entity client using | |
| * the `entityId` embedded in the proxy payload. | |
| * | |
| * @category layers | |
| * @since 4.0.0 | |
| */ | |
| export const layerRpcHandlers = < | |
| const Type extends string, | |
| Rpcs extends Rpc.Any | |
| >( | |
| entity: Entity.Entity<Type, Rpcs> | |
| ): Layer.Layer<RpcHandlers<Rpcs, Type>, never, Sharding | Rpc.ServicesServer<Rpcs>> => | |
| Layer.effectContext(Effect.gen(function*() { | |
| const context = yield* Effect.context<never>() | |
| const client = yield* entity.client | |
| const handlers = new Map<string, Rpc.Handler<string>>() | |
| for (const parentRpc_ of entity.protocol.requests.values()) { | |
| const parentRpc = parentRpc_ as any as Rpc.AnyWithProps | |
| const tag = `${entity.type}.${parentRpc._tag}` as const | |
| const key = `effect/rpc/Rpc/${tag}` | |
| handlers.set(key, { | |
| context, | |
| tag, | |
| handler: ({ entityId, payload }: any) => (client(entityId) as any)[parentRpc._tag](payload) as any | |
| } as any) | |
| handlers.set(`${key}Discard`, { | |
| context, | |
| tag, | |
| handler: ({ entityId, payload }: any) => | |
| (client(entityId) as any)[parentRpc._tag](payload, { discard: true }) as any | |
| } as any) | |
| } | |
| return Context.makeUnsafe(handlers) | |
| })) | |
| /** | |
| * Union of RPC handler services required to serve the proxy RPCs for an entity. | |
| * | |
| * **Details** | |
| * | |
| * Includes both the normal prefixed RPC handler and its discard variant. | |
| * | |
| * @category services | |
| * @since 4.0.0 | |
| */ | |
| export type RpcHandlers<Rpcs extends Rpc.Any, Prefix extends string> = Rpcs extends Rpc.Rpc< | |
| infer _Tag, | |
| infer _Payload, | |
| infer _Success, | |
| infer _Error, | |
| infer _Middleware, | |
| infer _Requires | |
| > ? Rpc.Handler<`${Prefix}.${_Tag}`> | Rpc.Handler<`${Prefix}.${_Tag}Discard`> | |
| : never | |
Xet Storage Details
- Size:
- 5.18 kB
- Xet hash:
- e3e3b430b2bb139834b7298f0f10aba3689f9bbff59c797965936b9aab9eaac1
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.