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
Variable<ReatomAbortController, [AbortController?]>
Constructors
Constructor
new AbortVariable():
AbortVariable
Defined in: packages/core/src/methods/abortVar.ts:63
Returns
Overrides
Properties
_findReactiveStartIndex
protected_findReactiveStartIndex:number=1
Defined in: packages/core/src/methods/abortVar.ts:47
Overrides
Variable._findReactiveStartIndex
create()
protectedcreate: (…params) =>ReatomAbortController
Defined in: packages/core/src/methods/variable.ts:30
Parameters
params
…[AbortController?]
Returns
Inherited from
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
name
readonlyname:`var#${string}`
Defined in: packages/core/src/methods/variable.ts:32
Inherited from
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) // 5Template
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
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
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
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
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
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
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
The current value (guaranteed to be defined)
Throws
If the variable is not set (undefined)
Inherited from
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
The new value
Inherited from
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
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
Overrides
AbortController.constructor
Properties
name
name:
string
Defined in: packages/core/src/methods/abortVar.ts:18
signal
readonlysignal: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.
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.
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()
protectedcreate: (…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> & [] extendsParams?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
readonlyname:`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) // 5Template
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()?
optionalcreate: (…params) =>T
Defined in: packages/core/src/methods/variable.ts:14
Parameters
params
…Params
Returns
T
defaultValue?
optionaldefaultValue:T
Defined in: packages/core/src/methods/variable.ts:13
name?
optionalname: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
Computed<State>
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
extend
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
set
set:
unknown
Defined in: packages/core/src/core/atom.ts:72
Inherited from
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
An unsubscribe function that removes the subscription when called
Inherited from
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: 0Param
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 removedType Aliases
Deatomize
Deatomize<
T> =TextendsLinkedListLikeAtom<infer T> ?TextendsLinkedList<LLNode<infer T>> ?Deatomize<T>[] :never:TextendsAtomLike<infer T, infer Params, infer Payload> ?TextendsAtomLike<ActionState<Params,Payload>,Params,Payload> ?T:Deatomize<T> :TextendsMap<infer K, infer T> ?Map<K,Deatomize<T>> :TextendsSet<infer T> ?Set<Deatomize<T>> :Textends infer T[] ?Deatomize<T>[] :TextendsPrimitive|Builtin?T:TextendsRecord<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
- reatomTransaction To customize the default rollback for a transaction scope
- withRollback To customize rollback per-atom via
onRollbackoption
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()
constreatomObservable: {<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()
constretryComputed: {(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
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 Concept | Variable Equivalent |
|---|---|
| Token/Key | variable<T>('name') |
| Provider | .run(impl, fn) / .set(impl) |
| Inject/Resolve | .require() or .get() |
| Container scope | Execution 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
withTransactionon actions that may fail
How it works:
- When the atom’s state changes, the previous state is captured
- A rollback function is registered in the current transaction
- If
rollback()is called, all registered functions execute in reverse order - Changes caused by
rollback()itself don’t register new rollback functions
Type Parameters
Target
Target extends Atom<any, [any]>
Parameters
options?
onRollback?
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 : currentStateParam
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 intoonRejectto callrollback() - 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
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 automaticallySee
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:
- Function wrapping: Returns a new function that preserves context when called
- 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
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
Returns
boolean
isSkip()
isSkip(
target):boolean
Defined in: packages/core/src/methods/getStackTrace.ts:4
Parameters
target
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
defaultRollbackSee
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
- defaultRollback The default rollback strategy
- withRollback Extension for atoms
- withTransaction Extension for actions
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) }), )