@runwayml/avatars-react 0.2.2 → 0.4.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.js CHANGED
@@ -1,30 +1,15 @@
1
1
  import { LiveKitRoom, RoomAudioRenderer, useRoomContext, useConnectionState, useRemoteParticipants, useTracks, isTrackReference, VideoTrack, useLocalParticipant, useMediaDevices, TrackToggle } from '@livekit/components-react';
2
- export { RoomAudioRenderer as AudioRenderer } from '@livekit/components-react';
3
- import { createContext, useRef, useCallback, useContext, useEffect, useReducer } from 'react';
2
+ export { RoomAudioRenderer as AudioRenderer, VideoTrack } from '@livekit/components-react';
3
+ import { createContext, useRef, useCallback, useContext, useEffect } from 'react';
4
4
  import { Track, ConnectionState } from 'livekit-client';
5
5
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
6
6
 
7
7
  // src/api/config.ts
8
8
  var DEFAULT_BASE_URL = "https://api.dev.runwayml.com";
9
- function getBaseUrl() {
10
- try {
11
- const envUrl = process.env.RUNWAYML_BASE_URL;
12
- if (envUrl) return envUrl;
13
- } catch {
14
- }
15
- return DEFAULT_BASE_URL;
16
- }
17
- var config = null;
18
- function getConfig() {
19
- if (!config) {
20
- config = { baseUrl: getBaseUrl() };
21
- }
22
- return config;
23
- }
24
9
 
25
10
  // src/api/consume.ts
26
11
  async function consumeSession(options) {
27
- const { sessionId, sessionKey, baseUrl = getConfig().baseUrl } = options;
12
+ const { sessionId, sessionKey, baseUrl = DEFAULT_BASE_URL } = options;
28
13
  const url = `${baseUrl}/v1/realtime_sessions/${sessionId}/consume`;
29
14
  const response = await fetch(url, {
30
15
  method: "POST",
@@ -42,92 +27,88 @@ async function consumeSession(options) {
42
27
  return response.json();
43
28
  }
44
29
 
30
+ // src/utils/suspense-resource.ts
31
+ function createSuspenseResource(promise) {
32
+ let status = "pending";
33
+ let result;
34
+ let error;
35
+ const suspender = promise.then(
36
+ (value) => {
37
+ status = "fulfilled";
38
+ result = value;
39
+ },
40
+ (err) => {
41
+ status = "rejected";
42
+ error = err;
43
+ }
44
+ );
45
+ return {
46
+ read() {
47
+ switch (status) {
48
+ case "pending":
49
+ throw suspender;
50
+ case "rejected":
51
+ throw error;
52
+ case "fulfilled":
53
+ return result;
54
+ }
55
+ }
56
+ };
57
+ }
58
+
45
59
  // src/hooks/useCredentials.ts
46
- function credentialsReducer(_state, action) {
47
- switch (action.type) {
48
- case "CONNECT":
49
- return { status: "connecting", credentials: null, error: null };
50
- case "CONNECTED":
51
- return {
52
- status: "connected",
53
- credentials: action.credentials,
54
- error: null
55
- };
56
- case "ERROR":
57
- return { status: "error", credentials: null, error: action.error };
60
+ var resourceCache = /* @__PURE__ */ new Map();
61
+ function computeKey(options) {
62
+ if (options.credentials) return `direct:${options.credentials.sessionId}`;
63
+ if (options.sessionId && options.sessionKey)
64
+ return `session:${options.sessionId}`;
65
+ return `connect:${options.avatarId}:${options.connectUrl ?? "custom"}`;
66
+ }
67
+ async function fetchCredentials(options) {
68
+ const { avatarId, sessionId, sessionKey, connectUrl, connect, baseUrl } = options;
69
+ if (sessionId && sessionKey) {
70
+ const { url, token, roomName } = await consumeSession({
71
+ sessionId,
72
+ sessionKey,
73
+ baseUrl
74
+ });
75
+ return { sessionId, serverUrl: url, token, roomName };
58
76
  }
77
+ if (connect) {
78
+ return connect(avatarId);
79
+ }
80
+ if (connectUrl) {
81
+ const response = await fetch(connectUrl, {
82
+ method: "POST",
83
+ headers: { "Content-Type": "application/json" },
84
+ body: JSON.stringify({ avatarId })
85
+ });
86
+ if (!response.ok) {
87
+ const errorText = await response.text();
88
+ throw new Error(`Failed to connect: ${response.status} ${errorText}`);
89
+ }
90
+ return response.json();
91
+ }
92
+ throw new Error(
93
+ "AvatarCall requires one of: credentials, sessionId+sessionKey, connectUrl, or connect"
94
+ );
59
95
  }
60
96
  function useCredentials(options) {
61
- const {
62
- avatarId,
63
- sessionId,
64
- sessionKey,
65
- credentials: directCredentials,
66
- connectUrl,
67
- connect,
68
- onError
69
- } = options;
70
- const [state, dispatch] = useReducer(credentialsReducer, {
71
- status: "idle",
72
- credentials: null,
73
- error: null
74
- });
75
- const fetchedForRef = useRef(null);
76
- const onErrorRef = useRef(onError);
77
- onErrorRef.current = onError;
78
- const mode = directCredentials ? "direct" : sessionId && sessionKey ? "session" : connectUrl || connect ? "connect" : null;
79
- useEffect(() => {
80
- if (mode !== "direct" || !directCredentials) return;
81
- dispatch({ type: "CONNECTED", credentials: directCredentials });
82
- }, [mode, directCredentials]);
97
+ const key = computeKey(options);
83
98
  useEffect(() => {
84
- if (mode !== "session" || !sessionId || !sessionKey) return;
85
- if (fetchedForRef.current === sessionId) return;
86
- fetchedForRef.current = sessionId;
87
- dispatch({ type: "CONNECT" });
88
- consumeSession({ sessionId, sessionKey }).then(({ url, token, roomName }) => {
89
- dispatch({
90
- type: "CONNECTED",
91
- credentials: { sessionId, serverUrl: url, token, roomName }
92
- });
93
- }).catch((err) => {
94
- const error = err instanceof Error ? err : new Error(String(err));
95
- dispatch({ type: "ERROR", error });
96
- onErrorRef.current?.(error);
97
- });
98
- }, [mode, sessionId, sessionKey]);
99
- useEffect(() => {
100
- if (mode !== "connect") return;
101
- if (fetchedForRef.current === avatarId) return;
102
- fetchedForRef.current = avatarId;
103
- dispatch({ type: "CONNECT" });
104
- async function fetchCredentials() {
105
- if (connect) {
106
- return connect(avatarId);
107
- }
108
- if (connectUrl) {
109
- const response = await fetch(connectUrl, {
110
- method: "POST",
111
- headers: { "Content-Type": "application/json" },
112
- body: JSON.stringify({ avatarId })
113
- });
114
- if (!response.ok) {
115
- const errorText = await response.text();
116
- throw new Error(`Failed to connect: ${response.status} ${errorText}`);
117
- }
118
- return response.json();
119
- }
120
- throw new Error("No connect method available");
121
- }
122
- fetchCredentials().then((credentials) => {
123
- dispatch({ type: "CONNECTED", credentials });
124
- }).catch((err) => {
125
- const error = err instanceof Error ? err : new Error(String(err));
126
- dispatch({ type: "ERROR", error });
127
- onErrorRef.current?.(error);
128
- });
129
- }, [mode, avatarId, connectUrl, connect]);
130
- return state;
99
+ return () => {
100
+ resourceCache.delete(key);
101
+ };
102
+ }, [key]);
103
+ if (options.credentials) {
104
+ return options.credentials;
105
+ }
106
+ let resource = resourceCache.get(key);
107
+ if (!resource) {
108
+ resource = createSuspenseResource(fetchCredentials(options));
109
+ resourceCache.set(key, resource);
110
+ }
111
+ return resource.read();
131
112
  }
132
113
  function useLatest(value) {
133
114
  const ref = useRef(value);
@@ -262,19 +243,35 @@ function useAvatarSession() {
262
243
  const context = useAvatarSessionContext();
263
244
  return context;
264
245
  }
265
- function AvatarVideo({ children, ...props }) {
246
+
247
+ // src/hooks/useAvatarStatus.ts
248
+ function useAvatarStatus() {
266
249
  const session = useAvatarSession();
267
250
  const { videoTrackRef, hasVideo } = useAvatar();
268
- const isConnecting = session.state === "connecting";
269
- const state = {
270
- hasVideo,
271
- isConnecting,
272
- trackRef: videoTrackRef
273
- };
251
+ switch (session.state) {
252
+ case "connecting":
253
+ case "idle":
254
+ return { status: "connecting" };
255
+ case "active":
256
+ if (hasVideo && videoTrackRef) {
257
+ return { status: "ready", videoTrackRef };
258
+ }
259
+ return { status: "waiting" };
260
+ case "ending":
261
+ return { status: "ending" };
262
+ case "ended":
263
+ return { status: "ended" };
264
+ case "error":
265
+ return { status: "error", error: session.error };
266
+ }
267
+ }
268
+ function AvatarVideo({ children, ...props }) {
269
+ const avatar = useAvatarStatus();
270
+ const videoStatus = avatar.status === "ready" ? avatar : avatar.status === "connecting" ? { status: "connecting" } : { status: "waiting" };
274
271
  if (children) {
275
- return /* @__PURE__ */ jsx(Fragment, { children: children(state) });
272
+ return /* @__PURE__ */ jsx(Fragment, { children: children(videoStatus) });
276
273
  }
277
- return /* @__PURE__ */ jsx("div", { ...props, "data-has-video": hasVideo, "data-connecting": isConnecting, children: hasVideo && videoTrackRef && isTrackReference(videoTrackRef) && /* @__PURE__ */ jsx(VideoTrack, { trackRef: videoTrackRef }) });
274
+ return /* @__PURE__ */ jsx("div", { ...props, "data-avatar-video": "", "data-status": videoStatus.status, children: videoStatus.status === "ready" && isTrackReference(videoStatus.videoTrackRef) && /* @__PURE__ */ jsx(VideoTrack, { trackRef: videoStatus.videoTrackRef }) });
278
275
  }
279
276
  function useLocalMedia() {
280
277
  const { localParticipant } = useLocalParticipant();
@@ -486,6 +483,7 @@ function AvatarCall({
486
483
  credentials: directCredentials,
487
484
  connectUrl,
488
485
  connect,
486
+ baseUrl,
489
487
  avatarImageUrl,
490
488
  onEnd,
491
489
  onError,
@@ -494,50 +492,24 @@ function AvatarCall({
494
492
  ...props
495
493
  }) {
496
494
  const onErrorRef = useLatest(onError);
497
- const { status, credentials, error } = useCredentials({
495
+ const credentials = useCredentials({
498
496
  avatarId,
499
497
  sessionId,
500
498
  sessionKey,
501
499
  credentials: directCredentials,
502
500
  connectUrl,
503
501
  connect,
504
- onError
502
+ baseUrl
505
503
  });
506
504
  const handleSessionError = (err) => {
507
505
  onErrorRef.current?.(err);
508
506
  };
509
507
  const backgroundStyle = avatarImageUrl ? { "--avatar-image": `url(${avatarImageUrl})` } : void 0;
510
- if (status === "idle" || status === "connecting") {
511
- return /* @__PURE__ */ jsx(
512
- "div",
513
- {
514
- ...props,
515
- "data-avatar-call": "",
516
- "data-state": "connecting",
517
- "data-avatar-id": avatarId,
518
- style: { ...props.style, ...backgroundStyle }
519
- }
520
- );
521
- }
522
- if (status === "error" || !credentials) {
523
- return /* @__PURE__ */ jsx(
524
- "div",
525
- {
526
- ...props,
527
- "data-avatar-call": "",
528
- "data-state": "error",
529
- "data-avatar-id": avatarId,
530
- "data-error": error?.message,
531
- style: { ...props.style, ...backgroundStyle }
532
- }
533
- );
534
- }
535
508
  return /* @__PURE__ */ jsx(
536
509
  "div",
537
510
  {
538
511
  ...props,
539
512
  "data-avatar-call": "",
540
- "data-state": "connected",
541
513
  "data-avatar-id": avatarId,
542
514
  style: { ...props.style, ...backgroundStyle },
543
515
  children: /* @__PURE__ */ jsx(
@@ -581,6 +553,6 @@ function ScreenShareVideo({ children, ...props }) {
581
553
  return /* @__PURE__ */ jsx("div", { ...props, "data-sharing": isSharing, children: screenShareTrackRef && isTrackReference(screenShareTrackRef) && /* @__PURE__ */ jsx(VideoTrack, { trackRef: screenShareTrackRef }) });
582
554
  }
583
555
 
584
- export { AvatarCall, AvatarSession, AvatarVideo, ControlBar, ScreenShareVideo, UserVideo, useAvatar, useAvatarSession, useLocalMedia };
556
+ export { AvatarCall, AvatarSession, AvatarVideo, ControlBar, ScreenShareVideo, UserVideo, useAvatar, useAvatarSession, useAvatarStatus, useLocalMedia };
585
557
  //# sourceMappingURL=index.js.map
586
558
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/api/config.ts","../src/api/consume.ts","../src/hooks/useCredentials.ts","../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","RoomAudioRenderer","jsx","isTrackReference","useCallback","useTracks","Track","Fragment","jsxs","VideoTrack","useLocalParticipant"],"mappings":"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","file":"index.js","sourcesContent":["export interface ApiConfig {\n baseUrl: string;\n}\n\nconst DEFAULT_BASE_URL = 'https://api.dev.runwayml.com';\n\nfunction getBaseUrl(): string {\n try {\n const envUrl = process.env.RUNWAYML_BASE_URL;\n if (envUrl) return envUrl;\n } catch {\n // process not available in browser\n }\n return DEFAULT_BASE_URL;\n}\n\nlet config: ApiConfig | null = null;\n\nexport function configure(options: Partial<ApiConfig>): void {\n config = { ...getConfig(), ...options };\n}\n\nexport function getConfig(): ApiConfig {\n if (!config) {\n config = { baseUrl: getBaseUrl() };\n }\n return config;\n}\n\nexport function resetConfig(): void {\n config = null;\n}\n","import type { ConsumeSessionOptions, ConsumeSessionResponse } from '../types';\nimport { getConfig } from './config';\n\nexport async function consumeSession(\n options: ConsumeSessionOptions,\n): Promise<ConsumeSessionResponse> {\n const { sessionId, sessionKey, baseUrl = getConfig().baseUrl } = options;\n\n const url = `${baseUrl}/v1/realtime_sessions/${sessionId}/consume`;\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${sessionKey}`,\n },\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(\n `Failed to consume session: ${response.status} ${errorText}`,\n );\n }\n\n return response.json();\n}\n","'use client';\n\nimport { useEffect, useReducer, useRef } from 'react';\nimport { consumeSession } from '../api/consume';\nimport type { SessionCredentials } from '../types';\n\ninterface CredentialsState {\n status: 'idle' | 'connecting' | 'connected' | 'error';\n credentials: SessionCredentials | null;\n error: Error | null;\n}\n\ntype CredentialsAction =\n | { type: 'CONNECT' }\n | { type: 'CONNECTED'; credentials: SessionCredentials }\n | { type: 'ERROR'; error: Error };\n\nfunction credentialsReducer(\n _state: CredentialsState,\n action: CredentialsAction,\n): CredentialsState {\n switch (action.type) {\n case 'CONNECT':\n return { status: 'connecting', credentials: null, error: null };\n case 'CONNECTED':\n return {\n status: 'connected',\n credentials: action.credentials,\n error: null,\n };\n case 'ERROR':\n return { status: 'error', credentials: null, error: action.error };\n }\n}\n\nexport interface UseCredentialsOptions {\n avatarId: string;\n sessionId?: string;\n sessionKey?: string;\n credentials?: SessionCredentials;\n connectUrl?: string;\n connect?: (avatarId: string) => Promise<SessionCredentials>;\n onError?: (error: Error) => void;\n}\n\nexport function useCredentials(\n options: UseCredentialsOptions,\n): CredentialsState {\n const {\n avatarId,\n sessionId,\n sessionKey,\n credentials: directCredentials,\n connectUrl,\n connect,\n onError,\n } = options;\n\n const [state, dispatch] = useReducer(credentialsReducer, {\n status: 'idle',\n credentials: null,\n error: null,\n });\n\n const fetchedForRef = useRef<string | null>(null);\n const onErrorRef = useRef(onError);\n onErrorRef.current = onError;\n\n const mode = directCredentials\n ? 'direct'\n : sessionId && sessionKey\n ? 'session'\n : connectUrl || connect\n ? 'connect'\n : null;\n\n useEffect(() => {\n if (mode !== 'direct' || !directCredentials) return;\n dispatch({ type: 'CONNECTED', credentials: directCredentials });\n }, [mode, directCredentials]);\n\n useEffect(() => {\n if (mode !== 'session' || !sessionId || !sessionKey) return;\n if (fetchedForRef.current === sessionId) return;\n fetchedForRef.current = sessionId;\n\n dispatch({ type: 'CONNECT' });\n\n consumeSession({ sessionId, sessionKey })\n .then(({ url, token, roomName }) => {\n dispatch({\n type: 'CONNECTED',\n credentials: { sessionId, serverUrl: url, token, roomName },\n });\n })\n .catch((err) => {\n const error = err instanceof Error ? err : new Error(String(err));\n dispatch({ type: 'ERROR', error });\n onErrorRef.current?.(error);\n });\n }, [mode, sessionId, sessionKey]);\n\n useEffect(() => {\n if (mode !== 'connect') return;\n if (fetchedForRef.current === avatarId) return;\n fetchedForRef.current = avatarId;\n\n dispatch({ type: 'CONNECT' });\n\n async function fetchCredentials(): Promise<SessionCredentials> {\n if (connect) {\n return connect(avatarId);\n }\n\n 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(`Failed to connect: ${response.status} ${errorText}`);\n }\n\n return response.json();\n }\n\n throw new Error('No connect method available');\n }\n\n fetchCredentials()\n .then((credentials) => {\n dispatch({ type: 'CONNECTED', credentials });\n })\n .catch((err) => {\n const error = err instanceof Error ? err : new Error(String(err));\n dispatch({ type: 'ERROR', error });\n onErrorRef.current?.(error);\n });\n }, [mode, avatarId, connectUrl, connect]);\n\n return state;\n}\n","'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 * Manages the WebRTC connection and exposes a clean API for child components.\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 type { RoomOptions } from 'livekit-client';\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\nconst DEFAULT_ROOM_OPTIONS: RoomOptions = {\n adaptiveStream: false,\n dynacast: false,\n};\n\n/**\n * Maps WebRTC connection state to 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 * Establishes a WebRTC connection and provides session state to children.\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 __unstable_roomOptions,\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 const roomOptions = {\n ...DEFAULT_ROOM_OPTIONS,\n ...__unstable_roomOptions,\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={roomOptions}\n connectOptions={{\n autoSubscribe: 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 the 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 track.\n * Audio is handled automatically by the session.\n *\n * @example\n * ```tsx\n * function AvatarDisplay() {\n * const { videoTrackRef, hasVideo } = useAvatar();\n *\n * if (!hasVideo) {\n * return <Placeholder />;\n * }\n *\n * return <VideoTrack trackRef={videoTrackRef} />;\n * }\n * ```\n */\n\nimport {\n isTrackReference,\n useRemoteParticipants,\n useTracks,\n} from '@livekit/components-react';\nimport { Track } from 'livekit-client';\nimport type { UseAvatarReturn } from '../types';\n\n/**\n * Hook to access the remote avatar participant's video track\n *\n * @returns Avatar participant info and video track reference\n */\nexport function useAvatar(): UseAvatarReturn {\n const remoteParticipants = useRemoteParticipants();\n const avatarParticipant = remoteParticipants[0] ?? null;\n\n // Only subscribe to video - audio is handled automatically by the session\n const videoTracks = useTracks(\n [{ source: Track.Source.Camera, withPlaceholder: true }],\n { onlySubscribed: true, updateOnlyOn: [] },\n ).filter((ref) => !ref.participant.isLocal);\n\n const videoTrackRef = videoTracks[0] ?? null;\n const hasVideo = videoTrackRef !== null && isTrackReference(videoTrackRef);\n\n return {\n participant: avatarParticipant,\n videoTrackRef,\n hasVideo,\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 { isTrackReference, VideoTrack } from '@livekit/components-react';\nimport type { ComponentPropsWithoutRef, ReactNode } from '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 trackRef: UseAvatarReturn['videoTrackRef'];\n}\n\nexport interface AvatarVideoProps\n 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, hasVideo } = useAvatar();\n\n const isConnecting = session.state === 'connecting';\n\n const state: AvatarVideoState = {\n hasVideo,\n isConnecting,\n trackRef: videoTrackRef,\n };\n\n if (children) {\n return <>{children(state)}</>;\n }\n\n return (\n <div {...props} data-has-video={hasVideo} data-connecting={isConnecting}>\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 updateOnlyOn: [],\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 { useCredentials } from '../hooks/useCredentials';\nimport { useLatest } from '../hooks/useLatest';\nimport type { AvatarCallProps } from '../types';\nimport { AvatarSession } from './AvatarSession';\nimport { AvatarVideo } from './AvatarVideo';\nimport { ControlBar } from './ControlBar';\nimport { UserVideo } from './UserVideo';\n\nexport function AvatarCall({\n avatarId,\n sessionId,\n sessionKey,\n credentials: directCredentials,\n connectUrl,\n connect,\n avatarImageUrl,\n onEnd,\n onError,\n children,\n __unstable_roomOptions,\n ...props\n}: AvatarCallProps) {\n const onErrorRef = useLatest(onError);\n\n const { status, credentials, error } = useCredentials({\n avatarId,\n sessionId,\n sessionKey,\n credentials: directCredentials,\n connectUrl,\n connect,\n onError,\n });\n\n const handleSessionError = (err: Error) => {\n onErrorRef.current?.(err);\n };\n\n const backgroundStyle = avatarImageUrl\n ? ({ '--avatar-image': `url(${avatarImageUrl})` } as React.CSSProperties)\n : undefined;\n\n if (status === 'idle' || status === '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 (status === '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={handleSessionError}\n __unstable_roomOptions={__unstable_roomOptions}\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"]}
1
+ {"version":3,"sources":["../src/api/config.ts","../src/api/consume.ts","../src/utils/suspense-resource.ts","../src/hooks/useCredentials.ts","../src/hooks/useLatest.ts","../src/components/AvatarSession.tsx","../src/hooks/useAvatar.ts","../src/hooks/useAvatarSession.ts","../src/hooks/useAvatarStatus.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":["useEffect","useRef","RoomAudioRenderer","jsx","isTrackReference","useCallback","useTracks","Track","Fragment","jsxs","VideoTrack","useLocalParticipant"],"mappings":"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","file":"index.js","sourcesContent":["export const DEFAULT_BASE_URL = 'https://api.dev.runwayml.com';\n","import type { ConsumeSessionOptions, ConsumeSessionResponse } from '../types';\nimport { DEFAULT_BASE_URL } from './config';\n\nexport async function consumeSession(\n options: ConsumeSessionOptions,\n): Promise<ConsumeSessionResponse> {\n const { sessionId, sessionKey, baseUrl = DEFAULT_BASE_URL } = options;\n\n const url = `${baseUrl}/v1/realtime_sessions/${sessionId}/consume`;\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${sessionKey}`,\n },\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(\n `Failed to consume session: ${response.status} ${errorText}`,\n );\n }\n\n return response.json();\n}\n","export interface SuspenseResource<T> {\n read(): T;\n}\n\nexport function createSuspenseResource<T>(\n promise: Promise<T>,\n): SuspenseResource<T> {\n let status: 'pending' | 'fulfilled' | 'rejected' = 'pending';\n let result: T;\n let error: unknown;\n\n const suspender = promise.then(\n (value) => {\n status = 'fulfilled';\n result = value;\n },\n (err) => {\n status = 'rejected';\n error = err;\n },\n );\n\n return {\n read() {\n switch (status) {\n case 'pending':\n throw suspender;\n case 'rejected':\n throw error;\n case 'fulfilled':\n return result;\n }\n },\n };\n}\n","'use client';\n\nimport { useEffect } from 'react';\nimport { consumeSession } from '../api/consume';\nimport type { SessionCredentials } from '../types';\nimport {\n createSuspenseResource,\n type SuspenseResource,\n} from '../utils/suspense-resource';\n\nexport interface UseCredentialsOptions {\n avatarId: string;\n sessionId?: string;\n sessionKey?: string;\n credentials?: SessionCredentials;\n connectUrl?: string;\n connect?: (avatarId: string) => Promise<SessionCredentials>;\n baseUrl?: string;\n}\n\nconst resourceCache = new Map<string, SuspenseResource<SessionCredentials>>();\n\nfunction computeKey(options: UseCredentialsOptions): string {\n if (options.credentials) return `direct:${options.credentials.sessionId}`;\n if (options.sessionId && options.sessionKey)\n return `session:${options.sessionId}`;\n return `connect:${options.avatarId}:${options.connectUrl ?? 'custom'}`;\n}\n\nasync function fetchCredentials(\n options: UseCredentialsOptions,\n): Promise<SessionCredentials> {\n const { avatarId, sessionId, sessionKey, connectUrl, connect, baseUrl } =\n options;\n\n if (sessionId && sessionKey) {\n const { url, token, roomName } = await consumeSession({\n sessionId,\n sessionKey,\n baseUrl,\n });\n return { sessionId, serverUrl: url, token, roomName };\n }\n\n if (connect) {\n return connect(avatarId);\n }\n\n 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(`Failed to connect: ${response.status} ${errorText}`);\n }\n\n return response.json();\n }\n\n throw new Error(\n 'AvatarCall requires one of: credentials, sessionId+sessionKey, connectUrl, or connect',\n );\n}\n\nexport function useCredentials(\n options: UseCredentialsOptions,\n): SessionCredentials {\n const key = computeKey(options);\n\n useEffect(() => {\n return () => {\n resourceCache.delete(key);\n };\n }, [key]);\n\n if (options.credentials) {\n return options.credentials;\n }\n\n let resource = resourceCache.get(key);\n if (!resource) {\n resource = createSuspenseResource(fetchCredentials(options));\n resourceCache.set(key, resource);\n }\n\n return resource.read();\n}\n","'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 * Manages the WebRTC connection and exposes a clean API for child components.\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 type { RoomOptions } from 'livekit-client';\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\nconst DEFAULT_ROOM_OPTIONS: RoomOptions = {\n adaptiveStream: false,\n dynacast: false,\n};\n\n/**\n * Maps WebRTC connection state to 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 * Establishes a WebRTC connection and provides session state to children.\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 __unstable_roomOptions,\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 const roomOptions = {\n ...DEFAULT_ROOM_OPTIONS,\n ...__unstable_roomOptions,\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={roomOptions}\n connectOptions={{\n autoSubscribe: 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 the 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 track.\n * Audio is handled automatically by the session.\n *\n * @example\n * ```tsx\n * function AvatarDisplay() {\n * const { videoTrackRef, hasVideo } = useAvatar();\n *\n * if (!hasVideo) {\n * return <Placeholder />;\n * }\n *\n * return <VideoTrack trackRef={videoTrackRef} />;\n * }\n * ```\n */\n\nimport {\n isTrackReference,\n useRemoteParticipants,\n useTracks,\n} from '@livekit/components-react';\nimport { Track } from 'livekit-client';\nimport type { UseAvatarReturn } from '../types';\n\n/**\n * Hook to access the remote avatar participant's video track\n *\n * @returns Avatar participant info and video track reference\n */\nexport function useAvatar(): UseAvatarReturn {\n const remoteParticipants = useRemoteParticipants();\n const avatarParticipant = remoteParticipants[0] ?? null;\n\n // Only subscribe to video - audio is handled automatically by the session\n const videoTracks = useTracks(\n [{ source: Track.Source.Camera, withPlaceholder: true }],\n { onlySubscribed: true, updateOnlyOn: [] },\n ).filter((ref) => !ref.participant.isLocal);\n\n const videoTrackRef = videoTracks[0] ?? null;\n const hasVideo = videoTrackRef !== null && isTrackReference(videoTrackRef);\n\n return {\n participant: avatarParticipant,\n videoTrackRef,\n hasVideo,\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\n/**\n * useAvatarStatus Hook\n *\n * Returns a single discriminated union representing the full avatar lifecycle\n * inside an AvatarSession. Combines session connection state and video\n * track availability into one status value.\n *\n * Must be used within <AvatarCall> or <AvatarSession>.\n *\n * @example\n * ```tsx\n * function MyAvatar() {\n * const avatar = useAvatarStatus();\n *\n * switch (avatar.status) {\n * case 'connecting':\n * return <Spinner />;\n * case 'waiting':\n * return <p>Waiting for video...</p>;\n * case 'ready':\n * return <VideoTrack trackRef={avatar.videoTrackRef} />;\n * case 'error':\n * return <p>{avatar.error.message}</p>;\n * case 'ended':\n * return <p>Call ended</p>;\n * }\n * }\n * ```\n */\n\nimport type { TrackReferenceOrPlaceholder } from '@livekit/components-react';\nimport { useAvatar } from './useAvatar';\nimport { useAvatarSession } from './useAvatarSession';\n\nexport type AvatarStatus =\n | { status: 'connecting' }\n | { status: 'waiting' }\n | { status: 'ready'; videoTrackRef: TrackReferenceOrPlaceholder }\n | { status: 'ending' }\n | { status: 'ended' }\n | { status: 'error'; error: Error };\n\nexport function useAvatarStatus(): AvatarStatus {\n const session = useAvatarSession();\n const { videoTrackRef, hasVideo } = useAvatar();\n\n switch (session.state) {\n case 'connecting':\n case 'idle':\n return { status: 'connecting' };\n\n case 'active':\n if (hasVideo && videoTrackRef) {\n return { status: 'ready', videoTrackRef };\n }\n return { status: 'waiting' };\n\n case 'ending':\n return { status: 'ending' };\n\n case 'ended':\n return { status: 'ended' };\n\n case 'error':\n return { status: 'error', error: session.error };\n }\n}\n","'use client';\n\nimport { isTrackReference, VideoTrack } from '@livekit/components-react';\nimport type { ComponentPropsWithoutRef, ReactNode } from 'react';\nimport { type AvatarStatus, useAvatarStatus } from '../hooks/useAvatarStatus';\n\n/** Subset of AvatarStatus relevant to the video display */\nexport type AvatarVideoStatus = Extract<\n AvatarStatus,\n { status: 'connecting' } | { status: 'waiting' } | { status: 'ready' }\n>;\n\nexport interface AvatarVideoProps\n extends Omit<ComponentPropsWithoutRef<'div'>, 'children'> {\n children?: (status: AvatarVideoStatus) => ReactNode;\n}\n\nexport function AvatarVideo({ children, ...props }: AvatarVideoProps) {\n const avatar = useAvatarStatus();\n\n const videoStatus: AvatarVideoStatus =\n avatar.status === 'ready'\n ? avatar\n : avatar.status === 'connecting'\n ? { status: 'connecting' }\n : { status: 'waiting' };\n\n if (children) {\n return <>{children(videoStatus)}</>;\n }\n\n return (\n <div {...props} data-avatar-video=\"\" data-status={videoStatus.status}>\n {videoStatus.status === 'ready' &&\n isTrackReference(videoStatus.videoTrackRef) && (\n <VideoTrack trackRef={videoStatus.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 updateOnlyOn: [],\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\n/**\n * AvatarCall Component\n *\n * High-level component that handles the complete session lifecycle.\n * Suspends during credential fetching (Phase 1) — wrap in <Suspense> to\n * show loading UI while the server creates the session.\n *\n * @example\n * ```tsx\n * <Suspense fallback={<Loading />}>\n * <AvatarCall avatarId=\"game-host\" connectUrl=\"/api/avatar/connect\">\n * <AvatarVideo />\n * <ControlBar />\n * </AvatarCall>\n * </Suspense>\n * ```\n */\n\nimport { useCredentials } from '../hooks/useCredentials';\nimport { useLatest } from '../hooks/useLatest';\nimport type { AvatarCallProps } from '../types';\nimport { AvatarSession } from './AvatarSession';\nimport { AvatarVideo } from './AvatarVideo';\nimport { ControlBar } from './ControlBar';\nimport { UserVideo } from './UserVideo';\n\nexport function AvatarCall({\n avatarId,\n sessionId,\n sessionKey,\n credentials: directCredentials,\n connectUrl,\n connect,\n baseUrl,\n avatarImageUrl,\n onEnd,\n onError,\n children,\n __unstable_roomOptions,\n ...props\n}: AvatarCallProps) {\n const onErrorRef = useLatest(onError);\n\n const credentials = useCredentials({\n avatarId,\n sessionId,\n sessionKey,\n credentials: directCredentials,\n connectUrl,\n connect,\n baseUrl,\n });\n\n const handleSessionError = (err: Error) => {\n onErrorRef.current?.(err);\n };\n\n const backgroundStyle = avatarImageUrl\n ? ({ '--avatar-image': `url(${avatarImageUrl})` } as React.CSSProperties)\n : undefined;\n\n return (\n <div\n {...props}\n data-avatar-call=\"\"\n data-avatar-id={avatarId}\n style={{ ...props.style, ...backgroundStyle }}\n >\n <AvatarSession\n credentials={credentials}\n onEnd={onEnd}\n onError={handleSessionError}\n __unstable_roomOptions={__unstable_roomOptions}\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"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@runwayml/avatars-react",
3
- "version": "0.2.2",
3
+ "version": "0.4.0",
4
4
  "description": "React SDK for real-time AI avatar interactions with GWM-1",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",