(n: number): <A, E>(self: TxDequeue<A, E>) => Effect.Effect<Array<A>, E>
<A, E>(self: TxDequeue<A, E>, n: number): Effect.Effect<Array<A>, E>Takes up to n items from the queue in a single transaction.
Details
For an open queue, waits until min(n, capacity) items are available, then removes that many items. If n is less than or equal to zero, returns an empty array without modifying the queue. If the queue is closing, drains the currently available items and transitions to Done. If the queue is already done, the effect fails with the queue's completion cause. This function mutates the original TxQueue by removing the taken items. It does not return a new TxQueue reference.
Example (Taking a fixed number of values)
import { Effect, TxQueue } from "effect"
const program = Effect.gen(function*() {
const queue = yield* TxQueue.bounded<number>(5)
yield* TxQueue.offerAll(queue, [1, 2, 3, 4])
const items = yield* TxQueue.takeN(queue, 4)
console.log(items) // [1, 2, 3, 4]
// This requests more than capacity (5), so takes all available (up to 5)
yield* TxQueue.offerAll(queue, [5, 6, 7, 8, 9])
const all = yield* TxQueue.takeN(queue, 10)
console.log(all) // [5, 6, 7, 8, 9]
})export const const takeN: {
(n: number): <A, E>(
self: TxDequeue<A, E>
) => Effect.Effect<Array<A>, E>
<A, E>(
self: TxDequeue<A, E>,
n: number
): Effect.Effect<Array<A>, E>
}
Takes up to n items from the queue in a single transaction.
Details
For an open queue, waits until min(n, capacity) items are available, then removes that many items. If n is less than or equal to zero, returns an empty array without modifying the queue. If the queue is closing, drains the currently available items and transitions to Done. If the queue is already done, the effect fails with the queue's completion cause. This function mutates the original TxQueue by removing the taken items. It does not return a new TxQueue reference.
Example (Taking a fixed number of values)
import { Effect, TxQueue } from "effect"
const program = Effect.gen(function*() {
const queue = yield* TxQueue.bounded<number>(5)
yield* TxQueue.offerAll(queue, [1, 2, 3, 4])
const items = yield* TxQueue.takeN(queue, 4)
console.log(items) // [1, 2, 3, 4]
// This requests more than capacity (5), so takes all available (up to 5)
yield* TxQueue.offerAll(queue, [5, 6, 7, 8, 9])
const all = yield* TxQueue.takeN(queue, 10)
console.log(all) // [5, 6, 7, 8, 9]
})
takeN: {
(n: numbern: number): <function (type parameter) A in <A, E>(self: TxDequeue<A, E>): Effect.Effect<Array<A>, E>A, function (type parameter) E in <A, E>(self: TxDequeue<A, E>): Effect.Effect<Array<A>, E>E>(self: TxDequeue<A, E>(parameter) self: {
strategy: "bounded" | "unbounded" | "dropping" | "sliding";
capacity: number;
items: TxChunk.TxChunk<any>;
stateRef: TxRef.TxRef<State<any, any>>;
toString: () => string;
toJSON: () => unknown;
}
self: interface TxDequeue<out A, out E = never>Namespace containing type definitions for TxDequeue variance annotations.
A TxDequeue represents the read-only interface of a transactional queue, providing
operations for consuming elements (dequeue operations) and inspecting queue state.
Example (Taking values through dequeue handles)
import { Effect, TxQueue } from "effect"
const program = Effect.gen(function*() {
// Queue without error channel
const queue = yield* TxQueue.bounded<number>(10)
yield* TxQueue.offer(queue, 42)
const item = yield* TxQueue.take(queue)
console.log(item) // 42
// Queue with error channel - errors propagate through E-channel
const faultTolerantQueue = yield* TxQueue.bounded<number, string>(10)
yield* TxQueue.fail(faultTolerantQueue, "processing failed")
// All dequeue operations now fail with the error directly
const takeResult = yield* Effect.flip(TxQueue.take(faultTolerantQueue)) // "processing failed"
const peekResult = yield* Effect.flip(TxQueue.peek(faultTolerantQueue)) // "processing failed"
})
TxDequeue<function (type parameter) A in <A, E>(self: TxDequeue<A, E>): Effect.Effect<Array<A>, E>A, function (type parameter) E in <A, E>(self: TxDequeue<A, E>): Effect.Effect<Array<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<interface Array<T>Array<function (type parameter) A in <A, E>(self: TxDequeue<A, E>): Effect.Effect<Array<A>, E>A>, function (type parameter) E in <A, E>(self: TxDequeue<A, E>): Effect.Effect<Array<A>, E>E>
<function (type parameter) A in <A, E>(self: TxDequeue<A, E>, n: number): Effect.Effect<Array<A>, E>A, function (type parameter) E in <A, E>(self: TxDequeue<A, E>, n: number): Effect.Effect<Array<A>, E>E>(self: TxDequeue<A, E>(parameter) self: {
strategy: "bounded" | "unbounded" | "dropping" | "sliding";
capacity: number;
items: TxChunk.TxChunk<any>;
stateRef: TxRef.TxRef<State<any, any>>;
toString: () => string;
toJSON: () => unknown;
}
self: interface TxDequeue<out A, out E = never>Namespace containing type definitions for TxDequeue variance annotations.
A TxDequeue represents the read-only interface of a transactional queue, providing
operations for consuming elements (dequeue operations) and inspecting queue state.
Example (Taking values through dequeue handles)
import { Effect, TxQueue } from "effect"
const program = Effect.gen(function*() {
// Queue without error channel
const queue = yield* TxQueue.bounded<number>(10)
yield* TxQueue.offer(queue, 42)
const item = yield* TxQueue.take(queue)
console.log(item) // 42
// Queue with error channel - errors propagate through E-channel
const faultTolerantQueue = yield* TxQueue.bounded<number, string>(10)
yield* TxQueue.fail(faultTolerantQueue, "processing failed")
// All dequeue operations now fail with the error directly
const takeResult = yield* Effect.flip(TxQueue.take(faultTolerantQueue)) // "processing failed"
const peekResult = yield* Effect.flip(TxQueue.peek(faultTolerantQueue)) // "processing failed"
})
TxDequeue<function (type parameter) A in <A, E>(self: TxDequeue<A, E>, n: number): Effect.Effect<Array<A>, E>A, function (type parameter) E in <A, E>(self: TxDequeue<A, E>, n: number): Effect.Effect<Array<A>, E>E>, n: numbern: number): 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<interface Array<T>Array<function (type parameter) A in <A, E>(self: TxDequeue<A, E>, n: number): Effect.Effect<Array<A>, E>A>, function (type parameter) E in <A, E>(self: TxDequeue<A, E>, n: number): Effect.Effect<Array<A>, E>E>
} = dual<(...args: Array<any>) => any, <A, E>(self: TxDequeue<A, E>, n: number) => Effect.Effect<Array<A>, E>>(arity: 2, body: <A, E>(self: TxDequeue<A, E>, n: number) => Effect.Effect<Array<A>, E>): ((...args: Array<any>) => any) & (<A, E>(self: TxDequeue<A, E>, n: number) => Effect.Effect<Array<A>, E>) (+1 overload)Creates a function that can be called in data-first style or data-last
(pipe-friendly) style.
When to use
Use to expose one implementation through both direct and pipe-friendly
call styles.
Details
Pass either the arity of the uncurried function or a predicate that decides
whether the current call is data-first. Arity is the common case. Use a
predicate when optional arguments make arity ambiguous.
Example (Selecting data-first or data-last style by arity)
import { Function, pipe } from "effect"
const sum = Function.dual<
(that: number) => (self: number) => number,
(self: number, that: number) => number
>(2, (self, that) => self + that)
console.log(sum(2, 3)) // 5
console.log(pipe(2, sum(3))) // 5
Example (Defining overloads with call signatures)
import { Function, pipe } from "effect"
const sum: {
(that: number): (self: number) => number
(self: number, that: number): number
} = Function.dual(2, (self: number, that: number): number => self + that)
console.log(sum(2, 3)) // 5
console.log(pipe(2, sum(3))) // 5
Example (Selecting data-first or data-last style with a predicate)
import { Function, pipe } from "effect"
const sum = Function.dual<
(that: number) => (self: number) => number,
(self: number, that: number) => number
>(
(args) => args.length === 2,
(self, that) => self + that
)
console.log(sum(2, 3)) // 5
console.log(pipe(2, sum(3))) // 5
dual(
2,
<function (type parameter) A in <A, E>(self: TxDequeue<A, E>, n: number): Effect.Effect<Array<A>, E>A, function (type parameter) E in <A, E>(self: TxDequeue<A, E>, n: number): Effect.Effect<Array<A>, E>E>(self: TxDequeue<A, E>(parameter) self: {
strategy: "bounded" | "unbounded" | "dropping" | "sliding";
capacity: number;
items: TxChunk.TxChunk<any>;
stateRef: TxRef.TxRef<State<any, any>>;
toString: () => string;
toJSON: () => unknown;
}
self: interface TxDequeue<out A, out E = never>Namespace containing type definitions for TxDequeue variance annotations.
A TxDequeue represents the read-only interface of a transactional queue, providing
operations for consuming elements (dequeue operations) and inspecting queue state.
Example (Taking values through dequeue handles)
import { Effect, TxQueue } from "effect"
const program = Effect.gen(function*() {
// Queue without error channel
const queue = yield* TxQueue.bounded<number>(10)
yield* TxQueue.offer(queue, 42)
const item = yield* TxQueue.take(queue)
console.log(item) // 42
// Queue with error channel - errors propagate through E-channel
const faultTolerantQueue = yield* TxQueue.bounded<number, string>(10)
yield* TxQueue.fail(faultTolerantQueue, "processing failed")
// All dequeue operations now fail with the error directly
const takeResult = yield* Effect.flip(TxQueue.take(faultTolerantQueue)) // "processing failed"
const peekResult = yield* Effect.flip(TxQueue.peek(faultTolerantQueue)) // "processing failed"
})
TxDequeue<function (type parameter) A in <A, E>(self: TxDequeue<A, E>, n: number): Effect.Effect<Array<A>, E>A, function (type parameter) E in <A, E>(self: TxDequeue<A, E>, n: number): Effect.Effect<Array<A>, E>E>, n: numbern: number): 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<interface Array<T>Array<function (type parameter) A in <A, E>(self: TxDequeue<A, E>, n: number): Effect.Effect<Array<A>, E>A>, function (type parameter) E in <A, E>(self: TxDequeue<A, E>, n: number): Effect.Effect<Array<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 state: State<any, any>state = 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: TxDequeue<A, E>(parameter) self: {
strategy: "bounded" | "unbounded" | "dropping" | "sliding";
capacity: number;
items: TxChunk.TxChunk<any>;
stateRef: TxRef.TxRef<State<any, any>>;
toString: () => string;
toJSON: () => unknown;
}
self.TxQueueState.stateRef: TxRef.TxRef<State<any, any>>(property) TxQueueState.stateRef: {
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; <…;
}
stateRef)
// Check if queue is done - forward the cause directly
if (const state: State<any, any>state._tag: "Open" | "Closing" | "Done"_tag === "Done") {
return yield* import EffectEffect.const failCause: <E>(
cause: Cause.Cause<E>
) => Effect<never, E>
Creates an Effect that represents a failure with a specific Cause.
When to use
Use when you already have a full Cause and need to preserve defects,
interruptions, annotations, or combined failures in the effect's failure
channel.
Details
This function allows you to create effects that fail with complex error
structures, including multiple errors, defects, interruptions, and more.
Example (Failing with a full Cause)
import { Cause, Effect } from "effect"
const program = Effect.failCause(
Cause.fail("Network error")
)
Effect.runPromiseExit(program).then(console.log)
// Output: { _id: 'Exit', _tag: 'Failure', cause: ... }
failCause(const state: {
readonly _tag: "Done"
readonly cause: Cause.Cause<any>
}
state.cause: Cause.Cause<E>(property) cause: {
reasons: ReadonlyArray<Reason<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;
}
cause)
}
const const currentSize: numbercurrentSize = yield* const size: (
self: TxQueueState
) => Effect.Effect<number>
Gets the current size of the queue.
Example (Reading queue size)
import { Effect, TxQueue } from "effect"
const program = Effect.gen(function*() {
const queue = yield* TxQueue.bounded<number>(10)
yield* TxQueue.offerAll(queue, [1, 2, 3])
const size = yield* TxQueue.size(queue)
console.log(size) // 3
})
size(self: TxDequeue<A, E>(parameter) self: {
strategy: "bounded" | "unbounded" | "dropping" | "sliding";
capacity: number;
items: TxChunk.TxChunk<any>;
stateRef: TxRef.TxRef<State<any, any>>;
toString: () => string;
toJSON: () => unknown;
}
self)
// Determine how many items we can/should take
const const requestedCount: numberrequestedCount = n: numbern
const const maxPossible: numbermaxPossible = var Math: MathAn intrinsic object that provides basic mathematics functionality and constants.
Math.Math.min(...values: number[]): numberReturns the smaller of a set of supplied numeric expressions.
min(const requestedCount: numberrequestedCount, self: TxDequeue<A, E>(parameter) self: {
strategy: "bounded" | "unbounded" | "dropping" | "sliding";
capacity: number;
items: TxChunk.TxChunk<any>;
stateRef: TxRef.TxRef<State<any, any>>;
toString: () => string;
toJSON: () => unknown;
}
self.TxQueueState.capacity: numbercapacity)
// If we can't get the requested amount due to capacity constraints,
// take what the capacity allows. Otherwise, wait for the full amount.
const const shouldWaitForFull: booleanshouldWaitForFull = const requestedCount: numberrequestedCount <= self: TxDequeue<A, E>(parameter) self: {
strategy: "bounded" | "unbounded" | "dropping" | "sliding";
capacity: number;
items: TxChunk.TxChunk<any>;
stateRef: TxRef.TxRef<State<any, any>>;
toString: () => string;
toJSON: () => unknown;
}
self.TxQueueState.capacity: numbercapacity
const const minimumRequired: numberminimumRequired = const shouldWaitForFull: booleanshouldWaitForFull ? const requestedCount: numberrequestedCount : const maxPossible: numbermaxPossible
// If we don't have enough items available
if (const currentSize: numbercurrentSize < const minimumRequired: numberminimumRequired) {
// If queue is closing, transition to done and return what we have
if (const state:
| {
readonly _tag: "Open"
}
| {
readonly _tag: "Closing"
readonly cause: Cause.Cause<any>
}
state._tag: "Open" | "Closing"_tag === "Closing") {
if (yield* const isEmpty: (
self: TxQueueState
) => Effect.Effect<boolean>
Checks whether the queue is empty.
Example (Checking whether a queue is empty)
import { Effect, TxQueue } from "effect"
const program = Effect.gen(function*() {
const queue = yield* TxQueue.bounded<number>(10)
const empty = yield* TxQueue.isEmpty(queue)
console.log(empty) // true
yield* TxQueue.offer(queue, 42)
const stillEmpty = yield* TxQueue.isEmpty(queue)
console.log(stillEmpty) // false
})
isEmpty(self: TxDequeue<A, E>(parameter) self: {
strategy: "bounded" | "unbounded" | "dropping" | "sliding";
capacity: number;
items: TxChunk.TxChunk<any>;
stateRef: TxRef.TxRef<State<any, any>>;
toString: () => string;
toJSON: () => unknown;
}
self)) {
yield* import TxRefTxRef.const set: {
<A>(value: A): (
self: TxRef<A>
) => Effect.Effect<void>
<A>(
self: TxRef<A>,
value: A
): Effect.Effect<void>
}
set(self: TxDequeue<A, E>(parameter) self: {
strategy: "bounded" | "unbounded" | "dropping" | "sliding";
capacity: number;
items: TxChunk.TxChunk<any>;
stateRef: TxRef.TxRef<State<any, any>>;
toString: () => string;
toJSON: () => unknown;
}
self.TxQueueState.stateRef: TxRef.TxRef<State<any, any>>(property) TxQueueState.stateRef: {
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; <…;
}
stateRef, { _tag: "Done"_tag: "Done", cause: Cause.Cause<any>(property) cause: {
reasons: ReadonlyArray<Reason<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;
}
cause: const state: {
readonly _tag: "Closing"
readonly cause: Cause.Cause<any>
}
state.cause: Cause.Cause<E>(property) cause: {
reasons: ReadonlyArray<Reason<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;
}
cause })
return []
}
// Take all remaining items when closing
const const chunk: Chunk.Chunk<any>const chunk: {
length: number;
right: Chunk<A>;
left: Chunk<A>;
backing: Backing<A>;
depth: number;
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;
}
chunk = yield* import TxChunkTxChunk.const get: <A>(
self: TxChunk<A>
) => Effect.Effect<Chunk.Chunk<A>>
Reads the current chunk from the TxChunk.
Example (Reading the current chunk)
import { Chunk, Effect, TxChunk } from "effect"
const program = Effect.gen(function*() {
const txChunk = yield* TxChunk.fromIterable([1, 2, 3])
// Read the current value within a transaction
const chunk = yield* TxChunk.get(txChunk)
console.log(Chunk.toReadonlyArray(chunk)) // [1, 2, 3]
// The value is tracked for conflict detection
const size = Chunk.size(chunk)
console.log(size) // 3
})
get(self: TxDequeue<A, E>(parameter) self: {
strategy: "bounded" | "unbounded" | "dropping" | "sliding";
capacity: number;
items: TxChunk.TxChunk<any>;
stateRef: TxRef.TxRef<State<any, any>>;
toString: () => string;
toJSON: () => unknown;
}
self.TxQueueState.items: TxChunk.TxChunk<any>(property) TxQueueState.items: {
ref: TxRef.TxRef<Chunk.Chunk<A>>;
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; <…;
}
items)
const const taken: any[]taken = import ChunkChunk.const toArray: <S extends Chunk<any>>(
self: S
) => S extends NonEmptyChunk<any>
? RA.NonEmptyArray<Chunk.Infer<S>>
: Array<Chunk.Infer<S>>
Converts a Chunk into an Array. If the provided Chunk is non-empty
(NonEmptyChunk), the function will return a NonEmptyArray, ensuring the
non-empty property is preserved.
Example (Converting chunks to mutable arrays)
import { Chunk } from "effect"
const chunk = Chunk.make(1, 2, 3)
const array = Chunk.toArray(chunk)
console.log(array) // [1, 2, 3]
console.log(Array.isArray(array)) // true
// With empty chunk
const emptyChunk = Chunk.empty<number>()
console.log(Chunk.toArray(emptyChunk)) // []
toArray(const chunk: Chunk.Chunk<any>const chunk: {
length: number;
right: Chunk<A>;
left: Chunk<A>;
backing: Backing<A>;
depth: number;
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;
}
chunk)
yield* import TxChunkTxChunk.const set: {
<A>(chunk: Chunk.Chunk<A>): (
self: TxChunk<A>
) => Effect.Effect<void>
<A>(
self: TxChunk<A>,
chunk: Chunk.Chunk<A>
): Effect.Effect<void>
}
set(self: TxDequeue<A, E>(parameter) self: {
strategy: "bounded" | "unbounded" | "dropping" | "sliding";
capacity: number;
items: TxChunk.TxChunk<any>;
stateRef: TxRef.TxRef<State<any, any>>;
toString: () => string;
toJSON: () => unknown;
}
self.TxQueueState.items: TxChunk.TxChunk<any>(property) TxQueueState.items: {
ref: TxRef.TxRef<Chunk.Chunk<A>>;
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; <…;
}
items, import ChunkChunk.const empty: <A = never>() => Chunk<A>Creates an empty Chunk.
Example (Creating an empty chunk)
import { Chunk } from "effect"
const emptyChunk = Chunk.empty()
console.log(Chunk.size(emptyChunk)) // 0
empty())
yield* import TxRefTxRef.const set: {
<A>(value: A): (
self: TxRef<A>
) => Effect.Effect<void>
<A>(
self: TxRef<A>,
value: A
): Effect.Effect<void>
}
set(self: TxDequeue<A, E>(parameter) self: {
strategy: "bounded" | "unbounded" | "dropping" | "sliding";
capacity: number;
items: TxChunk.TxChunk<any>;
stateRef: TxRef.TxRef<State<any, any>>;
toString: () => string;
toJSON: () => unknown;
}
self.TxQueueState.stateRef: TxRef.TxRef<State<any, any>>(property) TxQueueState.stateRef: {
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; <…;
}
stateRef, { _tag: "Done"_tag: "Done", cause: Cause.Cause<any>(property) cause: {
reasons: ReadonlyArray<Reason<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;
}
cause: const state: {
readonly _tag: "Closing"
readonly cause: Cause.Cause<any>
}
state.cause: Cause.Cause<E>(property) cause: {
reasons: ReadonlyArray<Reason<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;
}
cause })
return const taken: any[]taken
}
// Queue is still open but not enough items - retry transaction
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
}
// Take the determined number of items
const const toTake: numbertoTake = const minimumRequired: numberminimumRequired
const const chunk: Chunk.Chunk<any>const chunk: {
length: number;
right: Chunk<A>;
left: Chunk<A>;
backing: Backing<A>;
depth: number;
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;
}
chunk = yield* import TxChunkTxChunk.const get: <A>(
self: TxChunk<A>
) => Effect.Effect<Chunk.Chunk<A>>
Reads the current chunk from the TxChunk.
Example (Reading the current chunk)
import { Chunk, Effect, TxChunk } from "effect"
const program = Effect.gen(function*() {
const txChunk = yield* TxChunk.fromIterable([1, 2, 3])
// Read the current value within a transaction
const chunk = yield* TxChunk.get(txChunk)
console.log(Chunk.toReadonlyArray(chunk)) // [1, 2, 3]
// The value is tracked for conflict detection
const size = Chunk.size(chunk)
console.log(size) // 3
})
get(self: TxDequeue<A, E>(parameter) self: {
strategy: "bounded" | "unbounded" | "dropping" | "sliding";
capacity: number;
items: TxChunk.TxChunk<any>;
stateRef: TxRef.TxRef<State<any, any>>;
toString: () => string;
toJSON: () => unknown;
}
self.TxQueueState.items: TxChunk.TxChunk<any>(property) TxQueueState.items: {
ref: TxRef.TxRef<Chunk.Chunk<A>>;
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; <…;
}
items)
const const taken: Chunk.Chunk<any>const taken: {
length: number;
right: Chunk<A>;
left: Chunk<A>;
backing: Backing<A>;
depth: number;
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;
}
taken = import ChunkChunk.const take: {
(n: number): <A>(self: Chunk<A>) => Chunk<A>
<A>(self: Chunk<A>, n: number): Chunk<A>
}
take(const chunk: Chunk.Chunk<any>const chunk: {
length: number;
right: Chunk<A>;
left: Chunk<A>;
backing: Backing<A>;
depth: number;
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;
}
chunk, const toTake: numbertoTake)
yield* import TxChunkTxChunk.const drop: {
(n: number): <A>(
self: TxChunk<A>
) => Effect.Effect<void>
<A>(
self: TxChunk<A>,
n: number
): Effect.Effect<void>
}
drop(self: TxDequeue<A, E>(parameter) self: {
strategy: "bounded" | "unbounded" | "dropping" | "sliding";
capacity: number;
items: TxChunk.TxChunk<any>;
stateRef: TxRef.TxRef<State<any, any>>;
toString: () => string;
toJSON: () => unknown;
}
self.TxQueueState.items: TxChunk.TxChunk<any>(property) TxQueueState.items: {
ref: TxRef.TxRef<Chunk.Chunk<A>>;
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; <…;
}
items, const toTake: numbertoTake)
// Check if we need to transition Closing → Done
if (const state:
| {
readonly _tag: "Open"
}
| {
readonly _tag: "Closing"
readonly cause: Cause.Cause<any>
}
state._tag: "Open" | "Closing"_tag === "Closing" && (yield* const isEmpty: (
self: TxQueueState
) => Effect.Effect<boolean>
Checks whether the queue is empty.
Example (Checking whether a queue is empty)
import { Effect, TxQueue } from "effect"
const program = Effect.gen(function*() {
const queue = yield* TxQueue.bounded<number>(10)
const empty = yield* TxQueue.isEmpty(queue)
console.log(empty) // true
yield* TxQueue.offer(queue, 42)
const stillEmpty = yield* TxQueue.isEmpty(queue)
console.log(stillEmpty) // false
})
isEmpty(self: TxDequeue<A, E>(parameter) self: {
strategy: "bounded" | "unbounded" | "dropping" | "sliding";
capacity: number;
items: TxChunk.TxChunk<any>;
stateRef: TxRef.TxRef<State<any, any>>;
toString: () => string;
toJSON: () => unknown;
}
self))) {
yield* import TxRefTxRef.const set: {
<A>(value: A): (
self: TxRef<A>
) => Effect.Effect<void>
<A>(
self: TxRef<A>,
value: A
): Effect.Effect<void>
}
set(self: TxDequeue<A, E>(parameter) self: {
strategy: "bounded" | "unbounded" | "dropping" | "sliding";
capacity: number;
items: TxChunk.TxChunk<any>;
stateRef: TxRef.TxRef<State<any, any>>;
toString: () => string;
toJSON: () => unknown;
}
self.TxQueueState.stateRef: TxRef.TxRef<State<any, any>>(property) TxQueueState.stateRef: {
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; <…;
}
stateRef, { _tag: "Done"_tag: "Done", cause: Cause.Cause<any>(property) cause: {
reasons: ReadonlyArray<Reason<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;
}
cause: const state: {
readonly _tag: "Closing"
readonly cause: Cause.Cause<any>
}
state.cause: Cause.Cause<E>(property) cause: {
reasons: ReadonlyArray<Reason<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;
}
cause })
}
return import ChunkChunk.const toArray: <S extends Chunk<any>>(
self: S
) => S extends NonEmptyChunk<any>
? RA.NonEmptyArray<Chunk.Infer<S>>
: Array<Chunk.Infer<S>>
Converts a Chunk into an Array. If the provided Chunk is non-empty
(NonEmptyChunk), the function will return a NonEmptyArray, ensuring the
non-empty property is preserved.
Example (Converting chunks to mutable arrays)
import { Chunk } from "effect"
const chunk = Chunk.make(1, 2, 3)
const array = Chunk.toArray(chunk)
console.log(array) // [1, 2, 3]
console.log(Array.isArray(array)) // true
// With empty chunk
const emptyChunk = Chunk.empty<number>()
console.log(Chunk.toArray(emptyChunk)) // []
toArray(const taken: Chunk.Chunk<any>const taken: {
length: number;
right: Chunk<A>;
left: Chunk<A>;
backing: Backing<A>;
depth: number;
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;
}
taken)
}).Pipeable.pipe<Effect.Effect<any[], any, Effect.Transaction>, Effect.Effect<any[], any, never>>(this: Effect.Effect<any[], any, Effect.Transaction>, ab: (_: Effect.Effect<any[], any, Effect.Transaction>) => Effect.Effect<any[], any, never>): Effect.Effect<any[], any, 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)
)