API Reference

useFlux()

A single hook exposing the engine's live status — connectivity, queue depth, hydration, bootstrap state, unresolved conflicts, and the active user — so components can react to Flux without reaching into the engine instance directly.

Prerequisites
  • FluxProvider mounted above this component — see api/with-flux
  • @tsworldtech/flux-next or @tsworldtech/flux-react installed
1

Basic usage

Import useFlux from whichever framework package you're using — the returned shape is identical, since this hook has no Next.js-specific behavior of its own.
typescript
1import { useFlux } from '@tsworldtech/flux-next'
2// or '@tsworldtech/flux-react' — identical shape, no Next.js specifics
3
4function StatusBar() {
5 const { isOnline, queueCount, hydrated, isBootstrapped, activeConflicts, currentUserId } = useFlux()
6
7 if (!isOnline) return <Banner>You're offlinechanges will sync when you reconnect</Banner>
8 return null
9}
2

Return shape

Six fields, each mirroring a corresponding piece of state on the engine itself.
typescript
1interface UseFluxReturn {
2 isOnline: boolean // live browser connectivity state
3 queueCount: number // pending offline queue entries, across all registered stores
4 hydrated: boolean // mirrors flux.isHydrated
5 isBootstrapped: boolean // mirrors flux.isBootstrapped
6 activeConflicts: UnifiedConflictFrame[] // live, mirrors flux.getActiveConflicts()
7 currentUserId: string | null // mirrors flux.currentUserId
8}
3

isOnline and queueCount

Use these together to drive an offline banner or a "pending sync" indicator without wiring your own online/offline listeners or reading the queue yourself.
typescript
1function OfflineIndicator() {
2 const { isOnline, queueCount } = useFlux()
3
4 if (isOnline && queueCount === 0) return null
5
6 return (
7 <div>
8 {!isOnline && <span>Offline</span>}
9 {queueCount > 0 && <span>{queueCount} change{queueCount === 1 ? '' : 's'} pending sync</span>}
10 </div>
11 )
12}
4

hydrated and isBootstrapped

hydrated mirrors flux.isHydrated, isBootstrapped mirrors flux.isBootstrapped — the same two flags HydrationGate gates on, exposed here for any component that wants to check them directly instead of wrapping in the gate.
typescript
1function Page() {
2 const { hydrated, isBootstrapped } = useFlux()
3
4 // hydrated flips true once IDB has been read for every registered store —
5 // isBootstrapped flips true once the leader tab's single network
6 // request has completed. A component can gate on either independently.
7 if (!hydrated) return <Skeleton />
8
9 return <Dashboard />
10}
5

activeConflicts

The live array from flux.getActiveConflicts(), kept updated internally via the same subscription mechanism as subscribeToConflicts(). Read this to conditionally render a conflict resolution panel.
typescript
1function ConflictBadge() {
2 const { activeConflicts } = useFlux()
3
4 if (activeConflicts.length === 0) return null
5
6 return <Badge count={activeConflicts.length} onClick={openConflictPanel} />
7}
8
9// activeConflicts updates automatically — no manual subscription needed,
10// it's already wired to the same live feed as flux.subscribeToConflicts()
6

currentUserId

Mirrors flux.currentUserId, letting a component react to session start/end — set by a 'user'-scope bootstrap() call, cleared by clearUserSession() — without wiring its own auth listener.
typescript
1function Nav() {
2 const { currentUserId } = useFlux()
3
4 // Reacts to login/logout the instant clearUserSession() runs or a
5 // user-scope bootstrap() call sets the engine's active session —
6 // no separate auth listener needed inside this component.
7 return currentUserId ? <UserMenu userId={currentUserId} /> : <LoginButton />
8}
7

Composing multiple fields

Most real usage reads several fields from one call rather than sprinkling separate hooks — a top bar showing connectivity, pending syncs, conflicts, and auth state all from a single useFlux().
typescript
1function TopBar() {
2 const { isOnline, queueCount, activeConflicts, currentUserId } = useFlux()
3
4 return (
5 <header>
6 {!isOnline && <OfflinePill />}
7 {queueCount > 0 && <PendingSyncPill count={queueCount} />}
8 {activeConflicts.length > 0 && <ConflictBadge count={activeConflicts.length} />}
9 {currentUserId ? <UserMenu /> : <LoginButton />}
10 </header>
11 )
12}

For corrected timestamps instead of engine status, see the separate api/use-flux-time hook. For resolving what activeConflicts surfaces, see api/resolve-unified-conflict.