@reactor-team/js-sdk 2.6.0 → 2.7.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/dist/index.d.ts CHANGED
@@ -2,6 +2,95 @@ import { z } from 'zod';
2
2
  import * as react_jsx_runtime from 'react/jsx-runtime';
3
3
  import React, { ReactNode } from 'react';
4
4
 
5
+ /**
6
+ * Internal types for the Reactor SDK.
7
+ *
8
+ * All Zod schemas and derived TypeScript types live here.
9
+ * Version constants are sourced from package.json via resolveJsonModule.
10
+ */
11
+
12
+ declare const TransportDeclarationSchema: z.ZodObject<{
13
+ protocol: z.ZodString;
14
+ version: z.ZodString;
15
+ }, z.core.$strip>;
16
+ declare const TrackCapabilitySchema: z.ZodObject<{
17
+ name: z.ZodString;
18
+ kind: z.ZodEnum<{
19
+ video: "video";
20
+ audio: "audio";
21
+ }>;
22
+ direction: z.ZodEnum<{
23
+ recvonly: "recvonly";
24
+ sendonly: "sendonly";
25
+ }>;
26
+ }, z.core.$strip>;
27
+ declare const CommandCapabilitySchema: z.ZodObject<{
28
+ name: z.ZodString;
29
+ description: z.ZodString;
30
+ schema: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
31
+ }, z.core.$strip>;
32
+ declare const CapabilitiesSchema: z.ZodObject<{
33
+ protocol_version: z.ZodString;
34
+ tracks: z.ZodArray<z.ZodObject<{
35
+ name: z.ZodString;
36
+ kind: z.ZodEnum<{
37
+ video: "video";
38
+ audio: "audio";
39
+ }>;
40
+ direction: z.ZodEnum<{
41
+ recvonly: "recvonly";
42
+ sendonly: "sendonly";
43
+ }>;
44
+ }, z.core.$strip>>;
45
+ commands: z.ZodOptional<z.ZodArray<z.ZodObject<{
46
+ name: z.ZodString;
47
+ description: z.ZodString;
48
+ schema: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
49
+ }, z.core.$strip>>>;
50
+ emission_fps: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
51
+ }, z.core.$strip>;
52
+ declare const CreateSessionResponseSchema: z.ZodObject<{
53
+ session_id: z.ZodString;
54
+ server_info: z.ZodOptional<z.ZodObject<{
55
+ server_version: z.ZodString;
56
+ }, z.core.$strip>>;
57
+ model: z.ZodObject<{
58
+ name: z.ZodString;
59
+ version: z.ZodOptional<z.ZodString>;
60
+ }, z.core.$strip>;
61
+ state: z.ZodString;
62
+ cluster: z.ZodOptional<z.ZodString>;
63
+ selected_transport: z.ZodObject<{
64
+ protocol: z.ZodString;
65
+ version: z.ZodString;
66
+ }, z.core.$strip>;
67
+ capabilities: z.ZodObject<{
68
+ protocol_version: z.ZodString;
69
+ tracks: z.ZodArray<z.ZodObject<{
70
+ name: z.ZodString;
71
+ kind: z.ZodEnum<{
72
+ video: "video";
73
+ audio: "audio";
74
+ }>;
75
+ direction: z.ZodEnum<{
76
+ recvonly: "recvonly";
77
+ sendonly: "sendonly";
78
+ }>;
79
+ }, z.core.$strip>>;
80
+ commands: z.ZodOptional<z.ZodArray<z.ZodObject<{
81
+ name: z.ZodString;
82
+ description: z.ZodString;
83
+ schema: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
84
+ }, z.core.$strip>>>;
85
+ emission_fps: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
86
+ }, z.core.$strip>;
87
+ }, z.core.$strip>;
88
+ type TransportDeclaration = z.infer<typeof TransportDeclarationSchema>;
89
+ type TrackCapability = z.infer<typeof TrackCapabilitySchema>;
90
+ type CommandCapability = z.infer<typeof CommandCapabilitySchema>;
91
+ type CreateSessionResponse = z.infer<typeof CreateSessionResponseSchema>;
92
+ type Capabilities = z.infer<typeof CapabilitiesSchema>;
93
+
5
94
  type ReactorStatus = "disconnected" | "connecting" | "waiting" | "ready";
6
95
  /**
7
96
  * The message scope identifies the envelope layer a data channel message belongs to.
@@ -9,81 +98,7 @@ type ReactorStatus = "disconnected" | "connecting" | "waiting" | "ready";
9
98
  * - "runtime": platform-level control messages (e.g., capabilities exchange).
10
99
  */
11
100
  type MessageScope = "application" | "runtime";
12
- /**
13
- * Describes a single named media track for SDP negotiation.
14
- *
15
- * Track names must exactly match the class attribute names defined on the
16
- * model's Python code. The name is encoded as the SDP MID so both sides
17
- * can route media by name rather than by positional index.
18
- *
19
- * Use the {@link video} and {@link audio} helper functions to create
20
- * instances instead of constructing this interface directly.
21
- */
22
- interface TrackConfig {
23
- name: string;
24
- kind: "audio" | "video";
25
- }
26
- /**
27
- * Optional configuration for a video track (reserved for future use).
28
- */
29
- interface VideoTrackOptions {
30
- /** Maximum framerate constraint for the video track. */
31
- maxFramerate?: number;
32
- }
33
- /**
34
- * Optional configuration for an audio track (reserved for future use).
35
- */
36
- interface AudioTrackOptions {
37
- /** Sample rate constraint for the audio track. */
38
- sampleRate?: number;
39
- }
40
- /**
41
- * Creates a **video** {@link TrackConfig}.
42
- *
43
- * A track declared in the **`receive`** array means the client will
44
- * **RECEIVE** video frames **from the model** (model → client).
45
- *
46
- * A track declared in the **`send`** array means the client will
47
- * **SEND** video frames **to the model** (client → model).
48
- *
49
- * Track names must be unique across both arrays — the same name cannot
50
- * appear in `receive` and `send`.
51
- *
52
- * @param name - The track name. Must match the model's declared track attribute name.
53
- * @param options - Reserved for future constraints (e.g. `maxFramerate`).
54
- *
55
- * When no `receive` array is provided to the Reactor constructor, a single
56
- * `video("main_video")` track is used by default.
57
- *
58
- * @example
59
- * ```ts
60
- * receive: [video("main_video")] // receive video from the model
61
- * send: [video("webcam")] // send webcam video to the model
62
- * ```
63
- */
64
- declare function video(name: string, _options?: VideoTrackOptions): TrackConfig;
65
- /**
66
- * Creates an **audio** {@link TrackConfig}.
67
- *
68
- * A track declared in the **`receive`** array means the client will
69
- * **RECEIVE** audio samples **from the model** (model → client).
70
- *
71
- * A track declared in the **`send`** array means the client will
72
- * **SEND** audio samples **to the model** (client → model).
73
- *
74
- * Track names must be unique across both arrays — the same name cannot
75
- * appear in `receive` and `send`.
76
- *
77
- * @param name - The track name. Must match the model's declared track attribute name.
78
- * @param options - Reserved for future constraints (e.g. `sampleRate`).
79
- *
80
- * @example
81
- * ```ts
82
- * receive: [audio("main_audio")] // receive audio from the model
83
- * send: [audio("mic")] // send microphone audio to the model
84
- * ```
85
- */
86
- declare function audio(name: string, _options?: AudioTrackOptions): TrackConfig;
101
+
87
102
  interface ReactorError {
88
103
  code: string;
89
104
  message: string;
@@ -112,21 +127,18 @@ interface ConnectOptions {
112
127
  maxAttempts?: number;
113
128
  }
114
129
  /**
115
- * One-shot timing breakdown of the connect() handshake, recorded once per
116
- * connection and included in every subsequent {@link ConnectionStats} update.
117
- * All durations are in milliseconds (from `performance.now()`).
130
+ * Transport-agnostic timing breakdown of the connect() handshake, recorded
131
+ * once per connection and included in every subsequent {@link ConnectionStats}
132
+ * update. All durations are in milliseconds (from `performance.now()`).
133
+ *
134
+ * For transport-specific timings (e.g. ICE negotiation, data channel open),
135
+ * see the relevant transport stats type (e.g. {@link WebRTCTransportTimings}).
118
136
  */
119
137
  interface ConnectionTimings {
120
138
  /** POST /sessions round-trip time */
121
139
  sessionCreationMs: number;
122
- /** Total time spent polling for the SDP answer */
123
- sdpPollingMs: number;
124
- /** Number of SDP poll requests made (1 = answered on first try) */
125
- sdpPollingAttempts: number;
126
- /** setRemoteDescription → RTCPeerConnection connectionState "connected" */
127
- iceNegotiationMs: number;
128
- /** setRemoteDescription → RTCDataChannel "open" */
129
- dataChannelMs: number;
140
+ /** Total time spent in transport.connect() (signaling, negotiation, etc.) */
141
+ transportConnectingMs: number;
130
142
  /** End-to-end: connect() invocation → status "ready" */
131
143
  totalMs: number;
132
144
  }
@@ -147,123 +159,255 @@ interface ConnectionStats {
147
159
  connectionTimings?: ConnectionTimings;
148
160
  timestamp: number;
149
161
  }
150
- type ReactorEvent = "statusChanged" | "sessionIdChanged" | "message" | "runtimeMessage" | "trackReceived" | "error" | "sessionExpirationChanged" | "statsUpdate";
162
+ type ReactorEvent = "statusChanged" | "sessionIdChanged" | "message" | "runtimeMessage" | "trackReceived" | "error" | "sessionExpirationChanged" | "capabilitiesReceived" | "statsUpdate";
151
163
 
152
164
  declare const DEFAULT_BASE_URL = "https://api.reactor.inc";
153
165
  declare const OptionsSchema: z.ZodObject<{
154
166
  apiUrl: z.ZodDefault<z.ZodString>;
155
167
  modelName: z.ZodString;
156
168
  local: z.ZodDefault<z.ZodBoolean>;
157
- receive: z.ZodDefault<z.ZodArray<z.ZodObject<{
158
- name: z.ZodString;
159
- kind: z.ZodEnum<{
160
- audio: "audio";
161
- video: "video";
162
- }>;
163
- }, z.core.$strip>>>;
164
- send: z.ZodDefault<z.ZodArray<z.ZodObject<{
165
- name: z.ZodString;
166
- kind: z.ZodEnum<{
167
- audio: "audio";
168
- video: "video";
169
- }>;
170
- }, z.core.$strip>>>;
171
169
  }, z.core.$strip>;
172
170
  type Options = z.input<typeof OptionsSchema>;
173
- type EventHandler = (...args: any[]) => void;
171
+ type EventHandler$2 = (...args: any[]) => void;
174
172
  declare class Reactor {
175
173
  private coordinatorClient;
176
- private machineClient;
174
+ private transportClient;
177
175
  private status;
178
176
  private coordinatorUrl;
179
177
  private lastError?;
180
178
  private model;
181
179
  private sessionExpiration?;
182
180
  private local;
183
- /** Tracks the client RECEIVES from the model (model → client). */
184
- private receive;
185
- /** Tracks the client SENDS to the model (client → model). */
186
- private send;
187
181
  private sessionId?;
188
182
  private connectStartTime?;
189
183
  private connectionTimings?;
184
+ private capabilities?;
185
+ private tracks;
186
+ private sessionResponse?;
190
187
  constructor(options: Options);
191
188
  private eventListeners;
192
- on(event: ReactorEvent, handler: EventHandler): void;
193
- off(event: ReactorEvent, handler: EventHandler): void;
189
+ on(event: ReactorEvent, handler: EventHandler$2): void;
190
+ off(event: ReactorEvent, handler: EventHandler$2): void;
194
191
  emit(event: ReactorEvent, ...args: any[]): void;
195
192
  /**
196
193
  * Sends a command to the model via the data channel.
197
- *
198
- * @param command The command name.
199
- * @param data The command payload.
200
- * @param scope "application" (default) for model commands, "runtime" for platform messages.
201
194
  */
202
195
  sendCommand(command: string, data: any, scope?: MessageScope): Promise<void>;
203
196
  /**
204
- * Publishes a MediaStreamTrack to a named send track.
205
- *
206
- * @param name The declared send track name (e.g. "webcam").
207
- * @param track The MediaStreamTrack to publish.
197
+ * Publishes a MediaStreamTrack to a named sendonly track.
198
+ * The transceiver is already set up from capabilities — this just
199
+ * calls replaceTrack() on the sender.
208
200
  */
209
201
  publishTrack(name: string, track: MediaStreamTrack): Promise<void>;
210
- /**
211
- * Unpublishes the track with the given name.
212
- *
213
- * @param name The declared send track name to unpublish.
214
- */
215
202
  unpublishTrack(name: string): Promise<void>;
216
203
  /**
217
- * Public method for reconnecting to an existing session, that may have been interrupted but can be recovered.
218
- * @param options Optional connect options (e.g. maxAttempts for SDP polling)
204
+ * Reconnects to an existing session with a fresh transport.
219
205
  */
220
206
  reconnect(options?: ConnectOptions): Promise<void>;
221
207
  /**
222
- * Connects to the coordinator and waits for a GPU to be assigned.
223
- * Once a GPU is assigned, the Reactor will connect to the gpu machine via WebRTC.
224
- * If no authentication is provided and not in local mode, an error is thrown.
225
- * @param jwtToken Optional JWT token for authentication
226
- * @param options Optional connect options (e.g. maxAttempts for SDP polling)
208
+ * Connects to the coordinator, creates a session, then establishes
209
+ * the transport using server-declared capabilities.
227
210
  */
228
211
  connect(jwtToken?: string, options?: ConnectOptions): Promise<void>;
229
212
  /**
230
- * Sets up event handlers for the machine client.
231
- *
232
- * Each handler captures the client reference at registration time and
233
- * ignores events if this.machineClient has since changed (e.g. after
234
- * disconnect + reconnect), preventing stale WebRTC teardown events from
235
- * interfering with a new connection.
213
+ * Sets up event handlers for the transport client.
214
+ * Each handler captures the client reference to ignore stale events.
236
215
  */
237
- private setupMachineClientHandlers;
216
+ private setupTransportHandlers;
238
217
  /**
239
- * Disconnects from the coordinator and the gpu machine.
240
- * Ensures cleanup completes even if individual disconnections fail.
218
+ * Disconnects from both the transport and the coordinator.
241
219
  */
242
220
  disconnect(recoverable?: boolean): Promise<void>;
243
- private setSessionId;
244
221
  getSessionId(): string | undefined;
245
- private setStatus;
246
222
  getStatus(): ReactorStatus;
223
+ getState(): ReactorState$1;
224
+ getLastError(): ReactorError | undefined;
225
+ getCapabilities(): Capabilities | undefined;
226
+ getSessionInfo(): CreateSessionResponse | undefined;
227
+ getStats(): ConnectionStats | undefined;
228
+ private setSessionId;
229
+ private setStatus;
230
+ private setSessionExpiration;
231
+ private resetConnectionTimings;
232
+ private finalizeConnectionTimings;
233
+ private createError;
234
+ }
235
+
236
+ type EventHandler$1 = (...args: any[]) => void;
237
+ interface WebRTCTransportConfig extends TransportClientConfig {
238
+ webrtcVersion?: string;
239
+ maxPollAttempts?: number;
240
+ }
241
+ /**
242
+ * WebRTC-specific timing breakdown of the transport connection.
243
+ * Recorded once per connection and accessible via {@link WebRTCTransportClient.getTransportTimings}.
244
+ */
245
+ interface WebRTCTransportTimings {
246
+ protocol: "webrtc";
247
+ /** Time spent polling for the SDP answer (POST offer → GET answer 200) */
248
+ sdpPollingMs: number;
249
+ /** Number of SDP poll requests made (1 = answered on first try) */
250
+ sdpPollingAttempts: number;
251
+ /** setRemoteDescription → RTCPeerConnection connectionState "connected" */
252
+ iceNegotiationMs: number;
253
+ /** setRemoteDescription → RTCDataChannel "open" */
254
+ dataChannelMs: number;
255
+ }
256
+ declare class WebRTCTransportClient implements TransportClient {
257
+ private eventListeners;
258
+ private peerConnection;
259
+ private dataChannel;
260
+ private status;
261
+ private pingInterval;
262
+ private statsInterval;
263
+ private stats;
264
+ private transceiverMap;
265
+ private publishedTracks;
266
+ private peerConnected;
267
+ private dataChannelOpen;
268
+ private iceStartTime?;
269
+ private iceNegotiationMs?;
270
+ private dataChannelMs?;
271
+ private sdpPollingMs?;
272
+ private sdpPollingAttempts?;
273
+ private readonly baseUrl;
274
+ private readonly sessionId;
275
+ private readonly jwtToken;
276
+ private readonly webrtcVersion;
277
+ private readonly maxPollAttempts;
278
+ private abortController;
279
+ constructor(config: WebRTCTransportConfig);
280
+ on(event: TransportEvent, handler: EventHandler$1): void;
281
+ off(event: TransportEvent, handler: EventHandler$1): void;
282
+ private emit;
283
+ private get signal();
284
+ private get transportBaseUrl();
285
+ private getHeaders;
286
+ private checkVersionMismatch;
287
+ private sleep;
288
+ private fetchIceServers;
289
+ private sendSdpOffer;
290
+ private pollSdpAnswer;
291
+ connect(tracks: TrackCapability[]): Promise<void>;
292
+ reconnect(tracks: TrackCapability[]): Promise<void>;
293
+ disconnect(): Promise<void>;
294
+ abort(): void;
295
+ getStatus(): TransportStatus;
247
296
  /**
248
- * Set the session expiration time.
249
- * @param newSessionExpiration The new session expiration time in seconds.
297
+ * Builds the track_mapping array from capabilities + transceiver MIDs.
298
+ * Must be called after createOffer + setLocalDescription so that
299
+ * transceiver.mid is assigned.
250
300
  */
251
- private setSessionExpiration;
301
+ private buildTrackMapping;
302
+ private get maxMessageBytes();
303
+ sendCommand(command: string, data: any, scope?: MessageScope): void;
304
+ publishTrack(name: string, track: MediaStreamTrack): Promise<void>;
305
+ unpublishTrack(name: string): Promise<void>;
306
+ getStats(): ConnectionStats | undefined;
307
+ getTransportTimings(): WebRTCTransportTimings | undefined;
308
+ private resetTransportTimings;
309
+ private startStatsPolling;
310
+ private stopStatsPolling;
311
+ private startPing;
312
+ private stopPing;
313
+ private checkFullyConnected;
314
+ private setStatus;
315
+ private setupPeerConnectionHandlers;
316
+ private setupDataChannelHandlers;
317
+ }
318
+
319
+ /**
320
+ * Generic transport interface for connecting to a Reactor session.
321
+ *
322
+ * A TransportClient encapsulates the full transport lifecycle: signaling,
323
+ * connection establishment, media track management, and data channel
324
+ * messaging. Implementations handle protocol specifics (WebRTC, MOQ, etc.)
325
+ * while the Reactor orchestrator works only through this interface.
326
+ */
327
+
328
+ /**
329
+ * Discriminated union of all transport-specific timing types.
330
+ * Each member carries a `protocol` tag for narrowing.
331
+ * Extend this union when adding new transport implementations.
332
+ */
333
+ type TransportTimings = WebRTCTransportTimings;
334
+ type TransportStatus = "disconnected" | "connecting" | "connected" | "error";
335
+ type TransportEvent = "statusChanged" | "trackReceived" | "trackRemoved" | "message" | "statsUpdate";
336
+ type EventHandler = (...args: any[]) => void;
337
+ interface TransportClientConfig {
338
+ baseUrl: string;
339
+ sessionId: string;
340
+ jwtToken: string;
341
+ }
342
+ interface TransportClient {
252
343
  /**
253
- * Get the current state including status, error, and waiting info
344
+ * Establishes the transport connection using server-declared tracks.
345
+ *
346
+ * Internally handles: signaling (ICE servers, SDP offer/answer),
347
+ * connection negotiation, and transceiver setup. For sendonly tracks,
348
+ * no media flows until {@link publishTrack} is called.
254
349
  */
255
- getState(): ReactorState$1;
350
+ connect(tracks: TrackCapability[]): Promise<void>;
256
351
  /**
257
- * Get the last error that occurred
352
+ * Reconnects an existing session with a fresh transport negotiation.
353
+ * Uses the same tracks as the original connection.
354
+ */
355
+ reconnect(tracks: TrackCapability[]): Promise<void>;
356
+ /**
357
+ * Tears down the transport connection and releases all resources.
358
+ */
359
+ disconnect(): Promise<void>;
360
+ /**
361
+ * Returns the current transport connection status.
362
+ */
363
+ getStatus(): TransportStatus;
364
+ /**
365
+ * Sends a command to the model via the data channel.
366
+ *
367
+ * @param command The command name.
368
+ * @param data The command payload.
369
+ * @param scope "application" for model commands, "runtime" for platform messages.
370
+ */
371
+ sendCommand(command: string, data: any, scope: MessageScope): void;
372
+ /**
373
+ * Publishes a MediaStreamTrack to a named sendonly track.
374
+ * The transceiver must already exist (declared by capabilities).
375
+ * Uses replaceTrack() — no renegotiation needed.
376
+ */
377
+ publishTrack(name: string, track: MediaStreamTrack): Promise<void>;
378
+ /**
379
+ * Stops sending media on a named track.
380
+ */
381
+ unpublishTrack(name: string): Promise<void>;
382
+ /**
383
+ * Subscribes to transport events.
384
+ *
385
+ * Events:
386
+ * - "statusChanged" (status: TransportStatus)
387
+ * - "trackReceived" (name: string, track: MediaStreamTrack, stream: MediaStream)
388
+ * - "trackRemoved" (name: string)
389
+ * - "message" (message: any, scope: MessageScope)
390
+ * - "statsUpdate" (stats: ConnectionStats)
391
+ */
392
+ on(event: TransportEvent, handler: EventHandler): void;
393
+ /**
394
+ * Unsubscribes from transport events.
395
+ */
396
+ off(event: TransportEvent, handler: EventHandler): void;
397
+ /**
398
+ * Returns current connection statistics, or undefined if not connected.
258
399
  */
259
- getLastError(): ReactorError | undefined;
260
400
  getStats(): ConnectionStats | undefined;
261
- private resetConnectionTimings;
262
- private finalizeConnectionTimings;
263
401
  /**
264
- * Create and store an error
402
+ * Returns transport-specific timing breakdown of the most recent
403
+ * connection attempt. Narrow on the `protocol` discriminant to
404
+ * access implementation-specific fields.
265
405
  */
266
- private createError;
406
+ getTransportTimings(): TransportTimings | undefined;
407
+ /**
408
+ * Cancels any in-flight signaling (HTTP polling, pending fetches).
409
+ */
410
+ abort(): void;
267
411
  }
268
412
 
269
413
  interface ReactorState {
@@ -271,7 +415,7 @@ interface ReactorState {
271
415
  /**
272
416
  * Media tracks received from the model, keyed by track name.
273
417
  *
274
- * Each entry maps a declared **receive** track name (e.g. `"main_video"`,
418
+ * Each entry maps a recvonly track name (e.g. `"main_video"`,
275
419
  * `"main_audio"`) to the live `MediaStreamTrack` delivered by the model.
276
420
  */
277
421
  tracks: Record<string, MediaStreamTrack>;
@@ -316,14 +460,16 @@ declare function useReactorStore<T = ReactorStore>(selector: (state: ReactorStor
316
460
 
317
461
  interface ReactorViewProps {
318
462
  /**
319
- * The name of the **receive** track to render.
320
- * Must match a track name declared in the `receive` array (model → client).
463
+ * The name of the recvonly track to render.
464
+ * Must match a track name declared in the server capabilities.
465
+ * Check the model's documentation for available track names.
321
466
  * Defaults to `"main_video"`.
322
467
  */
323
468
  track?: string;
324
469
  /**
325
- * Optional name of a **receive** audio track to play alongside the video
326
- * (e.g. `"main_audio"`). The audio is mixed into the same `<video>` element.
470
+ * Optional name of a recvonly audio track to play alongside the video
471
+ * (e.g. `"main_audio"`). The audio is mixed into the same `<video>` element.
472
+ * Check the model's documentation for available track names.
327
473
  */
328
474
  audioTrack?: string;
329
475
  width?: number;
@@ -344,8 +490,9 @@ declare function ReactorController({ className, style, }: ReactorControllerProps
344
490
 
345
491
  interface WebcamStreamProps {
346
492
  /**
347
- * The name of the **send** track to publish the webcam to.
348
- * Must match a track name declared in the `send` array (client → model).
493
+ * The name of the sendonly track to publish the webcam to.
494
+ * Must match a track name declared in the server capabilities.
495
+ * Check the model's documentation for available track names.
349
496
  */
350
497
  track: string;
351
498
  className?: string;
@@ -402,4 +549,4 @@ declare function useStats(): ConnectionStats | undefined;
402
549
  */
403
550
  declare function fetchInsecureToken(apiKey: string, apiUrl?: string): Promise<string>;
404
551
 
405
- export { AbortError, type AudioTrackOptions, ConflictError, type ConnectOptions, type ConnectionStats, type ConnectionTimings, DEFAULT_BASE_URL, type MessageScope, type Options, Reactor, type ReactorConnectOptions, ReactorController, type ReactorControllerProps, type ReactorError, type ReactorEvent, ReactorProvider, type ReactorState$1 as ReactorState, type ReactorStatus, ReactorView, type ReactorViewProps, type TrackConfig, type VideoTrackOptions, WebcamStream, type WebcamStreamProps, audio, fetchInsecureToken, isAbortError, useReactor, useReactorInternalMessage, useReactorMessage, useReactorStore, useStats, video };
552
+ export { AbortError, type Capabilities, type CommandCapability, ConflictError, type ConnectOptions, type ConnectionStats, type ConnectionTimings, DEFAULT_BASE_URL, type MessageScope, type Options, Reactor, type ReactorConnectOptions, ReactorController, type ReactorControllerProps, type ReactorError, type ReactorEvent, ReactorProvider, type ReactorState$1 as ReactorState, type ReactorStatus, ReactorView, type ReactorViewProps, type CreateSessionResponse as SessionInfo, type TrackCapability, type TransportClient, type TransportClientConfig, type TransportDeclaration, type TransportEvent, type TransportStatus, type TransportTimings, WebRTCTransportClient, type WebRTCTransportConfig, type WebRTCTransportTimings, WebcamStream, type WebcamStreamProps, fetchInsecureToken, isAbortError, useReactor, useReactorInternalMessage, useReactorMessage, useReactorStore, useStats };