@webex/plugin-meetings 3.12.0-next.17 → 3.12.0-next.19

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.
@@ -178,7 +178,7 @@ var AIEnableRequest = _webexCore.WebexPlugin.extend({
178
178
  method: _constants.HTTP_VERBS.PUT
179
179
  });
180
180
  },
181
- version: "3.12.0-next.17"
181
+ version: "3.12.0-next.19"
182
182
  });
183
183
  var _default = exports.default = AIEnableRequest;
184
184
  //# sourceMappingURL=index.js.map
@@ -209,7 +209,7 @@ var Breakout = _webexCore.WebexPlugin.extend({
209
209
  sessionId: this.sessionId
210
210
  });
211
211
  },
212
- version: "3.12.0-next.17"
212
+ version: "3.12.0-next.19"
213
213
  });
214
214
  var _default = exports.default = Breakout;
215
215
  //# sourceMappingURL=breakout.js.map
@@ -1109,7 +1109,7 @@ var Breakouts = _webexCore.WebexPlugin.extend({
1109
1109
  this.trigger(_constants.BREAKOUTS.EVENTS.ASK_RETURN_TO_MAIN);
1110
1110
  }
1111
1111
  },
1112
- version: "3.12.0-next.17"
1112
+ version: "3.12.0-next.19"
1113
1113
  });
1114
1114
  var _default = exports.default = Breakouts;
1115
1115
  //# sourceMappingURL=index.js.map
@@ -372,7 +372,7 @@ var SimultaneousInterpretation = _webexCore.WebexPlugin.extend({
372
372
  throw error;
373
373
  });
374
374
  },
375
- version: "3.12.0-next.17"
375
+ version: "3.12.0-next.19"
376
376
  });
377
377
  var _default = exports.default = SimultaneousInterpretation;
378
378
  //# sourceMappingURL=index.js.map
@@ -18,7 +18,7 @@ var SILanguage = _webexCore.WebexPlugin.extend({
18
18
  languageCode: 'number',
19
19
  languageName: 'string'
20
20
  },
21
- version: "3.12.0-next.17"
21
+ version: "3.12.0-next.19"
22
22
  });
23
23
  var _default = exports.default = SILanguage;
24
24
  //# sourceMappingURL=siLanguage.js.map
@@ -723,7 +723,7 @@ var Webinar = _webexCore.WebexPlugin.extend({
723
723
  }, _callee1);
724
724
  }))();
725
725
  },
726
- version: "3.12.0-next.17"
726
+ version: "3.12.0-next.19"
727
727
  });
728
728
  var _default = exports.default = Webinar;
729
729
  //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -44,7 +44,7 @@
44
44
  "@webex/event-dictionary-ts": "^1.0.2073",
45
45
  "@webex/jest-config-legacy": "0.0.0",
46
46
  "@webex/legacy-tools": "0.0.0",
47
- "@webex/plugin-rooms": "3.12.0-next.7",
47
+ "@webex/plugin-rooms": "3.12.0-next.8",
48
48
  "@webex/test-helper-chai": "3.11.0-next.1",
49
49
  "@webex/test-helper-mocha": "3.11.0-next.1",
50
50
  "@webex/test-helper-mock-webex": "3.11.0-next.1",
@@ -63,20 +63,20 @@
63
63
  "dependencies": {
64
64
  "@webex/common": "3.11.0-next.1",
65
65
  "@webex/internal-media-core": "2.23.3",
66
- "@webex/internal-plugin-conversation": "3.12.0-next.7",
67
- "@webex/internal-plugin-device": "3.12.0-next.6",
68
- "@webex/internal-plugin-llm": "3.12.0-next.8",
69
- "@webex/internal-plugin-mercury": "3.12.0-next.7",
70
- "@webex/internal-plugin-metrics": "3.12.0-next.6",
71
- "@webex/internal-plugin-support": "3.12.0-next.7",
72
- "@webex/internal-plugin-user": "3.12.0-next.6",
73
- "@webex/internal-plugin-voicea": "3.12.0-next.8",
66
+ "@webex/internal-plugin-conversation": "3.12.0-next.8",
67
+ "@webex/internal-plugin-device": "3.12.0-next.7",
68
+ "@webex/internal-plugin-llm": "3.12.0-next.9",
69
+ "@webex/internal-plugin-mercury": "3.12.0-next.8",
70
+ "@webex/internal-plugin-metrics": "3.12.0-next.7",
71
+ "@webex/internal-plugin-support": "3.12.0-next.8",
72
+ "@webex/internal-plugin-user": "3.12.0-next.7",
73
+ "@webex/internal-plugin-voicea": "3.12.0-next.9",
74
74
  "@webex/media-helpers": "3.12.0-next.1",
75
- "@webex/plugin-people": "3.12.0-next.7",
76
- "@webex/plugin-rooms": "3.12.0-next.7",
75
+ "@webex/plugin-people": "3.12.0-next.8",
76
+ "@webex/plugin-rooms": "3.12.0-next.8",
77
77
  "@webex/ts-sdp": "^1.8.1",
78
78
  "@webex/web-capabilities": "^1.10.0",
79
- "@webex/webex-core": "3.12.0-next.6",
79
+ "@webex/webex-core": "3.12.0-next.7",
80
80
  "ampersand-collection": "^2.0.2",
81
81
  "bowser": "^2.11.0",
82
82
  "btoa": "^1.2.1",
@@ -94,5 +94,5 @@
94
94
  "//": [
95
95
  "TODO: upgrade jwt-decode when moving to node 18"
96
96
  ],
97
- "version": "3.12.0-next.17"
97
+ "version": "3.12.0-next.19"
98
98
  }
@@ -7,6 +7,7 @@ import {expect} from '@webex/test-helper-chai';
7
7
  import sinon from 'sinon';
8
8
  import {assert} from '@webex/test-helper-chai';
9
9
  import {EMPTY_HASH} from '@webex/plugin-meetings/src/hashTree/constants';
10
+ import { some } from 'lodash';
10
11
 
11
12
  const visibleDataSetsUrl = 'https://locus-a.wbx2.com/locus/api/v1/loci/97d64a5f/visibleDataSets';
12
13
 
@@ -2517,6 +2518,151 @@ describe('HashTreeParser', () => {
2517
2518
  // Verify callback was NOT called (no updates for non-visible datasets)
2518
2519
  assert.notCalled(callback);
2519
2520
  });
2521
+
2522
+ it('reports update for object that moves from removed visible dataset to new visible dataset even if version is unchanged', async () => {
2523
+ // The purpose of this test is to verify that when an object
2524
+ // moves from one visible dataset to another without version change,
2525
+ // the parser still reports it as an update.
2526
+ // Locus has some additional signalling for this - the "view" property in htMeta.elementId.
2527
+ // When a view changes, the contents of the object may change even if version doesn't.
2528
+ // HashTreeParser doesn't use the "view" property, because it doesn't need to -
2529
+ // the same functionality is achieved thanks to the fact that a new visible data set means
2530
+ // a new hash tree is created, so HashTreeParser still detects the change as new
2531
+ // object is added to the new hash tree.
2532
+
2533
+ // Setup: parser with visible datasets "self" and "unjoined"
2534
+ const unjoinedDataSet = createDataSet('unjoined', 4, 3000);
2535
+ const selfDataSet = createDataSet('self', 1, 2000);
2536
+
2537
+ // start with Locus that has "info" in both "unjoined" and "main" datasets,
2538
+ // but only "unjoined" is visible.
2539
+ const initialLocus = {
2540
+ dataSets: [selfDataSet, unjoinedDataSet],
2541
+ locus: {
2542
+ url: 'https://locus-a.wbx2.com/locus/api/v1/loci/97d64a5f',
2543
+ links: {resources: {visibleDataSets: {url: visibleDataSetsUrl}}},
2544
+ // info object in "unjoined" dataset with version 500
2545
+ info: {
2546
+ htMeta: {
2547
+ elementId: {
2548
+ type: 'info',
2549
+ id: 42,
2550
+ version: 500,
2551
+ view: ['unjoined'], // not used by our code, but here for completeness - that's what real Locus would send
2552
+ },
2553
+ dataSetNames: ['main', 'unjoined'],
2554
+ },
2555
+ someField: 'some-initial-value',
2556
+ },
2557
+ self: {
2558
+ htMeta: {
2559
+ elementId: {
2560
+ type: 'self',
2561
+ id: 4,
2562
+ version: 100,
2563
+ },
2564
+ dataSetNames: ['self'],
2565
+ },
2566
+ },
2567
+ },
2568
+ };
2569
+
2570
+ const metadata = {
2571
+ htMeta: {
2572
+ elementId: {
2573
+ type: 'metadata',
2574
+ id: 5,
2575
+ version: 50,
2576
+ },
2577
+ dataSetNames: ['self'],
2578
+ },
2579
+ visibleDataSets: [
2580
+ {name: 'self', url: selfDataSet.url},
2581
+ {name: 'unjoined', url: unjoinedDataSet.url},
2582
+ ],
2583
+ };
2584
+
2585
+ const parser = createHashTreeParser(initialLocus, metadata);
2586
+
2587
+ // Verify initial state: unjoined is visible and has the info object
2588
+ expect(parser.visibleDataSets.some((vds) => vds.name === 'unjoined')).to.be.true;
2589
+ assert.exists(parser.dataSets.unjoined.hashTree);
2590
+ assert.equal(parser.dataSets.unjoined.hashTree?.getItemVersion(42, 'info'), 500);
2591
+
2592
+ // Stub updateItems on self hash tree to return true for metadata update
2593
+ sinon.stub(parser.dataSets.self.hashTree, 'updateItems').returns([true]);
2594
+
2595
+ // Now send a message that:
2596
+ // 1. Changes visible datasets: removes "unjoined", adds "main"
2597
+ // 2. Contains the same info object (same id=42, same version=500) but we see the view from "main" dataset
2598
+ const mainDataSet = createDataSet('main', 16, 1000);
2599
+
2600
+ const message = {
2601
+ dataSets: [selfDataSet, mainDataSet],
2602
+ visibleDataSetsUrl,
2603
+ locusUrl,
2604
+ locusStateElements: [
2605
+ {
2606
+ htMeta: {
2607
+ elementId: {
2608
+ type: 'metadata' as const,
2609
+ id: 5,
2610
+ version: 51,
2611
+ },
2612
+ dataSetNames: ['self'],
2613
+ },
2614
+ data: {
2615
+ visibleDataSets: [
2616
+ {name: 'self', url: selfDataSet.url},
2617
+ {name: 'main', url: mainDataSet.url},
2618
+ // "unjoined" is no longer here
2619
+ ],
2620
+ },
2621
+ },
2622
+ {
2623
+ htMeta: {
2624
+ elementId: {
2625
+ type: 'info' as const,
2626
+ id: 42,
2627
+ version: 500, // same version as before
2628
+ view: ['main'], // now points to "main" instead of "unjoined"
2629
+ },
2630
+ dataSetNames: ['main', 'unjoined'], // still in both datasets, but only "main" is visible now
2631
+ },
2632
+ data: {someNewField: 'some-value'},
2633
+ },
2634
+ ],
2635
+ };
2636
+
2637
+ parser.handleMessage(message, 'visible dataset swap with same-version object');
2638
+
2639
+ // Verify "unjoined" is no longer visible and "main" is now visible
2640
+ expect(parser.visibleDataSets.some((vds) => vds.name === 'unjoined')).to.be.false;
2641
+ expect(parser.visibleDataSets.some((vds) => vds.name === 'main')).to.be.true;
2642
+
2643
+ // Verify the info object is now in the "main" hash tree
2644
+ assert.exists(parser.dataSets.main.hashTree);
2645
+ assert.equal(parser.dataSets.main.hashTree?.getItemVersion(42, 'info'), 500);
2646
+
2647
+ // The key assertion: callback should be called with the info object update even though
2648
+ // its version hasn't changed - because visible datasets changed (moved from unjoined to main)
2649
+ assert.calledOnce(callback);
2650
+ const callbackArgs = callback.firstCall.args[0];
2651
+ assert.equal(callbackArgs.updateType, LocusInfoUpdateType.OBJECTS_UPDATED);
2652
+
2653
+ // Should contain the info object update (with data)
2654
+ const infoUpdate = callbackArgs.updatedObjects.find(
2655
+ (obj) => obj.htMeta.elementId.type === 'info' && obj.htMeta.elementId.id === 42
2656
+ );
2657
+ assert.exists(infoUpdate);
2658
+ assert.deepEqual(infoUpdate.htMeta.elementId, {
2659
+ type: 'info',
2660
+ id: 42,
2661
+ version: 500,
2662
+ view: ['main'],
2663
+ });
2664
+ assert.deepEqual(infoUpdate.data, {someNewField: 'some-value'});
2665
+ });
2520
2666
  });
2521
2667
 
2522
2668
  describe('heartbeat watchdog', () => {