@webex/plugin-meetings 3.11.0-next.21 → 3.11.0-next.22

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.
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["types.ts"],"sourcesContent":["import {HtMeta} from '../hashTree/types';\n\nexport type LocusFullState = {\n active: boolean;\n count: number;\n lastActive: string;\n locked: boolean;\n sessionId: string;\n seessionIds: string[];\n startTime: number;\n state: string;\n type: string;\n};\n\nexport type Links = {\n services: Record<'breakout' | 'record', {url: string}>; // there exist also other services, but these are the ones we currently use\n resources: Record<'webcastInstance' | 'visibleDataSets', {url: string}>; // there exist also other resources, but these are the ones we currently use\n};\n\nexport type LocusDTO = {\n controls?: any;\n fullState?: LocusFullState;\n host?: {\n id: string;\n incomingCallProtocols: any[];\n isExternal: boolean;\n name: string;\n orgId: string;\n };\n htMeta?: HtMeta;\n info?: any;\n jsSdkMeta?: {\n removedParticipantIds: string[]; // list of ids of participants that are removed in the last update\n };\n links?: Links;\n mediaShares?: any[];\n meetings?: any[];\n participants: any[];\n replaces?: any[];\n self?: any;\n sequence?: {\n dirtyParticipants: number;\n entries: number[];\n rangeEnd: number;\n rangeStart: number;\n sequenceHash: number;\n sessionToken: string;\n since: string;\n totalParticipants: number;\n };\n syncUrl?: string;\n url?: string;\n};\n"],"mappings":"","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["types.ts"],"sourcesContent":["import {HtMeta} from '../hashTree/types';\n\nexport type LocusFullState = {\n active: boolean;\n count: number;\n lastActive: string;\n locked: boolean;\n sessionId: string;\n seessionIds: string[];\n startTime: number;\n state: string;\n type: string;\n};\n\nexport type Links = {\n services: Record<'breakout' | 'record', {url: string}>; // there exist also other services, but these are the ones we currently use\n resources: Record<'webcastInstance' | 'visibleDataSets', {url: string}>; // there exist also other resources, but these are the ones we currently use\n};\n\nexport type LocusDTO = {\n controls?: any;\n embeddedApps?: any[];\n fullState?: LocusFullState;\n host?: {\n id: string;\n incomingCallProtocols: any[];\n isExternal: boolean;\n name: string;\n orgId: string;\n };\n htMeta?: HtMeta;\n info?: any;\n jsSdkMeta?: {\n removedParticipantIds: string[]; // list of ids of participants that are removed in the last update\n };\n links?: Links;\n mediaShares?: any[];\n meetings?: any[];\n participants: any[];\n replaces?: any[];\n self?: any;\n sequence?: {\n dirtyParticipants: number;\n entries: number[];\n rangeEnd: number;\n rangeStart: number;\n sequenceHash: number;\n sessionToken: string;\n since: string;\n totalParticipants: number;\n };\n syncUrl?: string;\n url?: string;\n};\n"],"mappings":"","ignoreList":[]}
@@ -9,6 +9,7 @@ export declare const ObjectType: {
9
9
  readonly links: "links";
10
10
  readonly control: "controlentry";
11
11
  readonly metadata: "metadata";
12
+ readonly embeddedApp: "embeddedapp";
12
13
  };
13
14
  export type ObjectType = Enum<typeof ObjectType>;
14
15
  export declare const ObjectTypeToLocusKeyMap: {
@@ -19,6 +20,7 @@ export declare const ObjectTypeToLocusKeyMap: {
19
20
  participant: string;
20
21
  mediashare: string;
21
22
  controlentry: string;
23
+ embeddedapp: string;
22
24
  };
23
25
  export interface HtMeta {
24
26
  elementId: {
@@ -20,6 +20,7 @@ export type Links = {
20
20
  };
21
21
  export type LocusDTO = {
22
22
  controls?: any;
23
+ embeddedApps?: any[];
23
24
  fullState?: LocusFullState;
24
25
  host?: {
25
26
  id: string;
@@ -506,7 +506,7 @@ var Webinar = _webexCore.WebexPlugin.extend({
506
506
  }, _callee8);
507
507
  }))();
508
508
  },
509
- version: "3.11.0-next.21"
509
+ version: "3.11.0-next.22"
510
510
  });
511
511
  var _default = exports.default = Webinar;
512
512
  //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -93,5 +93,5 @@
93
93
  "//": [
94
94
  "TODO: upgrade jwt-decode when moving to node 18"
95
95
  ],
96
- "version": "3.11.0-next.21"
96
+ "version": "3.11.0-next.22"
97
97
  }
@@ -11,6 +11,7 @@ export const ObjectType = {
11
11
  links: 'links',
12
12
  control: 'controlentry',
13
13
  metadata: 'metadata',
14
+ embeddedApp: 'embeddedapp',
14
15
  } as const;
15
16
 
16
17
  export type ObjectType = Enum<typeof ObjectType>;
@@ -24,7 +25,9 @@ export const ObjectTypeToLocusKeyMap = {
24
25
  [ObjectType.participant]: 'participants', // note: each object is a single participant in participants array
25
26
  [ObjectType.mediaShare]: 'mediaShares', // note: each object is a single mediaShare in mediaShares array
26
27
  [ObjectType.control]: 'controls', // note: each object is a single control entry in controls object
28
+ [ObjectType.embeddedApp]: 'embeddedApps', // note: each object is a single embedded app in embeddedApps array
27
29
  };
30
+
28
31
  export interface HtMeta {
29
32
  elementId: {
30
33
  type: ObjectType;
@@ -53,6 +53,7 @@ export type LocusLLMEvent = {
53
53
  const LocusDtoTopLevelKeys = [
54
54
  'controls',
55
55
  'fullState',
56
+ 'embeddedApps',
56
57
  'host',
57
58
  'info',
58
59
  'links',
@@ -582,6 +583,31 @@ export default class LocusInfo extends EventsScope {
582
583
  );
583
584
  }
584
585
  break;
586
+ case ObjectType.embeddedApp:
587
+ if (object.data) {
588
+ LoggerProxy.logger.info(
589
+ `Locus-info:index#updateLocusFromHashTreeObject --> embeddedApp id=${object.htMeta.elementId.id} url='${object.data.url}' updated version=${object.htMeta.elementId.version}:`,
590
+ object.data
591
+ );
592
+ const existingEmbeddedApp = locus.embeddedApps?.find(
593
+ (ms) => ms.htMeta.elementId.id === object.htMeta.elementId.id
594
+ );
595
+
596
+ if (existingEmbeddedApp) {
597
+ Object.assign(existingEmbeddedApp, object.data);
598
+ } else {
599
+ locus.embeddedApps = locus.embeddedApps || [];
600
+ locus.embeddedApps.push(object.data);
601
+ }
602
+ } else {
603
+ LoggerProxy.logger.info(
604
+ `Locus-info:index#updateLocusFromHashTreeObject --> embeddedApp id=${object.htMeta.elementId.id} removed, version=${object.htMeta.elementId.version}`
605
+ );
606
+ locus.embeddedApps = locus.embeddedApps?.filter(
607
+ (ms) => ms.htMeta.elementId.id !== object.htMeta.elementId.id
608
+ );
609
+ }
610
+ break;
585
611
  case ObjectType.participant:
586
612
  LoggerProxy.logger.info(
587
613
  `Locus-info:index#updateLocusFromHashTreeObject --> participant id=${
@@ -19,6 +19,7 @@ export type Links = {
19
19
 
20
20
  export type LocusDTO = {
21
21
  controls?: any;
22
+ embeddedApps?: any[];
22
23
  fullState?: LocusFullState;
23
24
  host?: {
24
25
  id: string;
@@ -329,6 +329,16 @@ describe('plugin-meetings', () => {
329
329
  htMeta: {elementId: {type: 'mediashare', id: 'fake-ht-mediaShare-2', version: 1}},
330
330
  },
331
331
  ];
332
+ locusInfo.embeddedApps = [
333
+ {
334
+ id: 'fake-embedded-app-1',
335
+ htMeta: {elementId: {type: 'embeddedapp', id: 'fake-ht-embeddedApp-1', version: 1}},
336
+ },
337
+ {
338
+ id: 'fake-embedded-app-2',
339
+ htMeta: {elementId: {type: 'embeddedapp', id: 'fake-ht-embeddedApp-2', version: 1}},
340
+ },
341
+ ];
332
342
  locusInfo.meetings = {id: 'fake-meetings'};
333
343
  locusInfo.participants = [
334
344
  {id: 'fake-participant-1', name: 'Participant One'},
@@ -364,6 +374,16 @@ describe('plugin-meetings', () => {
364
374
  htMeta: {elementId: {type: 'mediashare', id: 'fake-ht-mediaShare-2', version: 1}},
365
375
  },
366
376
  ],
377
+ embeddedApps: [
378
+ {
379
+ id: 'fake-embedded-app-1',
380
+ htMeta: {elementId: {type: 'embeddedapp', id: 'fake-ht-embeddedApp-1', version: 1}},
381
+ },
382
+ {
383
+ id: 'fake-embedded-app-2',
384
+ htMeta: {elementId: {type: 'embeddedapp', id: 'fake-ht-embeddedApp-2', version: 1}},
385
+ },
386
+ ],
367
387
  meetings: {id: 'fake-meetings'},
368
388
  jsSdkMeta: {removedParticipantIds: []},
369
389
  participants: [], // empty means there were no participant updates
@@ -540,6 +560,7 @@ describe('plugin-meetings', () => {
540
560
  self: {id: 'fake-self'},
541
561
  links: {id: 'fake-links'},
542
562
  mediaShares: expectedLocusInfo.mediaShares,
563
+ embeddedApps: expectedLocusInfo.embeddedApps,
543
564
  // and now the new fields
544
565
  ...newLocus,
545
566
  htMeta: newLocusHtMeta,
@@ -572,6 +593,7 @@ describe('plugin-meetings', () => {
572
593
  self: 'new-self',
573
594
  participants: 'new-participants',
574
595
  mediaShares: 'new-mediaShares',
596
+ embeddedApps: 'new-embeddedApps',
575
597
  },
576
598
  },
577
599
  ],
@@ -587,6 +609,7 @@ describe('plugin-meetings', () => {
587
609
  self: {id: 'fake-self'},
588
610
  links: {id: 'fake-links'},
589
611
  mediaShares: expectedLocusInfo.mediaShares,
612
+ embeddedApps: expectedLocusInfo.embeddedApps,
590
613
  participants: [], // empty means there were no participant updates
591
614
  jsSdkMeta: {removedParticipantIds: []}, // no participants were removed
592
615
  ...newLocus,
@@ -622,6 +645,7 @@ describe('plugin-meetings', () => {
622
645
  self: {id: 'fake-self'},
623
646
  links: {id: 'fake-links'},
624
647
  mediaShares: expectedLocusInfo.mediaShares,
648
+ embeddedApps: expectedLocusInfo.embeddedApps,
625
649
  // and now the new fields
626
650
  ...newLocus,
627
651
  htMeta: newLocusHtMeta,
@@ -761,6 +785,39 @@ describe('plugin-meetings', () => {
761
785
  });
762
786
  });
763
787
 
788
+ it('should process locus update correctly when called with updated EMBEDDEDAPP objects', () => {
789
+ const newEmbeddedApp = {
790
+ id: 'new-embedded-app-3',
791
+ htMeta: {elementId: {type: 'embeddedapp', id: 'fake-ht-embeddedApp-3', version: 100}},
792
+ };
793
+ const updatedEmbeddedApp2 = {
794
+ id: 'fake-embedded-app-2',
795
+ someNewProp: 'newValue',
796
+ htMeta: {elementId: {type: 'embeddedapp', id: 'fake-ht-embeddedApp-2', version: 100}},
797
+ };
798
+ // simulate an update from the HashTreeParser (normally this would be triggered by incoming locus messages)
799
+ // with 1 embedded app added, 1 updated, and 1 removed
800
+ locusInfoUpdateCallback(OBJECTS_UPDATED, {
801
+ updatedObjects: [
802
+ {htMeta: {elementId: {type: 'embeddedapp', id: 'fake-ht-embeddedApp-1'}}, data: null},
803
+ {
804
+ htMeta: {elementId: {type: 'embeddedapp', id: 'fake-ht-embeddedApp-2'}},
805
+ data: updatedEmbeddedApp2,
806
+ },
807
+ {
808
+ htMeta: {elementId: {type: 'embeddedapp', id: 'fake-ht-embeddedApp-3'}},
809
+ data: newEmbeddedApp,
810
+ },
811
+ ],
812
+ });
813
+
814
+ // check onDeltaLocus() was called with correctly updated locus info
815
+ assert.calledOnceWithExactly(onDeltaLocusStub, {
816
+ ...expectedLocusInfo,
817
+ embeddedApps: [updatedEmbeddedApp2, newEmbeddedApp],
818
+ });
819
+ });
820
+
764
821
  it('should process locus update correctly when called with a combination of various updated objects', () => {
765
822
  const newSelf = {
766
823
  id: 'new-self',
@@ -2958,28 +3015,28 @@ describe('plugin-meetings', () => {
2958
3015
  assert.isFunction(locusParser.onDeltaAction);
2959
3016
  });
2960
3017
 
2961
- it("#updateLocusInfo invokes updateLocusUrl before updateMeetingInfo", () => {
3018
+ it('#updateLocusInfo invokes updateLocusUrl before updateMeetingInfo', () => {
2962
3019
  const callOrder = [];
2963
- sinon.stub(locusInfo, "updateControls");
2964
- sinon.stub(locusInfo, "updateConversationUrl");
2965
- sinon.stub(locusInfo, "updateCreated");
2966
- sinon.stub(locusInfo, "updateFullState");
2967
- sinon.stub(locusInfo, "updateHostInfo");
2968
- sinon.stub(locusInfo, "updateMeetingInfo").callsFake(() => {
2969
- callOrder.push("updateMeetingInfo");
3020
+ sinon.stub(locusInfo, 'updateControls');
3021
+ sinon.stub(locusInfo, 'updateConversationUrl');
3022
+ sinon.stub(locusInfo, 'updateCreated');
3023
+ sinon.stub(locusInfo, 'updateFullState');
3024
+ sinon.stub(locusInfo, 'updateHostInfo');
3025
+ sinon.stub(locusInfo, 'updateMeetingInfo').callsFake(() => {
3026
+ callOrder.push('updateMeetingInfo');
2970
3027
  });
2971
- sinon.stub(locusInfo, "updateMediaShares");
2972
- sinon.stub(locusInfo, "updateReplaces");
2973
- sinon.stub(locusInfo, "updateSelf");
2974
- sinon.stub(locusInfo, "updateLocusUrl").callsFake(() => {
2975
- callOrder.push("updateLocusUrl");
3028
+ sinon.stub(locusInfo, 'updateMediaShares');
3029
+ sinon.stub(locusInfo, 'updateReplaces');
3030
+ sinon.stub(locusInfo, 'updateSelf');
3031
+ sinon.stub(locusInfo, 'updateLocusUrl').callsFake(() => {
3032
+ callOrder.push('updateLocusUrl');
2976
3033
  });
2977
- sinon.stub(locusInfo, "updateAclUrl");
2978
- sinon.stub(locusInfo, "updateBasequence");
2979
- sinon.stub(locusInfo, "updateSequence");
2980
- sinon.stub(locusInfo, "updateEmbeddedApps");
2981
- sinon.stub(locusInfo, "updateLinks");
2982
- sinon.stub(locusInfo, "compareAndUpdate");
3034
+ sinon.stub(locusInfo, 'updateAclUrl');
3035
+ sinon.stub(locusInfo, 'updateBasequence');
3036
+ sinon.stub(locusInfo, 'updateSequence');
3037
+ sinon.stub(locusInfo, 'updateEmbeddedApps');
3038
+ sinon.stub(locusInfo, 'updateLinks');
3039
+ sinon.stub(locusInfo, 'compareAndUpdate');
2983
3040
 
2984
3041
  locusInfo.updateLocusInfo(locus);
2985
3042
 
@@ -3035,7 +3092,7 @@ describe('plugin-meetings', () => {
3035
3092
  it('#updateLocusInfo puts the Locus DTO top level properties at the right place in LocusInfo class', () => {
3036
3093
  // this test verifies that the top-level properties of Locus DTO are copied
3037
3094
  // into LocusInfo class and set as top level properties too
3038
- // this is important, because the code handling Locus hass trees relies on it, see updateFromHashTree()
3095
+ // this is important, because the code handling Locus hash trees relies on it, see updateFromHashTree()
3039
3096
  const info = {id: 'info id'};
3040
3097
  const fullState = {id: 'fullState id'};
3041
3098
  const links = {services: {id: 'service links'}, resources: {id: 'resource links'}};
@@ -3903,7 +3960,7 @@ describe('plugin-meetings', () => {
3903
3960
 
3904
3961
  describe('#updateLocusUrl', () => {
3905
3962
  it('trigger LOCUS_INFO_UPDATE_URL event with isMainLocus is true as default', () => {
3906
- const fakeUrl = "https://fake.com/locus";
3963
+ const fakeUrl = 'https://fake.com/locus';
3907
3964
  locusInfo.emitScoped = sinon.stub();
3908
3965
  locusInfo.updateLocusUrl(fakeUrl);
3909
3966
 
@@ -3916,12 +3973,12 @@ describe('plugin-meetings', () => {
3916
3973
  EVENTS.LOCUS_INFO_UPDATE_URL,
3917
3974
  {
3918
3975
  url: fakeUrl,
3919
- isMainLocus: true
3920
- },
3976
+ isMainLocus: true,
3977
+ }
3921
3978
  );
3922
3979
  });
3923
3980
  it('trigger LOCUS_INFO_UPDATE_URL event with isMainLocus is false', () => {
3924
- const fakeUrl = "https://fake.com/locus";
3981
+ const fakeUrl = 'https://fake.com/locus';
3925
3982
  locusInfo.emitScoped = sinon.stub();
3926
3983
  locusInfo.updateLocusUrl(fakeUrl, false);
3927
3984
 
@@ -3934,8 +3991,8 @@ describe('plugin-meetings', () => {
3934
3991
  EVENTS.LOCUS_INFO_UPDATE_URL,
3935
3992
  {
3936
3993
  url: fakeUrl,
3937
- isMainLocus: false
3938
- },
3994
+ isMainLocus: false,
3995
+ }
3939
3996
  );
3940
3997
  });
3941
3998
  });
@@ -3987,8 +4044,8 @@ describe('plugin-meetings', () => {
3987
4044
 
3988
4045
  sinon.stub(locusInfo, 'updateParticipants');
3989
4046
  sinon.stub(locusInfo, 'isMeetingActive');
3990
- sinon.stub(locusInfo, 'handleOneOnOneEvent');
3991
- (updateLocusInfoStub = sinon.stub(locusInfo, 'updateLocusInfo'));
4047
+ sinon.stub(locusInfo, 'handleOneOnOneEvent');
4048
+ updateLocusInfoStub = sinon.stub(locusInfo, 'updateLocusInfo');
3992
4049
  syncRequestStub = sinon.stub().resolves({body: {}});
3993
4050
 
3994
4051
  mockMeeting.locusInfo = locusInfo;