Effect CommunityEC
Effect Community2y ago
25 replies
acron

Defining Context at initialisation for Layers

I am fairly committed to layered architecture and it works well most of the time where variables often come from Config. In this instance though I would like to provide Context to a service but that Context is computed inside the service, only availablat "yield time" (?). Not using Context right now, but this means a lot of repetitive passing of arguments and I'd like to find a way, if possible, to do this in a way where I can still represent ServiceX (in the example below) as a Context requirement of ServiceA.


What I am doing

export const ServiceX = Layer.effect(
   ServiceX,
   Effect.gen(function* (_) {
       const doSomething = (args: {rate:any}) => Effect.Effect<whatever>
       ...
   }
)

export const ServiceA = Layer.effect(
   ServiceA,
   Effect.gen(function* (_) {
       const configForServiceX = {rate: doSomeCalculation()}
           const serviceX = yield* ServiceX
       

       const resultA = yield* serviceX.doSomething(configForServiceX)
       const resultB = yield* serviceX.doSomethingElse(configForServiceX)
       const resultC = yield* serviceX.doSomethingElseAgain(configForServiceX)
       ...
   }
)


What I'd like to do
export const ServiceX = Layer.effect(
   ServiceX,
   Effect.gen(function* (_) {
           
       const doSomething = () => Effect.Effect<whatever, whatever, {rate: any}> // context here?
       ...
   }
)

export const ServiceA = Layer.effect(
   ServiceA,
   Effect.gen(function* (_) {
       const configForServiceX = {rate: doSomeCalculation()}
       const serviceX = yield* withContext(ServiceX, configForServiceX))
       

       const resultA = yield* serviceX.doSomething()
       const resultB = yield* serviceX.doSomethingElse()
       const resultC = yield* serviceX.doSomethingElseAgain()
       ...
   }
)


My Effect-fu is lacking so guidance appreciated.
Was this page helpful?