CarpoSDK docs

Realtime database updates

Subscribe to authorized table invalidations and refresh Database queries.

Carpo Realtime sends table and operation metadata. It does not send row contents. The SDK responds to a change by invalidating the matching TanStack Query entries, then reads the current rows through the permission checked Database Data API.

Live rows hook

function TodoList() {
  const todos = useLiveDatabaseRows<Todo>(
    'todos',
    { where: { completed: false }, orderBy: 'id' },
    { onRealtimeError: (error) => console.error('Realtime error', error) },
  )

  return (
    <>
      <p>Connection: {todos.realtimeStatus}</p>
      <ul>
        {todos.data?.rows.map((todo) => <li key={todo.id}>{todo.title}</li>)}
      </ul>
    </>
  )
}

The hook re-fetches after a table change and when the socket reconnects. realtimeStatus is connecting, connected, reconnecting, or disconnected.

Subscribe without a hook

For client code that does not use React, subscribe with the Database client's Realtime client:

const unsubscribe = carpo.database.realtime.subscribe({
  tables: ['todos'],
  onChange(event) {
    console.log(event.table, event.operation, event.committedAt)
  },
  onStatusChange(status) {
    console.log(status)
  },
  onError(error) {
    console.error(error)
  },
})

unsubscribe()

The client shares one WebSocket across its local table subscriptions. Subscribe to between 1 and 100 distinct table names. When user credentials change, the React provider refreshes the connection identity. A non React integration can call setIdentityKey() or refresh() after the app changes credentials.

Delivery model

Realtime is best effort invalidation, not a durable event log or a row snapshot stream. Changes made through Carpo's Database Data API, managed table tools, SQL editor, and Function Database capability publish invalidations. Direct writes made with a privileged libSQL connection, Turso CLI, or another external database client do not pass through the event publisher.

When a connection returns, the hook refetches its rows to recover changes missed while offline. Keep normal refetch behavior in place for freshness. Database policies still apply when the SDK reloads results.

On this page