@ably/ai-transport 0.0.1 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +54 -47
- package/dist/ably-ai-transport.js +1006 -539
- package/dist/ably-ai-transport.js.map +1 -1
- package/dist/ably-ai-transport.umd.cjs +1 -1
- package/dist/ably-ai-transport.umd.cjs.map +1 -1
- package/dist/constants.d.ts +4 -0
- package/dist/core/codec/types.d.ts +19 -2
- package/dist/core/transport/decode-history.d.ts +8 -6
- package/dist/core/transport/headers.d.ts +4 -2
- package/dist/core/transport/index.d.ts +4 -1
- package/dist/core/transport/pipe-stream.d.ts +3 -2
- package/dist/core/transport/stream-router.d.ts +11 -1
- package/dist/core/transport/tree.d.ts +171 -0
- package/dist/core/transport/turn-manager.d.ts +4 -1
- package/dist/core/transport/types.d.ts +270 -119
- package/dist/core/transport/view.d.ts +166 -0
- package/dist/errors.d.ts +19 -2
- package/dist/index.d.ts +3 -1
- package/dist/react/ably-ai-transport-react.js +1019 -486
- package/dist/react/ably-ai-transport-react.js.map +1 -1
- package/dist/react/ably-ai-transport-react.umd.cjs +1 -1
- package/dist/react/ably-ai-transport-react.umd.cjs.map +1 -1
- package/dist/react/contexts/transport-context.d.ts +31 -0
- package/dist/react/contexts/transport-provider.d.ts +49 -0
- package/dist/react/create-transport-hooks.d.ts +124 -0
- package/dist/react/index.d.ts +14 -8
- package/dist/react/use-ably-messages.d.ts +14 -8
- package/dist/react/use-active-turns.d.ts +7 -3
- package/dist/react/use-client-transport.d.ts +78 -5
- package/dist/react/use-create-view.d.ts +22 -0
- package/dist/react/use-tree.d.ts +20 -0
- package/dist/react/use-view.d.ts +79 -0
- package/dist/vercel/ably-ai-transport-vercel.js +1478 -842
- package/dist/vercel/ably-ai-transport-vercel.js.map +1 -1
- package/dist/vercel/ably-ai-transport-vercel.umd.cjs +1 -1
- package/dist/vercel/ably-ai-transport-vercel.umd.cjs.map +1 -1
- package/dist/vercel/codec/tool-transitions.d.ts +50 -0
- package/dist/vercel/index.d.ts +3 -0
- package/dist/vercel/react/ably-ai-transport-vercel-react.js +9099 -852
- package/dist/vercel/react/ably-ai-transport-vercel-react.js.map +1 -1
- package/dist/vercel/react/ably-ai-transport-vercel-react.umd.cjs +45 -1
- package/dist/vercel/react/ably-ai-transport-vercel-react.umd.cjs.map +1 -1
- package/dist/vercel/react/contexts/chat-transport-context.d.ts +32 -0
- package/dist/vercel/react/contexts/chat-transport-provider.d.ts +84 -0
- package/dist/vercel/react/index.d.ts +5 -0
- package/dist/vercel/react/use-chat-transport.d.ts +61 -20
- package/dist/vercel/react/use-message-sync.d.ts +41 -9
- package/dist/vercel/react/use-staged-add-tool-approval-response.d.ts +30 -0
- package/dist/vercel/tool-approvals.d.ts +124 -0
- package/dist/vercel/tool-events.d.ts +26 -0
- package/dist/vercel/transport/chat-transport.d.ts +33 -11
- package/dist/vercel/transport/index.d.ts +5 -2
- package/package.json +23 -17
- package/src/constants.ts +6 -0
- package/src/core/codec/encoder.ts +10 -1
- package/src/core/codec/types.ts +19 -3
- package/src/core/transport/client-transport.ts +382 -364
- package/src/core/transport/decode-history.ts +229 -81
- package/src/core/transport/headers.ts +6 -2
- package/src/core/transport/index.ts +13 -5
- package/src/core/transport/pipe-stream.ts +8 -5
- package/src/core/transport/server-transport.ts +212 -58
- package/src/core/transport/stream-router.ts +21 -3
- package/src/core/transport/{conversation-tree.ts → tree.ts} +192 -77
- package/src/core/transport/turn-manager.ts +28 -10
- package/src/core/transport/types.ts +318 -139
- package/src/core/transport/view.ts +840 -0
- package/src/errors.ts +21 -1
- package/src/index.ts +10 -5
- package/src/react/contexts/transport-context.ts +37 -0
- package/src/react/contexts/transport-provider.tsx +164 -0
- package/src/react/create-transport-hooks.ts +144 -0
- package/src/react/index.ts +15 -8
- package/src/react/use-ably-messages.ts +34 -16
- package/src/react/use-active-turns.ts +28 -17
- package/src/react/use-client-transport.ts +184 -24
- package/src/react/use-create-view.ts +68 -0
- package/src/react/use-tree.ts +53 -0
- package/src/react/use-view.ts +233 -0
- package/src/react/vite.config.ts +4 -1
- package/src/vercel/codec/accumulator.ts +64 -79
- package/src/vercel/codec/decoder.ts +11 -8
- package/src/vercel/codec/encoder.ts +68 -54
- package/src/vercel/codec/index.ts +0 -2
- package/src/vercel/codec/tool-transitions.ts +122 -0
- package/src/vercel/index.ts +17 -0
- package/src/vercel/react/contexts/chat-transport-context.ts +40 -0
- package/src/vercel/react/contexts/chat-transport-provider.tsx +122 -0
- package/src/vercel/react/index.ts +14 -0
- package/src/vercel/react/use-chat-transport.ts +164 -42
- package/src/vercel/react/use-message-sync.ts +77 -19
- package/src/vercel/react/use-staged-add-tool-approval-response.ts +87 -0
- package/src/vercel/react/vite.config.ts +4 -2
- package/src/vercel/tool-approvals.ts +380 -0
- package/src/vercel/tool-events.ts +53 -0
- package/src/vercel/transport/chat-transport.ts +225 -79
- package/src/vercel/transport/index.ts +14 -3
- package/dist/core/transport/conversation-tree.d.ts +0 -9
- package/dist/react/use-conversation-tree.d.ts +0 -20
- package/dist/react/use-edit.d.ts +0 -7
- package/dist/react/use-history.d.ts +0 -19
- package/dist/react/use-messages.d.ts +0 -7
- package/dist/react/use-regenerate.d.ts +0 -7
- package/dist/react/use-send.d.ts +0 -7
- package/src/react/use-conversation-tree.ts +0 -71
- package/src/react/use-edit.ts +0 -24
- package/src/react/use-history.ts +0 -111
- package/src/react/use-messages.ts +0 -32
- package/src/react/use-regenerate.ts +0 -24
- package/src/react/use-send.ts +0 -25
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { ClientTransport } from '../../core/transport/types.js';
|
|
2
|
+
import type * as Ably from 'ably';
|
|
3
|
+
/**
|
|
4
|
+
* A single entry in the transport registry, holding the transport and any
|
|
5
|
+
* error that occurred during its construction.
|
|
6
|
+
*
|
|
7
|
+
* `transport` is `undefined` when construction failed.
|
|
8
|
+
* `error` is set when `createClientTransport` threw during provider render.
|
|
9
|
+
*/
|
|
10
|
+
export interface TransportSlot {
|
|
11
|
+
/** The constructed transport, or `undefined` if construction failed. */
|
|
12
|
+
transport: ClientTransport<unknown, unknown> | undefined;
|
|
13
|
+
/** Construction error from `createClientTransport`, or `undefined` on success. */
|
|
14
|
+
error: Ably.ErrorInfo | undefined;
|
|
15
|
+
}
|
|
16
|
+
/** The shape of the TransportContext value — a record of channelName → slot. */
|
|
17
|
+
export type TransportContextValue = Readonly<Record<string, TransportSlot>>;
|
|
18
|
+
/**
|
|
19
|
+
* Context that holds the registered {@link ClientTransport} slots, keyed by channelName.
|
|
20
|
+
* Each slot contains the transport (or `undefined` on construction failure) and any error.
|
|
21
|
+
* Populated by {@link TransportProvider}; read by {@link useClientTransport}.
|
|
22
|
+
*/
|
|
23
|
+
export declare const TransportContext: import('react').Context<Readonly<Record<string, TransportSlot>>>;
|
|
24
|
+
/**
|
|
25
|
+
* Context that holds the nearest (innermost) transport slot.
|
|
26
|
+
* Each {@link TransportProvider} sets this to its own slot, so descendants
|
|
27
|
+
* can access the nearest transport without knowing its channel name.
|
|
28
|
+
* `undefined` when no provider is present.
|
|
29
|
+
* Read by hooks whose `transport` argument is omitted.
|
|
30
|
+
*/
|
|
31
|
+
export declare const NearestTransportContext: import('react').Context<TransportSlot | undefined>;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { PropsWithChildren, ReactNode } from 'react';
|
|
2
|
+
import { ClientTransportOptions } from '../../core/transport/types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Props for {@link TransportProvider}.
|
|
5
|
+
*
|
|
6
|
+
* All {@link ClientTransportOptions} except `channel` (managed internally) plus `channelName`.
|
|
7
|
+
*/
|
|
8
|
+
export interface TransportProviderProps<TEvent, TMessage> extends Omit<ClientTransportOptions<TEvent, TMessage>, 'channel'>, PropsWithChildren {
|
|
9
|
+
/** The Ably channel name to subscribe to. Also used as the context registry key. */
|
|
10
|
+
channelName: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Provide a {@link ClientTransport} to descendant components.
|
|
14
|
+
*
|
|
15
|
+
* Wraps children with Ably's `ChannelProvider` using `channelName`, creates a
|
|
16
|
+
* transport from the resolved channel and the remaining options, and registers it
|
|
17
|
+
* in `TransportContext` under `channelName`. Descendants call
|
|
18
|
+
* {@link useClientTransport} with the same `channelName` to access the transport.
|
|
19
|
+
*
|
|
20
|
+
* If `createClientTransport` throws during construction, the error is surfaced
|
|
21
|
+
* through `useClientTransport` as `transportError` — the component tree does not
|
|
22
|
+
* crash and children are still rendered.
|
|
23
|
+
*
|
|
24
|
+
* ```tsx
|
|
25
|
+
* <TransportProvider channelName="ai:demo" codec={UIMessageCodec}>
|
|
26
|
+
* <Chat />
|
|
27
|
+
* </TransportProvider>
|
|
28
|
+
*
|
|
29
|
+
* // Inside Chat:
|
|
30
|
+
* const { transport, transportError } = useClientTransport({ channelName: 'ai:demo' });
|
|
31
|
+
* ```
|
|
32
|
+
*
|
|
33
|
+
* For multiple transports, nest providers with distinct channelNames:
|
|
34
|
+
*
|
|
35
|
+
* ```tsx
|
|
36
|
+
* <TransportProvider channelName="ai:main" codec={UIMessageCodec}>
|
|
37
|
+
* <TransportProvider channelName="ai:aux" codec={UIMessageCodec}>
|
|
38
|
+
* <App />
|
|
39
|
+
* </TransportProvider>
|
|
40
|
+
* </TransportProvider>
|
|
41
|
+
*
|
|
42
|
+
* // Inside App:
|
|
43
|
+
* const { transport: main } = useClientTransport({ channelName: 'ai:main' });
|
|
44
|
+
* const { transport: aux } = useClientTransport({ channelName: 'ai:aux' });
|
|
45
|
+
* ```
|
|
46
|
+
* @param props - Provider configuration including `channelName`, `codec`, and all other {@link ClientTransportOptions}.
|
|
47
|
+
* @returns A React element wrapping children with ChannelProvider and TransportContext.
|
|
48
|
+
*/
|
|
49
|
+
export declare const TransportProvider: <TEvent, TMessage>(props: TransportProviderProps<TEvent, TMessage>) => ReactNode;
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { ComponentType } from 'react';
|
|
2
|
+
import { ClientTransport, View } from '../core/transport/types.js';
|
|
3
|
+
import { TransportProviderProps } from './contexts/transport-provider.js';
|
|
4
|
+
import { ClientTransportHandle } from './use-client-transport.js';
|
|
5
|
+
import { TreeHandle } from './use-tree.js';
|
|
6
|
+
import { ViewHandle } from './use-view.js';
|
|
7
|
+
/**
|
|
8
|
+
* createTransportHooks: factory that captures TEvent and TMessage once and returns
|
|
9
|
+
* a bundle of type-safe hooks + TransportProvider. Hook call sites need no type
|
|
10
|
+
* parameters at every use — just call the hooks directly.
|
|
11
|
+
* @example
|
|
12
|
+
* // Once per app (e.g. in a shared transport.ts):
|
|
13
|
+
* export const {
|
|
14
|
+
* TransportProvider,
|
|
15
|
+
* useClientTransport,
|
|
16
|
+
* useView,
|
|
17
|
+
* useActiveTurns,
|
|
18
|
+
* } = createTransportHooks<UIMessageChunk, UIMessage>();
|
|
19
|
+
*
|
|
20
|
+
* // In page:
|
|
21
|
+
* <TransportProvider channelName="ai:demo" codec={UIMessageCodec}>
|
|
22
|
+
* <Chat />
|
|
23
|
+
* </TransportProvider>
|
|
24
|
+
*
|
|
25
|
+
* // In Chat — no type params needed, transport is implicit from nearest provider:
|
|
26
|
+
* const { nodes } = useView({ limit: 30 });
|
|
27
|
+
* const turns = useActiveTurns();
|
|
28
|
+
*/
|
|
29
|
+
import type * as Ably from 'ably';
|
|
30
|
+
/**
|
|
31
|
+
* Bundle of type-safe hooks and provider returned by {@link createTransportHooks}.
|
|
32
|
+
*
|
|
33
|
+
* `TEvent` and `TMessage` are baked in at factory creation time so no type params
|
|
34
|
+
* are needed at hook call sites.
|
|
35
|
+
*/
|
|
36
|
+
export interface TransportHooks<TEvent, TMessage> {
|
|
37
|
+
/**
|
|
38
|
+
* `TransportProvider` narrowed to `TEvent`/`TMessage`. No JSX type params needed.
|
|
39
|
+
*/
|
|
40
|
+
TransportProvider: ComponentType<TransportProviderProps<TEvent, TMessage>>;
|
|
41
|
+
/**
|
|
42
|
+
* Read the transport from context. No type params needed.
|
|
43
|
+
*
|
|
44
|
+
* Returns `{ transport, transportError }`. When no provider is found,
|
|
45
|
+
* `transportError` is set and `transport` is a stub that throws on access —
|
|
46
|
+
* the hook never throws during render.
|
|
47
|
+
*
|
|
48
|
+
* Pass `onError` to subscribe to post-construction transport errors
|
|
49
|
+
* (e.g. send failures, channel continuity loss) without wiring
|
|
50
|
+
* `transport.on('error', …)` manually.
|
|
51
|
+
*/
|
|
52
|
+
useClientTransport: (props?: {
|
|
53
|
+
/** Channel name to look up; omit to use the nearest {@link TransportProvider}. */
|
|
54
|
+
channelName?: string;
|
|
55
|
+
/** When `true`, return a stub transport that throws on any access. */
|
|
56
|
+
skip?: boolean;
|
|
57
|
+
/** Called whenever the resolved transport emits an error event. */
|
|
58
|
+
onError?: (error: Ably.ErrorInfo) => void;
|
|
59
|
+
}) => ClientTransportHandle<TEvent, TMessage>;
|
|
60
|
+
/**
|
|
61
|
+
* Subscribe to the nearest transport's view and return the visible node list with pagination.
|
|
62
|
+
* Pass `transport` to use a transport's default view, `view` to subscribe to a specific view
|
|
63
|
+
* directly. Pass `limit` to auto-load on mount. Pass `skip: true` for an empty handle.
|
|
64
|
+
*/
|
|
65
|
+
useView: (props?: {
|
|
66
|
+
/** Client transport whose default view to subscribe to; defaults to the nearest {@link TransportProvider}. */
|
|
67
|
+
transport?: ClientTransport<TEvent, TMessage> | null;
|
|
68
|
+
/** A specific {@link View} to subscribe to directly. Takes priority over `transport`. */
|
|
69
|
+
view?: View<TEvent, TMessage> | null;
|
|
70
|
+
/** When provided, auto-loads the first page on mount. */
|
|
71
|
+
limit?: number;
|
|
72
|
+
/** When `true`, skip all subscriptions and return an empty handle. */
|
|
73
|
+
skip?: boolean;
|
|
74
|
+
}) => ViewHandle<TEvent, TMessage>;
|
|
75
|
+
/**
|
|
76
|
+
* Track active turns across all clients on the channel.
|
|
77
|
+
* Pass `transport` to override; defaults to the nearest {@link TransportProvider}.
|
|
78
|
+
*/
|
|
79
|
+
useActiveTurns: (props?: {
|
|
80
|
+
/** Override transport; defaults to the nearest {@link TransportProvider}. */
|
|
81
|
+
transport?: ClientTransport<TEvent, TMessage> | null;
|
|
82
|
+
}) => Map<string, Set<string>>;
|
|
83
|
+
/**
|
|
84
|
+
* Navigate conversation branches in the transport tree.
|
|
85
|
+
* Pass `transport` to override; defaults to the nearest {@link TransportProvider}.
|
|
86
|
+
*/
|
|
87
|
+
useTree: (props?: {
|
|
88
|
+
/** Override transport; defaults to the nearest {@link TransportProvider}. */
|
|
89
|
+
transport?: ClientTransport<TEvent, TMessage>;
|
|
90
|
+
}) => TreeHandle<TMessage>;
|
|
91
|
+
/**
|
|
92
|
+
* Subscribe to raw Ably messages on the transport channel.
|
|
93
|
+
* Pass `transport` to override; defaults to the nearest {@link TransportProvider}.
|
|
94
|
+
* Pass `skip: true` to return an empty array without subscribing.
|
|
95
|
+
*/
|
|
96
|
+
useAblyMessages: (props?: {
|
|
97
|
+
/** Override transport; defaults to the nearest {@link TransportProvider}. */
|
|
98
|
+
transport?: ClientTransport<TEvent, TMessage>;
|
|
99
|
+
/** When `true`, skip all subscriptions and return an empty array. */
|
|
100
|
+
skip?: boolean;
|
|
101
|
+
}) => Ably.InboundMessage[];
|
|
102
|
+
/**
|
|
103
|
+
* Create an independent view over the same tree.
|
|
104
|
+
* Pass `transport` to override; defaults to the nearest {@link TransportProvider}.
|
|
105
|
+
* Pass `skip: true` to return an empty handle without creating a view.
|
|
106
|
+
*/
|
|
107
|
+
useCreateView: (props?: {
|
|
108
|
+
/** Override transport; defaults to the nearest {@link TransportProvider}. */
|
|
109
|
+
transport?: ClientTransport<TEvent, TMessage> | null;
|
|
110
|
+
/** When provided, auto-loads the first page on mount. */
|
|
111
|
+
limit?: number;
|
|
112
|
+
/** When `true`, skip view creation and return an empty handle. */
|
|
113
|
+
skip?: boolean;
|
|
114
|
+
}) => ViewHandle<TEvent, TMessage>;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Create a bundle of type-safe hooks and provider for a given `TEvent`/`TMessage` pair.
|
|
118
|
+
*
|
|
119
|
+
* `TEvent` and `TMessage` are captured at factory creation time; hook call sites need
|
|
120
|
+
* no type parameters. The returned hooks are thin wrappers around the standalone hooks
|
|
121
|
+
* with the types resolved.
|
|
122
|
+
* @returns A {@link TransportHooks} bundle.
|
|
123
|
+
*/
|
|
124
|
+
export declare const createTransportHooks: <TEvent, TMessage>() => TransportHooks<TEvent, TMessage>;
|
package/dist/react/index.d.ts
CHANGED
|
@@ -1,11 +1,17 @@
|
|
|
1
|
+
export type { EventsNode, MessageNode } from '../core/transport/types.js';
|
|
2
|
+
export type { TransportSlot } from './contexts/transport-context.js';
|
|
3
|
+
export { NearestTransportContext } from './contexts/transport-context.js';
|
|
4
|
+
export type { TransportProviderProps } from './contexts/transport-provider.js';
|
|
5
|
+
export { TransportProvider } from './contexts/transport-provider.js';
|
|
6
|
+
export type { TransportHooks } from './create-transport-hooks.js';
|
|
7
|
+
export { createTransportHooks } from './create-transport-hooks.js';
|
|
8
|
+
export type { EventNode, TreeNode } from '../core/transport/types.js';
|
|
1
9
|
export { useAblyMessages } from './use-ably-messages.js';
|
|
2
10
|
export { useActiveTurns } from './use-active-turns.js';
|
|
11
|
+
export type { ClientTransportHandle } from './use-client-transport.js';
|
|
3
12
|
export { useClientTransport } from './use-client-transport.js';
|
|
4
|
-
export
|
|
5
|
-
export {
|
|
6
|
-
export {
|
|
7
|
-
export type {
|
|
8
|
-
export {
|
|
9
|
-
export { useMessages } from './use-messages.js';
|
|
10
|
-
export { useRegenerate } from './use-regenerate.js';
|
|
11
|
-
export { useSend } from './use-send.js';
|
|
13
|
+
export { useCreateView } from './use-create-view.js';
|
|
14
|
+
export type { TreeHandle } from './use-tree.js';
|
|
15
|
+
export { useTree } from './use-tree.js';
|
|
16
|
+
export type { UseViewOptions, ViewHandle } from './use-view.js';
|
|
17
|
+
export { useView } from './use-view.js';
|
|
@@ -2,17 +2,23 @@ import { ClientTransport } from '../core/transport/types.js';
|
|
|
2
2
|
/**
|
|
3
3
|
* useAblyMessages — reactive raw Ably message log from a ClientTransport.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* history-loaded messages (from transport.history() calls).
|
|
5
|
+
* Accumulates raw Ably InboundMessages from the transport's tree
|
|
6
|
+
* 'ably-message' event. Messages are appended in arrival order.
|
|
8
7
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
8
|
+
* When `transport` is omitted, defaults to the nearest
|
|
9
|
+
* {@link TransportProvider}'s transport via context.
|
|
10
|
+
* Pass `skip: true` to bypass all subscriptions and return an empty array.
|
|
11
11
|
*/
|
|
12
12
|
import type * as Ably from 'ably';
|
|
13
13
|
/**
|
|
14
|
-
* Subscribe to raw Ably message updates from a client transport.
|
|
15
|
-
*
|
|
14
|
+
* Subscribe to raw Ably message updates from a client transport's tree.
|
|
15
|
+
* When `transport` is omitted, uses the nearest {@link TransportProvider}'s transport via context.
|
|
16
|
+
* @param props - Options including optional `transport` and `skip`.
|
|
17
|
+
* @param props.transport - Transport to subscribe to; defaults to the nearest provider.
|
|
18
|
+
* @param props.skip - When `true`, skip all subscriptions and return an empty array.
|
|
16
19
|
* @returns The accumulated raw Ably messages in chronological order.
|
|
17
20
|
*/
|
|
18
|
-
export declare const useAblyMessages: <TEvent, TMessage>(transport
|
|
21
|
+
export declare const useAblyMessages: <TEvent, TMessage>({ transport, skip, }?: {
|
|
22
|
+
transport?: ClientTransport<TEvent, TMessage>;
|
|
23
|
+
skip?: boolean;
|
|
24
|
+
}) => Ably.InboundMessage[];
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import { ClientTransport } from '../core/transport/types.js';
|
|
2
2
|
/**
|
|
3
3
|
* Returns a reactive Map of all active turns on the channel, keyed by clientId.
|
|
4
|
-
* Updates when turns start or end.
|
|
5
|
-
* @
|
|
4
|
+
* Updates when turns start or end. When `transport` is omitted, uses the nearest
|
|
5
|
+
* {@link TransportProvider}'s transport via context.
|
|
6
|
+
* @param props - Options including optional `transport`.
|
|
7
|
+
* @param props.transport - Transport to track turns for; defaults to the nearest provider.
|
|
6
8
|
* @returns A Map where keys are clientIds and values are Sets of active turnIds.
|
|
7
9
|
*/
|
|
8
|
-
export declare const useActiveTurns: <TEvent, TMessage>(transport
|
|
10
|
+
export declare const useActiveTurns: <TEvent, TMessage>({ transport, }?: {
|
|
11
|
+
transport?: ClientTransport<TEvent, TMessage> | null;
|
|
12
|
+
}) => Map<string, Set<string>>;
|
|
@@ -1,7 +1,80 @@
|
|
|
1
|
-
import { ClientTransport
|
|
1
|
+
import { ClientTransport } from '../core/transport/types.js';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* @
|
|
3
|
+
* useClientTransport — read a ClientTransport from the nearest TransportProvider.
|
|
4
|
+
*
|
|
5
|
+
* The transport is created by {@link TransportProvider}, which also wraps the subtree
|
|
6
|
+
* with Ably's `ChannelProvider`. This hook is a thin context reader — it does not
|
|
7
|
+
* create or manage transport state.
|
|
8
|
+
*
|
|
9
|
+
* **Provider lookup**
|
|
10
|
+
* - Omit `channelName` to use the innermost `TransportProvider` in the tree.
|
|
11
|
+
* - Pass `channelName` to look up a specific provider by name.
|
|
12
|
+
* - Pass `skip: true` to receive a stub transport that throws on any access —
|
|
13
|
+
* safe to hold in state before auth or other conditions are ready.
|
|
14
|
+
*
|
|
15
|
+
* **Error handling**
|
|
16
|
+
* - When no matching provider is found, or when the provider's `createClientTransport`
|
|
17
|
+
* call threw, `transportError` is set on the returned object instead of throwing.
|
|
18
|
+
* The component can render an error state without an error boundary.
|
|
19
|
+
* - Pass `onError` to receive post-construction transport errors (e.g. send failures,
|
|
20
|
+
* channel continuity loss) without wiring `transport.on('error', ...)` manually.
|
|
6
21
|
*/
|
|
7
|
-
|
|
22
|
+
import * as Ably from 'ably';
|
|
23
|
+
/**
|
|
24
|
+
* Return value of {@link useClientTransport}.
|
|
25
|
+
*
|
|
26
|
+
* `transport` is always a valid object. When `skip` is `true`, when no provider was
|
|
27
|
+
* found, or when the provider's transport construction failed, `transport` is a stub
|
|
28
|
+
* that throws {@link Ably.ErrorInfo} on every access.
|
|
29
|
+
* Check `transportError` before using `transport` to avoid those throws.
|
|
30
|
+
*/
|
|
31
|
+
export interface ClientTransportHandle<TEvent, TMessage> {
|
|
32
|
+
/**
|
|
33
|
+
* The resolved transport.
|
|
34
|
+
*
|
|
35
|
+
* A throwing stub when `skip` is `true`, when no matching {@link TransportProvider}
|
|
36
|
+
* was found in the tree, or when transport construction failed.
|
|
37
|
+
*/
|
|
38
|
+
transport: ClientTransport<TEvent, TMessage>;
|
|
39
|
+
/**
|
|
40
|
+
* Set when no matching {@link TransportProvider} was found, when transport
|
|
41
|
+
* construction failed, and `skip` is `false`.
|
|
42
|
+
* `undefined` when the transport resolved successfully or when `skip` is `true`.
|
|
43
|
+
*/
|
|
44
|
+
transportError?: Ably.ErrorInfo | undefined;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Read a {@link ClientTransport} from the nearest {@link TransportProvider}.
|
|
48
|
+
*
|
|
49
|
+
* Returns `{ transport, transportError }`. When no provider is found or transport
|
|
50
|
+
* construction failed, `transportError` is set and `transport` is a stub that throws
|
|
51
|
+
* on access — the hook never throws during render.
|
|
52
|
+
*
|
|
53
|
+
* Pass `onError` to subscribe to post-construction transport errors
|
|
54
|
+
* (e.g. {@link ErrorCode.TransportSendFailed}, {@link ErrorCode.ChannelContinuityLost})
|
|
55
|
+
* without calling `transport.on('error', …)` manually. The subscription is
|
|
56
|
+
* created when the transport resolves and removed on unmount.
|
|
57
|
+
* @param props - Hook options.
|
|
58
|
+
* @param props.channelName - Look up a specific provider by channel name; omit for the nearest.
|
|
59
|
+
* @param props.skip - When `true`, return the stub transport immediately without reading context.
|
|
60
|
+
* @param props.onError - Called whenever the resolved transport emits an error event.
|
|
61
|
+
* @returns `{ transport, transportError }`.
|
|
62
|
+
*/
|
|
63
|
+
export declare const useClientTransport: <TEvent, TMessage>({ channelName, skip, onError, }?: {
|
|
64
|
+
/**
|
|
65
|
+
* Channel name passed to the enclosing {@link TransportProvider}.
|
|
66
|
+
* Omit to use the nearest provider in the tree.
|
|
67
|
+
*/
|
|
68
|
+
channelName?: string;
|
|
69
|
+
/**
|
|
70
|
+
* When `true`, skip context lookup and return a stub transport that throws on
|
|
71
|
+
* any access. Use when a condition (auth, feature flag) is not yet resolved.
|
|
72
|
+
*/
|
|
73
|
+
skip?: boolean;
|
|
74
|
+
/**
|
|
75
|
+
* Called whenever the resolved transport emits an error event.
|
|
76
|
+
* The subscription is established once the transport resolves and
|
|
77
|
+
* automatically removed on unmount or when the transport changes.
|
|
78
|
+
*/
|
|
79
|
+
onError?: (error: Ably.ErrorInfo) => void;
|
|
80
|
+
}) => ClientTransportHandle<TEvent, TMessage>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { ClientTransport } from '../core/transport/types.js';
|
|
2
|
+
import { ViewHandle } from './use-view.js';
|
|
3
|
+
/**
|
|
4
|
+
* Create an independent {@link View} and subscribe to it.
|
|
5
|
+
* Returns the same {@link ViewHandle} as {@link useView}, but backed by a
|
|
6
|
+
* newly created view with its own branch selections and pagination state.
|
|
7
|
+
* The view is closed on unmount or when the transport changes.
|
|
8
|
+
* When `transport` is omitted, uses the nearest {@link TransportProvider}'s transport via context.
|
|
9
|
+
* @param props - Options including optional `transport`, `limit` for auto-load, and `skip`.
|
|
10
|
+
* @param props.transport - Transport to create a view from; defaults to the nearest provider.
|
|
11
|
+
* @param props.limit - Max older messages per page; when provided, auto-loads on mount.
|
|
12
|
+
* @param props.skip - When `true`, skip view creation and return an empty handle.
|
|
13
|
+
* @returns A {@link ViewHandle} with nodes, pagination, navigation, and write operations.
|
|
14
|
+
*/
|
|
15
|
+
export declare const useCreateView: <TEvent, TMessage>({ transport, limit, skip, }?: {
|
|
16
|
+
/** The transport to create a view from, or null/undefined to use the nearest provider. */
|
|
17
|
+
transport?: ClientTransport<TEvent, TMessage> | null;
|
|
18
|
+
/** When provided, auto-loads the first page on mount. Omit for manual load. */
|
|
19
|
+
limit?: number;
|
|
20
|
+
/** When `true`, skip view creation and return an empty handle immediately. */
|
|
21
|
+
skip?: boolean;
|
|
22
|
+
}) => ViewHandle<TEvent, TMessage>;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { ClientTransport, MessageNode } from '../core/transport/types.js';
|
|
2
|
+
/** Handle for querying the conversation tree structure. */
|
|
3
|
+
export interface TreeHandle<TMessage> {
|
|
4
|
+
/** Get all sibling messages at a fork point, ordered chronologically by serial. */
|
|
5
|
+
getSiblings: (msgId: string) => TMessage[];
|
|
6
|
+
/** Whether a message has sibling alternatives (i.e., show navigation arrows). */
|
|
7
|
+
hasSiblings: (msgId: string) => boolean;
|
|
8
|
+
/** Get a node by msgId, or undefined if not found. */
|
|
9
|
+
getNode: (msgId: string) => MessageNode<TMessage> | undefined;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Provide stable structural query callbacks backed by the transport's tree.
|
|
13
|
+
* When `transport` is omitted, uses the nearest {@link TransportProvider}'s transport via context.
|
|
14
|
+
* @param props - Options including optional `transport`.
|
|
15
|
+
* @param props.transport - Transport to read tree structure from; defaults to the nearest provider.
|
|
16
|
+
* @returns A {@link TreeHandle} with structural query methods.
|
|
17
|
+
*/
|
|
18
|
+
export declare const useTree: <TEvent, TMessage>({ transport, }?: {
|
|
19
|
+
transport?: ClientTransport<TEvent, TMessage>;
|
|
20
|
+
}) => TreeHandle<TMessage>;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { ActiveTurn, ClientTransport, MessageNode, SendOptions, View } from '../core/transport/types.js';
|
|
2
|
+
/**
|
|
3
|
+
* useView — reactive paginated view of the conversation.
|
|
4
|
+
*
|
|
5
|
+
* Subscribes to view updates and exposes the visible nodes, branch navigation,
|
|
6
|
+
* write operations, pagination state, and a `loadOlder` callback. Pass `transport`
|
|
7
|
+
* to use a transport's default view, or `view` to subscribe to a specific
|
|
8
|
+
* {@link View} directly. When both are omitted, defaults to the nearest
|
|
9
|
+
* {@link TransportProvider}'s transport via context.
|
|
10
|
+
*/
|
|
11
|
+
import * as Ably from 'ably';
|
|
12
|
+
/** Options for configuring the view's initial load behavior. */
|
|
13
|
+
export interface UseViewOptions {
|
|
14
|
+
/** Maximum number of older messages to load per page. Defaults to 100. */
|
|
15
|
+
limit?: number;
|
|
16
|
+
}
|
|
17
|
+
/** Handle for the paginated, branch-aware conversation view. */
|
|
18
|
+
export interface ViewHandle<TEvent, TMessage> {
|
|
19
|
+
/** The visible domain messages along the selected branch. */
|
|
20
|
+
messages: TMessage[];
|
|
21
|
+
/** Visible conversation nodes along the selected branch. */
|
|
22
|
+
nodes: MessageNode<TMessage>[];
|
|
23
|
+
/** Whether there are older messages that can be revealed via `loadOlder`. */
|
|
24
|
+
hasOlder: boolean;
|
|
25
|
+
/** Whether a page load is currently in progress. */
|
|
26
|
+
loading: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Set when the most recent `loadOlder` call failed.
|
|
29
|
+
* Cleared automatically on the next successful load.
|
|
30
|
+
* `undefined` when no error has occurred or when `skip` is `true`.
|
|
31
|
+
*/
|
|
32
|
+
loadError: Ably.ErrorInfo | undefined;
|
|
33
|
+
/**
|
|
34
|
+
* Load older messages into the view. No-op if already loading.
|
|
35
|
+
* On failure, `error` is set; on success, `error` is cleared.
|
|
36
|
+
*/
|
|
37
|
+
loadOlder: () => Promise<void>;
|
|
38
|
+
/** Select a sibling at a fork point by index. Triggers a view update with the new branch. */
|
|
39
|
+
select: (msgId: string, index: number) => void;
|
|
40
|
+
/** Index of the currently selected sibling at a fork point. */
|
|
41
|
+
getSelectedIndex: (msgId: string) => number;
|
|
42
|
+
/** Get all sibling messages at a fork point, ordered chronologically by serial. */
|
|
43
|
+
getSiblings: (msgId: string) => TMessage[];
|
|
44
|
+
/** Whether a message has sibling alternatives (i.e., show navigation arrows). */
|
|
45
|
+
hasSiblings: (msgId: string) => boolean;
|
|
46
|
+
/** Get a node by msgId, or undefined if not found. */
|
|
47
|
+
getNode: (msgId: string) => MessageNode<TMessage> | undefined;
|
|
48
|
+
/** Send one or more messages in the context of this view's selected branch. */
|
|
49
|
+
send: (messages: TMessage | TMessage[], options?: SendOptions) => Promise<ActiveTurn<TEvent>>;
|
|
50
|
+
/** Regenerate an assistant message, using this view's branch for history. */
|
|
51
|
+
regenerate: (messageId: string, options?: SendOptions) => Promise<ActiveTurn<TEvent>>;
|
|
52
|
+
/** Edit a user message, forking from this view's branch. */
|
|
53
|
+
edit: (messageId: string, newMessages: TMessage | TMessage[], options?: SendOptions) => Promise<ActiveTurn<TEvent>>;
|
|
54
|
+
/** Amend an existing message and start a continuation turn (e.g. tool results). */
|
|
55
|
+
update: (msgId: string, events: TEvent[], options?: SendOptions) => Promise<ActiveTurn<TEvent>>;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Subscribe to a view and return the visible node list with pagination, navigation, and write operations.
|
|
59
|
+
*
|
|
60
|
+
* `view` takes priority over `transport`. When neither is provided, the nearest
|
|
61
|
+
* {@link TransportProvider}'s transport is used. When `limit` is provided, auto-loads
|
|
62
|
+
* the first page on mount (SWR-style).
|
|
63
|
+
* @param props - Options for selecting the view source and configuring auto-load.
|
|
64
|
+
* @param props.transport - Client transport whose default view to subscribe to; defaults to the nearest provider.
|
|
65
|
+
* @param props.view - A specific {@link View} to subscribe to directly. Takes priority over `transport`.
|
|
66
|
+
* @param props.limit - Max older messages per page; when provided, auto-loads on mount.
|
|
67
|
+
* @param props.skip - When `true`, skip all subscriptions and return an empty handle.
|
|
68
|
+
* @returns A {@link ViewHandle} with nodes, pagination state, navigation, write operations, and loadOlder.
|
|
69
|
+
*/
|
|
70
|
+
export declare const useView: <TEvent, TMessage>({ transport, view, limit, skip, }?: {
|
|
71
|
+
/** Client transport whose default view to subscribe to; defaults to the nearest provider when omitted. */
|
|
72
|
+
transport?: ClientTransport<TEvent, TMessage> | null;
|
|
73
|
+
/** A specific {@link View} to subscribe to directly. Takes priority over `transport`. */
|
|
74
|
+
view?: View<TEvent, TMessage> | null;
|
|
75
|
+
/** When provided, auto-loads the first page on mount. Omit for manual loading. */
|
|
76
|
+
limit?: number;
|
|
77
|
+
/** When `true`, skip all subscriptions and return an empty handle immediately. */
|
|
78
|
+
skip?: boolean;
|
|
79
|
+
}) => ViewHandle<TEvent, TMessage>;
|