Skip to content

Commit

Permalink
improve: constructor vs request dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
patroza committed Oct 11, 2024
1 parent f36ea87 commit 0fb8b93
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 18 deletions.
5 changes: 5 additions & 0 deletions .changeset/empty-mugs-watch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@effect-app/infra": minor
---

improve: constructor vs request dependencies
60 changes: 42 additions & 18 deletions packages/infra/src/api/routing2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import type * as HttpApp from "@effect/platform/HttpApp"
import { Rpc, RpcRouter } from "@effect/rpc"
import { Serializable } from "@effect/schema"
import type { NonEmptyArray } from "effect-app"
import { Cause, Chunk, Context, Effect, FiberRef, Layer, Predicate, S, Scope, Stream, Tracer } from "effect-app"
import { Cause, Chunk, Context, Effect, FiberRef, flow, Layer, Predicate, S, Scope, Stream, Tracer } from "effect-app"
import type { GetEffectContext, RPCContextMap } from "effect-app/client/req"
import type { HttpServerError } from "effect-app/http"
import { HttpMiddleware, HttpRouter, HttpServerRequest, HttpServerResponse } from "effect-app/http"
Expand Down Expand Up @@ -408,7 +408,12 @@ export const makeRouter = <Context, CTXMap extends Record<string, RPCContextMap.
Router,
string,
never,
never
Exclude<
RPCRouteR<
{ [K in keyof Filter<Rsc>]: Rpc.Rpc<Rsc[K], _R<ReturnType<THandlers[K]["handler"]>>> }[keyof Filter<Rsc>]
>,
{ [k in keyof TLayers]: Layer.Layer.Success<TLayers[k]> }[number]
>
> = (class Router extends HttpRouter.Tag(meta.moduleName + "Router")<Router>() {}) as any

const layer = r.use((router) =>
Expand Down Expand Up @@ -439,13 +444,7 @@ export const makeRouter = <Context, CTXMap extends Record<string, RPCContextMap.
) as Layer.Layer<
Router,
{ [k in keyof TLayers]: Layer.Layer.Error<TLayers[k]> }[number],
| { [k in keyof TLayers]: Layer.Layer.Context<TLayers[k]> }[number]
| Exclude<
RPCRouteR<
{ [K in keyof Filter<Rsc>]: Rpc.Rpc<Rsc[K], _R<ReturnType<THandlers[K]["handler"]>>> }[keyof Filter<Rsc>]
>,
{ [k in keyof TLayers]: Layer.Layer.Success<TLayers[k]> }[number]
>
{ [k in keyof TLayers]: Layer.Layer.Context<TLayers[k]> }[number]
>

// Effect.Effect<HttpRouter.HttpRouter<unknown, HttpRouter.HttpRouter.DefaultServices>, never, UserRouter>
Expand Down Expand Up @@ -529,32 +528,57 @@ export const makeRouter = <Context, CTXMap extends Record<string, RPCContextMap.
return r
}

type HR<T> = T extends HttpRouter.HttpRouter<any, infer R> ? R : never
type HE<T> = T extends HttpRouter.HttpRouter<infer E, any> ? E : never

type RequestHandlersTest = {
[key: string]: {
Router: { router: Effect<HttpRouter.HttpRouter<any, any>, any, any> }
routes: Layer.Layer<any, any, any>
moduleName: string
}
}
function matchAll<T extends RequestHandlersTest>(handlers: T) {
function matchAll<T extends RequestHandlersTest, A, E, R>(
handlers: T,
requestLayer: Layer.Layer<A, E, R>
) {
const routers = typedValuesOf(handlers)

const r = HttpRouter
.Default
const rootRouter = class extends HttpRouter.Tag("RootRouter")<
"RootRouter",
HR<Effect.Success<typeof handlers[keyof typeof handlers]["Router"]["router"]>>,
HE<Effect.Success<typeof handlers[keyof typeof handlers]["Router"]["router"]>>
>() {}

const r = rootRouter
.use((router) =>
Effect.gen(function*() {
for (const route of routers) {
yield* router.mount(("/rpc/" + route.moduleName) as any, yield* route.Router.router)
yield* router.mount(
("/rpc/" + route.moduleName) as any,
yield* route
.Router
.router
.pipe(Effect.map(HttpRouter.use(flow(Effect.provide(requestLayer))))) as any
)
}
})
)
.pipe(Layer.provide(routers.map((r) => r.routes).flat() as unknown as NonEmptyArray<Layer.Layer.Any>))

return r as Layer.Layer<
never,
Layer.Layer.Error<typeof handlers[keyof typeof handlers]["routes"]>,
Layer.Layer.Context<typeof handlers[keyof typeof handlers]["routes"]>
>
return {
layer: r as Layer.Layer<
never,
Layer.Layer.Error<typeof handlers[keyof typeof handlers]["routes"]>,
Layer.Layer.Context<typeof handlers[keyof typeof handlers]["routes"]>
>,
Router: rootRouter as any as HttpRouter.HttpRouter.TagClass<
"RootRouter",
"RootRouter",
HE<Effect.Success<typeof handlers[keyof typeof handlers]["Router"]["router"]>>,
R | Exclude<HR<Effect.Success<typeof handlers[keyof typeof handlers]["Router"]["router"]>>, A>
>
}
}

return { matchAll, matchFor }
Expand Down

0 comments on commit 0fb8b93

Please sign in to comment.