<A, E>(self: TxDeferred<A, E>): Effect.Effect<A, E>Reads the deferred value. Retries the transaction if the deferred has not been completed yet.
Example (Awaiting a deferred value)
import { Effect, TxDeferred } from "effect"
const program = Effect.gen(function*() {
const deferred = yield* TxDeferred.make<number>()
yield* TxDeferred.succeed(deferred, 42)
const value = yield* TxDeferred.await(deferred)
console.log(value) // 42
})const const await_: <A, E>(
self: TxDeferred<A, E>
) => Effect.Effect<A, E>
Reads the deferred value. Retries the transaction if the deferred has not
been completed yet.
Example (Awaiting a deferred value)
import { Effect, TxDeferred } from "effect"
const program = Effect.gen(function*() {
const deferred = yield* TxDeferred.make<number>()
yield* TxDeferred.succeed(deferred, 42)
const value = yield* TxDeferred.await(deferred)
console.log(value) // 42
})
await_ = <function (type parameter) A in <A, E>(self: TxDeferred<A, E>): Effect.Effect<A, E>A, function (type parameter) E in <A, E>(self: TxDeferred<A, E>): Effect.Effect<A, E>E>(self: TxDeferred<A, E>(parameter) self: {
ref: TxRef.TxRef<Option<Result<A, E>>>;
toString: () => string;
toJSON: () => unknown;
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; <…;
}
self: interface TxDeferred<in out A, in out E = never>A transactional deferred is a write-once cell readable within transactions.
Readers block (retry the transaction) until a value is committed, and writers
succeed only on the first call; subsequent writes return false.
When to use
Use to coordinate transaction-local readers and one-time completion with a
success or failure result.
Example (Completing a transactional deferred)
import { Effect, TxDeferred } from "effect"
const program = Effect.gen(function*() {
const deferred = yield* TxDeferred.make<number>()
// Complete the deferred
const first = yield* TxDeferred.succeed(deferred, 42)
console.log(first) // true
// Second write is a no-op
const second = yield* TxDeferred.succeed(deferred, 99)
console.log(second) // false
// Read the value
const value = yield* TxDeferred.await(deferred)
console.log(value) // 42
})
TxDeferred<function (type parameter) A in <A, E>(self: TxDeferred<A, E>): Effect.Effect<A, E>A, function (type parameter) E in <A, E>(self: TxDeferred<A, E>): Effect.Effect<A, E>E>): import EffectEffect.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>(self: TxDeferred<A, E>): Effect.Effect<A, E>A, function (type parameter) E in <A, E>(self: TxDeferred<A, E>): Effect.Effect<A, E>E> =>
import EffectEffect.const gen: {
<Eff extends Effect<any, any, any>, AEff>(
f: () => Generator<Eff, AEff, never>
): Effect<
AEff,
[Eff] extends [never]
? never
: [Eff] extends [
Effect<infer _A, infer E, infer _R>
]
? E
: never,
[Eff] extends [never]
? never
: [Eff] extends [
Effect<infer _A, infer _E, infer R>
]
? R
: never
>
<Self, Eff extends Effect<any, any, any>, AEff>(
options: { readonly self: Self },
f: (this: Self) => Generator<Eff, AEff, never>
): Effect<
AEff,
[Eff] extends [never]
? never
: [Eff] extends [
Effect<infer _A, infer E, infer _R>
]
? E
: never,
[Eff] extends [never]
? never
: [Eff] extends [
Effect<infer _A, infer _E, infer R>
]
? R
: never
>
}
gen(function*() {
const const option: Option<Result<A, E>>option = yield* import TxRefTxRef.const get: <A>(
self: TxRef<A>
) => Effect.Effect<A>
Reads the current value of the TxRef.
When to use
Use to read the current value of a TxRef.
Example (Reading transactional references)
import { Effect, TxRef } from "effect"
const program = Effect.gen(function*() {
const counter = yield* TxRef.make(42)
// Read the value within a transaction
const value = yield* Effect.tx(
TxRef.get(counter)
)
console.log(value) // 42
})
get(self: TxDeferred<A, E>(parameter) self: {
ref: TxRef.TxRef<Option<Result<A, E>>>;
toString: () => string;
toJSON: () => unknown;
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; <…;
}
self.TxDeferred<A, E>.ref: TxRef.TxRef<Option<Result<A, E>>>(property) TxDeferred<A, E>.ref: {
version: number;
pending: Map<unknown, () => void>;
value: A;
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; <…;
}
ref)
if (import OO.const isNone: <A>(
self: Option<A>
) => self is None<A>
Checks whether an Option is None (absent).
When to use
Use when you need to branch on an absent Option before accessing .value.
Details
- Acts as a type guard, narrowing to
None<A>
Example (Checking for None)
import { Option } from "effect"
console.log(Option.isNone(Option.some(1)))
// Output: false
console.log(Option.isNone(Option.none()))
// Output: true
isNone(const option: Option<Result<A, E>>option)) {
return yield* import EffectEffect.const txRetry: Effect<
never,
never,
Transaction
>
const txRetry: {
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;
}
Retries the current transaction by signaling that it must be retried.
Details
NOTE: the transaction retries on any change to transactional values (i.e. TxRef) accessed in its body.
Example (Retrying transactions)
import { Effect, TxRef } from "effect"
const program = Effect.gen(function*() {
// create a transactional reference
const ref = yield* TxRef.make(0)
// forks a fiber that increases the value of `ref` every 100 millis
yield* Effect.forkChild(Effect.forever(
// update to transactional value
Effect.tx(TxRef.update(ref, (n) => n + 1)).pipe(Effect.delay("100 millis"))
))
// the following will retry 10 times until the `ref` value is 10
yield* Effect.tx(Effect.gen(function*() {
const value = yield* TxRef.get(ref)
if (value < 10) {
yield* Effect.log(`retry due to value: ${value}`)
return yield* Effect.txRetry
}
yield* Effect.log(`transaction done with value: ${value}`)
}))
})
Effect.runPromise(program).catch(console.error)
txRetry
}
return import ResRes.const isSuccess: <A, E>(
self: Result<A, E>
) => self is Success<A, E>
Checks whether a Result is a Success.
When to use
Use to narrow a known Result to the Success variant.
Details
- Acts as a TypeScript type guard, narrowing to
Success<A, E>
- After narrowing, you can access
.success to read the value
Example (Narrowing to success)
import { Result } from "effect"
const result = Result.succeed(42)
if (Result.isSuccess(result)) {
console.log(result.success)
// Output: 42
}
isSuccess(const option: O.Some<Result<A, E>>const option: {
_tag: "Some";
_op: "Some";
value: A;
valueOrUndefined: A;
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;
}
option.Some<Result<A, E>>.value: Result<A, E>value)
? const option: O.Some<Result<A, E>>const option: {
_tag: "Some";
_op: "Some";
value: A;
valueOrUndefined: A;
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;
}
option.Some<Result<A, E>>.value: Res.Success<A, E>(property) Some<Result<A, E>>.value: {
_tag: "Success";
_op: "Success";
success: A;
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;
}
value.Success<A, E>.success: Asuccess
: yield* import EffectEffect.const fail: <E>(
error: E
) => Effect<never, E>
Creates an Effect that represents a recoverable error.
When to use
Use to explicitly signal a recoverable error in an Effect.
Details
The error keeps propagating unless it is handled. You can handle tagged
errors with functions like
catchTag
or
catchTags
.
Example (Creating a failed effect)
import { Data, Effect } from "effect"
class OperationFailedError extends Data.TaggedError("OperationFailedError")<{}> {}
// ┌─── Effect<never, OperationFailedError, never>
// ▼
const failure = Effect.fail(
new OperationFailedError()
)
fail(const option: O.Some<Result<A, E>>const option: {
_tag: "Some";
_op: "Some";
value: A;
valueOrUndefined: A;
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;
}
option.Some<Result<A, E>>.value: Res.Failure<A, E>(property) Some<Result<A, E>>.value: {
_tag: "Failure";
_op: "Failure";
failure: E;
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;
}
value.Failure<A, E>.failure: Efailure)
}).Pipeable.pipe<Effect.Effect<A, E, Effect.Transaction>, Effect.Effect<A, E, never>>(this: Effect.Effect<A, E, Effect.Transaction>, ab: (_: Effect.Effect<A, E, Effect.Transaction>) => Effect.Effect<A, E, never>): Effect.Effect<A, E, never> (+21 overloads)pipe(import EffectEffect.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)