Effect CommunityEC
Effect Communityโ€ข3mo agoโ€ข
6 replies
Kristian Notari

Handling Effect Dependencies and Propagation in TypeScript

Not sure if better here or in a effect-๐Ÿš€-like channel, but here we are:

I have an Operation which consists of a couple of named steps, like check --> prepare --> process. I do a bunch of things between every step which is always the same, no matter the step itself. The step itself can differ quite a lot between different "operations".

I'd like to describe the steps (check, prepare, process) as a function (input: A) => Effect<B, E, R>.

Those steps are then ran in order by some common logic. Of course an operation NEEDS to define all the steps in order to be run.

I thought about using an effect for the running bit, which needs those 3 steps as requirements. My problem is that propagating correctly the E, R channels of those steps seems like a painful thing to achieve in typescript. Is there a way around it? Is asking for an effect with error and requirement channels as a requirement of another effect something I shouldn't do, and use X instead?

I experimented with this approach because I wanted to try avoid builder pattern for example.

Example:

type A = string
type B = number
const checkStep = (input: A) => Effect.succed(42)
const prepareStep = (input: A) => Effect.fail(new Error())
const processStep = (input: A) => Effect.suceed(42)

const Check extends Config.Tag('check')<Check, (input: A) => Effect<B, ?, ?>> {}
const Prepare extends Config.Tag('check')<Prepare, (input: A) => Effect<B, ?, ?>> {}
const Process extends Config.Tag('check')<Process, (input: A) => Effect<B, ?, ?>> {}

const run = (input: A) => Effect.gen(function* () {
   const check = yield* (Check)
   const prepare = yield* (Prepare)
   const process = yield* (Process)

   yield* Effect.all([
      check(input),
      prepare(input),
      process(input)
   ])
})

Effect.runPromise(run.pipe(
    Effect.provideService(Check, checkStep),
    Effect.provideService(Prepare, prepareStep),
    Effect.provideService(Process, processStep),
))
Was this page helpful?