import { DurationInternal } from "@tsplus/stdlib/data/Duration" /** * Retries constructing this layer according to the specified schedule. * * @tsplus static effect/core/io/Layer.Aspects retry * @tsplus pipeable effect/core/io/Layer retry */ export function retry(schedule: Schedule) { return (self: Layer): Layer => Layer.suspend(() => { const stateTag = Tag>() return Layer.succeed(stateTag)({ state: schedule.initial }) .flatMap((env) => loop(self, schedule, stateTag, env.get(stateTag).state)) }) } function loop( self: Layer, schedule: Schedule, stateTag: Tag>, s: S ): Layer { return self.catchAll((e) => update(schedule, stateTag, e, s).flatMap((env) => loop(self, schedule, stateTag, env.get(stateTag).state).fresh ) ) } interface UpdateState { readonly state: S } function update( schedule: Schedule, stateTag: Tag>, e: E, s: S ): Layer> { return Layer.fromEffect(stateTag)( Clock.currentTime.flatMap((now) => schedule.step(now, e, s).flatMap(([state, _, decision]) => decision._tag === "Done" ? Effect.fail(e) : Clock.sleep(new DurationInternal(decision.intervals.start - now)).as({ state }) ) ) ) }