@effect-app/infra 2.45.3 → 2.46.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,18 +2,16 @@
2
2
  /* eslint-disable @typescript-eslint/no-unsafe-argument */
3
3
  /* eslint-disable @typescript-eslint/no-empty-object-type */
4
4
  /* eslint-disable @typescript-eslint/no-explicit-any */
5
- import type * as HttpApp from "@effect/platform/HttpApp"
6
- import { Rpc, RpcRouter } from "@effect/rpc"
7
- import { Array, Cause, Duration, Effect, FiberRef, flow, Layer, type NonEmptyArray, type NonEmptyReadonlyArray, Predicate, Request, S, Schedule, Schema } from "effect-app"
5
+ import { determineMethod } from "@effect-app/infra/api/routing/utils"
6
+ import { logError, reportError } from "@effect-app/infra/errorReporter"
7
+ import { InfraLogger } from "@effect-app/infra/logger"
8
+ import { Rpc, RpcGroup, RpcServer } from "@effect/rpc"
9
+ import { Array, Cause, Duration, Effect, Layer, type NonEmptyReadonlyArray, Predicate, Request, S, Schedule, Schema } from "effect-app"
8
10
  import type { GetEffectContext, RPCContextMap } from "effect-app/client/req"
9
- import { HttpHeaders, HttpRouter, type HttpServerError, HttpServerRequest, HttpServerResponse } from "effect-app/http"
11
+ import { type HttpHeaders, type HttpRouter } from "effect-app/http"
10
12
  import { pretty, typedKeysOf, typedValuesOf } from "effect-app/utils"
11
- import type { ParseError } from "effect/ParseResult"
12
13
  import type { Contravariant } from "effect/Types"
13
- import { logError, reportError } from "../errorReporter.js"
14
- import { InfraLogger } from "../logger.js"
15
14
  import { makeRpc, type Middleware } from "./routing/DynamicMiddleware.js"
16
- import { determineMethod } from "./routing/utils.js"
17
15
 
18
16
  const logRequestError = logError("Request")
19
17
  const reportRequestError = reportError("Request")
@@ -35,33 +33,6 @@ export type _E<T extends Effect<any, any, any>> = [T] extends [
35
33
  export type EffectDeps<A> = {
36
34
  [K in keyof A as A[K] extends Effect<any, any, any> ? K : never]: A[K] extends Effect<any, any, any> ? A[K] : never
37
35
  }
38
- /**
39
- * Plain jane JSON version, with custom status codes just for fun
40
- */
41
- export const toHttpApp = <R extends RpcRouter.RpcRouter<any, any>>(self: R, options?: {
42
- readonly spanPrefix?: string
43
- }): HttpApp.Default<
44
- HttpServerError.RequestError | ParseError,
45
- RpcRouter.RpcRouter.Context<R>
46
- > => {
47
- const handler = RpcRouter.toHandlerNoStream(self, options)
48
- return HttpServerRequest.HttpServerRequest.pipe(
49
- Effect.flatMap((_) => _.json),
50
- Effect.flatMap(handler),
51
- Effect.flatMap((r) => {
52
- // currently only 200, 418, 422 are allowed, see apiClientFactory
53
- let status = 200
54
- const results = Array.isArray(r) ? r : [r]
55
- if (results.some((_: S.ExitEncoded<any, any, any>) => _._tag === "Failure" && _.cause._tag === "Die")) {
56
- status = 418
57
- } else if (results.some((_: S.ExitEncoded<any, any, any>) => _._tag === "Failure" && _.cause._tag === "Fail")) {
58
- status = 422 // 418
59
- }
60
- return HttpServerResponse.json(r, { status }).pipe(Effect.orDie)
61
- }),
62
- Effect.tapDefect(reportError("RPCHttpApp"))
63
- )
64
- }
65
36
 
66
37
  export type AnyRequestModule = S.Schema.Any & {
67
38
  _tag: string
@@ -98,7 +69,8 @@ type HandlerFull<Action extends AnyRequestModule, RT extends "raw" | "d", A, E,
98
69
  _tag: RT
99
70
  stack: string
100
71
  handler: (
101
- req: S.Schema.Type<Action>
72
+ req: S.Schema.Type<Action>,
73
+ headers: HttpHeaders.Headers
102
74
  ) => Effect<
103
75
  A,
104
76
  E,
@@ -132,16 +104,14 @@ export interface RouterShape<Rsc> {
132
104
  [RouterSymbol]: Rsc
133
105
  }
134
106
 
135
- type RPCRouteR<T extends Rpc.Rpc<any, any>> = [T] extends [
136
- Rpc.Rpc<any, infer R>
107
+ type RPCRouteR<
108
+ T extends [any, (requestLayers: any) => (req: any, headers: HttpHeaders.Headers) => Effect<any, any, any>]
109
+ > = T extends [
110
+ any,
111
+ (requestLayers: any) => (...args: any[]) => Effect<any, any, infer R>
137
112
  ] ? R
138
113
  : never
139
114
 
140
- type RPCRouteReq<T extends Rpc.Rpc<any, any>> = [T] extends [
141
- Rpc.Rpc<infer Req, any>
142
- ] ? Req
143
- : never
144
-
145
115
  type Match<
146
116
  Rsc extends Record<string, any>,
147
117
  CTXMap extends Record<string, any>,
@@ -309,158 +279,182 @@ export const makeRouter = <
309
279
  | { [k in keyof Layers]: Layer.Layer.Success<Layers[k]> }[number]
310
280
  | { [k in keyof TLayers]: Layer.Layer.Success<TLayers[k]> }[number]
311
281
  type Router = RouterShape<Rsc>
312
- const r: HttpRouter.HttpRouter.TagClass<
313
- Router,
314
- `${typeof meta.moduleName}Router`,
315
- never,
316
- Exclude<
317
- | Context
318
- | RPCRouteR<
319
- { [K in keyof Filter<Rsc>]: Rpc.Rpc<Rsc[K], _R<ReturnType<THandlers[K]["handler"]>>> }[keyof Filter<Rsc>]
320
- >,
321
- HttpRouter.HttpRouter.Provided
322
- >
323
- > = (class Router extends HttpRouter.Tag(`${meta.moduleName}Router`)<Router>() {}) as any
324
-
325
- const layer = r.use((router) =>
326
- Effect.gen(function*() {
327
- const controllers = yield* make
328
- const rpc = yield* makeRpc(middleware)
329
-
330
- // return make.pipe(Effect.map((c) => controllers(c, layers)))
331
- const mapped = typedKeysOf(filtered).reduce((acc, cur) => {
332
- const handler = controllers[cur as keyof typeof controllers]
333
- const req = rsc[cur]
334
-
335
- const method = determineMethod(String(cur), req)
336
- const isCommand = method._tag === "command"
337
-
338
- const handle = isCommand
339
- ? (req: any) => Effect.retry(handler.handler(req) as any, optimisticConcurrencySchedule)
340
- : (req: any) => Effect.interruptible(handler.handler(req) as any)
341
-
342
- acc[cur] = rpc.effect(
343
- handler._tag === "raw"
344
- ? class extends (req as any) {
345
- static success = S.encodedSchema(req.success)
346
- get [Schema.symbolSerializable]() {
347
- return this.constructor
348
- }
349
- get [Schema.symbolWithResult]() {
350
- return {
351
- failure: req.failure,
352
- success: S.encodedSchema(req.success)
282
+
283
+ const layer = (requestLayers: any) =>
284
+ Effect
285
+ .gen(function*() {
286
+ const controllers = yield* make
287
+ const rpc = yield* makeRpc(middleware)
288
+
289
+ // return make.pipe(Effect.map((c) => controllers(c, layers)))
290
+ const mapped = typedKeysOf(filtered).reduce((acc, cur) => {
291
+ const handler = controllers[cur as keyof typeof controllers]
292
+ const req = rsc[cur]
293
+
294
+ const method = determineMethod(String(cur), req)
295
+ const isCommand = method._tag === "command"
296
+
297
+ const handle = isCommand
298
+ ? (req: any, headers: HttpHeaders.Headers) =>
299
+ Effect.retry(handler.handler(req, headers) as any, optimisticConcurrencySchedule)
300
+ : (req: any, headers: HttpHeaders.Headers) => Effect.interruptible(handler.handler(req, headers) as any)
301
+
302
+ acc[cur] = [
303
+ handler._tag === "raw"
304
+ ? class extends (req as any) {
305
+ static success = S.encodedSchema(req.success)
306
+ get [Schema.symbolSerializable]() {
307
+ return this.constructor
353
308
  }
354
- }
355
- } as any
356
- : req,
357
- (req) =>
358
- // TODO: render more data... similar to console?
359
- Effect
360
- .annotateCurrentSpan(
361
- "requestInput",
362
- Object.entries(req).reduce((prev, [key, value]: [string, unknown]) => {
363
- prev[key] = key === "password"
364
- ? "<redacted>"
365
- : typeof value === "string" || typeof value === "number" || typeof value === "boolean"
366
- ? typeof value === "string" && value.length > 256
367
- ? (value.substring(0, 253) + "...")
368
- : value
369
- : Array.isArray(value)
370
- ? `Array[${value.length}]`
371
- : value === null || value === undefined
372
- ? `${value}`
373
- : typeof value === "object" && value
374
- ? `Object[${Object.keys(value).length}]`
375
- : typeof value
376
- return prev
377
- }, {} as Record<string, string | number | boolean>)
378
- )
379
- .pipe(
380
- // can't use andThen due to some being a function and effect
381
- Effect.zipRight(handle(req)),
382
- Effect.tapErrorCause((cause) => Cause.isFailure(cause) ? logRequestError(cause) : Effect.void),
383
- Effect.tapDefect((cause) =>
384
- Effect
385
- .all([
386
- reportRequestError(cause, {
387
- action: `${meta.moduleName}.${req._tag}`
388
- }),
389
- Rpc.currentHeaders.pipe(Effect.andThen((headers) => {
390
- return InfraLogger
391
- .logError("Finished request", cause)
392
- .pipe(Effect.annotateLogs({
393
- action: `${meta.moduleName}.${req._tag}`,
394
- req: pretty(req),
395
- headers: pretty(headers)
396
- // resHeaders: pretty(
397
- // Object
398
- // .entries(headers)
399
- // .reduce((prev, [key, value]) => {
400
- // prev[key] = value && typeof value === "string" ? snipString(value) : value
401
- // return prev
402
- // }, {} as Record<string, any>)
403
- // )
404
- }))
405
- }))
406
- ])
407
- ),
408
- // NOTE: this does not catch errors from the middlewares..
409
- // we should re-evalute this in any case..
410
- devMode ? (_) => _ : Effect.catchAllDefect(() => Effect.die("Internal Server Error")),
411
- Effect.withSpan("Request." + meta.moduleName + "." + req._tag, {
412
- captureStackTrace: () => handler.stack
413
- })
414
- ),
415
- meta.moduleName
416
- ) // TODO
417
- return acc
418
- }, {} as any) as {
419
- [K in Keys]: Rpc.Rpc<
420
- Rsc[K],
421
- Context | _R<ReturnType<THandlers[K]["handler"]>>
422
- >
423
- }
424
-
425
- const rpcRouter = RpcRouter.make(...Object.values(mapped) as any) as RpcRouter.RpcRouter<
426
- RPCRouteReq<typeof mapped[keyof typeof mapped]>,
427
- RPCRouteR<typeof mapped[keyof typeof mapped]>
428
- >
429
- const httpApp = toHttpApp(rpcRouter, {
430
- spanPrefix: rsc
431
- .meta
432
- .moduleName + "."
433
- })
434
- yield* router
435
- .post(
436
- "/",
437
- httpApp as any,
438
- { uninterruptible: true }
309
+ get [Schema.symbolWithResult]() {
310
+ return {
311
+ failure: req.failure,
312
+ success: S.encodedSchema(req.success)
313
+ }
314
+ }
315
+ } as any
316
+ : req,
317
+ (requestLayers: any) =>
318
+ rpc.effect(req, (input: any, headers: HttpHeaders.Headers) =>
319
+ // TODO: render more data... similar to console?
320
+ Effect
321
+ .annotateCurrentSpan(
322
+ "requestInput",
323
+ Object.entries(input).reduce((prev, [key, value]: [string, unknown]) => {
324
+ prev[key] = key === "password"
325
+ ? "<redacted>"
326
+ : typeof value === "string" || typeof value === "number" || typeof value === "boolean"
327
+ ? typeof value === "string" && value.length > 256
328
+ ? (value.substring(0, 253) + "...")
329
+ : value
330
+ : Array.isArray(value)
331
+ ? `Array[${value.length}]`
332
+ : value === null || value === undefined
333
+ ? `${value}`
334
+ : typeof value === "object" && value
335
+ ? `Object[${Object.keys(value).length}]`
336
+ : typeof value
337
+ return prev
338
+ }, {} as Record<string, string | number | boolean>)
339
+ )
340
+ .pipe(
341
+ // can't use andThen due to some being a function and effect
342
+ Effect.zipRight(handle(input, headers)),
343
+ Effect.tapErrorCause((cause) => Cause.isFailure(cause) ? logRequestError(cause) : Effect.void),
344
+ Effect.tapDefect((cause) =>
345
+ Effect
346
+ .all([
347
+ reportRequestError(cause, {
348
+ action: `${meta.moduleName}.${req._tag}`
349
+ }),
350
+ InfraLogger
351
+ .logError("Finished request", cause)
352
+ .pipe(Effect.annotateLogs({
353
+ action: `${meta.moduleName}.${req._tag}`,
354
+ req: pretty(req),
355
+ headers: pretty(headers)
356
+ // resHeaders: pretty(
357
+ // Object
358
+ // .entries(headers)
359
+ // .reduce((prev, [key, value]) => {
360
+ // prev[key] = value && typeof value === "string" ? snipString(value) : value
361
+ // return prev
362
+ // }, {} as Record<string, any>)
363
+ // )
364
+ }))
365
+ ])
366
+ ),
367
+ // NOTE: this does not catch errors from the middlewares..
368
+ // we should re-evalute this in any case..
369
+ devMode ? (_) => _ : Effect.catchAllDefect(() => Effect.die("Internal Server Error")),
370
+ Effect.withSpan("Request." + meta.moduleName + "." + req._tag, {
371
+ captureStackTrace: () => handler.stack
372
+ }),
373
+ Effect.provide(requestLayers)
374
+ ), meta.moduleName),
375
+ meta.moduleName
376
+ ] as const
377
+ return acc
378
+ }, {} as any) as {
379
+ [K in Keys]: [
380
+ Rsc[K],
381
+ (
382
+ requestLayers: any
383
+ ) => (
384
+ req: any,
385
+ headers: HttpHeaders.Headers
386
+ ) => Effect.Effect<
387
+ any,
388
+ _E<ReturnType<THandlers[K]["handler"]>>,
389
+ Context | _R<ReturnType<THandlers[K]["handler"]>>
390
+ > // Context | _R<ReturnType<THandlers[K]["handler"]>>
391
+ ]
392
+ }
393
+
394
+ const rpcs = RpcGroup.make(
395
+ ...typedValuesOf(mapped).map((_) => {
396
+ return Rpc.fromTaggedRequest(_[0])
397
+ })
439
398
  )
440
- })
441
- )
399
+ const rpcLayer = (requestLayers: any) =>
400
+ rpcs.toLayer(Effect.gen(function*() {
401
+ return typedValuesOf(mapped).reduce((acc, [req, handler]) => {
402
+ acc[req._tag] = handler(requestLayers)
403
+ return acc
404
+ }, {} as Record<string, any>)
405
+ })) as unknown as Layer<
406
+ { [K in keyof Filtered]: Rpc.Handler<K> },
407
+ never,
408
+ RPCRouteR<typeof mapped[keyof typeof mapped]>
409
+ >
410
+
411
+ const impl = rpcLayer(requestLayers)
412
+ const l = RpcServer.layer(rpcs).pipe(Layer.provide(impl))
413
+ // TODO: also takes optional a RouterTag..
414
+ return l.pipe(
415
+ Layer.provideMerge(
416
+ RpcServer.layerProtocolHttp({ path: ("/rpc/" + meta.moduleName) as `/rpc/${typeof meta.moduleName}` })
417
+ )
418
+ )
419
+
420
+ // const rpcRouter = RpcRouter.make(...typedValuesOf(mapped).map(_ => _[0]) as any) as RpcRouter.RpcRouter<
421
+ // RPCRouteReq<typeof mapped[keyof typeof mapped]>,
422
+ // RPCRouteR<typeof mapped[keyof typeof mapped]>
423
+ // >
424
+ // const httpApp = toHttpApp(rpcRouter, {
425
+ // spanPrefix: rsc
426
+ // .meta
427
+ // .moduleName + "."
428
+ // })
429
+ // yield* router
430
+ // .post(
431
+ // "/",
432
+ // httpApp as any,
433
+ // { uninterruptible: true }
434
+ // )
435
+ })
436
+ .pipe(Layer.unwrapEffect)
442
437
 
443
438
  // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
444
- const routes = layer.pipe(
445
- Layer.provideMerge(r.Live),
446
- layers && Array.isNonEmptyReadonlyArray(layers) ? Layer.provide(layers as any) as any : (_) => _,
447
- // TODO: only provide to the middleware?
448
- middleware.dependencies ? Layer.provide(middleware.dependencies as any) : (_) => _
449
- ) as Layer.Layer<
450
- Router,
451
- GetError<TLayers> | E,
452
- | GetContext<TLayers>
453
- | Exclude<
454
- RMW | R,
455
- ProvidedLayers
456
- >
457
- >
439
+ const routes = ((requestLayer: any) =>
440
+ layer(requestLayer).pipe(
441
+ layers && Array.isNonEmptyReadonlyArray(layers) ? Layer.provide(layers as any) as any : (_) => _,
442
+ // TODO: only provide to the middleware?
443
+ middleware.dependencies ? Layer.provide(middleware.dependencies as any) : (_) => _
444
+ )) as ((requestLayer: any) => Layer.Layer<
445
+ Router,
446
+ GetError<TLayers> | E,
447
+ | GetContext<TLayers>
448
+ | Exclude<
449
+ RMW | R,
450
+ ProvidedLayers
451
+ >
452
+ >)
458
453
 
459
454
  // Effect.Effect<HttpRouter.HttpRouter<unknown, HttpRouter.HttpRouter.DefaultServices>, never, UserRouter>
460
455
 
461
456
  return {
462
457
  moduleName: meta.moduleName,
463
- Router: r,
464
458
  routes
465
459
  }
466
460
  }
@@ -483,21 +477,8 @@ export const makeRouter = <
483
477
  make: Make
484
478
  ): {
485
479
  moduleName: ModuleName
486
- Router: HttpRouter.HttpRouter.TagClass<
487
- RouterShape<Rsc>,
488
- `${ModuleName}Router`,
489
- never,
490
- | Exclude<Context, HttpRouter.HttpRouter.Provided>
491
- | Exclude<
492
- RPCRouteR<
493
- {
494
- [K in keyof Filter<Rsc>]: Rpc.Rpc<Rsc[K], _R<ReturnType<MakeHandlers<Make, Filter<Rsc>>[K]["handler"]>>>
495
- }[keyof Filter<Rsc>]
496
- >,
497
- HttpRouter.HttpRouter.Provided
498
- >
499
- >
500
- routes: Layer.Layer<
480
+
481
+ routes: (requestLayers: any) => Layer.Layer<
501
482
  RouterShape<Rsc>,
502
483
  MakeErrors<Make> | GetError<Make["dependencies"]>,
503
484
  | GetContext<Make["dependencies"]>
@@ -521,21 +502,8 @@ export const makeRouter = <
521
502
  make: Make
522
503
  ): {
523
504
  moduleName: ModuleName
524
- Router: HttpRouter.HttpRouter.TagClass<
525
- RouterShape<Rsc>,
526
- `${ModuleName}Router`,
527
- never,
528
- | Exclude<Context, HttpRouter.HttpRouter.Provided>
529
- | Exclude<
530
- RPCRouteR<
531
- {
532
- [K in keyof Filter<Rsc>]: Rpc.Rpc<Rsc[K], _R<ReturnType<MakeHandlers<Make, Filter<Rsc>>[K]["handler"]>>>
533
- }[keyof Filter<Rsc>]
534
- >,
535
- HttpRouter.HttpRouter.Provided
536
- >
537
- >
538
- routes: Layer.Layer<
505
+
506
+ routes: (requestLayers: any) => Layer.Layer<
539
507
  RouterShape<Rsc>,
540
508
  MakeErrors<Make> | GetError<Make["dependencies"]>,
541
509
  | GetContext<Make["dependencies"]>
@@ -559,21 +527,8 @@ export const makeRouter = <
559
527
  make: Make
560
528
  ): {
561
529
  moduleName: ModuleName
562
- Router: HttpRouter.HttpRouter.TagClass<
563
- RouterShape<Rsc>,
564
- `${ModuleName}Router`,
565
- never,
566
- | Exclude<Context, HttpRouter.HttpRouter.Provided>
567
- | Exclude<
568
- RPCRouteR<
569
- {
570
- [K in keyof Filter<Rsc>]: Rpc.Rpc<Rsc[K], _R<ReturnType<MakeHandlers<Make, Filter<Rsc>>[K]["handler"]>>>
571
- }[keyof Filter<Rsc>]
572
- >,
573
- HttpRouter.HttpRouter.Provided
574
- >
575
- >
576
- routes: Layer.Layer<
530
+
531
+ routes: (requestLayers: any) => Layer.Layer<
577
532
  RouterShape<Rsc>,
578
533
  MakeErrors<Make> | GetError<Make["dependencies"]>,
579
534
  | GetContext<Make["dependencies"]>
@@ -597,21 +552,8 @@ export const makeRouter = <
597
552
  make: Make
598
553
  ): {
599
554
  moduleName: ModuleName
600
- Router: HttpRouter.HttpRouter.TagClass<
601
- RouterShape<Rsc>,
602
- `${ModuleName}Router`,
603
- never,
604
- | Exclude<Context, HttpRouter.HttpRouter.Provided>
605
- | Exclude<
606
- RPCRouteR<
607
- {
608
- [K in keyof Filter<Rsc>]: Rpc.Rpc<Rsc[K], _R<ReturnType<MakeHandlers<Make, Filter<Rsc>>[K]["handler"]>>>
609
- }[keyof Filter<Rsc>]
610
- >,
611
- HttpRouter.HttpRouter.Provided
612
- >
613
- >
614
- routes: Layer.Layer<
555
+
556
+ routes: (requestLayers: any) => Layer.Layer<
615
557
  RouterShape<Rsc>,
616
558
  MakeErrors<Make> | GetError<Make["dependencies"]>,
617
559
  | GetContext<Make["dependencies"]>
@@ -633,21 +575,8 @@ export const makeRouter = <
633
575
  make: Make
634
576
  ): {
635
577
  moduleName: ModuleName
636
- Router: HttpRouter.HttpRouter.TagClass<
637
- RouterShape<Rsc>,
638
- `${ModuleName}Router`,
639
- never,
640
- | Exclude<Context, HttpRouter.HttpRouter.Provided>
641
- | Exclude<
642
- RPCRouteR<
643
- {
644
- [K in keyof Filter<Rsc>]: Rpc.Rpc<Rsc[K], _R<ReturnType<MakeHandlers<Make, Filter<Rsc>>[K]["handler"]>>>
645
- }[keyof Filter<Rsc>]
646
- >,
647
- HttpRouter.HttpRouter.Provided
648
- >
649
- >
650
- routes: Layer.Layer<
578
+
579
+ routes: (requestLayers: any) => Layer.Layer<
651
580
  RouterShape<Rsc>,
652
581
  MakeErrors<Make> | GetError<Make["dependencies"]>,
653
582
  | GetContext<Make["dependencies"]>
@@ -758,13 +687,10 @@ export const makeRouter = <
758
687
  return Object.assign(effect, items, { router, router3 })
759
688
  }
760
689
 
761
- type HR<T> = T extends HttpRouter.HttpRouter<any, infer R> ? R : never
762
- type HE<T> = T extends HttpRouter.HttpRouter<infer E, any> ? E : never
763
-
764
690
  type RequestHandlersTest = {
765
691
  [key: string]: {
766
- Router: { router: Effect<HttpRouter.HttpRouter<any, any>, any, any> }
767
- routes: Layer.Layer<any, any, any>
692
+ // Router: { router: Effect<HttpRouter.HttpRouter<any, any>, any, any> }
693
+ routes: (requestLayers: any) => Layer.Layer<any, any, any>
768
694
  moduleName: string
769
695
  }
770
696
  }
@@ -774,45 +700,11 @@ export const makeRouter = <
774
700
  ) {
775
701
  const routers = typedValuesOf(handlers)
776
702
 
777
- const rootRouter = class extends HttpRouter.Tag("RootRouter")<
778
- "RootRouter",
779
- HR<Effect.Success<typeof handlers[keyof typeof handlers]["Router"]["router"]>>,
780
- HE<Effect.Success<typeof handlers[keyof typeof handlers]["Router"]["router"]>>
781
- >() {}
782
-
783
- const r = rootRouter
784
- .use((router) =>
785
- Effect.gen(function*() {
786
- for (const route of routers) {
787
- yield* router.mount(
788
- ("/rpc/" + route.moduleName) as any,
789
- yield* route
790
- .Router
791
- .router
792
- .pipe(Effect.map(HttpRouter.use(flow(Effect.provide(requestLayer))))) as any
793
- )
794
- }
795
- })
796
- )
797
- .pipe(
798
- routers.length
799
- ? Layer.provide(routers.map((r) => r.routes).flat() as unknown as NonEmptyArray<Layer.Layer.Any>)
800
- : (_) => _
801
- )
802
-
803
- return {
804
- layer: r as Layer.Layer<
805
- never,
806
- Layer.Layer.Error<typeof handlers[keyof typeof handlers]["routes"]>,
807
- Layer.Layer.Context<typeof handlers[keyof typeof handlers]["routes"]>
808
- >,
809
- Router: rootRouter as any as HttpRouter.HttpRouter.TagClass<
810
- "RootRouter",
811
- "RootRouter",
812
- HE<Effect.Success<typeof handlers[keyof typeof handlers]["Router"]["router"]>>,
813
- R | Exclude<HR<Effect.Success<typeof handlers[keyof typeof handlers]["Router"]["router"]>>, A>
814
- >
815
- }
703
+ return Layer.mergeAll(...routers.map((_) => _.routes(requestLayer)) as [any]) as unknown as Layer.Layer<
704
+ never,
705
+ Layer.Layer.Error<ReturnType<typeof handlers[keyof typeof handlers]["routes"]>>,
706
+ Layer.Layer.Context<ReturnType<typeof handlers[keyof typeof handlers]["routes"]>>
707
+ > // TODO
816
708
  }
817
709
 
818
710
  return {
@@ -854,14 +746,3 @@ export const RequestCacheLayers = Layer.mergeAll(
854
746
  Layer.setRequestCaching(true),
855
747
  Layer.setRequestBatching(true)
856
748
  )
857
-
858
- export const RpcHeadersFromHttpHeaders = Effect
859
- .gen(function*() {
860
- const httpReq = yield* HttpServerRequest.HttpServerRequest
861
- // TODO: only pass Authentication etc, or move headers to actual Rpc Headers
862
- yield* FiberRef.update(
863
- Rpc.currentHeaders,
864
- (headers) => HttpHeaders.merge(httpReq.headers, headers)
865
- )
866
- })
867
- .pipe(Layer.effectDiscard)