import type { Driver } from "@effect/core/io/Schedule" /** * Returns a new effect that repeats this effect according to the specified * schedule or until the first failure, at which point, the failure value and * schedule output are passed to the specified handler. * * Scheduled recurrences are in addition to the first execution, so that * `io.repeat(Schedule.once)` yields an effect that executes `io`, and then if * that succeeds, executes `io` an additional time. * * @tsplus static effect/core/io/Effect.Aspects repeatOrElseEither * @tsplus pipeable effect/core/io/Effect repeatOrElseEither */ export function repeatOrElseEither( schedule: Schedule, orElse: (e: E, option: Maybe) => Effect ): (self: Effect) => Effect> { return (self: Effect): Effect> => schedule.driver.flatMap((driver) => self.foldEffect( (e) => orElse(e, Maybe.none).map(Either.left), (a) => repeatOrElseEitherLoop(self, driver, orElse, a) ) ) } function repeatOrElseEitherLoop( self: Effect, driver: Driver, orElse: (e: E, option: Maybe) => Effect, value: A ): Effect> { return driver.next(value).foldEffect( () => driver.last.orDie.map(Either.right), (b) => self.foldEffect( (e) => orElse(e, Maybe.some(b)).map(Either.left), (a) => repeatOrElseEitherLoop(self, driver, orElse, a) ) ) }