React SDK — Realtime

Access the realtime client via the useAerostack hook.

import { useAerostack } from '@aerostack/react'
 
const { realtime } = useAerostack()

The realtime object is a RealtimeClient instance — connected automatically when AerostackProvider mounts.

RealtimeClient methods

realtime.channel(topic, options?)

Get (or create) a subscription for a topic. Returns a RealtimeSubscription.

const channel = realtime.channel('orders')           // DB table subscription
const channel = realtime.channel('chat/general')     // Custom pub/sub channel
const channel = realtime.channel('ai-chat/session-1') // Session channel
ParameterTypeDescription
topicstringChannel topic. No slash → DB table subscription. With slash → custom channel.
options.filterRecord<string, any>Optional server-side filter

realtime.onStatusChange(callback)

Subscribe to connection status changes. Returns an unsubscribe function.

const unsubscribe = realtime.onStatusChange((status) => {
  // 'idle' | 'connecting' | 'connected' | 'reconnecting' | 'disconnected'
  setConnectionStatus(status)
})
 
// Cleanup:
unsubscribe()

realtime.connect() / realtime.disconnect()

Manually connect or disconnect. The SDK connects automatically on mount.

await realtime.connect()
realtime.disconnect()

realtime.setToken(newToken)

Update the auth token on a live connection (e.g. after token refresh).

realtime.setToken(newAccessToken)

RealtimeSubscription methods

Returned by realtime.channel().

.on(event, callback)

Register a callback for an event. Returns this (chainable).

channel.on('INSERT', ({ data }) => { ... })
channel.on('UPDATE', ({ data, old }) => { ... })
channel.on('DELETE', ({ data }) => { ... })
channel.on('*', (payload) => { ... })           // All events
 
// Custom named events (pub/sub):
channel.on('todo:created', ({ data }) => { ... })
channel.on('presence:join', ({ data }) => { ... })

Payload shape:

interface RealtimePayload<T = any> {
  type: 'db_change' | 'event'
  topic: string
  operation?: 'INSERT' | 'UPDATE' | 'DELETE'  // DB changes
  event?: string                               // Custom event name
  data: T                                      // New/current value
  old?: T                                      // Previous value (UPDATE/DELETE)
  userId?: string
  timestamp?: number | string
}

.off(event, callback)

Remove a specific event listener.

const handler = ({ data }) => setItems(prev => [...prev, data])
channel.on('item:added', handler)
// later:
channel.off('item:added', handler)

.subscribe()

Send the subscribe message to the server. Call after registering all .on() listeners.

channel.on('INSERT', handler).subscribe()

.unsubscribe()

Send unsubscribe and clear all listeners. Call on component cleanup.

return () => channel.unsubscribe()

.publish(event, data, options?)

Broadcast a custom event to all channel subscribers.

channel.publish('todo:created', { id: '123', text: 'Buy milk' })
channel.publish('message', { text: 'Hello!' }, { persist: true })
ParameterTypeDescription
eventstringEvent name
dataanyPayload to broadcast
options.persistbooleanStore message in DB for history

.track(state)

Announce your presence on this channel.

channel.track({
  userId: user.id,
  name: user.name,
  color: '#FF5733',
  status: 'online',
})

.untrack()

Remove your presence from this channel. Broadcasts presence:leave.

channel.untrack()

.getHistory(limit?, before?)

Fetch persisted messages. Requires previous publishes with { persist: true }.

const messages = await channel.getHistory(50)
// messages: HistoryMessage[]
 
// Paginate:
const older = await channel.getHistory(50, messages[messages.length - 1].created_at)

HistoryMessage shape:

interface HistoryMessage {
  id: string
  room_id: string
  user_id: string
  event: string
  data: any
  created_at: number
}

React pattern: useEffect subscription

import { useAerostack } from '@aerostack/react'
import { useEffect, useState } from 'react'
 
function LiveData() {
  const { realtime } = useAerostack()
  const [items, setItems] = useState([])
 
  useEffect(() => {
    const channel = realtime.channel('items')
 
    channel
      .on('INSERT', ({ data }) => setItems(prev => [...prev, data]))
      .on('UPDATE', ({ data }) => setItems(prev => prev.map(i => i.id === data.id ? data : i)))
      .on('DELETE', ({ data }) => setItems(prev => prev.filter(i => i.id !== data.id)))
      .subscribe()
 
    return () => channel.unsubscribe()
  }, [realtime])
 
  return <ul>{items.map(i => <li key={i.id}>{i.name}</li>)}</ul>
}