@tuwaio/pulsar-react
@tuwaio/pulsar-react is the React Layer 4 (L4) package of Pulsar, the transaction tracking project of TUWA Stage 2 (“State & Connection”, next to Satellite Connect). Built on react only, it ships two hooks: useInitializeTransactionsPool, which restarts the trackers of pending transactions when your app mounts, and useTxFinished, which reacts to every finished transaction, also after a reload. It has no UI components and no dependency on the other Pulsar packages: to read the store in components, use createBoundedUseStore from @tuwaio/pulsar-core.
🏛️ Core Capabilities
- Resume after reload:
useInitializeTransactionsPoolcalls the store’sinitializeTransactionsPoolin an effect, on the client and after the store has restored its pool fromlocalStorage, so transactions that were pending before a reload are tracked again. - Runs once: the effect depends only on
initializeTransactionsPool, and the latestonErroris read without re-running it, so an inlineonErrordoes not start new trackers on every render. - Errors: a rejected initialization goes to
onError, or toconsole.errorby default; nothing is reported after unmount. - Finished transactions:
useTxFinishedsubscribes to the store’s “transaction finished” event while the component is mounted and callsonFinishedfor every transaction that reachesSuccess,FailedorReplaced, also for transactions resumed after a reload, which no longer have theonSuccessofexecuteTxAction. The latestonFinishedis used without subscribing again.
💾 Installation
pnpm add @tuwaio/pulsar-react react[!IMPORTANT]
react(>=19.2.3) is a peer dependency and must be installed alongside@tuwaio/pulsar-react. The hook is used with a store from@tuwaio/pulsar-core.
🚀 Usage
Render the initializer once, in a component that stays mounted, such as your root providers:
'use client';
import { createPulsarStore, type Transaction, type TxAdapter } from '@tuwaio/pulsar-core';
import { useInitializeTransactionsPool } from '@tuwaio/pulsar-react';
declare const adapter: TxAdapter<Transaction>; // pulsarEvmAdapter(...) or pulsarSolanaAdapter(...)
export const pulsarStore = createPulsarStore<Transaction>({ name: 'pulsar-transactions', adapter });
export function PulsarInitializer() {
useInitializeTransactionsPool({
initializeTransactionsPool: pulsarStore.getState().initializeTransactionsPool,
onError: (error) => console.warn('Could not resume transaction tracking:', error),
});
return null;
}With @tuwaio/pulsar-core 0.12 and later a transaction already tracked is not tracked twice, so React Strict Mode, which runs effects twice in development, does no harm. The complete setup is in the React transaction tracking guide .
React to finished transactions where the data lives, for example to refetch a list once a transaction that changed it succeeds, also after a reload. Use useTxFinished for data that must stay correct, and the onSuccess, onError and onReplaced of executeTxAction for the interface of the page that sent the transaction (closing a dialog, a message in place); those do not run for transactions resumed after a reload. The comparison is in the @tuwaio/pulsar-core README:
'use client';
import { TransactionStatus } from '@tuwaio/pulsar-core';
import { useTxFinished } from '@tuwaio/pulsar-react';
import { pulsarStore } from './pulsarStore';
export function CountersRefresher({ refetch }: { refetch: () => void }) {
useTxFinished({
subscribeTxFinished: pulsarStore.getState().subscribeTxFinished,
onFinished: (tx) => {
if (tx.status === TransactionStatus.Success) refetch();
},
});
return null;
}📚 API Reference
Every export, with signatures and types generated from the source, is documented at pulsar.docs.tuwa.io/packages/pulsar-react .
📄 License
Licensed under the Apache-2.0 License. See the LICENSE file for details.