{"version":3,"sources":["jsdelivr-header.js","/npm/@signalwire/js@3.30.0/src/index.ts","/npm/@signalwire/js@3.30.0/src/chat/index.ts","/npm/@signalwire/js@3.30.0/src/createClient.ts","/npm/@signalwire/js@3.30.0/src/Client.ts","/npm/@signalwire/js@3.30.0/src/features/mediaElements/mediaElementsSagas.ts","/npm/@signalwire/js@3.30.0/src/utils/audioElement.ts","/npm/@signalwire/js@3.30.0/src/features/actions.ts","/npm/@signalwire/js@3.30.0/src/cantina/VideoManager.ts","/npm/@signalwire/js@3.30.0/src/cantina/workers/videoManagerWorker.ts","/npm/@signalwire/js@3.30.0/src/cantina/workers/videoManagerRoomsWorker.ts","/npm/@signalwire/js@3.30.0/src/cantina/workers/videoManagerRoomWorker.ts","/npm/@signalwire/js@3.30.0/src/buildVideoElement.ts","/npm/@signalwire/js@3.30.0/src/utils/videoElement.ts","/npm/@signalwire/js@3.30.0/src/VideoOverlays.ts","/npm/@signalwire/js@3.30.0/src/video/VideoRoomSession.ts","/npm/@signalwire/js@3.30.0/src/BaseRoomSession.ts","/npm/@signalwire/js@3.30.0/src/utils/constants.ts","/npm/@signalwire/js@3.30.0/src/utils/roomSession.ts","/npm/@signalwire/js@3.30.0/src/RoomSessionScreenShare.ts","/npm/@signalwire/js@3.30.0/src/video/workers/memberListUpdatedWorker.ts","/npm/@signalwire/js@3.30.0/src/video/workers/childMemberJoinedWorker.ts","/npm/@signalwire/js@3.30.0/src/video/workers/videoWorker.ts","/npm/@signalwire/js@3.30.0/src/video/workers/videoStreamWorker.ts","/npm/@signalwire/js@3.30.0/src/video/workers/videoRecordWorker.ts","/npm/@signalwire/js@3.30.0/src/video/workers/videoPlaybackWorker.ts","/npm/@signalwire/js@3.30.0/src/RoomSessionDevice.ts","/npm/@signalwire/js@3.30.0/src/fabric/FabricRoomSession.ts","/npm/@signalwire/js@3.30.0/src/utils/storage.ts","/npm/@signalwire/js@3.30.0/src/fabric/utils/constants.ts","/npm/@signalwire/js@3.30.0/src/fabric/workers/wsClientWorker.ts","/npm/@signalwire/js@3.30.0/src/fabric/workers/fabricWorker.ts","/npm/@signalwire/js@3.30.0/src/fabric/FabricRoomSessionMember.ts","/npm/@signalwire/js@3.30.0/src/fabric/workers/callSegmentWorker.ts","/npm/@signalwire/js@3.30.0/src/fabric/workers/callLeftWorker.ts","/npm/@signalwire/js@3.30.0/src/fabric/workers/callJoinWorker.ts","/npm/@signalwire/js@3.30.0/src/fabric/workers/fabricMemberWorker.ts","/npm/@signalwire/js@3.30.0/src/fabric/utils/capabilitiesHelpers.ts","/npm/@signalwire/js@3.30.0/src/fabric/utils/eventMappers.ts","/npm/@signalwire/js@3.30.0/src/fabric/utils/validators.ts","/npm/@signalwire/js@3.30.0/src/fabric/utils/validationProxy.ts","/npm/@signalwire/js@3.30.0/src/JWTSession.ts","/npm/@signalwire/js@3.30.0/src/utils/CloseEvent.ts","/npm/@signalwire/js@3.30.0/src/chat/Client.ts","/npm/@signalwire/js@3.30.0/src/pubSub/index.ts","/npm/@signalwire/js@3.30.0/src/utils/interfaces/video.ts","/npm/@signalwire/js@3.30.0/src/pubSub/Client.ts","/npm/@signalwire/js@3.30.0/src/fabric/index.ts","/npm/@signalwire/js@3.30.0/src/fabric/HTTPClient.ts","/npm/@signalwire/js@3.30.0/src/fabric/createHttpClient.ts","/npm/@signalwire/js@3.30.0/src/utils/paginatedResult.ts","/npm/@signalwire/js@3.30.0/src/utils/makeQueryParamsUrl.ts","/npm/@signalwire/js@3.30.0/src/fabric/utils/typeGuard.ts","/npm/@signalwire/js@3.30.0/src/fabric/WSClient.ts","/npm/@signalwire/js@3.30.0/src/fabric/IncomingCallManager.ts","/npm/@signalwire/js@3.30.0/src/fabric/createWSClient.ts","/npm/@signalwire/js@3.30.0/src/fabric/SATSession.ts","/npm/@signalwire/js@3.30.0/src/fabric/SignalWire.ts","/npm/@signalwire/js@3.30.0/src/video/index.ts","/npm/@signalwire/js@3.30.0/src/createRoomObject.ts","/npm/@signalwire/js@3.30.0/src/joinRoom.ts","/npm/@signalwire/js@3.30.0/src/video/RoomSession.ts","/npm/@signalwire/js@3.30.0/src/webrtc.ts"],"names":[],"mappings":"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","file":"/npm/@signalwire/js@3.30.0/dist/index.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/@signalwire/js@3.30.0/dist/index.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","/**\n * Welcome to the technical documentation for the JavaScript SDK.\n *\n * At the outer level, when you import the SignalWire JS library you get access\n * to three different namespaces:\n *\n *  - {@link Video}\n *  - {@link Chat}\n *  - {@link WebRTC}\n *\n * Video gives you access to the classes and methods that let you\n * interface with the backend Video APIs. Chat gives you access to the classes and functions that you need to create a real-time chat application. WebRTC\n * contains several functions that are useful for interacting with the hardware of the user's device.\n *\n *\n * Don't know where to start? Create an instance of\n * {@link Video.RoomSession} to join a room, use the {@link Chat.Client} constructor to start a chat application, or take a look at [Getting Started\n * with the SignalWire Video\n * API](https://developer.signalwire.com/apis/docs/getting-started-with-the-signalwire-video-api-1).\n *\n * @module\n */\n\nimport type {\n  VideoRoomSessionEventNames,\n  RoomStarted,\n  RoomSubscribed,\n  RoomUpdated,\n  RoomEnded,\n  VideoMemberEntity,\n} from '@signalwire/core'\n\n/** @ignore @deprecated */\nexport type RoomStartedEventName = RoomStarted\n/** @ignore @deprecated */\nexport type RoomEndedEventName = RoomEnded\n/** @ignore @deprecated */\nexport type RoomSubscribedEventName = RoomSubscribed\n/** @ignore @deprecated */\nexport type RoomUpdatedEventName = RoomUpdated\n/** @ignore @deprecated */\nexport type RoomEvent = VideoRoomSessionEventNames\n/** @ignore @deprecated */\nexport type RoomMember = VideoMemberEntity & { type: 'member' }\n/** @ignore @deprecated */\nexport type RoomScreenShare = VideoMemberEntity & { type: 'screen' }\n/** @ignore @deprecated */\nexport type RoomDevice = VideoMemberEntity & { type: 'device' }\n\n/**\n * The Chat namespace contains the classes and functions that you need to\n * create a real-time chat application.\n */\nexport * as Chat from './chat'\n\nexport * as PubSub from './pubSub'\n\n/**\n * The Fabric namespace contains the classes and functions that you need to\n * create a unified communication application that includes Audio/Video calling\n * with Chat/Messaging capabilties.\n */\nexport * as Fabric from './fabric'\nexport { SignalWire } from './fabric'\nexport * from './fabric'\n\n/**\n * The Video namespace contains the classes and functions that you need to\n * create a video conferencing application.\n */\nexport * as Video from './video'\nexport { VideoRoomSession } from './video'\nexport { RoomSessionScreenShare } from './RoomSessionScreenShare'\nexport { RoomSessionDevice } from './RoomSessionDevice'\n\n/**\n * The WebRTC namespace includes functions that give you access to the input and\n * output media devices available on the user's machine. For example, you can\n * use these functions to request permission and get access to the media stream\n * from a webcam, from a microphone, or from a screen sharing.\n */\nexport * as WebRTC from './webrtc'\n\nexport type {\n  BaseComponentOptions,\n  BaseConnectionState,\n  ClientEvents,\n  EmitterContract,\n  RTCTrackEventName,\n  UserOptions,\n  SessionStatus,\n  SessionEvents,\n  VideoLayout,\n  InternalVideoLayout,\n  VideoLayoutEventNames,\n  VideoLayoutChangedEventParams,\n  VideoRoomSessionEventNames,\n  VideoRoomEventParams,\n  VideoRoomSubscribedEventParams,\n  VideoMemberEntity,\n  VideoMemberEventNames,\n  MemberTalkingEventNames,\n  VideoMemberTalkingEventParams,\n  InternalVideoMemberEntity,\n  InternalVideoLayoutLayer,\n  VideoPosition,\n  VideoPositions,\n  /**\n   * Call Fabric types\n   */\n  CallUpdatedEventParams,\n  CallLeftEventParams,\n  CallStateEventParams,\n  CallPlayEventParams,\n  CallConnectEventParams,\n  CallRoomEventParams,\n  FabricRoomEventParams,\n  FabricLayoutChangedEventParams,\n  FabricMemberJoinedEventParams,\n  FabricMemberUpdatedEventParams,\n  FabricMemberLeftEventParams,\n  FabricMemberTalkingEventParams,\n  FabricMemberEventParams,\n  FabricMemberEntity,\n  InternalFabricMemberEntity,\n  ConversationMessageEventName,\n  ConversationMessageEvent,\n  ConversationEventParams,\n  ConversationEvent,\n  SetAudioFlagsParams,\n} from '@signalwire/core'\n\nexport type {\n  BaseConnectionOptions,\n  ConnectionOptions,\n} from '@signalwire/webrtc'\n\nexport type {\n  CallJoinedEventParams,\n  RoomSessionObjectEventsHandlerMap,\n  RoomSessionObjectEvents,\n  // Just to keep backwards compatibility.\n  RoomSessionObjectEventsHandlerMap as RoomObjectEventsHandlerMap,\n  RoomSessionObjectEvents as RoomObjectEvents,\n  RoomEventNames,\n  StartScreenShareOptions,\n} from './utils/interfaces'\n\n/**\n * Build Video Element\n */\nexport { buildVideoElement } from './buildVideoElement'\nexport { LocalVideoOverlay, OverlayMap, UserOverlay } from './VideoOverlays'\n","export { Client, ClientOptions, ClientApiEvents } from './Client'\n\nexport { ChatMember, ChatMessage } from '@signalwire/core'\n\nexport type { PagingCursor } from '../utils/interfaces'\n\nexport type {\n  ChatAction,\n  ChatChannel,\n  ChatChannelMessageEvent,\n  ChatChannelMessageEventParams,\n  ChatChannelState,\n  ChatEvent,\n  ChatGetMembersParams,\n  ChatGetMemberStateParams,\n  ChatGetMessagesParams,\n  ChatMemberContract,\n  ChatMemberEntity,\n  ChatMemberJoinedEvent,\n  ChatMemberJoinedEventParams,\n  ChatMemberLeftEvent,\n  ChatMemberLeftEventParams,\n  ChatMemberUpdatedEvent,\n  ChatMemberUpdatedEventParams,\n  ChatMessageContract,\n  ChatMessageEntity,\n  ChatSetMemberStateParams,\n  InternalChatMemberEntity,\n  InternalChatMessageEntity,\n  PaginationCursor,\n} from '@signalwire/core'\n","import {\n  ClientEvents,\n  configureStore,\n  connect,\n  getEventEmitter,\n  UserOptions,\n} from '@signalwire/core'\nimport { ClientAPI, Client } from './Client'\nimport { JWTSession } from './JWTSession'\n\n/**\n * With Video.createClient() you can establish a WebSocket connection\n * with SignalWire and interact with the client.\n *\n * ## Examples\n * Create a client\n *\n * @example\n * ```js\n * try {\n *   const client = Video.createClient({\n *     token: '<YourJWT>',\n *   })\n *\n *   await client.connect()\n *   // Your client is ready now..\n * } catch (error) {\n *   console.error('Error', error)\n * }\n * ```\n * @internal\n */\nexport const createClient = <RoomSessionType>(userOptions: UserOptions) => {\n  const baseUserOptions = {\n    ...userOptions,\n    emitter: getEventEmitter<ClientEvents>(),\n  }\n  const store = configureStore({\n    userOptions: baseUserOptions,\n    SessionConstructor: JWTSession,\n  })\n  const client = connect<ClientEvents, ClientAPI, Client<RoomSessionType>>({\n    store,\n    Component: ClientAPI,\n  })(baseUserOptions)\n\n  return client\n}\n","import {\n  BaseClient,\n  ClientEvents,\n  ClientContract,\n  actions,\n  Chat as ChatNamespace,\n  PubSub as PubSubNamespace,\n} from '@signalwire/core'\nimport type { CustomSaga } from '@signalwire/core'\nimport { ConnectionOptions } from '@signalwire/webrtc'\nimport { makeAudioElementSaga } from './features/mediaElements/mediaElementsSagas'\nimport { VideoManager, createVideoManagerObject } from './cantina'\nimport type { Client as ChatClient } from './chat/Client'\nimport type { Client as PubSubClient } from './pubSub/Client'\nimport type { RoomSession } from './video/RoomSession'\nimport { buildVideoElement } from './buildVideoElement'\nimport {\n  createVideoRoomSessionObject,\n  VideoRoomSessionConnection,\n} from './video/VideoRoomSession'\nimport { CallParams } from './fabric/interfaces'\n\nexport interface Client<RoomSessionType = RoomSession>\n  extends ClientContract<Client<RoomSessionType>, ClientEvents> {\n  rooms: ClientAPI['rooms']\n  chat: ClientAPI['chat']\n  pubSub: ClientAPI['pubSub']\n}\n\nexport interface MakeRoomOptions extends CallParams, ConnectionOptions {\n  /** Local media stream to override the local video and audio stream tracks */\n  localStream?: MediaStream\n}\n\nexport class ClientAPI extends BaseClient<ClientEvents> {\n  private _videoManager: VideoManager\n  private _chat: ChatClient\n  private _pubSub: PubSubClient\n\n  get rooms() {\n    return {\n      makeRoomObject: (makeRoomOptions: MakeRoomOptions) => {\n        const {\n          rootElement,\n          applyLocalVideoOverlay = true,\n          applyMemberOverlay = true,\n          mirrorLocalVideoOverlay = true,\n          stopCameraWhileMuted = true,\n          stopMicrophoneWhileMuted = true,\n          ...options\n        } = makeRoomOptions\n\n        // TODO: This might not be needed here. We can initiate these sagas in the BaseRoomSession constructor.\n        const customSagas: Array<CustomSaga<VideoRoomSessionConnection>> = []\n\n        /**\n         * By default the SDK will attach the audio to\n         * an Audio element (regardless of \"rootElement\")\n         */\n        customSagas.push(\n          makeAudioElementSaga({\n            speakerId: options.speakerId,\n          })\n        )\n\n        const room = createVideoRoomSessionObject({\n          ...options,\n          store: this.store,\n          customSagas,\n        })\n\n        /**\n         * If the user provides a `rootElement` we'll\n         * automatically handle the Video element for them\n         */\n        if (rootElement) {\n          try {\n            buildVideoElement({\n              applyLocalVideoOverlay,\n              applyMemberOverlay,\n              mirrorLocalVideoOverlay,\n              room,\n              rootElement,\n            })\n          } catch (error) {\n            this.logger.error('Unable to build the video element automatically')\n          }\n        }\n\n        /**\n         * If the user joins with `join_video_muted: true` or\n         * `join_audio_muted: true` we'll stop the streams\n         * right away.\n         */\n        room.on('room.subscribed', (params) => {\n          const member = params.room_session.members?.find(\n            (m) => m.id === room.memberId\n          )\n\n          if (member?.audio_muted) {\n            try {\n              room.stopOutboundAudio()\n            } catch (error) {\n              this.logger.error('Error handling audio_muted', error)\n            }\n          }\n\n          if (member?.video_muted) {\n            try {\n              room.stopOutboundVideo()\n            } catch (error) {\n              this.logger.error('Error handling video_muted', error)\n            }\n          }\n        })\n\n        /**\n         * Stop and Restore outbound audio on audio_muted event\n         */\n        if (stopMicrophoneWhileMuted) {\n          room.on('member.updated.audio_muted', ({ member }) => {\n            try {\n              if (member.id === room.memberId && 'audio_muted' in member) {\n                member.audio_muted\n                  ? room.stopOutboundAudio()\n                  : room.restoreOutboundAudio()\n              }\n            } catch (error) {\n              this.logger.error('Error handling audio_muted', error)\n            }\n          })\n        }\n\n        /**\n         * Stop and Restore outbound video on video_muted event\n         */\n        if (stopCameraWhileMuted) {\n          room.on('member.updated.video_muted', ({ member }) => {\n            try {\n              if (member.id === room.memberId && 'video_muted' in member) {\n                member.video_muted\n                  ? room.stopOutboundVideo()\n                  : room.restoreOutboundVideo()\n              }\n            } catch (error) {\n              this.logger.error('Error handling video_muted', error)\n            }\n          })\n        }\n\n        return room\n      },\n    }\n  }\n\n  get chat() {\n    if (!this._chat) {\n      this._chat = ChatNamespace.createBaseChatObject<ChatClient>({\n        store: this.store,\n      })\n    }\n    return this._chat\n  }\n\n  get pubSub() {\n    if (!this._pubSub) {\n      this._pubSub = PubSubNamespace.createBasePubSubObject<PubSubClient>({\n        store: this.store,\n      })\n    }\n    return this._pubSub\n  }\n\n  /** @internal */\n  get videoManager() {\n    if (!this._videoManager) {\n      this._videoManager = createVideoManagerObject(this.options)\n    }\n    return this._videoManager\n  }\n\n  /**\n   * Reauthenticate with the SignalWire network using a new token\n   * For now it returns void since with an invalid token the server\n   * will close the connection right away so we can hook on the session\n   * events in case. Need to improve it.\n   *\n   * @internal\n   */\n  reauthenticate(token: string) {\n    this.store.dispatch(actions.reauthAction({ token }))\n  }\n}\n","import {\n  getLogger,\n  CustomSagaParams,\n  actions,\n  sagaEffects,\n  LOCAL_EVENT_PREFIX,\n} from '@signalwire/core'\nimport type { SagaIterator, Task } from '@signalwire/core'\nimport { setMediaElementSinkId } from '@signalwire/webrtc'\nimport { setAudioMediaTrack } from '../../utils/audioElement'\nimport { audioSetSpeakerAction } from '../actions'\nimport { VideoRoomSessionConnection } from '../../video/VideoRoomSession'\n\nexport const makeAudioElementSaga = ({ speakerId }: { speakerId?: string }) => {\n  return function* audioElementSaga({\n    instance: room,\n    runSaga,\n  }: CustomSagaParams<VideoRoomSessionConnection>): SagaIterator {\n    if (typeof Audio === 'undefined') {\n      getLogger().warn('`Audio` is not supported on this environment.')\n      return\n    }\n\n    try {\n      const audioEl = room.getAudioEl()\n      let audioTask: Task | undefined\n\n      const trackHandler = function (event: RTCTrackEvent) {\n        switch (event.track.kind) {\n          case 'audio': {\n            audioTask = runSaga(audioElementSetupWorker, {\n              track: event.track,\n              element: audioEl,\n              speakerId,\n              room,\n            })\n            break\n          }\n        }\n      }\n      /**\n       * Using `on` instead of `once` (or `off` within trackHandler) because\n       * there are cases (promote/demote) where we need to handle multiple `track`\n       * events and update the audioEl with the new track.\n       */\n      room.on('track', trackHandler)\n\n      room.once('destroy', () => {\n        audioTask?.cancel()\n      })\n    } catch (error) {\n      getLogger().error('audioElementSaga', error)\n    }\n  }\n}\n\nfunction* audioElementActionsWatcher({\n  element,\n  room,\n}: {\n  element: HTMLAudioElement\n  room: VideoRoomSessionConnection\n}): SagaIterator {\n  // TODO: For now we're handling individual actions but in the future\n  // we might want to have a single action per custom saga and use it\n  // in a similar fashion to `executeAction`\n  const setSpeakerActionType = actions.getCustomSagaActionType(\n    room.__uuid,\n    audioSetSpeakerAction\n  )\n\n  while (true) {\n    const action = yield sagaEffects.take([setSpeakerActionType])\n\n    try {\n      switch (action.type) {\n        case setSpeakerActionType:\n          const response = yield sagaEffects.call(\n            setMediaElementSinkId,\n            element,\n            action.payload\n          )\n\n          room.emit(\n            // @ts-expect-error\n            `${LOCAL_EVENT_PREFIX}.speaker.updated`,\n            action.payload\n          )\n\n          room.settleCustomSagaTrigger({\n            dispatchId: action.dispatchId,\n            payload: response,\n            kind: 'resolve',\n          })\n          break\n      }\n    } catch (error) {\n      room.settleCustomSagaTrigger({\n        dispatchId: action.dispatchId,\n        payload: error,\n        kind: 'reject',\n      })\n      getLogger().error(error)\n    }\n  }\n}\n\nfunction* audioElementSetupWorker({\n  track,\n  element,\n  speakerId,\n  room,\n}: {\n  track: MediaStreamTrack\n  element: HTMLAudioElement\n  speakerId?: string\n  room: VideoRoomSessionConnection\n}): SagaIterator {\n  setAudioMediaTrack({ track, element })\n  if (speakerId) {\n    // Catch no-op since setMediaElementSinkId already provides logs\n    setMediaElementSinkId(element, speakerId).catch(() => {})\n  }\n\n  yield sagaEffects.fork(audioElementActionsWatcher, {\n    element,\n    room,\n  })\n}\n","const setAudioMediaTrack = ({\n  track,\n  element,\n}: {\n  track: MediaStreamTrack\n  element: HTMLAudioElement\n}) => {\n  element.autoplay = true\n  // @ts-ignore\n  element.playsinline = true\n  element.srcObject = new MediaStream([track])\n\n  track.addEventListener('ended', () => {\n    element.srcObject = null\n    element.remove()\n  })\n\n  return element\n}\n\nexport { setAudioMediaTrack }\n","import { actions } from '@signalwire/core'\n\nexport const audioSetSpeakerAction = actions.createAction<string>(\n  'swJs/audioSetSpeakerAction'\n)\n","import {\n  BaseComponentOptions,\n  VideoManagerRoomEventNames,\n  connect,\n  ConsumerContract,\n  validateEventsToSubscribe,\n  EventEmitter,\n  BaseConsumer,\n  ToExternalJSONResult,\n  VideoManagerRoomEventParams,\n  InternalVideoManagerRoomEntity,\n  RoomsSubscribed,\n} from '@signalwire/core'\nimport { videoManagerWorker } from './workers'\n\n/** @internal */\nexport type VideoManagerEvents = Record<\n  VideoManagerRoomEventNames,\n  (room: ToExternalJSONResult<VideoManagerRoomEventParams>) => void\n> &\n  Record<\n    RoomsSubscribed,\n    (room: {\n      rooms: ToExternalJSONResult<InternalVideoManagerRoomEntity>[]\n    }) => void\n  >\n\n/** @internal */\nexport interface VideoManager extends ConsumerContract<VideoManagerEvents> {}\n\n/** @internal */\nexport class VideoManagerAPI extends BaseConsumer<VideoManagerEvents> {\n  constructor(options: BaseComponentOptions) {\n    super(options)\n\n    this.runWorker('videoManagerWorker', {\n      worker: videoManagerWorker,\n    })\n  }\n\n  /** @internal */\n  protected override getSubscriptions() {\n    const eventNamesWithPrefix = this.eventNames().map(\n      (event) => `video-manager.${event}`\n    ) as EventEmitter.EventNames<VideoManagerEvents>[]\n    return validateEventsToSubscribe(eventNamesWithPrefix)\n  }\n}\n\nexport const createVideoManagerObject = (params: BaseComponentOptions) => {\n  const manager = connect<VideoManagerEvents, VideoManagerAPI, VideoManager>({\n    store: params.store,\n    Component: VideoManagerAPI,\n  })(params)\n\n  const proxy = new Proxy<VideoManager>(manager, {\n    get(\n      target: VideoManager,\n      property: string | symbol,\n      receiver: ProxyHandler<VideoManager>\n    ) {\n      if (property === '_eventsNamespace') {\n        return ''\n      } else if (property === 'eventChannel') {\n        return 'video-manager.rooms'\n      }\n\n      return Reflect.get(target, property, receiver)\n    },\n  })\n  return proxy\n}\n","import { getLogger, sagaEffects } from '@signalwire/core'\nimport type {\n  SagaIterator,\n  MapToPubSubShape,\n  VideoManagerEvent,\n  SDKWorker,\n  SDKActions,\n  SDKWorkerParams,\n} from '@signalwire/core'\nimport type { VideoManager } from '../VideoManager'\nimport { videoManagerRoomsWorker } from './videoManagerRoomsWorker'\nimport { videoManagerRoomWorker } from './videoManagerRoomWorker'\n\nexport type VideoManagerWorkerParams<T> = SDKWorkerParams<VideoManager> & {\n  action: T\n}\n\nexport const videoManagerWorker: SDKWorker<VideoManager> = function* (\n  options\n): SagaIterator {\n  getLogger().trace('videoManagerWorker started')\n  const {\n    channels: { swEventChannel },\n  } = options\n\n  function* worker(action: MapToPubSubShape<VideoManagerEvent>) {\n    const { type } = action\n\n    switch (type) {\n      case 'video-manager.rooms.subscribed':\n        yield sagaEffects.fork(videoManagerRoomsWorker, {\n          action,\n          ...options,\n        })\n        break\n      case 'video-manager.room.added':\n      case 'video-manager.room.deleted':\n      case 'video-manager.room.ended':\n      case 'video-manager.room.started':\n      case 'video-manager.room.updated':\n        yield sagaEffects.fork(videoManagerRoomWorker, {\n          action,\n          ...options,\n        })\n        break\n      default:\n        getLogger().warn(`Unknown video-manager event: \"${type}\"`)\n        break\n    }\n  }\n\n  while (true) {\n    const action: MapToPubSubShape<VideoManagerEvent> = yield sagaEffects.take(\n      swEventChannel,\n      (action: SDKActions) => {\n        return action.type.startsWith('video-manager.')\n      }\n    )\n\n    yield sagaEffects.fork(worker, action)\n  }\n\n  getLogger().trace('videoManagerWorker ended')\n}\n","import {\n  getLogger,\n  SagaIterator,\n  MapToPubSubShape,\n  VideoManagerRoomsSubscribedEvent,\n  toExternalJSON,\n  VideoManagerRoomEventNames,\n  stripNamespacePrefix,\n} from '@signalwire/core'\nimport { VideoManagerWorkerParams } from './videoManagerWorker'\n\nexport const videoManagerRoomsWorker = function* (\n  options: VideoManagerWorkerParams<\n    MapToPubSubShape<VideoManagerRoomsSubscribedEvent>\n  >\n): SagaIterator {\n  getLogger().trace('videoManagerRoomsWorker started')\n  const {\n    instance: client,\n    action: { type, payload },\n  } = options\n\n  // For now we expose the transformed payload and not a RoomSession\n  const modPayload = {\n    rooms: payload.rooms.map((row) => toExternalJSON(row)),\n  }\n  client.emit(\n    stripNamespacePrefix(type) as VideoManagerRoomEventNames,\n    // @ts-expect-error\n    modPayload\n  )\n\n  getLogger().trace('videoManagerRoomsWorker ended')\n}\n","import {\n  getLogger,\n  SagaIterator,\n  MapToPubSubShape,\n  VideoManagerRoomEvent,\n  toExternalJSON,\n  VideoManagerRoomEventNames,\n  stripNamespacePrefix,\n} from '@signalwire/core'\nimport { VideoManagerWorkerParams } from './videoManagerWorker'\n\nexport const videoManagerRoomWorker = function* (\n  options: VideoManagerWorkerParams<MapToPubSubShape<VideoManagerRoomEvent>>\n): SagaIterator {\n  getLogger().trace('videoManagerRoomWorker started')\n  const {\n    instance: client,\n    action: { type, payload },\n  } = options\n\n  // For now we expose the transformed payload and not a RoomSession\n  client.emit(\n    stripNamespacePrefix(type) as VideoManagerRoomEventNames,\n    toExternalJSON(payload)\n  )\n\n  getLogger().trace('videoManagerRoomWorker ended')\n}\n","import {\n  FabricLayoutChangedEventParams,\n  VideoLayoutChangedEventParams,\n  getLogger,\n  uuid,\n} from '@signalwire/core'\nimport {\n  buildVideo,\n  cleanupElement,\n  createRootElementResizeObserver,\n  makeLayoutChangedHandler,\n  setVideoMediaTrack,\n  waitForVideoReady,\n} from './utils/videoElement'\nimport { addSDKPrefix } from './utils/roomSession'\nimport { OverlayMap, LocalVideoOverlay } from './VideoOverlays'\nimport {\n  FabricRoomSession,\n  isFabricRoomSession,\n} from './fabric/FabricRoomSession'\nimport { VideoRoomSession, isVideoRoomSession } from './video/VideoRoomSession'\n\nexport interface BuildVideoElementParams {\n  applyLocalVideoOverlay?: boolean\n  applyMemberOverlay?: boolean\n  mirrorLocalVideoOverlay?: boolean\n  room: FabricRoomSession | VideoRoomSession\n  rootElement?: HTMLElement\n}\n\nexport interface BuildVideoElementReturnType {\n  element: HTMLElement\n  overlayMap: OverlayMap\n  localVideoOverlay: LocalVideoOverlay\n  unsubscribe(): void\n}\n\nexport const buildVideoElement = async (\n  params: BuildVideoElementParams\n): Promise<BuildVideoElementReturnType> => {\n  try {\n    const {\n      room,\n      rootElement: element,\n      applyLocalVideoOverlay = true,\n      applyMemberOverlay = true,\n      mirrorLocalVideoOverlay = true,\n    } = params\n\n    let hasVideoTrack = false\n    const overlayMap: OverlayMap = new Map()\n    const id = uuid()\n\n    let rootElement: HTMLElement\n    if (element) {\n      rootElement = element\n    } else {\n      rootElement = document.createElement('div')\n      rootElement.id = `rootElement-${id}`\n    }\n\n    /**\n     * We used this `LocalVideoOverlay` class to interact with the localVideo\n     * overlay DOM element in here and in the `makeLayoutChangedHandler`.\n     */\n    const overlayId = addSDKPrefix(id)\n    const localVideoOverlay = new LocalVideoOverlay({\n      id: overlayId,\n      mirrorLocalVideoOverlay,\n      room,\n    })\n    if (applyLocalVideoOverlay) {\n      overlayMap.set(overlayId, localVideoOverlay)\n    }\n\n    const makeLayout = makeLayoutChangedHandler({\n      applyLocalVideoOverlay,\n      applyMemberOverlay,\n      overlayMap,\n      localVideoOverlay,\n      mirrorLocalVideoOverlay,\n      rootElement,\n    })\n\n    const processLayoutChanged = (params: any) => {\n      // @ts-expect-error\n      const hasVideoSender = room.peer?.hasVideoSender\n      if (hasVideoSender && room.localStream) {\n        makeLayout({\n          layout: params.layout,\n          localStream: room.localStream,\n          memberId: room.memberId,\n        })\n      } else {\n        getLogger().debug(\n          'No local video sender or local stream, hiding local video overlay',\n          hasVideoSender,\n          room.localStream\n        )\n        localVideoOverlay.hide()\n      }\n    }\n\n    const layoutChangedHandler = (\n      params: FabricLayoutChangedEventParams | VideoLayoutChangedEventParams\n    ) => {\n      getLogger().debug('Received layout.changed - videoTrack', hasVideoTrack)\n      if (hasVideoTrack) {\n        processLayoutChanged(params)\n        return\n      }\n    }\n\n    const processVideoTrack = async (track: MediaStreamTrack) => {\n      hasVideoTrack = true\n\n      await videoElementSetup({\n        applyLocalVideoOverlay,\n        applyMemberOverlay,\n        rootElement,\n        track,\n      })\n\n      const roomCurrentLayoutEvent = room.currentLayoutEvent\n      // If the `layout.changed` has already been received, process the layout\n      if (roomCurrentLayoutEvent) {\n        processLayoutChanged(roomCurrentLayoutEvent)\n      }\n    }\n\n    // If the remote video already exist, inject the remote stream to the video element\n    // @ts-expect-error\n    const videoTrack = room.peer?.remoteVideoTrack as MediaStreamTrack | null\n    if (videoTrack) {\n      await processVideoTrack(videoTrack)\n    }\n\n    // Handle the RTCPeer `track` event\n    const trackHandler = async function (event: RTCTrackEvent) {\n      if (event.track.kind === 'video') {\n        await processVideoTrack(event.track)\n      }\n    }\n\n    const unsubscribe = () => {\n      cleanupElement(rootElement)\n      overlayMap.clear() // Use \"delete\" rather than \"clear\" if we want to update the reference\n      room.overlayMap = overlayMap\n      if (isFabricRoomSession(room)) {\n        room.off('track', trackHandler)\n        room.off('layout.changed', layoutChangedHandler)\n        room.off('destroy', unsubscribe)\n      } else if (isVideoRoomSession(room)) {\n        room.off('track', trackHandler)\n        room.off('layout.changed', layoutChangedHandler)\n        room.off('destroy', unsubscribe)\n      }\n      localVideoOverlay.detachListeners()\n    }\n\n    /**\n     * Using `on` instead of `once` (or `off` within trackHandler) because\n     * there are cases (promote/demote) where we need to handle multiple `track`\n     * events and update the videoEl with the new track.\n     */\n    if (isFabricRoomSession(room)) {\n      room.on('track', trackHandler)\n      room.on('layout.changed', layoutChangedHandler)\n      room.once('destroy', unsubscribe)\n    } else if (isVideoRoomSession(room)) {\n      room.on('track', trackHandler)\n      room.on('layout.changed', layoutChangedHandler)\n      room.once('destroy', unsubscribe)\n    }\n\n    /**\n     * The room object is only being used to listen for events.\n     * The \"buildVideoElement\" function does not directly manipulate the room object in order to maintain immutability.\n     * Currently, we are overriding the following room properties in case the user calls \"buildVideoElement\" more than once.\n     * However, this can be moved out of here easily if we prefer not to override.\n     */\n    room.overlayMap = overlayMap\n    room.localVideoOverlay = localVideoOverlay\n\n    return { element: rootElement, overlayMap, localVideoOverlay, unsubscribe }\n  } catch (error) {\n    getLogger().error('Unable to build the video element')\n    throw error\n  }\n}\n\ninterface VideoElementSetupWorkerParams {\n  rootElement: HTMLElement\n  track: MediaStreamTrack\n  applyLocalVideoOverlay?: boolean\n  applyMemberOverlay?: boolean\n}\n\nconst videoElementSetup = async (options: VideoElementSetupWorkerParams) => {\n  try {\n    const { applyLocalVideoOverlay, applyMemberOverlay, track, rootElement } =\n      options\n\n    // Create a video element\n    const videoElement = buildVideo()\n\n    setVideoMediaTrack({ element: videoElement, track })\n\n    videoElement.style.width = '100%'\n    videoElement.style.maxHeight = '100%'\n\n    if (rootElement.querySelector('.mcuContent')) {\n      getLogger().debug('MCU Content already there')\n      return\n    }\n\n    const mcuWrapper = document.createElement('div')\n    mcuWrapper.style.position = 'absolute'\n    mcuWrapper.style.top = '0'\n    mcuWrapper.style.left = '0'\n    mcuWrapper.style.right = '0'\n    mcuWrapper.style.bottom = '0'\n    mcuWrapper.appendChild(videoElement)\n\n    const paddingWrapper = document.createElement('div')\n    paddingWrapper.classList.add('paddingWrapper')\n    paddingWrapper.style.paddingBottom = '56.25%' // (9 / 16) * 100\n    paddingWrapper.style.position = 'relative'\n    paddingWrapper.style.width = '100%'\n    paddingWrapper.appendChild(mcuWrapper)\n\n    let layersWrapper: HTMLDivElement | null = null\n\n    // If the both flags are false, no need to create the MCU\n    if (applyLocalVideoOverlay || applyMemberOverlay) {\n      layersWrapper = document.createElement('div')\n      layersWrapper.classList.add('mcuLayers')\n      layersWrapper.style.display = 'none'\n      paddingWrapper.appendChild(layersWrapper)\n    }\n\n    const relativeWrapper = document.createElement('div')\n    relativeWrapper.classList.add('mcuContent')\n    relativeWrapper.style.position = 'relative'\n    relativeWrapper.style.width = '100%'\n    relativeWrapper.style.height = '100%'\n    relativeWrapper.style.margin = '0 auto'\n    relativeWrapper.style.display = 'flex'\n    relativeWrapper.style.alignItems = 'center'\n    relativeWrapper.style.justifyContent = 'center'\n    relativeWrapper.appendChild(paddingWrapper)\n\n    rootElement.style.width = '100%'\n    rootElement.style.height = '100%'\n    rootElement.appendChild(relativeWrapper)\n\n    getLogger().debug('MCU readyState 1 >>', videoElement.readyState)\n    if (videoElement.readyState === HTMLMediaElement.HAVE_NOTHING) {\n      getLogger().debug('Wait for the MCU to be ready')\n      await waitForVideoReady({ element: videoElement })\n    }\n    getLogger().debug('MCU is ready..')\n\n    /**\n     * Listen for the rootElement and the videoElement size changes and update the paddingWrapper.\n     * The ResizeObserver and the video \"resize\" event make sure:\n     * - The video should always maintain the aspect ratio.\n     * - The video should not overflow the user passed rootElement.\n     * - The video should not be cropped.\n     */\n    const rootElementResizeObserver = createRootElementResizeObserver({\n      rootElement,\n      video: videoElement,\n      paddingWrapper,\n    })\n    rootElementResizeObserver.start()\n\n    track.addEventListener('ended', () => {\n      if (rootElementResizeObserver) {\n        rootElementResizeObserver.stop()\n      }\n    })\n\n    if (layersWrapper) {\n      layersWrapper.style.display = 'block'\n    }\n  } catch (error) {\n    getLogger().error('Handle video track error', error)\n  }\n}\n","import {\n  getLogger,\n  InternalVideoLayoutLayer,\n  InternalVideoLayout,\n  debounce,\n  uuid,\n} from '@signalwire/core'\nimport { OverlayMap, LocalVideoOverlay, UserOverlay } from '../VideoOverlays'\nimport { addOverlayPrefix } from './roomSession'\n\nconst buildVideo = () => {\n  const video = document.createElement('video')\n  video.muted = true\n  video.autoplay = true\n  video.playsInline = true\n\n  /**\n   * Local and Remote video elements should never be paused\n   * and Safari/Firefox pause the video (ie: enabling PiP, switch cameras etc)\n   * We try to force it to keep playing.\n   */\n  video.addEventListener('pause', () => {\n    video.play().catch((error) => {\n      getLogger().error('Video Element Paused', video, error)\n    })\n  })\n\n  return video\n}\n\nconst waitForVideoReady = ({ element }: { element: HTMLVideoElement }) => {\n  return new Promise<void>((resolve) => {\n    element.addEventListener('canplay', function listener() {\n      element.removeEventListener('canplay', listener)\n      resolve()\n    })\n    element.addEventListener('resize', function listener() {\n      element.removeEventListener('resize', listener)\n      resolve()\n    })\n  })\n}\n\nconst _getLocationStyles = ({\n  x,\n  y,\n  width,\n  height,\n}: InternalVideoLayoutLayer) => {\n  return {\n    top: `${y}%`,\n    left: `${x}%`,\n    width: `${width}%`,\n    height: `${height}%`,\n  }\n}\n\nconst _buildLayer = ({ location }: { location: InternalVideoLayoutLayer }) => {\n  const { top, left, width, height } = _getLocationStyles(location)\n  const layer = document.createElement('div')\n  layer.style.position = 'absolute'\n  layer.style.overflow = 'hidden'\n  layer.style.top = top\n  layer.style.left = left\n  layer.style.width = width\n  layer.style.height = height\n\n  return layer\n}\n\nconst _updateLayer = ({\n  location,\n  element,\n}: {\n  location: InternalVideoLayoutLayer\n  element: HTMLElement\n}) => {\n  const { top, left, width, height } = _getLocationStyles(location)\n  element.style.top = top\n  element.style.left = left\n  element.style.width = width\n  element.style.height = height\n\n  return element\n}\n\ninterface MakeLayoutChangedHandlerParams {\n  applyLocalVideoOverlay?: boolean\n  applyMemberOverlay?: boolean\n  overlayMap: OverlayMap\n  localVideoOverlay: LocalVideoOverlay\n  mirrorLocalVideoOverlay?: boolean\n  rootElement: HTMLElement\n}\n\ninterface LayoutChangedHandlerParams {\n  layout: InternalVideoLayout\n  memberId: string\n  localStream: MediaStream\n}\n\nconst makeLayoutChangedHandler = (params: MakeLayoutChangedHandlerParams) => {\n  const {\n    applyLocalVideoOverlay,\n    applyMemberOverlay,\n    overlayMap,\n    localVideoOverlay,\n    mirrorLocalVideoOverlay,\n    rootElement,\n  } = params\n\n  return async (params: LayoutChangedHandlerParams) => {\n    getLogger().debug('Process layout.changed')\n    try {\n      const { layout, memberId, localStream } = params\n      const { layers = [] } = layout\n      const mcuLayers = rootElement.querySelector('.mcuLayers')\n\n      // To handle the DOM updates in batch\n      const fragment = document.createDocumentFragment()\n      const currentOverlayIds = new Set()\n\n      // Make local video overlay for the self member\n      if (applyLocalVideoOverlay) {\n        const location = layers.find(({ member_id }) => member_id === memberId)\n        const overlayId = localVideoOverlay.id // LocalVideoOverlay ID is already unique\n        let myLayerEl = localVideoOverlay.domElement\n        currentOverlayIds.add(overlayId)\n\n        if (!location) {\n          getLogger().warn('Local video overlay location not found', memberId)\n          localVideoOverlay.status = 'hidden'\n          if (myLayerEl) {\n            // Should we remove it from the DOM and the OverlayMap?\n            localVideoOverlay.hide()\n          }\n        } else {\n          if (myLayerEl) {\n            getLogger().debug('Update local video overlay')\n            _updateLayer({ location, element: myLayerEl })\n          } else {\n            getLogger().debug('Build local video overlay')\n            myLayerEl = _buildLayer({ location })\n            myLayerEl.id = overlayId\n\n            const localVideo = buildVideo()\n            localVideo.srcObject = localStream\n            localVideo.disablePictureInPicture = true\n            localVideo.style.width = '100%'\n            localVideo.style.height = '100%'\n            localVideo.style.pointerEvents = 'none'\n            localVideo.style.objectFit = 'cover'\n\n            myLayerEl.appendChild(localVideo)\n            localVideoOverlay.domElement = myLayerEl\n\n            // Mirror the local video if user has requested it\n            if (mirrorLocalVideoOverlay) {\n              localVideoOverlay.setMirror()\n            }\n          }\n\n          // Show local overlay element only if the localStream has a valid video track\n          const hasVideo =\n            localStream\n              .getVideoTracks()\n              .filter((t) => t.enabled && t.readyState === 'live').length > 0\n          if (hasVideo && location.visible) {\n            localVideoOverlay.setMediaStream(localStream)\n            localVideoOverlay.show()\n          } else {\n            localVideoOverlay.hide()\n          }\n\n          // Append the local video overlay to the fragment\n          fragment.appendChild(myLayerEl)\n        }\n      }\n\n      // Make overlay for all members (including a self member)\n      if (applyMemberOverlay) {\n        layers.forEach((location) => {\n          const memberIdInLocation = location.member_id\n          if (!memberIdInLocation) return\n\n          const overlayId = addOverlayPrefix(memberIdInLocation)\n          currentOverlayIds.add(overlayId)\n\n          let overlay = overlayMap.get(overlayId)\n\n          if (overlay && overlay.domElement) {\n            // If the overlay already exists, modify its styles\n            getLogger().debug('Update an overlay for', memberIdInLocation)\n            _updateLayer({ location, element: overlay.domElement })\n          } else {\n            // If the overlay doesn't exist, create a new overlay\n            getLogger().debug('Build an overlay for', memberIdInLocation)\n            overlay = new UserOverlay({ id: overlayId })\n            overlayMap.set(overlayId, overlay)\n\n            const newLayer = _buildLayer({ location })\n            newLayer.id = `${overlayId}-${uuid()}` // Unique DOM ID since user is allowed to build multiple video elements\n\n            overlay.domElement = newLayer\n          }\n\n          if (!location.visible) {\n            overlay.hide()\n          } else {\n            overlay.show()\n          }\n\n          // Append the overlay element to the fragment\n          fragment.appendChild(overlay.domElement)\n        })\n      }\n\n      // Remove overlays that are no longer present\n      overlayMap.forEach((overlay, overlayId) => {\n        if (!currentOverlayIds.has(overlayId)) {\n          if (overlay.domElement && overlay.domElement.parentNode) {\n            overlay.domElement.parentNode.removeChild(overlay.domElement)\n          }\n          overlayMap.delete(overlayId)\n        }\n      })\n\n      // Replace mcuLayers content in batch with the fragment\n      if (mcuLayers) {\n        mcuLayers.innerHTML = ''\n        mcuLayers.appendChild(fragment)\n      }\n    } catch (error) {\n      getLogger().error('Layout Changed Error', error)\n    }\n  }\n}\n\nconst cleanupElement = (rootElement: HTMLElement) => {\n  while (rootElement.firstChild) {\n    rootElement.removeChild(rootElement.firstChild)\n  }\n}\n\nconst setVideoMediaTrack = ({\n  track,\n  element,\n}: {\n  track: MediaStreamTrack\n  element: HTMLVideoElement\n}) => {\n  element.srcObject = new MediaStream([track])\n\n  track.addEventListener('ended', () => {\n    element.srcObject = null\n    element.remove()\n  })\n}\n\nconst createRootElementResizeObserver = ({\n  video,\n  rootElement,\n  paddingWrapper,\n}: {\n  video: HTMLVideoElement\n  rootElement: HTMLElement\n  paddingWrapper: HTMLDivElement\n}) => {\n  const computePaddingWrapperWidth = (width: number, height: number) => {\n    const nativeVideoRatio = video.videoWidth / video.videoHeight\n    const rootElementRatio = width / height\n    if (nativeVideoRatio > rootElementRatio) {\n      return '100%'\n    } else {\n      return `${height * nativeVideoRatio}px`\n    }\n  }\n\n  // Debounce to avoid multiple calls\n  const update = debounce(\n    ({ width, height }: { width: number; height: number }) => {\n      const maxPaddingBottom = (video.videoHeight / video.videoWidth) * 100\n      if (paddingWrapper) {\n        const pb = (height / width) * 100\n        paddingWrapper.style.paddingBottom = `${\n          pb > maxPaddingBottom ? maxPaddingBottom : pb\n        }%`\n        paddingWrapper.style.width = computePaddingWrapperWidth(width, height)\n      }\n    },\n    100\n  )\n\n  const observer = new ResizeObserver((entries) => {\n    entries.forEach((entry) => {\n      if (entry.contentBoxSize) {\n        // Firefox implements `contentBoxSize` as a single content rect, rather than an array\n        const { inlineSize, blockSize } = Array.isArray(entry.contentBoxSize)\n          ? entry.contentBoxSize[0]\n          : entry.contentBoxSize\n        update({ width: inlineSize, height: blockSize })\n      } else if (entry.contentRect) {\n        update({\n          width: entry.contentRect.width,\n          height: entry.contentRect.height,\n        })\n      }\n    })\n  })\n\n  /**\n   * When the intrinsic dimensions of the video changes, the root element resize may or may not trigger.\n   * For example; remote stream from the server changes dimensions from 16/9 (Landscape) to 9/16 (Portrait) mode.\n   * For this reason we need to listen for the 'resize' event on the video element.\n   */\n  const onVideoResize = () => {\n    const width = rootElement.clientWidth\n    const height = rootElement.clientHeight\n    update({ width, height })\n  }\n\n  return {\n    start: () => {\n      observer.observe(rootElement)\n      video.addEventListener('resize', onVideoResize)\n    },\n    stop: () => {\n      observer.disconnect()\n      video.removeEventListener('resize', onVideoResize)\n    },\n  }\n}\n\nexport {\n  buildVideo,\n  cleanupElement,\n  makeLayoutChangedHandler,\n  setVideoMediaTrack,\n  waitForVideoReady,\n  createRootElementResizeObserver,\n  LocalVideoOverlay,\n}\n","import { FabricMemberUpdatedEventParams, getLogger } from '@signalwire/core'\nimport { VideoRoomSession, isVideoRoomSession } from './video/VideoRoomSession'\nimport {\n  FabricRoomSession,\n  isFabricRoomSession,\n} from './fabric/FabricRoomSession'\nimport { VideoMemberUpdatedHandlerParams } from './utils/interfaces'\nimport { OVERLAY_PREFIX, SDK_PREFIX } from './utils/roomSession'\n\nexport type OverlayMap = Map<string, UserOverlay>\n\ninterface UserOverlayOptions {\n  id: string\n}\n\nexport type OverlayStatus = 'hidden' | 'visible'\n\nexport class UserOverlay {\n  public id: string\n  private _domElement: HTMLDivElement | undefined\n  private _status: OverlayStatus\n\n  constructor(options: UserOverlayOptions) {\n    this.id = options.id\n    this._status = 'hidden'\n  }\n\n  get userId() {\n    return this.id.split(OVERLAY_PREFIX)[1]\n  }\n\n  get domElement() {\n    return this._domElement\n  }\n\n  set domElement(element: HTMLDivElement | undefined) {\n    getLogger().debug('Setting domElement for ', this.id)\n    this._domElement = element\n  }\n\n  get status() {\n    return this._status\n  }\n\n  set status(status: OverlayStatus) {\n    this._status = status\n  }\n\n  public hide() {\n    if (!this.domElement) {\n      return getLogger().warn('Missing overlay to hide')\n    }\n    this.domElement.style.opacity = '0'\n    this.status = 'hidden'\n  }\n\n  public show() {\n    if (!this.domElement) {\n      return getLogger().warn('Missing overlay to show')\n    }\n    this.domElement.style.opacity = '1'\n    this.status = 'visible'\n  }\n}\n\ninterface LocalVideoOverlayOptions {\n  id: string\n  mirrorLocalVideoOverlay: boolean\n  room: FabricRoomSession | VideoRoomSession\n}\n\nexport class LocalVideoOverlay extends UserOverlay {\n  private _mirrored: boolean\n  private _room: FabricRoomSession | VideoRoomSession\n\n  constructor(options: LocalVideoOverlayOptions) {\n    super(options)\n    this._mirrored = options.mirrorLocalVideoOverlay\n    this._room = options.room\n\n    // Bind the handler to preserve context\n    this.fabricMemberVideoMutedHandler =\n      this.fabricMemberVideoMutedHandler.bind(this)\n    this.videoMemberVideoMutedHandler =\n      this.videoMemberVideoMutedHandler.bind(this)\n\n    this.attachListeners()\n  }\n\n  get userId() {\n    return this.id.split(SDK_PREFIX)[1]\n  }\n\n  get mirrored() {\n    return this._mirrored\n  }\n\n  private attachListeners() {\n    if (isFabricRoomSession(this._room)) {\n      this._room.on(\n        'member.updated.videoMuted',\n        this.fabricMemberVideoMutedHandler\n      )\n    } else if (isVideoRoomSession(this._room)) {\n      this._room.on(\n        'member.updated.videoMuted',\n        this.videoMemberVideoMutedHandler\n      )\n    }\n  }\n\n  /** @internal */\n  public detachListeners() {\n    if (isFabricRoomSession(this._room)) {\n      this._room.off(\n        'member.updated.videoMuted',\n        this.fabricMemberVideoMutedHandler\n      )\n    } else if (isVideoRoomSession(this._room)) {\n      this._room.off(\n        'member.updated.videoMuted',\n        this.videoMemberVideoMutedHandler\n      )\n    }\n  }\n\n  private memberVideoMutedHandler(memberId: string, videoMuted: boolean) {\n    try {\n      if (memberId === this._room.memberId) {\n        videoMuted ? this.hide() : this.show()\n      }\n    } catch (error) {\n      getLogger().error('Error handling videoMuted in LocalVideoOverlay', error)\n    }\n  }\n\n  private fabricMemberVideoMutedHandler(\n    params: FabricMemberUpdatedEventParams\n  ) {\n    this.memberVideoMutedHandler(\n      params.member.member_id,\n      params.member.video_muted\n    )\n  }\n\n  private videoMemberVideoMutedHandler(\n    params: VideoMemberUpdatedHandlerParams\n  ) {\n    this.memberVideoMutedHandler(params.member.id, params.member.video_muted)\n  }\n\n  public setMediaStream(stream: MediaStream) {\n    if (!this.domElement) {\n      return getLogger().warn('Missing local overlay to set the stream')\n    }\n    const localVideo = this.domElement.querySelector('video')\n    if (localVideo) {\n      localVideo.srcObject = stream\n    }\n  }\n\n  public setMirror(mirror: boolean = this._mirrored) {\n    if (!this.domElement || !this.domElement.firstChild) {\n      return getLogger().warn('Missing local overlay to set the mirror')\n    }\n    const videoEl = this.domElement.firstChild as HTMLVideoElement\n    videoEl.style.transform = mirror ? 'scale(-1, 1)' : 'scale(1, 1)'\n    videoEl.style.webkitTransform = mirror ? 'scale(-1, 1)' : 'scale(1, 1)'\n    this._mirrored = mirror\n  }\n}\n","import {\n  BaseComponentContract,\n  BaseConnectionContract,\n  connect,\n  EventEmitter,\n  extendComponent,\n  Rooms,\n  validateEventsToSubscribe,\n  VideoAuthorization,\n  VideoLayoutChangedEventParams,\n} from '@signalwire/core'\nimport { BaseConnectionOptions } from '@signalwire/webrtc'\nimport {\n  BaseRoomSessionConnection,\n  BaseRoomSessionOptions,\n} from '../BaseRoomSession'\nimport {\n  RoomSessionDevice,\n  RoomSessionDeviceAPI,\n  RoomSessionDeviceConnection,\n  RoomSessionDeviceEvents,\n} from '../RoomSessionDevice'\nimport * as workers from './workers'\nimport {\n  AddCameraOptions,\n  AddDeviceOptions,\n  AddMicrophoneOptions,\n  CreateScreenShareObjectOptions,\n  VideoRoomSessionMethods,\n  VideoRoomSessionEvents,\n  VideoRoomSessionContract,\n  BaseRoomSessionContract,\n} from '../utils/interfaces'\n\nexport interface VideoRoomSession\n  extends VideoRoomSessionContract,\n    VideoRoomSessionMethods,\n    BaseRoomSessionContract,\n    BaseConnectionContract<VideoRoomSessionEvents>,\n    BaseComponentContract {}\n\nexport interface VideoRoomSessionOptions extends BaseRoomSessionOptions {}\n\nexport class VideoRoomSessionConnection\n  extends BaseRoomSessionConnection<VideoRoomSessionEvents>\n  implements VideoRoomSessionContract\n{\n  private _deviceList = new Set<RoomSessionDevice>()\n  private _currentLayoutEvent: VideoLayoutChangedEventParams\n\n  constructor(options: VideoRoomSessionOptions) {\n    super(options)\n\n    this.initWorker()\n  }\n\n  set currentLayoutEvent(event: VideoLayoutChangedEventParams) {\n    this._currentLayoutEvent = event\n  }\n\n  get currentLayoutEvent() {\n    return this._currentLayoutEvent\n  }\n\n  get currentLayout() {\n    return this._currentLayoutEvent?.layout\n  }\n\n  get currentPosition() {\n    return this._currentLayoutEvent?.layout.layers.find(\n      (layer) => layer.member_id === this.memberId\n    )?.position\n  }\n\n  get deviceList() {\n    return Array.from(this._deviceList)\n  }\n\n  get interactivityMode() {\n    return this.select(({ session }) => {\n      const { authorization } = session\n      return (authorization as VideoAuthorization)?.join_as ?? ''\n    })\n  }\n\n  get permissions() {\n    return this.select(({ session }) => {\n      const { authorization } = session\n      return (authorization as VideoAuthorization)?.room?.scopes ?? []\n    })\n  }\n\n  private initWorker() {\n    this.runWorker('videoWorker', {\n      worker: workers.videoWorker,\n    })\n  }\n\n  /** @internal */\n  protected override getSubscriptions() {\n    const eventNamesWithPrefix = this.eventNames().map((event) => {\n      return `video.${String(event)}`\n    })\n    return validateEventsToSubscribe(\n      eventNamesWithPrefix\n    ) as EventEmitter.EventNames<{}>[]\n  }\n\n  /** @internal */\n  protected _finalize() {\n    this._deviceList.clear()\n\n    super._finalize()\n  }\n\n  /** @internal */\n  override async hangup(id?: string) {\n    this._deviceList.forEach((device) => {\n      device.leave()\n    })\n\n    return super.hangup(id)\n  }\n\n  join() {\n    return super.invite<VideoRoomSession>()\n  }\n\n  /**\n   * @deprecated Use {@link getLayouts} instead. `getLayoutList` will\n   * be removed in v3.0.0\n   */\n  getLayoutList() {\n    // @ts-expect-error\n    return this.getLayouts()\n  }\n\n  /**\n   * @deprecated Use {@link getMembers} instead. `getMemberList` will\n   * be removed in v3.0.0\n   */\n  getMemberList() {\n    // @ts-expect-error\n    return this.getMembers()\n  }\n\n  /** @deprecated Use {@link startScreenShare} instead. */\n  async createScreenShareObject(opts: CreateScreenShareObjectOptions = {}) {\n    return this.startScreenShare(opts)\n  }\n\n  /**\n   * Allow to add a camera to the room.\n   */\n  addCamera(opts: AddCameraOptions = {}) {\n    const { autoJoin = true, ...video } = opts\n    return this.addDevice({\n      autoJoin,\n      video,\n    })\n  }\n\n  /**\n   * Allow to add a microphone to the room.\n   */\n  addMicrophone(opts: AddMicrophoneOptions = {}) {\n    const { autoJoin = true, ...audio } = opts\n    return this.addDevice({\n      autoJoin,\n      audio,\n    })\n  }\n\n  /**\n   * Allow to add additional devices to the room like cameras or microphones.\n   */\n  async addDevice(opts: AddDeviceOptions = {}) {\n    return new Promise<RoomSessionDevice>(async (resolve, reject) => {\n      const { autoJoin = true, audio = false, video = false } = opts\n      if (!audio && !video) {\n        throw new TypeError(\n          'At least one of `audio` or `video` must be requested.'\n        )\n      }\n\n      const options: BaseConnectionOptions = {\n        ...this.options,\n        localStream: undefined,\n        remoteStream: undefined,\n        audio,\n        video,\n        additionalDevice: true,\n        recoverCall: false,\n        userVariables: {\n          ...(this.options?.userVariables || {}),\n          memberCallId: this.callId,\n          memberId: this.memberId,\n        },\n      }\n\n      const roomDevice = connect<\n        RoomSessionDeviceEvents,\n        RoomSessionDeviceConnection,\n        RoomSessionDevice\n      >({\n        store: this.store,\n        Component: RoomSessionDeviceAPI,\n      })(options)\n\n      roomDevice.once('destroy', () => {\n        roomDevice.emit('room.left')\n        this._deviceList.delete(roomDevice)\n      })\n\n      try {\n        roomDevice.runWorker('childMemberJoinedWorker', {\n          worker: workers.childMemberJoinedWorker,\n          onDone: () => resolve(roomDevice),\n          onFail: reject,\n          initialState: {\n            parentId: this.memberId,\n          },\n        })\n\n        this._deviceList.add(roomDevice)\n        if (autoJoin) {\n          return await roomDevice.join()\n        }\n        return resolve(roomDevice)\n      } catch (error) {\n        this.logger.error('RoomDevice Error', error)\n        reject(error)\n      }\n    })\n  }\n}\n\nexport const VideoRoomSessionAPI = extendComponent<\n  VideoRoomSessionConnection,\n  VideoRoomSessionMethods\n>(VideoRoomSessionConnection, {\n  audioMute: Rooms.audioMuteMember,\n  audioUnmute: Rooms.audioUnmuteMember,\n  videoMute: Rooms.videoMuteMember,\n  videoUnmute: Rooms.videoUnmuteMember,\n  deaf: Rooms.deafMember,\n  undeaf: Rooms.undeafMember,\n  setInputVolume: Rooms.setInputVolumeMember,\n  setOutputVolume: Rooms.setOutputVolumeMember,\n  setMicrophoneVolume: Rooms.setInputVolumeMember,\n  setSpeakerVolume: Rooms.setOutputVolumeMember,\n  setInputSensitivity: Rooms.setInputSensitivityMember,\n  removeMember: Rooms.removeMember,\n  removeAllMembers: Rooms.removeAllMembers,\n  getMembers: Rooms.getMembers,\n  getLayouts: Rooms.getLayouts,\n  setLayout: Rooms.setLayout,\n  setPositions: Rooms.setPositions,\n  setMemberPosition: Rooms.setMemberPosition,\n  hideVideoMuted: Rooms.hideVideoMuted,\n  showVideoMuted: Rooms.showVideoMuted,\n  getRecordings: Rooms.getRecordings,\n  startRecording: Rooms.startRecording,\n  getPlaybacks: Rooms.getPlaybacks,\n  play: Rooms.play,\n  setHideVideoMuted: Rooms.setHideVideoMuted,\n  getMeta: Rooms.getMeta,\n  setMeta: Rooms.setMeta,\n  updateMeta: Rooms.updateMeta,\n  deleteMeta: Rooms.deleteMeta,\n  getMemberMeta: Rooms.getMemberMeta,\n  setMemberMeta: Rooms.setMemberMeta,\n  updateMemberMeta: Rooms.updateMemberMeta,\n  deleteMemberMeta: Rooms.deleteMemberMeta,\n  promote: Rooms.promote,\n  demote: Rooms.demote,\n  getStreams: Rooms.getStreams,\n  startStream: Rooms.startStream,\n  lock: Rooms.lock,\n  unlock: Rooms.unlock,\n  setRaisedHand: Rooms.setRaisedHand,\n  setPrioritizeHandraise: Rooms.setPrioritizeHandraise,\n})\n\nexport const isVideoRoomSession = (room: unknown): room is VideoRoomSession => {\n  return room instanceof VideoRoomSessionConnection\n}\n\n/** @internal */\nexport const createVideoRoomSessionObject = (\n  params: VideoRoomSessionOptions\n): VideoRoomSession => {\n  const room = connect<\n    VideoRoomSessionEvents,\n    VideoRoomSessionConnection,\n    VideoRoomSession\n  >({\n    store: params.store,\n    customSagas: params.customSagas,\n    Component: VideoRoomSessionAPI,\n  })(params)\n\n  return room\n}\n","import {\n  BaseComponentContract,\n  BaseConnectionState,\n  connect,\n  EventEmitter,\n  LOCAL_EVENT_PREFIX,\n} from '@signalwire/core'\nimport {\n  BaseConnection,\n  BaseConnectionOptions,\n  createSpeakerDeviceWatcher,\n  getDisplayMedia,\n  getSpeakerById,\n  supportsMediaOutput,\n  MediaEventNames,\n} from '@signalwire/webrtc'\nimport { LocalVideoOverlay, OverlayMap } from './VideoOverlays'\nimport {\n  AudioElement,\n  BaseRoomSessionContract,\n  StartScreenShareOptions,\n} from './utils/interfaces'\nimport { SCREENSHARE_AUDIO_CONSTRAINTS } from './utils/constants'\nimport { addOverlayPrefix } from './utils/roomSession'\nimport { audioSetSpeakerAction } from './features/actions'\nimport {\n  RoomSessionScreenShare,\n  RoomSessionScreenShareAPI,\n  RoomSessionScreenShareConnection,\n  RoomSessionScreenShareEvents,\n} from './RoomSessionScreenShare'\nimport * as workers from './video/workers'\n\nexport interface BaseRoomSession<\n  EventTypes extends EventEmitter.ValidEventTypes = BaseRoomSessionEvents\n> extends BaseRoomSessionContract,\n    BaseConnection<EventTypes>,\n    BaseComponentContract {}\n\nexport interface BaseRoomSessionOptions extends BaseConnectionOptions {}\n\nexport class BaseRoomSessionConnection<\n    EventTypes extends EventEmitter.ValidEventTypes = BaseRoomSessionEvents\n  >\n  extends BaseConnection<EventTypes>\n  implements BaseRoomSessionContract\n{\n  private _screenShareList = new Set<RoomSessionScreenShare>()\n  private _audioEl: AudioElement\n  private _overlayMap: OverlayMap\n  private _localVideoOverlay: LocalVideoOverlay\n\n  get audioEl() {\n    return this._audioEl\n  }\n\n  set overlayMap(map: OverlayMap) {\n    this._overlayMap = map\n  }\n\n  get overlayMap() {\n    return this._overlayMap\n  }\n\n  set localVideoOverlay(overlay: LocalVideoOverlay) {\n    this._localVideoOverlay = overlay\n  }\n\n  get localVideoOverlay() {\n    return this._localVideoOverlay\n  }\n\n  get screenShareList() {\n    return Array.from(this._screenShareList)\n  }\n\n  private _attachSpeakerTrackListener() {\n    if (!supportsMediaOutput()) return\n\n    // @TODO: Stop the watcher when user leave/disconnects\n    createSpeakerDeviceWatcher().then((deviceWatcher) => {\n      deviceWatcher.on('removed', async (data) => {\n        const sinkId = this._audioEl.sinkId\n        const disconnectedSpeaker = data.changes.find((device) => {\n          const payloadDeviceId = device.payload.deviceId\n\n          return (\n            payloadDeviceId === sinkId ||\n            (payloadDeviceId === '' && sinkId === 'default') ||\n            (payloadDeviceId === 'default' && sinkId === '')\n          )\n        })\n        if (disconnectedSpeaker) {\n          this.emit('speaker.disconnected', {\n            deviceId: disconnectedSpeaker.payload.deviceId,\n            label: disconnectedSpeaker.payload.label,\n          })\n\n          /**\n           * In case the currently in-use speaker disconnects, OS by default fallbacks to the default speaker\n           * Set the sink id here to make the SDK consistent with the OS\n           */\n          await this._audioEl.setSinkId?.('')\n\n          const defaultSpeakers = await getSpeakerById('default')\n\n          if (!defaultSpeakers?.deviceId) return\n\n          // Emit the speaker.updated event since the OS will fallback to the default speaker\n          this.emit('speaker.updated', {\n            previous: {\n              deviceId: disconnectedSpeaker.payload.deviceId,\n              label: disconnectedSpeaker.payload.label,\n            },\n            current: {\n              deviceId: defaultSpeakers.deviceId,\n              label: defaultSpeakers.label,\n            },\n          })\n        }\n      })\n    })\n  }\n\n  /** @internal */\n  protected override _finalize() {\n    this._screenShareList.clear()\n\n    super._finalize()\n  }\n\n  /** @internal */\n  override async hangup(id?: string) {\n    this._screenShareList.forEach((screenShare) => {\n      screenShare.leave()\n    })\n\n    return super.hangup(id)\n  }\n\n  leave() {\n    return this.hangup()\n  }\n\n  /**\n   * This method will be called by `join()` right before the\n   * `connect()` happens and it's a way for us to control\n   * exactly when the workers are attached.\n   * @internal\n   */\n  attachPreConnectWorkers() {\n    this.runWorker('memberListUpdated', {\n      worker: workers.memberListUpdatedWorker,\n    })\n  }\n\n  /** @internal */\n  getAudioEl() {\n    if (this._audioEl) return this._audioEl\n    this._audioEl = new Audio()\n    this._attachSpeakerTrackListener()\n    return this._audioEl\n  }\n\n  getMemberOverlay(memberId: string) {\n    return this.overlayMap.get(addOverlayPrefix(memberId))\n  }\n\n  /**\n   * Allow sharing the screen within the room.\n   */\n  async startScreenShare(opts: StartScreenShareOptions = {}) {\n    return new Promise<RoomSessionScreenShare>(async (resolve, reject) => {\n      const {\n        autoJoin = true,\n        audio = false,\n        video = true,\n        layout,\n        positions,\n      } = opts\n      try {\n        const displayStream: MediaStream = await getDisplayMedia({\n          audio: audio === true ? SCREENSHARE_AUDIO_CONSTRAINTS : audio,\n          video,\n        })\n        const options: BaseConnectionOptions = {\n          ...this.options,\n          screenShare: true,\n          recoverCall: false,\n          localStream: displayStream,\n          remoteStream: undefined,\n          userVariables: {\n            ...(this.options?.userVariables || {}),\n            memberCallId: this.callId,\n            memberId: this.memberId,\n          },\n          layout,\n          positions,\n        }\n\n        const screenShare = connect<\n          RoomSessionScreenShareEvents,\n          RoomSessionScreenShareConnection,\n          RoomSessionScreenShare\n        >({\n          store: this.store,\n          Component: RoomSessionScreenShareAPI,\n        })(options)\n\n        /**\n         * Hangup if the user stop the screenShare from the\n         * native browser button or if the videoTrack ends.\n         */\n        displayStream.getVideoTracks().forEach((t) => {\n          t.addEventListener('ended', () => {\n            if (screenShare && screenShare.active) {\n              screenShare.leave()\n            }\n          })\n        })\n\n        screenShare.once('destroy', () => {\n          screenShare.emit('room.left')\n          this._screenShareList.delete(screenShare)\n        })\n\n        screenShare.runWorker('childMemberJoinedWorker', {\n          worker: workers.childMemberJoinedWorker,\n          onDone: () => resolve(screenShare),\n          onFail: reject,\n          initialState: {\n            parentId: this.memberId,\n          },\n        })\n\n        this._screenShareList.add(screenShare)\n        if (autoJoin) {\n          return await screenShare.join()\n        }\n        return resolve(screenShare)\n      } catch (error) {\n        this.logger.error('ScreenShare Error', error)\n        reject(error)\n      }\n    })\n  }\n\n  updateSpeaker({ deviceId }: { deviceId: string }) {\n    const prevId = this.audioEl.sinkId as string\n    this.once(\n      // @ts-expect-error\n      `${LOCAL_EVENT_PREFIX}.speaker.updated`,\n      async (newId: string) => {\n        const prevSpeaker = await getSpeakerById(prevId)\n        const newSpeaker = await getSpeakerById(newId)\n\n        const isSame = newSpeaker?.deviceId === prevSpeaker?.deviceId\n        if (!newSpeaker?.deviceId || isSame) return\n\n        this.emit('speaker.updated', {\n          previous: {\n            deviceId: prevSpeaker?.deviceId,\n            label: prevSpeaker?.label,\n          },\n          current: {\n            deviceId: newSpeaker.deviceId,\n            label: newSpeaker.label,\n          },\n        })\n      }\n    )\n\n    return this.triggerCustomSaga<undefined>(audioSetSpeakerAction(deviceId))\n  }\n}\n\ntype BaseRoomSessionEventsHandlerMap = Record<\n  BaseConnectionState,\n  (params: BaseRoomSession<BaseRoomSessionEvents>) => void\n> &\n  Record<MediaEventNames, () => void>\n\nexport type BaseRoomSessionEvents = {\n  [k in keyof BaseRoomSessionEventsHandlerMap]: BaseRoomSessionEventsHandlerMap[k]\n}\n\n/** @internal */\nexport const createBaseRoomSessionObject = (\n  params: BaseRoomSessionOptions\n): BaseRoomSession<BaseRoomSessionEvents> => {\n  const room = connect<\n    BaseRoomSessionEvents,\n    BaseRoomSessionConnection<BaseRoomSessionEvents>,\n    BaseRoomSession<BaseRoomSessionEvents>\n  >({\n    store: params.store,\n    customSagas: params.customSagas,\n    Component: BaseRoomSessionConnection,\n  })(params)\n\n  return room\n}\n","export const SCREENSHARE_AUDIO_CONSTRAINTS: MediaTrackConstraints = {\n  echoCancellation: true,\n  noiseSuppression: false,\n  autoGainControl: false,\n  // @ts-expect-error\n  googAutoGainControl: false,\n}\n","import { getLogger } from '@signalwire/core'\nimport type { VideoAuthorization } from '@signalwire/core'\nimport type { BaseRoomSessionJoinParams } from './interfaces'\n\ntype GetJoinMediaParamsOptions = BaseRoomSessionJoinParams & {\n  authorization: VideoAuthorization\n}\n/**\n * getJoinMediaParams returns whether the Join method must send/recv\n * audio and video.\n * Based on values on the Auth block (media allowed and join_as type)\n * it matches the user's preferences and return an object that tells\n * if the negotiation has to include sendrecv/sendonly or recvonly\n * for audio and video.\n */\nexport const getJoinMediaParams = (options: GetJoinMediaParamsOptions) => {\n  const {\n    authorization,\n    audio = true,\n    video = true,\n    sendAudio,\n    sendVideo,\n    receiveAudio,\n    receiveVideo,\n  } = options\n  getLogger().debug('getJoinMediaParams options', { ...options })\n  const { audio_allowed, video_allowed, join_as } = authorization\n  // Fallback to 'member' in case of null/undefined\n  const joinAs = join_as ?? 'member'\n  const canSend = joinAs === 'member'\n\n  const canSendAudio = canSend && audio_allowed === 'both'\n  const canSendVideo = canSend && video_allowed === 'both'\n  const canReceiveAudio = audio_allowed !== 'none'\n  const canReceiveVideo = video_allowed !== 'none'\n\n  const reqToSendAudio = Boolean(sendAudio ?? audio)\n  const reqToSendVideo = Boolean(sendVideo ?? video)\n  const reqToReceiveAudio = Boolean(receiveAudio ?? audio)\n  const reqToReceiveVideo = Boolean(receiveVideo ?? video)\n\n  if (!canSendAudio && reqToSendAudio) {\n    getLogger().info(\n      'Not allowed to send audio on this room. Default values will be used.'\n    )\n  }\n  if (!canSendVideo && reqToSendVideo) {\n    getLogger().info(\n      'Not allowed to send video on this room. Default values will be used.'\n    )\n  }\n  if (!canReceiveAudio && reqToReceiveAudio) {\n    getLogger().info(\n      'Not allowed to receive video from the room. Default values will be used.'\n    )\n  }\n  if (!canReceiveVideo && reqToReceiveVideo) {\n    getLogger().info(\n      'Not allowed to receive video from the room. Default values will be used.'\n    )\n  }\n  return {\n    mustSendAudio: canSendAudio && reqToSendAudio,\n    mustSendVideo: canSendVideo && reqToSendVideo,\n    mustRecvAudio: canReceiveAudio && reqToReceiveAudio,\n    mustRecvVideo: canReceiveVideo && reqToReceiveVideo,\n  }\n}\n\nexport const checkMediaParams = (\n  options: Record<string, boolean | undefined>\n) => {\n  // At least one value must be true\n  return Object.values(options).some(Boolean)\n}\n\nexport const SDK_PREFIX = 'sw-sdk-'\nexport const addSDKPrefix = (id: string) => {\n  return `${SDK_PREFIX}${id}`\n}\n\nexport const OVERLAY_PREFIX = 'sw-overlay-'\nexport const addOverlayPrefix = (id: string) => {\n  return `${OVERLAY_PREFIX}${id}`\n}\n","import {\n  Rooms,\n  extendComponent,\n  BaseConnectionContract,\n  RoomLeft,\n  RoomLeftEventParams,\n  BaseConnectionState,\n} from '@signalwire/core'\nimport { BaseConnection, MediaEventNames } from '@signalwire/webrtc'\nimport { RoomScreenShareMethods } from './utils/interfaces'\n\ntype RoomSessionScreenShareEventsHandlerMap = Record<\n  BaseConnectionState,\n  (params: RoomSessionScreenShare) => void\n> &\n  Record<RoomLeft, (params?: RoomLeftEventParams) => void> &\n  Record<MediaEventNames, () => void>\n\nexport type RoomSessionScreenShareEvents = {\n  [k in keyof RoomSessionScreenShareEventsHandlerMap]: RoomSessionScreenShareEventsHandlerMap[k]\n}\n\n/** @deprecated Use {@link RoomSessionScreenShare} instead */\nexport interface RoomScreenShare extends RoomSessionScreenShare {}\nexport interface RoomSessionScreenShare\n  extends RoomScreenShareMethods,\n    BaseConnectionContract<RoomSessionScreenShareEvents> {\n  join(): Promise<void>\n  leave(): Promise<void>\n  /** @internal */\n  runWorker: BaseConnection<RoomSessionScreenShareEvents>['runWorker']\n}\n\nexport class RoomSessionScreenShareConnection extends BaseConnection<RoomSessionScreenShareEvents> {\n  join() {\n    return super.invite()\n  }\n\n  leave() {\n    return super.hangup()\n  }\n}\n\n/**\n * Represents a screen sharing.\n */\nexport const RoomSessionScreenShareAPI = extendComponent<\n  RoomSessionScreenShareConnection,\n  RoomScreenShareMethods\n>(RoomSessionScreenShareConnection, {\n  audioMute: Rooms.audioMuteMember,\n  audioUnmute: Rooms.audioUnmuteMember,\n  videoMute: Rooms.videoMuteMember,\n  videoUnmute: Rooms.videoUnmuteMember,\n  setMicrophoneVolume: Rooms.setInputVolumeMember,\n  setInputVolume: Rooms.setInputVolumeMember,\n  setInputSensitivity: Rooms.setInputSensitivityMember,\n})\n","import {\n  sagaEffects,\n  SagaIterator,\n  SDKWorker,\n  toSyntheticEvent,\n  validateEventsToSubscribe,\n  toInternalEventName,\n  SwEventChannel,\n  InternalVideoMemberEntity,\n  InternalVideoMemberUpdatedEvent,\n  VideoMemberJoinedEvent,\n  VideoMemberLeftEvent,\n  VideoMemberUpdatedEvent,\n  InternalVideoRoomJoinedEvent,\n  MapToPubSubShape,\n} from '@signalwire/core'\nimport type { VideoMemberListUpdatedParams } from '../../utils/interfaces'\nimport { VideoRoomSession } from '../VideoRoomSession'\n\nconst noop = () => {}\n\nconst EXTERNAL_MEMBER_LIST_UPDATED_EVENT = 'memberList.updated'\n\nconst INTERNAL_MEMBER_LIST_UPDATED_EVENT = toInternalEventName({\n  event: EXTERNAL_MEMBER_LIST_UPDATED_EVENT,\n})\n\nconst SYNTHETIC_MEMBER_LIST_UPDATED_EVENT = toSyntheticEvent(\n  INTERNAL_MEMBER_LIST_UPDATED_EVENT\n)\n\n/**\n * List of action types this worker cares about.\n */\ntype MemberListUpdatedTargetActions = MapToPubSubShape<\n  | InternalVideoRoomJoinedEvent\n  | InternalVideoMemberUpdatedEvent\n  | VideoMemberJoinedEvent\n  | VideoMemberLeftEvent\n  | VideoMemberUpdatedEvent\n>\n\nconst MEMBER_LIST_EVENTS: Array<MemberListUpdatedTargetActions['type']> = [\n  /** Alias to `video.room.subscribed` */\n  'video.room.joined',\n  'video.member.joined',\n  'video.member.left',\n  'video.member.updated',\n]\n\ntype MemberList = Map<string, InternalVideoMemberEntity>\n\nconst isMemberListEvent = (\n  event: string\n): event is MemberListUpdatedTargetActions['type'] => {\n  // @ts-expect-error\n  return MEMBER_LIST_EVENTS.includes(event)\n}\n\nconst getMemberListEventsToSubscribe = (\n  subscriptions: MemberListUpdatedTargetActions['type'][]\n) => {\n  return validateEventsToSubscribe(MEMBER_LIST_EVENTS).filter((event) => {\n    return !subscriptions.includes(event)\n  })\n}\n\nconst shouldHandleMemberList = (subscriptions: string[]) => {\n  return subscriptions.some((event) =>\n    event.includes(EXTERNAL_MEMBER_LIST_UPDATED_EVENT)\n  )\n}\n\nconst getMembersFromAction = (action: MemberListUpdatedTargetActions) => {\n  if (action.type === 'video.room.joined') {\n    return action.payload.room_session.members\n  }\n\n  return [action.payload.member]\n}\n\nexport const getUpdatedMembers = ({\n  action,\n  memberList,\n}: {\n  action: MemberListUpdatedTargetActions\n  memberList: MemberList\n}) => {\n  const actionMembers = getMembersFromAction(action)\n\n  switch (action.type) {\n    case 'video.member.left':\n      actionMembers.forEach((member: InternalVideoMemberEntity) => {\n        memberList.delete(member.id)\n      })\n      break\n    default:\n      actionMembers.forEach((member: InternalVideoMemberEntity) => {\n        memberList.set(member.id, member)\n      })\n  }\n\n  return Array.from(memberList.values())\n}\n\nconst initMemberListSubscriptions = (\n  room: VideoRoomSession,\n  subscriptions: MemberListUpdatedTargetActions['type'][]\n) => {\n  const events = getMemberListEventsToSubscribe(subscriptions)\n\n  events.forEach((event) => {\n    /**\n     * Params to `subscribe` come from the event handlers\n     * the user has attached so to make sure we subscribe to\n     * all the appropiate events needed for\n     * `memberList.updated` to work, we must subscribe to\n     * the required events. We don't need to act upon the\n     * event (that's why we attach a `noop`), just to\n     * register it (`subscribe` gets its values from\n     * `BaseComponent.getSubscriptions`, which gets\n     * populated by each of the  event handlers the user\n     * attached).\n     */\n    room.once(event as any, noop)\n  })\n\n  /**\n   * This handler will act as a simple bridge between\n   * synthetic events and external events.\n   */\n  const eventBridgeHandler = ({ members }: VideoMemberListUpdatedParams) => {\n    room.emit(EXTERNAL_MEMBER_LIST_UPDATED_EVENT, { members })\n  }\n\n  // @ts-expect-error\n  room.on(SYNTHETIC_MEMBER_LIST_UPDATED_EVENT, eventBridgeHandler)\n\n  /**\n   * Any events attached by the saga should be specified\n   * here so it can be cleaned up when needed.\n   */\n  const cleanup = () => {\n    // @ts-expect-error\n    room.off(SYNTHETIC_MEMBER_LIST_UPDATED_EVENT, eventBridgeHandler)\n  }\n\n  return {\n    cleanup,\n  }\n}\n\nfunction* membersListUpdatedWatcher({\n  swEventChannel,\n  instance,\n}: {\n  swEventChannel: SwEventChannel\n  instance: any\n}): SagaIterator {\n  const memberList: MemberList = new Map()\n\n  function* worker(pubSubAction: MemberListUpdatedTargetActions) {\n    const roomSessionId =\n      pubSubAction.type === 'video.room.joined'\n        ? pubSubAction.payload.room_session.id\n        : pubSubAction.payload.room_session_id\n\n    const members = getUpdatedMembers({ action: pubSubAction, memberList })\n    const memberListPayload = {\n      /**\n       * At this point it's needed to send the\n       * `room_session_id` so the pubSubSaga can properly\n       * infer the namespace for emitting the events to the\n       * appropiate room.\n       */\n      room_session_id: roomSessionId,\n      members,\n    }\n\n    instance.emit(SYNTHETIC_MEMBER_LIST_UPDATED_EVENT, memberListPayload)\n  }\n\n  while (true) {\n    const pubSubAction: MemberListUpdatedTargetActions = yield sagaEffects.take(\n      swEventChannel,\n      ({ type }: any) => {\n        return isMemberListEvent(type)\n      }\n    )\n\n    yield sagaEffects.fork(worker, pubSubAction)\n  }\n}\n\nexport const memberListUpdatedWorker: SDKWorker<VideoRoomSession> =\n  function* membersChangedWorker({\n    channels: { swEventChannel },\n    instance,\n  }): SagaIterator {\n    // @ts-expect-error\n    const subscriptions = instance.getSubscriptions()\n\n    if (!shouldHandleMemberList(subscriptions)) {\n      return\n    }\n\n    const { cleanup } = initMemberListSubscriptions(instance, subscriptions)\n\n    yield sagaEffects.fork(membersListUpdatedWatcher, {\n      swEventChannel,\n      instance,\n    })\n\n    instance.once('destroy', () => {\n      cleanup()\n    })\n  }\n","import {\n  getLogger,\n  sagaEffects,\n  SagaIterator,\n  SDKWorker,\n  SDKActions,\n  MapToPubSubShape,\n  SDKWorkerHooks,\n  VideoMemberJoinedEvent,\n  componentSelectors,\n  componentActions,\n  type ReduxComponent,\n} from '@signalwire/core'\n\nimport type { BaseConnection } from '@signalwire/webrtc'\n\ntype ChildMemberJoinedWorkerOnDone = () => void\ntype ChildMemberJoinedWorkerOnFail = (args: { error: Error }) => void\n\nexport type ChildMemberJoinedWorkerHooks = SDKWorkerHooks<\n  ChildMemberJoinedWorkerOnDone,\n  ChildMemberJoinedWorkerOnFail\n>\n\nexport const childMemberJoinedWorker: SDKWorker<\n  BaseConnection<any>,\n  ChildMemberJoinedWorkerHooks\n> = function* (options): SagaIterator {\n  getLogger().trace('childMemberJoinedWorker started')\n  const { channels, instance, initialState, onDone, onFail } = options\n  const { swEventChannel } = channels\n  const { parentId } = initialState\n  if (!parentId) {\n    throw new Error('Missing parentId for childMemberJoinedWorker')\n  }\n\n  const action: MapToPubSubShape<VideoMemberJoinedEvent> =\n    yield sagaEffects.take(swEventChannel, (action: SDKActions) => {\n      if (action.type === 'video.member.joined') {\n        return action.payload.member.parent_id === parentId\n      }\n      return false\n    })\n\n  /**\n   * On video.member.joined with a parent_id, check if we are the\n   * owner of the object comparing parent_id in the state.\n   * If so update the state with the room values to update the\n   * object.\n   */\n  const { member } = action.payload\n  if (member?.parent_id) {\n    const byId: Record<string, ReduxComponent> = yield sagaEffects.select(\n      componentSelectors.getComponentsById\n    )\n    const parent = Object.values(byId).find((row) => {\n      return 'memberId' in row && row.memberId === member.parent_id\n    })\n    if (parent) {\n      yield sagaEffects.put(\n        componentActions.upsert({\n          id: instance.callId,\n          roomId: action.payload.room_id,\n          roomSessionId: action.payload.room_session_id,\n          memberId: member.id,\n        })\n      )\n\n      onDone?.()\n    } else {\n      onFail?.({ error: new Error('Unknown parent_id') })\n    }\n  }\n  getLogger().trace('childMemberJoinedWorker ended')\n}\n","import {\n  SDKActions,\n  SDKWorker,\n  SagaIterator,\n  getLogger,\n  sagaEffects,\n  SDKWorkerParams,\n  MemberPosition,\n  stripNamespacePrefix,\n  VideoAction,\n  VideoRoomDeviceEventNames,\n  BaseConnectionState,\n} from '@signalwire/core'\nimport { videoStreamWorker } from './videoStreamWorker'\nimport { videoRecordWorker } from './videoRecordWorker'\nimport { videoPlaybackWorker } from './videoPlaybackWorker'\nimport { VideoRoomSessionConnection } from '../VideoRoomSession'\nimport { MediaEventNames } from '@signalwire/webrtc'\n\nexport type VideoWorkerParams<T> =\n  SDKWorkerParams<VideoRoomSessionConnection> & {\n    action: T\n  }\n\nexport const videoWorker: SDKWorker<VideoRoomSessionConnection> = function* (\n  options\n): SagaIterator {\n  getLogger().trace('videoWorker started')\n\n  const { channels, instance: roomSession } = options\n  const { swEventChannel } = channels\n\n  function* worker(action: VideoAction) {\n    const { type, payload } = action\n\n    switch (type) {\n      case 'video.room.subscribed':\n        yield sagaEffects.fork(MemberPosition.memberPositionWorker, {\n          ...options,\n          instance: roomSession,\n          initialState: payload,\n        })\n        return\n      case 'video.playback.started':\n      case 'video.playback.updated':\n      case 'video.playback.ended':\n        yield sagaEffects.fork(videoPlaybackWorker, {\n          action,\n          ...options,\n        })\n        return // Return since we don't need to handle the raw event for this\n      case 'video.recording.started':\n      case 'video.recording.updated':\n      case 'video.recording.ended':\n        yield sagaEffects.fork(videoRecordWorker, {\n          action,\n          ...options,\n        })\n        return\n      case 'video.stream.ended':\n      case 'video.stream.started':\n        yield sagaEffects.fork(videoStreamWorker, {\n          action,\n          ...options,\n        })\n        return\n      case 'video.room.audience_count': {\n        roomSession.emit('room.audienceCount', payload)\n        return\n      }\n      case 'video.member.talking': {\n        const { member } = payload\n        if ('talking' in member) {\n          const suffix = member.talking ? 'started' : 'ended'\n          roomSession.emit(`member.talking.${suffix}`, payload)\n\n          // Keep for backwards compat.\n          const deprecatedSuffix = member.talking ? 'start' : 'stop'\n          roomSession.emit(`member.talking.${deprecatedSuffix}`, payload)\n        }\n        break // Break here since we do need the raw event sent to the client\n      }\n      case 'video.layout.changed': {\n        // Upsert the layout event which is needed for buildVideoElement\n        roomSession.currentLayoutEvent = action.payload\n        break\n      }\n      default:\n        break\n    }\n\n    const event = stripNamespacePrefix(type, 'video') as\n      | VideoRoomDeviceEventNames\n      | MediaEventNames\n      | BaseConnectionState\n    roomSession.emit(event, payload)\n  }\n\n  const isVideoEvent = (action: SDKActions) => {\n    return action.type.startsWith('video.')\n  }\n\n  while (true) {\n    const action: VideoAction = yield sagaEffects.take(\n      swEventChannel,\n      isVideoEvent\n    )\n\n    yield sagaEffects.fork(worker, action)\n  }\n\n  getLogger().trace('videoWorker ended')\n}\n","import {\n  getLogger,\n  SagaIterator,\n  MapToPubSubShape,\n  VideoStreamEvent,\n  RoomSessionStream,\n  Rooms,\n} from '@signalwire/core'\nimport { VideoWorkerParams } from './videoWorker'\n\nexport const videoStreamWorker = function* (\n  options: VideoWorkerParams<MapToPubSubShape<VideoStreamEvent>>\n): SagaIterator {\n  getLogger().trace('videoStreamWorker started')\n  const {\n    instance: roomSession,\n    action: { type, payload },\n    instanceMap: { get, set, remove },\n  } = options\n\n  // For now, we are not storing the RoomSession object in the instance map\n\n  let streamInstance = get<RoomSessionStream>(payload.stream.id)\n  if (!streamInstance) {\n    streamInstance = Rooms.createRoomSessionStreamObject({\n      store: roomSession.store,\n      payload,\n    })\n  } else {\n    streamInstance.setPayload(payload)\n  }\n  set<RoomSessionStream>(payload.stream.id, streamInstance)\n\n  switch (type) {\n    case 'video.stream.started':\n      roomSession.emit('stream.started', streamInstance)\n      break\n    case 'video.stream.ended':\n      roomSession.emit('stream.ended', streamInstance)\n      remove<RoomSessionStream>(payload.stream.id)\n      break\n    default:\n      getLogger().warn(`Unknown video.stream event: \"${type}\"`)\n      break\n  }\n\n  getLogger().trace('videoStreamWorker ended')\n}\n","import {\n  getLogger,\n  SagaIterator,\n  MapToPubSubShape,\n  RoomSessionRecording,\n  Rooms,\n  VideoRecordingEvent,\n  VideoRecordingEventNames,\n  stripNamespacePrefix,\n} from '@signalwire/core'\nimport { VideoWorkerParams } from './videoWorker'\n\nexport const videoRecordWorker = function* (\n  options: VideoWorkerParams<MapToPubSubShape<VideoRecordingEvent>>\n): SagaIterator {\n  getLogger().trace('videoRecordWorker started')\n  const {\n    instance: roomSession,\n    action: { type, payload },\n    instanceMap: { get, set, remove },\n  } = options\n\n  // For now, we are not storing the RoomSession object in the instance map\n\n  let recordingInstance = get<RoomSessionRecording>(payload.recording.id)\n  if (!recordingInstance) {\n    recordingInstance = Rooms.createRoomSessionRecordingObject({\n      store: roomSession.store,\n      payload,\n    })\n  } else {\n    recordingInstance.setPayload(payload)\n  }\n  set<RoomSessionRecording>(payload.recording.id, recordingInstance)\n\n  const event = stripNamespacePrefix(type) as VideoRecordingEventNames\n\n  switch (type) {\n    case 'video.recording.started':\n    case 'video.recording.updated': {\n      roomSession.emit(event, recordingInstance)\n      break\n    }\n    case 'video.recording.ended':\n      roomSession.emit(event, recordingInstance)\n      remove<RoomSessionRecording>(payload.recording.id)\n      break\n    default:\n      getLogger().warn(`Unknown video.stream event: \"${type}\"`)\n      break\n  }\n\n  getLogger().trace('videoRecordWorker ended')\n}\n","import {\n  getLogger,\n  SagaIterator,\n  MapToPubSubShape,\n  RoomSessionPlayback,\n  Rooms,\n  VideoPlaybackEvent,\n  VideoPlaybackEventNames,\n  stripNamespacePrefix,\n} from '@signalwire/core'\nimport { VideoWorkerParams } from './videoWorker'\n\nexport const videoPlaybackWorker = function* (\n  options: VideoWorkerParams<MapToPubSubShape<VideoPlaybackEvent>>\n): SagaIterator {\n  getLogger().trace('videoPlaybackWorker started')\n  const {\n    instance: roomSession,\n    action: { type, payload },\n    instanceMap: { get, set, remove },\n  } = options\n\n  // For now, we are not storing the RoomSession object in the instance map\n\n  let playbackInstance = get<RoomSessionPlayback>(payload.playback.id)\n  if (!playbackInstance) {\n    playbackInstance = Rooms.createRoomSessionPlaybackObject({\n      store: roomSession.store,\n      payload,\n    })\n  } else {\n    playbackInstance.setPayload(payload)\n  }\n  set<RoomSessionPlayback>(payload.playback.id, playbackInstance)\n\n  const event = stripNamespacePrefix(type) as VideoPlaybackEventNames\n\n  switch (type) {\n    case 'video.playback.started':\n    case 'video.playback.updated': {\n      roomSession.emit(event, playbackInstance)\n      break\n    }\n    case 'video.playback.ended':\n      roomSession.emit(event, playbackInstance)\n      remove<RoomSessionPlayback>(payload.playback.id)\n      break\n    default:\n      getLogger().warn(`Unknown video.stream event: \"${type}\"`)\n      break\n  }\n\n  getLogger().trace('videoPlaybackWorker ended')\n}\n","import {\n  Rooms,\n  extendComponent,\n  BaseConnectionContract,\n  RoomLeft,\n  RoomLeftEventParams,\n  BaseConnectionState,\n} from '@signalwire/core'\nimport { BaseConnection, MediaEventNames } from '@signalwire/webrtc'\nimport { RoomSessionDeviceMethods } from './utils/interfaces'\n\ntype RoomSessionDeviceEventsHandlerMap = Record<\n  BaseConnectionState,\n  (params: RoomSessionDevice) => void\n> &\n  Record<RoomLeft, (params?: RoomLeftEventParams) => void> &\n  Record<MediaEventNames, () => void>\n\nexport type RoomSessionDeviceEvents = {\n  [k in keyof RoomSessionDeviceEventsHandlerMap]: RoomSessionDeviceEventsHandlerMap[k]\n}\n\n/** @deprecated Use {@link RoomSessionDevice} instead */\nexport interface RoomDevice extends RoomSessionDevice {}\nexport interface RoomSessionDevice\n  extends RoomSessionDeviceMethods,\n    BaseConnectionContract<RoomSessionDeviceEvents> {\n  join(): Promise<void>\n  leave(): Promise<void>\n  /** @internal */\n  runWorker: BaseConnection<RoomSessionDeviceEvents>['runWorker']\n}\n\nexport class RoomSessionDeviceConnection extends BaseConnection<RoomSessionDeviceEvents> {\n  join() {\n    return super.invite()\n  }\n\n  leave() {\n    return super.hangup()\n  }\n}\n\n/**\n * A RoomSessionDevice represents a device (such as a microphone or a camera)\n * that is at some point in its lifetime part of a {@link RoomSession}. You can\n * obtain a RoomSessionDevice from the {@link RoomSession} methods\n * {@link RoomSession.addCamera}, {@link RoomSession.addMicrophone}, and\n * {@link RoomSession.addDevice}.\n */\nexport const RoomSessionDeviceAPI = extendComponent<\n  RoomSessionDeviceConnection,\n  RoomSessionDeviceMethods\n>(RoomSessionDeviceConnection, {\n  audioMute: Rooms.audioMuteMember,\n  audioUnmute: Rooms.audioUnmuteMember,\n  videoMute: Rooms.videoMuteMember,\n  videoUnmute: Rooms.videoUnmuteMember,\n  setInputVolume: Rooms.setInputVolumeMember,\n  setMicrophoneVolume: Rooms.setInputVolumeMember,\n  setInputSensitivity: Rooms.setInputSensitivityMember,\n})\n","import {\n  connect,\n  BaseComponentContract,\n  BaseRPCResult,\n  FabricLayoutChangedEventParams,\n  ExecuteExtendedOptions,\n  Rooms,\n  VideoMemberEntity,\n  VideoPosition,\n  BaseConnectionContract,\n  FabricRoomSessionMethods,\n  MemberCommandParams,\n  MemberCommandWithVolumeParams,\n  MemberCommandWithValueParams,\n  SetAudioFlagsParams,\n  toSnakeCaseKeys,\n} from '@signalwire/core'\nimport {\n  BaseRoomSessionConnection,\n  BaseRoomSessionOptions,\n} from '../BaseRoomSession'\nimport {\n  BaseRoomSessionContract,\n  ExecuteMemberActionParams,\n  FabricRoomSessionContract,\n  FabricRoomSessionEvents,\n  RequestMemberParams,\n} from '../utils/interfaces'\nimport { getStorage } from '../utils/storage'\nimport { PREVIOUS_CALLID_STORAGE_KEY } from './utils/constants'\nimport { fabricWorker } from './workers'\nimport { FabricRoomSessionMember } from './FabricRoomSessionMember'\nimport { makeAudioElementSaga } from '../features/mediaElements/mediaElementsSagas'\nimport { CallCapabilitiesContract } from './interfaces/capabilities'\nimport { createFabricRoomSessionValidateProxy } from './utils/validationProxy'\n\nexport interface FabricRoomSession\n  extends FabricRoomSessionContract,\n    FabricRoomSessionMethods,\n    BaseRoomSessionContract,\n    BaseConnectionContract<FabricRoomSessionEvents>,\n    BaseComponentContract {}\n\nexport interface FabricRoomSessionOptions\n  extends Omit<BaseRoomSessionOptions, 'customSagas'> {}\n\nexport class FabricRoomSessionConnection\n  extends BaseRoomSessionConnection<FabricRoomSessionEvents>\n  implements FabricRoomSessionContract\n{\n  // this is \"self\" parameter required by the RPC, and is always \"the member\" on the 1st call segment\n  private _self?: FabricRoomSessionMember\n  // this is \"the member\" on the last/active call segment\n  private _member?: FabricRoomSessionMember\n  private _currentLayoutEvent: FabricLayoutChangedEventParams\n  //describes what are methods are allow for the user in a call segment\n  private _capabilities?: CallCapabilitiesContract\n\n  constructor(options: FabricRoomSessionOptions) {\n    super(options)\n\n    this.initWorker()\n  }\n\n  override get memberId() {\n    return this._member?.memberId\n  }\n\n  override dialogParams(rtcPeerId: string) {\n    const params = super.dialogParams(rtcPeerId)\n    params.dialogParams.attach = this.options.attach || this.resuming\n    params.dialogParams.reattaching = this.options.attach || this.resuming\n    return params\n  }\n\n  set currentLayoutEvent(event: FabricLayoutChangedEventParams) {\n    this._currentLayoutEvent = event\n  }\n\n  get currentLayoutEvent() {\n    return this._currentLayoutEvent\n  }\n\n  get currentLayout() {\n    return this._currentLayoutEvent?.layout\n  }\n\n  get currentPosition() {\n    return this._currentLayoutEvent?.layout.layers.find(\n      (layer) => layer.member_id === this.memberId\n    )?.position\n  }\n\n  get capabilities(): CallCapabilitiesContract | undefined {\n    return this._capabilities\n  }\n\n  set capabilities(capabilities: CallCapabilitiesContract | undefined) {\n    this._capabilities = capabilities\n  }\n\n  get selfMember(): FabricRoomSessionMember | undefined {\n    return this._self\n  }\n\n  set selfMember(member: FabricRoomSessionMember | undefined) {\n    this._self = member\n  }\n\n  set member(member: FabricRoomSessionMember) {\n    this._member = member\n  }\n\n  get member(): FabricRoomSessionMember {\n    return this._member!\n  }\n\n  private initWorker() {\n    this.runWorker('fabricWorker', {\n      worker: fabricWorker,\n    })\n\n    /**\n     * By default the SDK attaches the audio to\n     * an Audio element (regardless of \"rootElement\")\n     */\n    this.runWorker('makeAudioElement', {\n      worker: makeAudioElementSaga({\n        speakerId: this.options.speakerId,\n      }),\n    })\n  }\n\n  private async join() {\n    if (this.options.attach) {\n      this.options.prevCallId =\n        getStorage()?.getItem(PREVIOUS_CALLID_STORAGE_KEY) ?? undefined\n      this.logger.debug(\n        `Tying to reattach to previuos call? ${!!this.options\n          .prevCallId} - prevCallId: ${this.options.prevCallId}`\n      )\n    }\n\n    return super.invite<FabricRoomSession>()\n  }\n\n  private executeAction<\n    InputType,\n    OutputType = InputType,\n    ParamsType extends MemberCommandParams = MemberCommandParams\n  >(\n    params: ExecuteMemberActionParams,\n    options: ExecuteExtendedOptions<InputType, OutputType, ParamsType> = {}\n  ) {\n    const { method, channel, memberId, extraParams = {} } = params\n\n    const targetMember =\n      !memberId || memberId === 'all'\n        ? this.member\n        : this.instanceMap.get<FabricRoomSessionMember>(memberId)\n\n    if (!targetMember) {\n      throw new Error(\n        memberId && memberId !== 'all'\n          ? `Member ${memberId} not found`\n          : 'No target member available'\n      )\n    }\n\n    return this.execute<InputType, OutputType, ParamsType>(\n      {\n        method,\n        params: {\n          ...(channel && { channels: [channel] }),\n          self: {\n            member_id: this.selfMember?.id,\n            call_id: this.selfMember?.callId,\n            node_id: this.selfMember?.nodeId,\n          },\n          target: {\n            member_id: memberId === 'all' ? memberId : targetMember.id,\n            call_id: targetMember.callId,\n            node_id: targetMember.nodeId,\n          },\n          ...extraParams,\n        },\n      },\n      options\n    )\n  }\n\n  /** @internal */\n  public override async resume() {\n    this.logger.warn(`[resume] Call ${this.id}`)\n    if (this.peer?.instance) {\n      const { connectionState } = this.peer.instance\n      this.logger.debug(\n        `[resume] connectionState for ${this.id} is '${connectionState}'`\n      )\n      if (['closed', 'failed', 'disconnected'].includes(connectionState)) {\n        // should not resume when selfMember is defined (the SDK didn't lost its state since the `call.joined` was received)\n        this.resuming = !this.selfMember\n        this.peer.restartIce()\n      }\n    }\n  }\n\n  public async start() {\n    return new Promise<void>(async (resolve, reject) => {\n      try {\n        this.once('room.subscribed', (params) => {\n          getStorage()?.setItem(PREVIOUS_CALLID_STORAGE_KEY, params.call_id)\n          resolve()\n        })\n\n        this.once('destroy', () => {\n          getStorage()?.removeItem(PREVIOUS_CALLID_STORAGE_KEY)\n        })\n\n        await this.join()\n      } catch (error) {\n        this.logger.error('WSClient call start', error)\n        reject(error)\n      }\n    })\n  }\n\n  public async audioMute(params?: MemberCommandParams) {\n    return this.executeAction<BaseRPCResult>({\n      method: 'call.mute',\n      channel: 'audio',\n      memberId: params?.memberId,\n    })\n  }\n\n  public async audioUnmute(params?: MemberCommandParams) {\n    return this.executeAction<BaseRPCResult>({\n      method: 'call.unmute',\n      channel: 'audio',\n      memberId: params?.memberId,\n    })\n  }\n\n  public async videoMute(params?: MemberCommandParams) {\n    return this.executeAction<BaseRPCResult>({\n      method: 'call.mute',\n      channel: 'video',\n      memberId: params?.memberId,\n    })\n  }\n\n  public async videoUnmute(params?: MemberCommandParams) {\n    return this.executeAction<BaseRPCResult>({\n      method: 'call.unmute',\n      channel: 'video',\n      memberId: params?.memberId,\n    })\n  }\n\n  public async deaf(params?: MemberCommandParams) {\n    return this.executeAction<BaseRPCResult>({\n      method: 'call.deaf',\n      memberId: params?.memberId,\n    })\n  }\n\n  public async undeaf(params?: MemberCommandParams) {\n    return this.executeAction<BaseRPCResult>({\n      method: 'call.undeaf',\n      memberId: params?.memberId,\n    })\n  }\n\n  public async getLayouts() {\n    return this.executeAction<{ layouts: string[] }>(\n      {\n        method: 'call.layout.list',\n      },\n      {\n        transformResolve: (payload) => ({\n          layouts: payload.layouts,\n        }),\n      }\n    )\n  }\n\n  public async getMembers() {\n    return this.executeAction<{ members: VideoMemberEntity[] }>(\n      {\n        method: 'call.member.list',\n      },\n      {\n        transformResolve: (payload) => ({\n          members: payload.members,\n        }),\n      }\n    )\n  }\n\n  public async removeMember(params: Required<MemberCommandParams>) {\n    return this.executeAction<BaseRPCResult>({\n      method: 'call.member.remove',\n      memberId: params.memberId,\n    })\n  }\n\n  public async setRaisedHand(params?: Rooms.SetRaisedHandRoomParams) {\n    const { raised = true, memberId } = params || {}\n    return this.executeAction<BaseRPCResult>({\n      method: raised ? 'call.raisehand' : 'call.lowerhand',\n      memberId,\n    })\n  }\n\n  public async setLayout(params: Rooms.SetLayoutParams) {\n    const extraParams = {\n      layout: params.name,\n      positions: params.positions,\n    }\n    return this.executeAction<BaseRPCResult>({\n      method: 'call.layout.set',\n      extraParams,\n    })\n  }\n\n  public async setInputVolume(params: MemberCommandWithVolumeParams) {\n    return this.executeAction<BaseRPCResult>({\n      method: 'call.microphone.volume.set',\n      memberId: params.memberId,\n      extraParams: {\n        volume: params.volume,\n      },\n    })\n  }\n\n  public async setOutputVolume(params: MemberCommandWithVolumeParams) {\n    return this.executeAction<BaseRPCResult>({\n      method: 'call.speaker.volume.set',\n      memberId: params.memberId,\n      extraParams: {\n        volume: params.volume,\n      },\n    })\n  }\n\n  public async setInputSensitivity(params: MemberCommandWithValueParams) {\n    return this.executeAction<BaseRPCResult>({\n      method: 'call.microphone.sensitivity.set',\n      memberId: params.memberId,\n      extraParams: {\n        sensitivity: params.value,\n      },\n    })\n  }\n\n  public async setPositions(params: Rooms.SetPositionsParams) {\n    const targets: {\n      target: RequestMemberParams\n      position: VideoPosition\n    }[] = []\n\n    Object.entries(params.positions).forEach(([key, value]) => {\n      const targetMember =\n        key === 'self'\n          ? this.member\n          : this.instanceMap.get<FabricRoomSessionMember>(key)\n\n      if (targetMember) {\n        targets.push({\n          target: {\n            member_id: targetMember.id,\n            call_id: targetMember.callId!,\n            node_id: targetMember.nodeId!,\n          },\n          position: value,\n        })\n      }\n    })\n\n    if (!targets.length) {\n      throw new Error('Invalid targets')\n    }\n\n    return this.execute({\n      method: 'call.member.position.set',\n      params: {\n        self: {\n          member_id: this.selfMember?.id,\n          call_id: this.selfMember?.callId,\n          node_id: this.selfMember?.nodeId,\n        },\n        targets,\n      },\n    })\n  }\n\n  public async lock() {\n    return this.executeAction<BaseRPCResult>({\n      method: 'call.lock',\n    })\n  }\n\n  public async unlock() {\n    return this.executeAction<BaseRPCResult>({\n      method: 'call.unlock',\n    })\n  }\n\n  public async setAudioFlags(params: SetAudioFlagsParams) {\n    const { memberId, ...rest } = params\n    return this.executeAction<BaseRPCResult>({\n      method: 'call.audioflags.set',\n      memberId,\n      extraParams: toSnakeCaseKeys(rest),\n    })\n  }\n\n  public async end(params?: MemberCommandParams) {\n    return this.executeAction<BaseRPCResult>({\n      method: 'call.end',\n      memberId: params?.memberId,\n    })\n  }\n}\n\nexport const isFabricRoomSession = (\n  room: unknown\n): room is FabricRoomSession => {\n  return room instanceof FabricRoomSessionConnection\n}\n\n/** @internal */\nexport const createFabricRoomSessionObject = (\n  params: FabricRoomSessionOptions\n): FabricRoomSession => {\n  const room = connect<\n    FabricRoomSessionEvents,\n    FabricRoomSessionConnection,\n    FabricRoomSession\n  >({\n    store: params.store,\n    Component: FabricRoomSessionConnection,\n  })(params)\n\n  return createFabricRoomSessionValidateProxy(room)\n}\n","import jwtDecode from 'jwt-decode'\nimport { getLogger } from '@signalwire/core'\n\n/**\n * Note: ready to support RN with a \"storage.native.ts\" file.\n */\nexport const getStorage = () => {\n  if (window && window.sessionStorage) {\n    return window.sessionStorage\n  }\n  return undefined\n}\n\nexport const sessionStorageManager = (token: string) => {\n  let roomName: string = ''\n  try {\n    const jwtPayload = jwtDecode<{ r: string; ja: string }>(token)\n    roomName = jwtPayload?.r ?? ''\n  } catch (e) {\n    try {\n      const jwtPayload = jwtDecode<{ typ: string}>(token, {header: true})\n      roomName = jwtPayload.typ || ''\n    } catch {\n      if (process.env.NODE_ENV !== 'production') {\n        getLogger().error('[sessionStorageManager] error decoding JWT', token)\n      }\n      roomName = ''\n    }\n  }\n\n  const valid = Boolean(roomName)\n  return {\n    authStateKey: valid && `as-${roomName}`,\n    protocolKey: valid && `pt-${roomName}`,\n    callIdKey: valid && `ci-${roomName}`,\n  }\n}\n","export const PREVIOUS_CALLID_STORAGE_KEY = 'ci-SAT';\nexport  const DEFAULT_API_REQUEST_RETRIES = 10\nexport  const DEFAULT_API_REQUEST_RETRIES_DELAY = 300\nexport  const DEFAULT_API_REQUEST_RETRIES_DELAY_INCREMENT  = 100","import {\n  getLogger,\n  sagaEffects,\n  SagaIterator,\n  SDKWorker,\n  SDKActions,\n  MapToPubSubShape,\n  WebRTCMessageParams,\n} from '@signalwire/core'\nimport { WSClient } from '../WSClient'\n\nexport const wsClientWorker: SDKWorker<WSClient> = function* (\n  options\n): SagaIterator {\n  getLogger().debug('wsClientWorker started')\n  const { channels, initialState, instance: client } = options\n  const { swEventChannel } = channels\n  const { handleIncomingInvite } = initialState\n\n  function* fireHoseWorker(action: SDKActions) {\n    // @ts-expect-error Emit all events - This is for internal usage\n    client.emit(action.type, action.payload)\n  }\n\n  function* vertoInviteWorker(action: MapToPubSubShape<WebRTCMessageParams>) {\n    // Invoke WSClient function to build and answer the invite\n    handleIncomingInvite(action.payload.params)\n  }\n\n  const isVertoInvite = (action: SDKActions) => {\n    if (action.type === 'webrtc.message') {\n      return action.payload.method === 'verto.invite'\n    }\n    return false\n  }\n\n  try {\n    while (true) {\n      // Take all actions from the channel\n      const action: SDKActions = yield sagaEffects.take(\n        swEventChannel,\n        () => true\n      )\n\n      // Fire all the events with fireHoseWorker\n      yield sagaEffects.fork(fireHoseWorker, action)\n\n      // If the event is verto.invite, handle that with vertoInviteWorker\n      if (isVertoInvite(action)) {\n        getLogger().debug('Receiving a call over WebSocket', action)\n        yield sagaEffects.fork(\n          vertoInviteWorker,\n          action as MapToPubSubShape<WebRTCMessageParams>\n        )\n      }\n    }\n  } finally {\n    getLogger().trace('wsClientWorker ended')\n  }\n}\n","import {\n  SDKWorker,\n  SagaIterator,\n  getLogger,\n  sagaEffects,\n  SDKWorkerParams,\n  SDKActions,\n  FabricAction,\n  MapToPubSubShape,\n} from '@signalwire/core'\nimport { FabricRoomSessionConnection } from '../FabricRoomSession'\nimport { createFabricRoomSessionMemberObject } from '../FabricRoomSessionMember'\nimport { callSegmentWorker } from './callSegmentWorker'\n\nexport type FabricWorkerParams<T> =\n  SDKWorkerParams<FabricRoomSessionConnection> & {\n    action: MapToPubSubShape<T>\n  }\n\nexport const fabricWorker: SDKWorker<FabricRoomSessionConnection> = function* (\n  options\n): SagaIterator {\n  getLogger().trace('fabricWorker started')\n  const {\n    channels: { swEventChannel },\n    instance: cfRoomSession,\n  } = options\n\n  function* worker(action: FabricAction) {\n    const { type, payload } = action\n\n    switch (type) {\n      case 'call.joined': {\n        // since we depend on `cfRoomSession.selfMember` on the take logic\n        // we need to make sure we update the `cfRoomSession.selfMember`\n        // in this worker or have a race condition.\n        if (!cfRoomSession.selfMember) {\n          const memberInstance = createFabricRoomSessionMemberObject({\n            store: cfRoomSession.store,\n            payload: {\n              member: action.payload.room_session.members.find(\n                (m) => m.member_id === action.payload.member_id\n              )!,\n              room_id: action.payload.room_id,\n              room_session_id: action.payload.room_session_id,\n            },\n          })\n          cfRoomSession.selfMember = memberInstance\n        }\n\n        // Segment worker for each call_id\n        yield sagaEffects.fork(callSegmentWorker, {\n          ...options,\n          instance: cfRoomSession,\n          action,\n        })\n        break\n      }\n      case 'call.state':\n        cfRoomSession.emit(type, payload)\n        break\n    }\n  }\n\n  let firstCallJoinedReceived = false\n  const isFirstCallJoinedorCallStateEvent = (action: SDKActions) => {\n    if (action.type === 'call.state') {\n      return true\n    }\n\n    if (action.type !== 'call.joined') {\n      return false\n    }\n\n    // If this is the first call.joined event, verify the call origin ID\n    if (!firstCallJoinedReceived) {\n      const callId = action.payload.call_id\n      const originCallId = action.payload.origin_call_id\n      if (callId === originCallId) {\n        firstCallJoinedReceived = true\n        return true\n      }\n      return false // Discard all the call.joined event until the first call.joined is received\n    }\n\n    // If first call.joined event already received, only check the action type\n    return true\n  }\n\n  while (true) {\n    const action: FabricAction = yield sagaEffects.take(\n      swEventChannel,\n      isFirstCallJoinedorCallStateEvent\n    )\n\n    yield sagaEffects.fork(worker, action)\n  }\n\n  getLogger().trace('fabricWorker ended')\n}\n","import {\n  FabricMemberEventNames,\n  FabricMemberEventParams,\n  FabricMemberEventParamsExcludeTalking,\n  FabricMemberJoinedEventParams,\n  FabricMemberLeftEventParams,\n  FabricMemberTalkingEventParams,\n  FabricMemberUpdatedEventParams,\n  FabricMemberContract,\n  connect,\n  MemberJoined,\n  MemberLeft,\n  MemberTalking,\n  MemberUpdated,\n  BaseComponentOptionsWithPayload,\n  BaseComponent,\n} from '@signalwire/core'\n\nexport interface FabricRoomSessionMember extends FabricMemberContract {\n  /** Unique id of this member. */\n  id: string\n  setPayload(payload: FabricMemberEventParams): void\n}\n\n// TODO: Fabric Room Session Member instance does not emit any events yet\nexport type FabricRoomSessionMemberEventsHandlerMap = Record<\n  MemberJoined,\n  (params: FabricMemberJoinedEventParams) => void\n> &\n  Record<MemberUpdated, (params: FabricMemberUpdatedEventParams) => void> &\n  Record<MemberLeft, (params: FabricMemberLeftEventParams) => void> &\n  Record<MemberTalking, (params: FabricMemberTalkingEventParams) => void> &\n  Record<\n    Exclude<FabricMemberEventNames, MemberJoined | MemberLeft | MemberTalking>,\n    (params: FabricMemberUpdatedEventParams) => void\n  >\n\nexport type FabricRoomSessionMemberEvents = {\n  [k in keyof FabricRoomSessionMemberEventsHandlerMap]: FabricRoomSessionMemberEventsHandlerMap[k]\n}\n\nexport interface FabricRoomSessionMemberOptions\n  extends BaseComponentOptionsWithPayload<FabricMemberEventParamsExcludeTalking> {}\n\nexport class FabricRoomSessionMemberAPI\n  extends BaseComponent<FabricRoomSessionMemberEvents>\n  implements FabricMemberContract\n{\n  private _payload: FabricMemberEventParamsExcludeTalking\n\n  constructor(options: FabricRoomSessionMemberOptions) {\n    super(options)\n    this._payload = options.payload\n  }\n\n  get id() {\n    return this._payload.member.member_id\n  }\n\n  get callId() {\n    return this._payload.member.call_id\n  }\n\n  get nodeId() {\n    return this._payload.member.node_id\n  }\n\n  get memberId() {\n    return this.id\n  }\n\n  get roomSessionId() {\n    return this._payload.room_session_id\n  }\n\n  get roomId() {\n    return this._payload.room_id\n  }\n\n  get parentId() {\n    return this._payload.member.parent_id\n  }\n\n  get subscriberId() {\n    return this._payload.member.subscriber_id\n  }\n\n  get addressId() {\n    return this._payload.member.address_id\n  }\n\n  get name() {\n    return this._payload.member.name\n  }\n\n  get type() {\n    return this._payload.member.type\n  }\n\n  get requestedPosition() {\n    return this._payload.member.requested_position\n  }\n\n  get currentPosition() {\n    return this._payload.member.current_position\n  }\n\n  get meta() {\n    return this._payload.member.meta\n  }\n\n  get handraised() {\n    return this._payload.member.handraised\n  }\n\n  get talking() {\n    return this._payload.member.talking\n  }\n\n  get audioMuted() {\n    return this._payload.member.audio_muted\n  }\n\n  get videoMuted() {\n    return this._payload.member.video_muted\n  }\n\n  get deaf() {\n    return this._payload.member.deaf\n  }\n\n  get visible() {\n    return this._payload.member.visible\n  }\n\n  get inputVolume() {\n    return this._payload.member.input_volume\n  }\n\n  get outputVolume() {\n    return this._payload.member.output_volume\n  }\n\n  get inputSensitivity() {\n    return this._payload.member.input_sensitivity\n  }\n\n  get echoCancellation() {\n    return this._payload.member.echo_cancellation\n  }\n\n  get autoGain() {\n    return this._payload.member.auto_gain\n  }\n\n  get noiseSuppression() {\n    return this._payload.member.noise_suppression\n  }\n\n  /** @internal */\n  setPayload(payload: FabricMemberEventParams) {\n    // Reshape the payload since the `member.talking` event does not return all the parameters of a member\n    const newPayload = {\n      ...this._payload,\n      ...payload,\n      member: {\n        ...this._payload.member,\n        ...payload.member,\n      },\n    }\n    this._payload = newPayload\n  }\n}\n\nexport const createFabricRoomSessionMemberObject = (\n  params: FabricRoomSessionMemberOptions\n): FabricRoomSessionMember => {\n  const member = connect<\n    FabricRoomSessionMemberEventsHandlerMap,\n    FabricRoomSessionMemberAPI,\n    FabricRoomSessionMember\n  >({\n    store: params.store,\n    Component: FabricRoomSessionMemberAPI,\n  })(params)\n\n  return member\n}\n","import {\n  FabricAction,\n  CallJoinedEvent,\n  SDKActions,\n  SagaIterator,\n  getLogger,\n  sagaEffects,\n} from '@signalwire/core'\nimport { callLeftWorker } from './callLeftWorker'\nimport { callJoinWorker } from './callJoinWorker'\nimport { FabricWorkerParams } from './fabricWorker'\nimport {\n  mapFabricLayoutActionToVideoLayoutAction,\n  mapFabricMemberActionToVideoMemberJoinAndLeftAction,\n  mapFabricMemberActionToVideoMemberUpdatedAction,\n} from '../utils/eventMappers'\nimport { fabricMemberWorker } from './fabricMemberWorker'\n\nexport const callSegmentWorker = function* (\n  options: FabricWorkerParams<CallJoinedEvent>\n): SagaIterator {\n  const {\n    action,\n    channels: { swEventChannel },\n    instance: cfRoomSession,\n  } = options\n  const segmentCallId = action.payload.call_id\n  const segmentRooSessionId = action.payload.room_session_id\n\n  getLogger().debug(\n    `callSegmentWorker started for: callId ${segmentCallId}, roomSessionId ${segmentRooSessionId}`\n  )\n\n  // Handles the `call.joined` event before the worker loop\n  yield sagaEffects.fork(callJoinWorker, {\n    ...options,\n    action,\n  })\n\n  function* worker(action: FabricAction) {\n    const { type, payload } = action\n\n    switch (type) {\n      case 'call.joined':\n        /** NOOP since this event is handled by the {@link fabricWorker} */\n        break\n      case 'call.left':\n        // Wait for the `callLeftWorker` to finish and then stop this particular segment worker\n        yield sagaEffects.call(callLeftWorker, {\n          ...options,\n          action,\n        })\n        return true\n      case 'call.updated':\n        cfRoomSession.emit(type, payload)\n        cfRoomSession.emit('room.updated', payload)\n        break\n      case 'call.play':\n        cfRoomSession.emit(type, payload)\n        break\n      case 'call.connect':\n        cfRoomSession.emit(type, payload)\n        break\n      case 'call.room':\n        cfRoomSession.emit(type, payload)\n        break\n\n      /**\n       * The Core module includes a generic worker, {@link memberPositionWorker},\n       * which listens for member & layout events to add a \"current_position\" parameter\n       * and handle member \"updated\" parameter.\n       * This worker in CF SDK is initialized by the {@link callJoinWorker} worker.\n       *\n       * To ensure compatibility, we map these events to Video SDK events and\n       * re-publish them on the channel so that they can be processed by the\n       * generic worker. Note that the generic worker only dispatches \"member.updated\"\n       * and \"member.updated.*\" events.\n       *\n       * Additionally, the \"member.joined\" event is monitored by another worker,\n       * {@link childMemberJoinedWorker}, specifically for the screen share API.\n       */\n      case 'member.joined':\n      case 'member.left': {\n        yield sagaEffects.fork(fabricMemberWorker, {\n          ...options,\n          action,\n        })\n        const videoAction =\n          mapFabricMemberActionToVideoMemberJoinAndLeftAction(action)\n        yield sagaEffects.put(swEventChannel, videoAction)\n        break\n      }\n      case 'member.updated': {\n        const videoAction =\n          mapFabricMemberActionToVideoMemberUpdatedAction(action)\n        yield sagaEffects.put(swEventChannel, videoAction)\n        break\n      }\n      case 'layout.changed': {\n        // We need to update the layout event which is needed for rootElement.\n        cfRoomSession.currentLayoutEvent = action.payload\n        cfRoomSession.emit(type, payload)\n        const videoAction = mapFabricLayoutActionToVideoLayoutAction(action)\n        yield sagaEffects.put(swEventChannel, videoAction)\n        break\n      }\n      case 'member.talking': {\n        yield sagaEffects.fork(fabricMemberWorker, {\n          ...options,\n          action,\n        })\n        break\n      }\n      default: {\n        getLogger().warn('Got an unknown fabric event', action)\n      }\n    }\n\n    return false\n  }\n\n  const isSegmentEvent = (action: SDKActions) => {\n    const { type, payload } = action as FabricAction\n    const shouldWatch =\n      type.startsWith('call.') ||\n      type.startsWith('member.') ||\n      type.startsWith('layout.')\n    const hasSegmentCallId =\n      'call_id' in payload && segmentCallId === payload.call_id\n    const hasSegmentRoomSessionId =\n      segmentRooSessionId === payload.room_session_id\n\n    if (shouldWatch && (hasSegmentCallId || hasSegmentRoomSessionId)) {\n      return true\n    }\n\n    return false\n  }\n\n  while (true) {\n    const action: FabricAction = yield sagaEffects.take(\n      swEventChannel,\n      isSegmentEvent\n    )\n    const task = yield sagaEffects.fork(worker, action)\n\n    /**\n     * Wait for `worker` to finish and get its return value\n     * Stop the `callSegmentWorker' if the returned value is true\n     */\n    const shouldStop = yield sagaEffects.join(task)\n    if (shouldStop) return\n  }\n}\n","import { getLogger, SagaIterator, CallLeftEvent } from '@signalwire/core'\nimport { FabricWorkerParams } from './fabricWorker'\nimport { FabricRoomSessionMemberAPI } from '../FabricRoomSessionMember'\n\nexport const callLeftWorker = function* (\n  options: FabricWorkerParams<CallLeftEvent>\n): SagaIterator {\n  getLogger().trace('callLeftWorker started')\n\n  const {\n    action: { payload },\n    instance: cfRoomSession,\n    instanceMap,\n  } = options\n\n  const { room_session_id } = payload\n\n  // Remove all the member instance where roomSessionId matches\n  instanceMap.getAll().forEach(([key, obj]) => {\n    if (\n      obj instanceof FabricRoomSessionMemberAPI &&\n      obj.roomSessionId === room_session_id\n    ) {\n      instanceMap.remove(key)\n    }\n  })\n\n  cfRoomSession.emit('call.left', payload)\n  cfRoomSession.emit('room.left', payload)\n\n  getLogger().trace('callLeftWorker ended')\n}\n","import {\n  getLogger,\n  SagaIterator,\n  CallJoinedEvent,\n  sagaEffects,\n  MemberPosition,\n  stripNamespacePrefix,\n} from '@signalwire/core'\nimport {\n  createFabricRoomSessionMemberObject,\n  FabricRoomSessionMember,\n} from '../FabricRoomSessionMember'\nimport { FabricWorkerParams } from './fabricWorker'\nimport { fabricMemberWorker } from './fabricMemberWorker'\nimport { mapCapabilityPayload } from '../utils/capabilitiesHelpers'\nimport { mapCallJoinedToRoomSubscribedEventParams } from '../utils/eventMappers'\n\nexport const callJoinWorker = function* (\n  options: FabricWorkerParams<CallJoinedEvent>\n): SagaIterator {\n  getLogger().trace('callJoinWorker started')\n  const { action, instanceMap, instance: cfRoomSession } = options\n  const { payload } = action\n  const { get, set } = instanceMap\n\n  yield sagaEffects.fork(MemberPosition.memberPositionWorker, {\n    ...options,\n    /**\n     * The {@link memberPositionWorker} worker understands only the Video SDK events.\n     * So, we need to map CF SDK event to Video SDK event.\n     * Similar to what we do in the {@link callSegmentWorker}, for member events.\n     */\n    initialState: mapCallJoinedToRoomSubscribedEventParams(payload),\n    dispatcher: function* (subType, subPayload) {\n      /**\n       * The {@link memberPositionWorker} dispatches the Video SDK events.\n       * We need to convert it back to CF SDK event before emitting to the user.\n       */\n      const fabricType = stripNamespacePrefix(subType, 'video') as any\n      const fabricPaylod = {\n        ...subPayload,\n        member: {\n          ...subPayload.member,\n          member_id: subPayload.member.id,\n        },\n      }\n\n      yield sagaEffects.fork(fabricMemberWorker, {\n        ...options,\n        action: { type: fabricType, payload: fabricPaylod },\n      })\n    },\n  })\n\n  payload.room_session.members?.forEach((member: any) => {\n    let memberInstance = get<FabricRoomSessionMember>(member.member_id!)\n    if (!memberInstance) {\n      memberInstance = createFabricRoomSessionMemberObject({\n        store: cfRoomSession.store,\n        payload: {\n          member: member,\n          room_id: payload.room_id,\n          room_session_id: payload.room_session_id,\n        },\n      })\n    } else {\n      memberInstance.setPayload({\n        member: member,\n        room_id: payload.room_id,\n        room_session_id: payload.room_session_id,\n      })\n    }\n    set<FabricRoomSessionMember>(member.member_id, memberInstance)\n  })\n\n  cfRoomSession.member = get<FabricRoomSessionMember>(payload.member_id)\n  // the server send the capabilities payload as an array of string\n  cfRoomSession.capabilities = mapCapabilityPayload(payload.capabilities)\n\n  const fabricEvent = {\n    ...payload,\n    capabilities: cfRoomSession.capabilities,\n  }\n\n  cfRoomSession.emit('call.joined', fabricEvent)\n\n  getLogger().trace('callJoinWorker ended')\n}\n","import {\n  FabricMemberEvent,\n  FabricMemberUpdatedEventParams,\n  MemberUpdatedEventNames,\n  SagaIterator,\n  fromSnakeToCamelCase,\n  getLogger,\n} from '@signalwire/core'\nimport { FabricWorkerParams } from './fabricWorker'\nimport {\n  createFabricRoomSessionMemberObject,\n  FabricRoomSessionMember,\n} from '../FabricRoomSessionMember'\n\nexport const fabricMemberWorker = function* (\n  options: FabricWorkerParams<FabricMemberEvent>\n): SagaIterator {\n  getLogger().trace('fabricMemberWorker started')\n  const {\n    instance: roomSession,\n    action: { type, payload },\n    instanceMap: { get, set, remove },\n  } = options\n\n  const memberId = payload.member.member_id\n  let memberInstance = get<FabricRoomSessionMember>(memberId)\n  if (!memberInstance && type !== 'member.talking') {\n    memberInstance = createFabricRoomSessionMemberObject({\n      store: roomSession.store,\n      payload: payload,\n    })\n  }\n  if (memberInstance) {\n    memberInstance.setPayload(payload)\n  }\n  set<FabricRoomSessionMember>(memberId, memberInstance)\n\n  if (type.startsWith('member.updated.')) {\n    const clientType = fromSnakeToCamelCase(type) as MemberUpdatedEventNames\n    roomSession.emit(clientType, payload as FabricMemberUpdatedEventParams)\n  }\n\n  switch (type) {\n    case 'member.joined':\n      roomSession.emit(type, payload)\n      break\n    case 'member.updated':\n      roomSession.emit(type, payload)\n      break\n    case 'member.left':\n      roomSession.emit(type, payload)\n      remove<FabricRoomSessionMember>(memberId)\n      break\n    case 'member.talking':\n      roomSession.emit(type, payload)\n      break\n    default:\n      break\n  }\n\n  getLogger().trace('fabricMemberWorker ended')\n}\n","import {\n  CallCapabilitiesContract,\n  CapabilityOnOffStateContract,\n  MemberCapabilityContract,\n} from '../interfaces/capabilities'\n\nclass CapabilityOnOffState implements CapabilityOnOffStateContract {\n  constructor(private _flags: string[]) {}\n\n  get on() {\n    return this._flags.some((flag) => !flag.endsWith('.off'))\n  }\n\n  get off() {\n    return this._flags.some((flag) => !flag.endsWith('.on'))\n  }\n}\n\nclass MemberCapability implements MemberCapabilityContract {\n  private _muteAudio?: CapabilityOnOffState\n  private _muteVideo?: CapabilityOnOffState\n  private _deaf?: CapabilityOnOffState\n  private _raisehand?: CapabilityOnOffState\n\n  constructor(\n    private _flags: string[],\n    private _memberType: 'self' | 'member'\n  ) {}\n\n  get muteAudio() {\n    this._muteAudio =\n      this._muteAudio ??\n      new CapabilityOnOffState(\n        this._flags.filter(\n          (flag) =>\n            flag === this._memberType ||\n            flag === `${this._memberType}.mute` ||\n            flag.startsWith(`${this._memberType}.mute.audio`)\n        )\n      )\n    return this._muteAudio\n  }\n\n  get muteVideo() {\n    this._muteVideo =\n      this._muteVideo ??\n      new CapabilityOnOffState(\n        this._flags.filter(\n          (flag) =>\n            flag === this._memberType ||\n            flag === `${this._memberType}.mute` ||\n            flag.startsWith(`${this._memberType}.mute.video`)\n        )\n      )\n    return this._muteVideo\n  }\n\n  get microphoneVolume() {\n    return this._flags.some(\n      (flag) =>\n        flag === this._memberType ||\n        flag === `${this._memberType}.microphone` ||\n        flag.startsWith(`${this._memberType}.microphone.volume`)\n    )\n  }\n\n  get microphoneSensitivity() {\n    return this._flags.some(\n      (flag) =>\n        flag === this._memberType ||\n        flag === `${this._memberType}.microphone` ||\n        flag.startsWith(`${this._memberType}.microphone.sensitivity`)\n    )\n  }\n\n  get speakerVolume() {\n    return this._flags.some(\n      (flag) =>\n        flag === this._memberType ||\n        flag === `${this._memberType}.speaker` ||\n        flag.startsWith(`${this._memberType}.speaker.volume`)\n    )\n  }\n\n  get deaf() {\n    this._deaf =\n      this._deaf ??\n      new CapabilityOnOffState(\n        this._flags.filter(\n          (flag) =>\n            flag === this._memberType ||\n            flag.startsWith(`${this._memberType}.deaf`)\n        )\n      )\n    return this._deaf\n  }\n\n  get raisehand() {\n    this._raisehand =\n      this._raisehand ??\n      new CapabilityOnOffState(\n        this._flags.filter(\n          (flag) =>\n            flag === this._memberType ||\n            flag.startsWith(`${this._memberType}.raisehand`)\n        )\n      )\n    return this._raisehand\n  }\n\n  get position() {\n    return this._flags.some(\n      (flag) =>\n        flag === this._memberType ||\n        flag.startsWith(`${this._memberType}.position`)\n    )\n  }\n\n  get meta() {\n    return this._flags.some(\n      (flag) =>\n        flag === this._memberType || flag.startsWith(`${this._memberType}.meta`)\n    )\n  }\n\n  get remove() {\n    return this._flags.some(\n      (flag) =>\n        flag === this._memberType ||\n        flag.startsWith(`${this._memberType}.remove`)\n    )\n  }\n\n  get audioFlags() {\n    return this._flags.some(\n      (flag) =>\n        flag === this._memberType ||\n        flag.startsWith(`${this._memberType}.audioflags.set`)\n    )\n  }\n}\n\nexport class CallCapabilities implements CallCapabilitiesContract {\n  private _self?: MemberCapabilityContract\n  private _member?: MemberCapabilityContract\n  private _vmutedHide?: CapabilityOnOffState\n  private _lock?: CapabilityOnOffState\n\n  constructor(private _flags: string[]) {}\n\n  private _buildMemberCapability(memberType: 'self' | 'member') {\n    return new MemberCapability(\n      this._flags.filter((flag) => flag.startsWith(memberType)),\n      memberType\n    )\n  }\n\n  get self() {\n    this._self = this._self ?? this._buildMemberCapability('self')\n    return this._self\n  }\n\n  get member() {\n    this._member = this._member ?? this._buildMemberCapability('member')\n    return this._member\n  }\n\n  get end() {\n    return this._flags.some((capability) => capability === 'end')\n  }\n\n  get setLayout() {\n    return this._flags.some((capability) => capability.startsWith('layout'))\n  }\n\n  get sendDigit() {\n    return this._flags.some((capability) => capability.startsWith('digit'))\n  }\n\n  get vmutedHide() {\n    this._vmutedHide =\n      this._vmutedHide ??\n      new CapabilityOnOffState(\n        this._flags.filter((flag) => flag.startsWith('vmuted'))\n      )\n    return this._vmutedHide\n  }\n\n  get lock() {\n    this._lock =\n      this._lock ??\n      new CapabilityOnOffState(\n        this._flags.filter((flag) => flag.startsWith('lock'))\n      )\n    return this._lock\n  }\n\n  get device() {\n    return this._flags.some((capability) => capability === 'device')\n  }\n\n  get screenshare() {\n    return this._flags.some((capability) => capability === 'screenshare')\n  }\n}\n\nexport const mapCapabilityPayload = (capabilities: string[]) =>\n  new CallCapabilities(capabilities)\n","import {\n  CallJoinedEvent,\n  CallJoinedEventParams,\n  FabricLayoutChangedEvent,\n  FabricMemberJoinedEvent,\n  FabricMemberJoinedEventParams,\n  FabricMemberLeftEvent,\n  FabricMemberLeftEventParams,\n  FabricMemberTalkingEvent,\n  FabricMemberTalkingEventParams,\n  FabricMemberUpdatedEvent,\n  FabricMemberUpdatedEventParams,\n  InternalFabricMemberEntity,\n  InternalFabricMemberEntityUpdated,\n  InternalVideoMemberEntity,\n  InternalVideoMemberEntityUpdated,\n  MapToPubSubShape,\n  VideoLayoutChangedEvent,\n  VideoMemberJoinedEvent,\n  VideoMemberJoinedEventParams,\n  VideoMemberLeftEvent,\n  VideoMemberLeftEventParams,\n  VideoMemberTalkingEvent,\n  VideoMemberTalkingEventParams,\n  VideoMemberUpdatedEvent,\n  VideoMemberUpdatedEventParams,\n} from '@signalwire/core'\n\n/**\n * Map the InternalFabricMemberEntity to InternalVideoMemberEntity\n */\nexport const mapInternalFabricMemberToInternalVideoMemberEntity = (\n  params: InternalFabricMemberEntity\n): InternalVideoMemberEntity => {\n  return {\n    ...params,\n    id: params.member_id,\n  }\n}\n\n/**\n * Map the InternalFabricMemberEntityUpdated to InternalVideoMemberEntityUpdated\n */\nexport const mapInternalFabricMemberToInternalVideoMemberUpdatedEntity = (\n  params: InternalFabricMemberEntityUpdated\n): InternalVideoMemberEntityUpdated => {\n  return {\n    ...mapInternalFabricMemberToInternalVideoMemberEntity(params),\n    updated: params.updated.map((key) =>\n      key === 'member_id' ? 'id' : (key as keyof InternalVideoMemberEntity)\n    ),\n  }\n}\n\n/**\n * Map the \"call.joined\" event params to \"video.room.subscribed\" event params\n */\nexport const mapCallJoinedToRoomSubscribedEventParams = (\n  params: CallJoinedEventParams\n) => {\n  return {\n    ...params,\n    room: {\n      ...params.room_session,\n      members: params.room_session.members.map(\n        mapInternalFabricMemberToInternalVideoMemberEntity\n      ),\n    },\n    room_session: {\n      ...params.room_session,\n      members: params.room_session.members.map(\n        mapInternalFabricMemberToInternalVideoMemberEntity\n      ),\n    },\n  }\n}\n\n/**\n * Map the \"call.joined\" action to \"video.room.subscribed\" action\n */\nexport const mapCallJoinedToRoomSubscribedAction = (\n  action: MapToPubSubShape<CallJoinedEvent>\n) => {\n  return {\n    type: `video.room.subscribed`,\n    payload: mapCallJoinedToRoomSubscribedEventParams(action.payload),\n  }\n}\n\n/**\n * Map the \"member.joined\" and \"member.left\" event params\n * to \"video.member.joined\" and \"video.member.left\"  event params\n */\nexport const mapFabricMemberToVideoMemberJoinAndLeftEventParams = (\n  params: FabricMemberJoinedEventParams | FabricMemberLeftEventParams\n): VideoMemberJoinedEventParams | VideoMemberLeftEventParams => {\n  return {\n    room_session_id: params.room_session_id,\n    room_id: params.room_id,\n    member: mapInternalFabricMemberToInternalVideoMemberEntity(params.member),\n  }\n}\n\n/**\n * Map the \"member.joined\" and \"member.left\" actions\n * to \"video.member.joined\" and \"video.member.left\"  actions\n */\nexport const mapFabricMemberActionToVideoMemberJoinAndLeftAction = (\n  action: MapToPubSubShape<FabricMemberJoinedEvent | FabricMemberLeftEvent>\n): MapToPubSubShape<VideoMemberJoinedEvent | VideoMemberLeftEvent> => {\n  return {\n    type: `video.${action.type}`,\n    payload: mapFabricMemberToVideoMemberJoinAndLeftEventParams(action.payload),\n  }\n}\n\n/**\n * Map the \"member.updated\" event params to \"video.member.updated\"  event params\n */\nexport const mapFabricMemberEventToVideoMemberUpdatedEventParams = (\n  params: FabricMemberUpdatedEventParams\n): VideoMemberUpdatedEventParams => {\n  return {\n    room_session_id: params.room_session_id,\n    room_id: params.room_id,\n    member: mapInternalFabricMemberToInternalVideoMemberUpdatedEntity(\n      params.member\n    ),\n  }\n}\n\n/**\n * Map the \"member.updated\" action to \"video.member.updated\"  action\n */\nexport const mapFabricMemberActionToVideoMemberUpdatedAction = (\n  action: MapToPubSubShape<FabricMemberUpdatedEvent>\n): MapToPubSubShape<VideoMemberUpdatedEvent> => {\n  return {\n    type: `video.${action.type}`,\n    payload: mapFabricMemberEventToVideoMemberUpdatedEventParams(\n      action.payload\n    ),\n  }\n}\n\n/**\n * Map the \"member.talking\" event params to \"video.member.talking\"  event params\n */\nexport const mapFabricMemberToVideoMemberTalkingEventParams = (\n  params: FabricMemberTalkingEventParams\n): VideoMemberTalkingEventParams => {\n  return {\n    room_session_id: params.room_session_id,\n    room_id: params.room_id,\n    member: {\n      ...params.member,\n      id: params.member.member_id,\n    },\n  }\n}\n\n/**\n * Map the \"member.talking\" action to \"video.member.talking\"  action\n */\nexport const mapFabricMemberActionToVideoMemberTalkingAction = (\n  action: MapToPubSubShape<FabricMemberTalkingEvent>\n): MapToPubSubShape<VideoMemberTalkingEvent> => {\n  return {\n    type: `video.${action.type}`,\n    payload: mapFabricMemberToVideoMemberTalkingEventParams(action.payload),\n  }\n}\n\n/**\n * Map the \"layout.changed\" action to \"video.layout.changed\"  action\n */\nexport const mapFabricLayoutActionToVideoLayoutAction = (\n  action: MapToPubSubShape<FabricLayoutChangedEvent>\n): MapToPubSubShape<VideoLayoutChangedEvent> => {\n  return {\n    type: `video.${action.type}`,\n    payload: action.payload,\n  }\n}\n","import {\n  CapabilityError,\n  MemberCommandParams,\n  MemberCommandWithValueParams,\n  MemberCommandWithVolumeParams,\n  Rooms,\n  SetAudioFlagsParams,\n} from '@signalwire/core'\nimport { FabricRoomSessionConnection } from '../FabricRoomSession'\n\nconst isSelfMember = (\n  params: MemberCommandParams | undefined,\n  ctx: FabricRoomSessionConnection\n) => {\n  return !params?.memberId || params.memberId === ctx.member.id\n}\n\nexport function validateAudioMute(\n  this: FabricRoomSessionConnection,\n  params?: MemberCommandParams\n) {\n  const isSelf = isSelfMember(params, this)\n  const capability = isSelf\n    ? this.capabilities?.self.muteAudio.off\n    : this.capabilities?.member.muteAudio.off\n  if (!capability) {\n    throw new CapabilityError('Missing audio mute capability')\n  }\n}\n\nexport function validateAudioUnmute(\n  this: FabricRoomSessionConnection,\n  params?: MemberCommandParams\n) {\n  const isSelf = isSelfMember(params, this)\n  const capability = isSelf\n    ? this.capabilities?.self.muteAudio.on\n    : this.capabilities?.member.muteAudio.on\n  if (!capability) {\n    throw new CapabilityError('Missing audio unmute capability')\n  }\n}\n\nexport function validateVideoMute(\n  this: FabricRoomSessionConnection,\n  params?: MemberCommandParams\n) {\n  const isSelf = isSelfMember(params, this)\n  const capability = isSelf\n    ? this.capabilities?.self.muteVideo.off\n    : this.capabilities?.member.muteVideo.off\n  if (!capability) {\n    throw new CapabilityError('Missing video mute capability')\n  }\n}\n\nexport function validateVideoUnmute(\n  this: FabricRoomSessionConnection,\n  params?: MemberCommandParams\n) {\n  const isSelf = isSelfMember(params, this)\n  const capability = isSelf\n    ? this.capabilities?.self.muteVideo.on\n    : this.capabilities?.member.muteVideo.on\n  if (!capability) {\n    throw new CapabilityError('Missing video unmute capability')\n  }\n}\n\nexport function validateDeaf(\n  this: FabricRoomSessionConnection,\n  params?: MemberCommandParams\n) {\n  const isSelf = isSelfMember(params, this)\n  const capability = isSelf\n    ? this.capabilities?.self.deaf.on\n    : this.capabilities?.member.deaf.on\n  if (!capability) {\n    throw new CapabilityError('Missing deaf capability')\n  }\n}\n\nexport function validateUndeaf(\n  this: FabricRoomSessionConnection,\n  params?: MemberCommandParams\n) {\n  const isSelf = isSelfMember(params, this)\n  const capability = isSelf\n    ? this.capabilities?.self.deaf.off\n    : this.capabilities?.member.deaf.off\n  if (!capability) {\n    throw new CapabilityError('Missing undeaf capability')\n  }\n}\n\nexport function validateRemoveMember(\n  this: FabricRoomSessionConnection,\n  params: Required<MemberCommandParams>\n) {\n  if (!params?.memberId) {\n    throw new TypeError('Invalid or missing \"memberId\" argument')\n  }\n  const capability = this.capabilities?.member.remove\n  if (!capability) {\n    throw new CapabilityError('Missing remove member capability')\n  }\n}\n\nexport function validateSetRaiseHand(\n  this: FabricRoomSessionConnection,\n  params?: Rooms.SetRaisedHandRoomParams\n) {\n  const { raised = true } = params || {}\n  const self = isSelfMember(params, this)\n  const raiseCap = self\n    ? this.capabilities?.self.raisehand.on\n    : this.capabilities?.member.raisehand.on\n  const lowerCap = self\n    ? this.capabilities?.self.raisehand.off\n    : this.capabilities?.member.raisehand.off\n  if (raised && !raiseCap) {\n    throw new CapabilityError('Missing raisehand capability')\n  }\n  if (!raised && !lowerCap) {\n    throw new CapabilityError('Missing lowerhand capability')\n  }\n}\n\nexport function validateSetLayout(this: FabricRoomSessionConnection) {\n  if (!this.capabilities?.setLayout) {\n    throw new CapabilityError('Missing setLayout capability')\n  }\n}\n\nexport function validateSetInputVolume(\n  this: FabricRoomSessionConnection,\n  params: MemberCommandWithVolumeParams\n) {\n  const isSelf = isSelfMember(params, this)\n  const capability = isSelf\n    ? this.capabilities?.self?.microphoneVolume\n    : this.capabilities?.member?.microphoneVolume\n  if (!capability) {\n    throw new CapabilityError('Missing setInputVolume capability')\n  }\n  if (params.volume < -50 || params.volume > 50) {\n    throw new RangeError('The volume ranges from -50 to 50')\n  }\n}\n\nexport function validateSetOutputVolume(\n  this: FabricRoomSessionConnection,\n  params: MemberCommandWithVolumeParams\n) {\n  const isSelf = isSelfMember(params, this)\n  const capability = isSelf\n    ? this.capabilities?.self?.speakerVolume\n    : this.capabilities?.member?.speakerVolume\n  if (!capability) {\n    throw new CapabilityError('Missing setOutputVolume capability')\n  }\n  if (params.volume < -50 || params.volume > 50) {\n    throw new RangeError('The volume ranges from -50 to 50')\n  }\n}\n\nexport function validateSetInputSensitivity(\n  this: FabricRoomSessionConnection,\n  params: MemberCommandWithValueParams\n) {\n  const isSelf = isSelfMember(params, this)\n  const capability = isSelf\n    ? this.capabilities?.self.microphoneSensitivity\n    : this.capabilities?.member.microphoneSensitivity\n  if (!capability) {\n    throw new CapabilityError('Missing setInputSensitivity capability')\n  }\n  if (params.value < 0 || params.value > 100) {\n    throw new RangeError('The sensitivity value ranges from 0 to 100')\n  }\n}\n\nexport function validateSetPositions(\n  this: FabricRoomSessionConnection,\n  params: Rooms.SetPositionsParams\n) {\n  if (params.positions && !Object.keys(params.positions).length) {\n    throw new TypeError('Invalid positions specified')\n  }\n  const hasSelfPositions = Object.keys(params.positions).some((p) =>\n    ['self', `${this.memberId}`].includes(p)\n  )\n  const capability = hasSelfPositions\n    ? this.capabilities?.self.position\n    : this.capabilities?.member.position\n  if (!capability) {\n    throw new CapabilityError('Missing setPositions capability')\n  }\n}\n\nexport function validateLock(this: FabricRoomSessionConnection) {\n  if (!this.capabilities?.lock.on) {\n    throw new CapabilityError('Missing lock capability')\n  }\n}\n\nexport function validateUnlock(this: FabricRoomSessionConnection) {\n  if (!this.capabilities?.lock.off) {\n    throw new CapabilityError('Missing unlock capability')\n  }\n}\n\nexport function validateSetAudioFlags(\n  this: FabricRoomSessionConnection,\n  params?: SetAudioFlagsParams\n) {\n  const isSelf = isSelfMember(params, this)\n  const capability = isSelf\n    ? this.capabilities?.self.audioFlags\n    : this.capabilities?.member.audioFlags\n  if (!capability) {\n    throw new CapabilityError('Missing audio flags capability')\n  }\n\n  const { echoCancellation, autoGain, noiseSuppression } = params || {}\n  if (\n    echoCancellation === undefined &&\n    autoGain === undefined &&\n    noiseSuppression === undefined\n  ) {\n    throw new TypeError(\n      'Invalid parameters: you must specify at least one of `echoCancellation`, `autoGain`, or `noiseSuppression`'\n    )\n  }\n}\n\nexport function validateEnd(this: FabricRoomSessionConnection) {\n  const capability = this.capabilities?.end\n  if (!capability) {\n    throw new CapabilityError(\"Missing 'end' capability\")\n  }\n}\n","import {\n  validateAudioMute,\n  validateAudioUnmute,\n  validateDeaf,\n  validateLock,\n  validateRemoveMember,\n  validateSetAudioFlags,\n  validateSetInputSensitivity,\n  validateSetInputVolume,\n  validateSetLayout,\n  validateSetOutputVolume,\n  validateSetPositions,\n  validateSetRaiseHand,\n  validateUndeaf,\n  validateUnlock,\n  validateVideoMute,\n  validateVideoUnmute,\n  validateEnd\n} from './validators'\nimport {\n  FabricRoomSession,\n  FabricRoomSessionConnection,\n} from '../FabricRoomSession'\n\ntype ValidatorMap = Partial<\n  Record<\n    keyof FabricRoomSession,\n    (this: FabricRoomSessionConnection, ...args: any[]) => void\n  >\n>\n\nexport const validationsMap: ValidatorMap = {\n  audioMute: validateAudioMute,\n  audioUnmute: validateAudioUnmute,\n  videoMute: validateVideoMute,\n  videoUnmute: validateVideoUnmute,\n  deaf: validateDeaf,\n  undeaf: validateUndeaf,\n  removeMember: validateRemoveMember,\n  setRaisedHand: validateSetRaiseHand,\n  setLayout: validateSetLayout,\n  setInputVolume: validateSetInputVolume,\n  setOutputVolume: validateSetOutputVolume,\n  setInputSensitivity: validateSetInputSensitivity,\n  setPositions: validateSetPositions,\n  lock: validateLock,\n  unlock: validateUnlock,\n  setAudioFlags: validateSetAudioFlags,\n  end: validateEnd,\n}\n\n/**\n * Wraps a FabricRoomSession instance with a Proxy that runs validation\n * functions (from validationsMap) before calling the original method.\n *\n * @param instance - The FabricRoomSession instance to wrap.\n * @returns The proxied FabricRoomSession.\n */\nexport function createFabricRoomSessionValidateProxy(\n  instance: FabricRoomSession\n) {\n  return new Proxy(instance, {\n    get(target, prop: keyof FabricRoomSession, receiver) {\n      // Only intercept keys that have an associated validator\n      if (typeof prop === 'string' && prop in validationsMap) {\n        const targetConn = target as unknown as FabricRoomSessionConnection\n        const origMethod = targetConn[prop] as Function\n        if (typeof origMethod === 'function') {\n          // Wrap in a promise so validator runs asynchronously\n          return async function (...args: unknown[]) {\n            // Run the validator before calling the method\n            const validator = validationsMap[prop as keyof FabricRoomSession]\n            if (validator) {\n              validator.apply(targetConn, args)\n            }\n            return origMethod.apply(targetConn, args)\n          }\n        }\n      }\n      return Reflect.get(target, prop, receiver)\n    },\n  })\n}\n","import jwtDecode from 'jwt-decode'\nimport {\n  BaseJWTSession,\n  getLogger,\n  SessionOptions,\n  SwAuthorizationState,\n  type SWCloseEvent,\n} from '@signalwire/core'\nimport { getStorage, sessionStorageManager } from './utils/storage'\nimport { SwCloseEvent } from './utils/CloseEvent'\n\ntype JWTHeader = { ch?: string; typ?: string }\n\nexport class JWTSession extends BaseJWTSession {\n  public WebSocketConstructor = WebSocket\n  public CloseEventConstructor = SwCloseEvent\n  public agent = process.env.SDK_PKG_AGENT!\n\n  private tokenTyp: string\n\n  constructor(public options: SessionOptions) {\n    let decodedJwt: JWTHeader = {}\n    try {\n      decodedJwt = jwtDecode(options.token, {\n        header: true,\n      })\n    } catch (e) {\n      if (process.env.NODE_ENV !== 'production') {\n        getLogger().debug('[JWTSession] error decoding the JWT')\n      }\n    }\n\n    super({\n      ...options,\n      host: decodedJwt?.ch || options.host,\n    })\n    this.tokenTyp = decodedJwt.typ ?? 'VRT'\n  }\n\n  get allowReattach() {\n    // @ts-expect-error\n    return this.options?.reattach !== false && (this.isVRT() || this.isSAT())\n  }\n\n  override async retrieveRelayProtocol() {\n    if (!this.allowReattach) {\n      return ''\n    }\n\n    const { protocolKey } = sessionStorageManager(this.options.token)\n    if (protocolKey) {\n      this.logger.trace('Search protocol for', protocolKey)\n      return getStorage()?.getItem(protocolKey) ?? ''\n    }\n    return ''\n  }\n\n  override async persistRelayProtocol() {\n    if (!this.allowReattach) {\n      return\n    }\n\n    const { protocolKey } = sessionStorageManager(this.options.token)\n    if (protocolKey) {\n      this.logger.trace('Persist protocol', protocolKey, this.relayProtocol)\n      getStorage()?.setItem(protocolKey, this.relayProtocol)\n    }\n  }\n\n  override removeRelayProtocol() {\n    const { protocolKey } = sessionStorageManager(this.options.token)\n    if (protocolKey) {\n      this.logger.debug('Remove protocol', protocolKey, this.relayProtocol)\n      getStorage()?.removeItem(protocolKey)\n    }\n  }\n\n  override removePrevCallId() {\n    const { callIdKey } = sessionStorageManager(this.options.token)\n    if (callIdKey) {\n      this.logger.debug('Remove Call', callIdKey)\n      getStorage()?.removeItem(callIdKey)\n    }\n  }\n\n  protected override async retrieveSwAuthorizationState() {\n    const { authStateKey } = sessionStorageManager(this.options.token)\n    if (authStateKey) {\n      return getStorage()?.getItem(authStateKey) ?? ''\n    }\n    return ''\n  }\n\n  protected override async persistSwAuthorizationState(\n    state: SwAuthorizationState\n  ) {\n    if (!this.allowReattach) {\n      return\n    }\n\n    const { authStateKey } = sessionStorageManager(this.options.token)\n    if (authStateKey) {\n      this.logger.trace('Persist auth state', authStateKey, state)\n      getStorage()?.setItem(authStateKey, state)\n    }\n  }\n\n  override removeSwAuthorizationState() {\n    const { authStateKey } = sessionStorageManager(this.options.token)\n    if (authStateKey) {\n      this.logger.trace('Remove auth state', authStateKey)\n      getStorage()?.removeItem(authStateKey)\n    }\n  }\n\n  protected override _onSocketClose(event: SWCloseEvent) {\n    if (this.status === 'disconnected') {\n      const { protocolKey, authStateKey, callIdKey } = sessionStorageManager(\n        this.options.token\n      )\n      this.logger.debug('Cleaning up storage')\n      if (protocolKey) {\n        this.logger.debug('Remove protocolKey', protocolKey)\n        getStorage()?.removeItem(protocolKey)\n      }\n      if (authStateKey) {\n        this.logger.debug('Remove authStateKey', authStateKey)\n        getStorage()?.removeItem(authStateKey)\n      }\n      if (callIdKey) {\n        this.logger.debug('Remove callIdKey', callIdKey)\n        getStorage()?.removeItem(callIdKey)\n      }\n    }\n\n    super._onSocketClose(event)\n  }\n\n  private isVRT() {\n    return this.tokenTyp === 'VRT'\n  }\n\n  private isSAT() {\n    return this.tokenTyp === 'SAT'\n  }\n}\n","import { SWCloseEvent as CoreCloseEvent } from '@signalwire/core'\n\nconst SwCloseEvent =\n  typeof CloseEvent === 'function' ? CloseEvent : CoreCloseEvent\n\nexport { SwCloseEvent }\n","import type {\n  ChatContract,\n  ConsumerContract,\n  UserOptions,\n  Chat as ChatNamespace,\n} from '@signalwire/core'\nimport { createClient } from '../createClient'\n\nexport interface ClientApiEvents extends ChatNamespace.BaseChatApiEvents {}\n\n/** @ignore */\nexport interface ClientFullState extends Client {}\nexport interface Client\n  extends ChatContract,\n    Omit<ConsumerContract<ClientApiEvents, ClientFullState>, 'subscribe'> {}\n\n/** @ignore */\nexport interface ClientOptions extends UserOptions {}\n\ntype ClientMethods = keyof Client\nconst INTERCEPTED_METHODS: ClientMethods[] = [\n  'subscribe',\n  'publish',\n  'getMessages',\n  'getMembers',\n  'getMemberState',\n  'getAllowedChannels',\n  'setMemberState',\n]\n\n/**\n * You can use the Client object to build a messaging system into the browser.\n *\n * Example usage:\n *\n * ```js\n * import { Chat } from '@signalwire/js'\n *\n * const chatClient = new Chat.Client({\n *   token: '<your_chat_token>',  // get this from the REST APIs\n * })\n *\n * await chatClient.subscribe([ 'mychannel1', 'mychannel2' ])\n *\n * chatClient.on('message', (message) => {\n *   console.log(\"Received\", message.content,\n *               \"on\", message.channel,\n *               \"at\", message.publishedAt)\n * })\n *\n * await chatClient.publish({\n *   channel: 'mychannel1',\n *   content: 'hello world'\n * })\n * ```\n *\n * ## Events\n *\n * Please see {@link ClientApiEvents} for the list of events emitted by a chat\n * Client object.\n */\nexport const Client = function (chatOptions: ClientOptions) {\n  const client = createClient(chatOptions)\n\n  const createInterceptor = <K extends keyof Client>(prop: K) => {\n    return async (...params: Parameters<Client[K]>) => {\n      await client.connect()\n\n      // @ts-expect-error\n      return client.chat[prop](...params)\n    }\n  }\n\n  const interceptors = {\n    _session: client,\n    disconnect: () => client.disconnect(),\n  } as const\n\n  return new Proxy<Client>(client.chat, {\n    get(target: Client, prop: keyof Client, receiver: any) {\n      if (prop in interceptors) {\n        // @ts-expect-error\n        return interceptors[prop]\n      }\n\n      if (INTERCEPTED_METHODS.includes(prop)) {\n        return createInterceptor(prop)\n      }\n\n      return Reflect.get(target, prop, receiver)\n    },\n  })\n  // For consistency with other constructors we'll make TS force the use of `new`\n} as unknown as { new (chatOptions: ClientOptions): Client }\n","import { PubSub } from '@signalwire/core'\nimport { PagingCursor } from '../utils/interfaces'\nimport PubSubMessage = PubSub.PubSubMessage\n\nexport * from './Client'\n\nexport {\n  PubSubMessage,\n  PagingCursor\n}\n","import type {\n  Rooms,\n  VideoLayoutEventNames,\n  VideoRoomSessionEventNames,\n  VideoRoomEventParams,\n  InternalVideoMemberEntity,\n  InternalVideoMemberEntityUpdated,\n  VideoMemberEventNames,\n  MemberUpdated,\n  MemberUpdatedEventNames,\n  MemberTalkingEventNames,\n  VideoMemberTalkingEventParams,\n  RTCTrackEventName,\n  InternalVideoMemberUpdatableProps,\n  VideoRecordingEventNames,\n  VideoPlaybackEventNames,\n  RoomSessionRecording,\n  RoomSessionPlayback,\n  VideoRoomSessionContract as CoreVideoRoomSessionContract,\n  OnlyFunctionProperties,\n  MemberListUpdated,\n  VideoPositions,\n  RoomAudienceCount,\n  VideoRoomAudienceCountEventParams,\n  RoomLeft,\n  RoomLeftEventParams,\n  VideoStreamEventNames,\n  RoomSessionStream,\n  RoomJoined,\n  RoomSubscribed,\n  VideoRoomSubscribedEventParams,\n  VideoAuthorization,\n  VideoRoomDeviceUpdatedEventNames,\n  DeviceUpdatedEventParams,\n  VideoRoomDeviceDisconnectedEventNames,\n  DeviceDisconnectedEventParams,\n  VideoRoomDeviceEventNames,\n  VideoLayoutChangedEventParams,\n  VideoPosition,\n  BaseConnectionState,\n} from '@signalwire/core'\nimport { INTERNAL_MEMBER_UPDATABLE_PROPS } from '@signalwire/core'\nimport type { MediaEventNames } from '@signalwire/webrtc'\nimport type { RoomSessionDevice } from '../../RoomSessionDevice'\nimport type { RoomSessionScreenShare } from '../../RoomSessionScreenShare'\nimport { RoomSession } from '../../video/RoomSession'\n\n/**\n * @privateRemarks\n * Every other package exposing a `VideoMemberEntity` is\n * transforming the server payload into something else, with\n * the most significant change being converting properties\n * from snake to camel case. The `js` package, on the other\n * hand, exposes the server payload pretty much as is (as of\n * v3) so what we consider internal (sdk and server) in\n * other packages is external (user facing) for `js`. Same\n * applies to `VideoMemberEntityUpdated` since it's just a\n * derived type.\n */\ntype VideoMemberEntity = InternalVideoMemberEntity\ntype VideoMemberEntityUpdated = InternalVideoMemberEntityUpdated\n\nconst INTERNAL_MEMBER_UPDATED_EVENTS = Object.keys(\n  INTERNAL_MEMBER_UPDATABLE_PROPS\n).map((key) => {\n  return `member.updated.${\n    key as keyof InternalVideoMemberUpdatableProps\n  }` as const\n})\n/** @deprecated */\nexport type DeprecatedMemberUpdatableProps =\n  (typeof INTERNAL_MEMBER_UPDATED_EVENTS)[number]\n/** @deprecated */\nexport type DeprecatedVideoMemberHandlerParams = {\n  member: InternalVideoMemberEntity\n}\nexport type VideoMemberHandlerParams = { member: VideoMemberEntity }\nexport type VideoMemberUpdatedHandlerParams = {\n  member: VideoMemberEntityUpdated\n  room_id?: string\n  room_session_id?: string\n}\nexport type VideoMemberListUpdatedParams = { members: VideoMemberEntity[] }\n\n/**\n * List of all the events a RoomObject can listen to\n */\nexport type RoomEventNames =\n  | VideoRoomSessionEventNames\n  | VideoMemberEventNames\n  | VideoLayoutEventNames\n  | VideoRecordingEventNames\n  | VideoPlaybackEventNames\n  | VideoStreamEventNames\n  | RTCTrackEventName\n\nexport type RoomSessionObjectEventsHandlerMap = Record<\n  VideoRoomDeviceEventNames,\n  (params: DeviceUpdatedEventParams) => void\n> &\n  Record<\n    VideoLayoutEventNames,\n    (params: VideoLayoutChangedEventParams) => void\n  > &\n  Record<\n    Exclude<\n      VideoMemberEventNames,\n      MemberUpdated | MemberUpdatedEventNames | MemberListUpdated\n    >,\n    (params: VideoMemberHandlerParams) => void\n  > &\n  Record<\n    Extract<VideoMemberEventNames, MemberUpdated | MemberUpdatedEventNames>,\n    (params: VideoMemberUpdatedHandlerParams) => void\n  > &\n  Record<\n    Extract<VideoMemberEventNames, MemberListUpdated>,\n    (params: VideoMemberListUpdatedParams) => void\n  > &\n  Record<\n    DeprecatedMemberUpdatableProps,\n    (params: DeprecatedVideoMemberHandlerParams) => void\n  > &\n  Record<\n    MemberTalkingEventNames,\n    (params: VideoMemberTalkingEventParams) => void\n  > &\n  Record<\n    Exclude<VideoRoomSessionEventNames, RoomLeft | RoomJoined | RoomSubscribed>,\n    (params: VideoRoomEventParams) => void\n  > &\n  Record<\n    RoomJoined | RoomSubscribed,\n    (params: VideoRoomSubscribedEventParams) => void\n  > &\n  Record<RoomLeft, (params?: RoomLeftEventParams) => void> &\n  Record<MediaEventNames, () => void> &\n  Record<\n    VideoRoomDeviceUpdatedEventNames,\n    (params: DeviceUpdatedEventParams) => void\n  > &\n  Record<\n    VideoRoomDeviceDisconnectedEventNames,\n    (params: DeviceDisconnectedEventParams) => void\n  > &\n  Record<\n    RoomAudienceCount,\n    (params: VideoRoomAudienceCountEventParams) => void\n  > &\n  Record<RTCTrackEventName, (event: RTCTrackEvent) => void> &\n  Record<VideoRecordingEventNames, (recording: RoomSessionRecording) => void> &\n  Record<VideoPlaybackEventNames, (recording: RoomSessionPlayback) => void> &\n  Record<BaseConnectionState, (params: RoomSession) => void> &\n  Record<VideoStreamEventNames, (stream: RoomSessionStream) => void>\n\n// @deprecated Please use {@link VideoRoomSessionEvents}\nexport type RoomSessionObjectEvents = {\n  [k in keyof RoomSessionObjectEventsHandlerMap]: RoomSessionObjectEventsHandlerMap[k]\n}\n\nexport type VideoRoomSessionEvents = {\n  [k in keyof RoomSessionObjectEventsHandlerMap]: RoomSessionObjectEventsHandlerMap[k]\n}\n\nexport type StartScreenShareOptions = {\n  /** Whether the screen share object should automatically join the room */\n  autoJoin?: boolean\n  /** Audio constraints to use when joining the room. Default: `true`. */\n  audio?: MediaStreamConstraints['audio']\n  /** Video constraints to use when joining the room. Default: `true`. */\n  video?: MediaStreamConstraints['video']\n  layout?: string\n  positions?: VideoPositions\n}\n\n/**\n * @deprecated Use {@link StartScreenShareOptions} instead.\n */\nexport interface CreateScreenShareObjectOptions\n  extends StartScreenShareOptions {}\n\nexport type AddDeviceOptions = {\n  autoJoin?: boolean\n  audio?: MediaStreamConstraints['audio']\n  video?: MediaStreamConstraints['video']\n}\n\nexport type AddCameraOptions = MediaTrackConstraints & {\n  autoJoin?: boolean\n}\nexport type AddMicrophoneOptions = MediaTrackConstraints & {\n  autoJoin?: boolean\n}\n\nexport interface BaseRoomInterface {\n  join(): Promise<unknown>\n  leave(): Promise<unknown>\n}\n\ninterface RoomMemberSelfMethodsInterface {\n  /**\n   * Puts the microphone on mute. The other participants will not hear audio\n   * from the muted device anymore.\n   *\n   * @permissions\n   *  - `room.self.audio_mute`\n   *\n   * You need to specify the permissions when [creating the Video Room\n   * Token](https://developer.signalwire.com/apis/reference/create_room_token)\n   * on the server side.\n   *\n   * @example Muting the microphone:\n   * ```typescript\n   * await roomdevice.audioMute()\n   * ```\n   */\n  audioMute(): Rooms.AudioMuteMember\n\n  /**\n   * Unmutes the microphone if it had been previously muted.\n   *\n   * @permissions\n   *  - `room.self.audio_unmute`\n   *\n   * You need to specify the permissions when [creating the Video Room\n   * Token](https://developer.signalwire.com/apis/reference/create_room_token)\n   * on the server side.\n   *\n   * @example Unmuting the microphone:\n   * ```typescript\n   * await roomdevice.audioUnmute()\n   * ```\n   */\n  audioUnmute(): Rooms.AudioUnmuteMember\n\n  /**\n   * Puts the video on mute. Participants will see a mute image instead of the\n   * video stream.\n   *\n   * @permissions\n   *  - `room.self.video_mute`\n   *\n   * You need to specify the permissions when [creating the Video Room\n   * Token](https://developer.signalwire.com/apis/reference/create_room_token)\n   * on the server side.\n   *\n   * @example Muting the camera:\n   * ```typescript\n   * await roomdevice.videoMute()\n   * ```\n   */\n  videoMute(): Rooms.VideoMuteMember\n\n  /**\n   * Unmutes the video if it had been previously muted. Participants will start\n   * seeing the video stream again.\n   *\n   * @permissions\n   *  - `room.self.video_unmute`\n   *\n   * You need to specify the permissions when [creating the Video Room\n   * Token](https://developer.signalwire.com/apis/reference/create_room_token)\n   * on the server side.\n   *\n   * @example Unmuting the camera:\n   * ```typescript\n   * await roomdevice.videoUnmute()\n   * ```\n   */\n  videoUnmute(): Rooms.VideoUnmuteMember\n\n  /**\n   * @deprecated Use {@link setInputVolume} instead.\n   */\n  setMicrophoneVolume(params: { volume: number }): Rooms.SetInputVolumeMember\n\n  /**\n   * Sets the input volume level (e.g. for the microphone).\n   * @param params\n   * @param params.volume desired volume. Values range from -50 to 50, with a\n   * default of 0.\n   *\n   * @permissions\n   *  - `room.self.set_input_volume`\n   *\n   * You need to specify the permissions when [creating the Video Room\n   * Token](https://developer.signalwire.com/apis/reference/create_room_token)\n   * on the server side.\n   *\n   * @example\n   * ```typescript\n   * await roomdevice.setMicrophoneVolume({volume: -10})\n   * ```\n   */\n  setInputVolume(params: { volume: number }): Rooms.SetInputVolumeMember\n\n  /**\n   * Sets the input level at which the participant is identified as currently\n   * speaking.\n   * @param params\n   * @param params.value desired sensitivity. The default value is 30 and the\n   * scale goes from 0 (lowest sensitivity, essentially muted) to 100 (highest\n   * sensitivity).\n   *\n   * @permissions\n   *  - `room.self.set_input_sensitivity`\n   *\n   * You need to specify the permissions when [creating the Video Room\n   * Token](https://developer.signalwire.com/apis/reference/create_room_token)\n   * on the server side.\n   *\n   * @example\n   * ```typescript\n   * await roomdevice.setInputSensitivity({value: 80})\n   * ```\n   */\n  setInputSensitivity(params: {\n    value: number\n  }): Rooms.SetInputSensitivityMember\n}\n\n/**\n * We are using these interfaces in combination of\n * Object.defineProperties() to avoid code duplication and\n * expose a nice documentation via TypeDoc. The interface\n * forces TS checking while Object.defineProperties allow us\n * flexibility across different objects.\n */\nexport interface VideoRoomSessionMethods\n  extends OnlyFunctionProperties<CoreVideoRoomSessionContract> {\n  /** @deprecated Use {@link setVideoMuted} instead */\n  hideVideoMuted(): Rooms.HideVideoMuted\n  /** @deprecated Use {@link setVideoMuted} instead */\n  showVideoMuted(): Rooms.ShowVideoMuted\n}\n\nexport interface VideoRoomSessionContract {\n  deviceList: RoomSessionDevice[]\n  interactivityMode: VideoAuthorization['join_as']\n  permissions: VideoAuthorization['scopes']\n  /** The `layout.changed` event based on the current room layout */\n  currentLayoutEvent: VideoLayoutChangedEventParams\n  /** The layout returned from the `layout.changed` event based on the current room layout */\n  currentLayout: VideoLayoutChangedEventParams['layout']\n  /** The current position of the member returned from the `layout.changed` event */\n  currentPosition: VideoPosition | undefined\n  /**\n   * Joins the room session.\n   */\n  join(options?: BaseRoomSessionJoinParams): Promise<VideoRoomSessionContract>\n  /**\n   * Adds a screen sharing instance to the room. You can create multiple screen\n   * sharing instances and add all of them to the room.\n   * @param opts - {@link CreateScreenShareObjectOptions}\n   * @returns - {@link RoomSessionScreenShare}\n   *\n   * @deprecated Use {@link startScreenShare} instead.\n   */\n  createScreenShareObject(\n    opts?: CreateScreenShareObjectOptions\n  ): Promise<RoomSessionScreenShare>\n  /**\n   * Adds a camera device to the room. Using this method, a user can stream\n   * multiple video sources at the same time.\n   *\n   * @param opts - Specify the constraints for the device. In addition, you can\n   * add the `autoJoin` key to specify whether the device should immediately\n   * join the room or joining will be performed manually later. {@link AddCameraOptions}\n   * @returns - {@link RoomSessionDevice}\n   *\n   * @example Adding a specific camera:\n   * ```typescript\n   * await roomSession.addCamera({deviceId: \"gOtMHwZdoA6wMlAnhbfTmeRgPAsqa7iw1OwgKYtbTLA=\"})\n   * ```\n   */\n  addCamera(opts: AddCameraOptions): Promise<RoomSessionDevice>\n  /**\n   * Adds a microphone device to the room. Using this method, a user can stream\n   * multiple video sources at the same time.\n   *\n   * @param opts Specify the constraints for the device. In addition, you can\n   * add the `autoJoin` key to specify whether the device should immediately\n   * join the room or joining will be performed manually later. {@link AddMicrophoneOptions}\n   * @returns - {@link RoomSessionDevice}\n   *\n   * @example Adding a specific microphone:\n   * ```typescript\n   * await roomSession.addMicrophone({deviceId: \"PIn/IIDDgBUHzJkhRncv1m85hX1gC67xYIgJvvThB3Q=\"})\n   * ```\n   */\n  addMicrophone(opts: AddMicrophoneOptions): Promise<RoomSessionDevice>\n  /**\n   * Adds a device to the room. Using this method, a user can stream multiple\n   * sources at the same time. If you need to add a camera device or a\n   * microphone device, you can alternatively use the more specific methods\n   * {@link addCamera} and {@link addMicrophone}.\n   *\n   * @param opts Specify the constraints for the device. In addition, you can\n   * add the `autoJoin` key to specify whether the device should immediately\n   * join the room or joining will be performed manually later. {@link AddDeviceOptions}\n   * @returns - {@link RoomSessionDevice}\n   *\n   * @example Adding any of the microphone devices to the room (duplicate\n   * streams are possible):\n   * ```typescript\n   * await roomSession.addDevice({audio: true})\n   * ```\n   */\n  addDevice(opts: AddDeviceOptions): Promise<RoomSessionDevice>\n}\n\nexport interface RoomSessionDeviceMethods\n  extends RoomMemberSelfMethodsInterface {}\n\nexport interface RoomScreenShareMethods\n  extends RoomMemberSelfMethodsInterface {}\n\nexport interface BaseRoomSessionJoinParams {\n  audio?: MediaStreamConstraints['audio']\n  video?: MediaStreamConstraints['video']\n  receiveAudio?: boolean\n  receiveVideo?: boolean\n  sendAudio?: boolean\n  sendVideo?: boolean\n}\n\nexport type PagingCursor =\n  | {\n      before: string\n      after?: never\n    }\n  | {\n      before?: never\n      after: string\n    }\n\nexport type AudioElement = HTMLAudioElement & {\n  sinkId?: string\n  setSinkId?: (id: string) => Promise<void>\n}\n","import type {\n  PubSubContract,\n  ConsumerContract,\n  UserOptions,\n  PubSub as PubSubNamespace,\n} from '@signalwire/core'\nimport { createClient } from '../createClient'\n\nexport interface ClientApiEvents extends PubSubNamespace.BasePubSubApiEvents {}\n\n/** @ignore */\nexport interface ClientFullState extends Client {}\nexport interface Client\n  extends PubSubContract,\n    Omit<ConsumerContract<ClientApiEvents, ClientFullState>, 'subscribe'> {}\n\n/** @ignore */\nexport interface ClientOptions extends UserOptions {}\n\ntype ClientMethods = keyof Client\nconst INTERCEPTED_METHODS: ClientMethods[] = [\n  'getAllowedChannels',\n  'subscribe',\n  'publish',\n]\n\n/**\n * You can use the Client object to build a messaging system into the browser.\n *\n * Example usage:\n *\n * ```js\n * import { PubSub } from '@signalwire/js'\n *\n * const pubSubClient = new PubSub.Client({\n *   token: '<your pubSub token>', // get this from the REST APIs\n * })\n *\n * await pubSubClient.subscribe([ 'mychannel1', 'mychannel2' ])\n *\n * pubSubClient.on('message', (message) => {\n *   console.log(\"Received\", message.content,\n *               \"on\", message.channel,\n *               \"at\", message.publishedAt)\n * })\n *\n * await pubSubClient.publish({\n *   channel: 'mychannel1',\n *   content: 'hello world'\n * })\n * ```\n *\n * ## Events\n *\n * Please see {@link ClientApiEvents} for the list of events emitted by a pubSub\n * Client object.\n */\nexport const Client = function (pubSubOptions: ClientOptions) {\n  const client = createClient(pubSubOptions)\n\n  const createInterceptor = <K extends keyof Client>(prop: K) => {\n    return async (...params: Parameters<Client[K]>) => {\n      await client.connect()\n\n      // @ts-expect-error\n      return client.pubSub[prop](...params)\n    }\n  }\n\n  const interceptors = {\n    _session: client,\n    disconnect: () => client.disconnect(),\n  } as const\n\n  return new Proxy<Client>(client.pubSub, {\n    get(target: Client, prop: keyof Client, receiver: any) {\n      if (prop in interceptors) {\n        // @ts-expect-error\n        return interceptors[prop]\n      }\n\n      if (INTERCEPTED_METHODS.includes(prop)) {\n        return createInterceptor(prop)\n      }\n\n      return Reflect.get(target, prop, receiver)\n    },\n  })\n  // For consistency with other constructors we'll make TS force the use of `new`\n} as unknown as { new (pubSubOptions: ClientOptions): Client }\n","/**\n * ============ CAUTION ============\n *\n * Anything we export from here in available on the Public interface.\n */\n\nexport * from './SignalWire'\nexport * from './interfaces/address'\nexport * from './interfaces/capabilities'\nexport * from './interfaces/conversation'\nexport * from './interfaces/device'\nexport * from './interfaces/incomingCallManager'\n\nexport {\n  OnlineParams,\n  HandlePushNotificationParams,\n  HandlePushNotificationResult,\n  DialParams,\n  ReattachParams\n} from './interfaces/wsClient'\nexport {\n  SignalWireClient,\n  SignalWireContract,\n  SignalWireClientParams,\n  GetSubscriberInfoResponse,\n  GetSubscriberInfoResult,\n  PaginatedResponse,\n  PaginatedResult,\n} from './interfaces'\nexport { FabricRoomSession, isFabricRoomSession } from './FabricRoomSession'\n","import jwtDecode from 'jwt-decode'\nimport { getLogger, HttpError } from '@signalwire/core'\nimport type {\n  GetAddressResponse,\n  GetAddressesParams,\n  RegisterDeviceParams,\n  UnregisterDeviceParams,\n  RegisterDeviceResponse,\n  GetAddressParams,\n  GetAddressResult,\n  GetAddressesResponse,\n  GetAddressesResult,\n  RegisterDeviceResult,\n  GetSubscriberInfoResponse,\n  GetSubscriberInfoResult,\n  FabricUserOptions,\n} from './interfaces'\nimport { CreateHttpClient, createHttpClient } from './createHttpClient'\nimport { buildPaginatedResult } from '../utils/paginatedResult'\nimport { makeQueryParamsUrls } from '../utils/makeQueryParamsUrl'\nimport {\n  isGetAddressByIdParams,\n  isGetAddressByNameParams,\n  isGetAddressesResponse,\n} from './utils/typeGuard'\nimport { HTTPClientContract } from './interfaces/httpClient'\n\ntype JWTHeader = { ch?: string; typ?: string }\n\n// TODO: extends from a Base class to share from core\nexport class HTTPClient implements HTTPClientContract {\n  private httpClient: CreateHttpClient\n\n  constructor(public options: FabricUserOptions) {\n    this.httpClient = createHttpClient({\n      baseUrl: `https://${this.httpHost}`,\n      headers: {\n        Authorization: `Bearer ${this.options.token}`,\n      },\n      maxApiRequestRetries: this.options.maxApiRequestRetries,\n      apiRequestRetriesDelay: this.options.apiRequestRetriesDelay,\n      apiRequestRetriesDelayIncrement: this.options.apiRequestRetriesDelayIncrement\n    })\n  }\n\n  get fetch(): CreateHttpClient {\n    return this.httpClient\n  }\n\n  get httpHost() {\n    let decodedJwt: JWTHeader = {}\n    try {\n      decodedJwt = jwtDecode<JWTHeader>(this.options.token, {\n        header: true,\n      })\n    } catch (e) {\n      if (process.env.NODE_ENV !== 'production') {\n        getLogger().debug('[JWTSession] error decoding the JWT')\n      }\n    }\n    // Shouldn't this be other way around?\n    const host = this.options.host || decodedJwt?.ch\n    if (!host) {\n      return 'fabric.signalwire.com'\n    }\n    return `fabric.${host.split('.').splice(1).join('.')}`\n  }\n\n  public async getAddress(params: GetAddressParams): Promise<GetAddressResult> {\n    let path = '/api/fabric/addresses'\n    if (isGetAddressByNameParams(params)) {\n      path = `${path}?name=${params.name}`\n    } else if (isGetAddressByIdParams(params)) {\n      path = `${path}/${params.id}`\n    }\n\n    const { body } = await this.httpClient<\n      GetAddressResponse | GetAddressesResponse\n    >(path)\n    if (isGetAddressesResponse(body)) {\n      // FIXME until the server handles a index lookup by name we need to handle it as a search result\n      if (!body.data[0]) throw new HttpError(404, 'Not Found')\n      return body.data[0]\n    }\n    return body\n  }\n\n  public async getAddresses(\n    params?: GetAddressesParams\n  ): Promise<GetAddressesResult> {\n    const { type, displayName, pageSize, sortBy, sortOrder } = params || {}\n\n    let path = '/api/fabric/addresses'\n\n    const queryParams = new URLSearchParams()\n    if (type) {\n      queryParams.append('type', type)\n    }\n    if (displayName) {\n      queryParams.append('display_name', displayName)\n    }\n    if (pageSize) {\n      queryParams.append('page_size', pageSize.toString())\n    }\n\n    if (sortBy) {\n      queryParams.append('sort_by', sortBy)\n    }\n\n    if (sortOrder) {\n      queryParams.append('sort_order', sortOrder)\n    }\n\n    const queryUrl = makeQueryParamsUrls(path, queryParams)\n    getLogger().debug(`[getAddresses] query URL ${queryUrl}`)\n    const { body } = await this.httpClient<GetAddressesResponse>(queryUrl)\n\n    return buildPaginatedResult(body, this.httpClient)\n  }\n\n  public async registerDevice(\n    params: RegisterDeviceParams\n  ): Promise<RegisterDeviceResult> {\n    const { deviceType, deviceToken } = params\n\n    const path = '/subscriber/devices' as const\n    const { body } = await this.httpClient<RegisterDeviceResponse>(path, {\n      method: 'POST',\n      body: {\n        device_type: deviceType,\n        device_token: deviceToken,\n      },\n    })\n\n    return body\n  }\n\n  public async unregisterDevice(params: UnregisterDeviceParams) {\n    const { id } = params\n\n    const path = `/subscriber/devices/${id}` as const\n    await this.httpClient<void>(path, {\n      method: 'DELETE',\n    })\n  }\n\n  public async getSubscriberInfo(): Promise<GetSubscriberInfoResult> {\n    let path = '/api/fabric/subscriber/info'\n\n    const { body } = await this.httpClient<GetSubscriberInfoResponse>(path)\n\n    return body\n  }\n}\n","import {\n  asyncRetry,\n  AuthError,\n  HttpError,\n  increasingDelay,\n} from '@signalwire/core'\nimport { ApiRequestRetriesOptions } from './interfaces'\n\ninterface InternalHttpResponse<T> extends Response {\n  parsedBody?: T\n}\n\nconst DEFAULT_MAX_RETRIES = 0\nconst DEFAULT_INITIAL_DELAY = 0\nconst DEFAULT_DELAY_VARIATION = 0\nconst DEFAULT_TIMEOUT = 30000\n\nasync function http<T>(\n  input: string,\n  init: RequestInit | undefined,\n  maxRetries?: number,\n  retriesDelay?: number,\n  retriesDelayIncrement?: number\n): Promise<InternalHttpResponse<T>> {\n  const response: InternalHttpResponse<T> = await asyncRetry({\n    asyncCallable: () => fetch(input, init),\n    maxRetries,\n    validator: (response) => {\n      // whe should retry only error above Http-500\n      if (!response.ok && response.status >= 500) {\n        throw new HttpError(response.status, response.statusText)\n      }\n    },\n    delayFn: increasingDelay({\n      initialDelay: retriesDelay,\n      variation: retriesDelayIncrement,\n    }),\n  })\n\n  if (!response.ok) {\n    if (response.status === 401) {\n      throw new AuthError(response.status, 'Unauthorized')\n    }\n\n    let errorResponse\n    try {\n      errorResponse = await response.json()\n    } catch (e) {}\n\n    const errorMessage = errorResponse?.errors\n      ? JSON.stringify(errorResponse.errors)\n      : 'Not Found'\n\n    throw new HttpError(response.status, errorMessage, errorResponse)\n  }\n\n  try {\n    // might throw if body is empty\n    response.parsedBody = await response.json()\n  } catch (e) {}\n\n  return response\n}\n\ntype CreateHttpClientOptions = RequestInit &\n  Partial<ApiRequestRetriesOptions> & {\n    baseUrl: string\n    /**\n     * Timeout in milliseconds\n     */\n    timeout?: number\n  }\n\ninterface HttpClientRequestInit extends Omit<RequestInit, 'body'> {\n  body?: Record<string, unknown>\n  searchParams?: Record<string, any>\n}\n\nexport type CreateHttpClient = ReturnType<typeof createHttpClient>\n\nexport const createHttpClient = (\n  {\n    baseUrl,\n    maxApiRequestRetries: retries = DEFAULT_MAX_RETRIES,\n    apiRequestRetriesDelay: retriesDelay = DEFAULT_INITIAL_DELAY,\n    apiRequestRetriesDelayIncrement:\n      retriesDelayIncrement = DEFAULT_DELAY_VARIATION,\n    timeout = DEFAULT_TIMEOUT,\n    ...globalOptions\n  }: CreateHttpClientOptions,\n  fetcher = http\n) => {\n  const apiClient = async <T>(\n    path: string,\n    options?: HttpClientRequestInit\n  ): Promise<{ body: T }> => {\n    const headers = {\n      ...(options?.body ? { 'Content-Type': 'application/json' } : {}),\n      ...globalOptions.headers,\n      ...options?.headers,\n    }\n\n    const reqInit = getRequestInit({\n      ...globalOptions,\n      ...options,\n      headers,\n    })\n    // reqInit.mode = 'no-cors'\n    // reqInit.credentials = 'include'\n\n    let timerId\n    if (timeout) {\n      const controller = new AbortController()\n      const signal = controller.signal\n\n      reqInit.signal = signal\n\n      timerId = setTimeout(() => {\n        controller.abort()\n      }, timeout)\n    }\n\n    try {\n      const response = await fetcher<T>(\n        getUrl({\n          path,\n          baseUrl,\n          searchParams: options?.searchParams,\n        }),\n        reqInit,\n        retries,\n        retriesDelay,\n        retriesDelayIncrement\n      )\n\n      return { body: response.parsedBody as T }\n    } catch (e) {\n      throw e\n    } finally {\n      timerId && clearTimeout(timerId)\n    }\n  }\n\n  return apiClient\n}\n\nconst getBody = (body: unknown) => {\n  return typeof body === 'string' ? body : JSON.stringify(body)\n}\n\nconst getRequestInit = (options: any): RequestInit => {\n  return Object.entries(options).reduce((reducer, [key, value]) => {\n    if (key === 'body') {\n      return {\n        ...reducer,\n        body: getBody(value),\n      }\n    } else if (value != undefined) {\n      return {\n        ...reducer,\n        [key]: value,\n      }\n    }\n\n    return reducer\n  }, {} as RequestInit)\n}\n\nconst getUrl = ({\n  path,\n  baseUrl,\n  searchParams,\n}: {\n  baseUrl: string\n  path: string\n  searchParams?: Record<string, any>\n}) => {\n  const url = new URL(path, baseUrl)\n\n  if (searchParams) {\n    Object.entries(searchParams).forEach(([key, value]) => {\n      if (value != undefined) {\n        url.searchParams.append(key, value)\n      }\n    })\n  }\n  return url.toString()\n}\n","import { PaginatedResponse } from '../fabric/interfaces'\nimport { CreateHttpClient } from '../fabric/createHttpClient'\n\nexport function buildPaginatedResult<T>(\n  body: PaginatedResponse<T>,\n  client: CreateHttpClient\n) {\n  const anotherPage = async (url?: string) => {\n    if (!url) return Promise.resolve(undefined)\n    const { body } = await client<PaginatedResponse<T>>(url)\n    return buildPaginatedResult<T>(body, client)\n  }\n\n  return {\n    data: body.data,\n    self: async () => {\n      const { self } = body.links\n      return anotherPage(self)\n    },\n    nextPage: async () => {\n      const { next } = body.links\n      return anotherPage(next)\n    },\n    prevPage: async () => {\n      const { prev } = body.links\n      return anotherPage(prev)\n    },\n    firstPage: async () => {\n      const { first } = body.links\n      return anotherPage(first)\n    },\n    hasNext: Boolean(body.links.next),\n    hasPrev: Boolean(body.links.prev),\n  }\n}\n","/**\n * Constructs a URL with query parameters.\n *\n * @param path The base path of the URL.\n * @param queryParams An instance of URLSearchParams containing all query parameters.\n * @returns The constructed URL with query parameters.\n */\nexport function makeQueryParamsUrls(\n  path: string,\n  queryParams: URLSearchParams\n): string {\n  const queryString = queryParams.toString()\n  return queryString ? `${path}?${queryString}` : path\n}\n","import {\n  GetAddressParams,\n  GetAddressByNameParams,\n  GetAddressByIdParams,\n  GetAddressResponse,\n  GetAddressesResponse,\n} from '../interfaces'\n\nexport const isGetAddressByNameParams = (\n  obj: GetAddressParams\n): obj is GetAddressByNameParams => {\n  return obj && 'name' in obj\n}\n\nexport const isGetAddressByIdParams = (\n  obj: GetAddressParams\n): obj is GetAddressByIdParams => {\n  return obj && 'id' in obj\n}\n\nexport const isGetAddressResponse = (\n  obj: GetAddressResponse | GetAddressesResponse\n): obj is GetAddressResponse => {\n  return obj && 'id' in obj && 'name' in obj\n}\n\nexport const isGetAddressesResponse = (\n  obj: GetAddressResponse | GetAddressesResponse\n): obj is GetAddressesResponse => {\n  return obj && 'data' in obj\n}\n","import {\n  actions,\n  BaseClient,\n  CallJoinedEventParams as InternalCallJoinedEventParams,\n  VertoBye,\n  VertoSubscribe,\n} from '@signalwire/core'\nimport { MakeRoomOptions } from '../video'\nimport {\n  createFabricRoomSessionObject,\n  FabricRoomSession,\n} from './FabricRoomSession'\nimport { buildVideoElement } from '../buildVideoElement'\nimport {\n  CallParams,\n  DialParams,\n  ReattachParams,\n  IncomingInvite,\n  OnlineParams,\n  HandlePushNotificationParams,\n  WSClientOptions,\n  HandlePushNotificationResult,\n} from './interfaces'\nimport { IncomingCallManager } from './IncomingCallManager'\nimport { wsClientWorker } from './workers'\nimport { createWSClient } from './createWSClient'\nimport { WSClientContract } from './interfaces/wsClient'\nimport { getStorage } from '../utils/storage'\nimport { PREVIOUS_CALLID_STORAGE_KEY } from './utils/constants'\n\nexport class WSClient extends BaseClient<{}> implements WSClientContract {\n  private _incomingCallManager: IncomingCallManager\n  private _disconnected: boolean = false\n\n  constructor(private wsClientOptions: WSClientOptions) {\n    const client = createWSClient(wsClientOptions)\n    super(client)\n\n    this._incomingCallManager = new IncomingCallManager({\n      client: this,\n      buildInboundCall: this.buildInboundCall.bind(this),\n      executeVertoBye: this.executeVertoBye.bind(this),\n    })\n\n    this.runWorker('wsClientWorker', {\n      worker: wsClientWorker,\n      initialState: {\n        handleIncomingInvite: (invite: IncomingInvite) => {\n          this._incomingCallManager.handleIncomingInvite({\n            source: 'websocket',\n            ...invite,\n          })\n        },\n      },\n    })\n  }\n\n  private makeFabricObject(makeRoomOptions: MakeRoomOptions) {\n    const {\n      rootElement,\n      applyLocalVideoOverlay = true,\n      applyMemberOverlay = true,\n      stopCameraWhileMuted = true,\n      stopMicrophoneWhileMuted = true,\n      mirrorLocalVideoOverlay = true,\n      ...options\n    } = makeRoomOptions\n\n    const room = createFabricRoomSessionObject({\n      ...options,\n      store: this.store,\n    })\n\n    /**\n     * If the user provides a `rootElement` we'll\n     * automatically handle the Video element for them\n     */\n    if (rootElement) {\n      try {\n        buildVideoElement({\n          applyLocalVideoOverlay,\n          applyMemberOverlay,\n          mirrorLocalVideoOverlay,\n          room,\n          rootElement,\n        })\n      } catch (error) {\n        this.logger.error('Unable to build the video element automatically')\n      }\n    }\n\n    /**\n     * If the user joins with `join_video_muted: true` or\n     * `join_audio_muted: true` we'll stop the streams\n     * right away.\n     */\n    const joinMutedHandler = (params: InternalCallJoinedEventParams) => {\n      const member = params.room_session.members?.find(\n        (m) => m.member_id === room.memberId\n      )\n\n      if (member?.audio_muted) {\n        try {\n          room.stopOutboundAudio()\n        } catch (error) {\n          this.logger.error('Error handling audio_muted', error)\n        }\n      }\n\n      if (member?.video_muted) {\n        try {\n          room.stopOutboundVideo()\n        } catch (error) {\n          this.logger.error('Error handling video_muted', error)\n        }\n      }\n    }\n\n    room.on('room.subscribed', joinMutedHandler)\n\n    /**\n     * Stop or Restore outbound audio on \"member.updated\" event\n     */\n    if (stopMicrophoneWhileMuted) {\n      room.on('member.updated.audioMuted', ({ member }) => {\n        try {\n          if (member.member_id === room.memberId && 'audio_muted' in member) {\n            member.audio_muted\n              ? room.stopOutboundAudio()\n              : room.restoreOutboundAudio()\n          }\n        } catch (error) {\n          this.logger.error('Error handling audio_muted', error)\n        }\n      })\n    }\n\n    /**\n     * Stop or Restore outbound video on \"member.updated\" event\n     */\n    if (stopCameraWhileMuted) {\n      room.on('member.updated.videoMuted', ({ member }) => {\n        try {\n          if (member.member_id === room.memberId && 'video_muted' in member) {\n            member.video_muted\n              ? room.stopOutboundVideo()\n              : room.restoreOutboundVideo()\n          }\n        } catch (error) {\n          this.logger.error('Error handling video_muted', error)\n        }\n      })\n    }\n\n    return room\n  }\n\n  private buildOutboundCall(params: ReattachParams & { attach?: boolean }) {\n    let video = false\n    let negotiateVideo = false\n\n    if (params.to) {\n      const [pathname, query] = params.to.split('?')\n      if (!pathname) {\n        throw new Error('Invalid destination address')\n      }\n\n      const queryParams = new URLSearchParams(query)\n      const channel = queryParams.get('channel')\n      if (channel === 'video') {\n        video = true\n        negotiateVideo = true\n      }\n    }\n\n    const call = this.makeFabricObject({\n      audio: params.audio ?? true,\n      video: params.video ?? video,\n      negotiateAudio: params.negotiateAudio ?? true,\n      negotiateVideo: params.negotiateVideo ?? negotiateVideo,\n      rootElement: params.rootElement || this.wsClientOptions.rootElement,\n      applyLocalVideoOverlay: params.applyLocalVideoOverlay,\n      applyMemberOverlay: params.applyMemberOverlay,\n      stopCameraWhileMuted: params.stopCameraWhileMuted,\n      stopMicrophoneWhileMuted: params.stopMicrophoneWhileMuted,\n      mirrorLocalVideoOverlay: params.mirrorLocalVideoOverlay,\n      watchMediaPackets: false,\n      destinationNumber: params.to ?? '',\n      nodeId: params.nodeId,\n      attach: params.attach ?? false,\n      disableUdpIceServers: params.disableUdpIceServers || false,\n      userVariables: params.userVariables || this.wsClientOptions.userVariables,\n      fromFabricAddressId: params.fromFabricAddressId,\n    })\n\n    // WebRTC connection left the room.\n    call.once('destroy', () => {\n      this.logger.debug('RTC Connection Destroyed')\n      call.destroy()\n    })\n\n    this.session.once('session.disconnected', () => {\n      this.logger.debug('Session Disconnected')\n      call.destroy()\n      this.destroy()\n    })\n\n    // TODO: This is for memberList.updated event and it is not yet supported in CF SDK\n    // @ts-expect-error\n    call.attachPreConnectWorkers()\n    return call\n  }\n\n  private buildInboundCall(payload: IncomingInvite, params: CallParams) {\n    const call = this.makeFabricObject({\n      audio: params.audio ?? true,\n      video: params.video ?? true,\n      negotiateAudio: params.negotiateAudio ?? true,\n      negotiateVideo: params.negotiateVideo ?? true,\n      rootElement: params.rootElement || this.wsClientOptions.rootElement,\n      applyLocalVideoOverlay: true,\n      applyMemberOverlay: true,\n      stopCameraWhileMuted: true,\n      stopMicrophoneWhileMuted: true,\n      watchMediaPackets: false,\n      nodeId: payload.nodeId,\n      remoteSdp: payload.sdp,\n      prevCallId: payload.callID,\n      disableUdpIceServers: params.disableUdpIceServers || false,\n      userVariables: params.userVariables || this.wsClientOptions.userVariables,\n    })\n\n    // WebRTC connection left the room.\n    call.once('destroy', () => {\n      this.logger.debug('RTC Connection Destroyed')\n      call.destroy()\n    })\n\n    this.session.once('session.disconnected', () => {\n      this.logger.debug('Session Disconnected')\n      call.destroy()\n      this.destroy()\n    })\n\n    // TODO: This is for memberList.updated event and it is not yet supported in CF SDK\n    // @ts-expect-error\n    call.attachPreConnectWorkers()\n    return call\n  }\n\n  private async executeVertoBye(callId: string, nodeId: string) {\n    try {\n      return await this.execute<unknown, void>({\n        method: 'webrtc.verto',\n        params: {\n          callID: callId,\n          node_id: nodeId,\n          message: VertoBye({\n            cause: 'USER_BUSY',\n            causeCode: '17',\n            dialogParams: { callID: callId },\n          }),\n        },\n      })\n    } catch (error) {\n      this.logger.warn('The call is not available anymore', callId)\n      throw error\n    }\n  }\n\n  private async executeVertoSubscribe(callId: string, nodeId: string) {\n    try {\n      return await this.execute<unknown, void>({\n        method: 'webrtc.verto',\n        params: {\n          callID: callId,\n          node_id: nodeId,\n          subscribe: [],\n          message: VertoSubscribe({\n            sessid: callId,\n            eventChannel: [],\n          }),\n        },\n      })\n    } catch (error) {\n      this.logger.warn('The call is not available anymore', callId)\n      throw error\n    }\n  }\n\n  public override disconnect() {\n    return new Promise<void>((resolve, _reject) => {\n      if (this._disconnected) {\n        resolve()\n      }\n\n      this.session.once('session.disconnected', () => {\n        this.destroy()\n        resolve()\n        this._disconnected = true\n      })\n\n      super.disconnect()\n    })\n  }\n\n  public async dial(params: DialParams) {\n    return new Promise<FabricRoomSession>(async (resolve, reject) => {\n      try {\n        // in case the user left the previous call with hangup, and is not reattaching\n        getStorage()?.removeItem(PREVIOUS_CALLID_STORAGE_KEY)\n        const call = this.buildOutboundCall(params)\n        resolve(call)\n      } catch (error) {\n        this.logger.error('Unable to connect and dial a call', error)\n        reject(error)\n      }\n    })\n  }\n\n  public async reattach(params: ReattachParams) {\n    return new Promise<FabricRoomSession>(async (resolve, reject) => {\n      try {\n        const call = this.buildOutboundCall({ ...params, attach: true })\n        resolve(call)\n      } catch (error) {\n        this.logger.error('Unable to connect and reattach a call', error)\n        reject(error)\n      }\n    })\n  }\n\n  public handlePushNotification(params: HandlePushNotificationParams) {\n    const { incomingCallHandler } = params\n    this._incomingCallManager.setNotificationHandlers({\n      pushNotification: incomingCallHandler,\n    })\n\n    return new Promise<HandlePushNotificationResult>(\n      async (resolve, reject) => {\n        const { decrypted, type } = params\n        if (type !== 'call_invite') {\n          this.logger.warn('Unknown notification type', params)\n          reject('Unknown notification type')\n        }\n        this.logger.debug('handlePushNotification', params)\n        const {\n          params: { params: payload },\n          node_id: nodeId,\n        } = decrypted\n        try {\n          // Catch the error temporarly\n          try {\n            // Send verto.subscribe\n            await this.executeVertoSubscribe(payload.callID, nodeId)\n          } catch (error) {\n            this.logger.warn('Verto Subscribe', error)\n          }\n\n          this._incomingCallManager.handleIncomingInvite({\n            source: 'pushNotification',\n            nodeId,\n            ...payload,\n          })\n\n          resolve({ resultType: 'inboundCall' })\n        } catch (error) {\n          reject(error)\n        }\n      }\n    )\n  }\n\n  public updateToken(token: string) {\n    return new Promise<void>((resolve, reject) => {\n      this.session.once('session.auth_error', (error) => {\n        reject(error)\n      })\n      this.session.once('session.connected', () => {\n        resolve()\n      })\n      this.store.dispatch(actions.reauthAction({ token }))\n    })\n  }\n\n  /**\n   * Mark the client as 'online' to receive calls over WebSocket\n   */\n  public async online({ incomingCallHandlers }: OnlineParams) {\n    if (incomingCallHandlers.all || incomingCallHandlers.pushNotification) {\n      this.logger.warn(\n        `Make sure the device is not registered to receive Push Notifications while it is online`\n      )\n    }\n    this._incomingCallManager.setNotificationHandlers(incomingCallHandlers)\n    return this.execute<unknown, void>({\n      method: 'subscriber.online',\n      params: {},\n    })\n  }\n\n  /**\n   * Mark the client as 'offline' to receive calls over WebSocket\n   */\n  public offline() {\n    this._incomingCallManager.setNotificationHandlers({})\n    return this.execute<unknown, void>({\n      method: 'subscriber.offline',\n      params: {},\n    })\n  }\n\n}\n","import { FabricRoomSession } from './FabricRoomSession'\nimport {\n  CallParams,\n  IncomingCallHandlers,\n  IncomingCallNotification,\n  IncomingInvite,\n  IncomingInviteWithSource,\n} from './interfaces'\nimport { WSClient } from './WSClient'\n\ninterface IncomingCallManagerOptions {\n  client: WSClient\n  buildInboundCall: WSClient['buildInboundCall']\n  executeVertoBye: WSClient['executeVertoBye']\n}\n\nexport class IncomingCallManager {\n  private _client: WSClient\n  private _pendingInvites: Record<string, IncomingInvite> = {}\n  private _handlers: IncomingCallHandlers = {}\n\n  constructor(private options: IncomingCallManagerOptions) {\n    this._client = options.client\n  }\n\n  private _buildNotification(invite: IncomingInvite): IncomingCallNotification {\n    const accept = async (params: CallParams) => {\n      return new Promise<FabricRoomSession>((resolve, reject) => {\n        delete this._pendingInvites[invite.callID]\n        try {\n          const call = this.options.buildInboundCall(invite, params)\n          call.answer()\n\n          resolve(call)\n        } catch (e) {\n          reject(e)\n        }\n      })\n    }\n\n    const reject = () => {\n      delete this._pendingInvites[invite.callID]\n      return this.options.executeVertoBye(invite.callID, invite.nodeId)\n    }\n\n    return {\n      invite: {\n        details: invite,\n        accept: (params) => accept(params),\n        reject: () => reject(),\n      },\n    }\n  }\n\n  setNotificationHandlers(handlers: IncomingCallHandlers) {\n    this._handlers.all = handlers.all\n    if (\n      (handlers.pushNotification &&\n        this._handlers.all != handlers.pushNotification) ||\n      !handlers.pushNotification\n    ) {\n      this._handlers.pushNotification = handlers.pushNotification\n    }\n    if (\n      (handlers.websocket && this._handlers.all != handlers.websocket) ||\n      !handlers.websocket\n    ) {\n      this._handlers.websocket = handlers.websocket\n    }\n  }\n\n  handleIncomingInvite(incomingInvite: IncomingInviteWithSource) {\n    if (incomingInvite.callID in this._pendingInvites) {\n      this._client.logger.debug(\n        `skiping nottification for pending invite to callID: ${incomingInvite.callID}`\n      )\n      return\n    }\n    this._pendingInvites[incomingInvite.callID] = incomingInvite\n\n    if (!(this._handlers.all || this._handlers[incomingInvite.source])) {\n      this._client.logger.warn('Skiping nottification due to no listeners')\n      return\n    }\n\n    const notification = this._buildNotification(incomingInvite)\n\n    this._handlers.all?.(notification)\n    const handler = this._handlers[incomingInvite.source]\n    handler?.(notification)\n  }\n}\n","import { configureStore } from '@signalwire/core'\nimport { SATSession } from './SATSession'\nimport { WSClientOptions } from './interfaces'\n\nexport const createWSClient = (options: WSClientOptions) => {\n  const store = configureStore({\n    userOptions: options,\n    SessionConstructor: SATSession,\n  })\n\n  return { ...options, store }\n}\n","import {\n  asyncRetry,\n  increasingDelay,\n  JSONRPCRequest,\n  JSONRPCResponse,\n  RPCReauthenticate,\n  RPCReauthenticateParams,\n  SATAuthorization,\n  UNIFIED_CONNECT_VERSION,\n  isConnectRequest,\n  getLogger,\n  isVertoInvite,\n  SYMBOL_EXECUTE_CONNECTION_CLOSED,\n  SYMBOL_EXECUTE_TIMEOUT,\n} from '@signalwire/core'\nimport { JWTSession } from '../JWTSession'\nimport { SATSessionOptions } from './interfaces'\n/**\n * SAT Session is for the Call Fabric SDK\n */\nexport class SATSession extends JWTSession {\n  public connectVersion = UNIFIED_CONNECT_VERSION\n\n  constructor(public options: SATSessionOptions) {\n    super(options)\n  }\n\n  override get signature() {\n    if (this._rpcConnectResult) {\n      const { authorization } = this._rpcConnectResult\n      return (authorization as SATAuthorization).jti\n    }\n    return undefined\n  }\n\n  override async _checkTokenExpiration() {\n    /**\n     * noop\n     *\n     * The Call Fabric SDK does not attach any timer and\n     * does not emit any events to inform the user about the token expiry.\n     */\n  }\n\n  /**\n   * Reauthenticate with the SignalWire Network using a newer SAT.\n   * If the session has expired, this will reconnect it.\n   * @return Promise<void>\n   */\n  override async reauthenticate() {\n    this.logger.debug('Session Reauthenticate', {\n      ready: this.ready,\n      expired: this.expired,\n    })\n    if (!this.ready || this.expired) {\n      return this.connect()\n    }\n\n    const params: RPCReauthenticateParams = {\n      project: this._rpcConnectResult.authorization.project_id,\n      jwt_token: this.options.token,\n    }\n\n    try {\n      const reauthResponse = await this.execute(RPCReauthenticate(params))\n\n      this._rpcConnectResult = {\n        ...this._rpcConnectResult,\n        ...reauthResponse,\n      }\n    } catch (error) {\n      throw error\n    }\n  }\n\n  override async execute(msg: JSONRPCRequest | JSONRPCResponse): Promise<any> {\n    return asyncRetry({\n      asyncCallable: async () => {\n        await this._waitConnected() // avoid queuing a retry\n        return super.execute(msg)\n      },\n      maxRetries: this.options.maxApiRequestRetries,\n      delayFn: increasingDelay({\n        initialDelay: this.options.apiRequestRetriesDelay,\n        variation: this.options.apiRequestRetriesDelayIncrement,\n      }),\n      expectedErrorHandler: (error) => {\n        getLogger().warn(error)\n        if (isConnectRequest(msg)) {\n          // `signalwire.connect` retries are handle by the connection\n          return true\n        }\n        if (isVertoInvite(msg) && ![SYMBOL_EXECUTE_CONNECTION_CLOSED, SYMBOL_EXECUTE_TIMEOUT].includes(error)) {\n          // we can't retry verto.invites after errors on the transport layer\n          getLogger().debug('skip verto.invite retry on error:', error)\n          return true\n        }\n        return false\n      },\n    })\n  }\n}\n","import { HTTPClient } from './HTTPClient'\nimport { SignalWireClient, SignalWireClientParams } from './interfaces'\nimport { WSClient } from './WSClient'\nimport {\n  DEFAULT_API_REQUEST_RETRIES,\n  DEFAULT_API_REQUEST_RETRIES_DELAY,\n  DEFAULT_API_REQUEST_RETRIES_DELAY_INCREMENT,\n} from './utils/constants'\n\nexport const SignalWire = (() => {\n  let instance: Promise<SignalWireClient> | null = null\n\n  return (params: SignalWireClientParams): Promise<SignalWireClient> => {\n    if (!instance) {\n      instance = new Promise<SignalWireClient>(async (resolve, reject) => {\n        try {\n          const options = {\n            maxApiRequestRetries: DEFAULT_API_REQUEST_RETRIES,\n            apiRequestRetriesDelay: DEFAULT_API_REQUEST_RETRIES_DELAY,\n            apiRequestRetriesDelayIncrement:\n              DEFAULT_API_REQUEST_RETRIES_DELAY_INCREMENT,\n            ...params,\n          }\n\n          const wsClient = new WSClient(options)\n          const httpClient = new HTTPClient(options)\n          const conversationError = (method: string) => {\n            return () => {\n              throw new Error(\n                `This version Conversation.${method} is unsupported by the backend. Use @signalwire/client instead.`\n              )\n            }\n          }\n\n          // Connect the WebSocket and authenticate the user\n          await wsClient.connect()\n\n          resolve({\n            registerDevice: httpClient.registerDevice.bind(httpClient),\n            unregisterDevice: httpClient.unregisterDevice.bind(httpClient),\n            getSubscriberInfo: httpClient.getSubscriberInfo.bind(httpClient),\n            disconnect: async () => {\n              await wsClient.disconnect()\n              instance = null // Reset the singleton instance on disconnect\n            },\n            online: wsClient.online.bind(wsClient),\n            offline: wsClient.offline.bind(wsClient),\n            dial: wsClient.dial.bind(wsClient),\n            reattach: wsClient.reattach.bind(wsClient),\n            handlePushNotification:\n              wsClient.handlePushNotification.bind(wsClient),\n            updateToken: wsClient.updateToken.bind(wsClient),\n            address: {\n              getAddresses: httpClient.getAddresses.bind(httpClient),\n              getAddress: httpClient.getAddress.bind(httpClient),\n            },\n            conversation: {\n              getConversations: conversationError(\n                'getConversations'),\n              getMessages: conversationError(\n                'getMessages'),\n              getConversationMessages: conversationError(\n                'getConversationMessages'),\n              subscribe: conversationError(\n                'subscribe'),\n              sendMessage: conversationError(\n                'sendMessage'),\n              join: conversationError(\n                'join'),\n            },\n            chat: {\n              getMessages: conversationError(\n                'getMessages'),\n              subscribe: conversationError(\n                'subscribe'),\n              sendMessage: conversationError(\n                'sendMessage'),\n              join: conversationError(\n                'join'),\n            },\n            // @ts-expect-error For debugging purposes\n            on: wsClient.on.bind(wsClient),\n            off: wsClient.off.bind(wsClient),\n            __httpClient: httpClient,\n            __wsClient: wsClient,\n          })\n        } catch (error) {\n          reject(error)\n        }\n      }).catch((error) => {\n        /**\n         * Reset the instance to null explicitly since\n         * Promises are immutable: once rejected, a Promise remains rejected forever.\n         */\n        instance = null\n        throw error\n      })\n    }\n    return instance\n  }\n})()\n","import { createRoomObject, Room } from '../createRoomObject'\nimport { createClient } from '../createClient'\nimport { joinRoom } from '../joinRoom'\nimport { MakeRoomOptions } from '../Client'\nimport { RoomSession, RoomSessionOptions } from './RoomSession'\nimport { RoomSessionDevice, RoomDevice } from '../RoomSessionDevice'\nimport {\n  RoomSessionScreenShare,\n  RoomScreenShare,\n} from '../RoomSessionScreenShare'\n\nexport {\n  RoomSession,\n  RoomSessionDevice,\n  RoomSessionScreenShare,\n  // Just to keep backwards compatibility.\n  createRoomObject,\n  joinRoom,\n  Room,\n  RoomDevice,\n  RoomScreenShare,\n  createClient,\n}\n\n/** @ignore */\nexport type { MakeRoomOptions, RoomSessionOptions }\n\n/** @ignore */\nexport type {\n  DeprecatedMemberUpdatableProps,\n  DeprecatedVideoMemberHandlerParams,\n  VideoMemberHandlerParams,\n  VideoMemberListUpdatedParams,\n} from '../utils/interfaces'\n\nexport type { CreateRoomObjectOptions } from '../createRoomObject'\n\nexport type {\n  RoomSessionRecording,\n  RoomSessionPlayback,\n} from '@signalwire/core'\n\nexport { VideoRoomSession, isVideoRoomSession } from './VideoRoomSession'\n","import { UserOptions, getLogger } from '@signalwire/core'\nimport { createClient } from './createClient'\nimport { MakeRoomOptions } from './Client'\nimport { BaseRoomSession } from './BaseRoomSession'\n\n/**\n * @internal\n * @deprecated Use {@link RoomSession} instead.\n **/\nexport interface Room extends BaseRoomSession<Room> {}\n\nexport interface CreateRoomObjectOptions\n  extends UserOptions,\n    Omit<MakeRoomOptions, 'rootElement'> {\n  /** Id of the HTML element in which to display the video stream */\n  rootElementId?: string\n  /** Whether to automatically join the room session. */\n  autoJoin?: boolean\n}\n\nconst VIDEO_CONSTRAINTS: MediaTrackConstraints = {\n  aspectRatio: { ideal: 16 / 9 },\n}\n\n/**\n * Using Video.createRoomObject() you can create a `RoomObject` to join a room.\n *\n * @example\n * With an HTMLDivElement with id=\"root\" in the DOM.\n * ```js\n * // <div id=\"root\"></div>\n *\n * try {\n *   const roomObj = await Video.createRoomObject({\n *     token: '<YourJWT>',\n *     rootElementId: 'root',\n *   })\n *\n *   roomObj.join()\n * } catch (error) {\n *   console.error('Error', error)\n * }\n * ```\n * @deprecated Use {@link RoomSession} instead.\n */\nexport const createRoomObject = (\n  roomOptions: CreateRoomObjectOptions\n): Promise<Room> => {\n  return new Promise(async (resolve, reject) => {\n    const {\n      audio = true,\n      video = true,\n      iceServers,\n      rootElementId,\n      applyLocalVideoOverlay = true,\n      autoJoin = false,\n      stopCameraWhileMuted = true,\n      stopMicrophoneWhileMuted = true,\n      speakerId,\n      ...userOptions\n    } = roomOptions\n\n    const client = createClient({\n      ...userOptions,\n    })\n    await client.connect()\n\n    if (!client) {\n      return\n    }\n\n    /**\n     * Since `makeRoomObject` now only accepts a\n     * `rootElement` the following is to preserve backwards\n     * compatibility with the previous syntax\n     */\n    let rootElement: HTMLElement | undefined\n    if (rootElementId) {\n      const el = document.getElementById(rootElementId)\n\n      if (el) {\n        rootElement = el\n      } else {\n        rootElement = document.body\n\n        getLogger().warn(\n          `We couldn't find an element with id: ${rootElementId}: using 'document.body' instead.`\n        )\n      }\n    }\n\n    const roomObject = client.rooms.makeRoomObject({\n      audio,\n      video: video === true ? VIDEO_CONSTRAINTS : video,\n      negotiateAudio: true,\n      negotiateVideo: true,\n      iceServers,\n      rootElement,\n      applyLocalVideoOverlay,\n      stopCameraWhileMuted,\n      stopMicrophoneWhileMuted,\n      speakerId,\n    })\n\n    // WebRTC connection left the room.\n    roomObject.once('destroy', () => {\n      roomObject.emit('room.left')\n      client.disconnect()\n    })\n\n    const join = () => {\n      return new Promise(async (resolve, reject) => {\n        try {\n          roomObject.once('room.subscribed', (_payload) => {\n            resolve(roomObject)\n          })\n\n          await roomObject.join()\n        } catch (error) {\n          getLogger().error('Join', error)\n          // Disconnect the underlay client in case of media/signaling errors\n          client.disconnect()\n\n          reject(error)\n        }\n      })\n    }\n\n    const room = new Proxy(roomObject, {\n      get(target: any, prop: any, receiver: any) {\n        if (prop === 'join') {\n          return join\n        }\n        return Reflect.get(target, prop, receiver)\n      },\n    })\n\n    if (autoJoin) {\n      try {\n        await room.join()\n        resolve(room)\n      } catch (error) {\n        reject(error)\n      }\n    } else {\n      resolve(room)\n    }\n  })\n}\n","import { CreateRoomObjectOptions, createRoomObject } from './createRoomObject'\n\n/**\n * Using Video.joinRoom() you can automatically join a room.\n *\n * @example\n * With an HTMLDivElement with id=\"root\" in the DOM.\n * ```js\n * // <div id=\"root\"></div>\n *\n * try {\n *   const roomObj = await Video.joinRoom({\n *     token: '<YourJWT>',\n *     rootElementId: 'root',\n *   })\n *\n *   // You have joined the room..\n * } catch (error) {\n *   console.error('Error', error)\n * }\n * ```\n * @deprecated Use {@link RoomSession} instead.\n */\nexport const joinRoom = (roomOptions: CreateRoomObjectOptions) => {\n  return createRoomObject({\n    ...roomOptions,\n    autoJoin: true,\n  })\n}\n","import {\n  UserOptions,\n  getLogger,\n  VideoAuthorization,\n  VideoRoomSubscribedEventParams,\n} from '@signalwire/core'\nimport { createClient } from '../createClient'\nimport { checkMediaParams, getJoinMediaParams } from '../utils/roomSession'\nimport type { MakeRoomOptions } from '../Client'\nimport type {\n  BaseRoomSessionJoinParams,\n  RoomSessionObjectEvents,\n} from '../utils/interfaces'\nimport { getStorage, sessionStorageManager } from '../utils/storage'\nimport { VideoRoomSession } from './VideoRoomSession'\n\n/**\n * List of properties/methods the user shouldn't be able to\n * use until they sucessfully call `roomSession.join()`.\n */\nexport const UNSAFE_PROP_ACCESS = [\n  'audioMute',\n  'audioUnmute',\n  'deaf',\n  'getLayouts',\n  'getMembers',\n  'getRecordings',\n  'hideVideoMuted',\n  'leave',\n  'removerMember',\n  'restoreOutboundAudio',\n  'restoreOutboundVideo',\n  'setInputSensitivity',\n  'setInputVolume',\n  'setLayout',\n  'setPositions',\n  'setMemberPosition',\n  'setOutputVolume',\n  'showVideoMuted',\n  'startRecording',\n  'stopOutboundAudio',\n  'stopOutboundVideo',\n  'undeaf',\n  'videoMute',\n  'videoUnmute',\n  'setMicrophoneVolume',\n  'setSpeakerVolume',\n  'getMeta',\n  'setMeta',\n  'updateMeta',\n  'deleteMeta',\n  'getMemberMeta',\n  'setMemberMeta',\n  'updateMemberMeta',\n  'deleteMemberMeta',\n  'promote',\n  'demote',\n  'lock',\n  'unlock',\n]\n\n/**\n * List of events that the SDK must subscribe at the invite time.\n * ie. ScreenShare/AdditionaDevice are based on the member.joined logic.\n */\nconst REQUIRED_EVENTS: (keyof RoomSessionObjectEvents)[] = [\n  'member.joined',\n  'layout.changed',\n]\nconst noop = () => {}\n\nexport interface RoomSessionOptions extends UserOptions, MakeRoomOptions {}\n\nexport interface RoomSession extends VideoRoomSession {\n  new (opts: RoomSessionOptions): this\n}\n\n/**\n * A RoomSession allows you to start and control video sessions.\n *\n * For example, the following code joins a video session and listens for new\n * members joining:\n *\n * ```typescript\n * const roomSession = new SignalWire.Video.RoomSession({\n *   token: '<YourRoomToken>',\n *   rootElement: document.getElementById('myVideoElement'),\n *   audio: true,\n *   video: true,\n * })\n *\n * roomSession.on('member.joined', (e) => {\n *   console.log(`${e.member.name} joined`)\n * })\n *\n * roomSession.join({ receiveAudio: true, sendVideo: false })\n * ```\n */\nexport const RoomSession = function (roomOptions: RoomSessionOptions) {\n  const {\n    audio: audioFromConstructor = true,\n    video: videoFromConstructor = true,\n    iceServers,\n    rootElement,\n    applyLocalVideoOverlay = true,\n    mirrorLocalVideoOverlay = false,\n    stopCameraWhileMuted = true,\n    stopMicrophoneWhileMuted = true,\n    speakerId,\n    destinationNumber,\n    localStream,\n    watchMediaPackets,\n    watchMediaPacketsTimeout,\n    disableUdpIceServers = false,\n    ...userOptions\n  } = roomOptions\n\n  const deprecatedParams = ['audio', 'video']\n  deprecatedParams.forEach((param) => {\n    if (param in roomOptions) {\n      getLogger().warn(\n        `The '${param}' parameter on the RoomSession constructor is deprecated. Set it on the '.join()' function instead.`\n      )\n    }\n  })\n\n  // @ts-expect-error - true by default\n  const allowReattach = roomOptions?.reattach !== false\n\n  const { callIdKey } = sessionStorageManager(userOptions.token)\n  const reattachManager = {\n    joined: ({ call_id }: VideoRoomSubscribedEventParams) => {\n      if (allowReattach && callIdKey) {\n        getStorage()?.setItem(callIdKey, call_id)\n      }\n    },\n    init: () => {\n      if (allowReattach) {\n        room.on('room.subscribed', reattachManager.joined)\n      }\n      room.options.prevCallId = reattachManager.getPrevCallId()\n    },\n    destroy: () => {\n      if (!allowReattach) {\n        return\n      }\n\n      room.off('room.subscribed', reattachManager.joined)\n      if (callIdKey) {\n        getStorage()?.removeItem(callIdKey)\n      }\n    },\n    getPrevCallId: () => {\n      if (!allowReattach || !callIdKey) {\n        return\n      }\n\n      return getStorage()?.getItem(callIdKey) ?? undefined\n    },\n  }\n\n  const client = createClient<RoomSession>(userOptions)\n  const room = client.rooms.makeRoomObject({\n    // audio,\n    // video: video === true ? VIDEO_CONSTRAINTS : video,\n    negotiateAudio: true,\n    negotiateVideo: true,\n    iceServers,\n    rootElement,\n    applyLocalVideoOverlay,\n    mirrorLocalVideoOverlay,\n    stopCameraWhileMuted,\n    stopMicrophoneWhileMuted,\n    speakerId,\n    destinationNumber,\n    localStream,\n    watchMediaPackets,\n    watchMediaPacketsTimeout,\n    prevCallId: reattachManager.getPrevCallId(),\n    disableUdpIceServers,\n  })\n\n  // WebRTC connection left the room.\n  room.once('destroy', () => {\n    room.emit('room.left', { reason: room.leaveReason })\n\n    // Remove callId to reattach\n    reattachManager.destroy()\n    client.disconnect()\n  })\n\n  // @ts-expect-error\n  client.session.once('session.disconnected', () => {\n    room.destroy()\n  })\n\n  const join = (params?: BaseRoomSessionJoinParams) => {\n    return new Promise(async (resolve, reject) => {\n      try {\n        // @ts-expect-error\n        room.attachPreConnectWorkers()\n\n        await client.connect()\n\n        // Fallback to the constructor values for backwards compat.\n        const audio = params?.audio ?? audioFromConstructor\n        const video = params?.video ?? videoFromConstructor\n\n        // @ts-expect-error\n        const authorization: VideoAuthorization = client._sessionAuthorization\n        getLogger().debug('getJoinMediaParams authorization?', authorization)\n        if (authorization && authorization.type === 'video') {\n          const mediaOptions = getJoinMediaParams({\n            authorization,\n            // constructor values override the send\n            sendAudio: Boolean(audio),\n            sendVideo: Boolean(video),\n            ...params,\n          })\n\n          if (!checkMediaParams(mediaOptions)) {\n            client.disconnect()\n            return reject(\n              new Error(\n                `Invalid arguments to join the room. The token used has join_as: '${\n                  authorization.join_as\n                }'. \\n${JSON.stringify(params, null, 2)}\\n`\n              )\n            )\n          }\n          getLogger().debug('Set mediaOptions', mediaOptions)\n\n          /**\n           * audio and video might be objects with MediaStreamConstraints\n           * so if we must send media, we make sure to use the user's\n           * preferences.\n           * Note: params.sendAudio: `true` will override audio: `false` so\n           * we're using `||` instead of `??` for that reason.\n           */\n          // @ts-expect-error\n          room.updateMediaOptions({\n            audio: mediaOptions.mustSendAudio ? audio || true : false,\n            video: mediaOptions.mustSendVideo ? video || true : false,\n            negotiateAudio: mediaOptions.mustRecvAudio,\n            negotiateVideo: mediaOptions.mustRecvVideo,\n          })\n        }\n\n        room.once('room.subscribed', () => {\n          resolve(room)\n        })\n\n        // Hijack previous callId if present\n        reattachManager.init()\n\n        REQUIRED_EVENTS.forEach((event) => room.once(event, noop))\n\n        await room.join()\n      } catch (error) {\n        getLogger().error('RoomSession Join', error)\n        // Disconnect the underlay client in case of media/signaling errors\n        client.disconnect()\n\n        reject(error)\n      }\n    })\n  }\n\n  const interceptors = {\n    join,\n  } as const\n\n  return new Proxy<Omit<RoomSession, 'new'>>(room, {\n    get(target: RoomSession, prop: keyof RoomSession, receiver: any) {\n      if (prop in interceptors) {\n        // @ts-expect-error\n        return interceptors[prop]\n      }\n\n      if (!target.active && UNSAFE_PROP_ACCESS.includes(prop)) {\n        throw new Error(\n          `Tried to access the property/method \"${prop}\" before the room was connected. Please call roomSession.join() first.`\n        )\n      }\n\n      return Reflect.get(target, prop, receiver)\n    },\n  })\n  // For consistency with other constructors we'll make TS force the use of `new`\n} as unknown as { new (roomOptions: RoomSessionOptions): RoomSession }\n","export {\n  getDevices,\n  getCameraDevices,\n  getMicrophoneDevices,\n  getSpeakerDevices,\n  getDevicesWithPermissions,\n  getCameraDevicesWithPermissions,\n  getMicrophoneDevicesWithPermissions,\n  getSpeakerDevicesWithPermissions,\n  checkPermissions,\n  checkCameraPermissions,\n  checkMicrophonePermissions,\n  checkSpeakerPermissions,\n  requestPermissions,\n  createDeviceWatcher,\n  createCameraDeviceWatcher,\n  createMicrophoneDeviceWatcher,\n  createSpeakerDeviceWatcher,\n  supportsMediaDevices,\n  supportsGetUserMedia,\n  supportsGetDisplayMedia,\n  getUserMedia,\n  getDisplayMedia,\n  enumerateDevices,\n  enumerateDevicesByKind,\n  getSupportedConstraints,\n  supportsMediaOutput,\n  setMediaElementSinkId,\n  stopStream,\n  stopTrack,\n  createMicrophoneAnalyzer,\n} from '@signalwire/webrtc'\nexport type { MicrophoneAnalyzer } from '@signalwire/webrtc'\n"]}