@webex/plugin-meetings 3.10.0-webex-services-ready.2 → 3.10.0-webex-services-ready.3

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.
@@ -29,10 +29,7 @@ export default class LocusInfo extends EventsScope {
29
29
  aclUrl: any;
30
30
  baseSequence: any;
31
31
  created: any;
32
- identities: any;
33
- membership: any;
34
32
  participants: any;
35
- participantsUrl: any;
36
33
  replaces: any;
37
34
  scheduledMeeting: any;
38
35
  sequence: any;
@@ -44,7 +41,6 @@ export default class LocusInfo extends EventsScope {
44
41
  info: any;
45
42
  roles: any;
46
43
  mediaShares: any;
47
- replace: any;
48
44
  url: any;
49
45
  links?: Links;
50
46
  mainSessionLocusCache: any;
@@ -320,17 +316,11 @@ export default class LocusInfo extends EventsScope {
320
316
  */
321
317
  updateMediaShares(mediaShares: object, forceUpdate?: boolean): void;
322
318
  /**
323
- * @param {String} participantsUrl
319
+ * @param {Object} replaces
324
320
  * @returns {undefined}
325
321
  * @memberof LocusInfo
326
322
  */
327
- updateParticipantsUrl(participantsUrl: string): void;
328
- /**
329
- * @param {Object} replace
330
- * @returns {undefined}
331
- * @memberof LocusInfo
332
- */
333
- updateReplace(replace: object): void;
323
+ updateReplaces(replaces: object): void;
334
324
  /**
335
325
  * handles when the locus.self is updated
336
326
  * @param {Object} self the new locus.self
@@ -365,18 +355,6 @@ export default class LocusInfo extends EventsScope {
365
355
  * @memberof LocusInfo
366
356
  */
367
357
  updateSequence(sequence: number): void;
368
- /**
369
- * @param {Object} membership
370
- * @returns {undefined}
371
- * @memberof LocusInfo
372
- */
373
- updateMemberShip(membership: object): void;
374
- /**
375
- * @param {Array} identities
376
- * @returns {undefined}
377
- * @memberof LocusInfo
378
- */
379
- updateIdentifiers(identities: Array<any>): void;
380
358
  /**
381
359
  * check the locus is main session's one or not, if is main session's, update main session cache
382
360
  * @param {Object} locus
@@ -448,7 +448,7 @@ var Webinar = _webexCore.WebexPlugin.extend({
448
448
  }, _callee7);
449
449
  }))();
450
450
  },
451
- version: "3.10.0-webex-services-ready.2"
451
+ version: "3.10.0-webex-services-ready.3"
452
452
  });
453
453
  var _default = exports.default = Webinar;
454
454
  //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -43,12 +43,12 @@
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.10.0-webex-services-ready.2",
47
- "@webex/test-helper-chai": "3.10.0-webex-services-ready.1",
48
- "@webex/test-helper-mocha": "3.10.0-webex-services-ready.1",
49
- "@webex/test-helper-mock-webex": "3.10.0-webex-services-ready.1",
50
- "@webex/test-helper-retry": "3.10.0-webex-services-ready.1",
51
- "@webex/test-helper-test-users": "3.10.0-webex-services-ready.1",
46
+ "@webex/plugin-rooms": "3.10.0-webex-services-ready.3",
47
+ "@webex/test-helper-chai": "3.10.0-webex-services-ready.2",
48
+ "@webex/test-helper-mocha": "3.10.0-webex-services-ready.2",
49
+ "@webex/test-helper-mock-webex": "3.10.0-webex-services-ready.2",
50
+ "@webex/test-helper-retry": "3.10.0-webex-services-ready.2",
51
+ "@webex/test-helper-test-users": "3.10.0-webex-services-ready.2",
52
52
  "chai": "^4.3.4",
53
53
  "chai-as-promised": "^7.1.1",
54
54
  "eslint": "^8.24.0",
@@ -60,23 +60,23 @@
60
60
  "typescript": "^4.7.4"
61
61
  },
62
62
  "dependencies": {
63
- "@webex/common": "3.10.0-webex-services-ready.1",
63
+ "@webex/common": "3.10.0-webex-services-ready.2",
64
64
  "@webex/event-dictionary-ts": "^1.0.1930",
65
65
  "@webex/internal-media-core": "2.20.3",
66
- "@webex/internal-plugin-conversation": "3.10.0-webex-services-ready.2",
67
- "@webex/internal-plugin-device": "3.10.0-webex-services-ready.2",
68
- "@webex/internal-plugin-llm": "3.10.0-webex-services-ready.2",
69
- "@webex/internal-plugin-mercury": "3.10.0-webex-services-ready.2",
70
- "@webex/internal-plugin-metrics": "3.10.0-webex-services-ready.2",
71
- "@webex/internal-plugin-support": "3.10.0-webex-services-ready.2",
72
- "@webex/internal-plugin-user": "3.10.0-webex-services-ready.2",
73
- "@webex/internal-plugin-voicea": "3.10.0-webex-services-ready.2",
74
- "@webex/media-helpers": "3.10.0-webex-services-ready.1",
75
- "@webex/plugin-people": "3.10.0-webex-services-ready.2",
76
- "@webex/plugin-rooms": "3.10.0-webex-services-ready.2",
66
+ "@webex/internal-plugin-conversation": "3.10.0-webex-services-ready.3",
67
+ "@webex/internal-plugin-device": "3.10.0-webex-services-ready.3",
68
+ "@webex/internal-plugin-llm": "3.10.0-webex-services-ready.3",
69
+ "@webex/internal-plugin-mercury": "3.10.0-webex-services-ready.3",
70
+ "@webex/internal-plugin-metrics": "3.10.0-webex-services-ready.3",
71
+ "@webex/internal-plugin-support": "3.10.0-webex-services-ready.3",
72
+ "@webex/internal-plugin-user": "3.10.0-webex-services-ready.3",
73
+ "@webex/internal-plugin-voicea": "3.10.0-webex-services-ready.3",
74
+ "@webex/media-helpers": "3.10.0-webex-services-ready.2",
75
+ "@webex/plugin-people": "3.10.0-webex-services-ready.3",
76
+ "@webex/plugin-rooms": "3.10.0-webex-services-ready.3",
77
77
  "@webex/ts-sdp": "^1.8.1",
78
78
  "@webex/web-capabilities": "^1.7.1",
79
- "@webex/webex-core": "3.10.0-webex-services-ready.2",
79
+ "@webex/webex-core": "3.10.0-webex-services-ready.3",
80
80
  "ampersand-collection": "^2.0.2",
81
81
  "bowser": "^2.11.0",
82
82
  "btoa": "^1.2.1",
@@ -93,5 +93,5 @@
93
93
  "//": [
94
94
  "TODO: upgrade jwt-decode when moving to node 18"
95
95
  ],
96
- "version": "3.10.0-webex-services-ready.2"
96
+ "version": "3.10.0-webex-services-ready.3"
97
97
  }
@@ -1,4 +1,4 @@
1
- import {XXH3_128} from 'xxh3-ts';
1
+ import {XXH3_128} from 'xxh3-ts/xxh3';
2
2
  import {EMPTY_HASH} from './constants';
3
3
  import {ObjectType} from './types';
4
4
 
@@ -18,6 +18,7 @@ import {
18
18
  CALL_REMOVED_REASON,
19
19
  RECORDING_STATE,
20
20
  Enum,
21
+ SELF_ROLES,
21
22
  } from '../constants';
22
23
 
23
24
  import InfoUtils from './infoUtils';
@@ -96,10 +97,7 @@ export default class LocusInfo extends EventsScope {
96
97
  aclUrl: any;
97
98
  baseSequence: any;
98
99
  created: any;
99
- identities: any;
100
- membership: any;
101
100
  participants: any;
102
- participantsUrl: any;
103
101
  replaces: any;
104
102
  scheduledMeeting: any;
105
103
  sequence: any;
@@ -111,7 +109,6 @@ export default class LocusInfo extends EventsScope {
111
109
  info: any;
112
110
  roles: any;
113
111
  mediaShares: any;
114
- replace: any;
115
112
  url: any;
116
113
  links?: Links;
117
114
  mainSessionLocusCache: any;
@@ -327,13 +324,10 @@ export default class LocusInfo extends EventsScope {
327
324
  init(locus: any = {}) {
328
325
  this.created = locus.created || null;
329
326
  this.scheduledMeeting = locus.meeting || null;
330
- this.participantsUrl = locus.participantsUrl || null;
331
327
  this.replaces = locus.replaces || null;
332
328
  this.aclUrl = locus.aclUrl || null;
333
329
  this.baseSequence = locus.baseSequence || null;
334
330
  this.sequence = locus.sequence || null;
335
- this.membership = locus.membership || null;
336
- this.identities = locus.identities || null;
337
331
  this.participants = locus.participants || null;
338
332
 
339
333
  /**
@@ -512,6 +506,14 @@ export default class LocusInfo extends EventsScope {
512
506
  updateLocusFromHashTreeObject(object: HashTreeObject, locus: LocusDTO): LocusDTO {
513
507
  const type = object.htMeta.elementId.type.toLowerCase();
514
508
 
509
+ const addParticipantObject = (obj: HashTreeObject) => {
510
+ if (!locus.participants) {
511
+ locus.participants = [];
512
+ }
513
+ locus.participants.push(obj.data);
514
+ this.hashTreeObjectId2ParticipantId.set(obj.htMeta.elementId.id, obj.data.id);
515
+ };
516
+
515
517
  switch (type) {
516
518
  case ObjectType.locus: {
517
519
  if (!object.data) {
@@ -577,13 +579,7 @@ export default class LocusInfo extends EventsScope {
577
579
  } ${object.data ? 'updated' : 'removed'} version=${object.htMeta.elementId.version}`
578
580
  );
579
581
  if (object.data) {
580
- if (!locus.participants) {
581
- locus.participants = [];
582
- }
583
- const participantObject = object.data;
584
- participantObject.htMeta = object.htMeta;
585
- locus.participants.push(participantObject);
586
- this.hashTreeObjectId2ParticipantId.set(object.htMeta.elementId.id, participantObject.id);
582
+ addParticipantObject(object);
587
583
  } else {
588
584
  const participantId = this.hashTreeObjectId2ParticipantId.get(object.htMeta.elementId.id);
589
585
 
@@ -610,6 +606,24 @@ export default class LocusInfo extends EventsScope {
610
606
  );
611
607
  const locusDtoKey = ObjectTypeToLocusKeyMap[type];
612
608
  locus[locusDtoKey] = object.data;
609
+
610
+ /* Hash tree based webinar attendees don't receive a Participant object for themselves from Locus,
611
+ but a lot of existing code in SDK and web app expects a member object for self to exist,
612
+ so whenever SELF changes for a webinar attendee, we copy it into a participant object.
613
+ We can do it, because SELF has always all the same properties as a participant object.
614
+ */
615
+ if (
616
+ type === ObjectType.self &&
617
+ locus.info?.isWebinar &&
618
+ object.data.controls?.role?.roles?.find(
619
+ (r) => r.type === SELF_ROLES.ATTENDEE && r.hasRole
620
+ )
621
+ ) {
622
+ LoggerProxy.logger.info(
623
+ `Locus-info:index#updateLocusFromHashTreeObject --> webinar attendee: creating participant object from self`
624
+ );
625
+ addParticipantObject(object);
626
+ }
613
627
  }
614
628
  break;
615
629
  default:
@@ -1022,14 +1036,11 @@ export default class LocusInfo extends EventsScope {
1022
1036
  this.updateLocusUrl(locus.url, ControlsUtils.isMainSessionDTO(locus));
1023
1037
  this.updateMeetingInfo(locus.info, locus.self);
1024
1038
  this.updateMediaShares(locus.mediaShares);
1025
- this.updateParticipantsUrl(locus.participantsUrl);
1026
- this.updateReplace(locus.replace);
1039
+ this.updateReplaces(locus.replaces);
1027
1040
  this.updateSelf(locus.self);
1028
1041
  this.updateAclUrl(locus.aclUrl);
1029
1042
  this.updateBasequence(locus.baseSequence);
1030
1043
  this.updateSequence(locus.sequence);
1031
- this.updateMemberShip(locus.membership);
1032
- this.updateIdentifiers(locus.identities);
1033
1044
  this.updateEmbeddedApps(locus.embeddedApps);
1034
1045
  this.updateLinks(locus.links);
1035
1046
  this.compareAndUpdate();
@@ -1904,24 +1915,13 @@ export default class LocusInfo extends EventsScope {
1904
1915
  }
1905
1916
 
1906
1917
  /**
1907
- * @param {String} participantsUrl
1908
- * @returns {undefined}
1909
- * @memberof LocusInfo
1910
- */
1911
- updateParticipantsUrl(participantsUrl: string) {
1912
- if (participantsUrl && !isEqual(this.participantsUrl, participantsUrl)) {
1913
- this.participantsUrl = participantsUrl;
1914
- }
1915
- }
1916
-
1917
- /**
1918
- * @param {Object} replace
1918
+ * @param {Object} replaces
1919
1919
  * @returns {undefined}
1920
1920
  * @memberof LocusInfo
1921
1921
  */
1922
- updateReplace(replace: object) {
1923
- if (replace && !isEqual(this.replace, replace)) {
1924
- this.replace = replace;
1922
+ updateReplaces(replaces: object) {
1923
+ if (replaces && !isEqual(this.replaces, replaces)) {
1924
+ this.replaces = replaces;
1925
1925
  }
1926
1926
  }
1927
1927
 
@@ -2258,28 +2258,6 @@ export default class LocusInfo extends EventsScope {
2258
2258
  }
2259
2259
  }
2260
2260
 
2261
- /**
2262
- * @param {Object} membership
2263
- * @returns {undefined}
2264
- * @memberof LocusInfo
2265
- */
2266
- updateMemberShip(membership: object) {
2267
- if (membership && !isEqual(this.membership, membership)) {
2268
- this.membership = membership;
2269
- }
2270
- }
2271
-
2272
- /**
2273
- * @param {Array} identities
2274
- * @returns {undefined}
2275
- * @memberof LocusInfo
2276
- */
2277
- updateIdentifiers(identities: Array<any>) {
2278
- if (identities && !isEqual(this.identities, identities)) {
2279
- this.identities = identities;
2280
- }
2281
- }
2282
-
2283
2261
  /**
2284
2262
  * check the locus is main session's one or not, if is main session's, update main session cache
2285
2263
  * @param {Object} locus
@@ -358,6 +358,76 @@ describe('plugin-meetings', () => {
358
358
  });
359
359
  });
360
360
 
361
+ it('should process locus update correctly when called with updated SELF (webinar non-attendee)', () => {
362
+ const newSelf = {
363
+ id: 'new-self',
364
+ visibleDataSets: ['dataset1', 'dataset2'],
365
+ controls: {
366
+ role: {
367
+ roles: [
368
+ {type: 'PANELIST', hasRole: true},
369
+ {type: 'ATTENDEE', hasRole: false},
370
+ ],
371
+ },
372
+ },
373
+ };
374
+ locusInfo.info.isWebinar = true;
375
+
376
+ // simulate an update from the HashTreeParser (normally this would be triggered by incoming locus messages)
377
+ locusInfoUpdateCallback(OBJECTS_UPDATED, {
378
+ updatedObjects: [{htMeta: {elementId: {type: 'self'}}, data: newSelf}],
379
+ });
380
+
381
+ // check onDeltaLocus() was called with correctly updated locus info
382
+ // without any participant generated
383
+ assert.calledOnceWithExactly(onDeltaLocusStub, {
384
+ ...expectedLocusInfo,
385
+ info: {
386
+ ...expectedLocusInfo.info,
387
+ isWebinar: true,
388
+ },
389
+ self: newSelf,
390
+ });
391
+ });
392
+
393
+ it('should generate a participant when called with updated SELF for webinar attendee', () => {
394
+ const newSelf = {
395
+ id: 'new-self',
396
+ visibleDataSets: ['dataset1', 'dataset2'],
397
+ controls: {
398
+ role: {
399
+ roles: [
400
+ {type: 'something else - should be ignored', hasRole: true},
401
+ {type: 'ATTENDEE', hasRole: true},
402
+ ],
403
+ },
404
+ },
405
+ };
406
+
407
+ locusInfo.info.isWebinar = true;
408
+
409
+ // simulate an update from the HashTreeParser (normally this would be triggered by incoming locus messages)
410
+ locusInfoUpdateCallback(OBJECTS_UPDATED, {
411
+ updatedObjects: [{htMeta: {elementId: {type: 'self'}}, data: newSelf}],
412
+ });
413
+
414
+ // check onDeltaLocus() was called with correctly updated locus info
415
+ // that contains a participant created from self
416
+ assert.calledOnceWithExactly(onDeltaLocusStub, {
417
+ ...expectedLocusInfo,
418
+ info: {
419
+ ...expectedLocusInfo.info,
420
+ isWebinar: true,
421
+ },
422
+ self: newSelf,
423
+ participants: [
424
+ {
425
+ ...newSelf,
426
+ },
427
+ ],
428
+ });
429
+ });
430
+
361
431
  it('should process locus update correctly when called with updated fullState', () => {
362
432
  const newFullState = {
363
433
  id: 'new-fullState',
@@ -2780,8 +2850,7 @@ describe('plugin-meetings', () => {
2780
2850
  callOrder.push("updateMeetingInfo");
2781
2851
  });
2782
2852
  sinon.stub(locusInfo, "updateMediaShares");
2783
- sinon.stub(locusInfo, "updateParticipantsUrl");
2784
- sinon.stub(locusInfo, "updateReplace");
2853
+ sinon.stub(locusInfo, "updateReplaces");
2785
2854
  sinon.stub(locusInfo, "updateSelf");
2786
2855
  sinon.stub(locusInfo, "updateLocusUrl").callsFake(() => {
2787
2856
  callOrder.push("updateLocusUrl");
@@ -2789,8 +2858,6 @@ describe('plugin-meetings', () => {
2789
2858
  sinon.stub(locusInfo, "updateAclUrl");
2790
2859
  sinon.stub(locusInfo, "updateBasequence");
2791
2860
  sinon.stub(locusInfo, "updateSequence");
2792
- sinon.stub(locusInfo, "updateMemberShip");
2793
- sinon.stub(locusInfo, "updateIdentifiers");
2794
2861
  sinon.stub(locusInfo, "updateEmbeddedApps");
2795
2862
  sinon.stub(locusInfo, "updateLinks");
2796
2863
  sinon.stub(locusInfo, "compareAndUpdate");
@@ -2816,15 +2883,12 @@ describe('plugin-meetings', () => {
2816
2883
  locusInfo.updateHostInfo = sinon.stub();
2817
2884
  locusInfo.updateMeetingInfo = sinon.stub();
2818
2885
  locusInfo.updateMediaShares = sinon.stub();
2819
- locusInfo.updateParticipantsUrl = sinon.stub();
2820
- locusInfo.updateReplace = sinon.stub();
2886
+ locusInfo.updateReplaces = sinon.stub();
2821
2887
  locusInfo.updateSelf = sinon.stub();
2822
2888
  locusInfo.updateLocusUrl = sinon.stub();
2823
2889
  locusInfo.updateAclUrl = sinon.stub();
2824
2890
  locusInfo.updateBasequence = sinon.stub();
2825
2891
  locusInfo.updateSequence = sinon.stub();
2826
- locusInfo.updateMemberShip = sinon.stub();
2827
- locusInfo.updateIdentifiers = sinon.stub();
2828
2892
  locusInfo.updateEmbeddedApps = sinon.stub();
2829
2893
  locusInfo.updateLinks = sinon.stub();
2830
2894
  locusInfo.compareAndUpdate = sinon.stub();
@@ -2838,15 +2902,12 @@ describe('plugin-meetings', () => {
2838
2902
  assert.notCalled(locusInfo.updateHostInfo);
2839
2903
  assert.notCalled(locusInfo.updateMeetingInfo);
2840
2904
  assert.notCalled(locusInfo.updateMediaShares);
2841
- assert.notCalled(locusInfo.updateParticipantsUrl);
2842
- assert.notCalled(locusInfo.updateReplace);
2905
+ assert.notCalled(locusInfo.updateReplaces);
2843
2906
  assert.notCalled(locusInfo.updateSelf);
2844
2907
  assert.notCalled(locusInfo.updateLocusUrl);
2845
2908
  assert.notCalled(locusInfo.updateAclUrl);
2846
2909
  assert.notCalled(locusInfo.updateBasequence);
2847
2910
  assert.notCalled(locusInfo.updateSequence);
2848
- assert.notCalled(locusInfo.updateMemberShip);
2849
- assert.notCalled(locusInfo.updateIdentifiers);
2850
2911
  assert.notCalled(locusInfo.updateEmbeddedApps);
2851
2912
  assert.notCalled(locusInfo.updateLinks);
2852
2913
  assert.notCalled(locusInfo.compareAndUpdate);