@webex/plugin-meetings 3.8.1-next.4 → 3.8.1-next.40

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 (94) hide show
  1. package/README.md +26 -13
  2. package/dist/breakouts/breakout.js +1 -1
  3. package/dist/breakouts/index.js +1 -1
  4. package/dist/constants.js +24 -2
  5. package/dist/constants.js.map +1 -1
  6. package/dist/interpretation/index.js +1 -1
  7. package/dist/interpretation/siLanguage.js +1 -1
  8. package/dist/locus-info/index.js +38 -84
  9. package/dist/locus-info/index.js.map +1 -1
  10. package/dist/media/index.js +2 -2
  11. package/dist/media/index.js.map +1 -1
  12. package/dist/meeting/brbState.js +14 -12
  13. package/dist/meeting/brbState.js.map +1 -1
  14. package/dist/meeting/in-meeting-actions.js +6 -0
  15. package/dist/meeting/in-meeting-actions.js.map +1 -1
  16. package/dist/meeting/index.js +213 -77
  17. package/dist/meeting/index.js.map +1 -1
  18. package/dist/meeting/request.js +19 -0
  19. package/dist/meeting/request.js.map +1 -1
  20. package/dist/meeting/request.type.js.map +1 -1
  21. package/dist/meeting/type.js +7 -0
  22. package/dist/meeting/type.js.map +1 -0
  23. package/dist/meeting/util.js +11 -0
  24. package/dist/meeting/util.js.map +1 -1
  25. package/dist/meetings/index.js +35 -33
  26. package/dist/meetings/index.js.map +1 -1
  27. package/dist/members/index.js +11 -9
  28. package/dist/members/index.js.map +1 -1
  29. package/dist/members/request.js +3 -3
  30. package/dist/members/request.js.map +1 -1
  31. package/dist/members/util.js +18 -6
  32. package/dist/members/util.js.map +1 -1
  33. package/dist/multistream/mediaRequestManager.js +1 -1
  34. package/dist/multistream/mediaRequestManager.js.map +1 -1
  35. package/dist/multistream/remoteMedia.js +34 -5
  36. package/dist/multistream/remoteMedia.js.map +1 -1
  37. package/dist/multistream/remoteMediaGroup.js +42 -2
  38. package/dist/multistream/remoteMediaGroup.js.map +1 -1
  39. package/dist/multistream/sendSlotManager.js +32 -2
  40. package/dist/multistream/sendSlotManager.js.map +1 -1
  41. package/dist/reachability/index.js +5 -10
  42. package/dist/reachability/index.js.map +1 -1
  43. package/dist/types/constants.d.ts +22 -0
  44. package/dist/types/locus-info/index.d.ts +0 -9
  45. package/dist/types/meeting/brbState.d.ts +0 -1
  46. package/dist/types/meeting/in-meeting-actions.d.ts +6 -0
  47. package/dist/types/meeting/index.d.ts +35 -18
  48. package/dist/types/meeting/request.d.ts +9 -1
  49. package/dist/types/meeting/request.type.d.ts +74 -0
  50. package/dist/types/meeting/type.d.ts +9 -0
  51. package/dist/types/meeting/util.d.ts +3 -0
  52. package/dist/types/members/index.d.ts +10 -7
  53. package/dist/types/members/request.d.ts +1 -1
  54. package/dist/types/members/util.d.ts +7 -3
  55. package/dist/types/multistream/remoteMedia.d.ts +20 -1
  56. package/dist/types/multistream/remoteMediaGroup.d.ts +11 -0
  57. package/dist/types/multistream/sendSlotManager.d.ts +16 -0
  58. package/dist/types/reachability/index.d.ts +2 -2
  59. package/dist/webinar/index.js +1 -1
  60. package/package.json +24 -25
  61. package/src/constants.ts +23 -2
  62. package/src/locus-info/index.ts +47 -82
  63. package/src/media/index.ts +2 -2
  64. package/src/meeting/brbState.ts +9 -7
  65. package/src/meeting/in-meeting-actions.ts +13 -0
  66. package/src/meeting/index.ts +168 -42
  67. package/src/meeting/request.ts +16 -0
  68. package/src/meeting/request.type.ts +64 -0
  69. package/src/meeting/type.ts +9 -0
  70. package/src/meeting/util.ts +13 -0
  71. package/src/meetings/index.ts +3 -2
  72. package/src/members/index.ts +13 -10
  73. package/src/members/request.ts +2 -2
  74. package/src/members/util.ts +16 -4
  75. package/src/multistream/mediaRequestManager.ts +7 -7
  76. package/src/multistream/remoteMedia.ts +34 -4
  77. package/src/multistream/remoteMediaGroup.ts +37 -2
  78. package/src/multistream/sendSlotManager.ts +34 -2
  79. package/src/reachability/index.ts +5 -13
  80. package/test/unit/spec/locus-info/index.js +177 -83
  81. package/test/unit/spec/media/index.ts +107 -0
  82. package/test/unit/spec/meeting/brbState.ts +9 -9
  83. package/test/unit/spec/meeting/in-meeting-actions.ts +6 -0
  84. package/test/unit/spec/meeting/index.js +694 -60
  85. package/test/unit/spec/meeting/request.js +71 -0
  86. package/test/unit/spec/meeting/utils.js +21 -0
  87. package/test/unit/spec/meetings/index.js +2 -0
  88. package/test/unit/spec/members/index.js +68 -9
  89. package/test/unit/spec/members/request.js +2 -2
  90. package/test/unit/spec/members/utils.js +27 -7
  91. package/test/unit/spec/multistream/mediaRequestManager.ts +19 -6
  92. package/test/unit/spec/multistream/remoteMedia.ts +66 -2
  93. package/test/unit/spec/multistream/sendSlotManager.ts +59 -0
  94. package/test/unit/spec/reachability/index.ts +2 -6
package/src/constants.ts CHANGED
@@ -217,6 +217,7 @@ export const DIALER_REGEX = {
217
217
  PHONE_NUMBER:
218
218
  /^(?:(?:\+?1\s*(?:[.-]\s*)?)?(?:\(\s*([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9])\s*\)|([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9]))\s*(?:[.-]\s*)?)?([2-9]1[02-9]|[2-9][02-9]1|[2-9][02-9]{2})\s*(?:[.-]\s*)?([0-9]{4})(?:\s*(?:#|x\.?|ext\.?|extension)\s*(\d+))?$/,
219
219
  E164_FORMAT: /^\+[1-9]\d{1,14}$/,
220
+ INTERNAL_NUMBER: /^\d{1,14}$/,
220
221
  };
221
222
 
222
223
  // eslint-disable-next-line max-len
@@ -262,7 +263,6 @@ export const RECORDING_STATE = {
262
263
  PAUSED: 'paused',
263
264
  RESUMED: 'resumed',
264
265
  };
265
-
266
266
  export const SHARE_STATUS = {
267
267
  NO_SHARE: 'no_share',
268
268
  REMOTE_SHARE_ACTIVE: 'remote_share_active',
@@ -948,6 +948,9 @@ export const DISPLAY_HINTS = {
948
948
  PREMISE_RECORDING_CONTROL_PAUSE: 'PREMISE_RECORDING_CONTROL_PAUSE',
949
949
  PREMISE_RECORDING_CONTROL_STOP: 'PREMISE_RECORDING_CONTROL_STOP',
950
950
  PREMISE_RECORDING_CONTROL_RESUME: 'PREMISE_RECORDING_CONTROL_RESUME',
951
+ LOCAL_RECORDING_STATUS_STARTED: 'LOCAL_RECORDING_STATUS_STARTED',
952
+ LOCAL_RECORDING_STATUS_STOPPED: 'LOCAL_RECORDING_STATUS_STOPPED',
953
+ LOCAL_RECORDING_STATUS_PAUSED: 'LOCAL_RECORDING_STATUS_PAUSED',
951
954
  LOCK_CONTROL_UNLOCK: 'LOCK_CONTROL_UNLOCK',
952
955
  LOCK_CONTROL_LOCK: 'LOCK_CONTROL_LOCK',
953
956
  LOCK_STATUS_LOCKED: 'LOCK_STATUS_LOCKED',
@@ -987,7 +990,6 @@ export const DISPLAY_HINTS = {
987
990
  CAN_RENAME_SELF_AND_OBSERVED: 'CAN_RENAME_SELF_AND_OBSERVED',
988
991
  CAN_RENAME_OTHERS: 'CAN_RENAME_OTHERS',
989
992
  MOVE_TO_LOBBY: 'MOVE_TO_LOBBY',
990
-
991
993
  // breakout session
992
994
  BREAKOUT_MANAGEMENT: 'BREAKOUT_MANAGEMENT',
993
995
  BROADCAST_MESSAGE_TO_BREAKOUT: 'BROADCAST_MESSAGE_TO_BREAKOUT',
@@ -1188,6 +1190,7 @@ export const QUALITY_LEVELS = {
1188
1190
  HIGH: 'HIGH',
1189
1191
  '360p': '360p',
1190
1192
  '480p': '480p',
1193
+ '540p': '540p',
1191
1194
  '720p': '720p',
1192
1195
  '1080p': '1080p',
1193
1196
  };
@@ -1217,6 +1220,18 @@ export const AVAILABLE_RESOLUTIONS = {
1217
1220
  },
1218
1221
  },
1219
1222
  },
1223
+ '540p': {
1224
+ video: {
1225
+ width: {
1226
+ max: 960,
1227
+ ideal: 960,
1228
+ },
1229
+ height: {
1230
+ max: 540,
1231
+ ideal: 540,
1232
+ },
1233
+ },
1234
+ },
1220
1235
  '720p': {
1221
1236
  video: {
1222
1237
  width: {
@@ -1357,3 +1372,9 @@ export const INITIAL_REGISTRATION_STATUS = {
1357
1372
  mercuryConnect: false,
1358
1373
  checkH264Support: false,
1359
1374
  };
1375
+
1376
+ export const STAGE_MANAGER_TYPE = {
1377
+ LOGO: 0b001,
1378
+ BACKGROUND: 0b010,
1379
+ NAME_LABEL: 0b100,
1380
+ };
@@ -48,7 +48,6 @@ export default class LocusInfo extends EventsScope {
48
48
  aclUrl: any;
49
49
  baseSequence: any;
50
50
  created: any;
51
- deltaParticipants: any;
52
51
  identities: any;
53
52
  membership: any;
54
53
  participants: any;
@@ -99,6 +98,7 @@ export default class LocusInfo extends EventsScope {
99
98
  private doLocusSync(meeting: any) {
100
99
  let isDelta;
101
100
  let url;
101
+ let meetingDestroyed = false;
102
102
 
103
103
  if (this.locusParser.workingCopy.syncUrl) {
104
104
  url = this.locusParser.workingCopy.syncUrl;
@@ -134,32 +134,56 @@ export default class LocusInfo extends EventsScope {
134
134
 
135
135
  isDelta = false;
136
136
 
137
- return meeting.meetingRequest.getLocusDTO({url: meeting.locusUrl}).catch((err) => {
138
- LoggerProxy.logger.info(
139
- 'Locus-info:index#doLocusSync --> fallback full sync failed, destroying the meeting'
140
- );
141
- this.webex.meetings.destroy(meeting, MEETING_REMOVED_REASON.LOCUS_DTO_SYNC_FAILED);
142
- throw err;
143
- });
137
+ // Locus sometimes returns 403, for example if meeting has ended, no point trying the fallback to full sync in that case
138
+ if (e.statusCode !== 403) {
139
+ return meeting.meetingRequest.getLocusDTO({url: meeting.locusUrl}).catch((err) => {
140
+ LoggerProxy.logger.info(
141
+ 'Locus-info:index#doLocusSync --> fallback full sync failed, destroying the meeting'
142
+ );
143
+ this.webex.meetings.destroy(meeting, MEETING_REMOVED_REASON.LOCUS_DTO_SYNC_FAILED);
144
+ meetingDestroyed = true;
145
+ throw err;
146
+ });
147
+ }
148
+ LoggerProxy.logger.info(
149
+ 'Locus-info:index#doLocusSync --> got 403 from Locus, skipping fallback to full sync, destroying the meeting'
150
+ );
151
+ } else {
152
+ LoggerProxy.logger.info(
153
+ 'Locus-info:index#doLocusSync --> fallback full sync failed, destroying the meeting'
154
+ );
144
155
  }
145
- LoggerProxy.logger.info(
146
- 'Locus-info:index#doLocusSync --> fallback full sync failed, destroying the meeting'
147
- );
148
156
  this.webex.meetings.destroy(meeting, MEETING_REMOVED_REASON.LOCUS_DTO_SYNC_FAILED);
157
+ meetingDestroyed = true;
149
158
  throw e;
150
159
  })
151
160
  .then((res) => {
152
- if (isDelta) {
153
- if (!isEmpty(res.body)) {
154
- meeting.locusInfo.handleLocusDelta(res.body, meeting);
155
- } else {
161
+ if (isEmpty(res.body)) {
162
+ if (isDelta) {
156
163
  LoggerProxy.logger.info(
157
164
  'Locus-info:index#doLocusSync --> received empty body from syncUrl, so we already have latest Locus DTO'
158
165
  );
166
+ } else {
167
+ LoggerProxy.logger.info(
168
+ 'Locus-info:index#doLocusSync --> received empty body from full DTO sync request'
169
+ );
159
170
  }
160
- } else {
161
- meeting.locusInfo.onFullLocus(res.body);
171
+
172
+ return;
173
+ }
174
+
175
+ if (isDelta) {
176
+ if (res.body.baseSequence) {
177
+ meeting.locusInfo.handleLocusDelta(res.body, meeting);
178
+
179
+ return;
180
+ }
181
+ // in some cases Locus might return us full DTO even when we asked for a delta
182
+ LoggerProxy.logger.info(
183
+ 'Locus-info:index#doLocusSync --> got full DTO when we asked for delta'
184
+ );
162
185
  }
186
+ meeting.locusInfo.onFullLocus(res.body);
163
187
  })
164
188
  .catch((e) => {
165
189
  LoggerProxy.logger.info(
@@ -176,9 +200,11 @@ export default class LocusInfo extends EventsScope {
176
200
  });
177
201
  })
178
202
  .finally(() => {
179
- // Notify parser to resume processing delta events.
180
- // Any deltas in the queue that have now been superseded by this sync will simply be ignored
181
- this.locusParser.resume();
203
+ if (!meetingDestroyed) {
204
+ // Notify parser to resume processing delta events.
205
+ // Any deltas in the queue that have now been superseded by this sync will simply be ignored
206
+ this.locusParser.resume();
207
+ }
182
208
  });
183
209
  }
184
210
 
@@ -257,17 +283,6 @@ export default class LocusInfo extends EventsScope {
257
283
  * @property {Object} person - Contains person data.
258
284
  */
259
285
 
260
- /**
261
- * Stored participant changes between the last event and the current event.
262
- * All previously stored events are overwritten between events.
263
- *
264
- * @instance
265
- * @type {Array<DeltaParticipant>}
266
- * @private
267
- * @member LocusInfo
268
- */
269
- this.deltaParticipants = [];
270
-
271
286
  this.updateLocusCache(locus);
272
287
  // above section only updates the locusInfo object
273
288
  // The below section makes sure it updates the locusInfo as well as updates the meeting object
@@ -373,7 +388,6 @@ export default class LocusInfo extends EventsScope {
373
388
  return;
374
389
  }
375
390
 
376
- this.updateParticipantDeltas(locus.participants);
377
391
  this.scheduledMeeting = locus.meeting || null;
378
392
  this.participants = locus.participants;
379
393
  const isReplaceMembers = ControlsUtils.isNeedReplaceMembers(this.controls, locus.controls);
@@ -462,12 +476,12 @@ export default class LocusInfo extends EventsScope {
462
476
  this.updateCreated(locus.created);
463
477
  this.updateFullState(locus.fullState);
464
478
  this.updateHostInfo(locus.host);
479
+ this.updateLocusUrl(locus.url);
465
480
  this.updateMeetingInfo(locus.info, locus.self);
466
481
  this.updateMediaShares(locus.mediaShares);
467
482
  this.updateParticipantsUrl(locus.participantsUrl);
468
483
  this.updateReplace(locus.replace);
469
484
  this.updateSelf(locus.self);
470
- this.updateLocusUrl(locus.url);
471
485
  this.updateAclUrl(locus.aclUrl);
472
486
  this.updateBasequence(locus.baseSequence);
473
487
  this.updateSequence(locus.sequence);
@@ -728,55 +742,6 @@ export default class LocusInfo extends EventsScope {
728
742
  }
729
743
  }
730
744
 
731
- /**
732
- * Update the deltaParticipants property of this object based on a list of
733
- * provided participants.
734
- *
735
- * @param {Array} [participants] - The participants to update against.
736
- * @returns {void}
737
- */
738
- updateParticipantDeltas(participants: Array<any> = []) {
739
- // Used to find a participant within a participants collection.
740
- const findParticipant = (participant, collection) =>
741
- collection.find((item) => item.person.id === participant.person.id);
742
-
743
- // Generates an object that indicates which state properties have changed.
744
- const generateDelta = (prevState: any = {}, newState: any = {}) => {
745
- // Setup deltas.
746
- const deltas = {
747
- audioStatus: prevState.audioStatus !== newState.audioStatus,
748
- videoSlidesStatus: prevState.videoSlidesStatus !== newState.videoSlidesStatus,
749
- videoStatus: prevState.videoStatus !== newState.videoStatus,
750
- };
751
-
752
- // Clean the object
753
- Object.keys(deltas).forEach((key) => {
754
- if (deltas[key] !== true) {
755
- delete deltas[key];
756
- }
757
- });
758
-
759
- return deltas;
760
- };
761
-
762
- this.deltaParticipants = participants.reduce((collection, participant) => {
763
- const existingParticipant = findParticipant(participant, this.participants || []) || {};
764
-
765
- const delta = generateDelta(existingParticipant.status, participant.status);
766
-
767
- const changed = Object.keys(delta).length > 0;
768
-
769
- if (changed) {
770
- collection.push({
771
- person: participant.person,
772
- delta,
773
- });
774
- }
775
-
776
- return collection;
777
- }, []);
778
- }
779
-
780
745
  /**
781
746
  * update meeting's members
782
747
  * @param {Object} participants new participants object
@@ -239,8 +239,8 @@ Media.createMediaConnection = (
239
239
  screenShareAudio: shareAudioStream?.outputStream?.getTracks()[0], // TODO: add type for screenShareAudio in internal-media-core SPARK-446923
240
240
  } as unknown,
241
241
  direction: {
242
- audio: Media.getDirection(true, mediaDirection.receiveAudio, mediaDirection.sendAudio),
243
- video: Media.getDirection(true, mediaDirection.receiveVideo, mediaDirection.sendVideo),
242
+ audio: Media.getDirection(false, mediaDirection.receiveAudio, mediaDirection.sendAudio),
243
+ video: Media.getDirection(false, mediaDirection.receiveVideo, mediaDirection.sendVideo),
244
244
  screenShareVideo: Media.getDirection(
245
245
  false,
246
246
  mediaDirection.receiveShare,
@@ -58,7 +58,13 @@ export class BrbState {
58
58
  public enable(enabled: boolean, sendSlotManager: SendSlotManager) {
59
59
  this.state.client.enabled = enabled;
60
60
 
61
- return this.applyClientStateToServer(sendSlotManager);
61
+ // Don't set the source state override if enabling brb fails
62
+ return this.applyClientStateToServer(sendSlotManager).then(() => {
63
+ sendSlotManager.setSourceStateOverride(
64
+ MediaType.VideoMain,
65
+ this.state.client.enabled ? 'away' : null
66
+ );
67
+ });
62
68
  }
63
69
 
64
70
  /**
@@ -92,7 +98,7 @@ export class BrbState {
92
98
 
93
99
  this.state.syncToServerInProgress = true;
94
100
 
95
- return this.sendLocalBrbStateToServer(sendSlotManager)
101
+ return this.sendLocalBrbStateToServer()
96
102
  .then(() => {
97
103
  this.state.syncToServerInProgress = false;
98
104
 
@@ -120,10 +126,9 @@ export class BrbState {
120
126
  /**
121
127
  * Send the local brb state to the server
122
128
  *
123
- * @param {SendSlotManager} sendSlotManager
124
129
  * @returns {Promise}
125
130
  */
126
- private async sendLocalBrbStateToServer(sendSlotManager: SendSlotManager) {
131
+ private async sendLocalBrbStateToServer() {
127
132
  const {enabled} = this.state.client;
128
133
 
129
134
  if (!this.meeting.isMultistream) {
@@ -153,9 +158,6 @@ export class BrbState {
153
158
  deviceUrl: this.meeting.deviceUrl,
154
159
  selfId: this.meeting.selfId,
155
160
  })
156
- .then(() => {
157
- sendSlotManager.setSourceStateOverride(MediaType.VideoMain, enabled ? 'away' : null);
158
- })
159
161
  .catch((error) => {
160
162
  LoggerProxy.logger.error('Meeting:brbState#sendLocalBrbStateToServer: Error ', error);
161
163
 
@@ -38,6 +38,10 @@ interface IInMeetingActions {
38
38
  isClosedCaptionActive?: boolean;
39
39
  canStartManualCaption?: boolean;
40
40
  canStopManualCaption?: boolean;
41
+ isLocalRecordingStarted?: boolean;
42
+ isLocalRecordingStopped?: boolean;
43
+ isLocalRecordingPaused?: boolean;
44
+
41
45
  isManualCaptionActive?: boolean;
42
46
  isSaveTranscriptsEnabled?: boolean;
43
47
  isWebexAssistantActive?: boolean;
@@ -173,6 +177,12 @@ export default class InMeetingActions implements IInMeetingActions {
173
177
 
174
178
  canStopManualCaption = null;
175
179
 
180
+ isLocalRecordingStopped = null;
181
+
182
+ isLocalRecordingStarted = null;
183
+
184
+ isLocalRecordingPaused = null;
185
+
176
186
  isManualCaptionActive = null;
177
187
 
178
188
  isSaveTranscriptsEnabled = null;
@@ -347,6 +357,9 @@ export default class InMeetingActions implements IInMeetingActions {
347
357
  canStopTranscribing: this.canStopTranscribing,
348
358
  isClosedCaptionActive: this.isClosedCaptionActive,
349
359
  canStartManualCaption: this.canStartManualCaption,
360
+ isLocalRecordingStarted: this.isLocalRecordingStarted,
361
+ isLocalRecordingStopped: this.isLocalRecordingStopped,
362
+ isLocalRecordingPaused: this.isLocalRecordingPaused,
350
363
  canStopManualCaption: this.canStopManualCaption,
351
364
  isManualCaptionActive: this.isManualCaptionActive,
352
365
  isSaveTranscriptsEnabled: this.isSaveTranscriptsEnabled,