Skip to content

Commit bcea356

Browse files
committed
demo: use createTransportHooks for type-safe hook access
Both demos now call `createTransportHooks<TEvent, TMessage>()` in their `providers.tsx` and destructure `TransportProvider` and all hooks from the returned object, rather than importing them directly from `@ably/ai-transport/react`. This threads the codec generics through the hook layer so hook calls don't need explicit type annotations at the call site.
1 parent da36272 commit bcea356

File tree

6 files changed

+30
-18
lines changed

6 files changed

+30
-18
lines changed

demo/vercel/react/use-chat/src/app/chat.tsx

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,23 @@
11
'use client';
22

33
import { useChat } from '@ai-sdk/react';
4-
import type * as AI from 'ai';
5-
import { useClientTransport, useActiveTurns, useView, useAblyMessages } from '@ably/ai-transport/react';
64
import { useChatTransport, useMessageSync } from '@ably/ai-transport/vercel/react';
75
import { useState, useEffect, useCallback } from 'react';
86
import { MessageList } from './components/message-list';
97
import { DebugPane } from './components/debug-pane';
108
import type { CallbackLogEntry } from './components/debug-pane';
119
import { useClientTools } from './hooks/use-client-tools';
10+
import { TransportHooks } from './providers';
11+
12+
const { useClientTransport, useActiveTurns, useView, useAblyMessages } = TransportHooks;
1213

1314
// ---------------------------------------------------------------------------
1415
// Chat component
1516
// ---------------------------------------------------------------------------
1617

1718
export function Chat({ chatId, clientId, historyLimit }: { chatId: string; clientId?: string; historyLimit?: number }) {
1819
// Transport is created by TransportProvider in page.tsx
19-
const transport = useClientTransport<AI.UIMessageChunk, AI.UIMessage>({ channelName: chatId });
20+
const transport = useClientTransport();
2021
const chatTransport = useChatTransport(transport);
2122

2223
// -- Callback & status logging for debug pane ----------------------------
@@ -67,15 +68,15 @@ export function Chat({ chatId, clientId, historyLimit }: { chatId: string; clien
6768
setStatusLog((prev) => [...prev, { time: Date.now(), status }]);
6869
}, [status]);
6970

70-
const activeTurns = useActiveTurns({ transport });
71+
const activeTurns = useActiveTurns();
7172
const hasAnyTurns = activeTurns.size > 0;
7273

7374
// Auto-loads first page on mount
74-
const { nodes, hasOlder, loading, loadOlder } = useView({ transport, limit: historyLimit ?? 30 });
75+
const { nodes, hasOlder, loading, loadOlder } = useView({ limit: historyLimit ?? 30 });
7576

7677
useClientTools(chatMessages, addToolResult, nodes, clientId);
7778

78-
const ablyMessages = useAblyMessages({ transport });
79+
const ablyMessages = useAblyMessages();
7980

8081
return (
8182
<div className="flex h-dvh">

demo/vercel/react/use-chat/src/app/page.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
'use client';
22

3-
import { Providers, useAblyReady } from './providers';
4-
import { TransportProvider } from '@ably/ai-transport/react';
3+
import { Providers, useAblyReady, TransportHooks } from './providers';
54
import { UIMessageCodec } from '@ably/ai-transport/vercel';
65
import { Chat } from './chat';
76
import { useSearchParams } from 'next/navigation';
87
import { Suspense } from 'react';
98

9+
const { TransportProvider } = TransportHooks;
10+
1011
const DEFAULT_CHANNEL = process.env.NEXT_PUBLIC_ABLY_CHANNEL ?? 'ai:demo';
1112

1213
function ChatWhenReady({ channelName, clientId, limit }: { channelName: string; clientId?: string; limit?: number }) {

demo/vercel/react/use-chat/src/app/providers.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
import { createContext, useContext, useEffect, useState, type ReactNode } from 'react';
44
import * as Ably from 'ably';
55
import { AblyProvider } from 'ably/react';
6+
import { createTransportHooks } from '@ably/ai-transport/react';
7+
import type * as AI from 'ai';
8+
9+
export const TransportHooks = createTransportHooks<AI.UIMessageChunk, AI.UIMessage>();
610

711
const AblyReadyContext = createContext(false);
812

demo/vercel/react/use-client-transport/src/app/components/chat.tsx

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
'use client';
22

33
import { useState, useCallback } from 'react';
4-
import type * as AI from 'ai';
5-
import { useClientTransport, useCreateView, useActiveTurns, useView, useAblyMessages } from '@ably/ai-transport/react';
64

75
import { userMessage } from '../helpers';
86
import { useClientTools } from '../hooks/use-client-tools';
@@ -13,6 +11,9 @@ import { MessageQueue } from './message-queue';
1311
import { InputBar } from './input-bar';
1412
import { DebugPane } from './debug-pane';
1513
import { ChatPane } from './chat-pane';
14+
import { TransportHooks } from '../providers';
15+
16+
const { useClientTransport, useCreateView, useActiveTurns, useView, useAblyMessages } = TransportHooks;
1617

1718
export interface ToolApproval {
1819
toolCallId: string;
@@ -28,19 +29,19 @@ interface ChatProps {
2829
historyLimit?: number;
2930
}
3031

31-
export function Chat({ chatId, clientId, historyLimit }: ChatProps) {
32+
export function Chat({ clientId, historyLimit }: ChatProps) {
3233
// Transport is created by TransportProvider in page.tsx
33-
const transport = useClientTransport<AI.UIMessageChunk, AI.UIMessage>({ channelName: chatId });
34+
const transport = useClientTransport();
3435
const [split, setSplit] = useState(false);
3536

3637
const limit = historyLimit ?? 30;
37-
const view = useView({ transport, limit });
38-
const splitView = useCreateView({ transport, limit, skip: !split });
38+
const view = useView({ limit });
39+
const splitView = useCreateView({ limit, skip: !split });
3940

4041
useClientTools(view, clientId);
4142

42-
const activeTurns = useActiveTurns({ transport });
43-
const ablyMessages = useAblyMessages({ transport });
43+
const activeTurns = useActiveTurns();
44+
const ablyMessages = useAblyMessages();
4445
const queue = useMessageQueue(transport, view.send);
4546

4647
const handleToolApproved = useCallback(

demo/vercel/react/use-client-transport/src/app/page.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
'use client';
22

3-
import { Providers, useAblyReady } from './providers';
4-
import { TransportProvider } from '@ably/ai-transport/react';
3+
import { Providers, useAblyReady, TransportHooks } from './providers';
54
import { UIMessageCodec } from '@ably/ai-transport/vercel';
65
import { Chat } from './components/chat';
76
import { useSearchParams } from 'next/navigation';
87
import { Suspense } from 'react';
98

9+
const { TransportProvider } = TransportHooks;
10+
1011
const DEFAULT_CHANNEL = process.env.NEXT_PUBLIC_ABLY_CHANNEL ?? 'ai:demo';
1112

1213
function ChatWhenReady({ channelName, clientId, limit }: { channelName: string; clientId?: string; limit?: number }) {

demo/vercel/react/use-client-transport/src/app/providers.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
import { createContext, useContext, useEffect, useState, type ReactNode } from 'react';
44
import * as Ably from 'ably';
55
import { AblyProvider } from 'ably/react';
6+
import { createTransportHooks } from '@ably/ai-transport/react';
7+
import type * as AI from 'ai';
8+
9+
export const TransportHooks = createTransportHooks<AI.UIMessageChunk, AI.UIMessage>();
610

711
const AblyReadyContext = createContext(false);
812

0 commit comments

Comments
 (0)