Skip to content

Commit 05debba

Browse files
committed
refactor: convert to React.useXXX form for hooks
Longer term I think it might be worth discussing migrating away from that pattern since react won't be tree-shaken properly in end projects
1 parent 667d556 commit 05debba

File tree

4 files changed

+66
-60
lines changed

4 files changed

+66
-60
lines changed

packages/react/src/hooks/useAgent.ts

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
} from 'livekit-client';
1010
import type TypedEventEmitter from 'typed-emitter';
1111
import { EventEmitter } from 'events';
12-
import { useCallback, useEffect, useMemo, useState } from 'react';
12+
import * as React from 'react';
1313
import { create } from 'zustand';
1414
import { ParticipantAgentAttributes, TrackReference } from '@livekit/components-core';
1515

@@ -278,11 +278,11 @@ export function useAgent(session?: SessionStub): UseAgentReturn {
278278
internal: { agentConnectTimeoutMilliseconds },
279279
} = session;
280280

281-
const emitter = useMemo(() => new EventEmitter() as TypedEventEmitter<AgentCallbacks>, []);
281+
const emitter = React.useMemo(() => new EventEmitter() as TypedEventEmitter<AgentCallbacks>, []);
282282

283283
const roomRemoteParticipants = useRemoteParticipants({ room });
284284

285-
const agentParticipant = useMemo(() => {
285+
const agentParticipant = React.useMemo(() => {
286286
return (
287287
roomRemoteParticipants.find(
288288
(p) =>
@@ -291,7 +291,7 @@ export function useAgent(session?: SessionStub): UseAgentReturn {
291291
) ?? null
292292
);
293293
}, [roomRemoteParticipants]);
294-
const workerParticipant = useMemo(() => {
294+
const workerParticipant = React.useMemo(() => {
295295
if (!agentParticipant) {
296296
return null;
297297
}
@@ -305,10 +305,10 @@ export function useAgent(session?: SessionStub): UseAgentReturn {
305305
}, [agentParticipant, roomRemoteParticipants]);
306306

307307
// 1. Listen for agent participant attribute changes
308-
const [agentParticipantAttributes, setAgentParticipantAttributes] = useState<
308+
const [agentParticipantAttributes, setAgentParticipantAttributes] = React.useState<
309309
Record<string, string>
310310
>({});
311-
useEffect(() => {
311+
React.useEffect(() => {
312312
if (!agentParticipant) {
313313
return;
314314
}
@@ -333,30 +333,30 @@ export function useAgent(session?: SessionStub): UseAgentReturn {
333333
participantIdentity: workerParticipant?.identity,
334334
});
335335

336-
const videoTrack = useMemo(
336+
const videoTrack = React.useMemo(
337337
() =>
338338
agentTracks.find((t) => t.source === Track.Source.Camera) ??
339339
workerTracks.find((t) => t.source === Track.Source.Camera) ??
340340
null,
341341
[agentTracks, workerTracks],
342342
);
343-
useEffect(() => {
343+
React.useEffect(() => {
344344
emitter.emit(AgentEvent.CameraChanged, videoTrack);
345345
}, [emitter, videoTrack]);
346346

347-
const audioTrack = useMemo(
347+
const audioTrack = React.useMemo(
348348
() =>
349349
agentTracks.find((t) => t.source === Track.Source.Microphone) ??
350350
workerTracks.find((t) => t.source === Track.Source.Microphone) ??
351351
null,
352352
[agentTracks, workerTracks],
353353
);
354-
useEffect(() => {
354+
React.useEffect(() => {
355355
emitter.emit(AgentEvent.MicrophoneChanged, audioTrack);
356356
}, [emitter, audioTrack]);
357357

358-
const [roomConnectionState, setRoomConnectionState] = useState(room.state);
359-
useEffect(() => {
358+
const [roomConnectionState, setRoomConnectionState] = React.useState(room.state);
359+
React.useEffect(() => {
360360
const handleConnectionStateChanged = (connectionState: ConnectionState) => {
361361
setRoomConnectionState(connectionState);
362362
};
@@ -367,10 +367,10 @@ export function useAgent(session?: SessionStub): UseAgentReturn {
367367
};
368368
}, [room]);
369369

370-
const [localMicTrack, setLocalMicTrack] = useState<LocalTrackPublication | null>(
370+
const [localMicTrack, setLocalMicTrack] = React.useState<LocalTrackPublication | null>(
371371
() => room.localParticipant.getTrackPublication(Track.Source.Microphone) ?? null,
372372
);
373-
useEffect(() => {
373+
React.useEffect(() => {
374374
const handleLocalParticipantTrackPublished = () => {
375375
setLocalMicTrack(room.localParticipant.getTrackPublication(Track.Source.Microphone) ?? null);
376376
};
@@ -406,11 +406,11 @@ export function useAgent(session?: SessionStub): UseAgentReturn {
406406
updateAgentTimeoutParticipantExists,
407407
} = useAgentTimeoutIdStore();
408408

409-
const failureReasons = useMemo(() => {
409+
const failureReasons = React.useMemo(() => {
410410
return agentTimeoutFailureReason ? [agentTimeoutFailureReason] : [];
411411
}, [agentTimeoutFailureReason]);
412412

413-
const [state, isBufferingSpeech] = useMemo(() => {
413+
const [state, isBufferingSpeech] = React.useMemo(() => {
414414
if (failureReasons.length > 0) {
415415
return ['failed' as const, false];
416416
}
@@ -443,17 +443,17 @@ export function useAgent(session?: SessionStub): UseAgentReturn {
443443
agentParticipantAttributes,
444444
]);
445445

446-
useEffect(() => {
446+
React.useEffect(() => {
447447
emitter.emit(AgentEvent.StateChanged, state);
448448
updateAgentTimeoutState(state);
449449
}, [emitter, state]);
450-
useEffect(() => {
450+
React.useEffect(() => {
451451
updateAgentTimeoutParticipantExists(agentParticipant !== null);
452452
}, [agentParticipant]);
453453

454454
// When the session room begins connecting, start the agent timeout
455455
const isSessionDisconnected = session.connectionState === 'disconnected';
456-
useEffect(() => {
456+
React.useEffect(() => {
457457
if (isSessionDisconnected) {
458458
return;
459459
}
@@ -464,7 +464,7 @@ export function useAgent(session?: SessionStub): UseAgentReturn {
464464
};
465465
}, [isSessionDisconnected, agentConnectTimeoutMilliseconds]);
466466

467-
const agentState: AgentStateCases = useMemo(() => {
467+
const agentState: AgentStateCases = React.useMemo(() => {
468468
const common: AgentStateCommon = {
469469
attributes: agentParticipantAttributes,
470470

@@ -557,7 +557,7 @@ export function useAgent(session?: SessionStub): UseAgentReturn {
557557
isBufferingSpeech,
558558
]);
559559

560-
const waitUntilAvailable = useCallback(
560+
const waitUntilAvailable = React.useCallback(
561561
async (signal?: AbortSignal) => {
562562
const { isAvailable } = generateDerivedStateValues(state);
563563
if (isAvailable) {
@@ -590,7 +590,7 @@ export function useAgent(session?: SessionStub): UseAgentReturn {
590590
[state, emitter],
591591
);
592592

593-
const waitUntilCamera = useCallback(
593+
const waitUntilCamera = React.useCallback(
594594
(signal?: AbortSignal) => {
595595
return new Promise<TrackReference>((resolve, reject) => {
596596
const stateChangedHandler = (camera: TrackReference | null) => {
@@ -617,7 +617,7 @@ export function useAgent(session?: SessionStub): UseAgentReturn {
617617
[emitter],
618618
);
619619

620-
const waitUntilMicrophone = useCallback(
620+
const waitUntilMicrophone = React.useCallback(
621621
(signal?: AbortSignal) => {
622622
return new Promise<TrackReference>((resolve, reject) => {
623623
const stateChangedHandler = (microphone: TrackReference | null) => {
@@ -644,7 +644,7 @@ export function useAgent(session?: SessionStub): UseAgentReturn {
644644
[emitter],
645645
);
646646

647-
return useMemo(() => {
647+
return React.useMemo(() => {
648648
return {
649649
...agentState,
650650
waitUntilAvailable,

packages/react/src/hooks/useEvents.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useEffect, useCallback, useMemo } from 'react';
1+
import * as React from 'react';
22
import TypedEventEmitter, { EventMap } from 'typed-emitter';
33

44
/** @public */
@@ -13,11 +13,11 @@ export function useEvents<
1313
handlerFn: Callback | undefined,
1414
dependencies?: React.DependencyList,
1515
) {
16-
const fallback = useMemo(() => () => {}, []);
17-
const wrappedCallback = useCallback(handlerFn ?? fallback, dependencies ?? []);
16+
const fallback = React.useMemo(() => () => {}, []);
17+
const wrappedCallback = React.useCallback(handlerFn ?? fallback, dependencies ?? []);
1818
const callback = dependencies ? wrappedCallback : handlerFn;
1919

20-
const emitter = useMemo(() => {
20+
const emitter = React.useMemo(() => {
2121
if (!instance) {
2222
return null;
2323
}
@@ -27,7 +27,7 @@ export function useEvents<
2727
return instance;
2828
}, [instance]);
2929

30-
useEffect(() => {
30+
React.useEffect(() => {
3131
if (!emitter || !callback) {
3232
return;
3333
}

packages/react/src/hooks/useSession.ts

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import * as React from 'react';
12
import type TypedEventEmitter from 'typed-emitter';
23
import {
34
Room,
@@ -11,7 +12,6 @@ import {
1112
RoomConnectOptions,
1213
} from 'livekit-client';
1314
import { EventEmitter } from 'events';
14-
import { useCallback, useEffect, useMemo, useState } from 'react';
1515

1616
import { useMaybeRoomContext } from '../context';
1717
import { useAgent } from './useAgent';
@@ -170,14 +170,17 @@ export function useSession(
170170
const { room: optionsRoom, agentConnectTimeoutMilliseconds, ...restOptions } = options;
171171

172172
const roomFromContext = useMaybeRoomContext();
173-
const room = useMemo(
173+
const room = React.useMemo(
174174
() => roomFromContext ?? optionsRoom ?? new Room(),
175175
[roomFromContext, optionsRoom],
176176
);
177177

178-
const emitter = useMemo(() => new EventEmitter() as TypedEventEmitter<SessionCallbacks>, []);
178+
const emitter = React.useMemo(
179+
() => new EventEmitter() as TypedEventEmitter<SessionCallbacks>,
180+
[],
181+
);
179182

180-
const generateDerivedConnectionStateValues = useCallback(
183+
const generateDerivedConnectionStateValues = React.useCallback(
181184
<State extends UseSessionReturn['connectionState']>(connectionState: State) =>
182185
({
183186
isConnected:
@@ -203,8 +206,8 @@ export function useSession(
203206
[],
204207
);
205208

206-
const [roomConnectionState, setRoomConnectionState] = useState(room.state);
207-
useEffect(() => {
209+
const [roomConnectionState, setRoomConnectionState] = React.useState(room.state);
210+
React.useEffect(() => {
208211
const handleConnectionStateChanged = (connectionState: ConnectionState) => {
209212
setRoomConnectionState(connectionState);
210213
};
@@ -215,7 +218,7 @@ export function useSession(
215218
};
216219
}, [room]);
217220

218-
useEffect(() => {
221+
React.useEffect(() => {
219222
const handleMediaDevicesError = async (error: Error) => {
220223
emitter.emit(SessionEvent.MediaDevicesError, error);
221224
};
@@ -226,7 +229,7 @@ export function useSession(
226229
};
227230
}, [room, emitter]);
228231

229-
useEffect(() => {
232+
React.useEffect(() => {
230233
const handleEncryptionError = async (error: Error) => {
231234
emitter.emit(SessionEvent.EncryptionError, error);
232235
};
@@ -239,7 +242,7 @@ export function useSession(
239242

240243
const { localParticipant } = useLocalParticipant({ room });
241244
const cameraPublication = localParticipant.getTrackPublication(Track.Source.Camera);
242-
const localCamera = useMemo(() => {
245+
const localCamera = React.useMemo(() => {
243246
if (!cameraPublication || cameraPublication.isMuted) {
244247
return null;
245248
}
@@ -250,7 +253,7 @@ export function useSession(
250253
};
251254
}, [localParticipant, cameraPublication, cameraPublication?.isMuted]);
252255
const microphonePublication = localParticipant.getTrackPublication(Track.Source.Microphone);
253-
const localMicrophone = useMemo(() => {
256+
const localMicrophone = React.useMemo(() => {
254257
if (!microphonePublication || microphonePublication.isMuted) {
255258
return null;
256259
}
@@ -261,7 +264,7 @@ export function useSession(
261264
};
262265
}, [localParticipant, microphonePublication, microphonePublication?.isMuted]);
263266

264-
const conversationState = useMemo(():
267+
const conversationState = React.useMemo(():
265268
| SessionStateConnecting
266269
| SessionStateConnected
267270
| SessionStateDisconnected => {
@@ -327,11 +330,11 @@ export function useSession(
327330
localMicrophone,
328331
generateDerivedConnectionStateValues,
329332
]);
330-
useEffect(() => {
333+
React.useEffect(() => {
331334
emitter.emit(SessionEvent.ConnectionStateChanged, conversationState.connectionState);
332335
}, [emitter, conversationState.connectionState]);
333336

334-
const waitUntilConnectionState = useCallback(
337+
const waitUntilConnectionState = React.useCallback(
335338
async (state: UseSessionReturn['connectionState'], signal?: AbortSignal) => {
336339
if (conversationState.connectionState === state) {
337340
return;
@@ -362,7 +365,7 @@ export function useSession(
362365
[conversationState.connectionState, emitter],
363366
);
364367

365-
const waitUntilConnected = useCallback(
368+
const waitUntilConnected = React.useCallback(
366369
async (signal?: AbortSignal) => {
367370
return waitUntilConnectionState(
368371
ConnectionState.Connected /* FIXME: should I check for other states too? */,
@@ -372,15 +375,15 @@ export function useSession(
372375
[waitUntilConnectionState],
373376
);
374377

375-
const waitUntilDisconnected = useCallback(
378+
const waitUntilDisconnected = React.useCallback(
376379
async (signal?: AbortSignal) => {
377380
return waitUntilConnectionState(ConnectionState.Disconnected, signal);
378381
},
379382
[waitUntilConnectionState],
380383
);
381384

382385
const agent = useAgent(
383-
useMemo(
386+
React.useMemo(
384387
() => ({
385388
connectionState: conversationState.connectionState,
386389
room,
@@ -393,7 +396,7 @@ export function useSession(
393396
),
394397
);
395398

396-
const tokenSourceFetch = useCallback(async () => {
399+
const tokenSourceFetch = React.useCallback(async () => {
397400
const isConfigurable = tokenSource instanceof TokenSourceConfigurable;
398401
if (isConfigurable) {
399402
const tokenFetchOptions = restOptions as UseSessionConfigurableOptions;
@@ -403,7 +406,7 @@ export function useSession(
403406
}
404407
}, [tokenSource, restOptions]);
405408

406-
const start = useCallback(
409+
const start = React.useCallback(
407410
async (connectOptions: SessionConnectOptions = {}) => {
408411
const {
409412
signal,
@@ -443,24 +446,24 @@ export function useSession(
443446
[room, waitUntilDisconnected, tokenSourceFetch, waitUntilConnected, agent.waitUntilAvailable],
444447
);
445448

446-
const end = useCallback(async () => {
449+
const end = React.useCallback(async () => {
447450
await room.disconnect();
448451
}, [room]);
449452

450-
const prepareConnection = useCallback(async () => {
453+
const prepareConnection = React.useCallback(async () => {
451454
const credentials = await tokenSourceFetch();
452455
// FIXME: swap the below line in once the new `livekit-client` changes are published
453456
// room.prepareConnection(tokenSource, { tokenSourceOptions }),
454457
await room.prepareConnection(credentials.serverUrl, credentials.participantToken);
455458
}, [tokenSourceFetch, room]);
456-
useEffect(() => {
459+
React.useEffect(() => {
457460
prepareConnection().catch((err) => {
458461
// FIXME: figure out a better logging solution?
459462
console.warn('WARNING: Room.prepareConnection failed:', err);
460463
});
461464
}, [prepareConnection]);
462465

463-
return useMemo(
466+
return React.useMemo(
464467
() => ({
465468
...conversationState,
466469

0 commit comments

Comments
 (0)