@robinandeer/rtc-session-components 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.
package/dist/index.cjs CHANGED
@@ -1,11 +1,18 @@
1
1
  'use strict';
2
2
 
3
- var react = require('react');
4
3
  var componentsReact = require('@livekit/components-react');
4
+ var react = require('react');
5
5
  var livekitClient = require('livekit-client');
6
6
  var jsxRuntime = require('react/jsx-runtime');
7
7
 
8
- // src/components/AvatarSession.tsx
8
+ // src/components/AudioRenderer.tsx
9
+ function useLatest(value) {
10
+ const ref = react.useRef(value);
11
+ react.useEffect(() => {
12
+ ref.current = value;
13
+ }, [value]);
14
+ return ref;
15
+ }
9
16
  function mapConnectionState(connectionState) {
10
17
  switch (connectionState) {
11
18
  case livekitClient.ConnectionState.Connecting:
@@ -20,7 +27,9 @@ function mapConnectionState(connectionState) {
20
27
  return "ended";
21
28
  }
22
29
  }
23
- var AvatarSessionContext = react.createContext(null);
30
+ var AvatarSessionContext = react.createContext(
31
+ null
32
+ );
24
33
  function AvatarSession({
25
34
  credentials,
26
35
  children,
@@ -37,7 +46,7 @@ function AvatarSession({
37
46
  return /* @__PURE__ */ jsxRuntime.jsxs(
38
47
  componentsReact.LiveKitRoom,
39
48
  {
40
- serverUrl: credentials.livekitUrl,
49
+ serverUrl: credentials.serverUrl,
41
50
  token: credentials.token,
42
51
  connect: true,
43
52
  audio,
@@ -94,13 +103,12 @@ function AvatarSessionContextInner({
94
103
  function useAvatarSessionContext() {
95
104
  const context = react.useContext(AvatarSessionContext);
96
105
  if (!context) {
97
- throw new Error("useAvatarSessionContext must be used within an AvatarSession");
106
+ throw new Error(
107
+ "useAvatarSessionContext must be used within an AvatarSession"
108
+ );
98
109
  }
99
110
  return context;
100
111
  }
101
- function useMaybeAvatarSessionContext() {
102
- return react.useContext(AvatarSessionContext);
103
- }
104
112
  function useAvatar() {
105
113
  const remoteParticipants = componentsReact.useRemoteParticipants();
106
114
  const avatarParticipant = remoteParticipants[0] ?? null;
@@ -115,9 +123,15 @@ function useAvatar() {
115
123
  const handleIsSpeakingChanged = (speaking) => {
116
124
  setIsSpeaking(speaking);
117
125
  };
118
- avatarParticipant.on(livekitClient.ParticipantEvent.IsSpeakingChanged, handleIsSpeakingChanged);
126
+ avatarParticipant.on(
127
+ livekitClient.ParticipantEvent.IsSpeakingChanged,
128
+ handleIsSpeakingChanged
129
+ );
119
130
  return () => {
120
- avatarParticipant.off(livekitClient.ParticipantEvent.IsSpeakingChanged, handleIsSpeakingChanged);
131
+ avatarParticipant.off(
132
+ livekitClient.ParticipantEvent.IsSpeakingChanged,
133
+ handleIsSpeakingChanged
134
+ );
121
135
  };
122
136
  }, [avatarParticipant]);
123
137
  const tracks = componentsReact.useTracks(
@@ -188,30 +202,24 @@ function useLocalMedia() {
188
202
  const isMicEnabled = localParticipant?.isMicrophoneEnabled ?? false;
189
203
  const isCameraEnabled = localParticipant?.isCameraEnabled ?? false;
190
204
  const isScreenShareEnabled = localParticipant?.isScreenShareEnabled ?? false;
191
- const isMicEnabledRef = react.useRef(isMicEnabled);
192
- const isCameraEnabledRef = react.useRef(isCameraEnabled);
193
- const isScreenShareEnabledRef = react.useRef(isScreenShareEnabled);
194
- react.useEffect(() => {
195
- isMicEnabledRef.current = isMicEnabled;
196
- }, [isMicEnabled]);
197
- react.useEffect(() => {
198
- isCameraEnabledRef.current = isCameraEnabled;
199
- }, [isCameraEnabled]);
200
- react.useEffect(() => {
201
- isScreenShareEnabledRef.current = isScreenShareEnabled;
202
- }, [isScreenShareEnabled]);
205
+ const isMicEnabledRef = useLatest(isMicEnabled);
206
+ const isCameraEnabledRef = useLatest(isCameraEnabled);
207
+ const isScreenShareEnabledRef = useLatest(isScreenShareEnabled);
203
208
  const toggleMic = react.useCallback(() => {
204
209
  localParticipant?.setMicrophoneEnabled(!isMicEnabledRef.current);
205
- }, [localParticipant]);
210
+ }, [localParticipant, isMicEnabledRef]);
206
211
  const toggleCamera = react.useCallback(() => {
207
212
  localParticipant?.setCameraEnabled(!isCameraEnabledRef.current);
208
- }, [localParticipant]);
213
+ }, [localParticipant, isCameraEnabledRef]);
209
214
  const toggleScreenShare = react.useCallback(() => {
210
215
  localParticipant?.setScreenShareEnabled(!isScreenShareEnabledRef.current);
211
- }, [localParticipant]);
212
- const tracks = componentsReact.useTracks([{ source: livekitClient.Track.Source.Camera, withPlaceholder: true }], {
213
- onlySubscribed: false
214
- });
216
+ }, [localParticipant, isScreenShareEnabledRef]);
217
+ const tracks = componentsReact.useTracks(
218
+ [{ source: livekitClient.Track.Source.Camera, withPlaceholder: true }],
219
+ {
220
+ onlySubscribed: false
221
+ }
222
+ );
215
223
  const localIdentity = localParticipant?.identity;
216
224
  const localVideoTrackRef = tracks.find(
217
225
  (trackRef) => trackRef.participant.identity === localIdentity && trackRef.source === livekitClient.Track.Source.Camera
@@ -228,28 +236,6 @@ function useLocalMedia() {
228
236
  localVideoTrackRef
229
237
  };
230
238
  }
231
- function UserVideo({ children, mirror = true, ...props }) {
232
- const { localVideoTrackRef, isCameraEnabled } = useLocalMedia();
233
- const hasVideo = localVideoTrackRef !== null && componentsReact.isTrackReference(localVideoTrackRef);
234
- const state = {
235
- hasVideo,
236
- isCameraEnabled,
237
- trackRef: localVideoTrackRef
238
- };
239
- if (children) {
240
- return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: children(state) });
241
- }
242
- return /* @__PURE__ */ jsxRuntime.jsx(
243
- "div",
244
- {
245
- ...props,
246
- "data-has-video": hasVideo,
247
- "data-camera-enabled": isCameraEnabled,
248
- "data-mirror": mirror,
249
- children: hasVideo && localVideoTrackRef && componentsReact.isTrackReference(localVideoTrackRef) && /* @__PURE__ */ jsxRuntime.jsx(componentsReact.VideoTrack, { trackRef: localVideoTrackRef })
250
- }
251
- );
252
- }
253
239
  function ControlBar({
254
240
  children,
255
241
  showMicrophone = true,
@@ -284,7 +270,7 @@ function ControlBar({
284
270
  "data-control": "microphone",
285
271
  "data-enabled": isMicEnabled,
286
272
  "aria-label": isMicEnabled ? "Mute microphone" : "Unmute microphone",
287
- children: /* @__PURE__ */ jsxRuntime.jsx(MicrophoneIcon, {})
273
+ children: microphoneIcon
288
274
  }
289
275
  ),
290
276
  showCamera && /* @__PURE__ */ jsxRuntime.jsx(
@@ -295,45 +281,232 @@ function ControlBar({
295
281
  "data-control": "camera",
296
282
  "data-enabled": isCameraEnabled,
297
283
  "aria-label": isCameraEnabled ? "Turn off camera" : "Turn on camera",
298
- children: /* @__PURE__ */ jsxRuntime.jsx(CameraIcon, {})
284
+ children: cameraIcon
299
285
  }
300
286
  ),
301
- showScreenShare && /* @__PURE__ */ jsxRuntime.jsx(componentsReact.TrackToggle, { source: livekitClient.Track.Source.ScreenShare, showIcon: false, "data-control": "screen-share", children: /* @__PURE__ */ jsxRuntime.jsx(ScreenShareIcon, {}) }),
302
- showEndCall && /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: session.end, "data-control": "end-call", "aria-label": "End call", children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Leave" }) })
287
+ showScreenShare && /* @__PURE__ */ jsxRuntime.jsx(
288
+ componentsReact.TrackToggle,
289
+ {
290
+ source: livekitClient.Track.Source.ScreenShare,
291
+ showIcon: false,
292
+ "data-control": "screen-share",
293
+ "aria-label": "Toggle screen share",
294
+ children: screenShareIcon
295
+ }
296
+ ),
297
+ showEndCall && /* @__PURE__ */ jsxRuntime.jsx(
298
+ "button",
299
+ {
300
+ type: "button",
301
+ onClick: session.end,
302
+ "data-control": "end-call",
303
+ "aria-label": "End call",
304
+ children: phoneIcon
305
+ }
306
+ )
303
307
  ] });
304
308
  }
305
- function MicrophoneIcon() {
306
- return /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "20", height: "20", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx(
307
- "path",
309
+ var microphoneIcon = /* @__PURE__ */ jsxRuntime.jsxs(
310
+ "svg",
311
+ {
312
+ width: "20",
313
+ height: "20",
314
+ viewBox: "0 0 24 24",
315
+ fill: "none",
316
+ stroke: "currentColor",
317
+ strokeWidth: "2",
318
+ strokeLinecap: "round",
319
+ strokeLinejoin: "round",
320
+ "aria-hidden": "true",
321
+ children: [
322
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3Z" }),
323
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M19 10v2a7 7 0 0 1-14 0v-2" }),
324
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "12", x2: "12", y1: "19", y2: "22" })
325
+ ]
326
+ }
327
+ );
328
+ var cameraIcon = /* @__PURE__ */ jsxRuntime.jsxs(
329
+ "svg",
330
+ {
331
+ width: "20",
332
+ height: "20",
333
+ viewBox: "0 0 24 24",
334
+ fill: "none",
335
+ stroke: "currentColor",
336
+ strokeWidth: "2",
337
+ strokeLinecap: "round",
338
+ strokeLinejoin: "round",
339
+ "aria-hidden": "true",
340
+ children: [
341
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "m16 13 5.223 3.482a.5.5 0 0 0 .777-.416V7.87a.5.5 0 0 0-.752-.432L16 10.5" }),
342
+ /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "2", y: "6", width: "14", height: "12", rx: "2" })
343
+ ]
344
+ }
345
+ );
346
+ var screenShareIcon = /* @__PURE__ */ jsxRuntime.jsxs(
347
+ "svg",
348
+ {
349
+ width: "20",
350
+ height: "20",
351
+ viewBox: "0 0 24 24",
352
+ fill: "none",
353
+ stroke: "currentColor",
354
+ strokeWidth: "2",
355
+ strokeLinecap: "round",
356
+ strokeLinejoin: "round",
357
+ "aria-hidden": "true",
358
+ children: [
359
+ /* @__PURE__ */ jsxRuntime.jsx("rect", { width: "20", height: "14", x: "2", y: "3", rx: "2" }),
360
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "8", x2: "16", y1: "21", y2: "21" }),
361
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "12", x2: "12", y1: "17", y2: "21" })
362
+ ]
363
+ }
364
+ );
365
+ var phoneIcon = /* @__PURE__ */ jsxRuntime.jsx(
366
+ "svg",
367
+ {
368
+ width: "20",
369
+ height: "20",
370
+ viewBox: "8 14 24 12",
371
+ fill: "currentColor",
372
+ "aria-hidden": "true",
373
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M12.8429 22.5693L11.4018 21.0986C11.2675 20.9626 11.1625 20.7995 11.0935 20.6197C11.0245 20.4399 10.9931 20.2474 11.0013 20.0545C11.0094 19.8616 11.0569 19.6726 11.1408 19.4995C11.2247 19.3265 11.343 19.1732 11.4883 19.0495C13.127 17.7049 15.0519 16.7714 17.1083 16.3239C19.0064 15.892 20.9744 15.892 22.8725 16.3239C24.9374 16.7743 26.8693 17.7147 28.5117 19.0691C28.6565 19.1924 28.7746 19.3451 28.8585 19.5176C28.9423 19.69 28.99 19.8784 28.9986 20.0707C29.0072 20.263 28.9764 20.455 28.9083 20.6345C28.8402 20.814 28.7362 20.9771 28.603 21.1133L27.1619 22.584C26.9311 22.8242 26.6226 22.9706 26.2938 22.9959C25.9651 23.0211 25.6385 22.9235 25.3751 22.7212C24.8531 22.3127 24.2875 21.9657 23.689 21.6869C23.4525 21.5774 23.2517 21.4009 23.1103 21.1785C22.969 20.9561 22.8931 20.697 22.8917 20.4319V19.1867C21.0053 18.6573 19.0139 18.6573 17.1275 19.1867V20.4319C17.1261 20.697 17.0502 20.9561 16.9089 21.1785C16.7676 21.4009 16.5667 21.5774 16.3302 21.6869C15.7317 21.9657 15.1661 22.3127 14.6442 22.7212C14.3779 22.9258 14.0473 23.0233 13.7152 22.9953C13.383 22.9673 13.0726 22.8156 12.8429 22.5693Z" })
374
+ }
375
+ );
376
+ function UserVideo({ children, mirror = true, ...props }) {
377
+ const { localVideoTrackRef, isCameraEnabled } = useLocalMedia();
378
+ const hasVideo = localVideoTrackRef !== null && componentsReact.isTrackReference(localVideoTrackRef);
379
+ const state = {
380
+ hasVideo,
381
+ isCameraEnabled,
382
+ trackRef: localVideoTrackRef
383
+ };
384
+ if (children) {
385
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: children(state) });
386
+ }
387
+ return /* @__PURE__ */ jsxRuntime.jsx(
388
+ "div",
308
389
  {
309
- strokeLinecap: "round",
310
- strokeLinejoin: "round",
311
- strokeWidth: 2,
312
- d: "M19 11a7 7 0 01-7 7m0 0a7 7 0 01-7-7m7 7v4m0 0H8m4 0h4m-4-8a3 3 0 01-3-3V5a3 3 0 116 0v6a3 3 0 01-3 3z"
390
+ ...props,
391
+ "data-has-video": hasVideo,
392
+ "data-camera-enabled": isCameraEnabled,
393
+ "data-mirror": mirror,
394
+ children: hasVideo && localVideoTrackRef && componentsReact.isTrackReference(localVideoTrackRef) && /* @__PURE__ */ jsxRuntime.jsx(componentsReact.VideoTrack, { trackRef: localVideoTrackRef })
313
395
  }
314
- ) });
396
+ );
315
397
  }
316
- function CameraIcon() {
317
- return /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "20", height: "20", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx(
318
- "path",
319
- {
320
- strokeLinecap: "round",
321
- strokeLinejoin: "round",
322
- strokeWidth: 2,
323
- d: "M15 10l4.553-2.276A1 1 0 0121 8.618v6.764a1 1 0 01-1.447.894L15 14M5 18h8a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v8a2 2 0 002 2z"
398
+ function AvatarCall({
399
+ avatarId,
400
+ connectUrl,
401
+ connect,
402
+ avatarImageUrl,
403
+ onEnd,
404
+ onError,
405
+ children,
406
+ ...props
407
+ }) {
408
+ const [credentials, setCredentials] = react.useState(
409
+ null
410
+ );
411
+ const [connectionState, setConnectionState] = react.useState("idle");
412
+ const [error, setError] = react.useState(null);
413
+ const fetchedForRef = react.useRef(null);
414
+ const connectRef = useLatest(connect);
415
+ const onErrorRef = useLatest(onError);
416
+ react.useEffect(() => {
417
+ if (fetchedForRef.current === avatarId) return;
418
+ fetchedForRef.current = avatarId;
419
+ async function fetchCredentials() {
420
+ setConnectionState("connecting");
421
+ setError(null);
422
+ setCredentials(null);
423
+ try {
424
+ let creds;
425
+ if (connectRef.current) {
426
+ creds = await connectRef.current(avatarId);
427
+ } else if (connectUrl) {
428
+ const response = await fetch(connectUrl, {
429
+ method: "POST",
430
+ headers: { "Content-Type": "application/json" },
431
+ body: JSON.stringify({ avatarId })
432
+ });
433
+ if (!response.ok) {
434
+ const errorText = await response.text();
435
+ throw new Error(
436
+ `Failed to connect: ${response.status} ${errorText}`
437
+ );
438
+ }
439
+ creds = await response.json();
440
+ } else {
441
+ throw new Error(
442
+ "AvatarCall requires either connectUrl or connect prop"
443
+ );
444
+ }
445
+ setCredentials(creds);
446
+ setConnectionState("connected");
447
+ } catch (err) {
448
+ const error2 = err instanceof Error ? err : new Error(String(err));
449
+ setError(error2);
450
+ setConnectionState("error");
451
+ onErrorRef.current?.(error2);
452
+ }
324
453
  }
325
- ) });
326
- }
327
- function ScreenShareIcon() {
328
- return /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "20", height: "20", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx(
329
- "path",
454
+ fetchCredentials();
455
+ }, [avatarId, connectUrl, connectRef, onErrorRef]);
456
+ const handleError = (err) => {
457
+ setError(err);
458
+ setConnectionState("error");
459
+ onErrorRef.current?.(err);
460
+ };
461
+ const backgroundStyle = avatarImageUrl ? { "--avatar-image": `url(${avatarImageUrl})` } : void 0;
462
+ if (connectionState === "idle" || connectionState === "connecting") {
463
+ return /* @__PURE__ */ jsxRuntime.jsx(
464
+ "div",
465
+ {
466
+ ...props,
467
+ "data-avatar-call": "",
468
+ "data-state": "connecting",
469
+ "data-avatar-id": avatarId,
470
+ style: { ...props.style, ...backgroundStyle }
471
+ }
472
+ );
473
+ }
474
+ if (connectionState === "error" || !credentials) {
475
+ return /* @__PURE__ */ jsxRuntime.jsx(
476
+ "div",
477
+ {
478
+ ...props,
479
+ "data-avatar-call": "",
480
+ "data-state": "error",
481
+ "data-avatar-id": avatarId,
482
+ "data-error": error?.message,
483
+ style: { ...props.style, ...backgroundStyle }
484
+ }
485
+ );
486
+ }
487
+ return /* @__PURE__ */ jsxRuntime.jsx(
488
+ "div",
330
489
  {
331
- strokeLinecap: "round",
332
- strokeLinejoin: "round",
333
- strokeWidth: 2,
334
- d: "M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"
490
+ ...props,
491
+ "data-avatar-call": "",
492
+ "data-state": "connected",
493
+ "data-avatar-id": avatarId,
494
+ style: { ...props.style, ...backgroundStyle },
495
+ children: /* @__PURE__ */ jsxRuntime.jsx(
496
+ AvatarSession,
497
+ {
498
+ credentials,
499
+ onEnd,
500
+ onError: handleError,
501
+ children: children ?? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
502
+ /* @__PURE__ */ jsxRuntime.jsx(AvatarVideo, {}),
503
+ /* @__PURE__ */ jsxRuntime.jsx(UserVideo, {}),
504
+ /* @__PURE__ */ jsxRuntime.jsx(ControlBar, {})
505
+ ] })
506
+ }
507
+ )
335
508
  }
336
- ) });
509
+ );
337
510
  }
338
511
  function ScreenShareVideo({ children, ...props }) {
339
512
  const { localParticipant } = componentsReact.useLocalParticipant();
@@ -359,43 +532,18 @@ function ScreenShareVideo({ children, ...props }) {
359
532
  return /* @__PURE__ */ jsxRuntime.jsx("div", { ...props, "data-sharing": isSharing, children: screenShareTrackRef && componentsReact.isTrackReference(screenShareTrackRef) && /* @__PURE__ */ jsxRuntime.jsx(componentsReact.VideoTrack, { trackRef: screenShareTrackRef }) });
360
533
  }
361
534
 
362
- // src/api/consume.ts
363
- var DEFAULT_BASE_URL = "https://api.runwayml.com/v1";
364
- async function consumeSession(options) {
365
- const { sessionId, baseUrl = DEFAULT_BASE_URL } = options;
366
- const response = await fetch(`${baseUrl}/realtime/sessions/${sessionId}/consume`, {
367
- method: "POST",
368
- headers: {
369
- "Content-Type": "application/json"
370
- }
371
- });
372
- if (!response.ok) {
373
- const errorText = await response.text();
374
- throw new Error(`Failed to consume session: ${response.status} ${errorText}`);
375
- }
376
- const data = await response.json();
377
- return {
378
- sessionId,
379
- livekitUrl: data.url,
380
- token: data.token,
381
- roomName: data.roomName
382
- };
383
- }
384
-
385
535
  Object.defineProperty(exports, "AudioRenderer", {
386
536
  enumerable: true,
387
537
  get: function () { return componentsReact.RoomAudioRenderer; }
388
538
  });
539
+ exports.AvatarCall = AvatarCall;
389
540
  exports.AvatarSession = AvatarSession;
390
541
  exports.AvatarVideo = AvatarVideo;
391
542
  exports.ControlBar = ControlBar;
392
543
  exports.ScreenShareVideo = ScreenShareVideo;
393
544
  exports.UserVideo = UserVideo;
394
- exports.consumeSession = consumeSession;
395
545
  exports.useAvatar = useAvatar;
396
546
  exports.useAvatarSession = useAvatarSession;
397
- exports.useAvatarSessionContext = useAvatarSessionContext;
398
547
  exports.useLocalMedia = useLocalMedia;
399
- exports.useMaybeAvatarSessionContext = useMaybeAvatarSessionContext;
400
548
  //# sourceMappingURL=index.cjs.map
401
549
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/AvatarSession.tsx","../src/hooks/useAvatar.ts","../src/hooks/useAvatarSession.ts","../src/components/AvatarVideo.tsx","../src/hooks/useLocalMedia.ts","../src/components/UserVideo.tsx","../src/components/ControlBar.tsx","../src/components/ScreenShareVideo.tsx","../src/api/consume.ts"],"names":["ConnectionState","createContext","useRef","jsxs","LiveKitRoom","jsx","RoomAudioRenderer","useRoomContext","useConnectionState","useCallback","useContext","useRemoteParticipants","useState","useEffect","ParticipantEvent","useTracks","Track","isTrackReference","Fragment","VideoTrack","useLocalParticipant","useMediaDevices","TrackToggle"],"mappings":"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","file":"index.cjs","sourcesContent":["'use client';\n\n/**\n * AvatarSession Component\n *\n * Provides the session context for avatar interactions.\n * Wraps LiveKit's LiveKitRoom internally while exposing a clean API.\n *\n * @example\n * ```tsx\n * <AvatarSession credentials={credentials} onEnd={handleEnd}>\n * <AvatarVideo />\n * <ControlBar />\n * </AvatarSession>\n * ```\n */\n\nimport {\n createContext,\n useContext,\n useCallback,\n useRef,\n type ReactNode,\n} from 'react';\nimport {\n LiveKitRoom,\n useConnectionState,\n useRoomContext,\n RoomAudioRenderer,\n} from '@livekit/components-react';\nimport { ConnectionState } from 'livekit-client';\nimport type {\n SessionState,\n AvatarSessionContextValue,\n AvatarSessionProps,\n} from '../types';\n\n/**\n * Maps LiveKit connection state to our session state\n */\nfunction mapConnectionState(connectionState: ConnectionState): SessionState {\n switch (connectionState) {\n case ConnectionState.Connecting:\n return 'connecting';\n case ConnectionState.Connected:\n return 'active';\n case ConnectionState.Reconnecting:\n return 'connecting';\n case ConnectionState.Disconnected:\n return 'ended';\n default:\n return 'ended';\n }\n}\n\nconst AvatarSessionContext = createContext<AvatarSessionContextValue | null>(null);\n\n/**\n * AvatarSession component - the main entry point for avatar sessions\n *\n * Renders children within a LiveKit room context and provides session state.\n * This is a headless component that renders minimal DOM.\n */\nexport function AvatarSession({\n credentials,\n children,\n audio = true,\n video = true,\n onEnd,\n onError,\n}: AvatarSessionProps) {\n const errorRef = useRef<Error | null>(null);\n\n const handleError = (error: Error) => {\n errorRef.current = error;\n onError?.(error);\n };\n\n return (\n <LiveKitRoom\n serverUrl={credentials.livekitUrl}\n token={credentials.token}\n connect={true}\n audio={audio}\n video={video}\n onDisconnected={() => onEnd?.()}\n onError={handleError}\n options={{\n adaptiveStream: true,\n dynacast: true,\n }}\n >\n <AvatarSessionContextInner\n sessionId={credentials.sessionId}\n onEnd={onEnd}\n errorRef={errorRef}\n >\n {children}\n </AvatarSessionContextInner>\n <RoomAudioRenderer />\n </LiveKitRoom>\n );\n}\n\n/**\n * Inner context provider that has access to LiveKit room context\n */\nfunction AvatarSessionContextInner({\n sessionId,\n onEnd,\n errorRef,\n children,\n}: {\n sessionId: string;\n onEnd?: () => void;\n errorRef: React.RefObject<Error | null>;\n children: ReactNode;\n}) {\n const room = useRoomContext();\n const connectionState = useConnectionState();\n const onEndRef = useRef(onEnd);\n onEndRef.current = onEnd;\n\n const end = useCallback(async () => {\n try {\n // Send END_CALL message to the avatar\n const encoder = new TextEncoder();\n const data = encoder.encode(JSON.stringify({ type: 'END_CALL' }));\n await room.localParticipant.publishData(data, { reliable: true });\n } catch {\n // Ignore errors when sending end message\n }\n\n await room.disconnect();\n onEndRef.current?.();\n }, [room]);\n\n const contextValue: AvatarSessionContextValue = {\n state: mapConnectionState(connectionState),\n sessionId,\n error: errorRef.current,\n end,\n };\n\n return (\n <AvatarSessionContext.Provider value={contextValue}>\n {children}\n </AvatarSessionContext.Provider>\n );\n}\n\n/**\n * Hook to access the avatar session context\n * Must be used within an AvatarSession component\n */\nexport function useAvatarSessionContext(): AvatarSessionContextValue {\n const context = useContext(AvatarSessionContext);\n if (!context) {\n throw new Error('useAvatarSessionContext must be used within an AvatarSession');\n }\n return context;\n}\n\n/**\n * Hook to optionally access the avatar session context\n * Returns null if not within an AvatarSession\n */\nexport function useMaybeAvatarSessionContext(): AvatarSessionContextValue | null {\n return useContext(AvatarSessionContext);\n}\n","'use client';\n\n/**\n * useAvatar Hook\n *\n * Provides access to the remote avatar participant's video and audio tracks.\n * Uses LiveKit React hooks internally but exposes a clean API.\n *\n * @example\n * ```tsx\n * function AvatarDisplay() {\n * const { videoTrackRef, isSpeaking, hasVideo } = useAvatar();\n *\n * if (!hasVideo) {\n * return <Placeholder />;\n * }\n *\n * return (\n * <div data-speaking={isSpeaking}>\n * <VideoTrack trackRef={videoTrackRef} />\n * </div>\n * );\n * }\n * ```\n */\n\nimport { useState, useEffect } from 'react';\nimport {\n useRemoteParticipants,\n useTracks,\n isTrackReference,\n type TrackReferenceOrPlaceholder,\n} from '@livekit/components-react';\nimport {\n Track,\n ParticipantEvent,\n} from 'livekit-client';\nimport type { UseAvatarReturn } from '../types';\n\n/**\n * Hook to access the remote avatar participant's tracks and state\n *\n * @returns Avatar participant info, track references, and speaking state\n */\nexport function useAvatar(): UseAvatarReturn {\n const remoteParticipants = useRemoteParticipants();\n const avatarParticipant = remoteParticipants[0] ?? null;\n const avatarIdentity = avatarParticipant?.identity ?? null;\n\n const [isSpeaking, setIsSpeaking] = useState(false);\n\n useEffect(() => {\n if (!avatarParticipant) {\n setIsSpeaking(false);\n return;\n }\n\n setIsSpeaking(avatarParticipant.isSpeaking);\n\n const handleIsSpeakingChanged = (speaking: boolean) => {\n setIsSpeaking(speaking);\n };\n\n avatarParticipant.on(ParticipantEvent.IsSpeakingChanged, handleIsSpeakingChanged);\n\n return () => {\n avatarParticipant.off(ParticipantEvent.IsSpeakingChanged, handleIsSpeakingChanged);\n };\n }, [avatarParticipant]);\n\n const tracks = useTracks(\n [\n { source: Track.Source.Camera, withPlaceholder: true },\n { source: Track.Source.Microphone, withPlaceholder: true },\n ],\n { onlySubscribed: true }\n );\n\n let videoTrackRef: TrackReferenceOrPlaceholder | null = null;\n let audioTrackRef: TrackReferenceOrPlaceholder | null = null;\n\n for (const trackRef of tracks) {\n if (trackRef.participant.identity !== avatarIdentity) continue;\n\n if (trackRef.source === Track.Source.Camera && !videoTrackRef) {\n videoTrackRef = trackRef;\n } else if (trackRef.source === Track.Source.Microphone && !audioTrackRef) {\n audioTrackRef = trackRef;\n }\n\n if (videoTrackRef && audioTrackRef) break;\n }\n\n const hasVideo = videoTrackRef !== null && isTrackReference(videoTrackRef);\n const hasAudio = audioTrackRef !== null && isTrackReference(audioTrackRef);\n\n return {\n participant: avatarParticipant,\n videoTrackRef,\n audioTrackRef,\n isSpeaking,\n hasVideo,\n hasAudio,\n };\n}\n","'use client';\n\n/**\n * useAvatarSession Hook\n *\n * Provides access to the current avatar session state.\n * Returns a discriminated union based on session state for type-safe UI rendering.\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const session = useAvatarSession();\n *\n * if (session.state === 'connecting') {\n * return <Loading />;\n * }\n *\n * if (session.state === 'error') {\n * return <Error message={session.error.message} />;\n * }\n *\n * return <ActiveSession onEnd={session.end} />;\n * }\n * ```\n */\n\nimport { useAvatarSessionContext } from '../components/AvatarSession';\nimport type { AvatarSessionContextValue } from '../types';\n\n/**\n * Discriminated union types for type-safe session state handling\n */\nexport type UseAvatarSessionReturn =\n | { state: 'idle'; sessionId: string; error: null; end: () => Promise<void> }\n | { state: 'connecting'; sessionId: string; error: null; end: () => Promise<void> }\n | { state: 'active'; sessionId: string; error: null; end: () => Promise<void> }\n | { state: 'ending'; sessionId: string; error: null; end: () => Promise<void> }\n | { state: 'ended'; sessionId: string; error: null; end: () => Promise<void> }\n | { state: 'error'; sessionId: string; error: Error; end: () => Promise<void> };\n\n/**\n * Hook to access the current avatar session state\n *\n * @returns Session state as a discriminated union\n */\nexport function useAvatarSession(): UseAvatarSessionReturn {\n const context = useAvatarSessionContext();\n return context as UseAvatarSessionReturn;\n}\n\nexport type { AvatarSessionContextValue };\n","'use client';\n\nimport type { ReactNode, ComponentPropsWithoutRef } from 'react';\nimport { VideoTrack, isTrackReference } from '@livekit/components-react';\nimport { useAvatar } from '../hooks/useAvatar';\nimport { useAvatarSession } from '../hooks/useAvatarSession';\nimport type { UseAvatarReturn } from '../types';\n\nexport interface AvatarVideoState {\n hasVideo: boolean;\n isConnecting: boolean;\n isSpeaking: boolean;\n trackRef: UseAvatarReturn['videoTrackRef'];\n}\n\nexport interface AvatarVideoProps extends Omit<ComponentPropsWithoutRef<'div'>, 'children'> {\n children?: (state: AvatarVideoState) => ReactNode;\n}\n\nexport function AvatarVideo({ children, ...props }: AvatarVideoProps) {\n const session = useAvatarSession();\n const { videoTrackRef, isSpeaking, hasVideo } = useAvatar();\n\n const isConnecting = session.state === 'connecting';\n\n const state: AvatarVideoState = {\n hasVideo,\n isConnecting,\n isSpeaking,\n trackRef: videoTrackRef,\n };\n\n if (children) {\n return <>{children(state)}</>;\n }\n\n return (\n <div\n {...props}\n data-has-video={hasVideo}\n data-connecting={isConnecting}\n data-speaking={isSpeaking}\n >\n {hasVideo && videoTrackRef && isTrackReference(videoTrackRef) && (\n <VideoTrack trackRef={videoTrackRef} />\n )}\n </div>\n );\n}\n","'use client';\n\nimport { useCallback, useRef, useEffect } from 'react';\nimport { useLocalParticipant, useMediaDevices, useTracks } from '@livekit/components-react';\nimport { Track } from 'livekit-client';\nimport type { UseLocalMediaReturn } from '../types';\n\nexport function useLocalMedia(): UseLocalMediaReturn {\n const { localParticipant } = useLocalParticipant();\n\n const audioDevices = useMediaDevices({ kind: 'audioinput' });\n const videoDevices = useMediaDevices({ kind: 'videoinput' });\n\n const hasMic = audioDevices.length > 0;\n const hasCamera = videoDevices.length > 0;\n\n const isMicEnabled = localParticipant?.isMicrophoneEnabled ?? false;\n const isCameraEnabled = localParticipant?.isCameraEnabled ?? false;\n const isScreenShareEnabled = localParticipant?.isScreenShareEnabled ?? false;\n\n const isMicEnabledRef = useRef(isMicEnabled);\n const isCameraEnabledRef = useRef(isCameraEnabled);\n const isScreenShareEnabledRef = useRef(isScreenShareEnabled);\n\n useEffect(() => {\n isMicEnabledRef.current = isMicEnabled;\n }, [isMicEnabled]);\n\n useEffect(() => {\n isCameraEnabledRef.current = isCameraEnabled;\n }, [isCameraEnabled]);\n\n useEffect(() => {\n isScreenShareEnabledRef.current = isScreenShareEnabled;\n }, [isScreenShareEnabled]);\n\n const toggleMic = useCallback(() => {\n localParticipant?.setMicrophoneEnabled(!isMicEnabledRef.current);\n }, [localParticipant]);\n\n const toggleCamera = useCallback(() => {\n localParticipant?.setCameraEnabled(!isCameraEnabledRef.current);\n }, [localParticipant]);\n\n const toggleScreenShare = useCallback(() => {\n localParticipant?.setScreenShareEnabled(!isScreenShareEnabledRef.current);\n }, [localParticipant]);\n\n const tracks = useTracks([{ source: Track.Source.Camera, withPlaceholder: true }], {\n onlySubscribed: false,\n });\n\n const localIdentity = localParticipant?.identity;\n\n const localVideoTrackRef =\n tracks.find(\n (trackRef) =>\n trackRef.participant.identity === localIdentity && trackRef.source === Track.Source.Camera\n ) ?? null;\n\n return {\n hasMic,\n hasCamera,\n isMicEnabled,\n isCameraEnabled,\n isScreenShareEnabled,\n toggleMic,\n toggleCamera,\n toggleScreenShare,\n localVideoTrackRef,\n };\n}\n","'use client';\n\nimport type { ReactNode, ComponentPropsWithoutRef } from 'react';\nimport { VideoTrack, isTrackReference } from '@livekit/components-react';\nimport { useLocalMedia } from '../hooks/useLocalMedia';\nimport type { UseLocalMediaReturn } from '../types';\n\nexport interface UserVideoState {\n hasVideo: boolean;\n isCameraEnabled: boolean;\n trackRef: UseLocalMediaReturn['localVideoTrackRef'];\n}\n\nexport interface UserVideoProps extends Omit<ComponentPropsWithoutRef<'div'>, 'children'> {\n mirror?: boolean;\n children?: (state: UserVideoState) => ReactNode;\n}\n\nexport function UserVideo({ children, mirror = true, ...props }: UserVideoProps) {\n const { localVideoTrackRef, isCameraEnabled } = useLocalMedia();\n\n const hasVideo = localVideoTrackRef !== null && isTrackReference(localVideoTrackRef);\n\n const state: UserVideoState = {\n hasVideo,\n isCameraEnabled,\n trackRef: localVideoTrackRef,\n };\n\n if (children) {\n return <>{children(state)}</>;\n }\n\n return (\n <div\n {...props}\n data-has-video={hasVideo}\n data-camera-enabled={isCameraEnabled}\n data-mirror={mirror}\n >\n {hasVideo && localVideoTrackRef && isTrackReference(localVideoTrackRef) && (\n <VideoTrack trackRef={localVideoTrackRef} />\n )}\n </div>\n );\n}\n","'use client';\n\nimport type { ReactNode, ComponentPropsWithoutRef } from 'react';\nimport { TrackToggle } from '@livekit/components-react';\nimport { Track } from 'livekit-client';\nimport { useLocalMedia } from '../hooks/useLocalMedia';\nimport { useAvatarSession } from '../hooks/useAvatarSession';\n\nexport interface ControlBarState {\n isMicEnabled: boolean;\n isCameraEnabled: boolean;\n toggleMic: () => void;\n toggleCamera: () => void;\n endCall: () => Promise<void>;\n isActive: boolean;\n}\n\nexport interface ControlBarProps extends Omit<ComponentPropsWithoutRef<'div'>, 'children'> {\n showMicrophone?: boolean;\n showCamera?: boolean;\n showScreenShare?: boolean;\n showEndCall?: boolean;\n children?: (state: ControlBarState) => ReactNode;\n}\n\nexport function ControlBar({\n children,\n showMicrophone = true,\n showCamera = true,\n showScreenShare = false,\n showEndCall = true,\n ...props\n}: ControlBarProps) {\n const session = useAvatarSession();\n const { isMicEnabled, isCameraEnabled, toggleMic, toggleCamera } = useLocalMedia();\n\n const isActive = session.state === 'active';\n\n const state: ControlBarState = {\n isMicEnabled,\n isCameraEnabled,\n toggleMic,\n toggleCamera,\n endCall: session.end,\n isActive,\n };\n\n if (children) {\n return <>{children(state)}</>;\n }\n\n if (!isActive) {\n return null;\n }\n\n return (\n <div {...props} data-active={isActive}>\n {showMicrophone && (\n <button\n type=\"button\"\n onClick={toggleMic}\n data-control=\"microphone\"\n data-enabled={isMicEnabled}\n aria-label={isMicEnabled ? 'Mute microphone' : 'Unmute microphone'}\n >\n <MicrophoneIcon />\n </button>\n )}\n {showCamera && (\n <button\n type=\"button\"\n onClick={toggleCamera}\n data-control=\"camera\"\n data-enabled={isCameraEnabled}\n aria-label={isCameraEnabled ? 'Turn off camera' : 'Turn on camera'}\n >\n <CameraIcon />\n </button>\n )}\n {showScreenShare && (\n <TrackToggle source={Track.Source.ScreenShare} showIcon={false} data-control=\"screen-share\">\n <ScreenShareIcon />\n </TrackToggle>\n )}\n {showEndCall && (\n <button type=\"button\" onClick={session.end} data-control=\"end-call\" aria-label=\"End call\">\n <span>Leave</span>\n </button>\n )}\n </div>\n );\n}\n\nfunction MicrophoneIcon() {\n return (\n <svg width=\"20\" height=\"20\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" aria-hidden=\"true\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M19 11a7 7 0 01-7 7m0 0a7 7 0 01-7-7m7 7v4m0 0H8m4 0h4m-4-8a3 3 0 01-3-3V5a3 3 0 116 0v6a3 3 0 01-3 3z\"\n />\n </svg>\n );\n}\n\nfunction CameraIcon() {\n return (\n <svg width=\"20\" height=\"20\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" aria-hidden=\"true\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M15 10l4.553-2.276A1 1 0 0121 8.618v6.764a1 1 0 01-1.447.894L15 14M5 18h8a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v8a2 2 0 002 2z\"\n />\n </svg>\n );\n}\n\nfunction ScreenShareIcon() {\n return (\n <svg width=\"20\" height=\"20\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" aria-hidden=\"true\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z\"\n />\n </svg>\n );\n}\n","'use client';\n\nimport type { ReactNode, ComponentPropsWithoutRef } from 'react';\nimport {\n useLocalParticipant,\n useTracks,\n VideoTrack,\n isTrackReference,\n type TrackReferenceOrPlaceholder,\n} from '@livekit/components-react';\nimport { Track } from 'livekit-client';\n\nexport interface ScreenShareVideoState {\n isSharing: boolean;\n trackRef: TrackReferenceOrPlaceholder | null;\n}\n\nexport interface ScreenShareVideoProps extends Omit<ComponentPropsWithoutRef<'div'>, 'children'> {\n children?: (state: ScreenShareVideoState) => ReactNode;\n}\n\nexport function ScreenShareVideo({ children, ...props }: ScreenShareVideoProps) {\n const { localParticipant } = useLocalParticipant();\n\n const tracks = useTracks(\n [{ source: Track.Source.ScreenShare, withPlaceholder: false }],\n { onlySubscribed: false }\n );\n\n const localIdentity = localParticipant?.identity;\n\n const screenShareTrackRef = tracks.find(\n (trackRef) =>\n trackRef.participant.identity === localIdentity &&\n trackRef.source === Track.Source.ScreenShare\n ) ?? null;\n\n const isSharing = screenShareTrackRef !== null && isTrackReference(screenShareTrackRef);\n\n const state: ScreenShareVideoState = {\n isSharing,\n trackRef: screenShareTrackRef,\n };\n\n if (children) {\n return <>{children(state)}</>;\n }\n\n if (!isSharing) {\n return null;\n }\n\n return (\n <div {...props} data-sharing={isSharing}>\n {screenShareTrackRef && isTrackReference(screenShareTrackRef) && (\n <VideoTrack trackRef={screenShareTrackRef} />\n )}\n </div>\n );\n}\n","/**\n * Runway API - Consume Session\n *\n * Client for the Runway /consume endpoint.\n * Retrieves LiveKit credentials for an existing session.\n *\n * @example\n * ```tsx\n * const credentials = await consumeSession({\n * sessionId: 'sess_abc123',\n * });\n *\n * // Use credentials with AvatarSession\n * <AvatarSession credentials={credentials}>\n * ...\n * </AvatarSession>\n * ```\n */\n\nimport type { SessionCredentials, ConsumeSessionOptions } from '../types';\n\nconst DEFAULT_BASE_URL = 'https://api.runwayml.com/v1';\n\n/**\n * Consume a session to get LiveKit credentials\n *\n * This calls the Runway API's /consume endpoint to retrieve\n * the LiveKit connection details for an existing session.\n *\n * @param options - Session ID and optional base URL\n * @returns SessionCredentials for connecting to the avatar\n */\nexport async function consumeSession(\n options: ConsumeSessionOptions\n): Promise<SessionCredentials> {\n const { sessionId, baseUrl = DEFAULT_BASE_URL } = options;\n\n const response = await fetch(`${baseUrl}/realtime/sessions/${sessionId}/consume`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Failed to consume session: ${response.status} ${errorText}`);\n }\n\n const data = await response.json();\n\n return {\n sessionId,\n livekitUrl: data.url,\n token: data.token,\n roomName: data.roomName,\n };\n}\n"]}
1
+ {"version":3,"sources":["../src/hooks/useLatest.ts","../src/components/AvatarSession.tsx","../src/hooks/useAvatar.ts","../src/hooks/useAvatarSession.ts","../src/components/AvatarVideo.tsx","../src/hooks/useLocalMedia.ts","../src/components/ControlBar.tsx","../src/components/UserVideo.tsx","../src/components/AvatarCall.tsx","../src/components/ScreenShareVideo.tsx"],"names":["useRef","useEffect","ConnectionState","createContext","jsxs","LiveKitRoom","jsx","RoomAudioRenderer","useRoomContext","useConnectionState","useCallback","useContext","useRemoteParticipants","useState","ParticipantEvent","useTracks","Track","isTrackReference","Fragment","VideoTrack","useLocalParticipant","useMediaDevices","TrackToggle","error"],"mappings":"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","file":"index.cjs","sourcesContent":["'use client';\n\nimport { useEffect, useRef } from 'react';\n\nexport function useLatest<T>(value: T): React.RefObject<T> {\n const ref = useRef(value);\n\n useEffect(() => {\n ref.current = value;\n }, [value]);\n\n return ref;\n}\n","'use client';\n\n/**\n * AvatarSession Component\n *\n * Provides the session context for avatar interactions.\n * Wraps LiveKit's LiveKitRoom internally while exposing a clean API.\n *\n * @example\n * ```tsx\n * <AvatarSession credentials={credentials} onEnd={handleEnd}>\n * <AvatarVideo />\n * <ControlBar />\n * </AvatarSession>\n * ```\n */\n\nimport {\n LiveKitRoom,\n RoomAudioRenderer,\n useConnectionState,\n useRoomContext,\n} from '@livekit/components-react';\nimport { ConnectionState } from 'livekit-client';\nimport {\n createContext,\n type ReactNode,\n useCallback,\n useContext,\n useRef,\n} from 'react';\nimport type {\n AvatarSessionContextValue,\n AvatarSessionProps,\n SessionState,\n} from '../types';\n\n/**\n * Maps LiveKit connection state to our session state\n */\nfunction mapConnectionState(connectionState: ConnectionState): SessionState {\n switch (connectionState) {\n case ConnectionState.Connecting:\n return 'connecting';\n case ConnectionState.Connected:\n return 'active';\n case ConnectionState.Reconnecting:\n return 'connecting';\n case ConnectionState.Disconnected:\n return 'ended';\n default:\n return 'ended';\n }\n}\n\nconst AvatarSessionContext = createContext<AvatarSessionContextValue | null>(\n null,\n);\n\n/**\n * AvatarSession component - the main entry point for avatar sessions\n *\n * Renders children within a LiveKit room context and provides session state.\n * This is a headless component that renders minimal DOM.\n */\nexport function AvatarSession({\n credentials,\n children,\n audio = true,\n video = true,\n onEnd,\n onError,\n}: AvatarSessionProps) {\n const errorRef = useRef<Error | null>(null);\n\n const handleError = (error: Error) => {\n errorRef.current = error;\n onError?.(error);\n };\n\n return (\n <LiveKitRoom\n serverUrl={credentials.serverUrl}\n token={credentials.token}\n connect={true}\n audio={audio}\n video={video}\n onDisconnected={() => onEnd?.()}\n onError={handleError}\n options={{\n adaptiveStream: true,\n dynacast: true,\n }}\n >\n <AvatarSessionContextInner\n sessionId={credentials.sessionId}\n onEnd={onEnd}\n errorRef={errorRef}\n >\n {children}\n </AvatarSessionContextInner>\n <RoomAudioRenderer />\n </LiveKitRoom>\n );\n}\n\n/**\n * Inner context provider that has access to LiveKit room context\n */\nfunction AvatarSessionContextInner({\n sessionId,\n onEnd,\n errorRef,\n children,\n}: {\n sessionId: string;\n onEnd?: () => void;\n errorRef: React.RefObject<Error | null>;\n children: ReactNode;\n}) {\n const room = useRoomContext();\n const connectionState = useConnectionState();\n const onEndRef = useRef(onEnd);\n onEndRef.current = onEnd;\n\n const end = useCallback(async () => {\n try {\n // Send END_CALL message to the avatar\n const encoder = new TextEncoder();\n const data = encoder.encode(JSON.stringify({ type: 'END_CALL' }));\n await room.localParticipant.publishData(data, { reliable: true });\n } catch {\n // Ignore errors when sending end message\n }\n\n await room.disconnect();\n onEndRef.current?.();\n }, [room]);\n\n const contextValue: AvatarSessionContextValue = {\n state: mapConnectionState(connectionState),\n sessionId,\n error: errorRef.current,\n end,\n };\n\n return (\n <AvatarSessionContext.Provider value={contextValue}>\n {children}\n </AvatarSessionContext.Provider>\n );\n}\n\n/**\n * Hook to access the avatar session context\n * Must be used within an AvatarSession component\n */\nexport function useAvatarSessionContext(): AvatarSessionContextValue {\n const context = useContext(AvatarSessionContext);\n if (!context) {\n throw new Error(\n 'useAvatarSessionContext must be used within an AvatarSession',\n );\n }\n return context;\n}\n\n/**\n * Hook to optionally access the avatar session context\n * Returns null if not within an AvatarSession\n */\nexport function useMaybeAvatarSessionContext(): AvatarSessionContextValue | null {\n return useContext(AvatarSessionContext);\n}\n","'use client';\n\n/**\n * useAvatar Hook\n *\n * Provides access to the remote avatar participant's video and audio tracks.\n * Uses LiveKit React hooks internally but exposes a clean API.\n *\n * @example\n * ```tsx\n * function AvatarDisplay() {\n * const { videoTrackRef, isSpeaking, hasVideo } = useAvatar();\n *\n * if (!hasVideo) {\n * return <Placeholder />;\n * }\n *\n * return (\n * <div data-speaking={isSpeaking}>\n * <VideoTrack trackRef={videoTrackRef} />\n * </div>\n * );\n * }\n * ```\n */\n\nimport {\n isTrackReference,\n type TrackReferenceOrPlaceholder,\n useRemoteParticipants,\n useTracks,\n} from '@livekit/components-react';\nimport { ParticipantEvent, Track } from 'livekit-client';\nimport { useEffect, useState } from 'react';\nimport type { UseAvatarReturn } from '../types';\n\n/**\n * Hook to access the remote avatar participant's tracks and state\n *\n * @returns Avatar participant info, track references, and speaking state\n */\nexport function useAvatar(): UseAvatarReturn {\n const remoteParticipants = useRemoteParticipants();\n const avatarParticipant = remoteParticipants[0] ?? null;\n const avatarIdentity = avatarParticipant?.identity ?? null;\n\n const [isSpeaking, setIsSpeaking] = useState(false);\n\n useEffect(() => {\n if (!avatarParticipant) {\n setIsSpeaking(false);\n return;\n }\n\n setIsSpeaking(avatarParticipant.isSpeaking);\n\n const handleIsSpeakingChanged = (speaking: boolean) => {\n setIsSpeaking(speaking);\n };\n\n avatarParticipant.on(\n ParticipantEvent.IsSpeakingChanged,\n handleIsSpeakingChanged,\n );\n\n return () => {\n avatarParticipant.off(\n ParticipantEvent.IsSpeakingChanged,\n handleIsSpeakingChanged,\n );\n };\n }, [avatarParticipant]);\n\n const tracks = useTracks(\n [\n { source: Track.Source.Camera, withPlaceholder: true },\n { source: Track.Source.Microphone, withPlaceholder: true },\n ],\n { onlySubscribed: true },\n );\n\n let videoTrackRef: TrackReferenceOrPlaceholder | null = null;\n let audioTrackRef: TrackReferenceOrPlaceholder | null = null;\n\n for (const trackRef of tracks) {\n if (trackRef.participant.identity !== avatarIdentity) continue;\n\n if (trackRef.source === Track.Source.Camera && !videoTrackRef) {\n videoTrackRef = trackRef;\n } else if (trackRef.source === Track.Source.Microphone && !audioTrackRef) {\n audioTrackRef = trackRef;\n }\n\n if (videoTrackRef && audioTrackRef) break;\n }\n\n const hasVideo = videoTrackRef !== null && isTrackReference(videoTrackRef);\n const hasAudio = audioTrackRef !== null && isTrackReference(audioTrackRef);\n\n return {\n participant: avatarParticipant,\n videoTrackRef,\n audioTrackRef,\n isSpeaking,\n hasVideo,\n hasAudio,\n };\n}\n","'use client';\n\n/**\n * useAvatarSession Hook\n *\n * Provides access to the current avatar session state.\n * Returns a discriminated union based on session state for type-safe UI rendering.\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const session = useAvatarSession();\n *\n * if (session.state === 'connecting') {\n * return <Loading />;\n * }\n *\n * if (session.state === 'error') {\n * return <Error message={session.error.message} />;\n * }\n *\n * return <ActiveSession onEnd={session.end} />;\n * }\n * ```\n */\n\nimport { useAvatarSessionContext } from '../components/AvatarSession';\nimport type { AvatarSessionContextValue } from '../types';\n\n/**\n * Discriminated union types for type-safe session state handling\n */\nexport type UseAvatarSessionReturn =\n | { state: 'idle'; sessionId: string; error: null; end: () => Promise<void> }\n | { state: 'connecting'; sessionId: string; error: null; end: () => Promise<void> }\n | { state: 'active'; sessionId: string; error: null; end: () => Promise<void> }\n | { state: 'ending'; sessionId: string; error: null; end: () => Promise<void> }\n | { state: 'ended'; sessionId: string; error: null; end: () => Promise<void> }\n | { state: 'error'; sessionId: string; error: Error; end: () => Promise<void> };\n\n/**\n * Hook to access the current avatar session state\n *\n * @returns Session state as a discriminated union\n */\nexport function useAvatarSession(): UseAvatarSessionReturn {\n const context = useAvatarSessionContext();\n return context as UseAvatarSessionReturn;\n}\n\nexport type { AvatarSessionContextValue };\n","'use client';\n\nimport type { ReactNode, ComponentPropsWithoutRef } from 'react';\nimport { VideoTrack, isTrackReference } from '@livekit/components-react';\nimport { useAvatar } from '../hooks/useAvatar';\nimport { useAvatarSession } from '../hooks/useAvatarSession';\nimport type { UseAvatarReturn } from '../types';\n\nexport interface AvatarVideoState {\n hasVideo: boolean;\n isConnecting: boolean;\n isSpeaking: boolean;\n trackRef: UseAvatarReturn['videoTrackRef'];\n}\n\nexport interface AvatarVideoProps extends Omit<ComponentPropsWithoutRef<'div'>, 'children'> {\n children?: (state: AvatarVideoState) => ReactNode;\n}\n\nexport function AvatarVideo({ children, ...props }: AvatarVideoProps) {\n const session = useAvatarSession();\n const { videoTrackRef, isSpeaking, hasVideo } = useAvatar();\n\n const isConnecting = session.state === 'connecting';\n\n const state: AvatarVideoState = {\n hasVideo,\n isConnecting,\n isSpeaking,\n trackRef: videoTrackRef,\n };\n\n if (children) {\n return <>{children(state)}</>;\n }\n\n return (\n <div\n {...props}\n data-has-video={hasVideo}\n data-connecting={isConnecting}\n data-speaking={isSpeaking}\n >\n {hasVideo && videoTrackRef && isTrackReference(videoTrackRef) && (\n <VideoTrack trackRef={videoTrackRef} />\n )}\n </div>\n );\n}\n","'use client';\n\nimport {\n useLocalParticipant,\n useMediaDevices,\n useTracks,\n} from '@livekit/components-react';\nimport { Track } from 'livekit-client';\nimport { useCallback } from 'react';\nimport type { UseLocalMediaReturn } from '../types';\nimport { useLatest } from './useLatest';\n\nexport function useLocalMedia(): UseLocalMediaReturn {\n const { localParticipant } = useLocalParticipant();\n\n const audioDevices = useMediaDevices({ kind: 'audioinput' });\n const videoDevices = useMediaDevices({ kind: 'videoinput' });\n\n const hasMic = audioDevices.length > 0;\n const hasCamera = videoDevices.length > 0;\n\n const isMicEnabled = localParticipant?.isMicrophoneEnabled ?? false;\n const isCameraEnabled = localParticipant?.isCameraEnabled ?? false;\n const isScreenShareEnabled = localParticipant?.isScreenShareEnabled ?? false;\n\n const isMicEnabledRef = useLatest(isMicEnabled);\n const isCameraEnabledRef = useLatest(isCameraEnabled);\n const isScreenShareEnabledRef = useLatest(isScreenShareEnabled);\n\n const toggleMic = useCallback(() => {\n localParticipant?.setMicrophoneEnabled(!isMicEnabledRef.current);\n }, [localParticipant, isMicEnabledRef]);\n\n const toggleCamera = useCallback(() => {\n localParticipant?.setCameraEnabled(!isCameraEnabledRef.current);\n }, [localParticipant, isCameraEnabledRef]);\n\n const toggleScreenShare = useCallback(() => {\n localParticipant?.setScreenShareEnabled(!isScreenShareEnabledRef.current);\n }, [localParticipant, isScreenShareEnabledRef]);\n\n const tracks = useTracks(\n [{ source: Track.Source.Camera, withPlaceholder: true }],\n {\n onlySubscribed: false,\n },\n );\n\n const localIdentity = localParticipant?.identity;\n\n const localVideoTrackRef =\n tracks.find(\n (trackRef) =>\n trackRef.participant.identity === localIdentity &&\n trackRef.source === Track.Source.Camera,\n ) ?? null;\n\n return {\n hasMic,\n hasCamera,\n isMicEnabled,\n isCameraEnabled,\n isScreenShareEnabled,\n toggleMic,\n toggleCamera,\n toggleScreenShare,\n localVideoTrackRef,\n };\n}\n","'use client';\n\nimport { TrackToggle } from '@livekit/components-react';\nimport { Track } from 'livekit-client';\nimport type { ComponentPropsWithoutRef, ReactNode } from 'react';\nimport { useAvatarSession } from '../hooks/useAvatarSession';\nimport { useLocalMedia } from '../hooks/useLocalMedia';\n\nexport interface ControlBarState {\n isMicEnabled: boolean;\n isCameraEnabled: boolean;\n toggleMic: () => void;\n toggleCamera: () => void;\n endCall: () => Promise<void>;\n isActive: boolean;\n}\n\nexport interface ControlBarProps\n extends Omit<ComponentPropsWithoutRef<'div'>, 'children'> {\n showMicrophone?: boolean;\n showCamera?: boolean;\n showScreenShare?: boolean;\n showEndCall?: boolean;\n children?: (state: ControlBarState) => ReactNode;\n}\n\nexport function ControlBar({\n children,\n showMicrophone = true,\n showCamera = true,\n showScreenShare = false,\n showEndCall = true,\n ...props\n}: ControlBarProps) {\n const session = useAvatarSession();\n const { isMicEnabled, isCameraEnabled, toggleMic, toggleCamera } =\n useLocalMedia();\n\n const isActive = session.state === 'active';\n\n const state: ControlBarState = {\n isMicEnabled,\n isCameraEnabled,\n toggleMic,\n toggleCamera,\n endCall: session.end,\n isActive,\n };\n\n if (children) {\n return <>{children(state)}</>;\n }\n\n if (!isActive) {\n return null;\n }\n\n return (\n <div {...props} data-active={isActive}>\n {showMicrophone && (\n <button\n type=\"button\"\n onClick={toggleMic}\n data-control=\"microphone\"\n data-enabled={isMicEnabled}\n aria-label={isMicEnabled ? 'Mute microphone' : 'Unmute microphone'}\n >\n {microphoneIcon}\n </button>\n )}\n {showCamera && (\n <button\n type=\"button\"\n onClick={toggleCamera}\n data-control=\"camera\"\n data-enabled={isCameraEnabled}\n aria-label={isCameraEnabled ? 'Turn off camera' : 'Turn on camera'}\n >\n {cameraIcon}\n </button>\n )}\n {showScreenShare && (\n <TrackToggle\n source={Track.Source.ScreenShare}\n showIcon={false}\n data-control=\"screen-share\"\n aria-label=\"Toggle screen share\"\n >\n {screenShareIcon}\n </TrackToggle>\n )}\n {showEndCall && (\n <button\n type=\"button\"\n onClick={session.end}\n data-control=\"end-call\"\n aria-label=\"End call\"\n >\n {phoneIcon}\n </button>\n )}\n </div>\n );\n}\n\n// Lucide icons (https://lucide.dev) - MIT License\nconst microphoneIcon = (\n <svg\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3Z\" />\n <path d=\"M19 10v2a7 7 0 0 1-14 0v-2\" />\n <line x1=\"12\" x2=\"12\" y1=\"19\" y2=\"22\" />\n </svg>\n);\n\nconst cameraIcon = (\n <svg\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"m16 13 5.223 3.482a.5.5 0 0 0 .777-.416V7.87a.5.5 0 0 0-.752-.432L16 10.5\" />\n <rect x=\"2\" y=\"6\" width=\"14\" height=\"12\" rx=\"2\" />\n </svg>\n);\n\nconst screenShareIcon = (\n <svg\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <rect width=\"20\" height=\"14\" x=\"2\" y=\"3\" rx=\"2\" />\n <line x1=\"8\" x2=\"16\" y1=\"21\" y2=\"21\" />\n <line x1=\"12\" x2=\"12\" y1=\"17\" y2=\"21\" />\n </svg>\n);\n\nconst phoneIcon = (\n <svg\n width=\"20\"\n height=\"20\"\n viewBox=\"8 14 24 12\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path d=\"M12.8429 22.5693L11.4018 21.0986C11.2675 20.9626 11.1625 20.7995 11.0935 20.6197C11.0245 20.4399 10.9931 20.2474 11.0013 20.0545C11.0094 19.8616 11.0569 19.6726 11.1408 19.4995C11.2247 19.3265 11.343 19.1732 11.4883 19.0495C13.127 17.7049 15.0519 16.7714 17.1083 16.3239C19.0064 15.892 20.9744 15.892 22.8725 16.3239C24.9374 16.7743 26.8693 17.7147 28.5117 19.0691C28.6565 19.1924 28.7746 19.3451 28.8585 19.5176C28.9423 19.69 28.99 19.8784 28.9986 20.0707C29.0072 20.263 28.9764 20.455 28.9083 20.6345C28.8402 20.814 28.7362 20.9771 28.603 21.1133L27.1619 22.584C26.9311 22.8242 26.6226 22.9706 26.2938 22.9959C25.9651 23.0211 25.6385 22.9235 25.3751 22.7212C24.8531 22.3127 24.2875 21.9657 23.689 21.6869C23.4525 21.5774 23.2517 21.4009 23.1103 21.1785C22.969 20.9561 22.8931 20.697 22.8917 20.4319V19.1867C21.0053 18.6573 19.0139 18.6573 17.1275 19.1867V20.4319C17.1261 20.697 17.0502 20.9561 16.9089 21.1785C16.7676 21.4009 16.5667 21.5774 16.3302 21.6869C15.7317 21.9657 15.1661 22.3127 14.6442 22.7212C14.3779 22.9258 14.0473 23.0233 13.7152 22.9953C13.383 22.9673 13.0726 22.8156 12.8429 22.5693Z\" />\n </svg>\n);\n","'use client';\n\nimport type { ReactNode, ComponentPropsWithoutRef } from 'react';\nimport { VideoTrack, isTrackReference } from '@livekit/components-react';\nimport { useLocalMedia } from '../hooks/useLocalMedia';\nimport type { UseLocalMediaReturn } from '../types';\n\nexport interface UserVideoState {\n hasVideo: boolean;\n isCameraEnabled: boolean;\n trackRef: UseLocalMediaReturn['localVideoTrackRef'];\n}\n\nexport interface UserVideoProps extends Omit<ComponentPropsWithoutRef<'div'>, 'children'> {\n mirror?: boolean;\n children?: (state: UserVideoState) => ReactNode;\n}\n\nexport function UserVideo({ children, mirror = true, ...props }: UserVideoProps) {\n const { localVideoTrackRef, isCameraEnabled } = useLocalMedia();\n\n const hasVideo = localVideoTrackRef !== null && isTrackReference(localVideoTrackRef);\n\n const state: UserVideoState = {\n hasVideo,\n isCameraEnabled,\n trackRef: localVideoTrackRef,\n };\n\n if (children) {\n return <>{children(state)}</>;\n }\n\n return (\n <div\n {...props}\n data-has-video={hasVideo}\n data-camera-enabled={isCameraEnabled}\n data-mirror={mirror}\n >\n {hasVideo && localVideoTrackRef && isTrackReference(localVideoTrackRef) && (\n <VideoTrack trackRef={localVideoTrackRef} />\n )}\n </div>\n );\n}\n","'use client';\n\nimport { useEffect, useRef, useState } from 'react';\nimport { useLatest } from '../hooks/useLatest';\nimport type { AvatarCallProps, SessionCredentials } from '../types';\nimport { AvatarSession } from './AvatarSession';\nimport { AvatarVideo } from './AvatarVideo';\nimport { ControlBar } from './ControlBar';\nimport { UserVideo } from './UserVideo';\n\ntype ConnectionState = 'idle' | 'connecting' | 'connected' | 'error';\n\nexport function AvatarCall({\n avatarId,\n connectUrl,\n connect,\n avatarImageUrl,\n onEnd,\n onError,\n children,\n ...props\n}: AvatarCallProps) {\n const [credentials, setCredentials] = useState<SessionCredentials | null>(\n null,\n );\n const [connectionState, setConnectionState] =\n useState<ConnectionState>('idle');\n const [error, setError] = useState<Error | null>(null);\n const fetchedForRef = useRef<string | null>(null);\n const connectRef = useLatest(connect);\n const onErrorRef = useLatest(onError);\n\n useEffect(() => {\n if (fetchedForRef.current === avatarId) return;\n fetchedForRef.current = avatarId;\n\n async function fetchCredentials() {\n setConnectionState('connecting');\n setError(null);\n setCredentials(null);\n\n try {\n let creds: SessionCredentials;\n\n if (connectRef.current) {\n creds = await connectRef.current(avatarId);\n } else if (connectUrl) {\n const response = await fetch(connectUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ avatarId }),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(\n `Failed to connect: ${response.status} ${errorText}`,\n );\n }\n\n creds = await response.json();\n } else {\n throw new Error(\n 'AvatarCall requires either connectUrl or connect prop',\n );\n }\n\n setCredentials(creds);\n setConnectionState('connected');\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n setConnectionState('error');\n onErrorRef.current?.(error);\n }\n }\n\n fetchCredentials();\n }, [avatarId, connectUrl, connectRef, onErrorRef]);\n\n const handleError = (err: Error) => {\n setError(err);\n setConnectionState('error');\n onErrorRef.current?.(err);\n };\n\n const backgroundStyle = avatarImageUrl\n ? { '--avatar-image': `url(${avatarImageUrl})` } as React.CSSProperties\n : undefined;\n\n if (connectionState === 'idle' || connectionState === 'connecting') {\n return (\n <div\n {...props}\n data-avatar-call=\"\"\n data-state=\"connecting\"\n data-avatar-id={avatarId}\n style={{ ...props.style, ...backgroundStyle }}\n />\n );\n }\n\n if (connectionState === 'error' || !credentials) {\n return (\n <div\n {...props}\n data-avatar-call=\"\"\n data-state=\"error\"\n data-avatar-id={avatarId}\n data-error={error?.message}\n style={{ ...props.style, ...backgroundStyle }}\n />\n );\n }\n\n return (\n <div\n {...props}\n data-avatar-call=\"\"\n data-state=\"connected\"\n data-avatar-id={avatarId}\n style={{ ...props.style, ...backgroundStyle }}\n >\n <AvatarSession\n credentials={credentials}\n onEnd={onEnd}\n onError={handleError}\n >\n {children ?? (\n <>\n <AvatarVideo />\n <UserVideo />\n <ControlBar />\n </>\n )}\n </AvatarSession>\n </div>\n );\n}\n","'use client';\n\nimport type { ReactNode, ComponentPropsWithoutRef } from 'react';\nimport {\n useLocalParticipant,\n useTracks,\n VideoTrack,\n isTrackReference,\n type TrackReferenceOrPlaceholder,\n} from '@livekit/components-react';\nimport { Track } from 'livekit-client';\n\nexport interface ScreenShareVideoState {\n isSharing: boolean;\n trackRef: TrackReferenceOrPlaceholder | null;\n}\n\nexport interface ScreenShareVideoProps extends Omit<ComponentPropsWithoutRef<'div'>, 'children'> {\n children?: (state: ScreenShareVideoState) => ReactNode;\n}\n\nexport function ScreenShareVideo({ children, ...props }: ScreenShareVideoProps) {\n const { localParticipant } = useLocalParticipant();\n\n const tracks = useTracks(\n [{ source: Track.Source.ScreenShare, withPlaceholder: false }],\n { onlySubscribed: false }\n );\n\n const localIdentity = localParticipant?.identity;\n\n const screenShareTrackRef = tracks.find(\n (trackRef) =>\n trackRef.participant.identity === localIdentity &&\n trackRef.source === Track.Source.ScreenShare\n ) ?? null;\n\n const isSharing = screenShareTrackRef !== null && isTrackReference(screenShareTrackRef);\n\n const state: ScreenShareVideoState = {\n isSharing,\n trackRef: screenShareTrackRef,\n };\n\n if (children) {\n return <>{children(state)}</>;\n }\n\n if (!isSharing) {\n return null;\n }\n\n return (\n <div {...props} data-sharing={isSharing}>\n {screenShareTrackRef && isTrackReference(screenShareTrackRef) && (\n <VideoTrack trackRef={screenShareTrackRef} />\n )}\n </div>\n );\n}\n"]}