@ably/ai-transport 0.1.0 → 0.2.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.
Files changed (163) hide show
  1. package/README.md +91 -100
  2. package/dist/ably-ai-transport.js +1553 -1238
  3. package/dist/ably-ai-transport.js.map +1 -1
  4. package/dist/ably-ai-transport.umd.cjs +1 -1
  5. package/dist/ably-ai-transport.umd.cjs.map +1 -1
  6. package/dist/constants.d.ts +116 -42
  7. package/dist/core/agent.d.ts +29 -0
  8. package/dist/core/codec/decoder.d.ts +20 -23
  9. package/dist/core/codec/encoder.d.ts +11 -8
  10. package/dist/core/codec/index.d.ts +1 -2
  11. package/dist/core/codec/lifecycle-tracker.d.ts +10 -9
  12. package/dist/core/codec/types.d.ts +407 -115
  13. package/dist/core/transport/agent-session.d.ts +10 -0
  14. package/dist/core/transport/branch-chain.d.ts +43 -0
  15. package/dist/core/transport/client-session.d.ts +13 -0
  16. package/dist/core/transport/decode-fold.d.ts +47 -0
  17. package/dist/core/transport/headers.d.ts +96 -18
  18. package/dist/core/transport/index.d.ts +5 -6
  19. package/dist/core/transport/internal/bounded-map.d.ts +20 -0
  20. package/dist/core/transport/invocation.d.ts +74 -0
  21. package/dist/core/transport/load-conversation.d.ts +128 -0
  22. package/dist/core/transport/load-history.d.ts +39 -0
  23. package/dist/core/transport/pipe-stream.d.ts +9 -9
  24. package/dist/core/transport/run-manager.d.ts +78 -0
  25. package/dist/core/transport/tree.d.ts +373 -109
  26. package/dist/core/transport/types/agent.d.ts +353 -0
  27. package/dist/core/transport/types/client.d.ts +168 -0
  28. package/dist/core/transport/types/shared.d.ts +24 -0
  29. package/dist/core/transport/types/tree.d.ts +315 -0
  30. package/dist/core/transport/types/view.d.ts +222 -0
  31. package/dist/core/transport/types.d.ts +13 -553
  32. package/dist/core/transport/view.d.ts +272 -84
  33. package/dist/errors.d.ts +21 -10
  34. package/dist/index.d.ts +6 -8
  35. package/dist/logger.d.ts +12 -0
  36. package/dist/react/ably-ai-transport-react.js +976 -990
  37. package/dist/react/ably-ai-transport-react.js.map +1 -1
  38. package/dist/react/ably-ai-transport-react.umd.cjs +1 -1
  39. package/dist/react/ably-ai-transport-react.umd.cjs.map +1 -1
  40. package/dist/react/contexts/client-session-context.d.ts +36 -0
  41. package/dist/react/contexts/client-session-provider.d.ts +53 -0
  42. package/dist/react/create-session-hooks.d.ts +116 -0
  43. package/dist/react/index.d.ts +12 -12
  44. package/dist/react/internal/use-resolved-session.d.ts +36 -0
  45. package/dist/react/use-ably-messages.d.ts +17 -14
  46. package/dist/react/use-client-session.d.ts +81 -0
  47. package/dist/react/use-create-view.d.ts +14 -13
  48. package/dist/react/use-tree.d.ts +30 -15
  49. package/dist/react/use-view.d.ts +82 -51
  50. package/dist/utils.d.ts +32 -23
  51. package/dist/vercel/ably-ai-transport-vercel.js +2573 -2086
  52. package/dist/vercel/ably-ai-transport-vercel.js.map +1 -1
  53. package/dist/vercel/ably-ai-transport-vercel.umd.cjs +1 -1
  54. package/dist/vercel/ably-ai-transport-vercel.umd.cjs.map +1 -1
  55. package/dist/vercel/codec/decoder.d.ts +5 -18
  56. package/dist/vercel/codec/encoder.d.ts +6 -36
  57. package/dist/vercel/codec/events.d.ts +51 -0
  58. package/dist/vercel/codec/index.d.ts +24 -12
  59. package/dist/vercel/codec/reducer.d.ts +144 -0
  60. package/dist/vercel/codec/tool-transitions.d.ts +2 -2
  61. package/dist/vercel/index.d.ts +4 -5
  62. package/dist/vercel/react/ably-ai-transport-vercel-react.js +3907 -3266
  63. package/dist/vercel/react/ably-ai-transport-vercel-react.js.map +1 -1
  64. package/dist/vercel/react/ably-ai-transport-vercel-react.umd.cjs +33 -8
  65. package/dist/vercel/react/ably-ai-transport-vercel-react.umd.cjs.map +1 -1
  66. package/dist/vercel/react/contexts/chat-transport-context.d.ts +7 -6
  67. package/dist/vercel/react/contexts/chat-transport-provider.d.ts +53 -41
  68. package/dist/vercel/react/index.d.ts +1 -2
  69. package/dist/vercel/react/use-chat-transport.d.ts +30 -26
  70. package/dist/vercel/react/use-message-sync.d.ts +17 -30
  71. package/dist/vercel/run-end-reason.d.ts +29 -0
  72. package/dist/vercel/transport/chat-transport.d.ts +43 -24
  73. package/dist/vercel/transport/index.d.ts +25 -21
  74. package/dist/vercel/transport/run-output-stream.d.ts +56 -0
  75. package/dist/version.d.ts +2 -0
  76. package/package.json +30 -23
  77. package/src/constants.ts +124 -51
  78. package/src/core/agent.ts +68 -0
  79. package/src/core/codec/decoder.ts +71 -98
  80. package/src/core/codec/encoder.ts +113 -65
  81. package/src/core/codec/index.ts +13 -6
  82. package/src/core/codec/lifecycle-tracker.ts +10 -9
  83. package/src/core/codec/types.ts +436 -120
  84. package/src/core/transport/agent-session.ts +1344 -0
  85. package/src/core/transport/branch-chain.ts +58 -0
  86. package/src/core/transport/client-session.ts +775 -0
  87. package/src/core/transport/decode-fold.ts +91 -0
  88. package/src/core/transport/headers.ts +181 -22
  89. package/src/core/transport/index.ts +25 -26
  90. package/src/core/transport/internal/bounded-map.ts +27 -0
  91. package/src/core/transport/invocation.ts +98 -0
  92. package/src/core/transport/load-conversation.ts +355 -0
  93. package/src/core/transport/load-history.ts +269 -0
  94. package/src/core/transport/pipe-stream.ts +54 -39
  95. package/src/core/transport/run-manager.ts +249 -0
  96. package/src/core/transport/tree.ts +926 -308
  97. package/src/core/transport/types/agent.ts +407 -0
  98. package/src/core/transport/types/client.ts +211 -0
  99. package/src/core/transport/types/shared.ts +27 -0
  100. package/src/core/transport/types/tree.ts +344 -0
  101. package/src/core/transport/types/view.ts +259 -0
  102. package/src/core/transport/types.ts +13 -706
  103. package/src/core/transport/view.ts +864 -433
  104. package/src/errors.ts +22 -9
  105. package/src/event-emitter.ts +3 -2
  106. package/src/index.ts +52 -41
  107. package/src/logger.ts +14 -1
  108. package/src/react/contexts/client-session-context.ts +41 -0
  109. package/src/react/contexts/client-session-provider.tsx +186 -0
  110. package/src/react/create-session-hooks.ts +141 -0
  111. package/src/react/index.ts +23 -13
  112. package/src/react/internal/use-resolved-session.ts +63 -0
  113. package/src/react/use-ably-messages.ts +32 -22
  114. package/src/react/use-client-session.ts +201 -0
  115. package/src/react/use-create-view.ts +33 -29
  116. package/src/react/use-tree.ts +61 -30
  117. package/src/react/use-view.ts +139 -97
  118. package/src/utils.ts +63 -45
  119. package/src/vercel/codec/decoder.ts +336 -258
  120. package/src/vercel/codec/encoder.ts +343 -205
  121. package/src/vercel/codec/events.ts +87 -0
  122. package/src/vercel/codec/index.ts +60 -13
  123. package/src/vercel/codec/reducer.ts +977 -0
  124. package/src/vercel/codec/tool-transitions.ts +2 -2
  125. package/src/vercel/index.ts +6 -19
  126. package/src/vercel/react/contexts/chat-transport-context.ts +7 -6
  127. package/src/vercel/react/contexts/chat-transport-provider.tsx +87 -59
  128. package/src/vercel/react/index.ts +3 -5
  129. package/src/vercel/react/use-chat-transport.ts +47 -49
  130. package/src/vercel/react/use-message-sync.ts +80 -39
  131. package/src/vercel/run-end-reason.ts +78 -0
  132. package/src/vercel/transport/chat-transport.ts +392 -98
  133. package/src/vercel/transport/index.ts +39 -38
  134. package/src/vercel/transport/run-output-stream.ts +170 -0
  135. package/src/version.ts +2 -0
  136. package/dist/core/transport/client-transport.d.ts +0 -10
  137. package/dist/core/transport/decode-history.d.ts +0 -43
  138. package/dist/core/transport/server-transport.d.ts +0 -7
  139. package/dist/core/transport/stream-router.d.ts +0 -29
  140. package/dist/core/transport/turn-manager.d.ts +0 -37
  141. package/dist/react/contexts/transport-context.d.ts +0 -31
  142. package/dist/react/contexts/transport-provider.d.ts +0 -49
  143. package/dist/react/create-transport-hooks.d.ts +0 -124
  144. package/dist/react/use-active-turns.d.ts +0 -12
  145. package/dist/react/use-client-transport.d.ts +0 -80
  146. package/dist/vercel/codec/accumulator.d.ts +0 -21
  147. package/dist/vercel/react/use-staged-add-tool-approval-response.d.ts +0 -30
  148. package/dist/vercel/tool-approvals.d.ts +0 -124
  149. package/dist/vercel/tool-events.d.ts +0 -26
  150. package/src/core/transport/client-transport.ts +0 -977
  151. package/src/core/transport/decode-history.ts +0 -485
  152. package/src/core/transport/server-transport.ts +0 -612
  153. package/src/core/transport/stream-router.ts +0 -136
  154. package/src/core/transport/turn-manager.ts +0 -165
  155. package/src/react/contexts/transport-context.ts +0 -37
  156. package/src/react/contexts/transport-provider.tsx +0 -164
  157. package/src/react/create-transport-hooks.ts +0 -144
  158. package/src/react/use-active-turns.ts +0 -72
  159. package/src/react/use-client-transport.ts +0 -197
  160. package/src/vercel/codec/accumulator.ts +0 -588
  161. package/src/vercel/react/use-staged-add-tool-approval-response.ts +0 -87
  162. package/src/vercel/tool-approvals.ts +0 -380
  163. package/src/vercel/tool-events.ts +0 -53
@@ -0,0 +1,36 @@
1
+ import { CodecInputEvent, CodecOutputEvent } from '../../core/codec/types.js';
2
+ import { ClientSession } from '../../core/transport/types.js';
3
+ import type * as Ably from 'ably';
4
+ /**
5
+ * A single entry in the client-session registry, holding the session and any
6
+ * error that occurred during its construction.
7
+ *
8
+ * `session` is `undefined` when construction failed.
9
+ * `sessionError` is set when `createClientSession` threw during provider render.
10
+ */
11
+ export interface ClientSessionSlot {
12
+ /** The constructed session, or `undefined` if construction failed. */
13
+ session: ClientSession<CodecInputEvent, CodecOutputEvent, unknown, unknown> | undefined;
14
+ /** Construction error from `createClientSession`, or `undefined` on success. */
15
+ sessionError?: Ably.ErrorInfo | undefined;
16
+ }
17
+ /**
18
+ * The shape of the {@link ClientSessionContext} value.
19
+ *
20
+ * `nearest` is the slot from the innermost enclosing {@link ClientSessionProvider}.
21
+ * `providers` is the full registry of all enclosing providers, keyed by channelName.
22
+ */
23
+ export interface ClientSessionContextValue {
24
+ /** The innermost {@link ClientSessionProvider}'s slot. `undefined` when no provider is present. */
25
+ nearest: ClientSessionSlot | undefined;
26
+ /** All registered session slots from enclosing providers, keyed by channelName. */
27
+ providers: Readonly<Record<string, ClientSessionSlot>>;
28
+ }
29
+ /**
30
+ * Unified client-session context.
31
+ *
32
+ * Holds the nearest client-session slot and the full registry of all registered
33
+ * slots keyed by channelName. Populated by {@link ClientSessionProvider};
34
+ * read by {@link useClientSession} and internal hooks.
35
+ */
36
+ export declare const ClientSessionContext: import('react').Context<ClientSessionContextValue>;
@@ -0,0 +1,53 @@
1
+ import { PropsWithChildren, ReactNode } from 'react';
2
+ import { CodecInputEvent, CodecOutputEvent } from '../../core/codec/types.js';
3
+ import { ClientSessionOptions } from '../../core/transport/types.js';
4
+ /**
5
+ * Props for {@link ClientSessionProvider}.
6
+ *
7
+ * All {@link ClientSessionOptions} except `client` (read from the surrounding
8
+ * `<AblyProvider>`).
9
+ */
10
+ export interface ClientSessionProviderProps<TInput extends CodecInputEvent, TOutput extends CodecOutputEvent, TProjection, TMessage> extends Omit<ClientSessionOptions<TInput, TOutput, TProjection, TMessage>, 'client'>, PropsWithChildren {
11
+ }
12
+ /**
13
+ * Provide a {@link ClientSession} to descendant components.
14
+ *
15
+ * Reads the Ably Realtime client from the surrounding `<AblyProvider>`,
16
+ * creates a session bound to `channelName`, calls `connect()` on mount,
17
+ * and registers it in `ClientSessionContext` under `channelName`.
18
+ * Descendants call {@link useClientSession} with the same `channelName` to
19
+ * access the session.
20
+ *
21
+ * If `createClientSession` throws during construction, the error is surfaced
22
+ * through `useClientSession` as `sessionError` — the component tree does not
23
+ * crash and children are still rendered.
24
+ *
25
+ * ```tsx
26
+ * <AblyProvider client={ably}>
27
+ * <ClientSessionProvider channelName="ai:demo" codec={UIMessageCodec}>
28
+ * <Chat />
29
+ * </ClientSessionProvider>
30
+ * </AblyProvider>
31
+ *
32
+ * // Inside Chat:
33
+ * const { session, sessionError } = useClientSession({ channelName: 'ai:demo' });
34
+ * ```
35
+ *
36
+ * For multiple sessions, nest providers with distinct channelNames:
37
+ *
38
+ * ```tsx
39
+ * <ClientSessionProvider channelName="ai:main" codec={UIMessageCodec}>
40
+ * <ClientSessionProvider channelName="ai:aux" codec={UIMessageCodec}>
41
+ * <App />
42
+ * </ClientSessionProvider>
43
+ * </ClientSessionProvider>
44
+ *
45
+ * // Inside App:
46
+ * const { session: main } = useClientSession({ channelName: 'ai:main' });
47
+ * const { session: aux } = useClientSession({ channelName: 'ai:aux' });
48
+ * ```
49
+ * @param props - Provider configuration including `channelName`, `codec`, and all other {@link ClientSessionOptions} except `client`.
50
+ * @param props.children - Descendant components that consume the session via {@link useClientSession}.
51
+ * @returns A React element wrapping children with ClientSessionContext.
52
+ */
53
+ export declare const ClientSessionProvider: <TInput extends CodecInputEvent, TOutput extends CodecOutputEvent, TProjection, TMessage>({ children, ...sessionOptions }: ClientSessionProviderProps<TInput, TOutput, TProjection, TMessage>) => ReactNode;
@@ -0,0 +1,116 @@
1
+ import { ComponentType } from 'react';
2
+ import { CodecInputEvent, CodecOutputEvent } from '../core/codec/types.js';
3
+ import { ClientSession, View } from '../core/transport/types.js';
4
+ import { ClientSessionProviderProps } from './contexts/client-session-provider.js';
5
+ import { ClientSessionHandle } from './use-client-session.js';
6
+ import { TreeHandle } from './use-tree.js';
7
+ import { ViewHandle } from './use-view.js';
8
+ /**
9
+ * createSessionHooks: factory that captures the codec's type parameters once and
10
+ * returns a bundle of type-safe hooks + ClientSessionProvider. Hook call sites need
11
+ * no type parameters at every use — just call the hooks directly.
12
+ * @example
13
+ * // Once per app (e.g. in a shared session.ts):
14
+ * export const {
15
+ * ClientSessionProvider,
16
+ * useClientSession,
17
+ * useView,
18
+ * } = createSessionHooks<VercelInput, VercelOutput, VercelProjection, UIMessage>();
19
+ *
20
+ * // In page:
21
+ * <ClientSessionProvider channelName="ai:demo" codec={UIMessageCodec}>
22
+ * <Chat />
23
+ * </ClientSessionProvider>
24
+ *
25
+ * // In Chat — no type params needed, session is implicit from nearest provider:
26
+ * const { nodes } = useView({ limit: 30 });
27
+ */
28
+ import type * as Ably from 'ably';
29
+ /**
30
+ * Bundle of type-safe hooks and provider returned by {@link createSessionHooks}.
31
+ *
32
+ * The codec's `TInput`, `TOutput`, `TProjection`, and `TMessage` are baked in at
33
+ * factory creation time so no type params are needed at hook call sites.
34
+ */
35
+ export interface SessionHooks<TInput extends CodecInputEvent, TOutput extends CodecOutputEvent, TProjection, TMessage> {
36
+ /**
37
+ * `ClientSessionProvider` narrowed to the codec's `TInput`/`TOutput`/`TMessage`. No JSX type params needed.
38
+ */
39
+ ClientSessionProvider: ComponentType<ClientSessionProviderProps<TInput, TOutput, TProjection, TMessage>>;
40
+ /**
41
+ * Read the session from context. No type params needed.
42
+ *
43
+ * Returns `{ session, sessionError }`. When no provider is found (or session
44
+ * construction failed), `sessionError` is set and `session` is a stub that
45
+ * throws on access — the hook never throws during render.
46
+ *
47
+ * Pass `onError` to subscribe to post-construction session errors
48
+ * (e.g. send failures, channel continuity loss) without wiring
49
+ * `session.on('error', …)` manually.
50
+ */
51
+ useClientSession: (props?: {
52
+ /** Channel name to look up; omit to use the nearest {@link ClientSessionProvider}. */
53
+ channelName?: string;
54
+ /** When `true`, return a stub session that throws on any access. */
55
+ skip?: boolean;
56
+ /** Called whenever the resolved session emits an error event. */
57
+ onError?: (error: Ably.ErrorInfo) => void;
58
+ }) => ClientSessionHandle<TInput, TOutput, TProjection, TMessage>;
59
+ /**
60
+ * Subscribe to the nearest session's view and return the visible message list with pagination.
61
+ * Pass `session` to use a session's default view, `view` to subscribe to a specific view
62
+ * directly. Pass `limit` to auto-load on mount. Pass `skip: true` for an empty handle.
63
+ */
64
+ useView: (props?: {
65
+ /** Client session whose default view to subscribe to; defaults to the nearest {@link ClientSessionProvider}. */
66
+ session?: ClientSession<TInput, TOutput, TProjection, TMessage> | null;
67
+ /** A specific {@link View} to subscribe to directly. Takes priority over `session`. */
68
+ view?: View<TInput, TMessage> | null;
69
+ /** When provided, auto-loads the first page on mount. */
70
+ limit?: number;
71
+ /** When `true`, skip all subscriptions and return an empty handle. */
72
+ skip?: boolean;
73
+ }) => ViewHandle<TInput, TMessage>;
74
+ /**
75
+ * Navigate conversation branches in the session tree.
76
+ * Pass `session` to override; defaults to the nearest {@link ClientSessionProvider}.
77
+ */
78
+ useTree: (props?: {
79
+ /** Override session; defaults to the nearest {@link ClientSessionProvider}. */
80
+ session?: ClientSession<TInput, TOutput, TProjection, TMessage>;
81
+ }) => TreeHandle<TProjection>;
82
+ /**
83
+ * Subscribe to raw Ably messages on the session channel.
84
+ * Pass `session` to override; defaults to the nearest {@link ClientSessionProvider}.
85
+ * Pass `skip: true` to return an empty array without subscribing.
86
+ */
87
+ useAblyMessages: (props?: {
88
+ /** Override session; defaults to the nearest {@link ClientSessionProvider}. */
89
+ session?: ClientSession<TInput, TOutput, TProjection, TMessage>;
90
+ /** When `true`, skip all subscriptions and return an empty array. */
91
+ skip?: boolean;
92
+ }) => Ably.InboundMessage[];
93
+ /**
94
+ * Create an independent view over the same tree.
95
+ * Pass `session` to override; defaults to the nearest {@link ClientSessionProvider}.
96
+ * Pass `skip: true` to return an empty handle without creating a view.
97
+ */
98
+ useCreateView: (props?: {
99
+ /** Override session; defaults to the nearest {@link ClientSessionProvider}. */
100
+ session?: ClientSession<TInput, TOutput, TProjection, TMessage> | null;
101
+ /** When provided, auto-loads the first page on mount. */
102
+ limit?: number;
103
+ /** When `true`, skip view creation and return an empty handle. */
104
+ skip?: boolean;
105
+ }) => ViewHandle<TInput, TMessage>;
106
+ }
107
+ /**
108
+ * Create a bundle of type-safe hooks and provider for a given codec's
109
+ * `TInput`/`TOutput`/`TProjection`/`TMessage`.
110
+ *
111
+ * These type parameters are captured at factory creation time; hook call sites need
112
+ * no type parameters. The returned hooks are thin wrappers around the standalone hooks
113
+ * with the types resolved.
114
+ * @returns A {@link SessionHooks} bundle.
115
+ */
116
+ export declare const createSessionHooks: <TInput extends CodecInputEvent, TOutput extends CodecOutputEvent, TProjection, TMessage>() => SessionHooks<TInput, TOutput, TProjection, TMessage>;
@@ -1,17 +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
+ export type { CodecMessage } from '../core/codec/types.js';
2
+ export type { ActiveRun, BranchSelection, ClientSession, ConversationNode, EventsNode, InputNode, MessageNode, RunInfo, RunNode, SendOptions, } from '../core/transport/types.js';
3
+ export type { ClientSessionSlot } from './contexts/client-session-context.js';
4
+ export type { ClientSessionProviderProps } from './contexts/client-session-provider.js';
5
+ export { ClientSessionProvider } from './contexts/client-session-provider.js';
6
+ export type { SessionHooks } from './create-session-hooks.js';
7
+ export { createSessionHooks } from './create-session-hooks.js';
8
+ export type { UseAblyMessagesOptions } from './use-ably-messages.js';
9
9
  export { useAblyMessages } from './use-ably-messages.js';
10
- export { useActiveTurns } from './use-active-turns.js';
11
- export type { ClientTransportHandle } from './use-client-transport.js';
12
- export { useClientTransport } from './use-client-transport.js';
10
+ export type { ClientSessionHandle } from './use-client-session.js';
11
+ export { useClientSession } from './use-client-session.js';
12
+ export type { UseCreateViewOptions } from './use-create-view.js';
13
13
  export { useCreateView } from './use-create-view.js';
14
- export type { TreeHandle } from './use-tree.js';
14
+ export type { TreeHandle, UseTreeOptions } from './use-tree.js';
15
15
  export { useTree } from './use-tree.js';
16
16
  export type { UseViewOptions, ViewHandle } from './use-view.js';
17
17
  export { useView } from './use-view.js';
@@ -0,0 +1,36 @@
1
+ import { CodecInputEvent, CodecOutputEvent } from '../../core/codec/types.js';
2
+ import { ClientSession } from '../../core/transport/types.js';
3
+ /**
4
+ * Shared base for hook options that accept an explicit session override.
5
+ * Extend this interface for any hook whose `session` option defaults to the
6
+ * nearest {@link ClientSessionProvider} when omitted. Pass `null` to defer
7
+ * resolution (e.g. when a split pane is collapsed) — the helper returns
8
+ * `undefined` rather than falling back to the nearest provider.
9
+ */
10
+ export interface BaseSessionOption<TInput extends CodecInputEvent, TOutput extends CodecOutputEvent, TProjection, TMessage> {
11
+ /**
12
+ * Session to operate on; defaults to the nearest {@link ClientSessionProvider}.
13
+ * Pass `null` to defer (returns undefined; nearest provider is not used).
14
+ */
15
+ session?: ClientSession<TInput, TOutput, TProjection, TMessage> | null;
16
+ }
17
+ /**
18
+ * Resolve the active `ClientSession` for a hook.
19
+ *
20
+ * Reads `ClientSessionContext` and applies the standard three-way
21
+ * priority: explicit `session` argument → nearest provider → `undefined`.
22
+ * When `skip` is `true`, returns `undefined` regardless of context.
23
+ * When `session` is `null`, returns `undefined` (caller is deferring).
24
+ *
25
+ * Internal — not part of the public API.
26
+ * @param root0 - Options.
27
+ * @param root0.session - Explicit session; takes priority over the nearest provider. `null` to defer.
28
+ * @param root0.skip - When `true`, returns `undefined` immediately; context is still read but its value is ignored.
29
+ * @returns The resolved session, or `undefined` if none is available or `skip` is `true`.
30
+ */
31
+ export declare const useResolvedSession: <TInput extends CodecInputEvent, TOutput extends CodecOutputEvent, TProjection, TMessage>({ session, skip, }?: {
32
+ /** Explicit session; takes priority over the nearest provider. `null` to defer. */
33
+ session?: ClientSession<TInput, TOutput, TProjection, TMessage> | null;
34
+ /** When `true`, return `undefined` immediately (context is still read, but ignored). */
35
+ skip?: boolean;
36
+ }) => ClientSession<TInput, TOutput, TProjection, TMessage> | undefined;
@@ -1,24 +1,27 @@
1
- import { ClientTransport } from '../core/transport/types.js';
1
+ import { CodecInputEvent, CodecOutputEvent } from '../core/codec/types.js';
2
+ import { BaseSessionOption } from './internal/use-resolved-session.js';
2
3
  /**
3
- * useAblyMessages — reactive raw Ably message log from a ClientTransport.
4
+ * useAblyMessages — reactive raw Ably message log from a ClientSession.
4
5
  *
5
- * Accumulates raw Ably InboundMessages from the transport's tree
6
+ * Accumulates raw Ably InboundMessages from the session's tree
6
7
  * 'ably-message' event. Messages are appended in arrival order.
7
8
  *
8
- * When `transport` is omitted, defaults to the nearest
9
- * {@link TransportProvider}'s transport via context.
9
+ * When `session` is omitted, defaults to the nearest
10
+ * {@link ClientSessionProvider}'s session via context.
10
11
  * Pass `skip: true` to bypass all subscriptions and return an empty array.
11
12
  */
12
13
  import type * as Ably from 'ably';
14
+ /** Options for {@link useAblyMessages}. */
15
+ export interface UseAblyMessagesOptions<TInput extends CodecInputEvent, TOutput extends CodecOutputEvent, TProjection, TMessage> extends BaseSessionOption<TInput, TOutput, TProjection, TMessage> {
16
+ /** When `true`, skip all subscriptions and return an empty array. */
17
+ skip?: boolean;
18
+ }
13
19
  /**
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.
20
+ * Subscribe to raw Ably message updates from a client session's tree.
21
+ * When `session` is omitted, uses the nearest {@link ClientSessionProvider}'s session via context.
22
+ * @param props - Options including optional `session` and `skip`.
23
+ * @param props.session - Session to subscribe to; defaults to the nearest provider.
18
24
  * @param props.skip - When `true`, skip all subscriptions and return an empty array.
19
- * @returns The accumulated raw Ably messages in chronological order.
25
+ * @returns The accumulated raw Ably messages in event-arrival order — older history messages loaded later are appended after the live messages already present, so this is not strictly chronological.
20
26
  */
21
- export declare const useAblyMessages: <TEvent, TMessage>({ transport, skip, }?: {
22
- transport?: ClientTransport<TEvent, TMessage>;
23
- skip?: boolean;
24
- }) => Ably.InboundMessage[];
27
+ export declare const useAblyMessages: <TInput extends CodecInputEvent, TOutput extends CodecOutputEvent, TProjection, TMessage>({ session, skip }?: UseAblyMessagesOptions<TInput, TOutput, TProjection, TMessage>) => Ably.InboundMessage[];
@@ -0,0 +1,81 @@
1
+ import { CodecInputEvent, CodecOutputEvent } from '../core/codec/types.js';
2
+ import { ClientSession } from '../core/transport/types.js';
3
+ /**
4
+ * useClientSession — read a ClientSession from the nearest ClientSessionProvider.
5
+ *
6
+ * The session is created by {@link ClientSessionProvider}, which reads the Ably
7
+ * Realtime client from the surrounding `<AblyProvider>`. This hook is a thin
8
+ * context reader — it does not create or manage session state.
9
+ *
10
+ * **Provider lookup**
11
+ * - Omit `channelName` to use the innermost `ClientSessionProvider` in the tree.
12
+ * - Pass `channelName` to look up a specific provider by name.
13
+ * - Pass `skip: true` to receive a stub session that throws on any access —
14
+ * safe to hold in state before auth or other conditions are ready.
15
+ *
16
+ * **Error handling**
17
+ * - When no matching provider is found, or when the provider's `createClientSession`
18
+ * call threw, `sessionError` is set on the returned object instead of throwing.
19
+ * The component can render an error state without an error boundary.
20
+ * - Pass `onError` to receive post-construction session errors (e.g. send failures,
21
+ * channel continuity loss) without wiring `session.on('error', ...)` manually.
22
+ */
23
+ import * as Ably from 'ably';
24
+ /**
25
+ * Return value of {@link useClientSession}.
26
+ *
27
+ * `session` is always a valid object. When `skip` is `true`, when no provider was
28
+ * found, or when the provider's session construction failed, `session` is a stub
29
+ * that throws {@link Ably.ErrorInfo} on every access.
30
+ * Check `sessionError` before using `session` to avoid those throws.
31
+ */
32
+ export interface ClientSessionHandle<TInput extends CodecInputEvent, TOutput extends CodecOutputEvent, TProjection, TMessage> {
33
+ /**
34
+ * The resolved session.
35
+ *
36
+ * A throwing stub when `skip` is `true`, when no matching {@link ClientSessionProvider}
37
+ * was found in the tree, or when session construction failed.
38
+ */
39
+ session: ClientSession<TInput, TOutput, TProjection, TMessage>;
40
+ /**
41
+ * Set when no matching {@link ClientSessionProvider} was found, when session
42
+ * construction failed, and `skip` is `false`.
43
+ * `undefined` when the session resolved successfully or when `skip` is `true`.
44
+ */
45
+ sessionError?: Ably.ErrorInfo | undefined;
46
+ }
47
+ /**
48
+ * Read a {@link ClientSession} from the nearest {@link ClientSessionProvider}.
49
+ *
50
+ * Returns `{ session, sessionError }`. When no provider is found or session
51
+ * construction failed, `sessionError` is set and `session` is a stub that throws
52
+ * on access — the hook never throws during render.
53
+ *
54
+ * Pass `onError` to subscribe to post-construction session errors
55
+ * (e.g. {@link ErrorCode.SessionSendFailed}, {@link ErrorCode.ChannelContinuityLost})
56
+ * without calling `session.on('error', …)` manually. The subscription is
57
+ * created when the session resolves and removed on unmount.
58
+ * @param props - Hook options.
59
+ * @param props.channelName - Look up a specific provider by channel name; omit for the nearest.
60
+ * @param props.skip - When `true`, return the stub session immediately without resolving a provider slot.
61
+ * @param props.onError - Called whenever the resolved session emits an error event.
62
+ * @returns `{ session, sessionError }`.
63
+ */
64
+ export declare const useClientSession: <TInput extends CodecInputEvent, TOutput extends CodecOutputEvent, TProjection, TMessage>({ channelName, skip, onError, }?: {
65
+ /**
66
+ * Channel name passed to the enclosing {@link ClientSessionProvider}.
67
+ * Omit to use the nearest provider in the tree.
68
+ */
69
+ channelName?: string;
70
+ /**
71
+ * When `true`, skip context lookup and return a stub session that throws on
72
+ * any access. Use when a condition (auth, feature flag) is not yet resolved.
73
+ */
74
+ skip?: boolean;
75
+ /**
76
+ * Called whenever the resolved session emits an error event.
77
+ * The subscription is established once the session resolves and
78
+ * automatically removed on unmount or when the session changes.
79
+ */
80
+ onError?: (error: Ably.ErrorInfo) => void;
81
+ }) => ClientSessionHandle<TInput, TOutput, TProjection, TMessage>;
@@ -1,22 +1,23 @@
1
- import { ClientTransport } from '../core/transport/types.js';
1
+ import { CodecInputEvent, CodecOutputEvent } from '../core/codec/types.js';
2
+ import { BaseSessionOption } from './internal/use-resolved-session.js';
2
3
  import { ViewHandle } from './use-view.js';
4
+ /** Options for {@link useCreateView}. */
5
+ export interface UseCreateViewOptions<TInput extends CodecInputEvent, TOutput extends CodecOutputEvent, TProjection, TMessage> extends BaseSessionOption<TInput, TOutput, TProjection, TMessage> {
6
+ /** When provided, auto-loads the first page on mount. Omit for manual load. */
7
+ limit?: number;
8
+ /** When `true`, skip view creation and return an empty handle immediately. */
9
+ skip?: boolean;
10
+ }
3
11
  /**
4
12
  * Create an independent {@link View} and subscribe to it.
5
13
  * Returns the same {@link ViewHandle} as {@link useView}, but backed by a
6
14
  * 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.
15
+ * The view is closed on unmount or when the session changes.
16
+ * When `session` is omitted, uses the nearest {@link ClientSessionProvider}'s session via context.
17
+ * @param props - Options including optional `session`, `limit` for auto-load, and `skip`.
18
+ * @param props.session - Session to create a view from; defaults to the nearest provider.
11
19
  * @param props.limit - Max older messages per page; when provided, auto-loads on mount.
12
20
  * @param props.skip - When `true`, skip view creation and return an empty handle.
13
21
  * @returns A {@link ViewHandle} with nodes, pagination, navigation, and write operations.
14
22
  */
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>;
23
+ export declare const useCreateView: <TInput extends CodecInputEvent, TOutput extends CodecOutputEvent, TProjection, TMessage>({ session, limit, skip, }?: UseCreateViewOptions<TInput, TOutput, TProjection, TMessage>) => ViewHandle<TInput, TMessage>;
@@ -1,20 +1,35 @@
1
- import { ClientTransport, MessageNode } from '../core/transport/types.js';
1
+ import { CodecInputEvent, CodecOutputEvent } from '../core/codec/types.js';
2
+ import { ConversationNode, RunNode } from '../core/transport/types.js';
3
+ import { BaseSessionOption } from './internal/use-resolved-session.js';
2
4
  /** 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;
5
+ export interface TreeHandle<TProjection> {
6
+ /**
7
+ * Get the RunNode for `runId`, or undefined if no node is keyed by `runId`
8
+ * (or the keyed node is an input node, not a reply run).
9
+ */
10
+ getRunNode: (runId: string) => RunNode<TProjection> | undefined;
11
+ /**
12
+ * Get the node that owns a given codec-message-id, or undefined if not
13
+ * observed. Returns a {@link ConversationNode} union — narrow on `kind`
14
+ * (`'input'` vs `'run'`) before reading kind-specific fields.
15
+ */
16
+ getNodeByCodecMessageId: (codecMessageId: string) => ConversationNode<TProjection> | undefined;
17
+ /**
18
+ * Get the sibling group (both kinds) the node keyed by `key` belongs to —
19
+ * edit versions for an input node, regenerate runs for a reply run — ordered
20
+ * oldest-first. A single-element array when the node has no siblings; empty
21
+ * when `key` is unknown. `key` is a {@link RunNode.runId} or an
22
+ * {@link InputNode.codecMessageId}.
23
+ */
24
+ getSiblingNodes: (key: string) => ConversationNode<TProjection>[];
10
25
  }
26
+ /** Options for {@link useTree}. */
27
+ export type UseTreeOptions<TInput extends CodecInputEvent, TOutput extends CodecOutputEvent, TProjection, TMessage> = BaseSessionOption<TInput, TOutput, TProjection, TMessage>;
11
28
  /**
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.
29
+ * Provide stable structural query callbacks backed by the session's tree.
30
+ * When `session` is omitted, uses the nearest {@link ClientSessionProvider}'s session via context.
31
+ * @param props - Options including optional `session`.
32
+ * @param props.session - Session to read tree structure from; defaults to the nearest provider.
16
33
  * @returns A {@link TreeHandle} with structural query methods.
17
34
  */
18
- export declare const useTree: <TEvent, TMessage>({ transport, }?: {
19
- transport?: ClientTransport<TEvent, TMessage>;
20
- }) => TreeHandle<TMessage>;
35
+ export declare const useTree: <TInput extends CodecInputEvent, TOutput extends CodecOutputEvent, TProjection, TMessage>({ session, }?: UseTreeOptions<TInput, TOutput, TProjection, TMessage>) => TreeHandle<TProjection>;