@webex/plugin-meetings 3.9.0-next.2 → 3.9.0-next.20

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.
Files changed (85) hide show
  1. package/dist/breakouts/breakout.js +1 -1
  2. package/dist/breakouts/index.js +1 -1
  3. package/dist/constants.js +2 -0
  4. package/dist/constants.js.map +1 -1
  5. package/dist/interpretation/index.js +1 -1
  6. package/dist/interpretation/siLanguage.js +1 -1
  7. package/dist/locus-info/index.js +38 -10
  8. package/dist/locus-info/index.js.map +1 -1
  9. package/dist/locus-info/parser.js +4 -1
  10. package/dist/locus-info/parser.js.map +1 -1
  11. package/dist/media/properties.js +53 -5
  12. package/dist/media/properties.js.map +1 -1
  13. package/dist/meeting/in-meeting-actions.js +2 -0
  14. package/dist/meeting/in-meeting-actions.js.map +1 -1
  15. package/dist/meeting/index.js +189 -122
  16. package/dist/meeting/index.js.map +1 -1
  17. package/dist/meeting/muteState.js +2 -5
  18. package/dist/meeting/muteState.js.map +1 -1
  19. package/dist/meeting/request.js +25 -0
  20. package/dist/meeting/request.js.map +1 -1
  21. package/dist/meeting/util.js +30 -11
  22. package/dist/meeting/util.js.map +1 -1
  23. package/dist/meeting-info/meeting-info-v2.js +29 -21
  24. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  25. package/dist/meetings/index.js +31 -25
  26. package/dist/meetings/index.js.map +1 -1
  27. package/dist/member/types.js.map +1 -1
  28. package/dist/members/collection.js +13 -0
  29. package/dist/members/collection.js.map +1 -1
  30. package/dist/members/index.js +42 -20
  31. package/dist/members/index.js.map +1 -1
  32. package/dist/members/util.js +7 -2
  33. package/dist/members/util.js.map +1 -1
  34. package/dist/metrics/constants.js +2 -1
  35. package/dist/metrics/constants.js.map +1 -1
  36. package/dist/reachability/index.js +3 -3
  37. package/dist/reachability/index.js.map +1 -1
  38. package/dist/types/constants.d.ts +2 -0
  39. package/dist/types/locus-info/index.d.ts +54 -1
  40. package/dist/types/media/properties.d.ts +21 -0
  41. package/dist/types/meeting/in-meeting-actions.d.ts +2 -0
  42. package/dist/types/meeting/index.d.ts +11 -1
  43. package/dist/types/meeting/request.d.ts +9 -0
  44. package/dist/types/meeting/util.d.ts +10 -3
  45. package/dist/types/meeting-info/meeting-info-v2.d.ts +6 -3
  46. package/dist/types/meetings/index.d.ts +3 -1
  47. package/dist/types/member/types.d.ts +1 -0
  48. package/dist/types/members/collection.d.ts +6 -0
  49. package/dist/types/members/index.d.ts +12 -2
  50. package/dist/types/members/util.d.ts +6 -3
  51. package/dist/types/metrics/constants.d.ts +1 -0
  52. package/dist/webinar/index.js +1 -1
  53. package/package.json +16 -16
  54. package/src/constants.ts +2 -0
  55. package/src/locus-info/index.ts +84 -9
  56. package/src/locus-info/parser.ts +5 -1
  57. package/src/media/properties.ts +43 -0
  58. package/src/meeting/in-meeting-actions.ts +4 -0
  59. package/src/meeting/index.ts +91 -4
  60. package/src/meeting/muteState.ts +2 -6
  61. package/src/meeting/request.ts +23 -0
  62. package/src/meeting/util.ts +41 -20
  63. package/src/meeting-info/meeting-info-v2.ts +24 -5
  64. package/src/meetings/index.ts +9 -3
  65. package/src/member/types.ts +1 -0
  66. package/src/members/collection.ts +11 -0
  67. package/src/members/index.ts +38 -5
  68. package/src/members/util.ts +18 -2
  69. package/src/metrics/constants.ts +1 -0
  70. package/src/reachability/index.ts +3 -3
  71. package/test/unit/spec/locus-info/index.js +30 -15
  72. package/test/unit/spec/locus-info/parser.js +3 -2
  73. package/test/unit/spec/media/properties.ts +137 -0
  74. package/test/unit/spec/meeting/in-meeting-actions.ts +2 -0
  75. package/test/unit/spec/meeting/index.js +255 -27
  76. package/test/unit/spec/meeting/muteState.js +32 -6
  77. package/test/unit/spec/meeting/request.js +21 -0
  78. package/test/unit/spec/meeting/utils.js +45 -16
  79. package/test/unit/spec/meeting-info/meetinginfov2.js +8 -3
  80. package/test/unit/spec/meetings/index.js +10 -1
  81. package/test/unit/spec/members/collection.js +120 -0
  82. package/test/unit/spec/members/index.js +72 -3
  83. package/test/unit/spec/members/request.js +55 -0
  84. package/test/unit/spec/members/utils.js +116 -14
  85. package/test/unit/spec/reachability/index.ts +158 -3
@@ -1,4 +1,47 @@
1
1
  import EventsScope from '../common/events/events-scope';
2
+ export type LocusDTO = {
3
+ controls?: any;
4
+ fullState?: {
5
+ active: boolean;
6
+ count: number;
7
+ lastActive: string;
8
+ locked: boolean;
9
+ sessionId: string;
10
+ seessionIds: string[];
11
+ startTime: number;
12
+ state: string;
13
+ type: string;
14
+ };
15
+ host?: {
16
+ id: string;
17
+ incomingCallProtocols: any[];
18
+ isExternal: boolean;
19
+ name: string;
20
+ orgId: string;
21
+ };
22
+ info?: any;
23
+ links?: any;
24
+ mediaShares?: any[];
25
+ meetings?: any[];
26
+ participants: any[];
27
+ replaces?: any[];
28
+ self?: any;
29
+ sequence?: {
30
+ dirtyParticipants: number;
31
+ entries: number[];
32
+ rangeEnd: number;
33
+ rangeStart: number;
34
+ sequenceHash: number;
35
+ sessionToken: string;
36
+ since: string;
37
+ totalParticipants: number;
38
+ };
39
+ syncUrl?: string;
40
+ url?: string;
41
+ };
42
+ export type LocusApiResponseBody = {
43
+ locus: LocusDTO;
44
+ };
2
45
  /**
3
46
  * @description LocusInfo extends ChildEmitter to convert locusInfo info a private emitter to parent object
4
47
  * @export
@@ -49,6 +92,8 @@ export default class LocusInfo extends EventsScope {
49
92
  * Does a Locus sync. It tries to get the latest delta DTO or if it can't, it falls back to getting the full Locus DTO.
50
93
  *
51
94
  * @param {Meeting} meeting
95
+ * @param {boolean} isLocusUrlChanged
96
+ * @param {Locus} locus
52
97
  * @returns {undefined}
53
98
  */
54
99
  private doLocusSync;
@@ -81,6 +126,13 @@ export default class LocusInfo extends EventsScope {
81
126
  * @memberof LocusInfo
82
127
  */
83
128
  initialSetup(locus: object): void;
129
+ /**
130
+ * Handles HTTP response from Locus API call.
131
+ * @param {Meeting} meeting meeting object
132
+ * @param {LocusApiResponseBody} responseBody body of the http response from Locus API call
133
+ * @returns {void}
134
+ */
135
+ handleLocusAPIResponse(meeting: any, responseBody: LocusApiResponseBody): void;
84
136
  /**
85
137
  * @param {Meeting} meeting
86
138
  * @param {Object} data
@@ -150,11 +202,12 @@ export default class LocusInfo extends EventsScope {
150
202
  /**
151
203
  * update meeting's members
152
204
  * @param {Object} participants new participants object
205
+ * @param {Array} removedParticipantIds list of removed participants
153
206
  * @param {Boolean} isReplace is replace the whole members
154
207
  * @returns {Array} updatedParticipants
155
208
  * @memberof LocusInfo
156
209
  */
157
- updateParticipants(participants: object, isReplace?: boolean): void;
210
+ updateParticipants(participants: object, removedParticipantIds?: string[], isReplace?: boolean): void;
158
211
  /**
159
212
  * @param {Object} controls
160
213
  * @param {Object} self
@@ -1,5 +1,6 @@
1
1
  import { LocalCameraStream, LocalMicrophoneStream, LocalDisplayStream, LocalSystemAudioStream, RemoteStream } from '@webex/media-helpers';
2
2
  import { ClientEvent } from '@webex/internal-plugin-metrics';
3
+ import { throttle } from 'lodash';
3
4
  export type MediaDirection = {
4
5
  sendAudio: boolean;
5
6
  sendVideo: boolean;
@@ -26,6 +27,10 @@ export default class MediaProperties {
26
27
  videoDeviceId: any;
27
28
  videoStream?: LocalCameraStream;
28
29
  namespace: string;
30
+ mediaIssueCounters: {
31
+ [key: string]: number;
32
+ };
33
+ throttledSendMediaIssueMetric: ReturnType<typeof throttle>;
29
34
  /**
30
35
  * @param {Object} [options] -- to auto construct
31
36
  * @returns {MediaProperties}
@@ -63,6 +68,11 @@ export default class MediaProperties {
63
68
  * @returns {void}
64
69
  */
65
70
  setVideoDeviceId(deviceId: string): void;
71
+ /**
72
+ * Clears the webrtcMediaConnection. This method should be called after
73
+ * peer connection is closed and no longer needed.
74
+ * @returns {void}
75
+ */
66
76
  unsetPeerConnection(): void;
67
77
  /**
68
78
  * Removes both remote audio and video from class instance
@@ -129,4 +139,15 @@ export default class MediaProperties {
129
139
  selectedCandidatePairChanges: number;
130
140
  numTransports: number;
131
141
  }>;
142
+ /**
143
+ * Sends a metric about a media issue. Metrics are throttled so that we don't
144
+ * send too many of them, but include a count so that we know how many issues
145
+ * were detected.
146
+ *
147
+ * @param {string} issueType
148
+ * @param {string} issueSubType
149
+ * @param {string} correlationId
150
+ * @returns {void}
151
+ */
152
+ sendMediaIssueMetric(issueType: string, issueSubType: string, correlationId: any): void;
132
153
  }
@@ -39,6 +39,7 @@ interface IInMeetingActions {
39
39
  isLocalRecordingPaused?: boolean;
40
40
  isManualCaptionActive?: boolean;
41
41
  isSaveTranscriptsEnabled?: boolean;
42
+ isSpokenLanguageAutoDetectionEnabled?: boolean;
42
43
  isWebexAssistantActive?: boolean;
43
44
  canViewCaptionPanel?: boolean;
44
45
  isRealTimeTranslationEnabled?: boolean;
@@ -147,6 +148,7 @@ export default class InMeetingActions implements IInMeetingActions {
147
148
  isLocalRecordingPaused: any;
148
149
  isManualCaptionActive: any;
149
150
  isSaveTranscriptsEnabled: any;
151
+ isSpokenLanguageAutoDetectionEnabled: any;
150
152
  isWebexAssistantActive: any;
151
153
  canViewCaptionPanel: any;
152
154
  isRealTimeTranslationEnabled: any;
@@ -2,7 +2,7 @@
2
2
  import { StatelessWebexPlugin } from '@webex/webex-core';
3
3
  import { ClientEvent, ClientEventLeaveReason } from '@webex/internal-plugin-metrics';
4
4
  import { ClientEvent as RawClientEvent } from '@webex/event-dictionary-ts';
5
- import { MediaType, StatsAnalyzer, NetworkQualityMonitor } from '@webex/internal-media-core';
5
+ import { MediaType, StatsAnalyzer, NetworkQualityMonitor, StatsMonitor } from '@webex/internal-media-core';
6
6
  import { LocalStream, LocalCameraStream, LocalDisplayStream, LocalSystemAudioStream, LocalMicrophoneStream } from '@webex/media-helpers';
7
7
  import Roap, { type TurnDiscoverySkipReason } from '../roap/index';
8
8
  import { type TurnServerInfo } from '../roap/types';
@@ -98,6 +98,7 @@ export declare enum ScreenShareFloorStatus {
98
98
  type FetchMeetingInfoParams = {
99
99
  password?: string;
100
100
  registrationId?: string;
101
+ classificationId?: string;
101
102
  captchaCode?: string;
102
103
  extraParams?: Record<string, any>;
103
104
  sendCAevents?: boolean;
@@ -428,6 +429,7 @@ export default class Meeting extends StatelessWebexPlugin {
428
429
  shareStatus: string;
429
430
  screenShareFloorState: ScreenShareFloorStatus;
430
431
  statsAnalyzer: StatsAnalyzer;
432
+ statsMonitor: StatsMonitor;
431
433
  transcription: Transcription;
432
434
  updateMediaConnections: (mediaConnections: any[]) => void;
433
435
  userDisplayHints: any;
@@ -2021,5 +2023,13 @@ export default class Meeting extends StatelessWebexPlugin {
2021
2023
  * @returns {Promise} The locus request
2022
2024
  */
2023
2025
  unsetStage(): Promise<any>;
2026
+ /**
2027
+ * Notifies the host with the given meeting UUID and display names.
2028
+ *
2029
+ * @param {string} meetingUuid - The UUID of the meeting.
2030
+ * @param {string[]} displayName - An array of display names to notify the host with.
2031
+ * @returns {Promise<any>} The result of the notifyHost request.
2032
+ */
2033
+ notifyHost(meetingUuid: string, displayName: string[]): any;
2024
2034
  }
2025
2035
  export {};
@@ -322,4 +322,13 @@ export default class MeetingRequest extends StatelessWebexPlugin {
322
322
  * @returns {Promise} The locus request
323
323
  */
324
324
  synchronizeStage(locusUrl: string, videoLayout: SynchronizeVideoLayout): Promise<any>;
325
+ /**
326
+ * Sends a request to notify the host of a meeting.
327
+ * @param {string} siteFullUrl - The site URL.
328
+ * @param {string} locusId - The locus ID.
329
+ * @param {string} meetingUuid - The meeting UUID.
330
+ * @param {Array<string>} displayName - The display names to notify the host about.
331
+ * @returns {Promise}
332
+ */
333
+ notifyHost(siteFullUrl: string, locusId: string, meetingUuid: string, displayName: string[]): any;
325
334
  }
@@ -14,6 +14,12 @@ declare const MeetingUtil: {
14
14
  * @returns {IP_VERSION|undefined} ipver value to be passed to the backend APIs or undefined if we should not pass any value to the backend
15
15
  */
16
16
  getIpVersion(webex: any): IP_VERSION | undefined;
17
+ /**
18
+ * Returns CA event labels related to Orpheus ipver parameter that can be sent to CA with any CA event
19
+ * @param {any} webex instance
20
+ * @returns {Array<string>|undefined} array of CA event labels or undefined if no labels should be sent
21
+ */
22
+ getCaEventLabelsForIpVersion(webex: any): Array<string> | undefined;
17
23
  joinMeeting: (meeting: any, options: any) => Promise<any>;
18
24
  cleanUp: (meeting: any) => any;
19
25
  disconnectPhoneAudio: (meeting: any, phoneUrl: any) => any;
@@ -76,6 +82,7 @@ declare const MeetingUtil: {
76
82
  isLocalRecordingPaused: (displayHints: any) => any;
77
83
  canStopManualCaption: (displayHints: any) => any;
78
84
  isManualCaptionActive: (displayHints: any) => any;
85
+ isSpokenLanguageAutoDetectionEnabled: (displayHints: any) => any;
79
86
  isWebexAssistantActive: (displayHints: any) => any;
80
87
  canViewCaptionPanel: (displayHints: any) => any;
81
88
  isRealTimeTranslationEnabled: (displayHints: any) => any;
@@ -95,14 +102,14 @@ declare const MeetingUtil: {
95
102
  */
96
103
  addSequence: (meeting: any, requestBody: any) => void;
97
104
  /**
98
- * Updates the locus info for the meeting with the delta locus
99
- * returned from requests that include the sequence information
105
+ * Updates the locus info for the meeting with the locus
106
+ * information returned from API requests made to Locus
100
107
  * Returns the original response object
101
108
  * @param {Object} meeting The meeting object
102
109
  * @param {Object} response The response of the http request
103
110
  * @returns {Object}
104
111
  */
105
- updateLocusWithDelta: (meeting: any, response: any) => any;
112
+ updateLocusFromApiResponse: (meeting: any, response: any) => any;
106
113
  generateBuildLocusDeltaRequestOptions: (originalMeeting: any) => (originalOptions: any) => any;
107
114
  generateLocusDeltaRequest: (originalMeeting: any) => (originalOptions: any) => any;
108
115
  selfSupportsFeature: (feature: SELF_POLICY, userPolicies: Record<SELF_POLICY, boolean>) => boolean;
@@ -187,20 +187,22 @@ export default class MeetingInfoV2 {
187
187
  * @param {String} conversationUrl conversationUrl to start adhoc meeting on
188
188
  * @param {String} installedOrgID org ID of user's machine
189
189
  * @param {Boolean} enableStaticMeetingLink whether or not to enable static meeting link
190
+ * @param {String} classificationId need it to start adhoc meeting if space support classification
190
191
  * @returns {Promise} returns a meeting info object
191
192
  * @public
192
193
  * @memberof MeetingInfo
193
194
  */
194
- createAdhocSpaceMeetingOrEnableStaticMeetingLink(conversationUrl: string, installedOrgID?: string, enableStaticMeetingLink?: boolean): Promise<any>;
195
+ createAdhocSpaceMeetingOrEnableStaticMeetingLink(conversationUrl: string, installedOrgID?: string, enableStaticMeetingLink?: boolean, classificationId?: any): Promise<any>;
195
196
  /**
196
197
  * Creates adhoc space meetings for a space by fetching the conversation infomation
197
198
  * @param {String} conversationUrl conversationUrl to start adhoc meeting on
198
199
  * @param {String} installedOrgID org ID of user's machine
200
+ * @param {String} classificationId if space is support classification, it needs provide it during start instant meeting
199
201
  * @returns {Promise} returns a meeting info object
200
202
  * @public
201
203
  * @memberof MeetingInfo
202
204
  */
203
- createAdhocSpaceMeeting(conversationUrl: string, installedOrgID?: string): Promise<any>;
205
+ createAdhocSpaceMeeting(conversationUrl: string, installedOrgID?: string, classificationId?: string): Promise<any>;
204
206
  /**
205
207
  * Fetches details for static meeting link
206
208
  * @param {String} conversationUrl conversationUrl that's required to find static meeting link if it exists
@@ -239,6 +241,7 @@ export default class MeetingInfoV2 {
239
241
  * @param {Object} options
240
242
  * @param {String} registrationId
241
243
  * @param {String} fullSiteUrl
244
+ * @param {String} classificationId
242
245
  * @returns {Promise} returns a meeting info object
243
246
  * @public
244
247
  * @memberof MeetingInfo
@@ -249,5 +252,5 @@ export default class MeetingInfoV2 {
249
252
  }, installedOrgID?: any, locusId?: any, extraParams?: object, options?: {
250
253
  meetingId?: string;
251
254
  sendCAevents?: boolean;
252
- }, registrationId?: string, fullSiteUrl?: string): Promise<any>;
255
+ }, registrationId?: string, fullSiteUrl?: string, classificationId?: string): Promise<any>;
253
256
  }
@@ -400,11 +400,12 @@ export default class Meetings extends WebexPlugin {
400
400
  * @param {Object} [meetingInfo] - Pre-fetched complete meeting info
401
401
  * @param {String} [meetingLookupUrl] - meeting info prefetch url
402
402
  * @param {string} sessionCorrelationId - the optional specified sessionCorrelationId (callStateForMetrics.sessionCorrelationId) can be provided instead
403
+ * @param {String} classificationId - If space support classification, it will provide it while start instant meeting
403
404
  * @returns {Promise<Meeting>} A new Meeting.
404
405
  * @public
405
406
  * @memberof Meetings
406
407
  */
407
- create(destination: string, type?: DESTINATION_TYPE, useRandomDelayForInfo?: boolean, infoExtraParams?: {}, correlationId?: string, failOnMissingMeetingInfo?: boolean, callStateForMetrics?: CallStateForMetrics, meetingInfo?: any, meetingLookupUrl?: any, sessionCorrelationId?: string): any;
408
+ create(destination: string, type?: DESTINATION_TYPE, useRandomDelayForInfo?: boolean, infoExtraParams?: {}, correlationId?: string, failOnMissingMeetingInfo?: boolean, callStateForMetrics?: CallStateForMetrics, meetingInfo?: any, meetingLookupUrl?: any, sessionCorrelationId?: string, classificationId?: string): any;
408
409
  /**
409
410
  * Enable static meeting links for given conversation url.
410
411
  *
@@ -438,6 +439,7 @@ export default class Meetings extends WebexPlugin {
438
439
  * @param {Boolean} failOnMissingMeetingInfo - whether to throw an error if meeting info fails to fetch (for calls that are not 1:1 or content share)
439
440
  * @param {Object} [meetingInfo] - Pre-fetched complete meeting info
440
441
  * @param {String} [meetingLookupUrl] - meeting info prefetch url
442
+ * @param {String} classificationId see create()
441
443
  * @returns {Promise} a new meeting instance complete with meeting info and destination
442
444
  * @private
443
445
  * @memberof Meetings
@@ -95,4 +95,5 @@ export interface Participant {
95
95
  status: ParticipantMediaStatus;
96
96
  type: string;
97
97
  url: ParticipantUrl;
98
+ isRemoved: boolean;
98
99
  }
@@ -22,6 +22,12 @@ export default class MembersCollection {
22
22
  * @memberof MembersCollection
23
23
  */
24
24
  getAll(): Record<string, Member>;
25
+ /**
26
+ * Removes a member from the collection
27
+ * @param {String} id
28
+ * @returns {void}
29
+ */
30
+ remove(id: string): void;
25
31
  /**
26
32
  * @returns {void}
27
33
  * reset members
@@ -77,7 +77,9 @@ export default class Members extends StatelessWebexPlugin {
77
77
  * when new participant updates come in, both delta and full participants, update them in members collection
78
78
  * delta object in the event will have {updated, added} and full will be the full membersCollection
79
79
  * @param {Object} payload
80
- * @param {Object} payload.participants
80
+ * @param {Object} payload.participants new/updated participants
81
+ * @param {Boolean} payload.isReplace whether to replace the whole members collection
82
+ * @param {Object} payload.removedParticipantIds ids of the removed participants
81
83
  * @returns {undefined}
82
84
  * @private
83
85
  * @memberof Members
@@ -85,6 +87,7 @@ export default class Members extends StatelessWebexPlugin {
85
87
  locusParticipantsUpdate(payload: {
86
88
  participants: object;
87
89
  isReplace?: boolean;
90
+ removedParticipantIds?: Array<string>;
88
91
  }): void;
89
92
  /**
90
93
  * Internal update the content id
@@ -127,6 +130,12 @@ export default class Members extends StatelessWebexPlugin {
127
130
  * @memberof Members
128
131
  */
129
132
  private handleMembersUpdate;
133
+ /**
134
+ * removes members from the collection
135
+ * @param {Array<string>} removedMembers removed members ids
136
+ * @returns {void}
137
+ */
138
+ private removeMembers;
130
139
  /**
131
140
  * set members to the member collection from each updated/added lists as passed in
132
141
  * @param {Array} list
@@ -338,9 +347,10 @@ export default class Members extends StatelessWebexPlugin {
338
347
  * @param {string} memberId - id of the participant who is receiving request
339
348
  * @param {string} requestingParticipantId - id of the participant who is sending request (optional)
340
349
  * @param {string} [alias] - alias name
350
+ * @param {string} [suffix] - name suffix (optional)
341
351
  * @returns {Promise}
342
352
  * @public
343
353
  * @memberof Members
344
354
  */
345
- editDisplayName(memberId: string, requestingParticipantId: string, alias: string): any;
355
+ editDisplayName(memberId: string, requestingParticipantId: string, alias: string, suffix?: string): any;
346
356
  }
@@ -110,13 +110,15 @@ declare const MembersUtil: {
110
110
  * @param {String} requestingParticipantId id of the participant who is sending request (optional)
111
111
  * @param {String} alias alias name
112
112
  * @param {String} locusUrl url
113
+ * @param {String} suffix optional suffix
113
114
  * @returns {Object} consists of {memberID: string, requestingParticipantId: string, alias: string, locusUrl: string}
114
115
  */
115
- generateEditDisplayNameMemberOptions: (memberId: any, requestingParticipantId: any, alias: any, locusUrl: any) => {
116
+ generateEditDisplayNameMemberOptions: (memberId: any, requestingParticipantId: any, alias: any, locusUrl: any, suffix: any) => {
116
117
  memberId: any;
117
118
  requestingParticipantId: any;
118
119
  alias: any;
119
120
  locusUrl: any;
121
+ suffix: any;
120
122
  };
121
123
  getMuteMemberRequestParams: (options: any) => {
122
124
  method: string;
@@ -178,8 +180,9 @@ declare const MembersUtil: {
178
180
  method: string;
179
181
  uri: string;
180
182
  body: {
181
- aliasValue: any;
182
- requestingParticipantId: any;
183
+ aliasValue: string;
184
+ requestingParticipantId: string;
185
+ suffixValue?: string;
183
186
  };
184
187
  };
185
188
  getTransferHostToMemberRequestParams: (options: any) => {
@@ -83,5 +83,6 @@ declare const BEHAVIORAL_METRICS: {
83
83
  VERIFY_REGISTRATION_ID_SUCCESS: string;
84
84
  VERIFY_REGISTRATION_ID_ERROR: string;
85
85
  JOIN_FORBIDDEN_ERROR: string;
86
+ MEDIA_ISSUE_DETECTED: string;
86
87
  };
87
88
  export { BEHAVIORAL_METRICS as default };
@@ -458,7 +458,7 @@ var Webinar = _webexCore.WebexPlugin.extend({
458
458
  }, _callee7);
459
459
  }))();
460
460
  },
461
- version: "3.9.0-next.2"
461
+ version: "3.9.0-next.20"
462
462
  });
463
463
  var _default = exports.default = Webinar;
464
464
  //# sourceMappingURL=index.js.map
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-rooms": "3.8.1-next.15",
46
+ "@webex/plugin-rooms": "3.9.0-next.4",
47
47
  "@webex/test-helper-chai": "3.8.1-next.11",
48
48
  "@webex/test-helper-mocha": "3.8.1-next.11",
49
49
  "@webex/test-helper-mock-webex": "3.8.1-next.11",
@@ -61,22 +61,22 @@
61
61
  },
62
62
  "dependencies": {
63
63
  "@webex/common": "3.8.1-next.11",
64
- "@webex/event-dictionary-ts": "^1.0.1819",
65
- "@webex/internal-media-core": "2.18.5",
66
- "@webex/internal-plugin-conversation": "3.8.1-next.18",
67
- "@webex/internal-plugin-device": "3.8.1-next.15",
68
- "@webex/internal-plugin-llm": "3.8.1-next.16",
69
- "@webex/internal-plugin-mercury": "3.8.1-next.15",
70
- "@webex/internal-plugin-metrics": "3.8.1-next.15",
71
- "@webex/internal-plugin-support": "3.8.1-next.18",
72
- "@webex/internal-plugin-user": "3.8.1-next.15",
73
- "@webex/internal-plugin-voicea": "3.8.1-next.42",
74
- "@webex/media-helpers": "3.8.1-next.16",
75
- "@webex/plugin-people": "3.8.1-next.15",
76
- "@webex/plugin-rooms": "3.8.1-next.15",
64
+ "@webex/event-dictionary-ts": "^1.0.1930",
65
+ "@webex/internal-media-core": "2.19.0",
66
+ "@webex/internal-plugin-conversation": "3.9.0-next.4",
67
+ "@webex/internal-plugin-device": "3.9.0-next.3",
68
+ "@webex/internal-plugin-llm": "3.9.0-next.3",
69
+ "@webex/internal-plugin-mercury": "3.9.0-next.3",
70
+ "@webex/internal-plugin-metrics": "3.9.0-next.3",
71
+ "@webex/internal-plugin-support": "3.9.0-next.5",
72
+ "@webex/internal-plugin-user": "3.9.0-next.3",
73
+ "@webex/internal-plugin-voicea": "3.9.0-next.4",
74
+ "@webex/media-helpers": "3.9.0-next.1",
75
+ "@webex/plugin-people": "3.9.0-next.3",
76
+ "@webex/plugin-rooms": "3.9.0-next.4",
77
77
  "@webex/ts-sdp": "^1.8.1",
78
78
  "@webex/web-capabilities": "^1.6.0",
79
- "@webex/webex-core": "3.8.1-next.15",
79
+ "@webex/webex-core": "3.9.0-next.3",
80
80
  "ampersand-collection": "^2.0.2",
81
81
  "bowser": "^2.11.0",
82
82
  "btoa": "^1.2.1",
@@ -92,5 +92,5 @@
92
92
  "//": [
93
93
  "TODO: upgrade jwt-decode when moving to node 18"
94
94
  ],
95
- "version": "3.9.0-next.2"
95
+ "version": "3.9.0-next.20"
96
96
  }
package/src/constants.ts CHANGED
@@ -347,6 +347,7 @@ export const EVENT_TRIGGERS = {
347
347
  MEETING_SELF_LEFT: 'meeting:self:left',
348
348
  NETWORK_QUALITY: 'network:quality',
349
349
  MEDIA_NEGOTIATED: 'media:negotiated',
350
+ MEDIA_INBOUND_AUDIO_ISSUE_DETECTED: 'media:inboundAudio:issueDetected',
350
351
  // the following events apply only to multistream media connections
351
352
  ACTIVE_SPEAKER_CHANGED: 'media:activeSpeakerChanged',
352
353
  REMOTE_VIDEO_SOURCE_COUNT_CHANGED: 'media:remoteVideoSourceCountChanged',
@@ -966,6 +967,7 @@ export const DISPLAY_HINTS = {
966
967
  MANUAL_CAPTION_STOP: 'MANUAL_CAPTION_STOP',
967
968
  MANUAL_CAPTION_STATUS_ACTIVE: 'MANUAL_CAPTION_STATUS_ACTIVE',
968
969
  DISPLAY_REAL_TIME_TRANSLATION: 'DISPLAY_REAL_TIME_TRANSLATION',
970
+ SPOKEN_LANGUAGE_AUTO_DETECTION_ENABLED: 'SPOKEN_LANGUAGE_AUTO_DETECTION_ENABLED',
969
971
  ENABLE_CAPTION_PANEL: 'ENABLE_CAPTION_PANEL',
970
972
  DISPLAY_NON_ENGLISH_ASR: 'DISPLAY_NON_ENGLISH_ASR',
971
973
  TRANSCRIPTION_CONTROL_START: 'TRANSCRIPTION_CONTROL_START',
@@ -31,6 +31,51 @@ import LocusDeltaParser from './parser';
31
31
  import Metrics from '../metrics';
32
32
  import BEHAVIORAL_METRICS from '../metrics/constants';
33
33
 
34
+ export type LocusDTO = {
35
+ controls?: any;
36
+ fullState?: {
37
+ active: boolean;
38
+ count: number;
39
+ lastActive: string;
40
+ locked: boolean;
41
+ sessionId: string;
42
+ seessionIds: string[];
43
+ startTime: number;
44
+ state: string;
45
+ type: string;
46
+ };
47
+ host?: {
48
+ id: string;
49
+ incomingCallProtocols: any[];
50
+ isExternal: boolean;
51
+ name: string;
52
+ orgId: string;
53
+ };
54
+ info?: any;
55
+ links?: any;
56
+ mediaShares?: any[];
57
+ meetings?: any[];
58
+ participants: any[];
59
+ replaces?: any[];
60
+ self?: any;
61
+ sequence?: {
62
+ dirtyParticipants: number;
63
+ entries: number[];
64
+ rangeEnd: number;
65
+ rangeStart: number;
66
+ sequenceHash: number;
67
+ sessionToken: string;
68
+ since: string;
69
+ totalParticipants: number;
70
+ };
71
+ syncUrl?: string;
72
+ url?: string;
73
+ };
74
+
75
+ export type LocusApiResponseBody = {
76
+ locus: LocusDTO; // this LocusDTO here might not be the full one (for example it won't have all the participants, but it should have self)
77
+ };
78
+
34
79
  /**
35
80
  * @description LocusInfo extends ChildEmitter to convert locusInfo info a private emitter to parent object
36
81
  * @export
@@ -93,19 +138,26 @@ export default class LocusInfo extends EventsScope {
93
138
  * Does a Locus sync. It tries to get the latest delta DTO or if it can't, it falls back to getting the full Locus DTO.
94
139
  *
95
140
  * @param {Meeting} meeting
141
+ * @param {boolean} isLocusUrlChanged
142
+ * @param {Locus} locus
96
143
  * @returns {undefined}
97
144
  */
98
- private doLocusSync(meeting: any) {
99
- let isDelta;
145
+ private doLocusSync(meeting: any, isLocusUrlChanged: boolean, locus: any) {
100
146
  let url;
147
+ let isDelta = false;
101
148
  let meetingDestroyed = false;
102
149
 
103
- if (this.locusParser.workingCopy.syncUrl) {
150
+ if (isLocusUrlChanged) {
151
+ // for the locus url changed case from breakout to main session, we should always do a full sync, in this case, the url from locus is always on main session,
152
+ // so use the main session locus url to get the full locus(full participants list in the response).
153
+ // for the locus url changed case from main session to breakout, we don't need to care about it here,
154
+ // because it is a USE_INCOMING case, it will not be executed here.
155
+ url = locus.url;
156
+ } else if (this.locusParser.workingCopy?.syncUrl) {
104
157
  url = this.locusParser.workingCopy.syncUrl;
105
158
  isDelta = true;
106
159
  } else {
107
160
  url = meeting.locusUrl;
108
- isDelta = false;
109
161
  }
110
162
 
111
163
  LoggerProxy.logger.info(
@@ -217,6 +269,7 @@ export default class LocusInfo extends EventsScope {
217
269
  */
218
270
  applyLocusDeltaData(action: string, locus: any, meeting: any) {
219
271
  const {DESYNC, USE_CURRENT, USE_INCOMING, WAIT, LOCUS_URL_CHANGED} = LocusDeltaParser.loci;
272
+ const isLocusUrlChanged = action === LOCUS_URL_CHANGED;
220
273
 
221
274
  switch (action) {
222
275
  case USE_INCOMING:
@@ -228,7 +281,7 @@ export default class LocusInfo extends EventsScope {
228
281
  break;
229
282
  case DESYNC:
230
283
  case LOCUS_URL_CHANGED:
231
- this.doLocusSync(meeting);
284
+ this.doLocusSync(meeting, isLocusUrlChanged, locus);
232
285
  break;
233
286
  default:
234
287
  LoggerProxy.logger.info(
@@ -286,7 +339,7 @@ export default class LocusInfo extends EventsScope {
286
339
  this.updateLocusCache(locus);
287
340
  // above section only updates the locusInfo object
288
341
  // The below section makes sure it updates the locusInfo as well as updates the meeting object
289
- this.updateParticipants(locus.participants);
342
+ this.updateParticipants(locus.participants, []);
290
343
  // For 1:1 space meeting the conversation Url does not exist in locus.conversation
291
344
  this.updateConversationUrl(locus.conversationUrl, locus.info);
292
345
  this.updateControls(locus.controls, locus.self);
@@ -315,6 +368,16 @@ export default class LocusInfo extends EventsScope {
315
368
  this.emitChange = true;
316
369
  }
317
370
 
371
+ /**
372
+ * Handles HTTP response from Locus API call.
373
+ * @param {Meeting} meeting meeting object
374
+ * @param {LocusApiResponseBody} responseBody body of the http response from Locus API call
375
+ * @returns {void}
376
+ */
377
+ handleLocusAPIResponse(meeting, responseBody: LocusApiResponseBody): void {
378
+ this.handleLocusDelta(responseBody.locus, meeting);
379
+ }
380
+
318
381
  /**
319
382
  * @param {Meeting} meeting
320
383
  * @param {Object} data
@@ -327,6 +390,8 @@ export default class LocusInfo extends EventsScope {
327
390
  const locus = this.getTheLocusToUpdate(data.locus);
328
391
  LoggerProxy.logger.info(`Locus-info:index#parse --> received locus data: ${eventType}`);
329
392
 
393
+ locus.jsSdkMeta = {removedParticipantIds: []};
394
+
330
395
  switch (eventType) {
331
396
  case LOCUSEVENT.PARTICIPANT_JOIN:
332
397
  case LOCUSEVENT.PARTICIPANT_LEFT:
@@ -392,7 +457,11 @@ export default class LocusInfo extends EventsScope {
392
457
  this.participants = locus.participants;
393
458
  const isReplaceMembers = ControlsUtils.isNeedReplaceMembers(this.controls, locus.controls);
394
459
  this.updateLocusInfo(locus);
395
- this.updateParticipants(locus.participants, isReplaceMembers);
460
+ this.updateParticipants(
461
+ locus.participants,
462
+ locus.jsSdkMeta?.removedParticipantIds,
463
+ isReplaceMembers
464
+ );
396
465
  this.isMeetingActive();
397
466
  this.handleOneOnOneEvent(eventType);
398
467
  this.updateEmbeddedApps(locus.embeddedApps);
@@ -454,7 +523,11 @@ export default class LocusInfo extends EventsScope {
454
523
  const isReplaceMembers = ControlsUtils.isNeedReplaceMembers(this.controls, locus.controls);
455
524
  this.mergeParticipants(this.participants, locus.participants);
456
525
  this.updateLocusInfo(locus);
457
- this.updateParticipants(locus.participants, isReplaceMembers);
526
+ this.updateParticipants(
527
+ locus.participants,
528
+ locus.jsSdkMeta?.removedParticipantIds,
529
+ isReplaceMembers
530
+ );
458
531
  this.isMeetingActive();
459
532
  }
460
533
 
@@ -745,11 +818,12 @@ export default class LocusInfo extends EventsScope {
745
818
  /**
746
819
  * update meeting's members
747
820
  * @param {Object} participants new participants object
821
+ * @param {Array} removedParticipantIds list of removed participants
748
822
  * @param {Boolean} isReplace is replace the whole members
749
823
  * @returns {Array} updatedParticipants
750
824
  * @memberof LocusInfo
751
825
  */
752
- updateParticipants(participants: object, isReplace?: boolean) {
826
+ updateParticipants(participants: object, removedParticipantIds?: string[], isReplace?: boolean) {
753
827
  this.emitScoped(
754
828
  {
755
829
  file: 'locus-info',
@@ -758,6 +832,7 @@ export default class LocusInfo extends EventsScope {
758
832
  EVENTS.LOCUS_INFO_UPDATE_PARTICIPANTS,
759
833
  {
760
834
  participants,
835
+ removedParticipantIds,
761
836
  recordingId: this.parsedLocus.controls && this.parsedLocus.controls.record?.modifiedBy,
762
837
  selfIdentity: this.parsedLocus.self && this.parsedLocus.self.selfIdentity,
763
838
  selfId: this.parsedLocus.self && this.parsedLocus.self.selfId,