/** * Describes ordered fallback steps for running effects or streams. * * An `ExecutionPlan` contains one or more steps. Each step provides a `Context` * or `Layer`, and may also define attempt limits, retry schedules, or * predicates that decide whether to keep trying. The runtime tries steps in * order until the workflow succeeds or the plan is exhausted. This module also * supports merging plans and reading metadata for the active step and attempt. * * @stability unstable * @since 3.16.0 */ import type { NonEmptyReadonlyArray } from "./Array.ts"; import type * as Cause from "./Cause.ts"; import * as Context from "./Context.ts"; import type * as Duration from "./Duration.ts"; import type * as Effect from "./Effect.ts"; import * as Layer from "./Layer.ts"; import type { Pipeable } from "./Pipeable.ts"; import * as Schedule from "./Schedule.ts"; /** * String literal type used as the runtime type identifier for `ExecutionPlan` * values. * * @stability unstable * @category type IDs * @since 3.16.0 */ export type TypeId = "~effect/ExecutionPlan"; /** * Runtime type identifier attached to `ExecutionPlan` values and used by * `isExecutionPlan`. * * @stability unstable * @category type IDs * @since 3.16.0 */ export declare const TypeId: TypeId; /** * Returns `true` if a value is an `ExecutionPlan` by checking for the * `ExecutionPlan.TypeId` marker. * * **When to use** * * Use when accepting an unknown value and you need to narrow it to an * `ExecutionPlan` before reading plan fields or passing it to plan-consuming * APIs. * * **Gotchas** * * This is a structural marker check; it does not validate the marker value or * the shape of the plan steps. * * @see {@link make} for constructing execution plans that satisfy this guard * @see {@link TypeId} for the runtime marker checked by this guard * * @stability unstable * @category guards * @since 3.16.0 */ export declare const isExecutionPlan: (u: unknown) => u is ExecutionPlan; /** * 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) * * ```ts import.meta.vitest * import { Context, ExecutionPlan } from "effect" * * const ThePlan = ExecutionPlan.make( * { * provide: Context.empty(), * attempts: 2 * }, * { * provide: Context.empty() * } * ) * * ThePlan.steps.map((step) => step.attempts ?? 1) // => [2, 1] * ``` * * @stability unstable * @category models * @since 3.16.0 */ export interface ExecutionPlan extends Pipeable { readonly [TypeId]: TypeId; readonly steps: NonEmptyReadonlyArray<{ readonly provide: Context.Context | Layer.Layer; readonly attempts?: number | undefined; readonly while?: ((input: Config["input"]) => Effect.Effect) | undefined; readonly schedule?: Schedule.Schedule | undefined; }>; /** * Returns an equivalent `ExecutionPlan` with the requirements satisfied, using the current context. */ readonly captureRequirements: Effect.Effect, never, Config["requirements"]>; } /** * Base type-level configuration carried by an `ExecutionPlan`. * * **Details** * * `provides` tracks services supplied by plan steps, `input` tracks the error * input consumed by schedules and `while` predicates, `error` tracks failures * from plan layers, predicates, or schedules, and `requirements` tracks * services needed to build or run the plan. * * @stability unstable * @category models * @since 4.0.0 */ export type ConfigBase = { provides: any; input: any; error: any; requirements: any; }; /** * 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) * * ```ts import.meta.vitest * import { Context, ExecutionPlan } from "effect" * * const ThePlan = ExecutionPlan.make( * { * provide: Context.empty(), * attempts: 2 * }, * { * provide: Context.empty() * } * ) * * ThePlan.steps.length // => 2 * ``` * * @stability unstable * @category constructors * @since 3.16.0 */ export declare const make: >(...steps: Steps & { [K in keyof Steps]: make.Step; }) => ExecutionPlan<{ provides: make.StepProvides; input: make.StepInput; error: make.StepError; requirements: make.StepRequirements; }>; /** * Namespace containing type helpers used by `ExecutionPlan.make`. * * @stability unstable * @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 */ type Step = { readonly provide: Context.Context | Context.Context | Layer.Any; readonly attempts?: number | undefined; readonly while?: ((input: any) => boolean | Effect.Effect) | undefined; readonly schedule?: Schedule.Schedule | undefined; }; /** * Computes the errors from a step's layer, predicate, and schedule. * * @category utility types * @since 4.0.0 */ type StepError = (Step extends { readonly provide: Layer.Layer; } ? E : never) | (Step extends { readonly while?: (input: any) => infer Result; } ? Effect.Error : never) | (Step extends { readonly schedule?: infer S; } ? Schedule.Error : never); /** * Computes the services required by a step's layer, predicate, and schedule. * * @category utility types * @since 4.0.0 */ type StepRequirements = (Step extends { readonly provide: Layer.Layer; } ? R : never) | (Step extends { readonly while?: (input: any) => infer Result; } ? Effect.Services : never) | (Step extends { readonly schedule?: infer S; } ? Schedule.Env : never); /** * Computes the intersection of services provided by a list of execution-plan * steps. * * @category utility types * @since 3.16.1 */ type StepProvides, Out = unknown> = Steps extends readonly [infer Step, ...infer Rest] ? StepProvides | Layer.Layer; } ? P : unknown))> : Out; /** * Computes the intersection of services provided by a list of execution plans. * * @category utility types * @since 3.16.1 */ type PlanProvides, Out = unknown> = Plans extends readonly [infer Plan, ...infer Rest] ? PlanProvides ? T["provides"] : 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 */ type StepInput, Out = unknown> = Steps extends readonly [infer Step, ...infer Rest] ? StepInput infer _; } ? I : unknown) & (Step extends { readonly schedule: Schedule.Schedule; } ? I : unknown))> : Out; /** * Computes the combined input type consumed by a list of execution plans. * * @category utility types * @since 3.16.0 */ type PlanInput, Out = unknown> = Plans extends readonly [infer Plan, ...infer Rest] ? PlanInput ? T["input"] : unknown)> : Out; } /** * Combines multiple execution plans by concatenating their steps in order. * * **When to use** * * Use to combine separately defined fallback plans into one ordered plan before * applying it to an effect or stream. * * **Details** * * The resulting plan tries every step from the first plan, then every step from * the next plan, and so on. * * @see {@link make} for building a plan from individual steps instead of combining existing plans * * @stability unstable * @category combining * @since 3.16.0 */ export declare const merge: >>(...plans: Plans) => ExecutionPlan<{ provides: make.PlanProvides; input: make.PlanInput; error: Plans[number] extends ExecutionPlan ? T["error"] : never; requirements: Plans[number] extends ExecutionPlan ? T["requirements"] : never; }>; /** * Metadata describing the currently running execution-plan attempt. * * **Details** * * `attempt` is the current 1-based attempt number, and `stepIndex` is the * 0-based index of the plan step currently being evaluated. * * @stability unstable * @category metadata * @since 4.0.0 */ export interface Metadata { readonly attempt: number; readonly stepIndex: number; } /** * Context reference containing metadata for the currently running * execution-plan attempt. * * **When to use** * * Use to read the active plan step and attempt while code is running under an * execution plan. * * @stability unstable * @category services * @since 4.0.0 */ export declare const CurrentMetadata: Context.Reference; /** * Lifecycle event emitted before an execution-plan attempt runs. * * **Details** * * `attempt` is the cumulative 1-based attempt number across all steps and * matches `CurrentMetadata.attempt` for the same attempt. `stepAttempt` is the * 1-based attempt number within the current step, and `stepIndex` is the * 0-based index of the step being attempted. * * @stability unstable * @category models * @since 4.0.0 */ export interface AttemptStart { readonly _tag: "AttemptStart"; readonly attempt: number; readonly stepAttempt: number; readonly stepIndex: number; } /** * Lifecycle event emitted when an execution-plan attempt succeeds. * * **Details** * * A successful attempt completes the plan, so this is always the final event. * `duration` is the elapsed time of the attempt. * * @stability unstable * @category models * @since 4.0.0 */ export interface AttemptSuccess { readonly _tag: "AttemptSuccess"; readonly attempt: number; readonly stepAttempt: number; readonly stepIndex: number; readonly duration: Duration.Duration; } /** * Lifecycle event emitted when an execution-plan attempt fails. * * **Details** * * `cause` holds the full failure cause, so defects and interruption are * reported as well as expected errors. Whether the plan retries or fails over * afterwards is decided by the step's `attempts`, `while`, and `schedule`; a * following `AttemptStart` indicates another attempt was made. * * @stability unstable * @category models * @since 4.0.0 */ export interface AttemptFailure { readonly _tag: "AttemptFailure"; readonly attempt: number; readonly stepAttempt: number; readonly stepIndex: number; readonly duration: Duration.Duration; readonly cause: Cause.Cause; } /** * Union of the lifecycle events emitted while an execution plan runs. * * **Details** * * Every `AttemptStart` is followed by exactly one terminal event, either * `AttemptSuccess` or `AttemptFailure`. An interrupted attempt emits * `AttemptFailure` with the interruption cause. * * @stability unstable * @category models * @since 4.0.0 */ export type Event = AttemptStart | AttemptSuccess | AttemptFailure; //# sourceMappingURL=ExecutionPlan.d.ts.map