effect
Version:
The missing standard library for TypeScript, for writing production-grade software.
1,400 lines (1,357 loc) • 131 kB
text/typescript
/**
* @since 2.0.0
*/
import type * as Cause from "./Cause.js"
import type * as Chunk from "./Chunk.js"
import type * as Context from "./Context.js"
import type * as Cron from "./Cron.js"
import type * as DateTime from "./DateTime.js"
import type * as Duration from "./Duration.js"
import type * as Effect from "./Effect.js"
import type * as Either from "./Either.js"
import type { LazyArg } from "./Function.js"
import * as internal from "./internal/schedule.js"
import type * as Option from "./Option.js"
import type { Pipeable } from "./Pipeable.js"
import type { Predicate } from "./Predicate.js"
import type * as ScheduleDecision from "./ScheduleDecision.js"
import type * as Intervals from "./ScheduleIntervals.js"
import type * as Types from "./Types.js"
/**
* @since 2.0.0
* @category Symbols
*/
export const ScheduleTypeId: unique symbol = internal.ScheduleTypeId
/**
* @since 2.0.0
* @category Symbols
*/
export type ScheduleTypeId = typeof ScheduleTypeId
/**
* @since 2.0.0
* @category Symbols
*/
export const ScheduleDriverTypeId: unique symbol = internal.ScheduleDriverTypeId
/**
* @since 2.0.0
* @category Symbols
*/
export type ScheduleDriverTypeId = typeof ScheduleDriverTypeId
/**
* A `Schedule<Out, In, R>` defines a recurring schedule, which consumes values
* of type `In`, and which returns values of type `Out`.
*
* The `Schedule` type is structured as follows:
*
* ```text
* ┌─── The type of output produced by the schedule
* │ ┌─── The type of input consumed by the schedule
* │ │ ┌─── Additional requirements for the schedule
* ▼ ▼ ▼
* Schedule<Out, In, Requirements>
* ```
*
* A schedule operates by consuming values of type `In` (such as errors in the
* case of `Effect.retry`, or values in the case of `Effect.repeat`) and
* producing values of type `Out`. It determines when to halt or continue the
* execution based on input values and its internal state.
*
* The inclusion of a `Requirements` parameter allows the schedule to leverage
* additional services or resources as needed.
*
* Schedules are defined as a possibly infinite set of intervals spread out over
* time. Each interval defines a window in which recurrence is possible.
*
* When schedules are used to repeat or retry effects, the starting boundary of
* each interval produced by a schedule is used as the moment when the effect
* will be executed again.
*
* Schedules can be composed in different ways:
*
* - Union: Combines two schedules and recurs if either schedule wants to
* continue, using the shorter delay.
* - Intersection: Combines two schedules and recurs only if both schedules want
* to continue, using the longer delay.
* - Sequencing: Combines two schedules by running the first one fully, then
* switching to the second.
*
* In addition, schedule inputs and outputs can be transformed, filtered (to
* terminate a schedule early in response to some input or output), and so
* forth.
*
* A variety of other operators exist for transforming and combining schedules,
* and the companion object for `Schedule` contains all common types of
* schedules, both for performing retrying, as well as performing repetition.
*
* @category Model
* @since 2.0.0
*/
export interface Schedule<out Out, in In = unknown, out R = never> extends Schedule.Variance<Out, In, R>, Pipeable {
/**
* Initial State
*/
readonly initial: any
/**
* Schedule Step
*/
step(
now: number,
input: In,
state: any
): Effect.Effect<readonly [any, Out, ScheduleDecision.ScheduleDecision], never, R>
}
/**
* @since 2.0.0
*/
export declare namespace Schedule {
/**
* @since 2.0.0
* @category Models
*/
export interface Variance<out Out, in In, out R> {
readonly [ScheduleTypeId]: {
readonly _Out: Types.Covariant<Out>
readonly _In: Types.Contravariant<In>
readonly _R: Types.Covariant<R>
}
}
/**
* @since 2.0.0
*/
export interface DriverVariance<out Out, in In, out R> {
readonly [ScheduleDriverTypeId]: {
readonly _Out: Types.Covariant<Out>
readonly _In: Types.Contravariant<In>
readonly _R: Types.Covariant<R>
}
}
}
/**
* @since 2.0.0
* @category Models
*/
export interface ScheduleDriver<out Out, in In = unknown, out R = never> extends Schedule.DriverVariance<Out, In, R> {
readonly state: Effect.Effect<unknown>
readonly last: Effect.Effect<Out, Cause.NoSuchElementException>
readonly reset: Effect.Effect<void>
next(input: In): Effect.Effect<Out, Option.Option<never>, R>
}
/**
* Creates a new schedule with a custom state and step function.
*
* **Details**
*
* This function constructs a `Schedule` by defining its initial state and a
* step function, which determines how the schedule progresses over time. The
* step function is called on each iteration with the current time, an input
* value, and the schedule's current state. It returns the next state, an output
* value, and a decision on whether the schedule should continue or stop.
*
* This function is useful for creating custom scheduling logic that goes beyond
* predefined schedules like fixed intervals or exponential backoff. It allows
* full control over how the schedule behaves at each step.
*
* @since 2.0.0
* @category Constructors
*/
export const makeWithState: <S, In, Out, R = never>(
initial: S,
step: (
now: number,
input: In,
state: S
) => Effect.Effect<readonly [S, Out, ScheduleDecision.ScheduleDecision], never, R>
) => Schedule<Out, In, R> = internal.makeWithState
/**
* Checks whether a given value is a `Schedule`.
*
* @since 2.0.0
* @category Guards
*/
export const isSchedule: (u: unknown) => u is Schedule<unknown, never, unknown> = internal.isSchedule
/**
* Adds a delay to every interval in a schedule.
*
* **Details**
*
* This function modifies a given schedule by applying an additional delay to
* every interval it defines. The delay is determined by the provided function,
* which takes the schedule's output and returns a delay duration.
*
* @see {@link addDelayEffect} If you need to compute the delay using an effectful function.
*
* @since 2.0.0
* @category Timing & Delay
*/
export const addDelay: {
/**
* Adds a delay to every interval in a schedule.
*
* **Details**
*
* This function modifies a given schedule by applying an additional delay to
* every interval it defines. The delay is determined by the provided function,
* which takes the schedule's output and returns a delay duration.
*
* @see {@link addDelayEffect} If you need to compute the delay using an effectful function.
*
* @since 2.0.0
* @category Timing & Delay
*/
<Out>(f: (out: Out) => Duration.DurationInput): <In, R>(self: Schedule<Out, In, R>) => Schedule<Out, In, R>
/**
* Adds a delay to every interval in a schedule.
*
* **Details**
*
* This function modifies a given schedule by applying an additional delay to
* every interval it defines. The delay is determined by the provided function,
* which takes the schedule's output and returns a delay duration.
*
* @see {@link addDelayEffect} If you need to compute the delay using an effectful function.
*
* @since 2.0.0
* @category Timing & Delay
*/
<Out, In, R>(self: Schedule<Out, In, R>, f: (out: Out) => Duration.DurationInput): Schedule<Out, In, R>
} = internal.addDelay
/**
* Adds an effectfully computed delay to every interval in a schedule.
*
* **Details**
*
* This function modifies a given schedule by applying an additional delay to
* each interval, where the delay is determined by an effectful function. The
* function takes the schedule’s output and returns an effect that produces a
* delay duration.
*
* @see {@link addDelay} If you need to compute the delay using a pure function.
*
* @since 2.0.0
* @category Timing & Delay
*/
export const addDelayEffect: {
/**
* Adds an effectfully computed delay to every interval in a schedule.
*
* **Details**
*
* This function modifies a given schedule by applying an additional delay to
* each interval, where the delay is determined by an effectful function. The
* function takes the schedule’s output and returns an effect that produces a
* delay duration.
*
* @see {@link addDelay} If you need to compute the delay using a pure function.
*
* @since 2.0.0
* @category Timing & Delay
*/
<Out, R2>(f: (out: Out) => Effect.Effect<Duration.DurationInput, never, R2>): <In, R>(self: Schedule<Out, In, R>) => Schedule<Out, In, R2 | R>
/**
* Adds an effectfully computed delay to every interval in a schedule.
*
* **Details**
*
* This function modifies a given schedule by applying an additional delay to
* each interval, where the delay is determined by an effectful function. The
* function takes the schedule’s output and returns an effect that produces a
* delay duration.
*
* @see {@link addDelay} If you need to compute the delay using a pure function.
*
* @since 2.0.0
* @category Timing & Delay
*/
<Out, In, R, R2>(
self: Schedule<Out, In, R>,
f: (out: Out) => Effect.Effect<Duration.DurationInput, never, R2>
): Schedule<Out, In, R | R2>
} = internal.addDelayEffect
/**
* Runs two schedules sequentially, merging their outputs.
*
* **Details**
*
* This function executes two schedules one after the other. The first schedule
* runs to completion, and then the second schedule begins execution. Unlike
* {@link andThenEither}, this function merges the outputs instead of wrapping
* them in `Either`, allowing both schedules to contribute their results
* directly.
*
* This is useful when a workflow consists of two phases where the second phase
* should start only after the first one has fully completed.
*
* @see {@link andThenEither} If you need to keep track of which schedule
* produced each result.
*
* @since 2.0.0
* @category Sequential Composition
*/
export const andThen: {
/**
* Runs two schedules sequentially, merging their outputs.
*
* **Details**
*
* This function executes two schedules one after the other. The first schedule
* runs to completion, and then the second schedule begins execution. Unlike
* {@link andThenEither}, this function merges the outputs instead of wrapping
* them in `Either`, allowing both schedules to contribute their results
* directly.
*
* This is useful when a workflow consists of two phases where the second phase
* should start only after the first one has fully completed.
*
* @see {@link andThenEither} If you need to keep track of which schedule
* produced each result.
*
* @since 2.0.0
* @category Sequential Composition
*/
<Out2, In2, R2>(that: Schedule<Out2, In2, R2>): <Out, In, R>(self: Schedule<Out, In, R>) => Schedule<Out2 | Out, In & In2, R2 | R>
/**
* Runs two schedules sequentially, merging their outputs.
*
* **Details**
*
* This function executes two schedules one after the other. The first schedule
* runs to completion, and then the second schedule begins execution. Unlike
* {@link andThenEither}, this function merges the outputs instead of wrapping
* them in `Either`, allowing both schedules to contribute their results
* directly.
*
* This is useful when a workflow consists of two phases where the second phase
* should start only after the first one has fully completed.
*
* @see {@link andThenEither} If you need to keep track of which schedule
* produced each result.
*
* @since 2.0.0
* @category Sequential Composition
*/
<Out, In, R, Out2, In2, R2>(self: Schedule<Out, In, R>, that: Schedule<Out2, In2, R2>): Schedule<Out | Out2, In & In2, R | R2>
} = internal.andThen
/**
* Runs two schedules sequentially, collecting results in an `Either`.
*
* **Details**
*
* This function combines two schedules in sequence. The first schedule runs to
* completion, and then the second schedule starts and runs to completion as
* well. The outputs of both schedules are collected into an `Either` structure:
* - `Either.Left` contains the output of the second schedule.
* - `Either.Right` contains the output of the first schedule.
*
* This is useful when you need to switch from one schedule to another after the
* first one finishes, while still keeping track of which schedule produced each
* result.
*
* @see {@link andThen} If you need to merge the outputs of both schedules.
*
* @since 2.0.0
* @category Sequential Composition
*/
export const andThenEither: {
/**
* Runs two schedules sequentially, collecting results in an `Either`.
*
* **Details**
*
* This function combines two schedules in sequence. The first schedule runs to
* completion, and then the second schedule starts and runs to completion as
* well. The outputs of both schedules are collected into an `Either` structure:
* - `Either.Left` contains the output of the second schedule.
* - `Either.Right` contains the output of the first schedule.
*
* This is useful when you need to switch from one schedule to another after the
* first one finishes, while still keeping track of which schedule produced each
* result.
*
* @see {@link andThen} If you need to merge the outputs of both schedules.
*
* @since 2.0.0
* @category Sequential Composition
*/
<Out2, In2, R2>(that: Schedule<Out2, In2, R2>): <Out, In, R>(self: Schedule<Out, In, R>) => Schedule<Either.Either<Out2, Out>, In & In2, R2 | R>
/**
* Runs two schedules sequentially, collecting results in an `Either`.
*
* **Details**
*
* This function combines two schedules in sequence. The first schedule runs to
* completion, and then the second schedule starts and runs to completion as
* well. The outputs of both schedules are collected into an `Either` structure:
* - `Either.Left` contains the output of the second schedule.
* - `Either.Right` contains the output of the first schedule.
*
* This is useful when you need to switch from one schedule to another after the
* first one finishes, while still keeping track of which schedule produced each
* result.
*
* @see {@link andThen} If you need to merge the outputs of both schedules.
*
* @since 2.0.0
* @category Sequential Composition
*/
<Out, In, R, Out2, In2, R2>(self: Schedule<Out, In, R>, that: Schedule<Out2, In2, R2>): Schedule<Either.Either<Out2, Out>, In & In2, R | R2>
} = internal.andThenEither
/**
* Transforms a schedule to always produce a constant output.
*
* **Details**
*
* This function modifies a given schedule so that instead of returning its
* computed outputs, it always returns a constant value.
*
* This is useful when you need a schedule for timing but don’t care about its
* actual output, or when you want to standardize results across different
* scheduling strategies.
*
* @since 2.0.0
* @category Mapping
*/
export const as: {
/**
* Transforms a schedule to always produce a constant output.
*
* **Details**
*
* This function modifies a given schedule so that instead of returning its
* computed outputs, it always returns a constant value.
*
* This is useful when you need a schedule for timing but don’t care about its
* actual output, or when you want to standardize results across different
* scheduling strategies.
*
* @since 2.0.0
* @category Mapping
*/
<Out2>(out: Out2): <Out, In, R>(self: Schedule<Out, In, R>) => Schedule<Out2, In, R>
/**
* Transforms a schedule to always produce a constant output.
*
* **Details**
*
* This function modifies a given schedule so that instead of returning its
* computed outputs, it always returns a constant value.
*
* This is useful when you need a schedule for timing but don’t care about its
* actual output, or when you want to standardize results across different
* scheduling strategies.
*
* @since 2.0.0
* @category Mapping
*/
<Out, In, R, Out2>(self: Schedule<Out, In, R>, out: Out2): Schedule<Out2, In, R>
} = internal.as
/**
* Transforms a schedule to always return `void` instead of its output.
*
* **Details**
*
* This function modifies a given schedule so that it no longer returns
* meaningful output—each execution produces `void`. This is useful when the
* schedule is used only for timing purposes and the actual output of the
* schedule is irrelevant.
*
* The schedule still determines when executions should occur, but the results
* are discarded.
*
* @since 2.0.0
* @category Mapping
*/
export const asVoid: <Out, In, R>(self: Schedule<Out, In, R>) => Schedule<void, In, R> = internal.asVoid
// TODO(4.0): rename to `zip`?
/**
* Combines two schedules, preserving both their inputs and outputs.
*
* **Details**
*
* This function merges two schedules so that both their input types and output
* types are retained. When executed, the resulting schedule will take inputs
* from both original schedules and produce a tuple containing both outputs.
*
* It recurs if either schedule wants to continue, using the shorter delay.
*
* This is useful when you want to track multiple schedules simultaneously,
* ensuring that both receive the same inputs and produce combined results.
*
* @since 2.0.0
* @category Zipping
*/
export const bothInOut: {
// TODO(4.0): rename to `zip`?
/**
* Combines two schedules, preserving both their inputs and outputs.
*
* **Details**
*
* This function merges two schedules so that both their input types and output
* types are retained. When executed, the resulting schedule will take inputs
* from both original schedules and produce a tuple containing both outputs.
*
* It recurs if either schedule wants to continue, using the shorter delay.
*
* This is useful when you want to track multiple schedules simultaneously,
* ensuring that both receive the same inputs and produce combined results.
*
* @since 2.0.0
* @category Zipping
*/
<Out2, In2, R2>(that: Schedule<Out2, In2, R2>): <Out, In, R>(self: Schedule<Out, In, R>) => Schedule<[Out, Out2], readonly [In, In2], R2 | R>
// TODO(4.0): rename to `zip`?
/**
* Combines two schedules, preserving both their inputs and outputs.
*
* **Details**
*
* This function merges two schedules so that both their input types and output
* types are retained. When executed, the resulting schedule will take inputs
* from both original schedules and produce a tuple containing both outputs.
*
* It recurs if either schedule wants to continue, using the shorter delay.
*
* This is useful when you want to track multiple schedules simultaneously,
* ensuring that both receive the same inputs and produce combined results.
*
* @since 2.0.0
* @category Zipping
*/
<Out, In, R, Out2, In2, R2>(self: Schedule<Out, In, R>, that: Schedule<Out2, In2, R2>): Schedule<[Out, Out2], readonly [In, In2], R | R2>
} = internal.bothInOut
/**
* Filters schedule executions based on a custom condition.
*
* **Details**
*
* This function modifies a schedule by applying a custom test function to each
* input-output pair. The test function determines whether the schedule should
* continue or stop. If the function returns `true`, the schedule proceeds as
* usual; if it returns `false`, the schedule terminates.
*
* This is useful for conditional retries, custom stop conditions, or
* dynamically controlling execution based on observed inputs and outputs.
*
* @see {@link checkEffect} If you need to use an effectful test function.
*
* @since 2.0.0
* @category Recurrence Conditions
*/
export const check: {
/**
* Filters schedule executions based on a custom condition.
*
* **Details**
*
* This function modifies a schedule by applying a custom test function to each
* input-output pair. The test function determines whether the schedule should
* continue or stop. If the function returns `true`, the schedule proceeds as
* usual; if it returns `false`, the schedule terminates.
*
* This is useful for conditional retries, custom stop conditions, or
* dynamically controlling execution based on observed inputs and outputs.
*
* @see {@link checkEffect} If you need to use an effectful test function.
*
* @since 2.0.0
* @category Recurrence Conditions
*/
<In, Out>(test: (input: In, output: Out) => boolean): <R>(self: Schedule<Out, In, R>) => Schedule<Out, In, R>
/**
* Filters schedule executions based on a custom condition.
*
* **Details**
*
* This function modifies a schedule by applying a custom test function to each
* input-output pair. The test function determines whether the schedule should
* continue or stop. If the function returns `true`, the schedule proceeds as
* usual; if it returns `false`, the schedule terminates.
*
* This is useful for conditional retries, custom stop conditions, or
* dynamically controlling execution based on observed inputs and outputs.
*
* @see {@link checkEffect} If you need to use an effectful test function.
*
* @since 2.0.0
* @category Recurrence Conditions
*/
<Out, In, R>(self: Schedule<Out, In, R>, test: (input: In, output: Out) => boolean): Schedule<Out, In, R>
} = internal.check
/**
* Conditionally filters schedule executions using an effectful function.
*
* **Details**
*
* This function modifies a schedule by applying a custom effectful test
* function to each input-output pair. The test function determines whether the
* schedule should continue (`true`) or stop (`false`).
*
* This is useful when the decision to continue depends on external factors such
* as database lookups, API calls, or other asynchronous computations.
*
* @see {@link check} If you need to use a pure test function.
*
* @since 2.0.0
* @category Recurrence Conditions
*/
export const checkEffect: {
/**
* Conditionally filters schedule executions using an effectful function.
*
* **Details**
*
* This function modifies a schedule by applying a custom effectful test
* function to each input-output pair. The test function determines whether the
* schedule should continue (`true`) or stop (`false`).
*
* This is useful when the decision to continue depends on external factors such
* as database lookups, API calls, or other asynchronous computations.
*
* @see {@link check} If you need to use a pure test function.
*
* @since 2.0.0
* @category Recurrence Conditions
*/
<In, Out, R2>(test: (input: In, output: Out) => Effect.Effect<boolean, never, R2>): <R>(self: Schedule<Out, In, R>) => Schedule<Out, In, R2 | R>
/**
* Conditionally filters schedule executions using an effectful function.
*
* **Details**
*
* This function modifies a schedule by applying a custom effectful test
* function to each input-output pair. The test function determines whether the
* schedule should continue (`true`) or stop (`false`).
*
* This is useful when the decision to continue depends on external factors such
* as database lookups, API calls, or other asynchronous computations.
*
* @see {@link check} If you need to use a pure test function.
*
* @since 2.0.0
* @category Recurrence Conditions
*/
<Out, In, R, R2>(
self: Schedule<Out, In, R>,
test: (input: In, output: Out) => Effect.Effect<boolean, never, R2>
): Schedule<Out, In, R | R2>
} = internal.checkEffect
/**
* A schedule that collects all inputs into a `Chunk`.
*
* **Details**
*
* This function creates a schedule that never terminates and continuously
* collects every input it receives into a `Chunk`. Each time the schedule runs,
* it appends the new input to the collected list.
*
* This is useful when you need to track all received inputs over time, such as
* logging user actions, recording retry attempts, or accumulating data for
* later processing.
*
* @see {@link collectAllOutputs} If you need to collect outputs instead of
* inputs.
*
* @since 2.0.0
* @category Collecting
*/
export const collectAllInputs: <A>() => Schedule<Chunk.Chunk<A>, A> = internal.collectAllInputs
/**
* Collects all outputs of a schedule into a `Chunk`.
*
* **Details**
*
* This function modifies a given schedule so that instead of returning
* individual outputs, it accumulates them into a `Chunk`. The schedule
* continues to run, appending each output to the collected list.
*
* This is useful when you need to track all results over time, such as logging
* outputs, aggregating data, or keeping a history of previous values.
*
* @see {@link collectAllInputs} If you need to collect inputs instead of
* outputs.
*
* @since 2.0.0
* @category Collecting
*/
export const collectAllOutputs: <Out, In, R>(self: Schedule<Out, In, R>) => Schedule<Chunk.Chunk<Out>, In, R> =
internal.collectAllOutputs
/**
* Collects all inputs into a `Chunk` until a condition fails.
*
* **Details**
*
* This function creates a schedule that continuously collects inputs into a
* `Chunk` until the given predicate function `f` evaluates to `false`. Once the
* condition fails, the schedule stops.
*
* @since 2.0.0
* @category Collecting
*/
export const collectUntil: <A>(f: Predicate<A>) => Schedule<Chunk.Chunk<A>, A> = internal.collectUntil
/**
* Collects all inputs into a `Chunk` until an effectful condition fails.
*
* **Details**
*
* This function creates a schedule that continuously collects inputs into a
* `Chunk` until the given effectful predicate `f` returns `false`. The
* predicate runs as an effect, meaning it can involve asynchronous computations
* like API calls, database lookups, or randomness.
*
* @since 2.0.0
* @category Collecting
*/
export const collectUntilEffect: <A, R>(
f: (a: A) => Effect.Effect<boolean, never, R>
) => Schedule<Chunk.Chunk<A>, A, R> = internal.collectUntilEffect
/**
* Collects all inputs into a `Chunk` while a condition holds.
*
* **Details**
*
* This function creates a schedule that continuously collects inputs into a
* `Chunk` while the given predicate function `f` evaluates to `true`. As soon
* as the condition fails, the schedule stops.
*
* @since 2.0.0
* @category Collecting
*/
export const collectWhile: <A>(f: Predicate<A>) => Schedule<Chunk.Chunk<A>, A> = internal.collectWhile
/**
* Collects all inputs into a `Chunk` while an effectful condition holds.
*
* **Details**
*
* This function creates a schedule that continuously collects inputs into a
* `Chunk` while the given effectful predicate `f` returns `true`. The predicate
* returns an effect, meaning it can depend on external state, such as database
* queries, API responses, or real-time user conditions.
*
* As soon as the effectful condition returns `false`, the schedule stops. This
* is useful for dynamically controlled data collection, where stopping depends
* on an external or asynchronous factor.
*
* @since 2.0.0
* @category Collecting
*/
export const collectWhileEffect: <A, R>(
f: (a: A) => Effect.Effect<boolean, never, R>
) => Schedule<Chunk.Chunk<A>, A, R> = internal.collectWhileEffect
/**
* Chains two schedules, passing the output of the first as the input to the
* second, while selecting the shorter delay between them.
*
* **Details**
*
* This function composes two schedules so that the output of the first schedule
* becomes the input of the second schedule. The first schedule executes first,
* and once it produces a result, the second schedule receives that result and
* continues execution based on it.
*
* This is useful for building complex scheduling workflows where one schedule's
* behavior determines how the next schedule behaves.
*
* @since 2.0.0
* @category Composition
*/
export const compose: {
/**
* Chains two schedules, passing the output of the first as the input to the
* second, while selecting the shorter delay between them.
*
* **Details**
*
* This function composes two schedules so that the output of the first schedule
* becomes the input of the second schedule. The first schedule executes first,
* and once it produces a result, the second schedule receives that result and
* continues execution based on it.
*
* This is useful for building complex scheduling workflows where one schedule's
* behavior determines how the next schedule behaves.
*
* @since 2.0.0
* @category Composition
*/
<Out2, Out, R2>(that: Schedule<Out2, Out, R2>): <In, R>(self: Schedule<Out, In, R>) => Schedule<Out2, In, R2 | R>
/**
* Chains two schedules, passing the output of the first as the input to the
* second, while selecting the shorter delay between them.
*
* **Details**
*
* This function composes two schedules so that the output of the first schedule
* becomes the input of the second schedule. The first schedule executes first,
* and once it produces a result, the second schedule receives that result and
* continues execution based on it.
*
* This is useful for building complex scheduling workflows where one schedule's
* behavior determines how the next schedule behaves.
*
* @since 2.0.0
* @category Composition
*/
<Out, In, R, Out2, R2>(self: Schedule<Out, In, R>, that: Schedule<Out2, Out, R2>): Schedule<Out2, In, R | R2>
} = internal.compose
/**
* Transforms the input type of a schedule.
*
* **Details**
*
* This function modifies a given schedule by applying a transformation function
* to its inputs. Instead of directly receiving values of type `In`, the
* schedule will now accept values of type `In2`, which are converted to `In`
* using the provided mapping function `f`.
*
* This is useful when you have a schedule that expects a specific input type
* but you need to adapt it to work with a different type.
*
* @see {@link mapInputEffect} If you need to use an effectful transformation function.
*
* @since 2.0.0
* @category Mapping
*/
export const mapInput: {
/**
* Transforms the input type of a schedule.
*
* **Details**
*
* This function modifies a given schedule by applying a transformation function
* to its inputs. Instead of directly receiving values of type `In`, the
* schedule will now accept values of type `In2`, which are converted to `In`
* using the provided mapping function `f`.
*
* This is useful when you have a schedule that expects a specific input type
* but you need to adapt it to work with a different type.
*
* @see {@link mapInputEffect} If you need to use an effectful transformation function.
*
* @since 2.0.0
* @category Mapping
*/
<In, In2>(f: (in2: In2) => In): <Out, R>(self: Schedule<Out, In, R>) => Schedule<Out, In2, R>
/**
* Transforms the input type of a schedule.
*
* **Details**
*
* This function modifies a given schedule by applying a transformation function
* to its inputs. Instead of directly receiving values of type `In`, the
* schedule will now accept values of type `In2`, which are converted to `In`
* using the provided mapping function `f`.
*
* This is useful when you have a schedule that expects a specific input type
* but you need to adapt it to work with a different type.
*
* @see {@link mapInputEffect} If you need to use an effectful transformation function.
*
* @since 2.0.0
* @category Mapping
*/
<Out, In, R, In2>(self: Schedule<Out, In, R>, f: (in2: In2) => In): Schedule<Out, In2, R>
} = internal.mapInput
/**
* Transforms the input type of a schedule using an effectful function.
*
* **Details**
*
* This function modifies a schedule by applying an effectful transformation to
* its inputs. Instead of directly receiving values of type `In`, the schedule
* will now accept values of type `In2`, which are converted to `In` via an
* effectful function `f`.
*
* This is useful when the input transformation involves external dependencies,
* such as API calls, database lookups, or other asynchronous computations.
*
* @see {@link mapInput} If you need to use a pure transformation function.
*
* @since 2.0.0
* @category Mapping
*/
export const mapInputEffect: {
/**
* Transforms the input type of a schedule using an effectful function.
*
* **Details**
*
* This function modifies a schedule by applying an effectful transformation to
* its inputs. Instead of directly receiving values of type `In`, the schedule
* will now accept values of type `In2`, which are converted to `In` via an
* effectful function `f`.
*
* This is useful when the input transformation involves external dependencies,
* such as API calls, database lookups, or other asynchronous computations.
*
* @see {@link mapInput} If you need to use a pure transformation function.
*
* @since 2.0.0
* @category Mapping
*/
<In2, In, R2>(f: (in2: In2) => Effect.Effect<In, never, R2>): <Out, R>(self: Schedule<Out, In, R>) => Schedule<Out, In2, R2 | R>
/**
* Transforms the input type of a schedule using an effectful function.
*
* **Details**
*
* This function modifies a schedule by applying an effectful transformation to
* its inputs. Instead of directly receiving values of type `In`, the schedule
* will now accept values of type `In2`, which are converted to `In` via an
* effectful function `f`.
*
* This is useful when the input transformation involves external dependencies,
* such as API calls, database lookups, or other asynchronous computations.
*
* @see {@link mapInput} If you need to use a pure transformation function.
*
* @since 2.0.0
* @category Mapping
*/
<Out, In, R, In2, R2>(self: Schedule<Out, In, R>, f: (in2: In2) => Effect.Effect<In, never, R2>): Schedule<Out, In2, R | R2>
} = internal.mapInputEffect
/**
* Transforms the required context of a schedule.
*
* **Details**
*
* This function modifies a schedule by mapping its required context (`R`) into
* a new context (`R0`) using the provided function `f`.
*
* This is useful when you need to adapt a schedule to work with a different
* dependency environment without changing its core logic.
*
* @since 2.0.0
* @category Mapping
*/
export const mapInputContext: {
/**
* Transforms the required context of a schedule.
*
* **Details**
*
* This function modifies a schedule by mapping its required context (`R`) into
* a new context (`R0`) using the provided function `f`.
*
* This is useful when you need to adapt a schedule to work with a different
* dependency environment without changing its core logic.
*
* @since 2.0.0
* @category Mapping
*/
<R0, R>(f: (env0: Context.Context<R0>) => Context.Context<R>): <Out, In>(self: Schedule<Out, In, R>) => Schedule<Out, In, R0>
/**
* Transforms the required context of a schedule.
*
* **Details**
*
* This function modifies a schedule by mapping its required context (`R`) into
* a new context (`R0`) using the provided function `f`.
*
* This is useful when you need to adapt a schedule to work with a different
* dependency environment without changing its core logic.
*
* @since 2.0.0
* @category Mapping
*/
<Out, In, R, R0>(
self: Schedule<Out, In, R>,
f: (env0: Context.Context<R0>) => Context.Context<R>
): Schedule<Out, In, R0>
} = internal.mapInputContext
/**
* A schedule that recurs indefinitely, counting the number of recurrences.
*
* **Details**
*
* This schedule never stops and simply counts how many times it has executed.
* Each recurrence increases the count, starting from `0`.
*
* This is useful when tracking the number of attempts in retry policies,
* measuring execution loops, or implementing infinite polling scenarios.
*
* @since 2.0.0
* @category Constructors
*/
export const count: Schedule<number> = internal.count
/**
* Creates a schedule that recurs based on a cron expression.
*
* **Details**
*
* This schedule automatically executes at intervals defined by a cron
* expression. It triggers at the beginning of each matched interval and
* produces timestamps representing the start and end of the cron window.
*
* The cron `expression` is validated lazily, meaning errors may only be
* detected when the schedule is executed.
*
* @since 2.0.0
* @category Cron
*/
export const cron: {
/**
* Creates a schedule that recurs based on a cron expression.
*
* **Details**
*
* This schedule automatically executes at intervals defined by a cron
* expression. It triggers at the beginning of each matched interval and
* produces timestamps representing the start and end of the cron window.
*
* The cron `expression` is validated lazily, meaning errors may only be
* detected when the schedule is executed.
*
* @since 2.0.0
* @category Cron
*/
(cron: Cron.Cron): Schedule<[number, number]>
/**
* Creates a schedule that recurs based on a cron expression.
*
* **Details**
*
* This schedule automatically executes at intervals defined by a cron
* expression. It triggers at the beginning of each matched interval and
* produces timestamps representing the start and end of the cron window.
*
* The cron `expression` is validated lazily, meaning errors may only be
* detected when the schedule is executed.
*
* @since 2.0.0
* @category Cron
*/
(expression: string, tz?: DateTime.TimeZone | string): Schedule<[number, number]>
} = internal.cron
/**
* Cron-like schedule that recurs at a specific second of each minute.
*
* **Details**
*
* This schedule triggers at the specified `second` of each minute,
* starting at zero nanoseconds. It produces a count of executions
* (0, 1, 2, ...). The `second` parameter is validated lazily, meaning
* invalid values will only be caught at runtime.
*
* @since 2.0.0
* @category Cron
*/
export const secondOfMinute: (second: number) => Schedule<number> = internal.secondOfMinute
/**
* Creates a schedule that recurs every specified minute of each hour.
*
* **Details**
*
* This schedule triggers once per hour at the specified `minute`, starting
* exactly at `minute:00` (zero seconds). The schedule produces a count of
* executions (`0, 1, 2, ...`), representing how many times it has run.
*
* The `minute` parameter must be between `0` and `59`. It is validated lazily,
* meaning an invalid value will cause errors only when the schedule is
* executed.
*
* @since 2.0.0
* @category Cron
*/
export const minuteOfHour: (minute: number) => Schedule<number> = internal.minuteOfHour
/**
* Creates a schedule that recurs at a specific hour of each day.
*
* **Details**
*
* This schedule triggers once per day at the specified `hour`, starting at zero
* minutes of that hour. The schedule produces a count of executions (`0, 1, 2,
* ...`), indicating how many times it has been triggered.
*
* The `hour` parameter must be between `0` (midnight) and `23` (11 PM). It is
* validated lazily, meaning an invalid value will cause errors only when the
* schedule is executed.
*
* This is useful for scheduling daily recurring tasks at a fixed time, such as
* running batch jobs or refreshing data.
*
* @since 2.0.0
* @category Cron
*/
export const hourOfDay: (hour: number) => Schedule<number> = internal.hourOfDay
/**
* Creates a schedule that recurs on a specific day of the month.
*
* **Details**
*
* This schedule triggers at midnight on the specified day of each month. It
* will not execute in months that have fewer days than the given day. For
* example, if the schedule is set to run on the 31st, it will not execute in
* months with only 30 days.
*
* The schedule produces a count of executions, starting at 0 and incrementing
* with each recurrence.
*
* The `day` parameter is validated lazily, meaning errors may only be detected
* when the schedule is executed.
*
* @since 2.0.0
* @category Cron
*/
export const dayOfMonth: (day: number) => Schedule<number> = internal.dayOfMonth
/**
* Creates a schedule that recurs on a specific day of the week.
*
* **Details**
*
* This schedule triggers at midnight on the specified day of the week. The
* `day` parameter follows the standard convention where `Monday = 1` and
* `Sunday = 7`. The schedule produces a count of executions, starting at 0 and
* incrementing with each recurrence.
*
* The `day` parameter is validated lazily, meaning errors may only be detected
* when the schedule is executed.
*
* @since 2.0.0
* @category Cron
*/
export const dayOfWeek: (day: number) => Schedule<number> = internal.dayOfWeek
/**
* Modifies a schedule by adding a computed delay before each execution.
*
* **Details**
*
* This function adjusts an existing schedule by applying a transformation to
* its delays. Instead of using the default interval, each delay is modified
* using the provided function `f`, which takes the current delay and returns a
* new delay.
*
* This is useful for dynamically adjusting wait times between executions, such
* as introducing jitter, exponential backoff, or custom delay logic.
*
* @see {@link delayedEffect} If you need to compute the delay using an effectful function.
*
* @since 2.0.0
* @category Timing & Delay
*/
export const delayed: {
/**
* Modifies a schedule by adding a computed delay before each execution.
*
* **Details**
*
* This function adjusts an existing schedule by applying a transformation to
* its delays. Instead of using the default interval, each delay is modified
* using the provided function `f`, which takes the current delay and returns a
* new delay.
*
* This is useful for dynamically adjusting wait times between executions, such
* as introducing jitter, exponential backoff, or custom delay logic.
*
* @see {@link delayedEffect} If you need to compute the delay using an effectful function.
*
* @since 2.0.0
* @category Timing & Delay
*/
(f: (duration: Duration.Duration) => Duration.DurationInput): <Out, In, R>(self: Schedule<Out, In, R>) => Schedule<Out, In, R>
/**
* Modifies a schedule by adding a computed delay before each execution.
*
* **Details**
*
* This function adjusts an existing schedule by applying a transformation to
* its delays. Instead of using the default interval, each delay is modified
* using the provided function `f`, which takes the current delay and returns a
* new delay.
*
* This is useful for dynamically adjusting wait times between executions, such
* as introducing jitter, exponential backoff, or custom delay logic.
*
* @see {@link delayedEffect} If you need to compute the delay using an effectful function.
*
* @since 2.0.0
* @category Timing & Delay
*/
<Out, In, R>(
self: Schedule<Out, In, R>,
f: (duration: Duration.Duration) => Duration.DurationInput
): Schedule<Out, In, R>
} = internal.delayed
/**
* Modifies a schedule by adding an effectfully computed delay before each
* execution.
*
* **Details**
*
* This function adjusts an existing schedule by introducing a delay that is
* computed via an effect. Instead of using a fixed delay, each interval is
* dynamically adjusted based on an effectful function `f`, which takes the
* current delay and returns a new delay wrapped in an `Effect`.
*
* This is useful for adaptive scheduling where delays depend on external
* factors, such as API calls, database queries, or dynamic system conditions.
*
* @see {@link delayed} If you need to compute the delay using a pure function.
*
* @since 2.0.0
* @category Timing & Delay
*/
export const delayedEffect: {
/**
* Modifies a schedule by adding an effectfully computed delay before each
* execution.
*
* **Details**
*
* This function adjusts an existing schedule by introducing a delay that is
* computed via an effect. Instead of using a fixed delay, each interval is
* dynamically adjusted based on an effectful function `f`, which takes the
* current delay and returns a new delay wrapped in an `Effect`.
*
* This is useful for adaptive scheduling where delays depend on external
* factors, such as API calls, database queries, or dynamic system conditions.
*
* @see {@link delayed} If you need to compute the delay using a pure function.
*
* @since 2.0.0
* @category Timing & Delay
*/
<R2>(
f: (duration: Duration.Duration) => Effect.Effect<Duration.DurationInput, never, R2>
): <Out, In, R>(self: Schedule<Out, In, R>) => Schedule<Out, In, R2 | R>
/**
* Modifies a schedule by adding an effectfully computed delay before each
* execution.
*
* **Details**
*
* This function adjusts an existing schedule by introducing a delay that is
* computed via an effect. Instead of using a fixed delay, each interval is
* dynamically adjusted based on an effectful function `f`, which takes the
* current delay and returns a new delay wrapped in an `Effect`.
*
* This is useful for adaptive scheduling where delays depend on external
* factors, such as API calls, database queries, or dynamic system conditions.
*
* @see {@link delayed} If you need to compute the delay using a pure function.
*
* @since 2.0.0
* @category Timing & Delay
*/
<Out, In, R, R2>(
self: Schedule<Out, In, R>,
f: (duration: Duration.Duration) => Effect.Effect<Duration.DurationInput, never, R2>
): Schedule<Out, In, R | R2>
} = internal.delayedEffect
/**
* Uses the delays produced by a schedule to further delay its intervals.
*
* **Details**
*
* This function modifies a schedule by using its own output delays to control
* its execution timing. Instead of executing immediately at each interval, the
* schedule will be delayed by the duration it produces.
*
* @since 2.0.0
* @category Timing & Delay
*/
export const delayedSchedule: <In, R>(
schedule: Schedule<Duration.Duration, In, R>
) => Schedule<Duration.Duration, In, R> = internal.delayedSchedule
/**
* Transforms a schedule to output the delay between each occurrence.
*
* **Details**
*
* This function modifies an existing schedule so that instead of producing its
* original output, it now returns the delay between each scheduled execution.
*
* @since 2.0.0
* @category Monitoring
*/
export const delays: <Out, In, R>(self: Schedule<Out, In, R>) => Schedule<Duration.Duration, In, R> = internal.delays
/**
* Transforms both the input and output of a schedule.
*
* **Details**
*
* This function modifies an existing schedule by applying a transformation to
* both its input values and its output values. The provided transformation
* functions `onInput` and `onOutput` allow you to map the schedule to work with
* a different input type while modifying its outputs as well.
*
* @see {@link mapBothEffect} If you need to use effectful transformation functions.
*
* @since 2.0.0
* @category Mapping
*/
export const mapBoth: {
/**
* Transforms both the input and output of a schedule.
*
* **Details**
*
* This function modifies an existing schedule by applying a transformation to
* both its input values and its output values. The provided transformation
* functions `onInput` and `onOutput` allow you to map the schedule to work with
* a different input type while modifying its outputs as well.
*
* @see {@link mapBothEffect} If you need to use effectful transformation functions.
*
* @since 2.0.0
* @category Mapping
*/
<In2, In, Out, Out2>(
options: { readonly onInput: (in2: In2) => In; readonly onOutput: (out: Out) => Out2 }
): <R>(self: Schedule<Out, In, R>) => Schedule<Out2, In2, R>
/**
* Transforms both the input and output of a schedule.
*
* **Details**
*
* This function modifies an existing schedule by applying a transformation to
* both its input values and its output values. The provided transformation
* functions `onInput` and `onOutput` allow you to map the schedule to work with
* a different input type while modifying its outputs as well.
*
* @see {@link mapBothEffect} If you need to use effectful transformation functions.
*
* @since 2.0.0
* @category Mapping
*/
<Out, In, R, In2, Out2>(
self: Schedule<Out, In, R>,
options: { readonly onInput: (in2: In2) => In; readonly onOutput: (out: Out) => Out2 }
): Schedule<Out2, In2, R>
} = internal.mapBoth
/**
* Transforms both the input and output of a schedule using effectful
* computations.
*
* **Details**
*
* This function modifies an existing schedule by applying effectful
* transformations to both its input values and its output values. The provided
* effectful functions `onInput` and `onOutput` allow you to transform inputs
* and outputs using computations that may involve additional logic, resource
* access, or side effects.
*
* @see {@link mapBoth} If you need to use pure transformation functions.
*
* @since 2.0.0
* @category Mapping
*/
export const mapBothEffect: {
/**
* Transforms both the input and output of a schedule using effectful
* computations.
*
* **Details**
*
* This function modifies an existing schedule by applying effectful
* transformations to both its input values and its output values. The provided
* effectful functions `onInput` and `onOutput` allow you to transform inputs
* and outputs using computations that may involve additional logic, resource
* access, or side effects.
*
* @see {@link mapBoth} If you need to use pure transformation functions.
*
* @since 2.0.0
* @category Mapping
*/
<In2, In, R2, Out, R3, Out2>(
options: {
readonly onInput: (input: In2) => Effect.Effect<In, never, R2>