Skip to content

Commit 4ae3307

Browse files
transport: split into client/ and server/ subdirectories
Move client-only and server-only transport files into dedicated subdirectories to make navigability clearer for people finding their way around the codebase. Split types.ts into shared (root), client/types.ts, and server/types.ts. Mirror the same structure in test/core/transport/. Update all import paths and documentation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 264255b commit 4ae3307

44 files changed

Lines changed: 629 additions & 613 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.claude/rules/ABSTRACTIONS.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
src/
77
├── core/ # Core SDK — no model/agent library/framework -specific dependencies
88
│ ├── codec/ # Core codec definitions
9-
│ └── transport/ # Core transport definitions
9+
│ └── transport/ # Shared transport types and headers
10+
│ ├── client/ # Client transport, conversation tree, stream router, history
11+
│ └── server/ # Server transport, turn manager, pipe stream
1012
├── react/ # React bindings
1113
│ ├── hooks/ # React hooks - one file per hook
1214
│ │ └── internal/ # Shared hook helpers (not exported)

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,9 @@ npm run precommit # format:check + lint + typecheck
410410
src/
411411
├── core/ # Generic transport and codec (no framework deps)
412412
│ ├── codec/ # Codec interfaces and core encoder/decoder
413-
│ └── transport/ # ClientTransport, ServerTransport, ConversationTree
413+
│ └── transport/ # Shared types and headers
414+
│ ├── client/ # ClientTransport, ConversationTree, StreamRouter, decodeHistory
415+
│ └── server/ # ServerTransport, TurnManager, pipeStream
414416
├── react/ # React hooks for any codec
415417
├── vercel/ # Vercel AI SDK codec and transport adapters
416418
│ ├── codec/ # UIMessageCodec

docs/internals/client-transport.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Client transport
22

3-
The client transport (`src/core/transport/client-transport.ts`) manages the full client-side conversation lifecycle over a single Ably channel. It composes a [stream router](transport-components.md#streamrouter), [conversation tree](conversation-tree.md), and codec [decoder](decoder.md)/[accumulator](codec-interface.md#accumulator) to handle sending messages, receiving streamed responses, managing conversation state, and supporting branching operations (edit, regenerate).
3+
The client transport (`src/core/transport/client/client-transport.ts`) manages the full client-side conversation lifecycle over a single Ably channel. It composes a [stream router](transport-components.md#streamrouter), [conversation tree](conversation-tree.md), and codec [decoder](decoder.md)/[accumulator](codec-interface.md#accumulator) to handle sending messages, receiving streamed responses, managing conversation state, and supporting branching operations (edit, regenerate).
44

55
The client never publishes domain messages directly to the channel. Instead, it sends them to the server via HTTP POST. The server publishes user messages and [turn lifecycle events](wire-protocol.md#lifecycle-events) on behalf of the client. The channel subscription is the sole source of truth for conversation state.
66

docs/internals/conversation-tree.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Conversation tree
22

3-
The conversation tree (`src/core/transport/conversation-tree.ts`) materializes a branching conversation from a flat stream of Ably messages. It handles message ordering, sibling grouping for edit/regenerate forks, and branch selection - producing a linear message list via `flatten()` that represents the currently selected conversation path.
3+
The conversation tree (`src/core/transport/client/conversation-tree.ts`) materializes a branching conversation from a flat stream of Ably messages. It handles message ordering, sibling grouping for edit/regenerate forks, and branch selection - producing a linear message list via `flatten()` that represents the currently selected conversation path.
44

55
The tree is the single source of truth for conversation state. The transport's `getMessages()` delegates directly to `tree.flatten()`.
66

docs/internals/glossary.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ Every Ably message has an `extras` field that can carry metadata. The AI Transpo
4545

4646
The SDK has two layers with a strict boundary:
4747

48-
- **Transport layer** - generic machinery shared by all codecs. Handles turn lifecycle, stream routing, optimistic reconciliation, cancel signals, and conversation tree management. Uses `x-ably-*` headers. Lives in `src/core/transport/`.
48+
- **Transport layer** - generic machinery shared by all codecs. Handles turn lifecycle, stream routing, optimistic reconciliation, cancel signals, and conversation tree management. Uses `x-ably-*` headers. Lives in `src/core/transport/` (with client-side components in `src/core/transport/client/` and server-side components in `src/core/transport/server/`).
4949
- **Domain layer** - framework-specific encoding/decoding. Maps between domain events (e.g. Vercel's `UIMessageChunk`) and Ably messages. Uses `x-domain-*` headers. Lives in codec implementations (e.g. `src/vercel/codec/`).
5050

5151
The [codec interface](codec-interface.md) is the boundary between these layers.

docs/internals/history.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# History hydration
22

3-
`decodeHistory` (`src/core/transport/decode-history.ts`) loads conversation history from an Ably channel's history API and returns decoded domain messages. It handles the mismatch between Ably's newest-first history pagination and the decoder's requirement for chronological input.
3+
`decodeHistory` (`src/core/transport/client/decode-history.ts`) loads conversation history from an Ably channel's history API and returns decoded domain messages. It handles the mismatch between Ably's newest-first history pagination and the decoder's requirement for chronological input.
44

55
## The problem
66

docs/internals/server-transport.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Server transport
22

3-
The server transport (`src/core/transport/server-transport.ts`) handles the server-side turn lifecycle over an Ably channel. It composes a [TurnManager](transport-components.md#turnmanager) for turn state and lifecycle event publishing, and delegates stream piping to [pipeStream](transport-components.md#pipestream).
3+
The server transport (`src/core/transport/server/server-transport.ts`) handles the server-side turn lifecycle over an Ably channel. It composes a [TurnManager](transport-components.md#turnmanager) for turn state and lifecycle event publishing, and delegates stream piping to [pipeStream](transport-components.md#pipestream).
44

55
The transport exposes a single factory method - `newTurn()` - which returns a `Turn` object with explicit lifecycle methods: `start()`, `addMessages()`, `streamResponse()`, and `end()`.
66

docs/internals/transport-components.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ The client and server transports are composed from several focused sub-component
44

55
## StreamRouter
66

7-
`src/core/transport/stream-router.ts` - client-side only.
7+
`src/core/transport/client/stream-router.ts` - client-side only.
88

99
The stream router maps decoded events to per-turn `ReadableStream` instances for [own turns](glossary.md#own-turn-vs-observer-turn) - turns this client initiated via `send()`, `regenerate()`, or `edit()`. When the client starts a turn, the router creates a new stream. As decoded events arrive from the channel subscription, the transport routes them through the router to the correct stream.
1010

@@ -31,7 +31,7 @@ The router accepts an [`isTerminal`](codec-interface.md#the-codec-interface) pre
3131

3232
## TurnManager
3333

34-
`src/core/transport/turn-manager.ts` - server-side only.
34+
`src/core/transport/server/turn-manager.ts` - server-side only.
3535

3636
The turn manager tracks active turns and publishes [turn lifecycle events](wire-protocol.md#lifecycle-events) (`x-ably-turn-start`, `x-ably-turn-end`) on the Ably channel.
3737

@@ -55,7 +55,7 @@ The turn manager publishes `x-ably-turn-end` **before** deleting local state. If
5555

5656
## pipeStream
5757

58-
`src/core/transport/pipe-stream.ts` - server-side only.
58+
`src/core/transport/server/pipe-stream.ts` - server-side only.
5959

6060
A pure function that reads events from a `ReadableStream`, writes them through a [streaming encoder](codec-interface.md#encoder-architecture), and handles abort/error. No dependencies on turn state or transport internals.
6161

@@ -90,7 +90,7 @@ Returns `{ reason }` where reason is `'complete'`, `'cancelled'`, or `'error'`.
9090

9191
## Cancel routing (server transport)
9292

93-
Cancel routing lives in the server transport (`src/core/transport/server-transport.ts`), not in a separate component.
93+
Cancel routing lives in the server transport (`src/core/transport/server/server-transport.ts`), not in a separate component.
9494

9595
The server transport subscribes to [`x-ably-cancel`](wire-protocol.md#lifecycle-events) events on channel construction. When a cancel message arrives, it:
9696

src/core/transport/client-transport.ts renamed to src/core/transport/client/client-transport.ts

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,31 +26,28 @@ import {
2626
HEADER_TURN_CLIENT_ID,
2727
HEADER_TURN_ID,
2828
HEADER_TURN_REASON,
29-
} from '../../constants.js';
30-
import { ErrorCode } from '../../errors.js';
31-
import { EventEmitter } from '../../event-emitter.js';
32-
import type { Logger } from '../../logger.js';
33-
import { LogLevel, makeLogger } from '../../logger.js';
34-
import { getHeaders } from '../../utils.js';
35-
import type { DecoderOutput, MessageAccumulator, StreamDecoder } from '../codec/types.js';
29+
} from '../../../constants.js';
30+
import { ErrorCode } from '../../../errors.js';
31+
import { EventEmitter } from '../../../event-emitter.js';
32+
import type { Logger } from '../../../logger.js';
33+
import { LogLevel, makeLogger } from '../../../logger.js';
34+
import { getHeaders } from '../../../utils.js';
35+
import type { DecoderOutput, MessageAccumulator, StreamDecoder } from '../../codec/types.js';
36+
import { buildTransportHeaders } from '../headers.js';
37+
import type { CancelFilter, MessageWithHeaders, TurnEndReason, TurnLifecycleEvent } from '../types.js';
3638
import { createConversationTree } from './conversation-tree.js';
3739
import { decodeHistory } from './decode-history.js';
38-
import { buildTransportHeaders } from './headers.js';
3940
import type { StreamRouter } from './stream-router.js';
4041
import { createStreamRouter } from './stream-router.js';
4142
import type {
4243
ActiveTurn,
43-
CancelFilter,
4444
ClientTransport,
4545
ClientTransportOptions,
4646
CloseOptions,
4747
ConversationTree,
4848
LoadHistoryOptions,
49-
MessageWithHeaders,
5049
PaginatedMessages,
5150
SendOptions,
52-
TurnEndReason,
53-
TurnLifecycleEvent,
5451
} from './types.js';
5552

5653
/**

src/core/transport/conversation-tree.ts renamed to src/core/transport/client/conversation-tree.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@
1616
* `getMessages()` delegates to.
1717
*/
1818

19-
import { HEADER_FORK_OF, HEADER_PARENT } from '../../constants.js';
20-
import type { Logger } from '../../logger.js';
19+
import { HEADER_FORK_OF, HEADER_PARENT } from '../../../constants.js';
20+
import type { Logger } from '../../../logger.js';
2121
import type { ConversationNode, ConversationTree } from './types.js';
2222

2323
// ---------------------------------------------------------------------------

0 commit comments

Comments
 (0)