import * as Cause from "../../Cause.ts";
import * as Context from "../../Context.ts";
import * as Effect from "../../Effect.ts";
import * as Exit from "../../Exit.ts";
import * as Layer from "../../Layer.ts";
import * as Option from "../../Option.ts";
import type * as Schedule from "../../Schedule.ts";
import * as Schema from "../../Schema.ts";
import * as Scope from "../../Scope.ts";
import type { ExitEncoded } from "../rpc/RpcMessage.ts";
import type { WorkflowEngine, WorkflowInstance } from "./WorkflowEngine.ts";
declare const TypeId = "~effect/workflow/Workflow";
/**
 * @since 4.0.0
 * @category Models
 */
export interface Workflow<Name extends string, Payload extends AnyStructSchema, Success extends Schema.Top, Error extends Schema.Top> {
    readonly [TypeId]: typeof TypeId;
    readonly name: Name;
    readonly payloadSchema: Payload;
    readonly successSchema: Success;
    readonly errorSchema: Error;
    readonly annotations: Context.Context<never>;
    /**
     * Add an annotation to the workflow.
     */
    annotate<I, S>(key: Context.Key<I, S>, value: S): Workflow<Name, Payload, Success, Error>;
    /**
     * Merge multiple annotations into the workflow.
     */
    annotateMerge<I>(annotations: Context.Context<I>): Workflow<Name, Payload, Success, Error>;
    /**
     * Execute the workflow with the given payload.
     */
    readonly execute: <const Discard extends boolean = false>(payload: Payload["~type.make.in"], options?: {
        readonly discard?: Discard;
    }) => Effect.Effect<Discard extends true ? string : Success["Type"], Discard extends true ? never : Error["Type"], WorkflowEngine | Payload["EncodingServices"] | Success["DecodingServices"] | Error["DecodingServices"]>;
    /**
     * Execute the workflow with the given payload.
     */
    readonly poll: (executionId: string) => Effect.Effect<Option.Option<Result<Success["Type"], Error["Type"]>>, never, WorkflowEngine | Success["DecodingServices"] | Error["DecodingServices"]>;
    /**
     * Interrupt a workflow execution for the given execution ID.
     */
    readonly interrupt: (executionId: string) => Effect.Effect<void, never, WorkflowEngine>;
    /**
     * Manually resume a workflow execution for the given execution ID.
     */
    readonly resume: (executionId: string) => Effect.Effect<void, never, WorkflowEngine>;
    /**
     * Create a layer that registers the workflow and provides an effect to
     * execute it.
     */
    readonly toLayer: <R>(execute: (payload: Payload["Type"], executionId: string) => Effect.Effect<Success["Type"], Error["Type"], R>) => Layer.Layer<never, never, WorkflowEngine | Exclude<R, WorkflowEngine | WorkflowInstance | Execution<Name> | Scope.Scope> | Payload["DecodingServices"] | Payload["EncodingServices"] | Success["DecodingServices"] | Success["EncodingServices"] | Error["DecodingServices"] | Error["EncodingServices"]>;
    /**
     * For the given payload, compute the deterministic execution ID.
     */
    readonly executionId: (payload: Payload["~type.make.in"]) => Effect.Effect<string>;
    /**
     * Add compensation logic to an effect inside a Workflow. The compensation finalizer will be
     * 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.
     *
     * NOTE: Compensation will not work for nested activities. Compensation
     * finalizers are only registered for top-level effects in the workflow.
     */
    readonly withCompensation: {
        <A, R2>(compensation: (value: A, cause: Cause.Cause<Error["Type"]>) => Effect.Effect<void, never, R2>): <E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R | R2 | WorkflowInstance | Execution<Name> | Scope.Scope>;
        <A, E, R, R2>(effect: Effect.Effect<A, E, R>, compensation: (value: A, cause: Cause.Cause<Error["Type"]>) => Effect.Effect<void, never, R2>): Effect.Effect<A, E, R | R2 | WorkflowInstance | Execution<Name> | Scope.Scope>;
    };
}
/**
 * @since 4.0.0
 */
export interface AnyStructSchema extends Schema.Top {
    readonly fields: Schema.Struct.Fields;
}
/**
 * @since 4.0.0
 * @category Models
 */
export interface Execution<Name extends string> {
    readonly _: unique symbol;
    readonly name: Name;
}
/**
 * @since 4.0.0
 * @category Models
 */
export interface Any {
    readonly [TypeId]: typeof TypeId;
    readonly name: string;
    readonly executionId: (payload: any) => Effect.Effect<string>;
    readonly payloadSchema: AnyStructSchema;
    readonly successSchema: Schema.Top;
    readonly errorSchema: Schema.Top;
    readonly annotations: Context.Context<never>;
}
/**
 * @since 4.0.0
 * @category Models
 */
export interface AnyWithProps extends Any {
    readonly payloadSchema: AnyStructSchema;
    readonly successSchema: Schema.Top;
    readonly errorSchema: Schema.Top;
    readonly execute: (payload: any, options?: {
        readonly discard?: boolean;
    }) => Effect.Effect<any, any, any>;
    readonly resume: (executionId: string) => Effect.Effect<void, never, WorkflowEngine>;
}
/**
 * @since 4.0.0
 * @category Models
 */
export type PayloadSchema<W> = W extends Workflow<infer _Name, infer _Payload, infer _Success, infer _Error> ? _Payload : never;
/**
 * @since 4.0.0
 * @category Models
 */
export type RequirementsClient<Workflows extends Any> = Workflows extends Workflow<infer _Name, infer _Payload, infer _Success, infer _Error> ? _Payload["EncodingServices"] | _Success["DecodingServices"] | _Error["DecodingServices"] : never;
/**
 * @since 4.0.0
 * @category Models
 */
export 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;
/**
 * @since 4.0.0
 * @category Constructors
 */
export declare const make: <const Name extends string, Payload extends Schema.Struct.Fields | AnyStructSchema, Success extends Schema.Top = Schema.Void, Error extends Schema.Top = Schema.Never>(options: {
    readonly name: Name;
    readonly payload: Payload;
    readonly idempotencyKey: (payload: Payload extends Schema.Struct.Fields ? Schema.Struct.Type<Payload> : Payload["Type"]) => string;
    readonly success?: Success;
    readonly error?: Error;
    readonly suspendedRetrySchedule?: Schedule.Schedule<any, unknown> | undefined;
    readonly annotations?: Context.Context<never>;
}) => Workflow<Name, Payload extends Schema.Struct.Fields ? Schema.Struct<Payload> : Payload, Success, Error>;
declare const ResultTypeId = "~effect/workflow/Workflow/Result";
/**
 * @since 4.0.0
 * @category Result
 */
export declare const isResult: <A = unknown, E = unknown>(u: unknown) => u is Result<A, E>;
/**
 * @since 4.0.0
 * @category Result
 */
export type Result<A, E> = Complete<A, E> | Suspended;
/**
 * @since 4.0.0
 * @category Result
 */
export type ResultEncoded<A, E> = CompleteEncoded<A, E> | typeof Suspended.Encoded;
/**
 * @since 4.0.0
 * @category Result
 */
export interface CompleteEncoded<A, E> {
    readonly _tag: "Complete";
    readonly exit: ExitEncoded<A, E>;
}
/**
 * @since 4.0.0
 */
export interface CompleteSchema<Success extends Schema.Top, Error extends Schema.Top> extends Schema.declareConstructor<Complete<Success["Type"], Error["Type"]>, Complete<Success["Encoded"], Error["Encoded"]>, readonly [Schema.Exit<Success, Error, Schema.Defect>]> {
    readonly success: Success;
    readonly error: Error;
}
declare const Complete_base: new <A_1 extends Record<string, any> = {}>(args: import("../../Types.ts").VoidIfEmpty<{ readonly [P in keyof A_1 as P extends "_tag" ? never : P]: A_1[P]; }>) => Readonly<A_1> & {
    readonly _tag: "Complete";
} & import("../../Pipeable.ts").Pipeable;
/**
 * @since 4.0.0
 * @category Result
 */
export declare class Complete<A, E> extends Complete_base<{
    readonly exit: Exit.Exit<A, E>;
}> {
    /**
     * @since 4.0.0
     */
    readonly [ResultTypeId] = "~effect/workflow/Workflow/Result";
    /**
     * @since 4.0.0
     */
    static Schema<Success extends Schema.Top, Error extends Schema.Top>(options: {
        readonly success: Success;
        readonly error: Error;
    }): CompleteSchema<Success, Error>;
}
declare const Suspended_base: Schema.Class<Suspended, Schema.Struct<{
    readonly _tag: Schema.tag<"Suspended">;
    readonly cause: Schema.optional<Schema.Cause<Schema.Never, Schema.Defect>>;
}>, {}>;
/**
 * @since 4.0.0
 * @category Result
 */
export declare class Suspended extends Suspended_base {
    /**
     * @since 4.0.0
     */
    readonly [ResultTypeId] = "~effect/workflow/Workflow/Result";
}
/**
 * @since 4.0.0
 * @category Result
 */
export declare const Result: <Success extends Schema.Top, Error extends Schema.Top>(options: {
    readonly success: Success;
    readonly error: Error;
}) => Schema.Union<readonly [CompleteSchema<Success, Error>, typeof Suspended]>;
/**
 * @since 4.0.0
 * @category Result
 */
export declare const ResultEncoded: Schema.Codec<ResultEncoded<any, any>>;
/**
 * @since 4.0.0
 * @category Result
 */
export declare const intoResult: <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<Result<A, E>, never, Exclude<R, Scope.Scope> | WorkflowInstance>;
/**
 * @since 4.0.0
 * @category Result
 */
export declare const wrapActivityResult: <A, E, R>(effect: Effect.Effect<A, E, R>, isSuspend: (value: A) => boolean) => Effect.Effect<A, E, R | WorkflowInstance>;
/**
 * Accesses the workflow scope.
 *
 * The workflow scope is only closed when the workflow execution fully
 * completes.
 *
 * @since 1.0.0
 * @category Scope
 */
export declare const scope: Effect.Effect<Scope.Scope, never, WorkflowInstance>;
/**
 * Provides the workflow scope to the given effect.
 *
 * The workflow scope is only closed when the workflow execution fully
 * completes.
 *
 * @since 1.0.0
 * @category Scope
 */
export declare const provideScope: <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, Exclude<R, Scope.Scope> | WorkflowInstance>;
/**
 * @since 1.0.0
 * @category Scope
 */
export declare const addFinalizer: <R>(f: (exit: Exit.Exit<unknown, unknown>) => Effect.Effect<void, never, R>) => Effect.Effect<void, never, WorkflowInstance | R>;
/**
 * Add compensation logic to an effect inside a Workflow. The compensation finalizer will be
 * 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.
 *
 * NOTE: Compensation will not work for nested activities. Compensation
 * finalizers are only registered for top-level effects in the workflow.
 *
 * @since 1.0.0
 * @category Compensation
 */
export declare const withCompensation: {
    /**
     * Add compensation logic to an effect inside a Workflow. The compensation finalizer will be
     * 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.
     *
     * NOTE: Compensation will not work for nested activities. Compensation
     * finalizers are only registered for top-level effects in the workflow.
     *
     * @since 1.0.0
     * @category Compensation
     */
    <A, R2>(compensation: (value: A, cause: Cause.Cause<unknown>) => Effect.Effect<void, never, R2>): <E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R | R2 | WorkflowInstance | Scope.Scope>;
    /**
     * Add compensation logic to an effect inside a Workflow. The compensation finalizer will be
     * 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.
     *
     * NOTE: Compensation will not work for nested activities. Compensation
     * finalizers are only registered for top-level effects in the workflow.
     *
     * @since 1.0.0
     * @category Compensation
     */
    <A, E, R, R2>(effect: Effect.Effect<A, E, R>, compensation: (value: A, cause: Cause.Cause<unknown>) => Effect.Effect<void, never, R2>): Effect.Effect<A, E, R | R2 | WorkflowInstance | Scope.Scope>;
};
/**
 * @since 4.0.0
 * @category Result
 */
export declare const suspend: (instance: WorkflowInstance["Service"]) => Effect.Effect<never>;
/**
 * If you set this annotation to `true` for a workflow, it will capture defects
 * and include them in the result of the workflow or it's activities.
 *
 * By default, this is set to `true`, meaning that defects will be captured.
 *
 * @since 4.0.0
 * @category Annotations
 */
export declare const CaptureDefects: Context.Reference<boolean>;
/**
 * If you set this annotation to `true` for a workflow, it will suspend if it
 * encounters any kind of error.
 *
 * You can then manually resume the workflow later with
 * `Workflow.resume(executionId)`.
 *
 * @since 4.0.0
 * @category Annotations
 */
export declare const SuspendOnFailure: Context.Reference<boolean>;
export {};
//# sourceMappingURL=Workflow.d.ts.map