@webex/plugin-meetings 3.8.0-next.32 → 3.8.0-next.34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/breakouts/breakout.js +1 -1
- package/dist/breakouts/index.js +1 -1
- package/dist/interpretation/index.js +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/locus-info/controlsUtils.js +13 -7
- package/dist/locus-info/controlsUtils.js.map +1 -1
- package/dist/locus-info/index.js +2 -1
- package/dist/locus-info/index.js.map +1 -1
- package/dist/meeting/locusMediaRequest.js +0 -17
- package/dist/meeting/locusMediaRequest.js.map +1 -1
- package/dist/types/locus-info/index.d.ts +1 -0
- package/dist/webinar/index.js +1 -1
- package/package.json +3 -3
- package/src/locus-info/controlsUtils.ts +24 -12
- package/src/locus-info/index.ts +5 -1
- package/src/meeting/locusMediaRequest.ts +0 -18
- package/test/unit/spec/locus-info/controlsUtils.js +61 -9
- package/test/unit/spec/meeting/locusMediaRequest.ts +0 -30
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_lodash","require","_common","_events","_webexCore","_constants","_loggerProxy","_interopRequireDefault","_createSuper","Derived","hasNativeReflectConstruct","_isNativeReflectConstruct","_createSuperInternal","Super","_getPrototypeOf2","default","result","NewTarget","constructor","_Reflect$construct","arguments","apply","_possibleConstructorReturn2","Reflect","sham","Proxy","Boolean","prototype","valueOf","call","e","InternalRequestInfo","request","pendingPromise","sendRequestFn","_classCallCheck2","_defineProperty2","pendingPromises","_createClass2","key","value","getPendingPromises","addPendingPromises","_this$pendingPromises","push","_toConsumableArray2","execute","_this","then","forEach","d","resolve","catch","reject","isRequestAffectingConfluenceState","type","roapMessage","messageType","ROAP","ROAP_TYPES","OFFER","LocusMediaRequest","exports","_WebexPlugin","_inherits2","_super","config","options","_this2","_assertThisInitialized2","isRequestInProgress","queuedRequests","confluenceState","addToQueue","info","length","filter","r","executeNextQueuedRequest","_this3","nextRequest","shift","getLatestMuteState","audioMuted","latestAudioMuted","undefined","videoMuted","latestVideoMuted","sendHttpRequest","_this4","uri","concat","selfUrl","MEDIA","_this$getLatestMuteSt","body","device","correlationId","localMedias","respOnlySdp","usingResource","reachability","clientMediaPreferences","webex","internal","newMetrics","submitClientEvent","name","meetingId","sequence","localSdp","_stringify","mediaId","LoggerProxy","logger","upload","EventEmitter","download","method","HTTP_VERBS","PUT","promise","rawError","setupProgressListener","direction","eventEmitter","on","progressEvent","timeStamp","loaded","total","send","_this5","_request$muteOptions","muteOptions","_promise","Defer","newRequest","bind","defer","isConfluenceCreated","downgradeFromMultistreamToTranscoded","preferTranscoding","WebexPlugin"],"sources":["locusMediaRequest.ts"],"sourcesContent":["/* eslint-disable valid-jsdoc */\nimport {defer} from 'lodash';\nimport {Defer, transferEvents} from '@webex/common';\nimport {EventEmitter} from 'events';\nimport {WebexPlugin} from '@webex/webex-core';\nimport {MEDIA, HTTP_VERBS, ROAP} from '../constants';\nimport LoggerProxy from '../common/logs/logger-proxy';\nimport {ClientMediaPreferences} from '../reachability/reachability.types';\n\nexport type MediaRequestType = 'RoapMessage' | 'LocalMute';\nexport type RequestResult = any;\n\nexport type RoapRequest = {\n type: 'RoapMessage';\n selfUrl: string;\n mediaId: string;\n roapMessage: any;\n reachability: any;\n clientMediaPreferences: ClientMediaPreferences;\n sequence?: any;\n};\n\nexport type LocalMuteRequest = {\n type: 'LocalMute';\n selfUrl: string;\n mediaId: string;\n sequence?: any;\n muteOptions: {\n audioMuted?: boolean;\n videoMuted?: boolean;\n };\n};\n\nexport type Request = RoapRequest | LocalMuteRequest;\n\n/** Class representing a single /media request being sent to Locus */\nclass InternalRequestInfo {\n public readonly request: Request;\n private pendingPromises: Defer[];\n private sendRequestFn: (request: Request) => Promise<RequestResult>;\n\n /** Constructor */\n constructor(\n request: Request,\n pendingPromise: Defer,\n sendRequestFn: (request: Request) => Promise<RequestResult>\n ) {\n this.request = request;\n this.pendingPromises = [pendingPromise];\n this.sendRequestFn = sendRequestFn;\n }\n\n /**\n * Returns the list of pending promises associated with this request\n */\n public getPendingPromises() {\n return this.pendingPromises;\n }\n\n /**\n * Adds promises to the list of pending promises associated with this request\n */\n public addPendingPromises(pendingPromises: Defer[]) {\n this.pendingPromises.push(...pendingPromises);\n }\n\n /**\n * Executes the request. Returned promise is resolved once the request\n * is completed (no matter if it succeeded or failed).\n */\n public execute(): Promise<void> {\n return this.sendRequestFn(this.request)\n .then((result) => {\n // resolve all the pending promises associated with this request\n this.pendingPromises.forEach((d) => d.resolve(result));\n })\n .catch((e) => {\n // reject all the pending promises associated with this request\n this.pendingPromises.forEach((d) => d.reject(e));\n });\n }\n}\n\nexport type Config = {\n device: {\n url: string;\n deviceType: string;\n countryCode?: string;\n regionCode?: string;\n };\n correlationId: string;\n meetingId: string;\n preferTranscoding: boolean;\n};\n\n/**\n * Returns true if the request is triggering confluence creation in the server\n */\nfunction isRequestAffectingConfluenceState(request: Request): boolean {\n return (\n request.type === 'RoapMessage' && request.roapMessage.messageType === ROAP.ROAP_TYPES.OFFER\n );\n}\n\n/**\n * This class manages all /media API requests to Locus. Every call to that\n * Locus API has to go through this class.\n */\nexport class LocusMediaRequest extends WebexPlugin {\n private config: Config;\n private latestAudioMuted?: boolean;\n private latestVideoMuted?: boolean;\n private isRequestInProgress: boolean;\n private queuedRequests: InternalRequestInfo[];\n private confluenceState: 'not created' | 'creation in progress' | 'created';\n /**\n * Constructor\n */\n constructor(config: Config, options: any) {\n super({}, options);\n this.isRequestInProgress = false;\n this.queuedRequests = [];\n this.config = config;\n this.confluenceState = 'not created';\n }\n\n /**\n * Add a request to the internal queue.\n */\n private addToQueue(info: InternalRequestInfo) {\n if (info.request.type === 'LocalMute' && this.queuedRequests.length > 0) {\n // We don't need additional local mute requests in the queue.\n // We only need at most 1 local mute or 1 roap request, because\n // roap requests also include mute state, so whatever request\n // is sent out, it will send the latest local mute state.\n // We only need to store the pendingPromises so that they get resolved\n // when the roap request is sent out.\n this.queuedRequests[0].addPendingPromises(info.getPendingPromises());\n\n return;\n }\n\n if (info.request.type === 'RoapMessage' && this.queuedRequests.length > 0) {\n // remove any LocalMute requests from the queue, because this Roap message\n // will also update the mute status in Locus, so they are redundant\n this.queuedRequests = this.queuedRequests.filter((r) => {\n if (r.request.type === 'LocalMute') {\n // we need to keep the pending promises from the local mute request\n // that we're removing from the queue\n info.addPendingPromises(r.getPendingPromises());\n\n return false;\n }\n\n return true;\n });\n }\n\n this.queuedRequests.push(info);\n }\n\n /**\n * Takes the next request from the queue and executes it. Once that\n * request is completed, the next one will be taken from the queue\n * and executed and this is repeated until the queue is empty.\n */\n private executeNextQueuedRequest(): void {\n if (this.isRequestInProgress) {\n return;\n }\n\n const nextRequest = this.queuedRequests.shift();\n\n if (nextRequest) {\n this.isRequestInProgress = true;\n nextRequest.execute().then(() => {\n this.isRequestInProgress = false;\n this.executeNextQueuedRequest();\n });\n }\n }\n\n /**\n * Returns latest requested audio and video mute values. If they have never been\n * requested, we assume audio/video to be muted.\n */\n private getLatestMuteState() {\n const audioMuted = this.latestAudioMuted !== undefined ? this.latestAudioMuted : true;\n const videoMuted = this.latestVideoMuted !== undefined ? this.latestVideoMuted : true;\n\n return {audioMuted, videoMuted};\n }\n\n /**\n * Prepares the uri and body for the media request to be sent to Locus\n */\n private sendHttpRequest(request: Request) {\n const uri = `${request.selfUrl}/${MEDIA}`;\n\n const {audioMuted, videoMuted} = this.getLatestMuteState();\n\n // first setup things common to all requests\n const body: any = {\n device: this.config.device,\n correlationId: this.config.correlationId,\n };\n\n const localMedias: any = {\n audioMuted,\n videoMuted,\n };\n\n // now add things specific to request type\n switch (request.type) {\n case 'LocalMute':\n body.respOnlySdp = true;\n body.usingResource = null;\n break;\n\n case 'RoapMessage':\n localMedias.roapMessage = request.roapMessage;\n localMedias.reachability = request.reachability;\n body.clientMediaPreferences = request.clientMediaPreferences;\n\n // @ts-ignore\n this.webex.internal.newMetrics.submitClientEvent({\n name: 'client.locus.media.request',\n options: {\n meetingId: this.config.meetingId,\n },\n });\n break;\n }\n\n if (request.sequence) {\n body.sequence = request.sequence;\n }\n\n body.localMedias = [\n {\n localSdp: JSON.stringify(localMedias), // this part must be JSON stringified, Locus requires this\n mediaId: request.mediaId,\n },\n ];\n\n LoggerProxy.logger.info(\n `Meeting:LocusMediaRequest#sendHttpRequest --> ${request.type} audioMuted=${audioMuted} videoMuted=${videoMuted}`\n );\n\n if (isRequestAffectingConfluenceState(request) && this.confluenceState === 'not created') {\n this.confluenceState = 'creation in progress';\n }\n\n const upload = new EventEmitter();\n const download = new EventEmitter();\n\n const options = {\n method: HTTP_VERBS.PUT,\n uri,\n body,\n upload,\n download,\n };\n\n // @ts-ignore\n const promise = this.request(options)\n .then((result) => {\n if (isRequestAffectingConfluenceState(request)) {\n this.confluenceState = 'created';\n }\n\n if (request.type === 'RoapMessage') {\n // @ts-ignore\n this.webex.internal.newMetrics.submitClientEvent({\n name: 'client.locus.media.response',\n options: {\n meetingId: this.config.meetingId,\n },\n });\n }\n\n return result;\n })\n .catch((e) => {\n if (\n isRequestAffectingConfluenceState(request) &&\n this.confluenceState === 'creation in progress'\n ) {\n this.confluenceState = 'not created';\n }\n\n if (request.type === 'RoapMessage') {\n // @ts-ignore\n this.webex.internal.newMetrics.submitClientEvent({\n name: 'client.locus.media.response',\n options: {\n meetingId: this.config.meetingId,\n rawError: e,\n },\n });\n }\n\n throw e;\n });\n\n if (request.type === 'RoapMessage') {\n const setupProgressListener = (direction: string, eventEmitter: EventEmitter) => {\n eventEmitter.on('progress', (progressEvent: ProgressEvent) => {\n LoggerProxy.logger.info(\n `${request.type}: ${direction} Progress, Timestamp: ${progressEvent.timeStamp}, Progress: ${progressEvent.loaded}/${progressEvent.total}`\n );\n });\n };\n\n setupProgressListener('Upload', options.upload);\n setupProgressListener('Download', options.download);\n }\n\n return promise;\n }\n\n /**\n * Sends a media request to Locus\n */\n public send(request: Request): Promise<RequestResult> {\n if (request.type === 'LocalMute') {\n const {audioMuted, videoMuted} = request.muteOptions;\n\n if (audioMuted !== undefined) {\n this.latestAudioMuted = audioMuted;\n }\n if (videoMuted !== undefined) {\n this.latestVideoMuted = videoMuted;\n }\n\n if (this.confluenceState === 'not created') {\n // if there is no confluence, there is no point sending out local mute request\n // as it will fail so we just store the latest audio/video muted values\n // and resolve immediately, so that higher layer (MuteState class) doesn't get blocked\n // and can call us again if user mutes/unmutes again before confluence is created\n LoggerProxy.logger.info(\n 'Meeting:LocusMediaRequest#send --> called with LocalMute request before confluence creation'\n );\n\n return Promise.resolve({});\n }\n }\n\n const pendingPromise = new Defer();\n\n const newRequest = new InternalRequestInfo(\n request,\n pendingPromise,\n this.sendHttpRequest.bind(this)\n );\n\n this.addToQueue(newRequest);\n\n defer(() => this.executeNextQueuedRequest());\n\n return pendingPromise.promise;\n }\n\n /** Returns true if a confluence on the server is already created */\n public isConfluenceCreated() {\n return this.confluenceState === 'created';\n }\n\n /**\n * This method needs to be called when we downgrade from multistream to transcoded connection.\n */\n public downgradeFromMultistreamToTranscoded() {\n this.config.preferTranscoding = true;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"names":["_lodash","require","_common","_events","_webexCore","_constants","_loggerProxy","_interopRequireDefault","_createSuper","Derived","hasNativeReflectConstruct","_isNativeReflectConstruct","_createSuperInternal","Super","_getPrototypeOf2","default","result","NewTarget","constructor","_Reflect$construct","arguments","apply","_possibleConstructorReturn2","Reflect","sham","Proxy","Boolean","prototype","valueOf","call","e","InternalRequestInfo","request","pendingPromise","sendRequestFn","_classCallCheck2","_defineProperty2","pendingPromises","_createClass2","key","value","getPendingPromises","addPendingPromises","_this$pendingPromises","push","_toConsumableArray2","execute","_this","then","forEach","d","resolve","catch","reject","isRequestAffectingConfluenceState","type","roapMessage","messageType","ROAP","ROAP_TYPES","OFFER","LocusMediaRequest","exports","_WebexPlugin","_inherits2","_super","config","options","_this2","_assertThisInitialized2","isRequestInProgress","queuedRequests","confluenceState","addToQueue","info","length","filter","r","executeNextQueuedRequest","_this3","nextRequest","shift","getLatestMuteState","audioMuted","latestAudioMuted","undefined","videoMuted","latestVideoMuted","sendHttpRequest","_this4","uri","concat","selfUrl","MEDIA","_this$getLatestMuteSt","body","device","correlationId","localMedias","respOnlySdp","usingResource","reachability","clientMediaPreferences","sequence","localSdp","_stringify","mediaId","LoggerProxy","logger","upload","EventEmitter","download","method","HTTP_VERBS","PUT","promise","webex","internal","newMetrics","submitClientEvent","name","meetingId","rawError","setupProgressListener","direction","eventEmitter","on","progressEvent","timeStamp","loaded","total","send","_this5","_request$muteOptions","muteOptions","_promise","Defer","newRequest","bind","defer","isConfluenceCreated","downgradeFromMultistreamToTranscoded","preferTranscoding","WebexPlugin"],"sources":["locusMediaRequest.ts"],"sourcesContent":["/* eslint-disable valid-jsdoc */\nimport {defer} from 'lodash';\nimport {Defer, transferEvents} from '@webex/common';\nimport {EventEmitter} from 'events';\nimport {WebexPlugin} from '@webex/webex-core';\nimport {MEDIA, HTTP_VERBS, ROAP} from '../constants';\nimport LoggerProxy from '../common/logs/logger-proxy';\nimport {ClientMediaPreferences} from '../reachability/reachability.types';\n\nexport type MediaRequestType = 'RoapMessage' | 'LocalMute';\nexport type RequestResult = any;\n\nexport type RoapRequest = {\n type: 'RoapMessage';\n selfUrl: string;\n mediaId: string;\n roapMessage: any;\n reachability: any;\n clientMediaPreferences: ClientMediaPreferences;\n sequence?: any;\n};\n\nexport type LocalMuteRequest = {\n type: 'LocalMute';\n selfUrl: string;\n mediaId: string;\n sequence?: any;\n muteOptions: {\n audioMuted?: boolean;\n videoMuted?: boolean;\n };\n};\n\nexport type Request = RoapRequest | LocalMuteRequest;\n\n/** Class representing a single /media request being sent to Locus */\nclass InternalRequestInfo {\n public readonly request: Request;\n private pendingPromises: Defer[];\n private sendRequestFn: (request: Request) => Promise<RequestResult>;\n\n /** Constructor */\n constructor(\n request: Request,\n pendingPromise: Defer,\n sendRequestFn: (request: Request) => Promise<RequestResult>\n ) {\n this.request = request;\n this.pendingPromises = [pendingPromise];\n this.sendRequestFn = sendRequestFn;\n }\n\n /**\n * Returns the list of pending promises associated with this request\n */\n public getPendingPromises() {\n return this.pendingPromises;\n }\n\n /**\n * Adds promises to the list of pending promises associated with this request\n */\n public addPendingPromises(pendingPromises: Defer[]) {\n this.pendingPromises.push(...pendingPromises);\n }\n\n /**\n * Executes the request. Returned promise is resolved once the request\n * is completed (no matter if it succeeded or failed).\n */\n public execute(): Promise<void> {\n return this.sendRequestFn(this.request)\n .then((result) => {\n // resolve all the pending promises associated with this request\n this.pendingPromises.forEach((d) => d.resolve(result));\n })\n .catch((e) => {\n // reject all the pending promises associated with this request\n this.pendingPromises.forEach((d) => d.reject(e));\n });\n }\n}\n\nexport type Config = {\n device: {\n url: string;\n deviceType: string;\n countryCode?: string;\n regionCode?: string;\n };\n correlationId: string;\n meetingId: string;\n preferTranscoding: boolean;\n};\n\n/**\n * Returns true if the request is triggering confluence creation in the server\n */\nfunction isRequestAffectingConfluenceState(request: Request): boolean {\n return (\n request.type === 'RoapMessage' && request.roapMessage.messageType === ROAP.ROAP_TYPES.OFFER\n );\n}\n\n/**\n * This class manages all /media API requests to Locus. Every call to that\n * Locus API has to go through this class.\n */\nexport class LocusMediaRequest extends WebexPlugin {\n private config: Config;\n private latestAudioMuted?: boolean;\n private latestVideoMuted?: boolean;\n private isRequestInProgress: boolean;\n private queuedRequests: InternalRequestInfo[];\n private confluenceState: 'not created' | 'creation in progress' | 'created';\n /**\n * Constructor\n */\n constructor(config: Config, options: any) {\n super({}, options);\n this.isRequestInProgress = false;\n this.queuedRequests = [];\n this.config = config;\n this.confluenceState = 'not created';\n }\n\n /**\n * Add a request to the internal queue.\n */\n private addToQueue(info: InternalRequestInfo) {\n if (info.request.type === 'LocalMute' && this.queuedRequests.length > 0) {\n // We don't need additional local mute requests in the queue.\n // We only need at most 1 local mute or 1 roap request, because\n // roap requests also include mute state, so whatever request\n // is sent out, it will send the latest local mute state.\n // We only need to store the pendingPromises so that they get resolved\n // when the roap request is sent out.\n this.queuedRequests[0].addPendingPromises(info.getPendingPromises());\n\n return;\n }\n\n if (info.request.type === 'RoapMessage' && this.queuedRequests.length > 0) {\n // remove any LocalMute requests from the queue, because this Roap message\n // will also update the mute status in Locus, so they are redundant\n this.queuedRequests = this.queuedRequests.filter((r) => {\n if (r.request.type === 'LocalMute') {\n // we need to keep the pending promises from the local mute request\n // that we're removing from the queue\n info.addPendingPromises(r.getPendingPromises());\n\n return false;\n }\n\n return true;\n });\n }\n\n this.queuedRequests.push(info);\n }\n\n /**\n * Takes the next request from the queue and executes it. Once that\n * request is completed, the next one will be taken from the queue\n * and executed and this is repeated until the queue is empty.\n */\n private executeNextQueuedRequest(): void {\n if (this.isRequestInProgress) {\n return;\n }\n\n const nextRequest = this.queuedRequests.shift();\n\n if (nextRequest) {\n this.isRequestInProgress = true;\n nextRequest.execute().then(() => {\n this.isRequestInProgress = false;\n this.executeNextQueuedRequest();\n });\n }\n }\n\n /**\n * Returns latest requested audio and video mute values. If they have never been\n * requested, we assume audio/video to be muted.\n */\n private getLatestMuteState() {\n const audioMuted = this.latestAudioMuted !== undefined ? this.latestAudioMuted : true;\n const videoMuted = this.latestVideoMuted !== undefined ? this.latestVideoMuted : true;\n\n return {audioMuted, videoMuted};\n }\n\n /**\n * Prepares the uri and body for the media request to be sent to Locus\n */\n private sendHttpRequest(request: Request) {\n const uri = `${request.selfUrl}/${MEDIA}`;\n\n const {audioMuted, videoMuted} = this.getLatestMuteState();\n\n // first setup things common to all requests\n const body: any = {\n device: this.config.device,\n correlationId: this.config.correlationId,\n };\n\n const localMedias: any = {\n audioMuted,\n videoMuted,\n };\n\n // now add things specific to request type\n switch (request.type) {\n case 'LocalMute':\n body.respOnlySdp = true;\n body.usingResource = null;\n break;\n\n case 'RoapMessage':\n localMedias.roapMessage = request.roapMessage;\n localMedias.reachability = request.reachability;\n body.clientMediaPreferences = request.clientMediaPreferences;\n break;\n }\n\n if (request.sequence) {\n body.sequence = request.sequence;\n }\n\n body.localMedias = [\n {\n localSdp: JSON.stringify(localMedias), // this part must be JSON stringified, Locus requires this\n mediaId: request.mediaId,\n },\n ];\n\n LoggerProxy.logger.info(\n `Meeting:LocusMediaRequest#sendHttpRequest --> ${request.type} audioMuted=${audioMuted} videoMuted=${videoMuted}`\n );\n\n if (isRequestAffectingConfluenceState(request) && this.confluenceState === 'not created') {\n this.confluenceState = 'creation in progress';\n }\n\n const upload = new EventEmitter();\n const download = new EventEmitter();\n\n const options = {\n method: HTTP_VERBS.PUT,\n uri,\n body,\n upload,\n download,\n };\n\n // @ts-ignore\n const promise = this.request(options)\n .then((result) => {\n if (isRequestAffectingConfluenceState(request)) {\n this.confluenceState = 'created';\n }\n\n return result;\n })\n .catch((e) => {\n if (\n isRequestAffectingConfluenceState(request) &&\n this.confluenceState === 'creation in progress'\n ) {\n this.confluenceState = 'not created';\n }\n\n if (request.type === 'RoapMessage') {\n // @ts-ignore\n this.webex.internal.newMetrics.submitClientEvent({\n name: 'client.locus.media.response',\n options: {\n meetingId: this.config.meetingId,\n rawError: e,\n },\n });\n }\n\n throw e;\n });\n\n if (request.type === 'RoapMessage') {\n const setupProgressListener = (direction: string, eventEmitter: EventEmitter) => {\n eventEmitter.on('progress', (progressEvent: ProgressEvent) => {\n LoggerProxy.logger.info(\n `${request.type}: ${direction} Progress, Timestamp: ${progressEvent.timeStamp}, Progress: ${progressEvent.loaded}/${progressEvent.total}`\n );\n });\n };\n\n setupProgressListener('Upload', options.upload);\n setupProgressListener('Download', options.download);\n }\n\n return promise;\n }\n\n /**\n * Sends a media request to Locus\n */\n public send(request: Request): Promise<RequestResult> {\n if (request.type === 'LocalMute') {\n const {audioMuted, videoMuted} = request.muteOptions;\n\n if (audioMuted !== undefined) {\n this.latestAudioMuted = audioMuted;\n }\n if (videoMuted !== undefined) {\n this.latestVideoMuted = videoMuted;\n }\n\n if (this.confluenceState === 'not created') {\n // if there is no confluence, there is no point sending out local mute request\n // as it will fail so we just store the latest audio/video muted values\n // and resolve immediately, so that higher layer (MuteState class) doesn't get blocked\n // and can call us again if user mutes/unmutes again before confluence is created\n LoggerProxy.logger.info(\n 'Meeting:LocusMediaRequest#send --> called with LocalMute request before confluence creation'\n );\n\n return Promise.resolve({});\n }\n }\n\n const pendingPromise = new Defer();\n\n const newRequest = new InternalRequestInfo(\n request,\n pendingPromise,\n this.sendHttpRequest.bind(this)\n );\n\n this.addToQueue(newRequest);\n\n defer(() => this.executeNextQueuedRequest());\n\n return pendingPromise.promise;\n }\n\n /** Returns true if a confluence on the server is already created */\n public isConfluenceCreated() {\n return this.confluenceState === 'created';\n }\n\n /**\n * This method needs to be called when we downgrade from multistream to transcoded connection.\n */\n public downgradeFromMultistreamToTranscoded() {\n this.config.preferTranscoding = true;\n }\n}\n"],"mappings":"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"}
|
package/dist/webinar/index.js
CHANGED
package/package.json
CHANGED
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"@webex/eslint-config-legacy": "0.0.0",
|
|
44
44
|
"@webex/jest-config-legacy": "0.0.0",
|
|
45
45
|
"@webex/legacy-tools": "0.0.0",
|
|
46
|
-
"@webex/plugin-meetings": "3.8.0-next.
|
|
46
|
+
"@webex/plugin-meetings": "3.8.0-next.34",
|
|
47
47
|
"@webex/plugin-rooms": "3.8.0-next.13",
|
|
48
48
|
"@webex/test-helper-chai": "3.8.0-next.11",
|
|
49
49
|
"@webex/test-helper-mocha": "3.8.0-next.11",
|
|
@@ -71,7 +71,7 @@
|
|
|
71
71
|
"@webex/internal-plugin-metrics": "3.8.0-next.11",
|
|
72
72
|
"@webex/internal-plugin-support": "3.8.0-next.13",
|
|
73
73
|
"@webex/internal-plugin-user": "3.8.0-next.11",
|
|
74
|
-
"@webex/internal-plugin-voicea": "3.8.0-next.
|
|
74
|
+
"@webex/internal-plugin-voicea": "3.8.0-next.34",
|
|
75
75
|
"@webex/media-helpers": "3.8.0-next.12",
|
|
76
76
|
"@webex/plugin-people": "3.8.0-next.13",
|
|
77
77
|
"@webex/plugin-rooms": "3.8.0-next.13",
|
|
@@ -92,5 +92,5 @@
|
|
|
92
92
|
"//": [
|
|
93
93
|
"TODO: upgrade jwt-decode when moving to node 18"
|
|
94
94
|
],
|
|
95
|
-
"version": "3.8.0-next.
|
|
95
|
+
"version": "3.8.0-next.34"
|
|
96
96
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {isEqual} from 'lodash';
|
|
2
|
-
import {BREAKOUTS} from '../constants';
|
|
2
|
+
import {BREAKOUTS, MEETING_STATE} from '../constants';
|
|
3
3
|
|
|
4
4
|
const ControlsUtils: any = {};
|
|
5
5
|
|
|
@@ -242,30 +242,42 @@ ControlsUtils.isNeedReplaceMembers = (oldControls: any, controls: any) => {
|
|
|
242
242
|
}
|
|
243
243
|
|
|
244
244
|
return (
|
|
245
|
-
oldControls
|
|
246
|
-
oldControls
|
|
245
|
+
oldControls?.breakout?.groupId !== controls?.breakout?.groupId ||
|
|
246
|
+
oldControls?.breakout?.sessionId !== controls?.breakout?.sessionId
|
|
247
247
|
);
|
|
248
248
|
};
|
|
249
249
|
|
|
250
250
|
/**
|
|
251
251
|
* determine the switch status between breakout session and main session.
|
|
252
|
-
* @param {
|
|
253
|
-
* @param {
|
|
252
|
+
* @param {LocusInfo} oldLocus
|
|
253
|
+
* @param {LocusInfo} newLocus
|
|
254
254
|
* @returns {Object}
|
|
255
255
|
*/
|
|
256
|
-
ControlsUtils.getSessionSwitchStatus = (
|
|
256
|
+
ControlsUtils.getSessionSwitchStatus = (oldLocus: any, newLocus: any) => {
|
|
257
257
|
const status = {isReturnToMain: false, isJoinToBreakout: false};
|
|
258
258
|
// no breakout case
|
|
259
|
-
if (!
|
|
259
|
+
if (!oldLocus.controls?.breakout || !newLocus.controls?.breakout) {
|
|
260
260
|
return status;
|
|
261
261
|
}
|
|
262
262
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
263
|
+
// It is used to fix the timing issue triggered when the creator leaves session to ensure that the member list is complete
|
|
264
|
+
const needUseCache = !!(
|
|
265
|
+
oldLocus.self?.isCreator &&
|
|
266
|
+
newLocus.participants?.length === 1 &&
|
|
267
|
+
newLocus.participants?.[0].isCreator &&
|
|
268
|
+
newLocus.participants?.[0].state === MEETING_STATE.STATES.JOINED &&
|
|
269
|
+
newLocus.controls?.breakout?.sessionType === BREAKOUTS.SESSION_TYPES.MAIN &&
|
|
270
|
+
newLocus.controls?.breakout?.groups?.length
|
|
271
|
+
);
|
|
272
|
+
|
|
273
|
+
const isReturnToMain =
|
|
274
|
+
oldLocus.controls.breakout.sessionType === BREAKOUTS.SESSION_TYPES.BREAKOUT &&
|
|
275
|
+
newLocus.controls.breakout.sessionType === BREAKOUTS.SESSION_TYPES.MAIN;
|
|
276
|
+
|
|
277
|
+
status.isReturnToMain = needUseCache || isReturnToMain;
|
|
266
278
|
status.isJoinToBreakout =
|
|
267
|
-
|
|
268
|
-
controls.breakout.sessionType === BREAKOUTS.SESSION_TYPES.BREAKOUT;
|
|
279
|
+
oldLocus.controls.breakout.sessionType === BREAKOUTS.SESSION_TYPES.MAIN &&
|
|
280
|
+
newLocus.controls.breakout.sessionType === BREAKOUTS.SESSION_TYPES.BREAKOUT;
|
|
269
281
|
|
|
270
282
|
return status;
|
|
271
283
|
};
|
package/src/locus-info/index.ts
CHANGED
|
@@ -17,7 +17,9 @@ import {
|
|
|
17
17
|
MEETING_REMOVED_REASON,
|
|
18
18
|
CALL_REMOVED_REASON,
|
|
19
19
|
RECORDING_STATE,
|
|
20
|
+
BREAKOUTS,
|
|
20
21
|
} from '../constants';
|
|
22
|
+
|
|
21
23
|
import InfoUtils from './infoUtils';
|
|
22
24
|
import FullState from './fullState';
|
|
23
25
|
import SelfUtils from './selfUtils';
|
|
@@ -67,6 +69,7 @@ export default class LocusInfo extends EventsScope {
|
|
|
67
69
|
services: any;
|
|
68
70
|
resources: any;
|
|
69
71
|
mainSessionLocusCache: any;
|
|
72
|
+
self: any;
|
|
70
73
|
/**
|
|
71
74
|
* Constructor
|
|
72
75
|
* @param {function} updateMeeting callback to update the meeting object from an object
|
|
@@ -1706,7 +1709,8 @@ export default class LocusInfo extends EventsScope {
|
|
|
1706
1709
|
* @memberof LocusInfo
|
|
1707
1710
|
*/
|
|
1708
1711
|
getTheLocusToUpdate(newLocus: any) {
|
|
1709
|
-
const switchStatus = ControlsUtils.getSessionSwitchStatus(this
|
|
1712
|
+
const switchStatus = ControlsUtils.getSessionSwitchStatus(this, newLocus);
|
|
1713
|
+
|
|
1710
1714
|
if (switchStatus.isReturnToMain && this.mainSessionLocusCache) {
|
|
1711
1715
|
return cloneDeep(this.mainSessionLocusCache);
|
|
1712
1716
|
}
|
|
@@ -221,14 +221,6 @@ export class LocusMediaRequest extends WebexPlugin {
|
|
|
221
221
|
localMedias.roapMessage = request.roapMessage;
|
|
222
222
|
localMedias.reachability = request.reachability;
|
|
223
223
|
body.clientMediaPreferences = request.clientMediaPreferences;
|
|
224
|
-
|
|
225
|
-
// @ts-ignore
|
|
226
|
-
this.webex.internal.newMetrics.submitClientEvent({
|
|
227
|
-
name: 'client.locus.media.request',
|
|
228
|
-
options: {
|
|
229
|
-
meetingId: this.config.meetingId,
|
|
230
|
-
},
|
|
231
|
-
});
|
|
232
224
|
break;
|
|
233
225
|
}
|
|
234
226
|
|
|
@@ -269,16 +261,6 @@ export class LocusMediaRequest extends WebexPlugin {
|
|
|
269
261
|
this.confluenceState = 'created';
|
|
270
262
|
}
|
|
271
263
|
|
|
272
|
-
if (request.type === 'RoapMessage') {
|
|
273
|
-
// @ts-ignore
|
|
274
|
-
this.webex.internal.newMetrics.submitClientEvent({
|
|
275
|
-
name: 'client.locus.media.response',
|
|
276
|
-
options: {
|
|
277
|
-
meetingId: this.config.meetingId,
|
|
278
|
-
},
|
|
279
|
-
});
|
|
280
|
-
}
|
|
281
|
-
|
|
282
264
|
return result;
|
|
283
265
|
})
|
|
284
266
|
.catch((e) => {
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import {assert} from '@webex/test-helper-chai';
|
|
2
2
|
import ControlsUtils from '@webex/plugin-meetings/src/locus-info/controlsUtils';
|
|
3
3
|
import controlsUtils from "@webex/plugin-meetings/src/locus-info/controlsUtils";
|
|
4
|
+
import {
|
|
5
|
+
MEETING_STATE,
|
|
6
|
+
BREAKOUTS,
|
|
7
|
+
} from '../../../../src/constants';
|
|
4
8
|
|
|
5
9
|
const defaultControls = {
|
|
6
10
|
entryExitTone: {
|
|
@@ -432,28 +436,76 @@ describe('plugin-meetings', () => {
|
|
|
432
436
|
|
|
433
437
|
describe('getSessionSwitchStatus', () => {
|
|
434
438
|
it('if no breakout control, return switch status both false', () => {
|
|
435
|
-
const
|
|
436
|
-
const
|
|
437
|
-
assert.deepEqual(controlsUtils.getSessionSwitchStatus(
|
|
439
|
+
const oldLocus = {};
|
|
440
|
+
const newLocus = {};
|
|
441
|
+
assert.deepEqual(controlsUtils.getSessionSwitchStatus(oldLocus, newLocus), {
|
|
438
442
|
isReturnToMain: false, isJoinToBreakout: false
|
|
439
443
|
});
|
|
440
444
|
});
|
|
441
445
|
|
|
442
446
|
it('if switch session from breakout to main, return isReturnToMain as true', () => {
|
|
443
|
-
const
|
|
444
|
-
const
|
|
445
|
-
assert.deepEqual(controlsUtils.getSessionSwitchStatus(
|
|
447
|
+
const oldLocus = {controls: {breakout: {sessionType: 'BREAKOUT'}}};
|
|
448
|
+
const newLocus = {controls: {breakout: {sessionType: 'MAIN'}}};
|
|
449
|
+
assert.deepEqual(controlsUtils.getSessionSwitchStatus(oldLocus, newLocus), {
|
|
446
450
|
isReturnToMain: true, isJoinToBreakout: false
|
|
447
451
|
});
|
|
448
452
|
});
|
|
449
453
|
|
|
450
454
|
it('if switch session from main to breakout, return isJoinToBreakout as true', () => {
|
|
451
|
-
const
|
|
452
|
-
const
|
|
453
|
-
assert.deepEqual(controlsUtils.getSessionSwitchStatus(
|
|
455
|
+
const oldLocus = {controls: {breakout: {sessionType: 'MAIN'}}};
|
|
456
|
+
const newLocus = {controls: {breakout: {sessionType: 'BREAKOUT'}}};
|
|
457
|
+
assert.deepEqual(controlsUtils.getSessionSwitchStatus(oldLocus, newLocus), {
|
|
454
458
|
isReturnToMain: false, isJoinToBreakout: true
|
|
455
459
|
});
|
|
456
460
|
});
|
|
461
|
+
|
|
462
|
+
it('if needUseCache conditions are met, return isJoinToBreakout as true', () => {
|
|
463
|
+
const oldLocus = {
|
|
464
|
+
self: { isCreator: true },
|
|
465
|
+
controls: { breakout: { sessionType: BREAKOUTS.SESSION_TYPES.MAIN} },
|
|
466
|
+
};
|
|
467
|
+
|
|
468
|
+
const newLocus = {
|
|
469
|
+
participants: [
|
|
470
|
+
{ isCreator: true, state: MEETING_STATE.STATES.JOINED },
|
|
471
|
+
],
|
|
472
|
+
controls: {
|
|
473
|
+
breakout: {
|
|
474
|
+
sessionType: BREAKOUTS.SESSION_TYPES.MAIN,
|
|
475
|
+
groups: [{ id: 'group1' }]
|
|
476
|
+
},
|
|
477
|
+
},
|
|
478
|
+
};
|
|
479
|
+
|
|
480
|
+
assert.deepEqual(controlsUtils.getSessionSwitchStatus(oldLocus, newLocus), {
|
|
481
|
+
isReturnToMain: true,
|
|
482
|
+
isJoinToBreakout: false
|
|
483
|
+
});
|
|
484
|
+
});
|
|
485
|
+
|
|
486
|
+
it('if needUseCache conditions are not met, return newLocus and isReturnToMain as false', () => {
|
|
487
|
+
const oldLocus = {
|
|
488
|
+
self: { isCreator: false },
|
|
489
|
+
controls: { breakout: { sessionType: BREAKOUTS.SESSION_TYPES.BREAKOUT} },
|
|
490
|
+
};
|
|
491
|
+
|
|
492
|
+
const newLocus = {
|
|
493
|
+
participants: [
|
|
494
|
+
{ isCreator: true, state: MEETING_STATE.STATES.JOINED },
|
|
495
|
+
],
|
|
496
|
+
controls: {
|
|
497
|
+
breakout: {
|
|
498
|
+
sessionType: BREAKOUTS.SESSION_TYPES.BREAKOUT,
|
|
499
|
+
groups: []
|
|
500
|
+
},
|
|
501
|
+
},
|
|
502
|
+
};
|
|
503
|
+
|
|
504
|
+
assert.deepEqual(controlsUtils.getSessionSwitchStatus(oldLocus, newLocus), {
|
|
505
|
+
isReturnToMain: false,
|
|
506
|
+
isJoinToBreakout: false
|
|
507
|
+
});
|
|
508
|
+
});
|
|
457
509
|
});
|
|
458
510
|
|
|
459
511
|
describe('#isMainSessionDTO', () => {
|
|
@@ -169,26 +169,6 @@ describe('LocusMediaRequest.send()', () => {
|
|
|
169
169
|
mockWebex.internal.newMetrics.submitClientEvent.resetHistory();
|
|
170
170
|
};
|
|
171
171
|
|
|
172
|
-
const checkMetrics = (expectedMetrics: boolean = true) => {
|
|
173
|
-
if (expectedMetrics) {
|
|
174
|
-
assert.calledWith(mockWebex.internal.newMetrics.submitClientEvent, {
|
|
175
|
-
name: 'client.locus.media.request',
|
|
176
|
-
options: {
|
|
177
|
-
meetingId: 'meetingId',
|
|
178
|
-
},
|
|
179
|
-
});
|
|
180
|
-
|
|
181
|
-
assert.calledWith(mockWebex.internal.newMetrics.submitClientEvent, {
|
|
182
|
-
name: 'client.locus.media.response',
|
|
183
|
-
options: {
|
|
184
|
-
meetingId: 'meetingId',
|
|
185
|
-
},
|
|
186
|
-
});
|
|
187
|
-
} else {
|
|
188
|
-
assert.notCalled(mockWebex.internal.newMetrics.submitClientEvent);
|
|
189
|
-
}
|
|
190
|
-
};
|
|
191
|
-
|
|
192
172
|
it('sends a roap message', async () => {
|
|
193
173
|
const result = await sendRoapMessage('OFFER');
|
|
194
174
|
|
|
@@ -201,8 +181,6 @@ describe('LocusMediaRequest.send()', () => {
|
|
|
201
181
|
upload: sinon.match.instanceOf(EventEmitter),
|
|
202
182
|
download: sinon.match.instanceOf(EventEmitter),
|
|
203
183
|
});
|
|
204
|
-
|
|
205
|
-
checkMetrics();
|
|
206
184
|
});
|
|
207
185
|
|
|
208
186
|
it('sends correct metric event when roap message fails', async () => {
|
|
@@ -232,8 +210,6 @@ describe('LocusMediaRequest.send()', () => {
|
|
|
232
210
|
upload: sinon.match.instanceOf(EventEmitter),
|
|
233
211
|
download: sinon.match.instanceOf(EventEmitter),
|
|
234
212
|
});
|
|
235
|
-
|
|
236
|
-
checkMetrics(false);
|
|
237
213
|
});
|
|
238
214
|
|
|
239
215
|
it('sends a local mute request with sequence', async () => {
|
|
@@ -282,8 +258,6 @@ describe('LocusMediaRequest.send()', () => {
|
|
|
282
258
|
upload: sinon.match.instanceOf(EventEmitter),
|
|
283
259
|
download: sinon.match.instanceOf(EventEmitter),
|
|
284
260
|
});
|
|
285
|
-
|
|
286
|
-
checkMetrics(false);
|
|
287
261
|
});
|
|
288
262
|
|
|
289
263
|
it('sends a local mute request with the last audio/video mute values', async () => {
|
|
@@ -303,8 +277,6 @@ describe('LocusMediaRequest.send()', () => {
|
|
|
303
277
|
upload: sinon.match.instanceOf(EventEmitter),
|
|
304
278
|
download: sinon.match.instanceOf(EventEmitter),
|
|
305
279
|
});
|
|
306
|
-
|
|
307
|
-
checkMetrics(false);
|
|
308
280
|
});
|
|
309
281
|
|
|
310
282
|
it('sends only roap when roap and local mute are requested', async () => {
|
|
@@ -324,8 +296,6 @@ describe('LocusMediaRequest.send()', () => {
|
|
|
324
296
|
upload: sinon.match.instanceOf(EventEmitter),
|
|
325
297
|
download: sinon.match.instanceOf(EventEmitter),
|
|
326
298
|
});
|
|
327
|
-
|
|
328
|
-
checkMetrics();
|
|
329
299
|
});
|
|
330
300
|
|
|
331
301
|
describe('queueing', () => {
|