MutableRef.ts
MutableRef.ts overview
Section titled “MutableRef.ts overview”Stores synchronous mutable state in a small reference object.
A MutableRef<A> stores one current value and exposes it through .current.
Unlike Ref, its operations are synchronous and update the same object in
place. This module includes pipeable helpers for reading, setting, comparing,
and updating the value, plus numeric increment/decrement helpers and a
boolean toggle helper.
Since v2.0.0
Exports Grouped by Category
Section titled “Exports Grouped by Category”boolean
Section titled “boolean”toggle
Section titled “toggle”Switches a boolean MutableRef between true and false, then returns the
reference.
When to use
Use when you need an in-place boolean MutableRef toggle that returns the
same MutableRef.
Example (Toggling boolean refs)
import { MutableRef } from "effect"
const flag = MutableRef.make(false)
// Toggle the flagMutableRef.toggle(flag)console.log(MutableRef.get(flag)) // true
// Toggle againMutableRef.toggle(flag)console.log(MutableRef.get(flag)) // false
// Useful for state switchesconst isVisible = MutableRef.make(true)MutableRef.toggle(isVisible) // Hideconsole.log(MutableRef.get(isVisible)) // false
// Toggle button implementationconst darkMode = MutableRef.make(false)const toggleDarkMode = () => { MutableRef.toggle(darkMode) console.log(`Dark mode: ${MutableRef.get(darkMode) ? "ON" : "OFF"}`)}
toggleDarkMode() // "Dark mode: ON"toggleDarkMode() // "Dark mode: OFF"
// Returns the reference for chainingconst result = MutableRef.toggle(flag)console.log(result === flag) // trueSignature
declare const toggle: (self: MutableRef<boolean>) => MutableRef<boolean>Since v2.0.0
constructors
Section titled “constructors”Creates a new MutableRef with the specified initial value.
When to use
Use to create a synchronous MutableRef initialized with a value.
Example (Creating mutable refs)
import { MutableRef } from "effect"
// Create a counter referenceconst counter = MutableRef.make(0)console.log(MutableRef.get(counter)) // 0
// Create a configuration referenceconst config = MutableRef.make({ debug: false, timeout: 5000 })console.log(MutableRef.get(config)) // { debug: false, timeout: 5000 }
// Create a string referenceconst status = MutableRef.make("idle")MutableRef.set(status, "running")console.log(MutableRef.get(status)) // "running"Signature
declare const make: <T>(value: T) => MutableRef<T>Since v2.0.0
general
Section titled “general”compareAndSet
Section titled “compareAndSet”Sets the value to newValue atomically if the current value equals oldValue. Returns true if the value was updated, false otherwise. Uses Effect’s Equal interface for value comparison.
When to use
Use to replace a MutableRef value only when the current value still matches
an expected value.
Example (Comparing and setting values)
import { MutableRef } from "effect"
const ref = MutableRef.make("initial")
// Successful compare and setconst updated = MutableRef.compareAndSet(ref, "initial", "updated")console.log(updated) // trueconsole.log(MutableRef.get(ref)) // "updated"
// Failed compare and set (value doesn't match)const failed = MutableRef.compareAndSet(ref, "initial", "failed")console.log(failed) // falseconsole.log(MutableRef.get(ref)) // "updated" (unchanged)
// Thread-safe counter incrementconst counter = MutableRef.make(5)let current: numberdo { current = MutableRef.get(counter)} while (!MutableRef.compareAndSet(counter, current, current + 1))
// Pipe-able versionconst casUpdate = MutableRef.compareAndSet("updated", "final")console.log(casUpdate(ref)) // trueSignature
declare const compareAndSet: { <T>(oldValue: T, newValue: T): (self: MutableRef<T>) => boolean <T>(self: MutableRef<T>, oldValue: T, newValue: T): boolean}Since v2.0.0
Gets the current value of the MutableRef.
When to use
Use to read the current MutableRef value without mutating it.
Example (Reading current values)
import { MutableRef } from "effect"
const ref = MutableRef.make("hello")console.log(MutableRef.get(ref)) // "hello"
MutableRef.set(ref, "world")console.log(MutableRef.get(ref)) // "world"
// Reading complex objectsconst config = MutableRef.make({ port: 3000, host: "localhost" })const currentConfig = MutableRef.get(config)console.log(currentConfig.port) // 3000
// Multiple reads return the same valueconst value1 = MutableRef.get(ref)const value2 = MutableRef.get(ref)console.log(value1 === value2) // trueSignature
declare const get: <T>(self: MutableRef<T>) => TSince v2.0.0
getAndSet
Section titled “getAndSet”Sets the MutableRef to a new value and returns the previous value.
When to use
Use to replace the current MutableRef value while keeping the previous
value.
Example (Reading before setting)
import { MutableRef } from "effect"
const ref = MutableRef.make("old")
// Set new value and get the previous oneconst previous = MutableRef.getAndSet(ref, "new")console.log(previous) // "old"console.log(MutableRef.get(ref)) // "new"
// Swapping valuesconst counter = MutableRef.make(5)const oldValue = MutableRef.getAndSet(counter, 10)console.log(`Changed from ${oldValue} to ${MutableRef.get(counter)}`) // "Changed from 5 to 10"
// Pipe-able versionconst setValue = MutableRef.getAndSet("final")const previousValue = setValue(ref)console.log(previousValue) // "new"
// Useful for atomic swaps in algorithmsconst buffer = MutableRef.make<Array<string>>(["a", "b", "c"])const oldBuffer = MutableRef.getAndSet(buffer, [])console.log(oldBuffer) // ["a", "b", "c"]console.log(MutableRef.get(buffer)) // []Signature
declare const getAndSet: { <T>(value: T): (self: MutableRef<T>) => T; <T>(self: MutableRef<T>, value: T): T }Since v2.0.0
getAndUpdate
Section titled “getAndUpdate”Updates the MutableRef with the result of applying a function to its current value, and returns the previous value.
When to use
Use to transform the current MutableRef value while keeping the previous
value.
Example (Reading before updating)
import { MutableRef } from "effect"
const counter = MutableRef.make(5)
// Increment and get the old valueconst oldValue = MutableRef.getAndUpdate(counter, (n) => n + 1)console.log(oldValue) // 5console.log(MutableRef.get(counter)) // 6
// Double the value and get the previous oneconst previous = MutableRef.getAndUpdate(counter, (n) => n * 2)console.log(previous) // 6console.log(MutableRef.get(counter)) // 12
// Transform string and get old valueconst message = MutableRef.make("hello")const oldMessage = MutableRef.getAndUpdate(message, (s) => s.toUpperCase())console.log(oldMessage) // "hello"console.log(MutableRef.get(message)) // "HELLO"
// Pipe-able versionconst addOne = MutableRef.getAndUpdate((n: number) => n + 1)const result = addOne(counter)console.log(result) // Previous value before increment
// Useful for implementing atomic operationsconst list = MutableRef.make<Array<number>>([1, 2, 3])const oldList = MutableRef.getAndUpdate(list, (arr) => [...arr, 4])console.log(oldList) // [1, 2, 3]console.log(MutableRef.get(list)) // [1, 2, 3, 4]Signature
declare const getAndUpdate: { <T>(f: (value: T) => T): (self: MutableRef<T>) => T <T>(self: MutableRef<T>, f: (value: T) => T): T}Since v2.0.0
Sets the MutableRef to a new value and returns the reference.
When to use
Use when you need an in-place MutableRef replacement that returns the same
MutableRef.
Example (Setting values)
import { MutableRef } from "effect"
const ref = MutableRef.make("initial")
// Set a new valueMutableRef.set(ref, "updated")console.log(MutableRef.get(ref)) // "updated"
// Chain set operations (since it returns the ref)const result = MutableRef.set(ref, "final")console.log(result === ref) // true (same reference)console.log(MutableRef.get(ref)) // "final"
// Set complex objectsconst config = MutableRef.make({ debug: false, verbose: false })MutableRef.set(config, { debug: true, verbose: true })console.log(MutableRef.get(config)) // { debug: true, verbose: true }
// Pipe-able versionconst setValue = MutableRef.set("new value")setValue(ref)console.log(MutableRef.get(ref)) // "new value"
// Useful for state managementconst state = MutableRef.make<"idle" | "loading" | "success" | "error">("idle")MutableRef.set(state, "loading")// ... perform async operationMutableRef.set(state, "success")Signature
declare const set: { <T>(value: T): (self: MutableRef<T>) => MutableRef<T> <T>(self: MutableRef<T>, value: T): MutableRef<T>}Since v2.0.0
setAndGet
Section titled “setAndGet”Sets the MutableRef to a new value and returns the new value.
When to use
Use to replace the current MutableRef value and immediately read the
replacement.
Example (Setting and reading values)
import { MutableRef } from "effect"
const ref = MutableRef.make("old")
// Set and get the new valueconst newValue = MutableRef.setAndGet(ref, "new")console.log(newValue) // "new"console.log(MutableRef.get(ref)) // "new"
// Useful for assignments that need the valueconst counter = MutableRef.make(0)const currentValue = MutableRef.setAndGet(counter, 42)console.log(`Counter set to: ${currentValue}`) // "Counter set to: 42"
// Pipe-able versionconst setValue = MutableRef.setAndGet("final")const result = setValue(ref)console.log(result) // "final"
// Difference from set: returns value instead of referenceconst ref1 = MutableRef.make(1)const returnedRef = MutableRef.set(ref1, 2) // Returns MutableRefconst returnedValue = MutableRef.setAndGet(ref1, 3) // Returns valueconsole.log(returnedValue) // 3Signature
declare const setAndGet: { <T>(value: T): (self: MutableRef<T>) => T; <T>(self: MutableRef<T>, value: T): T }Since v2.0.0
update
Section titled “update”Updates the MutableRef with the result of applying a function to its current value, and returns the reference.
When to use
Use when you need an in-place MutableRef value transformation that returns
the same MutableRef.
Example (Updating values)
import { MutableRef } from "effect"
const counter = MutableRef.make(5)
// Increment the counterMutableRef.update(counter, (n) => n + 1)console.log(MutableRef.get(counter)) // 6
// Chain updates (since it returns the ref)const result = MutableRef.update(counter, (n) => n * 2)console.log(result === counter) // true (same reference)console.log(MutableRef.get(counter)) // 12
// Transform stringconst message = MutableRef.make("hello")MutableRef.update(message, (s) => s.toUpperCase())console.log(MutableRef.get(message)) // "HELLO"
// Update complex objectsconst user = MutableRef.make({ name: "Alice", age: 30 })MutableRef.update(user, (u) => ({ ...u, age: u.age + 1 }))console.log(MutableRef.get(user)) // { name: "Alice", age: 31 }
// Pipe-able versionconst double = MutableRef.update((n: number) => n * 2)double(counter)console.log(MutableRef.get(counter)) // 24
// Array operationsconst list = MutableRef.make<Array<number>>([1, 2, 3])MutableRef.update(list, (arr) => [...arr, 4])console.log(MutableRef.get(list)) // [1, 2, 3, 4]Signature
declare const update: { <T>(f: (value: T) => T): (self: MutableRef<T>) => MutableRef<T> <T>(self: MutableRef<T>, f: (value: T) => T): MutableRef<T>}Since v2.0.0
updateAndGet
Section titled “updateAndGet”Updates the MutableRef with the result of applying a function to its current value, and returns the new value.
When to use
Use to transform the current MutableRef value and immediately read the
updated value.
Example (Updating and reading values)
import { MutableRef } from "effect"
const counter = MutableRef.make(5)
// Increment and get the new valueconst newValue = MutableRef.updateAndGet(counter, (n) => n + 1)console.log(newValue) // 6console.log(MutableRef.get(counter)) // 6
// Double the value and get the resultconst doubled = MutableRef.updateAndGet(counter, (n) => n * 2)console.log(doubled) // 12
// Transform string and get resultconst message = MutableRef.make("hello")const upperCase = MutableRef.updateAndGet(message, (s) => s.toUpperCase())console.log(upperCase) // "HELLO"
// Pipe-able versionconst increment = MutableRef.updateAndGet((n: number) => n + 1)const result = increment(counter)console.log(result) // 13 (new value)
// Useful for calculations that need the resultconst score = MutableRef.make(100)const bonus = 50const newScore = MutableRef.updateAndGet(score, (s) => s + bonus)console.log(`New score: ${newScore}`) // "New score: 150"
// Array transformationsconst list = MutableRef.make<Array<number>>([1, 2, 3])const newList = MutableRef.updateAndGet(list, (arr) => arr.map((x) => x * 2))console.log(newList) // [2, 4, 6]console.log(MutableRef.get(list)) // [2, 4, 6]Signature
declare const updateAndGet: { <T>(f: (value: T) => T): (self: MutableRef<T>) => T <T>(self: MutableRef<T>, f: (value: T) => T): T}Since v2.0.0
models
Section titled “models”MutableRef (interface)
Section titled “MutableRef (interface)”A synchronous mutable reference that stores a current value.
When to use
Use to keep local mutable state in a stable, pipeable reference.
Details
Read or write the value directly through .current, or use the MutableRef
helpers for pipeable updates such as get, set, update, and
compareAndSet. All operations mutate the same reference in place.
Example (Creating and updating refs)
import { MutableRef } from "effect"
// Create a mutable referenceconst ref: MutableRef.MutableRef<number> = MutableRef.make(42)
// Read the current valueconsole.log(ref.current) // 42console.log(MutableRef.get(ref)) // 42
// Update the valueref.current = 100console.log(MutableRef.get(ref)) // 100
// Use with complex typesinterface Config { timeout: number retries: number}
const config: MutableRef.MutableRef<Config> = MutableRef.make({ timeout: 5000, retries: 3})
// Update through the interfaceconfig.current = { timeout: 10000, retries: 5 }console.log(config.current.timeout) // 10000Signature
export interface MutableRef<out T> extends Pipeable, Inspectable { readonly [TypeId]: typeof TypeId current: T}Since v2.0.0
numeric
Section titled “numeric”decrement
Section titled “decrement”Decrements a numeric MutableRef by 1 and returns the reference.
When to use
Use when you need an in-place MutableRef decrement that returns the same
MutableRef.
Example (Decrementing numeric refs)
import { MutableRef } from "effect"
const counter = MutableRef.make(5)
// Decrement the counterMutableRef.decrement(counter)console.log(MutableRef.get(counter)) // 4
// Chain operationsMutableRef.decrement(counter)MutableRef.decrement(counter)console.log(MutableRef.get(counter)) // 2
// Useful for countdown scenariosconst countdown = MutableRef.make(10)while (MutableRef.get(countdown) > 0) { console.log(MutableRef.get(countdown)) MutableRef.decrement(countdown)}Signature
declare const decrement: (self: MutableRef<number>) => MutableRef<number>Since v2.0.0
decrementAndGet
Section titled “decrementAndGet”Decrements a numeric MutableRef by 1 and returns the new value.
When to use
Use to decrement a numeric MutableRef and immediately read the updated
value.
Example (Decrementing and reading refs)
import { MutableRef } from "effect"
const counter = MutableRef.make(5)
// Decrement and get the new valueconst newValue = MutableRef.decrementAndGet(counter)console.log(newValue) // 4console.log(MutableRef.get(counter)) // 4
// Use in expressionsconst lives = MutableRef.make(3)console.log(`Lives remaining: ${MutableRef.decrementAndGet(lives)}`) // "Lives remaining: 2"
// Conditional logic based on decremented valueconst attempts = MutableRef.make(3)while (MutableRef.decrementAndGet(attempts) >= 0) { console.log("Retrying...") // retry logic}Signature
declare const decrementAndGet: (self: MutableRef<number>) => numberSince v2.0.0
getAndDecrement
Section titled “getAndDecrement”Decrements a numeric MutableRef by 1 and returns the previous value.
When to use
Use to read the current numeric MutableRef value before decrementing it.
Example (Reading before decrementing)
import { MutableRef } from "effect"
const counter = MutableRef.make(5)
// Get current value and then decrementconst previousValue = MutableRef.getAndDecrement(counter)console.log(previousValue) // 5console.log(MutableRef.get(counter)) // 4
// Useful for processing where you need the original valueconst itemsLeft = MutableRef.make(10)while (MutableRef.get(itemsLeft) > 0) { const currentItem = MutableRef.getAndDecrement(itemsLeft) console.log(`Processing item ${currentItem}`)}
// Post-decrement semantics (like i-- in other languages)const index = MutableRef.make(3)const currentIndex = MutableRef.getAndDecrement(index)console.log(`Current: ${currentIndex}, Next: ${MutableRef.get(index)}`) // "Current: 3, Next: 2"Signature
declare const getAndDecrement: (self: MutableRef<number>) => numberSince v2.0.0
getAndIncrement
Section titled “getAndIncrement”Increments a numeric MutableRef by 1 and returns the previous value.
When to use
Use to read the current numeric MutableRef value before incrementing it.
Example (Reading before incrementing)
import { MutableRef } from "effect"
const counter = MutableRef.make(5)
// Get current value and then incrementconst previousValue = MutableRef.getAndIncrement(counter)console.log(previousValue) // 5console.log(MutableRef.get(counter)) // 6
// Useful for ID generationconst idGenerator = MutableRef.make(0)const getId = () => MutableRef.getAndIncrement(idGenerator)
console.log(getId()) // 0console.log(getId()) // 1console.log(getId()) // 2
// Post-increment semantics (like i++ in other languages)const position = MutableRef.make(0)const currentPos = MutableRef.getAndIncrement(position)console.log(`Was at: ${currentPos}, Now at: ${MutableRef.get(position)}`) // "Was at: 0, Now at: 1"
// Useful for iteration countersconst iterations = MutableRef.make(0)while (MutableRef.get(iterations) < 5) { const iteration = MutableRef.getAndIncrement(iterations) console.log(`Iteration ${iteration}`)}Signature
declare const getAndIncrement: (self: MutableRef<number>) => numberSince v2.0.0
increment
Section titled “increment”Increments a numeric MutableRef by 1 and returns the reference.
When to use
Use when you need an in-place MutableRef increment that returns the same
MutableRef.
Example (Incrementing numeric refs)
import { MutableRef } from "effect"
const counter = MutableRef.make(5)
// Increment the counterMutableRef.increment(counter)console.log(MutableRef.get(counter)) // 6
// Chain operationsMutableRef.increment(counter)MutableRef.increment(counter)console.log(MutableRef.get(counter)) // 8
// Useful for simple countingconst visits = MutableRef.make(0)MutableRef.increment(visits) // User visitedMutableRef.increment(visits) // Another visitconsole.log(MutableRef.get(visits)) // 2
// Returns the reference for chainingconst result = MutableRef.increment(counter)console.log(result === counter) // trueSignature
declare const increment: (self: MutableRef<number>) => MutableRef<number>Since v2.0.0
incrementAndGet
Section titled “incrementAndGet”Increments a numeric MutableRef by 1 and returns the new value.
When to use
Use to increment a numeric MutableRef and immediately read the updated
value.
Example (Incrementing and reading refs)
import { MutableRef } from "effect"
const counter = MutableRef.make(5)
// Increment and get the new valueconst newValue = MutableRef.incrementAndGet(counter)console.log(newValue) // 6console.log(MutableRef.get(counter)) // 6
// Use in expressionsconst score = MutableRef.make(100)console.log(`New score: ${MutableRef.incrementAndGet(score)}`) // "New score: 101"
// Pre-increment semantics (like ++i in other languages)const level = MutableRef.make(0)const nextLevel = MutableRef.incrementAndGet(level)console.log(`Reached level ${nextLevel}`) // "Reached level 1"
// Conditional logic based on incremented valueconst attempts = MutableRef.make(0)if (MutableRef.incrementAndGet(attempts) > 3) { console.log("Too many attempts")}Signature
declare const incrementAndGet: (self: MutableRef<number>) => numberSince v2.0.0