<A, R>(f: (current: NoInfer<A>) => [returnValue: R, newValue: A]): (
self: TxRef<A>
) => Effect.Effect<R>
<A, R>(
self: TxRef<A>,
f: (current: A) => [returnValue: R, newValue: A]
): Effect.Effect<R>Modifies the value of the TxRef using the provided function.
When to use
Use to update a TxRef and return a computed result from the same
transaction step.
Example (Modifying transactional references)
import { Effect, TxRef } from "effect"
const program = Effect.gen(function*() {
const counter = yield* TxRef.make(0)
// Modify and return both old and new value
const result = yield* TxRef.modify(counter, (current) => [current * 2, current + 1])
console.log(result) // 0 (the return value: current * 2)
console.log(yield* TxRef.get(counter)) // 1 (the new value: current + 1)
})export const const modify: {
<A, R>(
f: (
current: NoInfer<A>
) => [returnValue: R, newValue: A]
): (self: TxRef<A>) => Effect.Effect<R>
<A, R>(
self: TxRef<A>,
f: (
current: A
) => [returnValue: R, newValue: A]
): Effect.Effect<R>
}
Modifies the value of the TxRef using the provided function.
When to use
Use to update a TxRef and return a computed result from the same
transaction step.
Example (Modifying transactional references)
import { Effect, TxRef } from "effect"
const program = Effect.gen(function*() {
const counter = yield* TxRef.make(0)
// Modify and return both old and new value
const result = yield* TxRef.modify(counter, (current) => [current * 2, current + 1])
console.log(result) // 0 (the return value: current * 2)
console.log(yield* TxRef.get(counter)) // 1 (the new value: current + 1)
})
modify: {
<function (type parameter) A in <A, R>(f: (current: NoInfer<A>) => [returnValue: R, newValue: A]): (self: TxRef<A>) => Effect.Effect<R>A, function (type parameter) R in <A, R>(f: (current: NoInfer<A>) => [returnValue: R, newValue: A]): (self: TxRef<A>) => Effect.Effect<R>R>(f: (
current: NoInfer<A>
) => [returnValue: R, newValue: A]
f: (current: NoInfer<A>current: type NoInfer<A> = [A][A extends any ? 0 : never]Prevents TypeScript from inferring a type parameter from a specific
position.
When to use
Use when a function parameter must match an inferred type without becoming
an inference source.
Details
The parameter using NoInfer must still match the inferred type.
Example (Controlling inference)
import type { Types } from "effect"
declare function withDefault<T>(value: T, fallback: Types.NoInfer<T>): T
// T is inferred as "a" | "b" from the first argument only
const result = withDefault<"a" | "b">("a", "b")
NoInfer<function (type parameter) A in <A, R>(f: (current: NoInfer<A>) => [returnValue: R, newValue: A]): (self: TxRef<A>) => Effect.Effect<R>A>) => [RreturnValue: function (type parameter) R in <A, R>(f: (current: NoInfer<A>) => [returnValue: R, newValue: A]): (self: TxRef<A>) => Effect.Effect<R>R, AnewValue: function (type parameter) A in <A, R>(f: (current: NoInfer<A>) => [returnValue: R, newValue: A]): (self: TxRef<A>) => Effect.Effect<R>A]): (self: TxRef<A>(parameter) self: {
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; <…;
}
self: interface TxRef<in out A>TxRef is a transactional value, it can be read and modified within the body of a transaction.
When to use
Use to store mutable state that must be read and modified inside Effect
transactions.
Details
Accessed values are tracked by the transaction in order to detect conflicts and in order to
track changes, a transaction will retry whenever a conflict is detected or whenever the
transaction explicitely calls to Effect.txRetry and any of the accessed TxRef values
change.
Example (Using a transactional reference)
import { Effect, TxRef } from "effect"
const program = Effect.gen(function*() {
// Create a transactional reference
const ref: TxRef.TxRef<number> = yield* TxRef.make(0)
// Use within a transaction
yield* Effect.tx(Effect.gen(function*() {
const current = yield* TxRef.get(ref)
yield* TxRef.set(ref, current + 1)
}))
const final = yield* TxRef.get(ref)
console.log(final) // 1
})
TxRef<function (type parameter) A in <A, R>(f: (current: NoInfer<A>) => [returnValue: R, newValue: A]): (self: TxRef<A>) => Effect.Effect<R>A>) => import EffectEffect.type Effect.Effect = /*unresolved*/ anyEffect<function (type parameter) R in <A, R>(f: (current: NoInfer<A>) => [returnValue: R, newValue: A]): (self: TxRef<A>) => Effect.Effect<R>R>
<function (type parameter) A in <A, R>(self: TxRef<A>, f: (current: A) => [returnValue: R, newValue: A]): Effect.Effect<R>A, function (type parameter) R in <A, R>(self: TxRef<A>, f: (current: A) => [returnValue: R, newValue: A]): Effect.Effect<R>R>(self: TxRef<A>(parameter) self: {
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; <…;
}
self: interface TxRef<in out A>TxRef is a transactional value, it can be read and modified within the body of a transaction.
When to use
Use to store mutable state that must be read and modified inside Effect
transactions.
Details
Accessed values are tracked by the transaction in order to detect conflicts and in order to
track changes, a transaction will retry whenever a conflict is detected or whenever the
transaction explicitely calls to Effect.txRetry and any of the accessed TxRef values
change.
Example (Using a transactional reference)
import { Effect, TxRef } from "effect"
const program = Effect.gen(function*() {
// Create a transactional reference
const ref: TxRef.TxRef<number> = yield* TxRef.make(0)
// Use within a transaction
yield* Effect.tx(Effect.gen(function*() {
const current = yield* TxRef.get(ref)
yield* TxRef.set(ref, current + 1)
}))
const final = yield* TxRef.get(ref)
console.log(final) // 1
})
TxRef<function (type parameter) A in <A, R>(self: TxRef<A>, f: (current: A) => [returnValue: R, newValue: A]): Effect.Effect<R>A>, f: (
current: A
) => [returnValue: R, newValue: A]
f: (current: Acurrent: function (type parameter) A in <A, R>(self: TxRef<A>, f: (current: A) => [returnValue: R, newValue: A]): Effect.Effect<R>A) => [RreturnValue: function (type parameter) R in <A, R>(self: TxRef<A>, f: (current: A) => [returnValue: R, newValue: A]): Effect.Effect<R>R, AnewValue: function (type parameter) A in <A, R>(self: TxRef<A>, f: (current: A) => [returnValue: R, newValue: A]): Effect.Effect<R>A]): import EffectEffect.type Effect.Effect = /*unresolved*/ anyEffect<function (type parameter) R in <A, R>(self: TxRef<A>, f: (current: A) => [returnValue: R, newValue: A]): Effect.Effect<R>R>
} = import dualdual(2, <function (type parameter) A in <A, R>(self: TxRef<A>, f: (current: A) => [returnValue: R, newValue: A]): Effect.Effect<R>A, function (type parameter) R in <A, R>(self: TxRef<A>, f: (current: A) => [returnValue: R, newValue: A]): Effect.Effect<R>R>(
self: TxRef<A>(parameter) self: {
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; <…;
}
self: interface TxRef<in out A>TxRef is a transactional value, it can be read and modified within the body of a transaction.
When to use
Use to store mutable state that must be read and modified inside Effect
transactions.
Details
Accessed values are tracked by the transaction in order to detect conflicts and in order to
track changes, a transaction will retry whenever a conflict is detected or whenever the
transaction explicitely calls to Effect.txRetry and any of the accessed TxRef values
change.
Example (Using a transactional reference)
import { Effect, TxRef } from "effect"
const program = Effect.gen(function*() {
// Create a transactional reference
const ref: TxRef.TxRef<number> = yield* TxRef.make(0)
// Use within a transaction
yield* Effect.tx(Effect.gen(function*() {
const current = yield* TxRef.get(ref)
yield* TxRef.set(ref, current + 1)
}))
const final = yield* TxRef.get(ref)
console.log(final) // 1
})
TxRef<function (type parameter) A in <A, R>(self: TxRef<A>, f: (current: A) => [returnValue: R, newValue: A]): Effect.Effect<R>A>,
f: (
current: A
) => [returnValue: R, newValue: A]
f: (current: Acurrent: function (type parameter) A in <A, R>(self: TxRef<A>, f: (current: A) => [returnValue: R, newValue: A]): Effect.Effect<R>A) => [RreturnValue: function (type parameter) R in <A, R>(self: TxRef<A>, f: (current: A) => [returnValue: R, newValue: A]): Effect.Effect<R>R, AnewValue: function (type parameter) A in <A, R>(self: TxRef<A>, f: (current: A) => [returnValue: R, newValue: A]): Effect.Effect<R>A]
): import EffectEffect.type Effect.Effect = /*unresolved*/ anyEffect<function (type parameter) R in <A, R>(self: TxRef<A>, f: (current: A) => [returnValue: R, newValue: A]): Effect.Effect<R>R> =>
import EffectEffect.Transaction.pipe(
import EffectEffect.flatMap((state: {
retry: boolean
readonly journal: Map<
TxRef<any>,
{ readonly version: number; value: any }
>
}
(parameter) state: {
retry: boolean;
journal: Map<TxRef<any>, { readonly version: number; value: any }>;
}
state) =>
import EffectEffect.sync(() => {
if (!state: {
retry: boolean
readonly journal: Map<
TxRef<any>,
{ readonly version: number; value: any }
>
}
(parameter) state: {
retry: boolean;
journal: Map<TxRef<any>, { readonly version: number; value: any }>;
}
state.journal.has(self: TxRef<A>(parameter) self: {
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; <…;
}
self)) {
state: {
retry: boolean
readonly journal: Map<
TxRef<any>,
{ readonly version: number; value: any }
>
}
(parameter) state: {
retry: boolean;
journal: Map<TxRef<any>, { readonly version: number; value: any }>;
}
state.journal.set(self: TxRef<A>(parameter) self: {
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; <…;
}
self, { version: numberversion: self: TxRef<A>(parameter) self: {
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; <…;
}
self.TxRef<in out A>.version: numberversion, value: Avalue: self: TxRef<A>(parameter) self: {
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; <…;
}
self.TxRef<A>.value: Avalue })
}
const const current: anyconst current: {
version: number;
value: any;
}
current = state: {
retry: boolean
readonly journal: Map<
TxRef<any>,
{ readonly version: number; value: any }
>
}
(parameter) state: {
retry: boolean;
journal: Map<TxRef<any>, { readonly version: number; value: any }>;
}
state.journal.get(self: TxRef<A>(parameter) self: {
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; <…;
}
self)!
const [const returnValue: RreturnValue, const next: Anext] = f: (
current: A
) => [returnValue: R, newValue: A]
f(const current: anyconst current: {
version: number;
value: any;
}
current.value)
const current: anyconst current: {
version: number;
value: any;
}
current.value = const next: Anext
return const returnValue: RreturnValue
})
),
import EffectEffect.tx
))