@reactor-team/js-sdk 2.5.1 → 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.mts 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,87 +98,13 @@ 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;
90
105
  timestamp: number;
91
106
  recoverable: boolean;
92
- component: "coordinator" | "gpu" | "livekit";
107
+ component: "api" | "gpu";
93
108
  retryAfter?: number;
94
109
  }
95
110
  declare class ConflictError extends Error {
@@ -111,6 +126,22 @@ interface ConnectOptions {
111
126
  /** Maximum number of SDP polling attempts before giving up. Default: 6. */
112
127
  maxAttempts?: number;
113
128
  }
129
+ /**
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}).
136
+ */
137
+ interface ConnectionTimings {
138
+ /** POST /sessions round-trip time */
139
+ sessionCreationMs: number;
140
+ /** Total time spent in transport.connect() (signaling, negotiation, etc.) */
141
+ transportConnectingMs: number;
142
+ /** End-to-end: connect() invocation → status "ready" */
143
+ totalMs: number;
144
+ }
114
145
  interface ConnectionStats {
115
146
  /** ICE candidate-pair round-trip time in milliseconds */
116
147
  rtt?: number;
@@ -124,121 +155,259 @@ interface ConnectionStats {
124
155
  packetLossRatio?: number;
125
156
  /** Network jitter in seconds (from inbound-rtp) */
126
157
  jitter?: number;
158
+ /** Timing breakdown of the initial connection handshake (set once, persisted until disconnect) */
159
+ connectionTimings?: ConnectionTimings;
127
160
  timestamp: number;
128
161
  }
129
- type ReactorEvent = "statusChanged" | "sessionIdChanged" | "message" | "runtimeMessage" | "trackReceived" | "error" | "sessionExpirationChanged" | "statsUpdate";
162
+ type ReactorEvent = "statusChanged" | "sessionIdChanged" | "message" | "runtimeMessage" | "trackReceived" | "error" | "sessionExpirationChanged" | "capabilitiesReceived" | "statsUpdate";
130
163
 
131
- declare const PROD_COORDINATOR_URL = "https://api.reactor.inc";
164
+ declare const DEFAULT_BASE_URL = "https://api.reactor.inc";
132
165
  declare const OptionsSchema: z.ZodObject<{
133
- coordinatorUrl: z.ZodDefault<z.ZodString>;
166
+ apiUrl: z.ZodDefault<z.ZodString>;
134
167
  modelName: z.ZodString;
135
168
  local: z.ZodDefault<z.ZodBoolean>;
136
- receive: z.ZodDefault<z.ZodArray<z.ZodObject<{
137
- name: z.ZodString;
138
- kind: z.ZodEnum<{
139
- audio: "audio";
140
- video: "video";
141
- }>;
142
- }, z.core.$strip>>>;
143
- send: z.ZodDefault<z.ZodArray<z.ZodObject<{
144
- name: z.ZodString;
145
- kind: z.ZodEnum<{
146
- audio: "audio";
147
- video: "video";
148
- }>;
149
- }, z.core.$strip>>>;
150
169
  }, z.core.$strip>;
151
170
  type Options = z.input<typeof OptionsSchema>;
152
- type EventHandler = (...args: any[]) => void;
171
+ type EventHandler$2 = (...args: any[]) => void;
153
172
  declare class Reactor {
154
173
  private coordinatorClient;
155
- private machineClient;
174
+ private transportClient;
156
175
  private status;
157
176
  private coordinatorUrl;
158
177
  private lastError?;
159
178
  private model;
160
179
  private sessionExpiration?;
161
180
  private local;
162
- /** Tracks the client RECEIVES from the model (model → client). */
163
- private receive;
164
- /** Tracks the client SENDS to the model (client → model). */
165
- private send;
166
181
  private sessionId?;
182
+ private connectStartTime?;
183
+ private connectionTimings?;
184
+ private capabilities?;
185
+ private tracks;
186
+ private sessionResponse?;
167
187
  constructor(options: Options);
168
188
  private eventListeners;
169
- on(event: ReactorEvent, handler: EventHandler): void;
170
- off(event: ReactorEvent, handler: EventHandler): void;
189
+ on(event: ReactorEvent, handler: EventHandler$2): void;
190
+ off(event: ReactorEvent, handler: EventHandler$2): void;
171
191
  emit(event: ReactorEvent, ...args: any[]): void;
172
192
  /**
173
193
  * Sends a command to the model via the data channel.
174
- *
175
- * @param command The command name.
176
- * @param data The command payload.
177
- * @param scope "application" (default) for model commands, "runtime" for platform messages.
178
194
  */
179
195
  sendCommand(command: string, data: any, scope?: MessageScope): Promise<void>;
180
196
  /**
181
- * Publishes a MediaStreamTrack to a named send track.
182
- *
183
- * @param name The declared send track name (e.g. "webcam").
184
- * @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.
185
200
  */
186
201
  publishTrack(name: string, track: MediaStreamTrack): Promise<void>;
187
- /**
188
- * Unpublishes the track with the given name.
189
- *
190
- * @param name The declared send track name to unpublish.
191
- */
192
202
  unpublishTrack(name: string): Promise<void>;
193
203
  /**
194
- * Public method for reconnecting to an existing session, that may have been interrupted but can be recovered.
195
- * @param options Optional connect options (e.g. maxAttempts for SDP polling)
204
+ * Reconnects to an existing session with a fresh transport.
196
205
  */
197
206
  reconnect(options?: ConnectOptions): Promise<void>;
198
207
  /**
199
- * Connects to the coordinator and waits for a GPU to be assigned.
200
- * Once a GPU is assigned, the Reactor will connect to the gpu machine via WebRTC.
201
- * If no authentication is provided and not in local mode, an error is thrown.
202
- * @param jwtToken Optional JWT token for authentication
203
- * @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.
204
210
  */
205
211
  connect(jwtToken?: string, options?: ConnectOptions): Promise<void>;
206
212
  /**
207
- * Sets up event handlers for the machine client.
208
- *
209
- * Each handler captures the client reference at registration time and
210
- * ignores events if this.machineClient has since changed (e.g. after
211
- * disconnect + reconnect), preventing stale WebRTC teardown events from
212
- * 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.
213
215
  */
214
- private setupMachineClientHandlers;
216
+ private setupTransportHandlers;
215
217
  /**
216
- * Disconnects from the coordinator and the gpu machine.
217
- * Ensures cleanup completes even if individual disconnections fail.
218
+ * Disconnects from both the transport and the coordinator.
218
219
  */
219
220
  disconnect(recoverable?: boolean): Promise<void>;
220
- private setSessionId;
221
221
  getSessionId(): string | undefined;
222
- private setStatus;
223
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;
224
296
  /**
225
- * Set the session expiration time.
226
- * @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.
227
300
  */
228
- 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 {
229
343
  /**
230
- * 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.
231
349
  */
232
- getState(): ReactorState$1;
350
+ connect(tracks: TrackCapability[]): Promise<void>;
233
351
  /**
234
- * 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.
235
399
  */
236
- getLastError(): ReactorError | undefined;
237
400
  getStats(): ConnectionStats | undefined;
238
401
  /**
239
- * 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.
240
405
  */
241
- private createError;
406
+ getTransportTimings(): TransportTimings | undefined;
407
+ /**
408
+ * Cancels any in-flight signaling (HTTP polling, pending fetches).
409
+ */
410
+ abort(): void;
242
411
  }
243
412
 
244
413
  interface ReactorState {
@@ -246,7 +415,7 @@ interface ReactorState {
246
415
  /**
247
416
  * Media tracks received from the model, keyed by track name.
248
417
  *
249
- * Each entry maps a declared **receive** track name (e.g. `"main_video"`,
418
+ * Each entry maps a recvonly track name (e.g. `"main_video"`,
250
419
  * `"main_audio"`) to the live `MediaStreamTrack` delivered by the model.
251
420
  */
252
421
  tracks: Record<string, MediaStreamTrack>;
@@ -291,14 +460,16 @@ declare function useReactorStore<T = ReactorStore>(selector: (state: ReactorStor
291
460
 
292
461
  interface ReactorViewProps {
293
462
  /**
294
- * The name of the **receive** track to render.
295
- * 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.
296
466
  * Defaults to `"main_video"`.
297
467
  */
298
468
  track?: string;
299
469
  /**
300
- * Optional name of a **receive** audio track to play alongside the video
301
- * (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.
302
473
  */
303
474
  audioTrack?: string;
304
475
  width?: number;
@@ -319,8 +490,9 @@ declare function ReactorController({ className, style, }: ReactorControllerProps
319
490
 
320
491
  interface WebcamStreamProps {
321
492
  /**
322
- * The name of the **send** track to publish the webcam to.
323
- * 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.
324
496
  */
325
497
  track: string;
326
498
  className?: string;
@@ -372,9 +544,9 @@ declare function useStats(): ConnectionStats | undefined;
372
544
  * In production, call /tokens from your server and pass the JWT to your frontend.
373
545
  *
374
546
  * @param apiKey - Your Reactor API key (will be exposed in client code!)
375
- * @param coordinatorUrl - Optional coordinator URL, defaults to production
547
+ * @param apiUrl - Optional API URL, defaults to production
376
548
  * @returns string containing the JWT token
377
549
  */
378
- declare function fetchInsecureJwtToken(apiKey: string, coordinatorUrl?: string): Promise<string>;
550
+ declare function fetchInsecureToken(apiKey: string, apiUrl?: string): Promise<string>;
379
551
 
380
- export { AbortError, type AudioTrackOptions, ConflictError, type ConnectOptions, type ConnectionStats, type MessageScope, type Options, PROD_COORDINATOR_URL, 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, fetchInsecureJwtToken, 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 };