<O extends Repeat.Options<A>, A>(options: O): <E, R>(
self: Effect<A, E, R>
) => Repeat.Return<R, E, A, O>
<Output, Input, Error, Env>(
schedule: Schedule<Output, NoInfer<Input>, Error, Env>
): <E, R>(self: Effect<Input, E, R>) => Effect<Output, E | Error, R | Env>
<Output, Input, Error, Env>(
builder: (
$: <O, E, R>(
_: Schedule<O, NoInfer<Input>, E, R>
) => Schedule<O, Input, E, R>
) => Schedule<Output, NoInfer<Input>, Error, Env>
): <E, R>(self: Effect<Input, E, R>) => Effect<Output, E | Error, R | Env>
<A, E, R, O extends Repeat.Options<A>>(
self: Effect<A, E, R>,
options: O
): Repeat.Return<R, E, A, O>
<Input, E, R, Output, Error, Env>(
self: Effect<Input, E, R>,
schedule: Schedule<Output, NoInfer<Input>, Error, Env>
): Effect<Output, E | Error, R | Env>
<Input, E, R, Output, Error, Env>(
self: Effect<Input, E, R>,
builder: (
$: <O, E, R>(
_: Schedule<O, NoInfer<Input>, E, R>
) => Schedule<O, Input, E, R>
) => Schedule<Output, NoInfer<Input>, Error, Env>
): Effect<Output, E | Error, R | Env>Repeats an effect based on a specified schedule or until the first failure.
When to use
Use to rerun an effect after successful executions.
Details
This function executes an effect repeatedly according to the given schedule.
Each repetition occurs after the initial execution of the effect, meaning
that the schedule determines the number of additional repetitions. For
example, using Schedule.once will result in the effect being executed twice
(once initially and once as part of the repetition).
If the effect succeeds, it is repeated according to the schedule. If it fails, the repetition stops immediately, and the failure is returned.
The schedule can also specify delays between repetitions, making it useful for tasks like retrying operations with backoff, periodic execution, or performing a series of dependent actions.
You can combine schedules for more advanced repetition logic, such as adding delays, limiting recursions, or dynamically adjusting based on the outcome of each execution.
Gotchas
The source effect is always evaluated once before the schedule is stepped. The schedule controls additional repetitions, not the initial execution.
Example (Repeating successful effects with a schedule)
// Success Example
import { Console, Effect, Schedule } from "effect"
const action = Console.log("success")
const policy = Schedule.addDelay(Schedule.recurs(2), () => Effect.succeed("100 millis"))
const program = Effect.repeat(action, policy)
// Effect.runPromise(program).then((n) => console.log(`repetitions: ${n}`))Example (Stopping repetition on failure)
// Failure Example
import { Effect, Schedule } from "effect"
let count = 0
// Define a callback effect that simulates an action with possible failures
const action = Effect.callback<string, string>((resume) => {
if (count > 1) {
console.log("failure")
resume(Effect.fail("Uh oh!"))
} else {
count++
console.log("success")
resume(Effect.succeed("yay!"))
}
})
const policy = Schedule.addDelay(Schedule.recurs(2), () => Effect.succeed("100 millis"))
const program = Effect.repeat(action, policy)
// Effect.runPromiseExit(program).then(console.log)export const const repeat: {
<O extends Repeat.Options<A>, A>(options: O): <
E,
R
>(
self: Effect<A, E, R>
) => Repeat.Return<R, E, A, O>
<Output, Input, Error, Env>(
schedule: Schedule<
Output,
NoInfer<Input>,
Error,
Env
>
): <E, R>(
self: Effect<Input, E, R>
) => Effect<Output, E | Error, R | Env>
<Output, Input, Error, Env>(
builder: (
$: <O, E, R>(
_: Schedule<O, NoInfer<Input>, E, R>
) => Schedule<O, Input, E, R>
) => Schedule<
Output,
NoInfer<Input>,
Error,
Env
>
): <E, R>(
self: Effect<Input, E, R>
) => Effect<Output, E | Error, R | Env>
<A, E, R, O extends Repeat.Options<A>>(
self: Effect<A, E, R>,
options: O
): Repeat.Return<R, E, A, O>
<Input, E, R, Output, Error, Env>(
self: Effect<Input, E, R>,
schedule: Schedule<
Output,
NoInfer<Input>,
Error,
Env
>
): Effect<Output, E | Error, R | Env>
<Input, E, R, Output, Error, Env>(
self: Effect<Input, E, R>,
builder: (
$: <O, E, R>(
_: Schedule<O, NoInfer<Input>, E, R>
) => Schedule<O, Input, E, R>
) => Schedule<
Output,
NoInfer<Input>,
Error,
Env
>
): Effect<Output, E | Error, R | Env>
}
Repeats an effect based on a specified schedule or until the first failure.
When to use
Use to rerun an effect after successful executions.
Details
This function executes an effect repeatedly according to the given schedule.
Each repetition occurs after the initial execution of the effect, meaning
that the schedule determines the number of additional repetitions. For
example, using Schedule.once will result in the effect being executed twice
(once initially and once as part of the repetition).
If the effect succeeds, it is repeated according to the schedule. If it
fails, the repetition stops immediately, and the failure is returned.
The schedule can also specify delays between repetitions, making it useful
for tasks like retrying operations with backoff, periodic execution, or
performing a series of dependent actions.
You can combine schedules for more advanced repetition logic, such as adding
delays, limiting recursions, or dynamically adjusting based on the outcome of
each execution.
Gotchas
The source effect is always evaluated once before the schedule is stepped.
The schedule controls additional repetitions, not the initial execution.
Example (Repeating successful effects with a schedule)
// Success Example
import { Console, Effect, Schedule } from "effect"
const action = Console.log("success")
const policy = Schedule.addDelay(Schedule.recurs(2), () => Effect.succeed("100 millis"))
const program = Effect.repeat(action, policy)
// Effect.runPromise(program).then((n) => console.log(`repetitions: ${n}`))
Example (Stopping repetition on failure)
// Failure Example
import { Effect, Schedule } from "effect"
let count = 0
// Define a callback effect that simulates an action with possible failures
const action = Effect.callback<string, string>((resume) => {
if (count > 1) {
console.log("failure")
resume(Effect.fail("Uh oh!"))
} else {
count++
console.log("success")
resume(Effect.succeed("yay!"))
}
})
const policy = Schedule.addDelay(Schedule.recurs(2), () => Effect.succeed("100 millis"))
const program = Effect.repeat(action, policy)
// Effect.runPromiseExit(program).then(console.log)
repeat: {
<function (type parameter) O in <O extends Repeat.Options<A>, A>(options: O): <E, R>(self: Effect<A, E, R>) => Repeat.Return<R, E, A, O>O extends Repeat.interface Repeat.Options<A>Options that control whether and how an effect is repeated.
Options<function (type parameter) A in <O extends Repeat.Options<A>, A>(options: O): <E, R>(self: Effect<A, E, R>) => Repeat.Return<R, E, A, O>A>, function (type parameter) A in <O extends Repeat.Options<A>, A>(options: O): <E, R>(self: Effect<A, E, R>) => Repeat.Return<R, E, A, O>A>(options: O extends Repeat.Options<A>options: function (type parameter) O in <O extends Repeat.Options<A>, A>(options: O): <E, R>(self: Effect<A, E, R>) => Repeat.Return<R, E, A, O>O): <function (type parameter) E in <E, R>(self: Effect<A, E, R>): Repeat.Return<R, E, A, O>E, function (type parameter) R in <E, R>(self: Effect<A, E, R>): Repeat.Return<R, E, A, O>R>(self: Effect<A, E, R>(parameter) self: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self: interface Effect<out A, out E = never, out R = never>The Effect interface defines a value that lazily describes a workflow or
job. The workflow requires some context R, and may fail with an error of
type E, or succeed with a value of type A.
When to use
Use when you need to represent a lazy, composable workflow that can require
services, fail with a typed error, or succeed with a typed value.
Details
Effect values model resourceful interaction with the outside world,
including synchronous, asynchronous, concurrent, and parallel interaction.
They use a fiber-based concurrency model, with built-in support for
scheduling, fine-grained interruption, structured concurrency, and high
scalability.
To run an Effect value, you need a Runtime, which is a type that is
capable of executing Effect values.
Effect<function (type parameter) A in <O extends Repeat.Options<A>, A>(options: O): <E, R>(self: Effect<A, E, R>) => Repeat.Return<R, E, A, O>A, function (type parameter) E in <E, R>(self: Effect<A, E, R>): Repeat.Return<R, E, A, O>E, function (type parameter) R in <E, R>(self: Effect<A, E, R>): Repeat.Return<R, E, A, O>R>) => Repeat.type Repeat.Return<R, E, A, O extends Repeat.Options<A>> = Effect<O extends {
until: Predicate.Refinement<A, infer B>;
} ? B : O extends {
while: Predicate.Refinement<A, infer B>;
} ? Exclude<A, B> : A, E | (O extends {
schedule: Schedule<infer _Out, infer _I, infer E, infer _R>;
} ? E : never) | (O extends {
while: (...args: Array<any>) => Effect<infer _A, infer E, infer _R>;
} ? E : never) | (O extends {
until: (...args: Array<any>) => Effect<infer _A, infer E, infer _R>;
} ? E : never), R | (O extends {
schedule: Schedule<infer _O, infer _I, infer _E, infer R>;
} ? R : never) | (O extends {
...;
} ? R : never) | (O extends {
...;
} ? R : never)>
Computes the result type of Effect.repeat from the original effect and repeat options.
Return<function (type parameter) R in <E, R>(self: Effect<A, E, R>): Repeat.Return<R, E, A, O>R, function (type parameter) E in <E, R>(self: Effect<A, E, R>): Repeat.Return<R, E, A, O>E, function (type parameter) A in <O extends Repeat.Options<A>, A>(options: O): <E, R>(self: Effect<A, E, R>) => Repeat.Return<R, E, A, O>A, function (type parameter) O in <O extends Repeat.Options<A>, A>(options: O): <E, R>(self: Effect<A, E, R>) => Repeat.Return<R, E, A, O>O>
<function (type parameter) Output in <Output, Input, Error, Env>(schedule: Schedule<Output, NoInfer<Input>, Error, Env>): <E, R>(self: Effect<Input, E, R>) => Effect<Output, E | Error, R | Env>Output, function (type parameter) Input in <Output, Input, Error, Env>(schedule: Schedule<Output, NoInfer<Input>, Error, Env>): <E, R>(self: Effect<Input, E, R>) => Effect<Output, E | Error, R | Env>Input, function (type parameter) Error in <Output, Input, Error, Env>(schedule: Schedule<Output, NoInfer<Input>, Error, Env>): <E, R>(self: Effect<Input, E, R>) => Effect<Output, E | Error, R | Env>Error, function (type parameter) Env in <Output, Input, Error, Env>(schedule: Schedule<Output, NoInfer<Input>, Error, Env>): <E, R>(self: Effect<Input, E, R>) => Effect<Output, E | Error, R | Env>Env>(
schedule: Schedule<
Output,
NoInfer<Input>,
Error,
Env
>
(parameter) schedule: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
schedule: interface Schedule<out Output, in Input = unknown, out Error = never, out Env = never>A Schedule defines a strategy for repeating or retrying effects based on some policy.
Example (Defining retry and repeat schedules)
import { Console, Data, Effect, Schedule } from "effect"
class NetworkError extends Data.TaggedError("NetworkError")<{
readonly attempt: number
}> {}
// Basic retry schedule - retry up to 3 times with exponential backoff
const retrySchedule = Schedule.max([
Schedule.exponential("100 millis"),
Schedule.recurs(3)
])
// Basic repeat schedule - repeat every 30 seconds forever
const repeatSchedule: Schedule.Schedule<number, unknown, never> = Schedule
.spaced("30 seconds")
const program = Effect.gen(function*() {
let attempts = 0
const result1 = yield* Effect.retry(
Effect.gen(function*() {
attempts++
if (attempts < 3) {
return yield* Effect.fail(new NetworkError({ attempt: attempts }))
}
return "Success"
}),
retrySchedule
)
console.log(result1) // "Success"
yield* Console.log("heartbeat").pipe(
Effect.repeat(repeatSchedule.pipe(Schedule.upTo({ times: 5 })))
)
})
The Schedule namespace contains types and utilities for working with schedules.
Schedule<function (type parameter) Output in <Output, Input, Error, Env>(schedule: Schedule<Output, NoInfer<Input>, Error, Env>): <E, R>(self: Effect<Input, E, R>) => Effect<Output, E | Error, R | Env>Output, type NoInfer<A> = [A][A extends any ? 0 : never]Prevents TypeScript from inferring a type parameter from a specific
position.
When to use
Use when a function parameter must match an inferred type without becoming
an inference source.
Details
The parameter using NoInfer must still match the inferred type.
Example (Controlling inference)
import type { Types } from "effect"
declare function withDefault<T>(value: T, fallback: Types.NoInfer<T>): T
// T is inferred as "a" | "b" from the first argument only
const result = withDefault<"a" | "b">("a", "b")
NoInfer<function (type parameter) Input in <Output, Input, Error, Env>(schedule: Schedule<Output, NoInfer<Input>, Error, Env>): <E, R>(self: Effect<Input, E, R>) => Effect<Output, E | Error, R | Env>Input>, function (type parameter) Error in <Output, Input, Error, Env>(schedule: Schedule<Output, NoInfer<Input>, Error, Env>): <E, R>(self: Effect<Input, E, R>) => Effect<Output, E | Error, R | Env>Error, function (type parameter) Env in <Output, Input, Error, Env>(schedule: Schedule<Output, NoInfer<Input>, Error, Env>): <E, R>(self: Effect<Input, E, R>) => Effect<Output, E | Error, R | Env>Env>
): <function (type parameter) E in <E, R>(self: Effect<Input, E, R>): Effect<Output, E | Error, R | Env>E, function (type parameter) R in <E, R>(self: Effect<Input, E, R>): Effect<Output, E | Error, R | Env>R>(self: Effect<Input, E, R>(parameter) self: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self: interface Effect<out A, out E = never, out R = never>The Effect interface defines a value that lazily describes a workflow or
job. The workflow requires some context R, and may fail with an error of
type E, or succeed with a value of type A.
When to use
Use when you need to represent a lazy, composable workflow that can require
services, fail with a typed error, or succeed with a typed value.
Details
Effect values model resourceful interaction with the outside world,
including synchronous, asynchronous, concurrent, and parallel interaction.
They use a fiber-based concurrency model, with built-in support for
scheduling, fine-grained interruption, structured concurrency, and high
scalability.
To run an Effect value, you need a Runtime, which is a type that is
capable of executing Effect values.
Effect<function (type parameter) Input in <Output, Input, Error, Env>(schedule: Schedule<Output, NoInfer<Input>, Error, Env>): <E, R>(self: Effect<Input, E, R>) => Effect<Output, E | Error, R | Env>Input, function (type parameter) E in <E, R>(self: Effect<Input, E, R>): Effect<Output, E | Error, R | Env>E, function (type parameter) R in <E, R>(self: Effect<Input, E, R>): Effect<Output, E | Error, R | Env>R>) => interface Effect<out A, out E = never, out R = never>The Effect interface defines a value that lazily describes a workflow or
job. The workflow requires some context R, and may fail with an error of
type E, or succeed with a value of type A.
When to use
Use when you need to represent a lazy, composable workflow that can require
services, fail with a typed error, or succeed with a typed value.
Details
Effect values model resourceful interaction with the outside world,
including synchronous, asynchronous, concurrent, and parallel interaction.
They use a fiber-based concurrency model, with built-in support for
scheduling, fine-grained interruption, structured concurrency, and high
scalability.
To run an Effect value, you need a Runtime, which is a type that is
capable of executing Effect values.
Effect<function (type parameter) Output in <Output, Input, Error, Env>(schedule: Schedule<Output, NoInfer<Input>, Error, Env>): <E, R>(self: Effect<Input, E, R>) => Effect<Output, E | Error, R | Env>Output, function (type parameter) E in <E, R>(self: Effect<Input, E, R>): Effect<Output, E | Error, R | Env>E | function (type parameter) Error in <Output, Input, Error, Env>(schedule: Schedule<Output, NoInfer<Input>, Error, Env>): <E, R>(self: Effect<Input, E, R>) => Effect<Output, E | Error, R | Env>Error, function (type parameter) R in <E, R>(self: Effect<Input, E, R>): Effect<Output, E | Error, R | Env>R | function (type parameter) Env in <Output, Input, Error, Env>(schedule: Schedule<Output, NoInfer<Input>, Error, Env>): <E, R>(self: Effect<Input, E, R>) => Effect<Output, E | Error, R | Env>Env>
<function (type parameter) Output in <Output, Input, Error, Env>(builder: ($: <O, E, R>(_: Schedule<O, NoInfer<Input>, E, R>) => Schedule<O, Input, E, R>) => Schedule<Output, NoInfer<Input>, Error, Env>): <E, R>(self: Effect<Input, E, R>) => Effect<Output, E | Error, R | Env>Output, function (type parameter) Input in <Output, Input, Error, Env>(builder: ($: <O, E, R>(_: Schedule<O, NoInfer<Input>, E, R>) => Schedule<O, Input, E, R>) => Schedule<Output, NoInfer<Input>, Error, Env>): <E, R>(self: Effect<Input, E, R>) => Effect<Output, E | Error, R | Env>Input, function (type parameter) Error in <Output, Input, Error, Env>(builder: ($: <O, E, R>(_: Schedule<O, NoInfer<Input>, E, R>) => Schedule<O, Input, E, R>) => Schedule<Output, NoInfer<Input>, Error, Env>): <E, R>(self: Effect<Input, E, R>) => Effect<Output, E | Error, R | Env>Error, function (type parameter) Env in <Output, Input, Error, Env>(builder: ($: <O, E, R>(_: Schedule<O, NoInfer<Input>, E, R>) => Schedule<O, Input, E, R>) => Schedule<Output, NoInfer<Input>, Error, Env>): <E, R>(self: Effect<Input, E, R>) => Effect<Output, E | Error, R | Env>Env>(
builder: (
$: <O, E, R>(
_: Schedule<O, NoInfer<Input>, E, R>
) => Schedule<O, Input, E, R>
) => Schedule<Output, NoInfer<Input>, Error, Env>
builder: (
$: <O, E, R>(
_: Schedule<O, NoInfer<Input>, E, R>
) => Schedule<O, Input, E, R>
$: <function (type parameter) O in <O, E, R>(_: Schedule<O, NoInfer<Input>, E, R>): Schedule<O, Input, E, R>O, function (type parameter) E in <O, E, R>(_: Schedule<O, NoInfer<Input>, E, R>): Schedule<O, Input, E, R>E, function (type parameter) R in <O, E, R>(_: Schedule<O, NoInfer<Input>, E, R>): Schedule<O, Input, E, R>R>(_: Schedule<O, NoInfer<Input>, E, R>(parameter) _: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
_: interface Schedule<out Output, in Input = unknown, out Error = never, out Env = never>A Schedule defines a strategy for repeating or retrying effects based on some policy.
Example (Defining retry and repeat schedules)
import { Console, Data, Effect, Schedule } from "effect"
class NetworkError extends Data.TaggedError("NetworkError")<{
readonly attempt: number
}> {}
// Basic retry schedule - retry up to 3 times with exponential backoff
const retrySchedule = Schedule.max([
Schedule.exponential("100 millis"),
Schedule.recurs(3)
])
// Basic repeat schedule - repeat every 30 seconds forever
const repeatSchedule: Schedule.Schedule<number, unknown, never> = Schedule
.spaced("30 seconds")
const program = Effect.gen(function*() {
let attempts = 0
const result1 = yield* Effect.retry(
Effect.gen(function*() {
attempts++
if (attempts < 3) {
return yield* Effect.fail(new NetworkError({ attempt: attempts }))
}
return "Success"
}),
retrySchedule
)
console.log(result1) // "Success"
yield* Console.log("heartbeat").pipe(
Effect.repeat(repeatSchedule.pipe(Schedule.upTo({ times: 5 })))
)
})
The Schedule namespace contains types and utilities for working with schedules.
Schedule<function (type parameter) O in <O, E, R>(_: Schedule<O, NoInfer<Input>, E, R>): Schedule<O, Input, E, R>O, type NoInfer<A> = [A][A extends any ? 0 : never]Prevents TypeScript from inferring a type parameter from a specific
position.
When to use
Use when a function parameter must match an inferred type without becoming
an inference source.
Details
The parameter using NoInfer must still match the inferred type.
Example (Controlling inference)
import type { Types } from "effect"
declare function withDefault<T>(value: T, fallback: Types.NoInfer<T>): T
// T is inferred as "a" | "b" from the first argument only
const result = withDefault<"a" | "b">("a", "b")
NoInfer<function (type parameter) Input in <Output, Input, Error, Env>(builder: ($: <O, E, R>(_: Schedule<O, NoInfer<Input>, E, R>) => Schedule<O, Input, E, R>) => Schedule<Output, NoInfer<Input>, Error, Env>): <E, R>(self: Effect<Input, E, R>) => Effect<Output, E | Error, R | Env>Input>, function (type parameter) E in <O, E, R>(_: Schedule<O, NoInfer<Input>, E, R>): Schedule<O, Input, E, R>E, function (type parameter) R in <O, E, R>(_: Schedule<O, NoInfer<Input>, E, R>): Schedule<O, Input, E, R>R>) => interface Schedule<out Output, in Input = unknown, out Error = never, out Env = never>A Schedule defines a strategy for repeating or retrying effects based on some policy.
Example (Defining retry and repeat schedules)
import { Console, Data, Effect, Schedule } from "effect"
class NetworkError extends Data.TaggedError("NetworkError")<{
readonly attempt: number
}> {}
// Basic retry schedule - retry up to 3 times with exponential backoff
const retrySchedule = Schedule.max([
Schedule.exponential("100 millis"),
Schedule.recurs(3)
])
// Basic repeat schedule - repeat every 30 seconds forever
const repeatSchedule: Schedule.Schedule<number, unknown, never> = Schedule
.spaced("30 seconds")
const program = Effect.gen(function*() {
let attempts = 0
const result1 = yield* Effect.retry(
Effect.gen(function*() {
attempts++
if (attempts < 3) {
return yield* Effect.fail(new NetworkError({ attempt: attempts }))
}
return "Success"
}),
retrySchedule
)
console.log(result1) // "Success"
yield* Console.log("heartbeat").pipe(
Effect.repeat(repeatSchedule.pipe(Schedule.upTo({ times: 5 })))
)
})
The Schedule namespace contains types and utilities for working with schedules.
Schedule<function (type parameter) O in <O, E, R>(_: Schedule<O, NoInfer<Input>, E, R>): Schedule<O, Input, E, R>O, function (type parameter) Input in <Output, Input, Error, Env>(builder: ($: <O, E, R>(_: Schedule<O, NoInfer<Input>, E, R>) => Schedule<O, Input, E, R>) => Schedule<Output, NoInfer<Input>, Error, Env>): <E, R>(self: Effect<Input, E, R>) => Effect<Output, E | Error, R | Env>Input, function (type parameter) E in <O, E, R>(_: Schedule<O, NoInfer<Input>, E, R>): Schedule<O, Input, E, R>E, function (type parameter) R in <O, E, R>(_: Schedule<O, NoInfer<Input>, E, R>): Schedule<O, Input, E, R>R>
) => interface Schedule<out Output, in Input = unknown, out Error = never, out Env = never>A Schedule defines a strategy for repeating or retrying effects based on some policy.
Example (Defining retry and repeat schedules)
import { Console, Data, Effect, Schedule } from "effect"
class NetworkError extends Data.TaggedError("NetworkError")<{
readonly attempt: number
}> {}
// Basic retry schedule - retry up to 3 times with exponential backoff
const retrySchedule = Schedule.max([
Schedule.exponential("100 millis"),
Schedule.recurs(3)
])
// Basic repeat schedule - repeat every 30 seconds forever
const repeatSchedule: Schedule.Schedule<number, unknown, never> = Schedule
.spaced("30 seconds")
const program = Effect.gen(function*() {
let attempts = 0
const result1 = yield* Effect.retry(
Effect.gen(function*() {
attempts++
if (attempts < 3) {
return yield* Effect.fail(new NetworkError({ attempt: attempts }))
}
return "Success"
}),
retrySchedule
)
console.log(result1) // "Success"
yield* Console.log("heartbeat").pipe(
Effect.repeat(repeatSchedule.pipe(Schedule.upTo({ times: 5 })))
)
})
The Schedule namespace contains types and utilities for working with schedules.
Schedule<function (type parameter) Output in <Output, Input, Error, Env>(builder: ($: <O, E, R>(_: Schedule<O, NoInfer<Input>, E, R>) => Schedule<O, Input, E, R>) => Schedule<Output, NoInfer<Input>, Error, Env>): <E, R>(self: Effect<Input, E, R>) => Effect<Output, E | Error, R | Env>Output, type NoInfer<A> = [A][A extends any ? 0 : never]Prevents TypeScript from inferring a type parameter from a specific
position.
When to use
Use when a function parameter must match an inferred type without becoming
an inference source.
Details
The parameter using NoInfer must still match the inferred type.
Example (Controlling inference)
import type { Types } from "effect"
declare function withDefault<T>(value: T, fallback: Types.NoInfer<T>): T
// T is inferred as "a" | "b" from the first argument only
const result = withDefault<"a" | "b">("a", "b")
NoInfer<function (type parameter) Input in <Output, Input, Error, Env>(builder: ($: <O, E, R>(_: Schedule<O, NoInfer<Input>, E, R>) => Schedule<O, Input, E, R>) => Schedule<Output, NoInfer<Input>, Error, Env>): <E, R>(self: Effect<Input, E, R>) => Effect<Output, E | Error, R | Env>Input>, function (type parameter) Error in <Output, Input, Error, Env>(builder: ($: <O, E, R>(_: Schedule<O, NoInfer<Input>, E, R>) => Schedule<O, Input, E, R>) => Schedule<Output, NoInfer<Input>, Error, Env>): <E, R>(self: Effect<Input, E, R>) => Effect<Output, E | Error, R | Env>Error, function (type parameter) Env in <Output, Input, Error, Env>(builder: ($: <O, E, R>(_: Schedule<O, NoInfer<Input>, E, R>) => Schedule<O, Input, E, R>) => Schedule<Output, NoInfer<Input>, Error, Env>): <E, R>(self: Effect<Input, E, R>) => Effect<Output, E | Error, R | Env>Env>
): <function (type parameter) E in <E, R>(self: Effect<Input, E, R>): Effect<Output, E | Error, R | Env>E, function (type parameter) R in <E, R>(self: Effect<Input, E, R>): Effect<Output, E | Error, R | Env>R>(self: Effect<Input, E, R>(parameter) self: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self: interface Effect<out A, out E = never, out R = never>The Effect interface defines a value that lazily describes a workflow or
job. The workflow requires some context R, and may fail with an error of
type E, or succeed with a value of type A.
When to use
Use when you need to represent a lazy, composable workflow that can require
services, fail with a typed error, or succeed with a typed value.
Details
Effect values model resourceful interaction with the outside world,
including synchronous, asynchronous, concurrent, and parallel interaction.
They use a fiber-based concurrency model, with built-in support for
scheduling, fine-grained interruption, structured concurrency, and high
scalability.
To run an Effect value, you need a Runtime, which is a type that is
capable of executing Effect values.
Effect<function (type parameter) Input in <Output, Input, Error, Env>(builder: ($: <O, E, R>(_: Schedule<O, NoInfer<Input>, E, R>) => Schedule<O, Input, E, R>) => Schedule<Output, NoInfer<Input>, Error, Env>): <E, R>(self: Effect<Input, E, R>) => Effect<Output, E | Error, R | Env>Input, function (type parameter) E in <E, R>(self: Effect<Input, E, R>): Effect<Output, E | Error, R | Env>E, function (type parameter) R in <E, R>(self: Effect<Input, E, R>): Effect<Output, E | Error, R | Env>R>) => interface Effect<out A, out E = never, out R = never>The Effect interface defines a value that lazily describes a workflow or
job. The workflow requires some context R, and may fail with an error of
type E, or succeed with a value of type A.
When to use
Use when you need to represent a lazy, composable workflow that can require
services, fail with a typed error, or succeed with a typed value.
Details
Effect values model resourceful interaction with the outside world,
including synchronous, asynchronous, concurrent, and parallel interaction.
They use a fiber-based concurrency model, with built-in support for
scheduling, fine-grained interruption, structured concurrency, and high
scalability.
To run an Effect value, you need a Runtime, which is a type that is
capable of executing Effect values.
Effect<function (type parameter) Output in <Output, Input, Error, Env>(builder: ($: <O, E, R>(_: Schedule<O, NoInfer<Input>, E, R>) => Schedule<O, Input, E, R>) => Schedule<Output, NoInfer<Input>, Error, Env>): <E, R>(self: Effect<Input, E, R>) => Effect<Output, E | Error, R | Env>Output, function (type parameter) E in <E, R>(self: Effect<Input, E, R>): Effect<Output, E | Error, R | Env>E | function (type parameter) Error in <Output, Input, Error, Env>(builder: ($: <O, E, R>(_: Schedule<O, NoInfer<Input>, E, R>) => Schedule<O, Input, E, R>) => Schedule<Output, NoInfer<Input>, Error, Env>): <E, R>(self: Effect<Input, E, R>) => Effect<Output, E | Error, R | Env>Error, function (type parameter) R in <E, R>(self: Effect<Input, E, R>): Effect<Output, E | Error, R | Env>R | function (type parameter) Env in <Output, Input, Error, Env>(builder: ($: <O, E, R>(_: Schedule<O, NoInfer<Input>, E, R>) => Schedule<O, Input, E, R>) => Schedule<Output, NoInfer<Input>, Error, Env>): <E, R>(self: Effect<Input, E, R>) => Effect<Output, E | Error, R | Env>Env>
<function (type parameter) A in <A, E, R, O extends Repeat.Options<A>>(self: Effect<A, E, R>, options: O): Repeat.Return<R, E, A, O>A, function (type parameter) E in <A, E, R, O extends Repeat.Options<A>>(self: Effect<A, E, R>, options: O): Repeat.Return<R, E, A, O>E, function (type parameter) R in <A, E, R, O extends Repeat.Options<A>>(self: Effect<A, E, R>, options: O): Repeat.Return<R, E, A, O>R, function (type parameter) O in <A, E, R, O extends Repeat.Options<A>>(self: Effect<A, E, R>, options: O): Repeat.Return<R, E, A, O>O extends Repeat.interface Repeat.Options<A>Options that control whether and how an effect is repeated.
Options<function (type parameter) A in <A, E, R, O extends Repeat.Options<A>>(self: Effect<A, E, R>, options: O): Repeat.Return<R, E, A, O>A>>(self: Effect<A, E, R>(parameter) self: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self: interface Effect<out A, out E = never, out R = never>The Effect interface defines a value that lazily describes a workflow or
job. The workflow requires some context R, and may fail with an error of
type E, or succeed with a value of type A.
When to use
Use when you need to represent a lazy, composable workflow that can require
services, fail with a typed error, or succeed with a typed value.
Details
Effect values model resourceful interaction with the outside world,
including synchronous, asynchronous, concurrent, and parallel interaction.
They use a fiber-based concurrency model, with built-in support for
scheduling, fine-grained interruption, structured concurrency, and high
scalability.
To run an Effect value, you need a Runtime, which is a type that is
capable of executing Effect values.
Effect<function (type parameter) A in <A, E, R, O extends Repeat.Options<A>>(self: Effect<A, E, R>, options: O): Repeat.Return<R, E, A, O>A, function (type parameter) E in <A, E, R, O extends Repeat.Options<A>>(self: Effect<A, E, R>, options: O): Repeat.Return<R, E, A, O>E, function (type parameter) R in <A, E, R, O extends Repeat.Options<A>>(self: Effect<A, E, R>, options: O): Repeat.Return<R, E, A, O>R>, options: O extends Repeat.Options<A>options: function (type parameter) O in <A, E, R, O extends Repeat.Options<A>>(self: Effect<A, E, R>, options: O): Repeat.Return<R, E, A, O>O): Repeat.type Repeat.Return<R, E, A, O extends Repeat.Options<A>> = Effect<O extends {
until: Predicate.Refinement<A, infer B>;
} ? B : O extends {
while: Predicate.Refinement<A, infer B>;
} ? Exclude<A, B> : A, E | (O extends {
schedule: Schedule<infer _Out, infer _I, infer E, infer _R>;
} ? E : never) | (O extends {
while: (...args: Array<any>) => Effect<infer _A, infer E, infer _R>;
} ? E : never) | (O extends {
until: (...args: Array<any>) => Effect<infer _A, infer E, infer _R>;
} ? E : never), R | (O extends {
schedule: Schedule<infer _O, infer _I, infer _E, infer R>;
} ? R : never) | (O extends {
...;
} ? R : never) | (O extends {
...;
} ? R : never)>
Computes the result type of Effect.repeat from the original effect and repeat options.
Return<function (type parameter) R in <A, E, R, O extends Repeat.Options<A>>(self: Effect<A, E, R>, options: O): Repeat.Return<R, E, A, O>R, function (type parameter) E in <A, E, R, O extends Repeat.Options<A>>(self: Effect<A, E, R>, options: O): Repeat.Return<R, E, A, O>E, function (type parameter) A in <A, E, R, O extends Repeat.Options<A>>(self: Effect<A, E, R>, options: O): Repeat.Return<R, E, A, O>A, function (type parameter) O in <A, E, R, O extends Repeat.Options<A>>(self: Effect<A, E, R>, options: O): Repeat.Return<R, E, A, O>O>
<function (type parameter) Input in <Input, E, R, Output, Error, Env>(self: Effect<Input, E, R>, schedule: Schedule<Output, NoInfer<Input>, Error, Env>): Effect<Output, E | Error, R | Env>Input, function (type parameter) E in <Input, E, R, Output, Error, Env>(self: Effect<Input, E, R>, schedule: Schedule<Output, NoInfer<Input>, Error, Env>): Effect<Output, E | Error, R | Env>E, function (type parameter) R in <Input, E, R, Output, Error, Env>(self: Effect<Input, E, R>, schedule: Schedule<Output, NoInfer<Input>, Error, Env>): Effect<Output, E | Error, R | Env>R, function (type parameter) Output in <Input, E, R, Output, Error, Env>(self: Effect<Input, E, R>, schedule: Schedule<Output, NoInfer<Input>, Error, Env>): Effect<Output, E | Error, R | Env>Output, function (type parameter) Error in <Input, E, R, Output, Error, Env>(self: Effect<Input, E, R>, schedule: Schedule<Output, NoInfer<Input>, Error, Env>): Effect<Output, E | Error, R | Env>Error, function (type parameter) Env in <Input, E, R, Output, Error, Env>(self: Effect<Input, E, R>, schedule: Schedule<Output, NoInfer<Input>, Error, Env>): Effect<Output, E | Error, R | Env>Env>(
self: Effect<Input, E, R>(parameter) self: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self: interface Effect<out A, out E = never, out R = never>The Effect interface defines a value that lazily describes a workflow or
job. The workflow requires some context R, and may fail with an error of
type E, or succeed with a value of type A.
When to use
Use when you need to represent a lazy, composable workflow that can require
services, fail with a typed error, or succeed with a typed value.
Details
Effect values model resourceful interaction with the outside world,
including synchronous, asynchronous, concurrent, and parallel interaction.
They use a fiber-based concurrency model, with built-in support for
scheduling, fine-grained interruption, structured concurrency, and high
scalability.
To run an Effect value, you need a Runtime, which is a type that is
capable of executing Effect values.
Effect<function (type parameter) Input in <Input, E, R, Output, Error, Env>(self: Effect<Input, E, R>, schedule: Schedule<Output, NoInfer<Input>, Error, Env>): Effect<Output, E | Error, R | Env>Input, function (type parameter) E in <Input, E, R, Output, Error, Env>(self: Effect<Input, E, R>, schedule: Schedule<Output, NoInfer<Input>, Error, Env>): Effect<Output, E | Error, R | Env>E, function (type parameter) R in <Input, E, R, Output, Error, Env>(self: Effect<Input, E, R>, schedule: Schedule<Output, NoInfer<Input>, Error, Env>): Effect<Output, E | Error, R | Env>R>,
schedule: Schedule<
Output,
NoInfer<Input>,
Error,
Env
>
(parameter) schedule: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
schedule: interface Schedule<out Output, in Input = unknown, out Error = never, out Env = never>A Schedule defines a strategy for repeating or retrying effects based on some policy.
Example (Defining retry and repeat schedules)
import { Console, Data, Effect, Schedule } from "effect"
class NetworkError extends Data.TaggedError("NetworkError")<{
readonly attempt: number
}> {}
// Basic retry schedule - retry up to 3 times with exponential backoff
const retrySchedule = Schedule.max([
Schedule.exponential("100 millis"),
Schedule.recurs(3)
])
// Basic repeat schedule - repeat every 30 seconds forever
const repeatSchedule: Schedule.Schedule<number, unknown, never> = Schedule
.spaced("30 seconds")
const program = Effect.gen(function*() {
let attempts = 0
const result1 = yield* Effect.retry(
Effect.gen(function*() {
attempts++
if (attempts < 3) {
return yield* Effect.fail(new NetworkError({ attempt: attempts }))
}
return "Success"
}),
retrySchedule
)
console.log(result1) // "Success"
yield* Console.log("heartbeat").pipe(
Effect.repeat(repeatSchedule.pipe(Schedule.upTo({ times: 5 })))
)
})
The Schedule namespace contains types and utilities for working with schedules.
Schedule<function (type parameter) Output in <Input, E, R, Output, Error, Env>(self: Effect<Input, E, R>, schedule: Schedule<Output, NoInfer<Input>, Error, Env>): Effect<Output, E | Error, R | Env>Output, type NoInfer<A> = [A][A extends any ? 0 : never]Prevents TypeScript from inferring a type parameter from a specific
position.
When to use
Use when a function parameter must match an inferred type without becoming
an inference source.
Details
The parameter using NoInfer must still match the inferred type.
Example (Controlling inference)
import type { Types } from "effect"
declare function withDefault<T>(value: T, fallback: Types.NoInfer<T>): T
// T is inferred as "a" | "b" from the first argument only
const result = withDefault<"a" | "b">("a", "b")
NoInfer<function (type parameter) Input in <Input, E, R, Output, Error, Env>(self: Effect<Input, E, R>, schedule: Schedule<Output, NoInfer<Input>, Error, Env>): Effect<Output, E | Error, R | Env>Input>, function (type parameter) Error in <Input, E, R, Output, Error, Env>(self: Effect<Input, E, R>, schedule: Schedule<Output, NoInfer<Input>, Error, Env>): Effect<Output, E | Error, R | Env>Error, function (type parameter) Env in <Input, E, R, Output, Error, Env>(self: Effect<Input, E, R>, schedule: Schedule<Output, NoInfer<Input>, Error, Env>): Effect<Output, E | Error, R | Env>Env>
): interface Effect<out A, out E = never, out R = never>The Effect interface defines a value that lazily describes a workflow or
job. The workflow requires some context R, and may fail with an error of
type E, or succeed with a value of type A.
When to use
Use when you need to represent a lazy, composable workflow that can require
services, fail with a typed error, or succeed with a typed value.
Details
Effect values model resourceful interaction with the outside world,
including synchronous, asynchronous, concurrent, and parallel interaction.
They use a fiber-based concurrency model, with built-in support for
scheduling, fine-grained interruption, structured concurrency, and high
scalability.
To run an Effect value, you need a Runtime, which is a type that is
capable of executing Effect values.
Effect<function (type parameter) Output in <Input, E, R, Output, Error, Env>(self: Effect<Input, E, R>, schedule: Schedule<Output, NoInfer<Input>, Error, Env>): Effect<Output, E | Error, R | Env>Output, function (type parameter) E in <Input, E, R, Output, Error, Env>(self: Effect<Input, E, R>, schedule: Schedule<Output, NoInfer<Input>, Error, Env>): Effect<Output, E | Error, R | Env>E | function (type parameter) Error in <Input, E, R, Output, Error, Env>(self: Effect<Input, E, R>, schedule: Schedule<Output, NoInfer<Input>, Error, Env>): Effect<Output, E | Error, R | Env>Error, function (type parameter) R in <Input, E, R, Output, Error, Env>(self: Effect<Input, E, R>, schedule: Schedule<Output, NoInfer<Input>, Error, Env>): Effect<Output, E | Error, R | Env>R | function (type parameter) Env in <Input, E, R, Output, Error, Env>(self: Effect<Input, E, R>, schedule: Schedule<Output, NoInfer<Input>, Error, Env>): Effect<Output, E | Error, R | Env>Env>
<function (type parameter) Input in <Input, E, R, Output, Error, Env>(self: Effect<Input, E, R>, builder: ($: <O, E, R>(_: Schedule<O, NoInfer<Input>, E, R>) => Schedule<O, Input, E, R>) => Schedule<Output, NoInfer<Input>, Error, Env>): Effect<Output, E | Error, R | Env>Input, function (type parameter) E in <Input, E, R, Output, Error, Env>(self: Effect<Input, E, R>, builder: ($: <O, E, R>(_: Schedule<O, NoInfer<Input>, E, R>) => Schedule<O, Input, E, R>) => Schedule<Output, NoInfer<Input>, Error, Env>): Effect<Output, E | Error, R | Env>E, function (type parameter) R in <Input, E, R, Output, Error, Env>(self: Effect<Input, E, R>, builder: ($: <O, E, R>(_: Schedule<O, NoInfer<Input>, E, R>) => Schedule<O, Input, E, R>) => Schedule<Output, NoInfer<Input>, Error, Env>): Effect<Output, E | Error, R | Env>R, function (type parameter) Output in <Input, E, R, Output, Error, Env>(self: Effect<Input, E, R>, builder: ($: <O, E, R>(_: Schedule<O, NoInfer<Input>, E, R>) => Schedule<O, Input, E, R>) => Schedule<Output, NoInfer<Input>, Error, Env>): Effect<Output, E | Error, R | Env>Output, function (type parameter) Error in <Input, E, R, Output, Error, Env>(self: Effect<Input, E, R>, builder: ($: <O, E, R>(_: Schedule<O, NoInfer<Input>, E, R>) => Schedule<O, Input, E, R>) => Schedule<Output, NoInfer<Input>, Error, Env>): Effect<Output, E | Error, R | Env>Error, function (type parameter) Env in <Input, E, R, Output, Error, Env>(self: Effect<Input, E, R>, builder: ($: <O, E, R>(_: Schedule<O, NoInfer<Input>, E, R>) => Schedule<O, Input, E, R>) => Schedule<Output, NoInfer<Input>, Error, Env>): Effect<Output, E | Error, R | Env>Env>(
self: Effect<Input, E, R>(parameter) self: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self: interface Effect<out A, out E = never, out R = never>The Effect interface defines a value that lazily describes a workflow or
job. The workflow requires some context R, and may fail with an error of
type E, or succeed with a value of type A.
When to use
Use when you need to represent a lazy, composable workflow that can require
services, fail with a typed error, or succeed with a typed value.
Details
Effect values model resourceful interaction with the outside world,
including synchronous, asynchronous, concurrent, and parallel interaction.
They use a fiber-based concurrency model, with built-in support for
scheduling, fine-grained interruption, structured concurrency, and high
scalability.
To run an Effect value, you need a Runtime, which is a type that is
capable of executing Effect values.
Effect<function (type parameter) Input in <Input, E, R, Output, Error, Env>(self: Effect<Input, E, R>, builder: ($: <O, E, R>(_: Schedule<O, NoInfer<Input>, E, R>) => Schedule<O, Input, E, R>) => Schedule<Output, NoInfer<Input>, Error, Env>): Effect<Output, E | Error, R | Env>Input, function (type parameter) E in <Input, E, R, Output, Error, Env>(self: Effect<Input, E, R>, builder: ($: <O, E, R>(_: Schedule<O, NoInfer<Input>, E, R>) => Schedule<O, Input, E, R>) => Schedule<Output, NoInfer<Input>, Error, Env>): Effect<Output, E | Error, R | Env>E, function (type parameter) R in <Input, E, R, Output, Error, Env>(self: Effect<Input, E, R>, builder: ($: <O, E, R>(_: Schedule<O, NoInfer<Input>, E, R>) => Schedule<O, Input, E, R>) => Schedule<Output, NoInfer<Input>, Error, Env>): Effect<Output, E | Error, R | Env>R>,
builder: (
$: <O, E, R>(
_: Schedule<O, NoInfer<Input>, E, R>
) => Schedule<O, Input, E, R>
) => Schedule<Output, NoInfer<Input>, Error, Env>
builder: (
$: <O, E, R>(
_: Schedule<O, NoInfer<Input>, E, R>
) => Schedule<O, Input, E, R>
$: <function (type parameter) O in <O, E, R>(_: Schedule<O, NoInfer<Input>, E, R>): Schedule<O, Input, E, R>O, function (type parameter) E in <O, E, R>(_: Schedule<O, NoInfer<Input>, E, R>): Schedule<O, Input, E, R>E, function (type parameter) R in <O, E, R>(_: Schedule<O, NoInfer<Input>, E, R>): Schedule<O, Input, E, R>R>(_: Schedule<O, NoInfer<Input>, E, R>(parameter) _: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
_: interface Schedule<out Output, in Input = unknown, out Error = never, out Env = never>A Schedule defines a strategy for repeating or retrying effects based on some policy.
Example (Defining retry and repeat schedules)
import { Console, Data, Effect, Schedule } from "effect"
class NetworkError extends Data.TaggedError("NetworkError")<{
readonly attempt: number
}> {}
// Basic retry schedule - retry up to 3 times with exponential backoff
const retrySchedule = Schedule.max([
Schedule.exponential("100 millis"),
Schedule.recurs(3)
])
// Basic repeat schedule - repeat every 30 seconds forever
const repeatSchedule: Schedule.Schedule<number, unknown, never> = Schedule
.spaced("30 seconds")
const program = Effect.gen(function*() {
let attempts = 0
const result1 = yield* Effect.retry(
Effect.gen(function*() {
attempts++
if (attempts < 3) {
return yield* Effect.fail(new NetworkError({ attempt: attempts }))
}
return "Success"
}),
retrySchedule
)
console.log(result1) // "Success"
yield* Console.log("heartbeat").pipe(
Effect.repeat(repeatSchedule.pipe(Schedule.upTo({ times: 5 })))
)
})
The Schedule namespace contains types and utilities for working with schedules.
Schedule<function (type parameter) O in <O, E, R>(_: Schedule<O, NoInfer<Input>, E, R>): Schedule<O, Input, E, R>O, type NoInfer<A> = [A][A extends any ? 0 : never]Prevents TypeScript from inferring a type parameter from a specific
position.
When to use
Use when a function parameter must match an inferred type without becoming
an inference source.
Details
The parameter using NoInfer must still match the inferred type.
Example (Controlling inference)
import type { Types } from "effect"
declare function withDefault<T>(value: T, fallback: Types.NoInfer<T>): T
// T is inferred as "a" | "b" from the first argument only
const result = withDefault<"a" | "b">("a", "b")
NoInfer<function (type parameter) Input in <Input, E, R, Output, Error, Env>(self: Effect<Input, E, R>, builder: ($: <O, E, R>(_: Schedule<O, NoInfer<Input>, E, R>) => Schedule<O, Input, E, R>) => Schedule<Output, NoInfer<Input>, Error, Env>): Effect<Output, E | Error, R | Env>Input>, function (type parameter) E in <O, E, R>(_: Schedule<O, NoInfer<Input>, E, R>): Schedule<O, Input, E, R>E, function (type parameter) R in <O, E, R>(_: Schedule<O, NoInfer<Input>, E, R>): Schedule<O, Input, E, R>R>) => interface Schedule<out Output, in Input = unknown, out Error = never, out Env = never>A Schedule defines a strategy for repeating or retrying effects based on some policy.
Example (Defining retry and repeat schedules)
import { Console, Data, Effect, Schedule } from "effect"
class NetworkError extends Data.TaggedError("NetworkError")<{
readonly attempt: number
}> {}
// Basic retry schedule - retry up to 3 times with exponential backoff
const retrySchedule = Schedule.max([
Schedule.exponential("100 millis"),
Schedule.recurs(3)
])
// Basic repeat schedule - repeat every 30 seconds forever
const repeatSchedule: Schedule.Schedule<number, unknown, never> = Schedule
.spaced("30 seconds")
const program = Effect.gen(function*() {
let attempts = 0
const result1 = yield* Effect.retry(
Effect.gen(function*() {
attempts++
if (attempts < 3) {
return yield* Effect.fail(new NetworkError({ attempt: attempts }))
}
return "Success"
}),
retrySchedule
)
console.log(result1) // "Success"
yield* Console.log("heartbeat").pipe(
Effect.repeat(repeatSchedule.pipe(Schedule.upTo({ times: 5 })))
)
})
The Schedule namespace contains types and utilities for working with schedules.
Schedule<function (type parameter) O in <O, E, R>(_: Schedule<O, NoInfer<Input>, E, R>): Schedule<O, Input, E, R>O, function (type parameter) Input in <Input, E, R, Output, Error, Env>(self: Effect<Input, E, R>, builder: ($: <O, E, R>(_: Schedule<O, NoInfer<Input>, E, R>) => Schedule<O, Input, E, R>) => Schedule<Output, NoInfer<Input>, Error, Env>): Effect<Output, E | Error, R | Env>Input, function (type parameter) E in <O, E, R>(_: Schedule<O, NoInfer<Input>, E, R>): Schedule<O, Input, E, R>E, function (type parameter) R in <O, E, R>(_: Schedule<O, NoInfer<Input>, E, R>): Schedule<O, Input, E, R>R>
) => interface Schedule<out Output, in Input = unknown, out Error = never, out Env = never>A Schedule defines a strategy for repeating or retrying effects based on some policy.
Example (Defining retry and repeat schedules)
import { Console, Data, Effect, Schedule } from "effect"
class NetworkError extends Data.TaggedError("NetworkError")<{
readonly attempt: number
}> {}
// Basic retry schedule - retry up to 3 times with exponential backoff
const retrySchedule = Schedule.max([
Schedule.exponential("100 millis"),
Schedule.recurs(3)
])
// Basic repeat schedule - repeat every 30 seconds forever
const repeatSchedule: Schedule.Schedule<number, unknown, never> = Schedule
.spaced("30 seconds")
const program = Effect.gen(function*() {
let attempts = 0
const result1 = yield* Effect.retry(
Effect.gen(function*() {
attempts++
if (attempts < 3) {
return yield* Effect.fail(new NetworkError({ attempt: attempts }))
}
return "Success"
}),
retrySchedule
)
console.log(result1) // "Success"
yield* Console.log("heartbeat").pipe(
Effect.repeat(repeatSchedule.pipe(Schedule.upTo({ times: 5 })))
)
})
The Schedule namespace contains types and utilities for working with schedules.
Schedule<function (type parameter) Output in <Input, E, R, Output, Error, Env>(self: Effect<Input, E, R>, builder: ($: <O, E, R>(_: Schedule<O, NoInfer<Input>, E, R>) => Schedule<O, Input, E, R>) => Schedule<Output, NoInfer<Input>, Error, Env>): Effect<Output, E | Error, R | Env>Output, type NoInfer<A> = [A][A extends any ? 0 : never]Prevents TypeScript from inferring a type parameter from a specific
position.
When to use
Use when a function parameter must match an inferred type without becoming
an inference source.
Details
The parameter using NoInfer must still match the inferred type.
Example (Controlling inference)
import type { Types } from "effect"
declare function withDefault<T>(value: T, fallback: Types.NoInfer<T>): T
// T is inferred as "a" | "b" from the first argument only
const result = withDefault<"a" | "b">("a", "b")
NoInfer<function (type parameter) Input in <Input, E, R, Output, Error, Env>(self: Effect<Input, E, R>, builder: ($: <O, E, R>(_: Schedule<O, NoInfer<Input>, E, R>) => Schedule<O, Input, E, R>) => Schedule<Output, NoInfer<Input>, Error, Env>): Effect<Output, E | Error, R | Env>Input>, function (type parameter) Error in <Input, E, R, Output, Error, Env>(self: Effect<Input, E, R>, builder: ($: <O, E, R>(_: Schedule<O, NoInfer<Input>, E, R>) => Schedule<O, Input, E, R>) => Schedule<Output, NoInfer<Input>, Error, Env>): Effect<Output, E | Error, R | Env>Error, function (type parameter) Env in <Input, E, R, Output, Error, Env>(self: Effect<Input, E, R>, builder: ($: <O, E, R>(_: Schedule<O, NoInfer<Input>, E, R>) => Schedule<O, Input, E, R>) => Schedule<Output, NoInfer<Input>, Error, Env>): Effect<Output, E | Error, R | Env>Env>
): interface Effect<out A, out E = never, out R = never>The Effect interface defines a value that lazily describes a workflow or
job. The workflow requires some context R, and may fail with an error of
type E, or succeed with a value of type A.
When to use
Use when you need to represent a lazy, composable workflow that can require
services, fail with a typed error, or succeed with a typed value.
Details
Effect values model resourceful interaction with the outside world,
including synchronous, asynchronous, concurrent, and parallel interaction.
They use a fiber-based concurrency model, with built-in support for
scheduling, fine-grained interruption, structured concurrency, and high
scalability.
To run an Effect value, you need a Runtime, which is a type that is
capable of executing Effect values.
Effect<function (type parameter) Output in <Input, E, R, Output, Error, Env>(self: Effect<Input, E, R>, builder: ($: <O, E, R>(_: Schedule<O, NoInfer<Input>, E, R>) => Schedule<O, Input, E, R>) => Schedule<Output, NoInfer<Input>, Error, Env>): Effect<Output, E | Error, R | Env>Output, function (type parameter) E in <Input, E, R, Output, Error, Env>(self: Effect<Input, E, R>, builder: ($: <O, E, R>(_: Schedule<O, NoInfer<Input>, E, R>) => Schedule<O, Input, E, R>) => Schedule<Output, NoInfer<Input>, Error, Env>): Effect<Output, E | Error, R | Env>E | function (type parameter) Error in <Input, E, R, Output, Error, Env>(self: Effect<Input, E, R>, builder: ($: <O, E, R>(_: Schedule<O, NoInfer<Input>, E, R>) => Schedule<O, Input, E, R>) => Schedule<Output, NoInfer<Input>, Error, Env>): Effect<Output, E | Error, R | Env>Error, function (type parameter) R in <Input, E, R, Output, Error, Env>(self: Effect<Input, E, R>, builder: ($: <O, E, R>(_: Schedule<O, NoInfer<Input>, E, R>) => Schedule<O, Input, E, R>) => Schedule<Output, NoInfer<Input>, Error, Env>): Effect<Output, E | Error, R | Env>R | function (type parameter) Env in <Input, E, R, Output, Error, Env>(self: Effect<Input, E, R>, builder: ($: <O, E, R>(_: Schedule<O, NoInfer<Input>, E, R>) => Schedule<O, Input, E, R>) => Schedule<Output, NoInfer<Input>, Error, Env>): Effect<Output, E | Error, R | Env>Env>
} = import internalScheduleinternalSchedule.const repeat: {
<O extends Repeat.Options<A>, A>(options: O): <
E,
R
>(
self: Effect<A, E, R>
) => Repeat.Return<R, E, A, O>
<Output, Input, Error, Env>(
schedule: Schedule<
Output,
NoInfer<Input>,
Error,
Env
>
): <E, R>(
self: Effect<Input, E, R>
) => Effect<Output, E | Error, R | Env>
<Output, Input, Error, Env>(
builder: (
$: <O, E, R>(
_: Schedule<O, NoInfer<Input>, E, R>
) => Schedule<O, Input, E, R>
) => Schedule<
Output,
NoInfer<Input>,
Error,
Env
>
): <E, R>(
self: Effect<Input, E, R>
) => Effect<Output, E | Error, R | Env>
} & {
<A, E, R, O extends Repeat.Options<A>>(
self: Effect<A, E, R>,
options: O
): Repeat.Return<R, E, A, O>
<Input, E, R, Output, Error, Env>(
self: Effect<Input, E, R>,
schedule: Schedule<
Output,
NoInfer<Input>,
Error,
Env
>
): Effect<Output, E | Error, R | Env>
<Input, E, R, Output, Error, Env>(
self: Effect<Input, E, R>,
builder: (
$: <O, E, R>(
_: Schedule<O, NoInfer<Input>, E, R>
) => Schedule<O, Input, E, R>
) => Schedule<
Output,
NoInfer<Input>,
Error,
Env
>
): Effect<Output, E | Error, R | Env>
}
repeat