@effect-app/infra 2.86.0 → 2.87.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 (49) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/api/layerUtils.d.ts +1 -5
  3. package/dist/api/layerUtils.d.ts.map +1 -1
  4. package/dist/api/layerUtils.js +3 -11
  5. package/dist/api/routing/middleware/RouterMiddleware.d.ts +33 -0
  6. package/dist/api/routing/middleware/RouterMiddleware.d.ts.map +1 -0
  7. package/dist/api/routing/middleware/RouterMiddleware.js +5 -0
  8. package/dist/api/routing/middleware/RpcMiddleware.d.ts +199 -0
  9. package/dist/api/routing/middleware/RpcMiddleware.d.ts.map +1 -0
  10. package/dist/api/routing/middleware/RpcMiddleware.js +14 -0
  11. package/dist/api/routing/middleware/dynamic-middleware.d.ts +2 -12
  12. package/dist/api/routing/middleware/dynamic-middleware.d.ts.map +1 -1
  13. package/dist/api/routing/middleware/dynamic-middleware.js +2 -18
  14. package/dist/api/routing/middleware/generic-middleware.d.ts +4 -23
  15. package/dist/api/routing/middleware/generic-middleware.d.ts.map +1 -1
  16. package/dist/api/routing/middleware/generic-middleware.js +13 -9
  17. package/dist/api/routing/middleware/middleware-api.d.ts +43 -7
  18. package/dist/api/routing/middleware/middleware-api.d.ts.map +1 -1
  19. package/dist/api/routing/middleware/middleware-api.js +47 -22
  20. package/dist/api/routing/middleware/middleware.d.ts +3 -3
  21. package/dist/api/routing/middleware/middleware.js +2 -2
  22. package/dist/api/routing/middleware.d.ts +2 -1
  23. package/dist/api/routing/middleware.d.ts.map +1 -1
  24. package/dist/api/routing/middleware.js +3 -2
  25. package/dist/api/routing/tsort.d.ts +2 -2
  26. package/dist/api/routing/tsort.d.ts.map +1 -1
  27. package/dist/api/routing/tsort.js +1 -1
  28. package/package.json +9 -5
  29. package/src/api/layerUtils.ts +4 -18
  30. package/src/api/routing/middleware/RouterMiddleware.ts +149 -0
  31. package/src/api/routing/middleware/RpcMiddleware.ts +287 -0
  32. package/src/api/routing/middleware/dynamic-middleware.ts +5 -52
  33. package/src/api/routing/middleware/generic-middleware.ts +23 -34
  34. package/src/api/routing/middleware/middleware-api.ts +142 -59
  35. package/src/api/routing/middleware/middleware.ts +1 -1
  36. package/src/api/routing/middleware.ts +2 -1
  37. package/src/api/routing/tsort.ts +2 -2
  38. package/test/controller.test.ts +22 -58
  39. package/test/dist/controller.test.d.ts.map +1 -1
  40. package/test/dist/fixtures.d.ts +4 -2
  41. package/test/dist/fixtures.d.ts.map +1 -1
  42. package/test/dist/fixtures.js +21 -9
  43. package/test/dist/requires.test.d.ts.map +1 -1
  44. package/test/fixtures.ts +29 -12
  45. package/test/requires.test.ts +98 -17
  46. package/dist/api/routing/middleware/DynamicMiddleware.d.ts +0 -229
  47. package/dist/api/routing/middleware/DynamicMiddleware.d.ts.map +0 -1
  48. package/dist/api/routing/middleware/DynamicMiddleware.js +0 -168
  49. package/src/api/routing/middleware/DynamicMiddleware.ts +0 -715
@@ -0,0 +1,287 @@
1
+ /* eslint-disable @typescript-eslint/no-unsafe-assignment */
2
+ /* eslint-disable @typescript-eslint/no-unsafe-return */
3
+ /* eslint-disable @typescript-eslint/no-explicit-any */
4
+ import { type Rpc, RpcMiddleware } from "@effect/rpc"
5
+ import { type SuccessValue, type TypeId } from "@effect/rpc/RpcMiddleware"
6
+ import { type Context, type Effect, Layer, type NonEmptyReadonlyArray, type Option, type S, type Schema, type Scope, Unify } from "effect-app"
7
+ import type { AnyService, ContextRepr, RPCContextMap } from "effect-app/client/req"
8
+ import { type HttpHeaders } from "effect-app/http"
9
+ import { type TagUnify, type TagUnifyIgnore } from "effect/Context"
10
+ import { type LayerUtils } from "../../layerUtils.js"
11
+
12
+ // updated to support Scope.Scope
13
+ export interface RpcMiddleware<Provides, E, Requires> {
14
+ (options: {
15
+ readonly clientId: number
16
+ readonly rpc: Rpc.AnyWithProps
17
+ readonly payload: unknown
18
+ readonly headers: HttpHeaders.Headers
19
+ }): Effect.Effect<Provides, E, Scope.Scope | Requires>
20
+ }
21
+ export interface RpcMiddlewareWrap<Provides, E, Requires> {
22
+ (options: {
23
+ readonly clientId: number
24
+ readonly rpc: Rpc.AnyWithProps
25
+ readonly payload: unknown
26
+ readonly headers: HttpHeaders.Headers
27
+ readonly next: Effect.Effect<SuccessValue, E, Provides | Scope.Scope | Requires>
28
+ }): Effect.Effect<SuccessValue, E, Scope.Scope | Requires>
29
+ }
30
+
31
+ type RpcOptionsOriginal = {
32
+ readonly wrap?: boolean
33
+ readonly optional?: boolean
34
+ readonly failure?: Schema.Schema.All
35
+ readonly provides?: AnyService
36
+ readonly requiredForClient?: boolean
37
+ }
38
+
39
+ export type RpcDynamic<Key extends string, A extends RPCContextMap.Any> = {
40
+ key: Key
41
+ settings: A
42
+ }
43
+
44
+ export type AnyDynamic = { dynamic: RpcDynamic<any, any> }
45
+
46
+ export type DependsOn = {
47
+ readonly dependsOn: NonEmptyReadonlyArray<AnyDynamic> | undefined
48
+ }
49
+
50
+ type RpcOptionsDynamic<Key extends string, A extends RPCContextMap.Any> = RpcOptionsOriginal & {
51
+ readonly dynamic: RpcDynamic<Key, A>
52
+ readonly dependsOn?: NonEmptyReadonlyArray<AnyDynamic> | undefined
53
+ }
54
+
55
+ export type Dynamic<Options> = Options extends RpcOptionsDynamic<any, any> ? true : false
56
+
57
+ export interface RpcMiddlewareDynamicWrap<E, R, Config> {
58
+ (options: {
59
+ readonly next: Effect.Effect<SuccessValue, E, Scope.Scope | R>
60
+ readonly config: Config // todo
61
+ readonly clientId: number
62
+ readonly rpc: Rpc.AnyWithProps
63
+ readonly payload: unknown
64
+ readonly headers: HttpHeaders.Headers
65
+ }): Effect.Effect<
66
+ SuccessValue,
67
+ E,
68
+ Scope.Scope | R
69
+ >
70
+ }
71
+
72
+ export interface RpcMiddlewareDynamicNormal<A, E, R, Config> {
73
+ (options: {
74
+ readonly config: Config // todo
75
+ readonly clientId: number
76
+ readonly rpc: Rpc.AnyWithProps
77
+ readonly payload: unknown
78
+ readonly headers: HttpHeaders.Headers
79
+ }): Effect.Effect<
80
+ Option.Option<A>,
81
+ E,
82
+ Scope.Scope | R
83
+ >
84
+ }
85
+
86
+ export interface TagClassAny extends Context.Tag<any, any> {
87
+ readonly [TypeId]: TypeId
88
+ readonly optional: boolean
89
+ readonly provides?: Context.Tag<any, any> | ContextRepr | undefined
90
+ readonly requires?: Context.Tag<any, any> | ContextRepr | undefined
91
+ readonly failure: Schema.Schema.All
92
+ readonly requiredForClient: boolean
93
+ readonly wrap: boolean
94
+ readonly dynamic?: RpcDynamic<any, any> | undefined
95
+ readonly dependsOn?: NonEmptyReadonlyArray<AnyDynamic> | undefined
96
+ }
97
+
98
+ export declare namespace TagClass {
99
+ /**
100
+ * @since 1.0.0
101
+ * @category models
102
+ */
103
+ export type Provides<Options> = Options extends {
104
+ readonly provides: Context.Tag<any, any>
105
+ readonly optional?: false
106
+ } ? Context.Tag.Identifier<Options["provides"]>
107
+ : Options extends {
108
+ readonly provides: ContextRepr
109
+ readonly optional?: false
110
+ } ? ContextRepr.Identifier<Options["provides"]>
111
+ : never
112
+
113
+ /**
114
+ * @since 1.0.0
115
+ * @category models
116
+ */
117
+ export type Requires<Options> = Options extends {
118
+ readonly requires: Context.Tag<any, any>
119
+ } ? Context.Tag.Identifier<Options["requires"]>
120
+ : Options extends {
121
+ readonly requires: ContextRepr
122
+ } ? ContextRepr.Identifier<Options["requires"]>
123
+ : never
124
+
125
+ /**
126
+ * @since 1.0.0
127
+ * @category models
128
+ */
129
+ export type Service<Options> = Options extends { readonly provides: Context.Tag<any, any> }
130
+ ? Context.Tag.Service<Options["provides"]>
131
+ : Options extends { readonly dynamic: RpcDynamic<any, infer A> }
132
+ ? Options extends { wrap: true } ? void : AnyService.Bla<A["service"]>
133
+ : Options extends { readonly provides: ContextRepr } ? Context.Context<ContextRepr.Identifier<Options["provides"]>>
134
+ : void
135
+
136
+ /**
137
+ * @since 1.0.0
138
+ * @category models
139
+ */
140
+ export type FailureSchema<Options> = Options extends
141
+ { readonly failure: Schema.Schema.All; readonly optional?: false } ? Options["failure"]
142
+ : Options extends { readonly dynamic: RpcDynamic<any, infer A> } ? A["error"]
143
+ : typeof Schema.Never
144
+
145
+ /**
146
+ * @since 1.0.0
147
+ * @category models
148
+ */
149
+ export type Failure<Options> = Options extends
150
+ { readonly failure: Schema.Schema<infer _A, infer _I, infer _R>; readonly optional?: false } ? _A
151
+ : Options extends { readonly dynamic: RpcDynamic<any, infer A> } ? S.Schema.Type<A["error"]>
152
+ : never
153
+
154
+ /**
155
+ * @since 1.0.0
156
+ * @category models
157
+ */
158
+ export type FailureContext<Options> = Schema.Schema.Context<FailureSchema<Options>>
159
+
160
+ /**
161
+ * @since 1.0.0
162
+ * @category models
163
+ */
164
+ export type FailureService<Options> = Optional<Options> extends true ? unknown : Failure<Options>
165
+
166
+ /**
167
+ * @since 1.0.0
168
+ * @category models
169
+ */
170
+ export type Optional<Options> = Options extends { readonly optional: true } ? true : false
171
+
172
+ /**
173
+ * @since 1.0.0
174
+ * @category models
175
+ */
176
+ export type RequiredForClient<Options> = Options extends { readonly requiredForClient: true } ? true : false
177
+
178
+ /**
179
+ * @since 1.0.0
180
+ * @category models
181
+ */
182
+ export type Wrap<Options> = Options extends { readonly wrap: true } ? true : false
183
+
184
+ /**
185
+ * @since 1.0.0
186
+ * @category models
187
+ */
188
+ export interface Base<Self, Name extends string, Options, Service> extends Context.Tag<Self, Service> {
189
+ new(_: never): Context.TagClassShape<Name, Service>
190
+ readonly [TypeId]: TypeId
191
+ readonly optional: Optional<Options>
192
+ readonly failure: FailureSchema<Options>
193
+ readonly provides: Options extends { readonly provides: Context.Tag<any, any> } ? Options["provides"]
194
+ : Options extends { readonly provides: ContextRepr } ? Options["provides"]
195
+ : undefined
196
+ readonly requires: Options extends { readonly requires: Context.Tag<any, any> } ? Options["requires"]
197
+ : Options extends { readonly requires: ContextRepr } ? Options["requires"]
198
+ : undefined
199
+ readonly dynamic: Options extends RpcOptionsDynamic<any, any> ? Options["dynamic"]
200
+ : undefined
201
+ readonly dependsOn: Options extends DependsOn ? Options["dependsOn"] : undefined
202
+ readonly requiredForClient: RequiredForClient<Options>
203
+ readonly wrap: Wrap<Options>
204
+ }
205
+ }
206
+
207
+ export interface TagClass<
208
+ Self,
209
+ Name extends string,
210
+ Options
211
+ > extends
212
+ TagClass.Base<
213
+ Self,
214
+ Name,
215
+ Options,
216
+ Options extends RpcOptionsDynamic<any, any> ? TagClass.Wrap<Options> extends true ? RpcMiddlewareDynamicWrap<
217
+ TagClass.FailureService<Options>,
218
+ TagClass.Requires<Options>,
219
+ { [K in Options["dynamic"]["key"]]?: Options["dynamic"]["settings"]["contextActivation"] }
220
+ >
221
+ : RpcMiddlewareDynamicNormal<
222
+ TagClass.Service<Options>,
223
+ TagClass.FailureService<Options>,
224
+ TagClass.Requires<Options>,
225
+ { [K in Options["dynamic"]["key"]]?: Options["dynamic"]["settings"]["contextActivation"] }
226
+ >
227
+ : TagClass.Wrap<Options> extends true ? RpcMiddlewareWrap<
228
+ TagClass.Provides<Options>,
229
+ TagClass.Requires<Options>,
230
+ TagClass.Failure<Options>
231
+ >
232
+ : RpcMiddleware<
233
+ TagClass.Service<Options>,
234
+ TagClass.FailureService<Options>,
235
+ TagClass.Requires<Options>
236
+ >
237
+ >
238
+ {}
239
+
240
+ export const Tag = <Self>() =>
241
+ <
242
+ const Name extends string,
243
+ const Options extends RpcOptionsOriginal | RpcOptionsDynamic<any, any>
244
+ >(
245
+ id: Name,
246
+ options?: Options | undefined
247
+ ) =>
248
+ <E, R, L extends NonEmptyReadonlyArray<Layer.Layer.Any>>(opts: {
249
+ effect: Effect.Effect<
250
+ Options extends RpcOptionsDynamic<any, any> ? TagClass.Wrap<Options> extends true ? RpcMiddlewareDynamicWrap<
251
+ TagClass.FailureService<Options>,
252
+ TagClass.Requires<Options>,
253
+ { [K in Options["dynamic"]["key"]]?: Options["dynamic"]["settings"]["contextActivation"] }
254
+ >
255
+ : RpcMiddlewareDynamicNormal<
256
+ TagClass.Service<Options>,
257
+ TagClass.FailureService<Options>,
258
+ TagClass.Requires<Options>,
259
+ { [K in Options["dynamic"]["key"]]?: Options["dynamic"]["settings"]["contextActivation"] }
260
+ >
261
+ : TagClass.Wrap<Options> extends true ? RpcMiddlewareWrap<
262
+ TagClass.Provides<Options>,
263
+ TagClass.Failure<Options>,
264
+ TagClass.Requires<Options>
265
+ >
266
+ : RpcMiddleware<
267
+ TagClass.Service<Options>,
268
+ TagClass.FailureService<Options>,
269
+ TagClass.Requires<Options>
270
+ >,
271
+ E,
272
+ R
273
+ >
274
+ dependencies?: L
275
+ }): TagClass<Self, Name, Options> & {
276
+ Default: Layer.Layer<Self, E | LayerUtils.GetLayersError<L>, Exclude<R, LayerUtils.GetLayersSuccess<L>>>
277
+ } =>
278
+ class extends RpcMiddleware.Tag<Self>()(id, options as any) {
279
+ static readonly dynamic = options && "dynamic" in options ? options.dynamic : undefined
280
+ static readonly dependsOn = options && "dependsOn" in options ? options.dependsOn : undefined
281
+ static readonly Default = Layer.scoped(this, opts.effect as any).pipe(
282
+ Layer.provide([Layer.empty, ...opts.dependencies ?? []])
283
+ )
284
+ static override [Unify.typeSymbol]?: unknown
285
+ static override [Unify.unifySymbol]?: TagUnify<typeof this>
286
+ static override [Unify.ignoreSymbol]?: TagUnifyIgnore
287
+ } as any
@@ -1,12 +1,9 @@
1
1
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
- import { Array, type Context, Effect, type S } from "effect-app"
3
- import { type GetEffectContext, type RPCContextMap } from "effect-app/client"
4
- import { type Tag } from "effect-app/Context"
5
- import { type HttpHeaders } from "effect-app/http"
6
- import { typedValuesOf } from "effect-app/utils"
7
- import { type ContextTagWithDefault, mergeOptionContexts } from "../../layerUtils.js"
8
- import { sort } from "../tsort.js"
9
- import { type RpcMiddlewareDynamic } from "./DynamicMiddleware.js"
2
+ import { type ContextTagWithDefault } from "../../layerUtils.js"
3
+ import { type RpcMiddlewareDynamicNormal, type RpcMiddlewareDynamicWrap } from "./RpcMiddleware.js"
4
+
5
+ export type RpcMiddlewareDynamic<A, E, R, Config> = [A] extends [void] ? RpcMiddlewareDynamicWrap<E, R, Config>
6
+ : RpcMiddlewareDynamicNormal<A, E, R, Config>
10
7
 
11
8
  export type ContextWithLayer<
12
9
  Config,
@@ -48,47 +45,3 @@ export namespace ContextWithLayer {
48
45
  any
49
46
  >
50
47
  }
51
-
52
- // Effect Rpc Middleware: no substitute atm. though maybe something could be achieved with Wrap, we just don't have type safety on the Request input etc.
53
- export const implementMiddleware = <T extends Record<string, RPCContextMap.Any>>() =>
54
- <
55
- TI extends {
56
- [K in keyof T]: ContextWithLayer.Base<
57
- { [K in keyof T]?: T[K]["contextActivation"] },
58
- T[K]["service"],
59
- S.Schema.Type<T[K]["error"]>
60
- >
61
- }
62
- >(implementations: TI) => ({
63
- dependencies: typedValuesOf(implementations).map((_) => _.Default) as {
64
- [K in keyof TI]: TI[K]["Default"]
65
- }[keyof TI][],
66
- effect: Effect.gen(function*() {
67
- const sorted = sort(typedValuesOf(implementations))
68
-
69
- const makers = yield* Effect.all(sorted)
70
- return Effect.fnUntraced(
71
- function*(options: { config: { [K in keyof T]?: T[K]["contextActivation"] }; headers: HttpHeaders.Headers }) {
72
- const ctx = yield* mergeOptionContexts(
73
- Array.map(
74
- makers,
75
- (_, i) => ({ maker: sorted[i], handle: (_ as any)(options) as any }) as any
76
- )
77
- )
78
- return ctx as Context.Context<
79
- GetEffectContext<T, typeof options["config"]>
80
- >
81
- }
82
- )
83
- }) as unknown as Effect<
84
- (
85
- options: { config: { [K in keyof T]?: T[K]["contextActivation"] }; headers: HttpHeaders.Headers }
86
- ) => Effect.Effect<
87
- Context.Context<GetEffectContext<T, typeof options["config"]>>,
88
- Effect.Error<ReturnType<Tag.Service<TI[keyof TI]>>>,
89
- Effect.Context<ReturnType<Tag.Service<TI[keyof TI]>>>
90
- >,
91
- never,
92
- Tag.Identifier<{ [K in keyof TI]: TI[K] }[keyof TI]>
93
- >
94
- })
@@ -1,28 +1,11 @@
1
1
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
2
  import { type Rpc, type RpcMiddleware } from "@effect/rpc"
3
- import { type SuccessValue, type TypeId } from "@effect/rpc/RpcMiddleware"
4
- import { type Array, Context, Effect, type Layer, type NonEmptyReadonlyArray, type Schema, type Scope } from "effect-app"
5
- import { type RPCContextMap } from "effect-app/client"
3
+ import { type SuccessValue } from "@effect/rpc/RpcMiddleware"
4
+ import { type Array, Context, Effect, type Layer, type NonEmptyReadonlyArray, Option, type Scope } from "effect-app"
5
+ import { type ContextRepr } from "effect-app/client"
6
6
  import { type HttpHeaders } from "effect-app/http"
7
- import { type Tag } from "effect/Context"
8
7
  import { InfraLogger } from "../../../logger.js"
9
- import { type TagClassDynamicAny } from "./DynamicMiddleware.js"
10
-
11
- export type ContextRepr = NonEmptyReadonlyArray<Context.Tag<any, any>>
12
- export namespace ContextRepr {
13
- export type Identifier<A> = A extends ContextRepr ? Tag.Identifier<A[number]> : never
14
- export type Service<A> = A extends ContextRepr ? Tag.Service<A[number]> : never
15
- }
16
-
17
- export interface TagClassAny extends Context.Tag<any, any> {
18
- readonly [TypeId]: TypeId
19
- readonly optional: boolean
20
- readonly provides?: Context.Tag<any, any> | ContextRepr | undefined
21
- readonly requires?: Context.Tag<any, any> | ContextRepr | undefined
22
- readonly failure: Schema.Schema.All
23
- readonly requiredForClient: boolean
24
- readonly wrap: boolean
25
- }
8
+ import { type TagClassAny } from "./RpcMiddleware.js"
26
9
 
27
10
  export interface GenericMiddlewareOptions<E> {
28
11
  // Effect rpc middleware does not support changing payload or headers, but we do..
@@ -34,9 +17,6 @@ export interface GenericMiddlewareOptions<E> {
34
17
  }
35
18
 
36
19
  export type GenericMiddlewareMaker = TagClassAny & { Default: Layer.Layer.Any } // todo; and Layer..
37
- export type DynamicMiddlewareMaker<RequestContext extends Record<string, RPCContextMap.Any>> =
38
- & TagClassDynamicAny<RequestContext>
39
- & { Default: Layer.Layer.Any } // todo; and Layer..
40
20
 
41
21
  export namespace GenericMiddlewareMaker {
42
22
  export type ApplyServices<A extends TagClassAny, R> = Exclude<R, Provided<A>> | Required<A>
@@ -56,8 +36,6 @@ export namespace GenericMiddlewareMaker {
56
36
  : never
57
37
  }
58
38
 
59
- export const genericMiddleware = (i: GenericMiddlewareMaker) => i
60
-
61
39
  export const genericMiddlewareMaker = <
62
40
  T extends Array<GenericMiddlewareMaker>
63
41
  >(...middlewares: T): {
@@ -70,11 +48,6 @@ export const genericMiddlewareMaker = <
70
48
  dependencies: middlewares.map((_) => _.Default),
71
49
  effect: Effect.gen(function*() {
72
50
  const context = yield* Effect.context()
73
- // const middlewares: readonly (RpcMiddlewareWrap<any, any> | RpcMiddleware.RpcMiddleware<any, any>)[] =
74
- // (yield* Effect.all(
75
- // middlewares
76
- // )) as any
77
-
78
51
  return <E>(
79
52
  options: GenericMiddlewareOptions<E>
80
53
  ) => {
@@ -83,13 +56,13 @@ export const genericMiddlewareMaker = <
83
56
  for (const tag of middlewares) {
84
57
  if (tag.wrap) {
85
58
  const middleware = Context.unsafeGet(context, tag)
86
- handler = InfraLogger.logDebug("Applying middleware " + tag.key).pipe(
87
- Effect.zipRight(middleware({ ...options, next: handler as any }))
59
+ handler = InfraLogger.logDebug("Applying middleware wrap " + tag.key).pipe(
60
+ Effect.zipRight(middleware({ ...options, next: handler }))
88
61
  ) as any
89
62
  } else if (tag.optional) {
90
63
  const middleware = Context.unsafeGet(context, tag) as RpcMiddleware.RpcMiddleware<any, any>
91
64
  const previous = handler
92
- handler = InfraLogger.logDebug("Applying middleware " + tag.key).pipe(
65
+ handler = InfraLogger.logDebug("Applying middleware optional " + tag.key).pipe(
93
66
  Effect.zipRight(Effect.matchEffect(middleware(options), {
94
67
  onFailure: () => previous,
95
68
  onSuccess: tag.provides !== undefined
@@ -100,6 +73,22 @@ export const genericMiddlewareMaker = <
100
73
  : (_) => previous
101
74
  }))
102
75
  )
76
+ } else if (tag.dynamic) {
77
+ const middleware = Context.unsafeGet(context, tag) as RpcMiddleware.RpcMiddleware<any, any>
78
+ const previous = handler
79
+ handler = InfraLogger.logDebug("Applying middleware dynamic " + tag.key, tag.dynamic).pipe(
80
+ Effect.zipRight(
81
+ middleware(options).pipe(
82
+ Effect.flatMap((value) =>
83
+ Option.isSome(value)
84
+ ? Context.isContext(value.value)
85
+ ? Effect.provide(previous, value.value)
86
+ : Effect.provideService(previous, tag.dynamic!.settings.service!, /* TODO */ value.value)
87
+ : previous
88
+ )
89
+ )
90
+ )
91
+ )
103
92
  } else {
104
93
  const middleware = Context.unsafeGet(context, tag) as RpcMiddleware.RpcMiddleware<any, any>
105
94
  const previous = handler