Skip to content

ait: add react token streaming examples#3268

Open
owenpearson wants to merge 1 commit intomainfrom
react-token-streaming
Open

ait: add react token streaming examples#3268
owenpearson wants to merge 1 commit intomainfrom
react-token-streaming

Conversation

@owenpearson
Copy link
Member

@owenpearson owenpearson commented Mar 12, 2026

AIT-253

  • Adds React token streaming examples to the token streaming docs based on what was agreed in aitdr-004

@coderabbitai
Copy link

coderabbitai bot commented Mar 12, 2026

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 3aab2d6d-0e63-487a-aa44-ed12ebcf79a5

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch react-token-streaming

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@VeskeR VeskeR added review-app Create a Heroku review app and removed review-app Create a Heroku review app labels Mar 19, 2026
return next;
});
} else if (message.name === 'stop') {
console.log('Response complete:', responses.get(responseId));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

responses can be stale here if batched setResponses updates haven't flushed to a render when stop arrives.
I think we need to use an updater here too, to read the latest state:

     setResponses((prev) => {
        console.log('Response complete:', prev.get(responseId));
        return prev; // no state change
      });

});
```
```react
// Set rewind via ChannelProvider options={{ params: { rewind: '2m' } }}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WDYT about adding quick React setup context for useChannel examples?

The JS/Python/Java examples don't show full realtime client setup either, but that's fine, in those languages, channel configuration is visible inline: realtime.channels.get('ai:channel', { params: { rewind: '2m' } }) - makes it clear how the channel name, namespace prefix, and options all come together.
React splits this across a component hierarchy (AblyProvider -> ChannelProvider -> useChannel), so a reader seeing only useChannel('ai:channel', callback) doesn't see where channel options like rewind are configured or that the component must be nested inside specific providers, like ChannelProvider with channelName="ai:channel".

This rewind example addresses this with a comment, but that's easy to miss and doesn't convey the structural requirement - that your component tree needs to be shaped in a specific way for the hook to work at all.

How about adding a short <If lang="react"> block right after the "Subscribing to token streams" heading (message-per-response) and "Streaming patterns" heading (message-per-token), before the user sees the first React code example:

<If lang="react">
<Aside data-type='note'>
These examples use the `useChannel` hook from `ably/react`. Your component must be wrapped in an [`AblyProvider`](/docs/getting-started/react#prerequisites-setup-ably-provider) and a [`ChannelProvider`](/docs/getting-started/react#step-2-channel-provider) that specifies the channel name and any channel options. For example, to subscribe with rewind enabled on an
`ai:` namespaced channel:

```react
<AblyProvider client={realtimeClient}>
  <ChannelProvider channelName="ai:my-channel" options={{ params: { rewind: '2m' } }}>
    <YourComponent />
  </ChannelProvider>
</AblyProvider>
\```
</Aside>
</If>

if (!responseId) return;

// Skip messages for responses already loaded from database
if (completedResponses.has(responseId)) return;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this react snippet is missing the example where completedResponses comes from (loaded from database)

const responseId = message.extras?.headers?.responseId;

if (!responseId) return;
if (completedResponses.has(responseId)) return;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same, not clear where completedResponses came from

hydrated.current = true;

(async () => {
let page = await history({ untilAttach: true, start: latestTimestamp });
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not clear where latestTimestamp came from (timestamp of the latest completedResponses message)

if (!responseId) return;

// Skip tokens for responses already hydrated from database
if (completedResponses.has(responseId)) return;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto unclear completedResponses

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

review-app Create a Heroku review app

Development

Successfully merging this pull request may close these issues.

2 participants