Skip to content
Effect Days 2026 Get your ticket

TxHashMap

Transactional hash maps for storing and updating key-value pairs inside Effect transactions.

A TxHashMap stores an immutable HashMap in a TxRef, so map reads and writes can commit atomically with other transactional operations. Use it for shared registries, counters, indexes, and other maps that need safe read-modify-write sequences alongside related transactional state.

38 exports Added in v2.0.0 Source

Combinators

clear

Added in v4.0.0 Source

Removes all entries from the TxHashMap.

Details

This function mutates the original TxHashMap by clearing all key-value pairs. It does not return a new TxHashMap reference.

Signature

declare function clear<K, V>(self: TxHashMap<K, V>): Effect<void>

Example

(Clearing all entries)

import { Effect, TxHashMap } from "effect"
const program = Effect.gen(function*() {
const sessionMap = yield* TxHashMap.make(
["session1", { userId: "alice", expires: "2024-01-01T12:00:00Z" }],
["session2", { userId: "bob", expires: "2024-01-01T13:00:00Z" }],
["session3", { userId: "charlie", expires: "2024-01-01T14:00:00Z" }]
)
// Check initial state
yield* TxHashMap.size(sessionMap) // => 3
// Clear all sessions (e.g., during maintenance)
yield* TxHashMap.clear(sessionMap)
// Verify cleared
yield* TxHashMap.size(sessionMap) // => 0
return yield* TxHashMap.isEmpty(sessionMap)
})
await Effect.runPromise(program) // => true

compact

Added in v4.0.0 Source

Removes all None values from a TxHashMap containing Option values.

Details

This function returns a new TxHashMap reference with only the Some values unwrapped. The original TxHashMap is not modified.

Signature

declare function compact<K, A>(self: TxHashMap<K, Option<A>>): Effect<TxHashMap<K, A>>

Example

(Compacting optional values)

import { Effect, Option, TxHashMap } from "effect"
const program = Effect.gen(function*() {
// Create a map with optional user data
const userData = yield* TxHashMap.make<
string,
Option.Option<{ age: number; email?: string }>
>(
["alice", Option.some({ age: 30, email: "alice@example.com" })],
["bob", Option.none()], // incomplete data
["charlie", Option.some({ age: 25 })],
["diana", Option.none()], // missing data
["eve", Option.some({ age: 28, email: "eve@example.com" })]
)
// Remove all None values and unwrap Some values
const validUsers = yield* TxHashMap.compact(userData)
yield* TxHashMap.size(validUsers) // => 3
yield* TxHashMap.get(validUsers, "alice") // => Option.some({ age: 30, email: "alice@example.com" })
yield* TxHashMap.get(validUsers, "bob") // => Option.none()
// Useful for cleaning up optional data processing results
const userAges = yield* TxHashMap.map(validUsers, (user) => user.age)
return (yield* TxHashMap.entries(userAges)).toSorted(([left], [right]) => left.localeCompare(right))
})
await Effect.runPromise(program) // => [["alice", 30], ["charlie", 25], ["eve", 28]]

entries

Added in v4.0.0 Source

Returns an array of all key-value pairs in the TxHashMap.

Signature

declare function entries<K, V>(self: TxHashMap<K, V>): Effect<Array<readonly [K, V]>>

Example

(Reading entries)

import { Effect, TxHashMap } from "effect"
const program = Effect.gen(function*() {
const config = yield* TxHashMap.make(
["host", "localhost"],
["port", "3000"],
["ssl", "false"]
)
return (yield* TxHashMap.entries(config)).toSorted(([left], [right]) => left.localeCompare(right))
})
await Effect.runPromise(program) // => [["host", "localhost"], ["port", "3000"], ["ssl", "false"]]

filter

Added in v4.0.0 Source

Filters the TxHashMap to keep only entries that satisfy the provided predicate.

Details

This function returns a new TxHashMap reference containing only the entries that match the condition. The original TxHashMap is not modified.

Signature

declare const filter: {
<K, V, B>(predicate: (value: V, key: K) => value is B): (self: TxHashMap<K, V>) => Effect<TxHashMap<K, B>>;
<K, V>(predicate: (value: V, key: K) => boolean): (self: TxHashMap<K, V>) => Effect<TxHashMap<K, V>>;
<K, V, B>(self: TxHashMap<K, V>, predicate: (value: V, key: K) => value is B): Effect<TxHashMap<K, B>>;
<K, V>(self: TxHashMap<K, V>, predicate: (value: V, key: K) => boolean): Effect<TxHashMap<K, V>>;
}

Example

(Filtering entries)

import { Effect, TxHashMap } from "effect"
const program = Effect.gen(function*() {
// Create a product inventory
const inventory = yield* TxHashMap.make(
["laptop", { price: 999, stock: 5, category: "electronics" }],
["mouse", { price: 29, stock: 50, category: "electronics" }],
["book", { price: 15, stock: 100, category: "books" }],
["phone", { price: 699, stock: 0, category: "electronics" }]
)
// Filter to get only electronics in stock
const electronicsInStock = yield* TxHashMap.filter(
inventory,
(product) => product.category === "electronics" && product.stock > 0
)
yield* TxHashMap.size(electronicsInStock) // => 2
// Data-last usage with pipe
const expensiveItems = yield* inventory.pipe(
TxHashMap.filter((product) => product.price > 500)
)
yield* TxHashMap.size(expensiveItems) // => 2
// Type guard usage
return yield* TxHashMap.filter(
inventory,
(product): product is typeof product & { price: number } =>
product.price > 50
)
})
await Effect.runPromise(program)

filterMap

Added in v4.0.0 Source

Combines filtering and mapping in a single operation. Applies a filter to each entry, keeping only successful results and transforming them.

Details

This function returns a new TxHashMap reference containing only the transformed entries that succeeded. The original TxHashMap is not modified.

Signature

declare const filterMap: {
<V, K, A, X>(f: (input: V, key: K) => Result<A, X>): (self: TxHashMap<K, V>) => Effect<TxHashMap<K, A>>;
<K, V, A, X>(self: TxHashMap<K, V>, f: (input: V, key: K) => Result<A, X>): Effect<TxHashMap<K, A>>;
}

Example

(Filtering and mapping entries)

import { Effect, Option, Result, TxHashMap } from "effect"
const program = Effect.gen(function*() {
// Create a mixed data map
const userData = yield* TxHashMap.make(
["alice", { age: "30", role: "admin", active: true }],
["bob", { age: "invalid", role: "user", active: true }],
["charlie", { age: "25", role: "admin", active: false }],
["diana", { age: "28", role: "user", active: true }]
)
// Extract valid ages for active admin users only
const activeAdminAges = yield* TxHashMap.filterMap(
userData,
(user, username) => {
if (!user.active || user.role !== "admin") return Result.failVoid
const age = parseInt(user.age)
if (isNaN(age)) return Result.failVoid
return Result.succeed({
username,
age,
seniority: age > 27 ? "senior" : "junior"
})
}
)
const aliceData = yield* TxHashMap.get(activeAdminAges, "alice")
aliceData // => Option.some({ username: "alice", age: 30, seniority: "senior" })
yield* TxHashMap.get(activeAdminAges, "charlie") // => Option.none()
// Data-last usage with pipe
const validAges = yield* userData.pipe(
TxHashMap.filterMap((user) => {
const age = parseInt(user.age)
return isNaN(age) ? Result.failVoid : Result.succeed(age)
})
)
return yield* TxHashMap.size(validAges)
})
await Effect.runPromise(program) // => 3

findFirst

Added in v4.0.0 Source

Finds the first entry in the TxHashMap that matches the given predicate. Returns the key-value pair as a tuple wrapped in an Option.

Signature

declare const findFirst: {
<K, V>(predicate: (value: V, key: K) => boolean): (self: TxHashMap<K, V>) => Effect<Option<[K, V]>>;
<K, V>(self: TxHashMap<K, V>, predicate: (value: V, key: K) => boolean): Effect<Option<[K, V]>>;
}

Example

(Finding the first matching entry)

import { Effect, Option, TxHashMap } from "effect"
const program = Effect.gen(function*() {
// Create a task priority map
const tasks = yield* TxHashMap.make(
["task1", { priority: 1, assignee: "alice", completed: false }],
["task2", { priority: 3, assignee: "bob", completed: true }],
["task3", { priority: 2, assignee: "alice", completed: false }]
)
// Find first high-priority incomplete task
const highPriorityTask = yield* TxHashMap.findFirst(
tasks,
(task) => task.priority >= 2 && !task.completed
)
highPriorityTask // => Option.some(["task3", { priority: 2, assignee: "alice", completed: false }])
// Find first task assigned to specific user
return yield* tasks.pipe(
TxHashMap.findFirst((task) => task.assignee === "alice")
)
})
await Effect.runPromise(program) // => Option.some(["task1", { priority: 1, assignee: "alice", completed: false }])

flatMap

Added in v4.0.0 Source

Maps each entry effectfully to a TxHashMap and flattens the produced maps.

Details

This function returns a new TxHashMap reference with the flattened results. The original TxHashMap is not modified.

Signature

declare const flatMap: {
<A, V, K>(f: (value: V, key: K) => Effect<TxHashMap<K, A>>): (self: TxHashMap<K, V>) => Effect<TxHashMap<K, A>>;
<K, V, A>(self: TxHashMap<K, V>, f: (value: V, key: K) => Effect<TxHashMap<K, A>>): Effect<TxHashMap<K, A>>;
}

Example

(Flat mapping entries)

import { Effect, Option, TxHashMap } from "effect"
const program = Effect.gen(function*() {
// Create a department-employee map
const departments = yield* TxHashMap.make(
["engineering", ["alice", "bob"]],
["marketing", ["charlie", "diana"]]
)
// Expand each department into individual employee entries with metadata
const employeeDetails = yield* TxHashMap.flatMap(
departments,
(employees, department) =>
Effect.gen(function*() {
const employeeMap = yield* TxHashMap.empty<
string,
{ department: string; role: string }
>()
for (let i = 0; i < employees.length; i++) {
const employee = employees[i]
const role = i === 0 ? "lead" : "member"
yield* TxHashMap.set(employeeMap, employee, { department, role })
}
return employeeMap
})
)
// Check the flattened result
yield* TxHashMap.get(employeeDetails, "alice") // => Option.some({ department: "engineering", role: "lead" })
yield* TxHashMap.get(employeeDetails, "charlie") // => Option.some({ department: "marketing", role: "lead" })
return yield* TxHashMap.size(employeeDetails)
})
await Effect.runPromise(program) // => 4

forEach

Added in v2.0.0 Source

Executes a side-effect function for each entry in the TxHashMap. The function receives the value and key as parameters and can perform effects.

Signature

declare const forEach: {
<V, K, R, E>(f: (value: V, key: K) => Effect<void, E, R>): (self: TxHashMap<K, V>) => Effect<void, E, R>;
<K, V, R, E>(self: TxHashMap<K, V>, f: (value: V, key: K) => Effect<void, E, R>): Effect<void, E, R>;
}

Example

(Running effects for each entry)

import { Effect, TxHashMap } from "effect"
const program = Effect.gen(function*() {
// Create a log processing map
const logs = yield* TxHashMap.make(
["error.log", { size: 1024, level: "error" }],
["access.log", { size: 2048, level: "info" }],
["debug.log", { size: 512, level: "debug" }]
)
const messages: Array<string> = []
yield* TxHashMap.forEach(logs, (logInfo, filename) =>
Effect.sync(() => {
messages.push(`${filename}: ${logInfo.size} bytes (${logInfo.level})`)
}))
return messages.sort()
})
const result = await Effect.runPromise(program)
result // => ["access.log: 2048 bytes (info)", "debug.log: 512 bytes (debug)", "error.log: 1024 bytes (error)"]

get

Added in v2.0.0 Source

Looks up the value for the specified key in the TxHashMap.

Signature

declare const get: {
<K1, K>(key: K1): <V>(self: TxHashMap<K, V>) => Effect<Option<V>>;
<K1, K, V>(self: TxHashMap<K, V>, key: K1): Effect<Option<V>>;
}

Example

(Looking up values safely)

import { Effect, Option, TxHashMap } from "effect"
const program = Effect.gen(function*() {
const userMap = yield* TxHashMap.make(
["alice", { name: "Alice", role: "admin" }],
["bob", { name: "Bob", role: "user" }]
)
// Safe lookup - returns Option
yield* TxHashMap.get(userMap, "alice") // => Option.some({ name: "Alice", role: "admin" })
yield* TxHashMap.get(userMap, "charlie") // => Option.none()
// Use with pipe syntax for type-safe access
return yield* TxHashMap.get(userMap, "bob")
})
await Effect.runPromise(program) // => Option.some({ name: "Bob", role: "user" })

getHash

Added in v4.0.0 Source

Looks up the value for the specified key using a caller-supplied hash.

Gotchas

The supplied hash must be the hash for the same key, such as a precomputed Hash.hash(key) value. If the hash does not match the key, an existing entry may not be found.

Signature

declare const getHash: {
<K1, K>(key: K1, hash: number): <V>(self: TxHashMap<K, V>) => Effect<Option<V>>;
<K1, K, V>(self: TxHashMap<K, V>, key: K1, hash: number): Effect<Option<V>>;
}

Example

(Looking up values with precomputed hashes)

import { Effect, Hash, Option, TxHashMap } from "effect"
const program = Effect.gen(function*() {
// Create a cache with user sessions
const cache = yield* TxHashMap.make(
["session_abc123", { userId: "user1", lastActive: 1_700_000_000_000 }],
["session_def456", { userId: "user2", lastActive: 1_700_000_060_000 }]
)
// When you have precomputed hash (e.g., from another lookup)
const sessionId = "session_abc123"
const precomputedHash = Hash.string(sessionId)
// Use hash-optimized lookup for performance in hot paths
const session = yield* TxHashMap.getHash(cache, sessionId, precomputedHash)
session // => Option.some({ userId: "user1", lastActive: 1_700_000_000_000 })
// This avoids recomputing the hash when you already have it
return yield* TxHashMap.getHash(
cache,
"invalid",
Hash.string("invalid")
)
})
await Effect.runPromise(program) // => Option.none()

keys

Added in v2.0.0 Source

Returns an array of all keys in the TxHashMap.

Signature

declare function keys<K, V>(self: TxHashMap<K, V>): Effect<Array<K>>

Example

(Reading keys)

import { Effect, Option, TxHashMap } from "effect"
const program = Effect.gen(function*() {
const userRoles = yield* TxHashMap.make(
["alice", "admin"],
["bob", "user"],
["charlie", "moderator"]
)
const usernames = (yield* TxHashMap.keys(userRoles)).sort()
usernames // => ["alice", "bob", "charlie"]
// Useful for iteration
const assignments: Array<string> = []
for (const username of usernames) {
const role = yield* TxHashMap.get(userRoles, username)
if (role._tag === "Some") {
assignments.push(`${username}: ${role.value}`)
}
}
return assignments
})
await Effect.runPromise(program) // => ["alice: admin", "bob: user", "charlie: moderator"]

map

Added in v4.0.0 Source

Transforms all values in the TxHashMap using the provided function, preserving keys.

Details

This function returns a new TxHashMap reference with the transformed values. The original TxHashMap is not modified.

Signature

declare const map: {
<A, V, K>(f: (value: V, key: K) => A): (self: TxHashMap<K, V>) => Effect<TxHashMap<K, A>>;
<K, V, A>(self: TxHashMap<K, V>, f: (value: V, key: K) => A): Effect<TxHashMap<K, A>>;
}

Example

(Mapping values)

import { Effect, Option, TxHashMap } from "effect"
const program = Effect.gen(function*() {
// Create a user profile map
const profiles = yield* TxHashMap.make(
["alice", { name: "Alice", age: 30, active: true }],
["bob", { name: "Bob", age: 25, active: false }],
["charlie", { name: "Charlie", age: 35, active: true }]
)
// Transform to extract just names with greeting
const greetings = yield* TxHashMap.map(
profiles,
(profile, userId) => `Hello, ${profile.name}! (User: ${userId})`
)
// Check the transformed values
yield* TxHashMap.get(greetings, "alice") // => Option.some("Hello, Alice! (User: alice)")
// Data-last usage with pipe
const ages = yield* profiles.pipe(
TxHashMap.map((profile) => profile.age)
)
yield* TxHashMap.get(ages, "alice") // => Option.some(30)
// Original map is unchanged
return yield* TxHashMap.get(profiles, "alice")
})
await Effect.runPromise(program) // => Option.some({ name: "Alice", age: 30, active: true })

modify

Added in v4.0.0 Source

Updates the value for the specified key if it exists, returning the previous value in Some; returns None and leaves the map unchanged when the key is absent.

Details

This function mutates the original TxHashMap by updating the value at the specified key. It does not return a new TxHashMap reference.

Signature

declare const modify: {
<K, V>(key: K, f: (value: V) => V): (self: TxHashMap<K, V>) => Effect<Option<V>>;
<K, V>(self: TxHashMap<K, V>, key: K, f: (value: V) => V): Effect<Option<V>>;
}

Example

(Updating existing values)

import { Effect, Option, TxHashMap } from "effect"
const program = Effect.gen(function*() {
const counters = yield* TxHashMap.make(
["downloads", 100],
["views", 250]
)
// Increment existing counter
const oldDownloads = yield* TxHashMap.modify(
counters,
"downloads",
(count) => count + 1
)
oldDownloads // => Option.some(100)
yield* TxHashMap.get(counters, "downloads") // => Option.some(101)
// Try to modify non-existent key
const nonExistent = yield* TxHashMap.modify(
counters,
"clicks",
(count) => count + 1
)
nonExistent // => Option.none()
// Update views counter with direct method call
yield* TxHashMap.modify(counters, "views", (views) => views * 2)
return yield* TxHashMap.get(counters, "views")
})
await Effect.runPromise(program) // => Option.some(500)

modifyAt

Added in v4.0.0 Source

Updates the value for the specified key using an Option-based update function.

Details

This function mutates the original TxHashMap by updating, adding, or removing the key-value pair based on the function result. It does not return a new TxHashMap reference.

Signature

declare const modifyAt: {
<K, V>(key: K, f: (value: Option<V>) => Option<V>): (self: TxHashMap<K, V>) => Effect<void>;
<K, V>(self: TxHashMap<K, V>, key: K, f: (value: Option<V>) => Option<V>): Effect<void>;
}

Example

(Updating values with Option)

import { Effect, Option, TxHashMap } from "effect"
const program = Effect.gen(function*() {
const storage = yield* TxHashMap.make<string, string | number>([
"file1.txt",
"content1"
], ["access_count", 0])
const increment = Option.map((value: string | number) => typeof value === "number" ? value + 1 : value)
// Increment existing counter
yield* TxHashMap.modifyAt(storage, "access_count", increment)
yield* TxHashMap.get(storage, "access_count") // => Option.some(1)
// Increment existing counter again
yield* TxHashMap.modifyAt(storage, "access_count", increment)
yield* TxHashMap.get(storage, "access_count") // => Option.some(2)
// Update an existing string entry
yield* TxHashMap.modifyAt(
storage,
"file1.txt",
Option.map((value) => typeof value === "string" ? `${value}.bak` : value)
)
return yield* TxHashMap.get(storage, "file1.txt")
})
await Effect.runPromise(program) // => Option.some("content1.bak")

reduce

Added in v2.0.0 Source

Reduces the TxHashMap entries to a single value by applying a reducer function. Iterates over all key-value pairs and accumulates them into a final result.

Signature

declare const reduce: {
<A, V, K>(zero: A, f: (accumulator: A, value: V, key: K) => A): (self: TxHashMap<K, V>) => Effect<A>;
<K, V, A>(self: TxHashMap<K, V>, zero: A, f: (accumulator: A, value: V, key: K) => A): Effect<A>;
}

Example

(Reducing entries)

import { Effect, TxHashMap } from "effect"
const program = Effect.gen(function*() {
// Create a sales data map
const sales = yield* TxHashMap.make(
["Q1", 15000],
["Q2", 18000],
["Q3", 22000],
["Q4", 25000]
)
// Calculate total sales
const totalSales = yield* TxHashMap.reduce(
sales,
0,
(total, amount) => total + amount
)
totalSales // => 80000
// Data-last usage with pipe
const quarterlyReport = yield* sales.pipe(
TxHashMap.reduce(
{ quarters: 0, total: 0, max: 0 },
(report, amount, quarter) => ({
quarters: report.quarters + 1,
total: report.total + amount,
max: Math.max(report.max, amount)
})
)
)
return quarterlyReport
})
await Effect.runPromise(program) // => { quarters: 4, total: 80000, max: 25000 }

remove

Added in v2.0.0 Source

Removes the specified key from the TxHashMap.

Details

This function mutates the original TxHashMap by removing the specified key-value pair. It does not return a new TxHashMap reference.

Signature

declare const remove: {
<K1, K>(key: K1): <V>(self: TxHashMap<K, V>) => Effect<boolean>;
<K1, K, V>(self: TxHashMap<K, V>, key: K1): Effect<boolean>;
}

Example

(Removing keys)

import { Effect, TxHashMap } from "effect"
const program = Effect.gen(function*() {
const cache = yield* TxHashMap.make(
["user:1", { name: "Alice", lastSeen: "2024-01-01" }],
["user:2", { name: "Bob", lastSeen: "2024-01-02" }],
["user:3", { name: "Charlie", lastSeen: "2023-12-30" }]
)
// Remove expired user
yield* TxHashMap.remove(cache, "user:3") // => true
// Try to remove non-existent key
yield* TxHashMap.remove(cache, "user:999") // => false
// Verify removal
yield* TxHashMap.has(cache, "user:3") // => false
return yield* TxHashMap.size(cache)
})
await Effect.runPromise(program) // => 2

removeMany

Added in v4.0.0 Source

Removes multiple keys from the TxHashMap.

Details

This function mutates the original TxHashMap by removing all specified keys. It does not return a new TxHashMap reference.

Signature

declare const removeMany: {
<K1, K>(keys: Iterable<K1>): <V>(self: TxHashMap<K, V>) => Effect<void>;
<K1, K, V>(self: TxHashMap<K, V>, keys: Iterable<K1>): Effect<void>;
}

Example

(Removing multiple keys)

import { Effect, Option, TxHashMap } from "effect"
const program = Effect.gen(function*() {
// Create a cache with temporary data
const cache = yield* TxHashMap.make(
["session_1", { user: "alice", expires: "2024-01-01" }],
["session_2", { user: "bob", expires: "2024-01-01" }],
["session_3", { user: "charlie", expires: "2024-12-31" }],
["temp_data_1", { value: "temporary" }],
["temp_data_2", { value: "also_temporary" }]
)
yield* TxHashMap.size(cache) // => 5
// Remove expired sessions and temporary data
const keysToRemove = ["session_1", "session_2", "temp_data_1", "temp_data_2"]
yield* TxHashMap.removeMany(cache, keysToRemove)
yield* TxHashMap.size(cache) // => 1
// Verify only the valid session remains
yield* TxHashMap.get(cache, "session_3") // => Option.some({ user: "charlie", expires: "2024-12-31" })
// Can also remove from Set, Array, or any iterable
const moreKeysToRemove = new Set(["session_3"])
yield* TxHashMap.removeMany(cache, moreKeysToRemove)
return yield* TxHashMap.isEmpty(cache)
})
await Effect.runPromise(program) // => true

set

Added in v2.0.0 Source

Sets the value for the specified key in the TxHashMap.

Details

This function mutates the original TxHashMap by updating its internal state. It does not return a new TxHashMap reference.

Signature

declare const set: {
<K, V>(key: K, value: V): (self: TxHashMap<K, V>) => Effect<void>;
<K, V>(self: TxHashMap<K, V>, key: K, value: V): Effect<void>;
}

Example

(Setting values)

import { Effect, Option, TxHashMap } from "effect"
const program = Effect.gen(function*() {
const inventory = yield* TxHashMap.make(
["laptop", 5],
["mouse", 20]
)
// Update existing item
yield* TxHashMap.set(inventory, "laptop", 3)
yield* TxHashMap.get(inventory, "laptop") // => Option.some(3)
// Add new item
yield* TxHashMap.set(inventory, "keyboard", 15)
yield* TxHashMap.get(inventory, "keyboard") // => Option.some(15)
// Use with pipe syntax
yield* TxHashMap.set("tablet", 8)(inventory)
return yield* TxHashMap.get(inventory, "tablet")
})
await Effect.runPromise(program) // => Option.some(8)

setMany

Added in v4.0.0 Source

Sets multiple key-value pairs in the TxHashMap.

Details

This function mutates the original TxHashMap by setting all provided key-value pairs. It does not return a new TxHashMap reference.

Signature

declare const setMany: {
<K1, K, V1, V>(entries: Iterable<readonly [K1, V1]>): (self: TxHashMap<K, V>) => Effect<void>;
<K1, K, V1, V>(self: TxHashMap<K, V>, entries: Iterable<readonly [K1, V1]>): Effect<void>;
}

Example

(Setting multiple entries)

import { Effect, Option, TxHashMap } from "effect"
const program = Effect.gen(function*() {
// Create an empty product catalog
const catalog = yield* TxHashMap.empty<
string,
{ price: number; stock: number }
>()
// Bulk load initial products
const initialProducts: Array<
readonly [string, { price: number; stock: number }]
> = [
["laptop", { price: 999, stock: 5 }],
["mouse", { price: 29, stock: 50 }],
["keyboard", { price: 79, stock: 20 }],
["monitor", { price: 299, stock: 8 }]
]
yield* TxHashMap.setMany(catalog, initialProducts)
yield* TxHashMap.size(catalog) // => 4
// Update prices with a new batch
const priceUpdates: Array<
readonly [string, { price: number; stock: number }]
> = [
["laptop", { price: 899, stock: 5 }], // sale price
["mouse", { price: 25, stock: 50 }], // sale price
["webcam", { price: 89, stock: 12 }] // new product
]
yield* TxHashMap.setMany(catalog, priceUpdates)
yield* TxHashMap.size(catalog) // => 5
// Verify the updates
yield* TxHashMap.get(catalog, "laptop") // => Option.some({ price: 899, stock: 5 })
// Can also use Map, Set of tuples, or any iterable of entries
const jsMap = new Map([["tablet", { price: 399, stock: 3 }]])
yield* TxHashMap.setMany(catalog, jsMap)
return yield* TxHashMap.get(catalog, "tablet")
})
await Effect.runPromise(program) // => Option.some({ price: 399, stock: 3 })

size

Added in v2.0.0 Source

Returns the number of entries in the TxHashMap.

Signature

declare function size<K, V>(self: TxHashMap<K, V>): Effect<number>

Example

(Counting entries)

import { Effect, TxHashMap } from "effect"
const program = Effect.gen(function*() {
const metrics = yield* TxHashMap.make(
["requests", 1000],
["errors", 5],
["users", 50]
)
yield* TxHashMap.size(metrics) // => 3
// Add more metrics
yield* TxHashMap.set(metrics, "response_time", 250)
yield* TxHashMap.size(metrics) // => 4
// Remove a metric
yield* TxHashMap.remove(metrics, "errors")
return yield* TxHashMap.size(metrics)
})
await Effect.runPromise(program) // => 3

snapshot

Added in v4.0.0 Source

Returns an immutable snapshot of the current TxHashMap state.

Signature

declare function snapshot<K, V>(self: TxHashMap<K, V>): Effect<HashMap<K, V>>

Example

(Taking immutable snapshots)

import { Effect, HashMap, Option, TxHashMap } from "effect"
const program = Effect.gen(function*() {
const liveData = yield* TxHashMap.make(
["temperature", 22.5],
["humidity", 45.2],
["pressure", 1013.25]
)
// Take snapshot for reporting
const snapshot = yield* TxHashMap.snapshot(liveData)
// Continue modifying live data
yield* TxHashMap.set(liveData, "temperature", 23.1)
yield* TxHashMap.set(liveData, "wind_speed", 5.3)
// Snapshot remains unchanged
HashMap.size(snapshot) // => 3
HashMap.get(snapshot, "temperature") // => Option.some(22.5)
// Can use regular HashMap operations on snapshot
return HashMap.get(snapshot, "humidity")
})
await Effect.runPromise(program) // => Option.some(45.2)

union

Added in v4.0.0 Source

Merges another HashMap into this TxHashMap. If both maps contain the same key, the value from the other map will be used.

Details

This function mutates the original TxHashMap by merging the provided HashMap into it. It does not return a new TxHashMap reference.

Signature

declare const union: {
<K1, K, V1, V>(other: HashMap<K1, V1>): (self: TxHashMap<K, V>) => Effect<void>;
<K1, K, V1, V>(self: TxHashMap<K, V>, other: HashMap<K1, V1>): Effect<void>;
}

Example

(Merging HashMaps)

import { Effect, HashMap, Option, TxHashMap } from "effect"
const program = Effect.gen(function*() {
// Create initial user preferences
const userPrefs = yield* TxHashMap.make(
["theme", "light"],
["language", "en"],
["notifications", "enabled"]
)
// New preferences to merge in
const newSettings = HashMap.make(
["theme", "dark"], // will override existing
["timezone", "UTC"], // new setting
["sound", "enabled"] // new setting
)
// Merge the new settings
yield* TxHashMap.union(userPrefs, newSettings)
// Check the merged result
yield* TxHashMap.get(userPrefs, "theme") // => Option.some("dark")
yield* TxHashMap.get(userPrefs, "language") // => Option.some("en")
yield* TxHashMap.get(userPrefs, "timezone") // => Option.some("UTC")
return yield* TxHashMap.size(userPrefs)
})
await Effect.runPromise(program) // => 5

values

Added in v2.0.0 Source

Returns an array of all values in the TxHashMap.

Signature

declare function values<K, V>(self: TxHashMap<K, V>): Effect<Array<V>>

Example

(Reading values)

import { Effect, TxHashMap } from "effect"
const program = Effect.gen(function*() {
const scores = yield* TxHashMap.make(
["alice", 95],
["bob", 87],
["charlie", 92]
)
const allScores = (yield* TxHashMap.values(scores)).sort((a, b) => a - b)
allScores // => [87, 92, 95]
// Calculate average
const average = allScores.reduce((sum, score) => sum + score, 0) /
allScores.length
average.toFixed(2) // => "91.33"
// Find maximum
return Math.max(...allScores)
})
await Effect.runPromise(program) // => 95

Constructors

empty

Added in v2.0.0 Source

Creates an empty TxHashMap.

Signature

declare function empty<K, V>(): Effect<TxHashMap<K, V>>

Example

(Creating an empty map)

import { Effect, TxHashMap } from "effect"
const program = Effect.gen(function*() {
// Create an empty transactional hash map
const emptyMap = yield* TxHashMap.empty<string, number>()
// Verify it's empty
yield* TxHashMap.isEmpty(emptyMap) // => true
yield* TxHashMap.size(emptyMap) // => 0
// Start adding elements
yield* TxHashMap.set(emptyMap, "first", 1)
return yield* TxHashMap.size(emptyMap)
})
await Effect.runPromise(program) // => 1

fromIterable

Added in v2.0.0 Source

Creates a TxHashMap from an iterable of key-value pairs.

Signature

declare function fromIterable<K, V>(entries: Iterable<readonly [K, V]>): Effect<TxHashMap<K, V>>

Example

(Creating a map from an iterable)

import { Effect, Option, TxHashMap } from "effect"
const program = Effect.gen(function*() {
// Create from various iterable sources
const configEntries = [
["database.host", "localhost"],
["database.port", "5432"],
["cache.enabled", "true"],
["logging.level", "info"]
] as const
const configMap = yield* TxHashMap.fromIterable(configEntries)
// Verify the configuration was loaded
yield* TxHashMap.size(configMap) // => 4
yield* TxHashMap.get(configMap, "database.host") // => Option.some("localhost")
// Can also create from Map, Set of tuples, etc.
const jsMap = new Map([["key1", "value1"], ["key2", "value2"]])
return yield* TxHashMap.fromIterable(jsMap)
})
await Effect.runPromise(program)

make

Added in v2.0.0 Source

Creates a TxHashMap from the provided key-value pairs.

Signature

declare function make<K, V>(...entries: Array<readonly [K, V]>): Effect<TxHashMap<K, V>>

Example

(Creating a map from entries)

import { Effect, Option, TxHashMap } from "effect"
const program = Effect.gen(function*() {
// Create a user directory
const userMap = yield* TxHashMap.make(
["alice", { name: "Alice Smith", role: "admin" }],
["bob", { name: "Bob Johnson", role: "user" }],
["charlie", { name: "Charlie Brown", role: "user" }]
)
// Check the initial size
yield* TxHashMap.size(userMap) // => 3
// Access users
yield* TxHashMap.get(userMap, "alice") // => Option.some({ name: "Alice Smith", role: "admin" })
return yield* TxHashMap.get(userMap, "david")
})
await Effect.runPromise(program) // => Option.none()

Getters

toEntries

Added in v4.0.0 Source

Returns an array of all key-value pairs in the TxHashMap. This is an alias for the entries function, providing API consistency with HashMap.

Signature

declare function toEntries<K, V>(self: TxHashMap<K, V>): Effect<Array<readonly [K, V]>>

Example

(Converting to entries)

import { Effect, TxHashMap } from "effect"
const program = Effect.gen(function*() {
const settings = yield* TxHashMap.make(
["theme", "dark"],
["language", "en-US"],
["timezone", "UTC"]
)
// Get all entries as an array
const sortedEntries = (yield* TxHashMap.toEntries(settings))
.toSorted(([left], [right]) => left.localeCompare(right))
sortedEntries // => [["language", "en-US"], ["theme", "dark"], ["timezone", "UTC"]]
// Convert to an object
return Object.fromEntries(sortedEntries)
})
await Effect.runPromise(program) // => { language: "en-US", theme: "dark", timezone: "UTC" }

toValues

Added in v4.0.0 Source

Returns an array of all values in the TxHashMap. This is an alias for the values function, providing API consistency with HashMap.

Signature

declare function toValues<K, V>(self: TxHashMap<K, V>): Effect<Array<V>>

Example

(Converting to values)

import { Effect, TxHashMap } from "effect"
const program = Effect.gen(function*() {
const inventory = yield* TxHashMap.make(
["laptop", { price: 999, stock: 5 }],
["mouse", { price: 29, stock: 50 }],
["keyboard", { price: 79, stock: 20 }]
)
// Get all product information
const products = yield* TxHashMap.toValues(inventory)
products.length // => 3
// Calculate total inventory value
const totalValue = products.reduce(
(sum, product) => sum + (product.price * product.stock),
0
)
totalValue // => 8025
// Find products with low stock
return products.filter((product) => product.stock < 10).length
})
await Effect.runPromise(program) // => 1

Guards

isTxHashMap

Added in v4.0.0 Source

Returns true if the specified value is a TxHashMap, false otherwise.

Signature

declare function isTxHashMap<K, V>(value: unknown): value is TxHashMap<K, V>

Example

(Checking TxHashMap values)

import { Effect, Exit, TxHashMap } from "effect"
const program = Effect.gen(function*() {
const txMap = yield* TxHashMap.make(["key", "value"])
TxHashMap.isTxHashMap(txMap) // => true
TxHashMap.isTxHashMap({}) // => false
TxHashMap.isTxHashMap(null) // => false
TxHashMap.isTxHashMap("not a map") // => false
// Useful for type guards in runtime checks
const validateInput = (value: unknown) => {
if (TxHashMap.isTxHashMap(value)) {
// TypeScript now knows this is a TxHashMap
return Effect.succeed("Valid TxHashMap")
}
return Effect.fail("Invalid input")
}
yield* Effect.exit(validateInput(null)) // => Exit.fail("Invalid input")
return yield* Effect.exit(validateInput(txMap))
})
await Effect.runPromise(program) // => Exit.succeed("Valid TxHashMap")

Models

TxHashMap interface

Added in v4.0.0 Source

A TxHashMap is a transactional hash map data structure that provides atomic operations on key-value pairs within Effect transactions. It uses an immutable HashMap internally with TxRef for transactional semantics, ensuring all operations are performed atomically.

Signature

interface TxHashMap<in out K, in out V> extends Inspectable, Pipeable {
readonly "~effect/transactions/TxHashMap": "~effect/transactions/TxHashMap";
readonly ref: TxRef<HashMap<K, V>>;
}

Example

(Using transactional hash maps)

import { Effect, Option, TxHashMap } from "effect"
const program = Effect.gen(function*() {
// Create a transactional hash map
const txMap = yield* TxHashMap.make(["user1", "Alice"], ["user2", "Bob"])
// Single operations are automatically transactional
yield* TxHashMap.set(txMap, "user3", "Charlie")
yield* TxHashMap.get(txMap, "user1") // => Option.some("Alice")
// Multi-step atomic operations
yield* Effect.tx(
Effect.gen(function*() {
const currentUser = yield* TxHashMap.get(txMap, "user1")
if (currentUser._tag === "Some") {
yield* TxHashMap.set(txMap, "user1", currentUser.value + "_updated")
yield* TxHashMap.remove(txMap, "user2")
}
})
)
return yield* TxHashMap.size(txMap)
})
await Effect.runPromise(program) // => 2

Other

TxHashMap

Added in v4.0.0 Source

The TxHashMap namespace contains type-level utilities and helper types for working with TxHashMap instances.

Example

(Reusing extracted TxHashMap types)

import { Effect, Option, TxHashMap } from "effect"
const program = Effect.gen(function*() {
// Create a transactional inventory map
const inventory = yield* TxHashMap.make(
["laptop", { stock: 5, price: 999 }],
["mouse", { stock: 20, price: 29 }]
)
// Extract types for reuse
type ProductId = TxHashMap.TxHashMap.Key<typeof inventory> // string
type Product = TxHashMap.TxHashMap.Value<typeof inventory> // { stock: number, price: number }
type InventoryEntry = TxHashMap.TxHashMap.Entry<typeof inventory> // [string, Product]
// Use extracted types in functions
const updateStock = (id: ProductId, newStock: number) =>
TxHashMap.modify(
inventory,
id,
(product) => ({ ...product, stock: newStock })
)
yield* updateStock("laptop", 3)
return yield* TxHashMap.get(inventory, "laptop")
})
await Effect.runPromise(program) // => Option.some({ stock: 3, price: 999 })

Predicates

every

Added in v4.0.0 Source

Checks whether all entries in the TxHashMap satisfy the given predicate.

Signature

declare const every: {
<K, V>(predicate: (value: V, key: K) => boolean): (self: TxHashMap<K, V>) => Effect<boolean>;
<K, V>(self: TxHashMap<K, V>, predicate: (value: V, key: K) => boolean): Effect<boolean>;
}

Example

(Checking whether every entry matches)

import { Effect, TxHashMap } from "effect"
const program = Effect.gen(function*() {
// Create a user permissions map
const permissions = yield* TxHashMap.make(
["alice", { canRead: true, canWrite: true, canDelete: false }],
["bob", { canRead: true, canWrite: false, canDelete: false }],
["charlie", { canRead: true, canWrite: true, canDelete: true }]
)
// Check if all users can read
yield* TxHashMap.every(
permissions,
(perms) => perms.canRead
) // => true
// Check if all users can write
yield* TxHashMap.every(
permissions,
(perms) => perms.canWrite
) // => false
// Data-last usage with pipe
return yield* permissions.pipe(
TxHashMap.every((perms, username) => perms.canRead && username.length > 2)
)
})
await Effect.runPromise(program) // => true

has

Added in v2.0.0 Source

Checks whether the specified key exists in the TxHashMap.

Signature

declare const has: {
<K1, K>(key: K1): <V>(self: TxHashMap<K, V>) => Effect<boolean>;
<K1, K, V>(self: TxHashMap<K, V>, key: K1): Effect<boolean>;
}

Example

(Checking for keys)

import { Effect, TxHashMap } from "effect"
const program = Effect.gen(function*() {
const permissions = yield* TxHashMap.make(
["alice", ["read", "write"]],
["bob", ["read"]],
["charlie", ["admin"]]
)
// Check if users exist
yield* TxHashMap.has(permissions, "alice") // => true
yield* TxHashMap.has(permissions, "david") // => false
// Use direct method call for type-safe access
return yield* TxHashMap.has(permissions, "bob")
})
await Effect.runPromise(program) // => true

hasBy

Added in v4.0.0 Source

Checks whether any entry in the TxHashMap matches the given predicate.

Signature

declare const hasBy: {
<K, V>(predicate: (value: V, key: K) => boolean): (self: TxHashMap<K, V>) => Effect<boolean>;
<K, V>(self: TxHashMap<K, V>, predicate: (value: V, key: K) => boolean): Effect<boolean>;
}

Example

(Checking entries with a predicate)

import { Effect, TxHashMap } from "effect"
const program = Effect.gen(function*() {
// Create a user status map
const currentTime = 1_700_000_000_000
const userStatuses = yield* TxHashMap.make(
["alice", { status: "online", lastSeen: currentTime }],
["bob", { status: "offline", lastSeen: currentTime - 3_600_000 }],
["charlie", { status: "online", lastSeen: currentTime }]
)
// Check if any users are online
yield* TxHashMap.hasBy(
userStatuses,
(user) => user.status === "online"
) // => true
// Check if any users have specific username pattern
yield* TxHashMap.hasBy(
userStatuses,
(user, username) => username.startsWith("admin")
) // => false
// Data-last usage with pipe
return yield* userStatuses.pipe(
TxHashMap.hasBy((user) => currentTime - user.lastSeen < 1_800_000) // 30 minutes
)
})
await Effect.runPromise(program) // => true

hasHash

Added in v4.0.0 Source

Checks whether the specified key has an entry using a caller-supplied hash.

Gotchas

The supplied hash must be the hash for the same key, such as a precomputed Hash.hash(key) value. If the hash does not match the key, an existing entry may not be found.

Signature

declare const hasHash: {
<K1, K>(key: K1, hash: number): <V>(self: TxHashMap<K, V>) => Effect<boolean>;
<K1, K, V>(self: TxHashMap<K, V>, key: K1, hash: number): Effect<boolean>;
}

Example

(Checking keys with precomputed hashes)

import { Effect, Hash, TxHashMap } from "effect"
const program = Effect.gen(function*() {
// Create an access control map
const permissions = yield* TxHashMap.make(
["admin", { read: true, write: true, delete: true }],
["user", { read: true, write: false, delete: false }]
)
// When checking permissions frequently with same roles
const role = "admin"
const roleHash = Hash.string(role)
// Use hash-optimized existence check
yield* TxHashMap.hasHash(permissions, role, roleHash) // => true
// Check non-existent role
yield* TxHashMap.hasHash(
permissions,
"guest",
Hash.string("guest")
) // => false
// Useful in hot paths where hash is computed once and reused
const roles = ["admin", "user", "moderator"]
const roleHashes = roles.map((role) => [role, Hash.string(role)] as const)
const results: Array<string> = []
for (const [role, hash] of roleHashes) {
const exists = yield* TxHashMap.hasHash(permissions, role, hash)
results.push(`Role ${role}: ${exists}`)
}
return results
})
await Effect.runPromise(program) // => ["Role admin: true", "Role user: true", "Role moderator: false"]

isEmpty

Added in v2.0.0 Source

Checks whether the TxHashMap is empty.

Signature

declare function isEmpty<K, V>(self: TxHashMap<K, V>): Effect<boolean>

Example

(Checking for an empty map)

import { Effect, TxHashMap } from "effect"
const program = Effect.gen(function*() {
// Start with empty map
const cache = yield* TxHashMap.empty<string, any>()
yield* TxHashMap.isEmpty(cache) // => true
// Add an item
yield* TxHashMap.set(cache, "key1", "value1")
yield* TxHashMap.isEmpty(cache) // => false
// Clear and check again
yield* TxHashMap.clear(cache)
return yield* TxHashMap.isEmpty(cache)
})
await Effect.runPromise(program) // => true

isNonEmpty

Added in v4.0.0 Source

Checks whether the TxHashMap is non-empty.

Signature

declare function isNonEmpty<K, V>(self: TxHashMap<K, V>): Effect<boolean>

Example

(Checking for a non-empty map)

import { Effect, TxHashMap } from "effect"
const program = Effect.gen(function*() {
const inventory = yield* TxHashMap.make(["laptop", 5])
yield* TxHashMap.isNonEmpty(inventory) // => true
// Clear inventory
yield* TxHashMap.clear(inventory)
return yield* TxHashMap.isNonEmpty(inventory)
})
await Effect.runPromise(program) // => false

some

Added in v4.0.0 Source

Checks whether at least one entry in the TxHashMap satisfies the given predicate.

Signature

declare const some: {
<K, V>(predicate: (value: V, key: K) => boolean): (self: TxHashMap<K, V>) => Effect<boolean>;
<K, V>(self: TxHashMap<K, V>, predicate: (value: V, key: K) => boolean): Effect<boolean>;
}

Example

(Checking whether some entries match)

import { Effect, TxHashMap } from "effect"
const program = Effect.gen(function*() {
// Create a product inventory
const inventory = yield* TxHashMap.make(
["laptop", { price: 999, stock: 5 }],
["mouse", { price: 29, stock: 50 }],
["keyboard", { price: 79, stock: 0 }]
)
// Check if any products are expensive
yield* TxHashMap.some(
inventory,
(product) => product.price > 500
) // => true
// Check if any products are out of stock
yield* TxHashMap.some(
inventory,
(product) => product.stock === 0
) // => true
// Data-last usage with pipe
return yield* inventory.pipe(
TxHashMap.some((product) => product.price < 50)
)
})
await Effect.runPromise(program) // => true