The Expo SDK (@fivexer/expo) is the worker-facing mobile layer. The base
@fivexer/sdk already works in Expo because it is zero-dependency and only needs
fetch; this package adds SecureStore session persistence, a live WebSocket
queue, React hooks, push notifications, and location updates.
Install
bashnpx expo install @fivexer/expo @fivexer/sdk expo-secure-store expo-notifications expo-location expo-constants react
Scope
This package is worker-portal only. It logs in with a worker id + PIN and
uses a scoped wt_... token. Never embed a workspace sk_... API key in a
mobile app.
Quickstart
tsximport { FivexerWorkerProvider, ExpoFivexerWorker, useWorkerSession, useQueue } from '@fivexer/expo'; const worker = new ExpoFivexerWorker({ baseUrl: 'https://api.fivexer.com' }); function App() { return ( <FivexerWorkerProvider worker={worker}> <WorkerScreen /> </FivexerWorkerProvider> ); } function WorkerScreen() { const { session, login, logout, loading } = useWorkerSession(); const { taskIds } = useQueue(); if (loading) return <Text>Resuming…</Text>; if (!session) { return <Button title="Log in" onPress={() => login({ workspaceId: 'ws_...', workerId: 'w_...', pin: '1234' })} />; } return ( <View> <Text>Hello, {session.workerId}</Text> <Text>Queue: {taskIds.length} tasks</Text> <Button title="Log out" onPress={logout} /> </View> ); }
Hooks
useWorkerSession()— session, realtime connection status,login,logout,refreshSession.useQueue()— live task queue; refreshes automatically ontask.matchedand other lifecycle events.useShift()— the worker's shift state and the switch that changes it. Workers are created off shift, so an app that never callssetAvailable(true)correctly receives no work; surface this control prominently.useTaskDetail(taskId)— rich task detail for a task assigned to the worker.useBreaks()— today's breaks and completed-task count.useTeamPresence()— read-only view of who is working vs on break.useMetricsToday()— completed tasks, break time, working time.
Push notifications
tsximport { registerForPushNotificationsAsync } from '@fivexer/expo'; async function enablePush(worker: ExpoFivexerWorker) { const registration = await registerForPushNotificationsAsync(worker); if (!registration) return; // permission denied // call registration.unregister() on logout }
The platform sends a push when a task is matched to this worker. Tapping the
notification is handled by your app's expo-notifications response listener.
Location updates
tsximport { startLocationUpdatesAsync } from '@fivexer/expo'; async function enableLocation(worker: ExpoFivexerWorker) { const { remove } = await startLocationUpdatesAsync(worker, { intervalMs: 30_000 }); // call remove() when the shift ends }
Updates are throttled client-side and the server rate-limits them to avoid churn on the matching data plane.
Realtime connection
The provider opens a WebSocket to /realtime?token=wt_... when the app is in
the foreground and a session exists. It reconnects with backoff after network
errors and pauses while the app is backgrounded to save battery.
Custom storage
For tests or non-standard environments you can pass a SecureStoreBackend:
tsconst worker = new ExpoFivexerWorker({ baseUrl: 'https://api.fivexer.com', storage: myAsyncKeyValueStore, });