createReactiveActionStore

function createReactiveActionStore<TArgs, TResult>(
    fn,
    options?,
): ReactiveActionStore<TArgs, TResult>;

Wraps an async function in a ReactiveActionStore. Each dispatch creates a fresh AbortController and aborts the previous one; the superseded call's outcome is dropped, so only the most recent dispatch can mutate state.

The wrapped function receives the AbortSignal as its first argument, followed by whatever arguments were passed to dispatch. When options.perRequestSignal is provided, that factory is invoked on every dispatch and the returned signal is combined with the per-dispatch controller via AbortSignal.any. Aborting the factory-returned signal cancels the in-flight call and transitions the store to error with the abort reason. Each new dispatch calls the factory again — useful for per-attempt timeouts (() => AbortSignal.timeout(N)) that reset on each call.

Type Parameters

Type ParameterDescription
TArgs extends readonly unknown[]Argument tuple forwarded from dispatch to fn.
TResultResolved value type of fn.

Parameters

ParameterTypeDescription
fn(signal, ...args) => Promise<TResult>Async function to wrap. Receives an AbortSignal plus the dispatch arguments.
options?{ perRequestSignal?: () => | AbortSignal | undefined; }Optional configuration.
options.perRequestSignal?() => | AbortSignal | undefinedFactory invoked on every dispatch; returns the signal to compose with the per-dispatch controller. Return undefined to skip composition for that attempt.

Returns

ReactiveActionStore<TArgs, TResult>

A ReactiveActionStore exposing dispatch, dispatchAsync, getState, subscribe, and reset.

Example

const store = createReactiveActionStore(
    async (signal, accountId: Address) => {
        const response = await fetch(`/api/accounts/${accountId}`, { signal });
        return response.json();
    },
    { perRequestSignal: () => AbortSignal.timeout(30_000) },
);
 
store.subscribe(() => console.log(store.getState()));
store.dispatch(someAccountId); // fire-and-forget; state is the source of truth
 
// Or, when you need the resolved value imperatively:
const account = await store.dispatchAsync(someAccountId);

See

ReactiveActionStore

On this page