26981 lines
921 KiB
TypeScript
26981 lines
921 KiB
TypeScript
/**
|
||
* @since 2.0.0
|
||
*/
|
||
import type * as RA from "./Array.js";
|
||
import type * as Cause from "./Cause.js";
|
||
import type * as Chunk from "./Chunk.js";
|
||
import type * as Clock from "./Clock.js";
|
||
import type { ConfigProvider } from "./ConfigProvider.js";
|
||
import type { Console } from "./Console.js";
|
||
import type * as Context from "./Context.js";
|
||
import type * as Deferred from "./Deferred.js";
|
||
import type * as Duration from "./Duration.js";
|
||
import type * as Either from "./Either.js";
|
||
import type { Equivalence } from "./Equivalence.js";
|
||
import type { ExecutionPlan } from "./ExecutionPlan.js";
|
||
import type { ExecutionStrategy } from "./ExecutionStrategy.js";
|
||
import type * as Exit from "./Exit.js";
|
||
import type * as Fiber from "./Fiber.js";
|
||
import type * as FiberId from "./FiberId.js";
|
||
import type * as FiberRef from "./FiberRef.js";
|
||
import type * as FiberRefs from "./FiberRefs.js";
|
||
import type * as FiberRefsPatch from "./FiberRefsPatch.js";
|
||
import type * as FiberStatus from "./FiberStatus.js";
|
||
import type { LazyArg } from "./Function.js";
|
||
import type * as HashMap from "./HashMap.js";
|
||
import type * as HashSet from "./HashSet.js";
|
||
import type { TypeLambda } from "./HKT.js";
|
||
import type * as Layer from "./Layer.js";
|
||
import type * as LogLevel from "./LogLevel.js";
|
||
import type * as ManagedRuntime from "./ManagedRuntime.js";
|
||
import type * as Metric from "./Metric.js";
|
||
import type * as MetricLabel from "./MetricLabel.js";
|
||
import type * as Option from "./Option.js";
|
||
import type { Pipeable } from "./Pipeable.js";
|
||
import type { Predicate, Refinement } from "./Predicate.js";
|
||
import * as Random from "./Random.js";
|
||
import type * as Ref from "./Ref.js";
|
||
import * as Request from "./Request.js";
|
||
import type { RequestBlock } from "./RequestBlock.js";
|
||
import type { RequestResolver } from "./RequestResolver.js";
|
||
import type * as Runtime from "./Runtime.js";
|
||
import type * as RuntimeFlags from "./RuntimeFlags.js";
|
||
import type * as RuntimeFlagsPatch from "./RuntimeFlagsPatch.js";
|
||
import type * as Schedule from "./Schedule.js";
|
||
import * as Scheduler from "./Scheduler.js";
|
||
import type * as Scope from "./Scope.js";
|
||
import type * as Supervisor from "./Supervisor.js";
|
||
import type * as Tracer from "./Tracer.js";
|
||
import type { Concurrency, Contravariant, Covariant, EqualsWith, NoExcessProperties, NoInfer, NotFunction } from "./Types.js";
|
||
import type * as Unify from "./Unify.js";
|
||
import { type YieldWrap } from "./Utils.js";
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Symbols
|
||
*/
|
||
export declare const EffectTypeId: unique symbol;
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Symbols
|
||
*/
|
||
export type EffectTypeId = typeof EffectTypeId;
|
||
/**
|
||
* The `Effect` interface defines a value that describes a workflow or job,
|
||
* which can succeed or fail.
|
||
*
|
||
* **Details**
|
||
*
|
||
* The `Effect` interface represents a computation that can model a workflow
|
||
* involving various types of operations, such as synchronous, asynchronous,
|
||
* concurrent, and parallel interactions. It operates within a context of type
|
||
* `R`, and the result can either be a success with a value of type `A` or a
|
||
* failure with an error of type `E`. The `Effect` is designed to handle complex
|
||
* interactions with external resources, offering advanced features such as
|
||
* fiber-based concurrency, scheduling, interruption handling, and scalability.
|
||
* This makes it suitable for tasks that require fine-grained control over
|
||
* concurrency and error management.
|
||
*
|
||
* To execute an `Effect` value, you need a `Runtime`, which provides the
|
||
* environment necessary to run and manage the computation.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Models
|
||
*/
|
||
export interface Effect<out A, out E = never, out R = never> extends Effect.Variance<A, E, R>, Pipeable {
|
||
readonly [Unify.typeSymbol]?: unknown;
|
||
readonly [Unify.unifySymbol]?: EffectUnify<this>;
|
||
readonly [Unify.ignoreSymbol]?: EffectUnifyIgnore;
|
||
[Symbol.iterator](): EffectGenerator<Effect<A, E, R>>;
|
||
}
|
||
/**
|
||
* @since 3.0.0
|
||
* @category Models
|
||
*/
|
||
export interface EffectGenerator<T extends Effect<any, any, any>> {
|
||
next(...args: ReadonlyArray<any>): IteratorResult<YieldWrap<T>, Effect.Success<T>>;
|
||
}
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Models
|
||
*/
|
||
export interface EffectUnify<A extends {
|
||
[Unify.typeSymbol]?: any;
|
||
}> extends Either.EitherUnify<A>, Option.OptionUnify<A>, Context.TagUnify<A> {
|
||
Effect?: () => A[Unify.typeSymbol] extends Effect<infer A0, infer E0, infer R0> | infer _ ? Effect<A0, E0, R0> : never;
|
||
}
|
||
/**
|
||
* @category Models
|
||
* @since 2.0.0
|
||
*/
|
||
export interface EffectUnifyIgnore {
|
||
Tag?: true;
|
||
Option?: true;
|
||
Either?: true;
|
||
}
|
||
/**
|
||
* @category Type lambdas
|
||
* @since 2.0.0
|
||
*/
|
||
export interface EffectTypeLambda extends TypeLambda {
|
||
readonly type: Effect<this["Target"], this["Out1"], this["Out2"]>;
|
||
}
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Models
|
||
*/
|
||
export interface Blocked<out A, out E> extends Effect<A, E> {
|
||
readonly _op: "Blocked";
|
||
readonly effect_instruction_i0: RequestBlock;
|
||
readonly effect_instruction_i1: Effect<A, E>;
|
||
}
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Models
|
||
*/
|
||
declare module "./Context.js" {
|
||
interface Tag<Id, Value> extends Effect<Value, never, Id> {
|
||
[Symbol.iterator](): EffectGenerator<Tag<Id, Value>>;
|
||
}
|
||
interface Reference<Id, Value> extends Effect<Value> {
|
||
[Symbol.iterator](): EffectGenerator<Reference<Id, Value>>;
|
||
}
|
||
interface TagUnifyIgnore {
|
||
Effect?: true;
|
||
Either?: true;
|
||
Option?: true;
|
||
}
|
||
}
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Models
|
||
*/
|
||
declare module "./Either.js" {
|
||
interface Left<E, A> extends Effect<A, E> {
|
||
readonly _tag: "Left";
|
||
[Symbol.iterator](): EffectGenerator<Left<E, A>>;
|
||
}
|
||
interface Right<E, A> extends Effect<A, E> {
|
||
readonly _tag: "Right";
|
||
[Symbol.iterator](): EffectGenerator<Right<E, A>>;
|
||
}
|
||
interface EitherUnifyIgnore {
|
||
Effect?: true;
|
||
Tag?: true;
|
||
Option?: true;
|
||
}
|
||
}
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Models
|
||
*/
|
||
declare module "./Option.js" {
|
||
interface None<A> extends Effect<A, Cause.NoSuchElementException> {
|
||
readonly _tag: "None";
|
||
[Symbol.iterator](): EffectGenerator<None<A>>;
|
||
}
|
||
interface Some<A> extends Effect<A, Cause.NoSuchElementException> {
|
||
readonly _tag: "Some";
|
||
[Symbol.iterator](): EffectGenerator<Some<A>>;
|
||
}
|
||
interface OptionUnifyIgnore {
|
||
Effect?: true;
|
||
Tag?: true;
|
||
Either?: true;
|
||
}
|
||
}
|
||
/**
|
||
* @since 2.0.0
|
||
*/
|
||
export declare namespace Effect {
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Models
|
||
*/
|
||
interface Variance<out A, out E, out R> {
|
||
readonly [EffectTypeId]: VarianceStruct<A, E, R>;
|
||
}
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Models
|
||
*/
|
||
interface VarianceStruct<out A, out E, out R> {
|
||
readonly _V: string;
|
||
readonly _A: Covariant<A>;
|
||
readonly _E: Covariant<E>;
|
||
readonly _R: Covariant<R>;
|
||
}
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Effect Type Extractors
|
||
*/
|
||
type Context<T extends Effect<any, any, any>> = [T] extends [Effect<infer _A, infer _E, infer _R>] ? _R : never;
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Effect Type Extractors
|
||
*/
|
||
type Error<T extends Effect<any, any, any>> = [T] extends [Effect<infer _A, infer _E, infer _R>] ? _E : never;
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Effect Type Extractors
|
||
*/
|
||
type Success<T extends Effect<any, any, any>> = [T] extends [Effect<infer _A, infer _E, infer _R>] ? _A : never;
|
||
/**
|
||
* @since 3.15.5
|
||
* @category Effect Type Extractors
|
||
*/
|
||
type AsEffect<T extends Effect<any, any, any>> = Effect<T extends Effect<infer _A, infer _E, infer _R> ? _A : never, T extends Effect<infer _A, infer _E, infer _R> ? _E : never, T extends Effect<infer _A, infer _E, infer _R> ? _R : never>;
|
||
}
|
||
/**
|
||
* Checks if a given value is an `Effect` value.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This function can be useful for checking the type of a value before
|
||
* attempting to operate on it as an `Effect` value. For example, you could use
|
||
* `Effect.isEffect` to check the type of a value before using it as an argument
|
||
* to a function that expects an `Effect` value.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Guards
|
||
*/
|
||
export declare const isEffect: (u: unknown) => u is Effect<unknown, unknown, unknown>;
|
||
/**
|
||
* Returns an effect that caches its result for a specified `Duration`,
|
||
* known as "timeToLive" (TTL).
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function is used to cache the result of an effect for a specified amount
|
||
* of time. This means that the first time the effect is evaluated, its result
|
||
* is computed and stored.
|
||
*
|
||
* If the effect is evaluated again within the specified `timeToLive`, the
|
||
* cached result will be used, avoiding recomputation.
|
||
*
|
||
* After the specified duration has passed, the cache expires, and the effect
|
||
* will be recomputed upon the next evaluation.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use this function when you have an effect that involves costly operations or
|
||
* computations, and you want to avoid repeating them within a short time frame.
|
||
*
|
||
* It's ideal for scenarios where the result of an effect doesn't change
|
||
* frequently and can be reused for a specified duration.
|
||
*
|
||
* By caching the result, you can improve efficiency and reduce unnecessary
|
||
* computations, especially in performance-critical applications.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* let i = 1
|
||
* const expensiveTask = Effect.promise<string>(() => {
|
||
* console.log("expensive task...")
|
||
* return new Promise((resolve) => {
|
||
* setTimeout(() => {
|
||
* resolve(`result ${i++}`)
|
||
* }, 100)
|
||
* })
|
||
* })
|
||
*
|
||
* const program = Effect.gen(function* () {
|
||
* const cached = yield* Effect.cachedWithTTL(expensiveTask, "150 millis")
|
||
* yield* cached.pipe(Effect.andThen(Console.log))
|
||
* yield* cached.pipe(Effect.andThen(Console.log))
|
||
* yield* Effect.sleep("100 millis")
|
||
* yield* cached.pipe(Effect.andThen(Console.log))
|
||
* })
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output:
|
||
* // expensive task...
|
||
* // result 1
|
||
* // result 1
|
||
* // expensive task...
|
||
* // result 2
|
||
* ```
|
||
*
|
||
* @see {@link cached} for a similar function that caches the result
|
||
* indefinitely.
|
||
* @see {@link cachedInvalidateWithTTL} for a similar function that includes an
|
||
* additional effect for manually invalidating the cached value.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Caching
|
||
*/
|
||
export declare const cachedWithTTL: {
|
||
/**
|
||
* Returns an effect that caches its result for a specified `Duration`,
|
||
* known as "timeToLive" (TTL).
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function is used to cache the result of an effect for a specified amount
|
||
* of time. This means that the first time the effect is evaluated, its result
|
||
* is computed and stored.
|
||
*
|
||
* If the effect is evaluated again within the specified `timeToLive`, the
|
||
* cached result will be used, avoiding recomputation.
|
||
*
|
||
* After the specified duration has passed, the cache expires, and the effect
|
||
* will be recomputed upon the next evaluation.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use this function when you have an effect that involves costly operations or
|
||
* computations, and you want to avoid repeating them within a short time frame.
|
||
*
|
||
* It's ideal for scenarios where the result of an effect doesn't change
|
||
* frequently and can be reused for a specified duration.
|
||
*
|
||
* By caching the result, you can improve efficiency and reduce unnecessary
|
||
* computations, especially in performance-critical applications.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* let i = 1
|
||
* const expensiveTask = Effect.promise<string>(() => {
|
||
* console.log("expensive task...")
|
||
* return new Promise((resolve) => {
|
||
* setTimeout(() => {
|
||
* resolve(`result ${i++}`)
|
||
* }, 100)
|
||
* })
|
||
* })
|
||
*
|
||
* const program = Effect.gen(function* () {
|
||
* const cached = yield* Effect.cachedWithTTL(expensiveTask, "150 millis")
|
||
* yield* cached.pipe(Effect.andThen(Console.log))
|
||
* yield* cached.pipe(Effect.andThen(Console.log))
|
||
* yield* Effect.sleep("100 millis")
|
||
* yield* cached.pipe(Effect.andThen(Console.log))
|
||
* })
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output:
|
||
* // expensive task...
|
||
* // result 1
|
||
* // result 1
|
||
* // expensive task...
|
||
* // result 2
|
||
* ```
|
||
*
|
||
* @see {@link cached} for a similar function that caches the result
|
||
* indefinitely.
|
||
* @see {@link cachedInvalidateWithTTL} for a similar function that includes an
|
||
* additional effect for manually invalidating the cached value.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Caching
|
||
*/
|
||
(timeToLive: Duration.DurationInput): <A, E, R>(self: Effect<A, E, R>) => Effect<Effect<A, E>, never, R>;
|
||
/**
|
||
* Returns an effect that caches its result for a specified `Duration`,
|
||
* known as "timeToLive" (TTL).
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function is used to cache the result of an effect for a specified amount
|
||
* of time. This means that the first time the effect is evaluated, its result
|
||
* is computed and stored.
|
||
*
|
||
* If the effect is evaluated again within the specified `timeToLive`, the
|
||
* cached result will be used, avoiding recomputation.
|
||
*
|
||
* After the specified duration has passed, the cache expires, and the effect
|
||
* will be recomputed upon the next evaluation.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use this function when you have an effect that involves costly operations or
|
||
* computations, and you want to avoid repeating them within a short time frame.
|
||
*
|
||
* It's ideal for scenarios where the result of an effect doesn't change
|
||
* frequently and can be reused for a specified duration.
|
||
*
|
||
* By caching the result, you can improve efficiency and reduce unnecessary
|
||
* computations, especially in performance-critical applications.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* let i = 1
|
||
* const expensiveTask = Effect.promise<string>(() => {
|
||
* console.log("expensive task...")
|
||
* return new Promise((resolve) => {
|
||
* setTimeout(() => {
|
||
* resolve(`result ${i++}`)
|
||
* }, 100)
|
||
* })
|
||
* })
|
||
*
|
||
* const program = Effect.gen(function* () {
|
||
* const cached = yield* Effect.cachedWithTTL(expensiveTask, "150 millis")
|
||
* yield* cached.pipe(Effect.andThen(Console.log))
|
||
* yield* cached.pipe(Effect.andThen(Console.log))
|
||
* yield* Effect.sleep("100 millis")
|
||
* yield* cached.pipe(Effect.andThen(Console.log))
|
||
* })
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output:
|
||
* // expensive task...
|
||
* // result 1
|
||
* // result 1
|
||
* // expensive task...
|
||
* // result 2
|
||
* ```
|
||
*
|
||
* @see {@link cached} for a similar function that caches the result
|
||
* indefinitely.
|
||
* @see {@link cachedInvalidateWithTTL} for a similar function that includes an
|
||
* additional effect for manually invalidating the cached value.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Caching
|
||
*/
|
||
<A, E, R>(self: Effect<A, E, R>, timeToLive: Duration.DurationInput): Effect<Effect<A, E>, never, R>;
|
||
};
|
||
/**
|
||
* Caches an effect's result for a specified duration and allows manual
|
||
* invalidation before expiration.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function behaves similarly to {@link cachedWithTTL} by caching the
|
||
* result of an effect for a specified period of time. However, it introduces an
|
||
* additional feature: it provides an effect that allows you to manually
|
||
* invalidate the cached result before it naturally expires.
|
||
*
|
||
* This gives you more control over the cache, allowing you to refresh the
|
||
* result when needed, even if the original cache has not yet expired.
|
||
*
|
||
* Once the cache is invalidated, the next time the effect is evaluated, the
|
||
* result will be recomputed, and the cache will be refreshed.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use this function when you have an effect whose result needs to be cached for
|
||
* a certain period, but you also want the option to refresh the cache manually
|
||
* before the expiration time.
|
||
*
|
||
* This is useful when you need to ensure that the cached data remains valid for
|
||
* a certain period but still want to invalidate it if the underlying data
|
||
* changes or if you want to force a recomputation.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* let i = 1
|
||
* const expensiveTask = Effect.promise<string>(() => {
|
||
* console.log("expensive task...")
|
||
* return new Promise((resolve) => {
|
||
* setTimeout(() => {
|
||
* resolve(`result ${i++}`)
|
||
* }, 100)
|
||
* })
|
||
* })
|
||
*
|
||
* const program = Effect.gen(function* () {
|
||
* const [cached, invalidate] = yield* Effect.cachedInvalidateWithTTL(
|
||
* expensiveTask,
|
||
* "1 hour"
|
||
* )
|
||
* yield* cached.pipe(Effect.andThen(Console.log))
|
||
* yield* cached.pipe(Effect.andThen(Console.log))
|
||
* yield* invalidate
|
||
* yield* cached.pipe(Effect.andThen(Console.log))
|
||
* })
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output:
|
||
* // expensive task...
|
||
* // result 1
|
||
* // result 1
|
||
* // expensive task...
|
||
* // result 2
|
||
* ```
|
||
*
|
||
* @see {@link cached} for a similar function that caches the result
|
||
* indefinitely.
|
||
* @see {@link cachedWithTTL} for a similar function that caches the result for
|
||
* a specified duration but does not include an effect for manual invalidation.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Caching
|
||
*/
|
||
export declare const cachedInvalidateWithTTL: {
|
||
/**
|
||
* Caches an effect's result for a specified duration and allows manual
|
||
* invalidation before expiration.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function behaves similarly to {@link cachedWithTTL} by caching the
|
||
* result of an effect for a specified period of time. However, it introduces an
|
||
* additional feature: it provides an effect that allows you to manually
|
||
* invalidate the cached result before it naturally expires.
|
||
*
|
||
* This gives you more control over the cache, allowing you to refresh the
|
||
* result when needed, even if the original cache has not yet expired.
|
||
*
|
||
* Once the cache is invalidated, the next time the effect is evaluated, the
|
||
* result will be recomputed, and the cache will be refreshed.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use this function when you have an effect whose result needs to be cached for
|
||
* a certain period, but you also want the option to refresh the cache manually
|
||
* before the expiration time.
|
||
*
|
||
* This is useful when you need to ensure that the cached data remains valid for
|
||
* a certain period but still want to invalidate it if the underlying data
|
||
* changes or if you want to force a recomputation.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* let i = 1
|
||
* const expensiveTask = Effect.promise<string>(() => {
|
||
* console.log("expensive task...")
|
||
* return new Promise((resolve) => {
|
||
* setTimeout(() => {
|
||
* resolve(`result ${i++}`)
|
||
* }, 100)
|
||
* })
|
||
* })
|
||
*
|
||
* const program = Effect.gen(function* () {
|
||
* const [cached, invalidate] = yield* Effect.cachedInvalidateWithTTL(
|
||
* expensiveTask,
|
||
* "1 hour"
|
||
* )
|
||
* yield* cached.pipe(Effect.andThen(Console.log))
|
||
* yield* cached.pipe(Effect.andThen(Console.log))
|
||
* yield* invalidate
|
||
* yield* cached.pipe(Effect.andThen(Console.log))
|
||
* })
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output:
|
||
* // expensive task...
|
||
* // result 1
|
||
* // result 1
|
||
* // expensive task...
|
||
* // result 2
|
||
* ```
|
||
*
|
||
* @see {@link cached} for a similar function that caches the result
|
||
* indefinitely.
|
||
* @see {@link cachedWithTTL} for a similar function that caches the result for
|
||
* a specified duration but does not include an effect for manual invalidation.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Caching
|
||
*/
|
||
(timeToLive: Duration.DurationInput): <A, E, R>(self: Effect<A, E, R>) => Effect<[Effect<A, E>, Effect<void>], never, R>;
|
||
/**
|
||
* Caches an effect's result for a specified duration and allows manual
|
||
* invalidation before expiration.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function behaves similarly to {@link cachedWithTTL} by caching the
|
||
* result of an effect for a specified period of time. However, it introduces an
|
||
* additional feature: it provides an effect that allows you to manually
|
||
* invalidate the cached result before it naturally expires.
|
||
*
|
||
* This gives you more control over the cache, allowing you to refresh the
|
||
* result when needed, even if the original cache has not yet expired.
|
||
*
|
||
* Once the cache is invalidated, the next time the effect is evaluated, the
|
||
* result will be recomputed, and the cache will be refreshed.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use this function when you have an effect whose result needs to be cached for
|
||
* a certain period, but you also want the option to refresh the cache manually
|
||
* before the expiration time.
|
||
*
|
||
* This is useful when you need to ensure that the cached data remains valid for
|
||
* a certain period but still want to invalidate it if the underlying data
|
||
* changes or if you want to force a recomputation.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* let i = 1
|
||
* const expensiveTask = Effect.promise<string>(() => {
|
||
* console.log("expensive task...")
|
||
* return new Promise((resolve) => {
|
||
* setTimeout(() => {
|
||
* resolve(`result ${i++}`)
|
||
* }, 100)
|
||
* })
|
||
* })
|
||
*
|
||
* const program = Effect.gen(function* () {
|
||
* const [cached, invalidate] = yield* Effect.cachedInvalidateWithTTL(
|
||
* expensiveTask,
|
||
* "1 hour"
|
||
* )
|
||
* yield* cached.pipe(Effect.andThen(Console.log))
|
||
* yield* cached.pipe(Effect.andThen(Console.log))
|
||
* yield* invalidate
|
||
* yield* cached.pipe(Effect.andThen(Console.log))
|
||
* })
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output:
|
||
* // expensive task...
|
||
* // result 1
|
||
* // result 1
|
||
* // expensive task...
|
||
* // result 2
|
||
* ```
|
||
*
|
||
* @see {@link cached} for a similar function that caches the result
|
||
* indefinitely.
|
||
* @see {@link cachedWithTTL} for a similar function that caches the result for
|
||
* a specified duration but does not include an effect for manual invalidation.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Caching
|
||
*/
|
||
<A, E, R>(self: Effect<A, E, R>, timeToLive: Duration.DurationInput): Effect<[Effect<A, E>, Effect<void>], never, R>;
|
||
};
|
||
/**
|
||
* Returns an effect that lazily computes a result and caches it for subsequent
|
||
* evaluations.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function wraps an effect and ensures that its result is computed only
|
||
* once. Once the result is computed, it is cached, meaning that subsequent
|
||
* evaluations of the same effect will return the cached result without
|
||
* re-executing the logic.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use this function when you have an expensive or time-consuming operation that
|
||
* you want to avoid repeating. The first evaluation will compute the result,
|
||
* and all following evaluations will immediately return the cached value,
|
||
* improving performance and reducing unnecessary work.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* let i = 1
|
||
* const expensiveTask = Effect.promise<string>(() => {
|
||
* console.log("expensive task...")
|
||
* return new Promise((resolve) => {
|
||
* setTimeout(() => {
|
||
* resolve(`result ${i++}`)
|
||
* }, 100)
|
||
* })
|
||
* })
|
||
*
|
||
* const program = Effect.gen(function* () {
|
||
* console.log("non-cached version:")
|
||
* yield* expensiveTask.pipe(Effect.andThen(Console.log))
|
||
* yield* expensiveTask.pipe(Effect.andThen(Console.log))
|
||
* console.log("cached version:")
|
||
* const cached = yield* Effect.cached(expensiveTask)
|
||
* yield* cached.pipe(Effect.andThen(Console.log))
|
||
* yield* cached.pipe(Effect.andThen(Console.log))
|
||
* })
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output:
|
||
* // non-cached version:
|
||
* // expensive task...
|
||
* // result 1
|
||
* // expensive task...
|
||
* // result 2
|
||
* // cached version:
|
||
* // expensive task...
|
||
* // result 3
|
||
* // result 3
|
||
* ```
|
||
*
|
||
* @see {@link cachedWithTTL} for a similar function that includes a
|
||
* time-to-live duration for the cached value.
|
||
* @see {@link cachedInvalidateWithTTL} for a similar function that includes an
|
||
* additional effect for manually invalidating the cached value.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Caching
|
||
*/
|
||
export declare const cached: <A, E, R>(self: Effect<A, E, R>) => Effect<Effect<A, E, R>>;
|
||
/**
|
||
* Returns a memoized version of a function with effects, reusing results for
|
||
* the same inputs.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function creates a memoized version of a given function that performs an
|
||
* effect. Memoization ensures that once a result is computed for a specific
|
||
* input, it is stored and reused for subsequent calls with the same input,
|
||
* reducing the need to recompute the result.
|
||
*
|
||
* The function can optionally take an `Equivalence` parameter to
|
||
* determine how inputs are compared for caching purposes.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use this function when you have a function that performs an effect and you
|
||
* want to avoid recomputing the result for the same input multiple times.
|
||
*
|
||
* It's ideal for functions that produce deterministic results based on their
|
||
* inputs, and you want to improve performance by caching the output.
|
||
*
|
||
* This is particularly useful in scenarios where the function involves
|
||
* expensive calculations or operations that should be avoided after the first
|
||
* execution with the same parameters.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Random } from "effect"
|
||
*
|
||
* const program = Effect.gen(function* () {
|
||
* const randomNumber = (n: number) => Random.nextIntBetween(1, n)
|
||
* console.log("non-memoized version:")
|
||
* console.log(yield* randomNumber(10))
|
||
* console.log(yield* randomNumber(10))
|
||
*
|
||
* console.log("memoized version:")
|
||
* const memoized = yield* Effect.cachedFunction(randomNumber)
|
||
* console.log(yield* memoized(10))
|
||
* console.log(yield* memoized(10))
|
||
* })
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Example Output:
|
||
* // non-memoized version:
|
||
* // 2
|
||
* // 8
|
||
* // memoized version:
|
||
* // 5
|
||
* // 5
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Caching
|
||
*/
|
||
export declare const cachedFunction: <A, B, E, R>(f: (a: A) => Effect<B, E, R>, eq?: Equivalence<A>) => Effect<(a: A) => Effect<B, E, R>>;
|
||
/**
|
||
* Returns an effect that executes only once, regardless of how many times it's
|
||
* called.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function ensures that a specific effect is executed only a single time,
|
||
* no matter how many times it is invoked. The result of the effect will be
|
||
* cached, and subsequent calls to the effect will immediately return the cached
|
||
* result without re-executing the original logic.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use this function when you need to perform a task only once, regardless of
|
||
* how many times the effect is triggered. It's particularly useful when you
|
||
* have initialization tasks, logging, or other one-time actions that should not
|
||
* be repeated. This can help optimize performance and avoid redundant actions.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* const program = Effect.gen(function* () {
|
||
* const task1 = Console.log("task1")
|
||
* yield* Effect.repeatN(task1, 2)
|
||
* const task2 = yield* Effect.once(Console.log("task2"))
|
||
* yield* Effect.repeatN(task2, 2)
|
||
* })
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output:
|
||
* // task1
|
||
* // task1
|
||
* // task1
|
||
* // task2
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Caching
|
||
*/
|
||
export declare const once: <A, E, R>(self: Effect<A, E, R>) => Effect<Effect<void, E, R>>;
|
||
/**
|
||
* Combines multiple effects into one, returning results based on the input
|
||
* structure.
|
||
*
|
||
* **Details**
|
||
*
|
||
* Use this function when you need to run multiple effects and combine their
|
||
* results into a single output. It supports tuples, iterables, structs, and
|
||
* records, making it flexible for different input types.
|
||
*
|
||
* For instance, if the input is a tuple:
|
||
*
|
||
* ```ts skip-type-checking
|
||
* // ┌─── a tuple of effects
|
||
* // ▼
|
||
* Effect.all([effect1, effect2, ...])
|
||
* ```
|
||
*
|
||
* the effects are executed sequentially, and the result is a new effect
|
||
* containing the results as a tuple. The results in the tuple match the order
|
||
* of the effects passed to `Effect.all`.
|
||
*
|
||
* **Concurrency**
|
||
*
|
||
* You can control the execution order (e.g., sequential vs. concurrent) using
|
||
* the `concurrency` option.
|
||
*
|
||
* **Short-Circuiting Behavior**
|
||
*
|
||
* This function stops execution on the first error it encounters, this is
|
||
* called "short-circuiting". If any effect in the collection fails, the
|
||
* remaining effects will not run, and the error will be propagated. To change
|
||
* this behavior, you can use the `mode` option, which allows all effects to run
|
||
* and collect results as `Either` or `Option`.
|
||
*
|
||
* **The `mode` option**
|
||
*
|
||
* The `{ mode: "either" }` option changes the behavior of `Effect.all` to
|
||
* ensure all effects run, even if some fail. Instead of stopping on the first
|
||
* failure, this mode collects both successes and failures, returning an array
|
||
* of `Either` instances where each result is either a `Right` (success) or a
|
||
* `Left` (failure).
|
||
*
|
||
* Similarly, the `{ mode: "validate" }` option uses `Option` to indicate
|
||
* success or failure. Each effect returns `None` for success and `Some` with
|
||
* the error for failure.
|
||
*
|
||
* **Example** (Combining Effects in Tuples)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* const tupleOfEffects = [
|
||
* Effect.succeed(42).pipe(Effect.tap(Console.log)),
|
||
* Effect.succeed("Hello").pipe(Effect.tap(Console.log))
|
||
* ] as const
|
||
*
|
||
* // ┌─── Effect<[number, string], never, never>
|
||
* // ▼
|
||
* const resultsAsTuple = Effect.all(tupleOfEffects)
|
||
*
|
||
* Effect.runPromise(resultsAsTuple).then(console.log)
|
||
* // Output:
|
||
* // 42
|
||
* // Hello
|
||
* // [ 42, 'Hello' ]
|
||
* ```
|
||
*
|
||
* **Example** (Combining Effects in Iterables)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* const iterableOfEffects: Iterable<Effect.Effect<number>> = [1, 2, 3].map(
|
||
* (n) => Effect.succeed(n).pipe(Effect.tap(Console.log))
|
||
* )
|
||
*
|
||
* // ┌─── Effect<number[], never, never>
|
||
* // ▼
|
||
* const resultsAsArray = Effect.all(iterableOfEffects)
|
||
*
|
||
* Effect.runPromise(resultsAsArray).then(console.log)
|
||
* // Output:
|
||
* // 1
|
||
* // 2
|
||
* // 3
|
||
* // [ 1, 2, 3 ]
|
||
* ```
|
||
*
|
||
* **Example** (Combining Effects in Structs)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* const structOfEffects = {
|
||
* a: Effect.succeed(42).pipe(Effect.tap(Console.log)),
|
||
* b: Effect.succeed("Hello").pipe(Effect.tap(Console.log))
|
||
* }
|
||
*
|
||
* // ┌─── Effect<{ a: number; b: string; }, never, never>
|
||
* // ▼
|
||
* const resultsAsStruct = Effect.all(structOfEffects)
|
||
*
|
||
* Effect.runPromise(resultsAsStruct).then(console.log)
|
||
* // Output:
|
||
* // 42
|
||
* // Hello
|
||
* // { a: 42, b: 'Hello' }
|
||
* ```
|
||
*
|
||
* **Example** (Combining Effects in Records)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* const recordOfEffects: Record<string, Effect.Effect<number>> = {
|
||
* key1: Effect.succeed(1).pipe(Effect.tap(Console.log)),
|
||
* key2: Effect.succeed(2).pipe(Effect.tap(Console.log))
|
||
* }
|
||
*
|
||
* // ┌─── Effect<{ [x: string]: number; }, never, never>
|
||
* // ▼
|
||
* const resultsAsRecord = Effect.all(recordOfEffects)
|
||
*
|
||
* Effect.runPromise(resultsAsRecord).then(console.log)
|
||
* // Output:
|
||
* // 1
|
||
* // 2
|
||
* // { key1: 1, key2: 2 }
|
||
* ```
|
||
*
|
||
* **Example** (Short-Circuiting Behavior)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* const program = Effect.all([
|
||
* Effect.succeed("Task1").pipe(Effect.tap(Console.log)),
|
||
* Effect.fail("Task2: Oh no!").pipe(Effect.tap(Console.log)),
|
||
* // Won't execute due to earlier failure
|
||
* Effect.succeed("Task3").pipe(Effect.tap(Console.log))
|
||
* ])
|
||
*
|
||
* Effect.runPromiseExit(program).then(console.log)
|
||
* // Output:
|
||
* // Task1
|
||
* // {
|
||
* // _id: 'Exit',
|
||
* // _tag: 'Failure',
|
||
* // cause: { _id: 'Cause', _tag: 'Fail', failure: 'Task2: Oh no!' }
|
||
* // }
|
||
* ```
|
||
*
|
||
* **Example** (Collecting Results with `mode: "either"`)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* const effects = [
|
||
* Effect.succeed("Task1").pipe(Effect.tap(Console.log)),
|
||
* Effect.fail("Task2: Oh no!").pipe(Effect.tap(Console.log)),
|
||
* Effect.succeed("Task3").pipe(Effect.tap(Console.log))
|
||
* ]
|
||
*
|
||
* const program = Effect.all(effects, { mode: "either" })
|
||
*
|
||
* Effect.runPromiseExit(program).then(console.log)
|
||
* // Output:
|
||
* // Task1
|
||
* // Task3
|
||
* // {
|
||
* // _id: 'Exit',
|
||
* // _tag: 'Success',
|
||
* // value: [
|
||
* // { _id: 'Either', _tag: 'Right', right: 'Task1' },
|
||
* // { _id: 'Either', _tag: 'Left', left: 'Task2: Oh no!' },
|
||
* // { _id: 'Either', _tag: 'Right', right: 'Task3' }
|
||
* // ]
|
||
* // }
|
||
* ```
|
||
*
|
||
* **Example** (Collecting Results with `mode: "validate"`)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* const effects = [
|
||
* Effect.succeed("Task1").pipe(Effect.tap(Console.log)),
|
||
* Effect.fail("Task2: Oh no!").pipe(Effect.tap(Console.log)),
|
||
* Effect.succeed("Task3").pipe(Effect.tap(Console.log))
|
||
* ]
|
||
*
|
||
* const program = Effect.all(effects, { mode: "validate" })
|
||
*
|
||
* Effect.runPromiseExit(program).then((result) => console.log("%o", result))
|
||
* // Output:
|
||
* // Task1
|
||
* // Task3
|
||
* // {
|
||
* // _id: 'Exit',
|
||
* // _tag: 'Failure',
|
||
* // cause: {
|
||
* // _id: 'Cause',
|
||
* // _tag: 'Fail',
|
||
* // failure: [
|
||
* // { _id: 'Option', _tag: 'None' },
|
||
* // { _id: 'Option', _tag: 'Some', value: 'Task2: Oh no!' },
|
||
* // { _id: 'Option', _tag: 'None' }
|
||
* // ]
|
||
* // }
|
||
* // }
|
||
* ```
|
||
*
|
||
* @see {@link forEach} for iterating over elements and applying an effect.
|
||
* @see {@link allWith} for a data-last version of this function.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Collecting
|
||
*/
|
||
export declare const all: <const Arg extends Iterable<Effect<any, any, any>> | Record<string, Effect<any, any, any>>, O extends NoExcessProperties<{
|
||
readonly concurrency?: Concurrency | undefined;
|
||
readonly batching?: boolean | "inherit" | undefined;
|
||
readonly discard?: boolean | undefined;
|
||
readonly mode?: "default" | "validate" | "either" | undefined;
|
||
readonly concurrentFinalizers?: boolean | undefined;
|
||
}, O>>(arg: Arg, options?: O) => All.Return<Arg, O>;
|
||
/**
|
||
* A data-last version of {@link all}, designed for use in pipelines.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This function enables you to combine multiple effects and customize execution
|
||
* options such as concurrency levels. This version is useful in functional
|
||
* pipelines where you first define your data and then apply operations to it.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, pipe } from "effect"
|
||
*
|
||
* const task1 = Effect.succeed(1).pipe(
|
||
* Effect.delay("200 millis"),
|
||
* Effect.tap(Effect.log("task1 done"))
|
||
* )
|
||
*
|
||
* const task2 = Effect.succeed("hello").pipe(
|
||
* Effect.delay("100 millis"),
|
||
* Effect.tap(Effect.log("task2 done"))
|
||
* )
|
||
*
|
||
* const program = pipe(
|
||
* [task1, task2],
|
||
* // Run both effects concurrently using the concurrent option
|
||
* Effect.allWith({ concurrency: 2 })
|
||
* )
|
||
*
|
||
* Effect.runPromise(program).then(console.log)
|
||
* // Output:
|
||
* // timestamp=... level=INFO fiber=#3 message="task2 done"
|
||
* // timestamp=... level=INFO fiber=#2 message="task1 done"
|
||
* // [ 1, 'hello' ]
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Collecting
|
||
*/
|
||
export declare const allWith: <O extends NoExcessProperties<{
|
||
readonly concurrency?: Concurrency | undefined;
|
||
readonly batching?: boolean | "inherit" | undefined;
|
||
readonly discard?: boolean | undefined;
|
||
readonly mode?: "default" | "validate" | "either" | undefined;
|
||
readonly concurrentFinalizers?: boolean | undefined;
|
||
}, O>>(options?: O) => <const Arg extends Iterable<Effect<any, any, any>> | Record<string, Effect<any, any, any>>>(arg: Arg) => All.Return<Arg, O>;
|
||
/**
|
||
* @since 2.0.0
|
||
*/
|
||
export declare namespace All {
|
||
/**
|
||
* @since 2.0.0
|
||
*/
|
||
type EffectAny = Effect<any, any, any>;
|
||
/**
|
||
* @since 2.0.0
|
||
*/
|
||
type ReturnIterable<T extends Iterable<EffectAny>, Discard extends boolean, Mode> = [T] extends [
|
||
Iterable<Effect.Variance<infer R0, infer L0, infer R>>
|
||
] ? Effect<Discard extends true ? void : Mode extends "either" ? Array<Either.Either<R0, L0>> : Array<R0>, Mode extends "either" ? never : Mode extends "validate" ? Array<Option.Option<L0>> : L0, R> : never;
|
||
/**
|
||
* @since 2.0.0
|
||
*/
|
||
type ReturnTuple<T extends ReadonlyArray<unknown>, Discard extends boolean, Mode> = Effect<Discard extends true ? void : T[number] extends never ? [] : Mode extends "either" ? {
|
||
-readonly [K in keyof T]: [T[K]] extends [Effect.Variance<infer _A, infer _E, infer _R>] ? Either.Either<_A, _E> : never;
|
||
} : {
|
||
-readonly [K in keyof T]: [T[K]] extends [Effect.Variance<infer _A, infer _E, infer _R>] ? _A : never;
|
||
}, Mode extends "either" ? never : T[number] extends never ? never : Mode extends "validate" ? {
|
||
-readonly [K in keyof T]: [T[K]] extends [Effect.Variance<infer _A, infer _E, infer _R>] ? Option.Option<_E> : never;
|
||
} : [T[number]] extends [{
|
||
[EffectTypeId]: {
|
||
_E: (_: never) => infer E;
|
||
};
|
||
}] ? E : never, T[number] extends never ? never : [T[number]] extends [{
|
||
[EffectTypeId]: {
|
||
_R: (_: never) => infer R;
|
||
};
|
||
}] ? R : never> extends infer X ? X : never;
|
||
/**
|
||
* @since 2.0.0
|
||
*/
|
||
type ReturnObject<T, Discard extends boolean, Mode> = [T] extends [{
|
||
[K: string]: EffectAny;
|
||
}] ? Effect<Discard extends true ? void : Mode extends "either" ? {
|
||
-readonly [K in keyof T]: [T[K]] extends [Effect.Variance<infer _A, infer _E, infer _R>] ? Either.Either<_A, _E> : never;
|
||
} : {
|
||
-readonly [K in keyof T]: [T[K]] extends [Effect.Variance<infer _A, infer _E, infer _R>] ? _A : never;
|
||
}, Mode extends "either" ? never : keyof T extends never ? never : Mode extends "validate" ? {
|
||
-readonly [K in keyof T]: [T[K]] extends [Effect.Variance<infer _A, infer _E, infer _R>] ? Option.Option<_E> : never;
|
||
} : [T[keyof T]] extends [{
|
||
[EffectTypeId]: {
|
||
_E: (_: never) => infer E;
|
||
};
|
||
}] ? E : never, keyof T extends never ? never : [T[keyof T]] extends [{
|
||
[EffectTypeId]: {
|
||
_R: (_: never) => infer R;
|
||
};
|
||
}] ? R : never> : never;
|
||
/**
|
||
* @since 2.0.0
|
||
*/
|
||
type IsDiscard<A> = [Extract<A, {
|
||
readonly discard: true;
|
||
}>] extends [never] ? false : true;
|
||
/**
|
||
* @since 2.0.0
|
||
*/
|
||
type ExtractMode<A> = [A] extends [{
|
||
mode: infer M;
|
||
}] ? M : "default";
|
||
/**
|
||
* @since 2.0.0
|
||
*/
|
||
type Return<Arg extends Iterable<EffectAny> | Record<string, EffectAny>, O extends NoExcessProperties<{
|
||
readonly concurrency?: Concurrency | undefined;
|
||
readonly batching?: boolean | "inherit" | undefined;
|
||
readonly discard?: boolean | undefined;
|
||
readonly mode?: "default" | "validate" | "either" | undefined;
|
||
readonly concurrentFinalizers?: boolean | undefined;
|
||
}, O>> = [Arg] extends [ReadonlyArray<EffectAny>] ? ReturnTuple<Arg, IsDiscard<O>, ExtractMode<O>> : [Arg] extends [Iterable<EffectAny>] ? ReturnIterable<Arg, IsDiscard<O>, ExtractMode<O>> : [Arg] extends [Record<string, EffectAny>] ? ReturnObject<Arg, IsDiscard<O>, ExtractMode<O>> : never;
|
||
}
|
||
/**
|
||
* Evaluates and runs each effect in the iterable, collecting only the
|
||
* successful results while discarding failures.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function function processes an iterable of effects and runs each one. If
|
||
* an effect is successful, its result is collected; if it fails, the result is
|
||
* discarded. This ensures that only successful outcomes are kept.
|
||
*
|
||
* **Options**
|
||
*
|
||
* The function also allows you to customize how the effects are handled by
|
||
* specifying options such as concurrency, batching, and how finalizers behave.
|
||
* These options provide flexibility in running the effects concurrently or
|
||
* adjusting other execution details.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const tasks = [
|
||
* Effect.succeed(1),
|
||
* Effect.fail("Error 1"),
|
||
* Effect.succeed(2),
|
||
* Effect.fail("Error 2")
|
||
* ]
|
||
*
|
||
* const program = Effect.gen(function*() {
|
||
* const successfulResults = yield* Effect.allSuccesses(tasks)
|
||
* console.log(successfulResults)
|
||
* })
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output: [1, 2]
|
||
*
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Collecting
|
||
*/
|
||
export declare const allSuccesses: <X extends Effect<any, any, any>>(elements: Iterable<X>, options?: {
|
||
readonly concurrency?: Concurrency | undefined;
|
||
readonly batching?: boolean | "inherit" | undefined;
|
||
readonly concurrentFinalizers?: boolean | undefined;
|
||
} | undefined) => Effect<Array<Effect.Success<X>>, never, Effect.Context<X>>;
|
||
/**
|
||
* Drops elements until the effectful predicate returns `true`.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function processes a collection of elements and uses an effectful
|
||
* predicate to determine when to stop dropping elements. It drops elements from
|
||
* the beginning of the collection until the predicate returns `true`.
|
||
*
|
||
* The predicate is a function that takes an element and its index in the
|
||
* collection and returns an effect that evaluates to a boolean.
|
||
*
|
||
* Once the predicate returns `true`, the remaining elements of the collection
|
||
* are returned.
|
||
*
|
||
* **Note**: The first element for which the predicate returns `true` is also
|
||
* dropped.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This function allows you to conditionally skip over a part of the collection
|
||
* based on some criteria defined in the predicate.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const numbers = [1, 2, 3, 4, 5, 6]
|
||
* const predicate = (n: number, i: number) => Effect.succeed(n > 3)
|
||
*
|
||
* const program = Effect.gen(function*() {
|
||
* const result = yield* Effect.dropUntil(numbers, predicate)
|
||
* console.log(result)
|
||
* })
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output: [5, 6]
|
||
* ```
|
||
*
|
||
* @see {@link dropWhile} for a similar function that drops elements while the
|
||
* predicate returns `true`.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Collecting
|
||
*/
|
||
export declare const dropUntil: {
|
||
/**
|
||
* Drops elements until the effectful predicate returns `true`.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function processes a collection of elements and uses an effectful
|
||
* predicate to determine when to stop dropping elements. It drops elements from
|
||
* the beginning of the collection until the predicate returns `true`.
|
||
*
|
||
* The predicate is a function that takes an element and its index in the
|
||
* collection and returns an effect that evaluates to a boolean.
|
||
*
|
||
* Once the predicate returns `true`, the remaining elements of the collection
|
||
* are returned.
|
||
*
|
||
* **Note**: The first element for which the predicate returns `true` is also
|
||
* dropped.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This function allows you to conditionally skip over a part of the collection
|
||
* based on some criteria defined in the predicate.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const numbers = [1, 2, 3, 4, 5, 6]
|
||
* const predicate = (n: number, i: number) => Effect.succeed(n > 3)
|
||
*
|
||
* const program = Effect.gen(function*() {
|
||
* const result = yield* Effect.dropUntil(numbers, predicate)
|
||
* console.log(result)
|
||
* })
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output: [5, 6]
|
||
* ```
|
||
*
|
||
* @see {@link dropWhile} for a similar function that drops elements while the
|
||
* predicate returns `true`.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Collecting
|
||
*/
|
||
<A, E, R>(predicate: (a: NoInfer<A>, i: number) => Effect<boolean, E, R>): (elements: Iterable<A>) => Effect<Array<A>, E, R>;
|
||
/**
|
||
* Drops elements until the effectful predicate returns `true`.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function processes a collection of elements and uses an effectful
|
||
* predicate to determine when to stop dropping elements. It drops elements from
|
||
* the beginning of the collection until the predicate returns `true`.
|
||
*
|
||
* The predicate is a function that takes an element and its index in the
|
||
* collection and returns an effect that evaluates to a boolean.
|
||
*
|
||
* Once the predicate returns `true`, the remaining elements of the collection
|
||
* are returned.
|
||
*
|
||
* **Note**: The first element for which the predicate returns `true` is also
|
||
* dropped.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This function allows you to conditionally skip over a part of the collection
|
||
* based on some criteria defined in the predicate.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const numbers = [1, 2, 3, 4, 5, 6]
|
||
* const predicate = (n: number, i: number) => Effect.succeed(n > 3)
|
||
*
|
||
* const program = Effect.gen(function*() {
|
||
* const result = yield* Effect.dropUntil(numbers, predicate)
|
||
* console.log(result)
|
||
* })
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output: [5, 6]
|
||
* ```
|
||
*
|
||
* @see {@link dropWhile} for a similar function that drops elements while the
|
||
* predicate returns `true`.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Collecting
|
||
*/
|
||
<A, E, R>(elements: Iterable<A>, predicate: (a: A, i: number) => Effect<boolean, E, R>): Effect<Array<A>, E, R>;
|
||
};
|
||
/**
|
||
* Drops elements as long as the predicate returns `true`.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function processes a collection of elements and uses a predicate to
|
||
* decide whether to drop an element.
|
||
*
|
||
* The predicate is a function that takes an element and its index, and it
|
||
* returns an effect that evaluates to a boolean.
|
||
*
|
||
* As long as the predicate returns `true`, elements will continue to be dropped
|
||
* from the collection.
|
||
*
|
||
* Once the predicate returns `false`, the remaining elements are kept.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This function allows you to discard elements from the start of a collection
|
||
* based on a condition, and only keep the rest when the condition no longer
|
||
* holds.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const numbers = [1, 2, 3, 4, 5, 6]
|
||
* const predicate = (n: number, i: number) => Effect.succeed(n <= 3)
|
||
*
|
||
* const program = Effect.gen(function*() {
|
||
* const result = yield* Effect.dropWhile(numbers, predicate)
|
||
* console.log(result)
|
||
* })
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output: [4, 5, 6]
|
||
* ```
|
||
*
|
||
* @see {@link dropUntil} for a similar function that drops elements until the
|
||
* predicate returns `true`.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Collecting
|
||
*/
|
||
export declare const dropWhile: {
|
||
/**
|
||
* Drops elements as long as the predicate returns `true`.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function processes a collection of elements and uses a predicate to
|
||
* decide whether to drop an element.
|
||
*
|
||
* The predicate is a function that takes an element and its index, and it
|
||
* returns an effect that evaluates to a boolean.
|
||
*
|
||
* As long as the predicate returns `true`, elements will continue to be dropped
|
||
* from the collection.
|
||
*
|
||
* Once the predicate returns `false`, the remaining elements are kept.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This function allows you to discard elements from the start of a collection
|
||
* based on a condition, and only keep the rest when the condition no longer
|
||
* holds.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const numbers = [1, 2, 3, 4, 5, 6]
|
||
* const predicate = (n: number, i: number) => Effect.succeed(n <= 3)
|
||
*
|
||
* const program = Effect.gen(function*() {
|
||
* const result = yield* Effect.dropWhile(numbers, predicate)
|
||
* console.log(result)
|
||
* })
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output: [4, 5, 6]
|
||
* ```
|
||
*
|
||
* @see {@link dropUntil} for a similar function that drops elements until the
|
||
* predicate returns `true`.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Collecting
|
||
*/
|
||
<A, E, R>(predicate: (a: NoInfer<A>, i: number) => Effect<boolean, E, R>): (elements: Iterable<A>) => Effect<Array<A>, E, R>;
|
||
/**
|
||
* Drops elements as long as the predicate returns `true`.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function processes a collection of elements and uses a predicate to
|
||
* decide whether to drop an element.
|
||
*
|
||
* The predicate is a function that takes an element and its index, and it
|
||
* returns an effect that evaluates to a boolean.
|
||
*
|
||
* As long as the predicate returns `true`, elements will continue to be dropped
|
||
* from the collection.
|
||
*
|
||
* Once the predicate returns `false`, the remaining elements are kept.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This function allows you to discard elements from the start of a collection
|
||
* based on a condition, and only keep the rest when the condition no longer
|
||
* holds.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const numbers = [1, 2, 3, 4, 5, 6]
|
||
* const predicate = (n: number, i: number) => Effect.succeed(n <= 3)
|
||
*
|
||
* const program = Effect.gen(function*() {
|
||
* const result = yield* Effect.dropWhile(numbers, predicate)
|
||
* console.log(result)
|
||
* })
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output: [4, 5, 6]
|
||
* ```
|
||
*
|
||
* @see {@link dropUntil} for a similar function that drops elements until the
|
||
* predicate returns `true`.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Collecting
|
||
*/
|
||
<A, E, R>(elements: Iterable<A>, predicate: (a: A, i: number) => Effect<boolean, E, R>): Effect<Array<A>, E, R>;
|
||
};
|
||
/**
|
||
* Takes elements from a collection until the effectful predicate returns
|
||
* `true`.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function processes a collection of elements and uses an effectful
|
||
* predicate to decide when to stop taking elements. The elements are taken from
|
||
* the beginning of the collection until the predicate returns `true`.
|
||
*
|
||
* The predicate is a function that takes an element and its index in the
|
||
* collection, and returns an effect that resolves to a boolean.
|
||
*
|
||
* Once the predicate returns `true`, the remaining elements of the collection
|
||
* are discarded, and the function stops taking more elements.
|
||
*
|
||
* **Note**: The first element for which the predicate returns `true` is also
|
||
* included in the result.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use this function when you want to conditionally take elements from a
|
||
* collection based on a dynamic condition. For example, you may want to collect
|
||
* numbers from a list until a certain threshold is reached, or gather items
|
||
* until a specific condition is met.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const numbers = [1, 2, 3, 4, 5, 6]
|
||
* const predicate = (n: number, i: number) => Effect.succeed(n > 3)
|
||
*
|
||
* const program = Effect.gen(function*() {
|
||
* const result = yield* Effect.takeUntil(numbers, predicate)
|
||
* console.log(result)
|
||
* })
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output: [ 1, 2, 3, 4 ]
|
||
* ```
|
||
*
|
||
* @see {@link takeWhile} for a similar function that takes elements while the
|
||
* predicate returns `true`.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Collecting
|
||
*/
|
||
export declare const takeUntil: {
|
||
/**
|
||
* Takes elements from a collection until the effectful predicate returns
|
||
* `true`.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function processes a collection of elements and uses an effectful
|
||
* predicate to decide when to stop taking elements. The elements are taken from
|
||
* the beginning of the collection until the predicate returns `true`.
|
||
*
|
||
* The predicate is a function that takes an element and its index in the
|
||
* collection, and returns an effect that resolves to a boolean.
|
||
*
|
||
* Once the predicate returns `true`, the remaining elements of the collection
|
||
* are discarded, and the function stops taking more elements.
|
||
*
|
||
* **Note**: The first element for which the predicate returns `true` is also
|
||
* included in the result.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use this function when you want to conditionally take elements from a
|
||
* collection based on a dynamic condition. For example, you may want to collect
|
||
* numbers from a list until a certain threshold is reached, or gather items
|
||
* until a specific condition is met.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const numbers = [1, 2, 3, 4, 5, 6]
|
||
* const predicate = (n: number, i: number) => Effect.succeed(n > 3)
|
||
*
|
||
* const program = Effect.gen(function*() {
|
||
* const result = yield* Effect.takeUntil(numbers, predicate)
|
||
* console.log(result)
|
||
* })
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output: [ 1, 2, 3, 4 ]
|
||
* ```
|
||
*
|
||
* @see {@link takeWhile} for a similar function that takes elements while the
|
||
* predicate returns `true`.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Collecting
|
||
*/
|
||
<A, R, E>(predicate: (a: NoInfer<A>, i: number) => Effect<boolean, E, R>): (elements: Iterable<A>) => Effect<Array<A>, E, R>;
|
||
/**
|
||
* Takes elements from a collection until the effectful predicate returns
|
||
* `true`.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function processes a collection of elements and uses an effectful
|
||
* predicate to decide when to stop taking elements. The elements are taken from
|
||
* the beginning of the collection until the predicate returns `true`.
|
||
*
|
||
* The predicate is a function that takes an element and its index in the
|
||
* collection, and returns an effect that resolves to a boolean.
|
||
*
|
||
* Once the predicate returns `true`, the remaining elements of the collection
|
||
* are discarded, and the function stops taking more elements.
|
||
*
|
||
* **Note**: The first element for which the predicate returns `true` is also
|
||
* included in the result.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use this function when you want to conditionally take elements from a
|
||
* collection based on a dynamic condition. For example, you may want to collect
|
||
* numbers from a list until a certain threshold is reached, or gather items
|
||
* until a specific condition is met.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const numbers = [1, 2, 3, 4, 5, 6]
|
||
* const predicate = (n: number, i: number) => Effect.succeed(n > 3)
|
||
*
|
||
* const program = Effect.gen(function*() {
|
||
* const result = yield* Effect.takeUntil(numbers, predicate)
|
||
* console.log(result)
|
||
* })
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output: [ 1, 2, 3, 4 ]
|
||
* ```
|
||
*
|
||
* @see {@link takeWhile} for a similar function that takes elements while the
|
||
* predicate returns `true`.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Collecting
|
||
*/
|
||
<A, E, R>(elements: Iterable<A>, predicate: (a: NoInfer<A>, i: number) => Effect<boolean, E, R>): Effect<Array<A>, E, R>;
|
||
};
|
||
/**
|
||
* Takes elements as long as the predicate returns `true`.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function processes a collection of elements and uses a predicate to
|
||
* decide whether to take an element.
|
||
*
|
||
* The predicate is a function that takes an element and its index, and it
|
||
* returns an effect that evaluates to a boolean.
|
||
*
|
||
* As long as the predicate returns `true`, elements will continue to be taken
|
||
* from the collection.
|
||
*
|
||
* Once the predicate returns `false`, the remaining elements are discarded.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const numbers = [1, 2, 3, 4, 5, 6]
|
||
* const predicate = (n: number, i: number) => Effect.succeed(n <= 3)
|
||
*
|
||
* const program = Effect.gen(function*() {
|
||
* const result = yield* Effect.takeWhile(numbers, predicate)
|
||
* console.log(result)
|
||
* })
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output: [1, 2, 3]
|
||
* ```
|
||
*
|
||
* @see {@link takeUntil} for a similar function that takes elements until the predicate returns `true`.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Collecting
|
||
*/
|
||
export declare const takeWhile: {
|
||
/**
|
||
* Takes elements as long as the predicate returns `true`.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function processes a collection of elements and uses a predicate to
|
||
* decide whether to take an element.
|
||
*
|
||
* The predicate is a function that takes an element and its index, and it
|
||
* returns an effect that evaluates to a boolean.
|
||
*
|
||
* As long as the predicate returns `true`, elements will continue to be taken
|
||
* from the collection.
|
||
*
|
||
* Once the predicate returns `false`, the remaining elements are discarded.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const numbers = [1, 2, 3, 4, 5, 6]
|
||
* const predicate = (n: number, i: number) => Effect.succeed(n <= 3)
|
||
*
|
||
* const program = Effect.gen(function*() {
|
||
* const result = yield* Effect.takeWhile(numbers, predicate)
|
||
* console.log(result)
|
||
* })
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output: [1, 2, 3]
|
||
* ```
|
||
*
|
||
* @see {@link takeUntil} for a similar function that takes elements until the predicate returns `true`.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Collecting
|
||
*/
|
||
<A, E, R>(predicate: (a: NoInfer<A>, i: number) => Effect<boolean, E, R>): (elements: Iterable<A>) => Effect<Array<A>, E, R>;
|
||
/**
|
||
* Takes elements as long as the predicate returns `true`.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function processes a collection of elements and uses a predicate to
|
||
* decide whether to take an element.
|
||
*
|
||
* The predicate is a function that takes an element and its index, and it
|
||
* returns an effect that evaluates to a boolean.
|
||
*
|
||
* As long as the predicate returns `true`, elements will continue to be taken
|
||
* from the collection.
|
||
*
|
||
* Once the predicate returns `false`, the remaining elements are discarded.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const numbers = [1, 2, 3, 4, 5, 6]
|
||
* const predicate = (n: number, i: number) => Effect.succeed(n <= 3)
|
||
*
|
||
* const program = Effect.gen(function*() {
|
||
* const result = yield* Effect.takeWhile(numbers, predicate)
|
||
* console.log(result)
|
||
* })
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output: [1, 2, 3]
|
||
* ```
|
||
*
|
||
* @see {@link takeUntil} for a similar function that takes elements until the predicate returns `true`.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Collecting
|
||
*/
|
||
<A, E, R>(elements: Iterable<A>, predicate: (a: NoInfer<A>, i: number) => Effect<boolean, E, R>): Effect<Array<A>, E, R>;
|
||
};
|
||
/**
|
||
* Determines whether all elements of the iterable satisfy the effectful
|
||
* predicate.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function checks whether every element in a given collection (an
|
||
* iterable) satisfies a condition defined by an effectful predicate.
|
||
*
|
||
* The predicate is a function that takes an element and its index, and it
|
||
* returns an effect that evaluates to a boolean.
|
||
*
|
||
* The function will process each element and return `true` if all elements
|
||
* satisfy the predicate; otherwise, it returns `false`.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This function is useful when you need to verify that all items in a
|
||
* collection meet certain criteria, even when the evaluation of each item
|
||
* involves effects, such as asynchronous checks or complex computations.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const numbers = [2, 4, 6, 8]
|
||
* const predicate = (n: number, i: number) => Effect.succeed(n % 2 === 0)
|
||
*
|
||
* const program = Effect.gen(function*() {
|
||
* const allEven = yield* Effect.every(numbers, predicate)
|
||
* console.log(allEven)
|
||
* })
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output: true
|
||
* ```
|
||
*
|
||
* @see {@link exists} for a similar function that returns a boolean indicating
|
||
* whether **any** element satisfies the predicate.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Condition Checking
|
||
*/
|
||
export declare const every: {
|
||
/**
|
||
* Determines whether all elements of the iterable satisfy the effectful
|
||
* predicate.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function checks whether every element in a given collection (an
|
||
* iterable) satisfies a condition defined by an effectful predicate.
|
||
*
|
||
* The predicate is a function that takes an element and its index, and it
|
||
* returns an effect that evaluates to a boolean.
|
||
*
|
||
* The function will process each element and return `true` if all elements
|
||
* satisfy the predicate; otherwise, it returns `false`.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This function is useful when you need to verify that all items in a
|
||
* collection meet certain criteria, even when the evaluation of each item
|
||
* involves effects, such as asynchronous checks or complex computations.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const numbers = [2, 4, 6, 8]
|
||
* const predicate = (n: number, i: number) => Effect.succeed(n % 2 === 0)
|
||
*
|
||
* const program = Effect.gen(function*() {
|
||
* const allEven = yield* Effect.every(numbers, predicate)
|
||
* console.log(allEven)
|
||
* })
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output: true
|
||
* ```
|
||
*
|
||
* @see {@link exists} for a similar function that returns a boolean indicating
|
||
* whether **any** element satisfies the predicate.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Condition Checking
|
||
*/
|
||
<A, E, R>(predicate: (a: A, i: number) => Effect<boolean, E, R>): (elements: Iterable<A>) => Effect<boolean, E, R>;
|
||
/**
|
||
* Determines whether all elements of the iterable satisfy the effectful
|
||
* predicate.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function checks whether every element in a given collection (an
|
||
* iterable) satisfies a condition defined by an effectful predicate.
|
||
*
|
||
* The predicate is a function that takes an element and its index, and it
|
||
* returns an effect that evaluates to a boolean.
|
||
*
|
||
* The function will process each element and return `true` if all elements
|
||
* satisfy the predicate; otherwise, it returns `false`.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This function is useful when you need to verify that all items in a
|
||
* collection meet certain criteria, even when the evaluation of each item
|
||
* involves effects, such as asynchronous checks or complex computations.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const numbers = [2, 4, 6, 8]
|
||
* const predicate = (n: number, i: number) => Effect.succeed(n % 2 === 0)
|
||
*
|
||
* const program = Effect.gen(function*() {
|
||
* const allEven = yield* Effect.every(numbers, predicate)
|
||
* console.log(allEven)
|
||
* })
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output: true
|
||
* ```
|
||
*
|
||
* @see {@link exists} for a similar function that returns a boolean indicating
|
||
* whether **any** element satisfies the predicate.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Condition Checking
|
||
*/
|
||
<A, E, R>(elements: Iterable<A>, predicate: (a: A, i: number) => Effect<boolean, E, R>): Effect<boolean, E, R>;
|
||
};
|
||
/**
|
||
* Determines whether any element of the iterable satisfies the effectual
|
||
* predicate.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function checks whether any element in a given collection (an iterable)
|
||
* satisfies a condition defined by an effectful predicate.
|
||
*
|
||
* The predicate is a function that takes an element and its index, and it
|
||
* returns an effect that evaluates to a boolean.
|
||
*
|
||
* The function will process each element, and if any element satisfies the
|
||
* predicate (returns `true`), the function will immediately return `true`.
|
||
*
|
||
* If none of the elements satisfy the condition, it will return `false`.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This function allows you to quickly check for a condition in a collection
|
||
* without having to manually iterate over it.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const numbers = [1, 2, 3, 4]
|
||
* const predicate = (n: number, i: number) => Effect.succeed(n > 2)
|
||
*
|
||
* const program = Effect.gen(function*() {
|
||
* const hasLargeNumber = yield* Effect.exists(numbers, predicate)
|
||
* console.log(hasLargeNumber)
|
||
* })
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output: true
|
||
* ```
|
||
*
|
||
* @see {@link every} for a similar function that checks if **all** elements
|
||
* satisfy the predicate.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Condition Checking
|
||
*/
|
||
export declare const exists: {
|
||
/**
|
||
* Determines whether any element of the iterable satisfies the effectual
|
||
* predicate.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function checks whether any element in a given collection (an iterable)
|
||
* satisfies a condition defined by an effectful predicate.
|
||
*
|
||
* The predicate is a function that takes an element and its index, and it
|
||
* returns an effect that evaluates to a boolean.
|
||
*
|
||
* The function will process each element, and if any element satisfies the
|
||
* predicate (returns `true`), the function will immediately return `true`.
|
||
*
|
||
* If none of the elements satisfy the condition, it will return `false`.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This function allows you to quickly check for a condition in a collection
|
||
* without having to manually iterate over it.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const numbers = [1, 2, 3, 4]
|
||
* const predicate = (n: number, i: number) => Effect.succeed(n > 2)
|
||
*
|
||
* const program = Effect.gen(function*() {
|
||
* const hasLargeNumber = yield* Effect.exists(numbers, predicate)
|
||
* console.log(hasLargeNumber)
|
||
* })
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output: true
|
||
* ```
|
||
*
|
||
* @see {@link every} for a similar function that checks if **all** elements
|
||
* satisfy the predicate.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Condition Checking
|
||
*/
|
||
<A, E, R>(predicate: (a: A, i: number) => Effect<boolean, E, R>, options?: {
|
||
readonly concurrency?: Concurrency | undefined;
|
||
readonly batching?: boolean | "inherit" | undefined;
|
||
readonly concurrentFinalizers?: boolean | undefined;
|
||
} | undefined): (elements: Iterable<A>) => Effect<boolean, E, R>;
|
||
/**
|
||
* Determines whether any element of the iterable satisfies the effectual
|
||
* predicate.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function checks whether any element in a given collection (an iterable)
|
||
* satisfies a condition defined by an effectful predicate.
|
||
*
|
||
* The predicate is a function that takes an element and its index, and it
|
||
* returns an effect that evaluates to a boolean.
|
||
*
|
||
* The function will process each element, and if any element satisfies the
|
||
* predicate (returns `true`), the function will immediately return `true`.
|
||
*
|
||
* If none of the elements satisfy the condition, it will return `false`.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This function allows you to quickly check for a condition in a collection
|
||
* without having to manually iterate over it.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const numbers = [1, 2, 3, 4]
|
||
* const predicate = (n: number, i: number) => Effect.succeed(n > 2)
|
||
*
|
||
* const program = Effect.gen(function*() {
|
||
* const hasLargeNumber = yield* Effect.exists(numbers, predicate)
|
||
* console.log(hasLargeNumber)
|
||
* })
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output: true
|
||
* ```
|
||
*
|
||
* @see {@link every} for a similar function that checks if **all** elements
|
||
* satisfy the predicate.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Condition Checking
|
||
*/
|
||
<A, E, R>(elements: Iterable<A>, predicate: (a: A, i: number) => Effect<boolean, E, R>, options?: {
|
||
readonly concurrency?: Concurrency | undefined;
|
||
readonly batching?: boolean | "inherit" | undefined;
|
||
readonly concurrentFinalizers?: boolean | undefined;
|
||
} | undefined): Effect<boolean, E, R>;
|
||
};
|
||
/**
|
||
* Filters an iterable using the specified effectful predicate.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function filters a collection (an iterable) by applying an effectful
|
||
* predicate.
|
||
*
|
||
* The predicate is a function that takes an element and its index, and it
|
||
* returns an effect that evaluates to a boolean.
|
||
*
|
||
* The function processes each element in the collection and keeps only those
|
||
* that satisfy the condition defined by the predicate.
|
||
*
|
||
* **Options**
|
||
*
|
||
* You can also adjust the behavior with options such as concurrency, batching,
|
||
* or whether to negate the condition.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This function allows you to selectively keep or remove elements based on a
|
||
* condition that may involve asynchronous or side-effect-causing operations.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const numbers = [1, 2, 3, 4, 5]
|
||
* const predicate = (n: number, i: number) => Effect.succeed(n % 2 === 0)
|
||
*
|
||
* const program = Effect.gen(function*() {
|
||
* const result = yield* Effect.filter(numbers, predicate)
|
||
* console.log(result)
|
||
* })
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output: [2, 4]
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Filtering
|
||
*/
|
||
export declare const filter: {
|
||
/**
|
||
* Filters an iterable using the specified effectful predicate.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function filters a collection (an iterable) by applying an effectful
|
||
* predicate.
|
||
*
|
||
* The predicate is a function that takes an element and its index, and it
|
||
* returns an effect that evaluates to a boolean.
|
||
*
|
||
* The function processes each element in the collection and keeps only those
|
||
* that satisfy the condition defined by the predicate.
|
||
*
|
||
* **Options**
|
||
*
|
||
* You can also adjust the behavior with options such as concurrency, batching,
|
||
* or whether to negate the condition.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This function allows you to selectively keep or remove elements based on a
|
||
* condition that may involve asynchronous or side-effect-causing operations.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const numbers = [1, 2, 3, 4, 5]
|
||
* const predicate = (n: number, i: number) => Effect.succeed(n % 2 === 0)
|
||
*
|
||
* const program = Effect.gen(function*() {
|
||
* const result = yield* Effect.filter(numbers, predicate)
|
||
* console.log(result)
|
||
* })
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output: [2, 4]
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Filtering
|
||
*/
|
||
<A, E, R>(predicate: (a: NoInfer<A>, i: number) => Effect<boolean, E, R>, options?: {
|
||
readonly concurrency?: Concurrency | undefined;
|
||
readonly batching?: boolean | "inherit" | undefined;
|
||
readonly negate?: boolean | undefined;
|
||
readonly concurrentFinalizers?: boolean | undefined;
|
||
} | undefined): (elements: Iterable<A>) => Effect<Array<A>, E, R>;
|
||
/**
|
||
* Filters an iterable using the specified effectful predicate.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function filters a collection (an iterable) by applying an effectful
|
||
* predicate.
|
||
*
|
||
* The predicate is a function that takes an element and its index, and it
|
||
* returns an effect that evaluates to a boolean.
|
||
*
|
||
* The function processes each element in the collection and keeps only those
|
||
* that satisfy the condition defined by the predicate.
|
||
*
|
||
* **Options**
|
||
*
|
||
* You can also adjust the behavior with options such as concurrency, batching,
|
||
* or whether to negate the condition.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This function allows you to selectively keep or remove elements based on a
|
||
* condition that may involve asynchronous or side-effect-causing operations.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const numbers = [1, 2, 3, 4, 5]
|
||
* const predicate = (n: number, i: number) => Effect.succeed(n % 2 === 0)
|
||
*
|
||
* const program = Effect.gen(function*() {
|
||
* const result = yield* Effect.filter(numbers, predicate)
|
||
* console.log(result)
|
||
* })
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output: [2, 4]
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Filtering
|
||
*/
|
||
<A, E, R>(elements: Iterable<A>, predicate: (a: NoInfer<A>, i: number) => Effect<boolean, E, R>, options?: {
|
||
readonly concurrency?: Concurrency | undefined;
|
||
readonly batching?: boolean | "inherit" | undefined;
|
||
readonly negate?: boolean | undefined;
|
||
readonly concurrentFinalizers?: boolean | undefined;
|
||
} | undefined): Effect<Array<A>, E, R>;
|
||
};
|
||
/**
|
||
* Filters and maps elements sequentially in one operation.
|
||
*
|
||
* This function processes each element one by one. It applies a function that
|
||
* returns an `Option` to each element. If the function returns `Some`, the
|
||
* element is kept; if it returns `None`, the element is removed. The operation
|
||
* is done sequentially for each element.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Console, Effect, Option } from "effect"
|
||
*
|
||
* const task = (n: number) =>
|
||
* Effect.succeed(n).pipe(
|
||
* Effect.delay(1000 - (n * 100)),
|
||
* Effect.tap(Console.log(`task${n} done`))
|
||
* )
|
||
*
|
||
* const program = Effect.filterMap(
|
||
* [task(1), task(2), task(3), task(4)],
|
||
* (n) => n % 2 === 0 ? Option.some(n) : Option.none()
|
||
* )
|
||
*
|
||
* Effect.runPromise(program).then(console.log)
|
||
* // Output:
|
||
* // task1 done
|
||
* // task2 done
|
||
* // task3 done
|
||
* // task4 done
|
||
* // [ 2, 4 ]
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Filtering
|
||
*/
|
||
export declare const filterMap: {
|
||
/**
|
||
* Filters and maps elements sequentially in one operation.
|
||
*
|
||
* This function processes each element one by one. It applies a function that
|
||
* returns an `Option` to each element. If the function returns `Some`, the
|
||
* element is kept; if it returns `None`, the element is removed. The operation
|
||
* is done sequentially for each element.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Console, Effect, Option } from "effect"
|
||
*
|
||
* const task = (n: number) =>
|
||
* Effect.succeed(n).pipe(
|
||
* Effect.delay(1000 - (n * 100)),
|
||
* Effect.tap(Console.log(`task${n} done`))
|
||
* )
|
||
*
|
||
* const program = Effect.filterMap(
|
||
* [task(1), task(2), task(3), task(4)],
|
||
* (n) => n % 2 === 0 ? Option.some(n) : Option.none()
|
||
* )
|
||
*
|
||
* Effect.runPromise(program).then(console.log)
|
||
* // Output:
|
||
* // task1 done
|
||
* // task2 done
|
||
* // task3 done
|
||
* // task4 done
|
||
* // [ 2, 4 ]
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Filtering
|
||
*/
|
||
<Eff extends Effect<any, any, any>, B>(pf: (a: Effect.Success<Eff>) => Option.Option<B>): (elements: Iterable<Eff>) => Effect<Array<B>, Effect.Error<Eff>, Effect.Context<Eff>>;
|
||
/**
|
||
* Filters and maps elements sequentially in one operation.
|
||
*
|
||
* This function processes each element one by one. It applies a function that
|
||
* returns an `Option` to each element. If the function returns `Some`, the
|
||
* element is kept; if it returns `None`, the element is removed. The operation
|
||
* is done sequentially for each element.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Console, Effect, Option } from "effect"
|
||
*
|
||
* const task = (n: number) =>
|
||
* Effect.succeed(n).pipe(
|
||
* Effect.delay(1000 - (n * 100)),
|
||
* Effect.tap(Console.log(`task${n} done`))
|
||
* )
|
||
*
|
||
* const program = Effect.filterMap(
|
||
* [task(1), task(2), task(3), task(4)],
|
||
* (n) => n % 2 === 0 ? Option.some(n) : Option.none()
|
||
* )
|
||
*
|
||
* Effect.runPromise(program).then(console.log)
|
||
* // Output:
|
||
* // task1 done
|
||
* // task2 done
|
||
* // task3 done
|
||
* // task4 done
|
||
* // [ 2, 4 ]
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Filtering
|
||
*/
|
||
<Eff extends Effect<any, any, any>, B>(elements: Iterable<Eff>, pf: (a: Effect.Success<Eff>) => Option.Option<B>): Effect<Array<B>, Effect.Error<Eff>, Effect.Context<Eff>>;
|
||
};
|
||
/**
|
||
* Returns the first element that satisfies the effectful predicate.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function processes a collection of elements and applies an effectful
|
||
* predicate to each element.
|
||
*
|
||
* The predicate is a function that takes an element and its index in the
|
||
* collection, and it returns an effect that evaluates to a boolean.
|
||
*
|
||
* The function stops as soon as it finds the first element for which the
|
||
* predicate returns `true` and returns that element wrapped in an `Option`.
|
||
*
|
||
* If no element satisfies the predicate, the result will be `None`.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This function allows you to efficiently find an element that meets a specific
|
||
* condition, even when the evaluation involves effects like asynchronous
|
||
* operations or side effects.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const numbers = [1, 2, 3, 4, 5]
|
||
* const predicate = (n: number, i: number) => Effect.succeed(n > 3)
|
||
*
|
||
* const program = Effect.gen(function*() {
|
||
* const result = yield* Effect.findFirst(numbers, predicate)
|
||
* console.log(result)
|
||
* })
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output: { _id: 'Option', _tag: 'Some', value: 4 }
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Collecting
|
||
*/
|
||
export declare const findFirst: {
|
||
/**
|
||
* Returns the first element that satisfies the effectful predicate.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function processes a collection of elements and applies an effectful
|
||
* predicate to each element.
|
||
*
|
||
* The predicate is a function that takes an element and its index in the
|
||
* collection, and it returns an effect that evaluates to a boolean.
|
||
*
|
||
* The function stops as soon as it finds the first element for which the
|
||
* predicate returns `true` and returns that element wrapped in an `Option`.
|
||
*
|
||
* If no element satisfies the predicate, the result will be `None`.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This function allows you to efficiently find an element that meets a specific
|
||
* condition, even when the evaluation involves effects like asynchronous
|
||
* operations or side effects.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const numbers = [1, 2, 3, 4, 5]
|
||
* const predicate = (n: number, i: number) => Effect.succeed(n > 3)
|
||
*
|
||
* const program = Effect.gen(function*() {
|
||
* const result = yield* Effect.findFirst(numbers, predicate)
|
||
* console.log(result)
|
||
* })
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output: { _id: 'Option', _tag: 'Some', value: 4 }
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Collecting
|
||
*/
|
||
<A, E, R>(predicate: (a: NoInfer<A>, i: number) => Effect<boolean, E, R>): (elements: Iterable<A>) => Effect<Option.Option<A>, E, R>;
|
||
/**
|
||
* Returns the first element that satisfies the effectful predicate.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function processes a collection of elements and applies an effectful
|
||
* predicate to each element.
|
||
*
|
||
* The predicate is a function that takes an element and its index in the
|
||
* collection, and it returns an effect that evaluates to a boolean.
|
||
*
|
||
* The function stops as soon as it finds the first element for which the
|
||
* predicate returns `true` and returns that element wrapped in an `Option`.
|
||
*
|
||
* If no element satisfies the predicate, the result will be `None`.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This function allows you to efficiently find an element that meets a specific
|
||
* condition, even when the evaluation involves effects like asynchronous
|
||
* operations or side effects.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const numbers = [1, 2, 3, 4, 5]
|
||
* const predicate = (n: number, i: number) => Effect.succeed(n > 3)
|
||
*
|
||
* const program = Effect.gen(function*() {
|
||
* const result = yield* Effect.findFirst(numbers, predicate)
|
||
* console.log(result)
|
||
* })
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output: { _id: 'Option', _tag: 'Some', value: 4 }
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Collecting
|
||
*/
|
||
<A, E, R>(elements: Iterable<A>, predicate: (a: NoInfer<A>, i: number) => Effect<boolean, E, R>): Effect<Option.Option<A>, E, R>;
|
||
};
|
||
/**
|
||
* Executes an effectful operation for each element in an `Iterable`.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function applies a provided operation to each element in the iterable,
|
||
* producing a new effect that returns an array of results.
|
||
*
|
||
* If any effect fails, the iteration stops immediately (short-circuiting), and
|
||
* the error is propagated.
|
||
*
|
||
* **Concurrency**
|
||
*
|
||
* The `concurrency` option controls how many operations are performed
|
||
* concurrently. By default, the operations are performed sequentially.
|
||
*
|
||
* **Discarding Results**
|
||
*
|
||
* If the `discard` option is set to `true`, the intermediate results are not
|
||
* collected, and the final result of the operation is `void`.
|
||
*
|
||
* **Example** (Applying Effects to Iterable Elements)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* const result = Effect.forEach([1, 2, 3, 4, 5], (n, index) =>
|
||
* Console.log(`Currently at index ${index}`).pipe(Effect.as(n * 2))
|
||
* )
|
||
*
|
||
* Effect.runPromise(result).then(console.log)
|
||
* // Output:
|
||
* // Currently at index 0
|
||
* // Currently at index 1
|
||
* // Currently at index 2
|
||
* // Currently at index 3
|
||
* // Currently at index 4
|
||
* // [ 2, 4, 6, 8, 10 ]
|
||
* ```
|
||
*
|
||
* **Example** (Discarding Results)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* // Apply effects but discard the results
|
||
* const result = Effect.forEach(
|
||
* [1, 2, 3, 4, 5],
|
||
* (n, index) =>
|
||
* Console.log(`Currently at index ${index}`).pipe(Effect.as(n * 2)),
|
||
* { discard: true }
|
||
* )
|
||
*
|
||
* Effect.runPromise(result).then(console.log)
|
||
* // Output:
|
||
* // Currently at index 0
|
||
* // Currently at index 1
|
||
* // Currently at index 2
|
||
* // Currently at index 3
|
||
* // Currently at index 4
|
||
* // undefined
|
||
* ```
|
||
*
|
||
* @see {@link all} for combining multiple effects into one.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Looping
|
||
*/
|
||
export declare const forEach: {
|
||
/**
|
||
* Executes an effectful operation for each element in an `Iterable`.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function applies a provided operation to each element in the iterable,
|
||
* producing a new effect that returns an array of results.
|
||
*
|
||
* If any effect fails, the iteration stops immediately (short-circuiting), and
|
||
* the error is propagated.
|
||
*
|
||
* **Concurrency**
|
||
*
|
||
* The `concurrency` option controls how many operations are performed
|
||
* concurrently. By default, the operations are performed sequentially.
|
||
*
|
||
* **Discarding Results**
|
||
*
|
||
* If the `discard` option is set to `true`, the intermediate results are not
|
||
* collected, and the final result of the operation is `void`.
|
||
*
|
||
* **Example** (Applying Effects to Iterable Elements)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* const result = Effect.forEach([1, 2, 3, 4, 5], (n, index) =>
|
||
* Console.log(`Currently at index ${index}`).pipe(Effect.as(n * 2))
|
||
* )
|
||
*
|
||
* Effect.runPromise(result).then(console.log)
|
||
* // Output:
|
||
* // Currently at index 0
|
||
* // Currently at index 1
|
||
* // Currently at index 2
|
||
* // Currently at index 3
|
||
* // Currently at index 4
|
||
* // [ 2, 4, 6, 8, 10 ]
|
||
* ```
|
||
*
|
||
* **Example** (Discarding Results)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* // Apply effects but discard the results
|
||
* const result = Effect.forEach(
|
||
* [1, 2, 3, 4, 5],
|
||
* (n, index) =>
|
||
* Console.log(`Currently at index ${index}`).pipe(Effect.as(n * 2)),
|
||
* { discard: true }
|
||
* )
|
||
*
|
||
* Effect.runPromise(result).then(console.log)
|
||
* // Output:
|
||
* // Currently at index 0
|
||
* // Currently at index 1
|
||
* // Currently at index 2
|
||
* // Currently at index 3
|
||
* // Currently at index 4
|
||
* // undefined
|
||
* ```
|
||
*
|
||
* @see {@link all} for combining multiple effects into one.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Looping
|
||
*/
|
||
<B, E, R, S extends Iterable<any>>(f: (a: RA.ReadonlyArray.Infer<S>, i: number) => Effect<B, E, R>, options?: {
|
||
readonly concurrency?: Concurrency | undefined;
|
||
readonly batching?: boolean | "inherit" | undefined;
|
||
readonly discard?: false | undefined;
|
||
readonly concurrentFinalizers?: boolean | undefined;
|
||
} | undefined): (self: S) => Effect<RA.ReadonlyArray.With<S, B>, E, R>;
|
||
/**
|
||
* Executes an effectful operation for each element in an `Iterable`.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function applies a provided operation to each element in the iterable,
|
||
* producing a new effect that returns an array of results.
|
||
*
|
||
* If any effect fails, the iteration stops immediately (short-circuiting), and
|
||
* the error is propagated.
|
||
*
|
||
* **Concurrency**
|
||
*
|
||
* The `concurrency` option controls how many operations are performed
|
||
* concurrently. By default, the operations are performed sequentially.
|
||
*
|
||
* **Discarding Results**
|
||
*
|
||
* If the `discard` option is set to `true`, the intermediate results are not
|
||
* collected, and the final result of the operation is `void`.
|
||
*
|
||
* **Example** (Applying Effects to Iterable Elements)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* const result = Effect.forEach([1, 2, 3, 4, 5], (n, index) =>
|
||
* Console.log(`Currently at index ${index}`).pipe(Effect.as(n * 2))
|
||
* )
|
||
*
|
||
* Effect.runPromise(result).then(console.log)
|
||
* // Output:
|
||
* // Currently at index 0
|
||
* // Currently at index 1
|
||
* // Currently at index 2
|
||
* // Currently at index 3
|
||
* // Currently at index 4
|
||
* // [ 2, 4, 6, 8, 10 ]
|
||
* ```
|
||
*
|
||
* **Example** (Discarding Results)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* // Apply effects but discard the results
|
||
* const result = Effect.forEach(
|
||
* [1, 2, 3, 4, 5],
|
||
* (n, index) =>
|
||
* Console.log(`Currently at index ${index}`).pipe(Effect.as(n * 2)),
|
||
* { discard: true }
|
||
* )
|
||
*
|
||
* Effect.runPromise(result).then(console.log)
|
||
* // Output:
|
||
* // Currently at index 0
|
||
* // Currently at index 1
|
||
* // Currently at index 2
|
||
* // Currently at index 3
|
||
* // Currently at index 4
|
||
* // undefined
|
||
* ```
|
||
*
|
||
* @see {@link all} for combining multiple effects into one.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Looping
|
||
*/
|
||
<A, B, E, R>(f: (a: A, i: number) => Effect<B, E, R>, options: {
|
||
readonly concurrency?: Concurrency | undefined;
|
||
readonly batching?: boolean | "inherit" | undefined;
|
||
readonly discard: true;
|
||
readonly concurrentFinalizers?: boolean | undefined;
|
||
}): (self: Iterable<A>) => Effect<void, E, R>;
|
||
/**
|
||
* Executes an effectful operation for each element in an `Iterable`.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function applies a provided operation to each element in the iterable,
|
||
* producing a new effect that returns an array of results.
|
||
*
|
||
* If any effect fails, the iteration stops immediately (short-circuiting), and
|
||
* the error is propagated.
|
||
*
|
||
* **Concurrency**
|
||
*
|
||
* The `concurrency` option controls how many operations are performed
|
||
* concurrently. By default, the operations are performed sequentially.
|
||
*
|
||
* **Discarding Results**
|
||
*
|
||
* If the `discard` option is set to `true`, the intermediate results are not
|
||
* collected, and the final result of the operation is `void`.
|
||
*
|
||
* **Example** (Applying Effects to Iterable Elements)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* const result = Effect.forEach([1, 2, 3, 4, 5], (n, index) =>
|
||
* Console.log(`Currently at index ${index}`).pipe(Effect.as(n * 2))
|
||
* )
|
||
*
|
||
* Effect.runPromise(result).then(console.log)
|
||
* // Output:
|
||
* // Currently at index 0
|
||
* // Currently at index 1
|
||
* // Currently at index 2
|
||
* // Currently at index 3
|
||
* // Currently at index 4
|
||
* // [ 2, 4, 6, 8, 10 ]
|
||
* ```
|
||
*
|
||
* **Example** (Discarding Results)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* // Apply effects but discard the results
|
||
* const result = Effect.forEach(
|
||
* [1, 2, 3, 4, 5],
|
||
* (n, index) =>
|
||
* Console.log(`Currently at index ${index}`).pipe(Effect.as(n * 2)),
|
||
* { discard: true }
|
||
* )
|
||
*
|
||
* Effect.runPromise(result).then(console.log)
|
||
* // Output:
|
||
* // Currently at index 0
|
||
* // Currently at index 1
|
||
* // Currently at index 2
|
||
* // Currently at index 3
|
||
* // Currently at index 4
|
||
* // undefined
|
||
* ```
|
||
*
|
||
* @see {@link all} for combining multiple effects into one.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Looping
|
||
*/
|
||
<B, E, R, S extends Iterable<any>>(self: S, f: (a: RA.ReadonlyArray.Infer<S>, i: number) => Effect<B, E, R>, options?: {
|
||
readonly concurrency?: Concurrency | undefined;
|
||
readonly batching?: boolean | "inherit" | undefined;
|
||
readonly discard?: false | undefined;
|
||
readonly concurrentFinalizers?: boolean | undefined;
|
||
} | undefined): Effect<RA.ReadonlyArray.With<S, B>, E, R>;
|
||
/**
|
||
* Executes an effectful operation for each element in an `Iterable`.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function applies a provided operation to each element in the iterable,
|
||
* producing a new effect that returns an array of results.
|
||
*
|
||
* If any effect fails, the iteration stops immediately (short-circuiting), and
|
||
* the error is propagated.
|
||
*
|
||
* **Concurrency**
|
||
*
|
||
* The `concurrency` option controls how many operations are performed
|
||
* concurrently. By default, the operations are performed sequentially.
|
||
*
|
||
* **Discarding Results**
|
||
*
|
||
* If the `discard` option is set to `true`, the intermediate results are not
|
||
* collected, and the final result of the operation is `void`.
|
||
*
|
||
* **Example** (Applying Effects to Iterable Elements)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* const result = Effect.forEach([1, 2, 3, 4, 5], (n, index) =>
|
||
* Console.log(`Currently at index ${index}`).pipe(Effect.as(n * 2))
|
||
* )
|
||
*
|
||
* Effect.runPromise(result).then(console.log)
|
||
* // Output:
|
||
* // Currently at index 0
|
||
* // Currently at index 1
|
||
* // Currently at index 2
|
||
* // Currently at index 3
|
||
* // Currently at index 4
|
||
* // [ 2, 4, 6, 8, 10 ]
|
||
* ```
|
||
*
|
||
* **Example** (Discarding Results)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* // Apply effects but discard the results
|
||
* const result = Effect.forEach(
|
||
* [1, 2, 3, 4, 5],
|
||
* (n, index) =>
|
||
* Console.log(`Currently at index ${index}`).pipe(Effect.as(n * 2)),
|
||
* { discard: true }
|
||
* )
|
||
*
|
||
* Effect.runPromise(result).then(console.log)
|
||
* // Output:
|
||
* // Currently at index 0
|
||
* // Currently at index 1
|
||
* // Currently at index 2
|
||
* // Currently at index 3
|
||
* // Currently at index 4
|
||
* // undefined
|
||
* ```
|
||
*
|
||
* @see {@link all} for combining multiple effects into one.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Looping
|
||
*/
|
||
<A, B, E, R>(self: Iterable<A>, f: (a: A, i: number) => Effect<B, E, R>, options: {
|
||
readonly concurrency?: Concurrency | undefined;
|
||
readonly batching?: boolean | "inherit" | undefined;
|
||
readonly discard: true;
|
||
readonly concurrentFinalizers?: boolean | undefined;
|
||
}): Effect<void, E, R>;
|
||
};
|
||
/**
|
||
* Returns the first element of the iterable if the collection is non-empty, or
|
||
* fails with the error `NoSuchElementException` if the collection is empty.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This function is useful when you need to retrieve the first item from a
|
||
* collection and want to handle the case where the collection might be empty
|
||
* without causing an unhandled exception.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* // Simulate an async operation
|
||
* const fetchNumbers = Effect.succeed([1, 2, 3]).pipe(Effect.delay("100 millis"))
|
||
*
|
||
* const program = Effect.gen(function*() {
|
||
* const firstElement = yield* Effect.head(fetchNumbers)
|
||
* console.log(firstElement)
|
||
* })
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output: 1
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Collecting
|
||
*/
|
||
export declare const head: <A, E, R>(self: Effect<Iterable<A>, E, R>) => Effect<A, Cause.NoSuchElementException | E, R>;
|
||
/**
|
||
* Merges an `Iterable<Effect<A, E, R>>` to a single effect.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function takes an iterable of effects and combines them into a single
|
||
* effect. It does this by iterating over each effect in the collection and
|
||
* applying a function that accumulates results into a "zero" value, which
|
||
* starts with an initial value and is updated with each effect's success.
|
||
*
|
||
* The provided function `f` is called for each element in the iterable,
|
||
* allowing you to specify how to combine the results.
|
||
*
|
||
* **Options**
|
||
*
|
||
* The function also allows you to customize how the effects are handled by
|
||
* specifying options such as concurrency, batching, and how finalizers behave.
|
||
* These options provide flexibility in running the effects concurrently or
|
||
* adjusting other execution details.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const numbers = [Effect.succeed(1), Effect.succeed(2), Effect.succeed(3)]
|
||
* const add = (sum: number, value: number, i: number) => sum + value
|
||
* const zero = 0
|
||
*
|
||
* const program = Effect.gen(function*() {
|
||
* const total = yield* Effect.mergeAll(numbers, zero, add)
|
||
* console.log(total)
|
||
* })
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output: 6
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Collecting
|
||
*/
|
||
export declare const mergeAll: {
|
||
/**
|
||
* Merges an `Iterable<Effect<A, E, R>>` to a single effect.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function takes an iterable of effects and combines them into a single
|
||
* effect. It does this by iterating over each effect in the collection and
|
||
* applying a function that accumulates results into a "zero" value, which
|
||
* starts with an initial value and is updated with each effect's success.
|
||
*
|
||
* The provided function `f` is called for each element in the iterable,
|
||
* allowing you to specify how to combine the results.
|
||
*
|
||
* **Options**
|
||
*
|
||
* The function also allows you to customize how the effects are handled by
|
||
* specifying options such as concurrency, batching, and how finalizers behave.
|
||
* These options provide flexibility in running the effects concurrently or
|
||
* adjusting other execution details.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const numbers = [Effect.succeed(1), Effect.succeed(2), Effect.succeed(3)]
|
||
* const add = (sum: number, value: number, i: number) => sum + value
|
||
* const zero = 0
|
||
*
|
||
* const program = Effect.gen(function*() {
|
||
* const total = yield* Effect.mergeAll(numbers, zero, add)
|
||
* console.log(total)
|
||
* })
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output: 6
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Collecting
|
||
*/
|
||
<Z, Eff extends Effect<any, any, any>>(zero: Z, f: (z: Z, a: Effect.Success<Eff>, i: number) => Z, options?: {
|
||
readonly concurrency?: Concurrency | undefined;
|
||
readonly batching?: boolean | "inherit" | undefined;
|
||
readonly concurrentFinalizers?: boolean | undefined;
|
||
} | undefined): (elements: Iterable<Eff>) => Effect<Z, Effect.Error<Eff>, Effect.Context<Eff>>;
|
||
/**
|
||
* Merges an `Iterable<Effect<A, E, R>>` to a single effect.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function takes an iterable of effects and combines them into a single
|
||
* effect. It does this by iterating over each effect in the collection and
|
||
* applying a function that accumulates results into a "zero" value, which
|
||
* starts with an initial value and is updated with each effect's success.
|
||
*
|
||
* The provided function `f` is called for each element in the iterable,
|
||
* allowing you to specify how to combine the results.
|
||
*
|
||
* **Options**
|
||
*
|
||
* The function also allows you to customize how the effects are handled by
|
||
* specifying options such as concurrency, batching, and how finalizers behave.
|
||
* These options provide flexibility in running the effects concurrently or
|
||
* adjusting other execution details.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const numbers = [Effect.succeed(1), Effect.succeed(2), Effect.succeed(3)]
|
||
* const add = (sum: number, value: number, i: number) => sum + value
|
||
* const zero = 0
|
||
*
|
||
* const program = Effect.gen(function*() {
|
||
* const total = yield* Effect.mergeAll(numbers, zero, add)
|
||
* console.log(total)
|
||
* })
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output: 6
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Collecting
|
||
*/
|
||
<Eff extends Effect<any, any, any>, Z>(elements: Iterable<Eff>, zero: Z, f: (z: Z, a: Effect.Success<Eff>, i: number) => Z, options?: {
|
||
readonly concurrency?: Concurrency | undefined;
|
||
readonly batching?: boolean | "inherit" | undefined;
|
||
readonly concurrentFinalizers?: boolean | undefined;
|
||
} | undefined): Effect<Z, Effect.Error<Eff>, Effect.Context<Eff>>;
|
||
};
|
||
/**
|
||
* Processes an iterable and applies an effectful function to each element,
|
||
* categorizing the results into successes and failures.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function processes each element in the provided iterable by applying an
|
||
* effectful function to it. The results are then categorized into two separate
|
||
* lists: one for failures and another for successes. This separation allows you
|
||
* to handle the two categories differently. Failures are collected in a list
|
||
* without interrupting the processing of the remaining elements, so the
|
||
* operation continues even if some elements fail. This is particularly useful
|
||
* when you need to handle both successful and failed results separately,
|
||
* without stopping the entire process on encountering a failure.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use this function when you want to process a collection of items and handle
|
||
* errors or failures without interrupting the processing of other items. It's
|
||
* useful when you need to distinguish between successful and failed results and
|
||
* process them separately, for example, when logging errors while continuing to
|
||
* work with valid data. The function ensures that failures are captured, while
|
||
* successes are processed normally.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* // ┌─── Effect<[string[], number[]], never, never>
|
||
* // ▼
|
||
* const program = Effect.partition([0, 1, 2, 3, 4], (n) => {
|
||
* if (n % 2 === 0) {
|
||
* return Effect.succeed(n)
|
||
* } else {
|
||
* return Effect.fail(`${n} is not even`)
|
||
* }
|
||
* })
|
||
*
|
||
* Effect.runPromise(program).then(console.log, console.error)
|
||
* // Output:
|
||
* // [ [ '1 is not even', '3 is not even' ], [ 0, 2, 4 ] ]
|
||
* ```
|
||
*
|
||
* @see {@link validateAll} for a function that either collects all failures or all successes.
|
||
* @see {@link validateFirst} for a function that stops at the first success.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error Accumulation
|
||
*/
|
||
export declare const partition: {
|
||
/**
|
||
* Processes an iterable and applies an effectful function to each element,
|
||
* categorizing the results into successes and failures.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function processes each element in the provided iterable by applying an
|
||
* effectful function to it. The results are then categorized into two separate
|
||
* lists: one for failures and another for successes. This separation allows you
|
||
* to handle the two categories differently. Failures are collected in a list
|
||
* without interrupting the processing of the remaining elements, so the
|
||
* operation continues even if some elements fail. This is particularly useful
|
||
* when you need to handle both successful and failed results separately,
|
||
* without stopping the entire process on encountering a failure.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use this function when you want to process a collection of items and handle
|
||
* errors or failures without interrupting the processing of other items. It's
|
||
* useful when you need to distinguish between successful and failed results and
|
||
* process them separately, for example, when logging errors while continuing to
|
||
* work with valid data. The function ensures that failures are captured, while
|
||
* successes are processed normally.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* // ┌─── Effect<[string[], number[]], never, never>
|
||
* // ▼
|
||
* const program = Effect.partition([0, 1, 2, 3, 4], (n) => {
|
||
* if (n % 2 === 0) {
|
||
* return Effect.succeed(n)
|
||
* } else {
|
||
* return Effect.fail(`${n} is not even`)
|
||
* }
|
||
* })
|
||
*
|
||
* Effect.runPromise(program).then(console.log, console.error)
|
||
* // Output:
|
||
* // [ [ '1 is not even', '3 is not even' ], [ 0, 2, 4 ] ]
|
||
* ```
|
||
*
|
||
* @see {@link validateAll} for a function that either collects all failures or all successes.
|
||
* @see {@link validateFirst} for a function that stops at the first success.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error Accumulation
|
||
*/
|
||
<A, B, E, R>(f: (a: A, i: number) => Effect<B, E, R>, options?: {
|
||
readonly concurrency?: Concurrency | undefined;
|
||
readonly batching?: boolean | "inherit" | undefined;
|
||
readonly concurrentFinalizers?: boolean | undefined;
|
||
} | undefined): (elements: Iterable<A>) => Effect<[excluded: Array<E>, satisfying: Array<B>], never, R>;
|
||
/**
|
||
* Processes an iterable and applies an effectful function to each element,
|
||
* categorizing the results into successes and failures.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function processes each element in the provided iterable by applying an
|
||
* effectful function to it. The results are then categorized into two separate
|
||
* lists: one for failures and another for successes. This separation allows you
|
||
* to handle the two categories differently. Failures are collected in a list
|
||
* without interrupting the processing of the remaining elements, so the
|
||
* operation continues even if some elements fail. This is particularly useful
|
||
* when you need to handle both successful and failed results separately,
|
||
* without stopping the entire process on encountering a failure.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use this function when you want to process a collection of items and handle
|
||
* errors or failures without interrupting the processing of other items. It's
|
||
* useful when you need to distinguish between successful and failed results and
|
||
* process them separately, for example, when logging errors while continuing to
|
||
* work with valid data. The function ensures that failures are captured, while
|
||
* successes are processed normally.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* // ┌─── Effect<[string[], number[]], never, never>
|
||
* // ▼
|
||
* const program = Effect.partition([0, 1, 2, 3, 4], (n) => {
|
||
* if (n % 2 === 0) {
|
||
* return Effect.succeed(n)
|
||
* } else {
|
||
* return Effect.fail(`${n} is not even`)
|
||
* }
|
||
* })
|
||
*
|
||
* Effect.runPromise(program).then(console.log, console.error)
|
||
* // Output:
|
||
* // [ [ '1 is not even', '3 is not even' ], [ 0, 2, 4 ] ]
|
||
* ```
|
||
*
|
||
* @see {@link validateAll} for a function that either collects all failures or all successes.
|
||
* @see {@link validateFirst} for a function that stops at the first success.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error Accumulation
|
||
*/
|
||
<A, B, E, R>(elements: Iterable<A>, f: (a: A, i: number) => Effect<B, E, R>, options?: {
|
||
readonly concurrency?: Concurrency | undefined;
|
||
readonly batching?: boolean | "inherit" | undefined;
|
||
readonly concurrentFinalizers?: boolean | undefined;
|
||
} | undefined): Effect<[excluded: Array<E>, satisfying: Array<B>], never, R>;
|
||
};
|
||
/**
|
||
* Reduces an `Iterable<A>` using an effectual function `f`, working
|
||
* sequentially from left to right.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function takes an iterable and applies a function `f` to each element in
|
||
* the iterable. The function works sequentially, starting with an initial value
|
||
* `zero` and then combining it with each element in the collection. The
|
||
* provided function `f` is called for each element in the iterable, allowing
|
||
* you to accumulate a result based on the current value and the element being
|
||
* processed.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* The function is often used for operations like summing a collection of
|
||
* numbers or combining results from multiple tasks. It ensures that operations
|
||
* are performed one after the other, maintaining the order of the elements.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Console, Effect } from "effect"
|
||
*
|
||
* const processOrder = (id: number) =>
|
||
* Effect.succeed({ id, price: 100 * id })
|
||
* .pipe(Effect.tap(() => Console.log(`Order ${id} processed`)), Effect.delay(500 - (id * 100)))
|
||
*
|
||
* const program = Effect.reduce(
|
||
* [1, 2, 3, 4],
|
||
* 0,
|
||
* (acc, id, i) =>
|
||
* processOrder(id)
|
||
* .pipe(Effect.map((order) => acc + order.price))
|
||
* )
|
||
*
|
||
* Effect.runPromise(program).then(console.log)
|
||
* // Output:
|
||
* // Order 1 processed
|
||
* // Order 2 processed
|
||
* // Order 3 processed
|
||
* // Order 4 processed
|
||
* // 1000
|
||
* ```
|
||
*
|
||
* @see {@link reduceWhile} for a similar function that stops the process based on a predicate.
|
||
* @see {@link reduceRight} for a similar function that works from right to left.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Collecting
|
||
*/
|
||
export declare const reduce: {
|
||
/**
|
||
* Reduces an `Iterable<A>` using an effectual function `f`, working
|
||
* sequentially from left to right.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function takes an iterable and applies a function `f` to each element in
|
||
* the iterable. The function works sequentially, starting with an initial value
|
||
* `zero` and then combining it with each element in the collection. The
|
||
* provided function `f` is called for each element in the iterable, allowing
|
||
* you to accumulate a result based on the current value and the element being
|
||
* processed.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* The function is often used for operations like summing a collection of
|
||
* numbers or combining results from multiple tasks. It ensures that operations
|
||
* are performed one after the other, maintaining the order of the elements.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Console, Effect } from "effect"
|
||
*
|
||
* const processOrder = (id: number) =>
|
||
* Effect.succeed({ id, price: 100 * id })
|
||
* .pipe(Effect.tap(() => Console.log(`Order ${id} processed`)), Effect.delay(500 - (id * 100)))
|
||
*
|
||
* const program = Effect.reduce(
|
||
* [1, 2, 3, 4],
|
||
* 0,
|
||
* (acc, id, i) =>
|
||
* processOrder(id)
|
||
* .pipe(Effect.map((order) => acc + order.price))
|
||
* )
|
||
*
|
||
* Effect.runPromise(program).then(console.log)
|
||
* // Output:
|
||
* // Order 1 processed
|
||
* // Order 2 processed
|
||
* // Order 3 processed
|
||
* // Order 4 processed
|
||
* // 1000
|
||
* ```
|
||
*
|
||
* @see {@link reduceWhile} for a similar function that stops the process based on a predicate.
|
||
* @see {@link reduceRight} for a similar function that works from right to left.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Collecting
|
||
*/
|
||
<Z, A, E, R>(zero: Z, f: (z: Z, a: A, i: number) => Effect<Z, E, R>): (elements: Iterable<A>) => Effect<Z, E, R>;
|
||
/**
|
||
* Reduces an `Iterable<A>` using an effectual function `f`, working
|
||
* sequentially from left to right.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function takes an iterable and applies a function `f` to each element in
|
||
* the iterable. The function works sequentially, starting with an initial value
|
||
* `zero` and then combining it with each element in the collection. The
|
||
* provided function `f` is called for each element in the iterable, allowing
|
||
* you to accumulate a result based on the current value and the element being
|
||
* processed.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* The function is often used for operations like summing a collection of
|
||
* numbers or combining results from multiple tasks. It ensures that operations
|
||
* are performed one after the other, maintaining the order of the elements.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Console, Effect } from "effect"
|
||
*
|
||
* const processOrder = (id: number) =>
|
||
* Effect.succeed({ id, price: 100 * id })
|
||
* .pipe(Effect.tap(() => Console.log(`Order ${id} processed`)), Effect.delay(500 - (id * 100)))
|
||
*
|
||
* const program = Effect.reduce(
|
||
* [1, 2, 3, 4],
|
||
* 0,
|
||
* (acc, id, i) =>
|
||
* processOrder(id)
|
||
* .pipe(Effect.map((order) => acc + order.price))
|
||
* )
|
||
*
|
||
* Effect.runPromise(program).then(console.log)
|
||
* // Output:
|
||
* // Order 1 processed
|
||
* // Order 2 processed
|
||
* // Order 3 processed
|
||
* // Order 4 processed
|
||
* // 1000
|
||
* ```
|
||
*
|
||
* @see {@link reduceWhile} for a similar function that stops the process based on a predicate.
|
||
* @see {@link reduceRight} for a similar function that works from right to left.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Collecting
|
||
*/
|
||
<A, Z, E, R>(elements: Iterable<A>, zero: Z, f: (z: Z, a: A, i: number) => Effect<Z, E, R>): Effect<Z, E, R>;
|
||
};
|
||
/**
|
||
* Reduces an `Iterable<A>` using an effectual function `body`, working
|
||
* sequentially from left to right, stopping the process early when the
|
||
* predicate `while` is not satisfied.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function processes a collection of elements, applying a function `body`
|
||
* to reduce them to a single value, starting from the first element. It checks
|
||
* the value of the accumulator against a predicate (`while`). If at any point
|
||
* the predicate returns `false`, the reduction stops, and the accumulated
|
||
* result is returned.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use this function when you need to reduce a collection of elements, but only
|
||
* continue the process as long as a certain condition holds true. For example,
|
||
* if you want to sum values in a list but stop as soon as the sum exceeds a
|
||
* certain threshold, you can use this function.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Console, Effect } from "effect"
|
||
*
|
||
* const processOrder = (id: number) =>
|
||
* Effect.succeed({ id, price: 100 * id })
|
||
* .pipe(Effect.tap(() => Console.log(`Order ${id} processed`)), Effect.delay(500 - (id * 100)))
|
||
*
|
||
* const program = Effect.reduceWhile(
|
||
* [1, 2, 3, 4],
|
||
* 0,
|
||
* {
|
||
* body: (acc, id, i) =>
|
||
* processOrder(id)
|
||
* .pipe(Effect.map((order) => acc + order.price)),
|
||
* while: (acc) => acc < 500
|
||
* }
|
||
* )
|
||
*
|
||
* Effect.runPromise(program).then(console.log)
|
||
* // Output:
|
||
* // Order 1 processed
|
||
* // Order 2 processed
|
||
* // Order 3 processed
|
||
* // 600
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Collecting
|
||
*/
|
||
export declare const reduceWhile: {
|
||
/**
|
||
* Reduces an `Iterable<A>` using an effectual function `body`, working
|
||
* sequentially from left to right, stopping the process early when the
|
||
* predicate `while` is not satisfied.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function processes a collection of elements, applying a function `body`
|
||
* to reduce them to a single value, starting from the first element. It checks
|
||
* the value of the accumulator against a predicate (`while`). If at any point
|
||
* the predicate returns `false`, the reduction stops, and the accumulated
|
||
* result is returned.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use this function when you need to reduce a collection of elements, but only
|
||
* continue the process as long as a certain condition holds true. For example,
|
||
* if you want to sum values in a list but stop as soon as the sum exceeds a
|
||
* certain threshold, you can use this function.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Console, Effect } from "effect"
|
||
*
|
||
* const processOrder = (id: number) =>
|
||
* Effect.succeed({ id, price: 100 * id })
|
||
* .pipe(Effect.tap(() => Console.log(`Order ${id} processed`)), Effect.delay(500 - (id * 100)))
|
||
*
|
||
* const program = Effect.reduceWhile(
|
||
* [1, 2, 3, 4],
|
||
* 0,
|
||
* {
|
||
* body: (acc, id, i) =>
|
||
* processOrder(id)
|
||
* .pipe(Effect.map((order) => acc + order.price)),
|
||
* while: (acc) => acc < 500
|
||
* }
|
||
* )
|
||
*
|
||
* Effect.runPromise(program).then(console.log)
|
||
* // Output:
|
||
* // Order 1 processed
|
||
* // Order 2 processed
|
||
* // Order 3 processed
|
||
* // 600
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Collecting
|
||
*/
|
||
<Z, A, E, R>(zero: Z, options: {
|
||
readonly while: Predicate<Z>;
|
||
readonly body: (s: Z, a: A, i: number) => Effect<Z, E, R>;
|
||
}): (elements: Iterable<A>) => Effect<Z, E, R>;
|
||
/**
|
||
* Reduces an `Iterable<A>` using an effectual function `body`, working
|
||
* sequentially from left to right, stopping the process early when the
|
||
* predicate `while` is not satisfied.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function processes a collection of elements, applying a function `body`
|
||
* to reduce them to a single value, starting from the first element. It checks
|
||
* the value of the accumulator against a predicate (`while`). If at any point
|
||
* the predicate returns `false`, the reduction stops, and the accumulated
|
||
* result is returned.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use this function when you need to reduce a collection of elements, but only
|
||
* continue the process as long as a certain condition holds true. For example,
|
||
* if you want to sum values in a list but stop as soon as the sum exceeds a
|
||
* certain threshold, you can use this function.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Console, Effect } from "effect"
|
||
*
|
||
* const processOrder = (id: number) =>
|
||
* Effect.succeed({ id, price: 100 * id })
|
||
* .pipe(Effect.tap(() => Console.log(`Order ${id} processed`)), Effect.delay(500 - (id * 100)))
|
||
*
|
||
* const program = Effect.reduceWhile(
|
||
* [1, 2, 3, 4],
|
||
* 0,
|
||
* {
|
||
* body: (acc, id, i) =>
|
||
* processOrder(id)
|
||
* .pipe(Effect.map((order) => acc + order.price)),
|
||
* while: (acc) => acc < 500
|
||
* }
|
||
* )
|
||
*
|
||
* Effect.runPromise(program).then(console.log)
|
||
* // Output:
|
||
* // Order 1 processed
|
||
* // Order 2 processed
|
||
* // Order 3 processed
|
||
* // 600
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Collecting
|
||
*/
|
||
<A, Z, E, R>(elements: Iterable<A>, zero: Z, options: {
|
||
readonly while: Predicate<Z>;
|
||
readonly body: (s: Z, a: A, i: number) => Effect<Z, E, R>;
|
||
}): Effect<Z, E, R>;
|
||
};
|
||
/**
|
||
* Reduces an `Iterable<A>` using an effectual function `f`, working
|
||
* sequentially from right to left.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function takes an iterable and applies a function `f` to each element in
|
||
* the iterable. The function works sequentially, starting with an initial value
|
||
* `zero` and then combining it with each element in the collection. The
|
||
* provided function `f` is called for each element in the iterable, allowing
|
||
* you to accumulate a result based on the current value and the element being
|
||
* processed.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* The function is often used for operations like summing a collection of
|
||
* numbers or combining results from multiple tasks. It ensures that operations
|
||
* are performed one after the other, maintaining the order of the elements.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Console, Effect } from "effect"
|
||
*
|
||
* const processOrder = (id: number) =>
|
||
* Effect.succeed({ id, price: 100 * id })
|
||
* .pipe(Effect.tap(() => Console.log(`Order ${id} processed`)), Effect.delay(500 - (id * 100)))
|
||
*
|
||
* const program = Effect.reduceRight(
|
||
* [1, 2, 3, 4],
|
||
* 0,
|
||
* (id, acc, i) =>
|
||
* processOrder(id)
|
||
* .pipe(Effect.map((order) => acc + order.price))
|
||
* )
|
||
*
|
||
* Effect.runPromise(program).then(console.log)
|
||
* // Output:
|
||
* // Order 4 processed
|
||
* // Order 3 processed
|
||
* // Order 2 processed
|
||
* // Order 1 processed
|
||
* // 1000
|
||
* ```
|
||
*
|
||
* @see {@link reduce} for a similar function that works from left to right.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Collecting
|
||
*/
|
||
export declare const reduceRight: {
|
||
/**
|
||
* Reduces an `Iterable<A>` using an effectual function `f`, working
|
||
* sequentially from right to left.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function takes an iterable and applies a function `f` to each element in
|
||
* the iterable. The function works sequentially, starting with an initial value
|
||
* `zero` and then combining it with each element in the collection. The
|
||
* provided function `f` is called for each element in the iterable, allowing
|
||
* you to accumulate a result based on the current value and the element being
|
||
* processed.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* The function is often used for operations like summing a collection of
|
||
* numbers or combining results from multiple tasks. It ensures that operations
|
||
* are performed one after the other, maintaining the order of the elements.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Console, Effect } from "effect"
|
||
*
|
||
* const processOrder = (id: number) =>
|
||
* Effect.succeed({ id, price: 100 * id })
|
||
* .pipe(Effect.tap(() => Console.log(`Order ${id} processed`)), Effect.delay(500 - (id * 100)))
|
||
*
|
||
* const program = Effect.reduceRight(
|
||
* [1, 2, 3, 4],
|
||
* 0,
|
||
* (id, acc, i) =>
|
||
* processOrder(id)
|
||
* .pipe(Effect.map((order) => acc + order.price))
|
||
* )
|
||
*
|
||
* Effect.runPromise(program).then(console.log)
|
||
* // Output:
|
||
* // Order 4 processed
|
||
* // Order 3 processed
|
||
* // Order 2 processed
|
||
* // Order 1 processed
|
||
* // 1000
|
||
* ```
|
||
*
|
||
* @see {@link reduce} for a similar function that works from left to right.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Collecting
|
||
*/
|
||
<A, Z, R, E>(zero: Z, f: (a: A, z: Z, i: number) => Effect<Z, E, R>): (elements: Iterable<A>) => Effect<Z, E, R>;
|
||
/**
|
||
* Reduces an `Iterable<A>` using an effectual function `f`, working
|
||
* sequentially from right to left.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function takes an iterable and applies a function `f` to each element in
|
||
* the iterable. The function works sequentially, starting with an initial value
|
||
* `zero` and then combining it with each element in the collection. The
|
||
* provided function `f` is called for each element in the iterable, allowing
|
||
* you to accumulate a result based on the current value and the element being
|
||
* processed.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* The function is often used for operations like summing a collection of
|
||
* numbers or combining results from multiple tasks. It ensures that operations
|
||
* are performed one after the other, maintaining the order of the elements.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Console, Effect } from "effect"
|
||
*
|
||
* const processOrder = (id: number) =>
|
||
* Effect.succeed({ id, price: 100 * id })
|
||
* .pipe(Effect.tap(() => Console.log(`Order ${id} processed`)), Effect.delay(500 - (id * 100)))
|
||
*
|
||
* const program = Effect.reduceRight(
|
||
* [1, 2, 3, 4],
|
||
* 0,
|
||
* (id, acc, i) =>
|
||
* processOrder(id)
|
||
* .pipe(Effect.map((order) => acc + order.price))
|
||
* )
|
||
*
|
||
* Effect.runPromise(program).then(console.log)
|
||
* // Output:
|
||
* // Order 4 processed
|
||
* // Order 3 processed
|
||
* // Order 2 processed
|
||
* // Order 1 processed
|
||
* // 1000
|
||
* ```
|
||
*
|
||
* @see {@link reduce} for a similar function that works from left to right.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Collecting
|
||
*/
|
||
<A, Z, R, E>(elements: Iterable<A>, zero: Z, f: (a: A, z: Z, i: number) => Effect<Z, E, R>): Effect<Z, E, R>;
|
||
};
|
||
/**
|
||
* Reduces an `Iterable<Effect<A, E, R>>` to a single effect.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function processes a collection of effects and combines them into one
|
||
* single effect. It starts with an initial effect (`zero`) and applies a
|
||
* function `f` to each element in the collection.
|
||
*
|
||
* **Options**
|
||
*
|
||
* The function also allows you to customize how the effects are handled by
|
||
* specifying options such as concurrency, batching, and how finalizers behave.
|
||
* These options provide flexibility in running the effects concurrently or
|
||
* adjusting other execution details.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Console, Effect } from "effect"
|
||
*
|
||
* const processOrder = (id: number) =>
|
||
* Effect.succeed({ id, price: 100 * id })
|
||
* .pipe(Effect.tap(() => Console.log(`Order ${id} processed`)), Effect.delay(500 - (id * 100)))
|
||
*
|
||
* const program = Effect.reduceEffect(
|
||
* [processOrder(1), processOrder(2), processOrder(3), processOrder(4)],
|
||
* Effect.succeed(0),
|
||
* (acc, order, i) => acc + order.price
|
||
* )
|
||
*
|
||
* Effect.runPromise(program).then(console.log)
|
||
* // Output:
|
||
* // Order 1 processed
|
||
* // Order 2 processed
|
||
* // Order 3 processed
|
||
* // Order 4 processed
|
||
* // 1000
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Collecting
|
||
*/
|
||
export declare const reduceEffect: {
|
||
/**
|
||
* Reduces an `Iterable<Effect<A, E, R>>` to a single effect.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function processes a collection of effects and combines them into one
|
||
* single effect. It starts with an initial effect (`zero`) and applies a
|
||
* function `f` to each element in the collection.
|
||
*
|
||
* **Options**
|
||
*
|
||
* The function also allows you to customize how the effects are handled by
|
||
* specifying options such as concurrency, batching, and how finalizers behave.
|
||
* These options provide flexibility in running the effects concurrently or
|
||
* adjusting other execution details.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Console, Effect } from "effect"
|
||
*
|
||
* const processOrder = (id: number) =>
|
||
* Effect.succeed({ id, price: 100 * id })
|
||
* .pipe(Effect.tap(() => Console.log(`Order ${id} processed`)), Effect.delay(500 - (id * 100)))
|
||
*
|
||
* const program = Effect.reduceEffect(
|
||
* [processOrder(1), processOrder(2), processOrder(3), processOrder(4)],
|
||
* Effect.succeed(0),
|
||
* (acc, order, i) => acc + order.price
|
||
* )
|
||
*
|
||
* Effect.runPromise(program).then(console.log)
|
||
* // Output:
|
||
* // Order 1 processed
|
||
* // Order 2 processed
|
||
* // Order 3 processed
|
||
* // Order 4 processed
|
||
* // 1000
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Collecting
|
||
*/
|
||
<Z, E, R, Eff extends Effect<any, any, any>>(zero: Effect<Z, E, R>, f: (z: NoInfer<Z>, a: Effect.Success<Eff>, i: number) => Z, options?: {
|
||
readonly concurrency?: Concurrency | undefined;
|
||
readonly batching?: boolean | "inherit" | undefined;
|
||
readonly concurrentFinalizers?: boolean | undefined;
|
||
} | undefined): (elements: Iterable<Eff>) => Effect<Z, E | Effect.Error<Eff>, R | Effect.Context<Eff>>;
|
||
/**
|
||
* Reduces an `Iterable<Effect<A, E, R>>` to a single effect.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function processes a collection of effects and combines them into one
|
||
* single effect. It starts with an initial effect (`zero`) and applies a
|
||
* function `f` to each element in the collection.
|
||
*
|
||
* **Options**
|
||
*
|
||
* The function also allows you to customize how the effects are handled by
|
||
* specifying options such as concurrency, batching, and how finalizers behave.
|
||
* These options provide flexibility in running the effects concurrently or
|
||
* adjusting other execution details.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Console, Effect } from "effect"
|
||
*
|
||
* const processOrder = (id: number) =>
|
||
* Effect.succeed({ id, price: 100 * id })
|
||
* .pipe(Effect.tap(() => Console.log(`Order ${id} processed`)), Effect.delay(500 - (id * 100)))
|
||
*
|
||
* const program = Effect.reduceEffect(
|
||
* [processOrder(1), processOrder(2), processOrder(3), processOrder(4)],
|
||
* Effect.succeed(0),
|
||
* (acc, order, i) => acc + order.price
|
||
* )
|
||
*
|
||
* Effect.runPromise(program).then(console.log)
|
||
* // Output:
|
||
* // Order 1 processed
|
||
* // Order 2 processed
|
||
* // Order 3 processed
|
||
* // Order 4 processed
|
||
* // 1000
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Collecting
|
||
*/
|
||
<Eff extends Effect<any, any, any>, Z, E, R>(elements: Iterable<Eff>, zero: Effect<Z, E, R>, f: (z: NoInfer<Z>, a: Effect.Success<Eff>, i: number) => Z, options?: {
|
||
readonly concurrency?: Concurrency | undefined;
|
||
readonly batching?: boolean | "inherit" | undefined;
|
||
readonly concurrentFinalizers?: boolean | undefined;
|
||
} | undefined): Effect<Z, E | Effect.Error<Eff>, R | Effect.Context<Eff>>;
|
||
};
|
||
/**
|
||
* Replicates the given effect `n` times.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function takes an effect and replicates it a specified number of times
|
||
* (`n`). The result is an array of `n` effects, each of which is identical to
|
||
* the original effect.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Console, Effect } from "effect"
|
||
*
|
||
* const task = Effect.succeed("Hello, World!").pipe(
|
||
* Effect.tap(Console.log)
|
||
* )
|
||
*
|
||
* const program = Effect.gen(function*() {
|
||
* // Replicate the task 3 times
|
||
* const tasks = Effect.replicate(task, 3)
|
||
* for (const t of tasks) {
|
||
* // Run each task
|
||
* yield* t
|
||
* }
|
||
* })
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output:
|
||
* // Hello, World!
|
||
* // Hello, World!
|
||
* // Hello, World!
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
*/
|
||
export declare const replicate: {
|
||
/**
|
||
* Replicates the given effect `n` times.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function takes an effect and replicates it a specified number of times
|
||
* (`n`). The result is an array of `n` effects, each of which is identical to
|
||
* the original effect.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Console, Effect } from "effect"
|
||
*
|
||
* const task = Effect.succeed("Hello, World!").pipe(
|
||
* Effect.tap(Console.log)
|
||
* )
|
||
*
|
||
* const program = Effect.gen(function*() {
|
||
* // Replicate the task 3 times
|
||
* const tasks = Effect.replicate(task, 3)
|
||
* for (const t of tasks) {
|
||
* // Run each task
|
||
* yield* t
|
||
* }
|
||
* })
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output:
|
||
* // Hello, World!
|
||
* // Hello, World!
|
||
* // Hello, World!
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
*/
|
||
(n: number): <A, E, R>(self: Effect<A, E, R>) => Array<Effect<A, E, R>>;
|
||
/**
|
||
* Replicates the given effect `n` times.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function takes an effect and replicates it a specified number of times
|
||
* (`n`). The result is an array of `n` effects, each of which is identical to
|
||
* the original effect.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Console, Effect } from "effect"
|
||
*
|
||
* const task = Effect.succeed("Hello, World!").pipe(
|
||
* Effect.tap(Console.log)
|
||
* )
|
||
*
|
||
* const program = Effect.gen(function*() {
|
||
* // Replicate the task 3 times
|
||
* const tasks = Effect.replicate(task, 3)
|
||
* for (const t of tasks) {
|
||
* // Run each task
|
||
* yield* t
|
||
* }
|
||
* })
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output:
|
||
* // Hello, World!
|
||
* // Hello, World!
|
||
* // Hello, World!
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
*/
|
||
<A, E, R>(self: Effect<A, E, R>, n: number): Array<Effect<A, E, R>>;
|
||
};
|
||
/**
|
||
* Performs this effect the specified number of times and collects the results.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function repeats an effect multiple times and collects the results into
|
||
* an array. You specify how many times to execute the effect, and it runs that
|
||
* many times, either in sequence or concurrently depending on the provided
|
||
* options.
|
||
*
|
||
* **Options**
|
||
*
|
||
* If the `discard` option is set to `true`, the intermediate results are not
|
||
* collected, and the final result of the operation is `void`.
|
||
*
|
||
* The function also allows you to customize how the effects are handled by
|
||
* specifying options such as concurrency, batching, and how finalizers behave.
|
||
* These options provide flexibility in running the effects concurrently or
|
||
* adjusting other execution details.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Console, Effect } from "effect"
|
||
*
|
||
* let counter = 0
|
||
*
|
||
* const task = Effect.sync(() => ++counter).pipe(
|
||
* Effect.tap(() => Console.log(`Task completed`))
|
||
* )
|
||
*
|
||
* const program = Effect.gen(function*() {
|
||
* // Replicate the task 3 times and collect the results
|
||
* const results = yield* Effect.replicateEffect(task, 3)
|
||
* yield* Console.log(`Results: ${results.join(", ")}`)
|
||
* })
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output:
|
||
* // Task completed
|
||
* // Task completed
|
||
* // Task completed
|
||
* // Results: 1, 2, 3
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Collecting
|
||
*/
|
||
export declare const replicateEffect: {
|
||
/**
|
||
* Performs this effect the specified number of times and collects the results.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function repeats an effect multiple times and collects the results into
|
||
* an array. You specify how many times to execute the effect, and it runs that
|
||
* many times, either in sequence or concurrently depending on the provided
|
||
* options.
|
||
*
|
||
* **Options**
|
||
*
|
||
* If the `discard` option is set to `true`, the intermediate results are not
|
||
* collected, and the final result of the operation is `void`.
|
||
*
|
||
* The function also allows you to customize how the effects are handled by
|
||
* specifying options such as concurrency, batching, and how finalizers behave.
|
||
* These options provide flexibility in running the effects concurrently or
|
||
* adjusting other execution details.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Console, Effect } from "effect"
|
||
*
|
||
* let counter = 0
|
||
*
|
||
* const task = Effect.sync(() => ++counter).pipe(
|
||
* Effect.tap(() => Console.log(`Task completed`))
|
||
* )
|
||
*
|
||
* const program = Effect.gen(function*() {
|
||
* // Replicate the task 3 times and collect the results
|
||
* const results = yield* Effect.replicateEffect(task, 3)
|
||
* yield* Console.log(`Results: ${results.join(", ")}`)
|
||
* })
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output:
|
||
* // Task completed
|
||
* // Task completed
|
||
* // Task completed
|
||
* // Results: 1, 2, 3
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Collecting
|
||
*/
|
||
(n: number, options?: {
|
||
readonly concurrency?: Concurrency | undefined;
|
||
readonly batching?: boolean | "inherit" | undefined;
|
||
readonly discard?: false | undefined;
|
||
readonly concurrentFinalizers?: boolean | undefined;
|
||
}): <A, E, R>(self: Effect<A, E, R>) => Effect<Array<A>, E, R>;
|
||
/**
|
||
* Performs this effect the specified number of times and collects the results.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function repeats an effect multiple times and collects the results into
|
||
* an array. You specify how many times to execute the effect, and it runs that
|
||
* many times, either in sequence or concurrently depending on the provided
|
||
* options.
|
||
*
|
||
* **Options**
|
||
*
|
||
* If the `discard` option is set to `true`, the intermediate results are not
|
||
* collected, and the final result of the operation is `void`.
|
||
*
|
||
* The function also allows you to customize how the effects are handled by
|
||
* specifying options such as concurrency, batching, and how finalizers behave.
|
||
* These options provide flexibility in running the effects concurrently or
|
||
* adjusting other execution details.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Console, Effect } from "effect"
|
||
*
|
||
* let counter = 0
|
||
*
|
||
* const task = Effect.sync(() => ++counter).pipe(
|
||
* Effect.tap(() => Console.log(`Task completed`))
|
||
* )
|
||
*
|
||
* const program = Effect.gen(function*() {
|
||
* // Replicate the task 3 times and collect the results
|
||
* const results = yield* Effect.replicateEffect(task, 3)
|
||
* yield* Console.log(`Results: ${results.join(", ")}`)
|
||
* })
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output:
|
||
* // Task completed
|
||
* // Task completed
|
||
* // Task completed
|
||
* // Results: 1, 2, 3
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Collecting
|
||
*/
|
||
(n: number, options: {
|
||
readonly concurrency?: Concurrency | undefined;
|
||
readonly batching?: boolean | "inherit" | undefined;
|
||
readonly discard: true;
|
||
readonly concurrentFinalizers?: boolean | undefined;
|
||
}): <A, E, R>(self: Effect<A, E, R>) => Effect<void, E, R>;
|
||
/**
|
||
* Performs this effect the specified number of times and collects the results.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function repeats an effect multiple times and collects the results into
|
||
* an array. You specify how many times to execute the effect, and it runs that
|
||
* many times, either in sequence or concurrently depending on the provided
|
||
* options.
|
||
*
|
||
* **Options**
|
||
*
|
||
* If the `discard` option is set to `true`, the intermediate results are not
|
||
* collected, and the final result of the operation is `void`.
|
||
*
|
||
* The function also allows you to customize how the effects are handled by
|
||
* specifying options such as concurrency, batching, and how finalizers behave.
|
||
* These options provide flexibility in running the effects concurrently or
|
||
* adjusting other execution details.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Console, Effect } from "effect"
|
||
*
|
||
* let counter = 0
|
||
*
|
||
* const task = Effect.sync(() => ++counter).pipe(
|
||
* Effect.tap(() => Console.log(`Task completed`))
|
||
* )
|
||
*
|
||
* const program = Effect.gen(function*() {
|
||
* // Replicate the task 3 times and collect the results
|
||
* const results = yield* Effect.replicateEffect(task, 3)
|
||
* yield* Console.log(`Results: ${results.join(", ")}`)
|
||
* })
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output:
|
||
* // Task completed
|
||
* // Task completed
|
||
* // Task completed
|
||
* // Results: 1, 2, 3
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Collecting
|
||
*/
|
||
<A, E, R>(self: Effect<A, E, R>, n: number, options?: {
|
||
readonly concurrency?: Concurrency | undefined;
|
||
readonly batching?: boolean | "inherit" | undefined;
|
||
readonly discard?: false | undefined;
|
||
readonly concurrentFinalizers?: boolean | undefined;
|
||
}): Effect<Array<A>, E, R>;
|
||
/**
|
||
* Performs this effect the specified number of times and collects the results.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function repeats an effect multiple times and collects the results into
|
||
* an array. You specify how many times to execute the effect, and it runs that
|
||
* many times, either in sequence or concurrently depending on the provided
|
||
* options.
|
||
*
|
||
* **Options**
|
||
*
|
||
* If the `discard` option is set to `true`, the intermediate results are not
|
||
* collected, and the final result of the operation is `void`.
|
||
*
|
||
* The function also allows you to customize how the effects are handled by
|
||
* specifying options such as concurrency, batching, and how finalizers behave.
|
||
* These options provide flexibility in running the effects concurrently or
|
||
* adjusting other execution details.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Console, Effect } from "effect"
|
||
*
|
||
* let counter = 0
|
||
*
|
||
* const task = Effect.sync(() => ++counter).pipe(
|
||
* Effect.tap(() => Console.log(`Task completed`))
|
||
* )
|
||
*
|
||
* const program = Effect.gen(function*() {
|
||
* // Replicate the task 3 times and collect the results
|
||
* const results = yield* Effect.replicateEffect(task, 3)
|
||
* yield* Console.log(`Results: ${results.join(", ")}`)
|
||
* })
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output:
|
||
* // Task completed
|
||
* // Task completed
|
||
* // Task completed
|
||
* // Results: 1, 2, 3
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Collecting
|
||
*/
|
||
<A, E, R>(self: Effect<A, E, R>, n: number, options: {
|
||
readonly concurrency?: Concurrency | undefined;
|
||
readonly batching?: boolean | "inherit" | undefined;
|
||
readonly discard: true;
|
||
readonly concurrentFinalizers?: boolean | undefined;
|
||
}): Effect<void, E, R>;
|
||
};
|
||
/**
|
||
* Applies an effectful operation to each element in a collection while
|
||
* collecting both successes and failures.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to apply an effectful operation to every item in a
|
||
* collection.
|
||
*
|
||
* Unlike {@link forEach}, which would stop at the first error, this function
|
||
* continues processing all elements, accumulating both successes and failures.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use this function when you want to process every item in a collection, even
|
||
* if some items fail. This is particularly useful when you need to perform
|
||
* operations on all elements without halting due to an error.
|
||
*
|
||
* Keep in mind that if there are any failures, **all successes will be lost**,
|
||
* so this function is not suitable when you need to keep the successful results
|
||
* in case of errors.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* // ┌─── Effect<number[], [string, ...string[]], never>
|
||
* // ▼
|
||
* const program = Effect.validateAll([1, 2, 3, 4, 5], (n) => {
|
||
* if (n < 4) {
|
||
* return Console.log(`item ${n}`).pipe(Effect.as(n))
|
||
* } else {
|
||
* return Effect.fail(`${n} is not less that 4`)
|
||
* }
|
||
* })
|
||
*
|
||
* Effect.runPromiseExit(program).then(console.log)
|
||
* // Output:
|
||
* // item 1
|
||
* // item 2
|
||
* // item 3
|
||
* // {
|
||
* // _id: 'Exit',
|
||
* // _tag: 'Failure',
|
||
* // cause: {
|
||
* // _id: 'Cause',
|
||
* // _tag: 'Fail',
|
||
* // failure: [ '4 is not less that 4', '5 is not less that 4' ]
|
||
* // }
|
||
* // }
|
||
* ```
|
||
*
|
||
* @see {@link forEach} for a similar function that stops at the first error.
|
||
* @see {@link partition} when you need to separate successes and failures
|
||
* instead of losing successes with errors.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error Accumulation
|
||
*/
|
||
export declare const validateAll: {
|
||
/**
|
||
* Applies an effectful operation to each element in a collection while
|
||
* collecting both successes and failures.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to apply an effectful operation to every item in a
|
||
* collection.
|
||
*
|
||
* Unlike {@link forEach}, which would stop at the first error, this function
|
||
* continues processing all elements, accumulating both successes and failures.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use this function when you want to process every item in a collection, even
|
||
* if some items fail. This is particularly useful when you need to perform
|
||
* operations on all elements without halting due to an error.
|
||
*
|
||
* Keep in mind that if there are any failures, **all successes will be lost**,
|
||
* so this function is not suitable when you need to keep the successful results
|
||
* in case of errors.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* // ┌─── Effect<number[], [string, ...string[]], never>
|
||
* // ▼
|
||
* const program = Effect.validateAll([1, 2, 3, 4, 5], (n) => {
|
||
* if (n < 4) {
|
||
* return Console.log(`item ${n}`).pipe(Effect.as(n))
|
||
* } else {
|
||
* return Effect.fail(`${n} is not less that 4`)
|
||
* }
|
||
* })
|
||
*
|
||
* Effect.runPromiseExit(program).then(console.log)
|
||
* // Output:
|
||
* // item 1
|
||
* // item 2
|
||
* // item 3
|
||
* // {
|
||
* // _id: 'Exit',
|
||
* // _tag: 'Failure',
|
||
* // cause: {
|
||
* // _id: 'Cause',
|
||
* // _tag: 'Fail',
|
||
* // failure: [ '4 is not less that 4', '5 is not less that 4' ]
|
||
* // }
|
||
* // }
|
||
* ```
|
||
*
|
||
* @see {@link forEach} for a similar function that stops at the first error.
|
||
* @see {@link partition} when you need to separate successes and failures
|
||
* instead of losing successes with errors.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error Accumulation
|
||
*/
|
||
<A, B, E, R>(f: (a: A, i: number) => Effect<B, E, R>, options?: {
|
||
readonly concurrency?: Concurrency | undefined;
|
||
readonly batching?: boolean | "inherit" | undefined;
|
||
readonly discard?: false | undefined;
|
||
readonly concurrentFinalizers?: boolean | undefined;
|
||
} | undefined): (elements: Iterable<A>) => Effect<Array<B>, RA.NonEmptyArray<E>, R>;
|
||
/**
|
||
* Applies an effectful operation to each element in a collection while
|
||
* collecting both successes and failures.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to apply an effectful operation to every item in a
|
||
* collection.
|
||
*
|
||
* Unlike {@link forEach}, which would stop at the first error, this function
|
||
* continues processing all elements, accumulating both successes and failures.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use this function when you want to process every item in a collection, even
|
||
* if some items fail. This is particularly useful when you need to perform
|
||
* operations on all elements without halting due to an error.
|
||
*
|
||
* Keep in mind that if there are any failures, **all successes will be lost**,
|
||
* so this function is not suitable when you need to keep the successful results
|
||
* in case of errors.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* // ┌─── Effect<number[], [string, ...string[]], never>
|
||
* // ▼
|
||
* const program = Effect.validateAll([1, 2, 3, 4, 5], (n) => {
|
||
* if (n < 4) {
|
||
* return Console.log(`item ${n}`).pipe(Effect.as(n))
|
||
* } else {
|
||
* return Effect.fail(`${n} is not less that 4`)
|
||
* }
|
||
* })
|
||
*
|
||
* Effect.runPromiseExit(program).then(console.log)
|
||
* // Output:
|
||
* // item 1
|
||
* // item 2
|
||
* // item 3
|
||
* // {
|
||
* // _id: 'Exit',
|
||
* // _tag: 'Failure',
|
||
* // cause: {
|
||
* // _id: 'Cause',
|
||
* // _tag: 'Fail',
|
||
* // failure: [ '4 is not less that 4', '5 is not less that 4' ]
|
||
* // }
|
||
* // }
|
||
* ```
|
||
*
|
||
* @see {@link forEach} for a similar function that stops at the first error.
|
||
* @see {@link partition} when you need to separate successes and failures
|
||
* instead of losing successes with errors.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error Accumulation
|
||
*/
|
||
<A, B, E, R>(f: (a: A, i: number) => Effect<B, E, R>, options: {
|
||
readonly concurrency?: Concurrency | undefined;
|
||
readonly batching?: boolean | "inherit" | undefined;
|
||
readonly discard: true;
|
||
readonly concurrentFinalizers?: boolean | undefined;
|
||
}): (elements: Iterable<A>) => Effect<void, RA.NonEmptyArray<E>, R>;
|
||
/**
|
||
* Applies an effectful operation to each element in a collection while
|
||
* collecting both successes and failures.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to apply an effectful operation to every item in a
|
||
* collection.
|
||
*
|
||
* Unlike {@link forEach}, which would stop at the first error, this function
|
||
* continues processing all elements, accumulating both successes and failures.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use this function when you want to process every item in a collection, even
|
||
* if some items fail. This is particularly useful when you need to perform
|
||
* operations on all elements without halting due to an error.
|
||
*
|
||
* Keep in mind that if there are any failures, **all successes will be lost**,
|
||
* so this function is not suitable when you need to keep the successful results
|
||
* in case of errors.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* // ┌─── Effect<number[], [string, ...string[]], never>
|
||
* // ▼
|
||
* const program = Effect.validateAll([1, 2, 3, 4, 5], (n) => {
|
||
* if (n < 4) {
|
||
* return Console.log(`item ${n}`).pipe(Effect.as(n))
|
||
* } else {
|
||
* return Effect.fail(`${n} is not less that 4`)
|
||
* }
|
||
* })
|
||
*
|
||
* Effect.runPromiseExit(program).then(console.log)
|
||
* // Output:
|
||
* // item 1
|
||
* // item 2
|
||
* // item 3
|
||
* // {
|
||
* // _id: 'Exit',
|
||
* // _tag: 'Failure',
|
||
* // cause: {
|
||
* // _id: 'Cause',
|
||
* // _tag: 'Fail',
|
||
* // failure: [ '4 is not less that 4', '5 is not less that 4' ]
|
||
* // }
|
||
* // }
|
||
* ```
|
||
*
|
||
* @see {@link forEach} for a similar function that stops at the first error.
|
||
* @see {@link partition} when you need to separate successes and failures
|
||
* instead of losing successes with errors.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error Accumulation
|
||
*/
|
||
<A, B, E, R>(elements: Iterable<A>, f: (a: A, i: number) => Effect<B, E, R>, options?: {
|
||
readonly concurrency?: Concurrency | undefined;
|
||
readonly batching?: boolean | "inherit" | undefined;
|
||
readonly discard?: false | undefined;
|
||
readonly concurrentFinalizers?: boolean | undefined;
|
||
} | undefined): Effect<Array<B>, RA.NonEmptyArray<E>, R>;
|
||
/**
|
||
* Applies an effectful operation to each element in a collection while
|
||
* collecting both successes and failures.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to apply an effectful operation to every item in a
|
||
* collection.
|
||
*
|
||
* Unlike {@link forEach}, which would stop at the first error, this function
|
||
* continues processing all elements, accumulating both successes and failures.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use this function when you want to process every item in a collection, even
|
||
* if some items fail. This is particularly useful when you need to perform
|
||
* operations on all elements without halting due to an error.
|
||
*
|
||
* Keep in mind that if there are any failures, **all successes will be lost**,
|
||
* so this function is not suitable when you need to keep the successful results
|
||
* in case of errors.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* // ┌─── Effect<number[], [string, ...string[]], never>
|
||
* // ▼
|
||
* const program = Effect.validateAll([1, 2, 3, 4, 5], (n) => {
|
||
* if (n < 4) {
|
||
* return Console.log(`item ${n}`).pipe(Effect.as(n))
|
||
* } else {
|
||
* return Effect.fail(`${n} is not less that 4`)
|
||
* }
|
||
* })
|
||
*
|
||
* Effect.runPromiseExit(program).then(console.log)
|
||
* // Output:
|
||
* // item 1
|
||
* // item 2
|
||
* // item 3
|
||
* // {
|
||
* // _id: 'Exit',
|
||
* // _tag: 'Failure',
|
||
* // cause: {
|
||
* // _id: 'Cause',
|
||
* // _tag: 'Fail',
|
||
* // failure: [ '4 is not less that 4', '5 is not less that 4' ]
|
||
* // }
|
||
* // }
|
||
* ```
|
||
*
|
||
* @see {@link forEach} for a similar function that stops at the first error.
|
||
* @see {@link partition} when you need to separate successes and failures
|
||
* instead of losing successes with errors.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error Accumulation
|
||
*/
|
||
<A, B, E, R>(elements: Iterable<A>, f: (a: A, i: number) => Effect<B, E, R>, options: {
|
||
readonly concurrency?: Concurrency | undefined;
|
||
readonly batching?: boolean | "inherit" | undefined;
|
||
readonly discard: true;
|
||
readonly concurrentFinalizers?: boolean | undefined;
|
||
}): Effect<void, RA.NonEmptyArray<E>, R>;
|
||
};
|
||
/**
|
||
* This function is similar to {@link validateAll} but with a key difference: it
|
||
* returns the first successful result or all errors if none of the operations
|
||
* succeed.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function processes a collection of elements and applies an effectful
|
||
* operation to each. Unlike {@link validateAll}, which accumulates both
|
||
* successes and failures, `Effect.validateFirst` stops and returns the first
|
||
* success it encounters. If no success occurs, it returns all accumulated
|
||
* errors. This can be useful when you are interested in the first successful
|
||
* result and want to avoid processing further once a valid result is found.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* // ┌─── Effect<number, string[], never>
|
||
* // ▼
|
||
* const program = Effect.validateFirst([1, 2, 3, 4, 5], (n) => {
|
||
* if (n < 4) {
|
||
* return Effect.fail(`${n} is not less that 4`)
|
||
* } else {
|
||
* return Console.log(`item ${n}`).pipe(Effect.as(n))
|
||
* }
|
||
* })
|
||
*
|
||
* Effect.runPromise(program).then(console.log, console.error)
|
||
* // Output:
|
||
* // item 4
|
||
* // 4
|
||
* ```
|
||
*
|
||
* @see {@link validateAll} for a similar function that accumulates all results.
|
||
* @see {@link firstSuccessOf} for a similar function that processes multiple
|
||
* effects and returns the first successful one or the last error.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error Accumulation
|
||
*/
|
||
export declare const validateFirst: {
|
||
/**
|
||
* This function is similar to {@link validateAll} but with a key difference: it
|
||
* returns the first successful result or all errors if none of the operations
|
||
* succeed.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function processes a collection of elements and applies an effectful
|
||
* operation to each. Unlike {@link validateAll}, which accumulates both
|
||
* successes and failures, `Effect.validateFirst` stops and returns the first
|
||
* success it encounters. If no success occurs, it returns all accumulated
|
||
* errors. This can be useful when you are interested in the first successful
|
||
* result and want to avoid processing further once a valid result is found.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* // ┌─── Effect<number, string[], never>
|
||
* // ▼
|
||
* const program = Effect.validateFirst([1, 2, 3, 4, 5], (n) => {
|
||
* if (n < 4) {
|
||
* return Effect.fail(`${n} is not less that 4`)
|
||
* } else {
|
||
* return Console.log(`item ${n}`).pipe(Effect.as(n))
|
||
* }
|
||
* })
|
||
*
|
||
* Effect.runPromise(program).then(console.log, console.error)
|
||
* // Output:
|
||
* // item 4
|
||
* // 4
|
||
* ```
|
||
*
|
||
* @see {@link validateAll} for a similar function that accumulates all results.
|
||
* @see {@link firstSuccessOf} for a similar function that processes multiple
|
||
* effects and returns the first successful one or the last error.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error Accumulation
|
||
*/
|
||
<A, B, E, R>(f: (a: A, i: number) => Effect<B, E, R>, options?: {
|
||
readonly concurrency?: Concurrency | undefined;
|
||
readonly batching?: boolean | "inherit" | undefined;
|
||
readonly concurrentFinalizers?: boolean | undefined;
|
||
} | undefined): (elements: Iterable<A>) => Effect<B, Array<E>, R>;
|
||
/**
|
||
* This function is similar to {@link validateAll} but with a key difference: it
|
||
* returns the first successful result or all errors if none of the operations
|
||
* succeed.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function processes a collection of elements and applies an effectful
|
||
* operation to each. Unlike {@link validateAll}, which accumulates both
|
||
* successes and failures, `Effect.validateFirst` stops and returns the first
|
||
* success it encounters. If no success occurs, it returns all accumulated
|
||
* errors. This can be useful when you are interested in the first successful
|
||
* result and want to avoid processing further once a valid result is found.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* // ┌─── Effect<number, string[], never>
|
||
* // ▼
|
||
* const program = Effect.validateFirst([1, 2, 3, 4, 5], (n) => {
|
||
* if (n < 4) {
|
||
* return Effect.fail(`${n} is not less that 4`)
|
||
* } else {
|
||
* return Console.log(`item ${n}`).pipe(Effect.as(n))
|
||
* }
|
||
* })
|
||
*
|
||
* Effect.runPromise(program).then(console.log, console.error)
|
||
* // Output:
|
||
* // item 4
|
||
* // 4
|
||
* ```
|
||
*
|
||
* @see {@link validateAll} for a similar function that accumulates all results.
|
||
* @see {@link firstSuccessOf} for a similar function that processes multiple
|
||
* effects and returns the first successful one or the last error.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error Accumulation
|
||
*/
|
||
<A, B, E, R>(elements: Iterable<A>, f: (a: A, i: number) => Effect<B, E, R>, options?: {
|
||
readonly concurrency?: Concurrency | undefined;
|
||
readonly batching?: boolean | "inherit" | undefined;
|
||
readonly concurrentFinalizers?: boolean | undefined;
|
||
} | undefined): Effect<B, Array<E>, R>;
|
||
};
|
||
/**
|
||
* Creates an `Effect` from a callback-based asynchronous function.
|
||
*
|
||
* **Details**
|
||
*
|
||
* The `resume` function:
|
||
* - Must be called exactly once. Any additional calls will be ignored.
|
||
* - Can return an optional `Effect` that will be run if the `Fiber` executing
|
||
* this `Effect` is interrupted. This can be useful in scenarios where you
|
||
* need to handle resource cleanup if the operation is interrupted.
|
||
* - Can receive an `AbortSignal` to handle interruption if needed.
|
||
*
|
||
* The `FiberId` of the fiber that may complete the async callback may also be
|
||
* specified using the `blockingOn` argument. This is called the "blocking
|
||
* fiber" because it suspends the fiber executing the `async` effect (i.e.
|
||
* semantically blocks the fiber from making progress). Specifying this fiber id
|
||
* in cases where it is known will improve diagnostics, but not affect the
|
||
* behavior of the returned effect.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use `Effect.async` when dealing with APIs that use callback-style instead of
|
||
* `async/await` or `Promise`.
|
||
*
|
||
* **Example** (Wrapping a Callback API)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
* import * as NodeFS from "node:fs"
|
||
*
|
||
* const readFile = (filename: string) =>
|
||
* Effect.async<Buffer, Error>((resume) => {
|
||
* NodeFS.readFile(filename, (error, data) => {
|
||
* if (error) {
|
||
* // Resume with a failed Effect if an error occurs
|
||
* resume(Effect.fail(error))
|
||
* } else {
|
||
* // Resume with a succeeded Effect if successful
|
||
* resume(Effect.succeed(data))
|
||
* }
|
||
* })
|
||
* })
|
||
*
|
||
* // ┌─── Effect<Buffer, Error, never>
|
||
* // ▼
|
||
* const program = readFile("example.txt")
|
||
* ```
|
||
*
|
||
* **Example** (Handling Interruption with Cleanup)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Fiber } from "effect"
|
||
* import * as NodeFS from "node:fs"
|
||
*
|
||
* // Simulates a long-running operation to write to a file
|
||
* const writeFileWithCleanup = (filename: string, data: string) =>
|
||
* Effect.async<void, Error>((resume) => {
|
||
* const writeStream = NodeFS.createWriteStream(filename)
|
||
*
|
||
* // Start writing data to the file
|
||
* writeStream.write(data)
|
||
*
|
||
* // When the stream is finished, resume with success
|
||
* writeStream.on("finish", () => resume(Effect.void))
|
||
*
|
||
* // In case of an error during writing, resume with failure
|
||
* writeStream.on("error", (err) => resume(Effect.fail(err)))
|
||
*
|
||
* // Handle interruption by returning a cleanup effect
|
||
* return Effect.sync(() => {
|
||
* console.log(`Cleaning up ${filename}`)
|
||
* NodeFS.unlinkSync(filename)
|
||
* })
|
||
* })
|
||
*
|
||
* const program = Effect.gen(function* () {
|
||
* const fiber = yield* Effect.fork(
|
||
* writeFileWithCleanup("example.txt", "Some long data...")
|
||
* )
|
||
* // Simulate interrupting the fiber after 1 second
|
||
* yield* Effect.sleep("1 second")
|
||
* yield* Fiber.interrupt(fiber) // This will trigger the cleanup
|
||
* })
|
||
*
|
||
* // Run the program
|
||
* Effect.runPromise(program)
|
||
* // Output:
|
||
* // Cleaning up example.txt
|
||
* ```
|
||
*
|
||
* **Example** (Handling Interruption with AbortSignal)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Fiber } from "effect"
|
||
*
|
||
* // A task that supports interruption using AbortSignal
|
||
* const interruptibleTask = Effect.async<void, Error>((resume, signal) => {
|
||
* // Handle interruption
|
||
* signal.addEventListener("abort", () => {
|
||
* console.log("Abort signal received")
|
||
* clearTimeout(timeoutId)
|
||
* })
|
||
*
|
||
* // Simulate a long-running task
|
||
* const timeoutId = setTimeout(() => {
|
||
* console.log("Operation completed")
|
||
* resume(Effect.void)
|
||
* }, 2000)
|
||
* })
|
||
*
|
||
* const program = Effect.gen(function* () {
|
||
* const fiber = yield* Effect.fork(interruptibleTask)
|
||
* // Simulate interrupting the fiber after 1 second
|
||
* yield* Effect.sleep("1 second")
|
||
* yield* Fiber.interrupt(fiber)
|
||
* })
|
||
*
|
||
* // Run the program
|
||
* Effect.runPromise(program)
|
||
* // Output:
|
||
* // Abort signal received
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Creating Effects
|
||
*/
|
||
export declare const async: <A, E = never, R = never>(resume: (callback: (_: Effect<A, E, R>) => void, signal: AbortSignal) => void | Effect<void, never, R>, blockingOn?: FiberId.FiberId) => Effect<A, E, R>;
|
||
/**
|
||
* A variant of {@link async} where the registration function may return an `Effect`.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Creating Effects
|
||
*/
|
||
export declare const asyncEffect: <A, E, R, R3, E2, R2>(register: (callback: (_: Effect<A, E, R>) => void) => Effect<Effect<void, never, R3> | void, E2, R2>) => Effect<A, E | E2, R | R2 | R3>;
|
||
/**
|
||
* Low level constructor that enables for custom stack tracing cutpoints.
|
||
*
|
||
* It is meant to be called with a bag of instructions that become available in
|
||
* the "this" of the effect.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const throwingFunction = () => { throw new Error() }
|
||
* const blowUp = Effect.custom(throwingFunction, function() {
|
||
* return Effect.succeed(this.effect_instruction_i0())
|
||
* })
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Creating Effects
|
||
*/
|
||
export declare const custom: {
|
||
/**
|
||
* Low level constructor that enables for custom stack tracing cutpoints.
|
||
*
|
||
* It is meant to be called with a bag of instructions that become available in
|
||
* the "this" of the effect.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const throwingFunction = () => { throw new Error() }
|
||
* const blowUp = Effect.custom(throwingFunction, function() {
|
||
* return Effect.succeed(this.effect_instruction_i0())
|
||
* })
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Creating Effects
|
||
*/
|
||
<X, A, E, R>(i0: X, body: (this: {
|
||
effect_instruction_i0: X;
|
||
}) => Effect<A, E, R>): Effect<A, E, R>;
|
||
/**
|
||
* Low level constructor that enables for custom stack tracing cutpoints.
|
||
*
|
||
* It is meant to be called with a bag of instructions that become available in
|
||
* the "this" of the effect.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const throwingFunction = () => { throw new Error() }
|
||
* const blowUp = Effect.custom(throwingFunction, function() {
|
||
* return Effect.succeed(this.effect_instruction_i0())
|
||
* })
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Creating Effects
|
||
*/
|
||
<X, Y, A, E, R>(i0: X, i1: Y, body: (this: {
|
||
effect_instruction_i0: X;
|
||
effect_instruction_i1: Y;
|
||
}) => Effect<A, E, R>): Effect<A, E, R>;
|
||
/**
|
||
* Low level constructor that enables for custom stack tracing cutpoints.
|
||
*
|
||
* It is meant to be called with a bag of instructions that become available in
|
||
* the "this" of the effect.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const throwingFunction = () => { throw new Error() }
|
||
* const blowUp = Effect.custom(throwingFunction, function() {
|
||
* return Effect.succeed(this.effect_instruction_i0())
|
||
* })
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Creating Effects
|
||
*/
|
||
<X, Y, Z, A, E, R>(i0: X, i1: Y, i2: Z, body: (this: {
|
||
effect_instruction_i0: X;
|
||
effect_instruction_i1: Y;
|
||
effect_instruction_i2: Z;
|
||
}) => Effect<A, E, R>): Effect<A, E, R>;
|
||
};
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Creating Effects
|
||
*/
|
||
export declare const withFiberRuntime: <A, E = never, R = never>(withRuntime: (fiber: Fiber.RuntimeFiber<A, E>, status: FiberStatus.Running) => Effect<A, E, R>) => Effect<A, E, R>;
|
||
/**
|
||
* Creates an `Effect` that represents a recoverable error.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use this function to explicitly signal an error in an `Effect`. The error
|
||
* will keep propagating unless it is handled. You can handle the error with
|
||
* functions like {@link catchAll} or {@link catchTag}.
|
||
*
|
||
* **Example** (Creating a Failed Effect)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* // ┌─── Effect<never, Error, never>
|
||
* // ▼
|
||
* const failure = Effect.fail(
|
||
* new Error("Operation failed due to network error")
|
||
* )
|
||
* ```
|
||
*
|
||
* @see {@link succeed} to create an effect that represents a successful value.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Creating Effects
|
||
*/
|
||
export declare const fail: <E>(error: E) => Effect<never, E>;
|
||
/**
|
||
* Creates an `Effect` that fails with the specified error, evaluated lazily.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Creating Effects
|
||
*/
|
||
export declare const failSync: <E>(evaluate: LazyArg<E>) => Effect<never, E>;
|
||
/**
|
||
* Creates an `Effect` that fails with the specified `Cause`.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Creating Effects
|
||
*/
|
||
export declare const failCause: <E>(cause: Cause.Cause<E>) => Effect<never, E>;
|
||
/**
|
||
* Creates an `Effect` that fails with the specified `Cause`, evaluated lazily.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Creating Effects
|
||
*/
|
||
export declare const failCauseSync: <E>(evaluate: LazyArg<Cause.Cause<E>>) => Effect<never, E>;
|
||
/**
|
||
* Creates an effect that terminates a fiber with a specified error.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function is used to signal a defect, which represents a critical and
|
||
* unexpected error in the code. When invoked, it produces an effect that does
|
||
* not handle the error and instead terminates the fiber.
|
||
*
|
||
* The error channel of the resulting effect is of type `never`, indicating that
|
||
* it cannot recover from this failure.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use this function when encountering unexpected conditions in your code that
|
||
* should not be handled as regular errors but instead represent unrecoverable
|
||
* defects.
|
||
*
|
||
* **Example** (Terminating on Division by Zero with a Specified Error)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const divide = (a: number, b: number) =>
|
||
* b === 0
|
||
* ? Effect.die(new Error("Cannot divide by zero"))
|
||
* : Effect.succeed(a / b)
|
||
*
|
||
* // ┌─── Effect<number, never, never>
|
||
* // ▼
|
||
* const program = divide(1, 0)
|
||
*
|
||
* Effect.runPromise(program).catch(console.error)
|
||
* // Output:
|
||
* // (FiberFailure) Error: Cannot divide by zero
|
||
* // ...stack trace...
|
||
* ```
|
||
*
|
||
* @see {@link dieSync} for a variant that throws a specified error, evaluated
|
||
* lazily.
|
||
* @see {@link dieMessage} for a variant that throws a `RuntimeException` with a
|
||
* message.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Creating Effects
|
||
*/
|
||
export declare const die: (defect: unknown) => Effect<never>;
|
||
/**
|
||
* Creates an effect that terminates a fiber with a `RuntimeException`
|
||
* containing the specified message.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function is used to signal a defect, representing a critical and
|
||
* unexpected error in the code. When invoked, it produces an effect that
|
||
* terminates the fiber with a `RuntimeException` carrying the given message.
|
||
*
|
||
* The resulting effect has an error channel of type `never`, indicating it does
|
||
* not handle or recover from the error.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use this function when you want to terminate a fiber due to an unrecoverable
|
||
* defect and include a clear explanation in the message.
|
||
*
|
||
* **Example** (Terminating on Division by Zero with a Specified Message)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const divide = (a: number, b: number) =>
|
||
* b === 0
|
||
* ? Effect.dieMessage("Cannot divide by zero")
|
||
* : Effect.succeed(a / b)
|
||
*
|
||
* // ┌─── Effect<number, never, never>
|
||
* // ▼
|
||
* const program = divide(1, 0)
|
||
*
|
||
* Effect.runPromise(program).catch(console.error)
|
||
* // Output:
|
||
* // (FiberFailure) RuntimeException: Cannot divide by zero
|
||
* // ...stack trace...
|
||
* ```
|
||
*
|
||
* @see {@link die} for a variant that throws a specified error.
|
||
* @see {@link dieSync} for a variant that throws a specified error, evaluated
|
||
* lazily.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Creating Effects
|
||
*/
|
||
export declare const dieMessage: (message: string) => Effect<never>;
|
||
/**
|
||
* Creates an effect that dies with the specified error, evaluated lazily.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to create an effect that will terminate with a fatal error.
|
||
* The error is provided as a lazy argument, meaning it will only be evaluated when the effect runs.
|
||
*
|
||
* @see {@link die} if you don't need to evaluate the error lazily.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Creating Effects
|
||
*/
|
||
export declare const dieSync: (evaluate: LazyArg<unknown>) => Effect<never>;
|
||
/**
|
||
* Provides a way to write effectful code using generator functions, simplifying
|
||
* control flow and error handling.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* `Effect.gen` allows you to write code that looks and behaves like synchronous
|
||
* code, but it can handle asynchronous tasks, errors, and complex control flow
|
||
* (like loops and conditions). It helps make asynchronous code more readable
|
||
* and easier to manage.
|
||
*
|
||
* The generator functions work similarly to `async/await` but with more
|
||
* explicit control over the execution of effects. You can `yield*` values from
|
||
* effects and return the final result at the end.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const addServiceCharge = (amount: number) => amount + 1
|
||
*
|
||
* const applyDiscount = (
|
||
* total: number,
|
||
* discountRate: number
|
||
* ): Effect.Effect<number, Error> =>
|
||
* discountRate === 0
|
||
* ? Effect.fail(new Error("Discount rate cannot be zero"))
|
||
* : Effect.succeed(total - (total * discountRate) / 100)
|
||
*
|
||
* const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
|
||
*
|
||
* const fetchDiscountRate = Effect.promise(() => Promise.resolve(5))
|
||
*
|
||
* export const program = Effect.gen(function* () {
|
||
* const transactionAmount = yield* fetchTransactionAmount
|
||
* const discountRate = yield* fetchDiscountRate
|
||
* const discountedAmount = yield* applyDiscount(
|
||
* transactionAmount,
|
||
* discountRate
|
||
* )
|
||
* const finalAmount = addServiceCharge(discountedAmount)
|
||
* return `Final amount to charge: ${finalAmount}`
|
||
* })
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Creating Effects
|
||
*/
|
||
export declare const gen: {
|
||
/**
|
||
* Provides a way to write effectful code using generator functions, simplifying
|
||
* control flow and error handling.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* `Effect.gen` allows you to write code that looks and behaves like synchronous
|
||
* code, but it can handle asynchronous tasks, errors, and complex control flow
|
||
* (like loops and conditions). It helps make asynchronous code more readable
|
||
* and easier to manage.
|
||
*
|
||
* The generator functions work similarly to `async/await` but with more
|
||
* explicit control over the execution of effects. You can `yield*` values from
|
||
* effects and return the final result at the end.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const addServiceCharge = (amount: number) => amount + 1
|
||
*
|
||
* const applyDiscount = (
|
||
* total: number,
|
||
* discountRate: number
|
||
* ): Effect.Effect<number, Error> =>
|
||
* discountRate === 0
|
||
* ? Effect.fail(new Error("Discount rate cannot be zero"))
|
||
* : Effect.succeed(total - (total * discountRate) / 100)
|
||
*
|
||
* const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
|
||
*
|
||
* const fetchDiscountRate = Effect.promise(() => Promise.resolve(5))
|
||
*
|
||
* export const program = Effect.gen(function* () {
|
||
* const transactionAmount = yield* fetchTransactionAmount
|
||
* const discountRate = yield* fetchDiscountRate
|
||
* const discountedAmount = yield* applyDiscount(
|
||
* transactionAmount,
|
||
* discountRate
|
||
* )
|
||
* const finalAmount = addServiceCharge(discountedAmount)
|
||
* return `Final amount to charge: ${finalAmount}`
|
||
* })
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Creating Effects
|
||
*/
|
||
<Eff extends YieldWrap<Effect<any, any, any>>, AEff>(f: (resume: Adapter) => Generator<Eff, AEff, never>): Effect<AEff, [
|
||
Eff
|
||
] extends [never] ? never : [Eff] extends [YieldWrap<Effect<infer _A, infer E, infer _R>>] ? E : never, [
|
||
Eff
|
||
] extends [never] ? never : [Eff] extends [YieldWrap<Effect<infer _A, infer _E, infer R>>] ? R : never>;
|
||
/**
|
||
* Provides a way to write effectful code using generator functions, simplifying
|
||
* control flow and error handling.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* `Effect.gen` allows you to write code that looks and behaves like synchronous
|
||
* code, but it can handle asynchronous tasks, errors, and complex control flow
|
||
* (like loops and conditions). It helps make asynchronous code more readable
|
||
* and easier to manage.
|
||
*
|
||
* The generator functions work similarly to `async/await` but with more
|
||
* explicit control over the execution of effects. You can `yield*` values from
|
||
* effects and return the final result at the end.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const addServiceCharge = (amount: number) => amount + 1
|
||
*
|
||
* const applyDiscount = (
|
||
* total: number,
|
||
* discountRate: number
|
||
* ): Effect.Effect<number, Error> =>
|
||
* discountRate === 0
|
||
* ? Effect.fail(new Error("Discount rate cannot be zero"))
|
||
* : Effect.succeed(total - (total * discountRate) / 100)
|
||
*
|
||
* const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
|
||
*
|
||
* const fetchDiscountRate = Effect.promise(() => Promise.resolve(5))
|
||
*
|
||
* export const program = Effect.gen(function* () {
|
||
* const transactionAmount = yield* fetchTransactionAmount
|
||
* const discountRate = yield* fetchDiscountRate
|
||
* const discountedAmount = yield* applyDiscount(
|
||
* transactionAmount,
|
||
* discountRate
|
||
* )
|
||
* const finalAmount = addServiceCharge(discountedAmount)
|
||
* return `Final amount to charge: ${finalAmount}`
|
||
* })
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Creating Effects
|
||
*/
|
||
<Self, Eff extends YieldWrap<Effect<any, any, any>>, AEff>(self: Self, f: (this: Self, resume: Adapter) => Generator<Eff, AEff, never>): Effect<AEff, [
|
||
Eff
|
||
] extends [never] ? never : [Eff] extends [YieldWrap<Effect<infer _A, infer E, infer _R>>] ? E : never, [
|
||
Eff
|
||
] extends [never] ? never : [Eff] extends [YieldWrap<Effect<infer _A, infer _E, infer R>>] ? R : never>;
|
||
};
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Models
|
||
*/
|
||
export interface Adapter {
|
||
<A, E, R>(self: Effect<A, E, R>): Effect<A, E, R>;
|
||
<A, _A, _E, _R>(a: A, ab: (a: A) => Effect<_A, _E, _R>): Effect<_A, _E, _R>;
|
||
<A, B, _A, _E, _R>(a: A, ab: (a: A) => B, bc: (b: B) => Effect<_A, _E, _R>): Effect<_A, _E, _R>;
|
||
<A, B, C, _A, _E, _R>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => Effect<_A, _E, _R>): Effect<_A, _E, _R>;
|
||
<A, B, C, D, _A, _E, _R>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => Effect<_A, _E, _R>): Effect<_A, _E, _R>;
|
||
<A, B, C, D, E, _A, _E, _R>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => Effect<_A, _E, _R>): Effect<_A, _E, _R>;
|
||
<A, B, C, D, E, F, _A, _E, _R>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => Effect<_A, _E, _R>): Effect<_A, _E, _R>;
|
||
<A, B, C, D, E, F, G, _A, _E, _R>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => Effect<_A, _E, _R>): Effect<_A, _E, _R>;
|
||
<A, B, C, D, E, F, G, H, _A, _E, _R>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (g: H) => Effect<_A, _E, _R>): Effect<_A, _E, _R>;
|
||
<A, B, C, D, E, F, G, H, I, _A, _E, _R>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => Effect<_A, _E, _R>): Effect<_A, _E, _R>;
|
||
<A, B, C, D, E, F, G, H, I, J, _A, _E, _R>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => Effect<_A, _E, _R>): Effect<_A, _E, _R>;
|
||
<A, B, C, D, E, F, G, H, I, J, K, _A, _E, _R>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => K, kl: (k: K) => Effect<_A, _E, _R>): Effect<_A, _E, _R>;
|
||
<A, B, C, D, E, F, G, H, I, J, K, L, _A, _E, _R>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => K, kl: (k: K) => L, lm: (l: L) => Effect<_A, _E, _R>): Effect<_A, _E, _R>;
|
||
<A, B, C, D, E, F, G, H, I, J, K, L, M, _A, _E, _R>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => K, kl: (k: K) => L, lm: (l: L) => M, mn: (m: M) => Effect<_A, _E, _R>): Effect<_A, _E, _R>;
|
||
<A, B, C, D, E, F, G, H, I, J, K, L, M, N, _A, _E, _R>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => K, kl: (k: K) => L, lm: (l: L) => M, mn: (m: M) => N, no: (n: N) => Effect<_A, _E, _R>): Effect<_A, _E, _R>;
|
||
<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, _A, _E, _R>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => K, kl: (k: K) => L, lm: (l: L) => M, mn: (m: M) => N, no: (n: N) => O, op: (o: O) => Effect<_A, _E, _R>): Effect<_A, _E, _R>;
|
||
<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, _A, _E, _R>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => K, kl: (k: K) => L, lm: (l: L) => M, mn: (m: M) => N, no: (n: N) => O, op: (o: O) => P, pq: (p: P) => Effect<_A, _E, _R>): Effect<_A, _E, _R>;
|
||
<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, _A, _E, _R>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => K, kl: (k: K) => L, lm: (l: L) => M, mn: (m: M) => N, no: (n: N) => O, op: (o: O) => P, pq: (p: P) => Q, qr: (q: Q) => Effect<_A, _E, _R>): Effect<_A, _E, _R>;
|
||
<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, _A, _E, _R>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => K, kl: (k: K) => L, lm: (l: L) => M, mn: (m: M) => N, no: (n: N) => O, op: (o: O) => P, pq: (p: P) => Q, qr: (q: Q) => R, rs: (r: R) => Effect<_A, _E, _R>): Effect<_A, _E, _R>;
|
||
<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, _A, _E, _R>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => K, kl: (k: K) => L, lm: (l: L) => M, mn: (m: M) => N, no: (n: N) => O, op: (o: O) => P, pq: (p: P) => Q, qr: (q: Q) => R, rs: (r: R) => S, st: (s: S) => Effect<_A, _E, _R>): Effect<_A, _E, _R>;
|
||
<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, _A, _E, _R>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => K, kl: (k: K) => L, lm: (l: L) => M, mn: (m: M) => N, no: (n: N) => O, op: (o: O) => P, pq: (p: P) => Q, qr: (q: Q) => R, rs: (r: R) => S, st: (s: S) => T, tu: (s: T) => Effect<_A, _E, _R>): Effect<_A, _E, _R>;
|
||
}
|
||
/**
|
||
* An effect that that runs indefinitely and never produces any result. The
|
||
* moral equivalent of `while(true) {}`, only without the wasted CPU cycles.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* It could be useful for long-running background tasks or to simulate waiting
|
||
* behavior without actually consuming resources. This effect is ideal for cases
|
||
* where you want to keep the program alive or in a certain state without
|
||
* performing any active work.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Creating Effects
|
||
*/
|
||
export declare const never: Effect<never>;
|
||
/**
|
||
* Ensures the `Option` is `None`, returning `void`. Otherwise, raises a
|
||
* `NoSuchElementException`.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function checks if the provided `Option` is `None`. If it is, it returns
|
||
* an effect that produces no result (i.e., `void`). If the `Option` is not
|
||
* `None` (i.e., it contains a value), the function will raise a
|
||
* `NoSuchElementException` error.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is useful when you want to ensure that a certain value is absent (i.e.,
|
||
* `None`) before continuing execution, and to handle cases where the value is
|
||
* unexpectedly present.
|
||
*
|
||
* @since 2.0.0
|
||
*/
|
||
export declare const none: <A, E, R>(self: Effect<Option.Option<A>, E, R>) => Effect<void, E | Cause.NoSuchElementException, R>;
|
||
/**
|
||
* Creates an `Effect` that represents an asynchronous computation guaranteed to
|
||
* succeed.
|
||
*
|
||
* **Details**
|
||
*
|
||
* The provided function (`thunk`) returns a `Promise` that should never reject; if it does, the error
|
||
* will be treated as a "defect".
|
||
*
|
||
* This defect is not a standard error but indicates a flaw in the logic that
|
||
* was expected to be error-free. You can think of it similar to an unexpected
|
||
* crash in the program, which can be further managed or logged using tools like
|
||
* {@link catchAllDefect}.
|
||
*
|
||
* **Interruptions**
|
||
*
|
||
* An optional `AbortSignal` can be provided to allow for interruption of the
|
||
* wrapped `Promise` API.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use this function when you are sure the operation will not reject.
|
||
*
|
||
* **Example** (Delayed Message)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const delay = (message: string) =>
|
||
* Effect.promise<string>(
|
||
* () =>
|
||
* new Promise((resolve) => {
|
||
* setTimeout(() => {
|
||
* resolve(message)
|
||
* }, 2000)
|
||
* })
|
||
* )
|
||
*
|
||
* // ┌─── Effect<string, never, never>
|
||
* // ▼
|
||
* const program = delay("Async operation completed successfully!")
|
||
* ```
|
||
*
|
||
* @see {@link tryPromise} for a version that can handle failures.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Creating Effects
|
||
*/
|
||
export declare const promise: <A>(evaluate: (signal: AbortSignal) => PromiseLike<A>) => Effect<A>;
|
||
/**
|
||
* Creates an `Effect` that always succeeds with a given value.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use this function when you need an effect that completes successfully with a
|
||
* specific value without any errors or external dependencies.
|
||
*
|
||
* **Example** (Creating a Successful Effect)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* // Creating an effect that represents a successful scenario
|
||
* //
|
||
* // ┌─── Effect<number, never, never>
|
||
* // ▼
|
||
* const success = Effect.succeed(42)
|
||
* ```
|
||
*
|
||
* @see {@link fail} to create an effect that represents a failure.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Creating Effects
|
||
*/
|
||
export declare const succeed: <A>(value: A) => Effect<A>;
|
||
/**
|
||
* Returns an effect which succeeds with `None`.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use this function when you need to represent the absence of a value in your
|
||
* code, especially when working with optional data. This can be helpful when
|
||
* you want to indicate that no result is available without throwing an error or
|
||
* performing additional logic.
|
||
*
|
||
* @see {@link succeedSome} to create an effect that succeeds with a `Some` value.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Creating Effects
|
||
*/
|
||
export declare const succeedNone: Effect<Option.Option<never>>;
|
||
/**
|
||
* Returns an effect which succeeds with the value wrapped in a `Some`.
|
||
*
|
||
* @see {@link succeedNone} for a similar function that returns `None` when the value is absent.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Creating Effects
|
||
*/
|
||
export declare const succeedSome: <A>(value: A) => Effect<Option.Option<A>>;
|
||
/**
|
||
* Delays the creation of an `Effect` until it is actually needed.
|
||
*
|
||
* **Details**
|
||
*
|
||
* The `Effect.suspend` function takes a thunk that represents the effect and
|
||
* wraps it in a suspended effect. This means the effect will not be created
|
||
* until it is explicitly needed, which is helpful in various scenarios:
|
||
* - **Lazy Evaluation**: Helps optimize performance by deferring computations,
|
||
* especially when the effect might not be needed, or when its computation is
|
||
* expensive. This also ensures that any side effects or scoped captures are
|
||
* re-executed on each invocation.
|
||
* - **Handling Circular Dependencies**: Useful in managing circular
|
||
* dependencies, such as recursive functions that need to avoid eager
|
||
* evaluation to prevent stack overflow.
|
||
* - **Unifying Return Types**: Can help TypeScript unify return types in
|
||
* situations where multiple branches of logic return different effects,
|
||
* simplifying type inference.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use this function when you need to defer the evaluation of an effect until it
|
||
* is required. This is particularly useful for optimizing expensive
|
||
* computations, managing circular dependencies, or resolving type inference
|
||
* issues.
|
||
*
|
||
* **Example** (Lazy Evaluation with Side Effects)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* let i = 0
|
||
*
|
||
* const bad = Effect.succeed(i++)
|
||
*
|
||
* const good = Effect.suspend(() => Effect.succeed(i++))
|
||
*
|
||
* console.log(Effect.runSync(bad)) // Output: 0
|
||
* console.log(Effect.runSync(bad)) // Output: 0
|
||
*
|
||
* console.log(Effect.runSync(good)) // Output: 1
|
||
* console.log(Effect.runSync(good)) // Output: 2
|
||
* ```
|
||
*
|
||
* **Example** (Recursive Fibonacci)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const blowsUp = (n: number): Effect.Effect<number> =>
|
||
* n < 2
|
||
* ? Effect.succeed(1)
|
||
* : Effect.zipWith(blowsUp(n - 1), blowsUp(n - 2), (a, b) => a + b)
|
||
*
|
||
* console.log(Effect.runSync(blowsUp(32)))
|
||
* // crash: JavaScript heap out of memory
|
||
*
|
||
* const allGood = (n: number): Effect.Effect<number> =>
|
||
* n < 2
|
||
* ? Effect.succeed(1)
|
||
* : Effect.zipWith(
|
||
* Effect.suspend(() => allGood(n - 1)),
|
||
* Effect.suspend(() => allGood(n - 2)),
|
||
* (a, b) => a + b
|
||
* )
|
||
*
|
||
* console.log(Effect.runSync(allGood(32)))
|
||
* // Output: 3524578
|
||
* ```
|
||
*
|
||
* **Example** (Using Effect.suspend to Help TypeScript Infer Types)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* // Without suspend, TypeScript may struggle with type inference.
|
||
* // Inferred type:
|
||
* // (a: number, b: number) =>
|
||
* // Effect<never, Error, never> | Effect<number, never, never>
|
||
* const withoutSuspend = (a: number, b: number) =>
|
||
* b === 0
|
||
* ? Effect.fail(new Error("Cannot divide by zero"))
|
||
* : Effect.succeed(a / b)
|
||
*
|
||
* // Using suspend to unify return types.
|
||
* // Inferred type:
|
||
* // (a: number, b: number) => Effect<number, Error, never>
|
||
* const withSuspend = (a: number, b: number) =>
|
||
* Effect.suspend(() =>
|
||
* b === 0
|
||
* ? Effect.fail(new Error("Cannot divide by zero"))
|
||
* : Effect.succeed(a / b)
|
||
* )
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Creating Effects
|
||
*/
|
||
export declare const suspend: <A, E, R>(effect: LazyArg<Effect<A, E, R>>) => Effect<A, E, R>;
|
||
/**
|
||
* Creates an `Effect` that represents a synchronous side-effectful computation.
|
||
*
|
||
* **Details**
|
||
*
|
||
* The provided function (`thunk`) must not throw errors; if it does, the error
|
||
* will be treated as a "defect".
|
||
*
|
||
* This defect is not a standard error but indicates a flaw in the logic that
|
||
* was expected to be error-free. You can think of it similar to an unexpected
|
||
* crash in the program, which can be further managed or logged using tools like
|
||
* {@link catchAllDefect}.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use this function when you are sure the operation will not fail.
|
||
*
|
||
* **Example** (Logging a Message)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const log = (message: string) =>
|
||
* Effect.sync(() => {
|
||
* console.log(message) // side effect
|
||
* })
|
||
*
|
||
* // ┌─── Effect<void, never, never>
|
||
* // ▼
|
||
* const program = log("Hello, World!")
|
||
* ```
|
||
*
|
||
* @see {@link try_ | try} for a version that can handle failures.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Creating Effects
|
||
*/
|
||
export declare const sync: <A>(thunk: LazyArg<A>) => Effect<A>;
|
||
declare const _void: Effect<void>;
|
||
export {
|
||
/**
|
||
* Represents an effect that does nothing and produces no value.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use this effect when you need to represent an effect that does nothing.
|
||
* This is useful in scenarios where you need to satisfy an effect-based
|
||
* interface or control program flow without performing any operations. For
|
||
* example, it can be used in situations where you want to return an effect
|
||
* from a function but do not need to compute or return any result.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Creating Effects
|
||
*/
|
||
_void as void };
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Creating Effects
|
||
*/
|
||
export declare const yieldNow: (options?: {
|
||
readonly priority?: number | undefined;
|
||
}) => Effect<void>;
|
||
declare const _catch: {
|
||
<N extends keyof E, K extends E[N] & string, E, A1, E1, R1>(discriminator: N, options: {
|
||
readonly failure: K;
|
||
readonly onFailure: (error: Extract<E, {
|
||
[n in N]: K;
|
||
}>) => Effect<A1, E1, R1>;
|
||
}): <A, R>(self: Effect<A, E, R>) => Effect<A1 | A, E1 | Exclude<E, {
|
||
[n in N]: K;
|
||
}>, R1 | R>;
|
||
<A, E, R, N extends keyof E, K extends E[N] & string, A1, E1, R1>(self: Effect<A, E, R>, discriminator: N, options: {
|
||
readonly failure: K;
|
||
readonly onFailure: (error: Extract<E, {
|
||
[n in N]: K;
|
||
}>) => Effect<A1, E1, R1>;
|
||
}): Effect<A | A1, E1 | Exclude<E, {
|
||
[n in N]: K;
|
||
}>, R | R1>;
|
||
};
|
||
export {
|
||
/**
|
||
* Recovers from a specified error by catching it and handling it with a provided function.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to recover from specific errors that occur during
|
||
* the execution of an effect. It works by catching a specific type of error
|
||
* (identified by a discriminator) and then handling it using a provided
|
||
* handler function. The handler can return a new effect that helps recover
|
||
* from the error, allowing the program to continue. If the error doesn't
|
||
* match the specified type, the function allows the original effect to
|
||
* continue as it was.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Console, Effect } from "effect"
|
||
*
|
||
* class NetworkError {
|
||
* readonly _tag = "NetworkError"
|
||
* }
|
||
* class ValidationError {
|
||
* readonly _tag = "ValidationError"
|
||
* }
|
||
*
|
||
* // Simulate an effect that may fail
|
||
* const task: Effect.Effect<never, NetworkError | ValidationError, never> = Effect.fail(new NetworkError())
|
||
*
|
||
* const program = Effect.gen(function*() {
|
||
* const result = yield* Effect.catch(task, "_tag", {
|
||
* failure: "NetworkError",
|
||
* onFailure: (error) => Effect.succeed(`recovered from error: ${error._tag}`)
|
||
* })
|
||
* console.log(`Result: ${result}`)
|
||
* })
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output: Result: recovered from error: NetworkError
|
||
* ```
|
||
*
|
||
* @see {@link catchTag} for a version that can recover from errors based on a `_tag` discriminator.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error handling
|
||
*/
|
||
_catch as catch };
|
||
/**
|
||
* Handles all errors in an effect by providing a fallback effect.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function catches any errors that may occur during the execution of an
|
||
* effect and allows you to handle them by specifying a fallback effect. This
|
||
* ensures that the program continues without failing by recovering from errors
|
||
* using the provided fallback logic.
|
||
*
|
||
* **Note**: This function only handles recoverable errors. It will not recover
|
||
* from unrecoverable defects.
|
||
*
|
||
* **Example** (Providing Recovery Logic for Recoverable Errors)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Random } from "effect"
|
||
*
|
||
* class HttpError {
|
||
* readonly _tag = "HttpError"
|
||
* }
|
||
*
|
||
* class ValidationError {
|
||
* readonly _tag = "ValidationError"
|
||
* }
|
||
*
|
||
* // ┌─── Effect<string, HttpError | ValidationError, never>
|
||
* // ▼
|
||
* const program = Effect.gen(function* () {
|
||
* const n1 = yield* Random.next
|
||
* const n2 = yield* Random.next
|
||
* if (n1 < 0.5) {
|
||
* yield* Effect.fail(new HttpError())
|
||
* }
|
||
* if (n2 < 0.5) {
|
||
* yield* Effect.fail(new ValidationError())
|
||
* }
|
||
* return "some result"
|
||
* })
|
||
*
|
||
* // ┌─── Effect<string, never, never>
|
||
* // ▼
|
||
* const recovered = program.pipe(
|
||
* Effect.catchAll((error) =>
|
||
* Effect.succeed(`Recovering from ${error._tag}`)
|
||
* )
|
||
* )
|
||
* ```
|
||
*
|
||
* @see {@link catchAllCause} for a version that can recover from both
|
||
* recoverable and unrecoverable errors.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error handling
|
||
*/
|
||
export declare const catchAll: {
|
||
/**
|
||
* Handles all errors in an effect by providing a fallback effect.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function catches any errors that may occur during the execution of an
|
||
* effect and allows you to handle them by specifying a fallback effect. This
|
||
* ensures that the program continues without failing by recovering from errors
|
||
* using the provided fallback logic.
|
||
*
|
||
* **Note**: This function only handles recoverable errors. It will not recover
|
||
* from unrecoverable defects.
|
||
*
|
||
* **Example** (Providing Recovery Logic for Recoverable Errors)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Random } from "effect"
|
||
*
|
||
* class HttpError {
|
||
* readonly _tag = "HttpError"
|
||
* }
|
||
*
|
||
* class ValidationError {
|
||
* readonly _tag = "ValidationError"
|
||
* }
|
||
*
|
||
* // ┌─── Effect<string, HttpError | ValidationError, never>
|
||
* // ▼
|
||
* const program = Effect.gen(function* () {
|
||
* const n1 = yield* Random.next
|
||
* const n2 = yield* Random.next
|
||
* if (n1 < 0.5) {
|
||
* yield* Effect.fail(new HttpError())
|
||
* }
|
||
* if (n2 < 0.5) {
|
||
* yield* Effect.fail(new ValidationError())
|
||
* }
|
||
* return "some result"
|
||
* })
|
||
*
|
||
* // ┌─── Effect<string, never, never>
|
||
* // ▼
|
||
* const recovered = program.pipe(
|
||
* Effect.catchAll((error) =>
|
||
* Effect.succeed(`Recovering from ${error._tag}`)
|
||
* )
|
||
* )
|
||
* ```
|
||
*
|
||
* @see {@link catchAllCause} for a version that can recover from both
|
||
* recoverable and unrecoverable errors.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error handling
|
||
*/
|
||
<E, A2, E2, R2>(f: (e: E) => Effect<A2, E2, R2>): <A, R>(self: Effect<A, E, R>) => Effect<A2 | A, E2, R2 | R>;
|
||
/**
|
||
* Handles all errors in an effect by providing a fallback effect.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function catches any errors that may occur during the execution of an
|
||
* effect and allows you to handle them by specifying a fallback effect. This
|
||
* ensures that the program continues without failing by recovering from errors
|
||
* using the provided fallback logic.
|
||
*
|
||
* **Note**: This function only handles recoverable errors. It will not recover
|
||
* from unrecoverable defects.
|
||
*
|
||
* **Example** (Providing Recovery Logic for Recoverable Errors)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Random } from "effect"
|
||
*
|
||
* class HttpError {
|
||
* readonly _tag = "HttpError"
|
||
* }
|
||
*
|
||
* class ValidationError {
|
||
* readonly _tag = "ValidationError"
|
||
* }
|
||
*
|
||
* // ┌─── Effect<string, HttpError | ValidationError, never>
|
||
* // ▼
|
||
* const program = Effect.gen(function* () {
|
||
* const n1 = yield* Random.next
|
||
* const n2 = yield* Random.next
|
||
* if (n1 < 0.5) {
|
||
* yield* Effect.fail(new HttpError())
|
||
* }
|
||
* if (n2 < 0.5) {
|
||
* yield* Effect.fail(new ValidationError())
|
||
* }
|
||
* return "some result"
|
||
* })
|
||
*
|
||
* // ┌─── Effect<string, never, never>
|
||
* // ▼
|
||
* const recovered = program.pipe(
|
||
* Effect.catchAll((error) =>
|
||
* Effect.succeed(`Recovering from ${error._tag}`)
|
||
* )
|
||
* )
|
||
* ```
|
||
*
|
||
* @see {@link catchAllCause} for a version that can recover from both
|
||
* recoverable and unrecoverable errors.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error handling
|
||
*/
|
||
<A, E, R, A2, E2, R2>(self: Effect<A, E, R>, f: (e: E) => Effect<A2, E2, R2>): Effect<A2 | A, E2, R2 | R>;
|
||
};
|
||
/**
|
||
* Handles both recoverable and unrecoverable errors by providing a recovery
|
||
* effect.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* The `catchAllCause` function allows you to handle all errors, including
|
||
* unrecoverable defects, by providing a recovery effect. The recovery logic is
|
||
* based on the `Cause` of the error, which provides detailed information about
|
||
* the failure.
|
||
*
|
||
* **When to Recover from Defects**
|
||
*
|
||
* Defects are unexpected errors that typically shouldn't be recovered from, as
|
||
* they often indicate serious issues. However, in some cases, such as
|
||
* dynamically loaded plugins, controlled recovery might be needed.
|
||
*
|
||
* **Example** (Recovering from All Errors)
|
||
*
|
||
* ```ts
|
||
* import { Cause, Effect } from "effect"
|
||
*
|
||
* // Define an effect that may fail with a recoverable or unrecoverable error
|
||
* const program = Effect.fail("Something went wrong!")
|
||
*
|
||
* // Recover from all errors by examining the cause
|
||
* const recovered = program.pipe(
|
||
* Effect.catchAllCause((cause) =>
|
||
* Cause.isFailure(cause)
|
||
* ? Effect.succeed("Recovered from a regular error")
|
||
* : Effect.succeed("Recovered from a defect")
|
||
* )
|
||
* )
|
||
*
|
||
* Effect.runPromise(recovered).then(console.log)
|
||
* // Output: "Recovered from a regular error"
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error handling
|
||
*/
|
||
export declare const catchAllCause: {
|
||
/**
|
||
* Handles both recoverable and unrecoverable errors by providing a recovery
|
||
* effect.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* The `catchAllCause` function allows you to handle all errors, including
|
||
* unrecoverable defects, by providing a recovery effect. The recovery logic is
|
||
* based on the `Cause` of the error, which provides detailed information about
|
||
* the failure.
|
||
*
|
||
* **When to Recover from Defects**
|
||
*
|
||
* Defects are unexpected errors that typically shouldn't be recovered from, as
|
||
* they often indicate serious issues. However, in some cases, such as
|
||
* dynamically loaded plugins, controlled recovery might be needed.
|
||
*
|
||
* **Example** (Recovering from All Errors)
|
||
*
|
||
* ```ts
|
||
* import { Cause, Effect } from "effect"
|
||
*
|
||
* // Define an effect that may fail with a recoverable or unrecoverable error
|
||
* const program = Effect.fail("Something went wrong!")
|
||
*
|
||
* // Recover from all errors by examining the cause
|
||
* const recovered = program.pipe(
|
||
* Effect.catchAllCause((cause) =>
|
||
* Cause.isFailure(cause)
|
||
* ? Effect.succeed("Recovered from a regular error")
|
||
* : Effect.succeed("Recovered from a defect")
|
||
* )
|
||
* )
|
||
*
|
||
* Effect.runPromise(recovered).then(console.log)
|
||
* // Output: "Recovered from a regular error"
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error handling
|
||
*/
|
||
<E, A2, E2, R2>(f: (cause: Cause.Cause<E>) => Effect<A2, E2, R2>): <A, R>(self: Effect<A, E, R>) => Effect<A2 | A, E2, R2 | R>;
|
||
/**
|
||
* Handles both recoverable and unrecoverable errors by providing a recovery
|
||
* effect.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* The `catchAllCause` function allows you to handle all errors, including
|
||
* unrecoverable defects, by providing a recovery effect. The recovery logic is
|
||
* based on the `Cause` of the error, which provides detailed information about
|
||
* the failure.
|
||
*
|
||
* **When to Recover from Defects**
|
||
*
|
||
* Defects are unexpected errors that typically shouldn't be recovered from, as
|
||
* they often indicate serious issues. However, in some cases, such as
|
||
* dynamically loaded plugins, controlled recovery might be needed.
|
||
*
|
||
* **Example** (Recovering from All Errors)
|
||
*
|
||
* ```ts
|
||
* import { Cause, Effect } from "effect"
|
||
*
|
||
* // Define an effect that may fail with a recoverable or unrecoverable error
|
||
* const program = Effect.fail("Something went wrong!")
|
||
*
|
||
* // Recover from all errors by examining the cause
|
||
* const recovered = program.pipe(
|
||
* Effect.catchAllCause((cause) =>
|
||
* Cause.isFailure(cause)
|
||
* ? Effect.succeed("Recovered from a regular error")
|
||
* : Effect.succeed("Recovered from a defect")
|
||
* )
|
||
* )
|
||
*
|
||
* Effect.runPromise(recovered).then(console.log)
|
||
* // Output: "Recovered from a regular error"
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error handling
|
||
*/
|
||
<A, E, R, A2, E2, R2>(self: Effect<A, E, R>, f: (cause: Cause.Cause<E>) => Effect<A2, E2, R2>): Effect<A | A2, E2, R | R2>;
|
||
};
|
||
/**
|
||
* Recovers from all defects using a provided recovery function.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* There is no sensible way to recover from defects. This method should be used
|
||
* only at the boundary between Effect and an external system, to transmit
|
||
* information on a defect for diagnostic or explanatory purposes.
|
||
*
|
||
* **Details**
|
||
*
|
||
* `catchAllDefect` allows you to handle defects, which are unexpected errors
|
||
* that usually cause the program to terminate. This function lets you recover
|
||
* from these defects by providing a function that handles the error. However,
|
||
* it does not handle expected errors (like those from {@link fail}) or
|
||
* execution interruptions (like those from {@link interrupt}).
|
||
*
|
||
* **When to Recover from Defects**
|
||
*
|
||
* Defects are unexpected errors that typically shouldn't be recovered from, as
|
||
* they often indicate serious issues. However, in some cases, such as
|
||
* dynamically loaded plugins, controlled recovery might be needed.
|
||
*
|
||
* **Example** (Handling All Defects)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Cause, Console } from "effect"
|
||
*
|
||
* // Simulating a runtime error
|
||
* const task = Effect.dieMessage("Boom!")
|
||
*
|
||
* const program = Effect.catchAllDefect(task, (defect) => {
|
||
* if (Cause.isRuntimeException(defect)) {
|
||
* return Console.log(
|
||
* `RuntimeException defect caught: ${defect.message}`
|
||
* )
|
||
* }
|
||
* return Console.log("Unknown defect caught.")
|
||
* })
|
||
*
|
||
* // We get an Exit.Success because we caught all defects
|
||
* Effect.runPromiseExit(program).then(console.log)
|
||
* // Output:
|
||
* // RuntimeException defect caught: Boom!
|
||
* // {
|
||
* // _id: "Exit",
|
||
* // _tag: "Success",
|
||
* // value: undefined
|
||
* // }
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error handling
|
||
*/
|
||
export declare const catchAllDefect: {
|
||
/**
|
||
* Recovers from all defects using a provided recovery function.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* There is no sensible way to recover from defects. This method should be used
|
||
* only at the boundary between Effect and an external system, to transmit
|
||
* information on a defect for diagnostic or explanatory purposes.
|
||
*
|
||
* **Details**
|
||
*
|
||
* `catchAllDefect` allows you to handle defects, which are unexpected errors
|
||
* that usually cause the program to terminate. This function lets you recover
|
||
* from these defects by providing a function that handles the error. However,
|
||
* it does not handle expected errors (like those from {@link fail}) or
|
||
* execution interruptions (like those from {@link interrupt}).
|
||
*
|
||
* **When to Recover from Defects**
|
||
*
|
||
* Defects are unexpected errors that typically shouldn't be recovered from, as
|
||
* they often indicate serious issues. However, in some cases, such as
|
||
* dynamically loaded plugins, controlled recovery might be needed.
|
||
*
|
||
* **Example** (Handling All Defects)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Cause, Console } from "effect"
|
||
*
|
||
* // Simulating a runtime error
|
||
* const task = Effect.dieMessage("Boom!")
|
||
*
|
||
* const program = Effect.catchAllDefect(task, (defect) => {
|
||
* if (Cause.isRuntimeException(defect)) {
|
||
* return Console.log(
|
||
* `RuntimeException defect caught: ${defect.message}`
|
||
* )
|
||
* }
|
||
* return Console.log("Unknown defect caught.")
|
||
* })
|
||
*
|
||
* // We get an Exit.Success because we caught all defects
|
||
* Effect.runPromiseExit(program).then(console.log)
|
||
* // Output:
|
||
* // RuntimeException defect caught: Boom!
|
||
* // {
|
||
* // _id: "Exit",
|
||
* // _tag: "Success",
|
||
* // value: undefined
|
||
* // }
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error handling
|
||
*/
|
||
<A2, E2, R2>(f: (defect: unknown) => Effect<A2, E2, R2>): <A, E, R>(self: Effect<A, E, R>) => Effect<A2 | A, E2 | E, R2 | R>;
|
||
/**
|
||
* Recovers from all defects using a provided recovery function.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* There is no sensible way to recover from defects. This method should be used
|
||
* only at the boundary between Effect and an external system, to transmit
|
||
* information on a defect for diagnostic or explanatory purposes.
|
||
*
|
||
* **Details**
|
||
*
|
||
* `catchAllDefect` allows you to handle defects, which are unexpected errors
|
||
* that usually cause the program to terminate. This function lets you recover
|
||
* from these defects by providing a function that handles the error. However,
|
||
* it does not handle expected errors (like those from {@link fail}) or
|
||
* execution interruptions (like those from {@link interrupt}).
|
||
*
|
||
* **When to Recover from Defects**
|
||
*
|
||
* Defects are unexpected errors that typically shouldn't be recovered from, as
|
||
* they often indicate serious issues. However, in some cases, such as
|
||
* dynamically loaded plugins, controlled recovery might be needed.
|
||
*
|
||
* **Example** (Handling All Defects)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Cause, Console } from "effect"
|
||
*
|
||
* // Simulating a runtime error
|
||
* const task = Effect.dieMessage("Boom!")
|
||
*
|
||
* const program = Effect.catchAllDefect(task, (defect) => {
|
||
* if (Cause.isRuntimeException(defect)) {
|
||
* return Console.log(
|
||
* `RuntimeException defect caught: ${defect.message}`
|
||
* )
|
||
* }
|
||
* return Console.log("Unknown defect caught.")
|
||
* })
|
||
*
|
||
* // We get an Exit.Success because we caught all defects
|
||
* Effect.runPromiseExit(program).then(console.log)
|
||
* // Output:
|
||
* // RuntimeException defect caught: Boom!
|
||
* // {
|
||
* // _id: "Exit",
|
||
* // _tag: "Success",
|
||
* // value: undefined
|
||
* // }
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error handling
|
||
*/
|
||
<A, E, R, A2, E2, R2>(self: Effect<A, E, R>, f: (defect: unknown) => Effect<A2, E2, R2>): Effect<A | A2, E | E2, R | R2>;
|
||
};
|
||
/**
|
||
* Recovers from specific errors based on a predicate.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* `catchIf` works similarly to {@link catchSome}, but it allows you to
|
||
* recover from errors by providing a predicate function. If the predicate
|
||
* matches the error, the recovery effect is applied. This function doesn't
|
||
* alter the error type, so the resulting effect still carries the original
|
||
* error type unless a user-defined type guard is used to narrow the type.
|
||
*
|
||
* **Example** (Catching Specific Errors with a Predicate)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Random } from "effect"
|
||
*
|
||
* class HttpError {
|
||
* readonly _tag = "HttpError"
|
||
* }
|
||
*
|
||
* class ValidationError {
|
||
* readonly _tag = "ValidationError"
|
||
* }
|
||
*
|
||
* // ┌─── Effect<string, HttpError | ValidationError, never>
|
||
* // ▼
|
||
* const program = Effect.gen(function* () {
|
||
* const n1 = yield* Random.next
|
||
* const n2 = yield* Random.next
|
||
* if (n1 < 0.5) {
|
||
* yield* Effect.fail(new HttpError())
|
||
* }
|
||
* if (n2 < 0.5) {
|
||
* yield* Effect.fail(new ValidationError())
|
||
* }
|
||
* return "some result"
|
||
* })
|
||
*
|
||
* // ┌─── Effect<string, ValidationError, never>
|
||
* // ▼
|
||
* const recovered = program.pipe(
|
||
* Effect.catchIf(
|
||
* // Only handle HttpError errors
|
||
* (error) => error._tag === "HttpError",
|
||
* () => Effect.succeed("Recovering from HttpError")
|
||
* )
|
||
* )
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error handling
|
||
*/
|
||
export declare const catchIf: {
|
||
/**
|
||
* Recovers from specific errors based on a predicate.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* `catchIf` works similarly to {@link catchSome}, but it allows you to
|
||
* recover from errors by providing a predicate function. If the predicate
|
||
* matches the error, the recovery effect is applied. This function doesn't
|
||
* alter the error type, so the resulting effect still carries the original
|
||
* error type unless a user-defined type guard is used to narrow the type.
|
||
*
|
||
* **Example** (Catching Specific Errors with a Predicate)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Random } from "effect"
|
||
*
|
||
* class HttpError {
|
||
* readonly _tag = "HttpError"
|
||
* }
|
||
*
|
||
* class ValidationError {
|
||
* readonly _tag = "ValidationError"
|
||
* }
|
||
*
|
||
* // ┌─── Effect<string, HttpError | ValidationError, never>
|
||
* // ▼
|
||
* const program = Effect.gen(function* () {
|
||
* const n1 = yield* Random.next
|
||
* const n2 = yield* Random.next
|
||
* if (n1 < 0.5) {
|
||
* yield* Effect.fail(new HttpError())
|
||
* }
|
||
* if (n2 < 0.5) {
|
||
* yield* Effect.fail(new ValidationError())
|
||
* }
|
||
* return "some result"
|
||
* })
|
||
*
|
||
* // ┌─── Effect<string, ValidationError, never>
|
||
* // ▼
|
||
* const recovered = program.pipe(
|
||
* Effect.catchIf(
|
||
* // Only handle HttpError errors
|
||
* (error) => error._tag === "HttpError",
|
||
* () => Effect.succeed("Recovering from HttpError")
|
||
* )
|
||
* )
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error handling
|
||
*/
|
||
<E, EB extends E, A2, E2, R2>(refinement: Refinement<NoInfer<E>, EB>, f: (e: EB) => Effect<A2, E2, R2>): <A, R>(self: Effect<A, E, R>) => Effect<A2 | A, E2 | Exclude<E, EB>, R2 | R>;
|
||
/**
|
||
* Recovers from specific errors based on a predicate.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* `catchIf` works similarly to {@link catchSome}, but it allows you to
|
||
* recover from errors by providing a predicate function. If the predicate
|
||
* matches the error, the recovery effect is applied. This function doesn't
|
||
* alter the error type, so the resulting effect still carries the original
|
||
* error type unless a user-defined type guard is used to narrow the type.
|
||
*
|
||
* **Example** (Catching Specific Errors with a Predicate)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Random } from "effect"
|
||
*
|
||
* class HttpError {
|
||
* readonly _tag = "HttpError"
|
||
* }
|
||
*
|
||
* class ValidationError {
|
||
* readonly _tag = "ValidationError"
|
||
* }
|
||
*
|
||
* // ┌─── Effect<string, HttpError | ValidationError, never>
|
||
* // ▼
|
||
* const program = Effect.gen(function* () {
|
||
* const n1 = yield* Random.next
|
||
* const n2 = yield* Random.next
|
||
* if (n1 < 0.5) {
|
||
* yield* Effect.fail(new HttpError())
|
||
* }
|
||
* if (n2 < 0.5) {
|
||
* yield* Effect.fail(new ValidationError())
|
||
* }
|
||
* return "some result"
|
||
* })
|
||
*
|
||
* // ┌─── Effect<string, ValidationError, never>
|
||
* // ▼
|
||
* const recovered = program.pipe(
|
||
* Effect.catchIf(
|
||
* // Only handle HttpError errors
|
||
* (error) => error._tag === "HttpError",
|
||
* () => Effect.succeed("Recovering from HttpError")
|
||
* )
|
||
* )
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error handling
|
||
*/
|
||
<E, A2, E2, R2>(predicate: Predicate<NoInfer<E>>, f: (e: NoInfer<E>) => Effect<A2, E2, R2>): <A, R>(self: Effect<A, E, R>) => Effect<A2 | A, E | E2, R2 | R>;
|
||
/**
|
||
* Recovers from specific errors based on a predicate.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* `catchIf` works similarly to {@link catchSome}, but it allows you to
|
||
* recover from errors by providing a predicate function. If the predicate
|
||
* matches the error, the recovery effect is applied. This function doesn't
|
||
* alter the error type, so the resulting effect still carries the original
|
||
* error type unless a user-defined type guard is used to narrow the type.
|
||
*
|
||
* **Example** (Catching Specific Errors with a Predicate)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Random } from "effect"
|
||
*
|
||
* class HttpError {
|
||
* readonly _tag = "HttpError"
|
||
* }
|
||
*
|
||
* class ValidationError {
|
||
* readonly _tag = "ValidationError"
|
||
* }
|
||
*
|
||
* // ┌─── Effect<string, HttpError | ValidationError, never>
|
||
* // ▼
|
||
* const program = Effect.gen(function* () {
|
||
* const n1 = yield* Random.next
|
||
* const n2 = yield* Random.next
|
||
* if (n1 < 0.5) {
|
||
* yield* Effect.fail(new HttpError())
|
||
* }
|
||
* if (n2 < 0.5) {
|
||
* yield* Effect.fail(new ValidationError())
|
||
* }
|
||
* return "some result"
|
||
* })
|
||
*
|
||
* // ┌─── Effect<string, ValidationError, never>
|
||
* // ▼
|
||
* const recovered = program.pipe(
|
||
* Effect.catchIf(
|
||
* // Only handle HttpError errors
|
||
* (error) => error._tag === "HttpError",
|
||
* () => Effect.succeed("Recovering from HttpError")
|
||
* )
|
||
* )
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error handling
|
||
*/
|
||
<A, E, R, EB extends E, A2, E2, R2>(self: Effect<A, E, R>, refinement: Refinement<E, EB>, f: (e: EB) => Effect<A2, E2, R2>): Effect<A | A2, E2 | Exclude<E, EB>, R | R2>;
|
||
/**
|
||
* Recovers from specific errors based on a predicate.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* `catchIf` works similarly to {@link catchSome}, but it allows you to
|
||
* recover from errors by providing a predicate function. If the predicate
|
||
* matches the error, the recovery effect is applied. This function doesn't
|
||
* alter the error type, so the resulting effect still carries the original
|
||
* error type unless a user-defined type guard is used to narrow the type.
|
||
*
|
||
* **Example** (Catching Specific Errors with a Predicate)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Random } from "effect"
|
||
*
|
||
* class HttpError {
|
||
* readonly _tag = "HttpError"
|
||
* }
|
||
*
|
||
* class ValidationError {
|
||
* readonly _tag = "ValidationError"
|
||
* }
|
||
*
|
||
* // ┌─── Effect<string, HttpError | ValidationError, never>
|
||
* // ▼
|
||
* const program = Effect.gen(function* () {
|
||
* const n1 = yield* Random.next
|
||
* const n2 = yield* Random.next
|
||
* if (n1 < 0.5) {
|
||
* yield* Effect.fail(new HttpError())
|
||
* }
|
||
* if (n2 < 0.5) {
|
||
* yield* Effect.fail(new ValidationError())
|
||
* }
|
||
* return "some result"
|
||
* })
|
||
*
|
||
* // ┌─── Effect<string, ValidationError, never>
|
||
* // ▼
|
||
* const recovered = program.pipe(
|
||
* Effect.catchIf(
|
||
* // Only handle HttpError errors
|
||
* (error) => error._tag === "HttpError",
|
||
* () => Effect.succeed("Recovering from HttpError")
|
||
* )
|
||
* )
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error handling
|
||
*/
|
||
<A, E, R, A2, E2, R2>(self: Effect<A, E, R>, predicate: Predicate<E>, f: (e: E) => Effect<A2, E2, R2>): Effect<A | A2, E | E2, R | R2>;
|
||
};
|
||
/**
|
||
* Catches and recovers from specific types of errors, allowing you to attempt
|
||
* recovery only for certain errors.
|
||
*
|
||
* **Details**
|
||
*
|
||
* `catchSome` lets you selectively catch and handle errors of certain
|
||
* types by providing a recovery effect for specific errors. If the error
|
||
* matches a condition, recovery is attempted; if not, it doesn't affect the
|
||
* program. This function doesn't alter the error type, meaning the error type
|
||
* remains the same as in the original effect.
|
||
*
|
||
* **Example** (Handling Specific Errors with Effect.catchSome)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Random, Option } from "effect"
|
||
*
|
||
* class HttpError {
|
||
* readonly _tag = "HttpError"
|
||
* }
|
||
*
|
||
* class ValidationError {
|
||
* readonly _tag = "ValidationError"
|
||
* }
|
||
*
|
||
* // ┌─── Effect<string, HttpError | ValidationError, never>
|
||
* // ▼
|
||
* const program = Effect.gen(function* () {
|
||
* const n1 = yield* Random.next
|
||
* const n2 = yield* Random.next
|
||
* if (n1 < 0.5) {
|
||
* yield* Effect.fail(new HttpError())
|
||
* }
|
||
* if (n2 < 0.5) {
|
||
* yield* Effect.fail(new ValidationError())
|
||
* }
|
||
* return "some result"
|
||
* })
|
||
*
|
||
* // ┌─── Effect<string, HttpError | ValidationError, never>
|
||
* // ▼
|
||
* const recovered = program.pipe(
|
||
* Effect.catchSome((error) => {
|
||
* // Only handle HttpError errors
|
||
* if (error._tag === "HttpError") {
|
||
* return Option.some(Effect.succeed("Recovering from HttpError"))
|
||
* } else {
|
||
* return Option.none()
|
||
* }
|
||
* })
|
||
* )
|
||
* ```
|
||
*
|
||
* @see {@link catchIf} for a version that allows you to recover from errors based on a predicate.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error handling
|
||
*/
|
||
export declare const catchSome: {
|
||
/**
|
||
* Catches and recovers from specific types of errors, allowing you to attempt
|
||
* recovery only for certain errors.
|
||
*
|
||
* **Details**
|
||
*
|
||
* `catchSome` lets you selectively catch and handle errors of certain
|
||
* types by providing a recovery effect for specific errors. If the error
|
||
* matches a condition, recovery is attempted; if not, it doesn't affect the
|
||
* program. This function doesn't alter the error type, meaning the error type
|
||
* remains the same as in the original effect.
|
||
*
|
||
* **Example** (Handling Specific Errors with Effect.catchSome)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Random, Option } from "effect"
|
||
*
|
||
* class HttpError {
|
||
* readonly _tag = "HttpError"
|
||
* }
|
||
*
|
||
* class ValidationError {
|
||
* readonly _tag = "ValidationError"
|
||
* }
|
||
*
|
||
* // ┌─── Effect<string, HttpError | ValidationError, never>
|
||
* // ▼
|
||
* const program = Effect.gen(function* () {
|
||
* const n1 = yield* Random.next
|
||
* const n2 = yield* Random.next
|
||
* if (n1 < 0.5) {
|
||
* yield* Effect.fail(new HttpError())
|
||
* }
|
||
* if (n2 < 0.5) {
|
||
* yield* Effect.fail(new ValidationError())
|
||
* }
|
||
* return "some result"
|
||
* })
|
||
*
|
||
* // ┌─── Effect<string, HttpError | ValidationError, never>
|
||
* // ▼
|
||
* const recovered = program.pipe(
|
||
* Effect.catchSome((error) => {
|
||
* // Only handle HttpError errors
|
||
* if (error._tag === "HttpError") {
|
||
* return Option.some(Effect.succeed("Recovering from HttpError"))
|
||
* } else {
|
||
* return Option.none()
|
||
* }
|
||
* })
|
||
* )
|
||
* ```
|
||
*
|
||
* @see {@link catchIf} for a version that allows you to recover from errors based on a predicate.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error handling
|
||
*/
|
||
<E, A2, E2, R2>(pf: (e: NoInfer<E>) => Option.Option<Effect<A2, E2, R2>>): <A, R>(self: Effect<A, E, R>) => Effect<A2 | A, E | E2, R2 | R>;
|
||
/**
|
||
* Catches and recovers from specific types of errors, allowing you to attempt
|
||
* recovery only for certain errors.
|
||
*
|
||
* **Details**
|
||
*
|
||
* `catchSome` lets you selectively catch and handle errors of certain
|
||
* types by providing a recovery effect for specific errors. If the error
|
||
* matches a condition, recovery is attempted; if not, it doesn't affect the
|
||
* program. This function doesn't alter the error type, meaning the error type
|
||
* remains the same as in the original effect.
|
||
*
|
||
* **Example** (Handling Specific Errors with Effect.catchSome)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Random, Option } from "effect"
|
||
*
|
||
* class HttpError {
|
||
* readonly _tag = "HttpError"
|
||
* }
|
||
*
|
||
* class ValidationError {
|
||
* readonly _tag = "ValidationError"
|
||
* }
|
||
*
|
||
* // ┌─── Effect<string, HttpError | ValidationError, never>
|
||
* // ▼
|
||
* const program = Effect.gen(function* () {
|
||
* const n1 = yield* Random.next
|
||
* const n2 = yield* Random.next
|
||
* if (n1 < 0.5) {
|
||
* yield* Effect.fail(new HttpError())
|
||
* }
|
||
* if (n2 < 0.5) {
|
||
* yield* Effect.fail(new ValidationError())
|
||
* }
|
||
* return "some result"
|
||
* })
|
||
*
|
||
* // ┌─── Effect<string, HttpError | ValidationError, never>
|
||
* // ▼
|
||
* const recovered = program.pipe(
|
||
* Effect.catchSome((error) => {
|
||
* // Only handle HttpError errors
|
||
* if (error._tag === "HttpError") {
|
||
* return Option.some(Effect.succeed("Recovering from HttpError"))
|
||
* } else {
|
||
* return Option.none()
|
||
* }
|
||
* })
|
||
* )
|
||
* ```
|
||
*
|
||
* @see {@link catchIf} for a version that allows you to recover from errors based on a predicate.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error handling
|
||
*/
|
||
<A, E, R, A2, E2, R2>(self: Effect<A, E, R>, pf: (e: NoInfer<E>) => Option.Option<Effect<A2, E2, R2>>): Effect<A | A2, E | E2, R | R2>;
|
||
};
|
||
/**
|
||
* Recovers from specific causes using a provided partial function.
|
||
*
|
||
* @see {@link catchSome} for a version that allows you to recover from errors.
|
||
* @see {@link catchSomeDefect} for a version that allows you to recover from defects.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error handling
|
||
*/
|
||
export declare const catchSomeCause: {
|
||
/**
|
||
* Recovers from specific causes using a provided partial function.
|
||
*
|
||
* @see {@link catchSome} for a version that allows you to recover from errors.
|
||
* @see {@link catchSomeDefect} for a version that allows you to recover from defects.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error handling
|
||
*/
|
||
<E, A2, E2, R2>(f: (cause: Cause.Cause<NoInfer<E>>) => Option.Option<Effect<A2, E2, R2>>): <A, R>(self: Effect<A, E, R>) => Effect<A2 | A, E | E2, R2 | R>;
|
||
/**
|
||
* Recovers from specific causes using a provided partial function.
|
||
*
|
||
* @see {@link catchSome} for a version that allows you to recover from errors.
|
||
* @see {@link catchSomeDefect} for a version that allows you to recover from defects.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error handling
|
||
*/
|
||
<A, E, R, A2, E2, R2>(self: Effect<A, E, R>, f: (cause: Cause.Cause<NoInfer<E>>) => Option.Option<Effect<A2, E2, R2>>): Effect<A2 | A, E | E2, R2 | R>;
|
||
};
|
||
/**
|
||
* Recovers from specific defects using a provided partial function.
|
||
*
|
||
* **Details**
|
||
*
|
||
* `catchSomeDefect` allows you to handle specific defects, which are
|
||
* unexpected errors that can cause the program to stop. It uses a partial
|
||
* function to catch only certain defects and ignores others. The function does
|
||
* not handle expected errors (such as those caused by {@link fail}) or
|
||
* interruptions in execution (like those caused by {@link interrupt}).
|
||
*
|
||
* This function provides a way to handle certain types of defects while
|
||
* allowing others to propagate and cause failure in the program.
|
||
*
|
||
* **Note**: There is no sensible way to recover from defects. This method
|
||
* should be used only at the boundary between Effect and an external system, to
|
||
* transmit information on a defect for diagnostic or explanatory purposes.
|
||
*
|
||
* **How the Partial Function Works**
|
||
*
|
||
* The function provided to `catchSomeDefect` acts as a filter and a handler for defects:
|
||
* - It receives the defect as an input.
|
||
* - If the defect matches a specific condition (e.g., a certain error type), the function returns
|
||
* an `Option.some` containing the recovery logic.
|
||
* - If the defect does not match, the function returns `Option.none`, allowing the defect to propagate.
|
||
*
|
||
* **Example** (Handling Specific Defects)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Cause, Option, Console } from "effect"
|
||
*
|
||
* // Simulating a runtime error
|
||
* const task = Effect.dieMessage("Boom!")
|
||
*
|
||
* const program = Effect.catchSomeDefect(task, (defect) => {
|
||
* if (Cause.isIllegalArgumentException(defect)) {
|
||
* return Option.some(
|
||
* Console.log(
|
||
* `Caught an IllegalArgumentException defect: ${defect.message}`
|
||
* )
|
||
* )
|
||
* }
|
||
* return Option.none()
|
||
* })
|
||
*
|
||
* // Since we are only catching IllegalArgumentException
|
||
* // we will get an Exit.Failure because we simulated a runtime error.
|
||
* Effect.runPromiseExit(program).then(console.log)
|
||
* // Output:
|
||
* // {
|
||
* // _id: 'Exit',
|
||
* // _tag: 'Failure',
|
||
* // cause: {
|
||
* // _id: 'Cause',
|
||
* // _tag: 'Die',
|
||
* // defect: { _tag: 'RuntimeException' }
|
||
* // }
|
||
* // }
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error handling
|
||
*/
|
||
export declare const catchSomeDefect: {
|
||
/**
|
||
* Recovers from specific defects using a provided partial function.
|
||
*
|
||
* **Details**
|
||
*
|
||
* `catchSomeDefect` allows you to handle specific defects, which are
|
||
* unexpected errors that can cause the program to stop. It uses a partial
|
||
* function to catch only certain defects and ignores others. The function does
|
||
* not handle expected errors (such as those caused by {@link fail}) or
|
||
* interruptions in execution (like those caused by {@link interrupt}).
|
||
*
|
||
* This function provides a way to handle certain types of defects while
|
||
* allowing others to propagate and cause failure in the program.
|
||
*
|
||
* **Note**: There is no sensible way to recover from defects. This method
|
||
* should be used only at the boundary between Effect and an external system, to
|
||
* transmit information on a defect for diagnostic or explanatory purposes.
|
||
*
|
||
* **How the Partial Function Works**
|
||
*
|
||
* The function provided to `catchSomeDefect` acts as a filter and a handler for defects:
|
||
* - It receives the defect as an input.
|
||
* - If the defect matches a specific condition (e.g., a certain error type), the function returns
|
||
* an `Option.some` containing the recovery logic.
|
||
* - If the defect does not match, the function returns `Option.none`, allowing the defect to propagate.
|
||
*
|
||
* **Example** (Handling Specific Defects)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Cause, Option, Console } from "effect"
|
||
*
|
||
* // Simulating a runtime error
|
||
* const task = Effect.dieMessage("Boom!")
|
||
*
|
||
* const program = Effect.catchSomeDefect(task, (defect) => {
|
||
* if (Cause.isIllegalArgumentException(defect)) {
|
||
* return Option.some(
|
||
* Console.log(
|
||
* `Caught an IllegalArgumentException defect: ${defect.message}`
|
||
* )
|
||
* )
|
||
* }
|
||
* return Option.none()
|
||
* })
|
||
*
|
||
* // Since we are only catching IllegalArgumentException
|
||
* // we will get an Exit.Failure because we simulated a runtime error.
|
||
* Effect.runPromiseExit(program).then(console.log)
|
||
* // Output:
|
||
* // {
|
||
* // _id: 'Exit',
|
||
* // _tag: 'Failure',
|
||
* // cause: {
|
||
* // _id: 'Cause',
|
||
* // _tag: 'Die',
|
||
* // defect: { _tag: 'RuntimeException' }
|
||
* // }
|
||
* // }
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error handling
|
||
*/
|
||
<A2, E2, R2>(pf: (defect: unknown) => Option.Option<Effect<A2, E2, R2>>): <A, E, R>(self: Effect<A, E, R>) => Effect<A2 | A, E2 | E, R2 | R>;
|
||
/**
|
||
* Recovers from specific defects using a provided partial function.
|
||
*
|
||
* **Details**
|
||
*
|
||
* `catchSomeDefect` allows you to handle specific defects, which are
|
||
* unexpected errors that can cause the program to stop. It uses a partial
|
||
* function to catch only certain defects and ignores others. The function does
|
||
* not handle expected errors (such as those caused by {@link fail}) or
|
||
* interruptions in execution (like those caused by {@link interrupt}).
|
||
*
|
||
* This function provides a way to handle certain types of defects while
|
||
* allowing others to propagate and cause failure in the program.
|
||
*
|
||
* **Note**: There is no sensible way to recover from defects. This method
|
||
* should be used only at the boundary between Effect and an external system, to
|
||
* transmit information on a defect for diagnostic or explanatory purposes.
|
||
*
|
||
* **How the Partial Function Works**
|
||
*
|
||
* The function provided to `catchSomeDefect` acts as a filter and a handler for defects:
|
||
* - It receives the defect as an input.
|
||
* - If the defect matches a specific condition (e.g., a certain error type), the function returns
|
||
* an `Option.some` containing the recovery logic.
|
||
* - If the defect does not match, the function returns `Option.none`, allowing the defect to propagate.
|
||
*
|
||
* **Example** (Handling Specific Defects)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Cause, Option, Console } from "effect"
|
||
*
|
||
* // Simulating a runtime error
|
||
* const task = Effect.dieMessage("Boom!")
|
||
*
|
||
* const program = Effect.catchSomeDefect(task, (defect) => {
|
||
* if (Cause.isIllegalArgumentException(defect)) {
|
||
* return Option.some(
|
||
* Console.log(
|
||
* `Caught an IllegalArgumentException defect: ${defect.message}`
|
||
* )
|
||
* )
|
||
* }
|
||
* return Option.none()
|
||
* })
|
||
*
|
||
* // Since we are only catching IllegalArgumentException
|
||
* // we will get an Exit.Failure because we simulated a runtime error.
|
||
* Effect.runPromiseExit(program).then(console.log)
|
||
* // Output:
|
||
* // {
|
||
* // _id: 'Exit',
|
||
* // _tag: 'Failure',
|
||
* // cause: {
|
||
* // _id: 'Cause',
|
||
* // _tag: 'Die',
|
||
* // defect: { _tag: 'RuntimeException' }
|
||
* // }
|
||
* // }
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error handling
|
||
*/
|
||
<A, E, R, A2, E2, R2>(self: Effect<A, E, R>, pf: (defect: unknown) => Option.Option<Effect<A2, E2, R2>>): Effect<A | A2, E | E2, R | R2>;
|
||
};
|
||
/**
|
||
* Catches and handles specific errors by their `_tag` field, which is used as a
|
||
* discriminator.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* `catchTag` is useful when your errors are tagged with a readonly `_tag` field
|
||
* that identifies the error type. You can use this function to handle specific
|
||
* error types by matching the `_tag` value. This allows for precise error
|
||
* handling, ensuring that only specific errors are caught and handled.
|
||
*
|
||
* The error type must have a readonly `_tag` field to use `catchTag`. This
|
||
* field is used to identify and match errors.
|
||
*
|
||
* **Example** (Handling Errors by Tag)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Random } from "effect"
|
||
*
|
||
* class HttpError {
|
||
* readonly _tag = "HttpError"
|
||
* }
|
||
*
|
||
* class ValidationError {
|
||
* readonly _tag = "ValidationError"
|
||
* }
|
||
*
|
||
* // ┌─── Effect<string, HttpError | ValidationError, never>
|
||
* // ▼
|
||
* const program = Effect.gen(function* () {
|
||
* const n1 = yield* Random.next
|
||
* const n2 = yield* Random.next
|
||
* if (n1 < 0.5) {
|
||
* yield* Effect.fail(new HttpError())
|
||
* }
|
||
* if (n2 < 0.5) {
|
||
* yield* Effect.fail(new ValidationError())
|
||
* }
|
||
* return "some result"
|
||
* })
|
||
*
|
||
* // ┌─── Effect<string, ValidationError, never>
|
||
* // ▼
|
||
* const recovered = program.pipe(
|
||
* // Only handle HttpError errors
|
||
* Effect.catchTag("HttpError", (_HttpError) =>
|
||
* Effect.succeed("Recovering from HttpError")
|
||
* )
|
||
* )
|
||
* ```
|
||
*
|
||
* @see {@link catchTags} for a version that allows you to handle multiple error
|
||
* types at once.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error handling
|
||
*/
|
||
export declare const catchTag: {
|
||
/**
|
||
* Catches and handles specific errors by their `_tag` field, which is used as a
|
||
* discriminator.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* `catchTag` is useful when your errors are tagged with a readonly `_tag` field
|
||
* that identifies the error type. You can use this function to handle specific
|
||
* error types by matching the `_tag` value. This allows for precise error
|
||
* handling, ensuring that only specific errors are caught and handled.
|
||
*
|
||
* The error type must have a readonly `_tag` field to use `catchTag`. This
|
||
* field is used to identify and match errors.
|
||
*
|
||
* **Example** (Handling Errors by Tag)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Random } from "effect"
|
||
*
|
||
* class HttpError {
|
||
* readonly _tag = "HttpError"
|
||
* }
|
||
*
|
||
* class ValidationError {
|
||
* readonly _tag = "ValidationError"
|
||
* }
|
||
*
|
||
* // ┌─── Effect<string, HttpError | ValidationError, never>
|
||
* // ▼
|
||
* const program = Effect.gen(function* () {
|
||
* const n1 = yield* Random.next
|
||
* const n2 = yield* Random.next
|
||
* if (n1 < 0.5) {
|
||
* yield* Effect.fail(new HttpError())
|
||
* }
|
||
* if (n2 < 0.5) {
|
||
* yield* Effect.fail(new ValidationError())
|
||
* }
|
||
* return "some result"
|
||
* })
|
||
*
|
||
* // ┌─── Effect<string, ValidationError, never>
|
||
* // ▼
|
||
* const recovered = program.pipe(
|
||
* // Only handle HttpError errors
|
||
* Effect.catchTag("HttpError", (_HttpError) =>
|
||
* Effect.succeed("Recovering from HttpError")
|
||
* )
|
||
* )
|
||
* ```
|
||
*
|
||
* @see {@link catchTags} for a version that allows you to handle multiple error
|
||
* types at once.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error handling
|
||
*/
|
||
<E, const K extends RA.NonEmptyReadonlyArray<E extends {
|
||
_tag: string;
|
||
} ? E["_tag"] : never>, A1, E1, R1>(...args: [...tags: K, f: (e: Extract<NoInfer<E>, {
|
||
_tag: K[number];
|
||
}>) => Effect<A1, E1, R1>]): <A, R>(self: Effect<A, E, R>) => Effect<A | A1, Exclude<E, {
|
||
_tag: K[number];
|
||
}> | E1, R | R1>;
|
||
/**
|
||
* Catches and handles specific errors by their `_tag` field, which is used as a
|
||
* discriminator.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* `catchTag` is useful when your errors are tagged with a readonly `_tag` field
|
||
* that identifies the error type. You can use this function to handle specific
|
||
* error types by matching the `_tag` value. This allows for precise error
|
||
* handling, ensuring that only specific errors are caught and handled.
|
||
*
|
||
* The error type must have a readonly `_tag` field to use `catchTag`. This
|
||
* field is used to identify and match errors.
|
||
*
|
||
* **Example** (Handling Errors by Tag)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Random } from "effect"
|
||
*
|
||
* class HttpError {
|
||
* readonly _tag = "HttpError"
|
||
* }
|
||
*
|
||
* class ValidationError {
|
||
* readonly _tag = "ValidationError"
|
||
* }
|
||
*
|
||
* // ┌─── Effect<string, HttpError | ValidationError, never>
|
||
* // ▼
|
||
* const program = Effect.gen(function* () {
|
||
* const n1 = yield* Random.next
|
||
* const n2 = yield* Random.next
|
||
* if (n1 < 0.5) {
|
||
* yield* Effect.fail(new HttpError())
|
||
* }
|
||
* if (n2 < 0.5) {
|
||
* yield* Effect.fail(new ValidationError())
|
||
* }
|
||
* return "some result"
|
||
* })
|
||
*
|
||
* // ┌─── Effect<string, ValidationError, never>
|
||
* // ▼
|
||
* const recovered = program.pipe(
|
||
* // Only handle HttpError errors
|
||
* Effect.catchTag("HttpError", (_HttpError) =>
|
||
* Effect.succeed("Recovering from HttpError")
|
||
* )
|
||
* )
|
||
* ```
|
||
*
|
||
* @see {@link catchTags} for a version that allows you to handle multiple error
|
||
* types at once.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error handling
|
||
*/
|
||
<A, E, R, const K extends RA.NonEmptyReadonlyArray<E extends {
|
||
_tag: string;
|
||
} ? E["_tag"] : never>, A1, E1, R1>(self: Effect<A, E, R>, ...args: [...tags: K, f: (e: Extract<NoInfer<E>, {
|
||
_tag: K[number];
|
||
}>) => Effect<A1, E1, R1>]): Effect<A | A1, Exclude<E, {
|
||
_tag: K[number];
|
||
}> | E1, R | R1>;
|
||
};
|
||
/**
|
||
* Handles multiple errors in a single block of code using their `_tag` field.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* `catchTags` is a convenient way to handle multiple error types at
|
||
* once. Instead of using {@link catchTag} multiple times, you can pass an
|
||
* object where each key is an error type's `_tag`, and the value is the handler
|
||
* for that specific error. This allows you to catch and recover from multiple
|
||
* error types in a single call.
|
||
*
|
||
* The error type must have a readonly `_tag` field to use `catchTag`. This
|
||
* field is used to identify and match errors.
|
||
*
|
||
* **Example** (Handling Multiple Tagged Error Types at Once)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Random } from "effect"
|
||
*
|
||
* class HttpError {
|
||
* readonly _tag = "HttpError"
|
||
* }
|
||
*
|
||
* class ValidationError {
|
||
* readonly _tag = "ValidationError"
|
||
* }
|
||
*
|
||
* // ┌─── Effect<string, HttpError | ValidationError, never>
|
||
* // ▼
|
||
* const program = Effect.gen(function* () {
|
||
* const n1 = yield* Random.next
|
||
* const n2 = yield* Random.next
|
||
* if (n1 < 0.5) {
|
||
* yield* Effect.fail(new HttpError())
|
||
* }
|
||
* if (n2 < 0.5) {
|
||
* yield* Effect.fail(new ValidationError())
|
||
* }
|
||
* return "some result"
|
||
* })
|
||
*
|
||
* // ┌─── Effect<string, never, never>
|
||
* // ▼
|
||
* const recovered = program.pipe(
|
||
* Effect.catchTags({
|
||
* HttpError: (_HttpError) =>
|
||
* Effect.succeed(`Recovering from HttpError`),
|
||
* ValidationError: (_ValidationError) =>
|
||
* Effect.succeed(`Recovering from ValidationError`)
|
||
* })
|
||
* )
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error handling
|
||
*/
|
||
export declare const catchTags: {
|
||
/**
|
||
* Handles multiple errors in a single block of code using their `_tag` field.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* `catchTags` is a convenient way to handle multiple error types at
|
||
* once. Instead of using {@link catchTag} multiple times, you can pass an
|
||
* object where each key is an error type's `_tag`, and the value is the handler
|
||
* for that specific error. This allows you to catch and recover from multiple
|
||
* error types in a single call.
|
||
*
|
||
* The error type must have a readonly `_tag` field to use `catchTag`. This
|
||
* field is used to identify and match errors.
|
||
*
|
||
* **Example** (Handling Multiple Tagged Error Types at Once)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Random } from "effect"
|
||
*
|
||
* class HttpError {
|
||
* readonly _tag = "HttpError"
|
||
* }
|
||
*
|
||
* class ValidationError {
|
||
* readonly _tag = "ValidationError"
|
||
* }
|
||
*
|
||
* // ┌─── Effect<string, HttpError | ValidationError, never>
|
||
* // ▼
|
||
* const program = Effect.gen(function* () {
|
||
* const n1 = yield* Random.next
|
||
* const n2 = yield* Random.next
|
||
* if (n1 < 0.5) {
|
||
* yield* Effect.fail(new HttpError())
|
||
* }
|
||
* if (n2 < 0.5) {
|
||
* yield* Effect.fail(new ValidationError())
|
||
* }
|
||
* return "some result"
|
||
* })
|
||
*
|
||
* // ┌─── Effect<string, never, never>
|
||
* // ▼
|
||
* const recovered = program.pipe(
|
||
* Effect.catchTags({
|
||
* HttpError: (_HttpError) =>
|
||
* Effect.succeed(`Recovering from HttpError`),
|
||
* ValidationError: (_ValidationError) =>
|
||
* Effect.succeed(`Recovering from ValidationError`)
|
||
* })
|
||
* )
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error handling
|
||
*/
|
||
<E, Cases extends {
|
||
[K in Extract<E, {
|
||
_tag: string;
|
||
}>["_tag"]]+?: ((error: Extract<E, {
|
||
_tag: K;
|
||
}>) => Effect<any, any, any>);
|
||
} & (unknown extends E ? {} : {
|
||
[K in Exclude<keyof Cases, Extract<E, {
|
||
_tag: string;
|
||
}>["_tag"]>]: never;
|
||
})>(cases: Cases): <A, R>(self: Effect<A, E, R>) => Effect<A | {
|
||
[K in keyof Cases]: Cases[K] extends (...args: Array<any>) => Effect<infer A, any, any> ? A : never;
|
||
}[keyof Cases], Exclude<E, {
|
||
_tag: keyof Cases;
|
||
}> | {
|
||
[K in keyof Cases]: Cases[K] extends (...args: Array<any>) => Effect<any, infer E, any> ? E : never;
|
||
}[keyof Cases], R | {
|
||
[K in keyof Cases]: Cases[K] extends (...args: Array<any>) => Effect<any, any, infer R> ? R : never;
|
||
}[keyof Cases]>;
|
||
/**
|
||
* Handles multiple errors in a single block of code using their `_tag` field.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* `catchTags` is a convenient way to handle multiple error types at
|
||
* once. Instead of using {@link catchTag} multiple times, you can pass an
|
||
* object where each key is an error type's `_tag`, and the value is the handler
|
||
* for that specific error. This allows you to catch and recover from multiple
|
||
* error types in a single call.
|
||
*
|
||
* The error type must have a readonly `_tag` field to use `catchTag`. This
|
||
* field is used to identify and match errors.
|
||
*
|
||
* **Example** (Handling Multiple Tagged Error Types at Once)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Random } from "effect"
|
||
*
|
||
* class HttpError {
|
||
* readonly _tag = "HttpError"
|
||
* }
|
||
*
|
||
* class ValidationError {
|
||
* readonly _tag = "ValidationError"
|
||
* }
|
||
*
|
||
* // ┌─── Effect<string, HttpError | ValidationError, never>
|
||
* // ▼
|
||
* const program = Effect.gen(function* () {
|
||
* const n1 = yield* Random.next
|
||
* const n2 = yield* Random.next
|
||
* if (n1 < 0.5) {
|
||
* yield* Effect.fail(new HttpError())
|
||
* }
|
||
* if (n2 < 0.5) {
|
||
* yield* Effect.fail(new ValidationError())
|
||
* }
|
||
* return "some result"
|
||
* })
|
||
*
|
||
* // ┌─── Effect<string, never, never>
|
||
* // ▼
|
||
* const recovered = program.pipe(
|
||
* Effect.catchTags({
|
||
* HttpError: (_HttpError) =>
|
||
* Effect.succeed(`Recovering from HttpError`),
|
||
* ValidationError: (_ValidationError) =>
|
||
* Effect.succeed(`Recovering from ValidationError`)
|
||
* })
|
||
* )
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error handling
|
||
*/
|
||
<R, E, A, Cases extends {
|
||
[K in Extract<E, {
|
||
_tag: string;
|
||
}>["_tag"]]+?: ((error: Extract<E, {
|
||
_tag: K;
|
||
}>) => Effect<any, any, any>);
|
||
} & (unknown extends E ? {} : {
|
||
[K in Exclude<keyof Cases, Extract<E, {
|
||
_tag: string;
|
||
}>["_tag"]>]: never;
|
||
})>(self: Effect<A, E, R>, cases: Cases): Effect<A | {
|
||
[K in keyof Cases]: Cases[K] extends (...args: Array<any>) => Effect<infer A, any, any> ? A : never;
|
||
}[keyof Cases], Exclude<E, {
|
||
_tag: keyof Cases;
|
||
}> | {
|
||
[K in keyof Cases]: Cases[K] extends (...args: Array<any>) => Effect<any, infer E, any> ? E : never;
|
||
}[keyof Cases], R | {
|
||
[K in keyof Cases]: Cases[K] extends (...args: Array<any>) => Effect<any, any, infer R> ? R : never;
|
||
}[keyof Cases]>;
|
||
};
|
||
/**
|
||
* Retrieves the cause of a failure in an effect.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to expose the detailed cause of an effect, which
|
||
* includes a more precise representation of failures, such as error messages
|
||
* and defects.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This function is helpful when you need to inspect the cause of a failure in
|
||
* an effect, giving you more information than just the error message. It can be
|
||
* used to log, handle, or analyze failures in more detail, including
|
||
* distinguishing between different types of defects (e.g., runtime exceptions,
|
||
* interruptions, etc.).
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* // ┌─── Effect<number, string, never>
|
||
* // ▼
|
||
* const program = Effect.fail("Oh uh!").pipe(Effect.as(2))
|
||
*
|
||
* // ┌─── Effect<void, never, never>
|
||
* // ▼
|
||
* const recovered = Effect.gen(function* () {
|
||
* const cause = yield* Effect.cause(program)
|
||
* yield* Console.log(cause)
|
||
* })
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error handling
|
||
*/
|
||
export declare const cause: <A, E, R>(self: Effect<A, E, R>) => Effect<Cause.Cause<E>, never, R>;
|
||
/**
|
||
* Runs an effect repeatedly until it succeeds, ignoring errors.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function takes an effect and runs it repeatedly until the effect
|
||
* successfully completes. If the effect fails, it will ignore the error and
|
||
* retry the operation. This is useful when you need to perform a task that may
|
||
* fail occasionally, but you want to keep trying until it eventually succeeds.
|
||
* It works by repeatedly executing the effect until it no longer throws an
|
||
* error.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use this function when you want to retry an operation multiple times until it
|
||
* succeeds. It is helpful in cases where the operation may fail temporarily
|
||
* (e.g., a network request), and you want to keep trying without handling or
|
||
* worrying about the errors.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* let counter = 0
|
||
*
|
||
* const effect = Effect.try(() => {
|
||
* counter++
|
||
* if (counter < 3) {
|
||
* console.log("running effect")
|
||
* throw new Error("error")
|
||
* } else {
|
||
* console.log("effect done")
|
||
* return "some result"
|
||
* }
|
||
* })
|
||
*
|
||
* const program = Effect.eventually(effect)
|
||
*
|
||
* Effect.runPromise(program).then(console.log)
|
||
* // Output:
|
||
* // running effect
|
||
* // running effect
|
||
* // effect done
|
||
* // some result
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error handling
|
||
*/
|
||
export declare const eventually: <A, E, R>(self: Effect<A, E, R>) => Effect<A, never, R>;
|
||
/**
|
||
* Discards both the success and failure values of an effect.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* `ignore` allows you to run an effect without caring about its result, whether
|
||
* it succeeds or fails. This is useful when you only care about the side
|
||
* effects of the effect and do not need to handle or process its outcome.
|
||
*
|
||
* **Example** (Using Effect.ignore to Discard Values)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* // ┌─── Effect<number, string, never>
|
||
* // ▼
|
||
* const task = Effect.fail("Uh oh!").pipe(Effect.as(5))
|
||
*
|
||
* // ┌─── Effect<void, never, never>
|
||
* // ▼
|
||
* const program = Effect.ignore(task)
|
||
* ```
|
||
*
|
||
* @see {@link ignoreLogged} to log failures while ignoring them.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error handling
|
||
*/
|
||
export declare const ignore: <A, E, R>(self: Effect<A, E, R>) => Effect<void, never, R>;
|
||
/**
|
||
* Ignores the result of an effect but logs any failures.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function takes an effect and returns a new effect that ignores whether
|
||
* the original effect succeeds or fails. However, if the effect fails, it will
|
||
* log the failure at the Debug level, so you can keep track of any issues that
|
||
* arise.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is useful in scenarios where you want to continue with your program
|
||
* regardless of the result of the effect, but you still want to be aware of
|
||
* potential failures that may need attention later.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error handling
|
||
*/
|
||
export declare const ignoreLogged: <A, E, R>(self: Effect<A, E, R>) => Effect<void, never, R>;
|
||
/**
|
||
* Combines all errors from concurrent operations into a single error.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function is used when you have multiple operations running at the same
|
||
* time, and you want to capture all the errors that occur across those
|
||
* operations. Instead of handling each error separately, it combines all the
|
||
* errors into one unified error.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* When using this function, any errors that occur in the concurrently running
|
||
* operations will be grouped together into a single error. This helps simplify
|
||
* error handling in cases where you don't need to differentiate between each
|
||
* failure, but simply want to know that multiple failures occurred.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const fail1 = Effect.fail("Oh uh!")
|
||
* const fail2 = Effect.fail("Oh no!")
|
||
* const die = Effect.dieMessage("Boom!")
|
||
*
|
||
* // Run all effects concurrently and capture all errors
|
||
* const program = Effect.all([fail1, fail2, die], {
|
||
* concurrency: "unbounded"
|
||
* }).pipe(Effect.asVoid, Effect.parallelErrors)
|
||
*
|
||
* Effect.runPromiseExit(program).then(console.log)
|
||
* // Output:
|
||
* // {
|
||
* // _id: 'Exit',
|
||
* // _tag: 'Failure',
|
||
* // cause: { _id: 'Cause', _tag: 'Fail', failure: [ 'Oh uh!', 'Oh no!' ] }
|
||
* // }
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error handling
|
||
*/
|
||
export declare const parallelErrors: <A, E, R>(self: Effect<A, E, R>) => Effect<A, Array<E>, R>;
|
||
/**
|
||
* Transforms an effect to expose detailed error causes.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function enhances an effect by providing detailed information about any
|
||
* error, defect, or interruption that may occur during its execution. It
|
||
* modifies the error channel of the effect so that it includes a full cause of
|
||
* the failure, wrapped in a `Cause<E>` type.
|
||
*
|
||
* After applying this function, you can use operators like {@link catchAll} and
|
||
* {@link catchTags} to handle specific types of errors.
|
||
*
|
||
* If you no longer need the detailed cause information, you can revert the
|
||
* changes using {@link unsandbox} to return to the original error-handling
|
||
* behavior.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* // ┌─── Effect<string, Error, never>
|
||
* // ▼
|
||
* const task = Effect.fail(new Error("Oh uh!")).pipe(
|
||
* Effect.as("primary result")
|
||
* )
|
||
*
|
||
* // ┌─── Effect<string, Cause<Error>, never>
|
||
* // ▼
|
||
* const sandboxed = Effect.sandbox(task)
|
||
*
|
||
* const program = Effect.catchTags(sandboxed, {
|
||
* Die: (cause) =>
|
||
* Console.log(`Caught a defect: ${cause.defect}`).pipe(
|
||
* Effect.as("fallback result on defect")
|
||
* ),
|
||
* Interrupt: (cause) =>
|
||
* Console.log(`Caught a defect: ${cause.fiberId}`).pipe(
|
||
* Effect.as("fallback result on fiber interruption")
|
||
* ),
|
||
* Fail: (cause) =>
|
||
* Console.log(`Caught a defect: ${cause.error}`).pipe(
|
||
* Effect.as("fallback result on failure")
|
||
* )
|
||
* })
|
||
*
|
||
* // Restore the original error handling with unsandbox
|
||
* const main = Effect.unsandbox(program)
|
||
*
|
||
* Effect.runPromise(main).then(console.log)
|
||
* // Output:
|
||
* // Caught a defect: Oh uh!
|
||
* // fallback result on failure
|
||
* ```
|
||
*
|
||
* @see {@link unsandbox} to restore the original error handling.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error handling
|
||
*/
|
||
export declare const sandbox: <A, E, R>(self: Effect<A, E, R>) => Effect<A, Cause.Cause<E>, R>;
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Error handling
|
||
*/
|
||
export declare namespace Retry {
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Error handling
|
||
*/
|
||
type Return<R, E, A, O extends NoExcessProperties<Options<E>, O>> = Effect<A, (O extends {
|
||
schedule: Schedule.Schedule<infer _O, infer _I, infer _R>;
|
||
} ? E : O extends {
|
||
until: Refinement<E, infer E2>;
|
||
} ? E2 : E) | (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.Schedule<infer _O, infer _I, infer R>;
|
||
} ? R : never) | (O extends {
|
||
while: (...args: Array<any>) => Effect<infer _A, infer _E, infer R>;
|
||
} ? R : never) | (O extends {
|
||
until: (...args: Array<any>) => Effect<infer _A, infer _E, infer R>;
|
||
} ? R : never)> extends infer Z ? Z : never;
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Error handling
|
||
*/
|
||
interface Options<E> {
|
||
while?: ((error: E) => boolean | Effect<boolean, any, any>) | undefined;
|
||
until?: ((error: E) => boolean | Effect<boolean, any, any>) | undefined;
|
||
times?: number | undefined;
|
||
schedule?: Schedule.Schedule<any, E, any> | undefined;
|
||
}
|
||
}
|
||
/**
|
||
* Retries a failing effect based on a defined retry policy.
|
||
*
|
||
* **Details**
|
||
*
|
||
* The `Effect.retry` function takes an effect and a {@link Schedule} policy,
|
||
* and will automatically retry the effect if it fails, following the rules of
|
||
* the policy.
|
||
*
|
||
* If the effect ultimately succeeds, the result will be returned.
|
||
*
|
||
* If the maximum retries are exhausted and the effect still fails, the failure
|
||
* is propagated.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This can be useful when dealing with intermittent failures, such as network
|
||
* issues or temporary resource unavailability. By defining a retry policy, you
|
||
* can control the number of retries, the delay between them, and when to stop
|
||
* retrying.
|
||
*
|
||
* **Example** (Retrying with a Fixed Delay)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Schedule } from "effect"
|
||
*
|
||
* let count = 0
|
||
*
|
||
* // Simulates an effect with possible failures
|
||
* const task = Effect.async<string, Error>((resume) => {
|
||
* if (count <= 2) {
|
||
* count++
|
||
* console.log("failure")
|
||
* resume(Effect.fail(new Error()))
|
||
* } else {
|
||
* console.log("success")
|
||
* resume(Effect.succeed("yay!"))
|
||
* }
|
||
* })
|
||
*
|
||
* // Define a repetition policy using a fixed delay between retries
|
||
* const policy = Schedule.fixed("100 millis")
|
||
*
|
||
* const repeated = Effect.retry(task, policy)
|
||
*
|
||
* Effect.runPromise(repeated).then(console.log)
|
||
* // Output:
|
||
* // failure
|
||
* // failure
|
||
* // failure
|
||
* // success
|
||
* // yay!
|
||
* ```
|
||
*
|
||
* **Example** (Retrying a Task up to 5 times)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* let count = 0
|
||
*
|
||
* // Simulates an effect with possible failures
|
||
* const task = Effect.async<string, Error>((resume) => {
|
||
* if (count <= 2) {
|
||
* count++
|
||
* console.log("failure")
|
||
* resume(Effect.fail(new Error()))
|
||
* } else {
|
||
* console.log("success")
|
||
* resume(Effect.succeed("yay!"))
|
||
* }
|
||
* })
|
||
*
|
||
* // Retry the task up to 5 times
|
||
* Effect.runPromise(Effect.retry(task, { times: 5 })).then(console.log)
|
||
* // Output:
|
||
* // failure
|
||
* // failure
|
||
* // failure
|
||
* // success
|
||
* ```
|
||
*
|
||
* **Example** (Retrying Until a Specific Condition is Met)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* let count = 0
|
||
*
|
||
* // Define an effect that simulates varying error on each invocation
|
||
* const action = Effect.failSync(() => {
|
||
* console.log(`Action called ${++count} time(s)`)
|
||
* return `Error ${count}`
|
||
* })
|
||
*
|
||
* // Retry the action until a specific condition is met
|
||
* const program = Effect.retry(action, {
|
||
* until: (err) => err === "Error 3"
|
||
* })
|
||
*
|
||
* Effect.runPromiseExit(program).then(console.log)
|
||
* // Output:
|
||
* // Action called 1 time(s)
|
||
* // Action called 2 time(s)
|
||
* // Action called 3 time(s)
|
||
* // {
|
||
* // _id: 'Exit',
|
||
* // _tag: 'Failure',
|
||
* // cause: { _id: 'Cause', _tag: 'Fail', failure: 'Error 3' }
|
||
* // }
|
||
* ```
|
||
*
|
||
* @see {@link retryOrElse} for a version that allows you to run a fallback.
|
||
* @see {@link repeat} if your retry condition is based on successful outcomes rather than errors.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error handling
|
||
*/
|
||
export declare const retry: {
|
||
/**
|
||
* Retries a failing effect based on a defined retry policy.
|
||
*
|
||
* **Details**
|
||
*
|
||
* The `Effect.retry` function takes an effect and a {@link Schedule} policy,
|
||
* and will automatically retry the effect if it fails, following the rules of
|
||
* the policy.
|
||
*
|
||
* If the effect ultimately succeeds, the result will be returned.
|
||
*
|
||
* If the maximum retries are exhausted and the effect still fails, the failure
|
||
* is propagated.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This can be useful when dealing with intermittent failures, such as network
|
||
* issues or temporary resource unavailability. By defining a retry policy, you
|
||
* can control the number of retries, the delay between them, and when to stop
|
||
* retrying.
|
||
*
|
||
* **Example** (Retrying with a Fixed Delay)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Schedule } from "effect"
|
||
*
|
||
* let count = 0
|
||
*
|
||
* // Simulates an effect with possible failures
|
||
* const task = Effect.async<string, Error>((resume) => {
|
||
* if (count <= 2) {
|
||
* count++
|
||
* console.log("failure")
|
||
* resume(Effect.fail(new Error()))
|
||
* } else {
|
||
* console.log("success")
|
||
* resume(Effect.succeed("yay!"))
|
||
* }
|
||
* })
|
||
*
|
||
* // Define a repetition policy using a fixed delay between retries
|
||
* const policy = Schedule.fixed("100 millis")
|
||
*
|
||
* const repeated = Effect.retry(task, policy)
|
||
*
|
||
* Effect.runPromise(repeated).then(console.log)
|
||
* // Output:
|
||
* // failure
|
||
* // failure
|
||
* // failure
|
||
* // success
|
||
* // yay!
|
||
* ```
|
||
*
|
||
* **Example** (Retrying a Task up to 5 times)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* let count = 0
|
||
*
|
||
* // Simulates an effect with possible failures
|
||
* const task = Effect.async<string, Error>((resume) => {
|
||
* if (count <= 2) {
|
||
* count++
|
||
* console.log("failure")
|
||
* resume(Effect.fail(new Error()))
|
||
* } else {
|
||
* console.log("success")
|
||
* resume(Effect.succeed("yay!"))
|
||
* }
|
||
* })
|
||
*
|
||
* // Retry the task up to 5 times
|
||
* Effect.runPromise(Effect.retry(task, { times: 5 })).then(console.log)
|
||
* // Output:
|
||
* // failure
|
||
* // failure
|
||
* // failure
|
||
* // success
|
||
* ```
|
||
*
|
||
* **Example** (Retrying Until a Specific Condition is Met)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* let count = 0
|
||
*
|
||
* // Define an effect that simulates varying error on each invocation
|
||
* const action = Effect.failSync(() => {
|
||
* console.log(`Action called ${++count} time(s)`)
|
||
* return `Error ${count}`
|
||
* })
|
||
*
|
||
* // Retry the action until a specific condition is met
|
||
* const program = Effect.retry(action, {
|
||
* until: (err) => err === "Error 3"
|
||
* })
|
||
*
|
||
* Effect.runPromiseExit(program).then(console.log)
|
||
* // Output:
|
||
* // Action called 1 time(s)
|
||
* // Action called 2 time(s)
|
||
* // Action called 3 time(s)
|
||
* // {
|
||
* // _id: 'Exit',
|
||
* // _tag: 'Failure',
|
||
* // cause: { _id: 'Cause', _tag: 'Fail', failure: 'Error 3' }
|
||
* // }
|
||
* ```
|
||
*
|
||
* @see {@link retryOrElse} for a version that allows you to run a fallback.
|
||
* @see {@link repeat} if your retry condition is based on successful outcomes rather than errors.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error handling
|
||
*/
|
||
<E, O extends NoExcessProperties<Retry.Options<E>, O>>(options: O): <A, R>(self: Effect<A, E, R>) => Retry.Return<R, E, A, O>;
|
||
/**
|
||
* Retries a failing effect based on a defined retry policy.
|
||
*
|
||
* **Details**
|
||
*
|
||
* The `Effect.retry` function takes an effect and a {@link Schedule} policy,
|
||
* and will automatically retry the effect if it fails, following the rules of
|
||
* the policy.
|
||
*
|
||
* If the effect ultimately succeeds, the result will be returned.
|
||
*
|
||
* If the maximum retries are exhausted and the effect still fails, the failure
|
||
* is propagated.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This can be useful when dealing with intermittent failures, such as network
|
||
* issues or temporary resource unavailability. By defining a retry policy, you
|
||
* can control the number of retries, the delay between them, and when to stop
|
||
* retrying.
|
||
*
|
||
* **Example** (Retrying with a Fixed Delay)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Schedule } from "effect"
|
||
*
|
||
* let count = 0
|
||
*
|
||
* // Simulates an effect with possible failures
|
||
* const task = Effect.async<string, Error>((resume) => {
|
||
* if (count <= 2) {
|
||
* count++
|
||
* console.log("failure")
|
||
* resume(Effect.fail(new Error()))
|
||
* } else {
|
||
* console.log("success")
|
||
* resume(Effect.succeed("yay!"))
|
||
* }
|
||
* })
|
||
*
|
||
* // Define a repetition policy using a fixed delay between retries
|
||
* const policy = Schedule.fixed("100 millis")
|
||
*
|
||
* const repeated = Effect.retry(task, policy)
|
||
*
|
||
* Effect.runPromise(repeated).then(console.log)
|
||
* // Output:
|
||
* // failure
|
||
* // failure
|
||
* // failure
|
||
* // success
|
||
* // yay!
|
||
* ```
|
||
*
|
||
* **Example** (Retrying a Task up to 5 times)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* let count = 0
|
||
*
|
||
* // Simulates an effect with possible failures
|
||
* const task = Effect.async<string, Error>((resume) => {
|
||
* if (count <= 2) {
|
||
* count++
|
||
* console.log("failure")
|
||
* resume(Effect.fail(new Error()))
|
||
* } else {
|
||
* console.log("success")
|
||
* resume(Effect.succeed("yay!"))
|
||
* }
|
||
* })
|
||
*
|
||
* // Retry the task up to 5 times
|
||
* Effect.runPromise(Effect.retry(task, { times: 5 })).then(console.log)
|
||
* // Output:
|
||
* // failure
|
||
* // failure
|
||
* // failure
|
||
* // success
|
||
* ```
|
||
*
|
||
* **Example** (Retrying Until a Specific Condition is Met)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* let count = 0
|
||
*
|
||
* // Define an effect that simulates varying error on each invocation
|
||
* const action = Effect.failSync(() => {
|
||
* console.log(`Action called ${++count} time(s)`)
|
||
* return `Error ${count}`
|
||
* })
|
||
*
|
||
* // Retry the action until a specific condition is met
|
||
* const program = Effect.retry(action, {
|
||
* until: (err) => err === "Error 3"
|
||
* })
|
||
*
|
||
* Effect.runPromiseExit(program).then(console.log)
|
||
* // Output:
|
||
* // Action called 1 time(s)
|
||
* // Action called 2 time(s)
|
||
* // Action called 3 time(s)
|
||
* // {
|
||
* // _id: 'Exit',
|
||
* // _tag: 'Failure',
|
||
* // cause: { _id: 'Cause', _tag: 'Fail', failure: 'Error 3' }
|
||
* // }
|
||
* ```
|
||
*
|
||
* @see {@link retryOrElse} for a version that allows you to run a fallback.
|
||
* @see {@link repeat} if your retry condition is based on successful outcomes rather than errors.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error handling
|
||
*/
|
||
<B, E, R1>(policy: Schedule.Schedule<B, NoInfer<E>, R1>): <A, R>(self: Effect<A, E, R>) => Effect<A, E, R1 | R>;
|
||
/**
|
||
* Retries a failing effect based on a defined retry policy.
|
||
*
|
||
* **Details**
|
||
*
|
||
* The `Effect.retry` function takes an effect and a {@link Schedule} policy,
|
||
* and will automatically retry the effect if it fails, following the rules of
|
||
* the policy.
|
||
*
|
||
* If the effect ultimately succeeds, the result will be returned.
|
||
*
|
||
* If the maximum retries are exhausted and the effect still fails, the failure
|
||
* is propagated.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This can be useful when dealing with intermittent failures, such as network
|
||
* issues or temporary resource unavailability. By defining a retry policy, you
|
||
* can control the number of retries, the delay between them, and when to stop
|
||
* retrying.
|
||
*
|
||
* **Example** (Retrying with a Fixed Delay)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Schedule } from "effect"
|
||
*
|
||
* let count = 0
|
||
*
|
||
* // Simulates an effect with possible failures
|
||
* const task = Effect.async<string, Error>((resume) => {
|
||
* if (count <= 2) {
|
||
* count++
|
||
* console.log("failure")
|
||
* resume(Effect.fail(new Error()))
|
||
* } else {
|
||
* console.log("success")
|
||
* resume(Effect.succeed("yay!"))
|
||
* }
|
||
* })
|
||
*
|
||
* // Define a repetition policy using a fixed delay between retries
|
||
* const policy = Schedule.fixed("100 millis")
|
||
*
|
||
* const repeated = Effect.retry(task, policy)
|
||
*
|
||
* Effect.runPromise(repeated).then(console.log)
|
||
* // Output:
|
||
* // failure
|
||
* // failure
|
||
* // failure
|
||
* // success
|
||
* // yay!
|
||
* ```
|
||
*
|
||
* **Example** (Retrying a Task up to 5 times)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* let count = 0
|
||
*
|
||
* // Simulates an effect with possible failures
|
||
* const task = Effect.async<string, Error>((resume) => {
|
||
* if (count <= 2) {
|
||
* count++
|
||
* console.log("failure")
|
||
* resume(Effect.fail(new Error()))
|
||
* } else {
|
||
* console.log("success")
|
||
* resume(Effect.succeed("yay!"))
|
||
* }
|
||
* })
|
||
*
|
||
* // Retry the task up to 5 times
|
||
* Effect.runPromise(Effect.retry(task, { times: 5 })).then(console.log)
|
||
* // Output:
|
||
* // failure
|
||
* // failure
|
||
* // failure
|
||
* // success
|
||
* ```
|
||
*
|
||
* **Example** (Retrying Until a Specific Condition is Met)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* let count = 0
|
||
*
|
||
* // Define an effect that simulates varying error on each invocation
|
||
* const action = Effect.failSync(() => {
|
||
* console.log(`Action called ${++count} time(s)`)
|
||
* return `Error ${count}`
|
||
* })
|
||
*
|
||
* // Retry the action until a specific condition is met
|
||
* const program = Effect.retry(action, {
|
||
* until: (err) => err === "Error 3"
|
||
* })
|
||
*
|
||
* Effect.runPromiseExit(program).then(console.log)
|
||
* // Output:
|
||
* // Action called 1 time(s)
|
||
* // Action called 2 time(s)
|
||
* // Action called 3 time(s)
|
||
* // {
|
||
* // _id: 'Exit',
|
||
* // _tag: 'Failure',
|
||
* // cause: { _id: 'Cause', _tag: 'Fail', failure: 'Error 3' }
|
||
* // }
|
||
* ```
|
||
*
|
||
* @see {@link retryOrElse} for a version that allows you to run a fallback.
|
||
* @see {@link repeat} if your retry condition is based on successful outcomes rather than errors.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error handling
|
||
*/
|
||
<A, E, R, O extends NoExcessProperties<Retry.Options<E>, O>>(self: Effect<A, E, R>, options: O): Retry.Return<R, E, A, O>;
|
||
/**
|
||
* Retries a failing effect based on a defined retry policy.
|
||
*
|
||
* **Details**
|
||
*
|
||
* The `Effect.retry` function takes an effect and a {@link Schedule} policy,
|
||
* and will automatically retry the effect if it fails, following the rules of
|
||
* the policy.
|
||
*
|
||
* If the effect ultimately succeeds, the result will be returned.
|
||
*
|
||
* If the maximum retries are exhausted and the effect still fails, the failure
|
||
* is propagated.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This can be useful when dealing with intermittent failures, such as network
|
||
* issues or temporary resource unavailability. By defining a retry policy, you
|
||
* can control the number of retries, the delay between them, and when to stop
|
||
* retrying.
|
||
*
|
||
* **Example** (Retrying with a Fixed Delay)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Schedule } from "effect"
|
||
*
|
||
* let count = 0
|
||
*
|
||
* // Simulates an effect with possible failures
|
||
* const task = Effect.async<string, Error>((resume) => {
|
||
* if (count <= 2) {
|
||
* count++
|
||
* console.log("failure")
|
||
* resume(Effect.fail(new Error()))
|
||
* } else {
|
||
* console.log("success")
|
||
* resume(Effect.succeed("yay!"))
|
||
* }
|
||
* })
|
||
*
|
||
* // Define a repetition policy using a fixed delay between retries
|
||
* const policy = Schedule.fixed("100 millis")
|
||
*
|
||
* const repeated = Effect.retry(task, policy)
|
||
*
|
||
* Effect.runPromise(repeated).then(console.log)
|
||
* // Output:
|
||
* // failure
|
||
* // failure
|
||
* // failure
|
||
* // success
|
||
* // yay!
|
||
* ```
|
||
*
|
||
* **Example** (Retrying a Task up to 5 times)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* let count = 0
|
||
*
|
||
* // Simulates an effect with possible failures
|
||
* const task = Effect.async<string, Error>((resume) => {
|
||
* if (count <= 2) {
|
||
* count++
|
||
* console.log("failure")
|
||
* resume(Effect.fail(new Error()))
|
||
* } else {
|
||
* console.log("success")
|
||
* resume(Effect.succeed("yay!"))
|
||
* }
|
||
* })
|
||
*
|
||
* // Retry the task up to 5 times
|
||
* Effect.runPromise(Effect.retry(task, { times: 5 })).then(console.log)
|
||
* // Output:
|
||
* // failure
|
||
* // failure
|
||
* // failure
|
||
* // success
|
||
* ```
|
||
*
|
||
* **Example** (Retrying Until a Specific Condition is Met)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* let count = 0
|
||
*
|
||
* // Define an effect that simulates varying error on each invocation
|
||
* const action = Effect.failSync(() => {
|
||
* console.log(`Action called ${++count} time(s)`)
|
||
* return `Error ${count}`
|
||
* })
|
||
*
|
||
* // Retry the action until a specific condition is met
|
||
* const program = Effect.retry(action, {
|
||
* until: (err) => err === "Error 3"
|
||
* })
|
||
*
|
||
* Effect.runPromiseExit(program).then(console.log)
|
||
* // Output:
|
||
* // Action called 1 time(s)
|
||
* // Action called 2 time(s)
|
||
* // Action called 3 time(s)
|
||
* // {
|
||
* // _id: 'Exit',
|
||
* // _tag: 'Failure',
|
||
* // cause: { _id: 'Cause', _tag: 'Fail', failure: 'Error 3' }
|
||
* // }
|
||
* ```
|
||
*
|
||
* @see {@link retryOrElse} for a version that allows you to run a fallback.
|
||
* @see {@link repeat} if your retry condition is based on successful outcomes rather than errors.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error handling
|
||
*/
|
||
<A, E, R, B, R1>(self: Effect<A, E, R>, policy: Schedule.Schedule<B, NoInfer<E>, R1>): Effect<A, E, R1 | R>;
|
||
};
|
||
/**
|
||
* Apply an `ExecutionPlan` to the effect, which allows you to fallback to
|
||
* different resources in case of failure.
|
||
*
|
||
* @since 3.16.0
|
||
* @category Error handling
|
||
* @experimental
|
||
*/
|
||
export declare const withExecutionPlan: {
|
||
/**
|
||
* Apply an `ExecutionPlan` to the effect, which allows you to fallback to
|
||
* different resources in case of failure.
|
||
*
|
||
* @since 3.16.0
|
||
* @category Error handling
|
||
* @experimental
|
||
*/
|
||
<Input, Provides, PlanE, PlanR>(plan: ExecutionPlan<{
|
||
provides: Provides;
|
||
input: Input;
|
||
error: PlanE;
|
||
requirements: PlanR;
|
||
}>): <A, E extends Input, R>(effect: Effect<A, E, R>) => Effect<A, E | PlanE, Exclude<R, Provides> | PlanR>;
|
||
/**
|
||
* Apply an `ExecutionPlan` to the effect, which allows you to fallback to
|
||
* different resources in case of failure.
|
||
*
|
||
* @since 3.16.0
|
||
* @category Error handling
|
||
* @experimental
|
||
*/
|
||
<A, E extends Input, R, Provides, Input, PlanE, PlanR>(effect: Effect<A, E, R>, plan: ExecutionPlan<{
|
||
provides: Provides;
|
||
input: Input;
|
||
error: PlanE;
|
||
requirements: PlanR;
|
||
}>): Effect<A, E | PlanE, Exclude<R, Provides> | PlanR>;
|
||
};
|
||
/**
|
||
* Retries a failing effect and runs a fallback effect if retries are exhausted.
|
||
*
|
||
* **Details**
|
||
*
|
||
* The `Effect.retryOrElse` function attempts to retry a failing effect multiple
|
||
* times according to a defined {@link Schedule} policy.
|
||
*
|
||
* If the retries are exhausted and the effect still fails, it runs a fallback
|
||
* effect instead.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This function is useful when you want to handle failures gracefully by
|
||
* specifying an alternative action after repeated failures.
|
||
*
|
||
* **Example** (Retrying with Fallback)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Schedule, Console } from "effect"
|
||
*
|
||
* let count = 0
|
||
*
|
||
* // Simulates an effect with possible failures
|
||
* const task = Effect.async<string, Error>((resume) => {
|
||
* if (count <= 2) {
|
||
* count++
|
||
* console.log("failure")
|
||
* resume(Effect.fail(new Error()))
|
||
* } else {
|
||
* console.log("success")
|
||
* resume(Effect.succeed("yay!"))
|
||
* }
|
||
* })
|
||
*
|
||
* // Retry the task with a delay between retries and a maximum of 2 retries
|
||
* const policy = Schedule.addDelay(Schedule.recurs(2), () => "100 millis")
|
||
*
|
||
* // If all retries fail, run the fallback effect
|
||
* const repeated = Effect.retryOrElse(
|
||
* task,
|
||
* policy,
|
||
* // fallback
|
||
* () => Console.log("orElse").pipe(Effect.as("default value"))
|
||
* )
|
||
*
|
||
* Effect.runPromise(repeated).then(console.log)
|
||
* // Output:
|
||
* // failure
|
||
* // failure
|
||
* // failure
|
||
* // orElse
|
||
* // default value
|
||
* ```
|
||
*
|
||
* @see {@link retry} for a version that does not run a fallback effect.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error handling
|
||
*/
|
||
export declare const retryOrElse: {
|
||
/**
|
||
* Retries a failing effect and runs a fallback effect if retries are exhausted.
|
||
*
|
||
* **Details**
|
||
*
|
||
* The `Effect.retryOrElse` function attempts to retry a failing effect multiple
|
||
* times according to a defined {@link Schedule} policy.
|
||
*
|
||
* If the retries are exhausted and the effect still fails, it runs a fallback
|
||
* effect instead.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This function is useful when you want to handle failures gracefully by
|
||
* specifying an alternative action after repeated failures.
|
||
*
|
||
* **Example** (Retrying with Fallback)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Schedule, Console } from "effect"
|
||
*
|
||
* let count = 0
|
||
*
|
||
* // Simulates an effect with possible failures
|
||
* const task = Effect.async<string, Error>((resume) => {
|
||
* if (count <= 2) {
|
||
* count++
|
||
* console.log("failure")
|
||
* resume(Effect.fail(new Error()))
|
||
* } else {
|
||
* console.log("success")
|
||
* resume(Effect.succeed("yay!"))
|
||
* }
|
||
* })
|
||
*
|
||
* // Retry the task with a delay between retries and a maximum of 2 retries
|
||
* const policy = Schedule.addDelay(Schedule.recurs(2), () => "100 millis")
|
||
*
|
||
* // If all retries fail, run the fallback effect
|
||
* const repeated = Effect.retryOrElse(
|
||
* task,
|
||
* policy,
|
||
* // fallback
|
||
* () => Console.log("orElse").pipe(Effect.as("default value"))
|
||
* )
|
||
*
|
||
* Effect.runPromise(repeated).then(console.log)
|
||
* // Output:
|
||
* // failure
|
||
* // failure
|
||
* // failure
|
||
* // orElse
|
||
* // default value
|
||
* ```
|
||
*
|
||
* @see {@link retry} for a version that does not run a fallback effect.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error handling
|
||
*/
|
||
<A1, E, R1, A2, E2, R2>(policy: Schedule.Schedule<A1, NoInfer<E>, R1>, orElse: (e: NoInfer<E>, out: A1) => Effect<A2, E2, R2>): <A, R>(self: Effect<A, E, R>) => Effect<A2 | A, E2, R1 | R2 | R>;
|
||
/**
|
||
* Retries a failing effect and runs a fallback effect if retries are exhausted.
|
||
*
|
||
* **Details**
|
||
*
|
||
* The `Effect.retryOrElse` function attempts to retry a failing effect multiple
|
||
* times according to a defined {@link Schedule} policy.
|
||
*
|
||
* If the retries are exhausted and the effect still fails, it runs a fallback
|
||
* effect instead.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This function is useful when you want to handle failures gracefully by
|
||
* specifying an alternative action after repeated failures.
|
||
*
|
||
* **Example** (Retrying with Fallback)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Schedule, Console } from "effect"
|
||
*
|
||
* let count = 0
|
||
*
|
||
* // Simulates an effect with possible failures
|
||
* const task = Effect.async<string, Error>((resume) => {
|
||
* if (count <= 2) {
|
||
* count++
|
||
* console.log("failure")
|
||
* resume(Effect.fail(new Error()))
|
||
* } else {
|
||
* console.log("success")
|
||
* resume(Effect.succeed("yay!"))
|
||
* }
|
||
* })
|
||
*
|
||
* // Retry the task with a delay between retries and a maximum of 2 retries
|
||
* const policy = Schedule.addDelay(Schedule.recurs(2), () => "100 millis")
|
||
*
|
||
* // If all retries fail, run the fallback effect
|
||
* const repeated = Effect.retryOrElse(
|
||
* task,
|
||
* policy,
|
||
* // fallback
|
||
* () => Console.log("orElse").pipe(Effect.as("default value"))
|
||
* )
|
||
*
|
||
* Effect.runPromise(repeated).then(console.log)
|
||
* // Output:
|
||
* // failure
|
||
* // failure
|
||
* // failure
|
||
* // orElse
|
||
* // default value
|
||
* ```
|
||
*
|
||
* @see {@link retry} for a version that does not run a fallback effect.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error handling
|
||
*/
|
||
<A, E, R, A1, R1, A2, E2, R2>(self: Effect<A, E, R>, policy: Schedule.Schedule<A1, NoInfer<E>, R1>, orElse: (e: NoInfer<E>, out: A1) => Effect<A2, E2, R2>): Effect<A | A2, E2, R | R1 | R2>;
|
||
};
|
||
declare const try_: {
|
||
<A, E>(options: {
|
||
readonly try: LazyArg<A>;
|
||
readonly catch: (error: unknown) => E;
|
||
}): Effect<A, E>;
|
||
<A>(thunk: LazyArg<A>): Effect<A, Cause.UnknownException>;
|
||
};
|
||
export {
|
||
/**
|
||
* Creates an `Effect` that represents a synchronous computation that might
|
||
* fail.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* In situations where you need to perform synchronous operations that might
|
||
* fail, such as parsing JSON, you can use the `try` constructor. This
|
||
* constructor is designed to handle operations that could throw exceptions by
|
||
* capturing those exceptions and transforming them into manageable errors.
|
||
*
|
||
* **Error Handling**
|
||
*
|
||
* There are two ways to handle errors with `try`:
|
||
*
|
||
* 1. If you don't provide a `catch` function, the error is caught and the
|
||
* effect fails with an `UnknownException`.
|
||
* 2. If you provide a `catch` function, the error is caught and the `catch`
|
||
* function maps it to an error of type `E`.
|
||
*
|
||
* **Example** (Safe JSON Parsing)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const parse = (input: string) =>
|
||
* // This might throw an error if input is not valid JSON
|
||
* Effect.try(() => JSON.parse(input))
|
||
*
|
||
* // ┌─── Effect<any, UnknownException, never>
|
||
* // ▼
|
||
* const program = parse("")
|
||
*
|
||
* ```
|
||
*
|
||
* **Example** (Custom Error Handling)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const parse = (input: string) =>
|
||
* Effect.try({
|
||
* // JSON.parse may throw for bad input
|
||
* try: () => JSON.parse(input),
|
||
* // remap the error
|
||
* catch: (unknown) => new Error(`something went wrong ${unknown}`)
|
||
* })
|
||
*
|
||
* // ┌─── Effect<any, Error, never>
|
||
* // ▼
|
||
* const program = parse("")
|
||
* ```
|
||
*
|
||
* @see {@link sync} if the effectful computation is synchronous and does not
|
||
* throw errors.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Creating Effects
|
||
*/
|
||
try_ as try };
|
||
/**
|
||
* Returns an effect that maps its success using the specified side-effecting
|
||
* `try` function, converting any errors into typed failed effects using the
|
||
* `catch` function.
|
||
*
|
||
* @see {@link tryPromise} for a version that works with asynchronous computations.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error handling
|
||
*/
|
||
export declare const tryMap: {
|
||
/**
|
||
* Returns an effect that maps its success using the specified side-effecting
|
||
* `try` function, converting any errors into typed failed effects using the
|
||
* `catch` function.
|
||
*
|
||
* @see {@link tryPromise} for a version that works with asynchronous computations.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error handling
|
||
*/
|
||
<A, B, E1>(options: {
|
||
readonly try: (a: A) => B;
|
||
readonly catch: (error: unknown) => E1;
|
||
}): <E, R>(self: Effect<A, E, R>) => Effect<B, E1 | E, R>;
|
||
/**
|
||
* Returns an effect that maps its success using the specified side-effecting
|
||
* `try` function, converting any errors into typed failed effects using the
|
||
* `catch` function.
|
||
*
|
||
* @see {@link tryPromise} for a version that works with asynchronous computations.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error handling
|
||
*/
|
||
<A, E, R, B, E1>(self: Effect<A, E, R>, options: {
|
||
readonly try: (a: A) => B;
|
||
readonly catch: (error: unknown) => E1;
|
||
}): Effect<B, E | E1, R>;
|
||
};
|
||
/**
|
||
* Returns an effect that maps its success using the specified side-effecting
|
||
* `try` function, converting any promise rejections into typed failed effects
|
||
* using the `catch` function.
|
||
*
|
||
* An optional `AbortSignal` can be provided to allow for interruption of the
|
||
* wrapped `Promise` API.
|
||
*
|
||
* @see {@link tryMap} for a version that works with synchronous computations.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error handling
|
||
*/
|
||
export declare const tryMapPromise: {
|
||
/**
|
||
* Returns an effect that maps its success using the specified side-effecting
|
||
* `try` function, converting any promise rejections into typed failed effects
|
||
* using the `catch` function.
|
||
*
|
||
* An optional `AbortSignal` can be provided to allow for interruption of the
|
||
* wrapped `Promise` API.
|
||
*
|
||
* @see {@link tryMap} for a version that works with synchronous computations.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error handling
|
||
*/
|
||
<A, B, E1>(options: {
|
||
readonly try: (a: A, signal: AbortSignal) => PromiseLike<B>;
|
||
readonly catch: (error: unknown) => E1;
|
||
}): <E, R>(self: Effect<A, E, R>) => Effect<B, E1 | E, R>;
|
||
/**
|
||
* Returns an effect that maps its success using the specified side-effecting
|
||
* `try` function, converting any promise rejections into typed failed effects
|
||
* using the `catch` function.
|
||
*
|
||
* An optional `AbortSignal` can be provided to allow for interruption of the
|
||
* wrapped `Promise` API.
|
||
*
|
||
* @see {@link tryMap} for a version that works with synchronous computations.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error handling
|
||
*/
|
||
<A, E, R, B, E1>(self: Effect<A, E, R>, options: {
|
||
readonly try: (a: A, signal: AbortSignal) => PromiseLike<B>;
|
||
readonly catch: (error: unknown) => E1;
|
||
}): Effect<B, E | E1, R>;
|
||
};
|
||
/**
|
||
* Creates an `Effect` that represents an asynchronous computation that might
|
||
* fail.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* In situations where you need to perform asynchronous operations that might
|
||
* fail, such as fetching data from an API, you can use the `tryPromise`
|
||
* constructor. This constructor is designed to handle operations that could
|
||
* throw exceptions by capturing those exceptions and transforming them into
|
||
* manageable errors.
|
||
*
|
||
* **Error Handling**
|
||
*
|
||
* There are two ways to handle errors with `tryPromise`:
|
||
*
|
||
* 1. If you don't provide a `catch` function, the error is caught and the
|
||
* effect fails with an `UnknownException`.
|
||
* 2. If you provide a `catch` function, the error is caught and the `catch`
|
||
* function maps it to an error of type `E`.
|
||
*
|
||
* **Interruptions**
|
||
*
|
||
* An optional `AbortSignal` can be provided to allow for interruption of the
|
||
* wrapped `Promise` API.
|
||
*
|
||
* **Example** (Fetching a TODO Item)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const getTodo = (id: number) =>
|
||
* // Will catch any errors and propagate them as UnknownException
|
||
* Effect.tryPromise(() =>
|
||
* fetch(`https://jsonplaceholder.typicode.com/todos/${id}`)
|
||
* )
|
||
*
|
||
* // ┌─── Effect<Response, UnknownException, never>
|
||
* // ▼
|
||
* const program = getTodo(1)
|
||
* ```
|
||
*
|
||
* **Example** (Custom Error Handling)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const getTodo = (id: number) =>
|
||
* Effect.tryPromise({
|
||
* try: () => fetch(`https://jsonplaceholder.typicode.com/todos/${id}`),
|
||
* // remap the error
|
||
* catch: (unknown) => new Error(`something went wrong ${unknown}`)
|
||
* })
|
||
*
|
||
* // ┌─── Effect<Response, Error, never>
|
||
* // ▼
|
||
* const program = getTodo(1)
|
||
* ```
|
||
*
|
||
* @see {@link promise} if the effectful computation is asynchronous and does not throw errors.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Creating Effects
|
||
*/
|
||
export declare const tryPromise: {
|
||
/**
|
||
* Creates an `Effect` that represents an asynchronous computation that might
|
||
* fail.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* In situations where you need to perform asynchronous operations that might
|
||
* fail, such as fetching data from an API, you can use the `tryPromise`
|
||
* constructor. This constructor is designed to handle operations that could
|
||
* throw exceptions by capturing those exceptions and transforming them into
|
||
* manageable errors.
|
||
*
|
||
* **Error Handling**
|
||
*
|
||
* There are two ways to handle errors with `tryPromise`:
|
||
*
|
||
* 1. If you don't provide a `catch` function, the error is caught and the
|
||
* effect fails with an `UnknownException`.
|
||
* 2. If you provide a `catch` function, the error is caught and the `catch`
|
||
* function maps it to an error of type `E`.
|
||
*
|
||
* **Interruptions**
|
||
*
|
||
* An optional `AbortSignal` can be provided to allow for interruption of the
|
||
* wrapped `Promise` API.
|
||
*
|
||
* **Example** (Fetching a TODO Item)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const getTodo = (id: number) =>
|
||
* // Will catch any errors and propagate them as UnknownException
|
||
* Effect.tryPromise(() =>
|
||
* fetch(`https://jsonplaceholder.typicode.com/todos/${id}`)
|
||
* )
|
||
*
|
||
* // ┌─── Effect<Response, UnknownException, never>
|
||
* // ▼
|
||
* const program = getTodo(1)
|
||
* ```
|
||
*
|
||
* **Example** (Custom Error Handling)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const getTodo = (id: number) =>
|
||
* Effect.tryPromise({
|
||
* try: () => fetch(`https://jsonplaceholder.typicode.com/todos/${id}`),
|
||
* // remap the error
|
||
* catch: (unknown) => new Error(`something went wrong ${unknown}`)
|
||
* })
|
||
*
|
||
* // ┌─── Effect<Response, Error, never>
|
||
* // ▼
|
||
* const program = getTodo(1)
|
||
* ```
|
||
*
|
||
* @see {@link promise} if the effectful computation is asynchronous and does not throw errors.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Creating Effects
|
||
*/
|
||
<A, E>(options: {
|
||
readonly try: (signal: AbortSignal) => PromiseLike<A>;
|
||
readonly catch: (error: unknown) => E;
|
||
}): Effect<A, E>;
|
||
/**
|
||
* Creates an `Effect` that represents an asynchronous computation that might
|
||
* fail.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* In situations where you need to perform asynchronous operations that might
|
||
* fail, such as fetching data from an API, you can use the `tryPromise`
|
||
* constructor. This constructor is designed to handle operations that could
|
||
* throw exceptions by capturing those exceptions and transforming them into
|
||
* manageable errors.
|
||
*
|
||
* **Error Handling**
|
||
*
|
||
* There are two ways to handle errors with `tryPromise`:
|
||
*
|
||
* 1. If you don't provide a `catch` function, the error is caught and the
|
||
* effect fails with an `UnknownException`.
|
||
* 2. If you provide a `catch` function, the error is caught and the `catch`
|
||
* function maps it to an error of type `E`.
|
||
*
|
||
* **Interruptions**
|
||
*
|
||
* An optional `AbortSignal` can be provided to allow for interruption of the
|
||
* wrapped `Promise` API.
|
||
*
|
||
* **Example** (Fetching a TODO Item)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const getTodo = (id: number) =>
|
||
* // Will catch any errors and propagate them as UnknownException
|
||
* Effect.tryPromise(() =>
|
||
* fetch(`https://jsonplaceholder.typicode.com/todos/${id}`)
|
||
* )
|
||
*
|
||
* // ┌─── Effect<Response, UnknownException, never>
|
||
* // ▼
|
||
* const program = getTodo(1)
|
||
* ```
|
||
*
|
||
* **Example** (Custom Error Handling)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const getTodo = (id: number) =>
|
||
* Effect.tryPromise({
|
||
* try: () => fetch(`https://jsonplaceholder.typicode.com/todos/${id}`),
|
||
* // remap the error
|
||
* catch: (unknown) => new Error(`something went wrong ${unknown}`)
|
||
* })
|
||
*
|
||
* // ┌─── Effect<Response, Error, never>
|
||
* // ▼
|
||
* const program = getTodo(1)
|
||
* ```
|
||
*
|
||
* @see {@link promise} if the effectful computation is asynchronous and does not throw errors.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Creating Effects
|
||
*/
|
||
<A>(evaluate: (signal: AbortSignal) => PromiseLike<A>): Effect<A, Cause.UnknownException>;
|
||
};
|
||
/**
|
||
* The `unsandbox` function is used to revert an effect that has been
|
||
* sandboxed by {@link sandbox}. When you apply `unsandbox`, the
|
||
* effect's error channel is restored to its original state, without the
|
||
* detailed `Cause<E>` information. This means that any underlying causes of
|
||
* errors, defects, or fiber interruptions are no longer exposed in the error
|
||
* channel.
|
||
*
|
||
* This function is useful when you want to remove the detailed error tracking
|
||
* provided by `sandbox` and return to the standard error handling for
|
||
* your effect. Once unsandboxed, the effect behaves as if `sandbox` was
|
||
* never applied.
|
||
*
|
||
* @see {@link sandbox} to expose the full cause of failures, defects, or interruptions.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error handling
|
||
*/
|
||
export declare const unsandbox: <A, E, R>(self: Effect<A, Cause.Cause<E>, R>) => Effect<A, E, R>;
|
||
/**
|
||
* Allows interruption of the current fiber, even in uninterruptible regions.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This effect checks whether any other fibers are attempting to interrupt the
|
||
* current fiber. If so, it allows the current fiber to perform a
|
||
* self-interruption.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is useful in situations where you want to allow interruption to happen
|
||
* even in regions of the code that are normally uninterruptible.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Interruption
|
||
*/
|
||
export declare const allowInterrupt: Effect<void>;
|
||
/**
|
||
* Checks if interruption is allowed and executes a callback accordingly.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function checks the current interrupt status of the running fiber. It
|
||
* then calls the provided callback, passing a boolean indicating whether
|
||
* interruption is allowed.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is useful for handling specific logic based on whether the current
|
||
* operation can be interrupted, such as when performing asynchronous operations
|
||
* or handling cancellation.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Console, Effect } from "effect"
|
||
*
|
||
* const program = Effect.gen(function*() {
|
||
* yield* Effect.checkInterruptible((isInterruptible) => {
|
||
* if (isInterruptible) {
|
||
* return Console.log("You can interrupt this operation.")
|
||
* } else {
|
||
* return Console.log("This operation cannot be interrupted.")
|
||
* }
|
||
* })
|
||
* })
|
||
*
|
||
* Effect.runPromise(program)
|
||
* // Output: You can interrupt this operation.
|
||
*
|
||
* Effect.runPromise(program.pipe(Effect.uninterruptible))
|
||
* // Output: This operation cannot be interrupted.
|
||
*
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Interruption
|
||
*/
|
||
export declare const checkInterruptible: <A, E, R>(f: (isInterruptible: boolean) => Effect<A, E, R>) => Effect<A, E, R>;
|
||
/**
|
||
* Provides a way to handle timeouts in uninterruptible effects, allowing them
|
||
* to continue in the background while the main control flow proceeds with the
|
||
* timeout error.
|
||
*
|
||
* **Details**
|
||
*
|
||
* The `disconnect` function allows an uninterruptible effect to continue
|
||
* running in the background, while enabling the main control flow to
|
||
* immediately recognize a timeout condition. This is useful when you want to
|
||
* avoid blocking the program due to long-running tasks, especially when those
|
||
* tasks do not need to affect the flow of the rest of the program.
|
||
*
|
||
* Without `disconnect`, an uninterruptible effect will ignore the
|
||
* timeout and continue executing until it completes. The timeout error will
|
||
* only be assessed after the effect finishes, which can cause delays in
|
||
* recognizing a timeout.
|
||
*
|
||
* With `disconnect`, the uninterruptible effect proceeds in the
|
||
* background while the main program flow can immediately handle the timeout
|
||
* error or trigger alternative logic. This enables faster timeout handling
|
||
* without waiting for the completion of the long-running task.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const longRunningTask = Effect.gen(function* () {
|
||
* console.log("Start heavy processing...")
|
||
* yield* Effect.sleep("5 seconds") // Simulate a long process
|
||
* console.log("Heavy processing done.")
|
||
* return "Data processed"
|
||
* })
|
||
*
|
||
* const timedEffect = longRunningTask.pipe(
|
||
* Effect.uninterruptible,
|
||
* // Allows the task to finish in the background if it times out
|
||
* Effect.disconnect,
|
||
* Effect.timeout("1 second")
|
||
* )
|
||
*
|
||
* Effect.runPromiseExit(timedEffect).then(console.log)
|
||
* // Output:
|
||
* // Start heavy processing...
|
||
* // {
|
||
* // _id: 'Exit',
|
||
* // _tag: 'Failure',
|
||
* // cause: {
|
||
* // _id: 'Cause',
|
||
* // _tag: 'Fail',
|
||
* // failure: { _tag: 'TimeoutException' }
|
||
* // }
|
||
* // }
|
||
* // Heavy processing done.
|
||
* ```
|
||
*
|
||
* @see {@link timeout} for a version that interrupts the effect.
|
||
* @see {@link uninterruptible} for creating an uninterruptible effect.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Interruption
|
||
*/
|
||
export declare const disconnect: <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, R>;
|
||
/**
|
||
* Represents an effect that interrupts the current fiber.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This effect models the explicit interruption of the fiber in which it runs.
|
||
* When executed, it causes the fiber to stop its operation immediately,
|
||
* capturing the interruption details such as the fiber's ID and its start time.
|
||
* The resulting interruption can be observed in the `Exit` type if the effect
|
||
* is run with functions like {@link runPromiseExit}.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const program = Effect.gen(function* () {
|
||
* console.log("start")
|
||
* yield* Effect.sleep("2 seconds")
|
||
* yield* Effect.interrupt
|
||
* console.log("done")
|
||
* return "some result"
|
||
* })
|
||
*
|
||
* Effect.runPromiseExit(program).then(console.log)
|
||
* // Output:
|
||
* // start
|
||
* // {
|
||
* // _id: 'Exit',
|
||
* // _tag: 'Failure',
|
||
* // cause: {
|
||
* // _id: 'Cause',
|
||
* // _tag: 'Interrupt',
|
||
* // fiberId: {
|
||
* // _id: 'FiberId',
|
||
* // _tag: 'Runtime',
|
||
* // id: 0,
|
||
* // startTimeMillis: ...
|
||
* // }
|
||
* // }
|
||
* // }
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Interruption
|
||
*/
|
||
export declare const interrupt: Effect<never>;
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Interruption
|
||
*/
|
||
export declare const interruptWith: (fiberId: FiberId.FiberId) => Effect<never>;
|
||
/**
|
||
* Marks an effect as interruptible.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Interruption
|
||
*/
|
||
export declare const interruptible: <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, R>;
|
||
/**
|
||
* This function behaves like {@link interruptible}, but it also provides a
|
||
* `restore` function. This function can be used to restore the interruptibility
|
||
* of any specific region of code.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Interruption
|
||
*/
|
||
export declare const interruptibleMask: <A, E, R>(f: (restore: <AX, EX, RX>(effect: Effect<AX, EX, RX>) => Effect<AX, EX, RX>) => Effect<A, E, R>) => Effect<A, E, R>;
|
||
/**
|
||
* Registers a cleanup effect to run when an effect is interrupted.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to specify an effect to run when the fiber is
|
||
* interrupted. This effect will be executed when the fiber is interrupted,
|
||
* allowing you to perform cleanup or other actions.
|
||
*
|
||
* **Example** (Running a Cleanup Action on Interruption)
|
||
*
|
||
* ```ts
|
||
* import { Console, Effect } from "effect"
|
||
*
|
||
* // This handler is executed when the fiber is interrupted
|
||
* const handler = Effect.onInterrupt((_fibers) => Console.log("Cleanup completed"))
|
||
*
|
||
* const success = Console.log("Task completed").pipe(Effect.as("some result"), handler)
|
||
*
|
||
* Effect.runFork(success)
|
||
* // Output:
|
||
* // Task completed
|
||
*
|
||
* const failure = Console.log("Task failed").pipe(Effect.andThen(Effect.fail("some error")), handler)
|
||
*
|
||
* Effect.runFork(failure)
|
||
* // Output:
|
||
* // Task failed
|
||
*
|
||
* const interruption = Console.log("Task interrupted").pipe(Effect.andThen(Effect.interrupt), handler)
|
||
*
|
||
* Effect.runFork(interruption)
|
||
* // Output:
|
||
* // Task interrupted
|
||
* // Cleanup completed
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Interruption
|
||
*/
|
||
export declare const onInterrupt: {
|
||
/**
|
||
* Registers a cleanup effect to run when an effect is interrupted.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to specify an effect to run when the fiber is
|
||
* interrupted. This effect will be executed when the fiber is interrupted,
|
||
* allowing you to perform cleanup or other actions.
|
||
*
|
||
* **Example** (Running a Cleanup Action on Interruption)
|
||
*
|
||
* ```ts
|
||
* import { Console, Effect } from "effect"
|
||
*
|
||
* // This handler is executed when the fiber is interrupted
|
||
* const handler = Effect.onInterrupt((_fibers) => Console.log("Cleanup completed"))
|
||
*
|
||
* const success = Console.log("Task completed").pipe(Effect.as("some result"), handler)
|
||
*
|
||
* Effect.runFork(success)
|
||
* // Output:
|
||
* // Task completed
|
||
*
|
||
* const failure = Console.log("Task failed").pipe(Effect.andThen(Effect.fail("some error")), handler)
|
||
*
|
||
* Effect.runFork(failure)
|
||
* // Output:
|
||
* // Task failed
|
||
*
|
||
* const interruption = Console.log("Task interrupted").pipe(Effect.andThen(Effect.interrupt), handler)
|
||
*
|
||
* Effect.runFork(interruption)
|
||
* // Output:
|
||
* // Task interrupted
|
||
* // Cleanup completed
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Interruption
|
||
*/
|
||
<X, R2>(cleanup: (interruptors: HashSet.HashSet<FiberId.FiberId>) => Effect<X, never, R2>): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, R2 | R>;
|
||
/**
|
||
* Registers a cleanup effect to run when an effect is interrupted.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to specify an effect to run when the fiber is
|
||
* interrupted. This effect will be executed when the fiber is interrupted,
|
||
* allowing you to perform cleanup or other actions.
|
||
*
|
||
* **Example** (Running a Cleanup Action on Interruption)
|
||
*
|
||
* ```ts
|
||
* import { Console, Effect } from "effect"
|
||
*
|
||
* // This handler is executed when the fiber is interrupted
|
||
* const handler = Effect.onInterrupt((_fibers) => Console.log("Cleanup completed"))
|
||
*
|
||
* const success = Console.log("Task completed").pipe(Effect.as("some result"), handler)
|
||
*
|
||
* Effect.runFork(success)
|
||
* // Output:
|
||
* // Task completed
|
||
*
|
||
* const failure = Console.log("Task failed").pipe(Effect.andThen(Effect.fail("some error")), handler)
|
||
*
|
||
* Effect.runFork(failure)
|
||
* // Output:
|
||
* // Task failed
|
||
*
|
||
* const interruption = Console.log("Task interrupted").pipe(Effect.andThen(Effect.interrupt), handler)
|
||
*
|
||
* Effect.runFork(interruption)
|
||
* // Output:
|
||
* // Task interrupted
|
||
* // Cleanup completed
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Interruption
|
||
*/
|
||
<A, E, R, X, R2>(self: Effect<A, E, R>, cleanup: (interruptors: HashSet.HashSet<FiberId.FiberId>) => Effect<X, never, R2>): Effect<A, E, R | R2>;
|
||
};
|
||
/**
|
||
* Marks an effect as uninterruptible.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Interruption
|
||
*/
|
||
export declare const uninterruptible: <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, R>;
|
||
/**
|
||
* This function behaves like {@link uninterruptible}, but it also provides a
|
||
* `restore` function. This function can be used to restore the interruptibility
|
||
* of any specific region of code.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Interruption
|
||
*/
|
||
export declare const uninterruptibleMask: <A, E, R>(f: (restore: <AX, EX, RX>(effect: Effect<AX, EX, RX>) => Effect<AX, EX, RX>) => Effect<A, E, R>) => Effect<A, E, R>;
|
||
/**
|
||
* Transforms a `Predicate` function into an `Effect` returning the input value if the predicate returns `true`
|
||
* or failing with specified error if the predicate fails
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const isPositive = (n: number): boolean => n > 0
|
||
*
|
||
* // succeeds with `1`
|
||
* Effect.liftPredicate(1, isPositive, n => `${n} is not positive`)
|
||
*
|
||
* // fails with `"0 is not positive"`
|
||
* Effect.liftPredicate(0, isPositive, n => `${n} is not positive`)
|
||
* ```
|
||
*
|
||
* @category Condition Checking
|
||
* @since 3.4.0
|
||
*/
|
||
export declare const liftPredicate: {
|
||
/**
|
||
* Transforms a `Predicate` function into an `Effect` returning the input value if the predicate returns `true`
|
||
* or failing with specified error if the predicate fails
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const isPositive = (n: number): boolean => n > 0
|
||
*
|
||
* // succeeds with `1`
|
||
* Effect.liftPredicate(1, isPositive, n => `${n} is not positive`)
|
||
*
|
||
* // fails with `"0 is not positive"`
|
||
* Effect.liftPredicate(0, isPositive, n => `${n} is not positive`)
|
||
* ```
|
||
*
|
||
* @category Condition Checking
|
||
* @since 3.4.0
|
||
*/
|
||
<T extends A, E, B extends T = T, A = T>(predicate: Refinement<T, B> | Predicate<T>, orFailWith: (a: EqualsWith<T, B, A, Exclude<A, B>>) => E): (a: A) => Effect<EqualsWith<T, B, A, B>, E>;
|
||
/**
|
||
* Transforms a `Predicate` function into an `Effect` returning the input value if the predicate returns `true`
|
||
* or failing with specified error if the predicate fails
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const isPositive = (n: number): boolean => n > 0
|
||
*
|
||
* // succeeds with `1`
|
||
* Effect.liftPredicate(1, isPositive, n => `${n} is not positive`)
|
||
*
|
||
* // fails with `"0 is not positive"`
|
||
* Effect.liftPredicate(0, isPositive, n => `${n} is not positive`)
|
||
* ```
|
||
*
|
||
* @category Condition Checking
|
||
* @since 3.4.0
|
||
*/
|
||
<A, E, B extends A = A>(self: A, predicate: Refinement<A, B> | Predicate<A>, orFailWith: (a: EqualsWith<A, B, A, Exclude<A, B>>) => E): Effect<B, E>;
|
||
};
|
||
/**
|
||
* Replaces the value inside an effect with a constant value.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to ignore the original value inside an effect and
|
||
* replace it with a constant value.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* It is useful when you no longer need the value produced by an effect but want
|
||
* to ensure that the effect completes successfully with a specific constant
|
||
* result instead. For instance, you can replace the value produced by a
|
||
* computation with a predefined value, ignoring what was calculated before.
|
||
*
|
||
* **Example** (Replacing a Value)
|
||
*
|
||
* ```ts
|
||
* import { pipe, Effect } from "effect"
|
||
*
|
||
* // Replaces the value 5 with the constant "new value"
|
||
* const program = pipe(Effect.succeed(5), Effect.as("new value"))
|
||
*
|
||
* Effect.runPromise(program).then(console.log)
|
||
* // Output: "new value"
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Mapping
|
||
*/
|
||
export declare const as: {
|
||
/**
|
||
* Replaces the value inside an effect with a constant value.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to ignore the original value inside an effect and
|
||
* replace it with a constant value.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* It is useful when you no longer need the value produced by an effect but want
|
||
* to ensure that the effect completes successfully with a specific constant
|
||
* result instead. For instance, you can replace the value produced by a
|
||
* computation with a predefined value, ignoring what was calculated before.
|
||
*
|
||
* **Example** (Replacing a Value)
|
||
*
|
||
* ```ts
|
||
* import { pipe, Effect } from "effect"
|
||
*
|
||
* // Replaces the value 5 with the constant "new value"
|
||
* const program = pipe(Effect.succeed(5), Effect.as("new value"))
|
||
*
|
||
* Effect.runPromise(program).then(console.log)
|
||
* // Output: "new value"
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Mapping
|
||
*/
|
||
<B>(value: B): <A, E, R>(self: Effect<A, E, R>) => Effect<B, E, R>;
|
||
/**
|
||
* Replaces the value inside an effect with a constant value.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to ignore the original value inside an effect and
|
||
* replace it with a constant value.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* It is useful when you no longer need the value produced by an effect but want
|
||
* to ensure that the effect completes successfully with a specific constant
|
||
* result instead. For instance, you can replace the value produced by a
|
||
* computation with a predefined value, ignoring what was calculated before.
|
||
*
|
||
* **Example** (Replacing a Value)
|
||
*
|
||
* ```ts
|
||
* import { pipe, Effect } from "effect"
|
||
*
|
||
* // Replaces the value 5 with the constant "new value"
|
||
* const program = pipe(Effect.succeed(5), Effect.as("new value"))
|
||
*
|
||
* Effect.runPromise(program).then(console.log)
|
||
* // Output: "new value"
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Mapping
|
||
*/
|
||
<A, E, R, B>(self: Effect<A, E, R>, value: B): Effect<B, E, R>;
|
||
};
|
||
/**
|
||
* This function maps the success value of an `Effect` value to a `Some` value
|
||
* in an `Option` value. If the original `Effect` value fails, the returned
|
||
* `Effect` value will also fail.
|
||
*
|
||
* @category Mapping
|
||
* @since 2.0.0
|
||
*/
|
||
export declare const asSome: <A, E, R>(self: Effect<A, E, R>) => Effect<Option.Option<A>, E, R>;
|
||
/**
|
||
* This function maps the error value of an `Effect` value to a `Some` value
|
||
* in an `Option` value. If the original `Effect` value succeeds, the returned
|
||
* `Effect` value will also succeed.
|
||
*
|
||
* @category Mapping
|
||
* @since 2.0.0
|
||
*/
|
||
export declare const asSomeError: <A, E, R>(self: Effect<A, E, R>) => Effect<A, Option.Option<E>, R>;
|
||
/**
|
||
* This function maps the success value of an `Effect` value to `void`. If the
|
||
* original `Effect` value succeeds, the returned `Effect` value will also
|
||
* succeed. If the original `Effect` value fails, the returned `Effect` value
|
||
* will fail with the same error.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Mapping
|
||
*/
|
||
export declare const asVoid: <A, E, R>(self: Effect<A, E, R>) => Effect<void, E, R>;
|
||
/**
|
||
* Swaps the success and error channels of an effect.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function reverses the flow of an effect by swapping its success and
|
||
* error channels. The success value becomes an error, and the error value
|
||
* becomes a success.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* // ┌─── Effect<number, string, never>
|
||
* // ▼
|
||
* const program = Effect.fail("Oh uh!").pipe(Effect.as(2))
|
||
*
|
||
* // ┌─── Effect<string, number, never>
|
||
* // ▼
|
||
* const flipped = Effect.flip(program)
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Mapping
|
||
*/
|
||
export declare const flip: <A, E, R>(self: Effect<A, E, R>) => Effect<E, A, R>;
|
||
/**
|
||
* Swaps the error/value parameters, applies the function `f` and flips the
|
||
* parameters back
|
||
*
|
||
* @since 2.0.0
|
||
* @category Mapping
|
||
*/
|
||
export declare const flipWith: {
|
||
/**
|
||
* Swaps the error/value parameters, applies the function `f` and flips the
|
||
* parameters back
|
||
*
|
||
* @since 2.0.0
|
||
* @category Mapping
|
||
*/
|
||
<E, A, R, E2, A2, R2>(f: (effect: Effect<E, A, R>) => Effect<E2, A2, R2>): (self: Effect<A, E, R>) => Effect<A2, E2, R2>;
|
||
/**
|
||
* Swaps the error/value parameters, applies the function `f` and flips the
|
||
* parameters back
|
||
*
|
||
* @since 2.0.0
|
||
* @category Mapping
|
||
*/
|
||
<A, E, R, E2, A2, R2>(self: Effect<A, E, R>, f: (effect: Effect<E, A, R>) => Effect<E2, A2, R2>): Effect<A2, E2, R2>;
|
||
};
|
||
/**
|
||
* Transforms the value inside an effect by applying a function to it.
|
||
*
|
||
* **Syntax**
|
||
*
|
||
* ```ts skip-type-checking
|
||
* const mappedEffect = pipe(myEffect, Effect.map(transformation))
|
||
* // or
|
||
* const mappedEffect = Effect.map(myEffect, transformation)
|
||
* // or
|
||
* const mappedEffect = myEffect.pipe(Effect.map(transformation))
|
||
* ```
|
||
*
|
||
* **Details**
|
||
*
|
||
* `map` takes a function and applies it to the value contained within an
|
||
* effect, creating a new effect with the transformed value.
|
||
*
|
||
* It's important to note that effects are immutable, meaning that the original
|
||
* effect is not modified. Instead, a new effect is returned with the updated
|
||
* value.
|
||
*
|
||
* **Example** (Adding a Service Charge)
|
||
*
|
||
* ```ts
|
||
* import { pipe, Effect } from "effect"
|
||
*
|
||
* const addServiceCharge = (amount: number) => amount + 1
|
||
*
|
||
* const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
|
||
*
|
||
* const finalAmount = pipe(
|
||
* fetchTransactionAmount,
|
||
* Effect.map(addServiceCharge)
|
||
* )
|
||
*
|
||
* Effect.runPromise(finalAmount).then(console.log)
|
||
* // Output: 101
|
||
* ```
|
||
*
|
||
* @see {@link mapError} for a version that operates on the error channel.
|
||
* @see {@link mapBoth} for a version that operates on both channels.
|
||
* @see {@link flatMap} or {@link andThen} for a version that can return a new effect.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Mapping
|
||
*/
|
||
export declare const map: {
|
||
/**
|
||
* Transforms the value inside an effect by applying a function to it.
|
||
*
|
||
* **Syntax**
|
||
*
|
||
* ```ts skip-type-checking
|
||
* const mappedEffect = pipe(myEffect, Effect.map(transformation))
|
||
* // or
|
||
* const mappedEffect = Effect.map(myEffect, transformation)
|
||
* // or
|
||
* const mappedEffect = myEffect.pipe(Effect.map(transformation))
|
||
* ```
|
||
*
|
||
* **Details**
|
||
*
|
||
* `map` takes a function and applies it to the value contained within an
|
||
* effect, creating a new effect with the transformed value.
|
||
*
|
||
* It's important to note that effects are immutable, meaning that the original
|
||
* effect is not modified. Instead, a new effect is returned with the updated
|
||
* value.
|
||
*
|
||
* **Example** (Adding a Service Charge)
|
||
*
|
||
* ```ts
|
||
* import { pipe, Effect } from "effect"
|
||
*
|
||
* const addServiceCharge = (amount: number) => amount + 1
|
||
*
|
||
* const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
|
||
*
|
||
* const finalAmount = pipe(
|
||
* fetchTransactionAmount,
|
||
* Effect.map(addServiceCharge)
|
||
* )
|
||
*
|
||
* Effect.runPromise(finalAmount).then(console.log)
|
||
* // Output: 101
|
||
* ```
|
||
*
|
||
* @see {@link mapError} for a version that operates on the error channel.
|
||
* @see {@link mapBoth} for a version that operates on both channels.
|
||
* @see {@link flatMap} or {@link andThen} for a version that can return a new effect.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Mapping
|
||
*/
|
||
<A, B>(f: (a: A) => B): <E, R>(self: Effect<A, E, R>) => Effect<B, E, R>;
|
||
/**
|
||
* Transforms the value inside an effect by applying a function to it.
|
||
*
|
||
* **Syntax**
|
||
*
|
||
* ```ts skip-type-checking
|
||
* const mappedEffect = pipe(myEffect, Effect.map(transformation))
|
||
* // or
|
||
* const mappedEffect = Effect.map(myEffect, transformation)
|
||
* // or
|
||
* const mappedEffect = myEffect.pipe(Effect.map(transformation))
|
||
* ```
|
||
*
|
||
* **Details**
|
||
*
|
||
* `map` takes a function and applies it to the value contained within an
|
||
* effect, creating a new effect with the transformed value.
|
||
*
|
||
* It's important to note that effects are immutable, meaning that the original
|
||
* effect is not modified. Instead, a new effect is returned with the updated
|
||
* value.
|
||
*
|
||
* **Example** (Adding a Service Charge)
|
||
*
|
||
* ```ts
|
||
* import { pipe, Effect } from "effect"
|
||
*
|
||
* const addServiceCharge = (amount: number) => amount + 1
|
||
*
|
||
* const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
|
||
*
|
||
* const finalAmount = pipe(
|
||
* fetchTransactionAmount,
|
||
* Effect.map(addServiceCharge)
|
||
* )
|
||
*
|
||
* Effect.runPromise(finalAmount).then(console.log)
|
||
* // Output: 101
|
||
* ```
|
||
*
|
||
* @see {@link mapError} for a version that operates on the error channel.
|
||
* @see {@link mapBoth} for a version that operates on both channels.
|
||
* @see {@link flatMap} or {@link andThen} for a version that can return a new effect.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Mapping
|
||
*/
|
||
<A, E, R, B>(self: Effect<A, E, R>, f: (a: A) => B): Effect<B, E, R>;
|
||
};
|
||
/**
|
||
* Applies a stateful transformation to each element of a collection, producing
|
||
* new elements along with an updated state.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use `mapAccum` when you need to process each element of a collection while
|
||
* keeping track of some state across iterations.
|
||
*
|
||
* **Details**
|
||
*
|
||
* `mapAccum` takes an initial state (`initial`) and a function (`f`) that is
|
||
* applied to each element. This function returns a new state and a transformed
|
||
* element. The final effect produces both the accumulated state and the
|
||
* transformed collection.
|
||
*
|
||
* If the input collection is a non-empty array, the return type will match the
|
||
* input collection type.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* // Define an initial state and a transformation function
|
||
* const initialState = 0
|
||
*
|
||
* const transformation = (state: number, element: string) =>
|
||
* Effect.succeed<[number, string]>([state + element.length, element.toUpperCase()])
|
||
*
|
||
* // Apply mapAccum to transform an array of strings
|
||
* const program = Effect.mapAccum(["a", "bb", "ccc"], initialState, transformation)
|
||
*
|
||
* Effect.runPromise(program).then(([finalState, transformedCollection]) => {
|
||
* console.log(finalState)
|
||
* console.log(transformedCollection)
|
||
* })
|
||
* // Output:
|
||
* // 6
|
||
* // [ 'A', 'BB', 'CCC' ]
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Mapping
|
||
*/
|
||
export declare const mapAccum: {
|
||
/**
|
||
* Applies a stateful transformation to each element of a collection, producing
|
||
* new elements along with an updated state.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use `mapAccum` when you need to process each element of a collection while
|
||
* keeping track of some state across iterations.
|
||
*
|
||
* **Details**
|
||
*
|
||
* `mapAccum` takes an initial state (`initial`) and a function (`f`) that is
|
||
* applied to each element. This function returns a new state and a transformed
|
||
* element. The final effect produces both the accumulated state and the
|
||
* transformed collection.
|
||
*
|
||
* If the input collection is a non-empty array, the return type will match the
|
||
* input collection type.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* // Define an initial state and a transformation function
|
||
* const initialState = 0
|
||
*
|
||
* const transformation = (state: number, element: string) =>
|
||
* Effect.succeed<[number, string]>([state + element.length, element.toUpperCase()])
|
||
*
|
||
* // Apply mapAccum to transform an array of strings
|
||
* const program = Effect.mapAccum(["a", "bb", "ccc"], initialState, transformation)
|
||
*
|
||
* Effect.runPromise(program).then(([finalState, transformedCollection]) => {
|
||
* console.log(finalState)
|
||
* console.log(transformedCollection)
|
||
* })
|
||
* // Output:
|
||
* // 6
|
||
* // [ 'A', 'BB', 'CCC' ]
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Mapping
|
||
*/
|
||
<S, A, B, E, R, I extends Iterable<A> = Iterable<A>>(initial: S, f: (state: S, a: RA.ReadonlyArray.Infer<I>, i: number) => Effect<readonly [S, B], E, R>): (elements: I) => Effect<[S, RA.ReadonlyArray.With<I, B>], E, R>;
|
||
/**
|
||
* Applies a stateful transformation to each element of a collection, producing
|
||
* new elements along with an updated state.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use `mapAccum` when you need to process each element of a collection while
|
||
* keeping track of some state across iterations.
|
||
*
|
||
* **Details**
|
||
*
|
||
* `mapAccum` takes an initial state (`initial`) and a function (`f`) that is
|
||
* applied to each element. This function returns a new state and a transformed
|
||
* element. The final effect produces both the accumulated state and the
|
||
* transformed collection.
|
||
*
|
||
* If the input collection is a non-empty array, the return type will match the
|
||
* input collection type.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* // Define an initial state and a transformation function
|
||
* const initialState = 0
|
||
*
|
||
* const transformation = (state: number, element: string) =>
|
||
* Effect.succeed<[number, string]>([state + element.length, element.toUpperCase()])
|
||
*
|
||
* // Apply mapAccum to transform an array of strings
|
||
* const program = Effect.mapAccum(["a", "bb", "ccc"], initialState, transformation)
|
||
*
|
||
* Effect.runPromise(program).then(([finalState, transformedCollection]) => {
|
||
* console.log(finalState)
|
||
* console.log(transformedCollection)
|
||
* })
|
||
* // Output:
|
||
* // 6
|
||
* // [ 'A', 'BB', 'CCC' ]
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Mapping
|
||
*/
|
||
<A, S, B, E, R, I extends Iterable<A> = Iterable<A>>(elements: I, initial: S, f: (state: S, a: RA.ReadonlyArray.Infer<I>, i: number) => Effect<readonly [S, B], E, R>): Effect<[S, RA.ReadonlyArray.With<I, B>], E, R>;
|
||
};
|
||
/**
|
||
* Applies transformations to both the success and error channels of an effect.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function takes two map functions as arguments: one for the error channel
|
||
* and one for the success channel. You can use it when you want to modify both
|
||
* the error and the success values without altering the overall success or
|
||
* failure status of the effect.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* // ┌─── Effect<number, string, never>
|
||
* // ▼
|
||
* const simulatedTask = Effect.fail("Oh no!").pipe(Effect.as(1))
|
||
*
|
||
* // ┌─── Effect<boolean, Error, never>
|
||
* // ▼
|
||
* const modified = Effect.mapBoth(simulatedTask, {
|
||
* onFailure: (message) => new Error(message),
|
||
* onSuccess: (n) => n > 0
|
||
* })
|
||
* ```
|
||
*
|
||
* @see {@link map} for a version that operates on the success channel.
|
||
* @see {@link mapError} for a version that operates on the error channel.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Mapping
|
||
*/
|
||
export declare const mapBoth: {
|
||
/**
|
||
* Applies transformations to both the success and error channels of an effect.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function takes two map functions as arguments: one for the error channel
|
||
* and one for the success channel. You can use it when you want to modify both
|
||
* the error and the success values without altering the overall success or
|
||
* failure status of the effect.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* // ┌─── Effect<number, string, never>
|
||
* // ▼
|
||
* const simulatedTask = Effect.fail("Oh no!").pipe(Effect.as(1))
|
||
*
|
||
* // ┌─── Effect<boolean, Error, never>
|
||
* // ▼
|
||
* const modified = Effect.mapBoth(simulatedTask, {
|
||
* onFailure: (message) => new Error(message),
|
||
* onSuccess: (n) => n > 0
|
||
* })
|
||
* ```
|
||
*
|
||
* @see {@link map} for a version that operates on the success channel.
|
||
* @see {@link mapError} for a version that operates on the error channel.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Mapping
|
||
*/
|
||
<E, E2, A, A2>(options: {
|
||
readonly onFailure: (e: E) => E2;
|
||
readonly onSuccess: (a: A) => A2;
|
||
}): <R>(self: Effect<A, E, R>) => Effect<A2, E2, R>;
|
||
/**
|
||
* Applies transformations to both the success and error channels of an effect.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function takes two map functions as arguments: one for the error channel
|
||
* and one for the success channel. You can use it when you want to modify both
|
||
* the error and the success values without altering the overall success or
|
||
* failure status of the effect.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* // ┌─── Effect<number, string, never>
|
||
* // ▼
|
||
* const simulatedTask = Effect.fail("Oh no!").pipe(Effect.as(1))
|
||
*
|
||
* // ┌─── Effect<boolean, Error, never>
|
||
* // ▼
|
||
* const modified = Effect.mapBoth(simulatedTask, {
|
||
* onFailure: (message) => new Error(message),
|
||
* onSuccess: (n) => n > 0
|
||
* })
|
||
* ```
|
||
*
|
||
* @see {@link map} for a version that operates on the success channel.
|
||
* @see {@link mapError} for a version that operates on the error channel.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Mapping
|
||
*/
|
||
<A, E, R, E2, A2>(self: Effect<A, E, R>, options: {
|
||
readonly onFailure: (e: E) => E2;
|
||
readonly onSuccess: (a: A) => A2;
|
||
}): Effect<A2, E2, R>;
|
||
};
|
||
/**
|
||
* Transforms or modifies the error produced by an effect without affecting its
|
||
* success value.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This function is helpful when you want to enhance the error with additional
|
||
* information, change the error type, or apply custom error handling while
|
||
* keeping the original behavior of the effect's success values intact. It only
|
||
* operates on the error channel and leaves the success channel unchanged.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* // ┌─── Effect<number, string, never>
|
||
* // ▼
|
||
* const simulatedTask = Effect.fail("Oh no!").pipe(Effect.as(1))
|
||
*
|
||
* // ┌─── Effect<number, Error, never>
|
||
* // ▼
|
||
* const mapped = Effect.mapError(
|
||
* simulatedTask,
|
||
* (message) => new Error(message)
|
||
* )
|
||
* ```
|
||
*
|
||
* @see {@link map} for a version that operates on the success channel.
|
||
* @see {@link mapBoth} for a version that operates on both channels.
|
||
* @see {@link orElseFail} if you want to replace the error with a new one.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Mapping
|
||
*/
|
||
export declare const mapError: {
|
||
/**
|
||
* Transforms or modifies the error produced by an effect without affecting its
|
||
* success value.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This function is helpful when you want to enhance the error with additional
|
||
* information, change the error type, or apply custom error handling while
|
||
* keeping the original behavior of the effect's success values intact. It only
|
||
* operates on the error channel and leaves the success channel unchanged.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* // ┌─── Effect<number, string, never>
|
||
* // ▼
|
||
* const simulatedTask = Effect.fail("Oh no!").pipe(Effect.as(1))
|
||
*
|
||
* // ┌─── Effect<number, Error, never>
|
||
* // ▼
|
||
* const mapped = Effect.mapError(
|
||
* simulatedTask,
|
||
* (message) => new Error(message)
|
||
* )
|
||
* ```
|
||
*
|
||
* @see {@link map} for a version that operates on the success channel.
|
||
* @see {@link mapBoth} for a version that operates on both channels.
|
||
* @see {@link orElseFail} if you want to replace the error with a new one.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Mapping
|
||
*/
|
||
<E, E2>(f: (e: E) => E2): <A, R>(self: Effect<A, E, R>) => Effect<A, E2, R>;
|
||
/**
|
||
* Transforms or modifies the error produced by an effect without affecting its
|
||
* success value.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This function is helpful when you want to enhance the error with additional
|
||
* information, change the error type, or apply custom error handling while
|
||
* keeping the original behavior of the effect's success values intact. It only
|
||
* operates on the error channel and leaves the success channel unchanged.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* // ┌─── Effect<number, string, never>
|
||
* // ▼
|
||
* const simulatedTask = Effect.fail("Oh no!").pipe(Effect.as(1))
|
||
*
|
||
* // ┌─── Effect<number, Error, never>
|
||
* // ▼
|
||
* const mapped = Effect.mapError(
|
||
* simulatedTask,
|
||
* (message) => new Error(message)
|
||
* )
|
||
* ```
|
||
*
|
||
* @see {@link map} for a version that operates on the success channel.
|
||
* @see {@link mapBoth} for a version that operates on both channels.
|
||
* @see {@link orElseFail} if you want to replace the error with a new one.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Mapping
|
||
*/
|
||
<A, E, R, E2>(self: Effect<A, E, R>, f: (e: E) => E2): Effect<A, E2, R>;
|
||
};
|
||
/**
|
||
* Maps the cause of failure of an effect using a specified function.
|
||
*
|
||
* @see {@link sandbox} for a version that exposes the full cause of failures, defects, or interruptions.
|
||
* @see {@link catchAllCause} for a version that can recover from all types of defects.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Mapping
|
||
*/
|
||
export declare const mapErrorCause: {
|
||
/**
|
||
* Maps the cause of failure of an effect using a specified function.
|
||
*
|
||
* @see {@link sandbox} for a version that exposes the full cause of failures, defects, or interruptions.
|
||
* @see {@link catchAllCause} for a version that can recover from all types of defects.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Mapping
|
||
*/
|
||
<E, E2>(f: (cause: Cause.Cause<E>) => Cause.Cause<E2>): <A, R>(self: Effect<A, E, R>) => Effect<A, E2, R>;
|
||
/**
|
||
* Maps the cause of failure of an effect using a specified function.
|
||
*
|
||
* @see {@link sandbox} for a version that exposes the full cause of failures, defects, or interruptions.
|
||
* @see {@link catchAllCause} for a version that can recover from all types of defects.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Mapping
|
||
*/
|
||
<A, E, R, E2>(self: Effect<A, E, R>, f: (cause: Cause.Cause<E>) => Cause.Cause<E2>): Effect<A, E2, R>;
|
||
};
|
||
/**
|
||
* Combines both success and error channels of an effect into a single outcome.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function transforms an effect that may fail into one that always returns
|
||
* a value, where both success and failure outcomes are handled as values in the
|
||
* success channel.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This can be useful when you want to continue execution regardless of the
|
||
* error type and still capture both successful results and errors as part of
|
||
* the outcome.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* // ┌─── Effect<number, string, never>
|
||
* // ▼
|
||
* const program = Effect.fail("Oh uh!").pipe(Effect.as(2))
|
||
*
|
||
* // ┌─── Effect<number | string, never, never>
|
||
* // ▼
|
||
* const recovered = Effect.merge(program)
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Mapping
|
||
*/
|
||
export declare const merge: <A, E, R>(self: Effect<A, E, R>) => Effect<E | A, never, R>;
|
||
/**
|
||
* Returns a new effect with the boolean value of this effect negated.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Mapping
|
||
*/
|
||
export declare const negate: <E, R>(self: Effect<boolean, E, R>) => Effect<boolean, E, R>;
|
||
/**
|
||
* Creates a scoped resource using an `acquire` and `release` effect.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function helps manage resources by combining two `Effect` values: one
|
||
* for acquiring the resource and one for releasing it.
|
||
*
|
||
* `acquireRelease` does the following:
|
||
*
|
||
* 1. Ensures that the effect that acquires the resource will not be
|
||
* interrupted. Note that acquisition may still fail due to internal
|
||
* reasons (such as an uncaught exception).
|
||
* 2. Ensures that the `release` effect will not be interrupted, and will be
|
||
* executed as long as the acquisition effect successfully acquires the
|
||
* resource.
|
||
*
|
||
* If the `acquire` function succeeds, the `release` function is added to the
|
||
* list of finalizers for the scope. This ensures that the release will happen
|
||
* automatically when the scope is closed.
|
||
*
|
||
* Both `acquire` and `release` run uninterruptibly, meaning they cannot be
|
||
* interrupted while they are executing.
|
||
*
|
||
* Additionally, the `release` function can be influenced by the exit value when
|
||
* the scope closes, allowing for custom handling of how the resource is
|
||
* released based on the execution outcome.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This function is used to ensure that an effect that represents the
|
||
* acquisition of a resource (for example, opening a file, launching a thread,
|
||
* etc.) will not be interrupted, and that the resource will always be released
|
||
* when the `Effect` completes execution.
|
||
*
|
||
* **Example** (Defining a Simple Resource)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* // Define an interface for a resource
|
||
* interface MyResource {
|
||
* readonly contents: string
|
||
* readonly close: () => Promise<void>
|
||
* }
|
||
*
|
||
* // Simulate resource acquisition
|
||
* const getMyResource = (): Promise<MyResource> =>
|
||
* Promise.resolve({
|
||
* contents: "lorem ipsum",
|
||
* close: () =>
|
||
* new Promise((resolve) => {
|
||
* console.log("Resource released")
|
||
* resolve()
|
||
* })
|
||
* })
|
||
*
|
||
* // Define how the resource is acquired
|
||
* const acquire = Effect.tryPromise({
|
||
* try: () =>
|
||
* getMyResource().then((res) => {
|
||
* console.log("Resource acquired")
|
||
* return res
|
||
* }),
|
||
* catch: () => new Error("getMyResourceError")
|
||
* })
|
||
*
|
||
* // Define how the resource is released
|
||
* const release = (res: MyResource) => Effect.promise(() => res.close())
|
||
*
|
||
* // Create the resource management workflow
|
||
* //
|
||
* // ┌─── Effect<MyResource, Error, Scope>
|
||
* // ▼
|
||
* const resource = Effect.acquireRelease(acquire, release)
|
||
* ```
|
||
*
|
||
* @see {@link acquireUseRelease} for a version that automatically handles the scoping of resources.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Scoping, Resources & Finalization
|
||
*/
|
||
export declare const acquireRelease: {
|
||
/**
|
||
* Creates a scoped resource using an `acquire` and `release` effect.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function helps manage resources by combining two `Effect` values: one
|
||
* for acquiring the resource and one for releasing it.
|
||
*
|
||
* `acquireRelease` does the following:
|
||
*
|
||
* 1. Ensures that the effect that acquires the resource will not be
|
||
* interrupted. Note that acquisition may still fail due to internal
|
||
* reasons (such as an uncaught exception).
|
||
* 2. Ensures that the `release` effect will not be interrupted, and will be
|
||
* executed as long as the acquisition effect successfully acquires the
|
||
* resource.
|
||
*
|
||
* If the `acquire` function succeeds, the `release` function is added to the
|
||
* list of finalizers for the scope. This ensures that the release will happen
|
||
* automatically when the scope is closed.
|
||
*
|
||
* Both `acquire` and `release` run uninterruptibly, meaning they cannot be
|
||
* interrupted while they are executing.
|
||
*
|
||
* Additionally, the `release` function can be influenced by the exit value when
|
||
* the scope closes, allowing for custom handling of how the resource is
|
||
* released based on the execution outcome.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This function is used to ensure that an effect that represents the
|
||
* acquisition of a resource (for example, opening a file, launching a thread,
|
||
* etc.) will not be interrupted, and that the resource will always be released
|
||
* when the `Effect` completes execution.
|
||
*
|
||
* **Example** (Defining a Simple Resource)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* // Define an interface for a resource
|
||
* interface MyResource {
|
||
* readonly contents: string
|
||
* readonly close: () => Promise<void>
|
||
* }
|
||
*
|
||
* // Simulate resource acquisition
|
||
* const getMyResource = (): Promise<MyResource> =>
|
||
* Promise.resolve({
|
||
* contents: "lorem ipsum",
|
||
* close: () =>
|
||
* new Promise((resolve) => {
|
||
* console.log("Resource released")
|
||
* resolve()
|
||
* })
|
||
* })
|
||
*
|
||
* // Define how the resource is acquired
|
||
* const acquire = Effect.tryPromise({
|
||
* try: () =>
|
||
* getMyResource().then((res) => {
|
||
* console.log("Resource acquired")
|
||
* return res
|
||
* }),
|
||
* catch: () => new Error("getMyResourceError")
|
||
* })
|
||
*
|
||
* // Define how the resource is released
|
||
* const release = (res: MyResource) => Effect.promise(() => res.close())
|
||
*
|
||
* // Create the resource management workflow
|
||
* //
|
||
* // ┌─── Effect<MyResource, Error, Scope>
|
||
* // ▼
|
||
* const resource = Effect.acquireRelease(acquire, release)
|
||
* ```
|
||
*
|
||
* @see {@link acquireUseRelease} for a version that automatically handles the scoping of resources.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Scoping, Resources & Finalization
|
||
*/
|
||
<A, X, R2>(release: (a: A, exit: Exit.Exit<unknown, unknown>) => Effect<X, never, R2>): <E, R>(acquire: Effect<A, E, R>) => Effect<A, E, Scope.Scope | R2 | R>;
|
||
/**
|
||
* Creates a scoped resource using an `acquire` and `release` effect.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function helps manage resources by combining two `Effect` values: one
|
||
* for acquiring the resource and one for releasing it.
|
||
*
|
||
* `acquireRelease` does the following:
|
||
*
|
||
* 1. Ensures that the effect that acquires the resource will not be
|
||
* interrupted. Note that acquisition may still fail due to internal
|
||
* reasons (such as an uncaught exception).
|
||
* 2. Ensures that the `release` effect will not be interrupted, and will be
|
||
* executed as long as the acquisition effect successfully acquires the
|
||
* resource.
|
||
*
|
||
* If the `acquire` function succeeds, the `release` function is added to the
|
||
* list of finalizers for the scope. This ensures that the release will happen
|
||
* automatically when the scope is closed.
|
||
*
|
||
* Both `acquire` and `release` run uninterruptibly, meaning they cannot be
|
||
* interrupted while they are executing.
|
||
*
|
||
* Additionally, the `release` function can be influenced by the exit value when
|
||
* the scope closes, allowing for custom handling of how the resource is
|
||
* released based on the execution outcome.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This function is used to ensure that an effect that represents the
|
||
* acquisition of a resource (for example, opening a file, launching a thread,
|
||
* etc.) will not be interrupted, and that the resource will always be released
|
||
* when the `Effect` completes execution.
|
||
*
|
||
* **Example** (Defining a Simple Resource)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* // Define an interface for a resource
|
||
* interface MyResource {
|
||
* readonly contents: string
|
||
* readonly close: () => Promise<void>
|
||
* }
|
||
*
|
||
* // Simulate resource acquisition
|
||
* const getMyResource = (): Promise<MyResource> =>
|
||
* Promise.resolve({
|
||
* contents: "lorem ipsum",
|
||
* close: () =>
|
||
* new Promise((resolve) => {
|
||
* console.log("Resource released")
|
||
* resolve()
|
||
* })
|
||
* })
|
||
*
|
||
* // Define how the resource is acquired
|
||
* const acquire = Effect.tryPromise({
|
||
* try: () =>
|
||
* getMyResource().then((res) => {
|
||
* console.log("Resource acquired")
|
||
* return res
|
||
* }),
|
||
* catch: () => new Error("getMyResourceError")
|
||
* })
|
||
*
|
||
* // Define how the resource is released
|
||
* const release = (res: MyResource) => Effect.promise(() => res.close())
|
||
*
|
||
* // Create the resource management workflow
|
||
* //
|
||
* // ┌─── Effect<MyResource, Error, Scope>
|
||
* // ▼
|
||
* const resource = Effect.acquireRelease(acquire, release)
|
||
* ```
|
||
*
|
||
* @see {@link acquireUseRelease} for a version that automatically handles the scoping of resources.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Scoping, Resources & Finalization
|
||
*/
|
||
<A, E, R, X, R2>(acquire: Effect<A, E, R>, release: (a: A, exit: Exit.Exit<unknown, unknown>) => Effect<X, never, R2>): Effect<A, E, Scope.Scope | R | R2>;
|
||
};
|
||
/**
|
||
* Creates a scoped resource with an interruptible acquire action.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function is similar to {@link acquireRelease}, but it allows the
|
||
* acquisition of the resource to be interrupted. The `acquire` effect, which
|
||
* represents the process of obtaining the resource, can be interrupted if
|
||
* necessary.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Scoping, Resources & Finalization
|
||
*/
|
||
export declare const acquireReleaseInterruptible: {
|
||
/**
|
||
* Creates a scoped resource with an interruptible acquire action.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function is similar to {@link acquireRelease}, but it allows the
|
||
* acquisition of the resource to be interrupted. The `acquire` effect, which
|
||
* represents the process of obtaining the resource, can be interrupted if
|
||
* necessary.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Scoping, Resources & Finalization
|
||
*/
|
||
<X, R2>(release: (exit: Exit.Exit<unknown, unknown>) => Effect<X, never, R2>): <A, E, R>(acquire: Effect<A, E, R>) => Effect<A, E, Scope.Scope | R2 | R>;
|
||
/**
|
||
* Creates a scoped resource with an interruptible acquire action.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function is similar to {@link acquireRelease}, but it allows the
|
||
* acquisition of the resource to be interrupted. The `acquire` effect, which
|
||
* represents the process of obtaining the resource, can be interrupted if
|
||
* necessary.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Scoping, Resources & Finalization
|
||
*/
|
||
<A, E, R, X, R2>(acquire: Effect<A, E, R>, release: (exit: Exit.Exit<unknown, unknown>) => Effect<X, never, R2>): Effect<A, E, Scope.Scope | R | R2>;
|
||
};
|
||
/**
|
||
* Many real-world operations involve working with resources that must be released when no longer needed, such as:
|
||
*
|
||
* - Database connections
|
||
* - File handles
|
||
* - Network requests
|
||
*
|
||
* This function ensures that a resource is:
|
||
*
|
||
* 1. **Acquired** properly.
|
||
* 2. **Used** for its intended purpose.
|
||
* 3. **Released** even if an error occurs.
|
||
*
|
||
* **Example** (Automatically Managing Resource Lifetime)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* // Define an interface for a resource
|
||
* interface MyResource {
|
||
* readonly contents: string
|
||
* readonly close: () => Promise<void>
|
||
* }
|
||
*
|
||
* // Simulate resource acquisition
|
||
* const getMyResource = (): Promise<MyResource> =>
|
||
* Promise.resolve({
|
||
* contents: "lorem ipsum",
|
||
* close: () =>
|
||
* new Promise((resolve) => {
|
||
* console.log("Resource released")
|
||
* resolve()
|
||
* })
|
||
* })
|
||
*
|
||
* // Define how the resource is acquired
|
||
* const acquire = Effect.tryPromise({
|
||
* try: () =>
|
||
* getMyResource().then((res) => {
|
||
* console.log("Resource acquired")
|
||
* return res
|
||
* }),
|
||
* catch: () => new Error("getMyResourceError")
|
||
* })
|
||
*
|
||
* // Define how the resource is released
|
||
* const release = (res: MyResource) => Effect.promise(() => res.close())
|
||
*
|
||
* const use = (res: MyResource) => Console.log(`content is ${res.contents}`)
|
||
*
|
||
* // ┌─── Effect<void, Error, never>
|
||
* // ▼
|
||
* const program = Effect.acquireUseRelease(acquire, use, release)
|
||
*
|
||
* Effect.runPromise(program)
|
||
* // Output:
|
||
* // Resource acquired
|
||
* // content is lorem ipsum
|
||
* // Resource released
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Scoping, Resources & Finalization
|
||
*/
|
||
export declare const acquireUseRelease: {
|
||
/**
|
||
* Many real-world operations involve working with resources that must be released when no longer needed, such as:
|
||
*
|
||
* - Database connections
|
||
* - File handles
|
||
* - Network requests
|
||
*
|
||
* This function ensures that a resource is:
|
||
*
|
||
* 1. **Acquired** properly.
|
||
* 2. **Used** for its intended purpose.
|
||
* 3. **Released** even if an error occurs.
|
||
*
|
||
* **Example** (Automatically Managing Resource Lifetime)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* // Define an interface for a resource
|
||
* interface MyResource {
|
||
* readonly contents: string
|
||
* readonly close: () => Promise<void>
|
||
* }
|
||
*
|
||
* // Simulate resource acquisition
|
||
* const getMyResource = (): Promise<MyResource> =>
|
||
* Promise.resolve({
|
||
* contents: "lorem ipsum",
|
||
* close: () =>
|
||
* new Promise((resolve) => {
|
||
* console.log("Resource released")
|
||
* resolve()
|
||
* })
|
||
* })
|
||
*
|
||
* // Define how the resource is acquired
|
||
* const acquire = Effect.tryPromise({
|
||
* try: () =>
|
||
* getMyResource().then((res) => {
|
||
* console.log("Resource acquired")
|
||
* return res
|
||
* }),
|
||
* catch: () => new Error("getMyResourceError")
|
||
* })
|
||
*
|
||
* // Define how the resource is released
|
||
* const release = (res: MyResource) => Effect.promise(() => res.close())
|
||
*
|
||
* const use = (res: MyResource) => Console.log(`content is ${res.contents}`)
|
||
*
|
||
* // ┌─── Effect<void, Error, never>
|
||
* // ▼
|
||
* const program = Effect.acquireUseRelease(acquire, use, release)
|
||
*
|
||
* Effect.runPromise(program)
|
||
* // Output:
|
||
* // Resource acquired
|
||
* // content is lorem ipsum
|
||
* // Resource released
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Scoping, Resources & Finalization
|
||
*/
|
||
<A2, E2, R2, A, X, R3>(use: (a: A) => Effect<A2, E2, R2>, release: (a: A, exit: Exit.Exit<A2, E2>) => Effect<X, never, R3>): <E, R>(acquire: Effect<A, E, R>) => Effect<A2, E2 | E, R2 | R3 | R>;
|
||
/**
|
||
* Many real-world operations involve working with resources that must be released when no longer needed, such as:
|
||
*
|
||
* - Database connections
|
||
* - File handles
|
||
* - Network requests
|
||
*
|
||
* This function ensures that a resource is:
|
||
*
|
||
* 1. **Acquired** properly.
|
||
* 2. **Used** for its intended purpose.
|
||
* 3. **Released** even if an error occurs.
|
||
*
|
||
* **Example** (Automatically Managing Resource Lifetime)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* // Define an interface for a resource
|
||
* interface MyResource {
|
||
* readonly contents: string
|
||
* readonly close: () => Promise<void>
|
||
* }
|
||
*
|
||
* // Simulate resource acquisition
|
||
* const getMyResource = (): Promise<MyResource> =>
|
||
* Promise.resolve({
|
||
* contents: "lorem ipsum",
|
||
* close: () =>
|
||
* new Promise((resolve) => {
|
||
* console.log("Resource released")
|
||
* resolve()
|
||
* })
|
||
* })
|
||
*
|
||
* // Define how the resource is acquired
|
||
* const acquire = Effect.tryPromise({
|
||
* try: () =>
|
||
* getMyResource().then((res) => {
|
||
* console.log("Resource acquired")
|
||
* return res
|
||
* }),
|
||
* catch: () => new Error("getMyResourceError")
|
||
* })
|
||
*
|
||
* // Define how the resource is released
|
||
* const release = (res: MyResource) => Effect.promise(() => res.close())
|
||
*
|
||
* const use = (res: MyResource) => Console.log(`content is ${res.contents}`)
|
||
*
|
||
* // ┌─── Effect<void, Error, never>
|
||
* // ▼
|
||
* const program = Effect.acquireUseRelease(acquire, use, release)
|
||
*
|
||
* Effect.runPromise(program)
|
||
* // Output:
|
||
* // Resource acquired
|
||
* // content is lorem ipsum
|
||
* // Resource released
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Scoping, Resources & Finalization
|
||
*/
|
||
<A, E, R, A2, E2, R2, X, R3>(acquire: Effect<A, E, R>, use: (a: A) => Effect<A2, E2, R2>, release: (a: A, exit: Exit.Exit<A2, E2>) => Effect<X, never, R3>): Effect<A2, E | E2, R | R2 | R3>;
|
||
};
|
||
/**
|
||
* Ensures a finalizer is added to the scope of the calling effect, guaranteeing
|
||
* it runs when the scope is closed.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function adds a finalizer that will execute whenever the scope of the
|
||
* effect is closed, regardless of whether the effect succeeds, fails, or is
|
||
* interrupted. The finalizer receives the `Exit` value of the effect's scope,
|
||
* allowing it to react differently depending on how the effect concludes.
|
||
*
|
||
* Finalizers are a reliable way to manage resource cleanup, ensuring that
|
||
* resources such as file handles, network connections, or database transactions
|
||
* are properly closed even in the event of an unexpected interruption or error.
|
||
*
|
||
* Finalizers operate in conjunction with Effect's scoped resources. If an
|
||
* effect with a finalizer is wrapped in a scope, the finalizer will execute
|
||
* automatically when the scope ends.
|
||
*
|
||
* **Example** (Adding a Finalizer on Success)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* // ┌─── Effect<string, never, Scope>
|
||
* // ▼
|
||
* const program = Effect.gen(function* () {
|
||
* yield* Effect.addFinalizer((exit) =>
|
||
* Console.log(`Finalizer executed. Exit status: ${exit._tag}`)
|
||
* )
|
||
* return "some result"
|
||
* })
|
||
*
|
||
* // Wrapping the effect in a scope
|
||
* //
|
||
* // ┌─── Effect<string, never, never>
|
||
* // ▼
|
||
* const runnable = Effect.scoped(program)
|
||
*
|
||
* Effect.runPromiseExit(runnable).then(console.log)
|
||
* // Output:
|
||
* // Finalizer executed. Exit status: Success
|
||
* // { _id: 'Exit', _tag: 'Success', value: 'some result' }
|
||
* ```
|
||
*
|
||
* **Example** (Adding a Finalizer on Failure)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* // ┌─── Effect<never, string, Scope>
|
||
* // ▼
|
||
* const program = Effect.gen(function* () {
|
||
* yield* Effect.addFinalizer((exit) =>
|
||
* Console.log(`Finalizer executed. Exit status: ${exit._tag}`)
|
||
* )
|
||
* return yield* Effect.fail("Uh oh!")
|
||
* })
|
||
*
|
||
* // Wrapping the effect in a scope
|
||
* //
|
||
* // ┌─── Effect<never, string, never>
|
||
* // ▼
|
||
* const runnable = Effect.scoped(program)
|
||
*
|
||
* Effect.runPromiseExit(runnable).then(console.log)
|
||
* // Output:
|
||
* // Finalizer executed. Exit status: Failure
|
||
* // {
|
||
* // _id: 'Exit',
|
||
* // _tag: 'Failure',
|
||
* // cause: { _id: 'Cause', _tag: 'Fail', failure: 'Uh oh!' }
|
||
* // }
|
||
* ```
|
||
*
|
||
* **Example** (Adding a Finalizer on Interruption)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* // ┌─── Effect<never, never, Scope>
|
||
* // ▼
|
||
* const program = Effect.gen(function* () {
|
||
* yield* Effect.addFinalizer((exit) =>
|
||
* Console.log(`Finalizer executed. Exit status: ${exit._tag}`)
|
||
* )
|
||
* return yield* Effect.interrupt
|
||
* })
|
||
*
|
||
* // Wrapping the effect in a scope
|
||
* //
|
||
* // ┌─── Effect<never, never, never>
|
||
* // ▼
|
||
* const runnable = Effect.scoped(program)
|
||
*
|
||
* Effect.runPromiseExit(runnable).then(console.log)
|
||
* // Output:
|
||
* // Finalizer executed. Exit status: Failure
|
||
* // {
|
||
* // _id: 'Exit',
|
||
* // _tag: 'Failure',
|
||
* // cause: {
|
||
* // _id: 'Cause',
|
||
* // _tag: 'Interrupt',
|
||
* // fiberId: {
|
||
* // _id: 'FiberId',
|
||
* // _tag: 'Runtime',
|
||
* // id: 0,
|
||
* // startTimeMillis: ...
|
||
* // }
|
||
* // }
|
||
* // }
|
||
* ```
|
||
*
|
||
* @see {@link onExit} for attaching a finalizer directly to an effect.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Scoping, Resources & Finalization
|
||
*/
|
||
export declare const addFinalizer: <X, R>(finalizer: (exit: Exit.Exit<unknown, unknown>) => Effect<X, never, R>) => Effect<void, never, Scope.Scope | R>;
|
||
/**
|
||
* Guarantees the execution of a finalizer when an effect starts execution.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to specify a `finalizer` effect that will always be
|
||
* run once the effect starts execution, regardless of whether the effect
|
||
* succeeds, fails, or is interrupted.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is useful when you need to ensure that certain cleanup or final steps
|
||
* are executed in all cases, such as releasing resources or performing
|
||
* necessary logging.
|
||
*
|
||
* While this function provides strong guarantees about executing the finalizer,
|
||
* it is considered a low-level tool, which may not be ideal for more complex
|
||
* resource management. For higher-level resource management with automatic
|
||
* acquisition and release, see the {@link acquireRelease} family of functions.
|
||
* For use cases where you need access to the result of an effect, consider
|
||
* using {@link onExit}.
|
||
*
|
||
* **Example** (Running a Finalizer in All Outcomes)
|
||
*
|
||
* ```ts
|
||
* import { Console, Effect } from "effect"
|
||
*
|
||
* // Define a cleanup effect
|
||
* const handler = Effect.ensuring(Console.log("Cleanup completed"))
|
||
*
|
||
* // Define a successful effect
|
||
* const success = Console.log("Task completed").pipe(
|
||
* Effect.as("some result"),
|
||
* handler
|
||
* )
|
||
*
|
||
* Effect.runFork(success)
|
||
* // Output:
|
||
* // Task completed
|
||
* // Cleanup completed
|
||
*
|
||
* // Define a failing effect
|
||
* const failure = Console.log("Task failed").pipe(
|
||
* Effect.andThen(Effect.fail("some error")),
|
||
* handler
|
||
* )
|
||
*
|
||
* Effect.runFork(failure)
|
||
* // Output:
|
||
* // Task failed
|
||
* // Cleanup completed
|
||
*
|
||
* // Define an interrupted effect
|
||
* const interruption = Console.log("Task interrupted").pipe(
|
||
* Effect.andThen(Effect.interrupt),
|
||
* handler
|
||
* )
|
||
*
|
||
* Effect.runFork(interruption)
|
||
* // Output:
|
||
* // Task interrupted
|
||
* // Cleanup completed
|
||
* ```
|
||
*
|
||
* @see {@link onExit} for a version that provides access to the result of an
|
||
* effect.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Scoping, Resources & Finalization
|
||
*/
|
||
export declare const ensuring: {
|
||
/**
|
||
* Guarantees the execution of a finalizer when an effect starts execution.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to specify a `finalizer` effect that will always be
|
||
* run once the effect starts execution, regardless of whether the effect
|
||
* succeeds, fails, or is interrupted.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is useful when you need to ensure that certain cleanup or final steps
|
||
* are executed in all cases, such as releasing resources or performing
|
||
* necessary logging.
|
||
*
|
||
* While this function provides strong guarantees about executing the finalizer,
|
||
* it is considered a low-level tool, which may not be ideal for more complex
|
||
* resource management. For higher-level resource management with automatic
|
||
* acquisition and release, see the {@link acquireRelease} family of functions.
|
||
* For use cases where you need access to the result of an effect, consider
|
||
* using {@link onExit}.
|
||
*
|
||
* **Example** (Running a Finalizer in All Outcomes)
|
||
*
|
||
* ```ts
|
||
* import { Console, Effect } from "effect"
|
||
*
|
||
* // Define a cleanup effect
|
||
* const handler = Effect.ensuring(Console.log("Cleanup completed"))
|
||
*
|
||
* // Define a successful effect
|
||
* const success = Console.log("Task completed").pipe(
|
||
* Effect.as("some result"),
|
||
* handler
|
||
* )
|
||
*
|
||
* Effect.runFork(success)
|
||
* // Output:
|
||
* // Task completed
|
||
* // Cleanup completed
|
||
*
|
||
* // Define a failing effect
|
||
* const failure = Console.log("Task failed").pipe(
|
||
* Effect.andThen(Effect.fail("some error")),
|
||
* handler
|
||
* )
|
||
*
|
||
* Effect.runFork(failure)
|
||
* // Output:
|
||
* // Task failed
|
||
* // Cleanup completed
|
||
*
|
||
* // Define an interrupted effect
|
||
* const interruption = Console.log("Task interrupted").pipe(
|
||
* Effect.andThen(Effect.interrupt),
|
||
* handler
|
||
* )
|
||
*
|
||
* Effect.runFork(interruption)
|
||
* // Output:
|
||
* // Task interrupted
|
||
* // Cleanup completed
|
||
* ```
|
||
*
|
||
* @see {@link onExit} for a version that provides access to the result of an
|
||
* effect.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Scoping, Resources & Finalization
|
||
*/
|
||
<X, R1>(finalizer: Effect<X, never, R1>): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, R1 | R>;
|
||
/**
|
||
* Guarantees the execution of a finalizer when an effect starts execution.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to specify a `finalizer` effect that will always be
|
||
* run once the effect starts execution, regardless of whether the effect
|
||
* succeeds, fails, or is interrupted.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is useful when you need to ensure that certain cleanup or final steps
|
||
* are executed in all cases, such as releasing resources or performing
|
||
* necessary logging.
|
||
*
|
||
* While this function provides strong guarantees about executing the finalizer,
|
||
* it is considered a low-level tool, which may not be ideal for more complex
|
||
* resource management. For higher-level resource management with automatic
|
||
* acquisition and release, see the {@link acquireRelease} family of functions.
|
||
* For use cases where you need access to the result of an effect, consider
|
||
* using {@link onExit}.
|
||
*
|
||
* **Example** (Running a Finalizer in All Outcomes)
|
||
*
|
||
* ```ts
|
||
* import { Console, Effect } from "effect"
|
||
*
|
||
* // Define a cleanup effect
|
||
* const handler = Effect.ensuring(Console.log("Cleanup completed"))
|
||
*
|
||
* // Define a successful effect
|
||
* const success = Console.log("Task completed").pipe(
|
||
* Effect.as("some result"),
|
||
* handler
|
||
* )
|
||
*
|
||
* Effect.runFork(success)
|
||
* // Output:
|
||
* // Task completed
|
||
* // Cleanup completed
|
||
*
|
||
* // Define a failing effect
|
||
* const failure = Console.log("Task failed").pipe(
|
||
* Effect.andThen(Effect.fail("some error")),
|
||
* handler
|
||
* )
|
||
*
|
||
* Effect.runFork(failure)
|
||
* // Output:
|
||
* // Task failed
|
||
* // Cleanup completed
|
||
*
|
||
* // Define an interrupted effect
|
||
* const interruption = Console.log("Task interrupted").pipe(
|
||
* Effect.andThen(Effect.interrupt),
|
||
* handler
|
||
* )
|
||
*
|
||
* Effect.runFork(interruption)
|
||
* // Output:
|
||
* // Task interrupted
|
||
* // Cleanup completed
|
||
* ```
|
||
*
|
||
* @see {@link onExit} for a version that provides access to the result of an
|
||
* effect.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Scoping, Resources & Finalization
|
||
*/
|
||
<A, E, R, X, R1>(self: Effect<A, E, R>, finalizer: Effect<X, never, R1>): Effect<A, E, R1 | R>;
|
||
};
|
||
/**
|
||
* Ensures a cleanup effect runs whenever the calling effect fails, providing
|
||
* the failure cause to the cleanup effect.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to attach a cleanup effect that runs whenever the
|
||
* calling effect fails. The cleanup effect receives the cause of the failure,
|
||
* allowing you to perform actions such as logging, releasing resources, or
|
||
* executing additional recovery logic based on the error. The cleanup effect
|
||
* will execute even if the failure is due to interruption.
|
||
*
|
||
* Importantly, the cleanup effect itself is uninterruptible, ensuring that it
|
||
* completes regardless of external interruptions.
|
||
*
|
||
* **Example** (Running Cleanup Only on Failure)
|
||
*
|
||
* ```ts
|
||
* import { Console, Effect } from "effect"
|
||
*
|
||
* // This handler logs the failure cause when the effect fails
|
||
* const handler = Effect.onError((cause) =>
|
||
* Console.log(`Cleanup completed: ${cause}`)
|
||
* )
|
||
*
|
||
* // Define a successful effect
|
||
* const success = Console.log("Task completed").pipe(
|
||
* Effect.as("some result"),
|
||
* handler
|
||
* )
|
||
*
|
||
* Effect.runFork(success)
|
||
* // Output:
|
||
* // Task completed
|
||
*
|
||
* // Define a failing effect
|
||
* const failure = Console.log("Task failed").pipe(
|
||
* Effect.andThen(Effect.fail("some error")),
|
||
* handler
|
||
* )
|
||
*
|
||
* Effect.runFork(failure)
|
||
* // Output:
|
||
* // Task failed
|
||
* // Cleanup completed: Error: some error
|
||
*
|
||
* // Define a failing effect
|
||
* const defect = Console.log("Task failed with defect").pipe(
|
||
* Effect.andThen(Effect.die("Boom!")),
|
||
* handler
|
||
* )
|
||
*
|
||
* Effect.runFork(defect)
|
||
* // Output:
|
||
* // Task failed with defect
|
||
* // Cleanup completed: Error: Boom!
|
||
*
|
||
* // Define an interrupted effect
|
||
* const interruption = Console.log("Task interrupted").pipe(
|
||
* Effect.andThen(Effect.interrupt),
|
||
* handler
|
||
* )
|
||
*
|
||
* Effect.runFork(interruption)
|
||
* // Output:
|
||
* // Task interrupted
|
||
* // Cleanup completed: All fibers interrupted without errors.
|
||
* ```
|
||
*
|
||
* @see {@link ensuring} for attaching a cleanup effect that runs on both success and failure.
|
||
* @see {@link onExit} for attaching a cleanup effect that runs on all possible exits.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Scoping, Resources & Finalization
|
||
*/
|
||
export declare const onError: {
|
||
/**
|
||
* Ensures a cleanup effect runs whenever the calling effect fails, providing
|
||
* the failure cause to the cleanup effect.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to attach a cleanup effect that runs whenever the
|
||
* calling effect fails. The cleanup effect receives the cause of the failure,
|
||
* allowing you to perform actions such as logging, releasing resources, or
|
||
* executing additional recovery logic based on the error. The cleanup effect
|
||
* will execute even if the failure is due to interruption.
|
||
*
|
||
* Importantly, the cleanup effect itself is uninterruptible, ensuring that it
|
||
* completes regardless of external interruptions.
|
||
*
|
||
* **Example** (Running Cleanup Only on Failure)
|
||
*
|
||
* ```ts
|
||
* import { Console, Effect } from "effect"
|
||
*
|
||
* // This handler logs the failure cause when the effect fails
|
||
* const handler = Effect.onError((cause) =>
|
||
* Console.log(`Cleanup completed: ${cause}`)
|
||
* )
|
||
*
|
||
* // Define a successful effect
|
||
* const success = Console.log("Task completed").pipe(
|
||
* Effect.as("some result"),
|
||
* handler
|
||
* )
|
||
*
|
||
* Effect.runFork(success)
|
||
* // Output:
|
||
* // Task completed
|
||
*
|
||
* // Define a failing effect
|
||
* const failure = Console.log("Task failed").pipe(
|
||
* Effect.andThen(Effect.fail("some error")),
|
||
* handler
|
||
* )
|
||
*
|
||
* Effect.runFork(failure)
|
||
* // Output:
|
||
* // Task failed
|
||
* // Cleanup completed: Error: some error
|
||
*
|
||
* // Define a failing effect
|
||
* const defect = Console.log("Task failed with defect").pipe(
|
||
* Effect.andThen(Effect.die("Boom!")),
|
||
* handler
|
||
* )
|
||
*
|
||
* Effect.runFork(defect)
|
||
* // Output:
|
||
* // Task failed with defect
|
||
* // Cleanup completed: Error: Boom!
|
||
*
|
||
* // Define an interrupted effect
|
||
* const interruption = Console.log("Task interrupted").pipe(
|
||
* Effect.andThen(Effect.interrupt),
|
||
* handler
|
||
* )
|
||
*
|
||
* Effect.runFork(interruption)
|
||
* // Output:
|
||
* // Task interrupted
|
||
* // Cleanup completed: All fibers interrupted without errors.
|
||
* ```
|
||
*
|
||
* @see {@link ensuring} for attaching a cleanup effect that runs on both success and failure.
|
||
* @see {@link onExit} for attaching a cleanup effect that runs on all possible exits.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Scoping, Resources & Finalization
|
||
*/
|
||
<E, X, R2>(cleanup: (cause: Cause.Cause<E>) => Effect<X, never, R2>): <A, R>(self: Effect<A, E, R>) => Effect<A, E, R2 | R>;
|
||
/**
|
||
* Ensures a cleanup effect runs whenever the calling effect fails, providing
|
||
* the failure cause to the cleanup effect.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to attach a cleanup effect that runs whenever the
|
||
* calling effect fails. The cleanup effect receives the cause of the failure,
|
||
* allowing you to perform actions such as logging, releasing resources, or
|
||
* executing additional recovery logic based on the error. The cleanup effect
|
||
* will execute even if the failure is due to interruption.
|
||
*
|
||
* Importantly, the cleanup effect itself is uninterruptible, ensuring that it
|
||
* completes regardless of external interruptions.
|
||
*
|
||
* **Example** (Running Cleanup Only on Failure)
|
||
*
|
||
* ```ts
|
||
* import { Console, Effect } from "effect"
|
||
*
|
||
* // This handler logs the failure cause when the effect fails
|
||
* const handler = Effect.onError((cause) =>
|
||
* Console.log(`Cleanup completed: ${cause}`)
|
||
* )
|
||
*
|
||
* // Define a successful effect
|
||
* const success = Console.log("Task completed").pipe(
|
||
* Effect.as("some result"),
|
||
* handler
|
||
* )
|
||
*
|
||
* Effect.runFork(success)
|
||
* // Output:
|
||
* // Task completed
|
||
*
|
||
* // Define a failing effect
|
||
* const failure = Console.log("Task failed").pipe(
|
||
* Effect.andThen(Effect.fail("some error")),
|
||
* handler
|
||
* )
|
||
*
|
||
* Effect.runFork(failure)
|
||
* // Output:
|
||
* // Task failed
|
||
* // Cleanup completed: Error: some error
|
||
*
|
||
* // Define a failing effect
|
||
* const defect = Console.log("Task failed with defect").pipe(
|
||
* Effect.andThen(Effect.die("Boom!")),
|
||
* handler
|
||
* )
|
||
*
|
||
* Effect.runFork(defect)
|
||
* // Output:
|
||
* // Task failed with defect
|
||
* // Cleanup completed: Error: Boom!
|
||
*
|
||
* // Define an interrupted effect
|
||
* const interruption = Console.log("Task interrupted").pipe(
|
||
* Effect.andThen(Effect.interrupt),
|
||
* handler
|
||
* )
|
||
*
|
||
* Effect.runFork(interruption)
|
||
* // Output:
|
||
* // Task interrupted
|
||
* // Cleanup completed: All fibers interrupted without errors.
|
||
* ```
|
||
*
|
||
* @see {@link ensuring} for attaching a cleanup effect that runs on both success and failure.
|
||
* @see {@link onExit} for attaching a cleanup effect that runs on all possible exits.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Scoping, Resources & Finalization
|
||
*/
|
||
<A, E, R, X, R2>(self: Effect<A, E, R>, cleanup: (cause: Cause.Cause<E>) => Effect<X, never, R2>): Effect<A, E, R2 | R>;
|
||
};
|
||
/**
|
||
* Guarantees that a cleanup function runs regardless of whether the effect
|
||
* succeeds, fails, or is interrupted.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function ensures that a provided cleanup function is executed after the
|
||
* effect completes, regardless of the outcome. The cleanup function is given
|
||
* the `Exit` value of the effect, which provides detailed information about the
|
||
* result:
|
||
* - If the effect succeeds, the `Exit` contains the success value.
|
||
* - If the effect fails, the `Exit` contains the error or failure cause.
|
||
* - If the effect is interrupted, the `Exit` reflects the interruption.
|
||
*
|
||
* The cleanup function is guaranteed to run uninterruptibly, ensuring reliable
|
||
* resource management even in complex or high-concurrency scenarios.
|
||
*
|
||
* **Example** (Running a Cleanup Function with the Effect’s Result)
|
||
*
|
||
* ```ts
|
||
* import { Console, Effect, Exit } from "effect"
|
||
*
|
||
* // Define a cleanup effect that logs the result
|
||
* const handler = Effect.onExit((exit) =>
|
||
* Console.log(`Cleanup completed: ${Exit.getOrElse(exit, String)}`)
|
||
* )
|
||
*
|
||
* // Define a successful effect
|
||
* const success = Console.log("Task completed").pipe(
|
||
* Effect.as("some result"),
|
||
* handler
|
||
* )
|
||
*
|
||
* Effect.runFork(success)
|
||
* // Output:
|
||
* // Task completed
|
||
* // Cleanup completed: some result
|
||
*
|
||
* // Define a failing effect
|
||
* const failure = Console.log("Task failed").pipe(
|
||
* Effect.andThen(Effect.fail("some error")),
|
||
* handler
|
||
* )
|
||
*
|
||
* Effect.runFork(failure)
|
||
* // Output:
|
||
* // Task failed
|
||
* // Cleanup completed: Error: some error
|
||
*
|
||
* // Define an interrupted effect
|
||
* const interruption = Console.log("Task interrupted").pipe(
|
||
* Effect.andThen(Effect.interrupt),
|
||
* handler
|
||
* )
|
||
*
|
||
* Effect.runFork(interruption)
|
||
* // Output:
|
||
* // Task interrupted
|
||
* // Cleanup completed: All fibers interrupted without errors.
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Scoping, Resources & Finalization
|
||
*/
|
||
export declare const onExit: {
|
||
/**
|
||
* Guarantees that a cleanup function runs regardless of whether the effect
|
||
* succeeds, fails, or is interrupted.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function ensures that a provided cleanup function is executed after the
|
||
* effect completes, regardless of the outcome. The cleanup function is given
|
||
* the `Exit` value of the effect, which provides detailed information about the
|
||
* result:
|
||
* - If the effect succeeds, the `Exit` contains the success value.
|
||
* - If the effect fails, the `Exit` contains the error or failure cause.
|
||
* - If the effect is interrupted, the `Exit` reflects the interruption.
|
||
*
|
||
* The cleanup function is guaranteed to run uninterruptibly, ensuring reliable
|
||
* resource management even in complex or high-concurrency scenarios.
|
||
*
|
||
* **Example** (Running a Cleanup Function with the Effect’s Result)
|
||
*
|
||
* ```ts
|
||
* import { Console, Effect, Exit } from "effect"
|
||
*
|
||
* // Define a cleanup effect that logs the result
|
||
* const handler = Effect.onExit((exit) =>
|
||
* Console.log(`Cleanup completed: ${Exit.getOrElse(exit, String)}`)
|
||
* )
|
||
*
|
||
* // Define a successful effect
|
||
* const success = Console.log("Task completed").pipe(
|
||
* Effect.as("some result"),
|
||
* handler
|
||
* )
|
||
*
|
||
* Effect.runFork(success)
|
||
* // Output:
|
||
* // Task completed
|
||
* // Cleanup completed: some result
|
||
*
|
||
* // Define a failing effect
|
||
* const failure = Console.log("Task failed").pipe(
|
||
* Effect.andThen(Effect.fail("some error")),
|
||
* handler
|
||
* )
|
||
*
|
||
* Effect.runFork(failure)
|
||
* // Output:
|
||
* // Task failed
|
||
* // Cleanup completed: Error: some error
|
||
*
|
||
* // Define an interrupted effect
|
||
* const interruption = Console.log("Task interrupted").pipe(
|
||
* Effect.andThen(Effect.interrupt),
|
||
* handler
|
||
* )
|
||
*
|
||
* Effect.runFork(interruption)
|
||
* // Output:
|
||
* // Task interrupted
|
||
* // Cleanup completed: All fibers interrupted without errors.
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Scoping, Resources & Finalization
|
||
*/
|
||
<A, E, X, R2>(cleanup: (exit: Exit.Exit<A, E>) => Effect<X, never, R2>): <R>(self: Effect<A, E, R>) => Effect<A, E, R2 | R>;
|
||
/**
|
||
* Guarantees that a cleanup function runs regardless of whether the effect
|
||
* succeeds, fails, or is interrupted.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function ensures that a provided cleanup function is executed after the
|
||
* effect completes, regardless of the outcome. The cleanup function is given
|
||
* the `Exit` value of the effect, which provides detailed information about the
|
||
* result:
|
||
* - If the effect succeeds, the `Exit` contains the success value.
|
||
* - If the effect fails, the `Exit` contains the error or failure cause.
|
||
* - If the effect is interrupted, the `Exit` reflects the interruption.
|
||
*
|
||
* The cleanup function is guaranteed to run uninterruptibly, ensuring reliable
|
||
* resource management even in complex or high-concurrency scenarios.
|
||
*
|
||
* **Example** (Running a Cleanup Function with the Effect’s Result)
|
||
*
|
||
* ```ts
|
||
* import { Console, Effect, Exit } from "effect"
|
||
*
|
||
* // Define a cleanup effect that logs the result
|
||
* const handler = Effect.onExit((exit) =>
|
||
* Console.log(`Cleanup completed: ${Exit.getOrElse(exit, String)}`)
|
||
* )
|
||
*
|
||
* // Define a successful effect
|
||
* const success = Console.log("Task completed").pipe(
|
||
* Effect.as("some result"),
|
||
* handler
|
||
* )
|
||
*
|
||
* Effect.runFork(success)
|
||
* // Output:
|
||
* // Task completed
|
||
* // Cleanup completed: some result
|
||
*
|
||
* // Define a failing effect
|
||
* const failure = Console.log("Task failed").pipe(
|
||
* Effect.andThen(Effect.fail("some error")),
|
||
* handler
|
||
* )
|
||
*
|
||
* Effect.runFork(failure)
|
||
* // Output:
|
||
* // Task failed
|
||
* // Cleanup completed: Error: some error
|
||
*
|
||
* // Define an interrupted effect
|
||
* const interruption = Console.log("Task interrupted").pipe(
|
||
* Effect.andThen(Effect.interrupt),
|
||
* handler
|
||
* )
|
||
*
|
||
* Effect.runFork(interruption)
|
||
* // Output:
|
||
* // Task interrupted
|
||
* // Cleanup completed: All fibers interrupted without errors.
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Scoping, Resources & Finalization
|
||
*/
|
||
<A, E, R, X, R2>(self: Effect<A, E, R>, cleanup: (exit: Exit.Exit<A, E>) => Effect<X, never, R2>): Effect<A, E, R | R2>;
|
||
};
|
||
/**
|
||
* Ensures that finalizers are run concurrently when the scope of an effect is
|
||
* closed.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function modifies the behavior of finalizers within a scoped workflow to
|
||
* allow them to run concurrently when the scope is closed.
|
||
*
|
||
* By default, finalizers are executed sequentially in reverse order of their
|
||
* addition, but this function changes that behavior to execute all finalizers
|
||
* concurrently.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Running finalizers concurrently can improve performance when multiple
|
||
* independent cleanup tasks need to be performed. However, it requires that
|
||
* these tasks do not depend on the order of execution or introduce race
|
||
* conditions.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Console, Effect } from "effect"
|
||
*
|
||
* // Define a program that adds multiple finalizers
|
||
* const program = Effect.gen(function*() {
|
||
* yield* Effect.addFinalizer(() => Console.log("Finalizer 1 executed").pipe(Effect.delay("300 millis")))
|
||
* yield* Effect.addFinalizer(() => Console.log("Finalizer 2 executed").pipe(Effect.delay("100 millis")))
|
||
* yield* Effect.addFinalizer(() => Console.log("Finalizer 3 executed").pipe(Effect.delay("200 millis")))
|
||
* return "some result"
|
||
* })
|
||
*
|
||
* // Modify the program to ensure finalizers run in parallel
|
||
* const modified = program.pipe(Effect.parallelFinalizers)
|
||
*
|
||
* const runnable = Effect.scoped(modified)
|
||
*
|
||
* Effect.runFork(runnable)
|
||
* // Output:
|
||
* // Finalizer 2 executed
|
||
* // Finalizer 3 executed
|
||
* // Finalizer 1 executed
|
||
* ```
|
||
*
|
||
* @see {@link sequentialFinalizers} for a version that ensures finalizers are run sequentially.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Scoping, Resources & Finalization
|
||
*/
|
||
export declare const parallelFinalizers: <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, R>;
|
||
/**
|
||
* Ensures that finalizers are run sequentially in reverse order of their
|
||
* addition.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function modifies the behavior of finalizers within a scoped workflow to
|
||
* ensure they are run sequentially in reverse order when the scope is closed.
|
||
*
|
||
* By default, finalizers are executed sequentially, so this only changes the
|
||
* behavior if the scope is configured to run finalizers concurrently.
|
||
*
|
||
* @see {@link parallelFinalizers} for a version that ensures finalizers are run concurrently.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Scoping, Resources & Finalization
|
||
*/
|
||
export declare const sequentialFinalizers: <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, R>;
|
||
/**
|
||
* Applies a custom execution strategy to finalizers within a scoped workflow.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to control how finalizers are executed in a scope by
|
||
* applying a specified `ExecutionStrategy`. The `strategy` can dictate whether
|
||
* finalizers run (e.g., sequentially or in parallel).
|
||
*
|
||
* Additionally, the function provides a `restore` operation, which ensures that
|
||
* the effect passed to it is executed under the default execution strategy.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Scoping, Resources & Finalization
|
||
*/
|
||
export declare const finalizersMask: (strategy: ExecutionStrategy) => <A, E, R>(self: (restore: <A1, E1, R1>(self: Effect<A1, E1, R1>) => Effect<A1, E1, R1>) => Effect<A, E, R>) => Effect<A, E, R>;
|
||
/**
|
||
* Provides access to the current scope in a scoped workflow.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Scoping, Resources & Finalization
|
||
*/
|
||
export declare const scope: Effect<Scope.Scope, never, Scope.Scope>;
|
||
/**
|
||
* Accesses the current scope and uses it to perform the specified effect.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Scoping, Resources & Finalization
|
||
*/
|
||
export declare const scopeWith: <A, E, R>(f: (scope: Scope.Scope) => Effect<A, E, R>) => Effect<A, E, R | Scope.Scope>;
|
||
/**
|
||
* Creates a `Scope`, passes it to the specified effectful function, and closes
|
||
* the scope when the effect completes (whether through success, failure, or
|
||
* interruption).
|
||
*
|
||
* @since 3.11.0
|
||
* @category Scoping, Resources & Finalization
|
||
*/
|
||
export declare const scopedWith: <A, E, R>(f: (scope: Scope.Scope) => Effect<A, E, R>) => Effect<A, E, R>;
|
||
/**
|
||
* Scopes all resources used in an effect to the lifetime of the effect.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function ensures that all resources used within an effect are tied to
|
||
* its lifetime. Finalizers for these resources are executed automatically when
|
||
* the effect completes, whether through success, failure, or interruption. This
|
||
* guarantees proper resource cleanup without requiring explicit management.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Scoping, Resources & Finalization
|
||
*/
|
||
export declare const scoped: <A, E, R>(effect: Effect<A, E, R>) => Effect<A, E, Exclude<R, Scope.Scope>>;
|
||
/**
|
||
* Scopes all resources acquired by one effect to the lifetime of another
|
||
* effect.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to scope the resources acquired by one effect
|
||
* (`self`) to the lifetime of another effect (`use`). This ensures that the
|
||
* resources are cleaned up as soon as the `use` effect completes, regardless of
|
||
* how the `use` effect ends (success, failure, or interruption).
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Console, Effect } from "effect"
|
||
*
|
||
* const acquire = Console.log("Acquiring resource").pipe(
|
||
* Effect.as(1),
|
||
* Effect.tap(Effect.addFinalizer(() => Console.log("Releasing resource")))
|
||
* )
|
||
* const use = (resource: number) => Console.log(`Using resource: ${resource}`)
|
||
*
|
||
* const program = acquire.pipe(Effect.using(use))
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output:
|
||
* // Acquiring resource
|
||
* // Using resource: 1
|
||
* // Releasing resource
|
||
* ```
|
||
*
|
||
* @see {@link scopedWith} Manage scoped operations with a temporary scope.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Scoping, Resources & Finalization
|
||
*/
|
||
export declare const using: {
|
||
/**
|
||
* Scopes all resources acquired by one effect to the lifetime of another
|
||
* effect.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to scope the resources acquired by one effect
|
||
* (`self`) to the lifetime of another effect (`use`). This ensures that the
|
||
* resources are cleaned up as soon as the `use` effect completes, regardless of
|
||
* how the `use` effect ends (success, failure, or interruption).
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Console, Effect } from "effect"
|
||
*
|
||
* const acquire = Console.log("Acquiring resource").pipe(
|
||
* Effect.as(1),
|
||
* Effect.tap(Effect.addFinalizer(() => Console.log("Releasing resource")))
|
||
* )
|
||
* const use = (resource: number) => Console.log(`Using resource: ${resource}`)
|
||
*
|
||
* const program = acquire.pipe(Effect.using(use))
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output:
|
||
* // Acquiring resource
|
||
* // Using resource: 1
|
||
* // Releasing resource
|
||
* ```
|
||
*
|
||
* @see {@link scopedWith} Manage scoped operations with a temporary scope.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Scoping, Resources & Finalization
|
||
*/
|
||
<A, A2, E2, R2>(use: (a: A) => Effect<A2, E2, R2>): <E, R>(self: Effect<A, E, R>) => Effect<A2, E2 | E, R2 | Exclude<R, Scope.Scope>>;
|
||
/**
|
||
* Scopes all resources acquired by one effect to the lifetime of another
|
||
* effect.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to scope the resources acquired by one effect
|
||
* (`self`) to the lifetime of another effect (`use`). This ensures that the
|
||
* resources are cleaned up as soon as the `use` effect completes, regardless of
|
||
* how the `use` effect ends (success, failure, or interruption).
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Console, Effect } from "effect"
|
||
*
|
||
* const acquire = Console.log("Acquiring resource").pipe(
|
||
* Effect.as(1),
|
||
* Effect.tap(Effect.addFinalizer(() => Console.log("Releasing resource")))
|
||
* )
|
||
* const use = (resource: number) => Console.log(`Using resource: ${resource}`)
|
||
*
|
||
* const program = acquire.pipe(Effect.using(use))
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output:
|
||
* // Acquiring resource
|
||
* // Using resource: 1
|
||
* // Releasing resource
|
||
* ```
|
||
*
|
||
* @see {@link scopedWith} Manage scoped operations with a temporary scope.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Scoping, Resources & Finalization
|
||
*/
|
||
<A, E, R, A2, E2, R2>(self: Effect<A, E, R>, use: (a: A) => Effect<A2, E2, R2>): Effect<A2, E | E2, R2 | Exclude<R, Scope.Scope>>;
|
||
};
|
||
/**
|
||
* Returns the result of the effect and a finalizer to close its scope.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to retrieve both the result of an effect and a
|
||
* finalizer that can be used to manually close its scope. This is useful for
|
||
* workflows where you need early access to the result while retaining control
|
||
* over the resource cleanup process.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Console, Effect } from "effect"
|
||
*
|
||
* const acquire = Console.log("Acquiring resource").pipe(
|
||
* Effect.as(1),
|
||
* Effect.tap(Effect.addFinalizer(() => Console.log("Releasing resource")))
|
||
* )
|
||
* const program = Effect.gen(function*() {
|
||
* const [finalizer, resource] = yield* Effect.withEarlyRelease(acquire)
|
||
* console.log(`Using resource: ${resource}`)
|
||
* yield* Effect.sleep("1 second")
|
||
* yield* finalizer
|
||
* })
|
||
*
|
||
* Effect.runFork(program.pipe(Effect.scoped))
|
||
* // Output:
|
||
* // Acquiring resource
|
||
* // Using resource: 1
|
||
* // Releasing resource
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Scoping, Resources & Finalization
|
||
*/
|
||
export declare const withEarlyRelease: <A, E, R>(self: Effect<A, E, R>) => Effect<[finalizer: Effect<void>, result: A], E, R | Scope.Scope>;
|
||
/**
|
||
* Returns a new effect that will not succeed with its value before first
|
||
* waiting for the end of all child fibers forked by the effect.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Supervision & Fibers
|
||
*/
|
||
export declare const awaitAllChildren: <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, R>;
|
||
/**
|
||
* Returns a new workflow that will not supervise any fibers forked by this
|
||
* workflow.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Supervision & Fibers
|
||
*/
|
||
export declare const daemonChildren: <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, R>;
|
||
/**
|
||
* Constructs an effect with information about the current `Fiber`.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Supervision & Fibers
|
||
*/
|
||
export declare const descriptor: Effect<Fiber.Fiber.Descriptor>;
|
||
/**
|
||
* Constructs an effect based on information about the current `Fiber`.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Supervision & Fibers
|
||
*/
|
||
export declare const descriptorWith: <A, E, R>(f: (descriptor: Fiber.Fiber.Descriptor) => Effect<A, E, R>) => Effect<A, E, R>;
|
||
/**
|
||
* Returns a new workflow that executes this one and captures the changes in
|
||
* `FiberRef` values.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Supervision & Fibers
|
||
*/
|
||
export declare const diffFiberRefs: <A, E, R>(self: Effect<A, E, R>) => Effect<[FiberRefsPatch.FiberRefsPatch, A], E, R>;
|
||
/**
|
||
* Acts on the children of this fiber (collected into a single fiber),
|
||
* guaranteeing the specified callback will be invoked, whether or not this
|
||
* effect succeeds.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Supervision & Fibers
|
||
*/
|
||
export declare const ensuringChild: {
|
||
/**
|
||
* Acts on the children of this fiber (collected into a single fiber),
|
||
* guaranteeing the specified callback will be invoked, whether or not this
|
||
* effect succeeds.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Supervision & Fibers
|
||
*/
|
||
<X, R2>(f: (fiber: Fiber.Fiber<ReadonlyArray<unknown>, any>) => Effect<X, never, R2>): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, R2 | R>;
|
||
/**
|
||
* Acts on the children of this fiber (collected into a single fiber),
|
||
* guaranteeing the specified callback will be invoked, whether or not this
|
||
* effect succeeds.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Supervision & Fibers
|
||
*/
|
||
<A, E, R, X, R2>(self: Effect<A, E, R>, f: (fiber: Fiber.Fiber<ReadonlyArray<unknown>, any>) => Effect<X, never, R2>): Effect<A, E, R | R2>;
|
||
};
|
||
/**
|
||
* Acts on the children of this fiber, guaranteeing the specified callback
|
||
* will be invoked, whether or not this effect succeeds.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Supervision & Fibers
|
||
*/
|
||
export declare const ensuringChildren: {
|
||
/**
|
||
* Acts on the children of this fiber, guaranteeing the specified callback
|
||
* will be invoked, whether or not this effect succeeds.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Supervision & Fibers
|
||
*/
|
||
<X, R2>(children: (fibers: ReadonlyArray<Fiber.RuntimeFiber<any, any>>) => Effect<X, never, R2>): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, R2 | R>;
|
||
/**
|
||
* Acts on the children of this fiber, guaranteeing the specified callback
|
||
* will be invoked, whether or not this effect succeeds.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Supervision & Fibers
|
||
*/
|
||
<A, E, R, X, R2>(self: Effect<A, E, R>, children: (fibers: ReadonlyArray<Fiber.RuntimeFiber<any, any>>) => Effect<X, never, R2>): Effect<A, E, R | R2>;
|
||
};
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Supervision & Fibers
|
||
*/
|
||
export declare const fiberId: Effect<FiberId.FiberId>;
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Supervision & Fibers
|
||
*/
|
||
export declare const fiberIdWith: <A, E, R>(f: (descriptor: FiberId.Runtime) => Effect<A, E, R>) => Effect<A, E, R>;
|
||
/**
|
||
* Creates a new fiber to run an effect concurrently.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function takes an effect and forks it into a separate fiber, allowing it
|
||
* to run concurrently without blocking the original effect. The new fiber
|
||
* starts execution immediately after being created, and the fiber object is
|
||
* returned immediately without waiting for the effect to begin. This is useful
|
||
* when you want to run tasks concurrently while continuing other tasks in the
|
||
* parent fiber.
|
||
*
|
||
* The forked fiber is attached to the parent fiber's scope. This means that
|
||
* when the parent fiber terminates, the child fiber will also be terminated
|
||
* automatically. This feature, known as "auto supervision," ensures that no
|
||
* fibers are left running unintentionally. If you prefer not to have this auto
|
||
* supervision behavior, you can use {@link forkDaemon} or {@link forkIn}.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use this function when you need to run an effect concurrently without
|
||
* blocking the current execution flow. For example, you might use it to launch
|
||
* background tasks or concurrent computations. However, working with fibers can
|
||
* be complex, so before using this function directly, you might want to explore
|
||
* higher-level functions like {@link raceWith}, {@link zip}, or others that can
|
||
* manage concurrency for you.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const fib = (n: number): Effect.Effect<number> =>
|
||
* n < 2
|
||
* ? Effect.succeed(n)
|
||
* : Effect.zipWith(fib(n - 1), fib(n - 2), (a, b) => a + b)
|
||
*
|
||
* // ┌─── Effect<RuntimeFiber<number, never>, never, never>
|
||
* // ▼
|
||
* const fib10Fiber = Effect.fork(fib(10))
|
||
* ```
|
||
*
|
||
* @see {@link forkWithErrorHandler} for a version that allows you to handle errors.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Supervision & Fibers
|
||
*/
|
||
export declare const fork: <A, E, R>(self: Effect<A, E, R>) => Effect<Fiber.RuntimeFiber<A, E>, never, R>;
|
||
/**
|
||
* Creates a long-running background fiber that is independent of its parent.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function creates a "daemon" fiber that runs in the background and is not
|
||
* tied to the lifecycle of its parent fiber. Unlike normal fibers that stop
|
||
* when the parent fiber terminates, a daemon fiber will continue running until
|
||
* the global scope closes or the fiber completes naturally. This makes it
|
||
* useful for tasks that need to run in the background independently, such as
|
||
* periodic logging, monitoring, or background data processing.
|
||
*
|
||
* **Example** (Creating a Daemon Fiber)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console, Schedule } from "effect"
|
||
*
|
||
* // Daemon fiber that logs a message repeatedly every second
|
||
* const daemon = Effect.repeat(
|
||
* Console.log("daemon: still running!"),
|
||
* Schedule.fixed("1 second")
|
||
* )
|
||
*
|
||
* const parent = Effect.gen(function* () {
|
||
* console.log("parent: started!")
|
||
* // Daemon fiber running independently
|
||
* yield* Effect.forkDaemon(daemon)
|
||
* yield* Effect.sleep("3 seconds")
|
||
* console.log("parent: finished!")
|
||
* })
|
||
*
|
||
* Effect.runFork(parent)
|
||
* // Output:
|
||
* // parent: started!
|
||
* // daemon: still running!
|
||
* // daemon: still running!
|
||
* // daemon: still running!
|
||
* // parent: finished!
|
||
* // daemon: still running!
|
||
* // daemon: still running!
|
||
* // daemon: still running!
|
||
* // daemon: still running!
|
||
* // daemon: still running!
|
||
* // ...etc...
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Supervision & Fibers
|
||
*/
|
||
export declare const forkDaemon: <A, E, R>(self: Effect<A, E, R>) => Effect<Fiber.RuntimeFiber<A, E>, never, R>;
|
||
/**
|
||
* Returns an effect that forks all of the specified values, and returns a
|
||
* composite fiber that produces a list of their results, in order.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Supervision & Fibers
|
||
*/
|
||
export declare const forkAll: {
|
||
/**
|
||
* Returns an effect that forks all of the specified values, and returns a
|
||
* composite fiber that produces a list of their results, in order.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Supervision & Fibers
|
||
*/
|
||
(options?: {
|
||
readonly discard?: false | undefined;
|
||
} | undefined): <Eff extends Effect<any, any, any>>(effects: Iterable<Eff>) => Effect<Fiber.Fiber<Array<Effect.Success<Eff>>, Effect.Error<Eff>>, never, Effect.Context<Eff>>;
|
||
/**
|
||
* Returns an effect that forks all of the specified values, and returns a
|
||
* composite fiber that produces a list of their results, in order.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Supervision & Fibers
|
||
*/
|
||
(options: {
|
||
readonly discard: true;
|
||
}): <Eff extends Effect<any, any, any>>(effects: Iterable<Eff>) => Effect<void, never, Effect.Context<Eff>>;
|
||
/**
|
||
* Returns an effect that forks all of the specified values, and returns a
|
||
* composite fiber that produces a list of their results, in order.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Supervision & Fibers
|
||
*/
|
||
<Eff extends Effect<any, any, any>>(effects: Iterable<Eff>, options?: {
|
||
readonly discard?: false | undefined;
|
||
} | undefined): Effect<Fiber.Fiber<Array<Effect.Success<Eff>>, Effect.Error<Eff>>, never, Effect.Context<Eff>>;
|
||
/**
|
||
* Returns an effect that forks all of the specified values, and returns a
|
||
* composite fiber that produces a list of their results, in order.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Supervision & Fibers
|
||
*/
|
||
<Eff extends Effect<any, any, any>>(effects: Iterable<Eff>, options: {
|
||
readonly discard: true;
|
||
}): Effect<void, never, Effect.Context<Eff>>;
|
||
};
|
||
/**
|
||
* Forks an effect in a specific scope, allowing finer control over its
|
||
* execution.
|
||
*
|
||
* **Details**
|
||
*
|
||
* There are some cases where we need more fine-grained control, so we want to
|
||
* fork a fiber in a specific scope. We can use the `Effect.forkIn` operator
|
||
* which takes the target scope as an argument.
|
||
*
|
||
* The fiber will be interrupted when the scope is closed.
|
||
*
|
||
* **Example** (Forking a Fiber in a Specific Scope)
|
||
*
|
||
* In this example, the child fiber is forked into the outerScope,
|
||
* allowing it to outlive the inner scope but still be terminated
|
||
* when the outerScope is closed.
|
||
*
|
||
* ```ts
|
||
* import { Console, Effect, Schedule } from "effect"
|
||
*
|
||
* // Child fiber that logs a message repeatedly every second
|
||
* const child = Effect.repeat(
|
||
* Console.log("child: still running!"),
|
||
* Schedule.fixed("1 second")
|
||
* )
|
||
*
|
||
* const program = Effect.scoped(
|
||
* Effect.gen(function* () {
|
||
* yield* Effect.addFinalizer(() =>
|
||
* Console.log("The outer scope is about to be closed!")
|
||
* )
|
||
*
|
||
* // Capture the outer scope
|
||
* const outerScope = yield* Effect.scope
|
||
*
|
||
* // Create an inner scope
|
||
* yield* Effect.scoped(
|
||
* Effect.gen(function* () {
|
||
* yield* Effect.addFinalizer(() =>
|
||
* Console.log("The inner scope is about to be closed!")
|
||
* )
|
||
* // Fork the child fiber in the outer scope
|
||
* yield* Effect.forkIn(child, outerScope)
|
||
* yield* Effect.sleep("3 seconds")
|
||
* })
|
||
* )
|
||
*
|
||
* yield* Effect.sleep("5 seconds")
|
||
* })
|
||
* )
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output:
|
||
* // child: still running!
|
||
* // child: still running!
|
||
* // child: still running!
|
||
* // The inner scope is about to be closed!
|
||
* // child: still running!
|
||
* // child: still running!
|
||
* // child: still running!
|
||
* // child: still running!
|
||
* // child: still running!
|
||
* // child: still running!
|
||
* // The outer scope is about to be closed!
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Supervision & Fibers
|
||
*/
|
||
export declare const forkIn: {
|
||
/**
|
||
* Forks an effect in a specific scope, allowing finer control over its
|
||
* execution.
|
||
*
|
||
* **Details**
|
||
*
|
||
* There are some cases where we need more fine-grained control, so we want to
|
||
* fork a fiber in a specific scope. We can use the `Effect.forkIn` operator
|
||
* which takes the target scope as an argument.
|
||
*
|
||
* The fiber will be interrupted when the scope is closed.
|
||
*
|
||
* **Example** (Forking a Fiber in a Specific Scope)
|
||
*
|
||
* In this example, the child fiber is forked into the outerScope,
|
||
* allowing it to outlive the inner scope but still be terminated
|
||
* when the outerScope is closed.
|
||
*
|
||
* ```ts
|
||
* import { Console, Effect, Schedule } from "effect"
|
||
*
|
||
* // Child fiber that logs a message repeatedly every second
|
||
* const child = Effect.repeat(
|
||
* Console.log("child: still running!"),
|
||
* Schedule.fixed("1 second")
|
||
* )
|
||
*
|
||
* const program = Effect.scoped(
|
||
* Effect.gen(function* () {
|
||
* yield* Effect.addFinalizer(() =>
|
||
* Console.log("The outer scope is about to be closed!")
|
||
* )
|
||
*
|
||
* // Capture the outer scope
|
||
* const outerScope = yield* Effect.scope
|
||
*
|
||
* // Create an inner scope
|
||
* yield* Effect.scoped(
|
||
* Effect.gen(function* () {
|
||
* yield* Effect.addFinalizer(() =>
|
||
* Console.log("The inner scope is about to be closed!")
|
||
* )
|
||
* // Fork the child fiber in the outer scope
|
||
* yield* Effect.forkIn(child, outerScope)
|
||
* yield* Effect.sleep("3 seconds")
|
||
* })
|
||
* )
|
||
*
|
||
* yield* Effect.sleep("5 seconds")
|
||
* })
|
||
* )
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output:
|
||
* // child: still running!
|
||
* // child: still running!
|
||
* // child: still running!
|
||
* // The inner scope is about to be closed!
|
||
* // child: still running!
|
||
* // child: still running!
|
||
* // child: still running!
|
||
* // child: still running!
|
||
* // child: still running!
|
||
* // child: still running!
|
||
* // The outer scope is about to be closed!
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Supervision & Fibers
|
||
*/
|
||
(scope: Scope.Scope): <A, E, R>(self: Effect<A, E, R>) => Effect<Fiber.RuntimeFiber<A, E>, never, R>;
|
||
/**
|
||
* Forks an effect in a specific scope, allowing finer control over its
|
||
* execution.
|
||
*
|
||
* **Details**
|
||
*
|
||
* There are some cases where we need more fine-grained control, so we want to
|
||
* fork a fiber in a specific scope. We can use the `Effect.forkIn` operator
|
||
* which takes the target scope as an argument.
|
||
*
|
||
* The fiber will be interrupted when the scope is closed.
|
||
*
|
||
* **Example** (Forking a Fiber in a Specific Scope)
|
||
*
|
||
* In this example, the child fiber is forked into the outerScope,
|
||
* allowing it to outlive the inner scope but still be terminated
|
||
* when the outerScope is closed.
|
||
*
|
||
* ```ts
|
||
* import { Console, Effect, Schedule } from "effect"
|
||
*
|
||
* // Child fiber that logs a message repeatedly every second
|
||
* const child = Effect.repeat(
|
||
* Console.log("child: still running!"),
|
||
* Schedule.fixed("1 second")
|
||
* )
|
||
*
|
||
* const program = Effect.scoped(
|
||
* Effect.gen(function* () {
|
||
* yield* Effect.addFinalizer(() =>
|
||
* Console.log("The outer scope is about to be closed!")
|
||
* )
|
||
*
|
||
* // Capture the outer scope
|
||
* const outerScope = yield* Effect.scope
|
||
*
|
||
* // Create an inner scope
|
||
* yield* Effect.scoped(
|
||
* Effect.gen(function* () {
|
||
* yield* Effect.addFinalizer(() =>
|
||
* Console.log("The inner scope is about to be closed!")
|
||
* )
|
||
* // Fork the child fiber in the outer scope
|
||
* yield* Effect.forkIn(child, outerScope)
|
||
* yield* Effect.sleep("3 seconds")
|
||
* })
|
||
* )
|
||
*
|
||
* yield* Effect.sleep("5 seconds")
|
||
* })
|
||
* )
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output:
|
||
* // child: still running!
|
||
* // child: still running!
|
||
* // child: still running!
|
||
* // The inner scope is about to be closed!
|
||
* // child: still running!
|
||
* // child: still running!
|
||
* // child: still running!
|
||
* // child: still running!
|
||
* // child: still running!
|
||
* // child: still running!
|
||
* // The outer scope is about to be closed!
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Supervision & Fibers
|
||
*/
|
||
<A, E, R>(self: Effect<A, E, R>, scope: Scope.Scope): Effect<Fiber.RuntimeFiber<A, E>, never, R>;
|
||
};
|
||
/**
|
||
* Forks a fiber in a local scope, ensuring it outlives its parent.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function is used to create fibers that are tied to a local scope,
|
||
* meaning they are not dependent on their parent fiber's lifecycle. Instead,
|
||
* they will continue running until the scope they were created in is closed.
|
||
* This is particularly useful when you need a fiber to run independently of the
|
||
* parent fiber, but still want it to be terminated when the scope ends.
|
||
*
|
||
* Fibers created with this function are isolated from the parent fiber’s
|
||
* termination, so they can run for a longer period. This behavior is different
|
||
* from fibers created with {@link fork}, which are terminated when the parent fiber
|
||
* terminates. With `forkScoped`, the child fiber will keep running until the
|
||
* local scope ends, regardless of the state of the parent fiber.
|
||
*
|
||
* **Example** (Forking a Fiber in a Local Scope)
|
||
*
|
||
* In this example, the child fiber continues to run beyond the lifetime of the parent fiber.
|
||
* The child fiber is tied to the local scope and will be terminated only when the scope ends.
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console, Schedule } from "effect"
|
||
*
|
||
* // Child fiber that logs a message repeatedly every second
|
||
* const child = Effect.repeat(
|
||
* Console.log("child: still running!"),
|
||
* Schedule.fixed("1 second")
|
||
* )
|
||
*
|
||
* // ┌─── Effect<void, never, Scope>
|
||
* // ▼
|
||
* const parent = Effect.gen(function* () {
|
||
* console.log("parent: started!")
|
||
* // Child fiber attached to local scope
|
||
* yield* Effect.forkScoped(child)
|
||
* yield* Effect.sleep("3 seconds")
|
||
* console.log("parent: finished!")
|
||
* })
|
||
*
|
||
* // Program runs within a local scope
|
||
* const program = Effect.scoped(
|
||
* Effect.gen(function* () {
|
||
* console.log("Local scope started!")
|
||
* yield* Effect.fork(parent)
|
||
* // Scope lasts for 5 seconds
|
||
* yield* Effect.sleep("5 seconds")
|
||
* console.log("Leaving the local scope!")
|
||
* })
|
||
* )
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output:
|
||
* // Local scope started!
|
||
* // parent: started!
|
||
* // child: still running!
|
||
* // child: still running!
|
||
* // child: still running!
|
||
* // parent: finished!
|
||
* // child: still running!
|
||
* // child: still running!
|
||
* // Leaving the local scope!
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Supervision & Fibers
|
||
*/
|
||
export declare const forkScoped: <A, E, R>(self: Effect<A, E, R>) => Effect<Fiber.RuntimeFiber<A, E>, never, Scope.Scope | R>;
|
||
/**
|
||
* Like {@link fork} but handles an error with the provided handler.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Supervision & Fibers
|
||
*/
|
||
export declare const forkWithErrorHandler: {
|
||
/**
|
||
* Like {@link fork} but handles an error with the provided handler.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Supervision & Fibers
|
||
*/
|
||
<E, X>(handler: (e: E) => Effect<X>): <A, R>(self: Effect<A, E, R>) => Effect<Fiber.RuntimeFiber<A, E>, never, R>;
|
||
/**
|
||
* Like {@link fork} but handles an error with the provided handler.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Supervision & Fibers
|
||
*/
|
||
<A, E, R, X>(self: Effect<A, E, R>, handler: (e: E) => Effect<X>): Effect<Fiber.RuntimeFiber<A, E>, never, R>;
|
||
};
|
||
/**
|
||
* Creates an `Effect` value that represents the exit value of the specified
|
||
* fiber.
|
||
*
|
||
* @see {@link fromFiberEffect} for creating an effect from a fiber obtained from an effect.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Supervision & Fibers
|
||
*/
|
||
export declare const fromFiber: <A, E>(fiber: Fiber.Fiber<A, E>) => Effect<A, E>;
|
||
/**
|
||
* Creates an `Effect` value that represents the exit value of a fiber obtained
|
||
* from an effect.
|
||
*
|
||
* @see {@link fromFiber} for creating an effect from a fiber.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Supervision & Fibers
|
||
*/
|
||
export declare const fromFiberEffect: <A, E, R>(fiber: Effect<Fiber.Fiber<A, E>, E, R>) => Effect<A, E, R>;
|
||
/**
|
||
* Supervises child fibers by reporting them to a specified supervisor.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function takes a supervisor as an argument and returns an effect where
|
||
* all child fibers forked within it are supervised by the provided supervisor.
|
||
* This enables you to capture detailed information about these child fibers,
|
||
* such as their status, through the supervisor.
|
||
*
|
||
* **Example** (Monitoring Fiber Count)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Supervisor, Schedule, Fiber, FiberStatus } from "effect"
|
||
*
|
||
* // Main program that monitors fibers while calculating a Fibonacci number
|
||
* const program = Effect.gen(function* () {
|
||
* // Create a supervisor to track child fibers
|
||
* const supervisor = yield* Supervisor.track
|
||
*
|
||
* // Start a Fibonacci calculation, supervised by the supervisor
|
||
* const fibFiber = yield* fib(20).pipe(
|
||
* Effect.supervised(supervisor),
|
||
* // Fork the Fibonacci effect into a fiber
|
||
* Effect.fork
|
||
* )
|
||
*
|
||
* // Define a schedule to periodically monitor the fiber count every 500ms
|
||
* const policy = Schedule.spaced("500 millis").pipe(
|
||
* Schedule.whileInputEffect((_) =>
|
||
* Fiber.status(fibFiber).pipe(
|
||
* // Continue while the Fibonacci fiber is not done
|
||
* Effect.andThen((status) => status !== FiberStatus.done)
|
||
* )
|
||
* )
|
||
* )
|
||
*
|
||
* // Start monitoring the fibers, using the supervisor to track the count
|
||
* const monitorFiber = yield* monitorFibers(supervisor).pipe(
|
||
* // Repeat the monitoring according to the schedule
|
||
* Effect.repeat(policy),
|
||
* // Fork the monitoring into its own fiber
|
||
* Effect.fork
|
||
* )
|
||
*
|
||
* // Join the monitor and Fibonacci fibers to ensure they complete
|
||
* yield* Fiber.join(monitorFiber)
|
||
* const result = yield* Fiber.join(fibFiber)
|
||
*
|
||
* console.log(`fibonacci result: ${result}`)
|
||
* })
|
||
*
|
||
* // Function to monitor and log the number of active fibers
|
||
* const monitorFibers = (
|
||
* supervisor: Supervisor.Supervisor<Array<Fiber.RuntimeFiber<any, any>>>
|
||
* ): Effect.Effect<void> =>
|
||
* Effect.gen(function* () {
|
||
* const fibers = yield* supervisor.value // Get the current set of fibers
|
||
* console.log(`number of fibers: ${fibers.length}`)
|
||
* })
|
||
*
|
||
* // Recursive Fibonacci calculation, spawning fibers for each recursive step
|
||
* const fib = (n: number): Effect.Effect<number> =>
|
||
* Effect.gen(function* () {
|
||
* if (n <= 1) {
|
||
* return 1
|
||
* }
|
||
* yield* Effect.sleep("500 millis") // Simulate work by delaying
|
||
*
|
||
* // Fork two fibers for the recursive Fibonacci calls
|
||
* const fiber1 = yield* Effect.fork(fib(n - 2))
|
||
* const fiber2 = yield* Effect.fork(fib(n - 1))
|
||
*
|
||
* // Join the fibers to retrieve their results
|
||
* const v1 = yield* Fiber.join(fiber1)
|
||
* const v2 = yield* Fiber.join(fiber2)
|
||
*
|
||
* return v1 + v2 // Combine the results
|
||
* })
|
||
*
|
||
* Effect.runPromise(program)
|
||
* // Output:
|
||
* // number of fibers: 0
|
||
* // number of fibers: 2
|
||
* // number of fibers: 6
|
||
* // number of fibers: 14
|
||
* // number of fibers: 30
|
||
* // number of fibers: 62
|
||
* // number of fibers: 126
|
||
* // number of fibers: 254
|
||
* // number of fibers: 510
|
||
* // number of fibers: 1022
|
||
* // number of fibers: 2034
|
||
* // number of fibers: 3795
|
||
* // number of fibers: 5810
|
||
* // number of fibers: 6474
|
||
* // number of fibers: 4942
|
||
* // number of fibers: 2515
|
||
* // number of fibers: 832
|
||
* // number of fibers: 170
|
||
* // number of fibers: 18
|
||
* // number of fibers: 0
|
||
* // fibonacci result: 10946
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Supervision & Fibers
|
||
*/
|
||
export declare const supervised: {
|
||
/**
|
||
* Supervises child fibers by reporting them to a specified supervisor.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function takes a supervisor as an argument and returns an effect where
|
||
* all child fibers forked within it are supervised by the provided supervisor.
|
||
* This enables you to capture detailed information about these child fibers,
|
||
* such as their status, through the supervisor.
|
||
*
|
||
* **Example** (Monitoring Fiber Count)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Supervisor, Schedule, Fiber, FiberStatus } from "effect"
|
||
*
|
||
* // Main program that monitors fibers while calculating a Fibonacci number
|
||
* const program = Effect.gen(function* () {
|
||
* // Create a supervisor to track child fibers
|
||
* const supervisor = yield* Supervisor.track
|
||
*
|
||
* // Start a Fibonacci calculation, supervised by the supervisor
|
||
* const fibFiber = yield* fib(20).pipe(
|
||
* Effect.supervised(supervisor),
|
||
* // Fork the Fibonacci effect into a fiber
|
||
* Effect.fork
|
||
* )
|
||
*
|
||
* // Define a schedule to periodically monitor the fiber count every 500ms
|
||
* const policy = Schedule.spaced("500 millis").pipe(
|
||
* Schedule.whileInputEffect((_) =>
|
||
* Fiber.status(fibFiber).pipe(
|
||
* // Continue while the Fibonacci fiber is not done
|
||
* Effect.andThen((status) => status !== FiberStatus.done)
|
||
* )
|
||
* )
|
||
* )
|
||
*
|
||
* // Start monitoring the fibers, using the supervisor to track the count
|
||
* const monitorFiber = yield* monitorFibers(supervisor).pipe(
|
||
* // Repeat the monitoring according to the schedule
|
||
* Effect.repeat(policy),
|
||
* // Fork the monitoring into its own fiber
|
||
* Effect.fork
|
||
* )
|
||
*
|
||
* // Join the monitor and Fibonacci fibers to ensure they complete
|
||
* yield* Fiber.join(monitorFiber)
|
||
* const result = yield* Fiber.join(fibFiber)
|
||
*
|
||
* console.log(`fibonacci result: ${result}`)
|
||
* })
|
||
*
|
||
* // Function to monitor and log the number of active fibers
|
||
* const monitorFibers = (
|
||
* supervisor: Supervisor.Supervisor<Array<Fiber.RuntimeFiber<any, any>>>
|
||
* ): Effect.Effect<void> =>
|
||
* Effect.gen(function* () {
|
||
* const fibers = yield* supervisor.value // Get the current set of fibers
|
||
* console.log(`number of fibers: ${fibers.length}`)
|
||
* })
|
||
*
|
||
* // Recursive Fibonacci calculation, spawning fibers for each recursive step
|
||
* const fib = (n: number): Effect.Effect<number> =>
|
||
* Effect.gen(function* () {
|
||
* if (n <= 1) {
|
||
* return 1
|
||
* }
|
||
* yield* Effect.sleep("500 millis") // Simulate work by delaying
|
||
*
|
||
* // Fork two fibers for the recursive Fibonacci calls
|
||
* const fiber1 = yield* Effect.fork(fib(n - 2))
|
||
* const fiber2 = yield* Effect.fork(fib(n - 1))
|
||
*
|
||
* // Join the fibers to retrieve their results
|
||
* const v1 = yield* Fiber.join(fiber1)
|
||
* const v2 = yield* Fiber.join(fiber2)
|
||
*
|
||
* return v1 + v2 // Combine the results
|
||
* })
|
||
*
|
||
* Effect.runPromise(program)
|
||
* // Output:
|
||
* // number of fibers: 0
|
||
* // number of fibers: 2
|
||
* // number of fibers: 6
|
||
* // number of fibers: 14
|
||
* // number of fibers: 30
|
||
* // number of fibers: 62
|
||
* // number of fibers: 126
|
||
* // number of fibers: 254
|
||
* // number of fibers: 510
|
||
* // number of fibers: 1022
|
||
* // number of fibers: 2034
|
||
* // number of fibers: 3795
|
||
* // number of fibers: 5810
|
||
* // number of fibers: 6474
|
||
* // number of fibers: 4942
|
||
* // number of fibers: 2515
|
||
* // number of fibers: 832
|
||
* // number of fibers: 170
|
||
* // number of fibers: 18
|
||
* // number of fibers: 0
|
||
* // fibonacci result: 10946
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Supervision & Fibers
|
||
*/
|
||
<X>(supervisor: Supervisor.Supervisor<X>): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, R>;
|
||
/**
|
||
* Supervises child fibers by reporting them to a specified supervisor.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function takes a supervisor as an argument and returns an effect where
|
||
* all child fibers forked within it are supervised by the provided supervisor.
|
||
* This enables you to capture detailed information about these child fibers,
|
||
* such as their status, through the supervisor.
|
||
*
|
||
* **Example** (Monitoring Fiber Count)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Supervisor, Schedule, Fiber, FiberStatus } from "effect"
|
||
*
|
||
* // Main program that monitors fibers while calculating a Fibonacci number
|
||
* const program = Effect.gen(function* () {
|
||
* // Create a supervisor to track child fibers
|
||
* const supervisor = yield* Supervisor.track
|
||
*
|
||
* // Start a Fibonacci calculation, supervised by the supervisor
|
||
* const fibFiber = yield* fib(20).pipe(
|
||
* Effect.supervised(supervisor),
|
||
* // Fork the Fibonacci effect into a fiber
|
||
* Effect.fork
|
||
* )
|
||
*
|
||
* // Define a schedule to periodically monitor the fiber count every 500ms
|
||
* const policy = Schedule.spaced("500 millis").pipe(
|
||
* Schedule.whileInputEffect((_) =>
|
||
* Fiber.status(fibFiber).pipe(
|
||
* // Continue while the Fibonacci fiber is not done
|
||
* Effect.andThen((status) => status !== FiberStatus.done)
|
||
* )
|
||
* )
|
||
* )
|
||
*
|
||
* // Start monitoring the fibers, using the supervisor to track the count
|
||
* const monitorFiber = yield* monitorFibers(supervisor).pipe(
|
||
* // Repeat the monitoring according to the schedule
|
||
* Effect.repeat(policy),
|
||
* // Fork the monitoring into its own fiber
|
||
* Effect.fork
|
||
* )
|
||
*
|
||
* // Join the monitor and Fibonacci fibers to ensure they complete
|
||
* yield* Fiber.join(monitorFiber)
|
||
* const result = yield* Fiber.join(fibFiber)
|
||
*
|
||
* console.log(`fibonacci result: ${result}`)
|
||
* })
|
||
*
|
||
* // Function to monitor and log the number of active fibers
|
||
* const monitorFibers = (
|
||
* supervisor: Supervisor.Supervisor<Array<Fiber.RuntimeFiber<any, any>>>
|
||
* ): Effect.Effect<void> =>
|
||
* Effect.gen(function* () {
|
||
* const fibers = yield* supervisor.value // Get the current set of fibers
|
||
* console.log(`number of fibers: ${fibers.length}`)
|
||
* })
|
||
*
|
||
* // Recursive Fibonacci calculation, spawning fibers for each recursive step
|
||
* const fib = (n: number): Effect.Effect<number> =>
|
||
* Effect.gen(function* () {
|
||
* if (n <= 1) {
|
||
* return 1
|
||
* }
|
||
* yield* Effect.sleep("500 millis") // Simulate work by delaying
|
||
*
|
||
* // Fork two fibers for the recursive Fibonacci calls
|
||
* const fiber1 = yield* Effect.fork(fib(n - 2))
|
||
* const fiber2 = yield* Effect.fork(fib(n - 1))
|
||
*
|
||
* // Join the fibers to retrieve their results
|
||
* const v1 = yield* Fiber.join(fiber1)
|
||
* const v2 = yield* Fiber.join(fiber2)
|
||
*
|
||
* return v1 + v2 // Combine the results
|
||
* })
|
||
*
|
||
* Effect.runPromise(program)
|
||
* // Output:
|
||
* // number of fibers: 0
|
||
* // number of fibers: 2
|
||
* // number of fibers: 6
|
||
* // number of fibers: 14
|
||
* // number of fibers: 30
|
||
* // number of fibers: 62
|
||
* // number of fibers: 126
|
||
* // number of fibers: 254
|
||
* // number of fibers: 510
|
||
* // number of fibers: 1022
|
||
* // number of fibers: 2034
|
||
* // number of fibers: 3795
|
||
* // number of fibers: 5810
|
||
* // number of fibers: 6474
|
||
* // number of fibers: 4942
|
||
* // number of fibers: 2515
|
||
* // number of fibers: 832
|
||
* // number of fibers: 170
|
||
* // number of fibers: 18
|
||
* // number of fibers: 0
|
||
* // fibonacci result: 10946
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Supervision & Fibers
|
||
*/
|
||
<A, E, R, X>(self: Effect<A, E, R>, supervisor: Supervisor.Supervisor<X>): Effect<A, E, R>;
|
||
};
|
||
/**
|
||
* Transplants specified effects so that when those effects fork other
|
||
* effects, the forked effects will be governed by the scope of the fiber that
|
||
* executes this effect.
|
||
*
|
||
* This can be used to "graft" deep grandchildren onto a higher-level scope,
|
||
* effectively extending their lifespans into the parent scope.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Supervision & Fibers
|
||
*/
|
||
export declare const transplant: <A, E, R>(f: (grafter: <A2, E2, R2>(effect: Effect<A2, E2, R2>) => Effect<A2, E2, R2>) => Effect<A, E, R>) => Effect<A, E, R>;
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Supervision & Fibers
|
||
*/
|
||
export declare const withConcurrency: {
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Supervision & Fibers
|
||
*/
|
||
(concurrency: number | "unbounded"): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, R>;
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Supervision & Fibers
|
||
*/
|
||
<A, E, R>(self: Effect<A, E, R>, concurrency: number | "unbounded"): Effect<A, E, R>;
|
||
};
|
||
/**
|
||
* Sets the provided scheduler for usage in the wrapped effect
|
||
*
|
||
* @since 2.0.0
|
||
* @category Scheduler
|
||
*/
|
||
export declare const withScheduler: {
|
||
/**
|
||
* Sets the provided scheduler for usage in the wrapped effect
|
||
*
|
||
* @since 2.0.0
|
||
* @category Scheduler
|
||
*/
|
||
(scheduler: Scheduler.Scheduler): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, R>;
|
||
/**
|
||
* Sets the provided scheduler for usage in the wrapped effect
|
||
*
|
||
* @since 2.0.0
|
||
* @category Scheduler
|
||
*/
|
||
<A, E, R>(self: Effect<A, E, R>, scheduler: Scheduler.Scheduler): Effect<A, E, R>;
|
||
};
|
||
/**
|
||
* Sets the scheduling priority used when yielding
|
||
*
|
||
* @since 2.0.0
|
||
* @category Scheduler
|
||
*/
|
||
export declare const withSchedulingPriority: {
|
||
/**
|
||
* Sets the scheduling priority used when yielding
|
||
*
|
||
* @since 2.0.0
|
||
* @category Scheduler
|
||
*/
|
||
(priority: number): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, R>;
|
||
/**
|
||
* Sets the scheduling priority used when yielding
|
||
*
|
||
* @since 2.0.0
|
||
* @category Scheduler
|
||
*/
|
||
<A, E, R>(self: Effect<A, E, R>, priority: number): Effect<A, E, R>;
|
||
};
|
||
/**
|
||
* Sets the maximum number of operations before yield by the default schedulers
|
||
*
|
||
* @since 2.0.0
|
||
* @category Scheduler
|
||
*/
|
||
export declare const withMaxOpsBeforeYield: {
|
||
/**
|
||
* Sets the maximum number of operations before yield by the default schedulers
|
||
*
|
||
* @since 2.0.0
|
||
* @category Scheduler
|
||
*/
|
||
(priority: number): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, R>;
|
||
/**
|
||
* Sets the maximum number of operations before yield by the default schedulers
|
||
*
|
||
* @since 2.0.0
|
||
* @category Scheduler
|
||
*/
|
||
<A, E, R>(self: Effect<A, E, R>, priority: number): Effect<A, E, R>;
|
||
};
|
||
/**
|
||
* Retrieves the `Clock` service from the context.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const program = Effect.gen(function*() {
|
||
* const clock = yield* Effect.clock
|
||
* const currentTime = yield* clock.currentTimeMillis
|
||
* console.log(`Current time in milliseconds: ${currentTime}`)
|
||
* })
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Example Output:
|
||
* // Current time in milliseconds: 1735484796134
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Clock
|
||
*/
|
||
export declare const clock: Effect<Clock.Clock>;
|
||
/**
|
||
* Retrieves the `Clock` service from the context and provides it to the
|
||
* specified effectful function.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Console, Effect } from "effect"
|
||
*
|
||
* const program = Effect.clockWith((clock) =>
|
||
* clock.currentTimeMillis.pipe(
|
||
* Effect.map((currentTime) => `Current time is: ${currentTime}`),
|
||
* Effect.tap(Console.log)
|
||
* )
|
||
* )
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Example Output:
|
||
* // Current time is: 1735484929744
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Clock
|
||
*/
|
||
export declare const clockWith: <A, E, R>(f: (clock: Clock.Clock) => Effect<A, E, R>) => Effect<A, E, R>;
|
||
/**
|
||
* Sets the implementation of the `Clock` service to the specified value and
|
||
* restores it to its original value when the scope is closed.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Clock
|
||
*/
|
||
export declare const withClockScoped: <C extends Clock.Clock>(clock: C) => Effect<void, never, Scope.Scope>;
|
||
/**
|
||
* Executes the specified workflow with the specified implementation of the
|
||
* `Clock` service.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Clock
|
||
*/
|
||
export declare const withClock: {
|
||
/**
|
||
* Executes the specified workflow with the specified implementation of the
|
||
* `Clock` service.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Clock
|
||
*/
|
||
<C extends Clock.Clock>(clock: C): <A, E, R>(effect: Effect<A, E, R>) => Effect<A, E, R>;
|
||
/**
|
||
* Executes the specified workflow with the specified implementation of the
|
||
* `Clock` service.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Clock
|
||
*/
|
||
<C extends Clock.Clock, A, E, R>(effect: Effect<A, E, R>, clock: C): Effect<A, E, R>;
|
||
};
|
||
/**
|
||
* Retreives the `Console` service from the context
|
||
*
|
||
* @since 2.0.0
|
||
* @category Console
|
||
*/
|
||
export declare const console: Effect<Console>;
|
||
/**
|
||
* Retreives the `Console` service from the context and provides it to the
|
||
* specified effectful function.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Console
|
||
*/
|
||
export declare const consoleWith: <A, E, R>(f: (console: Console) => Effect<A, E, R>) => Effect<A, E, R>;
|
||
/**
|
||
* Sets the implementation of the console service to the specified value and
|
||
* restores it to its original value when the scope is closed.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Creating Effects
|
||
*/
|
||
export declare const withConsoleScoped: <A extends Console>(console: A) => Effect<void, never, Scope.Scope>;
|
||
/**
|
||
* Executes the specified workflow with the specified implementation of the
|
||
* console service.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Console
|
||
*/
|
||
export declare const withConsole: {
|
||
/**
|
||
* Executes the specified workflow with the specified implementation of the
|
||
* console service.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Console
|
||
*/
|
||
<C extends Console>(console: C): <A, E, R>(effect: Effect<A, E, R>) => Effect<A, E, R>;
|
||
/**
|
||
* Executes the specified workflow with the specified implementation of the
|
||
* console service.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Console
|
||
*/
|
||
<A, E, R, C extends Console>(effect: Effect<A, E, R>, console: C): Effect<A, E, R>;
|
||
};
|
||
/**
|
||
* Delays the execution of an effect by a specified `Duration`.
|
||
*
|
||
* **Details
|
||
*
|
||
* This function postpones the execution of the provided effect by the specified
|
||
* duration. The duration can be provided in various formats supported by the
|
||
* `Duration` module.
|
||
*
|
||
* Internally, this function does not block the thread; instead, it uses an
|
||
* efficient, non-blocking mechanism to introduce the delay.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Console, Effect } from "effect"
|
||
*
|
||
* const task = Console.log("Task executed")
|
||
*
|
||
* const program = Console.log("start").pipe(
|
||
* Effect.andThen(
|
||
* // Delays the log message by 2 seconds
|
||
* task.pipe(Effect.delay("2 seconds"))
|
||
* )
|
||
* )
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output:
|
||
* // start
|
||
* // Task executed
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Delays & Timeouts
|
||
*/
|
||
export declare const delay: {
|
||
/**
|
||
* Delays the execution of an effect by a specified `Duration`.
|
||
*
|
||
* **Details
|
||
*
|
||
* This function postpones the execution of the provided effect by the specified
|
||
* duration. The duration can be provided in various formats supported by the
|
||
* `Duration` module.
|
||
*
|
||
* Internally, this function does not block the thread; instead, it uses an
|
||
* efficient, non-blocking mechanism to introduce the delay.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Console, Effect } from "effect"
|
||
*
|
||
* const task = Console.log("Task executed")
|
||
*
|
||
* const program = Console.log("start").pipe(
|
||
* Effect.andThen(
|
||
* // Delays the log message by 2 seconds
|
||
* task.pipe(Effect.delay("2 seconds"))
|
||
* )
|
||
* )
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output:
|
||
* // start
|
||
* // Task executed
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Delays & Timeouts
|
||
*/
|
||
(duration: Duration.DurationInput): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, R>;
|
||
/**
|
||
* Delays the execution of an effect by a specified `Duration`.
|
||
*
|
||
* **Details
|
||
*
|
||
* This function postpones the execution of the provided effect by the specified
|
||
* duration. The duration can be provided in various formats supported by the
|
||
* `Duration` module.
|
||
*
|
||
* Internally, this function does not block the thread; instead, it uses an
|
||
* efficient, non-blocking mechanism to introduce the delay.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Console, Effect } from "effect"
|
||
*
|
||
* const task = Console.log("Task executed")
|
||
*
|
||
* const program = Console.log("start").pipe(
|
||
* Effect.andThen(
|
||
* // Delays the log message by 2 seconds
|
||
* task.pipe(Effect.delay("2 seconds"))
|
||
* )
|
||
* )
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output:
|
||
* // start
|
||
* // Task executed
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Delays & Timeouts
|
||
*/
|
||
<A, E, R>(self: Effect<A, E, R>, duration: Duration.DurationInput): Effect<A, E, R>;
|
||
};
|
||
/**
|
||
* Suspends the execution of an effect for a specified `Duration`.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function pauses the execution of an effect for a given duration. It is
|
||
* asynchronous, meaning that it does not block the fiber executing the effect.
|
||
* Instead, the fiber is suspended during the delay period and can resume once
|
||
* the specified time has passed.
|
||
*
|
||
* The duration can be specified using various formats supported by the
|
||
* `Duration` module, such as a string (`"2 seconds"`) or numeric value
|
||
* representing milliseconds.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const program = Effect.gen(function*() {
|
||
* console.log("Starting task...")
|
||
* yield* Effect.sleep("3 seconds") // Waits for 3 seconds
|
||
* console.log("Task completed!")
|
||
* })
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output:
|
||
* // Starting task...
|
||
* // Task completed!
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Delays & Timeouts
|
||
*/
|
||
export declare const sleep: (duration: Duration.DurationInput) => Effect<void>;
|
||
/**
|
||
* Executes an effect and measures the time it takes to complete.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function wraps the provided effect and returns a new effect that, when
|
||
* executed, performs the original effect and calculates its execution duration.
|
||
*
|
||
* The result of the new effect includes both the execution time (as a
|
||
* `Duration`) and the original effect's result. This is useful for monitoring
|
||
* performance or gaining insights into the time taken by specific operations.
|
||
*
|
||
* The original effect's behavior (success, failure, or interruption) remains
|
||
* unchanged, and the timing information is provided alongside the result in a
|
||
* tuple.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Duration, Effect } from "effect"
|
||
*
|
||
* const task = Effect.gen(function*() {
|
||
* yield* Effect.sleep("2 seconds") // Simulates some work
|
||
* return "some result"
|
||
* })
|
||
*
|
||
* const timedTask = task.pipe(Effect.timed)
|
||
*
|
||
* const program = Effect.gen(function*() {
|
||
* const [duration, result] = yield* timedTask
|
||
* console.log(`Task completed in ${Duration.toMillis(duration)} ms with result: ${result}`)
|
||
* })
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output: Task completed in 2003.749125 ms with result: some result
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Delays & Timeouts
|
||
*/
|
||
export declare const timed: <A, E, R>(self: Effect<A, E, R>) => Effect<[duration: Duration.Duration, result: A], E, R>;
|
||
/**
|
||
* Executes an effect and measures its execution time using a custom clock.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function extends the functionality of {@link timed} by allowing you to
|
||
* specify a custom clock for measuring the execution duration. The provided
|
||
* effect (`nanoseconds`) represents the clock and should return the current
|
||
* time in nanoseconds. The timing information is computed using this custom
|
||
* clock instead of the default system clock.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Delays & Timeouts
|
||
*/
|
||
export declare const timedWith: {
|
||
/**
|
||
* Executes an effect and measures its execution time using a custom clock.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function extends the functionality of {@link timed} by allowing you to
|
||
* specify a custom clock for measuring the execution duration. The provided
|
||
* effect (`nanoseconds`) represents the clock and should return the current
|
||
* time in nanoseconds. The timing information is computed using this custom
|
||
* clock instead of the default system clock.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Delays & Timeouts
|
||
*/
|
||
<E1, R1>(nanoseconds: Effect<bigint, E1, R1>): <A, E, R>(self: Effect<A, E, R>) => Effect<[Duration.Duration, A], E1 | E, R1 | R>;
|
||
/**
|
||
* Executes an effect and measures its execution time using a custom clock.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function extends the functionality of {@link timed} by allowing you to
|
||
* specify a custom clock for measuring the execution duration. The provided
|
||
* effect (`nanoseconds`) represents the clock and should return the current
|
||
* time in nanoseconds. The timing information is computed using this custom
|
||
* clock instead of the default system clock.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Delays & Timeouts
|
||
*/
|
||
<A, E, R, E1, R1>(self: Effect<A, E, R>, nanoseconds: Effect<bigint, E1, R1>): Effect<[Duration.Duration, A], E | E1, R | R1>;
|
||
};
|
||
/**
|
||
* Adds a time limit to an effect, triggering a timeout if the effect exceeds
|
||
* the duration.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to enforce a time limit on the execution of an
|
||
* effect. If the effect does not complete within the given duration, it fails
|
||
* with a `TimeoutException`. This is useful for preventing tasks from hanging
|
||
* indefinitely, especially in scenarios where responsiveness or resource limits
|
||
* are critical.
|
||
*
|
||
* The returned effect will either:
|
||
* - Succeed with the original effect's result if it completes within the
|
||
* specified duration.
|
||
* - Fail with a `TimeoutException` if the time limit is exceeded.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const task = Effect.gen(function* () {
|
||
* console.log("Start processing...")
|
||
* yield* Effect.sleep("2 seconds") // Simulates a delay in processing
|
||
* console.log("Processing complete.")
|
||
* return "Result"
|
||
* })
|
||
*
|
||
* // Output will show a TimeoutException as the task takes longer
|
||
* // than the specified timeout duration
|
||
* const timedEffect = task.pipe(Effect.timeout("1 second"))
|
||
*
|
||
* Effect.runPromiseExit(timedEffect).then(console.log)
|
||
* // Output:
|
||
* // Start processing...
|
||
* // {
|
||
* // _id: 'Exit',
|
||
* // _tag: 'Failure',
|
||
* // cause: {
|
||
* // _id: 'Cause',
|
||
* // _tag: 'Fail',
|
||
* // failure: { _tag: 'TimeoutException' }
|
||
* // }
|
||
* // }
|
||
* ```
|
||
*
|
||
* @see {@link timeoutFail} for a version that raises a custom error.
|
||
* @see {@link timeoutFailCause} for a version that raises a custom defect.
|
||
* @see {@link timeoutTo} for a version that allows specifying both success and
|
||
* timeout handlers.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Delays & Timeouts
|
||
*/
|
||
export declare const timeout: {
|
||
/**
|
||
* Adds a time limit to an effect, triggering a timeout if the effect exceeds
|
||
* the duration.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to enforce a time limit on the execution of an
|
||
* effect. If the effect does not complete within the given duration, it fails
|
||
* with a `TimeoutException`. This is useful for preventing tasks from hanging
|
||
* indefinitely, especially in scenarios where responsiveness or resource limits
|
||
* are critical.
|
||
*
|
||
* The returned effect will either:
|
||
* - Succeed with the original effect's result if it completes within the
|
||
* specified duration.
|
||
* - Fail with a `TimeoutException` if the time limit is exceeded.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const task = Effect.gen(function* () {
|
||
* console.log("Start processing...")
|
||
* yield* Effect.sleep("2 seconds") // Simulates a delay in processing
|
||
* console.log("Processing complete.")
|
||
* return "Result"
|
||
* })
|
||
*
|
||
* // Output will show a TimeoutException as the task takes longer
|
||
* // than the specified timeout duration
|
||
* const timedEffect = task.pipe(Effect.timeout("1 second"))
|
||
*
|
||
* Effect.runPromiseExit(timedEffect).then(console.log)
|
||
* // Output:
|
||
* // Start processing...
|
||
* // {
|
||
* // _id: 'Exit',
|
||
* // _tag: 'Failure',
|
||
* // cause: {
|
||
* // _id: 'Cause',
|
||
* // _tag: 'Fail',
|
||
* // failure: { _tag: 'TimeoutException' }
|
||
* // }
|
||
* // }
|
||
* ```
|
||
*
|
||
* @see {@link timeoutFail} for a version that raises a custom error.
|
||
* @see {@link timeoutFailCause} for a version that raises a custom defect.
|
||
* @see {@link timeoutTo} for a version that allows specifying both success and
|
||
* timeout handlers.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Delays & Timeouts
|
||
*/
|
||
(duration: Duration.DurationInput): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E | Cause.TimeoutException, R>;
|
||
/**
|
||
* Adds a time limit to an effect, triggering a timeout if the effect exceeds
|
||
* the duration.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to enforce a time limit on the execution of an
|
||
* effect. If the effect does not complete within the given duration, it fails
|
||
* with a `TimeoutException`. This is useful for preventing tasks from hanging
|
||
* indefinitely, especially in scenarios where responsiveness or resource limits
|
||
* are critical.
|
||
*
|
||
* The returned effect will either:
|
||
* - Succeed with the original effect's result if it completes within the
|
||
* specified duration.
|
||
* - Fail with a `TimeoutException` if the time limit is exceeded.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const task = Effect.gen(function* () {
|
||
* console.log("Start processing...")
|
||
* yield* Effect.sleep("2 seconds") // Simulates a delay in processing
|
||
* console.log("Processing complete.")
|
||
* return "Result"
|
||
* })
|
||
*
|
||
* // Output will show a TimeoutException as the task takes longer
|
||
* // than the specified timeout duration
|
||
* const timedEffect = task.pipe(Effect.timeout("1 second"))
|
||
*
|
||
* Effect.runPromiseExit(timedEffect).then(console.log)
|
||
* // Output:
|
||
* // Start processing...
|
||
* // {
|
||
* // _id: 'Exit',
|
||
* // _tag: 'Failure',
|
||
* // cause: {
|
||
* // _id: 'Cause',
|
||
* // _tag: 'Fail',
|
||
* // failure: { _tag: 'TimeoutException' }
|
||
* // }
|
||
* // }
|
||
* ```
|
||
*
|
||
* @see {@link timeoutFail} for a version that raises a custom error.
|
||
* @see {@link timeoutFailCause} for a version that raises a custom defect.
|
||
* @see {@link timeoutTo} for a version that allows specifying both success and
|
||
* timeout handlers.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Delays & Timeouts
|
||
*/
|
||
<A, E, R>(self: Effect<A, E, R>, duration: Duration.DurationInput): Effect<A, Cause.TimeoutException | E, R>;
|
||
};
|
||
/**
|
||
* Gracefully handles timeouts by returning an `Option` that represents either
|
||
* the result or a timeout.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function wraps the outcome of an effect in an `Option` type. If the
|
||
* effect completes within the specified duration, it returns a `Some`
|
||
* containing the result. If the effect times out, it returns a `None`. Unlike
|
||
* other timeout methods, this approach does not raise errors or exceptions;
|
||
* instead, it allows you to treat timeouts as a regular outcome, simplifying
|
||
* the logic for handling delays.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is useful when you want to handle timeouts without causing the program
|
||
* to fail, making it easier to manage situations where you expect tasks might
|
||
* take too long but want to continue executing other tasks.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const task = Effect.gen(function* () {
|
||
* console.log("Start processing...")
|
||
* yield* Effect.sleep("2 seconds") // Simulates a delay in processing
|
||
* console.log("Processing complete.")
|
||
* return "Result"
|
||
* })
|
||
*
|
||
* const timedOutEffect = Effect.all([
|
||
* task.pipe(Effect.timeoutOption("3 seconds")),
|
||
* task.pipe(Effect.timeoutOption("1 second"))
|
||
* ])
|
||
*
|
||
* Effect.runPromise(timedOutEffect).then(console.log)
|
||
* // Output:
|
||
* // Start processing...
|
||
* // Processing complete.
|
||
* // Start processing...
|
||
* // [
|
||
* // { _id: 'Option', _tag: 'Some', value: 'Result' },
|
||
* // { _id: 'Option', _tag: 'None' }
|
||
* // ]
|
||
* ```
|
||
*
|
||
* @see {@link timeout} for a version that raises a `TimeoutException`.
|
||
* @see {@link timeoutFail} for a version that raises a custom error.
|
||
* @see {@link timeoutFailCause} for a version that raises a custom defect.
|
||
* @see {@link timeoutTo} for a version that allows specifying both success and
|
||
* timeout handlers.
|
||
*
|
||
* @since 3.1.0
|
||
* @category Delays & Timeouts
|
||
*/
|
||
export declare const timeoutOption: {
|
||
/**
|
||
* Gracefully handles timeouts by returning an `Option` that represents either
|
||
* the result or a timeout.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function wraps the outcome of an effect in an `Option` type. If the
|
||
* effect completes within the specified duration, it returns a `Some`
|
||
* containing the result. If the effect times out, it returns a `None`. Unlike
|
||
* other timeout methods, this approach does not raise errors or exceptions;
|
||
* instead, it allows you to treat timeouts as a regular outcome, simplifying
|
||
* the logic for handling delays.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is useful when you want to handle timeouts without causing the program
|
||
* to fail, making it easier to manage situations where you expect tasks might
|
||
* take too long but want to continue executing other tasks.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const task = Effect.gen(function* () {
|
||
* console.log("Start processing...")
|
||
* yield* Effect.sleep("2 seconds") // Simulates a delay in processing
|
||
* console.log("Processing complete.")
|
||
* return "Result"
|
||
* })
|
||
*
|
||
* const timedOutEffect = Effect.all([
|
||
* task.pipe(Effect.timeoutOption("3 seconds")),
|
||
* task.pipe(Effect.timeoutOption("1 second"))
|
||
* ])
|
||
*
|
||
* Effect.runPromise(timedOutEffect).then(console.log)
|
||
* // Output:
|
||
* // Start processing...
|
||
* // Processing complete.
|
||
* // Start processing...
|
||
* // [
|
||
* // { _id: 'Option', _tag: 'Some', value: 'Result' },
|
||
* // { _id: 'Option', _tag: 'None' }
|
||
* // ]
|
||
* ```
|
||
*
|
||
* @see {@link timeout} for a version that raises a `TimeoutException`.
|
||
* @see {@link timeoutFail} for a version that raises a custom error.
|
||
* @see {@link timeoutFailCause} for a version that raises a custom defect.
|
||
* @see {@link timeoutTo} for a version that allows specifying both success and
|
||
* timeout handlers.
|
||
*
|
||
* @since 3.1.0
|
||
* @category Delays & Timeouts
|
||
*/
|
||
(duration: Duration.DurationInput): <A, E, R>(self: Effect<A, E, R>) => Effect<Option.Option<A>, E, R>;
|
||
/**
|
||
* Gracefully handles timeouts by returning an `Option` that represents either
|
||
* the result or a timeout.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function wraps the outcome of an effect in an `Option` type. If the
|
||
* effect completes within the specified duration, it returns a `Some`
|
||
* containing the result. If the effect times out, it returns a `None`. Unlike
|
||
* other timeout methods, this approach does not raise errors or exceptions;
|
||
* instead, it allows you to treat timeouts as a regular outcome, simplifying
|
||
* the logic for handling delays.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is useful when you want to handle timeouts without causing the program
|
||
* to fail, making it easier to manage situations where you expect tasks might
|
||
* take too long but want to continue executing other tasks.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const task = Effect.gen(function* () {
|
||
* console.log("Start processing...")
|
||
* yield* Effect.sleep("2 seconds") // Simulates a delay in processing
|
||
* console.log("Processing complete.")
|
||
* return "Result"
|
||
* })
|
||
*
|
||
* const timedOutEffect = Effect.all([
|
||
* task.pipe(Effect.timeoutOption("3 seconds")),
|
||
* task.pipe(Effect.timeoutOption("1 second"))
|
||
* ])
|
||
*
|
||
* Effect.runPromise(timedOutEffect).then(console.log)
|
||
* // Output:
|
||
* // Start processing...
|
||
* // Processing complete.
|
||
* // Start processing...
|
||
* // [
|
||
* // { _id: 'Option', _tag: 'Some', value: 'Result' },
|
||
* // { _id: 'Option', _tag: 'None' }
|
||
* // ]
|
||
* ```
|
||
*
|
||
* @see {@link timeout} for a version that raises a `TimeoutException`.
|
||
* @see {@link timeoutFail} for a version that raises a custom error.
|
||
* @see {@link timeoutFailCause} for a version that raises a custom defect.
|
||
* @see {@link timeoutTo} for a version that allows specifying both success and
|
||
* timeout handlers.
|
||
*
|
||
* @since 3.1.0
|
||
* @category Delays & Timeouts
|
||
*/
|
||
<A, E, R>(self: Effect<A, E, R>, duration: Duration.DurationInput): Effect<Option.Option<A>, E, R>;
|
||
};
|
||
/**
|
||
* Specifies a custom error to be produced when a timeout occurs.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to handle timeouts in a customized way by defining a
|
||
* specific error to be raised when an effect exceeds the given duration. Unlike
|
||
* default timeout behaviors that use generic exceptions, this function gives
|
||
* you the flexibility to specify a meaningful error type that aligns with your
|
||
* application's needs.
|
||
*
|
||
* When you apply this function, you provide:
|
||
* - A `duration`: The time limit for the effect.
|
||
* - An `onTimeout` function: A lazy evaluation function that generates the
|
||
* custom error if the timeout occurs.
|
||
*
|
||
* If the effect completes within the time limit, its result is returned
|
||
* normally. Otherwise, the `onTimeout` function is triggered, and its output is
|
||
* used as the error for the effect.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const task = Effect.gen(function* () {
|
||
* console.log("Start processing...")
|
||
* yield* Effect.sleep("2 seconds") // Simulates a delay in processing
|
||
* console.log("Processing complete.")
|
||
* return "Result"
|
||
* })
|
||
*
|
||
* class MyTimeoutError {
|
||
* readonly _tag = "MyTimeoutError"
|
||
* }
|
||
*
|
||
* const program = task.pipe(
|
||
* Effect.timeoutFail({
|
||
* duration: "1 second",
|
||
* onTimeout: () => new MyTimeoutError() // Custom timeout error
|
||
* })
|
||
* )
|
||
*
|
||
* Effect.runPromiseExit(program).then(console.log)
|
||
* // Output:
|
||
* // Start processing...
|
||
* // {
|
||
* // _id: 'Exit',
|
||
* // _tag: 'Failure',
|
||
* // cause: {
|
||
* // _id: 'Cause',
|
||
* // _tag: 'Fail',
|
||
* // failure: MyTimeoutError { _tag: 'MyTimeoutError' }
|
||
* // }
|
||
* // }
|
||
* ```
|
||
*
|
||
* @see {@link timeout} for a version that raises a `TimeoutException`.
|
||
* @see {@link timeoutFailCause} for a version that raises a custom defect.
|
||
* @see {@link timeoutTo} for a version that allows specifying both success and
|
||
* timeout handlers.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Delays & Timeouts
|
||
*/
|
||
export declare const timeoutFail: {
|
||
/**
|
||
* Specifies a custom error to be produced when a timeout occurs.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to handle timeouts in a customized way by defining a
|
||
* specific error to be raised when an effect exceeds the given duration. Unlike
|
||
* default timeout behaviors that use generic exceptions, this function gives
|
||
* you the flexibility to specify a meaningful error type that aligns with your
|
||
* application's needs.
|
||
*
|
||
* When you apply this function, you provide:
|
||
* - A `duration`: The time limit for the effect.
|
||
* - An `onTimeout` function: A lazy evaluation function that generates the
|
||
* custom error if the timeout occurs.
|
||
*
|
||
* If the effect completes within the time limit, its result is returned
|
||
* normally. Otherwise, the `onTimeout` function is triggered, and its output is
|
||
* used as the error for the effect.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const task = Effect.gen(function* () {
|
||
* console.log("Start processing...")
|
||
* yield* Effect.sleep("2 seconds") // Simulates a delay in processing
|
||
* console.log("Processing complete.")
|
||
* return "Result"
|
||
* })
|
||
*
|
||
* class MyTimeoutError {
|
||
* readonly _tag = "MyTimeoutError"
|
||
* }
|
||
*
|
||
* const program = task.pipe(
|
||
* Effect.timeoutFail({
|
||
* duration: "1 second",
|
||
* onTimeout: () => new MyTimeoutError() // Custom timeout error
|
||
* })
|
||
* )
|
||
*
|
||
* Effect.runPromiseExit(program).then(console.log)
|
||
* // Output:
|
||
* // Start processing...
|
||
* // {
|
||
* // _id: 'Exit',
|
||
* // _tag: 'Failure',
|
||
* // cause: {
|
||
* // _id: 'Cause',
|
||
* // _tag: 'Fail',
|
||
* // failure: MyTimeoutError { _tag: 'MyTimeoutError' }
|
||
* // }
|
||
* // }
|
||
* ```
|
||
*
|
||
* @see {@link timeout} for a version that raises a `TimeoutException`.
|
||
* @see {@link timeoutFailCause} for a version that raises a custom defect.
|
||
* @see {@link timeoutTo} for a version that allows specifying both success and
|
||
* timeout handlers.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Delays & Timeouts
|
||
*/
|
||
<E1>(options: {
|
||
readonly onTimeout: LazyArg<E1>;
|
||
readonly duration: Duration.DurationInput;
|
||
}): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E1 | E, R>;
|
||
/**
|
||
* Specifies a custom error to be produced when a timeout occurs.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to handle timeouts in a customized way by defining a
|
||
* specific error to be raised when an effect exceeds the given duration. Unlike
|
||
* default timeout behaviors that use generic exceptions, this function gives
|
||
* you the flexibility to specify a meaningful error type that aligns with your
|
||
* application's needs.
|
||
*
|
||
* When you apply this function, you provide:
|
||
* - A `duration`: The time limit for the effect.
|
||
* - An `onTimeout` function: A lazy evaluation function that generates the
|
||
* custom error if the timeout occurs.
|
||
*
|
||
* If the effect completes within the time limit, its result is returned
|
||
* normally. Otherwise, the `onTimeout` function is triggered, and its output is
|
||
* used as the error for the effect.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const task = Effect.gen(function* () {
|
||
* console.log("Start processing...")
|
||
* yield* Effect.sleep("2 seconds") // Simulates a delay in processing
|
||
* console.log("Processing complete.")
|
||
* return "Result"
|
||
* })
|
||
*
|
||
* class MyTimeoutError {
|
||
* readonly _tag = "MyTimeoutError"
|
||
* }
|
||
*
|
||
* const program = task.pipe(
|
||
* Effect.timeoutFail({
|
||
* duration: "1 second",
|
||
* onTimeout: () => new MyTimeoutError() // Custom timeout error
|
||
* })
|
||
* )
|
||
*
|
||
* Effect.runPromiseExit(program).then(console.log)
|
||
* // Output:
|
||
* // Start processing...
|
||
* // {
|
||
* // _id: 'Exit',
|
||
* // _tag: 'Failure',
|
||
* // cause: {
|
||
* // _id: 'Cause',
|
||
* // _tag: 'Fail',
|
||
* // failure: MyTimeoutError { _tag: 'MyTimeoutError' }
|
||
* // }
|
||
* // }
|
||
* ```
|
||
*
|
||
* @see {@link timeout} for a version that raises a `TimeoutException`.
|
||
* @see {@link timeoutFailCause} for a version that raises a custom defect.
|
||
* @see {@link timeoutTo} for a version that allows specifying both success and
|
||
* timeout handlers.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Delays & Timeouts
|
||
*/
|
||
<A, E, R, E1>(self: Effect<A, E, R>, options: {
|
||
readonly onTimeout: LazyArg<E1>;
|
||
readonly duration: Duration.DurationInput;
|
||
}): Effect<A, E | E1, R>;
|
||
};
|
||
/**
|
||
* Specifies a custom defect to be thrown when a timeout occurs.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to handle timeouts as exceptional cases by
|
||
* generating a custom defect when an effect exceeds the specified duration. You
|
||
* provide:
|
||
* - A `duration`: The time limit for the effect.
|
||
* - An `onTimeout` function: A lazy evaluation function that generates the
|
||
* custom defect (typically created using `Cause.die`).
|
||
*
|
||
* If the effect completes within the time limit, its result is returned
|
||
* normally. Otherwise, the custom defect is triggered, and the effect fails
|
||
* with that defect.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is especially useful when you need to treat timeouts as critical
|
||
* failures in your application and wish to include meaningful information in
|
||
* the defect.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Cause } from "effect"
|
||
*
|
||
* const task = Effect.gen(function* () {
|
||
* console.log("Start processing...")
|
||
* yield* Effect.sleep("2 seconds") // Simulates a delay in processing
|
||
* console.log("Processing complete.")
|
||
* return "Result"
|
||
* })
|
||
*
|
||
* const program = task.pipe(
|
||
* Effect.timeoutFailCause({
|
||
* duration: "1 second",
|
||
* onTimeout: () => Cause.die("Timed out!") // Custom defect for timeout
|
||
* })
|
||
* )
|
||
*
|
||
* Effect.runPromiseExit(program).then(console.log)
|
||
* // Output:
|
||
* // Start processing...
|
||
* // {
|
||
* // _id: 'Exit',
|
||
* // _tag: 'Failure',
|
||
* // cause: { _id: 'Cause', _tag: 'Die', defect: 'Timed out!' }
|
||
* // }
|
||
* ```
|
||
*
|
||
* @see {@link timeout} for a version that raises a `TimeoutException`.
|
||
* @see {@link timeoutFail} for a version that raises a custom error.
|
||
* @see {@link timeoutTo} for a version that allows specifying both success and
|
||
* timeout handlers.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Delays & Timeouts
|
||
*/
|
||
export declare const timeoutFailCause: {
|
||
/**
|
||
* Specifies a custom defect to be thrown when a timeout occurs.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to handle timeouts as exceptional cases by
|
||
* generating a custom defect when an effect exceeds the specified duration. You
|
||
* provide:
|
||
* - A `duration`: The time limit for the effect.
|
||
* - An `onTimeout` function: A lazy evaluation function that generates the
|
||
* custom defect (typically created using `Cause.die`).
|
||
*
|
||
* If the effect completes within the time limit, its result is returned
|
||
* normally. Otherwise, the custom defect is triggered, and the effect fails
|
||
* with that defect.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is especially useful when you need to treat timeouts as critical
|
||
* failures in your application and wish to include meaningful information in
|
||
* the defect.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Cause } from "effect"
|
||
*
|
||
* const task = Effect.gen(function* () {
|
||
* console.log("Start processing...")
|
||
* yield* Effect.sleep("2 seconds") // Simulates a delay in processing
|
||
* console.log("Processing complete.")
|
||
* return "Result"
|
||
* })
|
||
*
|
||
* const program = task.pipe(
|
||
* Effect.timeoutFailCause({
|
||
* duration: "1 second",
|
||
* onTimeout: () => Cause.die("Timed out!") // Custom defect for timeout
|
||
* })
|
||
* )
|
||
*
|
||
* Effect.runPromiseExit(program).then(console.log)
|
||
* // Output:
|
||
* // Start processing...
|
||
* // {
|
||
* // _id: 'Exit',
|
||
* // _tag: 'Failure',
|
||
* // cause: { _id: 'Cause', _tag: 'Die', defect: 'Timed out!' }
|
||
* // }
|
||
* ```
|
||
*
|
||
* @see {@link timeout} for a version that raises a `TimeoutException`.
|
||
* @see {@link timeoutFail} for a version that raises a custom error.
|
||
* @see {@link timeoutTo} for a version that allows specifying both success and
|
||
* timeout handlers.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Delays & Timeouts
|
||
*/
|
||
<E1>(options: {
|
||
readonly onTimeout: LazyArg<Cause.Cause<E1>>;
|
||
readonly duration: Duration.DurationInput;
|
||
}): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E1 | E, R>;
|
||
/**
|
||
* Specifies a custom defect to be thrown when a timeout occurs.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to handle timeouts as exceptional cases by
|
||
* generating a custom defect when an effect exceeds the specified duration. You
|
||
* provide:
|
||
* - A `duration`: The time limit for the effect.
|
||
* - An `onTimeout` function: A lazy evaluation function that generates the
|
||
* custom defect (typically created using `Cause.die`).
|
||
*
|
||
* If the effect completes within the time limit, its result is returned
|
||
* normally. Otherwise, the custom defect is triggered, and the effect fails
|
||
* with that defect.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is especially useful when you need to treat timeouts as critical
|
||
* failures in your application and wish to include meaningful information in
|
||
* the defect.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Cause } from "effect"
|
||
*
|
||
* const task = Effect.gen(function* () {
|
||
* console.log("Start processing...")
|
||
* yield* Effect.sleep("2 seconds") // Simulates a delay in processing
|
||
* console.log("Processing complete.")
|
||
* return "Result"
|
||
* })
|
||
*
|
||
* const program = task.pipe(
|
||
* Effect.timeoutFailCause({
|
||
* duration: "1 second",
|
||
* onTimeout: () => Cause.die("Timed out!") // Custom defect for timeout
|
||
* })
|
||
* )
|
||
*
|
||
* Effect.runPromiseExit(program).then(console.log)
|
||
* // Output:
|
||
* // Start processing...
|
||
* // {
|
||
* // _id: 'Exit',
|
||
* // _tag: 'Failure',
|
||
* // cause: { _id: 'Cause', _tag: 'Die', defect: 'Timed out!' }
|
||
* // }
|
||
* ```
|
||
*
|
||
* @see {@link timeout} for a version that raises a `TimeoutException`.
|
||
* @see {@link timeoutFail} for a version that raises a custom error.
|
||
* @see {@link timeoutTo} for a version that allows specifying both success and
|
||
* timeout handlers.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Delays & Timeouts
|
||
*/
|
||
<A, E, R, E1>(self: Effect<A, E, R>, options: {
|
||
readonly onTimeout: LazyArg<Cause.Cause<E1>>;
|
||
readonly duration: Duration.DurationInput;
|
||
}): Effect<A, E | E1, R>;
|
||
};
|
||
/**
|
||
* Provides custom behavior for successful and timed-out operations.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to define distinct outcomes for an effect depending
|
||
* on whether it completes within a specified time frame or exceeds the timeout
|
||
* duration. You can provide:
|
||
* - `onSuccess`: A handler for processing the result of the effect if it
|
||
* completes successfully within the time limit.
|
||
* - `onTimeout`: A handler for generating a result when the effect times out.
|
||
* - `duration`: The maximum allowed time for the effect to complete.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Unlike {@link timeout}, which raises an exception for timeouts, this function
|
||
* gives you full control over the behavior for both success and timeout
|
||
* scenarios. It is particularly useful when you want to encapsulate timeouts
|
||
* and successes into a specific data structure, like an `Either` type, to
|
||
* represent these outcomes in a meaningful way.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Either } from "effect"
|
||
*
|
||
* const task = Effect.gen(function* () {
|
||
* console.log("Start processing...")
|
||
* yield* Effect.sleep("2 seconds") // Simulates a delay in processing
|
||
* console.log("Processing complete.")
|
||
* return "Result"
|
||
* })
|
||
*
|
||
* const program = task.pipe(
|
||
* Effect.timeoutTo({
|
||
* duration: "1 second",
|
||
* onSuccess: (result): Either.Either<string, string> =>
|
||
* Either.right(result),
|
||
* onTimeout: (): Either.Either<string, string> =>
|
||
* Either.left("Timed out!")
|
||
* })
|
||
* )
|
||
*
|
||
* Effect.runPromise(program).then(console.log)
|
||
* // Output:
|
||
* // Start processing...
|
||
* // {
|
||
* // _id: "Either",
|
||
* // _tag: "Left",
|
||
* // left: "Timed out!"
|
||
* // }
|
||
* ```
|
||
*
|
||
* @see {@link timeout} for a version that raises a `TimeoutException`.
|
||
* @see {@link timeoutFail} for a version that raises a custom error.
|
||
* @see {@link timeoutFailCause} for a version that raises a custom defect.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Delays & Timeouts
|
||
*/
|
||
export declare const timeoutTo: {
|
||
/**
|
||
* Provides custom behavior for successful and timed-out operations.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to define distinct outcomes for an effect depending
|
||
* on whether it completes within a specified time frame or exceeds the timeout
|
||
* duration. You can provide:
|
||
* - `onSuccess`: A handler for processing the result of the effect if it
|
||
* completes successfully within the time limit.
|
||
* - `onTimeout`: A handler for generating a result when the effect times out.
|
||
* - `duration`: The maximum allowed time for the effect to complete.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Unlike {@link timeout}, which raises an exception for timeouts, this function
|
||
* gives you full control over the behavior for both success and timeout
|
||
* scenarios. It is particularly useful when you want to encapsulate timeouts
|
||
* and successes into a specific data structure, like an `Either` type, to
|
||
* represent these outcomes in a meaningful way.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Either } from "effect"
|
||
*
|
||
* const task = Effect.gen(function* () {
|
||
* console.log("Start processing...")
|
||
* yield* Effect.sleep("2 seconds") // Simulates a delay in processing
|
||
* console.log("Processing complete.")
|
||
* return "Result"
|
||
* })
|
||
*
|
||
* const program = task.pipe(
|
||
* Effect.timeoutTo({
|
||
* duration: "1 second",
|
||
* onSuccess: (result): Either.Either<string, string> =>
|
||
* Either.right(result),
|
||
* onTimeout: (): Either.Either<string, string> =>
|
||
* Either.left("Timed out!")
|
||
* })
|
||
* )
|
||
*
|
||
* Effect.runPromise(program).then(console.log)
|
||
* // Output:
|
||
* // Start processing...
|
||
* // {
|
||
* // _id: "Either",
|
||
* // _tag: "Left",
|
||
* // left: "Timed out!"
|
||
* // }
|
||
* ```
|
||
*
|
||
* @see {@link timeout} for a version that raises a `TimeoutException`.
|
||
* @see {@link timeoutFail} for a version that raises a custom error.
|
||
* @see {@link timeoutFailCause} for a version that raises a custom defect.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Delays & Timeouts
|
||
*/
|
||
<A, B, B1>(options: {
|
||
readonly onTimeout: LazyArg<B1>;
|
||
readonly onSuccess: (a: A) => B;
|
||
readonly duration: Duration.DurationInput;
|
||
}): <E, R>(self: Effect<A, E, R>) => Effect<B | B1, E, R>;
|
||
/**
|
||
* Provides custom behavior for successful and timed-out operations.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to define distinct outcomes for an effect depending
|
||
* on whether it completes within a specified time frame or exceeds the timeout
|
||
* duration. You can provide:
|
||
* - `onSuccess`: A handler for processing the result of the effect if it
|
||
* completes successfully within the time limit.
|
||
* - `onTimeout`: A handler for generating a result when the effect times out.
|
||
* - `duration`: The maximum allowed time for the effect to complete.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Unlike {@link timeout}, which raises an exception for timeouts, this function
|
||
* gives you full control over the behavior for both success and timeout
|
||
* scenarios. It is particularly useful when you want to encapsulate timeouts
|
||
* and successes into a specific data structure, like an `Either` type, to
|
||
* represent these outcomes in a meaningful way.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Either } from "effect"
|
||
*
|
||
* const task = Effect.gen(function* () {
|
||
* console.log("Start processing...")
|
||
* yield* Effect.sleep("2 seconds") // Simulates a delay in processing
|
||
* console.log("Processing complete.")
|
||
* return "Result"
|
||
* })
|
||
*
|
||
* const program = task.pipe(
|
||
* Effect.timeoutTo({
|
||
* duration: "1 second",
|
||
* onSuccess: (result): Either.Either<string, string> =>
|
||
* Either.right(result),
|
||
* onTimeout: (): Either.Either<string, string> =>
|
||
* Either.left("Timed out!")
|
||
* })
|
||
* )
|
||
*
|
||
* Effect.runPromise(program).then(console.log)
|
||
* // Output:
|
||
* // Start processing...
|
||
* // {
|
||
* // _id: "Either",
|
||
* // _tag: "Left",
|
||
* // left: "Timed out!"
|
||
* // }
|
||
* ```
|
||
*
|
||
* @see {@link timeout} for a version that raises a `TimeoutException`.
|
||
* @see {@link timeoutFail} for a version that raises a custom error.
|
||
* @see {@link timeoutFailCause} for a version that raises a custom defect.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Delays & Timeouts
|
||
*/
|
||
<A, E, R, B1, B>(self: Effect<A, E, R>, options: {
|
||
readonly onTimeout: LazyArg<B1>;
|
||
readonly onSuccess: (a: A) => B;
|
||
readonly duration: Duration.DurationInput;
|
||
}): Effect<B1 | B, E, R>;
|
||
};
|
||
/**
|
||
* Allows working with the default configuration provider.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function retrieves the default configuration provider and passes it to
|
||
* the provided function, which can use it to perform computations or retrieve
|
||
* configuration values. The function can return an effect that leverages the
|
||
* configuration provider for its operations.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Config
|
||
*/
|
||
export declare const configProviderWith: <A, E, R>(f: (provider: ConfigProvider) => Effect<A, E, R>) => Effect<A, E, R>;
|
||
/**
|
||
* Executes an effect using a specific configuration provider.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function lets you run an effect with a specified configuration provider.
|
||
* The custom provider will override the default configuration provider for the
|
||
* duration of the effect's execution.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is particularly useful when you need to use a different set of
|
||
* configuration values or sources for specific parts of your application.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Config, ConfigProvider, Effect } from "effect"
|
||
*
|
||
* const customProvider: ConfigProvider.ConfigProvider = ConfigProvider.fromMap(
|
||
* new Map([["custom-key", "custom-value"]])
|
||
* )
|
||
*
|
||
* const program = Effect.withConfigProvider(customProvider)(
|
||
* Effect.gen(function*() {
|
||
* const value = yield* Config.string("custom-key")
|
||
* console.log(`Config value: ${value}`)
|
||
* })
|
||
* )
|
||
*
|
||
* Effect.runPromise(program)
|
||
* // Output:
|
||
* // Config value: custom-value
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Config
|
||
*/
|
||
export declare const withConfigProvider: {
|
||
/**
|
||
* Executes an effect using a specific configuration provider.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function lets you run an effect with a specified configuration provider.
|
||
* The custom provider will override the default configuration provider for the
|
||
* duration of the effect's execution.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is particularly useful when you need to use a different set of
|
||
* configuration values or sources for specific parts of your application.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Config, ConfigProvider, Effect } from "effect"
|
||
*
|
||
* const customProvider: ConfigProvider.ConfigProvider = ConfigProvider.fromMap(
|
||
* new Map([["custom-key", "custom-value"]])
|
||
* )
|
||
*
|
||
* const program = Effect.withConfigProvider(customProvider)(
|
||
* Effect.gen(function*() {
|
||
* const value = yield* Config.string("custom-key")
|
||
* console.log(`Config value: ${value}`)
|
||
* })
|
||
* )
|
||
*
|
||
* Effect.runPromise(program)
|
||
* // Output:
|
||
* // Config value: custom-value
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Config
|
||
*/
|
||
(provider: ConfigProvider): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, R>;
|
||
/**
|
||
* Executes an effect using a specific configuration provider.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function lets you run an effect with a specified configuration provider.
|
||
* The custom provider will override the default configuration provider for the
|
||
* duration of the effect's execution.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is particularly useful when you need to use a different set of
|
||
* configuration values or sources for specific parts of your application.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Config, ConfigProvider, Effect } from "effect"
|
||
*
|
||
* const customProvider: ConfigProvider.ConfigProvider = ConfigProvider.fromMap(
|
||
* new Map([["custom-key", "custom-value"]])
|
||
* )
|
||
*
|
||
* const program = Effect.withConfigProvider(customProvider)(
|
||
* Effect.gen(function*() {
|
||
* const value = yield* Config.string("custom-key")
|
||
* console.log(`Config value: ${value}`)
|
||
* })
|
||
* )
|
||
*
|
||
* Effect.runPromise(program)
|
||
* // Output:
|
||
* // Config value: custom-value
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Config
|
||
*/
|
||
<A, E, R>(self: Effect<A, E, R>, provider: ConfigProvider): Effect<A, E, R>;
|
||
};
|
||
/**
|
||
* Sets a configuration provider within a scope.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function sets the configuration provider to a specified value and
|
||
* ensures that it is restored to its original value when the scope is closed.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Config
|
||
*/
|
||
export declare const withConfigProviderScoped: (provider: ConfigProvider) => Effect<void, never, Scope.Scope>;
|
||
/**
|
||
* Accesses the full context of the effect.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function provides the ability to access the entire context required by
|
||
* an effect. The context is a container that holds dependencies or environment
|
||
* values needed by an effect to run. By using this function, you can retrieve
|
||
* and work with the context directly within an effect.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Context
|
||
*/
|
||
export declare const context: <R>() => Effect<Context.Context<R>, never, R>;
|
||
/**
|
||
* Accesses the context and applies a transformation function.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function retrieves the context of the effect and applies a pure
|
||
* transformation function to it. The result of the transformation is then
|
||
* returned within the effect.
|
||
*
|
||
* @see {@link contextWithEffect} for a version that allows effectful transformations.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Context
|
||
*/
|
||
export declare const contextWith: <R, A>(f: (context: Context.Context<R>) => A) => Effect<A, never, R>;
|
||
/**
|
||
* Accesses the context and performs an effectful transformation.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function retrieves the context and allows you to transform it
|
||
* effectually using another effect. It is useful when the transformation
|
||
* involves asynchronous or effectful operations.
|
||
*
|
||
* @see {@link contextWith} for a version that allows pure transformations.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Context
|
||
*/
|
||
export declare const contextWithEffect: <R2, A, E, R>(f: (context: Context.Context<R2>) => Effect<A, E, R>) => Effect<A, E, R | R2>;
|
||
/**
|
||
* Provides part of the required context while leaving the rest unchanged.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to transform the context required by an effect,
|
||
* providing part of the context and leaving the rest to be fulfilled later.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Context, Effect } from "effect"
|
||
*
|
||
* class Service1 extends Context.Tag("Service1")<Service1, { readonly port: number }>() {}
|
||
* class Service2 extends Context.Tag("Service2")<Service2, { readonly connection: string }>() {}
|
||
*
|
||
* const program = Effect.gen(function*() {
|
||
* const service1 = yield* Service1
|
||
* console.log(service1.port)
|
||
* const service2 = yield* Service2
|
||
* console.log(service2.connection)
|
||
* return "some result"
|
||
* })
|
||
*
|
||
* // ┌─── Effect<string, never, Service2>
|
||
* // ▼
|
||
* const programWithService1 = Effect.mapInputContext(
|
||
* program,
|
||
* (ctx: Context.Context<Service2>) => Context.add(ctx, Service1, { port: 3000 })
|
||
* )
|
||
*
|
||
* const runnable = programWithService1.pipe(
|
||
* Effect.provideService(Service2, { connection: "localhost" }),
|
||
* Effect.provideService(Service1, { port: 3001 })
|
||
* )
|
||
*
|
||
* Effect.runPromise(runnable)
|
||
* // Output:
|
||
* // 3000
|
||
* // localhost
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Context
|
||
*/
|
||
export declare const mapInputContext: {
|
||
/**
|
||
* Provides part of the required context while leaving the rest unchanged.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to transform the context required by an effect,
|
||
* providing part of the context and leaving the rest to be fulfilled later.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Context, Effect } from "effect"
|
||
*
|
||
* class Service1 extends Context.Tag("Service1")<Service1, { readonly port: number }>() {}
|
||
* class Service2 extends Context.Tag("Service2")<Service2, { readonly connection: string }>() {}
|
||
*
|
||
* const program = Effect.gen(function*() {
|
||
* const service1 = yield* Service1
|
||
* console.log(service1.port)
|
||
* const service2 = yield* Service2
|
||
* console.log(service2.connection)
|
||
* return "some result"
|
||
* })
|
||
*
|
||
* // ┌─── Effect<string, never, Service2>
|
||
* // ▼
|
||
* const programWithService1 = Effect.mapInputContext(
|
||
* program,
|
||
* (ctx: Context.Context<Service2>) => Context.add(ctx, Service1, { port: 3000 })
|
||
* )
|
||
*
|
||
* const runnable = programWithService1.pipe(
|
||
* Effect.provideService(Service2, { connection: "localhost" }),
|
||
* Effect.provideService(Service1, { port: 3001 })
|
||
* )
|
||
*
|
||
* Effect.runPromise(runnable)
|
||
* // Output:
|
||
* // 3000
|
||
* // localhost
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Context
|
||
*/
|
||
<R2, R>(f: (context: Context.Context<R2>) => Context.Context<R>): <A, E>(self: Effect<A, E, R>) => Effect<A, E, R2>;
|
||
/**
|
||
* Provides part of the required context while leaving the rest unchanged.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to transform the context required by an effect,
|
||
* providing part of the context and leaving the rest to be fulfilled later.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Context, Effect } from "effect"
|
||
*
|
||
* class Service1 extends Context.Tag("Service1")<Service1, { readonly port: number }>() {}
|
||
* class Service2 extends Context.Tag("Service2")<Service2, { readonly connection: string }>() {}
|
||
*
|
||
* const program = Effect.gen(function*() {
|
||
* const service1 = yield* Service1
|
||
* console.log(service1.port)
|
||
* const service2 = yield* Service2
|
||
* console.log(service2.connection)
|
||
* return "some result"
|
||
* })
|
||
*
|
||
* // ┌─── Effect<string, never, Service2>
|
||
* // ▼
|
||
* const programWithService1 = Effect.mapInputContext(
|
||
* program,
|
||
* (ctx: Context.Context<Service2>) => Context.add(ctx, Service1, { port: 3000 })
|
||
* )
|
||
*
|
||
* const runnable = programWithService1.pipe(
|
||
* Effect.provideService(Service2, { connection: "localhost" }),
|
||
* Effect.provideService(Service1, { port: 3001 })
|
||
* )
|
||
*
|
||
* Effect.runPromise(runnable)
|
||
* // Output:
|
||
* // 3000
|
||
* // localhost
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Context
|
||
*/
|
||
<A, E, R, R2>(self: Effect<A, E, R>, f: (context: Context.Context<R2>) => Context.Context<R>): Effect<A, E, R2>;
|
||
};
|
||
/**
|
||
* Provides necessary dependencies to an effect, removing its environmental
|
||
* requirements.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to supply the required environment for an effect.
|
||
* The environment can be provided in the form of one or more `Layer`s, a
|
||
* `Context`, a `Runtime`, or a `ManagedRuntime`. Once the environment is
|
||
* provided, the effect can run without requiring external dependencies.
|
||
*
|
||
* You can compose layers to create a modular and reusable way of setting up the
|
||
* environment for effects. For example, layers can be used to configure
|
||
* databases, logging services, or any other required dependencies.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Context, Effect, Layer } from "effect"
|
||
*
|
||
* class Database extends Context.Tag("Database")<
|
||
* Database,
|
||
* { readonly query: (sql: string) => Effect.Effect<Array<unknown>> }
|
||
* >() {}
|
||
*
|
||
* const DatabaseLive = Layer.succeed(
|
||
* Database,
|
||
* {
|
||
* // Simulate a database query
|
||
* query: (sql: string) => Effect.log(`Executing query: ${sql}`).pipe(Effect.as([]))
|
||
* }
|
||
* )
|
||
*
|
||
* // ┌─── Effect<unknown[], never, Database>
|
||
* // ▼
|
||
* const program = Effect.gen(function*() {
|
||
* const database = yield* Database
|
||
* const result = yield* database.query("SELECT * FROM users")
|
||
* return result
|
||
* })
|
||
*
|
||
* // ┌─── Effect<unknown[], never, never>
|
||
* // ▼
|
||
* const runnable = Effect.provide(program, DatabaseLive)
|
||
*
|
||
* Effect.runPromise(runnable).then(console.log)
|
||
* // Output:
|
||
* // timestamp=... level=INFO fiber=#0 message="Executing query: SELECT * FROM users"
|
||
* // []
|
||
* ```
|
||
*
|
||
* @see {@link provideService} for providing a service to an effect.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Context
|
||
*/
|
||
export declare const provide: {
|
||
/**
|
||
* Provides necessary dependencies to an effect, removing its environmental
|
||
* requirements.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to supply the required environment for an effect.
|
||
* The environment can be provided in the form of one or more `Layer`s, a
|
||
* `Context`, a `Runtime`, or a `ManagedRuntime`. Once the environment is
|
||
* provided, the effect can run without requiring external dependencies.
|
||
*
|
||
* You can compose layers to create a modular and reusable way of setting up the
|
||
* environment for effects. For example, layers can be used to configure
|
||
* databases, logging services, or any other required dependencies.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Context, Effect, Layer } from "effect"
|
||
*
|
||
* class Database extends Context.Tag("Database")<
|
||
* Database,
|
||
* { readonly query: (sql: string) => Effect.Effect<Array<unknown>> }
|
||
* >() {}
|
||
*
|
||
* const DatabaseLive = Layer.succeed(
|
||
* Database,
|
||
* {
|
||
* // Simulate a database query
|
||
* query: (sql: string) => Effect.log(`Executing query: ${sql}`).pipe(Effect.as([]))
|
||
* }
|
||
* )
|
||
*
|
||
* // ┌─── Effect<unknown[], never, Database>
|
||
* // ▼
|
||
* const program = Effect.gen(function*() {
|
||
* const database = yield* Database
|
||
* const result = yield* database.query("SELECT * FROM users")
|
||
* return result
|
||
* })
|
||
*
|
||
* // ┌─── Effect<unknown[], never, never>
|
||
* // ▼
|
||
* const runnable = Effect.provide(program, DatabaseLive)
|
||
*
|
||
* Effect.runPromise(runnable).then(console.log)
|
||
* // Output:
|
||
* // timestamp=... level=INFO fiber=#0 message="Executing query: SELECT * FROM users"
|
||
* // []
|
||
* ```
|
||
*
|
||
* @see {@link provideService} for providing a service to an effect.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Context
|
||
*/
|
||
<const Layers extends readonly [Layer.Layer.Any, ...Array<Layer.Layer.Any>]>(layers: Layers): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E | {
|
||
[k in keyof Layers]: Layer.Layer.Error<Layers[k]>;
|
||
}[number], {
|
||
[k in keyof Layers]: Layer.Layer.Context<Layers[k]>;
|
||
}[number] | Exclude<R, {
|
||
[k in keyof Layers]: Layer.Layer.Success<Layers[k]>;
|
||
}[number]>>;
|
||
/**
|
||
* Provides necessary dependencies to an effect, removing its environmental
|
||
* requirements.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to supply the required environment for an effect.
|
||
* The environment can be provided in the form of one or more `Layer`s, a
|
||
* `Context`, a `Runtime`, or a `ManagedRuntime`. Once the environment is
|
||
* provided, the effect can run without requiring external dependencies.
|
||
*
|
||
* You can compose layers to create a modular and reusable way of setting up the
|
||
* environment for effects. For example, layers can be used to configure
|
||
* databases, logging services, or any other required dependencies.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Context, Effect, Layer } from "effect"
|
||
*
|
||
* class Database extends Context.Tag("Database")<
|
||
* Database,
|
||
* { readonly query: (sql: string) => Effect.Effect<Array<unknown>> }
|
||
* >() {}
|
||
*
|
||
* const DatabaseLive = Layer.succeed(
|
||
* Database,
|
||
* {
|
||
* // Simulate a database query
|
||
* query: (sql: string) => Effect.log(`Executing query: ${sql}`).pipe(Effect.as([]))
|
||
* }
|
||
* )
|
||
*
|
||
* // ┌─── Effect<unknown[], never, Database>
|
||
* // ▼
|
||
* const program = Effect.gen(function*() {
|
||
* const database = yield* Database
|
||
* const result = yield* database.query("SELECT * FROM users")
|
||
* return result
|
||
* })
|
||
*
|
||
* // ┌─── Effect<unknown[], never, never>
|
||
* // ▼
|
||
* const runnable = Effect.provide(program, DatabaseLive)
|
||
*
|
||
* Effect.runPromise(runnable).then(console.log)
|
||
* // Output:
|
||
* // timestamp=... level=INFO fiber=#0 message="Executing query: SELECT * FROM users"
|
||
* // []
|
||
* ```
|
||
*
|
||
* @see {@link provideService} for providing a service to an effect.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Context
|
||
*/
|
||
<ROut, E2, RIn>(layer: Layer.Layer<ROut, E2, RIn>): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E | E2, RIn | Exclude<R, ROut>>;
|
||
/**
|
||
* Provides necessary dependencies to an effect, removing its environmental
|
||
* requirements.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to supply the required environment for an effect.
|
||
* The environment can be provided in the form of one or more `Layer`s, a
|
||
* `Context`, a `Runtime`, or a `ManagedRuntime`. Once the environment is
|
||
* provided, the effect can run without requiring external dependencies.
|
||
*
|
||
* You can compose layers to create a modular and reusable way of setting up the
|
||
* environment for effects. For example, layers can be used to configure
|
||
* databases, logging services, or any other required dependencies.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Context, Effect, Layer } from "effect"
|
||
*
|
||
* class Database extends Context.Tag("Database")<
|
||
* Database,
|
||
* { readonly query: (sql: string) => Effect.Effect<Array<unknown>> }
|
||
* >() {}
|
||
*
|
||
* const DatabaseLive = Layer.succeed(
|
||
* Database,
|
||
* {
|
||
* // Simulate a database query
|
||
* query: (sql: string) => Effect.log(`Executing query: ${sql}`).pipe(Effect.as([]))
|
||
* }
|
||
* )
|
||
*
|
||
* // ┌─── Effect<unknown[], never, Database>
|
||
* // ▼
|
||
* const program = Effect.gen(function*() {
|
||
* const database = yield* Database
|
||
* const result = yield* database.query("SELECT * FROM users")
|
||
* return result
|
||
* })
|
||
*
|
||
* // ┌─── Effect<unknown[], never, never>
|
||
* // ▼
|
||
* const runnable = Effect.provide(program, DatabaseLive)
|
||
*
|
||
* Effect.runPromise(runnable).then(console.log)
|
||
* // Output:
|
||
* // timestamp=... level=INFO fiber=#0 message="Executing query: SELECT * FROM users"
|
||
* // []
|
||
* ```
|
||
*
|
||
* @see {@link provideService} for providing a service to an effect.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Context
|
||
*/
|
||
<R2>(context: Context.Context<R2>): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, Exclude<R, R2>>;
|
||
/**
|
||
* Provides necessary dependencies to an effect, removing its environmental
|
||
* requirements.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to supply the required environment for an effect.
|
||
* The environment can be provided in the form of one or more `Layer`s, a
|
||
* `Context`, a `Runtime`, or a `ManagedRuntime`. Once the environment is
|
||
* provided, the effect can run without requiring external dependencies.
|
||
*
|
||
* You can compose layers to create a modular and reusable way of setting up the
|
||
* environment for effects. For example, layers can be used to configure
|
||
* databases, logging services, or any other required dependencies.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Context, Effect, Layer } from "effect"
|
||
*
|
||
* class Database extends Context.Tag("Database")<
|
||
* Database,
|
||
* { readonly query: (sql: string) => Effect.Effect<Array<unknown>> }
|
||
* >() {}
|
||
*
|
||
* const DatabaseLive = Layer.succeed(
|
||
* Database,
|
||
* {
|
||
* // Simulate a database query
|
||
* query: (sql: string) => Effect.log(`Executing query: ${sql}`).pipe(Effect.as([]))
|
||
* }
|
||
* )
|
||
*
|
||
* // ┌─── Effect<unknown[], never, Database>
|
||
* // ▼
|
||
* const program = Effect.gen(function*() {
|
||
* const database = yield* Database
|
||
* const result = yield* database.query("SELECT * FROM users")
|
||
* return result
|
||
* })
|
||
*
|
||
* // ┌─── Effect<unknown[], never, never>
|
||
* // ▼
|
||
* const runnable = Effect.provide(program, DatabaseLive)
|
||
*
|
||
* Effect.runPromise(runnable).then(console.log)
|
||
* // Output:
|
||
* // timestamp=... level=INFO fiber=#0 message="Executing query: SELECT * FROM users"
|
||
* // []
|
||
* ```
|
||
*
|
||
* @see {@link provideService} for providing a service to an effect.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Context
|
||
*/
|
||
<R2>(runtime: Runtime.Runtime<R2>): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, Exclude<R, R2>>;
|
||
/**
|
||
* Provides necessary dependencies to an effect, removing its environmental
|
||
* requirements.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to supply the required environment for an effect.
|
||
* The environment can be provided in the form of one or more `Layer`s, a
|
||
* `Context`, a `Runtime`, or a `ManagedRuntime`. Once the environment is
|
||
* provided, the effect can run without requiring external dependencies.
|
||
*
|
||
* You can compose layers to create a modular and reusable way of setting up the
|
||
* environment for effects. For example, layers can be used to configure
|
||
* databases, logging services, or any other required dependencies.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Context, Effect, Layer } from "effect"
|
||
*
|
||
* class Database extends Context.Tag("Database")<
|
||
* Database,
|
||
* { readonly query: (sql: string) => Effect.Effect<Array<unknown>> }
|
||
* >() {}
|
||
*
|
||
* const DatabaseLive = Layer.succeed(
|
||
* Database,
|
||
* {
|
||
* // Simulate a database query
|
||
* query: (sql: string) => Effect.log(`Executing query: ${sql}`).pipe(Effect.as([]))
|
||
* }
|
||
* )
|
||
*
|
||
* // ┌─── Effect<unknown[], never, Database>
|
||
* // ▼
|
||
* const program = Effect.gen(function*() {
|
||
* const database = yield* Database
|
||
* const result = yield* database.query("SELECT * FROM users")
|
||
* return result
|
||
* })
|
||
*
|
||
* // ┌─── Effect<unknown[], never, never>
|
||
* // ▼
|
||
* const runnable = Effect.provide(program, DatabaseLive)
|
||
*
|
||
* Effect.runPromise(runnable).then(console.log)
|
||
* // Output:
|
||
* // timestamp=... level=INFO fiber=#0 message="Executing query: SELECT * FROM users"
|
||
* // []
|
||
* ```
|
||
*
|
||
* @see {@link provideService} for providing a service to an effect.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Context
|
||
*/
|
||
<E2, R2>(managedRuntime: ManagedRuntime.ManagedRuntime<R2, E2>): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E | E2, Exclude<R, R2>>;
|
||
/**
|
||
* Provides necessary dependencies to an effect, removing its environmental
|
||
* requirements.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to supply the required environment for an effect.
|
||
* The environment can be provided in the form of one or more `Layer`s, a
|
||
* `Context`, a `Runtime`, or a `ManagedRuntime`. Once the environment is
|
||
* provided, the effect can run without requiring external dependencies.
|
||
*
|
||
* You can compose layers to create a modular and reusable way of setting up the
|
||
* environment for effects. For example, layers can be used to configure
|
||
* databases, logging services, or any other required dependencies.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Context, Effect, Layer } from "effect"
|
||
*
|
||
* class Database extends Context.Tag("Database")<
|
||
* Database,
|
||
* { readonly query: (sql: string) => Effect.Effect<Array<unknown>> }
|
||
* >() {}
|
||
*
|
||
* const DatabaseLive = Layer.succeed(
|
||
* Database,
|
||
* {
|
||
* // Simulate a database query
|
||
* query: (sql: string) => Effect.log(`Executing query: ${sql}`).pipe(Effect.as([]))
|
||
* }
|
||
* )
|
||
*
|
||
* // ┌─── Effect<unknown[], never, Database>
|
||
* // ▼
|
||
* const program = Effect.gen(function*() {
|
||
* const database = yield* Database
|
||
* const result = yield* database.query("SELECT * FROM users")
|
||
* return result
|
||
* })
|
||
*
|
||
* // ┌─── Effect<unknown[], never, never>
|
||
* // ▼
|
||
* const runnable = Effect.provide(program, DatabaseLive)
|
||
*
|
||
* Effect.runPromise(runnable).then(console.log)
|
||
* // Output:
|
||
* // timestamp=... level=INFO fiber=#0 message="Executing query: SELECT * FROM users"
|
||
* // []
|
||
* ```
|
||
*
|
||
* @see {@link provideService} for providing a service to an effect.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Context
|
||
*/
|
||
<A, E, R, const Layers extends readonly [Layer.Layer.Any, ...Array<Layer.Layer.Any>]>(self: Effect<A, E, R>, layers: Layers): Effect<A, E | {
|
||
[k in keyof Layers]: Layer.Layer.Error<Layers[k]>;
|
||
}[number], {
|
||
[k in keyof Layers]: Layer.Layer.Context<Layers[k]>;
|
||
}[number] | Exclude<R, {
|
||
[k in keyof Layers]: Layer.Layer.Success<Layers[k]>;
|
||
}[number]>>;
|
||
/**
|
||
* Provides necessary dependencies to an effect, removing its environmental
|
||
* requirements.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to supply the required environment for an effect.
|
||
* The environment can be provided in the form of one or more `Layer`s, a
|
||
* `Context`, a `Runtime`, or a `ManagedRuntime`. Once the environment is
|
||
* provided, the effect can run without requiring external dependencies.
|
||
*
|
||
* You can compose layers to create a modular and reusable way of setting up the
|
||
* environment for effects. For example, layers can be used to configure
|
||
* databases, logging services, or any other required dependencies.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Context, Effect, Layer } from "effect"
|
||
*
|
||
* class Database extends Context.Tag("Database")<
|
||
* Database,
|
||
* { readonly query: (sql: string) => Effect.Effect<Array<unknown>> }
|
||
* >() {}
|
||
*
|
||
* const DatabaseLive = Layer.succeed(
|
||
* Database,
|
||
* {
|
||
* // Simulate a database query
|
||
* query: (sql: string) => Effect.log(`Executing query: ${sql}`).pipe(Effect.as([]))
|
||
* }
|
||
* )
|
||
*
|
||
* // ┌─── Effect<unknown[], never, Database>
|
||
* // ▼
|
||
* const program = Effect.gen(function*() {
|
||
* const database = yield* Database
|
||
* const result = yield* database.query("SELECT * FROM users")
|
||
* return result
|
||
* })
|
||
*
|
||
* // ┌─── Effect<unknown[], never, never>
|
||
* // ▼
|
||
* const runnable = Effect.provide(program, DatabaseLive)
|
||
*
|
||
* Effect.runPromise(runnable).then(console.log)
|
||
* // Output:
|
||
* // timestamp=... level=INFO fiber=#0 message="Executing query: SELECT * FROM users"
|
||
* // []
|
||
* ```
|
||
*
|
||
* @see {@link provideService} for providing a service to an effect.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Context
|
||
*/
|
||
<A, E, R, ROut, E2, RIn>(self: Effect<A, E, R>, layer: Layer.Layer<ROut, E2, RIn>): Effect<A, E | E2, RIn | Exclude<R, ROut>>;
|
||
/**
|
||
* Provides necessary dependencies to an effect, removing its environmental
|
||
* requirements.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to supply the required environment for an effect.
|
||
* The environment can be provided in the form of one or more `Layer`s, a
|
||
* `Context`, a `Runtime`, or a `ManagedRuntime`. Once the environment is
|
||
* provided, the effect can run without requiring external dependencies.
|
||
*
|
||
* You can compose layers to create a modular and reusable way of setting up the
|
||
* environment for effects. For example, layers can be used to configure
|
||
* databases, logging services, or any other required dependencies.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Context, Effect, Layer } from "effect"
|
||
*
|
||
* class Database extends Context.Tag("Database")<
|
||
* Database,
|
||
* { readonly query: (sql: string) => Effect.Effect<Array<unknown>> }
|
||
* >() {}
|
||
*
|
||
* const DatabaseLive = Layer.succeed(
|
||
* Database,
|
||
* {
|
||
* // Simulate a database query
|
||
* query: (sql: string) => Effect.log(`Executing query: ${sql}`).pipe(Effect.as([]))
|
||
* }
|
||
* )
|
||
*
|
||
* // ┌─── Effect<unknown[], never, Database>
|
||
* // ▼
|
||
* const program = Effect.gen(function*() {
|
||
* const database = yield* Database
|
||
* const result = yield* database.query("SELECT * FROM users")
|
||
* return result
|
||
* })
|
||
*
|
||
* // ┌─── Effect<unknown[], never, never>
|
||
* // ▼
|
||
* const runnable = Effect.provide(program, DatabaseLive)
|
||
*
|
||
* Effect.runPromise(runnable).then(console.log)
|
||
* // Output:
|
||
* // timestamp=... level=INFO fiber=#0 message="Executing query: SELECT * FROM users"
|
||
* // []
|
||
* ```
|
||
*
|
||
* @see {@link provideService} for providing a service to an effect.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Context
|
||
*/
|
||
<A, E, R, R2>(self: Effect<A, E, R>, context: Context.Context<R2>): Effect<A, E, Exclude<R, R2>>;
|
||
/**
|
||
* Provides necessary dependencies to an effect, removing its environmental
|
||
* requirements.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to supply the required environment for an effect.
|
||
* The environment can be provided in the form of one or more `Layer`s, a
|
||
* `Context`, a `Runtime`, or a `ManagedRuntime`. Once the environment is
|
||
* provided, the effect can run without requiring external dependencies.
|
||
*
|
||
* You can compose layers to create a modular and reusable way of setting up the
|
||
* environment for effects. For example, layers can be used to configure
|
||
* databases, logging services, or any other required dependencies.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Context, Effect, Layer } from "effect"
|
||
*
|
||
* class Database extends Context.Tag("Database")<
|
||
* Database,
|
||
* { readonly query: (sql: string) => Effect.Effect<Array<unknown>> }
|
||
* >() {}
|
||
*
|
||
* const DatabaseLive = Layer.succeed(
|
||
* Database,
|
||
* {
|
||
* // Simulate a database query
|
||
* query: (sql: string) => Effect.log(`Executing query: ${sql}`).pipe(Effect.as([]))
|
||
* }
|
||
* )
|
||
*
|
||
* // ┌─── Effect<unknown[], never, Database>
|
||
* // ▼
|
||
* const program = Effect.gen(function*() {
|
||
* const database = yield* Database
|
||
* const result = yield* database.query("SELECT * FROM users")
|
||
* return result
|
||
* })
|
||
*
|
||
* // ┌─── Effect<unknown[], never, never>
|
||
* // ▼
|
||
* const runnable = Effect.provide(program, DatabaseLive)
|
||
*
|
||
* Effect.runPromise(runnable).then(console.log)
|
||
* // Output:
|
||
* // timestamp=... level=INFO fiber=#0 message="Executing query: SELECT * FROM users"
|
||
* // []
|
||
* ```
|
||
*
|
||
* @see {@link provideService} for providing a service to an effect.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Context
|
||
*/
|
||
<A, E, R, R2>(self: Effect<A, E, R>, runtime: Runtime.Runtime<R2>): Effect<A, E, Exclude<R, R2>>;
|
||
/**
|
||
* Provides necessary dependencies to an effect, removing its environmental
|
||
* requirements.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to supply the required environment for an effect.
|
||
* The environment can be provided in the form of one or more `Layer`s, a
|
||
* `Context`, a `Runtime`, or a `ManagedRuntime`. Once the environment is
|
||
* provided, the effect can run without requiring external dependencies.
|
||
*
|
||
* You can compose layers to create a modular and reusable way of setting up the
|
||
* environment for effects. For example, layers can be used to configure
|
||
* databases, logging services, or any other required dependencies.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Context, Effect, Layer } from "effect"
|
||
*
|
||
* class Database extends Context.Tag("Database")<
|
||
* Database,
|
||
* { readonly query: (sql: string) => Effect.Effect<Array<unknown>> }
|
||
* >() {}
|
||
*
|
||
* const DatabaseLive = Layer.succeed(
|
||
* Database,
|
||
* {
|
||
* // Simulate a database query
|
||
* query: (sql: string) => Effect.log(`Executing query: ${sql}`).pipe(Effect.as([]))
|
||
* }
|
||
* )
|
||
*
|
||
* // ┌─── Effect<unknown[], never, Database>
|
||
* // ▼
|
||
* const program = Effect.gen(function*() {
|
||
* const database = yield* Database
|
||
* const result = yield* database.query("SELECT * FROM users")
|
||
* return result
|
||
* })
|
||
*
|
||
* // ┌─── Effect<unknown[], never, never>
|
||
* // ▼
|
||
* const runnable = Effect.provide(program, DatabaseLive)
|
||
*
|
||
* Effect.runPromise(runnable).then(console.log)
|
||
* // Output:
|
||
* // timestamp=... level=INFO fiber=#0 message="Executing query: SELECT * FROM users"
|
||
* // []
|
||
* ```
|
||
*
|
||
* @see {@link provideService} for providing a service to an effect.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Context
|
||
*/
|
||
<A, E, E2, R, R2>(self: Effect<A, E, R>, runtime: ManagedRuntime.ManagedRuntime<R2, E2>): Effect<A, E | E2, Exclude<R, R2>>;
|
||
};
|
||
/**
|
||
* Provides an implementation for a service in the context of an effect.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to supply a specific implementation for a service
|
||
* required by an effect. Services are typically defined using `Context.Tag`,
|
||
* which acts as a unique identifier for the service. By using this function,
|
||
* you link the service to its concrete implementation, enabling the effect to
|
||
* execute successfully without additional requirements.
|
||
*
|
||
* For example, you can use this function to provide a random number generator,
|
||
* a logger, or any other service your effect depends on. Once the service is
|
||
* provided, all parts of the effect that rely on the service will automatically
|
||
* use the implementation you supplied.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Context } from "effect"
|
||
*
|
||
* // Declaring a tag for a service that generates random numbers
|
||
* class Random extends Context.Tag("MyRandomService")<
|
||
* Random,
|
||
* { readonly next: Effect.Effect<number> }
|
||
* >() {}
|
||
*
|
||
* // Using the service
|
||
* const program = Effect.gen(function* () {
|
||
* const random = yield* Random
|
||
* const randomNumber = yield* random.next
|
||
* console.log(`random number: ${randomNumber}`)
|
||
* })
|
||
*
|
||
* // Providing the implementation
|
||
* //
|
||
* // ┌─── Effect<void, never, never>
|
||
* // ▼
|
||
* const runnable = Effect.provideService(program, Random, {
|
||
* next: Effect.sync(() => Math.random())
|
||
* })
|
||
*
|
||
* // Run successfully
|
||
* Effect.runPromise(runnable)
|
||
* // Example Output:
|
||
* // random number: 0.8241872233134417
|
||
* ```
|
||
*
|
||
* @see {@link provide} for providing multiple layers to an effect.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Context
|
||
*/
|
||
export declare const provideService: {
|
||
/**
|
||
* Provides an implementation for a service in the context of an effect.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to supply a specific implementation for a service
|
||
* required by an effect. Services are typically defined using `Context.Tag`,
|
||
* which acts as a unique identifier for the service. By using this function,
|
||
* you link the service to its concrete implementation, enabling the effect to
|
||
* execute successfully without additional requirements.
|
||
*
|
||
* For example, you can use this function to provide a random number generator,
|
||
* a logger, or any other service your effect depends on. Once the service is
|
||
* provided, all parts of the effect that rely on the service will automatically
|
||
* use the implementation you supplied.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Context } from "effect"
|
||
*
|
||
* // Declaring a tag for a service that generates random numbers
|
||
* class Random extends Context.Tag("MyRandomService")<
|
||
* Random,
|
||
* { readonly next: Effect.Effect<number> }
|
||
* >() {}
|
||
*
|
||
* // Using the service
|
||
* const program = Effect.gen(function* () {
|
||
* const random = yield* Random
|
||
* const randomNumber = yield* random.next
|
||
* console.log(`random number: ${randomNumber}`)
|
||
* })
|
||
*
|
||
* // Providing the implementation
|
||
* //
|
||
* // ┌─── Effect<void, never, never>
|
||
* // ▼
|
||
* const runnable = Effect.provideService(program, Random, {
|
||
* next: Effect.sync(() => Math.random())
|
||
* })
|
||
*
|
||
* // Run successfully
|
||
* Effect.runPromise(runnable)
|
||
* // Example Output:
|
||
* // random number: 0.8241872233134417
|
||
* ```
|
||
*
|
||
* @see {@link provide} for providing multiple layers to an effect.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Context
|
||
*/
|
||
<I, S>(tag: Context.Tag<I, S>, service: NoInfer<S>): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, Exclude<R, I>>;
|
||
/**
|
||
* Provides an implementation for a service in the context of an effect.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to supply a specific implementation for a service
|
||
* required by an effect. Services are typically defined using `Context.Tag`,
|
||
* which acts as a unique identifier for the service. By using this function,
|
||
* you link the service to its concrete implementation, enabling the effect to
|
||
* execute successfully without additional requirements.
|
||
*
|
||
* For example, you can use this function to provide a random number generator,
|
||
* a logger, or any other service your effect depends on. Once the service is
|
||
* provided, all parts of the effect that rely on the service will automatically
|
||
* use the implementation you supplied.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Context } from "effect"
|
||
*
|
||
* // Declaring a tag for a service that generates random numbers
|
||
* class Random extends Context.Tag("MyRandomService")<
|
||
* Random,
|
||
* { readonly next: Effect.Effect<number> }
|
||
* >() {}
|
||
*
|
||
* // Using the service
|
||
* const program = Effect.gen(function* () {
|
||
* const random = yield* Random
|
||
* const randomNumber = yield* random.next
|
||
* console.log(`random number: ${randomNumber}`)
|
||
* })
|
||
*
|
||
* // Providing the implementation
|
||
* //
|
||
* // ┌─── Effect<void, never, never>
|
||
* // ▼
|
||
* const runnable = Effect.provideService(program, Random, {
|
||
* next: Effect.sync(() => Math.random())
|
||
* })
|
||
*
|
||
* // Run successfully
|
||
* Effect.runPromise(runnable)
|
||
* // Example Output:
|
||
* // random number: 0.8241872233134417
|
||
* ```
|
||
*
|
||
* @see {@link provide} for providing multiple layers to an effect.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Context
|
||
*/
|
||
<A, E, R, I, S>(self: Effect<A, E, R>, tag: Context.Tag<I, S>, service: NoInfer<S>): Effect<A, E, Exclude<R, I>>;
|
||
};
|
||
/**
|
||
* Dynamically provides an implementation for a service using an effect.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to provide an implementation for a service
|
||
* dynamically by using another effect. The provided effect is executed to
|
||
* produce the service implementation, which is then made available to the
|
||
* consuming effect. This is particularly useful when the service implementation
|
||
* itself requires asynchronous or resource-intensive initialization.
|
||
*
|
||
* For example, you can use this function to lazily initialize a database
|
||
* connection or fetch configuration values from an external source before
|
||
* making the service available to your effect.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Context
|
||
*/
|
||
export declare const provideServiceEffect: {
|
||
/**
|
||
* Dynamically provides an implementation for a service using an effect.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to provide an implementation for a service
|
||
* dynamically by using another effect. The provided effect is executed to
|
||
* produce the service implementation, which is then made available to the
|
||
* consuming effect. This is particularly useful when the service implementation
|
||
* itself requires asynchronous or resource-intensive initialization.
|
||
*
|
||
* For example, you can use this function to lazily initialize a database
|
||
* connection or fetch configuration values from an external source before
|
||
* making the service available to your effect.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Context
|
||
*/
|
||
<I, S, E1, R1>(tag: Context.Tag<I, S>, effect: Effect<NoInfer<S>, E1, R1>): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E | E1, R1 | Exclude<R, I>>;
|
||
/**
|
||
* Dynamically provides an implementation for a service using an effect.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to provide an implementation for a service
|
||
* dynamically by using another effect. The provided effect is executed to
|
||
* produce the service implementation, which is then made available to the
|
||
* consuming effect. This is particularly useful when the service implementation
|
||
* itself requires asynchronous or resource-intensive initialization.
|
||
*
|
||
* For example, you can use this function to lazily initialize a database
|
||
* connection or fetch configuration values from an external source before
|
||
* making the service available to your effect.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Context
|
||
*/
|
||
<A, E, R, I, S, E1, R1>(self: Effect<A, E, R>, tag: Context.Tag<I, S>, effect: Effect<NoInfer<S>, E1, R1>): Effect<A, E | E1, R1 | Exclude<R, I>>;
|
||
};
|
||
/**
|
||
* Creates a function that uses a service from the context to produce a value.
|
||
*
|
||
* @see {@link serviceFunctionEffect} for a version that returns an effect.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Context
|
||
*/
|
||
export declare const serviceFunction: <T extends Effect<any, any, any>, Args extends Array<any>, A>(getService: T, f: (_: Effect.Success<T>) => (...args: Args) => A) => (...args: Args) => Effect<A, Effect.Error<T>, Effect.Context<T>>;
|
||
/**
|
||
* Creates a function that uses a service from the context to produce an effect.
|
||
*
|
||
* @see {@link serviceFunction} for a version that returns a value.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Context
|
||
*/
|
||
export declare const serviceFunctionEffect: <T extends Effect<any, any, any>, Args extends Array<any>, A, E, R>(getService: T, f: (_: Effect.Success<T>) => (...args: Args) => Effect<A, E, R>) => (...args: Args) => Effect<A, E | Effect.Error<T>, R | Effect.Context<T>>;
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Context
|
||
*/
|
||
export declare const serviceFunctions: <S, SE, SR>(getService: Effect<S, SE, SR>) => {
|
||
[k in keyof S as S[k] extends (...args: Array<any>) => Effect<any, any, any> ? k : never]: S[k] extends (...args: infer Args) => Effect<infer A, infer E, infer R> ? (...args: Args) => Effect<A, SE | E, SR | R> : never;
|
||
};
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Context
|
||
*/
|
||
export declare const serviceConstants: <S, SE, SR>(getService: Effect<S, SE, SR>) => {
|
||
[k in {
|
||
[k in keyof S]: k;
|
||
}[keyof S]]: S[k] extends Effect<infer A, infer E, infer R> ? Effect<A, SE | E, SR | R> : Effect<S[k], SE, SR>;
|
||
};
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Context
|
||
*/
|
||
export declare const serviceMembers: <S, SE, SR>(getService: Effect<S, SE, SR>) => {
|
||
functions: {
|
||
[k in keyof S as S[k] extends (...args: Array<any>) => Effect<any, any, any> ? k : never]: S[k] extends (...args: infer Args) => Effect<infer A, infer E, infer R> ? (...args: Args) => Effect<A, SE | E, SR | R> : never;
|
||
};
|
||
constants: {
|
||
[k in {
|
||
[k in keyof S]: k;
|
||
}[keyof S]]: S[k] extends Effect<infer A, infer E, infer R> ? Effect<A, SE | E, SR | R> : Effect<S[k], SE, SR>;
|
||
};
|
||
};
|
||
/**
|
||
* Retrieves an optional service from the context as an `Option`.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function retrieves a service from the context and wraps it in an
|
||
* `Option`. If the service is available, it returns a `Some` containing the
|
||
* service. If the service is not found, it returns a `None`. This approach is
|
||
* useful when you want to handle the absence of a service gracefully without
|
||
* causing an error.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use this function when:
|
||
* - You need to access a service that may or may not be present in the context.
|
||
* - You want to handle the absence of a service using the `Option` type instead
|
||
* of throwing an error.
|
||
*
|
||
* @see {@link serviceOptional} for a version that throws an error if the service is missing.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Context
|
||
*/
|
||
export declare const serviceOption: <I, S>(tag: Context.Tag<I, S>) => Effect<Option.Option<S>>;
|
||
/**
|
||
* Retrieves a service from the context, throwing an error if it is missing.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function retrieves a required service from the context. If the service
|
||
* is available, it returns the service. If the service is missing, it throws a
|
||
* `NoSuchElementException`, which can be handled using Effect's error-handling
|
||
* mechanisms. This is useful for services that are critical to the execution of
|
||
* your effect.
|
||
*
|
||
* @see {@link serviceOption} for a version that returns an `Option` instead of throwing an error.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Context
|
||
*/
|
||
export declare const serviceOptional: <I, S>(tag: Context.Tag<I, S>) => Effect<S, Cause.NoSuchElementException>;
|
||
/**
|
||
* Updates a service in the context with a new implementation.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function modifies the existing implementation of a service in the
|
||
* context. It retrieves the current service, applies the provided
|
||
* transformation function `f`, and replaces the old service with the
|
||
* transformed one.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is useful for adapting or extending a service's behavior during the
|
||
* execution of an effect.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Context
|
||
*/
|
||
export declare const updateService: {
|
||
/**
|
||
* Updates a service in the context with a new implementation.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function modifies the existing implementation of a service in the
|
||
* context. It retrieves the current service, applies the provided
|
||
* transformation function `f`, and replaces the old service with the
|
||
* transformed one.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is useful for adapting or extending a service's behavior during the
|
||
* execution of an effect.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Context
|
||
*/
|
||
<I, S>(tag: Context.Tag<I, S>, f: (service: NoInfer<S>) => NoInfer<S>): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, R | I>;
|
||
/**
|
||
* Updates a service in the context with a new implementation.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function modifies the existing implementation of a service in the
|
||
* context. It retrieves the current service, applies the provided
|
||
* transformation function `f`, and replaces the old service with the
|
||
* transformed one.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is useful for adapting or extending a service's behavior during the
|
||
* execution of an effect.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Context
|
||
*/
|
||
<A, E, R, I, S>(self: Effect<A, E, R>, tag: Context.Tag<I, S>, f: (service: NoInfer<S>) => NoInfer<S>): Effect<A, E, R | I>;
|
||
};
|
||
/**
|
||
* The "do simulation" in Effect allows you to write code in a more declarative style, similar to the "do notation" in other programming languages. It provides a way to define variables and perform operations on them using functions like `bind` and `let`.
|
||
*
|
||
* Here's how the do simulation works:
|
||
*
|
||
* 1. Start the do simulation using the `Do` value
|
||
* 2. Within the do simulation scope, you can use the `bind` function to define variables and bind them to `Effect` values
|
||
* 3. You can accumulate multiple `bind` statements to define multiple variables within the scope
|
||
* 4. Inside the do simulation scope, you can also use the `let` function to define variables and bind them to simple values
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import * as assert from "node:assert"
|
||
* import { Effect, pipe } from "effect"
|
||
*
|
||
* const result = pipe(
|
||
* Effect.Do,
|
||
* Effect.bind("x", () => Effect.succeed(2)),
|
||
* Effect.bind("y", () => Effect.succeed(3)),
|
||
* Effect.let("sum", ({ x, y }) => x + y)
|
||
* )
|
||
* assert.deepStrictEqual(Effect.runSync(result), { x: 2, y: 3, sum: 5 })
|
||
* ```
|
||
*
|
||
* @see {@link bind}
|
||
* @see {@link bindTo}
|
||
* @see {@link let_ let}
|
||
*
|
||
* @category Do notation
|
||
* @since 2.0.0
|
||
*/
|
||
export declare const Do: Effect<{}>;
|
||
/**
|
||
* The "do simulation" in Effect allows you to write code in a more declarative style, similar to the "do notation" in other programming languages. It provides a way to define variables and perform operations on them using functions like `bind` and `let`.
|
||
*
|
||
* Here's how the do simulation works:
|
||
*
|
||
* 1. Start the do simulation using the `Do` value
|
||
* 2. Within the do simulation scope, you can use the `bind` function to define variables and bind them to `Effect` values
|
||
* 3. You can accumulate multiple `bind` statements to define multiple variables within the scope
|
||
* 4. Inside the do simulation scope, you can also use the `let` function to define variables and bind them to simple values
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import * as assert from "node:assert"
|
||
* import { Effect, pipe } from "effect"
|
||
*
|
||
* const result = pipe(
|
||
* Effect.Do,
|
||
* Effect.bind("x", () => Effect.succeed(2)),
|
||
* Effect.bind("y", () => Effect.succeed(3)),
|
||
* Effect.let("sum", ({ x, y }) => x + y)
|
||
* )
|
||
* assert.deepStrictEqual(Effect.runSync(result), { x: 2, y: 3, sum: 5 })
|
||
* ```
|
||
*
|
||
* @see {@link Do}
|
||
* @see {@link bindTo}
|
||
* @see {@link let_ let}
|
||
*
|
||
* @category Do notation
|
||
* @since 2.0.0
|
||
*/
|
||
export declare const bind: {
|
||
/**
|
||
* The "do simulation" in Effect allows you to write code in a more declarative style, similar to the "do notation" in other programming languages. It provides a way to define variables and perform operations on them using functions like `bind` and `let`.
|
||
*
|
||
* Here's how the do simulation works:
|
||
*
|
||
* 1. Start the do simulation using the `Do` value
|
||
* 2. Within the do simulation scope, you can use the `bind` function to define variables and bind them to `Effect` values
|
||
* 3. You can accumulate multiple `bind` statements to define multiple variables within the scope
|
||
* 4. Inside the do simulation scope, you can also use the `let` function to define variables and bind them to simple values
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import * as assert from "node:assert"
|
||
* import { Effect, pipe } from "effect"
|
||
*
|
||
* const result = pipe(
|
||
* Effect.Do,
|
||
* Effect.bind("x", () => Effect.succeed(2)),
|
||
* Effect.bind("y", () => Effect.succeed(3)),
|
||
* Effect.let("sum", ({ x, y }) => x + y)
|
||
* )
|
||
* assert.deepStrictEqual(Effect.runSync(result), { x: 2, y: 3, sum: 5 })
|
||
* ```
|
||
*
|
||
* @see {@link Do}
|
||
* @see {@link bindTo}
|
||
* @see {@link let_ let}
|
||
*
|
||
* @category Do notation
|
||
* @since 2.0.0
|
||
*/
|
||
<N extends string, A extends object, B, E2, R2>(name: Exclude<N, keyof A>, f: (a: NoInfer<A>) => Effect<B, E2, R2>): <E1, R1>(self: Effect<A, E1, R1>) => Effect<{
|
||
[K in N | keyof A]: K extends keyof A ? A[K] : B;
|
||
}, E2 | E1, R2 | R1>;
|
||
/**
|
||
* The "do simulation" in Effect allows you to write code in a more declarative style, similar to the "do notation" in other programming languages. It provides a way to define variables and perform operations on them using functions like `bind` and `let`.
|
||
*
|
||
* Here's how the do simulation works:
|
||
*
|
||
* 1. Start the do simulation using the `Do` value
|
||
* 2. Within the do simulation scope, you can use the `bind` function to define variables and bind them to `Effect` values
|
||
* 3. You can accumulate multiple `bind` statements to define multiple variables within the scope
|
||
* 4. Inside the do simulation scope, you can also use the `let` function to define variables and bind them to simple values
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import * as assert from "node:assert"
|
||
* import { Effect, pipe } from "effect"
|
||
*
|
||
* const result = pipe(
|
||
* Effect.Do,
|
||
* Effect.bind("x", () => Effect.succeed(2)),
|
||
* Effect.bind("y", () => Effect.succeed(3)),
|
||
* Effect.let("sum", ({ x, y }) => x + y)
|
||
* )
|
||
* assert.deepStrictEqual(Effect.runSync(result), { x: 2, y: 3, sum: 5 })
|
||
* ```
|
||
*
|
||
* @see {@link Do}
|
||
* @see {@link bindTo}
|
||
* @see {@link let_ let}
|
||
*
|
||
* @category Do notation
|
||
* @since 2.0.0
|
||
*/
|
||
<A extends object, N extends string, E1, R1, B, E2, R2>(self: Effect<A, E1, R1>, name: Exclude<N, keyof A>, f: (a: NoInfer<A>) => Effect<B, E2, R2>): Effect<{
|
||
[K in N | keyof A]: K extends keyof A ? A[K] : B;
|
||
}, E1 | E2, R1 | R2>;
|
||
};
|
||
/**
|
||
* `bindAll` combines `all` with `bind`. It is useful
|
||
* when you want to concurrently run multiple effects and then combine their
|
||
* results in a Do notation pipeline.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import * as assert from "node:assert"
|
||
* import { Effect, Either, pipe } from "effect"
|
||
*
|
||
* const result = pipe(
|
||
* Effect.Do,
|
||
* Effect.bind("x", () => Effect.succeed(2)),
|
||
* Effect.bindAll(({ x }) => ({
|
||
* a: Effect.succeed(x),
|
||
* b: Effect.fail("oops"),
|
||
* }), { concurrency: 2, mode: "either" })
|
||
* )
|
||
* assert.deepStrictEqual(Effect.runSync(result), { x: 2, a: Either.right(2), b: Either.left("oops") })
|
||
* ```
|
||
*
|
||
* @category Do notation
|
||
* @since 3.7.0
|
||
*/
|
||
export declare const bindAll: {
|
||
/**
|
||
* `bindAll` combines `all` with `bind`. It is useful
|
||
* when you want to concurrently run multiple effects and then combine their
|
||
* results in a Do notation pipeline.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import * as assert from "node:assert"
|
||
* import { Effect, Either, pipe } from "effect"
|
||
*
|
||
* const result = pipe(
|
||
* Effect.Do,
|
||
* Effect.bind("x", () => Effect.succeed(2)),
|
||
* Effect.bindAll(({ x }) => ({
|
||
* a: Effect.succeed(x),
|
||
* b: Effect.fail("oops"),
|
||
* }), { concurrency: 2, mode: "either" })
|
||
* )
|
||
* assert.deepStrictEqual(Effect.runSync(result), { x: 2, a: Either.right(2), b: Either.left("oops") })
|
||
* ```
|
||
*
|
||
* @category Do notation
|
||
* @since 3.7.0
|
||
*/
|
||
<A extends object, X extends Record<string, Effect<any, any, any>>, O extends NoExcessProperties<{
|
||
readonly concurrency?: Concurrency | undefined;
|
||
readonly batching?: boolean | "inherit" | undefined;
|
||
readonly mode?: "default" | "validate" | "either" | undefined;
|
||
readonly concurrentFinalizers?: boolean | undefined;
|
||
}, O>>(f: (a: NoInfer<A>) => [Extract<keyof X, keyof A>] extends [never] ? X : `Duplicate keys`, options?: undefined | O): <E1, R1>(self: Effect<A, E1, R1>) => [All.ReturnObject<X, false, All.ExtractMode<O>>] extends [Effect<infer Success, infer Error, infer Context>] ? Effect<{
|
||
[K in keyof A | keyof Success]: K extends keyof A ? A[K] : K extends keyof Success ? Success[K] : never;
|
||
}, E1 | Error, R1 | Context> : never;
|
||
/**
|
||
* `bindAll` combines `all` with `bind`. It is useful
|
||
* when you want to concurrently run multiple effects and then combine their
|
||
* results in a Do notation pipeline.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import * as assert from "node:assert"
|
||
* import { Effect, Either, pipe } from "effect"
|
||
*
|
||
* const result = pipe(
|
||
* Effect.Do,
|
||
* Effect.bind("x", () => Effect.succeed(2)),
|
||
* Effect.bindAll(({ x }) => ({
|
||
* a: Effect.succeed(x),
|
||
* b: Effect.fail("oops"),
|
||
* }), { concurrency: 2, mode: "either" })
|
||
* )
|
||
* assert.deepStrictEqual(Effect.runSync(result), { x: 2, a: Either.right(2), b: Either.left("oops") })
|
||
* ```
|
||
*
|
||
* @category Do notation
|
||
* @since 3.7.0
|
||
*/
|
||
<A extends object, X extends Record<string, Effect<any, any, any>>, O extends NoExcessProperties<{
|
||
readonly concurrency?: Concurrency | undefined;
|
||
readonly batching?: boolean | "inherit" | undefined;
|
||
readonly mode?: "default" | "validate" | "either" | undefined;
|
||
readonly concurrentFinalizers?: boolean | undefined;
|
||
}, O>, E1, R1>(self: Effect<A, E1, R1>, f: (a: NoInfer<A>) => [Extract<keyof X, keyof A>] extends [never] ? X : `Duplicate keys`, options?: undefined | {
|
||
readonly concurrency?: Concurrency | undefined;
|
||
readonly batching?: boolean | "inherit" | undefined;
|
||
readonly mode?: "default" | "validate" | "either" | undefined;
|
||
readonly concurrentFinalizers?: boolean | undefined;
|
||
}): [All.ReturnObject<X, false, All.ExtractMode<O>>] extends [Effect<infer Success, infer Error, infer Context>] ? Effect<{
|
||
[K in keyof A | keyof Success]: K extends keyof A ? A[K] : K extends keyof Success ? Success[K] : never;
|
||
}, E1 | Error, R1 | Context> : never;
|
||
};
|
||
/**
|
||
* The "do simulation" in Effect allows you to write code in a more declarative style, similar to the "do notation" in other programming languages. It provides a way to define variables and perform operations on them using functions like `bind` and `let`.
|
||
*
|
||
* Here's how the do simulation works:
|
||
*
|
||
* 1. Start the do simulation using the `Do` value
|
||
* 2. Within the do simulation scope, you can use the `bind` function to define variables and bind them to `Effect` values
|
||
* 3. You can accumulate multiple `bind` statements to define multiple variables within the scope
|
||
* 4. Inside the do simulation scope, you can also use the `let` function to define variables and bind them to simple values
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import * as assert from "node:assert"
|
||
* import { Effect, pipe } from "effect"
|
||
*
|
||
* const result = pipe(
|
||
* Effect.Do,
|
||
* Effect.bind("x", () => Effect.succeed(2)),
|
||
* Effect.bind("y", () => Effect.succeed(3)),
|
||
* Effect.let("sum", ({ x, y }) => x + y)
|
||
* )
|
||
* assert.deepStrictEqual(Effect.runSync(result), { x: 2, y: 3, sum: 5 })
|
||
* ```
|
||
*
|
||
* @see {@link Do}
|
||
* @see {@link bind}
|
||
* @see {@link let_ let}
|
||
*
|
||
* @category Do notation
|
||
* @since 2.0.0
|
||
*/
|
||
export declare const bindTo: {
|
||
/**
|
||
* The "do simulation" in Effect allows you to write code in a more declarative style, similar to the "do notation" in other programming languages. It provides a way to define variables and perform operations on them using functions like `bind` and `let`.
|
||
*
|
||
* Here's how the do simulation works:
|
||
*
|
||
* 1. Start the do simulation using the `Do` value
|
||
* 2. Within the do simulation scope, you can use the `bind` function to define variables and bind them to `Effect` values
|
||
* 3. You can accumulate multiple `bind` statements to define multiple variables within the scope
|
||
* 4. Inside the do simulation scope, you can also use the `let` function to define variables and bind them to simple values
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import * as assert from "node:assert"
|
||
* import { Effect, pipe } from "effect"
|
||
*
|
||
* const result = pipe(
|
||
* Effect.Do,
|
||
* Effect.bind("x", () => Effect.succeed(2)),
|
||
* Effect.bind("y", () => Effect.succeed(3)),
|
||
* Effect.let("sum", ({ x, y }) => x + y)
|
||
* )
|
||
* assert.deepStrictEqual(Effect.runSync(result), { x: 2, y: 3, sum: 5 })
|
||
* ```
|
||
*
|
||
* @see {@link Do}
|
||
* @see {@link bind}
|
||
* @see {@link let_ let}
|
||
*
|
||
* @category Do notation
|
||
* @since 2.0.0
|
||
*/
|
||
<N extends string>(name: N): <A, E, R>(self: Effect<A, E, R>) => Effect<{
|
||
[K in N]: A;
|
||
}, E, R>;
|
||
/**
|
||
* The "do simulation" in Effect allows you to write code in a more declarative style, similar to the "do notation" in other programming languages. It provides a way to define variables and perform operations on them using functions like `bind` and `let`.
|
||
*
|
||
* Here's how the do simulation works:
|
||
*
|
||
* 1. Start the do simulation using the `Do` value
|
||
* 2. Within the do simulation scope, you can use the `bind` function to define variables and bind them to `Effect` values
|
||
* 3. You can accumulate multiple `bind` statements to define multiple variables within the scope
|
||
* 4. Inside the do simulation scope, you can also use the `let` function to define variables and bind them to simple values
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import * as assert from "node:assert"
|
||
* import { Effect, pipe } from "effect"
|
||
*
|
||
* const result = pipe(
|
||
* Effect.Do,
|
||
* Effect.bind("x", () => Effect.succeed(2)),
|
||
* Effect.bind("y", () => Effect.succeed(3)),
|
||
* Effect.let("sum", ({ x, y }) => x + y)
|
||
* )
|
||
* assert.deepStrictEqual(Effect.runSync(result), { x: 2, y: 3, sum: 5 })
|
||
* ```
|
||
*
|
||
* @see {@link Do}
|
||
* @see {@link bind}
|
||
* @see {@link let_ let}
|
||
*
|
||
* @category Do notation
|
||
* @since 2.0.0
|
||
*/
|
||
<A, E, R, N extends string>(self: Effect<A, E, R>, name: N): Effect<{
|
||
[K in N]: A;
|
||
}, E, R>;
|
||
};
|
||
declare const let_: {
|
||
<N extends string, A extends object, B>(name: Exclude<N, keyof A>, f: (a: NoInfer<A>) => B): <E, R>(self: Effect<A, E, R>) => Effect<{
|
||
[K in N | keyof A]: K extends keyof A ? A[K] : B;
|
||
}, E, R>;
|
||
<A extends object, N extends string, E, R, B>(self: Effect<A, E, R>, name: Exclude<N, keyof A>, f: (a: NoInfer<A>) => B): Effect<{
|
||
[K in N | keyof A]: K extends keyof A ? A[K] : B;
|
||
}, E, R>;
|
||
};
|
||
export {
|
||
/**
|
||
* The "do simulation" in Effect allows you to write code in a more declarative style, similar to the "do notation" in other programming languages. It provides a way to define variables and perform operations on them using functions like `bind` and `let`.
|
||
*
|
||
* Here's how the do simulation works:
|
||
*
|
||
* 1. Start the do simulation using the `Do` value
|
||
* 2. Within the do simulation scope, you can use the `bind` function to define variables and bind them to `Effect` values
|
||
* 3. You can accumulate multiple `bind` statements to define multiple variables within the scope
|
||
* 4. Inside the do simulation scope, you can also use the `let` function to define variables and bind them to simple values
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import * as assert from "node:assert"
|
||
* import { Effect, pipe } from "effect"
|
||
*
|
||
* const result = pipe(
|
||
* Effect.Do,
|
||
* Effect.bind("x", () => Effect.succeed(2)),
|
||
* Effect.bind("y", () => Effect.succeed(3)),
|
||
* Effect.let("sum", ({ x, y }) => x + y)
|
||
* )
|
||
* assert.deepStrictEqual(Effect.runSync(result), { x: 2, y: 3, sum: 5 })
|
||
*
|
||
* ```
|
||
*
|
||
* @see {@link Do}
|
||
* @see {@link bind}
|
||
* @see {@link bindTo}
|
||
*
|
||
* @category Do notation
|
||
* @since 2.0.0
|
||
*/
|
||
let_ as let };
|
||
/**
|
||
* Encapsulates the result of an effect in an `Option`.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function wraps the outcome of an effect in an `Option` type. If the
|
||
* original effect succeeds, the success value is wrapped in `Option.some`. If
|
||
* the effect fails, the failure is converted to `Option.none`.
|
||
*
|
||
* This is particularly useful for scenarios where you want to represent the
|
||
* absence of a value explicitly, without causing the resulting effect to fail.
|
||
* The resulting effect has an error type of `never`, meaning it cannot fail
|
||
* directly. However, unrecoverable errors, also referred to as defects, are
|
||
* not captured and will still result in failure.
|
||
*
|
||
* **Example** (Using Effect.option to Handle Errors)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const maybe1 = Effect.option(Effect.succeed(1))
|
||
*
|
||
* Effect.runPromiseExit(maybe1).then(console.log)
|
||
* // Output:
|
||
* // {
|
||
* // _id: 'Exit',
|
||
* // _tag: 'Success',
|
||
* // value: { _id: 'Option', _tag: 'Some', value: 1 }
|
||
* // }
|
||
*
|
||
* const maybe2 = Effect.option(Effect.fail("Uh oh!"))
|
||
*
|
||
* Effect.runPromiseExit(maybe2).then(console.log)
|
||
* // Output:
|
||
* // {
|
||
* // _id: 'Exit',
|
||
* // _tag: 'Success',
|
||
* // value: { _id: 'Option', _tag: 'None' }
|
||
* // }
|
||
*
|
||
* const maybe3 = Effect.option(Effect.die("Boom!"))
|
||
*
|
||
* Effect.runPromiseExit(maybe3).then(console.log)
|
||
* // Output:
|
||
* // {
|
||
* // _id: 'Exit',
|
||
* // _tag: 'Failure',
|
||
* // cause: { _id: 'Cause', _tag: 'Die', defect: 'Boom!' }
|
||
* // }
|
||
* ```
|
||
*
|
||
* @see {@link either} for a version that uses `Either` instead.
|
||
* @see {@link exit} for a version that encapsulates both recoverable errors and defects in an `Exit`.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Outcome Encapsulation
|
||
*/
|
||
export declare const option: <A, E, R>(self: Effect<A, E, R>) => Effect<Option.Option<A>, never, R>;
|
||
/**
|
||
* Encapsulates both success and failure of an `Effect` into an `Either` type.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function converts an effect that may fail into an effect that always
|
||
* succeeds, wrapping the outcome in an `Either` type. The result will be
|
||
* `Either.Left` if the effect fails, containing the recoverable error, or
|
||
* `Either.Right` if it succeeds, containing the result.
|
||
*
|
||
* Using this function, you can handle recoverable errors explicitly without
|
||
* causing the effect to fail. This is particularly useful in scenarios where
|
||
* you want to chain effects and manage both success and failure in the same
|
||
* logical flow.
|
||
*
|
||
* It's important to note that unrecoverable errors, often referred to as
|
||
* "defects," are still thrown and not captured within the `Either` type. Only
|
||
* failures that are explicitly represented as recoverable errors in the effect
|
||
* are encapsulated.
|
||
*
|
||
* The resulting effect cannot fail directly because all recoverable failures
|
||
* are represented inside the `Either` type.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Either, Random } from "effect"
|
||
*
|
||
* class HttpError {
|
||
* readonly _tag = "HttpError"
|
||
* }
|
||
*
|
||
* class ValidationError {
|
||
* readonly _tag = "ValidationError"
|
||
* }
|
||
*
|
||
* // ┌─── Effect<string, HttpError | ValidationError, never>
|
||
* // ▼
|
||
* const program = Effect.gen(function* () {
|
||
* const n1 = yield* Random.next
|
||
* const n2 = yield* Random.next
|
||
* if (n1 < 0.5) {
|
||
* yield* Effect.fail(new HttpError())
|
||
* }
|
||
* if (n2 < 0.5) {
|
||
* yield* Effect.fail(new ValidationError())
|
||
* }
|
||
* return "some result"
|
||
* })
|
||
*
|
||
* // ┌─── Effect<string, never, never>
|
||
* // ▼
|
||
* const recovered = Effect.gen(function* () {
|
||
* // ┌─── Either<string, HttpError | ValidationError>
|
||
* // ▼
|
||
* const failureOrSuccess = yield* Effect.either(program)
|
||
* return Either.match(failureOrSuccess, {
|
||
* onLeft: (error) => `Recovering from ${error._tag}`,
|
||
* onRight: (value) => value // Do nothing in case of success
|
||
* })
|
||
* })
|
||
* ```
|
||
*
|
||
* @see {@link option} for a version that uses `Option` instead.
|
||
* @see {@link exit} for a version that encapsulates both recoverable errors and defects in an `Exit`.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Outcome Encapsulation
|
||
*/
|
||
export declare const either: <A, E, R>(self: Effect<A, E, R>) => Effect<Either.Either<A, E>, never, R>;
|
||
/**
|
||
* Encapsulates both success and failure of an `Effect` using the `Exit` type.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function converts an effect into one that always succeeds, wrapping its
|
||
* outcome in the `Exit` type. The `Exit` type provides explicit handling of
|
||
* both success (`Exit.Success`) and failure (`Exit.Failure`) cases, including
|
||
* defects (unrecoverable errors).
|
||
*
|
||
* Unlike {@link either} or {@link option}, this function also encapsulates
|
||
* defects, which are typically unrecoverable and would otherwise terminate the
|
||
* effect. With the `Exit` type, defects are represented in `Exit.Failure`,
|
||
* allowing for detailed introspection and structured error handling.
|
||
*
|
||
* This makes the resulting effect robust and incapable of direct failure (its
|
||
* error type is `never`). It is particularly useful for workflows where all
|
||
* outcomes, including unexpected defects, must be managed and analyzed.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Cause, Console, Exit } from "effect"
|
||
*
|
||
* // Simulating a runtime error
|
||
* const task = Effect.dieMessage("Boom!")
|
||
*
|
||
* const program = Effect.gen(function* () {
|
||
* const exit = yield* Effect.exit(task)
|
||
* if (Exit.isFailure(exit)) {
|
||
* const cause = exit.cause
|
||
* if (
|
||
* Cause.isDieType(cause) &&
|
||
* Cause.isRuntimeException(cause.defect)
|
||
* ) {
|
||
* yield* Console.log(
|
||
* `RuntimeException defect caught: ${cause.defect.message}`
|
||
* )
|
||
* } else {
|
||
* yield* Console.log("Unknown failure caught.")
|
||
* }
|
||
* }
|
||
* })
|
||
*
|
||
* // We get an Exit.Success because we caught all failures
|
||
* Effect.runPromiseExit(program).then(console.log)
|
||
* // Output:
|
||
* // RuntimeException defect caught: Boom!
|
||
* // {
|
||
* // _id: "Exit",
|
||
* // _tag: "Success",
|
||
* // value: undefined
|
||
* // }
|
||
* ```
|
||
*
|
||
* @see {@link option} for a version that uses `Option` instead.
|
||
* @see {@link either} for a version that uses `Either` instead.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Outcome Encapsulation
|
||
*/
|
||
export declare const exit: <A, E, R>(self: Effect<A, E, R>) => Effect<Exit.Exit<A, E>, never, R>;
|
||
/**
|
||
* Converts an `Effect` into an operation that completes a `Deferred` with its result.
|
||
*
|
||
* **Details**
|
||
*
|
||
* The `intoDeferred` function takes an effect and a `Deferred` and ensures that the `Deferred`
|
||
* is completed based on the outcome of the effect. If the effect succeeds, the `Deferred` is
|
||
* completed with the success value. If the effect fails, the `Deferred` is completed with the
|
||
* failure. Additionally, if the effect is interrupted, the `Deferred` will also be interrupted.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Deferred, Effect } from "effect"
|
||
*
|
||
* // Define an effect that succeeds
|
||
* const successEffect = Effect.succeed(42)
|
||
*
|
||
* const program = Effect.gen(function*() {
|
||
* // Create a deferred
|
||
* const deferred = yield* Deferred.make<number, string>()
|
||
*
|
||
* // Complete the deferred using the successEffect
|
||
* const isCompleted = yield* Effect.intoDeferred(successEffect, deferred)
|
||
*
|
||
* // Access the value of the deferred
|
||
* const value = yield* Deferred.await(deferred)
|
||
* console.log(value)
|
||
*
|
||
* return isCompleted
|
||
* })
|
||
*
|
||
* Effect.runPromise(program).then(console.log)
|
||
* // Output:
|
||
* // 42
|
||
* // true
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Synchronization Utilities
|
||
*/
|
||
export declare const intoDeferred: {
|
||
/**
|
||
* Converts an `Effect` into an operation that completes a `Deferred` with its result.
|
||
*
|
||
* **Details**
|
||
*
|
||
* The `intoDeferred` function takes an effect and a `Deferred` and ensures that the `Deferred`
|
||
* is completed based on the outcome of the effect. If the effect succeeds, the `Deferred` is
|
||
* completed with the success value. If the effect fails, the `Deferred` is completed with the
|
||
* failure. Additionally, if the effect is interrupted, the `Deferred` will also be interrupted.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Deferred, Effect } from "effect"
|
||
*
|
||
* // Define an effect that succeeds
|
||
* const successEffect = Effect.succeed(42)
|
||
*
|
||
* const program = Effect.gen(function*() {
|
||
* // Create a deferred
|
||
* const deferred = yield* Deferred.make<number, string>()
|
||
*
|
||
* // Complete the deferred using the successEffect
|
||
* const isCompleted = yield* Effect.intoDeferred(successEffect, deferred)
|
||
*
|
||
* // Access the value of the deferred
|
||
* const value = yield* Deferred.await(deferred)
|
||
* console.log(value)
|
||
*
|
||
* return isCompleted
|
||
* })
|
||
*
|
||
* Effect.runPromise(program).then(console.log)
|
||
* // Output:
|
||
* // 42
|
||
* // true
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Synchronization Utilities
|
||
*/
|
||
<A, E>(deferred: Deferred.Deferred<A, E>): <R>(self: Effect<A, E, R>) => Effect<boolean, never, R>;
|
||
/**
|
||
* Converts an `Effect` into an operation that completes a `Deferred` with its result.
|
||
*
|
||
* **Details**
|
||
*
|
||
* The `intoDeferred` function takes an effect and a `Deferred` and ensures that the `Deferred`
|
||
* is completed based on the outcome of the effect. If the effect succeeds, the `Deferred` is
|
||
* completed with the success value. If the effect fails, the `Deferred` is completed with the
|
||
* failure. Additionally, if the effect is interrupted, the `Deferred` will also be interrupted.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Deferred, Effect } from "effect"
|
||
*
|
||
* // Define an effect that succeeds
|
||
* const successEffect = Effect.succeed(42)
|
||
*
|
||
* const program = Effect.gen(function*() {
|
||
* // Create a deferred
|
||
* const deferred = yield* Deferred.make<number, string>()
|
||
*
|
||
* // Complete the deferred using the successEffect
|
||
* const isCompleted = yield* Effect.intoDeferred(successEffect, deferred)
|
||
*
|
||
* // Access the value of the deferred
|
||
* const value = yield* Deferred.await(deferred)
|
||
* console.log(value)
|
||
*
|
||
* return isCompleted
|
||
* })
|
||
*
|
||
* Effect.runPromise(program).then(console.log)
|
||
* // Output:
|
||
* // 42
|
||
* // true
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Synchronization Utilities
|
||
*/
|
||
<A, E, R>(self: Effect<A, E, R>, deferred: Deferred.Deferred<A, E>): Effect<boolean, never, R>;
|
||
};
|
||
declare const if_: {
|
||
<A1, E1, R1, A2, E2, R2>(options: {
|
||
readonly onTrue: LazyArg<Effect<A1, E1, R1>>;
|
||
readonly onFalse: LazyArg<Effect<A2, E2, R2>>;
|
||
}): <E = never, R = never>(self: boolean | Effect<boolean, E, R>) => Effect<A1 | A2, E1 | E2 | E, R1 | R2 | R>;
|
||
<A1, E1, R1, A2, E2, R2, E = never, R = never>(self: boolean | Effect<boolean, E, R>, options: {
|
||
readonly onTrue: LazyArg<Effect<A1, E1, R1>>;
|
||
readonly onFalse: LazyArg<Effect<A2, E2, R2>>;
|
||
}): Effect<A1 | A2, E1 | E2 | E, R1 | R2 | R>;
|
||
};
|
||
export {
|
||
/**
|
||
* Executes one of two effects based on a condition evaluated by an effectful predicate.
|
||
*
|
||
* Use `if` to run one of two effects depending on whether the predicate effect
|
||
* evaluates to `true` or `false`. If the predicate is `true`, the `onTrue` effect
|
||
* is executed. If it is `false`, the `onFalse` effect is executed instead.
|
||
*
|
||
* **Example** (Simulating a Coin Flip)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Random, Console } from "effect"
|
||
*
|
||
* const flipTheCoin = Effect.if(Random.nextBoolean, {
|
||
* onTrue: () => Console.log("Head"), // Runs if the predicate is true
|
||
* onFalse: () => Console.log("Tail") // Runs if the predicate is false
|
||
* })
|
||
*
|
||
* Effect.runFork(flipTheCoin)
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Conditional Operators
|
||
*/
|
||
if_ as if };
|
||
/**
|
||
* Filters an effect, dying with a custom defect if the predicate fails.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function applies a predicate to the result of an effect. If the
|
||
* predicate evaluates to `false`, the effect dies with a custom defect
|
||
* generated by the `orDieWith` function.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is useful for enforcing constraints on values and treating violations as
|
||
* fatal program errors.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Filtering
|
||
*/
|
||
export declare const filterOrDie: {
|
||
/**
|
||
* Filters an effect, dying with a custom defect if the predicate fails.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function applies a predicate to the result of an effect. If the
|
||
* predicate evaluates to `false`, the effect dies with a custom defect
|
||
* generated by the `orDieWith` function.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is useful for enforcing constraints on values and treating violations as
|
||
* fatal program errors.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Filtering
|
||
*/
|
||
<A, B extends A>(refinement: Refinement<NoInfer<A>, B>, orDieWith: (a: EqualsWith<A, B, A, Exclude<A, B>>) => unknown): <E, R>(self: Effect<A, E, R>) => Effect<B, E, R>;
|
||
/**
|
||
* Filters an effect, dying with a custom defect if the predicate fails.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function applies a predicate to the result of an effect. If the
|
||
* predicate evaluates to `false`, the effect dies with a custom defect
|
||
* generated by the `orDieWith` function.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is useful for enforcing constraints on values and treating violations as
|
||
* fatal program errors.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Filtering
|
||
*/
|
||
<A>(predicate: Predicate<NoInfer<A>>, orDieWith: (a: NoInfer<A>) => unknown): <E, R>(self: Effect<A, E, R>) => Effect<A, E, R>;
|
||
/**
|
||
* Filters an effect, dying with a custom defect if the predicate fails.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function applies a predicate to the result of an effect. If the
|
||
* predicate evaluates to `false`, the effect dies with a custom defect
|
||
* generated by the `orDieWith` function.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is useful for enforcing constraints on values and treating violations as
|
||
* fatal program errors.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Filtering
|
||
*/
|
||
<A, E, R, B extends A>(self: Effect<A, E, R>, refinement: Refinement<A, B>, orDieWith: (a: EqualsWith<A, B, A, Exclude<A, B>>) => unknown): Effect<B, E, R>;
|
||
/**
|
||
* Filters an effect, dying with a custom defect if the predicate fails.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function applies a predicate to the result of an effect. If the
|
||
* predicate evaluates to `false`, the effect dies with a custom defect
|
||
* generated by the `orDieWith` function.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is useful for enforcing constraints on values and treating violations as
|
||
* fatal program errors.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Filtering
|
||
*/
|
||
<A, E, R>(self: Effect<A, E, R>, predicate: Predicate<A>, orDieWith: (a: A) => unknown): Effect<A, E, R>;
|
||
};
|
||
/**
|
||
* Filters an effect, dying with a custom message if the predicate fails.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function works like {@link filterOrDie} but allows you to specify a
|
||
* custom error message to describe the reason for the failure. The message is
|
||
* included in the defect when the predicate evaluates to `false`.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Filtering
|
||
*/
|
||
export declare const filterOrDieMessage: {
|
||
/**
|
||
* Filters an effect, dying with a custom message if the predicate fails.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function works like {@link filterOrDie} but allows you to specify a
|
||
* custom error message to describe the reason for the failure. The message is
|
||
* included in the defect when the predicate evaluates to `false`.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Filtering
|
||
*/
|
||
<A, B extends A>(refinement: Refinement<NoInfer<A>, B>, message: string): <E, R>(self: Effect<A, E, R>) => Effect<B, E, R>;
|
||
/**
|
||
* Filters an effect, dying with a custom message if the predicate fails.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function works like {@link filterOrDie} but allows you to specify a
|
||
* custom error message to describe the reason for the failure. The message is
|
||
* included in the defect when the predicate evaluates to `false`.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Filtering
|
||
*/
|
||
<A>(predicate: Predicate<NoInfer<A>>, message: string): <E, R>(self: Effect<A, E, R>) => Effect<A, E, R>;
|
||
/**
|
||
* Filters an effect, dying with a custom message if the predicate fails.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function works like {@link filterOrDie} but allows you to specify a
|
||
* custom error message to describe the reason for the failure. The message is
|
||
* included in the defect when the predicate evaluates to `false`.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Filtering
|
||
*/
|
||
<A, E, R, B extends A>(self: Effect<A, E, R>, refinement: Refinement<A, B>, message: string): Effect<B, E, R>;
|
||
/**
|
||
* Filters an effect, dying with a custom message if the predicate fails.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function works like {@link filterOrDie} but allows you to specify a
|
||
* custom error message to describe the reason for the failure. The message is
|
||
* included in the defect when the predicate evaluates to `false`.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Filtering
|
||
*/
|
||
<A, E, R>(self: Effect<A, E, R>, predicate: Predicate<A>, message: string): Effect<A, E, R>;
|
||
};
|
||
/**
|
||
* Filters an effect, providing an alternative effect if the predicate fails.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function applies a predicate to the result of an effect. If the
|
||
* predicate evaluates to `false`, it executes the `orElse` effect instead. The
|
||
* `orElse` effect can produce an alternative value or perform additional
|
||
* computations.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Filtering
|
||
*/
|
||
export declare const filterOrElse: {
|
||
/**
|
||
* Filters an effect, providing an alternative effect if the predicate fails.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function applies a predicate to the result of an effect. If the
|
||
* predicate evaluates to `false`, it executes the `orElse` effect instead. The
|
||
* `orElse` effect can produce an alternative value or perform additional
|
||
* computations.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Filtering
|
||
*/
|
||
<A, C, E2, R2, B extends A>(refinement: Refinement<NoInfer<A>, B>, orElse: (a: EqualsWith<A, B, NoInfer<A>, Exclude<NoInfer<A>, B>>) => Effect<C, E2, R2>): <E, R>(self: Effect<A, E, R>) => Effect<B | C, E2 | E, R2 | R>;
|
||
/**
|
||
* Filters an effect, providing an alternative effect if the predicate fails.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function applies a predicate to the result of an effect. If the
|
||
* predicate evaluates to `false`, it executes the `orElse` effect instead. The
|
||
* `orElse` effect can produce an alternative value or perform additional
|
||
* computations.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Filtering
|
||
*/
|
||
<A, C, E2, R2>(predicate: Predicate<NoInfer<A>>, orElse: (a: NoInfer<A>) => Effect<C, E2, R2>): <E, R>(self: Effect<A, E, R>) => Effect<A | C, E2 | E, R2 | R>;
|
||
/**
|
||
* Filters an effect, providing an alternative effect if the predicate fails.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function applies a predicate to the result of an effect. If the
|
||
* predicate evaluates to `false`, it executes the `orElse` effect instead. The
|
||
* `orElse` effect can produce an alternative value or perform additional
|
||
* computations.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Filtering
|
||
*/
|
||
<A, E, R, C, E2, R2, B extends A>(self: Effect<A, E, R>, refinement: Refinement<A, B>, orElse: (a: EqualsWith<A, B, A, Exclude<A, B>>) => Effect<C, E2, R2>): Effect<B | C, E | E2, R | R2>;
|
||
/**
|
||
* Filters an effect, providing an alternative effect if the predicate fails.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function applies a predicate to the result of an effect. If the
|
||
* predicate evaluates to `false`, it executes the `orElse` effect instead. The
|
||
* `orElse` effect can produce an alternative value or perform additional
|
||
* computations.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Filtering
|
||
*/
|
||
<A, E, R, C, E2, R2>(self: Effect<A, E, R>, predicate: Predicate<A>, orElse: (a: A) => Effect<C, E2, R2>): Effect<A | C, E | E2, R | R2>;
|
||
};
|
||
/**
|
||
* Filters an effect, failing with a custom error if the predicate fails.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function applies a predicate to the result of an effect. If the
|
||
* predicate evaluates to `false`, the effect fails with a custom error
|
||
* generated by the `orFailWith` function.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is useful for enforcing constraints and treating violations as
|
||
* recoverable errors.
|
||
*
|
||
* **Providing a Guard**
|
||
*
|
||
* In addition to the filtering capabilities discussed earlier, you have the
|
||
* option to further refine and narrow down the type of the success channel by
|
||
* providing a [user-defined type
|
||
* guard](https://www.typescriptlang.org/docs/handbook/2/narrowing.html#using-type-predicates).
|
||
* Let's explore this concept through an example:
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, pipe } from "effect"
|
||
*
|
||
* // Define a user interface
|
||
* interface User {
|
||
* readonly name: string
|
||
* }
|
||
*
|
||
* // Simulate an asynchronous authentication function
|
||
* declare const auth: () => Promise<User | null>
|
||
*
|
||
* const program = pipe(
|
||
* Effect.promise(() => auth()),
|
||
* // Use filterOrFail with a custom type guard to ensure user is not null
|
||
* Effect.filterOrFail(
|
||
* (user): user is User => user !== null, // Type guard
|
||
* () => new Error("Unauthorized")
|
||
* ),
|
||
* // 'user' now has the type `User` (not `User | null`)
|
||
* Effect.andThen((user) => user.name)
|
||
* )
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Filtering
|
||
*/
|
||
export declare const filterOrFail: {
|
||
/**
|
||
* Filters an effect, failing with a custom error if the predicate fails.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function applies a predicate to the result of an effect. If the
|
||
* predicate evaluates to `false`, the effect fails with a custom error
|
||
* generated by the `orFailWith` function.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is useful for enforcing constraints and treating violations as
|
||
* recoverable errors.
|
||
*
|
||
* **Providing a Guard**
|
||
*
|
||
* In addition to the filtering capabilities discussed earlier, you have the
|
||
* option to further refine and narrow down the type of the success channel by
|
||
* providing a [user-defined type
|
||
* guard](https://www.typescriptlang.org/docs/handbook/2/narrowing.html#using-type-predicates).
|
||
* Let's explore this concept through an example:
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, pipe } from "effect"
|
||
*
|
||
* // Define a user interface
|
||
* interface User {
|
||
* readonly name: string
|
||
* }
|
||
*
|
||
* // Simulate an asynchronous authentication function
|
||
* declare const auth: () => Promise<User | null>
|
||
*
|
||
* const program = pipe(
|
||
* Effect.promise(() => auth()),
|
||
* // Use filterOrFail with a custom type guard to ensure user is not null
|
||
* Effect.filterOrFail(
|
||
* (user): user is User => user !== null, // Type guard
|
||
* () => new Error("Unauthorized")
|
||
* ),
|
||
* // 'user' now has the type `User` (not `User | null`)
|
||
* Effect.andThen((user) => user.name)
|
||
* )
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Filtering
|
||
*/
|
||
<A, E2, B extends A>(refinement: Refinement<NoInfer<A>, B>, orFailWith: (a: EqualsWith<A, B, NoInfer<A>, Exclude<NoInfer<A>, B>>) => E2): <E, R>(self: Effect<A, E, R>) => Effect<NoInfer<B>, E2 | E, R>;
|
||
/**
|
||
* Filters an effect, failing with a custom error if the predicate fails.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function applies a predicate to the result of an effect. If the
|
||
* predicate evaluates to `false`, the effect fails with a custom error
|
||
* generated by the `orFailWith` function.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is useful for enforcing constraints and treating violations as
|
||
* recoverable errors.
|
||
*
|
||
* **Providing a Guard**
|
||
*
|
||
* In addition to the filtering capabilities discussed earlier, you have the
|
||
* option to further refine and narrow down the type of the success channel by
|
||
* providing a [user-defined type
|
||
* guard](https://www.typescriptlang.org/docs/handbook/2/narrowing.html#using-type-predicates).
|
||
* Let's explore this concept through an example:
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, pipe } from "effect"
|
||
*
|
||
* // Define a user interface
|
||
* interface User {
|
||
* readonly name: string
|
||
* }
|
||
*
|
||
* // Simulate an asynchronous authentication function
|
||
* declare const auth: () => Promise<User | null>
|
||
*
|
||
* const program = pipe(
|
||
* Effect.promise(() => auth()),
|
||
* // Use filterOrFail with a custom type guard to ensure user is not null
|
||
* Effect.filterOrFail(
|
||
* (user): user is User => user !== null, // Type guard
|
||
* () => new Error("Unauthorized")
|
||
* ),
|
||
* // 'user' now has the type `User` (not `User | null`)
|
||
* Effect.andThen((user) => user.name)
|
||
* )
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Filtering
|
||
*/
|
||
<A, E2>(predicate: Predicate<NoInfer<A>>, orFailWith: (a: NoInfer<A>) => E2): <E, R>(self: Effect<A, E, R>) => Effect<A, E2 | E, R>;
|
||
/**
|
||
* Filters an effect, failing with a custom error if the predicate fails.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function applies a predicate to the result of an effect. If the
|
||
* predicate evaluates to `false`, the effect fails with a custom error
|
||
* generated by the `orFailWith` function.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is useful for enforcing constraints and treating violations as
|
||
* recoverable errors.
|
||
*
|
||
* **Providing a Guard**
|
||
*
|
||
* In addition to the filtering capabilities discussed earlier, you have the
|
||
* option to further refine and narrow down the type of the success channel by
|
||
* providing a [user-defined type
|
||
* guard](https://www.typescriptlang.org/docs/handbook/2/narrowing.html#using-type-predicates).
|
||
* Let's explore this concept through an example:
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, pipe } from "effect"
|
||
*
|
||
* // Define a user interface
|
||
* interface User {
|
||
* readonly name: string
|
||
* }
|
||
*
|
||
* // Simulate an asynchronous authentication function
|
||
* declare const auth: () => Promise<User | null>
|
||
*
|
||
* const program = pipe(
|
||
* Effect.promise(() => auth()),
|
||
* // Use filterOrFail with a custom type guard to ensure user is not null
|
||
* Effect.filterOrFail(
|
||
* (user): user is User => user !== null, // Type guard
|
||
* () => new Error("Unauthorized")
|
||
* ),
|
||
* // 'user' now has the type `User` (not `User | null`)
|
||
* Effect.andThen((user) => user.name)
|
||
* )
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Filtering
|
||
*/
|
||
<A, E, R, E2, B extends A>(self: Effect<A, E, R>, refinement: Refinement<A, B>, orFailWith: (a: EqualsWith<A, B, A, Exclude<A, B>>) => E2): Effect<NoInfer<B>, E2 | E, R>;
|
||
/**
|
||
* Filters an effect, failing with a custom error if the predicate fails.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function applies a predicate to the result of an effect. If the
|
||
* predicate evaluates to `false`, the effect fails with a custom error
|
||
* generated by the `orFailWith` function.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is useful for enforcing constraints and treating violations as
|
||
* recoverable errors.
|
||
*
|
||
* **Providing a Guard**
|
||
*
|
||
* In addition to the filtering capabilities discussed earlier, you have the
|
||
* option to further refine and narrow down the type of the success channel by
|
||
* providing a [user-defined type
|
||
* guard](https://www.typescriptlang.org/docs/handbook/2/narrowing.html#using-type-predicates).
|
||
* Let's explore this concept through an example:
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, pipe } from "effect"
|
||
*
|
||
* // Define a user interface
|
||
* interface User {
|
||
* readonly name: string
|
||
* }
|
||
*
|
||
* // Simulate an asynchronous authentication function
|
||
* declare const auth: () => Promise<User | null>
|
||
*
|
||
* const program = pipe(
|
||
* Effect.promise(() => auth()),
|
||
* // Use filterOrFail with a custom type guard to ensure user is not null
|
||
* Effect.filterOrFail(
|
||
* (user): user is User => user !== null, // Type guard
|
||
* () => new Error("Unauthorized")
|
||
* ),
|
||
* // 'user' now has the type `User` (not `User | null`)
|
||
* Effect.andThen((user) => user.name)
|
||
* )
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Filtering
|
||
*/
|
||
<A, E, R, E2>(self: Effect<A, E, R>, predicate: Predicate<A>, orFailWith: (a: A) => E2): Effect<A, E2 | E, R>;
|
||
/**
|
||
* Filters an effect, failing with a custom error if the predicate fails.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function applies a predicate to the result of an effect. If the
|
||
* predicate evaluates to `false`, the effect fails with a custom error
|
||
* generated by the `orFailWith` function.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is useful for enforcing constraints and treating violations as
|
||
* recoverable errors.
|
||
*
|
||
* **Providing a Guard**
|
||
*
|
||
* In addition to the filtering capabilities discussed earlier, you have the
|
||
* option to further refine and narrow down the type of the success channel by
|
||
* providing a [user-defined type
|
||
* guard](https://www.typescriptlang.org/docs/handbook/2/narrowing.html#using-type-predicates).
|
||
* Let's explore this concept through an example:
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, pipe } from "effect"
|
||
*
|
||
* // Define a user interface
|
||
* interface User {
|
||
* readonly name: string
|
||
* }
|
||
*
|
||
* // Simulate an asynchronous authentication function
|
||
* declare const auth: () => Promise<User | null>
|
||
*
|
||
* const program = pipe(
|
||
* Effect.promise(() => auth()),
|
||
* // Use filterOrFail with a custom type guard to ensure user is not null
|
||
* Effect.filterOrFail(
|
||
* (user): user is User => user !== null, // Type guard
|
||
* () => new Error("Unauthorized")
|
||
* ),
|
||
* // 'user' now has the type `User` (not `User | null`)
|
||
* Effect.andThen((user) => user.name)
|
||
* )
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Filtering
|
||
*/
|
||
<A, B extends A>(refinement: Refinement<NoInfer<A>, B>): <E, R>(self: Effect<A, E, R>) => Effect<NoInfer<B>, Cause.NoSuchElementException | E, R>;
|
||
/**
|
||
* Filters an effect, failing with a custom error if the predicate fails.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function applies a predicate to the result of an effect. If the
|
||
* predicate evaluates to `false`, the effect fails with a custom error
|
||
* generated by the `orFailWith` function.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is useful for enforcing constraints and treating violations as
|
||
* recoverable errors.
|
||
*
|
||
* **Providing a Guard**
|
||
*
|
||
* In addition to the filtering capabilities discussed earlier, you have the
|
||
* option to further refine and narrow down the type of the success channel by
|
||
* providing a [user-defined type
|
||
* guard](https://www.typescriptlang.org/docs/handbook/2/narrowing.html#using-type-predicates).
|
||
* Let's explore this concept through an example:
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, pipe } from "effect"
|
||
*
|
||
* // Define a user interface
|
||
* interface User {
|
||
* readonly name: string
|
||
* }
|
||
*
|
||
* // Simulate an asynchronous authentication function
|
||
* declare const auth: () => Promise<User | null>
|
||
*
|
||
* const program = pipe(
|
||
* Effect.promise(() => auth()),
|
||
* // Use filterOrFail with a custom type guard to ensure user is not null
|
||
* Effect.filterOrFail(
|
||
* (user): user is User => user !== null, // Type guard
|
||
* () => new Error("Unauthorized")
|
||
* ),
|
||
* // 'user' now has the type `User` (not `User | null`)
|
||
* Effect.andThen((user) => user.name)
|
||
* )
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Filtering
|
||
*/
|
||
<A>(predicate: Predicate<NoInfer<A>>): <E, R>(self: Effect<A, E, R>) => Effect<A, Cause.NoSuchElementException | E, R>;
|
||
/**
|
||
* Filters an effect, failing with a custom error if the predicate fails.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function applies a predicate to the result of an effect. If the
|
||
* predicate evaluates to `false`, the effect fails with a custom error
|
||
* generated by the `orFailWith` function.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is useful for enforcing constraints and treating violations as
|
||
* recoverable errors.
|
||
*
|
||
* **Providing a Guard**
|
||
*
|
||
* In addition to the filtering capabilities discussed earlier, you have the
|
||
* option to further refine and narrow down the type of the success channel by
|
||
* providing a [user-defined type
|
||
* guard](https://www.typescriptlang.org/docs/handbook/2/narrowing.html#using-type-predicates).
|
||
* Let's explore this concept through an example:
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, pipe } from "effect"
|
||
*
|
||
* // Define a user interface
|
||
* interface User {
|
||
* readonly name: string
|
||
* }
|
||
*
|
||
* // Simulate an asynchronous authentication function
|
||
* declare const auth: () => Promise<User | null>
|
||
*
|
||
* const program = pipe(
|
||
* Effect.promise(() => auth()),
|
||
* // Use filterOrFail with a custom type guard to ensure user is not null
|
||
* Effect.filterOrFail(
|
||
* (user): user is User => user !== null, // Type guard
|
||
* () => new Error("Unauthorized")
|
||
* ),
|
||
* // 'user' now has the type `User` (not `User | null`)
|
||
* Effect.andThen((user) => user.name)
|
||
* )
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Filtering
|
||
*/
|
||
<A, E, R, B extends A>(self: Effect<A, E, R>, refinement: Refinement<A, B>): Effect<NoInfer<B>, E | Cause.NoSuchElementException, R>;
|
||
/**
|
||
* Filters an effect, failing with a custom error if the predicate fails.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function applies a predicate to the result of an effect. If the
|
||
* predicate evaluates to `false`, the effect fails with a custom error
|
||
* generated by the `orFailWith` function.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is useful for enforcing constraints and treating violations as
|
||
* recoverable errors.
|
||
*
|
||
* **Providing a Guard**
|
||
*
|
||
* In addition to the filtering capabilities discussed earlier, you have the
|
||
* option to further refine and narrow down the type of the success channel by
|
||
* providing a [user-defined type
|
||
* guard](https://www.typescriptlang.org/docs/handbook/2/narrowing.html#using-type-predicates).
|
||
* Let's explore this concept through an example:
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, pipe } from "effect"
|
||
*
|
||
* // Define a user interface
|
||
* interface User {
|
||
* readonly name: string
|
||
* }
|
||
*
|
||
* // Simulate an asynchronous authentication function
|
||
* declare const auth: () => Promise<User | null>
|
||
*
|
||
* const program = pipe(
|
||
* Effect.promise(() => auth()),
|
||
* // Use filterOrFail with a custom type guard to ensure user is not null
|
||
* Effect.filterOrFail(
|
||
* (user): user is User => user !== null, // Type guard
|
||
* () => new Error("Unauthorized")
|
||
* ),
|
||
* // 'user' now has the type `User` (not `User | null`)
|
||
* Effect.andThen((user) => user.name)
|
||
* )
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Filtering
|
||
*/
|
||
<A, E, R>(self: Effect<A, E, R>, predicate: Predicate<A>): Effect<A, E | Cause.NoSuchElementException, R>;
|
||
};
|
||
/**
|
||
* Filters an effect with an effectful predicate, falling back to an alternative
|
||
* effect if the predicate fails.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function applies a predicate to the result of an effect. If the
|
||
* predicate evaluates to `false`, the effect falls back to the `orElse`
|
||
* effect. The `orElse` effect can produce an alternative value or perform
|
||
* additional computations.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, pipe } from "effect"
|
||
*
|
||
* // Define a user interface
|
||
* interface User {
|
||
* readonly name: string
|
||
* }
|
||
*
|
||
* // Simulate an asynchronous authentication function
|
||
* declare const auth: () => Promise<User | null>
|
||
*
|
||
* const program = pipe(
|
||
* Effect.promise(() => auth()),
|
||
* // Use filterEffectOrElse with an effectful predicate
|
||
* Effect.filterEffectOrElse({
|
||
* predicate: (user) => Effect.succeed(user !== null),
|
||
* orElse: (user) => Effect.fail(new Error(`Unauthorized user: ${user}`))
|
||
* }),
|
||
* )
|
||
* ```
|
||
*
|
||
* @since 3.13.0
|
||
* @category Filtering
|
||
*/
|
||
export declare const filterEffectOrElse: {
|
||
/**
|
||
* Filters an effect with an effectful predicate, falling back to an alternative
|
||
* effect if the predicate fails.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function applies a predicate to the result of an effect. If the
|
||
* predicate evaluates to `false`, the effect falls back to the `orElse`
|
||
* effect. The `orElse` effect can produce an alternative value or perform
|
||
* additional computations.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, pipe } from "effect"
|
||
*
|
||
* // Define a user interface
|
||
* interface User {
|
||
* readonly name: string
|
||
* }
|
||
*
|
||
* // Simulate an asynchronous authentication function
|
||
* declare const auth: () => Promise<User | null>
|
||
*
|
||
* const program = pipe(
|
||
* Effect.promise(() => auth()),
|
||
* // Use filterEffectOrElse with an effectful predicate
|
||
* Effect.filterEffectOrElse({
|
||
* predicate: (user) => Effect.succeed(user !== null),
|
||
* orElse: (user) => Effect.fail(new Error(`Unauthorized user: ${user}`))
|
||
* }),
|
||
* )
|
||
* ```
|
||
*
|
||
* @since 3.13.0
|
||
* @category Filtering
|
||
*/
|
||
<A, E2, R2, A2, E3, R3>(options: {
|
||
readonly predicate: (a: NoInfer<A>) => Effect<boolean, E2, R2>;
|
||
readonly orElse: (a: NoInfer<A>) => Effect<A2, E3, R3>;
|
||
}): <E, R>(self: Effect<A, E, R>) => Effect<A | A2, E | E2 | E3, R | R2 | R3>;
|
||
/**
|
||
* Filters an effect with an effectful predicate, falling back to an alternative
|
||
* effect if the predicate fails.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function applies a predicate to the result of an effect. If the
|
||
* predicate evaluates to `false`, the effect falls back to the `orElse`
|
||
* effect. The `orElse` effect can produce an alternative value or perform
|
||
* additional computations.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, pipe } from "effect"
|
||
*
|
||
* // Define a user interface
|
||
* interface User {
|
||
* readonly name: string
|
||
* }
|
||
*
|
||
* // Simulate an asynchronous authentication function
|
||
* declare const auth: () => Promise<User | null>
|
||
*
|
||
* const program = pipe(
|
||
* Effect.promise(() => auth()),
|
||
* // Use filterEffectOrElse with an effectful predicate
|
||
* Effect.filterEffectOrElse({
|
||
* predicate: (user) => Effect.succeed(user !== null),
|
||
* orElse: (user) => Effect.fail(new Error(`Unauthorized user: ${user}`))
|
||
* }),
|
||
* )
|
||
* ```
|
||
*
|
||
* @since 3.13.0
|
||
* @category Filtering
|
||
*/
|
||
<A, E, R, E2, R2, A2, E3, R3>(self: Effect<A, E, R>, options: {
|
||
readonly predicate: (a: A) => Effect<boolean, E2, R2>;
|
||
readonly orElse: (a: A) => Effect<A2, E3, R3>;
|
||
}): Effect<A | A2, E | E2 | E3, R | R2 | R3>;
|
||
};
|
||
/**
|
||
* Filters an effect with an effectful predicate, failing with a custom error if the predicate fails.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function applies a predicate to the result of an effect. If the
|
||
* predicate evaluates to `false`, the effect fails with a custom error
|
||
* generated by the `orFailWith` function.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is useful for enforcing constraints and treating violations as
|
||
* recoverable errors.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, pipe } from "effect"
|
||
*
|
||
* // Define a user interface
|
||
* interface User {
|
||
* readonly name: string
|
||
* }
|
||
*
|
||
* // Simulate an asynchronous authentication function
|
||
* declare const auth: () => Promise<User | null>
|
||
*
|
||
* const program = pipe(
|
||
* Effect.promise(() => auth()),
|
||
* // Use filterEffectOrFail with an effectful predicate
|
||
* Effect.filterEffectOrFail({
|
||
* predicate: (user) => Effect.succeed(user !== null),
|
||
* orFailWith: () => new Error("Unauthorized")
|
||
* }),
|
||
* )
|
||
* ```
|
||
*
|
||
* @since 3.13.0
|
||
* @category Filtering
|
||
*/
|
||
export declare const filterEffectOrFail: {
|
||
/**
|
||
* Filters an effect with an effectful predicate, failing with a custom error if the predicate fails.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function applies a predicate to the result of an effect. If the
|
||
* predicate evaluates to `false`, the effect fails with a custom error
|
||
* generated by the `orFailWith` function.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is useful for enforcing constraints and treating violations as
|
||
* recoverable errors.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, pipe } from "effect"
|
||
*
|
||
* // Define a user interface
|
||
* interface User {
|
||
* readonly name: string
|
||
* }
|
||
*
|
||
* // Simulate an asynchronous authentication function
|
||
* declare const auth: () => Promise<User | null>
|
||
*
|
||
* const program = pipe(
|
||
* Effect.promise(() => auth()),
|
||
* // Use filterEffectOrFail with an effectful predicate
|
||
* Effect.filterEffectOrFail({
|
||
* predicate: (user) => Effect.succeed(user !== null),
|
||
* orFailWith: () => new Error("Unauthorized")
|
||
* }),
|
||
* )
|
||
* ```
|
||
*
|
||
* @since 3.13.0
|
||
* @category Filtering
|
||
*/
|
||
<A, E2, R2, E3>(options: {
|
||
readonly predicate: (a: NoInfer<A>) => Effect<boolean, E2, R2>;
|
||
readonly orFailWith: (a: NoInfer<A>) => E3;
|
||
}): <E, R>(self: Effect<A, E, R>) => Effect<A, E | E2 | E3, R | R2>;
|
||
/**
|
||
* Filters an effect with an effectful predicate, failing with a custom error if the predicate fails.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function applies a predicate to the result of an effect. If the
|
||
* predicate evaluates to `false`, the effect fails with a custom error
|
||
* generated by the `orFailWith` function.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is useful for enforcing constraints and treating violations as
|
||
* recoverable errors.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, pipe } from "effect"
|
||
*
|
||
* // Define a user interface
|
||
* interface User {
|
||
* readonly name: string
|
||
* }
|
||
*
|
||
* // Simulate an asynchronous authentication function
|
||
* declare const auth: () => Promise<User | null>
|
||
*
|
||
* const program = pipe(
|
||
* Effect.promise(() => auth()),
|
||
* // Use filterEffectOrFail with an effectful predicate
|
||
* Effect.filterEffectOrFail({
|
||
* predicate: (user) => Effect.succeed(user !== null),
|
||
* orFailWith: () => new Error("Unauthorized")
|
||
* }),
|
||
* )
|
||
* ```
|
||
*
|
||
* @since 3.13.0
|
||
* @category Filtering
|
||
*/
|
||
<A, E, R, E2, R2, E3>(self: Effect<A, E, R>, options: {
|
||
readonly predicate: (a: A) => Effect<boolean, E2, R2>;
|
||
readonly orFailWith: (a: A) => E3;
|
||
}): Effect<A, E | E2 | E3, R | R2>;
|
||
};
|
||
/**
|
||
* Executes an effect only if the condition is `false`.
|
||
*
|
||
* @see {@link unlessEffect} for a version that allows the condition to be an effect.
|
||
* @see {@link when} for a version that executes the effect when the condition is `true`.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Conditional Operators
|
||
*/
|
||
export declare const unless: {
|
||
/**
|
||
* Executes an effect only if the condition is `false`.
|
||
*
|
||
* @see {@link unlessEffect} for a version that allows the condition to be an effect.
|
||
* @see {@link when} for a version that executes the effect when the condition is `true`.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Conditional Operators
|
||
*/
|
||
(condition: LazyArg<boolean>): <A, E, R>(self: Effect<A, E, R>) => Effect<Option.Option<A>, E, R>;
|
||
/**
|
||
* Executes an effect only if the condition is `false`.
|
||
*
|
||
* @see {@link unlessEffect} for a version that allows the condition to be an effect.
|
||
* @see {@link when} for a version that executes the effect when the condition is `true`.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Conditional Operators
|
||
*/
|
||
<A, E, R>(self: Effect<A, E, R>, condition: LazyArg<boolean>): Effect<Option.Option<A>, E, R>;
|
||
};
|
||
/**
|
||
* Conditionally execute an effect based on the result of another effect.
|
||
*
|
||
* @see {@link unless} for a version that allows the condition to be a boolean.
|
||
* @see {@link whenEffect} for a version that executes the effect when the condition is `true`.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Conditional Operators
|
||
*/
|
||
export declare const unlessEffect: {
|
||
/**
|
||
* Conditionally execute an effect based on the result of another effect.
|
||
*
|
||
* @see {@link unless} for a version that allows the condition to be a boolean.
|
||
* @see {@link whenEffect} for a version that executes the effect when the condition is `true`.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Conditional Operators
|
||
*/
|
||
<E2, R2>(condition: Effect<boolean, E2, R2>): <A, E, R>(self: Effect<A, E, R>) => Effect<Option.Option<A>, E2 | E, R2 | R>;
|
||
/**
|
||
* Conditionally execute an effect based on the result of another effect.
|
||
*
|
||
* @see {@link unless} for a version that allows the condition to be a boolean.
|
||
* @see {@link whenEffect} for a version that executes the effect when the condition is `true`.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Conditional Operators
|
||
*/
|
||
<A, E, R, E2, R2>(self: Effect<A, E, R>, condition: Effect<boolean, E2, R2>): Effect<Option.Option<A>, E | E2, R | R2>;
|
||
};
|
||
/**
|
||
* Conditionally executes an effect based on a boolean condition.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to run an effect only if a given condition evaluates
|
||
* to `true`. If the condition is `true`, the effect is executed, and its result
|
||
* is wrapped in an `Option.some`. If the condition is `false`, the effect is
|
||
* skipped, and the result is `Option.none`.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This function is useful for scenarios where you need to dynamically decide
|
||
* whether to execute an effect based on runtime logic, while also representing
|
||
* the skipped case explicitly.
|
||
*
|
||
* **Example** (Conditional Effect Execution)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Option } from "effect"
|
||
*
|
||
* const validateWeightOption = (
|
||
* weight: number
|
||
* ): Effect.Effect<Option.Option<number>> =>
|
||
* // Conditionally execute the effect if the weight is non-negative
|
||
* Effect.succeed(weight).pipe(Effect.when(() => weight >= 0))
|
||
*
|
||
* // Run with a valid weight
|
||
* Effect.runPromise(validateWeightOption(100)).then(console.log)
|
||
* // Output:
|
||
* // {
|
||
* // _id: "Option",
|
||
* // _tag: "Some",
|
||
* // value: 100
|
||
* // }
|
||
*
|
||
* // Run with an invalid weight
|
||
* Effect.runPromise(validateWeightOption(-5)).then(console.log)
|
||
* // Output:
|
||
* // {
|
||
* // _id: "Option",
|
||
* // _tag: "None"
|
||
* // }
|
||
* ```
|
||
*
|
||
* @see {@link whenEffect} for a version that allows the condition to be an effect.
|
||
* @see {@link unless} for a version that executes the effect when the condition is `false`.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Conditional Operators
|
||
*/
|
||
export declare const when: {
|
||
/**
|
||
* Conditionally executes an effect based on a boolean condition.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to run an effect only if a given condition evaluates
|
||
* to `true`. If the condition is `true`, the effect is executed, and its result
|
||
* is wrapped in an `Option.some`. If the condition is `false`, the effect is
|
||
* skipped, and the result is `Option.none`.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This function is useful for scenarios where you need to dynamically decide
|
||
* whether to execute an effect based on runtime logic, while also representing
|
||
* the skipped case explicitly.
|
||
*
|
||
* **Example** (Conditional Effect Execution)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Option } from "effect"
|
||
*
|
||
* const validateWeightOption = (
|
||
* weight: number
|
||
* ): Effect.Effect<Option.Option<number>> =>
|
||
* // Conditionally execute the effect if the weight is non-negative
|
||
* Effect.succeed(weight).pipe(Effect.when(() => weight >= 0))
|
||
*
|
||
* // Run with a valid weight
|
||
* Effect.runPromise(validateWeightOption(100)).then(console.log)
|
||
* // Output:
|
||
* // {
|
||
* // _id: "Option",
|
||
* // _tag: "Some",
|
||
* // value: 100
|
||
* // }
|
||
*
|
||
* // Run with an invalid weight
|
||
* Effect.runPromise(validateWeightOption(-5)).then(console.log)
|
||
* // Output:
|
||
* // {
|
||
* // _id: "Option",
|
||
* // _tag: "None"
|
||
* // }
|
||
* ```
|
||
*
|
||
* @see {@link whenEffect} for a version that allows the condition to be an effect.
|
||
* @see {@link unless} for a version that executes the effect when the condition is `false`.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Conditional Operators
|
||
*/
|
||
(condition: LazyArg<boolean>): <A, E, R>(self: Effect<A, E, R>) => Effect<Option.Option<A>, E, R>;
|
||
/**
|
||
* Conditionally executes an effect based on a boolean condition.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to run an effect only if a given condition evaluates
|
||
* to `true`. If the condition is `true`, the effect is executed, and its result
|
||
* is wrapped in an `Option.some`. If the condition is `false`, the effect is
|
||
* skipped, and the result is `Option.none`.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This function is useful for scenarios where you need to dynamically decide
|
||
* whether to execute an effect based on runtime logic, while also representing
|
||
* the skipped case explicitly.
|
||
*
|
||
* **Example** (Conditional Effect Execution)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Option } from "effect"
|
||
*
|
||
* const validateWeightOption = (
|
||
* weight: number
|
||
* ): Effect.Effect<Option.Option<number>> =>
|
||
* // Conditionally execute the effect if the weight is non-negative
|
||
* Effect.succeed(weight).pipe(Effect.when(() => weight >= 0))
|
||
*
|
||
* // Run with a valid weight
|
||
* Effect.runPromise(validateWeightOption(100)).then(console.log)
|
||
* // Output:
|
||
* // {
|
||
* // _id: "Option",
|
||
* // _tag: "Some",
|
||
* // value: 100
|
||
* // }
|
||
*
|
||
* // Run with an invalid weight
|
||
* Effect.runPromise(validateWeightOption(-5)).then(console.log)
|
||
* // Output:
|
||
* // {
|
||
* // _id: "Option",
|
||
* // _tag: "None"
|
||
* // }
|
||
* ```
|
||
*
|
||
* @see {@link whenEffect} for a version that allows the condition to be an effect.
|
||
* @see {@link unless} for a version that executes the effect when the condition is `false`.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Conditional Operators
|
||
*/
|
||
<A, E, R>(self: Effect<A, E, R>, condition: LazyArg<boolean>): Effect<Option.Option<A>, E, R>;
|
||
};
|
||
/**
|
||
* Conditionally executes an effect based on the result of another effect.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to run an effect only if a conditional effect
|
||
* evaluating to a boolean resolves to `true`. If the conditional effect
|
||
* evaluates to `true`, the specified effect is executed, and its result is
|
||
* wrapped in `Option.some`. If the conditional effect evaluates to `false`, the
|
||
* effect is skipped, and the result is `Option.none`.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This function is particularly useful when the decision to execute an effect
|
||
* depends on the result of another effect, such as a random value, a
|
||
* user-provided input, or a network request result.
|
||
*
|
||
* **Example** (Using an Effect as a Condition)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Random } from "effect"
|
||
*
|
||
* const randomIntOption = Random.nextInt.pipe(
|
||
* Effect.whenEffect(Random.nextBoolean)
|
||
* )
|
||
*
|
||
* console.log(Effect.runSync(randomIntOption))
|
||
* // Example Output:
|
||
* // { _id: 'Option', _tag: 'Some', value: 8609104974198840 }
|
||
* ```
|
||
*
|
||
* @see {@link when} for a version that allows the condition to be a boolean.
|
||
* @see {@link unlessEffect} for a version that executes the effect when the condition is `false`.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Conditional Operators
|
||
*/
|
||
export declare const whenEffect: {
|
||
/**
|
||
* Conditionally executes an effect based on the result of another effect.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to run an effect only if a conditional effect
|
||
* evaluating to a boolean resolves to `true`. If the conditional effect
|
||
* evaluates to `true`, the specified effect is executed, and its result is
|
||
* wrapped in `Option.some`. If the conditional effect evaluates to `false`, the
|
||
* effect is skipped, and the result is `Option.none`.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This function is particularly useful when the decision to execute an effect
|
||
* depends on the result of another effect, such as a random value, a
|
||
* user-provided input, or a network request result.
|
||
*
|
||
* **Example** (Using an Effect as a Condition)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Random } from "effect"
|
||
*
|
||
* const randomIntOption = Random.nextInt.pipe(
|
||
* Effect.whenEffect(Random.nextBoolean)
|
||
* )
|
||
*
|
||
* console.log(Effect.runSync(randomIntOption))
|
||
* // Example Output:
|
||
* // { _id: 'Option', _tag: 'Some', value: 8609104974198840 }
|
||
* ```
|
||
*
|
||
* @see {@link when} for a version that allows the condition to be a boolean.
|
||
* @see {@link unlessEffect} for a version that executes the effect when the condition is `false`.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Conditional Operators
|
||
*/
|
||
<E, R>(condition: Effect<boolean, E, R>): <A, E2, R2>(effect: Effect<A, E2, R2>) => Effect<Option.Option<A>, E | E2, R | R2>;
|
||
/**
|
||
* Conditionally executes an effect based on the result of another effect.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to run an effect only if a conditional effect
|
||
* evaluating to a boolean resolves to `true`. If the conditional effect
|
||
* evaluates to `true`, the specified effect is executed, and its result is
|
||
* wrapped in `Option.some`. If the conditional effect evaluates to `false`, the
|
||
* effect is skipped, and the result is `Option.none`.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This function is particularly useful when the decision to execute an effect
|
||
* depends on the result of another effect, such as a random value, a
|
||
* user-provided input, or a network request result.
|
||
*
|
||
* **Example** (Using an Effect as a Condition)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Random } from "effect"
|
||
*
|
||
* const randomIntOption = Random.nextInt.pipe(
|
||
* Effect.whenEffect(Random.nextBoolean)
|
||
* )
|
||
*
|
||
* console.log(Effect.runSync(randomIntOption))
|
||
* // Example Output:
|
||
* // { _id: 'Option', _tag: 'Some', value: 8609104974198840 }
|
||
* ```
|
||
*
|
||
* @see {@link when} for a version that allows the condition to be a boolean.
|
||
* @see {@link unlessEffect} for a version that executes the effect when the condition is `false`.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Conditional Operators
|
||
*/
|
||
<A, E2, R2, E, R>(self: Effect<A, E2, R2>, condition: Effect<boolean, E, R>): Effect<Option.Option<A>, E2 | E, R2 | R>;
|
||
};
|
||
/**
|
||
* Executes an effect conditionally based on the value of a `FiberRef` that
|
||
* satisfies a predicate.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function enables you to execute an effect only when the value of a
|
||
* specified `FiberRef` meets a certain condition defined by a predicate. If the
|
||
* value satisfies the predicate, the effect is executed, and the result is
|
||
* wrapped in an `Option.some`. If the predicate is not satisfied, the effect is
|
||
* skipped, and the result is `Option.none`. In both cases, the current value of
|
||
* the `FiberRef` is included in the result.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Conditional Operators
|
||
*/
|
||
export declare const whenFiberRef: {
|
||
/**
|
||
* Executes an effect conditionally based on the value of a `FiberRef` that
|
||
* satisfies a predicate.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function enables you to execute an effect only when the value of a
|
||
* specified `FiberRef` meets a certain condition defined by a predicate. If the
|
||
* value satisfies the predicate, the effect is executed, and the result is
|
||
* wrapped in an `Option.some`. If the predicate is not satisfied, the effect is
|
||
* skipped, and the result is `Option.none`. In both cases, the current value of
|
||
* the `FiberRef` is included in the result.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Conditional Operators
|
||
*/
|
||
<S>(fiberRef: FiberRef.FiberRef<S>, predicate: Predicate<S>): <A, E, R>(self: Effect<A, E, R>) => Effect<[S, Option.Option<A>], E, R>;
|
||
/**
|
||
* Executes an effect conditionally based on the value of a `FiberRef` that
|
||
* satisfies a predicate.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function enables you to execute an effect only when the value of a
|
||
* specified `FiberRef` meets a certain condition defined by a predicate. If the
|
||
* value satisfies the predicate, the effect is executed, and the result is
|
||
* wrapped in an `Option.some`. If the predicate is not satisfied, the effect is
|
||
* skipped, and the result is `Option.none`. In both cases, the current value of
|
||
* the `FiberRef` is included in the result.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Conditional Operators
|
||
*/
|
||
<A, E, R, S>(self: Effect<A, E, R>, fiberRef: FiberRef.FiberRef<S>, predicate: Predicate<S>): Effect<[S, Option.Option<A>], E, R>;
|
||
};
|
||
/**
|
||
* Executes an effect conditionally based on the value of a `Ref` that satisfies
|
||
* a predicate.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to execute an effect only when the value of a
|
||
* specified `Ref` meets a condition defined by a predicate. If the value
|
||
* satisfies the predicate, the effect is executed, and the result is wrapped in
|
||
* an `Option.some`. If the predicate is not satisfied, the effect is skipped,
|
||
* and the result is `Option.none`. In both cases, the current value of the
|
||
* `Ref` is included in the result.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Conditional Operators
|
||
*/
|
||
export declare const whenRef: {
|
||
/**
|
||
* Executes an effect conditionally based on the value of a `Ref` that satisfies
|
||
* a predicate.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to execute an effect only when the value of a
|
||
* specified `Ref` meets a condition defined by a predicate. If the value
|
||
* satisfies the predicate, the effect is executed, and the result is wrapped in
|
||
* an `Option.some`. If the predicate is not satisfied, the effect is skipped,
|
||
* and the result is `Option.none`. In both cases, the current value of the
|
||
* `Ref` is included in the result.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Conditional Operators
|
||
*/
|
||
<S>(ref: Ref.Ref<S>, predicate: Predicate<S>): <A, E, R>(self: Effect<A, E, R>) => Effect<[S, Option.Option<A>], E, R>;
|
||
/**
|
||
* Executes an effect conditionally based on the value of a `Ref` that satisfies
|
||
* a predicate.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to execute an effect only when the value of a
|
||
* specified `Ref` meets a condition defined by a predicate. If the value
|
||
* satisfies the predicate, the effect is executed, and the result is wrapped in
|
||
* an `Option.some`. If the predicate is not satisfied, the effect is skipped,
|
||
* and the result is `Option.none`. In both cases, the current value of the
|
||
* `Ref` is included in the result.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Conditional Operators
|
||
*/
|
||
<A, E, R, S>(self: Effect<A, E, R>, ref: Ref.Ref<S>, predicate: Predicate<S>): Effect<[S, Option.Option<A>], E, R>;
|
||
};
|
||
/**
|
||
* Chains effects to produce new `Effect` instances, useful for combining
|
||
* operations that depend on previous results.
|
||
*
|
||
* **Syntax**
|
||
*
|
||
* ```ts skip-type-checking
|
||
* const flatMappedEffect = pipe(myEffect, Effect.flatMap(transformation))
|
||
* // or
|
||
* const flatMappedEffect = Effect.flatMap(myEffect, transformation)
|
||
* // or
|
||
* const flatMappedEffect = myEffect.pipe(Effect.flatMap(transformation))
|
||
* ```
|
||
*
|
||
* **Details**
|
||
*
|
||
* `flatMap` lets you sequence effects so that the result of one effect can be
|
||
* used in the next step. It is similar to `flatMap` used with arrays but works
|
||
* specifically with `Effect` instances, allowing you to avoid deeply nested
|
||
* effect structures.
|
||
*
|
||
* Since effects are immutable, `flatMap` always returns a new effect instead of
|
||
* changing the original one.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use `flatMap` when you need to chain multiple effects, ensuring that each
|
||
* step produces a new `Effect` while flattening any nested effects that may
|
||
* occur.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { pipe, Effect } from "effect"
|
||
*
|
||
* // Function to apply a discount safely to a transaction amount
|
||
* const applyDiscount = (
|
||
* total: number,
|
||
* discountRate: number
|
||
* ): Effect.Effect<number, Error> =>
|
||
* discountRate === 0
|
||
* ? Effect.fail(new Error("Discount rate cannot be zero"))
|
||
* : Effect.succeed(total - (total * discountRate) / 100)
|
||
*
|
||
* // Simulated asynchronous task to fetch a transaction amount from database
|
||
* const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
|
||
*
|
||
* // Chaining the fetch and discount application using `flatMap`
|
||
* const finalAmount = pipe(
|
||
* fetchTransactionAmount,
|
||
* Effect.flatMap((amount) => applyDiscount(amount, 5))
|
||
* )
|
||
*
|
||
* Effect.runPromise(finalAmount).then(console.log)
|
||
* // Output: 95
|
||
* ```
|
||
*
|
||
* @see {@link tap} for a version that ignores the result of the effect.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Sequencing
|
||
*/
|
||
export declare const flatMap: {
|
||
/**
|
||
* Chains effects to produce new `Effect` instances, useful for combining
|
||
* operations that depend on previous results.
|
||
*
|
||
* **Syntax**
|
||
*
|
||
* ```ts skip-type-checking
|
||
* const flatMappedEffect = pipe(myEffect, Effect.flatMap(transformation))
|
||
* // or
|
||
* const flatMappedEffect = Effect.flatMap(myEffect, transformation)
|
||
* // or
|
||
* const flatMappedEffect = myEffect.pipe(Effect.flatMap(transformation))
|
||
* ```
|
||
*
|
||
* **Details**
|
||
*
|
||
* `flatMap` lets you sequence effects so that the result of one effect can be
|
||
* used in the next step. It is similar to `flatMap` used with arrays but works
|
||
* specifically with `Effect` instances, allowing you to avoid deeply nested
|
||
* effect structures.
|
||
*
|
||
* Since effects are immutable, `flatMap` always returns a new effect instead of
|
||
* changing the original one.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use `flatMap` when you need to chain multiple effects, ensuring that each
|
||
* step produces a new `Effect` while flattening any nested effects that may
|
||
* occur.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { pipe, Effect } from "effect"
|
||
*
|
||
* // Function to apply a discount safely to a transaction amount
|
||
* const applyDiscount = (
|
||
* total: number,
|
||
* discountRate: number
|
||
* ): Effect.Effect<number, Error> =>
|
||
* discountRate === 0
|
||
* ? Effect.fail(new Error("Discount rate cannot be zero"))
|
||
* : Effect.succeed(total - (total * discountRate) / 100)
|
||
*
|
||
* // Simulated asynchronous task to fetch a transaction amount from database
|
||
* const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
|
||
*
|
||
* // Chaining the fetch and discount application using `flatMap`
|
||
* const finalAmount = pipe(
|
||
* fetchTransactionAmount,
|
||
* Effect.flatMap((amount) => applyDiscount(amount, 5))
|
||
* )
|
||
*
|
||
* Effect.runPromise(finalAmount).then(console.log)
|
||
* // Output: 95
|
||
* ```
|
||
*
|
||
* @see {@link tap} for a version that ignores the result of the effect.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Sequencing
|
||
*/
|
||
<A, B, E1, R1>(f: (a: A) => Effect<B, E1, R1>): <E, R>(self: Effect<A, E, R>) => Effect<B, E1 | E, R1 | R>;
|
||
/**
|
||
* Chains effects to produce new `Effect` instances, useful for combining
|
||
* operations that depend on previous results.
|
||
*
|
||
* **Syntax**
|
||
*
|
||
* ```ts skip-type-checking
|
||
* const flatMappedEffect = pipe(myEffect, Effect.flatMap(transformation))
|
||
* // or
|
||
* const flatMappedEffect = Effect.flatMap(myEffect, transformation)
|
||
* // or
|
||
* const flatMappedEffect = myEffect.pipe(Effect.flatMap(transformation))
|
||
* ```
|
||
*
|
||
* **Details**
|
||
*
|
||
* `flatMap` lets you sequence effects so that the result of one effect can be
|
||
* used in the next step. It is similar to `flatMap` used with arrays but works
|
||
* specifically with `Effect` instances, allowing you to avoid deeply nested
|
||
* effect structures.
|
||
*
|
||
* Since effects are immutable, `flatMap` always returns a new effect instead of
|
||
* changing the original one.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use `flatMap` when you need to chain multiple effects, ensuring that each
|
||
* step produces a new `Effect` while flattening any nested effects that may
|
||
* occur.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { pipe, Effect } from "effect"
|
||
*
|
||
* // Function to apply a discount safely to a transaction amount
|
||
* const applyDiscount = (
|
||
* total: number,
|
||
* discountRate: number
|
||
* ): Effect.Effect<number, Error> =>
|
||
* discountRate === 0
|
||
* ? Effect.fail(new Error("Discount rate cannot be zero"))
|
||
* : Effect.succeed(total - (total * discountRate) / 100)
|
||
*
|
||
* // Simulated asynchronous task to fetch a transaction amount from database
|
||
* const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
|
||
*
|
||
* // Chaining the fetch and discount application using `flatMap`
|
||
* const finalAmount = pipe(
|
||
* fetchTransactionAmount,
|
||
* Effect.flatMap((amount) => applyDiscount(amount, 5))
|
||
* )
|
||
*
|
||
* Effect.runPromise(finalAmount).then(console.log)
|
||
* // Output: 95
|
||
* ```
|
||
*
|
||
* @see {@link tap} for a version that ignores the result of the effect.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Sequencing
|
||
*/
|
||
<A, E, R, B, E1, R1>(self: Effect<A, E, R>, f: (a: A) => Effect<B, E1, R1>): Effect<B, E | E1, R | R1>;
|
||
};
|
||
/**
|
||
* Chains two actions, where the second action can depend on the result of the
|
||
* first.
|
||
*
|
||
* **Syntax**
|
||
*
|
||
* ```ts skip-type-checking
|
||
* const transformedEffect = pipe(myEffect, Effect.andThen(anotherEffect))
|
||
* // or
|
||
* const transformedEffect = Effect.andThen(myEffect, anotherEffect)
|
||
* // or
|
||
* const transformedEffect = myEffect.pipe(Effect.andThen(anotherEffect))
|
||
* ```
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use `andThen` when you need to run multiple actions in sequence, with the
|
||
* second action depending on the result of the first. This is useful for
|
||
* combining effects or handling computations that must happen in order.
|
||
*
|
||
* **Details**
|
||
*
|
||
* The second action can be:
|
||
*
|
||
* - A constant value (similar to {@link as})
|
||
* - A function returning a value (similar to {@link map})
|
||
* - A `Promise`
|
||
* - A function returning a `Promise`
|
||
* - An `Effect`
|
||
* - A function returning an `Effect` (similar to {@link flatMap})
|
||
*
|
||
* **Note:** `andThen` works well with both `Option` and `Either` types,
|
||
* treating them as effects.
|
||
*
|
||
* **Example** (Applying a Discount Based on Fetched Amount)
|
||
*
|
||
* ```ts
|
||
* import { pipe, Effect } from "effect"
|
||
*
|
||
* // Function to apply a discount safely to a transaction amount
|
||
* const applyDiscount = (
|
||
* total: number,
|
||
* discountRate: number
|
||
* ): Effect.Effect<number, Error> =>
|
||
* discountRate === 0
|
||
* ? Effect.fail(new Error("Discount rate cannot be zero"))
|
||
* : Effect.succeed(total - (total * discountRate) / 100)
|
||
*
|
||
* // Simulated asynchronous task to fetch a transaction amount from database
|
||
* const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
|
||
*
|
||
* // Using Effect.map and Effect.flatMap
|
||
* const result1 = pipe(
|
||
* fetchTransactionAmount,
|
||
* Effect.map((amount) => amount * 2),
|
||
* Effect.flatMap((amount) => applyDiscount(amount, 5))
|
||
* )
|
||
*
|
||
* Effect.runPromise(result1).then(console.log)
|
||
* // Output: 190
|
||
*
|
||
* // Using Effect.andThen
|
||
* const result2 = pipe(
|
||
* fetchTransactionAmount,
|
||
* Effect.andThen((amount) => amount * 2),
|
||
* Effect.andThen((amount) => applyDiscount(amount, 5))
|
||
* )
|
||
*
|
||
* Effect.runPromise(result2).then(console.log)
|
||
* // Output: 190
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Sequencing
|
||
*/
|
||
export declare const andThen: {
|
||
/**
|
||
* Chains two actions, where the second action can depend on the result of the
|
||
* first.
|
||
*
|
||
* **Syntax**
|
||
*
|
||
* ```ts skip-type-checking
|
||
* const transformedEffect = pipe(myEffect, Effect.andThen(anotherEffect))
|
||
* // or
|
||
* const transformedEffect = Effect.andThen(myEffect, anotherEffect)
|
||
* // or
|
||
* const transformedEffect = myEffect.pipe(Effect.andThen(anotherEffect))
|
||
* ```
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use `andThen` when you need to run multiple actions in sequence, with the
|
||
* second action depending on the result of the first. This is useful for
|
||
* combining effects or handling computations that must happen in order.
|
||
*
|
||
* **Details**
|
||
*
|
||
* The second action can be:
|
||
*
|
||
* - A constant value (similar to {@link as})
|
||
* - A function returning a value (similar to {@link map})
|
||
* - A `Promise`
|
||
* - A function returning a `Promise`
|
||
* - An `Effect`
|
||
* - A function returning an `Effect` (similar to {@link flatMap})
|
||
*
|
||
* **Note:** `andThen` works well with both `Option` and `Either` types,
|
||
* treating them as effects.
|
||
*
|
||
* **Example** (Applying a Discount Based on Fetched Amount)
|
||
*
|
||
* ```ts
|
||
* import { pipe, Effect } from "effect"
|
||
*
|
||
* // Function to apply a discount safely to a transaction amount
|
||
* const applyDiscount = (
|
||
* total: number,
|
||
* discountRate: number
|
||
* ): Effect.Effect<number, Error> =>
|
||
* discountRate === 0
|
||
* ? Effect.fail(new Error("Discount rate cannot be zero"))
|
||
* : Effect.succeed(total - (total * discountRate) / 100)
|
||
*
|
||
* // Simulated asynchronous task to fetch a transaction amount from database
|
||
* const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
|
||
*
|
||
* // Using Effect.map and Effect.flatMap
|
||
* const result1 = pipe(
|
||
* fetchTransactionAmount,
|
||
* Effect.map((amount) => amount * 2),
|
||
* Effect.flatMap((amount) => applyDiscount(amount, 5))
|
||
* )
|
||
*
|
||
* Effect.runPromise(result1).then(console.log)
|
||
* // Output: 190
|
||
*
|
||
* // Using Effect.andThen
|
||
* const result2 = pipe(
|
||
* fetchTransactionAmount,
|
||
* Effect.andThen((amount) => amount * 2),
|
||
* Effect.andThen((amount) => applyDiscount(amount, 5))
|
||
* )
|
||
*
|
||
* Effect.runPromise(result2).then(console.log)
|
||
* // Output: 190
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Sequencing
|
||
*/
|
||
<A, X>(f: (a: NoInfer<A>) => X): <E, R>(self: Effect<A, E, R>) => [X] extends [Effect<infer A1, infer E1, infer R1>] ? Effect<A1, E | E1, R | R1> : [X] extends [PromiseLike<infer A1>] ? Effect<A1, E | Cause.UnknownException, R> : Effect<X, E, R>;
|
||
/**
|
||
* Chains two actions, where the second action can depend on the result of the
|
||
* first.
|
||
*
|
||
* **Syntax**
|
||
*
|
||
* ```ts skip-type-checking
|
||
* const transformedEffect = pipe(myEffect, Effect.andThen(anotherEffect))
|
||
* // or
|
||
* const transformedEffect = Effect.andThen(myEffect, anotherEffect)
|
||
* // or
|
||
* const transformedEffect = myEffect.pipe(Effect.andThen(anotherEffect))
|
||
* ```
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use `andThen` when you need to run multiple actions in sequence, with the
|
||
* second action depending on the result of the first. This is useful for
|
||
* combining effects or handling computations that must happen in order.
|
||
*
|
||
* **Details**
|
||
*
|
||
* The second action can be:
|
||
*
|
||
* - A constant value (similar to {@link as})
|
||
* - A function returning a value (similar to {@link map})
|
||
* - A `Promise`
|
||
* - A function returning a `Promise`
|
||
* - An `Effect`
|
||
* - A function returning an `Effect` (similar to {@link flatMap})
|
||
*
|
||
* **Note:** `andThen` works well with both `Option` and `Either` types,
|
||
* treating them as effects.
|
||
*
|
||
* **Example** (Applying a Discount Based on Fetched Amount)
|
||
*
|
||
* ```ts
|
||
* import { pipe, Effect } from "effect"
|
||
*
|
||
* // Function to apply a discount safely to a transaction amount
|
||
* const applyDiscount = (
|
||
* total: number,
|
||
* discountRate: number
|
||
* ): Effect.Effect<number, Error> =>
|
||
* discountRate === 0
|
||
* ? Effect.fail(new Error("Discount rate cannot be zero"))
|
||
* : Effect.succeed(total - (total * discountRate) / 100)
|
||
*
|
||
* // Simulated asynchronous task to fetch a transaction amount from database
|
||
* const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
|
||
*
|
||
* // Using Effect.map and Effect.flatMap
|
||
* const result1 = pipe(
|
||
* fetchTransactionAmount,
|
||
* Effect.map((amount) => amount * 2),
|
||
* Effect.flatMap((amount) => applyDiscount(amount, 5))
|
||
* )
|
||
*
|
||
* Effect.runPromise(result1).then(console.log)
|
||
* // Output: 190
|
||
*
|
||
* // Using Effect.andThen
|
||
* const result2 = pipe(
|
||
* fetchTransactionAmount,
|
||
* Effect.andThen((amount) => amount * 2),
|
||
* Effect.andThen((amount) => applyDiscount(amount, 5))
|
||
* )
|
||
*
|
||
* Effect.runPromise(result2).then(console.log)
|
||
* // Output: 190
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Sequencing
|
||
*/
|
||
<X>(f: NotFunction<X>): <A, E, R>(self: Effect<A, E, R>) => [X] extends [Effect<infer A1, infer E1, infer R1>] ? Effect<A1, E | E1, R | R1> : [X] extends [PromiseLike<infer A1>] ? Effect<A1, E | Cause.UnknownException, R> : Effect<X, E, R>;
|
||
/**
|
||
* Chains two actions, where the second action can depend on the result of the
|
||
* first.
|
||
*
|
||
* **Syntax**
|
||
*
|
||
* ```ts skip-type-checking
|
||
* const transformedEffect = pipe(myEffect, Effect.andThen(anotherEffect))
|
||
* // or
|
||
* const transformedEffect = Effect.andThen(myEffect, anotherEffect)
|
||
* // or
|
||
* const transformedEffect = myEffect.pipe(Effect.andThen(anotherEffect))
|
||
* ```
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use `andThen` when you need to run multiple actions in sequence, with the
|
||
* second action depending on the result of the first. This is useful for
|
||
* combining effects or handling computations that must happen in order.
|
||
*
|
||
* **Details**
|
||
*
|
||
* The second action can be:
|
||
*
|
||
* - A constant value (similar to {@link as})
|
||
* - A function returning a value (similar to {@link map})
|
||
* - A `Promise`
|
||
* - A function returning a `Promise`
|
||
* - An `Effect`
|
||
* - A function returning an `Effect` (similar to {@link flatMap})
|
||
*
|
||
* **Note:** `andThen` works well with both `Option` and `Either` types,
|
||
* treating them as effects.
|
||
*
|
||
* **Example** (Applying a Discount Based on Fetched Amount)
|
||
*
|
||
* ```ts
|
||
* import { pipe, Effect } from "effect"
|
||
*
|
||
* // Function to apply a discount safely to a transaction amount
|
||
* const applyDiscount = (
|
||
* total: number,
|
||
* discountRate: number
|
||
* ): Effect.Effect<number, Error> =>
|
||
* discountRate === 0
|
||
* ? Effect.fail(new Error("Discount rate cannot be zero"))
|
||
* : Effect.succeed(total - (total * discountRate) / 100)
|
||
*
|
||
* // Simulated asynchronous task to fetch a transaction amount from database
|
||
* const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
|
||
*
|
||
* // Using Effect.map and Effect.flatMap
|
||
* const result1 = pipe(
|
||
* fetchTransactionAmount,
|
||
* Effect.map((amount) => amount * 2),
|
||
* Effect.flatMap((amount) => applyDiscount(amount, 5))
|
||
* )
|
||
*
|
||
* Effect.runPromise(result1).then(console.log)
|
||
* // Output: 190
|
||
*
|
||
* // Using Effect.andThen
|
||
* const result2 = pipe(
|
||
* fetchTransactionAmount,
|
||
* Effect.andThen((amount) => amount * 2),
|
||
* Effect.andThen((amount) => applyDiscount(amount, 5))
|
||
* )
|
||
*
|
||
* Effect.runPromise(result2).then(console.log)
|
||
* // Output: 190
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Sequencing
|
||
*/
|
||
<A, E, R, X>(self: Effect<A, E, R>, f: (a: NoInfer<A>) => X): [X] extends [Effect<infer A1, infer E1, infer R1>] ? Effect<A1, E | E1, R | R1> : [X] extends [PromiseLike<infer A1>] ? Effect<A1, E | Cause.UnknownException, R> : Effect<X, E, R>;
|
||
/**
|
||
* Chains two actions, where the second action can depend on the result of the
|
||
* first.
|
||
*
|
||
* **Syntax**
|
||
*
|
||
* ```ts skip-type-checking
|
||
* const transformedEffect = pipe(myEffect, Effect.andThen(anotherEffect))
|
||
* // or
|
||
* const transformedEffect = Effect.andThen(myEffect, anotherEffect)
|
||
* // or
|
||
* const transformedEffect = myEffect.pipe(Effect.andThen(anotherEffect))
|
||
* ```
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use `andThen` when you need to run multiple actions in sequence, with the
|
||
* second action depending on the result of the first. This is useful for
|
||
* combining effects or handling computations that must happen in order.
|
||
*
|
||
* **Details**
|
||
*
|
||
* The second action can be:
|
||
*
|
||
* - A constant value (similar to {@link as})
|
||
* - A function returning a value (similar to {@link map})
|
||
* - A `Promise`
|
||
* - A function returning a `Promise`
|
||
* - An `Effect`
|
||
* - A function returning an `Effect` (similar to {@link flatMap})
|
||
*
|
||
* **Note:** `andThen` works well with both `Option` and `Either` types,
|
||
* treating them as effects.
|
||
*
|
||
* **Example** (Applying a Discount Based on Fetched Amount)
|
||
*
|
||
* ```ts
|
||
* import { pipe, Effect } from "effect"
|
||
*
|
||
* // Function to apply a discount safely to a transaction amount
|
||
* const applyDiscount = (
|
||
* total: number,
|
||
* discountRate: number
|
||
* ): Effect.Effect<number, Error> =>
|
||
* discountRate === 0
|
||
* ? Effect.fail(new Error("Discount rate cannot be zero"))
|
||
* : Effect.succeed(total - (total * discountRate) / 100)
|
||
*
|
||
* // Simulated asynchronous task to fetch a transaction amount from database
|
||
* const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
|
||
*
|
||
* // Using Effect.map and Effect.flatMap
|
||
* const result1 = pipe(
|
||
* fetchTransactionAmount,
|
||
* Effect.map((amount) => amount * 2),
|
||
* Effect.flatMap((amount) => applyDiscount(amount, 5))
|
||
* )
|
||
*
|
||
* Effect.runPromise(result1).then(console.log)
|
||
* // Output: 190
|
||
*
|
||
* // Using Effect.andThen
|
||
* const result2 = pipe(
|
||
* fetchTransactionAmount,
|
||
* Effect.andThen((amount) => amount * 2),
|
||
* Effect.andThen((amount) => applyDiscount(amount, 5))
|
||
* )
|
||
*
|
||
* Effect.runPromise(result2).then(console.log)
|
||
* // Output: 190
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Sequencing
|
||
*/
|
||
<A, E, R, X>(self: Effect<A, E, R>, f: NotFunction<X>): [X] extends [Effect<infer A1, infer E1, infer R1>] ? Effect<A1, E | E1, R | R1> : [X] extends [PromiseLike<infer A1>] ? Effect<A1, E | Cause.UnknownException, R> : Effect<X, E, R>;
|
||
};
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Sequencing
|
||
*/
|
||
export declare const flatten: <A, E1, R1, E, R>(self: Effect<Effect<A, E1, R1>, E, R>) => Effect<A, E | E1, R | R1>;
|
||
/**
|
||
* Races two effects and returns the result of the first successful one.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function takes two effects and runs them concurrently. The first effect
|
||
* that successfully completes will determine the result of the race, and the
|
||
* other effect will be interrupted.
|
||
*
|
||
* If neither effect succeeds, the function will fail with a `Cause`
|
||
* containing all the errors.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is useful when you want to run two effects concurrently, but only care
|
||
* about the first one to succeed. It is commonly used in cases like timeouts,
|
||
* retries, or when you want to optimize for the faster response without
|
||
* worrying about the other effect.
|
||
*
|
||
* **Handling Success or Failure with Either**
|
||
*
|
||
* If you want to handle the result of whichever task completes first, whether
|
||
* it succeeds or fails, you can use the `Effect.either` function. This function
|
||
* wraps the result in an `Either` type, allowing you to see if the result
|
||
* was a success (`Right`) or a failure (`Left`).
|
||
*
|
||
* **Example** (Both Tasks Succeed)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* const task1 = Effect.succeed("task1").pipe(
|
||
* Effect.delay("200 millis"),
|
||
* Effect.tap(Console.log("task1 done")),
|
||
* Effect.onInterrupt(() => Console.log("task1 interrupted"))
|
||
* )
|
||
* const task2 = Effect.succeed("task2").pipe(
|
||
* Effect.delay("100 millis"),
|
||
* Effect.tap(Console.log("task2 done")),
|
||
* Effect.onInterrupt(() => Console.log("task2 interrupted"))
|
||
* )
|
||
*
|
||
* const program = Effect.race(task1, task2)
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output:
|
||
* // task1 done
|
||
* // task2 interrupted
|
||
* ```
|
||
*
|
||
* **Example** (One Task Fails, One Succeeds)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* const task1 = Effect.fail("task1").pipe(
|
||
* Effect.delay("100 millis"),
|
||
* Effect.tap(Console.log("task1 done")),
|
||
* Effect.onInterrupt(() => Console.log("task1 interrupted"))
|
||
* )
|
||
* const task2 = Effect.succeed("task2").pipe(
|
||
* Effect.delay("200 millis"),
|
||
* Effect.tap(Console.log("task2 done")),
|
||
* Effect.onInterrupt(() => Console.log("task2 interrupted"))
|
||
* )
|
||
*
|
||
* const program = Effect.race(task1, task2)
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output:
|
||
* // task2 done
|
||
* ```
|
||
*
|
||
* **Example** (Both Tasks Fail)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* const task1 = Effect.fail("task1").pipe(
|
||
* Effect.delay("100 millis"),
|
||
* Effect.tap(Console.log("task1 done")),
|
||
* Effect.onInterrupt(() => Console.log("task1 interrupted"))
|
||
* )
|
||
* const task2 = Effect.fail("task2").pipe(
|
||
* Effect.delay("200 millis"),
|
||
* Effect.tap(Console.log("task2 done")),
|
||
* Effect.onInterrupt(() => Console.log("task2 interrupted"))
|
||
* )
|
||
*
|
||
* const program = Effect.race(task1, task2)
|
||
*
|
||
* Effect.runPromiseExit(program).then(console.log)
|
||
* // Output:
|
||
* // {
|
||
* // _id: 'Exit',
|
||
* // _tag: 'Failure',
|
||
* // cause: {
|
||
* // _id: 'Cause',
|
||
* // _tag: 'Parallel',
|
||
* // left: { _id: 'Cause', _tag: 'Fail', failure: 'task1' },
|
||
* // right: { _id: 'Cause', _tag: 'Fail', failure: 'task2' }
|
||
* // }
|
||
* // }
|
||
* ```
|
||
*
|
||
* **Example** (Handling Success or Failure with Either)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* const task1 = Effect.fail("task1").pipe(
|
||
* Effect.delay("100 millis"),
|
||
* Effect.tap(Console.log("task1 done")),
|
||
* Effect.onInterrupt(() => Console.log("task1 interrupted"))
|
||
* )
|
||
* const task2 = Effect.succeed("task2").pipe(
|
||
* Effect.delay("200 millis"),
|
||
* Effect.tap(Console.log("task2 done")),
|
||
* Effect.onInterrupt(() => Console.log("task2 interrupted"))
|
||
* )
|
||
*
|
||
* // Run both tasks concurrently, wrapping the result
|
||
* // in Either to capture success or failure
|
||
* const program = Effect.race(Effect.either(task1), Effect.either(task2))
|
||
*
|
||
* Effect.runPromise(program).then(console.log)
|
||
* // Output:
|
||
* // task2 interrupted
|
||
* // { _id: 'Either', _tag: 'Left', left: 'task1' }
|
||
* ```
|
||
*
|
||
* @see {@link raceAll} for a version that handles multiple effects.
|
||
* @see {@link raceFirst} for a version that returns the result of the first effect to complete.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Racing
|
||
*/
|
||
export declare const race: {
|
||
/**
|
||
* Races two effects and returns the result of the first successful one.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function takes two effects and runs them concurrently. The first effect
|
||
* that successfully completes will determine the result of the race, and the
|
||
* other effect will be interrupted.
|
||
*
|
||
* If neither effect succeeds, the function will fail with a `Cause`
|
||
* containing all the errors.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is useful when you want to run two effects concurrently, but only care
|
||
* about the first one to succeed. It is commonly used in cases like timeouts,
|
||
* retries, or when you want to optimize for the faster response without
|
||
* worrying about the other effect.
|
||
*
|
||
* **Handling Success or Failure with Either**
|
||
*
|
||
* If you want to handle the result of whichever task completes first, whether
|
||
* it succeeds or fails, you can use the `Effect.either` function. This function
|
||
* wraps the result in an `Either` type, allowing you to see if the result
|
||
* was a success (`Right`) or a failure (`Left`).
|
||
*
|
||
* **Example** (Both Tasks Succeed)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* const task1 = Effect.succeed("task1").pipe(
|
||
* Effect.delay("200 millis"),
|
||
* Effect.tap(Console.log("task1 done")),
|
||
* Effect.onInterrupt(() => Console.log("task1 interrupted"))
|
||
* )
|
||
* const task2 = Effect.succeed("task2").pipe(
|
||
* Effect.delay("100 millis"),
|
||
* Effect.tap(Console.log("task2 done")),
|
||
* Effect.onInterrupt(() => Console.log("task2 interrupted"))
|
||
* )
|
||
*
|
||
* const program = Effect.race(task1, task2)
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output:
|
||
* // task1 done
|
||
* // task2 interrupted
|
||
* ```
|
||
*
|
||
* **Example** (One Task Fails, One Succeeds)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* const task1 = Effect.fail("task1").pipe(
|
||
* Effect.delay("100 millis"),
|
||
* Effect.tap(Console.log("task1 done")),
|
||
* Effect.onInterrupt(() => Console.log("task1 interrupted"))
|
||
* )
|
||
* const task2 = Effect.succeed("task2").pipe(
|
||
* Effect.delay("200 millis"),
|
||
* Effect.tap(Console.log("task2 done")),
|
||
* Effect.onInterrupt(() => Console.log("task2 interrupted"))
|
||
* )
|
||
*
|
||
* const program = Effect.race(task1, task2)
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output:
|
||
* // task2 done
|
||
* ```
|
||
*
|
||
* **Example** (Both Tasks Fail)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* const task1 = Effect.fail("task1").pipe(
|
||
* Effect.delay("100 millis"),
|
||
* Effect.tap(Console.log("task1 done")),
|
||
* Effect.onInterrupt(() => Console.log("task1 interrupted"))
|
||
* )
|
||
* const task2 = Effect.fail("task2").pipe(
|
||
* Effect.delay("200 millis"),
|
||
* Effect.tap(Console.log("task2 done")),
|
||
* Effect.onInterrupt(() => Console.log("task2 interrupted"))
|
||
* )
|
||
*
|
||
* const program = Effect.race(task1, task2)
|
||
*
|
||
* Effect.runPromiseExit(program).then(console.log)
|
||
* // Output:
|
||
* // {
|
||
* // _id: 'Exit',
|
||
* // _tag: 'Failure',
|
||
* // cause: {
|
||
* // _id: 'Cause',
|
||
* // _tag: 'Parallel',
|
||
* // left: { _id: 'Cause', _tag: 'Fail', failure: 'task1' },
|
||
* // right: { _id: 'Cause', _tag: 'Fail', failure: 'task2' }
|
||
* // }
|
||
* // }
|
||
* ```
|
||
*
|
||
* **Example** (Handling Success or Failure with Either)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* const task1 = Effect.fail("task1").pipe(
|
||
* Effect.delay("100 millis"),
|
||
* Effect.tap(Console.log("task1 done")),
|
||
* Effect.onInterrupt(() => Console.log("task1 interrupted"))
|
||
* )
|
||
* const task2 = Effect.succeed("task2").pipe(
|
||
* Effect.delay("200 millis"),
|
||
* Effect.tap(Console.log("task2 done")),
|
||
* Effect.onInterrupt(() => Console.log("task2 interrupted"))
|
||
* )
|
||
*
|
||
* // Run both tasks concurrently, wrapping the result
|
||
* // in Either to capture success or failure
|
||
* const program = Effect.race(Effect.either(task1), Effect.either(task2))
|
||
*
|
||
* Effect.runPromise(program).then(console.log)
|
||
* // Output:
|
||
* // task2 interrupted
|
||
* // { _id: 'Either', _tag: 'Left', left: 'task1' }
|
||
* ```
|
||
*
|
||
* @see {@link raceAll} for a version that handles multiple effects.
|
||
* @see {@link raceFirst} for a version that returns the result of the first effect to complete.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Racing
|
||
*/
|
||
<A2, E2, R2>(that: Effect<A2, E2, R2>): <A, E, R>(self: Effect<A, E, R>) => Effect<A2 | A, E2 | E, R2 | R>;
|
||
/**
|
||
* Races two effects and returns the result of the first successful one.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function takes two effects and runs them concurrently. The first effect
|
||
* that successfully completes will determine the result of the race, and the
|
||
* other effect will be interrupted.
|
||
*
|
||
* If neither effect succeeds, the function will fail with a `Cause`
|
||
* containing all the errors.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is useful when you want to run two effects concurrently, but only care
|
||
* about the first one to succeed. It is commonly used in cases like timeouts,
|
||
* retries, or when you want to optimize for the faster response without
|
||
* worrying about the other effect.
|
||
*
|
||
* **Handling Success or Failure with Either**
|
||
*
|
||
* If you want to handle the result of whichever task completes first, whether
|
||
* it succeeds or fails, you can use the `Effect.either` function. This function
|
||
* wraps the result in an `Either` type, allowing you to see if the result
|
||
* was a success (`Right`) or a failure (`Left`).
|
||
*
|
||
* **Example** (Both Tasks Succeed)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* const task1 = Effect.succeed("task1").pipe(
|
||
* Effect.delay("200 millis"),
|
||
* Effect.tap(Console.log("task1 done")),
|
||
* Effect.onInterrupt(() => Console.log("task1 interrupted"))
|
||
* )
|
||
* const task2 = Effect.succeed("task2").pipe(
|
||
* Effect.delay("100 millis"),
|
||
* Effect.tap(Console.log("task2 done")),
|
||
* Effect.onInterrupt(() => Console.log("task2 interrupted"))
|
||
* )
|
||
*
|
||
* const program = Effect.race(task1, task2)
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output:
|
||
* // task1 done
|
||
* // task2 interrupted
|
||
* ```
|
||
*
|
||
* **Example** (One Task Fails, One Succeeds)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* const task1 = Effect.fail("task1").pipe(
|
||
* Effect.delay("100 millis"),
|
||
* Effect.tap(Console.log("task1 done")),
|
||
* Effect.onInterrupt(() => Console.log("task1 interrupted"))
|
||
* )
|
||
* const task2 = Effect.succeed("task2").pipe(
|
||
* Effect.delay("200 millis"),
|
||
* Effect.tap(Console.log("task2 done")),
|
||
* Effect.onInterrupt(() => Console.log("task2 interrupted"))
|
||
* )
|
||
*
|
||
* const program = Effect.race(task1, task2)
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output:
|
||
* // task2 done
|
||
* ```
|
||
*
|
||
* **Example** (Both Tasks Fail)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* const task1 = Effect.fail("task1").pipe(
|
||
* Effect.delay("100 millis"),
|
||
* Effect.tap(Console.log("task1 done")),
|
||
* Effect.onInterrupt(() => Console.log("task1 interrupted"))
|
||
* )
|
||
* const task2 = Effect.fail("task2").pipe(
|
||
* Effect.delay("200 millis"),
|
||
* Effect.tap(Console.log("task2 done")),
|
||
* Effect.onInterrupt(() => Console.log("task2 interrupted"))
|
||
* )
|
||
*
|
||
* const program = Effect.race(task1, task2)
|
||
*
|
||
* Effect.runPromiseExit(program).then(console.log)
|
||
* // Output:
|
||
* // {
|
||
* // _id: 'Exit',
|
||
* // _tag: 'Failure',
|
||
* // cause: {
|
||
* // _id: 'Cause',
|
||
* // _tag: 'Parallel',
|
||
* // left: { _id: 'Cause', _tag: 'Fail', failure: 'task1' },
|
||
* // right: { _id: 'Cause', _tag: 'Fail', failure: 'task2' }
|
||
* // }
|
||
* // }
|
||
* ```
|
||
*
|
||
* **Example** (Handling Success or Failure with Either)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* const task1 = Effect.fail("task1").pipe(
|
||
* Effect.delay("100 millis"),
|
||
* Effect.tap(Console.log("task1 done")),
|
||
* Effect.onInterrupt(() => Console.log("task1 interrupted"))
|
||
* )
|
||
* const task2 = Effect.succeed("task2").pipe(
|
||
* Effect.delay("200 millis"),
|
||
* Effect.tap(Console.log("task2 done")),
|
||
* Effect.onInterrupt(() => Console.log("task2 interrupted"))
|
||
* )
|
||
*
|
||
* // Run both tasks concurrently, wrapping the result
|
||
* // in Either to capture success or failure
|
||
* const program = Effect.race(Effect.either(task1), Effect.either(task2))
|
||
*
|
||
* Effect.runPromise(program).then(console.log)
|
||
* // Output:
|
||
* // task2 interrupted
|
||
* // { _id: 'Either', _tag: 'Left', left: 'task1' }
|
||
* ```
|
||
*
|
||
* @see {@link raceAll} for a version that handles multiple effects.
|
||
* @see {@link raceFirst} for a version that returns the result of the first effect to complete.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Racing
|
||
*/
|
||
<A, E, R, A2, E2, R2>(self: Effect<A, E, R>, that: Effect<A2, E2, R2>): Effect<A | A2, E | E2, R | R2>;
|
||
};
|
||
/**
|
||
* Races multiple effects and returns the first successful result.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function runs multiple effects concurrently and returns the result of
|
||
* the first one to succeed. If one effect succeeds, the others will be
|
||
* interrupted.
|
||
*
|
||
* If none of the effects succeed, the function will fail with the last error
|
||
* encountered.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is useful when you want to race multiple effects, but only care about
|
||
* the first one to succeed. It is commonly used in cases like timeouts,
|
||
* retries, or when you want to optimize for the faster response without
|
||
* worrying about the other effects.
|
||
*
|
||
* **Example** (All Tasks Succeed)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* const task1 = Effect.succeed("task1").pipe(
|
||
* Effect.delay("100 millis"),
|
||
* Effect.tap(Console.log("task1 done")),
|
||
* Effect.onInterrupt(() => Console.log("task1 interrupted"))
|
||
* )
|
||
* const task2 = Effect.succeed("task2").pipe(
|
||
* Effect.delay("200 millis"),
|
||
* Effect.tap(Console.log("task2 done")),
|
||
* Effect.onInterrupt(() => Console.log("task2 interrupted"))
|
||
* )
|
||
*
|
||
* const task3 = Effect.succeed("task3").pipe(
|
||
* Effect.delay("150 millis"),
|
||
* Effect.tap(Console.log("task3 done")),
|
||
* Effect.onInterrupt(() => Console.log("task3 interrupted"))
|
||
* )
|
||
*
|
||
* const program = Effect.raceAll([task1, task2, task3])
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output:
|
||
* // task1 done
|
||
* // task2 interrupted
|
||
* // task3 interrupted
|
||
* ```
|
||
*
|
||
* **Example** (One Task Fails, Two Tasks Succeed)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* const task1 = Effect.fail("task1").pipe(
|
||
* Effect.delay("100 millis"),
|
||
* Effect.tap(Console.log("task1 done")),
|
||
* Effect.onInterrupt(() => Console.log("task1 interrupted"))
|
||
* )
|
||
* const task2 = Effect.succeed("task2").pipe(
|
||
* Effect.delay("200 millis"),
|
||
* Effect.tap(Console.log("task2 done")),
|
||
* Effect.onInterrupt(() => Console.log("task2 interrupted"))
|
||
* )
|
||
*
|
||
* const task3 = Effect.succeed("task3").pipe(
|
||
* Effect.delay("150 millis"),
|
||
* Effect.tap(Console.log("task3 done")),
|
||
* Effect.onInterrupt(() => Console.log("task3 interrupted"))
|
||
* )
|
||
*
|
||
* const program = Effect.raceAll([task1, task2, task3])
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output:
|
||
* // task3 done
|
||
* // task2 interrupted
|
||
* ```
|
||
*
|
||
* **Example** (All Tasks Fail)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* const task1 = Effect.fail("task1").pipe(
|
||
* Effect.delay("100 millis"),
|
||
* Effect.tap(Console.log("task1 done")),
|
||
* Effect.onInterrupt(() => Console.log("task1 interrupted"))
|
||
* )
|
||
* const task2 = Effect.fail("task2").pipe(
|
||
* Effect.delay("200 millis"),
|
||
* Effect.tap(Console.log("task2 done")),
|
||
* Effect.onInterrupt(() => Console.log("task2 interrupted"))
|
||
* )
|
||
*
|
||
* const task3 = Effect.fail("task3").pipe(
|
||
* Effect.delay("150 millis"),
|
||
* Effect.tap(Console.log("task3 done")),
|
||
* Effect.onInterrupt(() => Console.log("task3 interrupted"))
|
||
* )
|
||
*
|
||
* const program = Effect.raceAll([task1, task2, task3])
|
||
*
|
||
* Effect.runPromiseExit(program).then(console.log)
|
||
* // Output:
|
||
* // {
|
||
* // _id: 'Exit',
|
||
* // _tag: 'Failure',
|
||
* // cause: { _id: 'Cause', _tag: 'Fail', failure: 'task2' }
|
||
* // }
|
||
* ```
|
||
*
|
||
* @see {@link race} for a version that handles only two effects.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Racing
|
||
*/
|
||
export declare const raceAll: <Eff extends Effect<any, any, any>>(all: Iterable<Eff>) => Effect<Effect.Success<Eff>, Effect.Error<Eff>, Effect.Context<Eff>>;
|
||
/**
|
||
* Races two effects and returns the result of the first one to complete.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function takes two effects and runs them concurrently, returning the
|
||
* result of the first one that completes, regardless of whether it succeeds or
|
||
* fails.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This function is useful when you want to race two operations, and you want to
|
||
* proceed with whichever one finishes first, regardless of whether it succeeds
|
||
* or fails.
|
||
*
|
||
* **Disconnecting Effects**
|
||
*
|
||
* The `Effect.raceFirst` function safely interrupts the “loser” effect once the other completes, but it will not resume until the loser is cleanly terminated.
|
||
*
|
||
* If you want a quicker return, you can disconnect the interrupt signal for both effects. Instead of calling:
|
||
*
|
||
* ```ts skip-type-checking
|
||
* Effect.raceFirst(task1, task2)
|
||
* ```
|
||
*
|
||
* You can use:
|
||
*
|
||
* ```ts skip-type-checking
|
||
* Effect.raceFirst(Effect.disconnect(task1), Effect.disconnect(task2))
|
||
* ```
|
||
*
|
||
* This allows both effects to complete independently while still terminating the losing effect in the background.
|
||
*
|
||
* **Example** (Both Tasks Succeed)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* const task1 = Effect.succeed("task1").pipe(
|
||
* Effect.delay("100 millis"),
|
||
* Effect.tap(Console.log("task1 done")),
|
||
* Effect.onInterrupt(() =>
|
||
* Console.log("task1 interrupted").pipe(Effect.delay("100 millis"))
|
||
* )
|
||
* )
|
||
* const task2 = Effect.succeed("task2").pipe(
|
||
* Effect.delay("200 millis"),
|
||
* Effect.tap(Console.log("task2 done")),
|
||
* Effect.onInterrupt(() =>
|
||
* Console.log("task2 interrupted").pipe(Effect.delay("100 millis"))
|
||
* )
|
||
* )
|
||
*
|
||
* const program = Effect.raceFirst(task1, task2).pipe(
|
||
* Effect.tap(Console.log("more work..."))
|
||
* )
|
||
*
|
||
* Effect.runPromiseExit(program).then(console.log)
|
||
* // Output:
|
||
* // task1 done
|
||
* // task2 interrupted
|
||
* // more work...
|
||
* // { _id: 'Exit', _tag: 'Success', value: 'task1' }
|
||
* ```
|
||
*
|
||
* **Example** (One Task Fails, One Succeeds)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* const task1 = Effect.fail("task1").pipe(
|
||
* Effect.delay("100 millis"),
|
||
* Effect.tap(Console.log("task1 done")),
|
||
* Effect.onInterrupt(() =>
|
||
* Console.log("task1 interrupted").pipe(Effect.delay("100 millis"))
|
||
* )
|
||
* )
|
||
* const task2 = Effect.succeed("task2").pipe(
|
||
* Effect.delay("200 millis"),
|
||
* Effect.tap(Console.log("task2 done")),
|
||
* Effect.onInterrupt(() =>
|
||
* Console.log("task2 interrupted").pipe(Effect.delay("100 millis"))
|
||
* )
|
||
* )
|
||
*
|
||
* const program = Effect.raceFirst(task1, task2).pipe(
|
||
* Effect.tap(Console.log("more work..."))
|
||
* )
|
||
*
|
||
* Effect.runPromiseExit(program).then(console.log)
|
||
* // Output:
|
||
* // task2 interrupted
|
||
* // {
|
||
* // _id: 'Exit',
|
||
* // _tag: 'Failure',
|
||
* // cause: { _id: 'Cause', _tag: 'Fail', failure: 'task1' }
|
||
* // }
|
||
* ```
|
||
*
|
||
* **Example** (Using Effect.disconnect for Quicker Return)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* const task1 = Effect.succeed("task1").pipe(
|
||
* Effect.delay("100 millis"),
|
||
* Effect.tap(Console.log("task1 done")),
|
||
* Effect.onInterrupt(() =>
|
||
* Console.log("task1 interrupted").pipe(Effect.delay("100 millis"))
|
||
* )
|
||
* )
|
||
* const task2 = Effect.succeed("task2").pipe(
|
||
* Effect.delay("200 millis"),
|
||
* Effect.tap(Console.log("task2 done")),
|
||
* Effect.onInterrupt(() =>
|
||
* Console.log("task2 interrupted").pipe(Effect.delay("100 millis"))
|
||
* )
|
||
* )
|
||
*
|
||
* // Race the two tasks with disconnect to allow quicker return
|
||
* const program = Effect.raceFirst(
|
||
* Effect.disconnect(task1),
|
||
* Effect.disconnect(task2)
|
||
* ).pipe(Effect.tap(Console.log("more work...")))
|
||
*
|
||
* Effect.runPromiseExit(program).then(console.log)
|
||
* // Output:
|
||
* // task1 done
|
||
* // more work...
|
||
* // { _id: 'Exit', _tag: 'Success', value: 'task1' }
|
||
* // task2 interrupted
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Racing
|
||
*/
|
||
export declare const raceFirst: {
|
||
/**
|
||
* Races two effects and returns the result of the first one to complete.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function takes two effects and runs them concurrently, returning the
|
||
* result of the first one that completes, regardless of whether it succeeds or
|
||
* fails.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This function is useful when you want to race two operations, and you want to
|
||
* proceed with whichever one finishes first, regardless of whether it succeeds
|
||
* or fails.
|
||
*
|
||
* **Disconnecting Effects**
|
||
*
|
||
* The `Effect.raceFirst` function safely interrupts the “loser” effect once the other completes, but it will not resume until the loser is cleanly terminated.
|
||
*
|
||
* If you want a quicker return, you can disconnect the interrupt signal for both effects. Instead of calling:
|
||
*
|
||
* ```ts skip-type-checking
|
||
* Effect.raceFirst(task1, task2)
|
||
* ```
|
||
*
|
||
* You can use:
|
||
*
|
||
* ```ts skip-type-checking
|
||
* Effect.raceFirst(Effect.disconnect(task1), Effect.disconnect(task2))
|
||
* ```
|
||
*
|
||
* This allows both effects to complete independently while still terminating the losing effect in the background.
|
||
*
|
||
* **Example** (Both Tasks Succeed)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* const task1 = Effect.succeed("task1").pipe(
|
||
* Effect.delay("100 millis"),
|
||
* Effect.tap(Console.log("task1 done")),
|
||
* Effect.onInterrupt(() =>
|
||
* Console.log("task1 interrupted").pipe(Effect.delay("100 millis"))
|
||
* )
|
||
* )
|
||
* const task2 = Effect.succeed("task2").pipe(
|
||
* Effect.delay("200 millis"),
|
||
* Effect.tap(Console.log("task2 done")),
|
||
* Effect.onInterrupt(() =>
|
||
* Console.log("task2 interrupted").pipe(Effect.delay("100 millis"))
|
||
* )
|
||
* )
|
||
*
|
||
* const program = Effect.raceFirst(task1, task2).pipe(
|
||
* Effect.tap(Console.log("more work..."))
|
||
* )
|
||
*
|
||
* Effect.runPromiseExit(program).then(console.log)
|
||
* // Output:
|
||
* // task1 done
|
||
* // task2 interrupted
|
||
* // more work...
|
||
* // { _id: 'Exit', _tag: 'Success', value: 'task1' }
|
||
* ```
|
||
*
|
||
* **Example** (One Task Fails, One Succeeds)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* const task1 = Effect.fail("task1").pipe(
|
||
* Effect.delay("100 millis"),
|
||
* Effect.tap(Console.log("task1 done")),
|
||
* Effect.onInterrupt(() =>
|
||
* Console.log("task1 interrupted").pipe(Effect.delay("100 millis"))
|
||
* )
|
||
* )
|
||
* const task2 = Effect.succeed("task2").pipe(
|
||
* Effect.delay("200 millis"),
|
||
* Effect.tap(Console.log("task2 done")),
|
||
* Effect.onInterrupt(() =>
|
||
* Console.log("task2 interrupted").pipe(Effect.delay("100 millis"))
|
||
* )
|
||
* )
|
||
*
|
||
* const program = Effect.raceFirst(task1, task2).pipe(
|
||
* Effect.tap(Console.log("more work..."))
|
||
* )
|
||
*
|
||
* Effect.runPromiseExit(program).then(console.log)
|
||
* // Output:
|
||
* // task2 interrupted
|
||
* // {
|
||
* // _id: 'Exit',
|
||
* // _tag: 'Failure',
|
||
* // cause: { _id: 'Cause', _tag: 'Fail', failure: 'task1' }
|
||
* // }
|
||
* ```
|
||
*
|
||
* **Example** (Using Effect.disconnect for Quicker Return)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* const task1 = Effect.succeed("task1").pipe(
|
||
* Effect.delay("100 millis"),
|
||
* Effect.tap(Console.log("task1 done")),
|
||
* Effect.onInterrupt(() =>
|
||
* Console.log("task1 interrupted").pipe(Effect.delay("100 millis"))
|
||
* )
|
||
* )
|
||
* const task2 = Effect.succeed("task2").pipe(
|
||
* Effect.delay("200 millis"),
|
||
* Effect.tap(Console.log("task2 done")),
|
||
* Effect.onInterrupt(() =>
|
||
* Console.log("task2 interrupted").pipe(Effect.delay("100 millis"))
|
||
* )
|
||
* )
|
||
*
|
||
* // Race the two tasks with disconnect to allow quicker return
|
||
* const program = Effect.raceFirst(
|
||
* Effect.disconnect(task1),
|
||
* Effect.disconnect(task2)
|
||
* ).pipe(Effect.tap(Console.log("more work...")))
|
||
*
|
||
* Effect.runPromiseExit(program).then(console.log)
|
||
* // Output:
|
||
* // task1 done
|
||
* // more work...
|
||
* // { _id: 'Exit', _tag: 'Success', value: 'task1' }
|
||
* // task2 interrupted
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Racing
|
||
*/
|
||
<A2, E2, R2>(that: Effect<A2, E2, R2>): <A, E, R>(self: Effect<A, E, R>) => Effect<A2 | A, E2 | E, R2 | R>;
|
||
/**
|
||
* Races two effects and returns the result of the first one to complete.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function takes two effects and runs them concurrently, returning the
|
||
* result of the first one that completes, regardless of whether it succeeds or
|
||
* fails.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This function is useful when you want to race two operations, and you want to
|
||
* proceed with whichever one finishes first, regardless of whether it succeeds
|
||
* or fails.
|
||
*
|
||
* **Disconnecting Effects**
|
||
*
|
||
* The `Effect.raceFirst` function safely interrupts the “loser” effect once the other completes, but it will not resume until the loser is cleanly terminated.
|
||
*
|
||
* If you want a quicker return, you can disconnect the interrupt signal for both effects. Instead of calling:
|
||
*
|
||
* ```ts skip-type-checking
|
||
* Effect.raceFirst(task1, task2)
|
||
* ```
|
||
*
|
||
* You can use:
|
||
*
|
||
* ```ts skip-type-checking
|
||
* Effect.raceFirst(Effect.disconnect(task1), Effect.disconnect(task2))
|
||
* ```
|
||
*
|
||
* This allows both effects to complete independently while still terminating the losing effect in the background.
|
||
*
|
||
* **Example** (Both Tasks Succeed)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* const task1 = Effect.succeed("task1").pipe(
|
||
* Effect.delay("100 millis"),
|
||
* Effect.tap(Console.log("task1 done")),
|
||
* Effect.onInterrupt(() =>
|
||
* Console.log("task1 interrupted").pipe(Effect.delay("100 millis"))
|
||
* )
|
||
* )
|
||
* const task2 = Effect.succeed("task2").pipe(
|
||
* Effect.delay("200 millis"),
|
||
* Effect.tap(Console.log("task2 done")),
|
||
* Effect.onInterrupt(() =>
|
||
* Console.log("task2 interrupted").pipe(Effect.delay("100 millis"))
|
||
* )
|
||
* )
|
||
*
|
||
* const program = Effect.raceFirst(task1, task2).pipe(
|
||
* Effect.tap(Console.log("more work..."))
|
||
* )
|
||
*
|
||
* Effect.runPromiseExit(program).then(console.log)
|
||
* // Output:
|
||
* // task1 done
|
||
* // task2 interrupted
|
||
* // more work...
|
||
* // { _id: 'Exit', _tag: 'Success', value: 'task1' }
|
||
* ```
|
||
*
|
||
* **Example** (One Task Fails, One Succeeds)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* const task1 = Effect.fail("task1").pipe(
|
||
* Effect.delay("100 millis"),
|
||
* Effect.tap(Console.log("task1 done")),
|
||
* Effect.onInterrupt(() =>
|
||
* Console.log("task1 interrupted").pipe(Effect.delay("100 millis"))
|
||
* )
|
||
* )
|
||
* const task2 = Effect.succeed("task2").pipe(
|
||
* Effect.delay("200 millis"),
|
||
* Effect.tap(Console.log("task2 done")),
|
||
* Effect.onInterrupt(() =>
|
||
* Console.log("task2 interrupted").pipe(Effect.delay("100 millis"))
|
||
* )
|
||
* )
|
||
*
|
||
* const program = Effect.raceFirst(task1, task2).pipe(
|
||
* Effect.tap(Console.log("more work..."))
|
||
* )
|
||
*
|
||
* Effect.runPromiseExit(program).then(console.log)
|
||
* // Output:
|
||
* // task2 interrupted
|
||
* // {
|
||
* // _id: 'Exit',
|
||
* // _tag: 'Failure',
|
||
* // cause: { _id: 'Cause', _tag: 'Fail', failure: 'task1' }
|
||
* // }
|
||
* ```
|
||
*
|
||
* **Example** (Using Effect.disconnect for Quicker Return)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* const task1 = Effect.succeed("task1").pipe(
|
||
* Effect.delay("100 millis"),
|
||
* Effect.tap(Console.log("task1 done")),
|
||
* Effect.onInterrupt(() =>
|
||
* Console.log("task1 interrupted").pipe(Effect.delay("100 millis"))
|
||
* )
|
||
* )
|
||
* const task2 = Effect.succeed("task2").pipe(
|
||
* Effect.delay("200 millis"),
|
||
* Effect.tap(Console.log("task2 done")),
|
||
* Effect.onInterrupt(() =>
|
||
* Console.log("task2 interrupted").pipe(Effect.delay("100 millis"))
|
||
* )
|
||
* )
|
||
*
|
||
* // Race the two tasks with disconnect to allow quicker return
|
||
* const program = Effect.raceFirst(
|
||
* Effect.disconnect(task1),
|
||
* Effect.disconnect(task2)
|
||
* ).pipe(Effect.tap(Console.log("more work...")))
|
||
*
|
||
* Effect.runPromiseExit(program).then(console.log)
|
||
* // Output:
|
||
* // task1 done
|
||
* // more work...
|
||
* // { _id: 'Exit', _tag: 'Success', value: 'task1' }
|
||
* // task2 interrupted
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Racing
|
||
*/
|
||
<A, E, R, A2, E2, R2>(self: Effect<A, E, R>, that: Effect<A2, E2, R2>): Effect<A | A2, E | E2, R | R2>;
|
||
};
|
||
/**
|
||
* Races two effects and calls a finisher when the first one completes.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function runs two effects concurrently and calls a specified “finisher”
|
||
* function once one of the effects completes, regardless of whether it succeeds
|
||
* or fails.
|
||
*
|
||
* The finisher functions for each effect allow you to handle the results of
|
||
* each effect as soon as they complete.
|
||
*
|
||
* The function takes two finisher callbacks, one for each effect, and allows
|
||
* you to specify how to handle the result of the race.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This function is useful when you need to react to the completion of either
|
||
* effect without waiting for both to finish. It can be used whenever you want
|
||
* to take action based on the first available result.
|
||
*
|
||
* **Example** (Handling Results of Concurrent Tasks)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* const task1 = Effect.succeed("task1").pipe(
|
||
* Effect.delay("100 millis"),
|
||
* Effect.tap(Console.log("task1 done")),
|
||
* Effect.onInterrupt(() =>
|
||
* Console.log("task1 interrupted").pipe(Effect.delay("100 millis"))
|
||
* )
|
||
* )
|
||
* const task2 = Effect.succeed("task2").pipe(
|
||
* Effect.delay("200 millis"),
|
||
* Effect.tap(Console.log("task2 done")),
|
||
* Effect.onInterrupt(() =>
|
||
* Console.log("task2 interrupted").pipe(Effect.delay("100 millis"))
|
||
* )
|
||
* )
|
||
*
|
||
* const program = Effect.raceWith(task1, task2, {
|
||
* onSelfDone: (exit) => Console.log(`task1 exited with ${exit}`),
|
||
* onOtherDone: (exit) => Console.log(`task2 exited with ${exit}`)
|
||
* })
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output:
|
||
* // task1 done
|
||
* // task1 exited with {
|
||
* // "_id": "Exit",
|
||
* // "_tag": "Success",
|
||
* // "value": "task1"
|
||
* // }
|
||
* // task2 interrupted
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Racing
|
||
*/
|
||
export declare const raceWith: {
|
||
/**
|
||
* Races two effects and calls a finisher when the first one completes.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function runs two effects concurrently and calls a specified “finisher”
|
||
* function once one of the effects completes, regardless of whether it succeeds
|
||
* or fails.
|
||
*
|
||
* The finisher functions for each effect allow you to handle the results of
|
||
* each effect as soon as they complete.
|
||
*
|
||
* The function takes two finisher callbacks, one for each effect, and allows
|
||
* you to specify how to handle the result of the race.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This function is useful when you need to react to the completion of either
|
||
* effect without waiting for both to finish. It can be used whenever you want
|
||
* to take action based on the first available result.
|
||
*
|
||
* **Example** (Handling Results of Concurrent Tasks)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* const task1 = Effect.succeed("task1").pipe(
|
||
* Effect.delay("100 millis"),
|
||
* Effect.tap(Console.log("task1 done")),
|
||
* Effect.onInterrupt(() =>
|
||
* Console.log("task1 interrupted").pipe(Effect.delay("100 millis"))
|
||
* )
|
||
* )
|
||
* const task2 = Effect.succeed("task2").pipe(
|
||
* Effect.delay("200 millis"),
|
||
* Effect.tap(Console.log("task2 done")),
|
||
* Effect.onInterrupt(() =>
|
||
* Console.log("task2 interrupted").pipe(Effect.delay("100 millis"))
|
||
* )
|
||
* )
|
||
*
|
||
* const program = Effect.raceWith(task1, task2, {
|
||
* onSelfDone: (exit) => Console.log(`task1 exited with ${exit}`),
|
||
* onOtherDone: (exit) => Console.log(`task2 exited with ${exit}`)
|
||
* })
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output:
|
||
* // task1 done
|
||
* // task1 exited with {
|
||
* // "_id": "Exit",
|
||
* // "_tag": "Success",
|
||
* // "value": "task1"
|
||
* // }
|
||
* // task2 interrupted
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Racing
|
||
*/
|
||
<A1, E1, R1, E, A, A2, E2, R2, A3, E3, R3>(other: Effect<A1, E1, R1>, options: {
|
||
readonly onSelfDone: (exit: Exit.Exit<A, E>, fiber: Fiber.Fiber<A1, E1>) => Effect<A2, E2, R2>;
|
||
readonly onOtherDone: (exit: Exit.Exit<A1, E1>, fiber: Fiber.Fiber<A, E>) => Effect<A3, E3, R3>;
|
||
}): <R>(self: Effect<A, E, R>) => Effect<A2 | A3, E2 | E3, R1 | R2 | R3 | R>;
|
||
/**
|
||
* Races two effects and calls a finisher when the first one completes.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function runs two effects concurrently and calls a specified “finisher”
|
||
* function once one of the effects completes, regardless of whether it succeeds
|
||
* or fails.
|
||
*
|
||
* The finisher functions for each effect allow you to handle the results of
|
||
* each effect as soon as they complete.
|
||
*
|
||
* The function takes two finisher callbacks, one for each effect, and allows
|
||
* you to specify how to handle the result of the race.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This function is useful when you need to react to the completion of either
|
||
* effect without waiting for both to finish. It can be used whenever you want
|
||
* to take action based on the first available result.
|
||
*
|
||
* **Example** (Handling Results of Concurrent Tasks)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* const task1 = Effect.succeed("task1").pipe(
|
||
* Effect.delay("100 millis"),
|
||
* Effect.tap(Console.log("task1 done")),
|
||
* Effect.onInterrupt(() =>
|
||
* Console.log("task1 interrupted").pipe(Effect.delay("100 millis"))
|
||
* )
|
||
* )
|
||
* const task2 = Effect.succeed("task2").pipe(
|
||
* Effect.delay("200 millis"),
|
||
* Effect.tap(Console.log("task2 done")),
|
||
* Effect.onInterrupt(() =>
|
||
* Console.log("task2 interrupted").pipe(Effect.delay("100 millis"))
|
||
* )
|
||
* )
|
||
*
|
||
* const program = Effect.raceWith(task1, task2, {
|
||
* onSelfDone: (exit) => Console.log(`task1 exited with ${exit}`),
|
||
* onOtherDone: (exit) => Console.log(`task2 exited with ${exit}`)
|
||
* })
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output:
|
||
* // task1 done
|
||
* // task1 exited with {
|
||
* // "_id": "Exit",
|
||
* // "_tag": "Success",
|
||
* // "value": "task1"
|
||
* // }
|
||
* // task2 interrupted
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Racing
|
||
*/
|
||
<A, E, R, A1, E1, R1, A2, E2, R2, A3, E3, R3>(self: Effect<A, E, R>, other: Effect<A1, E1, R1>, options: {
|
||
readonly onSelfDone: (exit: Exit.Exit<A, E>, fiber: Fiber.Fiber<A1, E1>) => Effect<A2, E2, R2>;
|
||
readonly onOtherDone: (exit: Exit.Exit<A1, E1>, fiber: Fiber.Fiber<A, E>) => Effect<A3, E3, R3>;
|
||
}): Effect<A2 | A3, E2 | E3, R | R1 | R2 | R3>;
|
||
};
|
||
/**
|
||
* Summarizes a effect by computing some value before and after execution, and
|
||
* then combining the values to produce a summary, together with the result of
|
||
* execution.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Sequencing
|
||
*/
|
||
export declare const summarized: {
|
||
/**
|
||
* Summarizes a effect by computing some value before and after execution, and
|
||
* then combining the values to produce a summary, together with the result of
|
||
* execution.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Sequencing
|
||
*/
|
||
<B, E2, R2, C>(summary: Effect<B, E2, R2>, f: (start: B, end: B) => C): <A, E, R>(self: Effect<A, E, R>) => Effect<[C, A], E2 | E, R2 | R>;
|
||
/**
|
||
* Summarizes a effect by computing some value before and after execution, and
|
||
* then combining the values to produce a summary, together with the result of
|
||
* execution.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Sequencing
|
||
*/
|
||
<A, E, R, B, E2, R2, C>(self: Effect<A, E, R>, summary: Effect<B, E2, R2>, f: (start: B, end: B) => C): Effect<[C, A], E2 | E, R2 | R>;
|
||
};
|
||
/**
|
||
* Runs a side effect with the result of an effect without changing the original
|
||
* value.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function works similarly to `flatMap`, but it ignores the result of the
|
||
* function passed to it. The value from the previous effect remains available
|
||
* for the next part of the chain. Note that if the side effect fails, the
|
||
* entire chain will fail too.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use this function when you want to perform a side effect, like logging or
|
||
* tracking, without modifying the main value. This is useful when you need to
|
||
* observe or record an action but want the original value to be passed to the
|
||
* next step.
|
||
*
|
||
* **Example** (Logging a step in a pipeline)
|
||
*
|
||
* ```ts
|
||
* import { Console, Effect, pipe } from "effect"
|
||
*
|
||
* // Function to apply a discount safely to a transaction amount
|
||
* const applyDiscount = (
|
||
* total: number,
|
||
* discountRate: number
|
||
* ): Effect.Effect<number, Error> =>
|
||
* discountRate === 0
|
||
* ? Effect.fail(new Error("Discount rate cannot be zero"))
|
||
* : Effect.succeed(total - (total * discountRate) / 100)
|
||
*
|
||
* // Simulated asynchronous task to fetch a transaction amount from database
|
||
* const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
|
||
*
|
||
* const finalAmount = pipe(
|
||
* fetchTransactionAmount,
|
||
* // Log the fetched transaction amount
|
||
* Effect.tap((amount) => Console.log(`Apply a discount to: ${amount}`)),
|
||
* // `amount` is still available!
|
||
* Effect.flatMap((amount) => applyDiscount(amount, 5))
|
||
* )
|
||
*
|
||
* Effect.runPromise(finalAmount).then(console.log)
|
||
* // Output:
|
||
* // Apply a discount to: 100
|
||
* // 95
|
||
* ```
|
||
*
|
||
* @see {@link flatMap} for a version that allows you to change the value.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Sequencing
|
||
*/
|
||
export declare const tap: {
|
||
/**
|
||
* Runs a side effect with the result of an effect without changing the original
|
||
* value.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function works similarly to `flatMap`, but it ignores the result of the
|
||
* function passed to it. The value from the previous effect remains available
|
||
* for the next part of the chain. Note that if the side effect fails, the
|
||
* entire chain will fail too.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use this function when you want to perform a side effect, like logging or
|
||
* tracking, without modifying the main value. This is useful when you need to
|
||
* observe or record an action but want the original value to be passed to the
|
||
* next step.
|
||
*
|
||
* **Example** (Logging a step in a pipeline)
|
||
*
|
||
* ```ts
|
||
* import { Console, Effect, pipe } from "effect"
|
||
*
|
||
* // Function to apply a discount safely to a transaction amount
|
||
* const applyDiscount = (
|
||
* total: number,
|
||
* discountRate: number
|
||
* ): Effect.Effect<number, Error> =>
|
||
* discountRate === 0
|
||
* ? Effect.fail(new Error("Discount rate cannot be zero"))
|
||
* : Effect.succeed(total - (total * discountRate) / 100)
|
||
*
|
||
* // Simulated asynchronous task to fetch a transaction amount from database
|
||
* const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
|
||
*
|
||
* const finalAmount = pipe(
|
||
* fetchTransactionAmount,
|
||
* // Log the fetched transaction amount
|
||
* Effect.tap((amount) => Console.log(`Apply a discount to: ${amount}`)),
|
||
* // `amount` is still available!
|
||
* Effect.flatMap((amount) => applyDiscount(amount, 5))
|
||
* )
|
||
*
|
||
* Effect.runPromise(finalAmount).then(console.log)
|
||
* // Output:
|
||
* // Apply a discount to: 100
|
||
* // 95
|
||
* ```
|
||
*
|
||
* @see {@link flatMap} for a version that allows you to change the value.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Sequencing
|
||
*/
|
||
<A, X>(f: (a: NoInfer<A>) => X): <E, R>(self: Effect<A, E, R>) => [X] extends [Effect<infer _A1, infer E1, infer R1>] ? Effect<A, E | E1, R | R1> : [X] extends [PromiseLike<infer _A1>] ? Effect<A, E | Cause.UnknownException, R> : Effect<A, E, R>;
|
||
/**
|
||
* Runs a side effect with the result of an effect without changing the original
|
||
* value.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function works similarly to `flatMap`, but it ignores the result of the
|
||
* function passed to it. The value from the previous effect remains available
|
||
* for the next part of the chain. Note that if the side effect fails, the
|
||
* entire chain will fail too.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use this function when you want to perform a side effect, like logging or
|
||
* tracking, without modifying the main value. This is useful when you need to
|
||
* observe or record an action but want the original value to be passed to the
|
||
* next step.
|
||
*
|
||
* **Example** (Logging a step in a pipeline)
|
||
*
|
||
* ```ts
|
||
* import { Console, Effect, pipe } from "effect"
|
||
*
|
||
* // Function to apply a discount safely to a transaction amount
|
||
* const applyDiscount = (
|
||
* total: number,
|
||
* discountRate: number
|
||
* ): Effect.Effect<number, Error> =>
|
||
* discountRate === 0
|
||
* ? Effect.fail(new Error("Discount rate cannot be zero"))
|
||
* : Effect.succeed(total - (total * discountRate) / 100)
|
||
*
|
||
* // Simulated asynchronous task to fetch a transaction amount from database
|
||
* const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
|
||
*
|
||
* const finalAmount = pipe(
|
||
* fetchTransactionAmount,
|
||
* // Log the fetched transaction amount
|
||
* Effect.tap((amount) => Console.log(`Apply a discount to: ${amount}`)),
|
||
* // `amount` is still available!
|
||
* Effect.flatMap((amount) => applyDiscount(amount, 5))
|
||
* )
|
||
*
|
||
* Effect.runPromise(finalAmount).then(console.log)
|
||
* // Output:
|
||
* // Apply a discount to: 100
|
||
* // 95
|
||
* ```
|
||
*
|
||
* @see {@link flatMap} for a version that allows you to change the value.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Sequencing
|
||
*/
|
||
<A, X, E1, R1>(f: (a: NoInfer<A>) => Effect<X, E1, R1>, options: {
|
||
onlyEffect: true;
|
||
}): <E, R>(self: Effect<A, E, R>) => Effect<A, E | E1, R | R1>;
|
||
/**
|
||
* Runs a side effect with the result of an effect without changing the original
|
||
* value.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function works similarly to `flatMap`, but it ignores the result of the
|
||
* function passed to it. The value from the previous effect remains available
|
||
* for the next part of the chain. Note that if the side effect fails, the
|
||
* entire chain will fail too.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use this function when you want to perform a side effect, like logging or
|
||
* tracking, without modifying the main value. This is useful when you need to
|
||
* observe or record an action but want the original value to be passed to the
|
||
* next step.
|
||
*
|
||
* **Example** (Logging a step in a pipeline)
|
||
*
|
||
* ```ts
|
||
* import { Console, Effect, pipe } from "effect"
|
||
*
|
||
* // Function to apply a discount safely to a transaction amount
|
||
* const applyDiscount = (
|
||
* total: number,
|
||
* discountRate: number
|
||
* ): Effect.Effect<number, Error> =>
|
||
* discountRate === 0
|
||
* ? Effect.fail(new Error("Discount rate cannot be zero"))
|
||
* : Effect.succeed(total - (total * discountRate) / 100)
|
||
*
|
||
* // Simulated asynchronous task to fetch a transaction amount from database
|
||
* const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
|
||
*
|
||
* const finalAmount = pipe(
|
||
* fetchTransactionAmount,
|
||
* // Log the fetched transaction amount
|
||
* Effect.tap((amount) => Console.log(`Apply a discount to: ${amount}`)),
|
||
* // `amount` is still available!
|
||
* Effect.flatMap((amount) => applyDiscount(amount, 5))
|
||
* )
|
||
*
|
||
* Effect.runPromise(finalAmount).then(console.log)
|
||
* // Output:
|
||
* // Apply a discount to: 100
|
||
* // 95
|
||
* ```
|
||
*
|
||
* @see {@link flatMap} for a version that allows you to change the value.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Sequencing
|
||
*/
|
||
<X>(f: NotFunction<X>): <A, E, R>(self: Effect<A, E, R>) => [X] extends [Effect<infer _A1, infer E1, infer R1>] ? Effect<A, E | E1, R | R1> : [X] extends [PromiseLike<infer _A1>] ? Effect<A, E | Cause.UnknownException, R> : Effect<A, E, R>;
|
||
/**
|
||
* Runs a side effect with the result of an effect without changing the original
|
||
* value.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function works similarly to `flatMap`, but it ignores the result of the
|
||
* function passed to it. The value from the previous effect remains available
|
||
* for the next part of the chain. Note that if the side effect fails, the
|
||
* entire chain will fail too.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use this function when you want to perform a side effect, like logging or
|
||
* tracking, without modifying the main value. This is useful when you need to
|
||
* observe or record an action but want the original value to be passed to the
|
||
* next step.
|
||
*
|
||
* **Example** (Logging a step in a pipeline)
|
||
*
|
||
* ```ts
|
||
* import { Console, Effect, pipe } from "effect"
|
||
*
|
||
* // Function to apply a discount safely to a transaction amount
|
||
* const applyDiscount = (
|
||
* total: number,
|
||
* discountRate: number
|
||
* ): Effect.Effect<number, Error> =>
|
||
* discountRate === 0
|
||
* ? Effect.fail(new Error("Discount rate cannot be zero"))
|
||
* : Effect.succeed(total - (total * discountRate) / 100)
|
||
*
|
||
* // Simulated asynchronous task to fetch a transaction amount from database
|
||
* const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
|
||
*
|
||
* const finalAmount = pipe(
|
||
* fetchTransactionAmount,
|
||
* // Log the fetched transaction amount
|
||
* Effect.tap((amount) => Console.log(`Apply a discount to: ${amount}`)),
|
||
* // `amount` is still available!
|
||
* Effect.flatMap((amount) => applyDiscount(amount, 5))
|
||
* )
|
||
*
|
||
* Effect.runPromise(finalAmount).then(console.log)
|
||
* // Output:
|
||
* // Apply a discount to: 100
|
||
* // 95
|
||
* ```
|
||
*
|
||
* @see {@link flatMap} for a version that allows you to change the value.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Sequencing
|
||
*/
|
||
<X, E1, R1>(f: Effect<X, E1, R1>, options: {
|
||
onlyEffect: true;
|
||
}): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E | E1, R | R1>;
|
||
/**
|
||
* Runs a side effect with the result of an effect without changing the original
|
||
* value.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function works similarly to `flatMap`, but it ignores the result of the
|
||
* function passed to it. The value from the previous effect remains available
|
||
* for the next part of the chain. Note that if the side effect fails, the
|
||
* entire chain will fail too.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use this function when you want to perform a side effect, like logging or
|
||
* tracking, without modifying the main value. This is useful when you need to
|
||
* observe or record an action but want the original value to be passed to the
|
||
* next step.
|
||
*
|
||
* **Example** (Logging a step in a pipeline)
|
||
*
|
||
* ```ts
|
||
* import { Console, Effect, pipe } from "effect"
|
||
*
|
||
* // Function to apply a discount safely to a transaction amount
|
||
* const applyDiscount = (
|
||
* total: number,
|
||
* discountRate: number
|
||
* ): Effect.Effect<number, Error> =>
|
||
* discountRate === 0
|
||
* ? Effect.fail(new Error("Discount rate cannot be zero"))
|
||
* : Effect.succeed(total - (total * discountRate) / 100)
|
||
*
|
||
* // Simulated asynchronous task to fetch a transaction amount from database
|
||
* const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
|
||
*
|
||
* const finalAmount = pipe(
|
||
* fetchTransactionAmount,
|
||
* // Log the fetched transaction amount
|
||
* Effect.tap((amount) => Console.log(`Apply a discount to: ${amount}`)),
|
||
* // `amount` is still available!
|
||
* Effect.flatMap((amount) => applyDiscount(amount, 5))
|
||
* )
|
||
*
|
||
* Effect.runPromise(finalAmount).then(console.log)
|
||
* // Output:
|
||
* // Apply a discount to: 100
|
||
* // 95
|
||
* ```
|
||
*
|
||
* @see {@link flatMap} for a version that allows you to change the value.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Sequencing
|
||
*/
|
||
<A, E, R, X>(self: Effect<A, E, R>, f: (a: NoInfer<A>) => X): [X] extends [Effect<infer _A1, infer E1, infer R1>] ? Effect<A, E | E1, R | R1> : [X] extends [PromiseLike<infer _A1>] ? Effect<A, E | Cause.UnknownException, R> : Effect<A, E, R>;
|
||
/**
|
||
* Runs a side effect with the result of an effect without changing the original
|
||
* value.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function works similarly to `flatMap`, but it ignores the result of the
|
||
* function passed to it. The value from the previous effect remains available
|
||
* for the next part of the chain. Note that if the side effect fails, the
|
||
* entire chain will fail too.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use this function when you want to perform a side effect, like logging or
|
||
* tracking, without modifying the main value. This is useful when you need to
|
||
* observe or record an action but want the original value to be passed to the
|
||
* next step.
|
||
*
|
||
* **Example** (Logging a step in a pipeline)
|
||
*
|
||
* ```ts
|
||
* import { Console, Effect, pipe } from "effect"
|
||
*
|
||
* // Function to apply a discount safely to a transaction amount
|
||
* const applyDiscount = (
|
||
* total: number,
|
||
* discountRate: number
|
||
* ): Effect.Effect<number, Error> =>
|
||
* discountRate === 0
|
||
* ? Effect.fail(new Error("Discount rate cannot be zero"))
|
||
* : Effect.succeed(total - (total * discountRate) / 100)
|
||
*
|
||
* // Simulated asynchronous task to fetch a transaction amount from database
|
||
* const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
|
||
*
|
||
* const finalAmount = pipe(
|
||
* fetchTransactionAmount,
|
||
* // Log the fetched transaction amount
|
||
* Effect.tap((amount) => Console.log(`Apply a discount to: ${amount}`)),
|
||
* // `amount` is still available!
|
||
* Effect.flatMap((amount) => applyDiscount(amount, 5))
|
||
* )
|
||
*
|
||
* Effect.runPromise(finalAmount).then(console.log)
|
||
* // Output:
|
||
* // Apply a discount to: 100
|
||
* // 95
|
||
* ```
|
||
*
|
||
* @see {@link flatMap} for a version that allows you to change the value.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Sequencing
|
||
*/
|
||
<A, E, R, X, E1, R1>(self: Effect<A, E, R>, f: (a: NoInfer<A>) => Effect<X, E1, R1>, options: {
|
||
onlyEffect: true;
|
||
}): Effect<A, E | E1, R | R1>;
|
||
/**
|
||
* Runs a side effect with the result of an effect without changing the original
|
||
* value.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function works similarly to `flatMap`, but it ignores the result of the
|
||
* function passed to it. The value from the previous effect remains available
|
||
* for the next part of the chain. Note that if the side effect fails, the
|
||
* entire chain will fail too.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use this function when you want to perform a side effect, like logging or
|
||
* tracking, without modifying the main value. This is useful when you need to
|
||
* observe or record an action but want the original value to be passed to the
|
||
* next step.
|
||
*
|
||
* **Example** (Logging a step in a pipeline)
|
||
*
|
||
* ```ts
|
||
* import { Console, Effect, pipe } from "effect"
|
||
*
|
||
* // Function to apply a discount safely to a transaction amount
|
||
* const applyDiscount = (
|
||
* total: number,
|
||
* discountRate: number
|
||
* ): Effect.Effect<number, Error> =>
|
||
* discountRate === 0
|
||
* ? Effect.fail(new Error("Discount rate cannot be zero"))
|
||
* : Effect.succeed(total - (total * discountRate) / 100)
|
||
*
|
||
* // Simulated asynchronous task to fetch a transaction amount from database
|
||
* const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
|
||
*
|
||
* const finalAmount = pipe(
|
||
* fetchTransactionAmount,
|
||
* // Log the fetched transaction amount
|
||
* Effect.tap((amount) => Console.log(`Apply a discount to: ${amount}`)),
|
||
* // `amount` is still available!
|
||
* Effect.flatMap((amount) => applyDiscount(amount, 5))
|
||
* )
|
||
*
|
||
* Effect.runPromise(finalAmount).then(console.log)
|
||
* // Output:
|
||
* // Apply a discount to: 100
|
||
* // 95
|
||
* ```
|
||
*
|
||
* @see {@link flatMap} for a version that allows you to change the value.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Sequencing
|
||
*/
|
||
<A, E, R, X>(self: Effect<A, E, R>, f: NotFunction<X>): [X] extends [Effect<infer _A1, infer E1, infer R1>] ? Effect<A, E | E1, R | R1> : [X] extends [PromiseLike<infer _A1>] ? Effect<A, E | Cause.UnknownException, R> : Effect<A, E, R>;
|
||
/**
|
||
* Runs a side effect with the result of an effect without changing the original
|
||
* value.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function works similarly to `flatMap`, but it ignores the result of the
|
||
* function passed to it. The value from the previous effect remains available
|
||
* for the next part of the chain. Note that if the side effect fails, the
|
||
* entire chain will fail too.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use this function when you want to perform a side effect, like logging or
|
||
* tracking, without modifying the main value. This is useful when you need to
|
||
* observe or record an action but want the original value to be passed to the
|
||
* next step.
|
||
*
|
||
* **Example** (Logging a step in a pipeline)
|
||
*
|
||
* ```ts
|
||
* import { Console, Effect, pipe } from "effect"
|
||
*
|
||
* // Function to apply a discount safely to a transaction amount
|
||
* const applyDiscount = (
|
||
* total: number,
|
||
* discountRate: number
|
||
* ): Effect.Effect<number, Error> =>
|
||
* discountRate === 0
|
||
* ? Effect.fail(new Error("Discount rate cannot be zero"))
|
||
* : Effect.succeed(total - (total * discountRate) / 100)
|
||
*
|
||
* // Simulated asynchronous task to fetch a transaction amount from database
|
||
* const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
|
||
*
|
||
* const finalAmount = pipe(
|
||
* fetchTransactionAmount,
|
||
* // Log the fetched transaction amount
|
||
* Effect.tap((amount) => Console.log(`Apply a discount to: ${amount}`)),
|
||
* // `amount` is still available!
|
||
* Effect.flatMap((amount) => applyDiscount(amount, 5))
|
||
* )
|
||
*
|
||
* Effect.runPromise(finalAmount).then(console.log)
|
||
* // Output:
|
||
* // Apply a discount to: 100
|
||
* // 95
|
||
* ```
|
||
*
|
||
* @see {@link flatMap} for a version that allows you to change the value.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Sequencing
|
||
*/
|
||
<A, E, R, X, E1, R1>(self: Effect<A, E, R>, f: Effect<X, E1, R1>, options: {
|
||
onlyEffect: true;
|
||
}): Effect<A, E | E1, R | R1>;
|
||
};
|
||
/**
|
||
* Allows you to inspect both success and failure outcomes of an effect and
|
||
* perform side effects for each.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function enables you to handle both success and failure cases
|
||
* separately, without modifying the main effect's result. It is particularly
|
||
* useful for scenarios where you need to log, monitor, or perform additional
|
||
* actions depending on whether the effect succeeded or failed.
|
||
*
|
||
* When the effect succeeds, the `onSuccess` handler is executed with the
|
||
* success value. When the effect fails, the `onFailure` handler is executed
|
||
* with the failure value. Both handlers can include side effects such as
|
||
* logging or analytics, and neither modifies the original effect's output.
|
||
*
|
||
* If either the success or failure handler fails, the overall effect will also
|
||
* fail.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Random, Console } from "effect"
|
||
*
|
||
* // Simulate a task that might fail
|
||
* const task = Effect.filterOrFail(
|
||
* Random.nextRange(-1, 1),
|
||
* (n) => n >= 0,
|
||
* () => "random number is negative"
|
||
* )
|
||
*
|
||
* // Use tapBoth to log both success and failure outcomes
|
||
* const tapping = Effect.tapBoth(task, {
|
||
* onFailure: (error) => Console.log(`failure: ${error}`),
|
||
* onSuccess: (randomNumber) =>
|
||
* Console.log(`random number: ${randomNumber}`)
|
||
* })
|
||
*
|
||
* Effect.runFork(tapping)
|
||
* // Example Output:
|
||
* // failure: random number is negative
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Sequencing
|
||
*/
|
||
export declare const tapBoth: {
|
||
/**
|
||
* Allows you to inspect both success and failure outcomes of an effect and
|
||
* perform side effects for each.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function enables you to handle both success and failure cases
|
||
* separately, without modifying the main effect's result. It is particularly
|
||
* useful for scenarios where you need to log, monitor, or perform additional
|
||
* actions depending on whether the effect succeeded or failed.
|
||
*
|
||
* When the effect succeeds, the `onSuccess` handler is executed with the
|
||
* success value. When the effect fails, the `onFailure` handler is executed
|
||
* with the failure value. Both handlers can include side effects such as
|
||
* logging or analytics, and neither modifies the original effect's output.
|
||
*
|
||
* If either the success or failure handler fails, the overall effect will also
|
||
* fail.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Random, Console } from "effect"
|
||
*
|
||
* // Simulate a task that might fail
|
||
* const task = Effect.filterOrFail(
|
||
* Random.nextRange(-1, 1),
|
||
* (n) => n >= 0,
|
||
* () => "random number is negative"
|
||
* )
|
||
*
|
||
* // Use tapBoth to log both success and failure outcomes
|
||
* const tapping = Effect.tapBoth(task, {
|
||
* onFailure: (error) => Console.log(`failure: ${error}`),
|
||
* onSuccess: (randomNumber) =>
|
||
* Console.log(`random number: ${randomNumber}`)
|
||
* })
|
||
*
|
||
* Effect.runFork(tapping)
|
||
* // Example Output:
|
||
* // failure: random number is negative
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Sequencing
|
||
*/
|
||
<E, X, E2, R2, A, X1, E3, R3>(options: {
|
||
readonly onFailure: (e: NoInfer<E>) => Effect<X, E2, R2>;
|
||
readonly onSuccess: (a: NoInfer<A>) => Effect<X1, E3, R3>;
|
||
}): <R>(self: Effect<A, E, R>) => Effect<A, E | E2 | E3, R2 | R3 | R>;
|
||
/**
|
||
* Allows you to inspect both success and failure outcomes of an effect and
|
||
* perform side effects for each.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function enables you to handle both success and failure cases
|
||
* separately, without modifying the main effect's result. It is particularly
|
||
* useful for scenarios where you need to log, monitor, or perform additional
|
||
* actions depending on whether the effect succeeded or failed.
|
||
*
|
||
* When the effect succeeds, the `onSuccess` handler is executed with the
|
||
* success value. When the effect fails, the `onFailure` handler is executed
|
||
* with the failure value. Both handlers can include side effects such as
|
||
* logging or analytics, and neither modifies the original effect's output.
|
||
*
|
||
* If either the success or failure handler fails, the overall effect will also
|
||
* fail.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Random, Console } from "effect"
|
||
*
|
||
* // Simulate a task that might fail
|
||
* const task = Effect.filterOrFail(
|
||
* Random.nextRange(-1, 1),
|
||
* (n) => n >= 0,
|
||
* () => "random number is negative"
|
||
* )
|
||
*
|
||
* // Use tapBoth to log both success and failure outcomes
|
||
* const tapping = Effect.tapBoth(task, {
|
||
* onFailure: (error) => Console.log(`failure: ${error}`),
|
||
* onSuccess: (randomNumber) =>
|
||
* Console.log(`random number: ${randomNumber}`)
|
||
* })
|
||
*
|
||
* Effect.runFork(tapping)
|
||
* // Example Output:
|
||
* // failure: random number is negative
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Sequencing
|
||
*/
|
||
<A, E, R, X, E2, R2, X1, E3, R3>(self: Effect<A, E, R>, options: {
|
||
readonly onFailure: (e: E) => Effect<X, E2, R2>;
|
||
readonly onSuccess: (a: A) => Effect<X1, E3, R3>;
|
||
}): Effect<A, E | E2 | E3, R | R2 | R3>;
|
||
};
|
||
/**
|
||
* Inspect severe errors or defects (non-recoverable failures) in an effect.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function is specifically designed to handle and inspect defects, which
|
||
* are critical failures in your program, such as unexpected runtime exceptions
|
||
* or system-level errors. Unlike normal recoverable errors, defects typically
|
||
* indicate serious issues that cannot be addressed through standard error
|
||
* handling.
|
||
*
|
||
* When a defect occurs in an effect, the function you provide to this function
|
||
* will be executed, allowing you to log, monitor, or handle the defect in some
|
||
* way. Importantly, this does not alter the main result of the effect. If no
|
||
* defect occurs, the effect behaves as if this function was not used.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* // Simulate a task that fails with a recoverable error
|
||
* const task1: Effect.Effect<number, string> = Effect.fail("NetworkError")
|
||
*
|
||
* // tapDefect won't log anything because NetworkError is not a defect
|
||
* const tapping1 = Effect.tapDefect(task1, (cause) =>
|
||
* Console.log(`defect: ${cause}`)
|
||
* )
|
||
*
|
||
* Effect.runFork(tapping1)
|
||
* // No Output
|
||
*
|
||
* // Simulate a severe failure in the system
|
||
* const task2: Effect.Effect<number, string> = Effect.dieMessage(
|
||
* "Something went wrong"
|
||
* )
|
||
*
|
||
* // Log the defect using tapDefect
|
||
* const tapping2 = Effect.tapDefect(task2, (cause) =>
|
||
* Console.log(`defect: ${cause}`)
|
||
* )
|
||
*
|
||
* Effect.runFork(tapping2)
|
||
* // Output:
|
||
* // defect: RuntimeException: Something went wrong
|
||
* // ... stack trace ...
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Sequencing
|
||
*/
|
||
export declare const tapDefect: {
|
||
/**
|
||
* Inspect severe errors or defects (non-recoverable failures) in an effect.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function is specifically designed to handle and inspect defects, which
|
||
* are critical failures in your program, such as unexpected runtime exceptions
|
||
* or system-level errors. Unlike normal recoverable errors, defects typically
|
||
* indicate serious issues that cannot be addressed through standard error
|
||
* handling.
|
||
*
|
||
* When a defect occurs in an effect, the function you provide to this function
|
||
* will be executed, allowing you to log, monitor, or handle the defect in some
|
||
* way. Importantly, this does not alter the main result of the effect. If no
|
||
* defect occurs, the effect behaves as if this function was not used.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* // Simulate a task that fails with a recoverable error
|
||
* const task1: Effect.Effect<number, string> = Effect.fail("NetworkError")
|
||
*
|
||
* // tapDefect won't log anything because NetworkError is not a defect
|
||
* const tapping1 = Effect.tapDefect(task1, (cause) =>
|
||
* Console.log(`defect: ${cause}`)
|
||
* )
|
||
*
|
||
* Effect.runFork(tapping1)
|
||
* // No Output
|
||
*
|
||
* // Simulate a severe failure in the system
|
||
* const task2: Effect.Effect<number, string> = Effect.dieMessage(
|
||
* "Something went wrong"
|
||
* )
|
||
*
|
||
* // Log the defect using tapDefect
|
||
* const tapping2 = Effect.tapDefect(task2, (cause) =>
|
||
* Console.log(`defect: ${cause}`)
|
||
* )
|
||
*
|
||
* Effect.runFork(tapping2)
|
||
* // Output:
|
||
* // defect: RuntimeException: Something went wrong
|
||
* // ... stack trace ...
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Sequencing
|
||
*/
|
||
<X, E2, R2>(f: (cause: Cause.Cause<never>) => Effect<X, E2, R2>): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E2 | E, R2 | R>;
|
||
/**
|
||
* Inspect severe errors or defects (non-recoverable failures) in an effect.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function is specifically designed to handle and inspect defects, which
|
||
* are critical failures in your program, such as unexpected runtime exceptions
|
||
* or system-level errors. Unlike normal recoverable errors, defects typically
|
||
* indicate serious issues that cannot be addressed through standard error
|
||
* handling.
|
||
*
|
||
* When a defect occurs in an effect, the function you provide to this function
|
||
* will be executed, allowing you to log, monitor, or handle the defect in some
|
||
* way. Importantly, this does not alter the main result of the effect. If no
|
||
* defect occurs, the effect behaves as if this function was not used.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* // Simulate a task that fails with a recoverable error
|
||
* const task1: Effect.Effect<number, string> = Effect.fail("NetworkError")
|
||
*
|
||
* // tapDefect won't log anything because NetworkError is not a defect
|
||
* const tapping1 = Effect.tapDefect(task1, (cause) =>
|
||
* Console.log(`defect: ${cause}`)
|
||
* )
|
||
*
|
||
* Effect.runFork(tapping1)
|
||
* // No Output
|
||
*
|
||
* // Simulate a severe failure in the system
|
||
* const task2: Effect.Effect<number, string> = Effect.dieMessage(
|
||
* "Something went wrong"
|
||
* )
|
||
*
|
||
* // Log the defect using tapDefect
|
||
* const tapping2 = Effect.tapDefect(task2, (cause) =>
|
||
* Console.log(`defect: ${cause}`)
|
||
* )
|
||
*
|
||
* Effect.runFork(tapping2)
|
||
* // Output:
|
||
* // defect: RuntimeException: Something went wrong
|
||
* // ... stack trace ...
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Sequencing
|
||
*/
|
||
<A, E, R, X, E2, R2>(self: Effect<A, E, R>, f: (cause: Cause.Cause<never>) => Effect<X, E2, R2>): Effect<A, E | E2, R | R2>;
|
||
};
|
||
/**
|
||
* Execute a side effect on failure without modifying the original effect.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to inspect and react to the failure of an effect by
|
||
* executing an additional effect. The failure value is passed to the provided
|
||
* function, enabling you to log it, track it, or perform any other operation.
|
||
* Importantly, the original failure remains intact and is re-propagated, so the
|
||
* effect's behavior is unchanged.
|
||
*
|
||
* The side effect you provide is only executed when the effect fails. If the
|
||
* effect succeeds, the function is ignored, and the success value is propagated
|
||
* as usual.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* // Simulate a task that fails with an error
|
||
* const task: Effect.Effect<number, string> = Effect.fail("NetworkError")
|
||
*
|
||
* // Use tapError to log the error message when the task fails
|
||
* const tapping = Effect.tapError(task, (error) =>
|
||
* Console.log(`expected error: ${error}`)
|
||
* )
|
||
*
|
||
* Effect.runFork(tapping)
|
||
* // Output:
|
||
* // expected error: NetworkError
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Sequencing
|
||
*/
|
||
export declare const tapError: {
|
||
/**
|
||
* Execute a side effect on failure without modifying the original effect.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to inspect and react to the failure of an effect by
|
||
* executing an additional effect. The failure value is passed to the provided
|
||
* function, enabling you to log it, track it, or perform any other operation.
|
||
* Importantly, the original failure remains intact and is re-propagated, so the
|
||
* effect's behavior is unchanged.
|
||
*
|
||
* The side effect you provide is only executed when the effect fails. If the
|
||
* effect succeeds, the function is ignored, and the success value is propagated
|
||
* as usual.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* // Simulate a task that fails with an error
|
||
* const task: Effect.Effect<number, string> = Effect.fail("NetworkError")
|
||
*
|
||
* // Use tapError to log the error message when the task fails
|
||
* const tapping = Effect.tapError(task, (error) =>
|
||
* Console.log(`expected error: ${error}`)
|
||
* )
|
||
*
|
||
* Effect.runFork(tapping)
|
||
* // Output:
|
||
* // expected error: NetworkError
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Sequencing
|
||
*/
|
||
<E, X, E2, R2>(f: (e: NoInfer<E>) => Effect<X, E2, R2>): <A, R>(self: Effect<A, E, R>) => Effect<A, E | E2, R2 | R>;
|
||
/**
|
||
* Execute a side effect on failure without modifying the original effect.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to inspect and react to the failure of an effect by
|
||
* executing an additional effect. The failure value is passed to the provided
|
||
* function, enabling you to log it, track it, or perform any other operation.
|
||
* Importantly, the original failure remains intact and is re-propagated, so the
|
||
* effect's behavior is unchanged.
|
||
*
|
||
* The side effect you provide is only executed when the effect fails. If the
|
||
* effect succeeds, the function is ignored, and the success value is propagated
|
||
* as usual.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* // Simulate a task that fails with an error
|
||
* const task: Effect.Effect<number, string> = Effect.fail("NetworkError")
|
||
*
|
||
* // Use tapError to log the error message when the task fails
|
||
* const tapping = Effect.tapError(task, (error) =>
|
||
* Console.log(`expected error: ${error}`)
|
||
* )
|
||
*
|
||
* Effect.runFork(tapping)
|
||
* // Output:
|
||
* // expected error: NetworkError
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Sequencing
|
||
*/
|
||
<A, E, R, X, E2, R2>(self: Effect<A, E, R>, f: (e: E) => Effect<X, E2, R2>): Effect<A, E | E2, R | R2>;
|
||
};
|
||
/**
|
||
* Inspect errors matching a specific tag without altering the original effect.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to inspect and handle specific error types based on
|
||
* their `_tag` property. It is particularly useful in applications where errors
|
||
* are modeled with tagged types (e.g., union types with discriminating tags).
|
||
* By targeting errors with a specific `_tag`, you can log or perform actions on
|
||
* them while leaving the error channel and overall effect unchanged.
|
||
*
|
||
* If the error doesn't match the specified tag, this function does nothing, and
|
||
* the effect proceeds as usual.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* class NetworkError {
|
||
* readonly _tag = "NetworkError"
|
||
* constructor(readonly statusCode: number) {}
|
||
* }
|
||
*
|
||
* class ValidationError {
|
||
* readonly _tag = "ValidationError"
|
||
* constructor(readonly field: string) {}
|
||
* }
|
||
*
|
||
* // Create a task that fails with a NetworkError
|
||
* const task: Effect.Effect<number, NetworkError | ValidationError> =
|
||
* Effect.fail(new NetworkError(504))
|
||
*
|
||
* // Use tapErrorTag to inspect only NetworkError types and log the status code
|
||
* const tapping = Effect.tapErrorTag(task, "NetworkError", (error) =>
|
||
* Console.log(`expected error: ${error.statusCode}`)
|
||
* )
|
||
*
|
||
* Effect.runFork(tapping)
|
||
* // Output:
|
||
* // expected error: 504
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Sequencing
|
||
*/
|
||
export declare const tapErrorTag: {
|
||
/**
|
||
* Inspect errors matching a specific tag without altering the original effect.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to inspect and handle specific error types based on
|
||
* their `_tag` property. It is particularly useful in applications where errors
|
||
* are modeled with tagged types (e.g., union types with discriminating tags).
|
||
* By targeting errors with a specific `_tag`, you can log or perform actions on
|
||
* them while leaving the error channel and overall effect unchanged.
|
||
*
|
||
* If the error doesn't match the specified tag, this function does nothing, and
|
||
* the effect proceeds as usual.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* class NetworkError {
|
||
* readonly _tag = "NetworkError"
|
||
* constructor(readonly statusCode: number) {}
|
||
* }
|
||
*
|
||
* class ValidationError {
|
||
* readonly _tag = "ValidationError"
|
||
* constructor(readonly field: string) {}
|
||
* }
|
||
*
|
||
* // Create a task that fails with a NetworkError
|
||
* const task: Effect.Effect<number, NetworkError | ValidationError> =
|
||
* Effect.fail(new NetworkError(504))
|
||
*
|
||
* // Use tapErrorTag to inspect only NetworkError types and log the status code
|
||
* const tapping = Effect.tapErrorTag(task, "NetworkError", (error) =>
|
||
* Console.log(`expected error: ${error.statusCode}`)
|
||
* )
|
||
*
|
||
* Effect.runFork(tapping)
|
||
* // Output:
|
||
* // expected error: 504
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Sequencing
|
||
*/
|
||
<K extends E extends {
|
||
_tag: string;
|
||
} ? E["_tag"] : never, E, A1, E1, R1>(k: K, f: (e: NoInfer<Extract<E, {
|
||
_tag: K;
|
||
}>>) => Effect<A1, E1, R1>): <A, R>(self: Effect<A, E, R>) => Effect<A, E | E1, R1 | R>;
|
||
/**
|
||
* Inspect errors matching a specific tag without altering the original effect.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to inspect and handle specific error types based on
|
||
* their `_tag` property. It is particularly useful in applications where errors
|
||
* are modeled with tagged types (e.g., union types with discriminating tags).
|
||
* By targeting errors with a specific `_tag`, you can log or perform actions on
|
||
* them while leaving the error channel and overall effect unchanged.
|
||
*
|
||
* If the error doesn't match the specified tag, this function does nothing, and
|
||
* the effect proceeds as usual.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* class NetworkError {
|
||
* readonly _tag = "NetworkError"
|
||
* constructor(readonly statusCode: number) {}
|
||
* }
|
||
*
|
||
* class ValidationError {
|
||
* readonly _tag = "ValidationError"
|
||
* constructor(readonly field: string) {}
|
||
* }
|
||
*
|
||
* // Create a task that fails with a NetworkError
|
||
* const task: Effect.Effect<number, NetworkError | ValidationError> =
|
||
* Effect.fail(new NetworkError(504))
|
||
*
|
||
* // Use tapErrorTag to inspect only NetworkError types and log the status code
|
||
* const tapping = Effect.tapErrorTag(task, "NetworkError", (error) =>
|
||
* Console.log(`expected error: ${error.statusCode}`)
|
||
* )
|
||
*
|
||
* Effect.runFork(tapping)
|
||
* // Output:
|
||
* // expected error: 504
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Sequencing
|
||
*/
|
||
<A, E, R, K extends E extends {
|
||
_tag: string;
|
||
} ? E["_tag"] : never, A1, E1, R1>(self: Effect<A, E, R>, k: K, f: (e: Extract<E, {
|
||
_tag: K;
|
||
}>) => Effect<A1, E1, R1>): Effect<A, E | E1, R | R1>;
|
||
};
|
||
/**
|
||
* Inspect the complete cause of an error, including failures and defects.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function provides access to the full cause of an error, including both
|
||
* recoverable failures and irrecoverable defects. It allows you to handle, log,
|
||
* or monitor specific error causes without modifying the result of the effect.
|
||
* The full `Cause` object encapsulates the error and its contextual
|
||
* information, making it useful for debugging and understanding failure
|
||
* scenarios in complex workflows.
|
||
*
|
||
* The effect itself is not modified, and any errors or defects remain in the
|
||
* error channel of the original effect.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* // Create a task that fails with a NetworkError
|
||
* const task1: Effect.Effect<number, string> = Effect.fail("NetworkError")
|
||
*
|
||
* const tapping1 = Effect.tapErrorCause(task1, (cause) =>
|
||
* Console.log(`error cause: ${cause}`)
|
||
* )
|
||
*
|
||
* Effect.runFork(tapping1)
|
||
* // Output:
|
||
* // error cause: Error: NetworkError
|
||
*
|
||
* // Simulate a severe failure in the system
|
||
* const task2: Effect.Effect<number, string> = Effect.dieMessage(
|
||
* "Something went wrong"
|
||
* )
|
||
*
|
||
* const tapping2 = Effect.tapErrorCause(task2, (cause) =>
|
||
* Console.log(`error cause: ${cause}`)
|
||
* )
|
||
*
|
||
* Effect.runFork(tapping2)
|
||
* // Output:
|
||
* // error cause: RuntimeException: Something went wrong
|
||
* // ... stack trace ...
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Sequencing
|
||
*/
|
||
export declare const tapErrorCause: {
|
||
/**
|
||
* Inspect the complete cause of an error, including failures and defects.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function provides access to the full cause of an error, including both
|
||
* recoverable failures and irrecoverable defects. It allows you to handle, log,
|
||
* or monitor specific error causes without modifying the result of the effect.
|
||
* The full `Cause` object encapsulates the error and its contextual
|
||
* information, making it useful for debugging and understanding failure
|
||
* scenarios in complex workflows.
|
||
*
|
||
* The effect itself is not modified, and any errors or defects remain in the
|
||
* error channel of the original effect.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* // Create a task that fails with a NetworkError
|
||
* const task1: Effect.Effect<number, string> = Effect.fail("NetworkError")
|
||
*
|
||
* const tapping1 = Effect.tapErrorCause(task1, (cause) =>
|
||
* Console.log(`error cause: ${cause}`)
|
||
* )
|
||
*
|
||
* Effect.runFork(tapping1)
|
||
* // Output:
|
||
* // error cause: Error: NetworkError
|
||
*
|
||
* // Simulate a severe failure in the system
|
||
* const task2: Effect.Effect<number, string> = Effect.dieMessage(
|
||
* "Something went wrong"
|
||
* )
|
||
*
|
||
* const tapping2 = Effect.tapErrorCause(task2, (cause) =>
|
||
* Console.log(`error cause: ${cause}`)
|
||
* )
|
||
*
|
||
* Effect.runFork(tapping2)
|
||
* // Output:
|
||
* // error cause: RuntimeException: Something went wrong
|
||
* // ... stack trace ...
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Sequencing
|
||
*/
|
||
<E, X, E2, R2>(f: (cause: Cause.Cause<NoInfer<E>>) => Effect<X, E2, R2>): <A, R>(self: Effect<A, E, R>) => Effect<A, E | E2, R2 | R>;
|
||
/**
|
||
* Inspect the complete cause of an error, including failures and defects.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function provides access to the full cause of an error, including both
|
||
* recoverable failures and irrecoverable defects. It allows you to handle, log,
|
||
* or monitor specific error causes without modifying the result of the effect.
|
||
* The full `Cause` object encapsulates the error and its contextual
|
||
* information, making it useful for debugging and understanding failure
|
||
* scenarios in complex workflows.
|
||
*
|
||
* The effect itself is not modified, and any errors or defects remain in the
|
||
* error channel of the original effect.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* // Create a task that fails with a NetworkError
|
||
* const task1: Effect.Effect<number, string> = Effect.fail("NetworkError")
|
||
*
|
||
* const tapping1 = Effect.tapErrorCause(task1, (cause) =>
|
||
* Console.log(`error cause: ${cause}`)
|
||
* )
|
||
*
|
||
* Effect.runFork(tapping1)
|
||
* // Output:
|
||
* // error cause: Error: NetworkError
|
||
*
|
||
* // Simulate a severe failure in the system
|
||
* const task2: Effect.Effect<number, string> = Effect.dieMessage(
|
||
* "Something went wrong"
|
||
* )
|
||
*
|
||
* const tapping2 = Effect.tapErrorCause(task2, (cause) =>
|
||
* Console.log(`error cause: ${cause}`)
|
||
* )
|
||
*
|
||
* Effect.runFork(tapping2)
|
||
* // Output:
|
||
* // error cause: RuntimeException: Something went wrong
|
||
* // ... stack trace ...
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Sequencing
|
||
*/
|
||
<A, E, R, X, E2, R2>(self: Effect<A, E, R>, f: (cause: Cause.Cause<E>) => Effect<X, E2, R2>): Effect<A, E | E2, R | R2>;
|
||
};
|
||
/**
|
||
* Repeats an effect indefinitely until an error occurs.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function executes an effect repeatedly in an infinite loop. Each
|
||
* iteration is executed sequentially, and the loop continues until the first
|
||
* error occurs. If the effect succeeds, it starts over from the beginning. If
|
||
* the effect fails, the error is propagated, and the loop stops.
|
||
*
|
||
* Be cautious when using this function, as it will run indefinitely unless an
|
||
* error interrupts it. This makes it suitable for long-running processes or
|
||
* continuous polling tasks, but you should ensure proper error handling or
|
||
* combine it with other operators like `timeout` or `schedule` to prevent
|
||
* unintentional infinite loops.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Repetition / Recursion
|
||
*/
|
||
export declare const forever: <A, E, R>(self: Effect<A, E, R>) => Effect<never, E, R>;
|
||
/**
|
||
* Repeatedly updates a state through an effectful operation until a condition
|
||
* is no longer met.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function provides a way to implement effectful loops, similar to a
|
||
* `while` loop in JavaScript.
|
||
*
|
||
* ```ts skip-type-checking
|
||
* let result = initial
|
||
*
|
||
* while (options.while(result)) {
|
||
* result = options.body(result)
|
||
* }
|
||
*
|
||
* return result
|
||
* ```
|
||
*
|
||
* It starts with an initial state, checks a
|
||
* condition (`while`), and executes a body operation to update the state if the
|
||
* condition evaluates to `true`. The process repeats until the condition
|
||
* returns `false`.
|
||
*
|
||
* The state is passed between iterations, allowing the body operation to modify
|
||
* it dynamically. The final state after the loop ends is returned as the result
|
||
* of the effect.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is particularly useful for scenarios where looping logic involves
|
||
* asynchronous or side-effectful operations, such as polling or iterative
|
||
* computations that depend on external factors.
|
||
*
|
||
* **Example** (Effectful Iteration)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const result = Effect.iterate(
|
||
* // Initial result
|
||
* 1,
|
||
* {
|
||
* // Condition to continue iterating
|
||
* while: (result) => result <= 5,
|
||
* // Operation to change the result
|
||
* body: (result) => Effect.succeed(result + 1)
|
||
* }
|
||
* )
|
||
*
|
||
* Effect.runPromise(result).then(console.log)
|
||
* // Output: 6
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Looping
|
||
*/
|
||
export declare const iterate: {
|
||
/**
|
||
* Repeatedly updates a state through an effectful operation until a condition
|
||
* is no longer met.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function provides a way to implement effectful loops, similar to a
|
||
* `while` loop in JavaScript.
|
||
*
|
||
* ```ts skip-type-checking
|
||
* let result = initial
|
||
*
|
||
* while (options.while(result)) {
|
||
* result = options.body(result)
|
||
* }
|
||
*
|
||
* return result
|
||
* ```
|
||
*
|
||
* It starts with an initial state, checks a
|
||
* condition (`while`), and executes a body operation to update the state if the
|
||
* condition evaluates to `true`. The process repeats until the condition
|
||
* returns `false`.
|
||
*
|
||
* The state is passed between iterations, allowing the body operation to modify
|
||
* it dynamically. The final state after the loop ends is returned as the result
|
||
* of the effect.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is particularly useful for scenarios where looping logic involves
|
||
* asynchronous or side-effectful operations, such as polling or iterative
|
||
* computations that depend on external factors.
|
||
*
|
||
* **Example** (Effectful Iteration)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const result = Effect.iterate(
|
||
* // Initial result
|
||
* 1,
|
||
* {
|
||
* // Condition to continue iterating
|
||
* while: (result) => result <= 5,
|
||
* // Operation to change the result
|
||
* body: (result) => Effect.succeed(result + 1)
|
||
* }
|
||
* )
|
||
*
|
||
* Effect.runPromise(result).then(console.log)
|
||
* // Output: 6
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Looping
|
||
*/
|
||
<A, B extends A, R, E>(initial: A, options: {
|
||
readonly while: Refinement<A, B>;
|
||
readonly body: (b: B) => Effect<A, E, R>;
|
||
}): Effect<A, E, R>;
|
||
/**
|
||
* Repeatedly updates a state through an effectful operation until a condition
|
||
* is no longer met.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function provides a way to implement effectful loops, similar to a
|
||
* `while` loop in JavaScript.
|
||
*
|
||
* ```ts skip-type-checking
|
||
* let result = initial
|
||
*
|
||
* while (options.while(result)) {
|
||
* result = options.body(result)
|
||
* }
|
||
*
|
||
* return result
|
||
* ```
|
||
*
|
||
* It starts with an initial state, checks a
|
||
* condition (`while`), and executes a body operation to update the state if the
|
||
* condition evaluates to `true`. The process repeats until the condition
|
||
* returns `false`.
|
||
*
|
||
* The state is passed between iterations, allowing the body operation to modify
|
||
* it dynamically. The final state after the loop ends is returned as the result
|
||
* of the effect.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is particularly useful for scenarios where looping logic involves
|
||
* asynchronous or side-effectful operations, such as polling or iterative
|
||
* computations that depend on external factors.
|
||
*
|
||
* **Example** (Effectful Iteration)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const result = Effect.iterate(
|
||
* // Initial result
|
||
* 1,
|
||
* {
|
||
* // Condition to continue iterating
|
||
* while: (result) => result <= 5,
|
||
* // Operation to change the result
|
||
* body: (result) => Effect.succeed(result + 1)
|
||
* }
|
||
* )
|
||
*
|
||
* Effect.runPromise(result).then(console.log)
|
||
* // Output: 6
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Looping
|
||
*/
|
||
<A, R, E>(initial: A, options: {
|
||
readonly while: Predicate<A>;
|
||
readonly body: (a: A) => Effect<A, E, R>;
|
||
}): Effect<A, E, R>;
|
||
};
|
||
/**
|
||
* Repeatedly executes a loop with a state, collecting results or discarding
|
||
* them based on configuration.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function performs an effectful loop, starting with an initial state and
|
||
* iterating as long as the `while` condition evaluates to `true`, similar to a
|
||
* `while` loop in JavaScript.
|
||
*
|
||
* ```ts skip-type-checking
|
||
* let state = initial
|
||
* const result = []
|
||
*
|
||
* while (options.while(state)) {
|
||
* result.push(options.body(state)) // Perform the effectful operation
|
||
* state = options.step(state) // Update the state
|
||
* }
|
||
*
|
||
* return result
|
||
* ```
|
||
*
|
||
* During each iteration, the `step` function updates the state, and the `body`
|
||
* effect is executed.
|
||
*
|
||
* The results of the body effect can be collected in an array or discarded
|
||
* based on the `discard` option.
|
||
*
|
||
* **Discarding Intermediate Results**
|
||
*
|
||
* - If `discard` is `false` or not provided, the intermediate results are
|
||
* collected into an array and returned as the final result.
|
||
* - If `discard` is `true`, the intermediate results are ignored, and the
|
||
* effect returns `void`.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is useful for implementing loops where you need to perform effectful
|
||
* computations repeatedly, such as processing items in a list, generating
|
||
* values, or performing iterative updates.
|
||
*
|
||
* **Example** (Looping with Collected Results)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* // A loop that runs 5 times, collecting each iteration's result
|
||
* const result = Effect.loop(
|
||
* // Initial state
|
||
* 1,
|
||
* {
|
||
* // Condition to continue looping
|
||
* while: (state) => state <= 5,
|
||
* // State update function
|
||
* step: (state) => state + 1,
|
||
* // Effect to be performed on each iteration
|
||
* body: (state) => Effect.succeed(state)
|
||
* }
|
||
* )
|
||
*
|
||
* Effect.runPromise(result).then(console.log)
|
||
* // Output: [1, 2, 3, 4, 5]
|
||
* ```
|
||
*
|
||
* **Example** (Loop with Discarded Results)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* const result = Effect.loop(
|
||
* // Initial state
|
||
* 1,
|
||
* {
|
||
* // Condition to continue looping
|
||
* while: (state) => state <= 5,
|
||
* // State update function
|
||
* step: (state) => state + 1,
|
||
* // Effect to be performed on each iteration
|
||
* body: (state) => Console.log(`Currently at state ${state}`),
|
||
* // Discard intermediate results
|
||
* discard: true
|
||
* }
|
||
* )
|
||
*
|
||
* Effect.runPromise(result).then(console.log)
|
||
* // Output:
|
||
* // Currently at state 1
|
||
* // Currently at state 2
|
||
* // Currently at state 3
|
||
* // Currently at state 4
|
||
* // Currently at state 5
|
||
* // undefined
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Looping
|
||
*/
|
||
export declare const loop: {
|
||
/**
|
||
* Repeatedly executes a loop with a state, collecting results or discarding
|
||
* them based on configuration.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function performs an effectful loop, starting with an initial state and
|
||
* iterating as long as the `while` condition evaluates to `true`, similar to a
|
||
* `while` loop in JavaScript.
|
||
*
|
||
* ```ts skip-type-checking
|
||
* let state = initial
|
||
* const result = []
|
||
*
|
||
* while (options.while(state)) {
|
||
* result.push(options.body(state)) // Perform the effectful operation
|
||
* state = options.step(state) // Update the state
|
||
* }
|
||
*
|
||
* return result
|
||
* ```
|
||
*
|
||
* During each iteration, the `step` function updates the state, and the `body`
|
||
* effect is executed.
|
||
*
|
||
* The results of the body effect can be collected in an array or discarded
|
||
* based on the `discard` option.
|
||
*
|
||
* **Discarding Intermediate Results**
|
||
*
|
||
* - If `discard` is `false` or not provided, the intermediate results are
|
||
* collected into an array and returned as the final result.
|
||
* - If `discard` is `true`, the intermediate results are ignored, and the
|
||
* effect returns `void`.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is useful for implementing loops where you need to perform effectful
|
||
* computations repeatedly, such as processing items in a list, generating
|
||
* values, or performing iterative updates.
|
||
*
|
||
* **Example** (Looping with Collected Results)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* // A loop that runs 5 times, collecting each iteration's result
|
||
* const result = Effect.loop(
|
||
* // Initial state
|
||
* 1,
|
||
* {
|
||
* // Condition to continue looping
|
||
* while: (state) => state <= 5,
|
||
* // State update function
|
||
* step: (state) => state + 1,
|
||
* // Effect to be performed on each iteration
|
||
* body: (state) => Effect.succeed(state)
|
||
* }
|
||
* )
|
||
*
|
||
* Effect.runPromise(result).then(console.log)
|
||
* // Output: [1, 2, 3, 4, 5]
|
||
* ```
|
||
*
|
||
* **Example** (Loop with Discarded Results)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* const result = Effect.loop(
|
||
* // Initial state
|
||
* 1,
|
||
* {
|
||
* // Condition to continue looping
|
||
* while: (state) => state <= 5,
|
||
* // State update function
|
||
* step: (state) => state + 1,
|
||
* // Effect to be performed on each iteration
|
||
* body: (state) => Console.log(`Currently at state ${state}`),
|
||
* // Discard intermediate results
|
||
* discard: true
|
||
* }
|
||
* )
|
||
*
|
||
* Effect.runPromise(result).then(console.log)
|
||
* // Output:
|
||
* // Currently at state 1
|
||
* // Currently at state 2
|
||
* // Currently at state 3
|
||
* // Currently at state 4
|
||
* // Currently at state 5
|
||
* // undefined
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Looping
|
||
*/
|
||
<A, B extends A, C, E, R>(initial: A, options: {
|
||
readonly while: Refinement<A, B>;
|
||
readonly step: (b: B) => A;
|
||
readonly body: (b: B) => Effect<C, E, R>;
|
||
readonly discard?: false | undefined;
|
||
}): Effect<Array<C>, E, R>;
|
||
/**
|
||
* Repeatedly executes a loop with a state, collecting results or discarding
|
||
* them based on configuration.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function performs an effectful loop, starting with an initial state and
|
||
* iterating as long as the `while` condition evaluates to `true`, similar to a
|
||
* `while` loop in JavaScript.
|
||
*
|
||
* ```ts skip-type-checking
|
||
* let state = initial
|
||
* const result = []
|
||
*
|
||
* while (options.while(state)) {
|
||
* result.push(options.body(state)) // Perform the effectful operation
|
||
* state = options.step(state) // Update the state
|
||
* }
|
||
*
|
||
* return result
|
||
* ```
|
||
*
|
||
* During each iteration, the `step` function updates the state, and the `body`
|
||
* effect is executed.
|
||
*
|
||
* The results of the body effect can be collected in an array or discarded
|
||
* based on the `discard` option.
|
||
*
|
||
* **Discarding Intermediate Results**
|
||
*
|
||
* - If `discard` is `false` or not provided, the intermediate results are
|
||
* collected into an array and returned as the final result.
|
||
* - If `discard` is `true`, the intermediate results are ignored, and the
|
||
* effect returns `void`.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is useful for implementing loops where you need to perform effectful
|
||
* computations repeatedly, such as processing items in a list, generating
|
||
* values, or performing iterative updates.
|
||
*
|
||
* **Example** (Looping with Collected Results)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* // A loop that runs 5 times, collecting each iteration's result
|
||
* const result = Effect.loop(
|
||
* // Initial state
|
||
* 1,
|
||
* {
|
||
* // Condition to continue looping
|
||
* while: (state) => state <= 5,
|
||
* // State update function
|
||
* step: (state) => state + 1,
|
||
* // Effect to be performed on each iteration
|
||
* body: (state) => Effect.succeed(state)
|
||
* }
|
||
* )
|
||
*
|
||
* Effect.runPromise(result).then(console.log)
|
||
* // Output: [1, 2, 3, 4, 5]
|
||
* ```
|
||
*
|
||
* **Example** (Loop with Discarded Results)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* const result = Effect.loop(
|
||
* // Initial state
|
||
* 1,
|
||
* {
|
||
* // Condition to continue looping
|
||
* while: (state) => state <= 5,
|
||
* // State update function
|
||
* step: (state) => state + 1,
|
||
* // Effect to be performed on each iteration
|
||
* body: (state) => Console.log(`Currently at state ${state}`),
|
||
* // Discard intermediate results
|
||
* discard: true
|
||
* }
|
||
* )
|
||
*
|
||
* Effect.runPromise(result).then(console.log)
|
||
* // Output:
|
||
* // Currently at state 1
|
||
* // Currently at state 2
|
||
* // Currently at state 3
|
||
* // Currently at state 4
|
||
* // Currently at state 5
|
||
* // undefined
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Looping
|
||
*/
|
||
<A, C, E, R>(initial: A, options: {
|
||
readonly while: (a: A) => boolean;
|
||
readonly step: (a: A) => A;
|
||
readonly body: (a: A) => Effect<C, E, R>;
|
||
readonly discard?: false | undefined;
|
||
}): Effect<Array<C>, E, R>;
|
||
/**
|
||
* Repeatedly executes a loop with a state, collecting results or discarding
|
||
* them based on configuration.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function performs an effectful loop, starting with an initial state and
|
||
* iterating as long as the `while` condition evaluates to `true`, similar to a
|
||
* `while` loop in JavaScript.
|
||
*
|
||
* ```ts skip-type-checking
|
||
* let state = initial
|
||
* const result = []
|
||
*
|
||
* while (options.while(state)) {
|
||
* result.push(options.body(state)) // Perform the effectful operation
|
||
* state = options.step(state) // Update the state
|
||
* }
|
||
*
|
||
* return result
|
||
* ```
|
||
*
|
||
* During each iteration, the `step` function updates the state, and the `body`
|
||
* effect is executed.
|
||
*
|
||
* The results of the body effect can be collected in an array or discarded
|
||
* based on the `discard` option.
|
||
*
|
||
* **Discarding Intermediate Results**
|
||
*
|
||
* - If `discard` is `false` or not provided, the intermediate results are
|
||
* collected into an array and returned as the final result.
|
||
* - If `discard` is `true`, the intermediate results are ignored, and the
|
||
* effect returns `void`.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is useful for implementing loops where you need to perform effectful
|
||
* computations repeatedly, such as processing items in a list, generating
|
||
* values, or performing iterative updates.
|
||
*
|
||
* **Example** (Looping with Collected Results)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* // A loop that runs 5 times, collecting each iteration's result
|
||
* const result = Effect.loop(
|
||
* // Initial state
|
||
* 1,
|
||
* {
|
||
* // Condition to continue looping
|
||
* while: (state) => state <= 5,
|
||
* // State update function
|
||
* step: (state) => state + 1,
|
||
* // Effect to be performed on each iteration
|
||
* body: (state) => Effect.succeed(state)
|
||
* }
|
||
* )
|
||
*
|
||
* Effect.runPromise(result).then(console.log)
|
||
* // Output: [1, 2, 3, 4, 5]
|
||
* ```
|
||
*
|
||
* **Example** (Loop with Discarded Results)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* const result = Effect.loop(
|
||
* // Initial state
|
||
* 1,
|
||
* {
|
||
* // Condition to continue looping
|
||
* while: (state) => state <= 5,
|
||
* // State update function
|
||
* step: (state) => state + 1,
|
||
* // Effect to be performed on each iteration
|
||
* body: (state) => Console.log(`Currently at state ${state}`),
|
||
* // Discard intermediate results
|
||
* discard: true
|
||
* }
|
||
* )
|
||
*
|
||
* Effect.runPromise(result).then(console.log)
|
||
* // Output:
|
||
* // Currently at state 1
|
||
* // Currently at state 2
|
||
* // Currently at state 3
|
||
* // Currently at state 4
|
||
* // Currently at state 5
|
||
* // undefined
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Looping
|
||
*/
|
||
<A, B extends A, C, E, R>(initial: A, options: {
|
||
readonly while: Refinement<A, B>;
|
||
readonly step: (b: B) => A;
|
||
readonly body: (b: B) => Effect<C, E, R>;
|
||
readonly discard: true;
|
||
}): Effect<void, E, R>;
|
||
/**
|
||
* Repeatedly executes a loop with a state, collecting results or discarding
|
||
* them based on configuration.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function performs an effectful loop, starting with an initial state and
|
||
* iterating as long as the `while` condition evaluates to `true`, similar to a
|
||
* `while` loop in JavaScript.
|
||
*
|
||
* ```ts skip-type-checking
|
||
* let state = initial
|
||
* const result = []
|
||
*
|
||
* while (options.while(state)) {
|
||
* result.push(options.body(state)) // Perform the effectful operation
|
||
* state = options.step(state) // Update the state
|
||
* }
|
||
*
|
||
* return result
|
||
* ```
|
||
*
|
||
* During each iteration, the `step` function updates the state, and the `body`
|
||
* effect is executed.
|
||
*
|
||
* The results of the body effect can be collected in an array or discarded
|
||
* based on the `discard` option.
|
||
*
|
||
* **Discarding Intermediate Results**
|
||
*
|
||
* - If `discard` is `false` or not provided, the intermediate results are
|
||
* collected into an array and returned as the final result.
|
||
* - If `discard` is `true`, the intermediate results are ignored, and the
|
||
* effect returns `void`.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is useful for implementing loops where you need to perform effectful
|
||
* computations repeatedly, such as processing items in a list, generating
|
||
* values, or performing iterative updates.
|
||
*
|
||
* **Example** (Looping with Collected Results)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* // A loop that runs 5 times, collecting each iteration's result
|
||
* const result = Effect.loop(
|
||
* // Initial state
|
||
* 1,
|
||
* {
|
||
* // Condition to continue looping
|
||
* while: (state) => state <= 5,
|
||
* // State update function
|
||
* step: (state) => state + 1,
|
||
* // Effect to be performed on each iteration
|
||
* body: (state) => Effect.succeed(state)
|
||
* }
|
||
* )
|
||
*
|
||
* Effect.runPromise(result).then(console.log)
|
||
* // Output: [1, 2, 3, 4, 5]
|
||
* ```
|
||
*
|
||
* **Example** (Loop with Discarded Results)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* const result = Effect.loop(
|
||
* // Initial state
|
||
* 1,
|
||
* {
|
||
* // Condition to continue looping
|
||
* while: (state) => state <= 5,
|
||
* // State update function
|
||
* step: (state) => state + 1,
|
||
* // Effect to be performed on each iteration
|
||
* body: (state) => Console.log(`Currently at state ${state}`),
|
||
* // Discard intermediate results
|
||
* discard: true
|
||
* }
|
||
* )
|
||
*
|
||
* Effect.runPromise(result).then(console.log)
|
||
* // Output:
|
||
* // Currently at state 1
|
||
* // Currently at state 2
|
||
* // Currently at state 3
|
||
* // Currently at state 4
|
||
* // Currently at state 5
|
||
* // undefined
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Looping
|
||
*/
|
||
<A, C, E, R>(initial: A, options: {
|
||
readonly while: (a: A) => boolean;
|
||
readonly step: (a: A) => A;
|
||
readonly body: (a: A) => Effect<C, E, R>;
|
||
readonly discard: true;
|
||
}): Effect<void, E, R>;
|
||
};
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Repetition / Recursion
|
||
*/
|
||
export declare namespace Repeat {
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Repetition / Recursion
|
||
*/
|
||
type Return<R, E, A, O extends NoExcessProperties<Options<A>, O>> = Effect<(O extends {
|
||
schedule: Schedule.Schedule<infer Out, infer _I, infer _R>;
|
||
} ? Out : O extends {
|
||
until: Refinement<A, infer B>;
|
||
} ? B : A), E | (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.Schedule<infer _O, infer _I, infer R>;
|
||
} ? R : never) | (O extends {
|
||
while: (...args: Array<any>) => Effect<infer _A, infer _E, infer R>;
|
||
} ? R : never) | (O extends {
|
||
until: (...args: Array<any>) => Effect<infer _A, infer _E, infer R>;
|
||
} ? R : never)> extends infer Z ? Z : never;
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Repetition / Recursion
|
||
*/
|
||
interface Options<A> {
|
||
while?: ((_: A) => boolean | Effect<boolean, any, any>) | undefined;
|
||
until?: ((_: A) => boolean | Effect<boolean, any, any>) | undefined;
|
||
times?: number | undefined;
|
||
schedule?: Schedule.Schedule<any, A, any> | undefined;
|
||
}
|
||
}
|
||
/**
|
||
* Repeats an effect based on a specified schedule or until the first failure.
|
||
*
|
||
* **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.
|
||
*
|
||
* **Example** (Success Example)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Schedule, Console } from "effect"
|
||
*
|
||
* const action = Console.log("success")
|
||
* const policy = Schedule.addDelay(Schedule.recurs(2), () => "100 millis")
|
||
* const program = Effect.repeat(action, policy)
|
||
*
|
||
* Effect.runPromise(program).then((n) => console.log(`repetitions: ${n}`))
|
||
* ```
|
||
*
|
||
* **Example** (Failure Example)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Schedule } from "effect"
|
||
*
|
||
* let count = 0
|
||
*
|
||
* // Define an async effect that simulates an action with possible failures
|
||
* const action = Effect.async<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), () => "100 millis")
|
||
* const program = Effect.repeat(action, policy)
|
||
*
|
||
* Effect.runPromiseExit(program).then(console.log)
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Repetition / Recursion
|
||
*/
|
||
export declare const repeat: {
|
||
/**
|
||
* Repeats an effect based on a specified schedule or until the first failure.
|
||
*
|
||
* **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.
|
||
*
|
||
* **Example** (Success Example)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Schedule, Console } from "effect"
|
||
*
|
||
* const action = Console.log("success")
|
||
* const policy = Schedule.addDelay(Schedule.recurs(2), () => "100 millis")
|
||
* const program = Effect.repeat(action, policy)
|
||
*
|
||
* Effect.runPromise(program).then((n) => console.log(`repetitions: ${n}`))
|
||
* ```
|
||
*
|
||
* **Example** (Failure Example)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Schedule } from "effect"
|
||
*
|
||
* let count = 0
|
||
*
|
||
* // Define an async effect that simulates an action with possible failures
|
||
* const action = Effect.async<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), () => "100 millis")
|
||
* const program = Effect.repeat(action, policy)
|
||
*
|
||
* Effect.runPromiseExit(program).then(console.log)
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Repetition / Recursion
|
||
*/
|
||
<O extends NoExcessProperties<Repeat.Options<A>, O>, A>(options: O): <E, R>(self: Effect<A, E, R>) => Repeat.Return<R, E, A, O>;
|
||
/**
|
||
* Repeats an effect based on a specified schedule or until the first failure.
|
||
*
|
||
* **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.
|
||
*
|
||
* **Example** (Success Example)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Schedule, Console } from "effect"
|
||
*
|
||
* const action = Console.log("success")
|
||
* const policy = Schedule.addDelay(Schedule.recurs(2), () => "100 millis")
|
||
* const program = Effect.repeat(action, policy)
|
||
*
|
||
* Effect.runPromise(program).then((n) => console.log(`repetitions: ${n}`))
|
||
* ```
|
||
*
|
||
* **Example** (Failure Example)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Schedule } from "effect"
|
||
*
|
||
* let count = 0
|
||
*
|
||
* // Define an async effect that simulates an action with possible failures
|
||
* const action = Effect.async<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), () => "100 millis")
|
||
* const program = Effect.repeat(action, policy)
|
||
*
|
||
* Effect.runPromiseExit(program).then(console.log)
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Repetition / Recursion
|
||
*/
|
||
<B, A, R1>(schedule: Schedule.Schedule<B, A, R1>): <E, R>(self: Effect<A, E, R>) => Effect<B, E, R1 | R>;
|
||
/**
|
||
* Repeats an effect based on a specified schedule or until the first failure.
|
||
*
|
||
* **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.
|
||
*
|
||
* **Example** (Success Example)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Schedule, Console } from "effect"
|
||
*
|
||
* const action = Console.log("success")
|
||
* const policy = Schedule.addDelay(Schedule.recurs(2), () => "100 millis")
|
||
* const program = Effect.repeat(action, policy)
|
||
*
|
||
* Effect.runPromise(program).then((n) => console.log(`repetitions: ${n}`))
|
||
* ```
|
||
*
|
||
* **Example** (Failure Example)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Schedule } from "effect"
|
||
*
|
||
* let count = 0
|
||
*
|
||
* // Define an async effect that simulates an action with possible failures
|
||
* const action = Effect.async<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), () => "100 millis")
|
||
* const program = Effect.repeat(action, policy)
|
||
*
|
||
* Effect.runPromiseExit(program).then(console.log)
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Repetition / Recursion
|
||
*/
|
||
<A, E, R, O extends NoExcessProperties<Repeat.Options<A>, O>>(self: Effect<A, E, R>, options: O): Repeat.Return<R, E, A, O>;
|
||
/**
|
||
* Repeats an effect based on a specified schedule or until the first failure.
|
||
*
|
||
* **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.
|
||
*
|
||
* **Example** (Success Example)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Schedule, Console } from "effect"
|
||
*
|
||
* const action = Console.log("success")
|
||
* const policy = Schedule.addDelay(Schedule.recurs(2), () => "100 millis")
|
||
* const program = Effect.repeat(action, policy)
|
||
*
|
||
* Effect.runPromise(program).then((n) => console.log(`repetitions: ${n}`))
|
||
* ```
|
||
*
|
||
* **Example** (Failure Example)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Schedule } from "effect"
|
||
*
|
||
* let count = 0
|
||
*
|
||
* // Define an async effect that simulates an action with possible failures
|
||
* const action = Effect.async<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), () => "100 millis")
|
||
* const program = Effect.repeat(action, policy)
|
||
*
|
||
* Effect.runPromiseExit(program).then(console.log)
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Repetition / Recursion
|
||
*/
|
||
<A, E, R, B, R1>(self: Effect<A, E, R>, schedule: Schedule.Schedule<B, A, R1>): Effect<B, E, R | R1>;
|
||
};
|
||
/**
|
||
* Repeats an effect a specified number of times or until the first failure.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function executes an effect initially and then repeats it the specified
|
||
* number of times, as long as it succeeds. For example, calling
|
||
* `repeatN(action, 2)` will execute `action` once initially and then repeat it
|
||
* two additional times if there are no failures.
|
||
*
|
||
* If the effect fails during any repetition, the failure is returned, and no
|
||
* further repetitions are attempted.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This function is useful for tasks that need to be retried a fixed number of
|
||
* times or for performing repeated actions without requiring a schedule.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* const action = Console.log("success")
|
||
* const program = Effect.repeatN(action, 2)
|
||
*
|
||
* Effect.runPromise(program)
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Repetition / Recursion
|
||
*/
|
||
export declare const repeatN: {
|
||
/**
|
||
* Repeats an effect a specified number of times or until the first failure.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function executes an effect initially and then repeats it the specified
|
||
* number of times, as long as it succeeds. For example, calling
|
||
* `repeatN(action, 2)` will execute `action` once initially and then repeat it
|
||
* two additional times if there are no failures.
|
||
*
|
||
* If the effect fails during any repetition, the failure is returned, and no
|
||
* further repetitions are attempted.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This function is useful for tasks that need to be retried a fixed number of
|
||
* times or for performing repeated actions without requiring a schedule.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* const action = Console.log("success")
|
||
* const program = Effect.repeatN(action, 2)
|
||
*
|
||
* Effect.runPromise(program)
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Repetition / Recursion
|
||
*/
|
||
(n: number): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, R>;
|
||
/**
|
||
* Repeats an effect a specified number of times or until the first failure.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function executes an effect initially and then repeats it the specified
|
||
* number of times, as long as it succeeds. For example, calling
|
||
* `repeatN(action, 2)` will execute `action` once initially and then repeat it
|
||
* two additional times if there are no failures.
|
||
*
|
||
* If the effect fails during any repetition, the failure is returned, and no
|
||
* further repetitions are attempted.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This function is useful for tasks that need to be retried a fixed number of
|
||
* times or for performing repeated actions without requiring a schedule.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* const action = Console.log("success")
|
||
* const program = Effect.repeatN(action, 2)
|
||
*
|
||
* Effect.runPromise(program)
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Repetition / Recursion
|
||
*/
|
||
<A, E, R>(self: Effect<A, E, R>, n: number): Effect<A, E, R>;
|
||
};
|
||
/**
|
||
* Repeats an effect with a schedule, handling failures using a custom handler.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to execute an effect repeatedly based on a specified
|
||
* schedule. If the effect fails at any point, a custom failure handler is
|
||
* invoked. The handler is provided with both the failure value and the output
|
||
* of the schedule at the time of failure. This enables advanced error recovery
|
||
* or alternative fallback logic while maintaining flexibility in how
|
||
* repetitions are handled.
|
||
*
|
||
* For example, using a schedule with `recurs(2)` will allow for two additional
|
||
* repetitions after the initial execution, provided the effect succeeds. If a
|
||
* failure occurs during any iteration, the failure handler is invoked to handle
|
||
* the situation.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Schedule } from "effect"
|
||
*
|
||
* let count = 0
|
||
*
|
||
* // Define an async effect that simulates an action with possible failures
|
||
* const action = Effect.async<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), // Repeat for a maximum of 2 times
|
||
* () => "100 millis" // Add a delay of 100 milliseconds between repetitions
|
||
* )
|
||
*
|
||
* const program = Effect.repeatOrElse(action, policy, () =>
|
||
* Effect.sync(() => {
|
||
* console.log("orElse")
|
||
* return count - 1
|
||
* })
|
||
* )
|
||
*
|
||
* Effect.runPromise(program).then((n) => console.log(`repetitions: ${n}`))
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Repetition / Recursion
|
||
*/
|
||
export declare const repeatOrElse: {
|
||
/**
|
||
* Repeats an effect with a schedule, handling failures using a custom handler.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to execute an effect repeatedly based on a specified
|
||
* schedule. If the effect fails at any point, a custom failure handler is
|
||
* invoked. The handler is provided with both the failure value and the output
|
||
* of the schedule at the time of failure. This enables advanced error recovery
|
||
* or alternative fallback logic while maintaining flexibility in how
|
||
* repetitions are handled.
|
||
*
|
||
* For example, using a schedule with `recurs(2)` will allow for two additional
|
||
* repetitions after the initial execution, provided the effect succeeds. If a
|
||
* failure occurs during any iteration, the failure handler is invoked to handle
|
||
* the situation.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Schedule } from "effect"
|
||
*
|
||
* let count = 0
|
||
*
|
||
* // Define an async effect that simulates an action with possible failures
|
||
* const action = Effect.async<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), // Repeat for a maximum of 2 times
|
||
* () => "100 millis" // Add a delay of 100 milliseconds between repetitions
|
||
* )
|
||
*
|
||
* const program = Effect.repeatOrElse(action, policy, () =>
|
||
* Effect.sync(() => {
|
||
* console.log("orElse")
|
||
* return count - 1
|
||
* })
|
||
* )
|
||
*
|
||
* Effect.runPromise(program).then((n) => console.log(`repetitions: ${n}`))
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Repetition / Recursion
|
||
*/
|
||
<R2, A, B, E, E2, R3>(schedule: Schedule.Schedule<B, A, R2>, orElse: (error: E, option: Option.Option<B>) => Effect<B, E2, R3>): <R>(self: Effect<A, E, R>) => Effect<B, E2, R2 | R3 | R>;
|
||
/**
|
||
* Repeats an effect with a schedule, handling failures using a custom handler.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to execute an effect repeatedly based on a specified
|
||
* schedule. If the effect fails at any point, a custom failure handler is
|
||
* invoked. The handler is provided with both the failure value and the output
|
||
* of the schedule at the time of failure. This enables advanced error recovery
|
||
* or alternative fallback logic while maintaining flexibility in how
|
||
* repetitions are handled.
|
||
*
|
||
* For example, using a schedule with `recurs(2)` will allow for two additional
|
||
* repetitions after the initial execution, provided the effect succeeds. If a
|
||
* failure occurs during any iteration, the failure handler is invoked to handle
|
||
* the situation.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Schedule } from "effect"
|
||
*
|
||
* let count = 0
|
||
*
|
||
* // Define an async effect that simulates an action with possible failures
|
||
* const action = Effect.async<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), // Repeat for a maximum of 2 times
|
||
* () => "100 millis" // Add a delay of 100 milliseconds between repetitions
|
||
* )
|
||
*
|
||
* const program = Effect.repeatOrElse(action, policy, () =>
|
||
* Effect.sync(() => {
|
||
* console.log("orElse")
|
||
* return count - 1
|
||
* })
|
||
* )
|
||
*
|
||
* Effect.runPromise(program).then((n) => console.log(`repetitions: ${n}`))
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Repetition / Recursion
|
||
*/
|
||
<A, E, R, R2, B, E2, R3>(self: Effect<A, E, R>, schedule: Schedule.Schedule<B, A, R2>, orElse: (error: E, option: Option.Option<B>) => Effect<B, E2, R3>): Effect<B, E2, R | R2 | R3>;
|
||
};
|
||
/**
|
||
* Repeats an effect based on a specified schedule.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to execute an effect repeatedly according to a given
|
||
* schedule. The schedule determines the timing and number of repetitions. Each
|
||
* repetition can also depend on the decision of the schedule, providing
|
||
* flexibility for complex workflows. This function does not modify the effect's
|
||
* success or failure; it only controls its repetition.
|
||
*
|
||
* For example, you can use a schedule that recurs a specific number of times,
|
||
* adds delays between repetitions, or customizes repetition behavior based on
|
||
* external inputs. The effect runs initially and is repeated according to the
|
||
* schedule.
|
||
*
|
||
* @see {@link scheduleFrom} for a variant that allows the schedule's decision
|
||
* to depend on the result of this effect.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Repetition / Recursion
|
||
*/
|
||
export declare const schedule: {
|
||
/**
|
||
* Repeats an effect based on a specified schedule.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to execute an effect repeatedly according to a given
|
||
* schedule. The schedule determines the timing and number of repetitions. Each
|
||
* repetition can also depend on the decision of the schedule, providing
|
||
* flexibility for complex workflows. This function does not modify the effect's
|
||
* success or failure; it only controls its repetition.
|
||
*
|
||
* For example, you can use a schedule that recurs a specific number of times,
|
||
* adds delays between repetitions, or customizes repetition behavior based on
|
||
* external inputs. The effect runs initially and is repeated according to the
|
||
* schedule.
|
||
*
|
||
* @see {@link scheduleFrom} for a variant that allows the schedule's decision
|
||
* to depend on the result of this effect.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Repetition / Recursion
|
||
*/
|
||
<A, R2, Out>(schedule: Schedule.Schedule<Out, NoInfer<A> | undefined, R2>): <E, R>(self: Effect<A, E, R>) => Effect<Out, E, R2 | R>;
|
||
/**
|
||
* Repeats an effect based on a specified schedule.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to execute an effect repeatedly according to a given
|
||
* schedule. The schedule determines the timing and number of repetitions. Each
|
||
* repetition can also depend on the decision of the schedule, providing
|
||
* flexibility for complex workflows. This function does not modify the effect's
|
||
* success or failure; it only controls its repetition.
|
||
*
|
||
* For example, you can use a schedule that recurs a specific number of times,
|
||
* adds delays between repetitions, or customizes repetition behavior based on
|
||
* external inputs. The effect runs initially and is repeated according to the
|
||
* schedule.
|
||
*
|
||
* @see {@link scheduleFrom} for a variant that allows the schedule's decision
|
||
* to depend on the result of this effect.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Repetition / Recursion
|
||
*/
|
||
<A, E, R, R2, Out>(self: Effect<A, E, R>, schedule: Schedule.Schedule<Out, A | undefined, R2>): Effect<Out, E, R | R2>;
|
||
};
|
||
/**
|
||
* Runs an effect repeatedly on a new fiber according to a given schedule.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function starts the provided effect on a new fiber and runs it
|
||
* repeatedly based on the specified schedule. The repetitions are managed by
|
||
* the schedule's rules, which define the timing and number of iterations. The
|
||
* fiber is attached to the current scope, meaning it is automatically managed
|
||
* and cleaned up when the scope is closed.
|
||
*
|
||
* The function returns a `RuntimeFiber` that allows you to monitor or interact
|
||
* with the running fiber.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is particularly useful for concurrent execution of scheduled tasks or
|
||
* when you want to continue processing without waiting for the repetitions to
|
||
* complete.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Repetition / Recursion
|
||
*/
|
||
export declare const scheduleForked: {
|
||
/**
|
||
* Runs an effect repeatedly on a new fiber according to a given schedule.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function starts the provided effect on a new fiber and runs it
|
||
* repeatedly based on the specified schedule. The repetitions are managed by
|
||
* the schedule's rules, which define the timing and number of iterations. The
|
||
* fiber is attached to the current scope, meaning it is automatically managed
|
||
* and cleaned up when the scope is closed.
|
||
*
|
||
* The function returns a `RuntimeFiber` that allows you to monitor or interact
|
||
* with the running fiber.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is particularly useful for concurrent execution of scheduled tasks or
|
||
* when you want to continue processing without waiting for the repetitions to
|
||
* complete.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Repetition / Recursion
|
||
*/
|
||
<Out, R2>(schedule: Schedule.Schedule<Out, unknown, R2>): <A, E, R>(self: Effect<A, E, R>) => Effect<Fiber.RuntimeFiber<Out, E>, never, Scope.Scope | R2 | R>;
|
||
/**
|
||
* Runs an effect repeatedly on a new fiber according to a given schedule.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function starts the provided effect on a new fiber and runs it
|
||
* repeatedly based on the specified schedule. The repetitions are managed by
|
||
* the schedule's rules, which define the timing and number of iterations. The
|
||
* fiber is attached to the current scope, meaning it is automatically managed
|
||
* and cleaned up when the scope is closed.
|
||
*
|
||
* The function returns a `RuntimeFiber` that allows you to monitor or interact
|
||
* with the running fiber.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is particularly useful for concurrent execution of scheduled tasks or
|
||
* when you want to continue processing without waiting for the repetitions to
|
||
* complete.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Repetition / Recursion
|
||
*/
|
||
<A, E, R, Out, R2>(self: Effect<A, E, R>, schedule: Schedule.Schedule<Out, unknown, R2>): Effect<Fiber.RuntimeFiber<Out, E>, never, Scope.Scope | R | R2>;
|
||
};
|
||
/**
|
||
* Runs an effect repeatedly according to a schedule, starting from a specified
|
||
* input value.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to repeatedly execute an effect based on a schedule.
|
||
* The schedule starts with the given `initial` input value, which is passed to
|
||
* the first execution. Subsequent executions of the effect are controlled by
|
||
* the schedule's rules, using the output of the previous iteration as the input
|
||
* for the next one.
|
||
*
|
||
* The returned effect will complete when the schedule ends or the effect fails,
|
||
* propagating the error.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Repetition / Recursion
|
||
*/
|
||
export declare const scheduleFrom: {
|
||
/**
|
||
* Runs an effect repeatedly according to a schedule, starting from a specified
|
||
* input value.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to repeatedly execute an effect based on a schedule.
|
||
* The schedule starts with the given `initial` input value, which is passed to
|
||
* the first execution. Subsequent executions of the effect are controlled by
|
||
* the schedule's rules, using the output of the previous iteration as the input
|
||
* for the next one.
|
||
*
|
||
* The returned effect will complete when the schedule ends or the effect fails,
|
||
* propagating the error.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Repetition / Recursion
|
||
*/
|
||
<R2, In, Out>(initial: In, schedule: Schedule.Schedule<Out, In, R2>): <E, R>(self: Effect<In, E, R>) => Effect<Out, E, R2 | R>;
|
||
/**
|
||
* Runs an effect repeatedly according to a schedule, starting from a specified
|
||
* input value.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to repeatedly execute an effect based on a schedule.
|
||
* The schedule starts with the given `initial` input value, which is passed to
|
||
* the first execution. Subsequent executions of the effect are controlled by
|
||
* the schedule's rules, using the output of the previous iteration as the input
|
||
* for the next one.
|
||
*
|
||
* The returned effect will complete when the schedule ends or the effect fails,
|
||
* propagating the error.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Repetition / Recursion
|
||
*/
|
||
<In, E, R, R2, Out>(self: Effect<In, E, R>, initial: In, schedule: Schedule.Schedule<Out, In, R2>): Effect<Out, E, R | R2>;
|
||
};
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Repetition / Recursion
|
||
*/
|
||
export declare const whileLoop: <A, E, R>(options: {
|
||
readonly while: LazyArg<boolean>;
|
||
readonly body: LazyArg<Effect<A, E, R>>;
|
||
readonly step: (a: A) => void;
|
||
}) => Effect<void, E, R>;
|
||
/**
|
||
* Returns a collection of all `FiberRef` values for the fiber running this
|
||
* effect.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Fiber Refs
|
||
*/
|
||
export declare const getFiberRefs: Effect<FiberRefs.FiberRefs>;
|
||
/**
|
||
* Inherits values from all `FiberRef` instances into current fiber.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Fiber Refs
|
||
*/
|
||
export declare const inheritFiberRefs: (childFiberRefs: FiberRefs.FiberRefs) => Effect<void>;
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Fiber Refs
|
||
*/
|
||
export declare const locally: {
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Fiber Refs
|
||
*/
|
||
<A>(self: FiberRef.FiberRef<A>, value: A): <B, E, R>(use: Effect<B, E, R>) => Effect<B, E, R>;
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Fiber Refs
|
||
*/
|
||
<B, E, R, A>(use: Effect<B, E, R>, self: FiberRef.FiberRef<A>, value: A): Effect<B, E, R>;
|
||
};
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Fiber Refs
|
||
*/
|
||
export declare const locallyWith: {
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Fiber Refs
|
||
*/
|
||
<A>(self: FiberRef.FiberRef<A>, f: (a: A) => A): <B, E, R>(use: Effect<B, E, R>) => Effect<B, E, R>;
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Fiber Refs
|
||
*/
|
||
<B, E, R, A>(use: Effect<B, E, R>, self: FiberRef.FiberRef<A>, f: (a: A) => A): Effect<B, E, R>;
|
||
};
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Fiber Refs
|
||
*/
|
||
export declare const locallyScoped: {
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Fiber Refs
|
||
*/
|
||
<A>(value: A): (self: FiberRef.FiberRef<A>) => Effect<void, never, Scope.Scope>;
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Fiber Refs
|
||
*/
|
||
<A>(self: FiberRef.FiberRef<A>, value: A): Effect<void, never, Scope.Scope>;
|
||
};
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Fiber Refs
|
||
*/
|
||
export declare const locallyScopedWith: {
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Fiber Refs
|
||
*/
|
||
<A>(f: (a: A) => A): (self: FiberRef.FiberRef<A>) => Effect<void, never, Scope.Scope>;
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Fiber Refs
|
||
*/
|
||
<A>(self: FiberRef.FiberRef<A>, f: (a: A) => A): Effect<void, never, Scope.Scope>;
|
||
};
|
||
/**
|
||
* Applies the specified changes to the `FiberRef` values for the fiber
|
||
* running this workflow.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Fiber Refs
|
||
*/
|
||
export declare const patchFiberRefs: (patch: FiberRefsPatch.FiberRefsPatch) => Effect<void>;
|
||
/**
|
||
* Sets the `FiberRef` values for the fiber running this effect to the values
|
||
* in the specified collection of `FiberRef` values.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Fiber Refs
|
||
*/
|
||
export declare const setFiberRefs: (fiberRefs: FiberRefs.FiberRefs) => Effect<void>;
|
||
/**
|
||
* Updates the `FiberRef` values for the fiber running this effect using the
|
||
* specified function.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Fiber Refs
|
||
*/
|
||
export declare const updateFiberRefs: (f: (fiberId: FiberId.Runtime, fiberRefs: FiberRefs.FiberRefs) => FiberRefs.FiberRefs) => Effect<void>;
|
||
/**
|
||
* Checks if an effect has failed.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function evaluates whether an effect has resulted in a failure. It
|
||
* returns a boolean value wrapped in an effect, with `true` indicating the
|
||
* effect failed and `false` otherwise.
|
||
*
|
||
* The resulting effect cannot fail (`never` in the error channel) but retains
|
||
* the context of the original effect.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const failure = Effect.fail("Uh oh!")
|
||
*
|
||
* console.log(Effect.runSync(Effect.isFailure(failure)))
|
||
* // Output: true
|
||
*
|
||
* const defect = Effect.dieMessage("BOOM!")
|
||
*
|
||
* Effect.runSync(Effect.isFailure(defect))
|
||
* // throws: BOOM!
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Condition Checking
|
||
*/
|
||
export declare const isFailure: <A, E, R>(self: Effect<A, E, R>) => Effect<boolean, never, R>;
|
||
/**
|
||
* Checks if an effect has succeeded.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function evaluates whether an effect has resulted in a success. It
|
||
* returns a boolean value wrapped in an effect, with `true` indicating the
|
||
* effect succeeded and `false` otherwise.
|
||
*
|
||
* The resulting effect cannot fail (`never` in the error channel) but retains
|
||
* the context of the original effect.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Condition Checking
|
||
*/
|
||
export declare const isSuccess: <A, E, R>(self: Effect<A, E, R>) => Effect<boolean, never, R>;
|
||
/**
|
||
* Handles both success and failure cases of an effect without performing side
|
||
* effects.
|
||
*
|
||
* **Details**
|
||
*
|
||
* `match` lets you define custom handlers for both success and failure
|
||
* scenarios. You provide separate functions to handle each case, allowing you
|
||
* to process the result if the effect succeeds, or handle the error if the
|
||
* effect fails.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is useful for structuring your code to respond differently to success or
|
||
* failure without triggering side effects.
|
||
*
|
||
* **Example** (Handling Both Success and Failure Cases)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const success: Effect.Effect<number, Error> = Effect.succeed(42)
|
||
*
|
||
* const program1 = Effect.match(success, {
|
||
* onFailure: (error) => `failure: ${error.message}`,
|
||
* onSuccess: (value) => `success: ${value}`
|
||
* })
|
||
*
|
||
* // Run and log the result of the successful effect
|
||
* Effect.runPromise(program1).then(console.log)
|
||
* // Output: "success: 42"
|
||
*
|
||
* const failure: Effect.Effect<number, Error> = Effect.fail(
|
||
* new Error("Uh oh!")
|
||
* )
|
||
*
|
||
* const program2 = Effect.match(failure, {
|
||
* onFailure: (error) => `failure: ${error.message}`,
|
||
* onSuccess: (value) => `success: ${value}`
|
||
* })
|
||
*
|
||
* // Run and log the result of the failed effect
|
||
* Effect.runPromise(program2).then(console.log)
|
||
* // Output: "failure: Uh oh!"
|
||
* ```
|
||
*
|
||
* @see {@link matchEffect} if you need to perform side effects in the handlers.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Matching
|
||
*/
|
||
export declare const match: {
|
||
/**
|
||
* Handles both success and failure cases of an effect without performing side
|
||
* effects.
|
||
*
|
||
* **Details**
|
||
*
|
||
* `match` lets you define custom handlers for both success and failure
|
||
* scenarios. You provide separate functions to handle each case, allowing you
|
||
* to process the result if the effect succeeds, or handle the error if the
|
||
* effect fails.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is useful for structuring your code to respond differently to success or
|
||
* failure without triggering side effects.
|
||
*
|
||
* **Example** (Handling Both Success and Failure Cases)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const success: Effect.Effect<number, Error> = Effect.succeed(42)
|
||
*
|
||
* const program1 = Effect.match(success, {
|
||
* onFailure: (error) => `failure: ${error.message}`,
|
||
* onSuccess: (value) => `success: ${value}`
|
||
* })
|
||
*
|
||
* // Run and log the result of the successful effect
|
||
* Effect.runPromise(program1).then(console.log)
|
||
* // Output: "success: 42"
|
||
*
|
||
* const failure: Effect.Effect<number, Error> = Effect.fail(
|
||
* new Error("Uh oh!")
|
||
* )
|
||
*
|
||
* const program2 = Effect.match(failure, {
|
||
* onFailure: (error) => `failure: ${error.message}`,
|
||
* onSuccess: (value) => `success: ${value}`
|
||
* })
|
||
*
|
||
* // Run and log the result of the failed effect
|
||
* Effect.runPromise(program2).then(console.log)
|
||
* // Output: "failure: Uh oh!"
|
||
* ```
|
||
*
|
||
* @see {@link matchEffect} if you need to perform side effects in the handlers.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Matching
|
||
*/
|
||
<E, A2, A, A3>(options: {
|
||
readonly onFailure: (error: E) => A2;
|
||
readonly onSuccess: (value: A) => A3;
|
||
}): <R>(self: Effect<A, E, R>) => Effect<A2 | A3, never, R>;
|
||
/**
|
||
* Handles both success and failure cases of an effect without performing side
|
||
* effects.
|
||
*
|
||
* **Details**
|
||
*
|
||
* `match` lets you define custom handlers for both success and failure
|
||
* scenarios. You provide separate functions to handle each case, allowing you
|
||
* to process the result if the effect succeeds, or handle the error if the
|
||
* effect fails.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is useful for structuring your code to respond differently to success or
|
||
* failure without triggering side effects.
|
||
*
|
||
* **Example** (Handling Both Success and Failure Cases)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const success: Effect.Effect<number, Error> = Effect.succeed(42)
|
||
*
|
||
* const program1 = Effect.match(success, {
|
||
* onFailure: (error) => `failure: ${error.message}`,
|
||
* onSuccess: (value) => `success: ${value}`
|
||
* })
|
||
*
|
||
* // Run and log the result of the successful effect
|
||
* Effect.runPromise(program1).then(console.log)
|
||
* // Output: "success: 42"
|
||
*
|
||
* const failure: Effect.Effect<number, Error> = Effect.fail(
|
||
* new Error("Uh oh!")
|
||
* )
|
||
*
|
||
* const program2 = Effect.match(failure, {
|
||
* onFailure: (error) => `failure: ${error.message}`,
|
||
* onSuccess: (value) => `success: ${value}`
|
||
* })
|
||
*
|
||
* // Run and log the result of the failed effect
|
||
* Effect.runPromise(program2).then(console.log)
|
||
* // Output: "failure: Uh oh!"
|
||
* ```
|
||
*
|
||
* @see {@link matchEffect} if you need to perform side effects in the handlers.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Matching
|
||
*/
|
||
<A, E, R, A2, A3>(self: Effect<A, E, R>, options: {
|
||
readonly onFailure: (error: E) => A2;
|
||
readonly onSuccess: (value: A) => A3;
|
||
}): Effect<A2 | A3, never, R>;
|
||
};
|
||
/**
|
||
* Handles failures by matching the cause of failure.
|
||
*
|
||
* **Details**
|
||
*
|
||
* The `matchCause` function allows you to handle failures with access to the
|
||
* full cause of the failure within a fiber.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is useful for differentiating between different types of errors, such as
|
||
* regular failures, defects, or interruptions. You can provide specific
|
||
* handling logic for each failure type based on the cause.
|
||
*
|
||
* **Example** (Handling Different Failure Causes)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const task: Effect.Effect<number, Error> = Effect.die("Uh oh!")
|
||
*
|
||
* const program = Effect.matchCause(task, {
|
||
* onFailure: (cause) => {
|
||
* switch (cause._tag) {
|
||
* case "Fail":
|
||
* // Handle standard failure
|
||
* return `Fail: ${cause.error.message}`
|
||
* case "Die":
|
||
* // Handle defects (unexpected errors)
|
||
* return `Die: ${cause.defect}`
|
||
* case "Interrupt":
|
||
* // Handle interruption
|
||
* return `${cause.fiberId} interrupted!`
|
||
* }
|
||
* // Fallback for other causes
|
||
* return "failed due to other causes"
|
||
* },
|
||
* onSuccess: (value) =>
|
||
* // task completes successfully
|
||
* `succeeded with ${value} value`
|
||
* })
|
||
*
|
||
* Effect.runPromise(program).then(console.log)
|
||
* // Output: "Die: Uh oh!"
|
||
* ```
|
||
*
|
||
* @see {@link matchCauseEffect} if you need to perform side effects in the
|
||
* handlers.
|
||
* @see {@link match} if you don't need to handle the cause of the failure.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Matching
|
||
*/
|
||
export declare const matchCause: {
|
||
/**
|
||
* Handles failures by matching the cause of failure.
|
||
*
|
||
* **Details**
|
||
*
|
||
* The `matchCause` function allows you to handle failures with access to the
|
||
* full cause of the failure within a fiber.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is useful for differentiating between different types of errors, such as
|
||
* regular failures, defects, or interruptions. You can provide specific
|
||
* handling logic for each failure type based on the cause.
|
||
*
|
||
* **Example** (Handling Different Failure Causes)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const task: Effect.Effect<number, Error> = Effect.die("Uh oh!")
|
||
*
|
||
* const program = Effect.matchCause(task, {
|
||
* onFailure: (cause) => {
|
||
* switch (cause._tag) {
|
||
* case "Fail":
|
||
* // Handle standard failure
|
||
* return `Fail: ${cause.error.message}`
|
||
* case "Die":
|
||
* // Handle defects (unexpected errors)
|
||
* return `Die: ${cause.defect}`
|
||
* case "Interrupt":
|
||
* // Handle interruption
|
||
* return `${cause.fiberId} interrupted!`
|
||
* }
|
||
* // Fallback for other causes
|
||
* return "failed due to other causes"
|
||
* },
|
||
* onSuccess: (value) =>
|
||
* // task completes successfully
|
||
* `succeeded with ${value} value`
|
||
* })
|
||
*
|
||
* Effect.runPromise(program).then(console.log)
|
||
* // Output: "Die: Uh oh!"
|
||
* ```
|
||
*
|
||
* @see {@link matchCauseEffect} if you need to perform side effects in the
|
||
* handlers.
|
||
* @see {@link match} if you don't need to handle the cause of the failure.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Matching
|
||
*/
|
||
<E, A2, A, A3>(options: {
|
||
readonly onFailure: (cause: Cause.Cause<E>) => A2;
|
||
readonly onSuccess: (a: A) => A3;
|
||
}): <R>(self: Effect<A, E, R>) => Effect<A2 | A3, never, R>;
|
||
/**
|
||
* Handles failures by matching the cause of failure.
|
||
*
|
||
* **Details**
|
||
*
|
||
* The `matchCause` function allows you to handle failures with access to the
|
||
* full cause of the failure within a fiber.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is useful for differentiating between different types of errors, such as
|
||
* regular failures, defects, or interruptions. You can provide specific
|
||
* handling logic for each failure type based on the cause.
|
||
*
|
||
* **Example** (Handling Different Failure Causes)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const task: Effect.Effect<number, Error> = Effect.die("Uh oh!")
|
||
*
|
||
* const program = Effect.matchCause(task, {
|
||
* onFailure: (cause) => {
|
||
* switch (cause._tag) {
|
||
* case "Fail":
|
||
* // Handle standard failure
|
||
* return `Fail: ${cause.error.message}`
|
||
* case "Die":
|
||
* // Handle defects (unexpected errors)
|
||
* return `Die: ${cause.defect}`
|
||
* case "Interrupt":
|
||
* // Handle interruption
|
||
* return `${cause.fiberId} interrupted!`
|
||
* }
|
||
* // Fallback for other causes
|
||
* return "failed due to other causes"
|
||
* },
|
||
* onSuccess: (value) =>
|
||
* // task completes successfully
|
||
* `succeeded with ${value} value`
|
||
* })
|
||
*
|
||
* Effect.runPromise(program).then(console.log)
|
||
* // Output: "Die: Uh oh!"
|
||
* ```
|
||
*
|
||
* @see {@link matchCauseEffect} if you need to perform side effects in the
|
||
* handlers.
|
||
* @see {@link match} if you don't need to handle the cause of the failure.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Matching
|
||
*/
|
||
<A, E, R, A2, A3>(self: Effect<A, E, R>, options: {
|
||
readonly onFailure: (cause: Cause.Cause<E>) => A2;
|
||
readonly onSuccess: (a: A) => A3;
|
||
}): Effect<A2 | A3, never, R>;
|
||
};
|
||
/**
|
||
* Handles failures with access to the cause and allows performing side effects.
|
||
*
|
||
* **Details**
|
||
*
|
||
* The `matchCauseEffect` function works similarly to {@link matchCause}, but it
|
||
* also allows you to perform additional side effects based on the failure
|
||
* cause. This function provides access to the complete cause of the failure,
|
||
* making it possible to differentiate between various failure types, and allows
|
||
* you to respond accordingly while performing side effects (like logging or
|
||
* other operations).
|
||
*
|
||
* **Example** (Handling Different Failure Causes with Side Effects)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* const task: Effect.Effect<number, Error> = Effect.die("Uh oh!")
|
||
*
|
||
* const program = Effect.matchCauseEffect(task, {
|
||
* onFailure: (cause) => {
|
||
* switch (cause._tag) {
|
||
* case "Fail":
|
||
* // Handle standard failure with a logged message
|
||
* return Console.log(`Fail: ${cause.error.message}`)
|
||
* case "Die":
|
||
* // Handle defects (unexpected errors) by logging the defect
|
||
* return Console.log(`Die: ${cause.defect}`)
|
||
* case "Interrupt":
|
||
* // Handle interruption and log the fiberId that was interrupted
|
||
* return Console.log(`${cause.fiberId} interrupted!`)
|
||
* }
|
||
* // Fallback for other causes
|
||
* return Console.log("failed due to other causes")
|
||
* },
|
||
* onSuccess: (value) =>
|
||
* // Log success if the task completes successfully
|
||
* Console.log(`succeeded with ${value} value`)
|
||
* })
|
||
*
|
||
* Effect.runPromise(program)
|
||
* // Output: "Die: Uh oh!"
|
||
* ```
|
||
*
|
||
* @see {@link matchCause} if you don't need side effects and only want to handle the result or failure.
|
||
* @see {@link matchEffect} if you don't need to handle the cause of the failure.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Matching
|
||
*/
|
||
export declare const matchCauseEffect: {
|
||
/**
|
||
* Handles failures with access to the cause and allows performing side effects.
|
||
*
|
||
* **Details**
|
||
*
|
||
* The `matchCauseEffect` function works similarly to {@link matchCause}, but it
|
||
* also allows you to perform additional side effects based on the failure
|
||
* cause. This function provides access to the complete cause of the failure,
|
||
* making it possible to differentiate between various failure types, and allows
|
||
* you to respond accordingly while performing side effects (like logging or
|
||
* other operations).
|
||
*
|
||
* **Example** (Handling Different Failure Causes with Side Effects)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* const task: Effect.Effect<number, Error> = Effect.die("Uh oh!")
|
||
*
|
||
* const program = Effect.matchCauseEffect(task, {
|
||
* onFailure: (cause) => {
|
||
* switch (cause._tag) {
|
||
* case "Fail":
|
||
* // Handle standard failure with a logged message
|
||
* return Console.log(`Fail: ${cause.error.message}`)
|
||
* case "Die":
|
||
* // Handle defects (unexpected errors) by logging the defect
|
||
* return Console.log(`Die: ${cause.defect}`)
|
||
* case "Interrupt":
|
||
* // Handle interruption and log the fiberId that was interrupted
|
||
* return Console.log(`${cause.fiberId} interrupted!`)
|
||
* }
|
||
* // Fallback for other causes
|
||
* return Console.log("failed due to other causes")
|
||
* },
|
||
* onSuccess: (value) =>
|
||
* // Log success if the task completes successfully
|
||
* Console.log(`succeeded with ${value} value`)
|
||
* })
|
||
*
|
||
* Effect.runPromise(program)
|
||
* // Output: "Die: Uh oh!"
|
||
* ```
|
||
*
|
||
* @see {@link matchCause} if you don't need side effects and only want to handle the result or failure.
|
||
* @see {@link matchEffect} if you don't need to handle the cause of the failure.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Matching
|
||
*/
|
||
<E, A2, E2, R2, A, A3, E3, R3>(options: {
|
||
readonly onFailure: (cause: Cause.Cause<E>) => Effect<A2, E2, R2>;
|
||
readonly onSuccess: (a: A) => Effect<A3, E3, R3>;
|
||
}): <R>(self: Effect<A, E, R>) => Effect<A2 | A3, E2 | E3, R2 | R3 | R>;
|
||
/**
|
||
* Handles failures with access to the cause and allows performing side effects.
|
||
*
|
||
* **Details**
|
||
*
|
||
* The `matchCauseEffect` function works similarly to {@link matchCause}, but it
|
||
* also allows you to perform additional side effects based on the failure
|
||
* cause. This function provides access to the complete cause of the failure,
|
||
* making it possible to differentiate between various failure types, and allows
|
||
* you to respond accordingly while performing side effects (like logging or
|
||
* other operations).
|
||
*
|
||
* **Example** (Handling Different Failure Causes with Side Effects)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* const task: Effect.Effect<number, Error> = Effect.die("Uh oh!")
|
||
*
|
||
* const program = Effect.matchCauseEffect(task, {
|
||
* onFailure: (cause) => {
|
||
* switch (cause._tag) {
|
||
* case "Fail":
|
||
* // Handle standard failure with a logged message
|
||
* return Console.log(`Fail: ${cause.error.message}`)
|
||
* case "Die":
|
||
* // Handle defects (unexpected errors) by logging the defect
|
||
* return Console.log(`Die: ${cause.defect}`)
|
||
* case "Interrupt":
|
||
* // Handle interruption and log the fiberId that was interrupted
|
||
* return Console.log(`${cause.fiberId} interrupted!`)
|
||
* }
|
||
* // Fallback for other causes
|
||
* return Console.log("failed due to other causes")
|
||
* },
|
||
* onSuccess: (value) =>
|
||
* // Log success if the task completes successfully
|
||
* Console.log(`succeeded with ${value} value`)
|
||
* })
|
||
*
|
||
* Effect.runPromise(program)
|
||
* // Output: "Die: Uh oh!"
|
||
* ```
|
||
*
|
||
* @see {@link matchCause} if you don't need side effects and only want to handle the result or failure.
|
||
* @see {@link matchEffect} if you don't need to handle the cause of the failure.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Matching
|
||
*/
|
||
<A, E, R, A2, E2, R2, A3, E3, R3>(self: Effect<A, E, R>, options: {
|
||
readonly onFailure: (cause: Cause.Cause<E>) => Effect<A2, E2, R2>;
|
||
readonly onSuccess: (a: A) => Effect<A3, E3, R3>;
|
||
}): Effect<A2 | A3, E2 | E3, R2 | R3 | R>;
|
||
};
|
||
/**
|
||
* Handles both success and failure cases of an effect, allowing for additional
|
||
* side effects.
|
||
*
|
||
* **Details**
|
||
*
|
||
* The `matchEffect` function is similar to {@link match}, but it enables you to
|
||
* perform side effects in the handlers for both success and failure outcomes.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is useful when you need to execute additional actions, like logging or
|
||
* notifying users, based on whether an effect succeeds or fails.
|
||
*
|
||
* **Example** (Handling Both Success and Failure Cases with Side Effects)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const success: Effect.Effect<number, Error> = Effect.succeed(42)
|
||
* const failure: Effect.Effect<number, Error> = Effect.fail(
|
||
* new Error("Uh oh!")
|
||
* )
|
||
*
|
||
* const program1 = Effect.matchEffect(success, {
|
||
* onFailure: (error) =>
|
||
* Effect.succeed(`failure: ${error.message}`).pipe(
|
||
* Effect.tap(Effect.log)
|
||
* ),
|
||
* onSuccess: (value) =>
|
||
* Effect.succeed(`success: ${value}`).pipe(Effect.tap(Effect.log))
|
||
* })
|
||
*
|
||
* console.log(Effect.runSync(program1))
|
||
* // Output:
|
||
* // timestamp=... level=INFO fiber=#0 message="success: 42"
|
||
* // success: 42
|
||
*
|
||
* const program2 = Effect.matchEffect(failure, {
|
||
* onFailure: (error) =>
|
||
* Effect.succeed(`failure: ${error.message}`).pipe(
|
||
* Effect.tap(Effect.log)
|
||
* ),
|
||
* onSuccess: (value) =>
|
||
* Effect.succeed(`success: ${value}`).pipe(Effect.tap(Effect.log))
|
||
* })
|
||
*
|
||
* console.log(Effect.runSync(program2))
|
||
* // Output:
|
||
* // timestamp=... level=INFO fiber=#1 message="failure: Uh oh!"
|
||
* // failure: Uh oh!
|
||
* ```
|
||
*
|
||
* @see {@link match} if you don't need side effects and only want to handle the
|
||
* result or failure.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Matching
|
||
*/
|
||
export declare const matchEffect: {
|
||
/**
|
||
* Handles both success and failure cases of an effect, allowing for additional
|
||
* side effects.
|
||
*
|
||
* **Details**
|
||
*
|
||
* The `matchEffect` function is similar to {@link match}, but it enables you to
|
||
* perform side effects in the handlers for both success and failure outcomes.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is useful when you need to execute additional actions, like logging or
|
||
* notifying users, based on whether an effect succeeds or fails.
|
||
*
|
||
* **Example** (Handling Both Success and Failure Cases with Side Effects)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const success: Effect.Effect<number, Error> = Effect.succeed(42)
|
||
* const failure: Effect.Effect<number, Error> = Effect.fail(
|
||
* new Error("Uh oh!")
|
||
* )
|
||
*
|
||
* const program1 = Effect.matchEffect(success, {
|
||
* onFailure: (error) =>
|
||
* Effect.succeed(`failure: ${error.message}`).pipe(
|
||
* Effect.tap(Effect.log)
|
||
* ),
|
||
* onSuccess: (value) =>
|
||
* Effect.succeed(`success: ${value}`).pipe(Effect.tap(Effect.log))
|
||
* })
|
||
*
|
||
* console.log(Effect.runSync(program1))
|
||
* // Output:
|
||
* // timestamp=... level=INFO fiber=#0 message="success: 42"
|
||
* // success: 42
|
||
*
|
||
* const program2 = Effect.matchEffect(failure, {
|
||
* onFailure: (error) =>
|
||
* Effect.succeed(`failure: ${error.message}`).pipe(
|
||
* Effect.tap(Effect.log)
|
||
* ),
|
||
* onSuccess: (value) =>
|
||
* Effect.succeed(`success: ${value}`).pipe(Effect.tap(Effect.log))
|
||
* })
|
||
*
|
||
* console.log(Effect.runSync(program2))
|
||
* // Output:
|
||
* // timestamp=... level=INFO fiber=#1 message="failure: Uh oh!"
|
||
* // failure: Uh oh!
|
||
* ```
|
||
*
|
||
* @see {@link match} if you don't need side effects and only want to handle the
|
||
* result or failure.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Matching
|
||
*/
|
||
<E, A2, E2, R2, A, A3, E3, R3>(options: {
|
||
readonly onFailure: (e: E) => Effect<A2, E2, R2>;
|
||
readonly onSuccess: (a: A) => Effect<A3, E3, R3>;
|
||
}): <R>(self: Effect<A, E, R>) => Effect<A2 | A3, E2 | E3, R2 | R3 | R>;
|
||
/**
|
||
* Handles both success and failure cases of an effect, allowing for additional
|
||
* side effects.
|
||
*
|
||
* **Details**
|
||
*
|
||
* The `matchEffect` function is similar to {@link match}, but it enables you to
|
||
* perform side effects in the handlers for both success and failure outcomes.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is useful when you need to execute additional actions, like logging or
|
||
* notifying users, based on whether an effect succeeds or fails.
|
||
*
|
||
* **Example** (Handling Both Success and Failure Cases with Side Effects)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const success: Effect.Effect<number, Error> = Effect.succeed(42)
|
||
* const failure: Effect.Effect<number, Error> = Effect.fail(
|
||
* new Error("Uh oh!")
|
||
* )
|
||
*
|
||
* const program1 = Effect.matchEffect(success, {
|
||
* onFailure: (error) =>
|
||
* Effect.succeed(`failure: ${error.message}`).pipe(
|
||
* Effect.tap(Effect.log)
|
||
* ),
|
||
* onSuccess: (value) =>
|
||
* Effect.succeed(`success: ${value}`).pipe(Effect.tap(Effect.log))
|
||
* })
|
||
*
|
||
* console.log(Effect.runSync(program1))
|
||
* // Output:
|
||
* // timestamp=... level=INFO fiber=#0 message="success: 42"
|
||
* // success: 42
|
||
*
|
||
* const program2 = Effect.matchEffect(failure, {
|
||
* onFailure: (error) =>
|
||
* Effect.succeed(`failure: ${error.message}`).pipe(
|
||
* Effect.tap(Effect.log)
|
||
* ),
|
||
* onSuccess: (value) =>
|
||
* Effect.succeed(`success: ${value}`).pipe(Effect.tap(Effect.log))
|
||
* })
|
||
*
|
||
* console.log(Effect.runSync(program2))
|
||
* // Output:
|
||
* // timestamp=... level=INFO fiber=#1 message="failure: Uh oh!"
|
||
* // failure: Uh oh!
|
||
* ```
|
||
*
|
||
* @see {@link match} if you don't need side effects and only want to handle the
|
||
* result or failure.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Matching
|
||
*/
|
||
<A, E, R, A2, E2, R2, A3, E3, R3>(self: Effect<A, E, R>, options: {
|
||
readonly onFailure: (e: E) => Effect<A2, E2, R2>;
|
||
readonly onSuccess: (a: A) => Effect<A3, E3, R3>;
|
||
}): Effect<A2 | A3, E2 | E3, R2 | R3 | R>;
|
||
};
|
||
/**
|
||
* Logs one or more messages or error causes at the current log level.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function provides a simple way to log messages or error causes during
|
||
* the execution of your effects. By default, logs are recorded at the `INFO`
|
||
* level, but this can be adjusted using other logging utilities
|
||
* (`Logger.withMinimumLogLevel`). Multiple items, including `Cause` instances,
|
||
* can be logged in a single call. When logging `Cause` instances, detailed
|
||
* error information is included in the log output.
|
||
*
|
||
* The log output includes useful metadata like the current timestamp, log
|
||
* level, and fiber ID, making it suitable for debugging and tracking purposes.
|
||
* This function does not interrupt or alter the effect's execution flow.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Cause, Effect } from "effect"
|
||
*
|
||
* const program = Effect.log(
|
||
* "message1",
|
||
* "message2",
|
||
* Cause.die("Oh no!"),
|
||
* Cause.die("Oh uh!")
|
||
* )
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output:
|
||
* // timestamp=... level=INFO fiber=#0 message=message1 message=message2 cause="Error: Oh no!
|
||
* // Error: Oh uh!"
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Logging
|
||
*/
|
||
export declare const log: (...message: ReadonlyArray<any>) => Effect<void, never, never>;
|
||
/**
|
||
* Logs messages or error causes at a specified log level.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to log one or more messages or error causes while
|
||
* specifying the desired log level (e.g., DEBUG, INFO, ERROR). It provides
|
||
* flexibility in categorizing logs based on their importance or severity,
|
||
* making it easier to filter logs during debugging or production monitoring.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Cause, Effect, LogLevel } from "effect"
|
||
*
|
||
* const program = Effect.logWithLevel(
|
||
* LogLevel.Error,
|
||
* "Critical error encountered",
|
||
* Cause.die("System failure!")
|
||
* )
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output:
|
||
* // timestamp=... level=ERROR fiber=#0 message=Critical error encountered cause="Error: System failure!"
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Logging
|
||
*/
|
||
export declare const logWithLevel: (level: LogLevel.LogLevel, ...message: ReadonlyArray<any>) => Effect<void>;
|
||
/**
|
||
* Logs messages at the TRACE log level.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function logs the specified messages at the TRACE level. TRACE logs are
|
||
* typically used for very detailed diagnostic information. These messages are
|
||
* not displayed by default. To view them, you must adjust the logging
|
||
* configuration by setting the minimum log level to `LogLevel.Trace` using
|
||
* `Logger.withMinimumLogLevel`.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Logger, LogLevel } from "effect"
|
||
*
|
||
* const program = Effect.logTrace("message1").pipe(Logger.withMinimumLogLevel(LogLevel.Trace))
|
||
*
|
||
* Effect.runFork(program)
|
||
* // timestamp=... level=TRACE fiber=#0 message=message1
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Logging
|
||
*/
|
||
export declare const logTrace: (...message: ReadonlyArray<any>) => Effect<void, never, never>;
|
||
/**
|
||
* Logs messages at the DEBUG log level.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function logs messages at the DEBUG level, which is typically used for
|
||
* diagnosing application behavior during development. DEBUG messages provide
|
||
* less detailed information than TRACE logs but are still not shown by default.
|
||
* To view these logs, adjust the log level using `Logger.withMinimumLogLevel`.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Logger, LogLevel } from "effect"
|
||
*
|
||
* const program = Effect.logDebug("message1").pipe(Logger.withMinimumLogLevel(LogLevel.Debug))
|
||
*
|
||
* Effect.runFork(program)
|
||
* // timestamp=... level=DEBUG fiber=#0 message=message1
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Logging
|
||
*/
|
||
export declare const logDebug: (...message: ReadonlyArray<any>) => Effect<void, never, never>;
|
||
/**
|
||
* Logs messages at the INFO log level.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function logs messages at the INFO level, suitable for general
|
||
* application events or operational messages. INFO logs are shown by default
|
||
* and are commonly used for highlighting normal, non-error operations.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Logging
|
||
*/
|
||
export declare const logInfo: (...message: ReadonlyArray<any>) => Effect<void, never, never>;
|
||
/**
|
||
* Logs messages at the WARNING log level.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function logs messages at the WARNING level, suitable for highlighting
|
||
* potential issues that are not errors but may require attention. These
|
||
* messages indicate that something unexpected occurred or might lead to errors
|
||
* in the future.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Logging
|
||
*/
|
||
export declare const logWarning: (...message: ReadonlyArray<any>) => Effect<void, never, never>;
|
||
/**
|
||
* Logs messages at the ERROR log level.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function logs messages at the ERROR level, suitable for reporting
|
||
* application errors or failures. These logs are typically used for unexpected
|
||
* issues that need immediate attention.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Logging
|
||
*/
|
||
export declare const logError: (...message: ReadonlyArray<any>) => Effect<void, never, never>;
|
||
/**
|
||
* Logs messages at the FATAL log level.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function logs messages at the FATAL level, suitable for reporting
|
||
* critical errors that cause the application to terminate or stop functioning.
|
||
* These logs are typically used for unrecoverable errors that require immediate
|
||
* attention.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Logging
|
||
*/
|
||
export declare const logFatal: (...message: ReadonlyArray<any>) => Effect<void, never, never>;
|
||
/**
|
||
* Adds a log span to an effect for tracking and logging its execution duration.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function wraps an effect with a log span, providing performance
|
||
* monitoring and debugging capabilities. The log span tracks the duration of
|
||
* the wrapped effect and logs it with the specified label. This is particularly
|
||
* useful when analyzing time-sensitive operations or understanding the
|
||
* execution time of specific tasks in your application.
|
||
*
|
||
* The logged output will include the label and the total time taken for the
|
||
* operation. The span information is included in the log metadata, making it
|
||
* easy to trace performance metrics in logs.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const program = Effect.gen(function*() {
|
||
* yield* Effect.sleep("1 second")
|
||
* yield* Effect.log("The job is finished!")
|
||
* }).pipe(Effect.withLogSpan("myspan"))
|
||
*
|
||
* Effect.runFork(program)
|
||
* // timestamp=... level=INFO fiber=#0 message="The job is finished!" myspan=1011ms
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Logging
|
||
*/
|
||
export declare const withLogSpan: {
|
||
/**
|
||
* Adds a log span to an effect for tracking and logging its execution duration.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function wraps an effect with a log span, providing performance
|
||
* monitoring and debugging capabilities. The log span tracks the duration of
|
||
* the wrapped effect and logs it with the specified label. This is particularly
|
||
* useful when analyzing time-sensitive operations or understanding the
|
||
* execution time of specific tasks in your application.
|
||
*
|
||
* The logged output will include the label and the total time taken for the
|
||
* operation. The span information is included in the log metadata, making it
|
||
* easy to trace performance metrics in logs.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const program = Effect.gen(function*() {
|
||
* yield* Effect.sleep("1 second")
|
||
* yield* Effect.log("The job is finished!")
|
||
* }).pipe(Effect.withLogSpan("myspan"))
|
||
*
|
||
* Effect.runFork(program)
|
||
* // timestamp=... level=INFO fiber=#0 message="The job is finished!" myspan=1011ms
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Logging
|
||
*/
|
||
(label: string): <A, E, R>(effect: Effect<A, E, R>) => Effect<A, E, R>;
|
||
/**
|
||
* Adds a log span to an effect for tracking and logging its execution duration.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function wraps an effect with a log span, providing performance
|
||
* monitoring and debugging capabilities. The log span tracks the duration of
|
||
* the wrapped effect and logs it with the specified label. This is particularly
|
||
* useful when analyzing time-sensitive operations or understanding the
|
||
* execution time of specific tasks in your application.
|
||
*
|
||
* The logged output will include the label and the total time taken for the
|
||
* operation. The span information is included in the log metadata, making it
|
||
* easy to trace performance metrics in logs.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const program = Effect.gen(function*() {
|
||
* yield* Effect.sleep("1 second")
|
||
* yield* Effect.log("The job is finished!")
|
||
* }).pipe(Effect.withLogSpan("myspan"))
|
||
*
|
||
* Effect.runFork(program)
|
||
* // timestamp=... level=INFO fiber=#0 message="The job is finished!" myspan=1011ms
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Logging
|
||
*/
|
||
<A, E, R>(effect: Effect<A, E, R>, label: string): Effect<A, E, R>;
|
||
};
|
||
/**
|
||
* Adds custom annotations to log entries generated within an effect.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to enhance log messages by appending additional
|
||
* context in the form of key-value pairs. These annotations are included in
|
||
* every log message created during the execution of the effect, making the logs
|
||
* more informative and easier to trace.
|
||
*
|
||
* The annotations can be specified as a single key-value pair or as a record of
|
||
* multiple key-value pairs. This is particularly useful for tracking
|
||
* operations, debugging, or associating specific metadata with logs for better
|
||
* observability.
|
||
*
|
||
* The annotated key-value pairs will appear alongside the log message in the
|
||
* output.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const program = Effect.gen(function*() {
|
||
* yield* Effect.log("message1")
|
||
* yield* Effect.log("message2")
|
||
* }).pipe(Effect.annotateLogs("taskId", "1234")) // Annotation as key/value pair
|
||
*
|
||
* Effect.runFork(program)
|
||
* // timestamp=... level=INFO fiber=#0 message=message1 taskId=1234
|
||
* // timestamp=... level=INFO fiber=#0 message=message2 taskId=1234
|
||
* ```
|
||
*
|
||
* @see {@link annotateLogsScoped} to add log annotations with a limited scope.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Logging
|
||
*/
|
||
export declare const annotateLogs: {
|
||
/**
|
||
* Adds custom annotations to log entries generated within an effect.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to enhance log messages by appending additional
|
||
* context in the form of key-value pairs. These annotations are included in
|
||
* every log message created during the execution of the effect, making the logs
|
||
* more informative and easier to trace.
|
||
*
|
||
* The annotations can be specified as a single key-value pair or as a record of
|
||
* multiple key-value pairs. This is particularly useful for tracking
|
||
* operations, debugging, or associating specific metadata with logs for better
|
||
* observability.
|
||
*
|
||
* The annotated key-value pairs will appear alongside the log message in the
|
||
* output.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const program = Effect.gen(function*() {
|
||
* yield* Effect.log("message1")
|
||
* yield* Effect.log("message2")
|
||
* }).pipe(Effect.annotateLogs("taskId", "1234")) // Annotation as key/value pair
|
||
*
|
||
* Effect.runFork(program)
|
||
* // timestamp=... level=INFO fiber=#0 message=message1 taskId=1234
|
||
* // timestamp=... level=INFO fiber=#0 message=message2 taskId=1234
|
||
* ```
|
||
*
|
||
* @see {@link annotateLogsScoped} to add log annotations with a limited scope.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Logging
|
||
*/
|
||
(key: string, value: unknown): <A, E, R>(effect: Effect<A, E, R>) => Effect<A, E, R>;
|
||
/**
|
||
* Adds custom annotations to log entries generated within an effect.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to enhance log messages by appending additional
|
||
* context in the form of key-value pairs. These annotations are included in
|
||
* every log message created during the execution of the effect, making the logs
|
||
* more informative and easier to trace.
|
||
*
|
||
* The annotations can be specified as a single key-value pair or as a record of
|
||
* multiple key-value pairs. This is particularly useful for tracking
|
||
* operations, debugging, or associating specific metadata with logs for better
|
||
* observability.
|
||
*
|
||
* The annotated key-value pairs will appear alongside the log message in the
|
||
* output.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const program = Effect.gen(function*() {
|
||
* yield* Effect.log("message1")
|
||
* yield* Effect.log("message2")
|
||
* }).pipe(Effect.annotateLogs("taskId", "1234")) // Annotation as key/value pair
|
||
*
|
||
* Effect.runFork(program)
|
||
* // timestamp=... level=INFO fiber=#0 message=message1 taskId=1234
|
||
* // timestamp=... level=INFO fiber=#0 message=message2 taskId=1234
|
||
* ```
|
||
*
|
||
* @see {@link annotateLogsScoped} to add log annotations with a limited scope.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Logging
|
||
*/
|
||
(values: Record<string, unknown>): <A, E, R>(effect: Effect<A, E, R>) => Effect<A, E, R>;
|
||
/**
|
||
* Adds custom annotations to log entries generated within an effect.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to enhance log messages by appending additional
|
||
* context in the form of key-value pairs. These annotations are included in
|
||
* every log message created during the execution of the effect, making the logs
|
||
* more informative and easier to trace.
|
||
*
|
||
* The annotations can be specified as a single key-value pair or as a record of
|
||
* multiple key-value pairs. This is particularly useful for tracking
|
||
* operations, debugging, or associating specific metadata with logs for better
|
||
* observability.
|
||
*
|
||
* The annotated key-value pairs will appear alongside the log message in the
|
||
* output.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const program = Effect.gen(function*() {
|
||
* yield* Effect.log("message1")
|
||
* yield* Effect.log("message2")
|
||
* }).pipe(Effect.annotateLogs("taskId", "1234")) // Annotation as key/value pair
|
||
*
|
||
* Effect.runFork(program)
|
||
* // timestamp=... level=INFO fiber=#0 message=message1 taskId=1234
|
||
* // timestamp=... level=INFO fiber=#0 message=message2 taskId=1234
|
||
* ```
|
||
*
|
||
* @see {@link annotateLogsScoped} to add log annotations with a limited scope.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Logging
|
||
*/
|
||
<A, E, R>(effect: Effect<A, E, R>, key: string, value: unknown): Effect<A, E, R>;
|
||
/**
|
||
* Adds custom annotations to log entries generated within an effect.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to enhance log messages by appending additional
|
||
* context in the form of key-value pairs. These annotations are included in
|
||
* every log message created during the execution of the effect, making the logs
|
||
* more informative and easier to trace.
|
||
*
|
||
* The annotations can be specified as a single key-value pair or as a record of
|
||
* multiple key-value pairs. This is particularly useful for tracking
|
||
* operations, debugging, or associating specific metadata with logs for better
|
||
* observability.
|
||
*
|
||
* The annotated key-value pairs will appear alongside the log message in the
|
||
* output.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const program = Effect.gen(function*() {
|
||
* yield* Effect.log("message1")
|
||
* yield* Effect.log("message2")
|
||
* }).pipe(Effect.annotateLogs("taskId", "1234")) // Annotation as key/value pair
|
||
*
|
||
* Effect.runFork(program)
|
||
* // timestamp=... level=INFO fiber=#0 message=message1 taskId=1234
|
||
* // timestamp=... level=INFO fiber=#0 message=message2 taskId=1234
|
||
* ```
|
||
*
|
||
* @see {@link annotateLogsScoped} to add log annotations with a limited scope.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Logging
|
||
*/
|
||
<A, E, R>(effect: Effect<A, E, R>, values: Record<string, unknown>): Effect<A, E, R>;
|
||
};
|
||
/**
|
||
* Adds log annotations with a limited scope to enhance contextual logging.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to apply key-value annotations to log entries
|
||
* generated within a specific scope of your effect computations. The
|
||
* annotations are restricted to the defined `Scope`, ensuring that they are
|
||
* only applied to logs produced during that scope. Once the scope ends, the
|
||
* annotations are automatically removed, making it easier to manage
|
||
* context-specific logging without affecting other parts of your application.
|
||
*
|
||
* The annotations can be provided as a single key-value pair or as a record of
|
||
* multiple key-value pairs. This flexibility enables fine-grained control over
|
||
* the additional metadata included in logs for specific tasks or operations.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const program = Effect.gen(function*() {
|
||
* yield* Effect.log("no annotations")
|
||
* yield* Effect.annotateLogsScoped({ key: "value" })
|
||
* yield* Effect.log("message1") // Annotation is applied to this log
|
||
* yield* Effect.log("message2") // Annotation is applied to this log
|
||
* }).pipe(Effect.scoped, Effect.andThen(Effect.log("no annotations again")))
|
||
*
|
||
* Effect.runFork(program)
|
||
* // timestamp=... level=INFO fiber=#0 message="no annotations"
|
||
* // timestamp=... level=INFO fiber=#0 message=message1 key=value
|
||
* // timestamp=... level=INFO fiber=#0 message=message2 key=value
|
||
* // timestamp=... level=INFO fiber=#0 message="no annotations again"
|
||
* ```
|
||
*
|
||
* @see {@link annotateLogs} to add custom annotations to log entries generated within an effect.
|
||
*
|
||
* @since 3.1.0
|
||
* @category Logging
|
||
*/
|
||
export declare const annotateLogsScoped: {
|
||
/**
|
||
* Adds log annotations with a limited scope to enhance contextual logging.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to apply key-value annotations to log entries
|
||
* generated within a specific scope of your effect computations. The
|
||
* annotations are restricted to the defined `Scope`, ensuring that they are
|
||
* only applied to logs produced during that scope. Once the scope ends, the
|
||
* annotations are automatically removed, making it easier to manage
|
||
* context-specific logging without affecting other parts of your application.
|
||
*
|
||
* The annotations can be provided as a single key-value pair or as a record of
|
||
* multiple key-value pairs. This flexibility enables fine-grained control over
|
||
* the additional metadata included in logs for specific tasks or operations.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const program = Effect.gen(function*() {
|
||
* yield* Effect.log("no annotations")
|
||
* yield* Effect.annotateLogsScoped({ key: "value" })
|
||
* yield* Effect.log("message1") // Annotation is applied to this log
|
||
* yield* Effect.log("message2") // Annotation is applied to this log
|
||
* }).pipe(Effect.scoped, Effect.andThen(Effect.log("no annotations again")))
|
||
*
|
||
* Effect.runFork(program)
|
||
* // timestamp=... level=INFO fiber=#0 message="no annotations"
|
||
* // timestamp=... level=INFO fiber=#0 message=message1 key=value
|
||
* // timestamp=... level=INFO fiber=#0 message=message2 key=value
|
||
* // timestamp=... level=INFO fiber=#0 message="no annotations again"
|
||
* ```
|
||
*
|
||
* @see {@link annotateLogs} to add custom annotations to log entries generated within an effect.
|
||
*
|
||
* @since 3.1.0
|
||
* @category Logging
|
||
*/
|
||
(key: string, value: unknown): Effect<void, never, Scope.Scope>;
|
||
/**
|
||
* Adds log annotations with a limited scope to enhance contextual logging.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to apply key-value annotations to log entries
|
||
* generated within a specific scope of your effect computations. The
|
||
* annotations are restricted to the defined `Scope`, ensuring that they are
|
||
* only applied to logs produced during that scope. Once the scope ends, the
|
||
* annotations are automatically removed, making it easier to manage
|
||
* context-specific logging without affecting other parts of your application.
|
||
*
|
||
* The annotations can be provided as a single key-value pair or as a record of
|
||
* multiple key-value pairs. This flexibility enables fine-grained control over
|
||
* the additional metadata included in logs for specific tasks or operations.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const program = Effect.gen(function*() {
|
||
* yield* Effect.log("no annotations")
|
||
* yield* Effect.annotateLogsScoped({ key: "value" })
|
||
* yield* Effect.log("message1") // Annotation is applied to this log
|
||
* yield* Effect.log("message2") // Annotation is applied to this log
|
||
* }).pipe(Effect.scoped, Effect.andThen(Effect.log("no annotations again")))
|
||
*
|
||
* Effect.runFork(program)
|
||
* // timestamp=... level=INFO fiber=#0 message="no annotations"
|
||
* // timestamp=... level=INFO fiber=#0 message=message1 key=value
|
||
* // timestamp=... level=INFO fiber=#0 message=message2 key=value
|
||
* // timestamp=... level=INFO fiber=#0 message="no annotations again"
|
||
* ```
|
||
*
|
||
* @see {@link annotateLogs} to add custom annotations to log entries generated within an effect.
|
||
*
|
||
* @since 3.1.0
|
||
* @category Logging
|
||
*/
|
||
(values: Record<string, unknown>): Effect<void, never, Scope.Scope>;
|
||
};
|
||
/**
|
||
* Retrieves the current log annotations for the current scope.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function provides access to the log annotations associated with the
|
||
* current scope. Log annotations are key-value pairs that provide additional
|
||
* context to log entries. They are often used to add metadata such as tags,
|
||
* identifiers, or extra debugging information to logs.
|
||
*
|
||
* By using this function, you can inspect or utilize the annotations applied to
|
||
* the current scope, making it easier to trace and debug specific sections of
|
||
* your application.
|
||
*
|
||
* @see {@link annotateLogs} to add custom annotations to log entries generated within an effect.
|
||
* @see {@link annotateLogsScoped} to add log annotations with a limited scope.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Logging
|
||
*/
|
||
export declare const logAnnotations: Effect<HashMap.HashMap<string, unknown>>;
|
||
/**
|
||
* Configures whether child fibers will log unhandled errors and at what log
|
||
* level.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to control whether unhandled errors from child
|
||
* fibers are logged and to specify the log level for these errors. By default,
|
||
* unhandled errors are reported via the logger. However, using this function,
|
||
* you can choose to suppress these logs by passing `Option.none` or adjust the
|
||
* log level to a specific severity, such as `Error`, `Warning`, or `Info`.
|
||
*
|
||
* This configuration is scoped to the effect it is applied to, meaning the
|
||
* changes only apply to the child fibers created within that effect's context.
|
||
* It is especially useful when you want to reduce noise in logs or prioritize
|
||
* certain types of errors.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Fiber, LogLevel, Option } from "effect"
|
||
*
|
||
* const program = Effect.gen(function*() {
|
||
* const fiber = yield* Effect.fork(Effect.fail("Unhandled error!"))
|
||
* yield* Fiber.join(fiber)
|
||
* })
|
||
*
|
||
* Effect.runFork(program.pipe(Effect.withUnhandledErrorLogLevel(Option.some(LogLevel.Error))))
|
||
* // Output:
|
||
* // timestamp=... level=ERROR fiber=#1 message="Fiber terminated with an unhandled error" cause="Error: Unhandled error!"
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Logging
|
||
*/
|
||
export declare const withUnhandledErrorLogLevel: {
|
||
/**
|
||
* Configures whether child fibers will log unhandled errors and at what log
|
||
* level.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to control whether unhandled errors from child
|
||
* fibers are logged and to specify the log level for these errors. By default,
|
||
* unhandled errors are reported via the logger. However, using this function,
|
||
* you can choose to suppress these logs by passing `Option.none` or adjust the
|
||
* log level to a specific severity, such as `Error`, `Warning`, or `Info`.
|
||
*
|
||
* This configuration is scoped to the effect it is applied to, meaning the
|
||
* changes only apply to the child fibers created within that effect's context.
|
||
* It is especially useful when you want to reduce noise in logs or prioritize
|
||
* certain types of errors.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Fiber, LogLevel, Option } from "effect"
|
||
*
|
||
* const program = Effect.gen(function*() {
|
||
* const fiber = yield* Effect.fork(Effect.fail("Unhandled error!"))
|
||
* yield* Fiber.join(fiber)
|
||
* })
|
||
*
|
||
* Effect.runFork(program.pipe(Effect.withUnhandledErrorLogLevel(Option.some(LogLevel.Error))))
|
||
* // Output:
|
||
* // timestamp=... level=ERROR fiber=#1 message="Fiber terminated with an unhandled error" cause="Error: Unhandled error!"
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Logging
|
||
*/
|
||
(level: Option.Option<LogLevel.LogLevel>): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, R>;
|
||
/**
|
||
* Configures whether child fibers will log unhandled errors and at what log
|
||
* level.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to control whether unhandled errors from child
|
||
* fibers are logged and to specify the log level for these errors. By default,
|
||
* unhandled errors are reported via the logger. However, using this function,
|
||
* you can choose to suppress these logs by passing `Option.none` or adjust the
|
||
* log level to a specific severity, such as `Error`, `Warning`, or `Info`.
|
||
*
|
||
* This configuration is scoped to the effect it is applied to, meaning the
|
||
* changes only apply to the child fibers created within that effect's context.
|
||
* It is especially useful when you want to reduce noise in logs or prioritize
|
||
* certain types of errors.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Fiber, LogLevel, Option } from "effect"
|
||
*
|
||
* const program = Effect.gen(function*() {
|
||
* const fiber = yield* Effect.fork(Effect.fail("Unhandled error!"))
|
||
* yield* Fiber.join(fiber)
|
||
* })
|
||
*
|
||
* Effect.runFork(program.pipe(Effect.withUnhandledErrorLogLevel(Option.some(LogLevel.Error))))
|
||
* // Output:
|
||
* // timestamp=... level=ERROR fiber=#1 message="Fiber terminated with an unhandled error" cause="Error: Unhandled error!"
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Logging
|
||
*/
|
||
<A, E, R>(self: Effect<A, E, R>, level: Option.Option<LogLevel.LogLevel>): Effect<A, E, R>;
|
||
};
|
||
/**
|
||
* Conditionally executes an effect based on the specified log level and currently enabled log level.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function runs the provided effect only if the specified log level is
|
||
* enabled. If the log level is enabled, the effect is executed and its result
|
||
* is wrapped in `Some`. If the log level is not enabled, the effect is not
|
||
* executed and `None` is returned.
|
||
*
|
||
* This function is useful for conditionally executing logging-related effects
|
||
* or other operations that depend on the current log level configuration.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Logger, LogLevel } from "effect"
|
||
*
|
||
* const program = Effect.gen(function* () {
|
||
* yield* Effect.whenLogLevel(Effect.logTrace("message1"), LogLevel.Trace); // returns `None`
|
||
* yield* Effect.whenLogLevel(Effect.logDebug("message2"), LogLevel.Debug); // returns `Some`
|
||
* }).pipe(Logger.withMinimumLogLevel(LogLevel.Debug));
|
||
*
|
||
* Effect.runFork(program)
|
||
* // timestamp=... level=DEBUG fiber=#0 message=message2
|
||
* ```
|
||
*
|
||
* @see {@link FiberRef.currentMinimumLogLevel} to retrieve the current minimum log level.
|
||
*
|
||
* @since 3.13.0
|
||
* @category Logging
|
||
*/
|
||
export declare const whenLogLevel: {
|
||
/**
|
||
* Conditionally executes an effect based on the specified log level and currently enabled log level.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function runs the provided effect only if the specified log level is
|
||
* enabled. If the log level is enabled, the effect is executed and its result
|
||
* is wrapped in `Some`. If the log level is not enabled, the effect is not
|
||
* executed and `None` is returned.
|
||
*
|
||
* This function is useful for conditionally executing logging-related effects
|
||
* or other operations that depend on the current log level configuration.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Logger, LogLevel } from "effect"
|
||
*
|
||
* const program = Effect.gen(function* () {
|
||
* yield* Effect.whenLogLevel(Effect.logTrace("message1"), LogLevel.Trace); // returns `None`
|
||
* yield* Effect.whenLogLevel(Effect.logDebug("message2"), LogLevel.Debug); // returns `Some`
|
||
* }).pipe(Logger.withMinimumLogLevel(LogLevel.Debug));
|
||
*
|
||
* Effect.runFork(program)
|
||
* // timestamp=... level=DEBUG fiber=#0 message=message2
|
||
* ```
|
||
*
|
||
* @see {@link FiberRef.currentMinimumLogLevel} to retrieve the current minimum log level.
|
||
*
|
||
* @since 3.13.0
|
||
* @category Logging
|
||
*/
|
||
(level: LogLevel.LogLevel | LogLevel.Literal): <A, E, R>(self: Effect<A, E, R>) => Effect<Option.Option<A>, E, R>;
|
||
/**
|
||
* Conditionally executes an effect based on the specified log level and currently enabled log level.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function runs the provided effect only if the specified log level is
|
||
* enabled. If the log level is enabled, the effect is executed and its result
|
||
* is wrapped in `Some`. If the log level is not enabled, the effect is not
|
||
* executed and `None` is returned.
|
||
*
|
||
* This function is useful for conditionally executing logging-related effects
|
||
* or other operations that depend on the current log level configuration.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Logger, LogLevel } from "effect"
|
||
*
|
||
* const program = Effect.gen(function* () {
|
||
* yield* Effect.whenLogLevel(Effect.logTrace("message1"), LogLevel.Trace); // returns `None`
|
||
* yield* Effect.whenLogLevel(Effect.logDebug("message2"), LogLevel.Debug); // returns `Some`
|
||
* }).pipe(Logger.withMinimumLogLevel(LogLevel.Debug));
|
||
*
|
||
* Effect.runFork(program)
|
||
* // timestamp=... level=DEBUG fiber=#0 message=message2
|
||
* ```
|
||
*
|
||
* @see {@link FiberRef.currentMinimumLogLevel} to retrieve the current minimum log level.
|
||
*
|
||
* @since 3.13.0
|
||
* @category Logging
|
||
*/
|
||
<A, E, R>(self: Effect<A, E, R>, level: LogLevel.LogLevel | LogLevel.Literal): Effect<Option.Option<A>, E, R>;
|
||
};
|
||
/**
|
||
* Converts an effect's failure into a fiber termination, removing the error
|
||
* from the effect's type.
|
||
*
|
||
* **Details**
|
||
*
|
||
* The `orDie` function is used when you encounter errors that you do not want
|
||
* to handle or recover from. It removes the error type from the effect and
|
||
* ensures that any failure will terminate the fiber. This is useful for
|
||
* propagating failures as defects, signaling that they should not be handled
|
||
* within the effect.
|
||
*
|
||
* **When to Use*
|
||
*
|
||
* Use `orDie` when failures should be treated as unrecoverable defects and no
|
||
* error handling is required.
|
||
*
|
||
* **Example** (Propagating an Error as a Defect)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const divide = (a: number, b: number) =>
|
||
* b === 0
|
||
* ? Effect.fail(new Error("Cannot divide by zero"))
|
||
* : Effect.succeed(a / b)
|
||
*
|
||
* // ┌─── Effect<number, never, never>
|
||
* // ▼
|
||
* const program = Effect.orDie(divide(1, 0))
|
||
*
|
||
* Effect.runPromise(program).catch(console.error)
|
||
* // Output:
|
||
* // (FiberFailure) Error: Cannot divide by zero
|
||
* // ...stack trace...
|
||
* ```
|
||
*
|
||
* @see {@link orDieWith} if you need to customize the error.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Converting Failures to Defects
|
||
*/
|
||
export declare const orDie: <A, E, R>(self: Effect<A, E, R>) => Effect<A, never, R>;
|
||
/**
|
||
* Converts an effect's failure into a fiber termination with a custom error.
|
||
*
|
||
* **Details**
|
||
*
|
||
* The `orDieWith` function behaves like {@link orDie}, but it allows you to provide a mapping
|
||
* function to transform the error before terminating the fiber. This is useful for cases where
|
||
* you want to include a more detailed or user-friendly error when the failure is propagated
|
||
* as a defect.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use `orDieWith` when failures should terminate the fiber as defects, and you want to customize
|
||
* the error for clarity or debugging purposes.
|
||
*
|
||
* **Example** (Customizing Defect)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const divide = (a: number, b: number) =>
|
||
* b === 0
|
||
* ? Effect.fail(new Error("Cannot divide by zero"))
|
||
* : Effect.succeed(a / b)
|
||
*
|
||
* // ┌─── Effect<number, never, never>
|
||
* // ▼
|
||
* const program = Effect.orDieWith(
|
||
* divide(1, 0),
|
||
* (error) => new Error(`defect: ${error.message}`)
|
||
* )
|
||
*
|
||
* Effect.runPromise(program).catch(console.error)
|
||
* // Output:
|
||
* // (FiberFailure) Error: defect: Cannot divide by zero
|
||
* // ...stack trace...
|
||
* ```
|
||
*
|
||
* @see {@link orDie} if you don't need to customize the error.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Converting Failures to Defects
|
||
*/
|
||
export declare const orDieWith: {
|
||
/**
|
||
* Converts an effect's failure into a fiber termination with a custom error.
|
||
*
|
||
* **Details**
|
||
*
|
||
* The `orDieWith` function behaves like {@link orDie}, but it allows you to provide a mapping
|
||
* function to transform the error before terminating the fiber. This is useful for cases where
|
||
* you want to include a more detailed or user-friendly error when the failure is propagated
|
||
* as a defect.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use `orDieWith` when failures should terminate the fiber as defects, and you want to customize
|
||
* the error for clarity or debugging purposes.
|
||
*
|
||
* **Example** (Customizing Defect)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const divide = (a: number, b: number) =>
|
||
* b === 0
|
||
* ? Effect.fail(new Error("Cannot divide by zero"))
|
||
* : Effect.succeed(a / b)
|
||
*
|
||
* // ┌─── Effect<number, never, never>
|
||
* // ▼
|
||
* const program = Effect.orDieWith(
|
||
* divide(1, 0),
|
||
* (error) => new Error(`defect: ${error.message}`)
|
||
* )
|
||
*
|
||
* Effect.runPromise(program).catch(console.error)
|
||
* // Output:
|
||
* // (FiberFailure) Error: defect: Cannot divide by zero
|
||
* // ...stack trace...
|
||
* ```
|
||
*
|
||
* @see {@link orDie} if you don't need to customize the error.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Converting Failures to Defects
|
||
*/
|
||
<E>(f: (error: E) => unknown): <A, R>(self: Effect<A, E, R>) => Effect<A, never, R>;
|
||
/**
|
||
* Converts an effect's failure into a fiber termination with a custom error.
|
||
*
|
||
* **Details**
|
||
*
|
||
* The `orDieWith` function behaves like {@link orDie}, but it allows you to provide a mapping
|
||
* function to transform the error before terminating the fiber. This is useful for cases where
|
||
* you want to include a more detailed or user-friendly error when the failure is propagated
|
||
* as a defect.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use `orDieWith` when failures should terminate the fiber as defects, and you want to customize
|
||
* the error for clarity or debugging purposes.
|
||
*
|
||
* **Example** (Customizing Defect)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const divide = (a: number, b: number) =>
|
||
* b === 0
|
||
* ? Effect.fail(new Error("Cannot divide by zero"))
|
||
* : Effect.succeed(a / b)
|
||
*
|
||
* // ┌─── Effect<number, never, never>
|
||
* // ▼
|
||
* const program = Effect.orDieWith(
|
||
* divide(1, 0),
|
||
* (error) => new Error(`defect: ${error.message}`)
|
||
* )
|
||
*
|
||
* Effect.runPromise(program).catch(console.error)
|
||
* // Output:
|
||
* // (FiberFailure) Error: defect: Cannot divide by zero
|
||
* // ...stack trace...
|
||
* ```
|
||
*
|
||
* @see {@link orDie} if you don't need to customize the error.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Converting Failures to Defects
|
||
*/
|
||
<A, E, R>(self: Effect<A, E, R>, f: (error: E) => unknown): Effect<A, never, R>;
|
||
};
|
||
/**
|
||
* Attempts one effect, and if it fails, falls back to another effect.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to try executing an effect, and if it fails
|
||
* (produces an error), a fallback effect is executed instead. The fallback
|
||
* effect is defined as a lazy argument, meaning it will only be evaluated if
|
||
* the first effect fails. This provides a way to recover from errors by
|
||
* specifying an alternative path of execution.
|
||
*
|
||
* The error type of the resulting effect will be that of the fallback effect,
|
||
* as the first effect's error is replaced when the fallback is executed.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const success = Effect.succeed("success")
|
||
* const failure = Effect.fail("failure")
|
||
* const fallback = Effect.succeed("fallback")
|
||
*
|
||
* // Try the success effect first, fallback is not used
|
||
* const program1 = Effect.orElse(success, () => fallback)
|
||
* console.log(Effect.runSync(program1))
|
||
* // Output: "success"
|
||
*
|
||
* // Try the failure effect first, fallback is used
|
||
* const program2 = Effect.orElse(failure, () => fallback)
|
||
* console.log(Effect.runSync(program2))
|
||
* // Output: "fallback"
|
||
* ```
|
||
*
|
||
* @see {@link catchAll} if you need to access the error in the fallback effect.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Fallback
|
||
*/
|
||
export declare const orElse: {
|
||
/**
|
||
* Attempts one effect, and if it fails, falls back to another effect.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to try executing an effect, and if it fails
|
||
* (produces an error), a fallback effect is executed instead. The fallback
|
||
* effect is defined as a lazy argument, meaning it will only be evaluated if
|
||
* the first effect fails. This provides a way to recover from errors by
|
||
* specifying an alternative path of execution.
|
||
*
|
||
* The error type of the resulting effect will be that of the fallback effect,
|
||
* as the first effect's error is replaced when the fallback is executed.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const success = Effect.succeed("success")
|
||
* const failure = Effect.fail("failure")
|
||
* const fallback = Effect.succeed("fallback")
|
||
*
|
||
* // Try the success effect first, fallback is not used
|
||
* const program1 = Effect.orElse(success, () => fallback)
|
||
* console.log(Effect.runSync(program1))
|
||
* // Output: "success"
|
||
*
|
||
* // Try the failure effect first, fallback is used
|
||
* const program2 = Effect.orElse(failure, () => fallback)
|
||
* console.log(Effect.runSync(program2))
|
||
* // Output: "fallback"
|
||
* ```
|
||
*
|
||
* @see {@link catchAll} if you need to access the error in the fallback effect.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Fallback
|
||
*/
|
||
<A2, E2, R2>(that: LazyArg<Effect<A2, E2, R2>>): <A, E, R>(self: Effect<A, E, R>) => Effect<A2 | A, E2, R2 | R>;
|
||
/**
|
||
* Attempts one effect, and if it fails, falls back to another effect.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to try executing an effect, and if it fails
|
||
* (produces an error), a fallback effect is executed instead. The fallback
|
||
* effect is defined as a lazy argument, meaning it will only be evaluated if
|
||
* the first effect fails. This provides a way to recover from errors by
|
||
* specifying an alternative path of execution.
|
||
*
|
||
* The error type of the resulting effect will be that of the fallback effect,
|
||
* as the first effect's error is replaced when the fallback is executed.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const success = Effect.succeed("success")
|
||
* const failure = Effect.fail("failure")
|
||
* const fallback = Effect.succeed("fallback")
|
||
*
|
||
* // Try the success effect first, fallback is not used
|
||
* const program1 = Effect.orElse(success, () => fallback)
|
||
* console.log(Effect.runSync(program1))
|
||
* // Output: "success"
|
||
*
|
||
* // Try the failure effect first, fallback is used
|
||
* const program2 = Effect.orElse(failure, () => fallback)
|
||
* console.log(Effect.runSync(program2))
|
||
* // Output: "fallback"
|
||
* ```
|
||
*
|
||
* @see {@link catchAll} if you need to access the error in the fallback effect.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Fallback
|
||
*/
|
||
<A, E, R, A2, E2, R2>(self: Effect<A, E, R>, that: LazyArg<Effect<A2, E2, R2>>): Effect<A2 | A, E2, R2 | R>;
|
||
};
|
||
/**
|
||
* Replaces the failure of an effect with a custom failure value.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to handle the failure of an effect by replacing it
|
||
* with a predefined failure value. If the effect fails, the new failure value
|
||
* provided by the `evaluate` function will be returned instead of the original
|
||
* failure. If the effect succeeds, the original success value is returned
|
||
* unchanged.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is particularly useful when you want to standardize error handling or
|
||
* provide a consistent failure value for specific operations. It simplifies
|
||
* error management by ensuring that all failures are replaced with a controlled
|
||
* alternative.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const validate = (age: number): Effect.Effect<number, string> => {
|
||
* if (age < 0) {
|
||
* return Effect.fail("NegativeAgeError")
|
||
* } else if (age < 18) {
|
||
* return Effect.fail("IllegalAgeError")
|
||
* } else {
|
||
* return Effect.succeed(age)
|
||
* }
|
||
* }
|
||
*
|
||
* const program = Effect.orElseFail(validate(-1), () => "invalid age")
|
||
*
|
||
* console.log(Effect.runSyncExit(program))
|
||
* // Output:
|
||
* // {
|
||
* // _id: 'Exit',
|
||
* // _tag: 'Failure',
|
||
* // cause: { _id: 'Cause', _tag: 'Fail', failure: 'invalid age' }
|
||
* // }
|
||
* ```
|
||
*
|
||
* @see {@link mapError} if you need to access the error to transform it.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Fallback
|
||
*/
|
||
export declare const orElseFail: {
|
||
/**
|
||
* Replaces the failure of an effect with a custom failure value.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to handle the failure of an effect by replacing it
|
||
* with a predefined failure value. If the effect fails, the new failure value
|
||
* provided by the `evaluate` function will be returned instead of the original
|
||
* failure. If the effect succeeds, the original success value is returned
|
||
* unchanged.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is particularly useful when you want to standardize error handling or
|
||
* provide a consistent failure value for specific operations. It simplifies
|
||
* error management by ensuring that all failures are replaced with a controlled
|
||
* alternative.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const validate = (age: number): Effect.Effect<number, string> => {
|
||
* if (age < 0) {
|
||
* return Effect.fail("NegativeAgeError")
|
||
* } else if (age < 18) {
|
||
* return Effect.fail("IllegalAgeError")
|
||
* } else {
|
||
* return Effect.succeed(age)
|
||
* }
|
||
* }
|
||
*
|
||
* const program = Effect.orElseFail(validate(-1), () => "invalid age")
|
||
*
|
||
* console.log(Effect.runSyncExit(program))
|
||
* // Output:
|
||
* // {
|
||
* // _id: 'Exit',
|
||
* // _tag: 'Failure',
|
||
* // cause: { _id: 'Cause', _tag: 'Fail', failure: 'invalid age' }
|
||
* // }
|
||
* ```
|
||
*
|
||
* @see {@link mapError} if you need to access the error to transform it.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Fallback
|
||
*/
|
||
<E2>(evaluate: LazyArg<E2>): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E2, R>;
|
||
/**
|
||
* Replaces the failure of an effect with a custom failure value.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to handle the failure of an effect by replacing it
|
||
* with a predefined failure value. If the effect fails, the new failure value
|
||
* provided by the `evaluate` function will be returned instead of the original
|
||
* failure. If the effect succeeds, the original success value is returned
|
||
* unchanged.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is particularly useful when you want to standardize error handling or
|
||
* provide a consistent failure value for specific operations. It simplifies
|
||
* error management by ensuring that all failures are replaced with a controlled
|
||
* alternative.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const validate = (age: number): Effect.Effect<number, string> => {
|
||
* if (age < 0) {
|
||
* return Effect.fail("NegativeAgeError")
|
||
* } else if (age < 18) {
|
||
* return Effect.fail("IllegalAgeError")
|
||
* } else {
|
||
* return Effect.succeed(age)
|
||
* }
|
||
* }
|
||
*
|
||
* const program = Effect.orElseFail(validate(-1), () => "invalid age")
|
||
*
|
||
* console.log(Effect.runSyncExit(program))
|
||
* // Output:
|
||
* // {
|
||
* // _id: 'Exit',
|
||
* // _tag: 'Failure',
|
||
* // cause: { _id: 'Cause', _tag: 'Fail', failure: 'invalid age' }
|
||
* // }
|
||
* ```
|
||
*
|
||
* @see {@link mapError} if you need to access the error to transform it.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Fallback
|
||
*/
|
||
<A, E, R, E2>(self: Effect<A, E, R>, evaluate: LazyArg<E2>): Effect<A, E2, R>;
|
||
};
|
||
/**
|
||
* Ensures the effect always succeeds by replacing failures with a default
|
||
* success value.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function transforms an effect that may fail into one that cannot fail by
|
||
* replacing any failure with a provided success value. If the original effect
|
||
* fails, the failure is "swallowed," and the specified success value is
|
||
* returned instead. If the original effect succeeds, its value remains
|
||
* unchanged.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is especially useful for providing default values in case of failure,
|
||
* ensuring that an effect always completes successfully. By using this
|
||
* function, you can avoid the need for complex error handling and guarantee a
|
||
* fallback result.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const validate = (age: number): Effect.Effect<number, string> => {
|
||
* if (age < 0) {
|
||
* return Effect.fail("NegativeAgeError")
|
||
* } else if (age < 18) {
|
||
* return Effect.fail("IllegalAgeError")
|
||
* } else {
|
||
* return Effect.succeed(age)
|
||
* }
|
||
* }
|
||
*
|
||
* const program = Effect.orElseSucceed(validate(-1), () => 18)
|
||
*
|
||
* console.log(Effect.runSyncExit(program))
|
||
* // Output:
|
||
* // { _id: 'Exit', _tag: 'Success', value: 18 }
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Fallback
|
||
*/
|
||
export declare const orElseSucceed: {
|
||
/**
|
||
* Ensures the effect always succeeds by replacing failures with a default
|
||
* success value.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function transforms an effect that may fail into one that cannot fail by
|
||
* replacing any failure with a provided success value. If the original effect
|
||
* fails, the failure is "swallowed," and the specified success value is
|
||
* returned instead. If the original effect succeeds, its value remains
|
||
* unchanged.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is especially useful for providing default values in case of failure,
|
||
* ensuring that an effect always completes successfully. By using this
|
||
* function, you can avoid the need for complex error handling and guarantee a
|
||
* fallback result.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const validate = (age: number): Effect.Effect<number, string> => {
|
||
* if (age < 0) {
|
||
* return Effect.fail("NegativeAgeError")
|
||
* } else if (age < 18) {
|
||
* return Effect.fail("IllegalAgeError")
|
||
* } else {
|
||
* return Effect.succeed(age)
|
||
* }
|
||
* }
|
||
*
|
||
* const program = Effect.orElseSucceed(validate(-1), () => 18)
|
||
*
|
||
* console.log(Effect.runSyncExit(program))
|
||
* // Output:
|
||
* // { _id: 'Exit', _tag: 'Success', value: 18 }
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Fallback
|
||
*/
|
||
<A2>(evaluate: LazyArg<A2>): <A, E, R>(self: Effect<A, E, R>) => Effect<A2 | A, never, R>;
|
||
/**
|
||
* Ensures the effect always succeeds by replacing failures with a default
|
||
* success value.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function transforms an effect that may fail into one that cannot fail by
|
||
* replacing any failure with a provided success value. If the original effect
|
||
* fails, the failure is "swallowed," and the specified success value is
|
||
* returned instead. If the original effect succeeds, its value remains
|
||
* unchanged.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is especially useful for providing default values in case of failure,
|
||
* ensuring that an effect always completes successfully. By using this
|
||
* function, you can avoid the need for complex error handling and guarantee a
|
||
* fallback result.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const validate = (age: number): Effect.Effect<number, string> => {
|
||
* if (age < 0) {
|
||
* return Effect.fail("NegativeAgeError")
|
||
* } else if (age < 18) {
|
||
* return Effect.fail("IllegalAgeError")
|
||
* } else {
|
||
* return Effect.succeed(age)
|
||
* }
|
||
* }
|
||
*
|
||
* const program = Effect.orElseSucceed(validate(-1), () => 18)
|
||
*
|
||
* console.log(Effect.runSyncExit(program))
|
||
* // Output:
|
||
* // { _id: 'Exit', _tag: 'Success', value: 18 }
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Fallback
|
||
*/
|
||
<A, E, R, A2>(self: Effect<A, E, R>, evaluate: LazyArg<A2>): Effect<A | A2, never, R>;
|
||
};
|
||
/**
|
||
* Runs a sequence of effects and returns the result of the first successful
|
||
* one.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to execute a collection of effects in sequence,
|
||
* stopping at the first success. If an effect succeeds, its result is
|
||
* immediately returned, and no further effects in the sequence are executed.
|
||
* However, if all the effects fail, the function will return the error of the
|
||
* last effect.
|
||
*
|
||
* The execution is sequential, meaning that effects are evaluated one at a time
|
||
* in the order they are provided. This ensures predictable behavior and avoids
|
||
* unnecessary computations.
|
||
*
|
||
* If the collection of effects is empty, an `IllegalArgumentException` is
|
||
* thrown, indicating that the operation is invalid without any effects to try.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is particularly useful when you have multiple fallback strategies or
|
||
* alternative sources to obtain a result, such as attempting multiple APIs,
|
||
* retrieving configurations, or accessing resources in a prioritized manner.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* interface Config {
|
||
* host: string
|
||
* port: number
|
||
* apiKey: string
|
||
* }
|
||
*
|
||
* // Create a configuration object with sample values
|
||
* const makeConfig = (name: string): Config => ({
|
||
* host: `${name}.example.com`,
|
||
* port: 8080,
|
||
* apiKey: "12345-abcde"
|
||
* })
|
||
*
|
||
* // Simulate retrieving configuration from a remote node
|
||
* const remoteConfig = (name: string): Effect.Effect<Config, Error> =>
|
||
* Effect.gen(function* () {
|
||
* // Simulate node3 being the only one with available config
|
||
* if (name === "node3") {
|
||
* yield* Console.log(`Config for ${name} found`)
|
||
* return makeConfig(name)
|
||
* } else {
|
||
* yield* Console.log(`Unavailable config for ${name}`)
|
||
* return yield* Effect.fail(new Error(`Config not found for ${name}`))
|
||
* }
|
||
* })
|
||
*
|
||
* // Define the master configuration and potential fallback nodes
|
||
* const masterConfig = remoteConfig("master")
|
||
* const nodeConfigs = ["node1", "node2", "node3", "node4"].map(remoteConfig)
|
||
*
|
||
* // Attempt to find a working configuration,
|
||
* // starting with the master and then falling back to other nodes
|
||
* const config = Effect.firstSuccessOf([masterConfig, ...nodeConfigs])
|
||
*
|
||
* // Run the effect to retrieve the configuration
|
||
* const result = Effect.runSync(config)
|
||
*
|
||
* console.log(result)
|
||
* // Output:
|
||
* // Unavailable config for master
|
||
* // Unavailable config for node1
|
||
* // Unavailable config for node2
|
||
* // Config for node3 found
|
||
* // { host: 'node3.example.com', port: 8080, apiKey: '12345-abcde' }
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Fallback
|
||
*/
|
||
export declare const firstSuccessOf: <Eff extends Effect<any, any, any>>(effects: Iterable<Eff>) => Effect<Effect.Success<Eff>, Effect.Error<Eff>, Effect.Context<Eff>>;
|
||
/**
|
||
* Retrieves the `Random` service from the context.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Random
|
||
*/
|
||
export declare const random: Effect<Random.Random>;
|
||
/**
|
||
* Retrieves the `Random` service from the context and uses it to run the
|
||
* specified effect.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Random
|
||
*/
|
||
export declare const randomWith: <A, E, R>(f: (random: Random.Random) => Effect<A, E, R>) => Effect<A, E, R>;
|
||
/**
|
||
* Executes the specified effect with the specified implementation of the
|
||
* `Random` service.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Random
|
||
*/
|
||
export declare const withRandom: {
|
||
/**
|
||
* Executes the specified effect with the specified implementation of the
|
||
* `Random` service.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Random
|
||
*/
|
||
<X extends Random.Random>(value: X): <A, E, R>(effect: Effect<A, E, R>) => Effect<A, E, R>;
|
||
/**
|
||
* Executes the specified effect with the specified implementation of the
|
||
* `Random` service.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Random
|
||
*/
|
||
<X extends Random.Random, A, E, R>(effect: Effect<A, E, R>, value: X): Effect<A, E, R>;
|
||
};
|
||
/**
|
||
* Executes the specified effect with a `Random` service that cycles through
|
||
* a provided array of values.
|
||
*
|
||
* @example
|
||
* ```ts
|
||
* import { Effect, Random } from "effect"
|
||
*
|
||
* Effect.gen(function*() {
|
||
* console.log(yield* Random.next) // 0.2
|
||
* console.log(yield* Random.next) // 0.5
|
||
* console.log(yield* Random.next) // 0.8
|
||
* }).pipe(Effect.withRandomFixed([0.2, 0.5, 0.8]))
|
||
* ```
|
||
*
|
||
* @since 3.11.0
|
||
* @category Random
|
||
*/
|
||
export declare const withRandomFixed: {
|
||
/**
|
||
* Executes the specified effect with a `Random` service that cycles through
|
||
* a provided array of values.
|
||
*
|
||
* @example
|
||
* ```ts
|
||
* import { Effect, Random } from "effect"
|
||
*
|
||
* Effect.gen(function*() {
|
||
* console.log(yield* Random.next) // 0.2
|
||
* console.log(yield* Random.next) // 0.5
|
||
* console.log(yield* Random.next) // 0.8
|
||
* }).pipe(Effect.withRandomFixed([0.2, 0.5, 0.8]))
|
||
* ```
|
||
*
|
||
* @since 3.11.0
|
||
* @category Random
|
||
*/
|
||
<T extends RA.NonEmptyArray<any>>(values: T): <A, E, R>(effect: Effect<A, E, R>) => Effect<A, E, R>;
|
||
/**
|
||
* Executes the specified effect with a `Random` service that cycles through
|
||
* a provided array of values.
|
||
*
|
||
* @example
|
||
* ```ts
|
||
* import { Effect, Random } from "effect"
|
||
*
|
||
* Effect.gen(function*() {
|
||
* console.log(yield* Random.next) // 0.2
|
||
* console.log(yield* Random.next) // 0.5
|
||
* console.log(yield* Random.next) // 0.8
|
||
* }).pipe(Effect.withRandomFixed([0.2, 0.5, 0.8]))
|
||
* ```
|
||
*
|
||
* @since 3.11.0
|
||
* @category Random
|
||
*/
|
||
<T extends RA.NonEmptyArray<any>, A, E, R>(effect: Effect<A, E, R>, values: T): Effect<A, E, R>;
|
||
};
|
||
/**
|
||
* Sets the implementation of the `Random` service to the specified value and
|
||
* restores it to its original value when the scope is closed.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Random
|
||
*/
|
||
export declare const withRandomScoped: <A extends Random.Random>(value: A) => Effect<void, never, Scope.Scope>;
|
||
/**
|
||
* Returns an effect that accesses the runtime, which can be used to (unsafely)
|
||
* execute tasks.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This is useful for integration with legacy code that must call back into
|
||
* Effect code.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Runtime
|
||
*/
|
||
export declare const runtime: <R = never>() => Effect<Runtime.Runtime<R>, never, R>;
|
||
/**
|
||
* Retrieves an effect that succeeds with the current runtime flags, which
|
||
* govern behavior and features of the runtime system.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Runtime
|
||
*/
|
||
export declare const getRuntimeFlags: Effect<RuntimeFlags.RuntimeFlags>;
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Runtime
|
||
*/
|
||
export declare const patchRuntimeFlags: (patch: RuntimeFlagsPatch.RuntimeFlagsPatch) => Effect<void>;
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Runtime
|
||
*/
|
||
export declare const withRuntimeFlagsPatch: {
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Runtime
|
||
*/
|
||
(update: RuntimeFlagsPatch.RuntimeFlagsPatch): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, R>;
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Runtime
|
||
*/
|
||
<A, E, R>(self: Effect<A, E, R>, update: RuntimeFlagsPatch.RuntimeFlagsPatch): Effect<A, E, R>;
|
||
};
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Runtime
|
||
*/
|
||
export declare const withRuntimeFlagsPatchScoped: (update: RuntimeFlagsPatch.RuntimeFlagsPatch) => Effect<void, never, Scope.Scope>;
|
||
/**
|
||
* Tags each metric in an effect with specific key-value pairs.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to tag all metrics in an effect with a set of
|
||
* key-value pairs or a single key-value pair. Tags help you add metadata to
|
||
* metrics, making it easier to filter and categorize them in monitoring
|
||
* systems. The provided tags will apply to all metrics generated within the
|
||
* effect's scope.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Metrics
|
||
*/
|
||
export declare const tagMetrics: {
|
||
/**
|
||
* Tags each metric in an effect with specific key-value pairs.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to tag all metrics in an effect with a set of
|
||
* key-value pairs or a single key-value pair. Tags help you add metadata to
|
||
* metrics, making it easier to filter and categorize them in monitoring
|
||
* systems. The provided tags will apply to all metrics generated within the
|
||
* effect's scope.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Metrics
|
||
*/
|
||
(key: string, value: string): <A, E, R>(effect: Effect<A, E, R>) => Effect<A, E, R>;
|
||
/**
|
||
* Tags each metric in an effect with specific key-value pairs.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to tag all metrics in an effect with a set of
|
||
* key-value pairs or a single key-value pair. Tags help you add metadata to
|
||
* metrics, making it easier to filter and categorize them in monitoring
|
||
* systems. The provided tags will apply to all metrics generated within the
|
||
* effect's scope.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Metrics
|
||
*/
|
||
(values: Record<string, string>): <A, E, R>(effect: Effect<A, E, R>) => Effect<A, E, R>;
|
||
/**
|
||
* Tags each metric in an effect with specific key-value pairs.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to tag all metrics in an effect with a set of
|
||
* key-value pairs or a single key-value pair. Tags help you add metadata to
|
||
* metrics, making it easier to filter and categorize them in monitoring
|
||
* systems. The provided tags will apply to all metrics generated within the
|
||
* effect's scope.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Metrics
|
||
*/
|
||
<A, E, R>(effect: Effect<A, E, R>, key: string, value: string): Effect<A, E, R>;
|
||
/**
|
||
* Tags each metric in an effect with specific key-value pairs.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to tag all metrics in an effect with a set of
|
||
* key-value pairs or a single key-value pair. Tags help you add metadata to
|
||
* metrics, making it easier to filter and categorize them in monitoring
|
||
* systems. The provided tags will apply to all metrics generated within the
|
||
* effect's scope.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Metrics
|
||
*/
|
||
<A, E, R>(effect: Effect<A, E, R>, values: Record<string, string>): Effect<A, E, R>;
|
||
};
|
||
/**
|
||
* Adds labels to metrics within an effect using `MetricLabel` objects.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to label metrics using `MetricLabel` objects. Labels
|
||
* help add structured metadata to metrics for categorization and filtering in
|
||
* monitoring systems. The provided labels will apply to all metrics within the
|
||
* effect's execution.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Metrics
|
||
*/
|
||
export declare const labelMetrics: {
|
||
/**
|
||
* Adds labels to metrics within an effect using `MetricLabel` objects.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to label metrics using `MetricLabel` objects. Labels
|
||
* help add structured metadata to metrics for categorization and filtering in
|
||
* monitoring systems. The provided labels will apply to all metrics within the
|
||
* effect's execution.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Metrics
|
||
*/
|
||
(labels: Iterable<MetricLabel.MetricLabel>): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, R>;
|
||
/**
|
||
* Adds labels to metrics within an effect using `MetricLabel` objects.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to label metrics using `MetricLabel` objects. Labels
|
||
* help add structured metadata to metrics for categorization and filtering in
|
||
* monitoring systems. The provided labels will apply to all metrics within the
|
||
* effect's execution.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Metrics
|
||
*/
|
||
<A, E, R>(self: Effect<A, E, R>, labels: Iterable<MetricLabel.MetricLabel>): Effect<A, E, R>;
|
||
};
|
||
/**
|
||
* Tags metrics within a scope with a specific key-value pair.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function tags all metrics within a scope with the provided key-value
|
||
* pair. Once the scope is closed, the tag is automatically removed. This is
|
||
* useful for applying temporary context-specific tags to metrics during scoped
|
||
* operations.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Metrics
|
||
*/
|
||
export declare const tagMetricsScoped: (key: string, value: string) => Effect<void, never, Scope.Scope>;
|
||
/**
|
||
* Adds labels to metrics within a scope using `MetricLabel` objects.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to apply labels to all metrics generated within a
|
||
* specific scope using an array of `MetricLabel` objects. These labels provide
|
||
* additional metadata to metrics, which can be used for categorization,
|
||
* filtering, or monitoring purposes. The labels are scoped and will be removed
|
||
* automatically once the scope is closed, ensuring they are only applied
|
||
* temporarily within the defined context.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Metrics
|
||
*/
|
||
export declare const labelMetricsScoped: (labels: ReadonlyArray<MetricLabel.MetricLabel>) => Effect<void, never, Scope.Scope>;
|
||
/**
|
||
* Retrieves the metric labels associated with the current scope.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Metrics
|
||
*/
|
||
export declare const metricLabels: Effect<ReadonlyArray<MetricLabel.MetricLabel>>;
|
||
/**
|
||
* Associates a metric with the current effect, updating it as the effect progresses.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Metrics
|
||
*/
|
||
export declare const withMetric: {
|
||
/**
|
||
* Associates a metric with the current effect, updating it as the effect progresses.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Metrics
|
||
*/
|
||
<Type, In, Out>(metric: Metric.Metric<Type, In, Out>): <A extends In, E, R>(self: Effect<A, E, R>) => Effect<A, E, R>;
|
||
/**
|
||
* Associates a metric with the current effect, updating it as the effect progresses.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Metrics
|
||
*/
|
||
<A extends In, E, R, Type, In, Out>(self: Effect<A, E, R>, metric: Metric.Metric<Type, In, Out>): Effect<A, E, R>;
|
||
};
|
||
/**
|
||
* @category Semaphore
|
||
* @since 2.0.0
|
||
*/
|
||
export interface Permit {
|
||
readonly index: number;
|
||
}
|
||
/**
|
||
* A semaphore is a synchronization mechanism used to manage access to a shared
|
||
* resource. In Effect, semaphores help control resource access or coordinate
|
||
* tasks within asynchronous, concurrent operations.
|
||
*
|
||
* A semaphore acts as a generalized mutex, allowing a set number of permits to
|
||
* be held and released concurrently. Permits act like tickets, giving tasks or
|
||
* fibers controlled access to a shared resource. When no permits are available,
|
||
* tasks trying to acquire one will wait until a permit is released.
|
||
*
|
||
* @category Semaphore
|
||
* @since 2.0.0
|
||
*/
|
||
export interface Semaphore {
|
||
/**
|
||
* Adjusts the number of permits available in the semaphore.
|
||
*/
|
||
resize(permits: number): Effect<void>;
|
||
/**
|
||
* Runs an effect with the given number of permits and releases the permits
|
||
* when the effect completes.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function acquires the specified number of permits before executing
|
||
* the provided effect. Once the effect finishes, the permits are released.
|
||
* If insufficient permits are available, the function will wait until they
|
||
* are released by other tasks.
|
||
*/
|
||
withPermits(permits: number): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, R>;
|
||
/**
|
||
* Runs an effect only if the specified number of permits are immediately
|
||
* available.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function attempts to acquire the specified number of permits. If they
|
||
* are available, it runs the effect and releases the permits after the effect
|
||
* completes. If permits are not available, the effect does not execute, and
|
||
* the result is `Option.none`.
|
||
*/
|
||
withPermitsIfAvailable(permits: number): <A, E, R>(self: Effect<A, E, R>) => Effect<Option.Option<A>, E, R>;
|
||
/**
|
||
* Acquires the specified number of permits and returns the resulting
|
||
* available permits, suspending the task if they are not yet available.
|
||
* Concurrent pending `take` calls are processed in a first-in, first-out manner.
|
||
*/
|
||
take(permits: number): Effect<number>;
|
||
/**
|
||
* Releases the specified number of permits and returns the resulting
|
||
* available permits.
|
||
*/
|
||
release(permits: number): Effect<number>;
|
||
/**
|
||
* Releases all permits held by this semaphore and returns the resulting available permits.
|
||
*/
|
||
releaseAll: Effect<number>;
|
||
}
|
||
/**
|
||
* Unsafely creates a new Semaphore.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Semaphore
|
||
*/
|
||
export declare const unsafeMakeSemaphore: (permits: number) => Semaphore;
|
||
/**
|
||
* Creates a new semaphore with the specified number of permits.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function initializes a semaphore that controls concurrent access to a
|
||
* shared resource. The number of permits determines how many tasks can access
|
||
* the resource concurrently.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* // Create a semaphore with 3 permits
|
||
* const mutex = Effect.makeSemaphore(3)
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Semaphore
|
||
*/
|
||
export declare const makeSemaphore: (permits: number) => Effect<Semaphore>;
|
||
/**
|
||
* A `Latch` is a synchronization primitive that allows you to control the
|
||
* execution of fibers based on an open or closed state. It acts as a gate,
|
||
* where fibers can wait for the latch to open before proceeding.
|
||
*
|
||
* **Details**
|
||
*
|
||
* A `Latch` can be in one of two states: open or closed. Fibers can:
|
||
* - Wait for the latch to open using `await`.
|
||
* - Proceed only when the latch is open using `whenOpen`.
|
||
* - Open the latch to release all waiting fibers using `open`.
|
||
* - Close the latch to block fibers using `close`.
|
||
*
|
||
* Additionally, fibers can be released without changing the state of the latch
|
||
* using `release`.
|
||
*
|
||
* @category Latch
|
||
* @since 3.8.0
|
||
*/
|
||
export interface Latch extends Effect<void> {
|
||
/**
|
||
* Opens the latch, releasing all fibers waiting on it.
|
||
*
|
||
* **Details**
|
||
*
|
||
* Once the latch is opened, it remains open. Any fibers waiting on `await`
|
||
* will be released and can continue execution.
|
||
*/
|
||
readonly open: Effect<void>;
|
||
/**
|
||
* Opens the latch, releasing all fibers waiting on it.
|
||
*
|
||
* **Details**
|
||
*
|
||
* Once the latch is opened, it remains open. Any fibers waiting on `await`
|
||
* will be released and can continue execution.
|
||
*/
|
||
readonly unsafeOpen: () => void;
|
||
/**
|
||
* Releases all fibers waiting on the latch without opening it.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function lets waiting fibers proceed without permanently changing the
|
||
* state of the latch.
|
||
*/
|
||
readonly release: Effect<void>;
|
||
/**
|
||
* Waits for the latch to be opened.
|
||
*
|
||
* **Details**
|
||
*
|
||
* If the latch is already open, this effect completes immediately. Otherwise,
|
||
* it suspends the fiber until the latch is opened.
|
||
*/
|
||
readonly await: Effect<void>;
|
||
/**
|
||
* Closes the latch, blocking fibers from proceeding.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This operation puts the latch into a closed state, requiring it to be
|
||
* reopened before waiting fibers can proceed.
|
||
*/
|
||
readonly close: Effect<void>;
|
||
/**
|
||
* Unsafely closes the latch, blocking fibers without effect guarantees.
|
||
*
|
||
* **Details**
|
||
*
|
||
* Use this operation cautiously, as it does not run within an effect context
|
||
* and bypasses runtime guarantees.
|
||
*/
|
||
readonly unsafeClose: () => void;
|
||
/**
|
||
* Runs the given effect only when the latch is open.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function ensures that the provided effect executes only if the latch
|
||
* is open. If the latch is closed, the fiber will wait until it opens.
|
||
*/
|
||
readonly whenOpen: <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, R>;
|
||
readonly [Unify.typeSymbol]?: unknown;
|
||
readonly [Unify.unifySymbol]?: LatchUnify<this>;
|
||
readonly [Unify.ignoreSymbol]?: LatchUnifyIgnore;
|
||
}
|
||
/**
|
||
* @category Models
|
||
* @since 3.8.0
|
||
*/
|
||
export interface LatchUnify<A extends {
|
||
[Unify.typeSymbol]?: any;
|
||
}> extends EffectUnify<A> {
|
||
Latch?: () => Latch;
|
||
}
|
||
/**
|
||
* @category Models
|
||
* @since 3.8.0
|
||
*/
|
||
export interface LatchUnifyIgnore extends EffectUnifyIgnore {
|
||
Effect?: true;
|
||
}
|
||
/**
|
||
* @category Latch
|
||
* @since 3.8.0
|
||
*/
|
||
export declare const unsafeMakeLatch: (open?: boolean | undefined) => Latch;
|
||
/**
|
||
* Creates a new `Latch`, starting in the specified state.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function initializes a `Latch` safely, ensuring proper runtime
|
||
* guarantees. By default, the latch starts in the closed state.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Console, Effect } from "effect"
|
||
*
|
||
* const program = Effect.gen(function*() {
|
||
* // Create a latch, starting in the closed state
|
||
* const latch = yield* Effect.makeLatch(false)
|
||
*
|
||
* // Fork a fiber that logs "open sesame" when the latch is opened
|
||
* const fiber = yield* Console.log("open sesame").pipe(
|
||
* latch.whenOpen,
|
||
* Effect.fork
|
||
* )
|
||
*
|
||
* yield* Effect.sleep("1 second")
|
||
*
|
||
* // Open the latch
|
||
* yield* latch.open
|
||
* yield* fiber.await
|
||
* })
|
||
*
|
||
* Effect.runFork(program)
|
||
* // Output: open sesame (after 1 second)
|
||
* ```
|
||
*
|
||
* @category Latch
|
||
* @since 3.8.0
|
||
*/
|
||
export declare const makeLatch: (open?: boolean | undefined) => Effect<Latch, never, never>;
|
||
/**
|
||
* Runs an effect in the background, returning a fiber that can be observed or
|
||
* interrupted.
|
||
*
|
||
* Unless you specifically need a `Promise` or synchronous operation, `runFork`
|
||
* is a good default choice.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function is the foundational way to execute an effect in the background.
|
||
* It creates a "fiber," a lightweight, cooperative thread of execution that can
|
||
* be observed (to access its result), interrupted, or joined. Fibers are useful
|
||
* for concurrent programming and allow effects to run independently of the main
|
||
* program flow.
|
||
*
|
||
* Once the effect is running in a fiber, you can monitor its progress, cancel
|
||
* it if necessary, or retrieve its result when it completes. If the effect
|
||
* fails, the fiber will propagate the failure, which you can observe and
|
||
* handle.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use this function when you need to run an effect in the background,
|
||
* especially if the effect is long-running or performs periodic tasks. It's
|
||
* suitable for tasks that need to run independently but might still need
|
||
* observation or management, like logging, monitoring, or scheduled tasks.
|
||
*
|
||
* This function is ideal if you don't need the result immediately or if the
|
||
* effect is part of a larger concurrent workflow.
|
||
*
|
||
* **Example** (Running an Effect in the Background)
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console, Schedule, Fiber } from "effect"
|
||
*
|
||
* // ┌─── Effect<number, never, never>
|
||
* // ▼
|
||
* const program = Effect.repeat(
|
||
* Console.log("running..."),
|
||
* Schedule.spaced("200 millis")
|
||
* )
|
||
*
|
||
* // ┌─── RuntimeFiber<number, never>
|
||
* // ▼
|
||
* const fiber = Effect.runFork(program)
|
||
*
|
||
* setTimeout(() => {
|
||
* Effect.runFork(Fiber.interrupt(fiber))
|
||
* }, 500)
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Running Effects
|
||
*/
|
||
export declare const runFork: <A, E>(effect: Effect<A, E>, options?: Runtime.RunForkOptions) => Fiber.RuntimeFiber<A, E>;
|
||
/**
|
||
* Executes an effect asynchronously and handles the result using a callback.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function runs an effect asynchronously and passes the result (`Exit`) to
|
||
* a specified callback. The callback is invoked with the outcome of the effect:
|
||
* - On success, the callback receives the successful result.
|
||
* - On failure, the callback receives the failure information.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* This function is effectful and should only be invoked at the edges of your
|
||
* program.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Running Effects
|
||
*/
|
||
export declare const runCallback: <A, E>(effect: Effect<A, E>, options?: Runtime.RunCallbackOptions<A, E> | undefined) => Runtime.Cancel<A, E>;
|
||
/**
|
||
* Executes an effect and returns the result as a `Promise`.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function runs an effect and converts its result into a `Promise`. If the
|
||
* effect succeeds, the `Promise` will resolve with the successful result. If
|
||
* the effect fails, the `Promise` will reject with an error, which includes the
|
||
* failure details of the effect.
|
||
*
|
||
* The optional `options` parameter allows you to pass an `AbortSignal` for
|
||
* cancellation, enabling more fine-grained control over asynchronous tasks.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use this function when you need to execute an effect and work with its result
|
||
* in a promise-based system, such as when integrating with third-party
|
||
* libraries that expect `Promise` results.
|
||
*
|
||
* **Example** (Running a Successful Effect as a Promise)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* Effect.runPromise(Effect.succeed(1)).then(console.log)
|
||
* // Output: 1
|
||
* ```
|
||
*
|
||
* **Example** (Handling a Failing Effect as a Rejected Promise)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* Effect.runPromise(Effect.fail("my error")).catch(console.error)
|
||
* // Output:
|
||
* // (FiberFailure) Error: my error
|
||
* ```
|
||
*
|
||
* @see {@link runPromiseExit} for a version that returns an `Exit` type instead
|
||
* of rejecting.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Running Effects
|
||
*/
|
||
export declare const runPromise: <A, E>(effect: Effect<A, E, never>, options?: {
|
||
readonly signal?: AbortSignal | undefined;
|
||
} | undefined) => Promise<A>;
|
||
/**
|
||
* Runs an effect and returns a `Promise` that resolves to an `Exit`,
|
||
* representing the outcome.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function executes an effect and resolves to an `Exit` object. The `Exit`
|
||
* type provides detailed information about the result of the effect:
|
||
* - If the effect succeeds, the `Exit` will be of type `Success` and include
|
||
* the value produced by the effect.
|
||
* - If the effect fails, the `Exit` will be of type `Failure` and contain a
|
||
* `Cause` object, detailing the failure.
|
||
*
|
||
* Using this function allows you to examine both successful results and failure
|
||
* cases in a unified way, while still leveraging `Promise` for handling the
|
||
* asynchronous behavior of the effect.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use this function when you need to understand the outcome of an effect,
|
||
* whether it succeeded or failed, and want to work with this result using
|
||
* `Promise` syntax. This is particularly useful when integrating with systems
|
||
* that rely on promises but need more detailed error handling than a simple
|
||
* rejection.
|
||
*
|
||
* **Example** (Handling Results as Exit)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* // Execute a successful effect and get the Exit result as a Promise
|
||
* Effect.runPromiseExit(Effect.succeed(1)).then(console.log)
|
||
* // Output:
|
||
* // {
|
||
* // _id: "Exit",
|
||
* // _tag: "Success",
|
||
* // value: 1
|
||
* // }
|
||
*
|
||
* // Execute a failing effect and get the Exit result as a Promise
|
||
* Effect.runPromiseExit(Effect.fail("my error")).then(console.log)
|
||
* // Output:
|
||
* // {
|
||
* // _id: "Exit",
|
||
* // _tag: "Failure",
|
||
* // cause: {
|
||
* // _id: "Cause",
|
||
* // _tag: "Fail",
|
||
* // failure: "my error"
|
||
* // }
|
||
* // }
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Running Effects
|
||
*/
|
||
export declare const runPromiseExit: <A, E>(effect: Effect<A, E, never>, options?: {
|
||
readonly signal?: AbortSignal;
|
||
} | undefined) => Promise<Exit.Exit<A, E>>;
|
||
/**
|
||
* Executes an effect synchronously, running it immediately and returning the
|
||
* result.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function evaluates the provided effect synchronously, returning its
|
||
* result directly. It is ideal for effects that do not fail or include
|
||
* asynchronous operations. If the effect does fail or involves async tasks, it
|
||
* will throw an error. Execution stops at the point of failure or asynchronous
|
||
* operation, making it unsuitable for effects that require asynchronous
|
||
* handling.
|
||
*
|
||
* **Important**: Attempting to run effects that involve asynchronous operations
|
||
* or failures will result in exceptions being thrown, so use this function with
|
||
* care for purely synchronous and error-free effects.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use this function when:
|
||
* - You are sure that the effect will not fail or involve asynchronous
|
||
* operations.
|
||
* - You need a direct, synchronous result from the effect.
|
||
* - You are working within a context where asynchronous effects are not
|
||
* allowed.
|
||
*
|
||
* Avoid using this function for effects that can fail or require asynchronous
|
||
* handling. For such cases, consider using {@link runPromise} or
|
||
* {@link runSyncExit}.
|
||
*
|
||
* **Example** (Synchronous Logging)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const program = Effect.sync(() => {
|
||
* console.log("Hello, World!")
|
||
* return 1
|
||
* })
|
||
*
|
||
* const result = Effect.runSync(program)
|
||
* // Output: Hello, World!
|
||
*
|
||
* console.log(result)
|
||
* // Output: 1
|
||
* ```
|
||
*
|
||
* **Example** (Incorrect Usage with Failing or Async Effects)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* try {
|
||
* // Attempt to run an effect that fails
|
||
* Effect.runSync(Effect.fail("my error"))
|
||
* } catch (e) {
|
||
* console.error(e)
|
||
* }
|
||
* // Output:
|
||
* // (FiberFailure) Error: my error
|
||
*
|
||
* try {
|
||
* // Attempt to run an effect that involves async work
|
||
* Effect.runSync(Effect.promise(() => Promise.resolve(1)))
|
||
* } catch (e) {
|
||
* console.error(e)
|
||
* }
|
||
* // Output:
|
||
* // (FiberFailure) AsyncFiberException: Fiber #0 cannot be resolved synchronously. This is caused by using runSync on an effect that performs async work
|
||
* ```
|
||
*
|
||
* @see {@link runSyncExit} for a version that returns an `Exit` type instead of
|
||
* throwing an error.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Running Effects
|
||
*/
|
||
export declare const runSync: <A, E>(effect: Effect<A, E>) => A;
|
||
/**
|
||
* Runs an effect synchronously and returns the result as an `Exit` type.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function executes the provided effect synchronously and returns an `Exit`
|
||
* type that encapsulates the outcome of the effect:
|
||
* - If the effect succeeds, the result is wrapped in a `Success`.
|
||
* - If the effect fails, it returns a `Failure` containing a `Cause` that explains
|
||
* the failure.
|
||
*
|
||
* If the effect involves asynchronous operations, this function will return a `Failure`
|
||
* with a `Die` cause, indicating that it cannot resolve the effect synchronously.
|
||
* This makes the function suitable for use only with effects that are synchronous
|
||
* in nature.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use this function when:
|
||
* - You want to handle both success and failure outcomes in a structured way using the `Exit` type.
|
||
* - You are working with effects that are purely synchronous and do not involve asynchronous operations.
|
||
* - You need to debug or inspect failures, including their causes, in a detailed manner.
|
||
*
|
||
* Avoid using this function for effects that involve asynchronous operations, as it will fail with a `Die` cause.
|
||
*
|
||
* **Example** (Handling Results as Exit)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* console.log(Effect.runSyncExit(Effect.succeed(1)))
|
||
* // Output:
|
||
* // {
|
||
* // _id: "Exit",
|
||
* // _tag: "Success",
|
||
* // value: 1
|
||
* // }
|
||
*
|
||
* console.log(Effect.runSyncExit(Effect.fail("my error")))
|
||
* // Output:
|
||
* // {
|
||
* // _id: "Exit",
|
||
* // _tag: "Failure",
|
||
* // cause: {
|
||
* // _id: "Cause",
|
||
* // _tag: "Fail",
|
||
* // failure: "my error"
|
||
* // }
|
||
* // }
|
||
* ```
|
||
*
|
||
* **Example** (Asynchronous Operation Resulting in Die)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* console.log(Effect.runSyncExit(Effect.promise(() => Promise.resolve(1))))
|
||
* // Output:
|
||
* // {
|
||
* // _id: 'Exit',
|
||
* // _tag: 'Failure',
|
||
* // cause: {
|
||
* // _id: 'Cause',
|
||
* // _tag: 'Die',
|
||
* // defect: [Fiber #0 cannot be resolved synchronously. This is caused by using runSync on an effect that performs async work] {
|
||
* // fiber: [FiberRuntime],
|
||
* // _tag: 'AsyncFiberException',
|
||
* // name: 'AsyncFiberException'
|
||
* // }
|
||
* // }
|
||
* // }
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Running Effects
|
||
*/
|
||
export declare const runSyncExit: <A, E>(effect: Effect<A, E>) => Exit.Exit<A, E>;
|
||
/**
|
||
* Combines multiple effects and accumulates both successes and failures.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to combine multiple effects, continuing through all
|
||
* effects even if some of them fail. Unlike other functions that stop execution
|
||
* upon encountering an error, this function collects all errors into a `Cause`.
|
||
* The final result includes all successes and the accumulated failures.
|
||
*
|
||
* By default, effects are executed sequentially, but you can control
|
||
* concurrency and batching behavior using the `options` parameter. This
|
||
* provides flexibility in scenarios where you want to maximize performance or
|
||
* ensure specific ordering.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* const task1 = Console.log("task1").pipe(Effect.as(1))
|
||
* const task2 = Effect.fail("Oh uh!").pipe(Effect.as(2))
|
||
* const task3 = Console.log("task2").pipe(Effect.as(3))
|
||
* const task4 = Effect.fail("Oh no!").pipe(Effect.as(4))
|
||
*
|
||
* const program = task1.pipe(
|
||
* Effect.validate(task2),
|
||
* Effect.validate(task3),
|
||
* Effect.validate(task4)
|
||
* )
|
||
*
|
||
* Effect.runPromiseExit(program).then(console.log)
|
||
* // Output:
|
||
* // task1
|
||
* // task2
|
||
* // {
|
||
* // _id: 'Exit',
|
||
* // _tag: 'Failure',
|
||
* // cause: {
|
||
* // _id: 'Cause',
|
||
* // _tag: 'Sequential',
|
||
* // left: { _id: 'Cause', _tag: 'Fail', failure: 'Oh uh!' },
|
||
* // right: { _id: 'Cause', _tag: 'Fail', failure: 'Oh no!' }
|
||
* // }
|
||
* // }
|
||
* ```
|
||
*
|
||
* @see {@link zip} for a version that stops at the first error.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error Accumulation
|
||
*/
|
||
export declare const validate: {
|
||
/**
|
||
* Combines multiple effects and accumulates both successes and failures.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to combine multiple effects, continuing through all
|
||
* effects even if some of them fail. Unlike other functions that stop execution
|
||
* upon encountering an error, this function collects all errors into a `Cause`.
|
||
* The final result includes all successes and the accumulated failures.
|
||
*
|
||
* By default, effects are executed sequentially, but you can control
|
||
* concurrency and batching behavior using the `options` parameter. This
|
||
* provides flexibility in scenarios where you want to maximize performance or
|
||
* ensure specific ordering.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* const task1 = Console.log("task1").pipe(Effect.as(1))
|
||
* const task2 = Effect.fail("Oh uh!").pipe(Effect.as(2))
|
||
* const task3 = Console.log("task2").pipe(Effect.as(3))
|
||
* const task4 = Effect.fail("Oh no!").pipe(Effect.as(4))
|
||
*
|
||
* const program = task1.pipe(
|
||
* Effect.validate(task2),
|
||
* Effect.validate(task3),
|
||
* Effect.validate(task4)
|
||
* )
|
||
*
|
||
* Effect.runPromiseExit(program).then(console.log)
|
||
* // Output:
|
||
* // task1
|
||
* // task2
|
||
* // {
|
||
* // _id: 'Exit',
|
||
* // _tag: 'Failure',
|
||
* // cause: {
|
||
* // _id: 'Cause',
|
||
* // _tag: 'Sequential',
|
||
* // left: { _id: 'Cause', _tag: 'Fail', failure: 'Oh uh!' },
|
||
* // right: { _id: 'Cause', _tag: 'Fail', failure: 'Oh no!' }
|
||
* // }
|
||
* // }
|
||
* ```
|
||
*
|
||
* @see {@link zip} for a version that stops at the first error.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error Accumulation
|
||
*/
|
||
<B, E1, R1>(that: Effect<B, E1, R1>, options?: {
|
||
readonly concurrent?: boolean | undefined;
|
||
readonly batching?: boolean | "inherit" | undefined;
|
||
readonly concurrentFinalizers?: boolean | undefined;
|
||
} | undefined): <A, E, R>(self: Effect<A, E, R>) => Effect<[A, B], E1 | E, R1 | R>;
|
||
/**
|
||
* Combines multiple effects and accumulates both successes and failures.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to combine multiple effects, continuing through all
|
||
* effects even if some of them fail. Unlike other functions that stop execution
|
||
* upon encountering an error, this function collects all errors into a `Cause`.
|
||
* The final result includes all successes and the accumulated failures.
|
||
*
|
||
* By default, effects are executed sequentially, but you can control
|
||
* concurrency and batching behavior using the `options` parameter. This
|
||
* provides flexibility in scenarios where you want to maximize performance or
|
||
* ensure specific ordering.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Console } from "effect"
|
||
*
|
||
* const task1 = Console.log("task1").pipe(Effect.as(1))
|
||
* const task2 = Effect.fail("Oh uh!").pipe(Effect.as(2))
|
||
* const task3 = Console.log("task2").pipe(Effect.as(3))
|
||
* const task4 = Effect.fail("Oh no!").pipe(Effect.as(4))
|
||
*
|
||
* const program = task1.pipe(
|
||
* Effect.validate(task2),
|
||
* Effect.validate(task3),
|
||
* Effect.validate(task4)
|
||
* )
|
||
*
|
||
* Effect.runPromiseExit(program).then(console.log)
|
||
* // Output:
|
||
* // task1
|
||
* // task2
|
||
* // {
|
||
* // _id: 'Exit',
|
||
* // _tag: 'Failure',
|
||
* // cause: {
|
||
* // _id: 'Cause',
|
||
* // _tag: 'Sequential',
|
||
* // left: { _id: 'Cause', _tag: 'Fail', failure: 'Oh uh!' },
|
||
* // right: { _id: 'Cause', _tag: 'Fail', failure: 'Oh no!' }
|
||
* // }
|
||
* // }
|
||
* ```
|
||
*
|
||
* @see {@link zip} for a version that stops at the first error.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error Accumulation
|
||
*/
|
||
<A, E, R, B, E1, R1>(self: Effect<A, E, R>, that: Effect<B, E1, R1>, options?: {
|
||
readonly concurrent?: boolean | undefined;
|
||
readonly batching?: boolean | "inherit" | undefined;
|
||
readonly concurrentFinalizers?: boolean | undefined;
|
||
} | undefined): Effect<[A, B], E | E1, R | R1>;
|
||
};
|
||
/**
|
||
* Sequentially combines two effects using a specified combiner function while
|
||
* accumulating errors.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function combines two effects, `self` and `that`, into a single effect
|
||
* by applying the provided combiner function to their results. If both effects
|
||
* succeed, the combiner function is applied to their results to produce the
|
||
* final value. If either effect fails, the failures are accumulated into a
|
||
* combined `Cause`.
|
||
*
|
||
* By default, effects are executed sequentially. However, the execution mode
|
||
* can be controlled using the `options` parameter to enable concurrency,
|
||
* batching, or customized finalizer behavior.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error Accumulation
|
||
*/
|
||
export declare const validateWith: {
|
||
/**
|
||
* Sequentially combines two effects using a specified combiner function while
|
||
* accumulating errors.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function combines two effects, `self` and `that`, into a single effect
|
||
* by applying the provided combiner function to their results. If both effects
|
||
* succeed, the combiner function is applied to their results to produce the
|
||
* final value. If either effect fails, the failures are accumulated into a
|
||
* combined `Cause`.
|
||
*
|
||
* By default, effects are executed sequentially. However, the execution mode
|
||
* can be controlled using the `options` parameter to enable concurrency,
|
||
* batching, or customized finalizer behavior.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error Accumulation
|
||
*/
|
||
<B, E1, R1, A, C>(that: Effect<B, E1, R1>, f: (a: A, b: B) => C, options?: {
|
||
readonly concurrent?: boolean | undefined;
|
||
readonly batching?: boolean | "inherit" | undefined;
|
||
readonly concurrentFinalizers?: boolean | undefined;
|
||
} | undefined): <E, R>(self: Effect<A, E, R>) => Effect<C, E1 | E, R1 | R>;
|
||
/**
|
||
* Sequentially combines two effects using a specified combiner function while
|
||
* accumulating errors.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function combines two effects, `self` and `that`, into a single effect
|
||
* by applying the provided combiner function to their results. If both effects
|
||
* succeed, the combiner function is applied to their results to produce the
|
||
* final value. If either effect fails, the failures are accumulated into a
|
||
* combined `Cause`.
|
||
*
|
||
* By default, effects are executed sequentially. However, the execution mode
|
||
* can be controlled using the `options` parameter to enable concurrency,
|
||
* batching, or customized finalizer behavior.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Error Accumulation
|
||
*/
|
||
<A, E, R, B, E1, R1, C>(self: Effect<A, E, R>, that: Effect<B, E1, R1>, f: (a: A, b: B) => C, options?: {
|
||
readonly concurrent?: boolean | undefined;
|
||
readonly batching?: boolean | "inherit" | undefined;
|
||
readonly concurrentFinalizers?: boolean | undefined;
|
||
} | undefined): Effect<C, E | E1, R | R1>;
|
||
};
|
||
/**
|
||
* Combines two effects into a single effect, producing a tuple of their
|
||
* results.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function combines two effects, `self` and `that`, into one. It executes
|
||
* the first effect (`self`) and then the second effect (`that`), collecting
|
||
* their results into a tuple. Both effects must succeed for the resulting
|
||
* effect to succeed. If either effect fails, the entire operation fails.
|
||
*
|
||
* By default, the effects are executed sequentially. If the `concurrent` option
|
||
* is set to `true`, the effects will run concurrently, potentially improving
|
||
* performance for independent operations.
|
||
*
|
||
* **Example** (Combining Two Effects Sequentially)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const task1 = Effect.succeed(1).pipe(
|
||
* Effect.delay("200 millis"),
|
||
* Effect.tap(Effect.log("task1 done"))
|
||
* )
|
||
* const task2 = Effect.succeed("hello").pipe(
|
||
* Effect.delay("100 millis"),
|
||
* Effect.tap(Effect.log("task2 done"))
|
||
* )
|
||
*
|
||
* // Combine the two effects together
|
||
* //
|
||
* // ┌─── Effect<[number, string], never, never>
|
||
* // ▼
|
||
* const program = Effect.zip(task1, task2)
|
||
*
|
||
* Effect.runPromise(program).then(console.log)
|
||
* // Output:
|
||
* // timestamp=... level=INFO fiber=#0 message="task1 done"
|
||
* // timestamp=... level=INFO fiber=#0 message="task2 done"
|
||
* // [ 1, 'hello' ]
|
||
* ```
|
||
*
|
||
* **Example** (Combining Two Effects Concurrently)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const task1 = Effect.succeed(1).pipe(
|
||
* Effect.delay("200 millis"),
|
||
* Effect.tap(Effect.log("task1 done"))
|
||
* )
|
||
* const task2 = Effect.succeed("hello").pipe(
|
||
* Effect.delay("100 millis"),
|
||
* Effect.tap(Effect.log("task2 done"))
|
||
* )
|
||
*
|
||
* // Run both effects concurrently using the concurrent option
|
||
* const program = Effect.zip(task1, task2, { concurrent: true })
|
||
*
|
||
* Effect.runPromise(program).then(console.log)
|
||
* // Output:
|
||
* // timestamp=... level=INFO fiber=#0 message="task2 done"
|
||
* // timestamp=... level=INFO fiber=#0 message="task1 done"
|
||
* // [ 1, 'hello' ]
|
||
* ```
|
||
*
|
||
* @see {@link zipWith} for a version that combines the results with a custom
|
||
* function.
|
||
* @see {@link validate} for a version that accumulates errors.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Zipping
|
||
*/
|
||
export declare const zip: {
|
||
/**
|
||
* Combines two effects into a single effect, producing a tuple of their
|
||
* results.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function combines two effects, `self` and `that`, into one. It executes
|
||
* the first effect (`self`) and then the second effect (`that`), collecting
|
||
* their results into a tuple. Both effects must succeed for the resulting
|
||
* effect to succeed. If either effect fails, the entire operation fails.
|
||
*
|
||
* By default, the effects are executed sequentially. If the `concurrent` option
|
||
* is set to `true`, the effects will run concurrently, potentially improving
|
||
* performance for independent operations.
|
||
*
|
||
* **Example** (Combining Two Effects Sequentially)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const task1 = Effect.succeed(1).pipe(
|
||
* Effect.delay("200 millis"),
|
||
* Effect.tap(Effect.log("task1 done"))
|
||
* )
|
||
* const task2 = Effect.succeed("hello").pipe(
|
||
* Effect.delay("100 millis"),
|
||
* Effect.tap(Effect.log("task2 done"))
|
||
* )
|
||
*
|
||
* // Combine the two effects together
|
||
* //
|
||
* // ┌─── Effect<[number, string], never, never>
|
||
* // ▼
|
||
* const program = Effect.zip(task1, task2)
|
||
*
|
||
* Effect.runPromise(program).then(console.log)
|
||
* // Output:
|
||
* // timestamp=... level=INFO fiber=#0 message="task1 done"
|
||
* // timestamp=... level=INFO fiber=#0 message="task2 done"
|
||
* // [ 1, 'hello' ]
|
||
* ```
|
||
*
|
||
* **Example** (Combining Two Effects Concurrently)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const task1 = Effect.succeed(1).pipe(
|
||
* Effect.delay("200 millis"),
|
||
* Effect.tap(Effect.log("task1 done"))
|
||
* )
|
||
* const task2 = Effect.succeed("hello").pipe(
|
||
* Effect.delay("100 millis"),
|
||
* Effect.tap(Effect.log("task2 done"))
|
||
* )
|
||
*
|
||
* // Run both effects concurrently using the concurrent option
|
||
* const program = Effect.zip(task1, task2, { concurrent: true })
|
||
*
|
||
* Effect.runPromise(program).then(console.log)
|
||
* // Output:
|
||
* // timestamp=... level=INFO fiber=#0 message="task2 done"
|
||
* // timestamp=... level=INFO fiber=#0 message="task1 done"
|
||
* // [ 1, 'hello' ]
|
||
* ```
|
||
*
|
||
* @see {@link zipWith} for a version that combines the results with a custom
|
||
* function.
|
||
* @see {@link validate} for a version that accumulates errors.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Zipping
|
||
*/
|
||
<A2, E2, R2>(that: Effect<A2, E2, R2>, options?: {
|
||
readonly concurrent?: boolean | undefined;
|
||
readonly batching?: boolean | "inherit" | undefined;
|
||
readonly concurrentFinalizers?: boolean | undefined;
|
||
} | undefined): <A, E, R>(self: Effect<A, E, R>) => Effect<[A, A2], E2 | E, R2 | R>;
|
||
/**
|
||
* Combines two effects into a single effect, producing a tuple of their
|
||
* results.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function combines two effects, `self` and `that`, into one. It executes
|
||
* the first effect (`self`) and then the second effect (`that`), collecting
|
||
* their results into a tuple. Both effects must succeed for the resulting
|
||
* effect to succeed. If either effect fails, the entire operation fails.
|
||
*
|
||
* By default, the effects are executed sequentially. If the `concurrent` option
|
||
* is set to `true`, the effects will run concurrently, potentially improving
|
||
* performance for independent operations.
|
||
*
|
||
* **Example** (Combining Two Effects Sequentially)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const task1 = Effect.succeed(1).pipe(
|
||
* Effect.delay("200 millis"),
|
||
* Effect.tap(Effect.log("task1 done"))
|
||
* )
|
||
* const task2 = Effect.succeed("hello").pipe(
|
||
* Effect.delay("100 millis"),
|
||
* Effect.tap(Effect.log("task2 done"))
|
||
* )
|
||
*
|
||
* // Combine the two effects together
|
||
* //
|
||
* // ┌─── Effect<[number, string], never, never>
|
||
* // ▼
|
||
* const program = Effect.zip(task1, task2)
|
||
*
|
||
* Effect.runPromise(program).then(console.log)
|
||
* // Output:
|
||
* // timestamp=... level=INFO fiber=#0 message="task1 done"
|
||
* // timestamp=... level=INFO fiber=#0 message="task2 done"
|
||
* // [ 1, 'hello' ]
|
||
* ```
|
||
*
|
||
* **Example** (Combining Two Effects Concurrently)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const task1 = Effect.succeed(1).pipe(
|
||
* Effect.delay("200 millis"),
|
||
* Effect.tap(Effect.log("task1 done"))
|
||
* )
|
||
* const task2 = Effect.succeed("hello").pipe(
|
||
* Effect.delay("100 millis"),
|
||
* Effect.tap(Effect.log("task2 done"))
|
||
* )
|
||
*
|
||
* // Run both effects concurrently using the concurrent option
|
||
* const program = Effect.zip(task1, task2, { concurrent: true })
|
||
*
|
||
* Effect.runPromise(program).then(console.log)
|
||
* // Output:
|
||
* // timestamp=... level=INFO fiber=#0 message="task2 done"
|
||
* // timestamp=... level=INFO fiber=#0 message="task1 done"
|
||
* // [ 1, 'hello' ]
|
||
* ```
|
||
*
|
||
* @see {@link zipWith} for a version that combines the results with a custom
|
||
* function.
|
||
* @see {@link validate} for a version that accumulates errors.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Zipping
|
||
*/
|
||
<A, E, R, A2, E2, R2>(self: Effect<A, E, R>, that: Effect<A2, E2, R2>, options?: {
|
||
readonly concurrent?: boolean | undefined;
|
||
readonly batching?: boolean | "inherit" | undefined;
|
||
readonly concurrentFinalizers?: boolean | undefined;
|
||
} | undefined): Effect<[A, A2], E | E2, R | R2>;
|
||
};
|
||
/**
|
||
* Executes two effects sequentially, returning the result of the first effect
|
||
* and ignoring the result of the second.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to run two effects in sequence, where the result of
|
||
* the first effect is preserved, and the result of the second effect is
|
||
* discarded. By default, the two effects are executed sequentially. If you need
|
||
* them to run concurrently, you can pass the `{ concurrent: true }` option.
|
||
*
|
||
* The second effect will always be executed, even though its result is ignored.
|
||
* This makes it useful for cases where you want to execute an effect for its
|
||
* side effects while keeping the result of another effect.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use this function when you are only interested in the result of the first
|
||
* effect but still need to run the second effect for its side effects, such as
|
||
* logging or performing a cleanup action.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const task1 = Effect.succeed(1).pipe(
|
||
* Effect.delay("200 millis"),
|
||
* Effect.tap(Effect.log("task1 done"))
|
||
* )
|
||
* const task2 = Effect.succeed("hello").pipe(
|
||
* Effect.delay("100 millis"),
|
||
* Effect.tap(Effect.log("task2 done"))
|
||
* )
|
||
*
|
||
* const program = Effect.zipLeft(task1, task2)
|
||
*
|
||
* Effect.runPromise(program).then(console.log)
|
||
* // Output:
|
||
* // timestamp=... level=INFO fiber=#0 message="task1 done"
|
||
* // timestamp=... level=INFO fiber=#0 message="task2 done"
|
||
* // 1
|
||
* ```
|
||
*
|
||
* @see {@link zipRight} for a version that returns the result of the second
|
||
* effect.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Zipping
|
||
*/
|
||
export declare const zipLeft: {
|
||
/**
|
||
* Executes two effects sequentially, returning the result of the first effect
|
||
* and ignoring the result of the second.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to run two effects in sequence, where the result of
|
||
* the first effect is preserved, and the result of the second effect is
|
||
* discarded. By default, the two effects are executed sequentially. If you need
|
||
* them to run concurrently, you can pass the `{ concurrent: true }` option.
|
||
*
|
||
* The second effect will always be executed, even though its result is ignored.
|
||
* This makes it useful for cases where you want to execute an effect for its
|
||
* side effects while keeping the result of another effect.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use this function when you are only interested in the result of the first
|
||
* effect but still need to run the second effect for its side effects, such as
|
||
* logging or performing a cleanup action.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const task1 = Effect.succeed(1).pipe(
|
||
* Effect.delay("200 millis"),
|
||
* Effect.tap(Effect.log("task1 done"))
|
||
* )
|
||
* const task2 = Effect.succeed("hello").pipe(
|
||
* Effect.delay("100 millis"),
|
||
* Effect.tap(Effect.log("task2 done"))
|
||
* )
|
||
*
|
||
* const program = Effect.zipLeft(task1, task2)
|
||
*
|
||
* Effect.runPromise(program).then(console.log)
|
||
* // Output:
|
||
* // timestamp=... level=INFO fiber=#0 message="task1 done"
|
||
* // timestamp=... level=INFO fiber=#0 message="task2 done"
|
||
* // 1
|
||
* ```
|
||
*
|
||
* @see {@link zipRight} for a version that returns the result of the second
|
||
* effect.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Zipping
|
||
*/
|
||
<A2, E2, R2>(that: Effect<A2, E2, R2>, options?: {
|
||
readonly concurrent?: boolean | undefined;
|
||
readonly batching?: boolean | "inherit" | undefined;
|
||
readonly concurrentFinalizers?: boolean | undefined;
|
||
} | undefined): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E2 | E, R2 | R>;
|
||
/**
|
||
* Executes two effects sequentially, returning the result of the first effect
|
||
* and ignoring the result of the second.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to run two effects in sequence, where the result of
|
||
* the first effect is preserved, and the result of the second effect is
|
||
* discarded. By default, the two effects are executed sequentially. If you need
|
||
* them to run concurrently, you can pass the `{ concurrent: true }` option.
|
||
*
|
||
* The second effect will always be executed, even though its result is ignored.
|
||
* This makes it useful for cases where you want to execute an effect for its
|
||
* side effects while keeping the result of another effect.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use this function when you are only interested in the result of the first
|
||
* effect but still need to run the second effect for its side effects, such as
|
||
* logging or performing a cleanup action.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const task1 = Effect.succeed(1).pipe(
|
||
* Effect.delay("200 millis"),
|
||
* Effect.tap(Effect.log("task1 done"))
|
||
* )
|
||
* const task2 = Effect.succeed("hello").pipe(
|
||
* Effect.delay("100 millis"),
|
||
* Effect.tap(Effect.log("task2 done"))
|
||
* )
|
||
*
|
||
* const program = Effect.zipLeft(task1, task2)
|
||
*
|
||
* Effect.runPromise(program).then(console.log)
|
||
* // Output:
|
||
* // timestamp=... level=INFO fiber=#0 message="task1 done"
|
||
* // timestamp=... level=INFO fiber=#0 message="task2 done"
|
||
* // 1
|
||
* ```
|
||
*
|
||
* @see {@link zipRight} for a version that returns the result of the second
|
||
* effect.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Zipping
|
||
*/
|
||
<A, E, R, A2, E2, R2>(self: Effect<A, E, R>, that: Effect<A2, E2, R2>, options?: {
|
||
readonly concurrent?: boolean | undefined;
|
||
readonly batching?: boolean | "inherit" | undefined;
|
||
readonly concurrentFinalizers?: boolean | undefined;
|
||
} | undefined): Effect<A, E | E2, R | R2>;
|
||
};
|
||
/**
|
||
* Executes two effects sequentially, returning the result of the second effect
|
||
* while ignoring the result of the first.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to run two effects in sequence, keeping the result
|
||
* of the second effect and discarding the result of the first. By default, the
|
||
* two effects are executed sequentially. If you need them to run concurrently,
|
||
* you can pass the `{ concurrent: true }` option.
|
||
*
|
||
* The first effect will always be executed, even though its result is ignored.
|
||
* This makes it useful for scenarios where the first effect is needed for its
|
||
* side effects, but only the result of the second effect is important.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use this function when you are only interested in the result of the second
|
||
* effect but still need to run the first effect for its side effects, such as
|
||
* initialization or setup tasks.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const task1 = Effect.succeed(1).pipe(
|
||
* Effect.delay("200 millis"),
|
||
* Effect.tap(Effect.log("task1 done"))
|
||
* )
|
||
* const task2 = Effect.succeed("hello").pipe(
|
||
* Effect.delay("100 millis"),
|
||
* Effect.tap(Effect.log("task2 done"))
|
||
* )
|
||
*
|
||
* const program = Effect.zipRight(task1, task2)
|
||
*
|
||
* Effect.runPromise(program).then(console.log)
|
||
* // Output:
|
||
* // timestamp=... level=INFO fiber=#0 message="task1 done"
|
||
* // timestamp=... level=INFO fiber=#0 message="task2 done"
|
||
* // hello
|
||
* ```
|
||
*
|
||
* @see {@link zipLeft} for a version that returns the result of the first
|
||
* effect.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Zipping
|
||
*/
|
||
export declare const zipRight: {
|
||
/**
|
||
* Executes two effects sequentially, returning the result of the second effect
|
||
* while ignoring the result of the first.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to run two effects in sequence, keeping the result
|
||
* of the second effect and discarding the result of the first. By default, the
|
||
* two effects are executed sequentially. If you need them to run concurrently,
|
||
* you can pass the `{ concurrent: true }` option.
|
||
*
|
||
* The first effect will always be executed, even though its result is ignored.
|
||
* This makes it useful for scenarios where the first effect is needed for its
|
||
* side effects, but only the result of the second effect is important.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use this function when you are only interested in the result of the second
|
||
* effect but still need to run the first effect for its side effects, such as
|
||
* initialization or setup tasks.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const task1 = Effect.succeed(1).pipe(
|
||
* Effect.delay("200 millis"),
|
||
* Effect.tap(Effect.log("task1 done"))
|
||
* )
|
||
* const task2 = Effect.succeed("hello").pipe(
|
||
* Effect.delay("100 millis"),
|
||
* Effect.tap(Effect.log("task2 done"))
|
||
* )
|
||
*
|
||
* const program = Effect.zipRight(task1, task2)
|
||
*
|
||
* Effect.runPromise(program).then(console.log)
|
||
* // Output:
|
||
* // timestamp=... level=INFO fiber=#0 message="task1 done"
|
||
* // timestamp=... level=INFO fiber=#0 message="task2 done"
|
||
* // hello
|
||
* ```
|
||
*
|
||
* @see {@link zipLeft} for a version that returns the result of the first
|
||
* effect.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Zipping
|
||
*/
|
||
<A2, E2, R2>(that: Effect<A2, E2, R2>, options?: {
|
||
readonly concurrent?: boolean | undefined;
|
||
readonly batching?: boolean | "inherit" | undefined;
|
||
readonly concurrentFinalizers?: boolean | undefined;
|
||
}): <A, E, R>(self: Effect<A, E, R>) => Effect<A2, E2 | E, R2 | R>;
|
||
/**
|
||
* Executes two effects sequentially, returning the result of the second effect
|
||
* while ignoring the result of the first.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to run two effects in sequence, keeping the result
|
||
* of the second effect and discarding the result of the first. By default, the
|
||
* two effects are executed sequentially. If you need them to run concurrently,
|
||
* you can pass the `{ concurrent: true }` option.
|
||
*
|
||
* The first effect will always be executed, even though its result is ignored.
|
||
* This makes it useful for scenarios where the first effect is needed for its
|
||
* side effects, but only the result of the second effect is important.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use this function when you are only interested in the result of the second
|
||
* effect but still need to run the first effect for its side effects, such as
|
||
* initialization or setup tasks.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const task1 = Effect.succeed(1).pipe(
|
||
* Effect.delay("200 millis"),
|
||
* Effect.tap(Effect.log("task1 done"))
|
||
* )
|
||
* const task2 = Effect.succeed("hello").pipe(
|
||
* Effect.delay("100 millis"),
|
||
* Effect.tap(Effect.log("task2 done"))
|
||
* )
|
||
*
|
||
* const program = Effect.zipRight(task1, task2)
|
||
*
|
||
* Effect.runPromise(program).then(console.log)
|
||
* // Output:
|
||
* // timestamp=... level=INFO fiber=#0 message="task1 done"
|
||
* // timestamp=... level=INFO fiber=#0 message="task2 done"
|
||
* // hello
|
||
* ```
|
||
*
|
||
* @see {@link zipLeft} for a version that returns the result of the first
|
||
* effect.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Zipping
|
||
*/
|
||
<A, E, R, A2, E2, R2>(self: Effect<A, E, R>, that: Effect<A2, E2, R2>, options?: {
|
||
readonly concurrent?: boolean | undefined;
|
||
readonly batching?: boolean | "inherit" | undefined;
|
||
readonly concurrentFinalizers?: boolean | undefined;
|
||
}): Effect<A2, E2 | E, R2 | R>;
|
||
};
|
||
/**
|
||
* Combines two effects sequentially and applies a function to their results to
|
||
* produce a single value.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function runs two effects in sequence (or concurrently, if the `{
|
||
* concurrent: true }` option is provided) and combines their results using a
|
||
* provided function. Unlike {@link zip}, which returns a tuple of the results,
|
||
* this function processes the results with a custom function to produce a
|
||
* single output.
|
||
*
|
||
* **Example** (Combining Effects with a Custom Function)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const task1 = Effect.succeed(1).pipe(
|
||
* Effect.delay("200 millis"),
|
||
* Effect.tap(Effect.log("task1 done"))
|
||
* )
|
||
* const task2 = Effect.succeed("hello").pipe(
|
||
* Effect.delay("100 millis"),
|
||
* Effect.tap(Effect.log("task2 done"))
|
||
* )
|
||
*
|
||
* const task3 = Effect.zipWith(
|
||
* task1,
|
||
* task2,
|
||
* // Combines results into a single value
|
||
* (number, string) => number + string.length
|
||
* )
|
||
*
|
||
* Effect.runPromise(task3).then(console.log)
|
||
* // Output:
|
||
* // timestamp=... level=INFO fiber=#3 message="task1 done"
|
||
* // timestamp=... level=INFO fiber=#2 message="task2 done"
|
||
* // 6
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Zipping
|
||
*/
|
||
export declare const zipWith: {
|
||
/**
|
||
* Combines two effects sequentially and applies a function to their results to
|
||
* produce a single value.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function runs two effects in sequence (or concurrently, if the `{
|
||
* concurrent: true }` option is provided) and combines their results using a
|
||
* provided function. Unlike {@link zip}, which returns a tuple of the results,
|
||
* this function processes the results with a custom function to produce a
|
||
* single output.
|
||
*
|
||
* **Example** (Combining Effects with a Custom Function)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const task1 = Effect.succeed(1).pipe(
|
||
* Effect.delay("200 millis"),
|
||
* Effect.tap(Effect.log("task1 done"))
|
||
* )
|
||
* const task2 = Effect.succeed("hello").pipe(
|
||
* Effect.delay("100 millis"),
|
||
* Effect.tap(Effect.log("task2 done"))
|
||
* )
|
||
*
|
||
* const task3 = Effect.zipWith(
|
||
* task1,
|
||
* task2,
|
||
* // Combines results into a single value
|
||
* (number, string) => number + string.length
|
||
* )
|
||
*
|
||
* Effect.runPromise(task3).then(console.log)
|
||
* // Output:
|
||
* // timestamp=... level=INFO fiber=#3 message="task1 done"
|
||
* // timestamp=... level=INFO fiber=#2 message="task2 done"
|
||
* // 6
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Zipping
|
||
*/
|
||
<A2, E2, R2, A, B>(that: Effect<A2, E2, R2>, f: (a: A, b: A2) => B, options?: {
|
||
readonly concurrent?: boolean | undefined;
|
||
readonly batching?: boolean | "inherit" | undefined;
|
||
readonly concurrentFinalizers?: boolean | undefined;
|
||
}): <E, R>(self: Effect<A, E, R>) => Effect<B, E2 | E, R2 | R>;
|
||
/**
|
||
* Combines two effects sequentially and applies a function to their results to
|
||
* produce a single value.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function runs two effects in sequence (or concurrently, if the `{
|
||
* concurrent: true }` option is provided) and combines their results using a
|
||
* provided function. Unlike {@link zip}, which returns a tuple of the results,
|
||
* this function processes the results with a custom function to produce a
|
||
* single output.
|
||
*
|
||
* **Example** (Combining Effects with a Custom Function)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const task1 = Effect.succeed(1).pipe(
|
||
* Effect.delay("200 millis"),
|
||
* Effect.tap(Effect.log("task1 done"))
|
||
* )
|
||
* const task2 = Effect.succeed("hello").pipe(
|
||
* Effect.delay("100 millis"),
|
||
* Effect.tap(Effect.log("task2 done"))
|
||
* )
|
||
*
|
||
* const task3 = Effect.zipWith(
|
||
* task1,
|
||
* task2,
|
||
* // Combines results into a single value
|
||
* (number, string) => number + string.length
|
||
* )
|
||
*
|
||
* Effect.runPromise(task3).then(console.log)
|
||
* // Output:
|
||
* // timestamp=... level=INFO fiber=#3 message="task1 done"
|
||
* // timestamp=... level=INFO fiber=#2 message="task2 done"
|
||
* // 6
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Zipping
|
||
*/
|
||
<A, E, R, A2, E2, R2, B>(self: Effect<A, E, R>, that: Effect<A2, E2, R2>, f: (a: A, b: A2) => B, options?: {
|
||
readonly concurrent?: boolean | undefined;
|
||
readonly batching?: boolean | "inherit" | undefined;
|
||
readonly concurrentFinalizers?: boolean | undefined;
|
||
}): Effect<B, E2 | E, R2 | R>;
|
||
};
|
||
/**
|
||
* Applies the function produced by one effect to the value produced by another effect.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function combines two effects:
|
||
* - The first effect produces a function of type `(a: A) => B`.
|
||
* - The second effect produces a value of type `A`.
|
||
*
|
||
* Once both effects complete successfully, the function is applied to the value, resulting in an effect that produces a value of type `B`.
|
||
*
|
||
* @since 2.0.0
|
||
*/
|
||
export declare const ap: {
|
||
/**
|
||
* Applies the function produced by one effect to the value produced by another effect.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function combines two effects:
|
||
* - The first effect produces a function of type `(a: A) => B`.
|
||
* - The second effect produces a value of type `A`.
|
||
*
|
||
* Once both effects complete successfully, the function is applied to the value, resulting in an effect that produces a value of type `B`.
|
||
*
|
||
* @since 2.0.0
|
||
*/
|
||
<A, E2, R2>(that: Effect<A, E2, R2>): <B, R, E>(self: Effect<(a: A) => B, E, R>) => Effect<B, E | E2, R | R2>;
|
||
/**
|
||
* Applies the function produced by one effect to the value produced by another effect.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function combines two effects:
|
||
* - The first effect produces a function of type `(a: A) => B`.
|
||
* - The second effect produces a value of type `A`.
|
||
*
|
||
* Once both effects complete successfully, the function is applied to the value, resulting in an effect that produces a value of type `B`.
|
||
*
|
||
* @since 2.0.0
|
||
*/
|
||
<A, B, E, R, E2, R2>(self: Effect<(a: A) => B, E, R>, that: Effect<A, E2, R2>): Effect<B, E | E2, R | R2>;
|
||
};
|
||
/**
|
||
* @category Requests & Batching
|
||
* @since 2.0.0
|
||
*/
|
||
export declare const blocked: <A, E>(blockedRequests: RequestBlock, _continue: Effect<A, E>) => Blocked<A, E>;
|
||
/**
|
||
* @category Requests & Batching
|
||
* @since 2.0.0
|
||
*/
|
||
export declare const runRequestBlock: (blockedRequests: RequestBlock) => Effect<void>;
|
||
/**
|
||
* @category Requests & Batching
|
||
* @since 2.0.0
|
||
*/
|
||
export declare const step: <A, E, R>(self: Effect<A, E, R>) => Effect<Exit.Exit<A, E> | Blocked<A, E>, never, R>;
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Requests & Batching
|
||
*/
|
||
export declare const request: {
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Requests & Batching
|
||
*/
|
||
<A extends Request.Request<any, any>, Ds extends RequestResolver<A> | Effect<RequestResolver<A>, any, any>>(dataSource: Ds): (self: A) => Effect<Request.Request.Success<A>, Request.Request.Error<A>, [
|
||
Ds
|
||
] extends [Effect<any, any, any>] ? Effect.Context<Ds> : never>;
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Requests & Batching
|
||
*/
|
||
<Ds extends RequestResolver<A> | Effect<RequestResolver<A>, any, any>, A extends Request.Request<any, any>>(self: A, dataSource: Ds): Effect<Request.Request.Success<A>, Request.Request.Error<A>, [
|
||
Ds
|
||
] extends [Effect<any, any, any>] ? Effect.Context<Ds> : never>;
|
||
};
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Requests & Batching
|
||
*/
|
||
export declare const cacheRequestResult: <A extends Request.Request<any, any>>(request: A, result: Request.Request.Result<A>) => Effect<void>;
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Requests & Batching
|
||
*/
|
||
export declare const withRequestBatching: {
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Requests & Batching
|
||
*/
|
||
(requestBatching: boolean): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, R>;
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Requests & Batching
|
||
*/
|
||
<A, E, R>(self: Effect<A, E, R>, requestBatching: boolean): Effect<A, E, R>;
|
||
};
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Requests & Batching
|
||
*/
|
||
export declare const withRequestCaching: {
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Requests & Batching
|
||
*/
|
||
(strategy: boolean): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, R>;
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Requests & Batching
|
||
*/
|
||
<A, E, R>(self: Effect<A, E, R>, strategy: boolean): Effect<A, E, R>;
|
||
};
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Requests & Batching
|
||
*/
|
||
export declare const withRequestCache: {
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Requests & Batching
|
||
*/
|
||
(cache: Request.Cache): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, R>;
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Requests & Batching
|
||
*/
|
||
<A, E, R>(self: Effect<A, E, R>, cache: Request.Cache): Effect<A, E, R>;
|
||
};
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Tracing
|
||
*/
|
||
export declare const tracer: Effect<Tracer.Tracer>;
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Tracing
|
||
*/
|
||
export declare const tracerWith: <A, E, R>(f: (tracer: Tracer.Tracer) => Effect<A, E, R>) => Effect<A, E, R>;
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Tracing
|
||
*/
|
||
export declare const withTracer: {
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Tracing
|
||
*/
|
||
(value: Tracer.Tracer): <A, E, R>(effect: Effect<A, E, R>) => Effect<A, E, R>;
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Tracing
|
||
*/
|
||
<A, E, R>(effect: Effect<A, E, R>, value: Tracer.Tracer): Effect<A, E, R>;
|
||
};
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Tracing
|
||
*/
|
||
export declare const withTracerScoped: (value: Tracer.Tracer) => Effect<void, never, Scope.Scope>;
|
||
/**
|
||
* Disable the tracer for the given Effect.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* Effect.succeed(42).pipe(
|
||
* Effect.withSpan("my-span"),
|
||
* // the span will not be registered with the tracer
|
||
* Effect.withTracerEnabled(false)
|
||
* )
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Tracing
|
||
*/
|
||
export declare const withTracerEnabled: {
|
||
/**
|
||
* Disable the tracer for the given Effect.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* Effect.succeed(42).pipe(
|
||
* Effect.withSpan("my-span"),
|
||
* // the span will not be registered with the tracer
|
||
* Effect.withTracerEnabled(false)
|
||
* )
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Tracing
|
||
*/
|
||
(enabled: boolean): <A, E, R>(effect: Effect<A, E, R>) => Effect<A, E, R>;
|
||
/**
|
||
* Disable the tracer for the given Effect.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* Effect.succeed(42).pipe(
|
||
* Effect.withSpan("my-span"),
|
||
* // the span will not be registered with the tracer
|
||
* Effect.withTracerEnabled(false)
|
||
* )
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Tracing
|
||
*/
|
||
<A, E, R>(effect: Effect<A, E, R>, enabled: boolean): Effect<A, E, R>;
|
||
};
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Tracing
|
||
*/
|
||
export declare const withTracerTiming: {
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Tracing
|
||
*/
|
||
(enabled: boolean): <A, E, R>(effect: Effect<A, E, R>) => Effect<A, E, R>;
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Tracing
|
||
*/
|
||
<A, E, R>(effect: Effect<A, E, R>, enabled: boolean): Effect<A, E, R>;
|
||
};
|
||
/**
|
||
* Adds annotations to each span in the effect for enhanced traceability.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function lets you attach key-value annotations to all spans generated
|
||
* during the execution of an effect. Annotations provide additional context,
|
||
* such as metadata or labels, which can help you understand and debug
|
||
* asynchronous workflows more effectively.
|
||
*
|
||
* You can either pass a single key-value pair or a record of key-value pairs to
|
||
* annotate the spans. These annotations can then be visualized in tracing tools
|
||
* that support span annotations.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Tracing
|
||
*/
|
||
export declare const annotateSpans: {
|
||
/**
|
||
* Adds annotations to each span in the effect for enhanced traceability.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function lets you attach key-value annotations to all spans generated
|
||
* during the execution of an effect. Annotations provide additional context,
|
||
* such as metadata or labels, which can help you understand and debug
|
||
* asynchronous workflows more effectively.
|
||
*
|
||
* You can either pass a single key-value pair or a record of key-value pairs to
|
||
* annotate the spans. These annotations can then be visualized in tracing tools
|
||
* that support span annotations.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Tracing
|
||
*/
|
||
(key: string, value: unknown): <A, E, R>(effect: Effect<A, E, R>) => Effect<A, E, R>;
|
||
/**
|
||
* Adds annotations to each span in the effect for enhanced traceability.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function lets you attach key-value annotations to all spans generated
|
||
* during the execution of an effect. Annotations provide additional context,
|
||
* such as metadata or labels, which can help you understand and debug
|
||
* asynchronous workflows more effectively.
|
||
*
|
||
* You can either pass a single key-value pair or a record of key-value pairs to
|
||
* annotate the spans. These annotations can then be visualized in tracing tools
|
||
* that support span annotations.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Tracing
|
||
*/
|
||
(values: Record<string, unknown>): <A, E, R>(effect: Effect<A, E, R>) => Effect<A, E, R>;
|
||
/**
|
||
* Adds annotations to each span in the effect for enhanced traceability.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function lets you attach key-value annotations to all spans generated
|
||
* during the execution of an effect. Annotations provide additional context,
|
||
* such as metadata or labels, which can help you understand and debug
|
||
* asynchronous workflows more effectively.
|
||
*
|
||
* You can either pass a single key-value pair or a record of key-value pairs to
|
||
* annotate the spans. These annotations can then be visualized in tracing tools
|
||
* that support span annotations.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Tracing
|
||
*/
|
||
<A, E, R>(effect: Effect<A, E, R>, key: string, value: unknown): Effect<A, E, R>;
|
||
/**
|
||
* Adds annotations to each span in the effect for enhanced traceability.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function lets you attach key-value annotations to all spans generated
|
||
* during the execution of an effect. Annotations provide additional context,
|
||
* such as metadata or labels, which can help you understand and debug
|
||
* asynchronous workflows more effectively.
|
||
*
|
||
* You can either pass a single key-value pair or a record of key-value pairs to
|
||
* annotate the spans. These annotations can then be visualized in tracing tools
|
||
* that support span annotations.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Tracing
|
||
*/
|
||
<A, E, R>(effect: Effect<A, E, R>, values: Record<string, unknown>): Effect<A, E, R>;
|
||
};
|
||
/**
|
||
* Adds annotations to the currently active span for traceability.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function adds key-value annotations to the currently active span in the
|
||
* effect's trace. These annotations help provide more context about the
|
||
* operation being executed at a specific point in time. Unlike
|
||
* {@link annotateSpans}, which applies to all spans in an effect, this function
|
||
* focuses solely on the active span.
|
||
*
|
||
* You can either pass a single key-value pair or a record of key-value pairs to
|
||
* annotate the span. These annotations are useful for adding metadata to
|
||
* operations, especially in systems with detailed observability requirements.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Tracing
|
||
*/
|
||
export declare const annotateCurrentSpan: {
|
||
/**
|
||
* Adds annotations to the currently active span for traceability.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function adds key-value annotations to the currently active span in the
|
||
* effect's trace. These annotations help provide more context about the
|
||
* operation being executed at a specific point in time. Unlike
|
||
* {@link annotateSpans}, which applies to all spans in an effect, this function
|
||
* focuses solely on the active span.
|
||
*
|
||
* You can either pass a single key-value pair or a record of key-value pairs to
|
||
* annotate the span. These annotations are useful for adding metadata to
|
||
* operations, especially in systems with detailed observability requirements.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Tracing
|
||
*/
|
||
(key: string, value: unknown): Effect<void>;
|
||
/**
|
||
* Adds annotations to the currently active span for traceability.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function adds key-value annotations to the currently active span in the
|
||
* effect's trace. These annotations help provide more context about the
|
||
* operation being executed at a specific point in time. Unlike
|
||
* {@link annotateSpans}, which applies to all spans in an effect, this function
|
||
* focuses solely on the active span.
|
||
*
|
||
* You can either pass a single key-value pair or a record of key-value pairs to
|
||
* annotate the span. These annotations are useful for adding metadata to
|
||
* operations, especially in systems with detailed observability requirements.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Tracing
|
||
*/
|
||
(values: Record<string, unknown>): Effect<void>;
|
||
};
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Tracing
|
||
*/
|
||
export declare const currentSpan: Effect<Tracer.Span, Cause.NoSuchElementException>;
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Tracing
|
||
*/
|
||
export declare const currentParentSpan: Effect<Tracer.AnySpan, Cause.NoSuchElementException>;
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Tracing
|
||
*/
|
||
export declare const spanAnnotations: Effect<HashMap.HashMap<string, unknown>>;
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Tracing
|
||
*/
|
||
export declare const spanLinks: Effect<Chunk.Chunk<Tracer.SpanLink>>;
|
||
/**
|
||
* For all spans in this effect, add a link with the provided span.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Tracing
|
||
*/
|
||
export declare const linkSpans: {
|
||
/**
|
||
* For all spans in this effect, add a link with the provided span.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Tracing
|
||
*/
|
||
(span: Tracer.AnySpan, attributes?: Record<string, unknown>): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, R>;
|
||
/**
|
||
* For all spans in this effect, add a link with the provided span.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Tracing
|
||
*/
|
||
<A, E, R>(self: Effect<A, E, R>, span: Tracer.AnySpan, attributes?: Record<string, unknown>): Effect<A, E, R>;
|
||
};
|
||
/**
|
||
* Add span links to the current span.
|
||
*
|
||
* @since 3.14.0
|
||
* @category Tracing
|
||
*/
|
||
export declare const linkSpanCurrent: {
|
||
/**
|
||
* Add span links to the current span.
|
||
*
|
||
* @since 3.14.0
|
||
* @category Tracing
|
||
*/
|
||
(span: Tracer.AnySpan, attributes?: Readonly<Record<string, unknown>> | undefined): Effect<void>;
|
||
/**
|
||
* Add span links to the current span.
|
||
*
|
||
* @since 3.14.0
|
||
* @category Tracing
|
||
*/
|
||
(links: ReadonlyArray<Tracer.SpanLink>): Effect<void>;
|
||
};
|
||
/**
|
||
* Create a new span for tracing.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Tracing
|
||
*/
|
||
export declare const makeSpan: (name: string, options?: Tracer.SpanOptions) => Effect<Tracer.Span>;
|
||
/**
|
||
* Create a new span for tracing, and automatically close it when the Scope
|
||
* finalizes.
|
||
*
|
||
* The span is not added to the current span stack, so no child spans will be
|
||
* created for it.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Tracing
|
||
*/
|
||
export declare const makeSpanScoped: (name: string, options?: Tracer.SpanOptions | undefined) => Effect<Tracer.Span, never, Scope.Scope>;
|
||
/**
|
||
* Create a new span for tracing, and automatically close it when the effect
|
||
* completes.
|
||
*
|
||
* The span is not added to the current span stack, so no child spans will be
|
||
* created for it.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Tracing
|
||
*/
|
||
export declare const useSpan: {
|
||
/**
|
||
* Create a new span for tracing, and automatically close it when the effect
|
||
* completes.
|
||
*
|
||
* The span is not added to the current span stack, so no child spans will be
|
||
* created for it.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Tracing
|
||
*/
|
||
<A, E, R>(name: string, evaluate: (span: Tracer.Span) => Effect<A, E, R>): Effect<A, E, R>;
|
||
/**
|
||
* Create a new span for tracing, and automatically close it when the effect
|
||
* completes.
|
||
*
|
||
* The span is not added to the current span stack, so no child spans will be
|
||
* created for it.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Tracing
|
||
*/
|
||
<A, E, R>(name: string, options: Tracer.SpanOptions, evaluate: (span: Tracer.Span) => Effect<A, E, R>): Effect<A, E, R>;
|
||
};
|
||
/**
|
||
* Wraps the effect with a new span for tracing.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Tracing
|
||
*/
|
||
export declare const withSpan: {
|
||
/**
|
||
* Wraps the effect with a new span for tracing.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Tracing
|
||
*/
|
||
(name: string, options?: Tracer.SpanOptions | undefined): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, Exclude<R, Tracer.ParentSpan>>;
|
||
/**
|
||
* Wraps the effect with a new span for tracing.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Tracing
|
||
*/
|
||
<A, E, R>(self: Effect<A, E, R>, name: string, options?: Tracer.SpanOptions | undefined): Effect<A, E, Exclude<R, Tracer.ParentSpan>>;
|
||
};
|
||
/**
|
||
* Wraps a function that returns an effect with a new span for tracing.
|
||
*
|
||
* @since 3.2.0
|
||
* @category Models
|
||
*/
|
||
export interface FunctionWithSpanOptions {
|
||
readonly name: string;
|
||
readonly attributes?: Record<string, unknown> | undefined;
|
||
readonly links?: ReadonlyArray<Tracer.SpanLink> | undefined;
|
||
readonly parent?: Tracer.AnySpan | undefined;
|
||
readonly root?: boolean | undefined;
|
||
readonly context?: Context.Context<never> | undefined;
|
||
readonly kind?: Tracer.SpanKind | undefined;
|
||
}
|
||
/**
|
||
* Wraps a function that returns an effect with a new span for tracing.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const getTodo = Effect.functionWithSpan({
|
||
* body: (id: number) => Effect.succeed(`Got todo ${id}!`),
|
||
* options: (id) => ({
|
||
* name: `getTodo-${id}`,
|
||
* attributes: { id }
|
||
* })
|
||
* })
|
||
* ```
|
||
*
|
||
* @since 3.2.0
|
||
* @category Tracing
|
||
*/
|
||
export declare const functionWithSpan: <Args extends Array<any>, Ret extends Effect<any, any, any>>(options: {
|
||
readonly body: (...args: Args) => Ret;
|
||
readonly options: FunctionWithSpanOptions | ((...args: Args) => FunctionWithSpanOptions);
|
||
readonly captureStackTrace?: boolean | undefined;
|
||
}) => (...args: Args) => Unify.Unify<Ret>;
|
||
/**
|
||
* Wraps the effect with a new span for tracing.
|
||
*
|
||
* The span is ended when the Scope is finalized.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Tracing
|
||
*/
|
||
export declare const withSpanScoped: {
|
||
/**
|
||
* Wraps the effect with a new span for tracing.
|
||
*
|
||
* The span is ended when the Scope is finalized.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Tracing
|
||
*/
|
||
(name: string, options?: Tracer.SpanOptions): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, Exclude<R, Tracer.ParentSpan> | Scope.Scope>;
|
||
/**
|
||
* Wraps the effect with a new span for tracing.
|
||
*
|
||
* The span is ended when the Scope is finalized.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Tracing
|
||
*/
|
||
<A, E, R>(self: Effect<A, E, R>, name: string, options?: Tracer.SpanOptions): Effect<A, E, Exclude<R, Tracer.ParentSpan> | Scope.Scope>;
|
||
};
|
||
/**
|
||
* Adds the provided span to the current span stack.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Tracing
|
||
*/
|
||
export declare const withParentSpan: {
|
||
/**
|
||
* Adds the provided span to the current span stack.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Tracing
|
||
*/
|
||
(span: Tracer.AnySpan): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, Exclude<R, Tracer.ParentSpan>>;
|
||
/**
|
||
* Adds the provided span to the current span stack.
|
||
*
|
||
* @since 2.0.0
|
||
* @category Tracing
|
||
*/
|
||
<A, E, R>(self: Effect<A, E, R>, span: Tracer.AnySpan): Effect<A, E, Exclude<R, Tracer.ParentSpan>>;
|
||
};
|
||
/**
|
||
* Safely handles nullable values by creating an effect that fails for `null` or
|
||
* `undefined`.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function ensures that an input value is non-null and non-undefined
|
||
* before processing it. If the value is valid, the effect succeeds with the
|
||
* value. If the value is `null` or `undefined`, the effect fails with a
|
||
* `NoSuchElementException`. This is particularly useful for avoiding
|
||
* null-related errors by clearly separating valid values from invalid ones in
|
||
* effectful computations.
|
||
*
|
||
* The failure with `NoSuchElementException` allows you to explicitly handle
|
||
* cases where a value is expected but not provided, leading to safer and more
|
||
* predictable code.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use this function when working with values that may be `null` or `undefined`
|
||
* and you want to ensure that only non-null values are processed. It helps
|
||
* enforce null-safety and makes error handling more explicit.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* // ┌─── Effect<number, NoSuchElementException, never>
|
||
* // ▼
|
||
* const maybe1 = Effect.fromNullable(1)
|
||
*
|
||
* Effect.runPromiseExit(maybe1).then(console.log)
|
||
* // Output:
|
||
* // { _id: 'Exit', _tag: 'Success', value: 1 }
|
||
*
|
||
* // ┌─── Effect<number, NoSuchElementException, never>
|
||
* // ▼
|
||
* const maybe2 = Effect.fromNullable(null as number | null)
|
||
*
|
||
* Effect.runPromiseExit(maybe2).then(console.log)
|
||
* // Output:
|
||
* // {
|
||
* // _id: 'Exit',
|
||
* // _tag: 'Failure',
|
||
* // cause: {
|
||
* // _id: 'Cause',
|
||
* // _tag: 'Fail',
|
||
* // failure: { _tag: 'NoSuchElementException' }
|
||
* // }
|
||
* // }
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Optional Wrapping & Unwrapping
|
||
*/
|
||
export declare const fromNullable: <A>(value: A) => Effect<NonNullable<A>, Cause.NoSuchElementException>;
|
||
/**
|
||
* Converts an effect that may fail with a `NoSuchElementException` into an
|
||
* effect that succeeds with an `Option`.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function transforms an effect that might fail with
|
||
* `Cause.NoSuchElementException` into an effect that succeeds with an `Option`
|
||
* type. If the original effect succeeds, its value is wrapped in `Option.some`.
|
||
* If it fails specifically due to a `NoSuchElementException`, the failure is
|
||
* mapped to `Option.none`. Other types of failures remain unchanged and are
|
||
* passed through as they are.
|
||
*
|
||
* This is useful when working with effects where you want to gracefully handle
|
||
* the absence of a value while preserving other potential failures.
|
||
*
|
||
* **When to Use**
|
||
*
|
||
* Use this function when you need to handle missing values as `Option.none`
|
||
* rather than throwing or propagating errors like `NoSuchElementException`.
|
||
* It’s ideal for scenarios where you want to explicitly represent optionality
|
||
* in a type-safe way while retaining other failure information.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* // ┌─── Effect<number, NoSuchElementException, never>
|
||
* // ▼
|
||
* const maybe1 = Effect.fromNullable(1)
|
||
*
|
||
* // ┌─── Effect<Option<number>, never, never>
|
||
* // ▼
|
||
* const option1 = Effect.optionFromOptional(maybe1)
|
||
*
|
||
* Effect.runPromise(option1).then(console.log)
|
||
* // Output: { _id: 'Option', _tag: 'Some', value: 1 }
|
||
*
|
||
* // ┌─── Effect<number, NoSuchElementException, never>
|
||
* // ▼
|
||
* const maybe2 = Effect.fromNullable(null as number | null)
|
||
*
|
||
* // ┌─── Effect<Option<number>, never, never>
|
||
* // ▼
|
||
* const option2 = Effect.optionFromOptional(maybe2)
|
||
*
|
||
* Effect.runPromise(option2).then(console.log)
|
||
* // Output: { _tag: 'None' }
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Optional Wrapping & Unwrapping
|
||
*/
|
||
export declare const optionFromOptional: <A, E, R>(self: Effect<A, E, R>) => Effect<Option.Option<A>, Exclude<E, Cause.NoSuchElementException>, R>;
|
||
/**
|
||
* Converts an `Option` of an `Effect` into an `Effect` of an `Option`.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function transforms an `Option<Effect<A, E, R>>` into an
|
||
* `Effect<Option<A>, E, R>`. If the `Option` is `None`, the resulting `Effect`
|
||
* will immediately succeed with a `None` value. If the `Option` is `Some`, the
|
||
* inner `Effect` will be executed, and its result wrapped in a `Some`.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect, Option } from "effect"
|
||
*
|
||
* // ┌─── Option<Effect<number, never, never>>
|
||
* // ▼
|
||
* const maybe = Option.some(Effect.succeed(42))
|
||
*
|
||
* // ┌─── Effect<Option<number>, never, never>
|
||
* // ▼
|
||
* const result = Effect.transposeOption(maybe)
|
||
*
|
||
* console.log(Effect.runSync(result))
|
||
* // Output: { _id: 'Option', _tag: 'Some', value: 42 }
|
||
* ```
|
||
*
|
||
* @since 3.13.0
|
||
* @category Optional Wrapping & Unwrapping
|
||
*/
|
||
export declare const transposeOption: <A = never, E = never, R = never>(self: Option.Option<Effect<A, E, R>>) => Effect<Option.Option<A>, E, R>;
|
||
/**
|
||
* Applies an `Effect` on an `Option` and transposes the result.
|
||
*
|
||
* **Details**
|
||
*
|
||
* If the `Option` is `None`, the resulting `Effect` will immediately succeed with a `None` value.
|
||
* If the `Option` is `Some`, the effectful operation will be executed on the inner value, and its result wrapped in a `Some`.
|
||
*
|
||
* @example
|
||
* ```ts
|
||
* import { Effect, Option, pipe } from "effect"
|
||
*
|
||
* // ┌─── Effect<Option<number>, never, never>>
|
||
* // ▼
|
||
* const noneResult = pipe(
|
||
* Option.none(),
|
||
* Effect.transposeMapOption(() => Effect.succeed(42)) // will not be executed
|
||
* )
|
||
* console.log(Effect.runSync(noneResult))
|
||
* // Output: { _id: 'Option', _tag: 'None' }
|
||
*
|
||
* // ┌─── Effect<Option<number>, never, never>>
|
||
* // ▼
|
||
* const someSuccessResult = pipe(
|
||
* Option.some(42),
|
||
* Effect.transposeMapOption((value) => Effect.succeed(value * 2))
|
||
* )
|
||
* console.log(Effect.runSync(someSuccessResult))
|
||
* // Output: { _id: 'Option', _tag: 'Some', value: 84 }
|
||
* ```
|
||
*
|
||
* @since 3.14.0
|
||
* @category Optional Wrapping & Unwrapping
|
||
*/
|
||
export declare const transposeMapOption: (<A, B, E = never, R = never>(f: (self: A) => Effect<B, E, R>) => (self: Option.Option<A>) => Effect<Option.Option<B>, E, R>) & (<A, B, E = never, R = never>(self: Option.Option<A>, f: (self: A) => Effect<B, E, R>) => Effect<Option.Option<B>, E, R>);
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Models
|
||
*/
|
||
export declare namespace Tag {
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Models
|
||
*/
|
||
interface ProhibitedType {
|
||
Service?: `property "Service" is forbidden`;
|
||
Identifier?: `property "Identifier" is forbidden`;
|
||
_op?: `property "_op" is forbidden`;
|
||
of?: `property "of" is forbidden`;
|
||
context?: `property "context" is forbidden`;
|
||
key?: `property "key" is forbidden`;
|
||
stack?: `property "stack" is forbidden`;
|
||
name?: `property "name" is forbidden`;
|
||
pipe?: `property "pipe" is forbidden`;
|
||
use?: `property "use" is forbidden`;
|
||
}
|
||
/**
|
||
* @since 2.0.0
|
||
* @category Models
|
||
*/
|
||
type AllowedType = (Record<PropertyKey, any> & ProhibitedType) | string | number | symbol;
|
||
/**
|
||
* @since 3.9.0
|
||
* @category Models
|
||
*/
|
||
type Proxy<Self, Type> = {
|
||
[k in keyof Type as Type[k] extends ((...args: infer Args extends ReadonlyArray<any>) => infer Ret) ? ((...args: Readonly<Args>) => Ret) extends Type[k] ? k : never : k]: Type[k] extends (...args: infer Args extends ReadonlyArray<any>) => Effect<infer A, infer E, infer R> ? (...args: Readonly<Args>) => Effect<A, E, Self | R> : Type[k] extends (...args: infer Args extends ReadonlyArray<any>) => Promise<infer A> ? (...args: Readonly<Args>) => Effect<A, Cause.UnknownException, Self> : Type[k] extends (...args: infer Args extends ReadonlyArray<any>) => infer A ? (...args: Readonly<Args>) => Effect<A, never, Self> : Type[k] extends Effect<infer A, infer E, infer R> ? Effect<A, E, Self | R> : Effect<Type[k], never, Self>;
|
||
};
|
||
}
|
||
/**
|
||
* Creates a unique tag for a dependency, embedding the service's methods as
|
||
* static properties.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to define a `Tag` for a service or dependency in
|
||
* your application. The `Tag` not only acts as an identifier but also provides
|
||
* direct access to the service's methods via static properties. This makes it
|
||
* easier to access and use the service in your code without manually managing
|
||
* contexts.
|
||
*
|
||
* In the example below, the fields of the service (in this case, the `notify`
|
||
* method) are turned into static properties of the Notifications class, making
|
||
* it easier to access them.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* class Notifications extends Effect.Tag("Notifications")<
|
||
* Notifications,
|
||
* { readonly notify: (message: string) => Effect.Effect<void> }
|
||
* >() {}
|
||
*
|
||
* // Create an effect that depends on the Notifications service
|
||
* const action = Notifications.notify("Hello, world!")
|
||
* ```
|
||
*
|
||
* @since 2.0.0
|
||
* @category Context
|
||
*/
|
||
export declare const Tag: <const Id extends string>(id: Id) => <Self, Type extends Tag.AllowedType>() => Context.TagClass<Self, Id, Type> & (Type extends Record<PropertyKey, any> ? Tag.Proxy<Self, Type> : {}) & {
|
||
use: <X>(body: (_: Type) => X) => [X] extends [Effect<infer A, infer E, infer R>] ? Effect<A, E, R | Self> : [X] extends [PromiseLike<infer A>] ? Effect<A, Cause.UnknownException, Self> : Effect<X, never, Self>;
|
||
};
|
||
type MissingSelfGeneric = `Missing \`Self\` generic - use \`class Self extends Effect.Service<Self>()...\``;
|
||
/**
|
||
* Simplifies the creation and management of services in Effect by defining both
|
||
* a `Tag` and a `Layer`.
|
||
*
|
||
* **Details**
|
||
*
|
||
* This function allows you to streamline the creation of services by combining
|
||
* the definition of a `Context.Tag` and a `Layer` in a single step. It supports
|
||
* various ways of providing the service implementation:
|
||
* - Using an `effect` to define the service dynamically.
|
||
* - Using `sync` or `succeed` to define the service statically.
|
||
* - Using `scoped` to create services with lifecycle management.
|
||
*
|
||
* It also allows you to specify dependencies for the service, which will be
|
||
* provided automatically when the service is used. Accessors can be optionally
|
||
* generated for the service, making it more convenient to use.
|
||
*
|
||
* **Example**
|
||
*
|
||
* ```ts
|
||
* import { Effect } from 'effect';
|
||
*
|
||
* class Prefix extends Effect.Service<Prefix>()("Prefix", {
|
||
* sync: () => ({ prefix: "PRE" })
|
||
* }) {}
|
||
*
|
||
* class Logger extends Effect.Service<Logger>()("Logger", {
|
||
* accessors: true,
|
||
* effect: Effect.gen(function* () {
|
||
* const { prefix } = yield* Prefix
|
||
* return {
|
||
* info: (message: string) =>
|
||
* Effect.sync(() => {
|
||
* console.log(`[${prefix}][${message}]`)
|
||
* })
|
||
* }
|
||
* }),
|
||
* dependencies: [Prefix.Default]
|
||
* }) {}
|
||
* ```
|
||
*
|
||
* @since 3.9.0
|
||
* @category Context
|
||
* @experimental might be up for breaking changes
|
||
*/
|
||
export declare const Service: <Self = never>() => [Self] extends [never] ? MissingSelfGeneric : {
|
||
<const Key extends string, const Make extends {
|
||
readonly scoped: Effect<Service.AllowedType<Key, Make>, any, any> | ((...args: any) => Effect<Service.AllowedType<Key, Make>, any, any>);
|
||
readonly dependencies?: ReadonlyArray<Layer.Layer.Any>;
|
||
readonly accessors?: boolean;
|
||
/** @deprecated */
|
||
readonly ಠ_ಠ: never;
|
||
} | {
|
||
readonly effect: Effect<Service.AllowedType<Key, Make>, any, any> | ((...args: any) => Effect<Service.AllowedType<Key, Make>, any, any>);
|
||
readonly dependencies?: ReadonlyArray<Layer.Layer.Any>;
|
||
readonly accessors?: boolean;
|
||
/** @deprecated */
|
||
readonly ಠ_ಠ: never;
|
||
} | {
|
||
readonly sync: LazyArg<Service.AllowedType<Key, Make>>;
|
||
readonly dependencies?: ReadonlyArray<Layer.Layer.Any>;
|
||
readonly accessors?: boolean;
|
||
/** @deprecated */
|
||
readonly ಠ_ಠ: never;
|
||
} | {
|
||
readonly succeed: Service.AllowedType<Key, Make>;
|
||
readonly dependencies?: ReadonlyArray<Layer.Layer.Any>;
|
||
readonly accessors?: boolean;
|
||
/** @deprecated */
|
||
readonly ಠ_ಠ: never;
|
||
}>(key: Key, make: Make): Service.Class<Self, Key, Make>;
|
||
<const Key extends string, const Make extends NoExcessProperties<{
|
||
readonly scoped: Effect<Service.AllowedType<Key, Make>, any, any> | ((...args: any) => Effect<Service.AllowedType<Key, Make>, any, any>);
|
||
readonly dependencies?: ReadonlyArray<Layer.Layer.Any>;
|
||
readonly accessors?: boolean;
|
||
}, Make>>(key: Key, make: Make): Service.Class<Self, Key, Make>;
|
||
<const Key extends string, const Make extends NoExcessProperties<{
|
||
readonly effect: Effect<Service.AllowedType<Key, Make>, any, any> | ((...args: any) => Effect<Service.AllowedType<Key, Make>, any, any>);
|
||
readonly dependencies?: ReadonlyArray<Layer.Layer.Any>;
|
||
readonly accessors?: boolean;
|
||
}, Make>>(key: Key, make: Make): Service.Class<Self, Key, Make>;
|
||
<const Key extends string, const Make extends NoExcessProperties<{
|
||
readonly sync: LazyArg<Service.AllowedType<Key, Make>>;
|
||
readonly dependencies?: ReadonlyArray<Layer.Layer.Any>;
|
||
readonly accessors?: boolean;
|
||
}, Make>>(key: Key, make: Make): Service.Class<Self, Key, Make>;
|
||
<const Key extends string, const Make extends NoExcessProperties<{
|
||
readonly succeed: Service.AllowedType<Key, Make>;
|
||
readonly dependencies?: ReadonlyArray<Layer.Layer.Any>;
|
||
readonly accessors?: boolean;
|
||
}, Make>>(key: Key, make: Make): Service.Class<Self, Key, Make>;
|
||
};
|
||
/**
|
||
* @since 3.9.0
|
||
* @category Context
|
||
*/
|
||
export declare namespace Service {
|
||
/**
|
||
* @since 3.9.0
|
||
*/
|
||
interface ProhibitedType {
|
||
Service?: `property "Service" is forbidden`;
|
||
Identifier?: `property "Identifier" is forbidden`;
|
||
Default?: `property "Default" is forbidden`;
|
||
DefaultWithoutDependencies?: `property "DefaultWithoutDependencies" is forbidden`;
|
||
_op_layer?: `property "_op_layer" is forbidden`;
|
||
_op?: `property "_op" is forbidden`;
|
||
of?: `property "of" is forbidden`;
|
||
make?: `property "make" is forbidden`;
|
||
context?: `property "context" is forbidden`;
|
||
key?: `property "key" is forbidden`;
|
||
stack?: `property "stack" is forbidden`;
|
||
name?: `property "name" is forbidden`;
|
||
pipe?: `property "pipe" is forbidden`;
|
||
use?: `property "use" is forbidden`;
|
||
_tag?: `property "_tag" is forbidden`;
|
||
}
|
||
/**
|
||
* @since 3.9.0
|
||
*/
|
||
type AllowedType<Key extends string, Make> = MakeAccessors<Make> extends true ? Record<PropertyKey, any> & {
|
||
readonly [K in Extract<keyof MakeService<Make>, keyof ProhibitedType>]: K extends "_tag" ? Key : ProhibitedType[K];
|
||
} : Record<PropertyKey, any> & {
|
||
readonly _tag?: Key;
|
||
};
|
||
/**
|
||
* @since 3.9.0
|
||
*/
|
||
type Class<Self, Key extends string, Make> = {
|
||
new (_: MakeService<Make>): MakeService<Make> & {
|
||
readonly _tag: Key;
|
||
};
|
||
readonly use: <X>(body: (_: Self) => X) => [X] extends [Effect<infer A, infer E, infer R>] ? Effect<A, E, R | Self> : [X] extends [PromiseLike<infer A>] ? Effect<A, Cause.UnknownException, Self> : Effect<X, never, Self>;
|
||
readonly make: (_: MakeService<Make>) => Self;
|
||
} & Context.Tag<Self, Self> & {
|
||
key: Key;
|
||
} & (MakeAccessors<Make> extends true ? Tag.Proxy<Self, MakeService<Make>> : {}) & (MakeDeps<Make> extends never ? {
|
||
readonly Default: HasArguments<Make> extends true ? (...args: MakeArguments<Make>) => Layer.Layer<Self, MakeError<Make>, MakeContext<Make>> : Layer.Layer<Self, MakeError<Make>, MakeContext<Make>>;
|
||
} : {
|
||
readonly DefaultWithoutDependencies: HasArguments<Make> extends true ? (...args: MakeArguments<Make>) => Layer.Layer<Self, MakeError<Make>, MakeContext<Make>> : Layer.Layer<Self, MakeError<Make>, MakeContext<Make>>;
|
||
readonly Default: HasArguments<Make> extends true ? (...args: MakeArguments<Make>) => Layer.Layer<Self, MakeError<Make> | MakeDepsE<Make>, Exclude<MakeContext<Make>, MakeDepsOut<Make>> | MakeDepsIn<Make>> : Layer.Layer<Self, MakeError<Make> | MakeDepsE<Make>, Exclude<MakeContext<Make>, MakeDepsOut<Make>> | MakeDepsIn<Make>>;
|
||
});
|
||
/**
|
||
* @since 3.9.0
|
||
*/
|
||
type MakeService<Make> = Make extends {
|
||
readonly effect: Effect<infer _A, infer _E, infer _R>;
|
||
} ? _A : Make extends {
|
||
readonly scoped: Effect<infer _A, infer _E, infer _R>;
|
||
} ? _A : Make extends {
|
||
readonly effect: (...args: infer _Args) => Effect<infer _A, infer _E, infer _R>;
|
||
} ? _A : Make extends {
|
||
readonly scoped: (...args: infer _Args) => Effect<infer _A, infer _E, infer _R>;
|
||
} ? _A : Make extends {
|
||
readonly sync: LazyArg<infer A>;
|
||
} ? A : Make extends {
|
||
readonly succeed: infer A;
|
||
} ? A : never;
|
||
/**
|
||
* @since 3.9.0
|
||
*/
|
||
type MakeError<Make> = Make extends {
|
||
readonly effect: Effect<infer _A, infer _E, infer _R>;
|
||
} ? _E : Make extends {
|
||
readonly scoped: Effect<infer _A, infer _E, infer _R>;
|
||
} ? _E : Make extends {
|
||
readonly effect: (...args: infer _Args) => Effect<infer _A, infer _E, infer _R>;
|
||
} ? _E : Make extends {
|
||
readonly scoped: (...args: infer _Args) => Effect<infer _A, infer _E, infer _R>;
|
||
} ? _E : never;
|
||
/**
|
||
* @since 3.9.0
|
||
*/
|
||
type MakeContext<Make> = Make extends {
|
||
readonly effect: Effect<infer _A, infer _E, infer _R>;
|
||
} ? _R : Make extends {
|
||
readonly scoped: Effect<infer _A, infer _E, infer _R>;
|
||
} ? Exclude<_R, Scope.Scope> : Make extends {
|
||
readonly effect: (...args: infer _Args) => Effect<infer _A, infer _E, infer _R>;
|
||
} ? _R : Make extends {
|
||
readonly scoped: (...args: infer _Args) => Effect<infer _A, infer _E, infer _R>;
|
||
} ? Exclude<_R, Scope.Scope> : never;
|
||
/**
|
||
* @since 3.9.0
|
||
*/
|
||
type MakeDeps<Make> = Make extends {
|
||
readonly dependencies: ReadonlyArray<Layer.Layer.Any>;
|
||
} ? Make["dependencies"][number] : never;
|
||
/**
|
||
* @since 3.9.0
|
||
*/
|
||
type MakeDepsOut<Make> = Contravariant.Type<MakeDeps<Make>[Layer.LayerTypeId]["_ROut"]>;
|
||
/**
|
||
* @since 3.9.0
|
||
*/
|
||
type MakeDepsE<Make> = Covariant.Type<MakeDeps<Make>[Layer.LayerTypeId]["_E"]>;
|
||
/**
|
||
* @since 3.9.0
|
||
*/
|
||
type MakeDepsIn<Make> = Covariant.Type<MakeDeps<Make>[Layer.LayerTypeId]["_RIn"]>;
|
||
/**
|
||
* @since 3.9.0
|
||
*/
|
||
type MakeAccessors<Make> = Make extends {
|
||
readonly accessors: true;
|
||
} ? true : false;
|
||
/**
|
||
* @since 3.16.0
|
||
*/
|
||
type MakeArguments<Make> = Make extends {
|
||
readonly effect: (...args: infer Args) => Effect<infer _A, infer _E, infer _R>;
|
||
} ? Args : Make extends {
|
||
readonly scoped: (...args: infer Args) => Effect<infer _A, infer _E, infer _R>;
|
||
} ? Args : never;
|
||
/**
|
||
* @since 3.16.0
|
||
*/
|
||
type HasArguments<Make> = Make extends {
|
||
readonly scoped: (...args: ReadonlyArray<any>) => Effect<infer _A, infer _E, infer _R>;
|
||
} ? true : Make extends {
|
||
readonly effect: (...args: ReadonlyArray<any>) => Effect<infer _A, infer _E, infer _R>;
|
||
} ? true : false;
|
||
}
|
||
/**
|
||
* @since 3.11.0
|
||
* @category Models
|
||
*/
|
||
export declare namespace fn {
|
||
/**
|
||
* @since 3.11.0
|
||
* @category Models
|
||
*/
|
||
type Gen = {
|
||
<Eff extends YieldWrap<Effect<any, any, any>>, AEff, Args extends Array<any>>(body: (...args: Args) => Generator<Eff, AEff, never>): (...args: Args) => Effect<AEff, [
|
||
Eff
|
||
] extends [never] ? never : [Eff] extends [YieldWrap<Effect<infer _A, infer E, infer _R>>] ? E : never, [
|
||
Eff
|
||
] extends [never] ? never : [Eff] extends [YieldWrap<Effect<infer _A, infer _E, infer R>>] ? R : never>;
|
||
<Eff extends YieldWrap<Effect<any, any, any>>, AEff, Args extends Array<any>, A extends Effect<any, any, any>>(body: (...args: Args) => Generator<Eff, AEff, never>, a: (_: Effect<AEff, [
|
||
Eff
|
||
] extends [never] ? never : [Eff] extends [YieldWrap<Effect<infer _A, infer E, infer _R>>] ? E : never, [
|
||
Eff
|
||
] extends [never] ? never : [Eff] extends [YieldWrap<Effect<infer _A, infer _E, infer R>>] ? R : never>, ...args: NoInfer<Args>) => A): (...args: Args) => Effect.AsEffect<A>;
|
||
<Eff extends YieldWrap<Effect<any, any, any>>, AEff, Args extends Array<any>, A, B extends Effect<any, any, any>>(body: (...args: Args) => Generator<Eff, AEff, never>, a: (_: Effect<AEff, [
|
||
Eff
|
||
] extends [never] ? never : [Eff] extends [YieldWrap<Effect<infer _A, infer E, infer _R>>] ? E : never, [
|
||
Eff
|
||
] extends [never] ? never : [Eff] extends [YieldWrap<Effect<infer _A, infer _E, infer R>>] ? R : never>, ...args: NoInfer<Args>) => A, b: (_: A, ...args: NoInfer<Args>) => B): (...args: Args) => Effect.AsEffect<B>;
|
||
<Eff extends YieldWrap<Effect<any, any, any>>, AEff, Args extends Array<any>, A, B, C extends Effect<any, any, any>>(body: (...args: Args) => Generator<Eff, AEff, never>, a: (_: Effect<AEff, [
|
||
Eff
|
||
] extends [never] ? never : [Eff] extends [YieldWrap<Effect<infer _A, infer E, infer _R>>] ? E : never, [
|
||
Eff
|
||
] extends [never] ? never : [Eff] extends [YieldWrap<Effect<infer _A, infer _E, infer R>>] ? R : never>, ...args: NoInfer<Args>) => A, b: (_: A, ...args: NoInfer<Args>) => B, c: (_: B, ...args: NoInfer<Args>) => C): (...args: Args) => Effect.AsEffect<C>;
|
||
<Eff extends YieldWrap<Effect<any, any, any>>, AEff, Args extends Array<any>, A, B, C, D extends Effect<any, any, any>>(body: (...args: Args) => Generator<Eff, AEff, never>, a: (_: Effect<AEff, [
|
||
Eff
|
||
] extends [never] ? never : [Eff] extends [YieldWrap<Effect<infer _A, infer E, infer _R>>] ? E : never, [
|
||
Eff
|
||
] extends [never] ? never : [Eff] extends [YieldWrap<Effect<infer _A, infer _E, infer R>>] ? R : never>, ...args: NoInfer<Args>) => A, b: (_: A, ...args: NoInfer<Args>) => B, c: (_: B, ...args: NoInfer<Args>) => C, d: (_: C, ...args: NoInfer<Args>) => D): (...args: Args) => Effect.AsEffect<D>;
|
||
<Eff extends YieldWrap<Effect<any, any, any>>, AEff, Args extends Array<any>, A, B, C, D, E extends Effect<any, any, any>>(body: (...args: Args) => Generator<Eff, AEff, never>, a: (_: Effect<AEff, [
|
||
Eff
|
||
] extends [never] ? never : [Eff] extends [YieldWrap<Effect<infer _A, infer E, infer _R>>] ? E : never, [
|
||
Eff
|
||
] extends [never] ? never : [Eff] extends [YieldWrap<Effect<infer _A, infer _E, infer R>>] ? R : never>, ...args: NoInfer<Args>) => A, b: (_: A, ...args: NoInfer<Args>) => B, c: (_: B, ...args: NoInfer<Args>) => C, d: (_: C, ...args: NoInfer<Args>) => D, e: (_: D, ...args: NoInfer<Args>) => E): (...args: Args) => Effect.AsEffect<E>;
|
||
<Eff extends YieldWrap<Effect<any, any, any>>, AEff, Args extends Array<any>, A, B, C, D, E, F extends Effect<any, any, any>>(body: (...args: Args) => Generator<Eff, AEff, never>, a: (_: Effect<AEff, [
|
||
Eff
|
||
] extends [never] ? never : [Eff] extends [YieldWrap<Effect<infer _A, infer E, infer _R>>] ? E : never, [
|
||
Eff
|
||
] extends [never] ? never : [Eff] extends [YieldWrap<Effect<infer _A, infer _E, infer R>>] ? R : never>, ...args: NoInfer<Args>) => A, b: (_: A, ...args: NoInfer<Args>) => B, c: (_: B, ...args: NoInfer<Args>) => C, d: (_: C, ...args: NoInfer<Args>) => D, e: (_: D, ...args: NoInfer<Args>) => E, f: (_: E, ...args: NoInfer<Args>) => F): (...args: Args) => Effect.AsEffect<F>;
|
||
<Eff extends YieldWrap<Effect<any, any, any>>, AEff, Args extends Array<any>, A, B, C, D, E, F, G extends Effect<any, any, any>>(body: (...args: Args) => Generator<Eff, AEff, never>, a: (_: Effect<AEff, [
|
||
Eff
|
||
] extends [never] ? never : [Eff] extends [YieldWrap<Effect<infer _A, infer E, infer _R>>] ? E : never, [
|
||
Eff
|
||
] extends [never] ? never : [Eff] extends [YieldWrap<Effect<infer _A, infer _E, infer R>>] ? R : never>, ...args: NoInfer<Args>) => A, b: (_: A, ...args: NoInfer<Args>) => B, c: (_: B, ...args: NoInfer<Args>) => C, d: (_: C, ...args: NoInfer<Args>) => D, e: (_: D, ...args: NoInfer<Args>) => E, f: (_: E, ...args: NoInfer<Args>) => F, g: (_: F, ...args: NoInfer<Args>) => G): (...args: Args) => Effect.AsEffect<G>;
|
||
<Eff extends YieldWrap<Effect<any, any, any>>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H extends Effect<any, any, any>>(body: (...args: Args) => Generator<Eff, AEff, never>, a: (_: Effect<AEff, [
|
||
Eff
|
||
] extends [never] ? never : [Eff] extends [YieldWrap<Effect<infer _A, infer E, infer _R>>] ? E : never, [
|
||
Eff
|
||
] extends [never] ? never : [Eff] extends [YieldWrap<Effect<infer _A, infer _E, infer R>>] ? R : never>, ...args: NoInfer<Args>) => A, b: (_: A, ...args: NoInfer<Args>) => B, c: (_: B, ...args: NoInfer<Args>) => C, d: (_: C, ...args: NoInfer<Args>) => D, e: (_: D, ...args: NoInfer<Args>) => E, f: (_: E, ...args: NoInfer<Args>) => F, g: (_: F, ...args: NoInfer<Args>) => G, h: (_: G, ...args: NoInfer<Args>) => H): (...args: Args) => Effect.AsEffect<H>;
|
||
<Eff extends YieldWrap<Effect<any, any, any>>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H, I extends Effect<any, any, any>>(body: (...args: Args) => Generator<Eff, AEff, never>, a: (_: Effect<AEff, [
|
||
Eff
|
||
] extends [never] ? never : [Eff] extends [YieldWrap<Effect<infer _A, infer E, infer _R>>] ? E : never, [
|
||
Eff
|
||
] extends [never] ? never : [Eff] extends [YieldWrap<Effect<infer _A, infer _E, infer R>>] ? R : never>, ...args: NoInfer<Args>) => A, b: (_: A, ...args: NoInfer<Args>) => B, c: (_: B, ...args: NoInfer<Args>) => C, d: (_: C, ...args: NoInfer<Args>) => D, e: (_: D, ...args: NoInfer<Args>) => E, f: (_: E, ...args: NoInfer<Args>) => F, g: (_: F, ...args: NoInfer<Args>) => G, h: (_: G, ...args: NoInfer<Args>) => H, i: (_: H, ...args: NoInfer<Args>) => I): (...args: Args) => Effect.AsEffect<I>;
|
||
};
|
||
/**
|
||
* @since 3.11.0
|
||
* @category Models
|
||
*/
|
||
type NonGen = {
|
||
<Eff extends Effect<any, any, any>, Args extends Array<any>>(body: (...args: Args) => Eff): (...args: Args) => Effect.AsEffect<Eff>;
|
||
<Eff extends Effect<any, any, any>, A, Args extends Array<any>>(body: (...args: Args) => A, a: (_: A, ...args: NoInfer<Args>) => Eff): (...args: Args) => Effect.AsEffect<Eff>;
|
||
<Eff extends Effect<any, any, any>, A, B, Args extends Array<any>>(body: (...args: Args) => A, a: (_: A, ...args: NoInfer<Args>) => B, b: (_: B, ...args: NoInfer<Args>) => Eff): (...args: Args) => Effect.AsEffect<Eff>;
|
||
<Eff extends Effect<any, any, any>, A, B, C, Args extends Array<any>>(body: (...args: Args) => A, a: (_: A, ...args: NoInfer<Args>) => B, b: (_: B, ...args: NoInfer<Args>) => C, c: (_: C, ...args: NoInfer<Args>) => Eff): (...args: Args) => Effect.AsEffect<Eff>;
|
||
<Eff extends Effect<any, any, any>, A, B, C, D, Args extends Array<any>>(body: (...args: Args) => A, a: (_: A, ...args: NoInfer<Args>) => B, b: (_: B, ...args: NoInfer<Args>) => C, c: (_: C, ...args: NoInfer<Args>) => D, d: (_: D, ...args: NoInfer<Args>) => Eff): (...args: Args) => Effect.AsEffect<Eff>;
|
||
<Eff extends Effect<any, any, any>, A, B, C, D, E, Args extends Array<any>>(body: (...args: Args) => A, a: (_: A, ...args: NoInfer<Args>) => B, b: (_: B, ...args: NoInfer<Args>) => C, c: (_: C, ...args: NoInfer<Args>) => D, d: (_: D, ...args: NoInfer<Args>) => E, e: (_: E, ...args: NoInfer<Args>) => Eff): (...args: Args) => Effect.AsEffect<Eff>;
|
||
<Eff extends Effect<any, any, any>, A, B, C, D, E, F, Args extends Array<any>>(body: (...args: Args) => A, a: (_: A, ...args: NoInfer<Args>) => B, b: (_: B, ...args: NoInfer<Args>) => C, c: (_: C, ...args: NoInfer<Args>) => D, d: (_: D, ...args: NoInfer<Args>) => E, e: (_: E, ...args: NoInfer<Args>) => F, f: (_: F, ...args: NoInfer<Args>) => Eff): (...args: Args) => Effect.AsEffect<Eff>;
|
||
<Eff extends Effect<any, any, any>, A, B, C, D, E, F, G, Args extends Array<any>>(body: (...args: Args) => A, a: (_: A, ...args: NoInfer<Args>) => B, b: (_: B, ...args: NoInfer<Args>) => C, c: (_: C, ...args: NoInfer<Args>) => D, d: (_: D, ...args: NoInfer<Args>) => E, e: (_: E, ...args: NoInfer<Args>) => F, f: (_: F, ...args: NoInfer<Args>) => G, g: (_: G, ...args: NoInfer<Args>) => Eff): (...args: Args) => Effect.AsEffect<Eff>;
|
||
<Eff extends Effect<any, any, any>, A, B, C, D, E, F, G, H, Args extends Array<any>>(body: (...args: Args) => A, a: (_: A, ...args: NoInfer<Args>) => B, b: (_: B, ...args: NoInfer<Args>) => C, c: (_: C, ...args: NoInfer<Args>) => D, d: (_: D, ...args: NoInfer<Args>) => E, e: (_: E, ...args: NoInfer<Args>) => F, f: (_: F, ...args: NoInfer<Args>) => G, g: (_: G, ...args: NoInfer<Args>) => H, h: (_: H, ...args: NoInfer<Args>) => Eff): (...args: Args) => Effect.AsEffect<Eff>;
|
||
<Eff extends Effect<any, any, any>, A, B, C, D, E, F, G, H, I, Args extends Array<any>>(body: (...args: Args) => A, a: (_: A, ...args: NoInfer<Args>) => B, b: (_: B, ...args: NoInfer<Args>) => C, c: (_: C, ...args: NoInfer<Args>) => D, d: (_: D, ...args: NoInfer<Args>) => E, e: (_: E, ...args: NoInfer<Args>) => F, f: (_: F, ...args: NoInfer<Args>) => G, g: (_: G, ...args: NoInfer<Args>) => H, h: (_: H, ...args: NoInfer<Args>) => I, i: (_: H, ...args: NoInfer<Args>) => Eff): (...args: Args) => Effect.AsEffect<Eff>;
|
||
};
|
||
/**
|
||
* @since 3.11.0
|
||
* @category Models
|
||
*/
|
||
type Untraced = {
|
||
<Eff extends YieldWrap<Effect<any, any, any>>, AEff, Args extends Array<any>>(body: (...args: Args) => Generator<Eff, AEff, never>): (...args: Args) => Effect<AEff, [
|
||
Eff
|
||
] extends [never] ? never : [Eff] extends [YieldWrap<Effect<infer _A, infer E, infer _R>>] ? E : never, [
|
||
Eff
|
||
] extends [never] ? never : [Eff] extends [YieldWrap<Effect<infer _A, infer _E, infer R>>] ? R : never>;
|
||
<Eff extends YieldWrap<Effect<any, any, any>>, AEff, Args extends Array<any>, A>(body: (...args: Args) => Generator<Eff, AEff, never>, a: (_: Effect<AEff, [
|
||
Eff
|
||
] extends [never] ? never : [Eff] extends [YieldWrap<Effect<infer _A, infer E, infer _R>>] ? E : never, [
|
||
Eff
|
||
] extends [never] ? never : [Eff] extends [YieldWrap<Effect<infer _A, infer _E, infer R>>] ? R : never>, ...args: NoInfer<Args>) => A): (...args: Args) => A;
|
||
<Eff extends YieldWrap<Effect<any, any, any>>, AEff, Args extends Array<any>, A, B>(body: (...args: Args) => Generator<Eff, AEff, never>, a: (_: Effect<AEff, [
|
||
Eff
|
||
] extends [never] ? never : [Eff] extends [YieldWrap<Effect<infer _A, infer E, infer _R>>] ? E : never, [
|
||
Eff
|
||
] extends [never] ? never : [Eff] extends [YieldWrap<Effect<infer _A, infer _E, infer R>>] ? R : never>, ...args: NoInfer<Args>) => A, b: (_: A, ...args: NoInfer<Args>) => B): (...args: Args) => B;
|
||
<Eff extends YieldWrap<Effect<any, any, any>>, AEff, Args extends Array<any>, A, B, C>(body: (...args: Args) => Generator<Eff, AEff, never>, a: (_: Effect<AEff, [
|
||
Eff
|
||
] extends [never] ? never : [Eff] extends [YieldWrap<Effect<infer _A, infer E, infer _R>>] ? E : never, [
|
||
Eff
|
||
] extends [never] ? never : [Eff] extends [YieldWrap<Effect<infer _A, infer _E, infer R>>] ? R : never>, ...args: NoInfer<Args>) => A, b: (_: A, ...args: NoInfer<Args>) => B, c: (_: B, ...args: NoInfer<Args>) => C): (...args: Args) => C;
|
||
<Eff extends YieldWrap<Effect<any, any, any>>, AEff, Args extends Array<any>, A, B, C, D>(body: (...args: Args) => Generator<Eff, AEff, never>, a: (_: Effect<AEff, [
|
||
Eff
|
||
] extends [never] ? never : [Eff] extends [YieldWrap<Effect<infer _A, infer E, infer _R>>] ? E : never, [
|
||
Eff
|
||
] extends [never] ? never : [Eff] extends [YieldWrap<Effect<infer _A, infer _E, infer R>>] ? R : never>, ...args: NoInfer<Args>) => A, b: (_: A, ...args: NoInfer<Args>) => B, c: (_: B, ...args: NoInfer<Args>) => C, d: (_: C, ...args: NoInfer<Args>) => D): (...args: Args) => D;
|
||
<Eff extends YieldWrap<Effect<any, any, any>>, AEff, Args extends Array<any>, A, B, C, D, E>(body: (...args: Args) => Generator<Eff, AEff, never>, a: (_: Effect<AEff, [
|
||
Eff
|
||
] extends [never] ? never : [Eff] extends [YieldWrap<Effect<infer _A, infer E, infer _R>>] ? E : never, [
|
||
Eff
|
||
] extends [never] ? never : [Eff] extends [YieldWrap<Effect<infer _A, infer _E, infer R>>] ? R : never>, ...args: NoInfer<Args>) => A, b: (_: A, ...args: NoInfer<Args>) => B, c: (_: B, ...args: NoInfer<Args>) => C, d: (_: C, ...args: NoInfer<Args>) => D, e: (_: D, ...args: NoInfer<Args>) => E): (...args: Args) => E;
|
||
<Eff extends YieldWrap<Effect<any, any, any>>, AEff, Args extends Array<any>, A, B, C, D, E, F>(body: (...args: Args) => Generator<Eff, AEff, never>, a: (_: Effect<AEff, [
|
||
Eff
|
||
] extends [never] ? never : [Eff] extends [YieldWrap<Effect<infer _A, infer E, infer _R>>] ? E : never, [
|
||
Eff
|
||
] extends [never] ? never : [Eff] extends [YieldWrap<Effect<infer _A, infer _E, infer R>>] ? R : never>, ...args: NoInfer<Args>) => A, b: (_: A, ...args: NoInfer<Args>) => B, c: (_: B, ...args: NoInfer<Args>) => C, d: (_: C, ...args: NoInfer<Args>) => D, e: (_: D, ...args: NoInfer<Args>) => E, f: (_: E, ...args: NoInfer<Args>) => F): (...args: Args) => F;
|
||
<Eff extends YieldWrap<Effect<any, any, any>>, AEff, Args extends Array<any>, A, B, C, D, E, F, G>(body: (...args: Args) => Generator<Eff, AEff, never>, a: (_: Effect<AEff, [
|
||
Eff
|
||
] extends [never] ? never : [Eff] extends [YieldWrap<Effect<infer _A, infer E, infer _R>>] ? E : never, [
|
||
Eff
|
||
] extends [never] ? never : [Eff] extends [YieldWrap<Effect<infer _A, infer _E, infer R>>] ? R : never>, ...args: NoInfer<Args>) => A, b: (_: A, ...args: NoInfer<Args>) => B, c: (_: B, ...args: NoInfer<Args>) => C, d: (_: C, ...args: NoInfer<Args>) => D, e: (_: D, ...args: NoInfer<Args>) => E, f: (_: E, ...args: NoInfer<Args>) => F, g: (_: F, ...args: NoInfer<Args>) => G): (...args: Args) => G;
|
||
<Eff extends YieldWrap<Effect<any, any, any>>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H>(body: (...args: Args) => Generator<Eff, AEff, never>, a: (_: Effect<AEff, [
|
||
Eff
|
||
] extends [never] ? never : [Eff] extends [YieldWrap<Effect<infer _A, infer E, infer _R>>] ? E : never, [
|
||
Eff
|
||
] extends [never] ? never : [Eff] extends [YieldWrap<Effect<infer _A, infer _E, infer R>>] ? R : never>, ...args: NoInfer<Args>) => A, b: (_: A, ...args: NoInfer<Args>) => B, c: (_: B, ...args: NoInfer<Args>) => C, d: (_: C, ...args: NoInfer<Args>) => D, e: (_: D, ...args: NoInfer<Args>) => E, f: (_: E, ...args: NoInfer<Args>) => F, g: (_: F, ...args: NoInfer<Args>) => G, h: (_: G, ...args: NoInfer<Args>) => H): (...args: Args) => H;
|
||
<Eff extends YieldWrap<Effect<any, any, any>>, AEff, Args extends Array<any>, A, B, C, D, E, F, G, H, I>(body: (...args: Args) => Generator<Eff, AEff, never>, a: (_: Effect<AEff, [
|
||
Eff
|
||
] extends [never] ? never : [Eff] extends [YieldWrap<Effect<infer _A, infer E, infer _R>>] ? E : never, [
|
||
Eff
|
||
] extends [never] ? never : [Eff] extends [YieldWrap<Effect<infer _A, infer _E, infer R>>] ? R : never>, ...args: NoInfer<Args>) => A, b: (_: A, ...args: NoInfer<Args>) => B, c: (_: B, ...args: NoInfer<Args>) => C, d: (_: C, ...args: NoInfer<Args>) => D, e: (_: D, ...args: NoInfer<Args>) => E, f: (_: E, ...args: NoInfer<Args>) => F, g: (_: F, ...args: NoInfer<Args>) => G, h: (_: G, ...args: NoInfer<Args>) => H, i: (_: H, ...args: NoInfer<Args>) => I): (...args: Args) => I;
|
||
};
|
||
}
|
||
/**
|
||
* The `Effect.fn` function allows you to create traced functions that return an
|
||
* effect. It provides two key features:
|
||
*
|
||
* - **Stack traces with location details** if an error occurs.
|
||
* - **Automatic span creation** for tracing when a span name is provided.
|
||
*
|
||
* If a span name is passed as the first argument, the function's execution is
|
||
* tracked using that name. If no name is provided, stack tracing still works,
|
||
* but spans are not created.
|
||
*
|
||
* A function can be defined using either:
|
||
*
|
||
* - A generator function, allowing the use of `yield*` for effect composition.
|
||
* - A regular function that returns an `Effect`.
|
||
*
|
||
* **Example** (Creating a Traced Function with a Span Name)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const myfunc = Effect.fn("myspan")(function* <N extends number>(n: N) {
|
||
* yield* Effect.annotateCurrentSpan("n", n) // Attach metadata to the span
|
||
* console.log(`got: ${n}`)
|
||
* yield* Effect.fail(new Error("Boom!")) // Simulate failure
|
||
* })
|
||
*
|
||
* Effect.runFork(myfunc(100).pipe(Effect.catchAllCause(Effect.logError)))
|
||
* // Output:
|
||
* // got: 100
|
||
* // timestamp=... level=ERROR fiber=#0 cause="Error: Boom!
|
||
* // at <anonymous> (/.../index.ts:6:22) <= Raise location
|
||
* // at myspan (/.../index.ts:3:23) <= Definition location
|
||
* // at myspan (/.../index.ts:9:16)" <= Call location
|
||
* ```
|
||
*
|
||
* `Effect.fn` automatically creates spans. The spans capture information about
|
||
* the function execution, including metadata and error details.
|
||
*
|
||
* **Example** (Exporting Spans to the Console)
|
||
*
|
||
* ```ts skip-type-checking
|
||
* import { Effect } from "effect"
|
||
* import { NodeSdk } from "@effect/opentelemetry"
|
||
* import {
|
||
* ConsoleSpanExporter,
|
||
* BatchSpanProcessor
|
||
* } from "@opentelemetry/sdk-trace-base"
|
||
*
|
||
* const myfunc = Effect.fn("myspan")(function* <N extends number>(n: N) {
|
||
* yield* Effect.annotateCurrentSpan("n", n)
|
||
* console.log(`got: ${n}`)
|
||
* yield* Effect.fail(new Error("Boom!"))
|
||
* })
|
||
*
|
||
* const program = myfunc(100)
|
||
*
|
||
* const NodeSdkLive = NodeSdk.layer(() => ({
|
||
* resource: { serviceName: "example" },
|
||
* // Export span data to the console
|
||
* spanProcessor: new BatchSpanProcessor(new ConsoleSpanExporter())
|
||
* }))
|
||
*
|
||
* Effect.runFork(program.pipe(Effect.provide(NodeSdkLive)))
|
||
* // Output:
|
||
* // got: 100
|
||
* // {
|
||
* // resource: {
|
||
* // attributes: {
|
||
* // 'service.name': 'example',
|
||
* // 'telemetry.sdk.language': 'nodejs',
|
||
* // 'telemetry.sdk.name': '@effect/opentelemetry',
|
||
* // 'telemetry.sdk.version': '1.30.1'
|
||
* // }
|
||
* // },
|
||
* // instrumentationScope: { name: 'example', version: undefined, schemaUrl: undefined },
|
||
* // traceId: '22801570119e57a6e2aacda3dec9665b',
|
||
* // parentId: undefined,
|
||
* // traceState: undefined,
|
||
* // name: 'myspan',
|
||
* // id: '7af530c1e01bc0cb',
|
||
* // kind: 0,
|
||
* // timestamp: 1741182277518402.2,
|
||
* // duration: 4300.416,
|
||
* // attributes: {
|
||
* // n: 100,
|
||
* // 'code.stacktrace': 'at <anonymous> (/.../index.ts:8:23)\n' +
|
||
* // 'at <anonymous> (/.../index.ts:14:17)'
|
||
* // },
|
||
* // status: { code: 2, message: 'Boom!' },
|
||
* // events: [
|
||
* // {
|
||
* // name: 'exception',
|
||
* // attributes: {
|
||
* // 'exception.type': 'Error',
|
||
* // 'exception.message': 'Boom!',
|
||
* // 'exception.stacktrace': 'Error: Boom!\n' +
|
||
* // ' at <anonymous> (/.../index.ts:11:22)\n' +
|
||
* // ' at myspan (/.../index.ts:8:23)\n' +
|
||
* // ' at myspan (/.../index.ts:14:17)'
|
||
* // },
|
||
* // time: [ 1741182277, 522702583 ],
|
||
* // droppedAttributesCount: 0
|
||
* // }
|
||
* // ],
|
||
* // links: []
|
||
* // }
|
||
* ```
|
||
*
|
||
* `Effect.fn` also acts as a pipe function, allowing you to create a pipeline
|
||
* after the function definition using the effect returned by the generator
|
||
* function as the starting value of the pipeline.
|
||
*
|
||
* **Example** (Creating a Traced Function with a Delay)
|
||
*
|
||
* ```ts
|
||
* import { Effect } from "effect"
|
||
*
|
||
* const myfunc = Effect.fn(
|
||
* function* (n: number) {
|
||
* console.log(`got: ${n}`)
|
||
* yield* Effect.fail(new Error("Boom!"))
|
||
* },
|
||
* // You can access both the created effect and the original arguments
|
||
* (effect, n) => Effect.delay(effect, `${n / 100} seconds`)
|
||
* )
|
||
*
|
||
* Effect.runFork(myfunc(100).pipe(Effect.catchAllCause(Effect.logError)))
|
||
* // Output:
|
||
* // got: 100
|
||
* // timestamp=... level=ERROR fiber=#0 cause="Error: Boom! (<= after 1 second)
|
||
* ```
|
||
*
|
||
* @see {@link fnUntraced} for a version of this function that doesn't add a span.
|
||
*
|
||
* @since 3.11.0
|
||
* @category Tracing
|
||
*/
|
||
export declare const fn: fn.Gen & fn.NonGen & ((name: string, options?: Tracer.SpanOptions) => fn.Gen & fn.NonGen);
|
||
/**
|
||
* Same as {@link fn}, but allows you to create a function that is not traced, for when performance is critical.
|
||
*
|
||
* @see {@link fn} for a version that includes tracing.
|
||
*
|
||
* @since 3.12.0
|
||
* @category Tracing
|
||
*/
|
||
export declare const fnUntraced: fn.Untraced;
|
||
/**
|
||
* A no-op type constraint that enforces the success channel of an Effect conforms to
|
||
* the specified success type `A`.
|
||
*
|
||
* @example
|
||
* import { Effect } from "effect"
|
||
*
|
||
* // Ensure that the program does not expose any unhandled errors.
|
||
* const program = Effect.succeed(42).pipe(Effect.ensureSuccessType<number>())
|
||
*
|
||
* @since 3.17.0
|
||
* @category Type constraints
|
||
*/
|
||
export declare const ensureSuccessType: <A>() => <A2 extends A, E, R>(effect: Effect<A2, E, R>) => Effect<A2, E, R>;
|
||
/**
|
||
* A no-op type constraint that enforces the error channel of an Effect conforms to
|
||
* the specified error type `E`.
|
||
*
|
||
* @example
|
||
* import { Effect } from "effect"
|
||
*
|
||
* // Ensure that the program does not expose any unhandled errors.
|
||
* const program = Effect.succeed(42).pipe(Effect.ensureErrorType<never>())
|
||
*
|
||
* @since 3.17.0
|
||
* @category Type constraints
|
||
*/
|
||
export declare const ensureErrorType: <E>() => <A, E2 extends E, R>(effect: Effect<A, E2, R>) => Effect<A, E2, R>;
|
||
/**
|
||
* A no-op type constraint that enforces the requirements channel of an Effect conforms to
|
||
* the specified requirements type `R`.
|
||
*
|
||
* @example
|
||
* import { Effect } from "effect"
|
||
*
|
||
* // Ensure that the program does not have any requirements.
|
||
* const program = Effect.succeed(42).pipe(Effect.ensureRequirementsType<never>())
|
||
*
|
||
* @since 3.17.0
|
||
* @category Type constraints
|
||
*/
|
||
export declare const ensureRequirementsType: <R>() => <A, E, R2 extends R>(effect: Effect<A, E, R2>) => Effect<A, E, R2>;
|
||
//# sourceMappingURL=Effect.d.ts.map
|