Skip to content

Workflow

Defines typed durable workflows.

A Workflow has a stable tag, schemas for payload, success, and failure, and an idempotency key used to derive execution ids. Workflow definitions can be executed, discarded, polled, interrupted, resumed, and registered with a handler layer. This module also includes workflow result types, compensation and cleanup helpers, suspension support, and settings for defect capture or failure suspension.

27 exports Added in v4.0.0 Source

Compensation

Adds compensation logic to an effect inside a Workflow.

When to use

Use when a top-level workflow step needs compensating cleanup if the overall workflow later fails after the step succeeds.

Details

The compensation finalizer is called if the entire workflow fails, allowing you to perform cleanup or other actions based on the success value and the cause of the workflow failure.

Gotchas

Compensation finalizers are only registered for top-level effects in the workflow and do not work for nested activities.

Signature

declare const withCompensation: {
  <A, R2>(
    compensation: (value: A, cause: Cause<unknown>) => Effect<void, never, R2>,
  ): <E, R>(effect: Effect<A, E, R>) => Effect<A, E, Scope | WorkflowInstance | R2 | R>;
  <A, E, R, R2>(
    effect: Effect<A, E, R>,
    compensation: (value: A, cause: Cause<unknown>) => Effect<void, never, R2>,
  ): Effect<A, E, Scope | WorkflowInstance | R | R2>;
};

Constructors

make

Added in v4.0.0 Source

Creates a durable workflow definition with schemas, annotations, and deterministic execution IDs derived from the workflow tag and idempotency key.

Signature

declare function make<
  Tag extends string,
  Payload extends Fields | AnyStructSchema,
  Success extends Top = Void,
  Error extends Top = Never,
>(
  tag: Tag,
  options: {
    readonly annotations?: Context<never>;
    readonly error?: Error;
    readonly idempotencyKey: (
      payload: Payload extends Fields
        ? View<Payload, "Type", TypeOptionalKeys<Payload>, TypeMutableKeys<Payload>>
        : Payload["Type"],
    ) => string;
    readonly payload: Payload;
    readonly success?: Success;
    readonly suspendedRetrySchedule?: Schedule<any, unknown, never, never>;
  },
): Workflow<Tag, Payload extends Fields ? Struct<Payload> : Payload, Success, Error>;

Converting

intoResult

Added in v4.0.0 Source

Runs an effect as a workflow execution and converts its outcome into a Result, handling suspension, defect capture, interruption, and workflow scope finalization.

Signature

declare function intoResult<A, E, R>(
  effect: Effect<A, E, R>,
): Effect<Result<A, E>, never, WorkflowInstance | Exclude<R, Scope>>;

Guards

isResult

Added in v4.0.0 Source

Returns true when a value is a workflow Result.

Signature

declare function isResult<A = unknown, E = unknown>(u: unknown): u is Result<A, E>;

Interruption

suspend

Added in v4.0.0 Source

Marks a workflow instance as suspended and interrupts the current fiber to stop execution until it is resumed.

Signature

declare function suspend(instance: {
  readonly activityState: {
    count: number;
    readonly latch: Latch;
  };
  cause: Cause<never> | undefined;
  readonly executionId: string;
  interrupted: boolean;
  readonly scope: Closeable;
  suspended: boolean;
  readonly workflow: Any;
}): Effect<never>;

Models

Any interface

Added in v4.0.0 Source

Type-erased workflow shape for APIs that operate on workflows without preserving their specific payload, success, or error types.

Signature

interface Any {
  constructor(_: never);
  readonly _tag: string;
  readonly "~effect/workflow/Workflow": "~effect/workflow/Workflow";
  readonly annotations: Context<never>;
  readonly errorSchema: Top;
  readonly executionId: (payload: any) => Effect<string>;
  readonly idempotencyKey: (payload: any) => string;
  readonly payloadSchema: AnyStructSchema;
  readonly successSchema: Top;
  readonly suspendedRetrySchedule?: Schedule<any, unknown, never, never>;
}

AnyWithProps interface

Added in v4.0.0 Source

Type-erased workflow shape that also exposes executable operations needed by workflow proxy and engine helpers.

Signature

interface AnyWithProps extends Any {
  constructor(_: never);
  readonly errorSchema: Top;
  readonly execute: (
    payload: any,
    options?: {
      readonly discard?: boolean;
    },
  ) => Effect<any, any, any>;
  readonly payloadSchema: AnyStructSchema;
  readonly resume: (executionId: string) => Effect<void, never, WorkflowEngine>;
  readonly successSchema: Top;
}

Complete

Added in v4.0.0 Source

Represents a completed workflow execution with its success or failure Exit.

Signature

declare class Complete<A, E> extends Readonly<{
  readonly exit: Exit<A, E>;
}> & {
  readonly _tag: "Complete";
} & Pipeable {
  constructor<A, E>(args: {
    readonly exit: Exit<A, E>;
  });
  readonly "~effect/workflow/Workflow/Result": "~effect/workflow/Workflow/Result";
  static Schema<Success extends Constraint, Error extends Constraint>(options: {
    readonly error: Error;
    readonly success: Success;
  }): CompleteSchema<Success, Error>;
}

CompleteEncoded interface

Added in v4.0.0 Source

Encoded representation of a completed workflow result containing an encoded Exit.

Signature

interface CompleteEncoded<A, E> {
  readonly _tag: "Complete";
  readonly exit: ExitEncoded<A, E>;
}

Result type

Added in v4.0.0 Source

Result of a workflow execution, either a completed exit or a suspended workflow state.

Signature

type Result<A, E> = Complete<A, E> | Suspended;

ResultEncoded type

Added in v4.0.0 Source

Encoded representation of a workflow Result.

Signature

type ResultEncoded<A, E> = CompleteEncoded<A, E> | typeof Suspended.Encoded;

Workflow interface

Added in v4.0.0 Source

Durable workflow definition with typed payload, success, and error schemas plus operations for execution, polling, interruption, resumption, and registration.

Signature

interface Workflow<
  Tag extends string,
  Payload extends AnyStructSchema,
  Success extends Schema.Top,
  Error extends Schema.Top,
> {
  constructor(_: never);
  readonly _tag: Tag;
  readonly "~effect/workflow/Workflow": "~effect/workflow/Workflow";
  readonly annotations: Context<never>;
  readonly errorSchema: Error;
  readonly execute: <Discard extends boolean = false>(
    payload: Payload["~type.make.in"],
    options?: {
      readonly discard?: Discard;
    },
  ) => Effect<
    Discard extends true ? string : Success["Type"],
    Discard extends true ? never : Error["Type"],
    | WorkflowEngine
    | Payload["EncodingServices"]
    | Success["DecodingServices"]
    | Error["DecodingServices"]
  >;
  readonly executionId: (payload: Payload["~type.make.in"]) => Effect<string>;
  readonly idempotencyKey: (payload: Payload["Type"]) => string;
  readonly interrupt: (executionId: string) => Effect<void, never, WorkflowEngine>;
  readonly payloadSchema: Payload;
  readonly poll: (
    executionId: string,
  ) => Effect<
    Option<Result<Success["Type"], Error["Type"]>>,
    never,
    WorkflowEngine | Success["DecodingServices"] | Error["DecodingServices"]
  >;
  readonly resume: (executionId: string) => Effect<void, never, WorkflowEngine>;
  readonly successSchema: Success;
  readonly suspendedRetrySchedule?: Schedule<any, unknown, never, never>;
  readonly toLayer: <R>(
    execute: (
      payload: Payload["Type"],
      executionId: string,
    ) => Effect<Success["Type"], Error["Type"], R>,
  ) => Layer<
    never,
    never,
    | WorkflowEngine
    | Payload["EncodingServices"]
    | Success["DecodingServices"]
    | Error["DecodingServices"]
    | Exclude<R, Scope | WorkflowEngine | WorkflowInstance | Execution<Tag>>
    | Payload["DecodingServices"]
    | Success["EncodingServices"]
    | Error["EncodingServices"]
  >;
  readonly withCompensation: {
    <A, R2>(
      compensation: (value: A, cause: Cause<Error["Type"]>) => Effect<void, never, R2>,
    ): <E, R>(
      effect: Effect<A, E, R>,
    ) => Effect<A, E, Scope | WorkflowInstance | Execution<Tag> | R2 | R>;
    <A, E, R, R2>(
      effect: Effect<A, E, R>,
      compensation: (value: A, cause: Cause<Error["Type"]>) => Effect<void, never, R2>,
    ): Effect<A, E, Scope | WorkflowInstance | Execution<Tag> | R | R2>;
  };
  annotate<I, S>(key: Key<I, S>, value: S): Workflow<Tag, Payload, Success, Error>;
  annotateMerge<I>(annotations: Context<I>): Workflow<Tag, Payload, Success, Error>;
}

Resource Management

addFinalizer

Added in v4.0.0 Source

Adds an exit finalizer to the current workflow scope, preserving the services available when the finalizer is registered.

Signature

declare const addFinalizer: <R>(
  f: (exit: Exit.Exit<unknown, unknown>) => Effect.Effect<void, never, R>,
) => Effect.Effect<void, never, WorkflowInstance | R>;

provideScope

Added in v4.0.0 Source

Provides the workflow scope to the given effect, and closes the scope only when the workflow execution fully completes.

Signature

declare function provideScope<A, E, R>(
  effect: Effect<A, E, R>,
): Effect<A, E, WorkflowInstance | Exclude<R, Scope>>;

scope

Added in v4.0.0 Source

Accesses the workflow scope, which is only closed when the workflow execution fully completes.

Signature

declare const scope: Effect.Effect<Scope.Scope, never, WorkflowInstance>;

Wraps an activity-like effect so workflow suspension waits for currently running activities to finish or suspend.

Signature

declare function wrapActivityResult<A, E, R>(
  effect: Effect<A, E, R>,
  isSuspend: (value: A) => boolean,
): Effect<A, E, WorkflowInstance | R>;

Schemas

AnyStructSchema interface

Added in v4.0.0 Source

Schema constraint for workflow payload schemas that expose struct fields.

Signature

interface AnyStructSchema extends Top {
  constructor(_: never);
  readonly fields: Fields;
}

CompleteSchema interface

Added in v4.0.0 Source

Schema constructor for Complete workflow results using the supplied success and error schemas.

Signature

interface CompleteSchema<
  Success extends Schema.Constraint,
  Error extends Schema.Constraint,
> extends declareConstructor<
  Complete<Success["Type"], Error["Type"]>,
  Complete<Success["Encoded"], Error["Encoded"]>,
  readonly [Schema.Exit<Success, Error, Schema.Defect>]
> {
  constructor(_: never);
  readonly error: Error;
  readonly success: Success;
}

Result

Added in v4.0.0 Source

Creates a schema for workflow results using the supplied success and error schemas.

Signature

declare const Result: <Success extends Constraint, Error extends Constraint>(options: {
  readonly error: Error;
  readonly success: Success;
}) => Union<readonly [CompleteSchema<Success, Error>, typeof Suspended]>;

Schema for encoded workflow results with generic success and error payloads.

Signature

declare const ResultEncoded: Codec<ResultEncoded<any, any>, ResultEncoded<any, any>, never, never>;

Suspended

Added in v4.0.0 Source

Represents a suspended workflow execution, optionally carrying the cause that triggered suspension.

Signature

declare class Suspended extends {
  readonly _tag: "Suspended";
  readonly cause?: Cause<never>;
} {
  constructor(...args: [props?: {
    readonly _tag?: "Suspended";
    readonly cause?: Cause<never>;
  }, options?: MakeOptions]);
  readonly "~effect/workflow/Workflow/Result": "~effect/workflow/Workflow/Result";
}

Services

Captures defects for a workflow and includes them in the result of the workflow or its activities.

Details

By default, this annotation is set to true, meaning defects are captured.

Signature

declare const CaptureDefects: Reference<boolean>;

Marks a workflow to suspend when it encounters any error.

Details

The suspended execution can later be resumed with the workflow's resume method, for example MyWorkflow.resume(executionId).

Signature

declare const SuspendOnFailure: Reference<boolean>;

Utility Types

Execution interface

Added in v4.0.0 Source

Type-level marker for services associated with a specific workflow execution tag.

Signature

interface Execution<Tag extends string> {
  readonly _: typeof _;
  readonly _tag: Tag;
}

PayloadSchema type

Added in v4.0.0 Source

Extracts the payload schema from a Workflow.

Signature

type PayloadSchema<W> =
  W extends Workflow<infer _Name, infer _Payload, infer _Success, infer _Error> ? _Payload : never;

RequirementsClient type

Added in v4.0.0 Source

Computes the schema services required by clients that execute or poll workflows.

Signature

type RequirementsClient<Workflows extends Any> =
  Workflows extends Workflow<infer _Name, infer _Payload, infer _Success, infer _Error>
    ? _Payload["EncodingServices"] | _Success["DecodingServices"] | _Error["DecodingServices"]
    : never;

RequirementsHandler type

Added in v4.0.0 Source

Computes the schema services required by handlers that decode workflow payloads and encode workflow results.

Signature

type RequirementsHandler<Workflows extends Any> =
  Workflows extends Workflow<infer _Name, infer _Payload, infer _Success, infer _Error>
    ?
        | _Payload["DecodingServices"]
        | _Payload["EncodingServices"]
        | _Success["DecodingServices"]
        | _Success["EncodingServices"]
        | _Error["DecodingServices"]
        | _Error["EncodingServices"]
    : never;