Skip to content

Commit b43799e

Browse files
mschristensenclaude
andcommitted
docs: fix flattenNodes return type and simplify code examples
Update docs to reflect that flattenNodes() returns ConversationNode<TMessage>[], not TMessage[]. Simplify code examples to iterate getMessagesWithHeaders() directly instead of constructing a Map. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 2bdedef commit b43799e

5 files changed

Lines changed: 13 additions & 17 deletions

File tree

docs/features/branching.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,11 @@ const tree = useConversationTree(transport);
7474
// tree.getSelectedIndex(nodeId) - which sibling is currently selected
7575
// tree.selectSibling(nodeId, index) - switch to a different sibling
7676
//
77-
// nodeId is the x-ably-msg-id for each message - resolve it from headers:
78-
// const allWithHeaders = transport.getMessagesWithHeaders();
79-
// const headers = allWithHeaders.find((entry) => entry.message === msg)?.headers;
80-
// const nodeId = headers?.['x-ably-msg-id'] ?? msg.id;
77+
// nodeId is the x-ably-msg-id for each message - iterate getMessagesWithHeaders()
78+
// to get messages paired with their headers:
79+
// transport.getMessagesWithHeaders().map(({ message: msg, headers }) => {
80+
// const nodeId = headers?.['x-ably-msg-id'] ?? msg.id;
81+
// });
8182
```
8283

8384
Build a sibling navigator (where `nodeId` is the resolved `x-ably-msg-id` for the message):

docs/get-started/vercel-use-client-transport.md

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,7 @@ import { useState } from 'react';
3131

3232
// Resolve the x-ably-msg-id for a message. Tree methods and regenerate/edit
3333
// use x-ably-msg-id as the key, not UIMessage.id.
34-
// Build a headers lookup once, then resolve per message.
35-
function treeMsgId(msg: UIMessage, headersByMessage: Map<UIMessage, Record<string, string> | undefined>): string {
36-
const headers = headersByMessage.get(msg);
34+
function treeMsgId(headers: Record<string, string> | undefined, msg: UIMessage): string {
3735
return headers?.['x-ably-msg-id'] ?? msg.id;
3836
}
3937

@@ -60,10 +58,7 @@ function ChatInner({ chatId, clientId }: { chatId: string; clientId?: string })
6058

6159
const isStreaming = activeTurns.size > 0;
6260

63-
// Build a lookup map from message to headers once per render.
64-
const headersByMessage = new Map(
65-
transport.getMessagesWithHeaders().map((entry) => [entry.message, entry.headers]),
66-
);
61+
const messagesWithHeaders = transport.getMessagesWithHeaders();
6762

6863
const handleSend = () => {
6964
const text = input.trim();
@@ -88,9 +83,9 @@ function ChatInner({ chatId, clientId }: { chatId: string; clientId?: string })
8883
</button>
8984
)}
9085

91-
{/* Message list from the conversation tree */}
92-
{tree.messages.map((msg) => {
93-
const nodeId = treeMsgId(msg, headersByMessage);
86+
{/* Message list with headers for tree navigation */}
87+
{messagesWithHeaders.map(({ message: msg, headers }) => {
88+
const nodeId = treeMsgId(headers, msg);
9489
return (
9590
<div key={msg.id}>
9691
<strong>{msg.role}:</strong>

docs/internals/client-transport.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ The client never publishes domain messages directly to the channel. Instead, it
88

99
```
1010
DefaultClientTransport
11-
├── ConversationTree - branching message history (flatten → getMessages)
11+
├── ConversationTree - branching message history (flattenNodes → getMessages)
1212
├── StreamRouter - maps turn events to per-turn ReadableStreams
1313
├── StreamDecoder - decodes inbound Ably messages to events/messages
1414
├── EventEmitter - typed event bus for message/turn/error/ably-message

docs/internals/glossary.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ A codec-provided component that assembles [decoder outputs](decoder.md#decoder-o
118118

119119
### Message materialization
120120

121-
The act of producing a flat `TMessage[]` from the [conversation tree](conversation-tree.md) via [`flattenNodes()`](#flatten). Every call rebuilds from scratch - there is no cached list - because the result depends on branch selection state. All consumers go through `getMessages()`, which delegates to `flattenNodes()`: React hooks, `send()` (for the HTTP POST body), `history()` (for pagination snapshots). See [Message lifecycle](message-lifecycle.md#why-no-cached-message-list).
121+
The act of producing a flat message list from the [conversation tree](conversation-tree.md) via [`flattenNodes()`](#flatten). `flattenNodes()` returns `ConversationNode<TMessage>[]` - the transport's `getMessages()` extracts `.message` from each node to produce the public `TMessage[]`. Every call rebuilds from scratch - there is no cached list - because the result depends on branch selection state. All consumers go through `getMessages()`, which delegates to `flattenNodes()`: React hooks, `send()` (for the HTTP POST body), `history()` (for pagination snapshots). See [Message lifecycle](message-lifecycle.md#why-no-cached-message-list).
122122

123123
### Flatten
124124

docs/internals/message-lifecycle.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ When the decoder produces a `{ kind: 'message' }` output (e.g. a user message de
8888

8989
## How messages reach the UI
9090

91-
The [conversation tree's](conversation-tree.md#flatten-producing-the-linear-path) `flattenNodes()` method is the sole path from tree state to a message array. It walks the sorted node list, checks parent reachability and sibling selection, and returns the linear `TMessage[]` for the currently selected conversation path.
91+
The [conversation tree's](conversation-tree.md#flatten-producing-the-linear-path) `flattenNodes()` method is the sole path from tree state to a message array. It walks the sorted node list, checks parent reachability and sibling selection, and returns `ConversationNode<TMessage>[]` for the currently selected conversation path. `ClientTransport.getMessages()` extracts the `.message` from each node to produce the public `TMessage[]`.
9292

9393
`ClientTransport.getMessages()` calls `flattenNodes()` and filters out any messages withheld by the history pagination buffer. This is the public API that all downstream consumers call.
9494

0 commit comments

Comments
 (0)