<A, E, R>(effect: Effect<A, E, R>): Effect<A, E, Exclude<R, Transaction>>Defines a transaction boundary. Transactions are "all or nothing" with respect to changes made to transactional values (i.e. TxRef) that occur within the transaction body.
Details
If called inside an active transaction, tx composes with the current transaction and reuses
its journal and retry state instead of creating a nested boundary.
Effect transactions are optimistic with retry. A transaction is retried when
its body explicitly calls Effect.txRetry and any accessed transactional
value changes, or when any accessed transactional value changes because a
different transaction commits before the current one.
The outermost tx call creates the transaction boundary and commits or rolls back the full
composed transaction.
Example (Running a transaction)
import { Effect, TxRef } from "effect"
const program = Effect.gen(function*() {
const ref1 = yield* TxRef.make(0)
const ref2 = yield* TxRef.make(0)
// Nested tx calls compose into the same transaction
yield* Effect.tx(Effect.gen(function*() {
yield* TxRef.set(ref1, 10)
yield* Effect.tx(TxRef.set(ref2, 20))
const sum = (yield* TxRef.get(ref1)) + (yield* TxRef.get(ref2))
console.log(`Transaction sum: ${sum}`)
}))
console.log(`Final ref1: ${yield* TxRef.get(ref1)}`) // 10
console.log(`Final ref2: ${yield* TxRef.get(ref2)}`) // 20
})export const const tx: <A, E, R>(
effect: Effect<A, E, R>
) => Effect<A, E, Exclude<R, Transaction>>
Defines a transaction boundary. Transactions are "all or nothing" with respect to changes
made to transactional values (i.e. TxRef) that occur within the transaction body.
Details
If called inside an active transaction, tx composes with the current transaction and reuses
its journal and retry state instead of creating a nested boundary.
Effect transactions are optimistic with retry. A transaction is retried when
its body explicitly calls Effect.txRetry and any accessed transactional
value changes, or when any accessed transactional value changes because a
different transaction commits before the current one.
The outermost tx call creates the transaction boundary and commits or rolls back the full
composed transaction.
Example (Running a transaction)
import { Effect, TxRef } from "effect"
const program = Effect.gen(function*() {
const ref1 = yield* TxRef.make(0)
const ref2 = yield* TxRef.make(0)
// Nested tx calls compose into the same transaction
yield* Effect.tx(Effect.gen(function*() {
yield* TxRef.set(ref1, 10)
yield* Effect.tx(TxRef.set(ref2, 20))
const sum = (yield* TxRef.get(ref1)) + (yield* TxRef.get(ref2))
console.log(`Transaction sum: ${sum}`)
}))
console.log(`Final ref1: ${yield* TxRef.get(ref1)}`) // 10
console.log(`Final ref2: ${yield* TxRef.get(ref2)}`) // 20
})
tx = <function (type parameter) A in <A, E, R>(effect: Effect<A, E, R>): Effect<A, E, Exclude<R, Transaction>>A, function (type parameter) E in <A, E, R>(effect: Effect<A, E, R>): Effect<A, E, Exclude<R, Transaction>>E, function (type parameter) R in <A, E, R>(effect: Effect<A, E, R>): Effect<A, E, Exclude<R, Transaction>>R>(
effect: Effect<A, E, R>(parameter) effect: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
effect: interface Effect<out A, out E = never, out R = never>The Effect interface defines a value that lazily describes a workflow or
job. The workflow requires some context R, and may fail with an error of
type E, or succeed with a value of type A.
When to use
Use when you need to represent a lazy, composable workflow that can require
services, fail with a typed error, or succeed with a typed value.
Details
Effect values model resourceful interaction with the outside world,
including synchronous, asynchronous, concurrent, and parallel interaction.
They use a fiber-based concurrency model, with built-in support for
scheduling, fine-grained interruption, structured concurrency, and high
scalability.
To run an Effect value, you need a Runtime, which is a type that is
capable of executing Effect values.
Effect<function (type parameter) A in <A, E, R>(effect: Effect<A, E, R>): Effect<A, E, Exclude<R, Transaction>>A, function (type parameter) E in <A, E, R>(effect: Effect<A, E, R>): Effect<A, E, Exclude<R, Transaction>>E, function (type parameter) R in <A, E, R>(effect: Effect<A, E, R>): Effect<A, E, Exclude<R, Transaction>>R>
): interface Effect<out A, out E = never, out R = never>The Effect interface defines a value that lazily describes a workflow or
job. The workflow requires some context R, and may fail with an error of
type E, or succeed with a value of type A.
When to use
Use when you need to represent a lazy, composable workflow that can require
services, fail with a typed error, or succeed with a typed value.
Details
Effect values model resourceful interaction with the outside world,
including synchronous, asynchronous, concurrent, and parallel interaction.
They use a fiber-based concurrency model, with built-in support for
scheduling, fine-grained interruption, structured concurrency, and high
scalability.
To run an Effect value, you need a Runtime, which is a type that is
capable of executing Effect values.
Effect<function (type parameter) A in <A, E, R>(effect: Effect<A, E, R>): Effect<A, E, Exclude<R, Transaction>>A, function (type parameter) E in <A, E, R>(effect: Effect<A, E, R>): Effect<A, E, Exclude<R, Transaction>>E, type Exclude<T, U> = T extends U
? never
: T
Exclude from T those types that are assignable to U
Exclude<function (type parameter) R in <A, E, R>(effect: Effect<A, E, R>): Effect<A, E, Exclude<R, Transaction>>R, class Transactionclass Transaction {
key: Identifier;
Service: {
retry: boolean;
journal: Map<TxRef<any>, { readonly version: number; value: any }>;
};
}
Service that holds the current transaction state.
Details
It includes a journal that stores non-committed changes to TxRef values and
a retry flag that records whether the transaction should be retried.
Example (Building transactions)
import { Effect } from "effect"
// Transaction class for software transactional memory operations
const txEffect = Effect.gen(function*() {
const tx = yield* Effect.Transaction
// Use transaction for coordinated state changes
return "Transaction complete"
})
Transaction>> =>
const withFiber: <
A,
E = never,
R = never
>(
evaluate: (
fiber: Fiber<unknown, unknown>
) => Effect<A, E, R>
) => Effect<A, E, R>
Provides access to the current fiber within an effect computation.
Example (Reading the current fiber)
import { Effect } from "effect"
const program = Effect.withFiber((fiber) =>
Effect.succeed(`Fiber ID: ${fiber.id}`)
)
Effect.runPromise(program).then(console.log)
// Output: Fiber ID: 1
withFiber((fiber: Fiber<unknown, unknown>(parameter) fiber: {
id: number;
currentOpCount: number;
getRef: <A>(ref: Context.Reference<A>) => A;
context: Context.Context<never>;
setContext: (context: Context.Context<never>) => void;
currentScheduler: Scheduler;
currentDispatcher: SchedulerDispatcher;
currentSpan: AnySpan | undefined;
currentLogLevel: LogLevel;
minimumLogLevel: LogLevel;
currentStackFrame: StackFrame | undefined;
maxOpsBeforeYield: number;
currentPreventYield: boolean;
addObserver: (cb: (exit: Exit<A, E>) => void) => () => void;
interruptUnsafe: (fiberId?: number | undefined, annotations?: Context.Context<never> | undefined) => void;
pollUnsafe: () => Exit<A, E> | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
fiber) => {
if (fiber: Fiber<unknown, unknown>(parameter) fiber: {
id: number;
currentOpCount: number;
getRef: <A>(ref: Context.Reference<A>) => A;
context: Context.Context<never>;
setContext: (context: Context.Context<never>) => void;
currentScheduler: Scheduler;
currentDispatcher: SchedulerDispatcher;
currentSpan: AnySpan | undefined;
currentLogLevel: LogLevel;
minimumLogLevel: LogLevel;
currentStackFrame: StackFrame | undefined;
maxOpsBeforeYield: number;
currentPreventYield: boolean;
addObserver: (cb: (exit: Exit<A, E>) => void) => () => void;
interruptUnsafe: (fiberId?: number | undefined, annotations?: Context.Context<never> | undefined) => void;
pollUnsafe: () => Exit<A, E> | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
fiber.Fiber<out A, out E = never>.context: Context.Context<never>(property) Fiber<out A, out E = never>.context: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
context.mapUnsafe.has(class Transactionclass Transaction {
key: Identifier;
Service: {
retry: boolean;
journal: Map<TxRef<any>, { readonly version: number; value: any }>;
};
of: (this: void, self: { retry: boolean; readonly journal: Map<TxRef<any>, { readonly version: number; value: any }> }) => { retry: boolean; readonly journal: Map<TxRef<any>, { readonly version: number; value: any }> };
context: (self: { retry: boolean; readonly journal: Map<TxRef<any>, { readonly version: number; value: any }> }) => Context.Context<Transaction>;
use: (f: (service: { retry: boolean; readonly journal: Map<TxRef<any>, { readonly version: number; value: any }> }) => Effect<A, E, R>) => Effect<A, E, Transaction | R>;
useSync: (f: (service: { retry: boolean; readonly journal: Map<TxRef<any>, { readonly version: number; value: any }> }) => A) => Effect<A, never, Transaction>;
Identifier: Identifier;
stack: string | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
Service that holds the current transaction state.
Details
It includes a journal that stores non-committed changes to TxRef values and
a retry flag that records whether the transaction should be retried.
Example (Building transactions)
import { Effect } from "effect"
// Transaction class for software transactional memory operations
const txEffect = Effect.gen(function*() {
const tx = yield* Effect.Transaction
// Use transaction for coordinated state changes
return "Transaction complete"
})
Transaction.key)) {
return effect: Effect<A, E, R>(parameter) effect: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
effect as interface Effect<out A, out E = never, out R = never>The Effect interface defines a value that lazily describes a workflow or
job. The workflow requires some context R, and may fail with an error of
type E, or succeed with a value of type A.
When to use
Use when you need to represent a lazy, composable workflow that can require
services, fail with a typed error, or succeed with a typed value.
Details
Effect values model resourceful interaction with the outside world,
including synchronous, asynchronous, concurrent, and parallel interaction.
They use a fiber-based concurrency model, with built-in support for
scheduling, fine-grained interruption, structured concurrency, and high
scalability.
To run an Effect value, you need a Runtime, which is a type that is
capable of executing Effect values.
Effect<function (type parameter) A in <A, E, R>(effect: Effect<A, E, R>): Effect<A, E, Exclude<R, Transaction>>A, function (type parameter) E in <A, E, R>(effect: Effect<A, E, R>): Effect<A, E, Exclude<R, Transaction>>E, type Exclude<T, U> = T extends U
? never
: T
Exclude from T those types that are assignable to U
Exclude<function (type parameter) R in <A, E, R>(effect: Effect<A, E, R>): Effect<A, E, Exclude<R, Transaction>>R, class Transactionclass Transaction {
key: Identifier;
Service: {
retry: boolean;
journal: Map<TxRef<any>, { readonly version: number; value: any }>;
};
}
Service that holds the current transaction state.
Details
It includes a journal that stores non-committed changes to TxRef values and
a retry flag that records whether the transaction should be retried.
Example (Building transactions)
import { Effect } from "effect"
// Transaction class for software transactional memory operations
const txEffect = Effect.gen(function*() {
const tx = yield* Effect.Transaction
// Use transaction for coordinated state changes
return "Transaction complete"
})
Transaction>>
}
// Create transaction state only at the outermost boundary
const const state: Transaction["Service"]const state: {
retry: boolean;
journal: Map<TxRef<any>, { readonly version: number; value: any }>;
}
state: class Transactionclass Transaction {
key: Identifier;
Service: {
retry: boolean;
journal: Map<TxRef<any>, { readonly version: number; value: any }>;
};
}
Service that holds the current transaction state.
Details
It includes a journal that stores non-committed changes to TxRef values and
a retry flag that records whether the transaction should be retried.
Example (Building transactions)
import { Effect } from "effect"
// Transaction class for software transactional memory operations
const txEffect = Effect.gen(function*() {
const tx = yield* Effect.Transaction
// Use transaction for coordinated state changes
return "Transaction complete"
})
Transaction["Service"] = { journal: Map<any, any>journal: new var Map: MapConstructor
new () => Map<any, any> (+3 overloads)
Map(), retry: booleanretry: false }
let let result: Exit.Exit<A, E> | undefinedresult: import ExitExit.type Exit<A, E = never> = Exit.Success<A, E> | Exit.Failure<A, E>Represents the result of an Effect computation.
When to use
Use when you need to synchronously inspect whether an Effect computation
succeeded or failed.
Details
An Exit<A, E> is either Success<A, E> containing a value of type A, or
Failure<A, E> containing a Cause<E> describing why the computation
failed.
Since Exit is also an Effect, you can yield it inside Effect.gen.
Example (Pattern matching on an Exit)
import { Exit } from "effect"
const success: Exit.Exit<number> = Exit.succeed(42)
const failure: Exit.Exit<number, string> = Exit.fail("error")
const result = Exit.match(success, {
onSuccess: (value) => `Got value: ${value}`,
onFailure: (cause) => `Got error: ${cause}`
})
Namespace containing helper types shared by Exit values.
When to use
Use to reference helper types that describe the shared structure of Exit
values.
Exit<function (type parameter) A in <A, E, R>(effect: Effect<A, E, R>): Effect<A, E, Exclude<R, Transaction>>A, function (type parameter) E in <A, E, R>(effect: Effect<A, E, R>): Effect<A, E, Exclude<R, Transaction>>E> | undefined
return 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>
Disables interruption and provides a restore function to restore the
interruptible state within the effect.
Example (Restoring interruption in protected regions)
import { Console, Effect } from "effect"
const program = Effect.uninterruptibleMask((restore) =>
Effect.gen(function*() {
yield* Console.log("Uninterruptible phase...")
yield* Effect.sleep("1 second")
// Restore interruptibility for this part
yield* restore(
Effect.gen(function*() {
yield* Console.log("Interruptible phase...")
yield* Effect.sleep("2 seconds")
})
)
yield* Console.log("Back to uninterruptible")
})
)
uninterruptibleMask((restore: <AX, EX, RX>(
effect: Effect<AX, EX, RX>
) => Effect<AX, EX, RX>
restore) =>
const flatMap: {
<A, B, E1, R1>(
f: (a: A) => Effect<B, E1, R1>
): <E, R>(
self: Effect<A, E, R>
) => Effect<B, E1 | E, R1 | R>
<A, E, R, B, E1, R1>(
self: Effect<A, E, R>,
f: (a: A) => Effect<B, E1, R1>
): Effect<B, E | E1, R | R1>
}
flatMap(
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>
Executes a body effect repeatedly while a condition holds true.
Example (Repeating an effectful loop)
import { Effect } from "effect"
let counter = 0
const program = Effect.whileLoop({
while: () => counter < 5,
body: () => Effect.sync(() => ++counter),
step: (n) => console.log(`Current count: ${n}`)
})
Effect.runPromise(program)
// Output:
// Current count: 1
// Current count: 2
// Current count: 3
// Current count: 4
// Current count: 5
whileLoop({
while: LazyArg<boolean>while: () => !let result: Exit.Exit<A, E> | undefinedresult,
body: LazyArg<
Effect<
Exit.Exit<A, E>,
never,
Exclude<R, Transaction>
>
>
body: constant<A>(value: A): LazyArg<A>Creates a zero-argument function that always returns the provided value.
When to use
Use when you need a thunk or callback that returns the same value on every
invocation.
Example (Creating a constant thunk)
import { Function } from "effect"
import * as assert from "node:assert"
const constNull = Function.constant(null)
assert.deepStrictEqual(constNull(), null)
assert.deepStrictEqual(constNull(), null)
constant(
restore: <AX, EX, RX>(
effect: Effect<AX, EX, RX>
) => Effect<AX, EX, RX>
restore(effect: Effect<A, E, R>(parameter) effect: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
effect).Pipeable.pipe<Effect<A, E, R>, Effect<A, E, Exclude<R, unknown>>, Effect<A, E, Exclude<R, unknown>>, Effect<Exit.Exit<A, E>, never, Exclude<R, unknown>>>(this: Effect<...>, ab: (_: Effect<A, E, R>) => Effect<A, E, Exclude<R, unknown>>, bc: (_: Effect<A, E, Exclude<R, unknown>>) => Effect<A, E, Exclude<R, unknown>>, cd: (_: Effect<A, E, Exclude<R, unknown>>) => Effect<Exit.Exit<A, E>, never, Exclude<...>>): Effect<...> (+21 overloads)pipe(
const provideService: {
<I, S>(service: Context.Key<I, S>): {
(implementation: S): <A, E, R>(
self: Effect<A, E, R>
) => Effect<A, E, Exclude<R, I>>
<A, E, R>(
self: Effect<A, E, R>,
implementation: S
): Effect<A, E, Exclude<R, I>>
}
<I, S>(
service: Context.Key<I, S>,
implementation: S
): <A, E, R>(
self: Effect<A, E, R>
) => Effect<A, E, Exclude<R, I>>
<A, E, R, I, S>(
self: Effect<A, E, R>,
service: Context.Key<I, S>,
implementation: S
): Effect<A, E, Exclude<R, I>>
}
provideService(class Transactionclass Transaction {
key: Identifier;
Service: {
retry: boolean;
journal: Map<TxRef<any>, { readonly version: number; value: any }>;
};
of: (this: void, self: { retry: boolean; readonly journal: Map<TxRef<any>, { readonly version: number; value: any }> }) => { retry: boolean; readonly journal: Map<TxRef<any>, { readonly version: number; value: any }> };
context: (self: { retry: boolean; readonly journal: Map<TxRef<any>, { readonly version: number; value: any }> }) => Context.Context<Transaction>;
use: (f: (service: { retry: boolean; readonly journal: Map<TxRef<any>, { readonly version: number; value: any }> }) => Effect<A, E, R>) => Effect<A, E, Transaction | R>;
useSync: (f: (service: { retry: boolean; readonly journal: Map<TxRef<any>, { readonly version: number; value: any }> }) => A) => Effect<A, never, Transaction>;
Identifier: Identifier;
stack: string | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
Service that holds the current transaction state.
Details
It includes a journal that stores non-committed changes to TxRef values and
a retry flag that records whether the transaction should be retried.
Example (Building transactions)
import { Effect } from "effect"
// Transaction class for software transactional memory operations
const txEffect = Effect.gen(function*() {
const tx = yield* Effect.Transaction
// Use transaction for coordinated state changes
return "Transaction complete"
})
Transaction, const state: Transaction["Service"]const state: {
retry: boolean;
journal: Map<TxRef<any>, { readonly version: number; value: any }>;
}
state),
const tapCause: {
<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>
<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>
}
tapCause(() => {
if (!const state: Transaction["Service"]const state: {
retry: boolean;
journal: Map<TxRef<any>, { readonly version: number; value: any }>;
}
state.retry) return const void_: Effect<void>const void_: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
void_
return restore: <AX, EX, RX>(
effect: Effect<AX, EX, RX>
) => Effect<AX, EX, RX>
restore(const awaitPendingTransaction: (
state: Transaction["Service"]
) => Effect<void, never, never>
awaitPendingTransaction(const state: Transaction["Service"]const state: {
retry: boolean;
journal: Map<TxRef<any>, { readonly version: number; value: any }>;
}
state))
}),
const exit: <A, E, R>(
self: Effect<A, E, R>
) => Effect<Exit.Exit<A, E>, never, R>
Transforms an effect to encapsulate both failure and success using the Exit
data type.
When to use
Use when you need to inspect the full outcome, including typed failures, defects,
and interruptions.
Details
exit wraps an effect's success or failure inside an Exit type, allowing
you to handle both cases explicitly.
The resulting effect cannot fail because the failure is encapsulated within
the Exit.Failure type. The error type is set to never, indicating that
the effect is structured to never fail directly.
Example (Capturing completion as Exit)
import { Effect } from "effect"
const success = Effect.succeed(42)
const failure = Effect.fail("Something went wrong")
const program1 = Effect.exit(success)
const program2 = Effect.exit(failure)
Effect.runPromise(program1).then(console.log)
// { _id: 'Exit', _tag: 'Success', value: 42 }
Effect.runPromise(program2).then(console.log)
// { _id: 'Exit', _tag: 'Failure', cause: { _id: 'Cause', _tag: 'Fail', failure: 'Something went wrong' } }
exit
)
),
step: (exit: Exit.Exit<A, E>) => voidstep(exit: Exit.Exit<A, E>exit: import ExitExit.type Exit<A, E = never> = Exit.Success<A, E> | Exit.Failure<A, E>Represents the result of an Effect computation.
When to use
Use when you need to synchronously inspect whether an Effect computation
succeeded or failed.
Details
An Exit<A, E> is either Success<A, E> containing a value of type A, or
Failure<A, E> containing a Cause<E> describing why the computation
failed.
Since Exit is also an Effect, you can yield it inside Effect.gen.
Example (Pattern matching on an Exit)
import { Exit } from "effect"
const success: Exit.Exit<number> = Exit.succeed(42)
const failure: Exit.Exit<number, string> = Exit.fail("error")
const result = Exit.match(success, {
onSuccess: (value) => `Got value: ${value}`,
onFailure: (cause) => `Got error: ${cause}`
})
Namespace containing helper types shared by Exit values.
When to use
Use to reference helper types that describe the shared structure of Exit
values.
Exit<function (type parameter) A in <A, E, R>(effect: Effect<A, E, R>): Effect<A, E, Exclude<R, Transaction>>A, function (type parameter) E in <A, E, R>(effect: Effect<A, E, R>): Effect<A, E, Exclude<R, Transaction>>E>) {
if (const state: Transaction["Service"]const state: {
retry: boolean;
journal: Map<TxRef<any>, { readonly version: number; value: any }>;
}
state.retry || !const isTransactionConsistent: (
state: Transaction["Service"]
) => boolean
isTransactionConsistent(const state: Transaction["Service"]const state: {
retry: boolean;
journal: Map<TxRef<any>, { readonly version: number; value: any }>;
}
state)) {
return function clearTransaction(
state: Transaction["Service"]
): void
clearTransaction(const state: Transaction["Service"]const state: {
retry: boolean;
journal: Map<TxRef<any>, { readonly version: number; value: any }>;
}
state)
}
if (import ExitExit.const isSuccess: <A, E>(
self: Exit<A, E>
) => self is Success<A, E>
Checks whether an Exit is a Success.
When to use
Use as a type guard to narrow Exit<A, E> to Success<A, E> and access the
value property.
Example (Narrowing to success)
import { Exit } from "effect"
const exit = Exit.succeed(42)
if (Exit.isSuccess(exit)) {
console.log(exit.value) // 42
}
isSuccess(exit: Exit.Exit<A, E>exit)) {
function commitTransaction(
fiber: Fiber<unknown, unknown>,
state: Transaction["Service"]
): void
commitTransaction(fiber: Fiber<unknown, unknown>(parameter) fiber: {
id: number;
currentOpCount: number;
getRef: <A>(ref: Context.Reference<A>) => A;
context: Context.Context<never>;
setContext: (context: Context.Context<never>) => void;
currentScheduler: Scheduler;
currentDispatcher: SchedulerDispatcher;
currentSpan: AnySpan | undefined;
currentLogLevel: LogLevel;
minimumLogLevel: LogLevel;
currentStackFrame: StackFrame | undefined;
maxOpsBeforeYield: number;
currentPreventYield: boolean;
addObserver: (cb: (exit: Exit<A, E>) => void) => () => void;
interruptUnsafe: (fiberId?: number | undefined, annotations?: Context.Context<never> | undefined) => void;
pollUnsafe: () => Exit<A, E> | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
fiber, const state: Transaction["Service"]const state: {
retry: boolean;
journal: Map<TxRef<any>, { readonly version: number; value: any }>;
}
state)
} else {
function clearTransaction(
state: Transaction["Service"]
): void
clearTransaction(const state: Transaction["Service"]const state: {
retry: boolean;
journal: Map<TxRef<any>, { readonly version: number; value: any }>;
}
state)
}
let result: Exit.Exit<A, E> | undefinedresult = exit: Exit.Exit<A, E>exit
}
}),
() => let result: Exit.Exit<A, E> | undefinedresult!
)
)
})