Skip to content

Package @reatom/methods

Method is special API which works only in Reatom context frame, like action or atom. Some methods are reactive and may work only in reactive context (in atom). Some methods are isomorphic and can be used both in reactive and non-reactive context. Some methods may change the type of context, like peek for none reactive atom reading or wrap for context binding.

Classes

AbortVariable

Defined in: packages/core/src/methods/abortVar.ts:43

Interface for context variables in Reatom

Variables maintain values within the context of a computation tree, allowing for context-aware state similar to React’s Context API but with more granular control and integration with Reatom’s reactive system.

See

https://github.com/tc39/proposal-async-context?tab=readme-ov-file#asynccontextvariable

Extends

Constructors

Constructor

new AbortVariable(): AbortVariable

Defined in: packages/core/src/methods/abortVar.ts:63

Returns

AbortVariable

Overrides

Variable.constructor

Properties

_findReactiveStartIndex

protected _findReactiveStartIndex: number = 1

Defined in: packages/core/src/methods/abortVar.ts:47

Overrides

Variable._findReactiveStartIndex

create()

protected create: (…params) => ReatomAbortController

Defined in: packages/core/src/methods/variable.ts:30

Parameters
params

…[AbortController?]

Returns

ReatomAbortController

Inherited from

Variable.create

createAndRun

createAndRun: <Params, Payload>(cb, …params) => Payload & Action<[(…params) => unknown, ...params: any[]], unknown>

Defined in: packages/core/src/methods/variable.ts:143

Runs a callback with an auto-created variable value. Only available when the variable’s create function requires no parameters.

Example
const loggerVar = variable(() => console, 'logger')
loggerVar.createAndRun(() => {
loggerVar.get()?.log('Hello!') // uses auto-created console
})
Inherited from

Variable.createAndRun

name

readonly name: `var#${string}`

Defined in: packages/core/src/methods/variable.ts:32

Inherited from

Variable.name

run

run: GenericAction<<Params, Payload>(value, cb, …params) => Payload>

Defined in: packages/core/src/methods/variable.ts:124

Executes a callback function with the variable set to a specific value within that execution context

This method creates a new frame in the context tree where the variable is bound to the provided value. The callback function runs within this frame, allowing any code inside (and its descendants) to access this value via get().

Example
const userVar = variable<string>('user')
userVar.run('Alice', () => {
console.log(userVar.get()) // 'Alice'
})
// Passing parameters to callback
const result = userVar.run('Bob', (x, y) => x + y, 2, 3)
console.log(result) // 5
Template

Types of parameters passed to the callback

Template

Return type of the callback

Param

The value to set for this variable during callback execution. Cannot be undefined.

Param

The callback function to execute with the variable set

Param

Additional parameters to pass to the callback

Returns

The return value of the callback

Throws

If value is undefined

Inherited from

Variable.run

spawn

spawn: GenericAction<<Params, Payload>(cb, …params) => Payload>

Defined in: packages/core/src/methods/variable.ts:168

This utility allow you to start a function which will NOT follow the async context of this variable.

Example
// If you want to start a fetch when the atom gets a subscription,
// but don't want to abort the fetch when the subscription is lost to save the data anyway.
const some = atom('...').extend(
withConnectHook((target) => {
abortVar.spawn(async () => {
// here `wrap` doesn't follow the connection abort
const data = await wrap(api.getSome())
some(data)
})
}),
)
Inherited from

Variable.spawn

Methods

find()

find<Result>(cb?, frame?): Result | undefined

Defined in: packages/core/src/methods/abortVar.ts:49

Traverses the frame tree to find and map the variable value.

Type Parameters
Result

Result = ReatomAbortController

Return type of the callback

Parameters
cb?

(payload) => Result | undefined

Optional transformation callback

frame?

Frame<any, any[], any>

Optional frame to check (defaults to current top frame)

Returns

Result | undefined

The transformed value or undefined if not found

Overrides

Variable.find

first()

first(frame): ReatomAbortController | undefined

Defined in: packages/core/src/methods/variable.ts:185

Gets the variable value from the first frame only, without traversing the whole frame tree

Unlike get() which searches through parent frames, this method only checks the top frame. Returns undefined if the variable is not set in the frame.

Parameters
frame

Frame<any, any[], any> = ...

Returns

ReatomAbortController | undefined

The value in the frame, or undefined if not set

Inherited from

Variable.first

get()

get(frame?): ReatomAbortController | undefined

Defined in: packages/core/src/methods/variable.ts:69

Gets the frame value of the variable. Traverse the whole stack to find it.

Parameters
frame?

Frame<any, any[], any>

Optional frame to check (defaults to current top frame)

Returns

ReatomAbortController | undefined

The current value

Throws

If the variable is not found in the frame tree

Inherited from

Variable.get

has()

has(frame?): boolean

Defined in: packages/core/src/methods/variable.ts:196

Checks if the variable exists in the passed frame stack

Parameters
frame?

Frame<any, any[], any>

Optional frame to check (defaults to current top frame)

Returns

boolean

True if the variable exists in the context

Inherited from

Variable.has

require()

require(frame?): ReatomAbortController

Defined in: packages/core/src/methods/variable.ts:86

Gets the value of the variable and throws an error if it is not found in the frame stack.

This method is a stricter version of get() that ensures the variable has been set to a value. Use this when you expect the variable to always be defined and want to fail fast if it is not.

Parameters
frame?

Frame<any, any[], any>

Optional frame to check (defaults to current top frame)

Returns

ReatomAbortController

The current value (guaranteed to be defined)

Throws

If the variable is not set (undefined)

Inherited from

Variable.require

set()

set(…params): ReatomAbortController

Defined in: packages/core/src/methods/variable.ts:241

Sets a new variable value for CURRENT frame. Be aware that it is mostly for internal use!

Parameters
params

…[AbortController?]

Parameters passed to the setter function

Returns

ReatomAbortController

The new value

Inherited from

Variable.set

subscribe()

subscribe(cb?): AbortSubscription

Defined in: packages/core/src/methods/abortVar.ts:122

Subscribes to abortion events from parent context tree (including current frame).

Creates a subscription that listens for abort signals from any parent AbortController in the context tree. When an abort occurs, the callback is invoked with the abort error and the subscription automatically cleans up.

It is IMPORTANT to clean up the subscription when it is no longer needed, otherwise a memory leak will occur. You can use the unsubscribe function returned by this method or using statement.

Parameters
cb?

(error) => void

Callback invoked when abortion occurs

Returns

AbortSubscription

Subscription object

Examples
const myResource = computed(async () => {
const { controller, unsubscribe } = abortVar.subscribe()
const { signal } = controller
try {
const response = await fetch('/api/my-resource', { signal })
return await response.json()
} finally {
unsubscribe()
}
}).extend(withAsyncData())
const myResource = computed(async () => {
using { controller } = abortVar.subscribe()
const { signal } = controller
const response = await fetch('/api/my-resource', { signal })
return await response.json()
}).extend(withAsyncData())
throwIfAborted()

throwIfAborted(): void

Defined in: packages/core/src/methods/abortVar.ts:174

NOTE: this method already used in wrap, that you should use in your code instead.

Throws if any AbortController in the parent context (frame) tree, including the current frame, is aborted.

Returns

void

Throws

ReatomAbortController

Defined in: packages/core/src/methods/abortVar.ts:16

Version of abort controller with explicit name for better debugging.

May control variable propagation by setting the spawned flag (used internally to handle abort boundaries).

Param

The name of the abort controller

Param

Whether to traverse the frame tree beyond the current frame (default: false)

Extends

  • AbortController

Constructors

Constructor

new ReatomAbortController(name, spawned): ReatomAbortController

Defined in: packages/core/src/methods/abortVar.ts:17

Parameters
name

string

spawned

boolean = false

Returns

ReatomAbortController

Overrides

AbortController.constructor

Properties

name

name: string

Defined in: packages/core/src/methods/abortVar.ts:18

signal

readonly signal: AbortSignal

Defined in: node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.dom.d.ts:2723

The signal read-only property of the AbortController interface returns an AbortSignal object instance, which can be used to communicate with/abort an asynchronous operation as desired.

MDN Reference

Inherited from

AbortController.signal

spawned

spawned: boolean = false

Defined in: packages/core/src/methods/abortVar.ts:19

Methods

abort()

abort(reason?): void

Defined in: packages/core/src/methods/abortVar.ts:23

The abort() method of the AbortController interface aborts an asynchronous operation before it has completed.

MDN Reference

Parameters
reason?

any

Returns

void

Overrides

AbortController.abort


Variable

Defined in: packages/core/src/methods/variable.ts:27

Interface for context variables in Reatom

Variables maintain values within the context of a computation tree, allowing for context-aware state similar to React’s Context API but with more granular control and integration with Reatom’s reactive system.

See

https://github.com/tc39/proposal-async-context?tab=readme-ov-file#asynccontextvariable

Extended by

Type Parameters

T

T extends NonUndefined

Type of the stored value

Params

Params extends any[] = any[]

Constructors

Constructor

new Variable<T, Params>(options?): Variable<T, Params>

Defined in: packages/core/src/methods/variable.ts:34

Parameters
options?

AsyncVariableOptions<T, Params>

Returns

Variable<T, Params>

Properties

_findReactiveStartIndex

protected _findReactiveStartIndex: number = 0

Defined in: packages/core/src/methods/variable.ts:28

create()

protected create: (…params) => T

Defined in: packages/core/src/methods/variable.ts:30

Parameters
params

Params

Returns

T

createAndRun

createAndRun: <Params, Payload>(cb, …params) => Payload & Action<[(…params) => unknown, ...params: any[]], unknown> & [] extends Params ? object : never

Defined in: packages/core/src/methods/variable.ts:143

Runs a callback with an auto-created variable value. Only available when the variable’s create function requires no parameters.

Example
const loggerVar = variable(() => console, 'logger')
loggerVar.createAndRun(() => {
loggerVar.get()?.log('Hello!') // uses auto-created console
})
name

readonly name: `var#${string}`

Defined in: packages/core/src/methods/variable.ts:32

run

run: GenericAction<<Params, Payload>(value, cb, …params) => Payload>

Defined in: packages/core/src/methods/variable.ts:124

Executes a callback function with the variable set to a specific value within that execution context

This method creates a new frame in the context tree where the variable is bound to the provided value. The callback function runs within this frame, allowing any code inside (and its descendants) to access this value via get().

Example
const userVar = variable<string>('user')
userVar.run('Alice', () => {
console.log(userVar.get()) // 'Alice'
})
// Passing parameters to callback
const result = userVar.run('Bob', (x, y) => x + y, 2, 3)
console.log(result) // 5
Template

Types of parameters passed to the callback

Template

Return type of the callback

Param

The value to set for this variable during callback execution. Cannot be undefined.

Param

The callback function to execute with the variable set

Param

Additional parameters to pass to the callback

Returns

The return value of the callback

Throws

If value is undefined

spawn

spawn: GenericAction<<Params, Payload>(cb, …params) => Payload>

Defined in: packages/core/src/methods/variable.ts:168

This utility allow you to start a function which will NOT follow the async context of this variable.

Example
// If you want to start a fetch when the atom gets a subscription,
// but don't want to abort the fetch when the subscription is lost to save the data anyway.
const some = atom('...').extend(
withConnectHook((target) => {
abortVar.spawn(async () => {
// here `wrap` doesn't follow the connection abort
const data = await wrap(api.getSome())
some(data)
})
}),
)

Methods

find()

find<Result>(cb?, frame?): Result | undefined

Defined in: packages/core/src/methods/variable.ts:211

Traverses the frame tree to find and map the variable value.

Type Parameters
Result

Result = T

Return type of the callback

Parameters
cb?

(payload) => Result | undefined

Optional transformation callback

frame?

Frame<any, any[], any> = ...

Optional frame to check (defaults to current top frame)

Returns

Result | undefined

The transformed value or undefined if not found

first()

first(frame): T | undefined

Defined in: packages/core/src/methods/variable.ts:185

Gets the variable value from the first frame only, without traversing the whole frame tree

Unlike get() which searches through parent frames, this method only checks the top frame. Returns undefined if the variable is not set in the frame.

Parameters
frame

Frame<any, any[], any> = ...

Returns

T | undefined

The value in the frame, or undefined if not set

get()

get(frame?): T | undefined

Defined in: packages/core/src/methods/variable.ts:69

Gets the frame value of the variable. Traverse the whole stack to find it.

Parameters
frame?

Frame<any, any[], any>

Optional frame to check (defaults to current top frame)

Returns

T | undefined

The current value

Throws

If the variable is not found in the frame tree

has()

has(frame?): boolean

Defined in: packages/core/src/methods/variable.ts:196

Checks if the variable exists in the passed frame stack

Parameters
frame?

Frame<any, any[], any>

Optional frame to check (defaults to current top frame)

Returns

boolean

True if the variable exists in the context

require()

require(frame?): T

Defined in: packages/core/src/methods/variable.ts:86

Gets the value of the variable and throws an error if it is not found in the frame stack.

This method is a stricter version of get() that ensures the variable has been set to a value. Use this when you expect the variable to always be defined and want to fail fast if it is not.

Parameters
frame?

Frame<any, any[], any>

Optional frame to check (defaults to current top frame)

Returns

T

The current value (guaranteed to be defined)

Throws

If the variable is not set (undefined)

set()

set(…params): T

Defined in: packages/core/src/methods/variable.ts:241

Sets a new variable value for CURRENT frame. Be aware that it is mostly for internal use!

Parameters
params

Params

Parameters passed to the setter function

Returns

T

The new value

Interfaces

AbortSubscription

Defined in: packages/core/src/methods/abortVar.ts:30

Properties

[asyncDispose]

[asyncDispose]: Unsubscribe

Defined in: packages/core/src/methods/abortVar.ts:34

[dispose]

[dispose]: Unsubscribe

Defined in: packages/core/src/methods/abortVar.ts:33

controller

controller: ReatomAbortController

Defined in: packages/core/src/methods/abortVar.ts:31

unsubscribe

unsubscribe: Unsubscribe

Defined in: packages/core/src/methods/abortVar.ts:32


AsyncVariableOptions

Defined in: packages/core/src/methods/variable.ts:8

Type Parameters

T

T extends NonUndefined

Params

Params extends any[] = any[]

Properties

create()?

optional create: (…params) => T

Defined in: packages/core/src/methods/variable.ts:14

Parameters
params

Params

Returns

T

defaultValue?

optional defaultValue: T

Defined in: packages/core/src/methods/variable.ts:13

name?

optional name: string

Defined in: packages/core/src/methods/variable.ts:12


Effect()

Defined in: packages/core/src/methods/effect.ts:10

Derived state container.

A computed atom automatically tracks dependencies and recalculates only when those dependencies change. The calculation is performed lazily, only when the computed value is read AND subscribed to.

Extends

Type Parameters

State

State

The type of derived state

Effect(…params): State

Defined in: packages/core/src/methods/effect.ts:10

Call the atom to either read or update its state.

Parameters

params

…[]

Parameters to pass to the atom

Returns

State

The atom’s payload (typically its current state)

Properties

__reatom

__reatom: AtomMeta

Defined in: packages/core/src/core/atom.ts:92

Reference to the atom’s internal metadata.

Inherited from

Computed.__reatom

extend

extend: Extend<Effect<State>>

Defined in: packages/core/src/core/atom.ts:78

Extension system to add capabilities to atoms. Allows adding middleware, methods, or other functionality to modify atom behavior.

Inherited from

Computed.extend

set

set: unknown

Defined in: packages/core/src/core/atom.ts:72

Inherited from

Computed.set

subscribe()

subscribe: (cb?) => Unsubscribe

Defined in: packages/core/src/core/atom.ts:89

Subscribe to state changes, with the first call happening immediately. When a subscriber is added, the callback is immediately invoked with the current state. After that, it’s called whenever the atom’s state changes.

Parameters
cb?

(state) => any

Callback function that receives the atom’s state when it changes

Returns

Unsubscribe

An unsubscribe function that removes the subscription when called

Inherited from

Computed.subscribe

unsubscribe

unsubscribe: Unsubscribe

Defined in: packages/core/src/methods/effect.ts:11


TransactionExt

Defined in: packages/core/src/methods/transaction.ts:19

Extension result for actions that use withTransaction.

Adds a rollback method to manually trigger rollback for the last action call.

Properties

rollback

rollback: Action<[any], void>

Defined in: packages/core/src/methods/transaction.ts:39

Rollback action that executes all collected rollback functions from the last call of this action.

Each action call has its own rollback scope. Calling rollback() only reverts changes from the most recent call, not all previous calls.

Example
const counter = atom(0, 'counter').extend(withRollback())
const increment = action(() => {
counter.set((n) => n + 1)
}, 'increment').extend(withTransaction())
increment() // counter: 1
increment.rollback() // counter: 0
Param

Optional error that triggered the rollback

stop

stop: Action<[], void>

Defined in: packages/core/src/methods/transaction.ts:60

Stop action that clears all collected rollback functions from the last call of this action without executing them.

Use this when you want to “commit” the transaction and prevent any future rollback from reverting the changes.

Example
const todos = atom<Todo[]>([], 'todos').extend(withRollback())
const addTodo = action(async (todo: Todo) => {
todos.set((list) => [...list, todo]) // optimistic update
await wrap(api.saveTodo(todo))
addTodo.stop() // success - commit the change, prevent rollback
}, 'addTodo').extend(withAsync(), withTransaction())
// On success: stop() prevents rollback from todos hooks or other code, todo stays in the list
// On failure: withTransaction() auto-rollbacks, todo is removed

Type Aliases

Deatomize

Deatomize<T> = T extends LinkedListLikeAtom<infer T> ? T extends LinkedList<LLNode<infer T>> ? Deatomize<T>[] : never : T extends AtomLike<infer T, infer Params, infer Payload> ? T extends AtomLike<ActionState<Params, Payload>, Params, Payload> ? T : Deatomize<T> : T extends Map<infer K, infer T> ? Map<K, Deatomize<T>> : T extends Set<infer T> ? Set<Deatomize<T>> : T extends infer T[] ? Deatomize<T>[] : T extends Primitive | Builtin ? T : T extends Record<PropertyKey, unknown> ? { [K in keyof T]: Deatomize<T[K]> } : T

Defined in: packages/core/src/methods/deatomize.ts:27

Type utility that recursively unwraps atom types to their state types

This complex type recursively traverses a type structure, unwrapping atoms to their contained state types. It handles various container types like arrays, maps, sets, and objects.

Type Parameters

T

T

The type to unwrap

Returns

Unwrapped version of the type with atoms replaced by their state types


FunctionSource

FunctionSource = string

Defined in: packages/core/src/methods/memo.ts:33

Type representing the source of a function as a string. Used for caching and identification purposes.


Rollback()

Rollback<State> = ({ beforeState, currentState, transactionState, }) => State

Defined in: packages/core/src/methods/transaction.ts:236

Type Parameters

State

State = any

Parameters

{

beforeState, currentState, transactionState, }

beforeState

State

currentState

State

transactionState

State

Returns

State


Rollbacks

Rollbacks = Fn[]

Defined in: packages/core/src/methods/transaction.ts:11

Variables

abortVar

abortVar: AbortVariable

Defined in: packages/core/src/methods/abortVar.ts:209

Global abort variable that precess AbortController’s coupled to the current frame stack.

The abortVar is computed from all other abort atoms in the current frame tree, which allows for propagation of abortion signals through the computation hierarchy. This is a critical component for cancellation handling in Reatom’s async operations.

Examples

// Trigger abortion of the current frame
abortVar.abortCurrent('Operation cancelled')
// Trigger abortion of the current frame stack
abortVar.get()?.abort('Operation cancelled')
// Check if current operation (the whole frame stack) is aborted
abortVar.throwIfAborted()
// continue operation...
// Get AbortController for fetch API
const { controller, unsubscribe } = abortVar.subscribe()
await fetch('/api/data', { signal: controller.signal })
unsubscribe()

defaultRollback

defaultRollback: Rollback

Defined in: packages/core/src/methods/transaction.ts:264

Default rollback strategy for withRollback extension.

This function determines what state to restore when a rollback occurs. It only restores the beforeState if the currentState hasn’t changed since the transaction started (i.e., currentState === transactionState). If the state was modified after the transaction, it preserves the current state to avoid overwriting unrelated changes.

Param

State before the change in transaction

Param

State after the change in transaction

Param

Current state at the time rollback executes

Returns

The state to set after rollback

See


log

log: Action<any[], any>

Defined in: packages/core/src/methods/connectLogger.ts:81

A special logging action for debugging Reatom applications.

log provides an enhanced logging experience with automatic tracing and production-safe output. It forwards all arguments to the native console.log while providing additional context about the call stack and dependencies.

Key Benefits

  • Short and handy name - Easy to type and use throughout your codebase
  • Automatic stack tracing - Shows the relative call stack each time it’s called
  • Use it everywhere - Logs are only visible when connectLogger() is active
  • Production-safe - Logs won’t appear in production builds when logger is not connected
  • Context-aware - Integrates with Reatom’s dependency tracking system
  • Extendable - You can extend it with other extensions to add custom behavior

Examples

import { log } from '@reatom/core'
// Make LOG available globally (recommended)
declare global {
var LOG: typeof log
}
globalThis.LOG = log
// Use anywhere in your code
const myAtom = atom((ctx) => {
const value = ctx.spy(someAtom)
LOG('Current value:', value)
return value * 2
})
// In actions
const myAction = action((ctx, payload) => {
LOG('Action called with:', payload)
// ... action logic
})
// Multiple arguments like console.log
LOG('Debug info:', { foo: 'bar' }, [1, 2, 3])
// Extend LOG with custom behavior using withCallHook
import { withCallHook } from '@reatom/core'
LOG.extend(
withCallHook((ctx, params) => {
// Send logs to a remote service
sendToAnalytics({ level: 'debug', args: params })
}),
)

See

connectLogger - Must be called to enable logging output


reatomObservable()

const reatomObservable: {<T>(producer, init?, name?): Atom<T | undefined>; <T>(producer, init, name?): Atom<T>; }

Defined in: packages/core/src/methods/reatomObservable.ts:133

Creates a Reatom atom from an observable-like data source.

This function bridges external observable sources (like RxJS observables, event emitters, or custom observable implementations) with Reatom’s reactive system. The atom will automatically subscribe to the observable when it gains subscribers and unsubscribe when it loses all subscribers.

Call Signature

<T>(producer, init?, name?): Atom<T | undefined>

Type Parameters
T

T

Parameters
producer

Producer<T>

init?

undefined

name?

string

Returns

Atom<T | undefined>

Call Signature

<T>(producer, init, name?): Atom<T>

Type Parameters
T

T

Parameters
producer

Producer<T>

init

T | () => T

name?

string

Returns

Atom<T>

Examples

// With RxJS Observable
import { interval } from 'rxjs'
const timerAtom = reatomObservable(interval(1000))
// With custom observable function
const customAtom = reatomObservable((setter) => {
const id = setInterval(() => setter(Date.now()), 1000)
return () => clearInterval(id)
})
// With MobX observable
import { autorun, observable } from 'mobx'
const mobxStore = observable({ count: 0 })
const atomWithDefault = reatomObservable(
() => autorun(() => mobxStore.count),
() => mobxStore.count,
)
// With addEventListener
const clickAtom = reatomObservable((setter) => {
document.addEventListener('click', setter)
return () => document.removeEventListener('click', setter)
})

Template

The type of values emitted by the observable

Param

Either a function that accepts a setter callback and returns an unsubscribe function, or an object with a subscribe method

Param

Optional initial value or function that returns the initial value. If not provided, the atom starts with undefined

Returns

A Reatom atom that reflects the observable’s values


retryComputed()

const retryComputed: {(target): never; <T>(target): T; }

Defined in: packages/core/src/methods/retry.ts:38

Retries computed atom by resetting its dependencies and re-evaluating the computed function .

Call Signature

(target): never

Parameters
target

Action

Returns

never

Call Signature

<T>(target): T

Type Parameters
T

T

Parameters
target

AtomLike<any, any, T>

Returns

T

Template

The return type of the atom.

Param

The atom to retry.

Returns

The result of the atom after retrying.

Throws

If the target is not an action.


rollback

rollback: Action<[any], void>

Defined in: packages/core/src/methods/transaction.ts:468

See

TransactionVariable.rollback


transactionVar

transactionVar: TransactionVariable

Defined in: packages/core/src/methods/transaction.ts:456

Global transaction variable instance.

See

reatomTransaction To create isolated transaction contexts


variable()

variable: {<T>(name?): Variable<T, [T]>; <Params, Payload>(set, name?): Variable<Payload, Params>; }

Defined in: packages/core/src/methods/variable.ts:345

Creates a new context variable with getter and setter functionality

This implementation provides a similar capability to the proposed TC39 AsyncContextVariable, allowing you to maintain values that are specific to a particular execution context. Variables created with this function can be accessed and modified within their frame context.

Also, it can be used as IoC/DI container replacement:

IoC/DI ConceptVariable Equivalent
Token/Keyvariable<T>('name')
Provider.run(impl, fn) / .set(impl)
Inject/Resolve.require() or .get()
Container scopeExecution context (frame stack)

Call Signature

<T>(name?): Variable<T, [T]>

Type Parameters
T

T extends NonUndefined

Parameters
name?

string

Returns

Variable<T, [T]>

Call Signature

<Params, Payload>(set, name?): Variable<Payload, Params>

Type Parameters
Params

Params extends any[]

Payload

Payload extends NonUndefined

Parameters
set

(…params) => Payload

name?

string

Returns

Variable<Payload, Params>

Examples

// Simple variable with string values
const currentUser = variable<string>('currentUser')
// Set the value
currentUser.set('Alice')
// Get the value
console.log(currentUser.get()) // 'Alice'
// Run code with a different value
currentUser.run('Bob', () => {
console.log(currentUser.get()) // 'Bob'
})
// Advanced variable with custom setter logic
const userRole = variable((role: string, permissions: string[]) => {
return { role, permissions }
}, 'userRole')
userRole.set('admin', ['read', 'write', 'delete'])
// Using variable as IoC/DI container replacement
// Step 1: Define service interface (DI contract)
interface Logger {
log: (message: string) => void
}
// Step 2: Create a variable as DI token/key
const loggerVar = variable<Logger>('logger')
// Step 3: Inject dependency in atoms/actions via `require()`
const fetchData = action(async (url: string) => {
const logger = loggerVar.require()
logger.log(`Fetching ${url}`)
const response = await wrap(fetch(url))
logger.log(`Fetched ${url}`)
return response.json()
}, 'fetchData')
// Step 4: Provide implementation at application entry point
loggerVar.run(console, () => {
fetchData('/api/users') // uses console as logger
})
// In tests, createAndRun a mock implementation
const mockLogger = { log: vi.fn() }
loggerVar.run(mockLogger, () => {
fetchData('/api/users') // uses mock logger
})
// Variable with creation function for lazy initialization
// Useful when the dependency needs configuration or is expensive to create
const dbVar = variable(
(connectionString: string) => new Database(connectionString),
'db',
)
// Inside a main process function, use `.set()` instead of `.run()`
// This is handy when you control the whole feature lifecycle
const initApp = action(async () => {
// `.set()` creates and binds the value to the current frame
const db = dbVar.set(process.env.DATABASE_URL)
// All subsequent calls in this frame can access the db
await loadUsers() // uses dbVar.require() internally
await loadPosts() // uses dbVar.require() internally
}, 'initApp')
const loadUsers = action(async () => {
const db = dbVar.require()
return db.query('SELECT * FROM users')
}, 'loadUsers')

Template

The type of the simple variable (when used with just a name)

Template

Types of parameters for the setter function

Template

The type of the stored value

See

https://github.com/tc39/proposal-async-context?tab=readme-ov-file#asynccontextvariable


withRollback()

withRollback: <Target>(options?) => Ext<Target>

Defined in: packages/core/src/methods/transaction.ts:461

Extension to schedule state restoration for atoms when rollback() is called within the same transaction context.

This extension tracks state changes on atoms and registers rollback functions that restore the previous state when the transaction’s rollback action is invoked. The rollback functions are executed in reverse order (LIFO) to properly unwind nested state changes.

When to use:

  • For atoms that participate in optimistic updates
  • When you need automatic state restoration on transaction failure
  • In combination with withTransaction on actions that may fail

How it works:

  1. When the atom’s state changes, the previous state is captured
  2. A rollback function is registered in the current transaction
  3. If rollback() is called, all registered functions execute in reverse order
  4. Changes caused by rollback() itself don’t register new rollback functions

Type Parameters

Target

Target extends Atom<any, [any]>

Parameters

options?
onRollback?

Rollback<AtomState<Target>>

Custom state transformation function called during rollback.

Use this when the default rollback behavior (restore to beforeState only if currentState === transactionState) doesn’t fit your needs.

Default

({ beforeState, currentState, transactionState }) =>
Object.is(currentState, transactionState) ? beforeState : currentState

Param

State before the change in transaction

Param

State after the change in transaction

Param

Current state at the time rollback executes

Returns

Ext<Target>

Extension function to be used with .extend() on atoms

Examples

const counter = atom(0, 'counter').extend(
withRollback(), // Schedule state restoration for rollback()
)
const increment = action(() => {
counter.set((n) => n + 1)
}, 'increment').extend(withTransaction())
increment() // counter: 1
increment.rollback() // counter: 0
// Optimistic update pattern with automatic rollback
const list = atom<string[]>([], 'list').extend(
withChangeHook(saveList), // Trigger save on change
withRollback(), // Restore on failure
)
const saveList = action(async () => {
await api.save(list())
}, 'saveList').extend(withAsync(), withTransaction())
// Custom rollback transformation for list state
const list = atom<string[]>([], 'list').extend(
withRollback({
onRollback: ({ beforeState, currentState, transactionState }) => {
// Remove only the items that were added in the rolled-back change
const addedItems = transactionState.filter(
(item) => !beforeState.includes(item),
)
return currentState.filter((item) => !addedItems.includes(item))
},
}),
)

See

withTransaction For handling errors in actions and triggering rollback

See

TransactionVariable.withRollback


withTransaction()

withTransaction: <Target>() => (target) => TransactionExt

Defined in: packages/core/src/methods/transaction.ts:464

Extension to handle errors in actions and automatically call rollback(). Also adds a rollback method to the action for manual rollback.

Each action call has its own rollback scope. The action.rollback() method only reverts changes from the most recent call.

How it works:

  • For actions with withAsync(): hooks into onReject to call rollback()
  • For plain actions returning promises: catches rejections and calls rollback()
  • For synchronous errors: catches and calls rollback(), then re-throws
  • Abort errors are ignored (they don’t trigger rollback)

Type Parameters

Target

Target extends Action<any[], any>

Returns

(target): TransactionExt

Parameters
target

Target

Returns

TransactionExt

Examples

const counter = atom(0, 'counter').extend(withRollback())
const increment = action(() => {
counter.set((n) => n + 1)
}, 'increment').extend(withTransaction())
increment() // counter: 1
increment.rollback() // counter: 0
// Optimistic update with automatic rollback on failure
const todos = atom<Todo[]>([], 'todos').extend(withRollback())
const saveTodos = action(async () => {
todos.set((list) => [...list, optimisticTodo])
await api.save(todos())
}, 'saveTodos').extend(withAsync(), withTransaction())
saveTodos() // On failure, todos will rollback automatically

See

withRollback For scheduling atom state restoration

See

TransactionVariable.withTransaction


wrap()

wrap: {<Params, Payload>(target, frame?): (…params) => Payload; <T>(target, frame?): Promise<Awaited<T>>; }

Defined in: packages/core/src/methods/wrap.ts:47

Preserves Reatom’s reactive context across async boundaries or function calls.

This is a CRITICAL function in Reatom that ensures proper context tracking across asynchronous operations like Promises, setTimeout, event handlers, and more. Without proper wrapping, atoms would lose their context after async operations, leading to “Missed context” errors when attempting to update state.

Wrap handles two scenarios:

  1. Function wrapping: Returns a new function that preserves context when called
  2. Promise wrapping: Returns a new promise that preserves context through its chain

Call Signature

<Params, Payload>(target, frame?): (…params) => Payload

Type Parameters
Params

Params extends any[]

Payload

Payload

Parameters
target

(…params) => Payload

frame?

Frame<any, any[], any>

Returns

(…params): Payload

Parameters
params

Params

Returns

Payload

Call Signature

<T>(target, frame?): Promise<Awaited<T>>

Type Parameters
T

T

Parameters
target

T

frame?

Frame<any, any[], any>

Returns

Promise<Awaited<T>>

Example

// Wrapping a function (e.g., an event handler)
button.addEventListener(
'click',
wrap(() => {
counter((prev) => prev + 1) // Works, context preserved
}),
)
// Wrapping async operations
action(async () => {
const response = await wrap(fetch('/api/data'))
const data = await wrap(response.json())
results(data) // Works, context preserved
})

Template

The parameter types when wrapping a function

Template

The return type when wrapping a function

Template

The promise type when wrapping a promise

Param

The function or promise to wrap with context preservation

Param

The frame to use (defaults to the current top frame)

Returns

A wrapped function or promise that preserves reactive context

See

https://github.com/tc39/proposal-async-context?tab=readme-ov-file#asynccontextsnapshotwrap

Functions

connectLogger()

connectLogger(): void

Defined in: packages/core/src/methods/connectLogger.ts:111

Sets up and connects a logger to the Reatom system for debugging and tracing.

This function enhances all non-private atoms and actions with logging capabilities. When an atom’s value changes or an action is called, it logs the event with relevant information to the console including:

  • Previous and current state for atoms
  • Parameters and return values for actions
  • Complete dependency stack traces
  • Error information when exceptions occur

The logger adapts to the environment, using different formatting for browser and Node.js. Private atoms (those with names starting with '' or containing ’.’) are not logged.

Returns

void

Example

// Connect the logger at application startup
import { connectLogger } from '@reatom/core'
connectLogger()

deatomize()

deatomize<Value>(value): Deatomize<Value>

Defined in: packages/core/src/methods/deatomize.ts:76

Recursively unwraps atoms in a value to get their current states

This function deeply traverses a value, including nested objects, arrays, maps, and sets, replacing atoms with their current state values. It’s useful for serialization, debugging, or creating snapshots of state that don’t contain reactive references.

Type Parameters

Value

Value

The type of value to parse

Parameters

value

Value

The value containing atoms to unwrap

Returns

Deatomize<Value>

A new value with all atoms replaced by their current states

Example

const user = {
id: 42,
name: atom('John', 'userName'),
stats: {
score: atom(100, 'userScore'),
badges: atom(['gold', 'silver'], 'userBadges'),
},
}
// Results in: { id: 42, name: 'John', stats: { score: 100, badges: ['gold', 'silver'] }}
const plainUser = deatomize(user)

effect()

effect<T>(cb, name?): Computed<T> & AbortExt & DynamicSubscriptionExt & object

Defined in: packages/core/src/methods/effect.ts:56

Creates a reactive side effect that automatically tracks dependencies and cleans itself up.

effect is similar to computed but designed for running side effects. It automatically subscribes to any atoms read within the callback (cb). When the effect’s reactive context is aborted (e.g., component unmount in reatomFactoryComponent, cancellation in withAbort / withAsyncData), the effect’s execution is stopped, and any ongoing async operations within it (like await wrap(sleep(...))) are cancelled.

Type Parameters

T

T

Parameters

cb

() => T

The function to run as a side effect. It can be async. Any atoms read inside cb will become dependencies.

name?

string

Optional name for debugging purposes. Auto-generated if not provided.

Returns

Computed<T> & AbortExt & DynamicSubscriptionExt & object

The new computed atom with unsubscribe method to manually clean up the effect. Calling this function is usually not necessary when effect is used within managed contexts like reatomFactoryComponent or withConnectHook, as cleanup happens automatically.

Example

import { atom, effect, wrap, sleep, isAbort } from '@reatom/core'
const isActive = atom(true, 'isActive')
const data = atom(0, 'data')
// This effect polls data every 5 seconds while isActive is true
const polling = effect(async () => {
if (!isActive()) return // Depends on isActive
console.log('Polling started...')
while (true) {
const fetchedData = await wrap(fetch('/api/poll'))
const jsonData = await wrap(fetchedData.json())
data(jsonData.value)
await wrap(sleep(5000)) // Abortable sleep == debounce
}
}, 'pollingEffect')
// To manually stop:
// polling.unsubscribe()

framePromise()

framePromise(queue): Promise<unknown>

Defined in: packages/core/src/methods/framePromise.ts:79

Request the result of the current atom or action function as a promise.

Returns a promise that resolves to the current execution frame’s state (action payload or atom state). Use it to catch errors from subsequent operations in a cleaner way than traditional try-catch. Use finally to clean up resources and so on. This method respects wrap and abortVar policies.

Inspired by TC39 explicit resource management proposal, but simpler and coupled to Reatom’s async stack for an ergonomic usage.

Parameters

queue

QueueKind = 'effect'

Queue type to schedule in (default: “effect”)

Returns

Promise<unknown>

Promise that resolves with the current frame’s state

Examples

export const processPayment = action(async (orderId: string) => {
framePromise().catch((error) => showErrorNotification(error))
let order = await wrap(fetchOrder(orderId))
await wrap(validateInventory(order))
await wrap(chargeCustomer(order))
await wrap(updateOrderStatus(order, 'completed'))
return order
})
// Classic approach - boilerplate with try-catch
export const doSome = action(async () => {
try {
await wrap(fetchUser())
await wrap(updateProfile())
await wrap(syncData())
} catch (error) {
toast(error)
}
})
// native using - no try-catch and no "finally" logic
// only resource management with extra variables
// you can adapt `toast`, but without the payload / error data
export const doSome = action(async () => {
using _ = toast
await wrap(fetchUser())
await wrap(updateProfile())
await wrap(syncData())
})
// With our framePromise() - clean and declarative
export const doSome = action(async () => {
framePromise().catch((error) => toast(error))
await wrap(fetchUser())
await wrap(updateProfile())
await wrap(syncData())
})
// Native using works only within the current function scope=*
export const processOrder = action(async (orderId: string) => {
withErrorLogging() // Impossible with native using
await wrap(fetchOrder(orderId))
})
// But framePromise works with the current action/atom frame!
// Helper functions can use parent's framePromise - powerful composition!
let withErrorLogging = () => {
framePromise().catch((error) => logger.error(error))
}
export const processOrder = action(async (orderId: string) => {
withErrorLogging() // Helper uses the SAME action frame!
await wrap(fetchOrder(orderId))
})

See

https://github.com/tc39/proposal-explicit-resource-management


getCalls()

getCalls<Params, Payload>(target): object[]

Defined in: packages/core/src/methods/ifChanged.ts:97

Retrieves new action calls that occurred in the current batch.

This utility function tracks action invocations and returns an array of new calls that have been made during the current batch. It’s particularly useful for monitoring action activity within computed atoms or effects without triggering side effects during the action execution itself.

In a computed atom, the function compares the current action state with the previous frame’s state to determine which calls are new. If this is the first time the action is being tracked, all current calls are considered new. Otherwise, only calls that weren’t present in the previous frame are returned. If the computed triggered by some other dependent atom change, the function may return an empty array. The past calls are not stored!

Type Parameters

Params

Params extends any[]

Array type representing the action’s parameter types

Payload

Payload

Type of the action’s return value/payload

Parameters

target

Action<Params, Payload>

The action to monitor for new calls

Returns

object[]

Array of new action calls, each containing the action’s payload (return value) and the parameters it was called with

Example

// Monitor API calls in an effect
const apiCall = action((endpoint: string) => fetch(endpoint), 'apiCall')
effect(() => {
const newCalls = getCalls(apiCall)
newCalls.forEach(({ payload, params }) => {
console.log(`API called: ${params[0]}, Response:`, payload)
})
}, 'apiMonitor')

Throws

If target is a reactive atom instead of an action


getSerial()

getSerial(frame): string

Defined in: packages/core/src/methods/getStackTrace.ts:10

Parameters

frame

Frame<any, any[], any> = ...

Returns

string


ifChanged()

ifChanged<T>(target, cb): void

Defined in: packages/core/src/methods/ifChanged.ts:40

Executes a callback when an atom’s state changes

This utility evaluates if an atom’s state has changed during the current frame execution and calls the provided callback with the new state (and optionally the previous state if available).

Type Parameters

T

T extends AtomLike<any, any[], any>

Type extending AtomLike

Parameters

target

T

The atom to monitor for changes

cb

(newState, oldState?) => void

Callback to execute when the atom changes

Returns

void

Example

// Log when the user's name changes
ifChanged(userName, (newName, oldName) => {
console.log(`Name changed from ${oldName} to ${newName}`)
})

Throws

If target is not a reactive atom


isCausedBy()

isCausedBy(target, depth?, frame?, visited?): boolean

Defined in: packages/core/src/methods/isCausedBy.ts:27

Determines if an atom is part of the causal chain leading to the current computation

This recursive function checks if the given atom has caused the current computation by traversing the computation tree. It’s useful for determining dependencies and understanding the flow of state changes through your application.

Parameters

target

AtomLike

The atom to check if it’s part of the causal chain

depth?

number = Infinity

The depth of the causal chain to check. Default is Infinity

frame?

Frame<any, any[], any> = ...

The frame to check (defaults to the current top frame). Default is top()

visited?

Set<Frame<any, any[], any>> = ...

Returns

boolean

True if the target atom is part of the causal chain, false otherwise

Example

// Check if user atom changes caused the current computation
if (isCausedBy(userAtom)) {
console.log('This computation was triggered by user state change')
}

isChanged()

isChanged(target): boolean

Defined in: packages/core/src/methods/ifChanged.ts:7

Parameters

target

AtomLike

Returns

boolean


isSkip()

isSkip(target): boolean

Defined in: packages/core/src/methods/getStackTrace.ts:4

Parameters

target

AtomLike

Returns

boolean


memo()

memo<State>(cb, equal, key?): State

Defined in: packages/core/src/methods/memo.ts:112

Memoize additional computation inside a different calls of an atom (computed or an effect) or an action.

It’s useful when you want to avoid recomputing of the whole computed function, especially if the computation is expensive. You could create an external atom by yourself, but it is not handy sometimes.

The memo function takes a callback function cb that returns the value to be memoized, an optional equal function that compares the new and old values to determine if the memoized value should be updated, and an optional key to uniquely identify the memoized value.

Important note: The created internal atom only uses the first passed callback function. This means it’s unsafe to rely on data from the closure that changes on every recall, as subsequent calls will not update the callback used by the internal atom.

Note for rare cases: A created underhood atom is memorized for each memo by the passed function sources from “toString()” method, so every computed callback in different memos of the same atom should contain different code. However, you can provide a custom key parameter to uniquely identify different memo calls instead of relying on toString().

When a custom key is provided, the toString() duplication check is bypassed, allowing you to use the same callback function multiple times within the same atom by providing different keys for each usage.

Type Parameters

State

State

Parameters

cb

A function that returns the value to be selected and memoized.

() => State | (state?) => State

equal

(newState, oldState) => boolean

key?

string

An optional unique identifier for the memoized value. Defaults to cb.toString(). Used to distinguish between different memo calls within the same computed function. Providing a custom key is recommended when using similar callback functions to avoid conflicts.

Returns

State

The memoized value.

Examples

// This is very useful to memoize not just the end string,
// but, for example, a template computation inside `reatomComponent` or so on.
export const listSum = computed(() => {
// Simple call of `list().length` will cause extra recomputations for elements sorting or its internal changes.
// correct optimal way, the component will rerender only on `length` change
const length = memo(() => list().length)
// you could call different `memo` many times in one computed
const sum = memo(() => list().reduce((acc, el) => acc + el().value, 0))
return `The sum of ${length} elements is: ${sum}`
}, 'listSum')
// An example of using the equality function as part of the logic
const scroll = atom(0, 'scroll')
const throttledScroll = computed(() => {
const { state } = memo(
() => ({ state: scroll(), time: Date.now() }),
// Only update if 50ms have passed since the last update
(next, prev) => prev.time + 50 < Date.now(),
)
return state
}, 'throttledScroll')
// Using memo in actions for expensive computations
const processData = action((data: string[]) => {
// You can even create a service, but not one that is tied only to this action.
const myService = memo(() => new Service())
myService.send(data)
}, 'processData')

memoKey()

memoKey<T>(key, create): T

Defined in: packages/core/src/methods/memo.ts:19

Internal utility for keyed memoization within an atom’s execution context.

Caches values by key within the current atom frame, creating the value on first access and returning the cached value on subsequent calls. This enables persistent memoization across multiple invocations of the same atom.

The cache is scoped per-atom and persists across all calls to that atom within the same context, making it suitable for creating internal computed atoms or other resources that should be created once and reused.

Type Parameters

T

T

The type of value being cached

Parameters

key

string

Unique identifier for the cached value within the atom

create

() => T

Factory function to create the value if not already cached

Returns

T

The cached value, either newly created or retrieved from cache


peek()

peek<Params, Result>(cb, …params): Result

Defined in: packages/core/src/methods/peek.ts:38

Executes a callback in the current context without reactive bindings (dependencies tracking)

Type Parameters

Params

Params extends any[]

Result

Result

Parameters

cb

(…params) => Result

params

Params

Returns

Result

Examples

// reset paging on search changes
effect(() => {
const searchState = search()
// get page state without subscribing to it!
if (peek(page) > 1) peek(0)
})
const query = atom('', 'query')
const someResource = computed(
async () => api.getSome(query()),
'someResource',
).extend(withAsyncData())
const tip = computed(() => {
if (!someResource.ready()) {
return 'Searching...'
}
const list = someResource.data()
if (list.length === 0) {
// no need to subscribe to the query changes!
return peek(query) ? 'Nothing found' : 'Try to search something'
}
return `Found ${list.length} elements`
})

reatomLens()

reatomLens<Parent, Key, Value>(parent, key, options?, name?): Atom<Value>

Defined in: packages/core/src/methods/reatomLens.ts:120

Creates a lens atom that provides focused access to a nested property within a parent atom’s state.

A lens atom automatically tracks changes in the parent atom and provides immutable updates back to the parent when modified. It supports objects, arrays, and Maps.

Type Parameters

Parent

Parent extends Atom<any, [any]>

The type of the parent atom

Key

Key extends LensKey

The key type to access the nested property

Value

Value = LensValue<AtomState<Parent>, Key>

Parameters

parent

Parent

The parent atom containing the state to lens into

key

Key

The key to access the nested property (string for objects, number for arrays, any for Maps)

options?

Optional configuration with custom get/set functions

get?

(parent, key) => Value

Custom function to extract the value from the parent state. Defaults to parent[key] for objects/arrays or parent.get(key) for Maps

set?

(parent, key, value) => AtomState<Parent>

Custom function to immutably update the parent state. Defaults to creating new objects/arrays/Maps with the updated value

name?

string

Optional name for the lens atom. Defaults to ${parent.name}.${String(key)}

Returns

Atom<Value>

A lens atom that tracks and updates the parent atom’s nested property

Examples

// With an object
const userAtom = atom({ name: 'John', age: 30 })
const nameAtom = reatomLens(userAtom, 'name')
nameAtom() // → 'John'
nameAtom.set('Jane') // Updates userAtom to { name: 'Jane', age: 30 }
// With an array
const listAtom = atom(['a', 'b', 'c'])
const firstAtom = reatomLens(listAtom, 0)
firstAtom() // → 'a'
firstAtom.set('x') // Updates listAtom to ['x', 'b', 'c']
// With a Map
const mapAtom = atom(new Map([['key1', 'value1']]))
const valueAtom = reatomLens(mapAtom, 'key1')
valueAtom() // → 'value1'
valueAtom.set('value2') // Updates mapAtom with new Map
// With custom get/set functions
const dataAtom = atom({ nested: { deep: { value: 42 } } })
const deepAtom = reatomLens(dataAtom, 'nested', {
get: (parent) => parent.nested?.deep?.value,
set: (parent, _, value) => ({
...parent,
nested: {
...parent.nested,
deep: { ...parent.nested.deep, value },
},
}),
})

reatomTransaction()

reatomTransaction(__namedParameters): TransactionVariable

Defined in: packages/core/src/methods/transaction.ts:307

Creates an isolated transaction context with rollback capabilities.

Use this to create feature-specific transaction scopes. For most cases, use the global withRollback and withTransaction exports instead.

Parameters

__namedParameters
defaultRollback?

Rollback<any> = defaultRollback

Custom rollback strategy applied to all atoms using withRollback() from this transaction scope.

Default

defaultRollback

See

defaultRollback

name

string

Unique name for the transaction scope.

Used for debugging and identifying transaction contexts.

Returns

TransactionVariable

Transaction variable with withRollback, withTransaction, and rollback methods

Examples

// Create a custom transaction scope for a specific feature
const formTransaction = reatomTransaction({ name: 'form' })
const formData = atom({ name: '', email: '' }, 'formData').extend(
formTransaction.withRollback(),
)
const submitForm = action(async () => {
// ... form submission logic
}, 'submitForm').extend(withAsync(), formTransaction.withTransaction())
// Custom default rollback strategy for all atoms in the scope
const alwaysRestoreTransaction = reatomTransaction({
name: 'alwaysRestore',
defaultRollback: ({ beforeState }) => beforeState, // Always restore
})

See


reset()

reset<T>(target): void

Defined in: packages/core/src/methods/retry.ts:16

Removes all computed atom dependencies. Useful for resources / effects invalidation.

Note that this method not recall and recompute the atom, it only throws it’s deps. Use retryComputed to reevaluate the computed.

Type Parameters

T

T extends AtomLike<any, any[], any>

Parameters

target

T

The reactive atom whose dependencies should be reset.

Returns

void

Throws

If the target is an action.


schedule()

schedule<T>(fn, queue): Promise<T>

Defined in: packages/core/src/methods/schedule.ts:15

Schedule a callback to execute after all current computations complete.

The callback is added to the specified queue (“effect” by default) and processes alongside subscription callbacks and other side effects. This method respects wrap and abortVar policies.

Type Parameters

T

T

Parameters

fn

() => T

Callback function to execute

queue

QueueKind = 'effect'

Queue type to schedule in (default: “effect”)

Returns

Promise<T>

Promise that resolves with the callback’s return value


take()

Call Signature

take<Return>(target, name?): Promise<Awaited<Return>>

Defined in: packages/core/src/methods/take.ts:42

Awaits the next update of an atom or call of an action.

This function returns a Promise that resolves when the specified atom’s state changes or when the specified action is called. This is valuable for orchestrating workflows that depend on future state changes or action calls.

Note: Must be used with wrap() when used in an async context to preserve reactive context.

Type Parameters
Return

Return

Parameters
target

The atom or action to wait for

AtomLike<any, any, Return> | () => Return

name?

string

Optional name for debugging purposes

Returns

Promise<Awaited<Return>>

A promise that resolves with the next value of the atom or action result

Example
// Wait for form validation before proceeding
const submitWhenValid = action(async () => {
while (true) {
const currentData = formData()
const error = validate(currentData)
if (!error) break // Exit loop if valid
formData({ ...currentData, error }) // Show error
// Wait for the next change in formData - need wrap() to preserve context
await wrap(take(formData))
}
// Now formData is valid, proceed with submission...
})

Call Signature

take<Return, Result>(target, map, name?): Result | Promise<Result>

Defined in: packages/core/src/methods/take.ts:58

Awaits the next update of the target AtomLike and maps the result. If the map function executes synchronously without throwing, its result is returned directly. Otherwise, a promise is returned.

Type Parameters
Return

Return

The type of the awaited value from the target.

Result

Result

The type of the mapped result.

Parameters
target

The AtomLike to await.

AtomLike<any, any, Return> | () => Return

map

(value) => Result

A function to map the awaited value.

name?

string

Optional name for debugging.

Returns

Result | Promise<Result>

The mapped result or a promise that resolves with the mapped result.


withObservable()

withObservable<Target>(producer, init?): Ext<Target>

Defined in: packages/core/src/methods/reatomObservable.ts:71

Extends an existing atom to synchronize with an observable-like data source.

This extension bridges external observable sources (like RxJS observables, event emitters, or custom observable implementations) with Reatom’s reactive system. The extended atom will automatically subscribe to the observable when it gains subscribers and unsubscribe when it loses all subscribers.

Type Parameters

Target

Target extends Atom<any, [any]>

The type of the atom being extended

Parameters

producer

Producer<AtomState<Target>>

Either a function that accepts a setter callback and returns an unsubscribe function, or an object with a subscribe method (like RxJS observables)

init?

() => AtomState<Target>

Optional initialization function that returns the initial value. This will be called when the atom is first connected

Returns

Ext<Target>

An extension function that adds observable synchronization to an atom

Examples

// Extending an existing atom with RxJS Observable
import { interval } from 'rxjs'
const counterAtom = atom(0)
const timerAtom = counterAtom.extend(withObservable(interval(1000)))
// With custom observable function
const stateAtom = atom({ timestamp: 0 })
const liveAtom = stateAtom.extend(
withObservable((setter) => {
const id = setInterval(() => setter({ timestamp: Date.now() }), 1000)
return () => clearInterval(id)
}),
)
// With MobX observable, providing initial value
import { autorun, observable } from 'mobx'
const mobxStore = observable({ count: 0 })
const syncedAtom = atom(0).extend(
withObservable((setter) => autorun(() => setter(mobxStore.count))),
)
// With DOM events
const clickCountAtom = atom(0)
const trackedAtom = clickCountAtom.extend(
withObservable((setter) => {
let count = 0
const handler = () => setter(++count)
document.addEventListener('click', handler)
return () => document.removeEventListener('click', handler)
}),
)