@@ -154,6 +154,84 @@ type UseSessionCommonOptions = {
154154type UseSessionConfigurableOptions = UseSessionCommonOptions & TokenSourceFetchOptions ;
155155type UseSessionFixedOptions = UseSessionCommonOptions ;
156156
157+ /**
158+ * Given two TokenSourceFetchOptions values, check to see if they are deep equal.
159+ *
160+ * FIXME: swap this for an import from livekit-client once
161+ * https://github.com/livekit/client-sdk-js/pull/1733 is merged and published!
162+ * */
163+ function areTokenSourceFetchOptionsEqual ( a : TokenSourceFetchOptions , b : TokenSourceFetchOptions ) {
164+ const allKeysSet = new Set ( [ ...Object . keys ( a ) , ...Object . keys ( b ) ] ) as Set <
165+ keyof TokenSourceFetchOptions
166+ > ;
167+
168+ for ( const key of allKeysSet ) {
169+ switch ( key ) {
170+ case 'roomName' :
171+ case 'participantName' :
172+ case 'participantIdentity' :
173+ case 'participantMetadata' :
174+ case 'participantAttributes' :
175+ case 'agentName' :
176+ case 'agentMetadata' :
177+ if ( a [ key ] !== b [ key ] ) {
178+ return false ;
179+ }
180+ break ;
181+ default :
182+ // ref: https://stackoverflow.com/a/58009992
183+ const exhaustiveCheckedKey : never = key ;
184+ throw new Error ( `Options key ${ exhaustiveCheckedKey } not being checked for equality!` ) ;
185+ }
186+ }
187+
188+ return true ;
189+ }
190+
191+ /** Internal hook used by useSession to manage creating a function that properly invokes
192+ * tokenSource.fetch(...) with any fetch options */
193+ function useSessionTokenSourceFetch (
194+ tokenSource : TokenSourceConfigurable | TokenSourceFixed ,
195+ unstableRestOptions : Exclude < UseSessionConfigurableOptions , keyof UseSessionCommonOptions > ,
196+ ) {
197+ const isConfigurable = tokenSource instanceof TokenSourceConfigurable ;
198+
199+ const memoizedTokenFetchOptionsRef = React . useRef < TokenSourceFetchOptions | null > (
200+ isConfigurable ? unstableRestOptions : null ,
201+ ) ;
202+
203+ React . useEffect ( ( ) => {
204+ if ( ! isConfigurable ) {
205+ memoizedTokenFetchOptionsRef . current = null ;
206+ return ;
207+ }
208+
209+ if (
210+ memoizedTokenFetchOptionsRef . current !== null &&
211+ areTokenSourceFetchOptionsEqual ( memoizedTokenFetchOptionsRef . current , unstableRestOptions )
212+ ) {
213+ return ;
214+ }
215+
216+ memoizedTokenFetchOptionsRef . current = unstableRestOptions ;
217+ } , [ isConfigurable , unstableRestOptions ] ) ;
218+
219+ const tokenSourceFetch = React . useCallback ( async ( ) => {
220+ if ( isConfigurable ) {
221+ if ( ! memoizedTokenFetchOptionsRef . current ) {
222+ throw new Error (
223+ `AgentSession - memoized token fetch options are not set, but the passed tokenSource was an instance of TokenSourceConfigurable. If you are seeing this please make a new GitHub issue!` ,
224+ ) ;
225+ }
226+ return tokenSource . fetch ( memoizedTokenFetchOptionsRef . current ) ;
227+ } else {
228+ return tokenSource . fetch ( ) ;
229+ }
230+ } , [ isConfigurable , tokenSource ] ) ;
231+
232+ return tokenSourceFetch ;
233+ }
234+
157235/**
158236 * A Session represents a manages connection to a Room which can contain Agents.
159237 * @public
@@ -357,9 +435,7 @@ export function useSession(
357435 } , [
358436 sessionInternal ,
359437 room ,
360- emitter ,
361438 roomConnectionState ,
362- localParticipant ,
363439 localCamera ,
364440 localMicrophone ,
365441 generateDerivedConnectionStateValues ,
@@ -427,15 +503,7 @@ export function useSession(
427503 ) ,
428504 ) ;
429505
430- const tokenSourceFetch = React . useCallback ( async ( ) => {
431- const isConfigurable = tokenSource instanceof TokenSourceConfigurable ;
432- if ( isConfigurable ) {
433- const tokenFetchOptions = restOptions as UseSessionConfigurableOptions ;
434- return tokenSource . fetch ( tokenFetchOptions ) ;
435- } else {
436- return tokenSource . fetch ( ) ;
437- }
438- } , [ tokenSource , restOptions ] ) ;
506+ const tokenSourceFetch = useSessionTokenSourceFetch ( tokenSource , restOptions ) ;
439507
440508 const start = React . useCallback (
441509 async ( connectOptions : SessionConnectOptions = { } ) => {
@@ -454,8 +522,6 @@ export function useSession(
454522
455523 let tokenDispatchesAgent = false ;
456524 await Promise . all ( [
457- // FIXME: swap the below line in once the new `livekit-client` changes are published
458- // room.connect(tokenSource, { tokenSourceOptions }),
459525 tokenSourceFetch ( ) . then ( ( { serverUrl, participantToken } ) => {
460526 const participantTokenPayload = decodeTokenPayload ( participantToken ) ;
461527 const participantTokenAgentDispatchCount =
@@ -491,8 +557,6 @@ export function useSession(
491557
492558 const prepareConnection = React . useCallback ( async ( ) => {
493559 const credentials = await tokenSourceFetch ( ) ;
494- // FIXME: swap the below line in once the new `livekit-client` changes are published
495- // room.prepareConnection(tokenSource, { tokenSourceOptions }),
496560 await room . prepareConnection ( credentials . serverUrl , credentials . participantToken ) ;
497561 } , [ tokenSourceFetch , room ] ) ;
498562 React . useEffect (
0 commit comments