@effect-app/infra 2.87.2 → 2.89.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.
Files changed (50) hide show
  1. package/CHANGELOG.md +24 -1
  2. package/dist/api/{routing/middleware/ContextProvider.d.ts → ContextProvider.d.ts} +1 -1
  3. package/dist/api/ContextProvider.d.ts.map +1 -0
  4. package/dist/api/ContextProvider.js +38 -0
  5. package/dist/api/routing/middleware/RouterMiddleware.d.ts +15 -28
  6. package/dist/api/routing/middleware/RouterMiddleware.d.ts.map +1 -1
  7. package/dist/api/routing/middleware/RouterMiddleware.js +2 -5
  8. package/dist/api/routing/middleware/RpcMiddleware.d.ts +19 -23
  9. package/dist/api/routing/middleware/RpcMiddleware.d.ts.map +1 -1
  10. package/dist/api/routing/middleware/RpcMiddleware.js +1 -1
  11. package/dist/api/routing/middleware/dynamic-middleware.d.ts +1 -9
  12. package/dist/api/routing/middleware/dynamic-middleware.d.ts.map +1 -1
  13. package/dist/api/routing/middleware/generic-middleware.d.ts +24 -22
  14. package/dist/api/routing/middleware/generic-middleware.d.ts.map +1 -1
  15. package/dist/api/routing/middleware/generic-middleware.js +24 -8
  16. package/dist/api/routing/middleware/middleware-api.d.ts +68 -36
  17. package/dist/api/routing/middleware/middleware-api.d.ts.map +1 -1
  18. package/dist/api/routing/middleware/middleware-api.js +45 -45
  19. package/dist/api/routing/middleware/middleware.d.ts +7 -7
  20. package/dist/api/routing/middleware/middleware.d.ts.map +1 -1
  21. package/dist/api/routing/middleware/middleware.js +5 -5
  22. package/dist/api/routing/middleware.d.ts +0 -1
  23. package/dist/api/routing/middleware.d.ts.map +1 -1
  24. package/dist/api/routing/middleware.js +1 -2
  25. package/dist/api/routing.d.ts +1 -1
  26. package/dist/api/routing.d.ts.map +1 -1
  27. package/dist/api/routing.js +12 -10
  28. package/package.json +6 -6
  29. package/src/api/{routing/middleware/ContextProvider.ts → ContextProvider.ts} +1 -1
  30. package/src/api/routing/middleware/RouterMiddleware.ts +22 -134
  31. package/src/api/routing/middleware/RpcMiddleware.ts +28 -23
  32. package/src/api/routing/middleware/dynamic-middleware.ts +0 -47
  33. package/src/api/routing/middleware/generic-middleware.ts +84 -35
  34. package/src/api/routing/middleware/middleware-api.ts +190 -159
  35. package/src/api/routing/middleware/middleware.ts +5 -5
  36. package/src/api/routing/middleware.ts +0 -1
  37. package/src/api/routing.ts +22 -20
  38. package/test/contextProvider.test.ts +28 -25
  39. package/test/controller.test.ts +44 -9
  40. package/test/dist/contextProvider.test.d.ts.map +1 -1
  41. package/test/dist/controller.test.d.ts.map +1 -1
  42. package/test/dist/fixtures.d.ts +39 -45
  43. package/test/dist/fixtures.d.ts.map +1 -1
  44. package/test/dist/fixtures.js +27 -14
  45. package/test/dist/requires.test.d.ts.map +1 -1
  46. package/test/fixtures.ts +29 -18
  47. package/test/layerUtils.test.ts +1 -2
  48. package/test/requires.test.ts +146 -103
  49. package/dist/api/routing/middleware/ContextProvider.d.ts.map +0 -1
  50. package/dist/api/routing/middleware/ContextProvider.js +0 -38
@@ -1,199 +1,230 @@
1
- import { Rpc } from "@effect/rpc"
2
- import { Context, Effect, Layer, type NonEmptyArray, type NonEmptyReadonlyArray } from "effect-app"
3
- import { type RPCContextMap } from "effect-app/client"
4
- import { type LayerUtils } from "../../layerUtils.js"
5
- import { type GenericMiddlewareMaker, genericMiddlewareMaker } from "./generic-middleware.js"
6
- import { makeRpcEffect, type MiddlewareMakerId, type RPCHandlerFactory } from "./RouterMiddleware.js"
7
- import { type AnyDynamic, type RpcDynamic, type TagClassAny } from "./RpcMiddleware.js"
8
-
9
- // TODO: don't expect service when it's wrap/never
10
- // perhaps RequestContextMap should be an object, instead of an interface, so that we don't need to provide anything here
11
- export const contextMap =
12
- <RequestContextMap extends Record<string, RPCContextMap.Any>>() =>
13
- <K extends keyof RequestContextMap>(a: K, service: RequestContextMap[K]["service"]) => ({
14
- key: a,
15
- settings: { service } as any as RequestContextMap[typeof a]
16
- })
17
-
18
- export interface MiddlewareM<
19
- RequestContext extends Record<string, RPCContextMap.Any>,
20
- Provided extends keyof RequestContext,
21
- Middlewares extends ReadonlyArray<GenericMiddlewareMaker>,
22
- DynamicMiddlewareProviders,
23
- // out MiddlewareR = never
24
- MiddlewareR = never
25
- > {
26
- middleware<MW extends NonEmptyArray<GenericMiddlewareMaker>>(
27
- ...mw: MW
28
- ): DynamicMiddlewareMakerrsss<
29
- RequestContext,
30
- Provided,
31
- [...Middlewares, ...MW],
32
- DynamicMiddlewareProviders,
33
- GenericMiddlewareMaker.ApplyManyServices<MW, MiddlewareR>
34
- >
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ import { type AnyWithProps } from "@effect/rpc/Rpc"
3
+ import { Context, type Effect, type NonEmptyArray, type NonEmptyReadonlyArray, S } from "effect-app"
4
+ import { type GetContextConfig, type RPCContextMap } from "effect-app/client"
5
+ import { type MiddlewareMaker, middlewareMaker } from "./generic-middleware.js"
6
+ import { type AnyDynamic, type RpcDynamic, Tag, type TagClassAny } from "./RpcMiddleware.js"
7
+
8
+ /** Adapter used when setting the dynamic prop on a middleware implementation */
9
+ export const contextMap = <
10
+ RequestContextMap extends Record<string, RPCContextMap.Any>,
11
+ Key extends (keyof RequestContextMap) & string
12
+ >(rcm: RequestContextMap, key: Key): RpcDynamic<Key, RequestContextMap[Key]> => ({
13
+ key,
14
+ settings: { service: rcm[key]!["service"] } as RequestContextMap[Key]
15
+ })
16
+
17
+ /** Retrieves RequestContextConfig out of the RPC annotations */
18
+ export const getConfig = <
19
+ RequestContextMap extends Record<string, RPCContextMap.Any>
20
+ >() =>
21
+ (rpc: AnyWithProps): GetContextConfig<RequestContextMap> => {
22
+ return Context.unsafeGet(rpc.annotations, Context.GenericTag("RequestContextConfig"))
35
23
  }
36
24
 
37
- type GetDependsOnKeys<MW extends GenericMiddlewareMaker> = MW extends { dependsOn: NonEmptyReadonlyArray<TagClassAny> }
38
- ? {
25
+ // the following implements sort of builder pattern
26
+ // we support both sideways and upwards elimination of dependencies
27
+
28
+ // it's for dynamic middlewares
29
+ type GetDependsOnKeys<MW extends MiddlewareMaker> = MW extends { dependsOn: NonEmptyReadonlyArray<TagClassAny> } ? {
39
30
  [K in keyof MW["dependsOn"]]: MW["dependsOn"][K] extends AnyDynamic ? MW["dependsOn"][K]["dynamic"]["key"]
40
31
  : never
41
32
  }[keyof MW["dependsOn"]]
42
33
  : never
43
34
 
44
- export interface MiddlewareDynamic<
45
- RequestContext extends Record<string, RPCContextMap.Any>,
46
- Provided extends keyof RequestContext,
47
- Middlewares extends ReadonlyArray<GenericMiddlewareMaker>,
35
+ type FilterInDynamicMiddlewares<
36
+ MWs extends ReadonlyArray<MiddlewareMaker>,
37
+ RequestContextMap extends Record<string, RPCContextMap.Any>
38
+ > = {
39
+ [K in keyof MWs]: MWs[K] extends { dynamic: RpcDynamic<any, RequestContextMap[keyof RequestContextMap]> } ? MWs[K]
40
+ : never
41
+ }
42
+
43
+ type RecursiveHandleMWsSideways<
44
+ MWs,
45
+ R extends {
46
+ rcm: Record<string, RPCContextMap.Any>
47
+ provided: keyof R["rcm"] // that's fine
48
+ middlewares: ReadonlyArray<MiddlewareMaker>
49
+ dmp: any
50
+ middlewareR: any
51
+ }
52
+ > = MWs extends [
53
+ infer F extends MiddlewareMaker,
54
+ ...infer Rest extends ReadonlyArray<MiddlewareMaker>
55
+ ] ? RecursiveHandleMWsSideways<Rest, {
56
+ rcm: R["rcm"]
57
+ // when one dynamic middleware depends on another, subtract the key to enforce the dependency to be provided after
58
+ // (if already provided, it would have to be re-provided anyway, so better to provide it after)
59
+ provided: Exclude<
60
+ R["provided"] | FilterInDynamicMiddlewares<[F], R["rcm"]>[number]["dynamic"]["key"],
61
+ // F is fine here because only dynamic middlewares will have 'dependsOn' prop
62
+ GetDependsOnKeys<F>
63
+ >
64
+ middlewares: [...R["middlewares"], F]
65
+ dmp: [FilterInDynamicMiddlewares<[F], R["rcm"]>[number]] extends [never] ? R["dmp"]
66
+ :
67
+ & R["dmp"]
68
+ & {
69
+ [U in FilterInDynamicMiddlewares<[F], R["rcm"]>[number] as U["dynamic"]["key"]]: U
70
+ }
71
+ middlewareR: MiddlewareMaker.ApplyManyServices<[F], R["middlewareR"]>
72
+ }>
73
+ : R
74
+
75
+ export interface BuildingMiddleware<
76
+ RequestContextMap extends Record<string, RPCContextMap.Any>,
77
+ Provided extends keyof RequestContextMap,
78
+ Middlewares extends ReadonlyArray<MiddlewareMaker>,
48
79
  DynamicMiddlewareProviders,
49
- out MiddlewareR
80
+ out MiddlewareR extends { _tag: string } = never
50
81
  > {
51
- middleware<MW extends NonEmptyArray<GenericMiddlewareMaker>>(
52
- ...mw: MW
53
- ): MW extends NonEmptyArray<{ dynamic: RpcDynamic<any, RequestContext[keyof RequestContext]> }>
54
- ? DynamicMiddlewareMakerrsss<
55
- RequestContext,
56
- // when one dynamic middleware depends on another, substract the key, to enforce the dependency to be provided after.
57
- Exclude<
58
- Provided | MW[number]["dynamic"]["key"],
59
- { [K in keyof MW]: GetDependsOnKeys<MW[K]> }[number]
60
- >,
61
- [...Middlewares, ...MW],
62
- & DynamicMiddlewareProviders
63
- & {
64
- [U in MW[number] as U["dynamic"]["key"]]: U
65
- },
66
- GenericMiddlewareMaker.ApplyManyServices<MW, MiddlewareR>
67
- >
68
- : DynamicMiddlewareMakerrsss<
69
- RequestContext,
70
- Provided,
71
- [...Middlewares, ...MW],
72
- DynamicMiddlewareProviders,
73
- GenericMiddlewareMaker.ApplyManyServices<MW, MiddlewareR>
82
+ middleware<MWs extends NonEmptyArray<MiddlewareMaker>>(
83
+ ...mw: MWs
84
+ ): RecursiveHandleMWsSideways<MWs, {
85
+ rcm: RequestContextMap
86
+ provided: Provided
87
+ middlewares: Middlewares
88
+ dmp: DynamicMiddlewareProviders
89
+ middlewareR: MiddlewareR
90
+ }> extends infer Res extends {
91
+ rcm: RequestContextMap
92
+ provided: keyof RequestContextMap
93
+ middlewares: ReadonlyArray<MiddlewareMaker>
94
+ dmp: any
95
+ middlewareR: any
96
+ } ? MiddlewaresBuilder<
97
+ Res["rcm"],
98
+ Res["provided"],
99
+ Res["middlewares"],
100
+ Res["dmp"],
101
+ Res["middlewareR"]
74
102
  >
103
+ : never
104
+
105
+ // helps debugging what are the missing requirements (type only)
106
+ missing: {
107
+ missingDynamicMiddlewares: Exclude<keyof RequestContextMap, Provided>
108
+ missingContext: MiddlewareR
109
+ }
75
110
  }
76
111
 
77
- type DynamicMiddlewareMakerrsss<
78
- RequestContext extends Record<string, RPCContextMap.Any>,
79
- Provided extends keyof RequestContext = never,
80
- Middlewares extends ReadonlyArray<GenericMiddlewareMaker> = [],
112
+ export type MiddlewaresBuilder<
113
+ RequestContextMap extends Record<string, RPCContextMap.Any>,
114
+ Provided extends keyof RequestContextMap = never,
115
+ Middlewares extends ReadonlyArray<MiddlewareMaker> = [],
81
116
  DynamicMiddlewareProviders = unknown,
82
- MiddlewareR = never
83
- > = keyof Omit<RequestContext, Provided> extends never ? [MiddlewareR] extends [never] ?
84
- & ReturnType<
117
+ MiddlewareR extends { _tag: string } = never
118
+ > =
119
+ // keyof Omit<RequestContextMap, Provided> extends never is true when all the dynamic middlewares are provided
120
+ // MiddlewareR is never when all the required services from generic & dynamic middlewares are provided
121
+ keyof Omit<RequestContextMap, Provided> extends never ? [MiddlewareR] extends [never] ? ReturnType<
85
122
  typeof makeMiddlewareBasic<
86
- RequestContext,
123
+ RequestContextMap,
87
124
  Middlewares
88
125
  >
89
126
  >
90
- & MiddlewareM<
91
- RequestContext,
92
- Provided,
93
- Middlewares,
94
- DynamicMiddlewareProviders,
95
- MiddlewareR
96
- >
97
- : MiddlewareM<
98
- RequestContext,
99
- Provided,
100
- Middlewares,
101
- DynamicMiddlewareProviders,
102
- MiddlewareR
103
- >
104
- : MiddlewareDynamic<
105
- RequestContext,
106
- Provided,
107
- Middlewares,
108
- DynamicMiddlewareProviders,
109
- MiddlewareR
110
- >
127
+ : BuildingMiddleware<
128
+ RequestContextMap,
129
+ Provided,
130
+ Middlewares,
131
+ DynamicMiddlewareProviders,
132
+ MiddlewareR
133
+ >
134
+ : BuildingMiddleware<
135
+ RequestContextMap,
136
+ Provided,
137
+ Middlewares,
138
+ DynamicMiddlewareProviders,
139
+ MiddlewareR
140
+ >
111
141
 
112
142
  export const makeMiddleware: <
113
143
  RequestContextMap extends Record<string, RPCContextMap.Any>
114
- >() => DynamicMiddlewareMakerrsss<RequestContextMap> = () => {
115
- let allMiddleware: GenericMiddlewareMaker[] = []
144
+ >(rcm: RequestContextMap) => MiddlewaresBuilder<RequestContextMap> = (rcm) => {
145
+ let allMiddleware: MiddlewareMaker[] = []
116
146
  const it = {
117
147
  middleware: (...middlewares: any[]) => {
118
148
  for (const mw of middlewares) {
149
+ // recall that we run middlewares in reverse order
119
150
  allMiddleware = [mw, ...allMiddleware]
120
151
  }
121
- // TODO: support dynamic and generic intertwined. treat them as one
122
- return Object.assign(makeMiddlewareBasic<any, any>(...allMiddleware), it)
152
+ return allMiddleware.filter((m) => !!m.dynamic).length !== Object.keys(rcm).length
153
+ // for sure, until all the dynamic middlewares are provided it's non sensical to call makeMiddlewareBasic
154
+ ? it
155
+ // actually, we don't know yet if MiddlewareR is never, but we can't easily check it at runtime
156
+ : Object.assign(makeMiddlewareBasic<any, any>(rcm, ...allMiddleware), it)
123
157
  }
124
158
  }
125
159
  return it as any
126
160
  }
127
161
 
128
- export const makeMiddlewareBasic =
162
+ //
163
+ export interface MiddlewareMakerId {
164
+ readonly _id: unique symbol
165
+ }
166
+
167
+ // TODO: actually end up with [Tag<A, A>, Tag<B, B>, ...]
168
+ type MakeTags<A> = Context.Tag<A, A>
169
+
170
+ const makeMiddlewareBasic =
129
171
  // by setting RequestContextMap beforehand, execute contextual typing does not fuck up itself to anys
130
172
  <
131
173
  RequestContextMap extends Record<string, RPCContextMap.Any>,
132
- // RequestContextProviders extends RequestContextMapProvider<RequestContextMap>, // how to resolve the dynamic middleware
133
- GenericMiddlewareProviders extends ReadonlyArray<GenericMiddlewareMaker>
174
+ MiddlewareProviders extends ReadonlyArray<MiddlewareMaker>
134
175
  >(
135
- ...make: GenericMiddlewareProviders
176
+ _rcm: RequestContextMap,
177
+ ...make: MiddlewareProviders
136
178
  ) => {
137
- const MiddlewareMaker = Context.GenericTag<
138
- MiddlewareMakerId,
139
- {
140
- effect: RPCHandlerFactory<
141
- RequestContextMap,
142
- GenericMiddlewareMaker.Provided<GenericMiddlewareProviders[number]>
179
+ // reverse middlewares and wrap one after the other
180
+ const middleware = middlewareMaker(make)
181
+
182
+ const failures = make.map((_) => _.failure).filter(Boolean)
183
+ const provides = make.flatMap((_) => !_.provides ? [] : Array.isArray(_.provides) ? _.provides : [_.provides])
184
+ const requires = make
185
+ .flatMap((_) => !_.requires ? [] : Array.isArray(_.requires) ? _.requires : [_.requires])
186
+ .filter((_) => !provides.includes(_))
187
+
188
+ const MiddlewareMaker = Tag<MiddlewareMakerId>()("MiddlewareMaker", {
189
+ failure: (failures.length > 0
190
+ ? S.Union(...failures)
191
+ : S.Never) as unknown as MiddlewareMaker.ManyErrors<MiddlewareProviders> extends never ? never
192
+ : S.Schema<MiddlewareMaker.ManyErrors<MiddlewareProviders>>,
193
+ requires: (requires.length > 0
194
+ ? requires
195
+ : undefined) as unknown as Exclude<
196
+ MiddlewareMaker.ManyRequired<MiddlewareProviders>,
197
+ MiddlewareMaker.ManyProvided<MiddlewareProviders>
198
+ > extends never ? never : [
199
+ MakeTags<
200
+ Exclude<
201
+ MiddlewareMaker.ManyRequired<MiddlewareProviders>,
202
+ MiddlewareMaker.ManyProvided<MiddlewareProviders>
203
+ >
204
+ >
205
+ ],
206
+ provides: (provides.length > 0
207
+ ? provides
208
+ : undefined) as unknown as MiddlewareMaker.ManyProvided<MiddlewareProviders> extends never ? never : [
209
+ MakeTags<MiddlewareMaker.ManyProvided<MiddlewareProviders>>
210
+ ],
211
+ wrap: true
212
+ })(
213
+ middleware as {
214
+ dependencies: typeof middleware["dependencies"]
215
+ effect: Effect<
216
+ any, // TODO: why ?
217
+ Effect.Error<typeof middleware["effect"]>,
218
+ Effect.Context<typeof middleware["effect"]>
143
219
  >
144
- _tag: "MiddlewareMaker"
145
220
  }
146
- >(
147
- "MiddlewareMaker"
148
221
  )
149
222
 
150
- const middlewares = genericMiddlewareMaker(...make)
151
-
152
- const l = Layer.scoped(
153
- MiddlewareMaker,
154
- middlewares
155
- .effect
156
- .pipe(
157
- Effect.map((generic) => ({
158
- _tag: "MiddlewareMaker" as const,
159
- effect: makeRpcEffect<
160
- RequestContextMap,
161
- GenericMiddlewareMaker.Provided<GenericMiddlewareProviders[number]>
162
- >()(
163
- (schema, next, moduleName) => {
164
- return (payload, headers) =>
165
- Effect
166
- .gen(function*() {
167
- const basic = {
168
- config: schema.config ?? {},
169
- payload,
170
- headers,
171
- clientId: 0, // TODO: get the clientId from the request context
172
- rpc: {
173
- ...Rpc.fromTaggedRequest(schema as any),
174
- key: `${moduleName}.${payload._tag}`,
175
- _tag: `${moduleName}.${payload._tag}`
176
- }
177
- }
178
- return yield* generic({
179
- ...basic,
180
- next: next(payload, headers) as any
181
- })
182
- }) as any // why?
183
- }
184
- )
185
- }))
186
- )
187
- )
188
-
189
- const middlewareLayer = l
190
- .pipe(
191
- Layer.provide(middlewares.dependencies as any)
192
- ) as Layer.Layer<
193
- MiddlewareMakerId,
194
- LayerUtils.GetLayersError<typeof middlewares.dependencies>, // what could go wrong when building the dynamic middleware provider
195
- LayerUtils.GetLayersContext<typeof middlewares.dependencies>
196
- >
197
-
198
- return Object.assign(MiddlewareMaker, { Default: middlewareLayer })
223
+ // add to the tag a default implementation
224
+ return Object.assign(MiddlewareMaker, {
225
+ // tag to be used to retrieve the RequestContextConfig from RPC annotations
226
+ requestContext: Context.GenericTag<"RequestContextConfig", GetContextConfig<RequestContextMap>>(
227
+ "RequestContextConfig"
228
+ )
229
+ })
199
230
  }
@@ -23,8 +23,8 @@ export class RequestCacheMiddleware extends Tag<RequestCacheMiddleware>()("Reque
23
23
  }) {
24
24
  }
25
25
 
26
- export class ConfigureInterruptibility
27
- extends Tag<ConfigureInterruptibility>()("ConfigureInterruptibility", { wrap: true })({
26
+ export class ConfigureInterruptibilityMiddleware
27
+ extends Tag<ConfigureInterruptibilityMiddleware>()("ConfigureInterruptibilityMiddleware", { wrap: true })({
28
28
  effect: Effect.succeed(({ next }) =>
29
29
  next.pipe(
30
30
  // TODO: make this depend on query/command, and consider if middleware also should be affected. right now it's not.
@@ -35,7 +35,7 @@ export class ConfigureInterruptibility
35
35
  {
36
36
  }
37
37
 
38
- export class MiddlewareLogger extends Tag<MiddlewareLogger>()("MiddlewareLogger", { wrap: true })({
38
+ export class LoggerMiddleware extends Tag<LoggerMiddleware>()("LoggerMiddleware", { wrap: true })({
39
39
  effect: Effect.gen(function*() {
40
40
  const devMode = yield* DevMode
41
41
  return ({ headers, next, payload, rpc }) =>
@@ -98,6 +98,6 @@ export class MiddlewareLogger extends Tag<MiddlewareLogger>()("MiddlewareLogger"
98
98
 
99
99
  export const DefaultGenericMiddlewares = [
100
100
  RequestCacheMiddleware,
101
- ConfigureInterruptibility,
102
- MiddlewareLogger
101
+ ConfigureInterruptibilityMiddleware,
102
+ LoggerMiddleware
103
103
  ] as const
@@ -1,5 +1,4 @@
1
1
  // codegen:start {preset: barrel, include: ./middleware/*.ts, nodir: false }
2
- export * from "./middleware/ContextProvider.js"
3
2
  export * from "./middleware/dynamic-middleware.js"
4
3
  export * from "./middleware/generic-middleware.js"
5
4
  export * from "./middleware/middleware-api.js"
@@ -167,13 +167,17 @@ export const makeRouter = <
167
167
  RequestContextMap extends Record<string, RPCContextMap.Any>,
168
168
  MakeMiddlewareE,
169
169
  MakeMiddlewareR,
170
- ContextProviderA
170
+ ContextProviderA,
171
+ ContextProviderE,
172
+ ContextProviderR
171
173
  >(
172
174
  middleware: RouterMiddleware<
173
175
  RequestContextMap,
174
176
  MakeMiddlewareE,
175
177
  MakeMiddlewareR,
176
- ContextProviderA
178
+ ContextProviderA,
179
+ ContextProviderE,
180
+ ContextProviderR
177
181
  >,
178
182
  devMode: boolean
179
183
  ) => {
@@ -370,7 +374,6 @@ export const makeRouter = <
370
374
  : make
371
375
 
372
376
  const controllers = yield* make
373
- const rpc = yield* middleware
374
377
 
375
378
  // return make.pipe(Effect.map((c) => controllers(c, dependencies)))
376
379
  const mapped = typedKeysOf(requestModules).reduce((acc, cur) => {
@@ -400,16 +403,12 @@ export const makeRouter = <
400
403
  }
401
404
  } as any
402
405
  : resource,
403
- rpc.effect(
404
- resource,
405
- (req, headers) =>
406
- handle(req, headers).pipe(
407
- Effect.withSpan("Request." + meta.moduleName + "." + resource._tag, {
408
- captureStackTrace: () => handler.stack
409
- })
410
- ),
411
- meta.moduleName
412
- ),
406
+ (payload: any, headers: any) =>
407
+ handle(payload, headers).pipe(
408
+ Effect.withSpan("Request." + resource._tag, {
409
+ captureStackTrace: () => handler.stack // capturing the handler stack is the main reason why we are doing the span here
410
+ })
411
+ ),
413
412
  meta.moduleName
414
413
  ] as const
415
414
  return acc
@@ -431,16 +430,19 @@ export const makeRouter = <
431
430
  ]
432
431
  }
433
432
 
434
- const rpcs = RpcGroup.make(
435
- ...typedValuesOf(mapped).map(([resource]) => {
436
- return Rpc.fromTaggedRequest(resource)
437
- })
438
- )
433
+ const rpcs = RpcGroup
434
+ .make(
435
+ ...typedValuesOf(mapped).map(([resource]) => {
436
+ return Rpc.fromTaggedRequest(resource).annotate(middleware.requestContext, resource.config ?? {})
437
+ })
438
+ )
439
+ .prefix(`${meta.moduleName}.`)
440
+ .middleware(middleware as any)
439
441
  const rpcLayer = rpcs.toLayer(Effect.gen(function*() {
440
442
  return typedValuesOf(mapped).reduce((acc, [resource, handler]) => {
441
- acc[resource._tag] = handler
443
+ acc[`${meta.moduleName}.${resource._tag}`] = handler
442
444
  return acc
443
- }, {} as Record<string, any>)
445
+ }, {} as Record<string, any>) as any // TODO
444
446
  })) as unknown as Layer<
445
447
  { [K in keyof RequestModules]: Rpc.Handler<K> },
446
448
  | Layer.Error<typeof middleware.Default>
@@ -1,8 +1,8 @@
1
1
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
2
  /* eslint-disable @typescript-eslint/no-unsafe-member-access */
3
- import { expectTypeOf } from "@effect/vitest"
3
+ import { expectTypeOf, it } from "@effect/vitest"
4
4
  import { Context, Effect, Scope } from "effect-app"
5
- import { ContextProvider, mergeContextProviders, MergedContextProvider } from "../src/api/routing.js"
5
+ import { ContextProvider, mergeContextProviders, MergedContextProvider } from "../src/api/ContextProvider.js"
6
6
  import { CustomError1, Some, SomeElse, SomeService } from "./fixtures.js"
7
7
 
8
8
  // @effect-diagnostics-next-line missingEffectServiceDependency:off
@@ -119,33 +119,36 @@ export const someContextProviderGen = ContextProvider({
119
119
  }
120
120
  })
121
121
  })
122
- expectTypeOf(someContextProvider).toEqualTypeOf<typeof someContextProviderGen>()
123
122
 
124
- const merged = mergeContextProviders(MyContextProvider)
125
- const mergedGen = mergeContextProviders(MyContextProviderGen)
123
+ it("works", () => {
124
+ expectTypeOf(someContextProvider).toEqualTypeOf<typeof someContextProviderGen>()
126
125
 
127
- export const contextProvider2 = ContextProvider(merged)
128
- export const contextProvider3 = MergedContextProvider(MyContextProvider)
129
- expectTypeOf(contextProvider2).toEqualTypeOf<typeof someContextProvider>()
130
- expectTypeOf(contextProvider3).toEqualTypeOf<typeof contextProvider2>()
126
+ const merged = mergeContextProviders(MyContextProvider)
127
+ const mergedGen = mergeContextProviders(MyContextProviderGen)
131
128
 
132
- export const contextProvider2Gen = ContextProvider(mergedGen)
133
- export const contextProvider3Gen = MergedContextProvider(MyContextProviderGen)
134
- expectTypeOf(contextProvider2Gen).toEqualTypeOf<typeof someContextProvider>()
135
- expectTypeOf(contextProvider3Gen).toEqualTypeOf<typeof contextProvider2Gen>()
129
+ const contextProvider2 = ContextProvider(merged)
130
+ const contextProvider3 = MergedContextProvider(MyContextProvider)
131
+ expectTypeOf(contextProvider2).toEqualTypeOf<typeof someContextProvider>()
132
+ expectTypeOf(contextProvider3).toEqualTypeOf<typeof contextProvider2>()
136
133
 
137
- expectTypeOf(contextProvider2Gen).toEqualTypeOf<typeof contextProvider2>()
138
- expectTypeOf(contextProvider3Gen).toEqualTypeOf<typeof contextProvider3>()
134
+ const contextProvider2Gen = ContextProvider(mergedGen)
135
+ const contextProvider3Gen = MergedContextProvider(MyContextProviderGen)
136
+ expectTypeOf(contextProvider2Gen).toEqualTypeOf<typeof someContextProvider>()
137
+ expectTypeOf(contextProvider3Gen).toEqualTypeOf<typeof contextProvider2Gen>()
139
138
 
140
- const merged2 = mergeContextProviders(MyContextProvider, MyContextProvider2)
141
- export const contextProvider22 = ContextProvider(merged2)
142
- export const contextProvider23 = MergedContextProvider(MyContextProvider, MyContextProvider2)
143
- expectTypeOf(contextProvider23).toEqualTypeOf<typeof contextProvider22>()
139
+ expectTypeOf(contextProvider2Gen).toEqualTypeOf<typeof contextProvider2>()
140
+ expectTypeOf(contextProvider3Gen).toEqualTypeOf<typeof contextProvider3>()
144
141
 
145
- const merged2Gen = mergeContextProviders(MyContextProviderGen, MyContextProvider2Gen)
146
- export const contextProvider22Gen = ContextProvider(merged2Gen)
147
- export const contextProvider23Gen = MergedContextProvider(MyContextProviderGen, MyContextProvider2Gen)
148
- expectTypeOf(contextProvider23Gen).toEqualTypeOf<typeof contextProvider22Gen>()
142
+ const merged2 = mergeContextProviders(MyContextProvider, MyContextProvider2)
143
+ const contextProvider22 = ContextProvider(merged2)
144
+ const contextProvider23 = MergedContextProvider(MyContextProvider, MyContextProvider2)
145
+ expectTypeOf(contextProvider23).toEqualTypeOf<typeof contextProvider22>()
149
146
 
150
- expectTypeOf(contextProvider22Gen).toEqualTypeOf<typeof contextProvider22>()
151
- expectTypeOf(contextProvider23Gen).toEqualTypeOf<typeof contextProvider23>()
147
+ const merged2Gen = mergeContextProviders(MyContextProviderGen, MyContextProvider2Gen)
148
+ const contextProvider22Gen = ContextProvider(merged2Gen)
149
+ const contextProvider23Gen = MergedContextProvider(MyContextProviderGen, MyContextProvider2Gen)
150
+ expectTypeOf(contextProvider23Gen).toEqualTypeOf<typeof contextProvider22Gen>()
151
+
152
+ expectTypeOf(contextProvider22Gen).toEqualTypeOf<typeof contextProvider22>()
153
+ expectTypeOf(contextProvider23Gen).toEqualTypeOf<typeof contextProvider23>()
154
+ })