Fleet & auto-reconnect
Once a device is saved, the SDK remembers it, reconnects it when it comes back into range, and lets you manage it — all as reactive state and declarative policy. This guide covers the saved-device list, per-device actions, the derived reconnect toast, and the provider-level fleet policy.
Saved devices
Section titled “Saved devices”useSavedDevices() is the data source for a “My devices” screen: the saved
devices in deterministic fleet order, plus a hydration flag so you can render a
skeleton before persisted state has loaded from storage.
import { useSavedDevices } from '@rogue/console-sdk';
function MyDevices() { const { devices, isHydrated } = useSavedDevices(); if (!isHydrated) return <Skeleton />; if (devices.length === 0) return <EmptyState />; return devices.map((device) => <SavedDeviceRow key={device.id} device={device} />);}Saved is just a facet of the one Device record — this is
useDevices({ saved: true }) with a hydration flag, not a second list to
reconcile against the discovered one.
Per-device actions
Section titled “Per-device actions”useDeviceActions(deviceId) collapses the whole legacy five-function blocklist
protocol into three verbs, each keyed by one device. All three are bare verbs
that never reject — a failure routes to state and the error reporter, so an
onPress={forget} handler can never float an unhandled rejection.
import { useDeviceActions } from '@rogue/console-sdk';
function SavedDeviceRow({ device }: { device: Device }) { const { disconnect, forget, setAutoReconnect } = useDeviceActions(device.id); return ( <Row> <Text>{device.displayName}</Text> <Switch value={device.autoReconnect} onValueChange={setAutoReconnect} /> {device.isConnected && <Button title="Disconnect" onPress={() => disconnect()} />} <Button title="Forget" onPress={forget} /> </Row> );}disconnect()— a deliberate disconnect. It suppresses auto-reconnect for the rest of the session; pass{ autoReconnect: false }to also persist the per-device opt-out.forget()— removes persistence and auto-reconnect eligibility.setAutoReconnect(enabled)— the whole protocol, now one boolean.
Passing null/undefined as the id is legal and yields dev-warned no-op actions,
so you can call the hook unconditionally even before a device is selected.
The reconnect toast, derived from state
Section titled “The reconnect toast, derived from state”This is the benchmark the SDK was built to hit: the ninety lines of
event-to-state adaptation the app used to write become one hook. useAutoReconnect()
derives “recently reconnected” from connection provenance — a ready
connection whose via is 'auto-reconnect' that you have not acknowledged — never
from a stored event. isSettling deletes the last reason to poll for settling.
import { useAutoReconnect } from '@rogue/console-sdk';
function AutoReconnectToast() { const { recentlyReconnected, acknowledge } = useAutoReconnect(); if (recentlyReconnected.length === 0) return null; const names = recentlyReconnected.map((r) => r.device.displayName).join(', '); return ( <Toast onDismiss={() => acknowledge()}> Reconnected to {names} </Toast> );}Mount that once near your root and reconnections announce themselves. Each
ReconnectedEntry carries the reconnected device, the epoch ms at, and a
duringWorkout flag. acknowledge(id?) drops one device from the feed (omit the
id to clear all) with no stored event to manage.
The same hook exposes the global switch:
const { enabled, setEnabled, isSettling } = useAutoReconnect();<Switch value={enabled} onValueChange={setEnabled} />;{isSettling && <Text>Reconnecting…</Text>}Fleet policy is declarative
Section titled “Fleet policy is declarative”The old MDM flag-and-blocklist choreography becomes provider config. Set it once
on createConsoleConfig(); the engine enforces it.
import { createConsoleConfig } from '@rogue/console-sdk';
const config = createConsoleConfig({ fleet: { maxDevices: 4, // max simultaneously connected onePerModality: true, // one machine per modality connectTimeoutMs: 15_000, autoReconnect: { enabled: true, duringWorkout: true, // reconnect mid-workout for session devices }, autoScan: { enabled: true, cooldownMs: 15_000, // pause between background scans inWorkoutCooldownMultiplier: 3, // scan more often during a workout postDisconnectDebounceMs: 3_000, // debounce the post-drop rescan }, },});Every field is optional and shown here at its default. onePerModality: true is
what surfaces the connect/modality-conflict error covered in
Connecting devices; maxDevices is what surfaces
connect/device-limit. Auto-scan scheduling is the machinery that lets
auto-reconnect find a device that comes back into range without you running any
timers.