<const Steps extends NonEmptyReadonlyArray<make.Step>>(
...steps: Steps & { [K in keyof Steps]: make.Step }
): ExecutionPlan<{
provides: make.StepProvides<Steps>
input: make.StepInput<Steps>
error:
| (Steps[number]["provide"] extends
| Context.Context<infer _P>
| Layer.Layer<infer _P, infer E, infer _R>
? E
: never)
| (Steps[number]["while"] extends (
input: infer _I
) => Effect.Effect<infer _A, infer _E, infer _R>
? _E
: never)
requirements:
| (Steps[number]["provide"] extends Layer.Layer<
infer _A,
infer _E,
infer R
>
? R
: never)
| (Steps[number]["while"] extends (
input: infer _I
) => Effect.Effect<infer _A, infer _E, infer R>
? R
: never)
| (Steps[number]["schedule"] extends Schedule.Schedule<
infer _O,
infer _I,
infer R
>
? R
: never)
}>Create an ExecutionPlan, which can be used with Effect.withExecutionPlan or Stream.withExecutionPlan, allowing you to provide different resources for each step of execution until the effect succeeds or the plan is exhausted.
Example (Creating an execution plan)
import { Effect, ExecutionPlan, Schedule } from "effect"
import type { Layer } from "effect"
import type { LanguageModel } from "effect/unstable/ai"
declare const layerBad: Layer.Layer<LanguageModel.LanguageModel>
declare const layerGood: Layer.Layer<LanguageModel.LanguageModel>
const ThePlan = ExecutionPlan.make(
{
// First try with the bad layer 2 times with a 3 second delay between attempts
provide: layerBad,
attempts: 2,
schedule: Schedule.spaced(3000)
},
// Then try with the bad layer 3 times with a 1 second delay between attempts
{
provide: layerBad,
attempts: 3,
schedule: Schedule.spaced(1000)
},
// Finally try with the good layer.
//
// If `attempts` is omitted, the plan will only attempt once, unless a schedule is provided.
{
provide: layerGood
}
)
declare const effect: Effect.Effect<
void,
never,
LanguageModel.LanguageModel
>
const withPlan: Effect.Effect<void> = Effect.withExecutionPlan(effect, ThePlan)export const const make: <const Steps extends NonEmptyReadonlyArray<make.Step>>(...steps: Steps & { [K in keyof Steps]: make.Step; }) => ExecutionPlan<{
provides: make.StepProvides<Steps>;
input: make.StepInput<Steps>;
error: (Steps[number]["provide"] extends Context.Context<infer _P> | Layer.Layer<infer _P, infer E, infer _R> ? E : never) | (Steps[number]["while"] extends (input: infer _I) => Effect.Effect<infer _A, infer _E, infer _R> ? _E : never);
requirements: (Steps[number]["provide"] extends Layer.Layer<infer _A, infer _E, infer R> ? R : never) | (Steps[number]["while"] extends (input: infer _I) => Effect.Effect<infer _A, infer _E, infer R> ? R : never) | (Steps[number]["schedule"] extends Schedule.Schedule<infer _O, infer _I, infer R> ? R : never);
}>
Create an ExecutionPlan, which can be used with Effect.withExecutionPlan or Stream.withExecutionPlan, allowing you to provide different resources for each step of execution until the effect succeeds or the plan is exhausted.
Example (Creating an execution plan)
import { Effect, ExecutionPlan, Schedule } from "effect"
import type { Layer } from "effect"
import type { LanguageModel } from "effect/unstable/ai"
declare const layerBad: Layer.Layer<LanguageModel.LanguageModel>
declare const layerGood: Layer.Layer<LanguageModel.LanguageModel>
const ThePlan = ExecutionPlan.make(
{
// First try with the bad layer 2 times with a 3 second delay between attempts
provide: layerBad,
attempts: 2,
schedule: Schedule.spaced(3000)
},
// Then try with the bad layer 3 times with a 1 second delay between attempts
{
provide: layerBad,
attempts: 3,
schedule: Schedule.spaced(1000)
},
// Finally try with the good layer.
//
// If `attempts` is omitted, the plan will only attempt once, unless a schedule is provided.
{
provide: layerGood
}
)
declare const effect: Effect.Effect<
void,
never,
LanguageModel.LanguageModel
>
const withPlan: Effect.Effect<void> = Effect.withExecutionPlan(effect, ThePlan)
Namespace containing type helpers used by ExecutionPlan.make.
make = <const function (type parameter) Steps in <const Steps extends NonEmptyReadonlyArray<make.Step>>(...steps: Steps & { [K in keyof Steps]: make.Step; }): ExecutionPlan<{
provides: make.StepProvides<Steps>;
input: make.StepInput<Steps>;
error: (Steps[number]["provide"] extends Context.Context<infer _P> | Layer.Layer<infer _P, infer E, infer _R> ? E : never) | (Steps[number]["while"] extends (input: infer _I) => Effect.Effect<infer _A, infer _E, infer _R> ? _E : never);
requirements: (Steps[number]["provide"] extends Layer.Layer<infer _A, infer _E, infer R> ? R : never) | (Steps[number]["while"] extends (input: infer _I) => Effect.Effect<infer _A, infer _E, infer R> ? R : never) | (Steps[number]["schedule"] extends Schedule.Schedule<infer _O, infer _I, infer R> ? R : never);
}>
Steps extends import NonEmptyReadonlyArrayNonEmptyReadonlyArray<make.type make.Step = {
readonly provide: Context.Context<any> | Context.Context<never> | Layer.Any;
readonly attempts?: number | undefined;
readonly while?: ((input: any) => boolean | Effect.Effect<boolean, any, any>) | undefined;
readonly schedule?: Schedule.Schedule<any, any, any> | undefined;
}
Input shape for a single execution-plan step.
Details
Each step provides a Context or Layer and may limit attempts, add a
while predicate for retry decisions, or attach a Schedule for retry
timing.
Step>>(
...steps: Steps & {
[K in keyof Steps]: make.Step
}
steps: function (type parameter) Steps in <const Steps extends NonEmptyReadonlyArray<make.Step>>(...steps: Steps & { [K in keyof Steps]: make.Step; }): ExecutionPlan<{
provides: make.StepProvides<Steps>;
input: make.StepInput<Steps>;
error: (Steps[number]["provide"] extends Context.Context<infer _P> | Layer.Layer<infer _P, infer E, infer _R> ? E : never) | (Steps[number]["while"] extends (input: infer _I) => Effect.Effect<infer _A, infer _E, infer _R> ? _E : never);
requirements: (Steps[number]["provide"] extends Layer.Layer<infer _A, infer _E, infer R> ? R : never) | (Steps[number]["while"] extends (input: infer _I) => Effect.Effect<infer _A, infer _E, infer R> ? R : never) | (Steps[number]["schedule"] extends Schedule.Schedule<infer _O, infer _I, infer R> ? R : never);
}>
Steps & { [function (type parameter) KK in keyof function (type parameter) Steps in <const Steps extends NonEmptyReadonlyArray<make.Step>>(...steps: Steps & { [K in keyof Steps]: make.Step; }): ExecutionPlan<{
provides: make.StepProvides<Steps>;
input: make.StepInput<Steps>;
error: (Steps[number]["provide"] extends Context.Context<infer _P> | Layer.Layer<infer _P, infer E, infer _R> ? E : never) | (Steps[number]["while"] extends (input: infer _I) => Effect.Effect<infer _A, infer _E, infer _R> ? _E : never);
requirements: (Steps[number]["provide"] extends Layer.Layer<infer _A, infer _E, infer R> ? R : never) | (Steps[number]["while"] extends (input: infer _I) => Effect.Effect<infer _A, infer _E, infer R> ? R : never) | (Steps[number]["schedule"] extends Schedule.Schedule<infer _O, infer _I, infer R> ? R : never);
}>
Steps]: make.type make.Step = {
readonly provide: Context.Context<any> | Context.Context<never> | Layer.Any;
readonly attempts?: number | undefined;
readonly while?: ((input: any) => boolean | Effect.Effect<boolean, any, any>) | undefined;
readonly schedule?: Schedule.Schedule<any, any, any> | undefined;
}
Input shape for a single execution-plan step.
Details
Each step provides a Context or Layer and may limit attempts, add a
while predicate for retry decisions, or attach a Schedule for retry
timing.
Step }
): interface ExecutionPlan<Config extends { provides: any; input: any; error: any; requirements: any; }>A ExecutionPlan can be used with Effect.withExecutionPlan or Stream.withExecutionPlan, allowing you to provide different resources for each step of execution until the effect succeeds or the plan is exhausted.
Example (Defining fallback execution steps)
import { Effect, ExecutionPlan, Schedule } from "effect"
import type { Layer } from "effect"
import type { LanguageModel } from "effect/unstable/ai"
declare const layerBad: Layer.Layer<LanguageModel.LanguageModel>
declare const layerGood: Layer.Layer<LanguageModel.LanguageModel>
const ThePlan = ExecutionPlan.make(
{
// First try with the bad layer 2 times with a 3 second delay between attempts
provide: layerBad,
attempts: 2,
schedule: Schedule.spaced(3000)
},
// Then try with the bad layer 3 times with a 1 second delay between attempts
{
provide: layerBad,
attempts: 3,
schedule: Schedule.spaced(1000)
},
// Finally try with the good layer.
//
// If `attempts` is omitted, the plan will only attempt once, unless a schedule is provided.
{
provide: layerGood
}
)
declare const effect: Effect.Effect<
void,
never,
LanguageModel.LanguageModel
>
const withPlan: Effect.Effect<void> = Effect.withExecutionPlan(effect, ThePlan)
ExecutionPlan<{
provides: make.StepProvides<Steps, unknown>provides: make.type make.StepProvides<Steps extends ReadonlyArray<any>, Out = unknown> = Steps extends readonly [infer Step, ...infer Rest] ? make.StepProvides<Rest, Out & (Step extends {
readonly provide: Context.Context<infer P> | Layer.Layer<infer P, infer _E, infer _R>;
} ? P : unknown)> : Out
Computes the intersection of services provided by a list of execution-plan
steps.
StepProvides<function (type parameter) Steps in <const Steps extends NonEmptyReadonlyArray<make.Step>>(...steps: Steps & { [K in keyof Steps]: make.Step; }): ExecutionPlan<{
provides: make.StepProvides<Steps>;
input: make.StepInput<Steps>;
error: (Steps[number]["provide"] extends Context.Context<infer _P> | Layer.Layer<infer _P, infer E, infer _R> ? E : never) | (Steps[number]["while"] extends (input: infer _I) => Effect.Effect<infer _A, infer _E, infer _R> ? _E : never);
requirements: (Steps[number]["provide"] extends Layer.Layer<infer _A, infer _E, infer R> ? R : never) | (Steps[number]["while"] extends (input: infer _I) => Effect.Effect<infer _A, infer _E, infer R> ? R : never) | (Steps[number]["schedule"] extends Schedule.Schedule<infer _O, infer _I, infer R> ? R : never);
}>
Steps>
input: make.StepInput<Steps, unknown>input: make.type make.StepInput<Steps extends ReadonlyArray<any>, Out = unknown> = Steps extends readonly [infer Step, ...infer Rest] ? make.StepInput<Rest, Out & (Step extends {
readonly while: (input: infer I) => infer _;
} ? I : unknown) & (Step extends {
readonly schedule: Schedule.Schedule<infer _O, infer I, infer _R>;
} ? I : unknown)> : Out
Computes the input type consumed by the while predicates and schedules in
a list of execution-plan steps.
StepInput<function (type parameter) Steps in <const Steps extends NonEmptyReadonlyArray<make.Step>>(...steps: Steps & { [K in keyof Steps]: make.Step; }): ExecutionPlan<{
provides: make.StepProvides<Steps>;
input: make.StepInput<Steps>;
error: (Steps[number]["provide"] extends Context.Context<infer _P> | Layer.Layer<infer _P, infer E, infer _R> ? E : never) | (Steps[number]["while"] extends (input: infer _I) => Effect.Effect<infer _A, infer _E, infer _R> ? _E : never);
requirements: (Steps[number]["provide"] extends Layer.Layer<infer _A, infer _E, infer R> ? R : never) | (Steps[number]["while"] extends (input: infer _I) => Effect.Effect<infer _A, infer _E, infer R> ? R : never) | (Steps[number]["schedule"] extends Schedule.Schedule<infer _O, infer _I, infer R> ? R : never);
}>
Steps>
error: | (Steps[number]["provide"] extends
| Context.Context<infer _P>
| Layer.Layer<infer _P, infer E, infer _R>
? E
: never)
| (Steps[number]["while"] extends (
input: infer _I
) => Effect.Effect<
infer _A,
infer _E,
infer _R
>
? _E
: never)
error:
| (function (type parameter) Steps in <const Steps extends NonEmptyReadonlyArray<make.Step>>(...steps: Steps & { [K in keyof Steps]: make.Step; }): ExecutionPlan<{
provides: make.StepProvides<Steps>;
input: make.StepInput<Steps>;
error: (Steps[number]["provide"] extends Context.Context<infer _P> | Layer.Layer<infer _P, infer E, infer _R> ? E : never) | (Steps[number]["while"] extends (input: infer _I) => Effect.Effect<infer _A, infer _E, infer _R> ? _E : never);
requirements: (Steps[number]["provide"] extends Layer.Layer<infer _A, infer _E, infer R> ? R : never) | (Steps[number]["while"] extends (input: infer _I) => Effect.Effect<infer _A, infer _E, infer R> ? R : never) | (Steps[number]["schedule"] extends Schedule.Schedule<infer _O, infer _I, infer R> ? R : never);
}>
Steps[number]["provide"] extends import ContextContext.type Context.Context = /*unresolved*/ anyContext<infer function (type parameter) _P_P> | import LayerLayer.interface Layer<in ROut, out E = never, out RIn = never>A Layer describes how to build one or more services for dependency injection.
When to use
Use to model construction of application services for dependency injection,
especially when services have dependencies, can fail during construction, or
need scoped setup and release.
Details
A Layer<ROut, E, RIn> represents ROut as the services this layer
provides, E as the possible errors during layer construction, and RIn as
the services this layer requires as dependencies.
Layer<infer function (type parameter) _P_P, infer function (type parameter) EE, infer function (type parameter) _R_R> ? function (type parameter) EE
: never)
| (function (type parameter) Steps in <const Steps extends NonEmptyReadonlyArray<make.Step>>(...steps: Steps & { [K in keyof Steps]: make.Step; }): ExecutionPlan<{
provides: make.StepProvides<Steps>;
input: make.StepInput<Steps>;
error: (Steps[number]["provide"] extends Context.Context<infer _P> | Layer.Layer<infer _P, infer E, infer _R> ? E : never) | (Steps[number]["while"] extends (input: infer _I) => Effect.Effect<infer _A, infer _E, infer _R> ? _E : never);
requirements: (Steps[number]["provide"] extends Layer.Layer<infer _A, infer _E, infer R> ? R : never) | (Steps[number]["while"] extends (input: infer _I) => Effect.Effect<infer _A, infer _E, infer R> ? R : never) | (Steps[number]["schedule"] extends Schedule.Schedule<infer _O, infer _I, infer R> ? R : never);
}>
Steps[number]["while"] extends (input: _Iinput: infer function (type parameter) _I_I) => import EffectEffect.type Effect.Effect = /*unresolved*/ anyEffect<infer function (type parameter) _A_A, infer function (type parameter) _E_E, infer function (type parameter) _R_R> ? function (type parameter) _E_E : never)
requirements: | (Steps[number]["provide"] extends Layer.Layer<
infer _A,
infer _E,
infer R
>
? R
: never)
| (Steps[number]["while"] extends (
input: infer _I
) => Effect.Effect<
infer _A,
infer _E,
infer R
>
? R
: never)
| (Steps[number]["schedule"] extends Schedule.Schedule<
infer _O,
infer _I,
infer R
>
? R
: never)
requirements:
| (function (type parameter) Steps in <const Steps extends NonEmptyReadonlyArray<make.Step>>(...steps: Steps & { [K in keyof Steps]: make.Step; }): ExecutionPlan<{
provides: make.StepProvides<Steps>;
input: make.StepInput<Steps>;
error: (Steps[number]["provide"] extends Context.Context<infer _P> | Layer.Layer<infer _P, infer E, infer _R> ? E : never) | (Steps[number]["while"] extends (input: infer _I) => Effect.Effect<infer _A, infer _E, infer _R> ? _E : never);
requirements: (Steps[number]["provide"] extends Layer.Layer<infer _A, infer _E, infer R> ? R : never) | (Steps[number]["while"] extends (input: infer _I) => Effect.Effect<infer _A, infer _E, infer R> ? R : never) | (Steps[number]["schedule"] extends Schedule.Schedule<infer _O, infer _I, infer R> ? R : never);
}>
Steps[number]["provide"] extends import LayerLayer.interface Layer<in ROut, out E = never, out RIn = never>A Layer describes how to build one or more services for dependency injection.
When to use
Use to model construction of application services for dependency injection,
especially when services have dependencies, can fail during construction, or
need scoped setup and release.
Details
A Layer<ROut, E, RIn> represents ROut as the services this layer
provides, E as the possible errors during layer construction, and RIn as
the services this layer requires as dependencies.
Layer<infer function (type parameter) _A_A, infer function (type parameter) _E_E, infer function (type parameter) RR> ? function (type parameter) RR : never)
| (function (type parameter) Steps in <const Steps extends NonEmptyReadonlyArray<make.Step>>(...steps: Steps & { [K in keyof Steps]: make.Step; }): ExecutionPlan<{
provides: make.StepProvides<Steps>;
input: make.StepInput<Steps>;
error: (Steps[number]["provide"] extends Context.Context<infer _P> | Layer.Layer<infer _P, infer E, infer _R> ? E : never) | (Steps[number]["while"] extends (input: infer _I) => Effect.Effect<infer _A, infer _E, infer _R> ? _E : never);
requirements: (Steps[number]["provide"] extends Layer.Layer<infer _A, infer _E, infer R> ? R : never) | (Steps[number]["while"] extends (input: infer _I) => Effect.Effect<infer _A, infer _E, infer R> ? R : never) | (Steps[number]["schedule"] extends Schedule.Schedule<infer _O, infer _I, infer R> ? R : never);
}>
Steps[number]["while"] extends (input: _Iinput: infer function (type parameter) _I_I) => import EffectEffect.type Effect.Effect = /*unresolved*/ anyEffect<infer function (type parameter) _A_A, infer function (type parameter) _E_E, infer function (type parameter) RR> ? function (type parameter) RR : never)
| (function (type parameter) Steps in <const Steps extends NonEmptyReadonlyArray<make.Step>>(...steps: Steps & { [K in keyof Steps]: make.Step; }): ExecutionPlan<{
provides: make.StepProvides<Steps>;
input: make.StepInput<Steps>;
error: (Steps[number]["provide"] extends Context.Context<infer _P> | Layer.Layer<infer _P, infer E, infer _R> ? E : never) | (Steps[number]["while"] extends (input: infer _I) => Effect.Effect<infer _A, infer _E, infer _R> ? _E : never);
requirements: (Steps[number]["provide"] extends Layer.Layer<infer _A, infer _E, infer R> ? R : never) | (Steps[number]["while"] extends (input: infer _I) => Effect.Effect<infer _A, infer _E, infer R> ? R : never) | (Steps[number]["schedule"] extends Schedule.Schedule<infer _O, infer _I, infer R> ? R : never);
}>
Steps[number]["schedule"] extends import ScheduleSchedule.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<infer function (type parameter) _O_O, infer function (type parameter) _I_I, infer function (type parameter) RR> ? function (type parameter) RR : never)
}> =>
const makeProto: <
Provides,
In,
PlanE,
PlanR
>(
steps: ExecutionPlan<{
provides: Provides
input: In
error: PlanE
requirements: PlanR
}>["steps"]
) => any
makeProto(steps: Steps & {
[K in keyof Steps]: make.Step
}
steps.map((options: any(parameter) options: {
provide: Context.Context<any> | Context.Context<never> | Layer.Any;
attempts: number | undefined;
while: ((input: any) => boolean | Effect.Effect<boolean, any, any>) | undefined;
schedule: Schedule.Schedule<any, any, any> | undefined;
}
options, i: anyi) => {
if (options: any(parameter) options: {
provide: Context.Context<any> | Context.Context<never> | Layer.Any;
attempts: number | undefined;
while: ((input: any) => boolean | Effect.Effect<boolean, any, any>) | undefined;
schedule: Schedule.Schedule<any, any, any> | undefined;
}
options.attempts && options: any(parameter) options: {
provide: Context.Context<any> | Context.Context<never> | Layer.Any;
attempts: number | undefined;
while: ((input: any) => boolean | Effect.Effect<boolean, any, any>) | undefined;
schedule: Schedule.Schedule<any, any, any> | undefined;
}
options.attempts < 1) {
throw new var Error: ErrorConstructor
new (message?: string, options?: ErrorOptions) => Error (+1 overload)
Error(`ExecutionPlan.make: step[${i: anyi}].attempts must be greater than 0`)
}
return {
schedule: anyschedule: options: any(parameter) options: {
provide: Context.Context<any> | Context.Context<never> | Layer.Any;
attempts: number | undefined;
while: ((input: any) => boolean | Effect.Effect<boolean, any, any>) | undefined;
schedule: Schedule.Schedule<any, any, any> | undefined;
}
options.schedule,
attempts: anyattempts: options: any(parameter) options: {
provide: Context.Context<any> | Context.Context<never> | Layer.Any;
attempts: number | undefined;
while: ((input: any) => boolean | Effect.Effect<boolean, any, any>) | undefined;
schedule: Schedule.Schedule<any, any, any> | undefined;
}
options.attempts,
while: | ((input: any) => Effect.Effect<A, E, R>)
| undefined
while: options: any(parameter) options: {
provide: Context.Context<any> | Context.Context<never> | Layer.Any;
attempts: number | undefined;
while: ((input: any) => boolean | Effect.Effect<boolean, any, any>) | undefined;
schedule: Schedule.Schedule<any, any, any> | undefined;
}
options.while
? (input: anyinput: any) =>
import effecteffect.const suspend: <A, E, R>(
evaluate: LazyArg<Effect.Effect<A, E, R>>
) => Effect.Effect<A, E, R>
suspend(() => {
const const result: anyresult = options: any(parameter) options: {
provide: Context.Context<any> | Context.Context<never> | Layer.Any;
attempts: number | undefined;
while: ((input: any) => boolean | Effect.Effect<boolean, any, any>) | undefined;
schedule: Schedule.Schedule<any, any, any> | undefined;
}
options.while!(input: anyinput)
return typeof const result: anyresult === "boolean" ? import effecteffect.const succeed: <A>(
value: A
) => Effect.Effect<A>
succeed(const result: booleanresult) : const result: Effect.Effect<
boolean,
any,
any
>
const result: {
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;
}
result
})
: var undefinedundefined,
provide: anyprovide: options: any(parameter) options: {
provide: Context.Context<any> | Context.Context<never> | Layer.Any;
attempts: number | undefined;
while: ((input: any) => boolean | Effect.Effect<boolean, any, any>) | undefined;
schedule: Schedule.Schedule<any, any, any> | undefined;
}
options.provide
}
}) as any)
/**
* Namespace containing type helpers used by `ExecutionPlan.make`.
*
* @since 3.16.0
*/
export declare namespace make {
/**
* Input shape for a single execution-plan step.
*
* **Details**
*
* Each step provides a `Context` or `Layer` and may limit attempts, add a
* `while` predicate for retry decisions, or attach a `Schedule` for retry
* timing.
*
* @category models
* @since 3.16.0
*/
export type type make.Step = {
readonly provide: Context.Context<any> | Context.Context<never> | Layer.Any;
readonly attempts?: number | undefined;
readonly while?: ((input: any) => boolean | Effect.Effect<boolean, any, any>) | undefined;
readonly schedule?: Schedule.Schedule<any, any, any> | undefined;
}
Input shape for a single execution-plan step.
Details
Each step provides a Context or Layer and may limit attempts, add a
while predicate for retry decisions, or attach a Schedule for retry
timing.
Step = {
readonly provide: | Context.Context<any>
| Context.Context<never>
| Layer.Any
provide: import ContextContext.type Context.Context = /*unresolved*/ anyContext<any> | import ContextContext.type Context.Context = /*unresolved*/ anyContext<never> | import LayerLayer.Any
readonly attempts?: number | undefinedattempts?: number | undefined
readonly while?: | ((
input: any
) =>
| boolean
| Effect.Effect<boolean, any, any>)
| undefined
while?: ((input: anyinput: any) => boolean | import EffectEffect.type Effect.Effect = /*unresolved*/ anyEffect<boolean, any, any>) | undefined
readonly schedule?: | Schedule.Schedule<any, any, any>
| undefined
schedule?: import ScheduleSchedule.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<any, any, any> | undefined
}
/**
* Computes the intersection of services provided by a list of execution-plan
* steps.
*
* @category utility types
* @since 3.16.1
*/
export type type make.StepProvides<Steps extends ReadonlyArray<any>, Out = unknown> = Steps extends readonly [infer Step, ...infer Rest] ? StepProvides<Rest, Out & (Step extends {
readonly provide: Context.Context<infer P> | Layer.Layer<infer P, infer _E, infer _R>;
} ? P : unknown)> : Out
Computes the intersection of services provided by a list of execution-plan
steps.
StepProvides<function (type parameter) Steps in type make.StepProvides<Steps extends ReadonlyArray<any>, Out = unknown>Steps extends interface ReadonlyArray<T>ReadonlyArray<any>, function (type parameter) Out in type make.StepProvides<Steps extends ReadonlyArray<any>, Out = unknown>Out = unknown> = function (type parameter) Steps in type make.StepProvides<Steps extends ReadonlyArray<any>, Out = unknown>Steps extends
readonly [infer function (type parameter) StepStep, ...infer function (type parameter) RestRest] ? type make.StepProvides<Steps extends ReadonlyArray<any>, Out = unknown> = Steps extends readonly [infer Step, ...infer Rest] ? StepProvides<Rest, Out & (Step extends {
readonly provide: Context.Context<infer P> | Layer.Layer<infer P, infer _E, infer _R>;
} ? P : unknown)> : Out
Computes the intersection of services provided by a list of execution-plan
steps.
StepProvides<
function (type parameter) RestRest,
& function (type parameter) Out in type make.StepProvides<Steps extends ReadonlyArray<any>, Out = unknown>Out
& (
(function (type parameter) StepStep extends { readonly provide: | Context.Context<infer P>
| Layer.Layer<infer P, infer _E, infer _R>
provide: import ContextContext.type Context.Context = /*unresolved*/ anyContext<infer function (type parameter) PP> | import LayerLayer.interface Layer<in ROut, out E = never, out RIn = never>A Layer describes how to build one or more services for dependency injection.
When to use
Use to model construction of application services for dependency injection,
especially when services have dependencies, can fail during construction, or
need scoped setup and release.
Details
A Layer<ROut, E, RIn> represents ROut as the services this layer
provides, E as the possible errors during layer construction, and RIn as
the services this layer requires as dependencies.
Layer<infer function (type parameter) PP, infer function (type parameter) _E_E, infer function (type parameter) _R_R> } ? function (type parameter) PP
: unknown)
)
> :
function (type parameter) Out in type make.StepProvides<Steps extends ReadonlyArray<any>, Out = unknown>Out
/**
* Computes the intersection of services provided by a list of execution plans.
*
* @category utility types
* @since 3.16.1
*/
export type type make.PlanProvides<Plans extends ReadonlyArray<any>, Out = unknown> = Plans extends readonly [infer Plan, ...infer Rest] ? PlanProvides<Rest, Out & (Plan extends ExecutionPlan<infer T extends {
provides: any;
input: any;
error: any;
requirements: any;
}> ? T["provides"] : unknown)> : Out
Computes the intersection of services provided by a list of execution plans.
PlanProvides<function (type parameter) Plans in type make.PlanProvides<Plans extends ReadonlyArray<any>, Out = unknown>Plans extends interface ReadonlyArray<T>ReadonlyArray<any>, function (type parameter) Out in type make.PlanProvides<Plans extends ReadonlyArray<any>, Out = unknown>Out = unknown> = function (type parameter) Plans in type make.PlanProvides<Plans extends ReadonlyArray<any>, Out = unknown>Plans extends
readonly [infer function (type parameter) PlanPlan, ...infer function (type parameter) RestRest] ?
type make.PlanProvides<Plans extends ReadonlyArray<any>, Out = unknown> = Plans extends readonly [infer Plan, ...infer Rest] ? PlanProvides<Rest, Out & (Plan extends ExecutionPlan<infer T extends {
provides: any;
input: any;
error: any;
requirements: any;
}> ? T["provides"] : unknown)> : Out
Computes the intersection of services provided by a list of execution plans.
PlanProvides<function (type parameter) RestRest, function (type parameter) Out in type make.PlanProvides<Plans extends ReadonlyArray<any>, Out = unknown>Out & (function (type parameter) PlanPlan extends interface ExecutionPlan<Config extends { provides: any; input: any; error: any; requirements: any; }>A ExecutionPlan can be used with Effect.withExecutionPlan or Stream.withExecutionPlan, allowing you to provide different resources for each step of execution until the effect succeeds or the plan is exhausted.
Example (Defining fallback execution steps)
import { Effect, ExecutionPlan, Schedule } from "effect"
import type { Layer } from "effect"
import type { LanguageModel } from "effect/unstable/ai"
declare const layerBad: Layer.Layer<LanguageModel.LanguageModel>
declare const layerGood: Layer.Layer<LanguageModel.LanguageModel>
const ThePlan = ExecutionPlan.make(
{
// First try with the bad layer 2 times with a 3 second delay between attempts
provide: layerBad,
attempts: 2,
schedule: Schedule.spaced(3000)
},
// Then try with the bad layer 3 times with a 1 second delay between attempts
{
provide: layerBad,
attempts: 3,
schedule: Schedule.spaced(1000)
},
// Finally try with the good layer.
//
// If `attempts` is omitted, the plan will only attempt once, unless a schedule is provided.
{
provide: layerGood
}
)
declare const effect: Effect.Effect<
void,
never,
LanguageModel.LanguageModel
>
const withPlan: Effect.Effect<void> = Effect.withExecutionPlan(effect, ThePlan)
ExecutionPlan<infer function (type parameter) TT> ? function (type parameter) TT["provides"] : unknown)> :
function (type parameter) Out in type make.PlanProvides<Plans extends ReadonlyArray<any>, Out = unknown>Out
/**
* Computes the input type consumed by the `while` predicates and schedules in
* a list of execution-plan steps.
*
* @category utility types
* @since 3.16.0
*/
export type type make.StepInput<Steps extends ReadonlyArray<any>, Out = unknown> = Steps extends readonly [infer Step, ...infer Rest] ? StepInput<Rest, Out & (Step extends {
readonly while: (input: infer I) => infer _;
} ? I : unknown) & (Step extends {
readonly schedule: Schedule.Schedule<infer _O, infer I, infer _R>;
} ? I : unknown)> : Out
Computes the input type consumed by the while predicates and schedules in
a list of execution-plan steps.
StepInput<function (type parameter) Steps in type make.StepInput<Steps extends ReadonlyArray<any>, Out = unknown>Steps extends interface ReadonlyArray<T>ReadonlyArray<any>, function (type parameter) Out in type make.StepInput<Steps extends ReadonlyArray<any>, Out = unknown>Out = unknown> = function (type parameter) Steps in type make.StepInput<Steps extends ReadonlyArray<any>, Out = unknown>Steps extends
readonly [infer function (type parameter) StepStep, ...infer function (type parameter) RestRest] ? type make.StepInput<Steps extends ReadonlyArray<any>, Out = unknown> = Steps extends readonly [infer Step, ...infer Rest] ? StepInput<Rest, Out & (Step extends {
readonly while: (input: infer I) => infer _;
} ? I : unknown) & (Step extends {
readonly schedule: Schedule.Schedule<infer _O, infer I, infer _R>;
} ? I : unknown)> : Out
Computes the input type consumed by the while predicates and schedules in
a list of execution-plan steps.
StepInput<
function (type parameter) RestRest,
& function (type parameter) Out in type make.StepInput<Steps extends ReadonlyArray<any>, Out = unknown>Out
& (
& (function (type parameter) StepStep extends { readonly while: (input: infer I) => infer _while: (input: Iinput: infer function (type parameter) II) => infer function (type parameter) __ } ? function (type parameter) II : unknown)
& (function (type parameter) StepStep extends { readonly schedule: Schedule.Schedule<
infer _O,
infer I,
infer _R
>
(property) 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: import ScheduleSchedule.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<infer function (type parameter) _O_O, infer function (type parameter) II, infer function (type parameter) _R_R> } ? function (type parameter) II : unknown)
)
> :
function (type parameter) Out in type make.StepInput<Steps extends ReadonlyArray<any>, Out = unknown>Out
/**
* Computes the combined input type consumed by a list of execution plans.
*
* @category utility types
* @since 3.16.0
*/
export type type make.PlanInput<Plans extends ReadonlyArray<any>, Out = unknown> = Plans extends readonly [infer Plan, ...infer Rest] ? PlanInput<Rest, Out & (Plan extends ExecutionPlan<infer T extends {
provides: any;
input: any;
error: any;
requirements: any;
}> ? T["input"] : unknown)> : Out
Computes the combined input type consumed by a list of execution plans.
PlanInput<function (type parameter) Plans in type make.PlanInput<Plans extends ReadonlyArray<any>, Out = unknown>Plans extends interface ReadonlyArray<T>ReadonlyArray<any>, function (type parameter) Out in type make.PlanInput<Plans extends ReadonlyArray<any>, Out = unknown>Out = unknown> = function (type parameter) Plans in type make.PlanInput<Plans extends ReadonlyArray<any>, Out = unknown>Plans extends
readonly [infer function (type parameter) PlanPlan, ...infer function (type parameter) RestRest] ?
type make.PlanInput<Plans extends ReadonlyArray<any>, Out = unknown> = Plans extends readonly [infer Plan, ...infer Rest] ? PlanInput<Rest, Out & (Plan extends ExecutionPlan<infer T extends {
provides: any;
input: any;
error: any;
requirements: any;
}> ? T["input"] : unknown)> : Out
Computes the combined input type consumed by a list of execution plans.
PlanInput<function (type parameter) RestRest, function (type parameter) Out in type make.PlanInput<Plans extends ReadonlyArray<any>, Out = unknown>Out & (function (type parameter) PlanPlan extends interface ExecutionPlan<Config extends { provides: any; input: any; error: any; requirements: any; }>A ExecutionPlan can be used with Effect.withExecutionPlan or Stream.withExecutionPlan, allowing you to provide different resources for each step of execution until the effect succeeds or the plan is exhausted.
Example (Defining fallback execution steps)
import { Effect, ExecutionPlan, Schedule } from "effect"
import type { Layer } from "effect"
import type { LanguageModel } from "effect/unstable/ai"
declare const layerBad: Layer.Layer<LanguageModel.LanguageModel>
declare const layerGood: Layer.Layer<LanguageModel.LanguageModel>
const ThePlan = ExecutionPlan.make(
{
// First try with the bad layer 2 times with a 3 second delay between attempts
provide: layerBad,
attempts: 2,
schedule: Schedule.spaced(3000)
},
// Then try with the bad layer 3 times with a 1 second delay between attempts
{
provide: layerBad,
attempts: 3,
schedule: Schedule.spaced(1000)
},
// Finally try with the good layer.
//
// If `attempts` is omitted, the plan will only attempt once, unless a schedule is provided.
{
provide: layerGood
}
)
declare const effect: Effect.Effect<
void,
never,
LanguageModel.LanguageModel
>
const withPlan: Effect.Effect<void> = Effect.withExecutionPlan(effect, ThePlan)
ExecutionPlan<infer function (type parameter) TT> ? function (type parameter) TT["input"] : unknown)> :
function (type parameter) Out in type make.PlanInput<Plans extends ReadonlyArray<any>, Out = unknown>Out
}