// ets_tracing: off import type { HasClock } from "../Clock/index.js" import * as E from "../Either/index.js" import { pipe } from "../Function/index.js" import * as O from "../Option/index.js" import * as S from "../Schedule/index.js" import { chain } from "./core.js" import type { Effect } from "./effect.js" import { fail } from "./fail.js" import { foldM } from "./foldM.js" import * as map from "./map.js" import { orDie } from "./orDie.js" /** * 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. */ export function repeatOrElseEither_( self: Effect, schedule: S.Schedule, orElse: (_: E, __: O.Option) => Effect, __trace?: string ): Effect> { return pipe( S.driver(schedule), chain((driver) => { function loop(a: A): Effect> { return pipe( driver.next(a), foldM( () => pipe(orDie(driver.last), map.map(E.right)), (b) => pipe( self, foldM( (e) => pipe(orElse(e, O.some(b)), map.map(E.left)), (a) => loop(a) ) ) ) ) } return pipe( self, foldM( (e) => pipe(orElse(e, O.none), map.map(E.left)), (a) => loop(a), __trace ) ) }) ) } /** * 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. * * @ets_data_first repeatOrElseEither_ */ export function repeatOrElseEither( schedule: S.Schedule, orElse: (_: E, __: O.Option) => Effect, __trace?: string ): (self: Effect) => Effect> { return (self) => repeatOrElseEither_(self, schedule, orElse, __trace) } /** * 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. */ export function repeatOrElse_( self: Effect, schedule: S.Schedule, orElse: (_: E, __: O.Option) => Effect, __trace?: string ): Effect { return map.map_(repeatOrElseEither_(self, schedule, orElse, __trace), E.merge) } /** * 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. * * @ets_data_first repeatOrElse_ */ export function repeatOrElse( schedule: S.Schedule, orElse: (_: E, __: O.Option) => Effect, __trace?: string ): (self: Effect) => Effect { return (self) => repeatOrElse_(self, schedule, orElse, __trace) } /** * Returns a new effect that repeats this effect according to the specified * schedule or until the first failure. 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. */ export function repeat_( self: Effect, schedule: S.Schedule, __trace?: string ): Effect { return repeatOrElse_(self, schedule, (e) => fail(e), __trace) } /** * Returns a new effect that repeats this effect according to the specified * schedule or until the first failure. 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. * * @ets_data_first repeat_ */ export function repeat(schedule: S.Schedule, __trace?: string) { return (self: Effect): Effect => repeat_(self, schedule, __trace) }