@webex/plugin-meetings 3.11.0-next.27 → 3.11.0-next.29
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.
- package/dist/breakouts/breakout.js +1 -1
- package/dist/breakouts/index.js +1 -1
- package/dist/config.js +5 -1
- package/dist/config.js.map +1 -1
- package/dist/hashTree/hashTreeParser.js +143 -87
- package/dist/hashTree/hashTreeParser.js.map +1 -1
- package/dist/interpretation/index.js +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/locus-info/index.js +3 -1
- package/dist/locus-info/index.js.map +1 -1
- package/dist/meeting/index.js +2 -2
- package/dist/meeting/index.js.map +1 -1
- package/dist/types/config.d.ts +3 -0
- package/dist/types/hashTree/hashTreeParser.d.ts +14 -0
- package/dist/webinar/index.js +1 -1
- package/package.json +1 -1
- package/src/config.ts +3 -0
- package/src/hashTree/hashTreeParser.ts +54 -8
- package/src/locus-info/index.ts +1 -0
- package/src/meeting/index.ts +4 -8
- package/test/unit/spec/hashTree/hashTreeParser.ts +63 -1
- package/test/unit/spec/meeting/index.js +4 -1
package/dist/types/config.d.ts
CHANGED
|
@@ -59,6 +59,7 @@ declare class HashTreeParser {
|
|
|
59
59
|
visibleDataSets: VisibleDataSetInfo[];
|
|
60
60
|
debugId: string;
|
|
61
61
|
heartbeatIntervalMs?: number;
|
|
62
|
+
private excludedDataSets;
|
|
62
63
|
/**
|
|
63
64
|
* Constructor for HashTreeParser
|
|
64
65
|
* @param {Object} options
|
|
@@ -73,6 +74,7 @@ declare class HashTreeParser {
|
|
|
73
74
|
webexRequest: WebexRequestMethod;
|
|
74
75
|
locusInfoUpdateCallback: LocusInfoUpdateCallback;
|
|
75
76
|
debugId: string;
|
|
77
|
+
excludedDataSets?: string[];
|
|
76
78
|
});
|
|
77
79
|
/**
|
|
78
80
|
* Checks if the given data set name is in the list of visible data sets
|
|
@@ -80,6 +82,18 @@ declare class HashTreeParser {
|
|
|
80
82
|
* @returns {Boolean} True if the data set is visible, false otherwise
|
|
81
83
|
*/
|
|
82
84
|
private isVisibleDataSet;
|
|
85
|
+
/**
|
|
86
|
+
* Checks if the given data set name is in the excluded list
|
|
87
|
+
* @param {string} dataSetName data set name to check
|
|
88
|
+
* @returns {boolean} True if the data set is excluded, false otherwise
|
|
89
|
+
*/
|
|
90
|
+
private isExcludedDataSet;
|
|
91
|
+
/**
|
|
92
|
+
* Adds a data set to the visible data sets list, unless it is in the excluded list.
|
|
93
|
+
* @param {VisibleDataSetInfo} dataSetInfo data set info to add
|
|
94
|
+
* @returns {boolean} True if the data set was added, false if it was excluded
|
|
95
|
+
*/
|
|
96
|
+
private addToVisibleDataSetsList;
|
|
83
97
|
/**
|
|
84
98
|
* Initializes a new visible data set by creating a hash tree for it, adding it to all the internal structures,
|
|
85
99
|
* and sending an initial sync request to Locus with empty leaf data - that will trigger Locus to gives us all the data
|
package/dist/webinar/index.js
CHANGED
package/package.json
CHANGED
package/src/config.ts
CHANGED
|
@@ -101,5 +101,8 @@ export default {
|
|
|
101
101
|
stopIceGatheringAfterFirstRelayCandidate: false,
|
|
102
102
|
enableAudioTwccForMultistream: false,
|
|
103
103
|
enablePerUdpUrlReachability: false, // true: separate peer connection per each UDP URL; false: single peer connection for all URLs
|
|
104
|
+
locus: {
|
|
105
|
+
excludedDataSets: ['attendees'], // attendees data set only applies to webinar attendees and we never really need that
|
|
106
|
+
},
|
|
104
107
|
},
|
|
105
108
|
};
|
|
@@ -91,6 +91,7 @@ class HashTreeParser {
|
|
|
91
91
|
visibleDataSets: VisibleDataSetInfo[];
|
|
92
92
|
debugId: string;
|
|
93
93
|
heartbeatIntervalMs?: number;
|
|
94
|
+
private excludedDataSets: string[];
|
|
94
95
|
|
|
95
96
|
/**
|
|
96
97
|
* Constructor for HashTreeParser
|
|
@@ -106,14 +107,18 @@ class HashTreeParser {
|
|
|
106
107
|
webexRequest: WebexRequestMethod;
|
|
107
108
|
locusInfoUpdateCallback: LocusInfoUpdateCallback;
|
|
108
109
|
debugId: string;
|
|
110
|
+
excludedDataSets?: string[];
|
|
109
111
|
}) {
|
|
110
112
|
const {dataSets, locus} = options.initialLocus; // extract dataSets from initialLocus
|
|
111
113
|
|
|
112
114
|
this.debugId = options.debugId;
|
|
113
115
|
this.webexRequest = options.webexRequest;
|
|
114
116
|
this.locusInfoUpdateCallback = options.locusInfoUpdateCallback;
|
|
117
|
+
this.excludedDataSets = options.excludedDataSets || [];
|
|
115
118
|
this.visibleDataSetsUrl = locus?.links?.resources?.visibleDataSets?.url;
|
|
116
|
-
this.visibleDataSets =
|
|
119
|
+
this.visibleDataSets = (
|
|
120
|
+
cloneDeep(options.metadata?.visibleDataSets || []) as VisibleDataSetInfo[]
|
|
121
|
+
).filter((vds) => !this.isExcludedDataSet(vds.name));
|
|
117
122
|
|
|
118
123
|
if (options.metadata?.visibleDataSets?.length === 0) {
|
|
119
124
|
LoggerProxy.logger.warn(
|
|
@@ -155,6 +160,34 @@ class HashTreeParser {
|
|
|
155
160
|
return this.visibleDataSets.some((vds) => vds.name === dataSetName);
|
|
156
161
|
}
|
|
157
162
|
|
|
163
|
+
/**
|
|
164
|
+
* Checks if the given data set name is in the excluded list
|
|
165
|
+
* @param {string} dataSetName data set name to check
|
|
166
|
+
* @returns {boolean} True if the data set is excluded, false otherwise
|
|
167
|
+
*/
|
|
168
|
+
private isExcludedDataSet(dataSetName: string): boolean {
|
|
169
|
+
return this.excludedDataSets.some((name) => name === dataSetName);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Adds a data set to the visible data sets list, unless it is in the excluded list.
|
|
174
|
+
* @param {VisibleDataSetInfo} dataSetInfo data set info to add
|
|
175
|
+
* @returns {boolean} True if the data set was added, false if it was excluded
|
|
176
|
+
*/
|
|
177
|
+
private addToVisibleDataSetsList(dataSetInfo: VisibleDataSetInfo): boolean {
|
|
178
|
+
if (this.isExcludedDataSet(dataSetInfo.name)) {
|
|
179
|
+
LoggerProxy.logger.info(
|
|
180
|
+
`HashTreeParser#addToVisibleDataSetsList --> ${this.debugId} Data set "${dataSetInfo.name}" is in the excluded list, ignoring`
|
|
181
|
+
);
|
|
182
|
+
|
|
183
|
+
return false;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
this.visibleDataSets.push(dataSetInfo);
|
|
187
|
+
|
|
188
|
+
return true;
|
|
189
|
+
}
|
|
190
|
+
|
|
158
191
|
/**
|
|
159
192
|
* Initializes a new visible data set by creating a hash tree for it, adding it to all the internal structures,
|
|
160
193
|
* and sending an initial sync request to Locus with empty leaf data - that will trigger Locus to gives us all the data
|
|
@@ -180,7 +213,9 @@ class HashTreeParser {
|
|
|
180
213
|
`HashTreeParser#initializeNewVisibleDataSet --> ${this.debugId} Adding visible data set "${dataSetInfo.name}"`
|
|
181
214
|
);
|
|
182
215
|
|
|
183
|
-
this.
|
|
216
|
+
if (!this.addToVisibleDataSetsList(visibleDataSetInfo)) {
|
|
217
|
+
return Promise.resolve({updateType: LocusInfoUpdateType.OBJECTS_UPDATED, updatedObjects: []});
|
|
218
|
+
}
|
|
184
219
|
|
|
185
220
|
const hashTree = new HashTree([], dataSetInfo.leafCount);
|
|
186
221
|
|
|
@@ -328,10 +363,16 @@ class HashTreeParser {
|
|
|
328
363
|
}
|
|
329
364
|
|
|
330
365
|
if (!this.isVisibleDataSet(name)) {
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
366
|
+
if (
|
|
367
|
+
!this.addToVisibleDataSetsList({
|
|
368
|
+
name,
|
|
369
|
+
url,
|
|
370
|
+
})
|
|
371
|
+
) {
|
|
372
|
+
// dataset is excluded, skip it
|
|
373
|
+
// eslint-disable-next-line no-continue
|
|
374
|
+
continue;
|
|
375
|
+
}
|
|
335
376
|
}
|
|
336
377
|
|
|
337
378
|
if (!this.dataSets[name].hashTree) {
|
|
@@ -693,7 +734,9 @@ class HashTreeParser {
|
|
|
693
734
|
// visibleDataSets can only be changed by Metadata object updates
|
|
694
735
|
updatedObjects.forEach((object) => {
|
|
695
736
|
if (isMetadata(object) && object.data?.visibleDataSets) {
|
|
696
|
-
const newVisibleDataSets = object.data.visibleDataSets
|
|
737
|
+
const newVisibleDataSets = object.data.visibleDataSets.filter(
|
|
738
|
+
(vds) => !this.isExcludedDataSet(vds.name)
|
|
739
|
+
);
|
|
697
740
|
|
|
698
741
|
removedDataSets = this.visibleDataSets.filter(
|
|
699
742
|
(ds) => !newVisibleDataSets.some((nvs) => nvs.name === ds.name)
|
|
@@ -805,7 +848,10 @@ class HashTreeParser {
|
|
|
805
848
|
`HashTreeParser#processVisibleDataSetChanges --> ${this.debugId} Adding visible data set "${ds.name}"`
|
|
806
849
|
);
|
|
807
850
|
|
|
808
|
-
this.
|
|
851
|
+
if (!this.addToVisibleDataSetsList(ds)) {
|
|
852
|
+
// eslint-disable-next-line no-continue
|
|
853
|
+
continue;
|
|
854
|
+
}
|
|
809
855
|
|
|
810
856
|
const hashTree = new HashTree([], dataSetInfo.leafCount);
|
|
811
857
|
|
package/src/locus-info/index.ts
CHANGED
|
@@ -379,6 +379,7 @@ export default class LocusInfo extends EventsScope {
|
|
|
379
379
|
webexRequest: this.webex.request.bind(this.webex),
|
|
380
380
|
locusInfoUpdateCallback: this.updateFromHashTree.bind(this),
|
|
381
381
|
debugId: `HT-${this.meetingId.substring(0, 4)}`,
|
|
382
|
+
excludedDataSets: this.webex.config.meetings.locus?.excludedDataSets,
|
|
382
383
|
});
|
|
383
384
|
}
|
|
384
385
|
|
package/src/meeting/index.ts
CHANGED
|
@@ -6214,14 +6214,10 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6214
6214
|
return undefined;
|
|
6215
6215
|
}
|
|
6216
6216
|
// @ts-ignore - Fix type
|
|
6217
|
-
await this.webex.internal.llm.disconnectLLM(
|
|
6218
|
-
|
|
6219
|
-
|
|
6220
|
-
|
|
6221
|
-
reason: 'done (permanent)',
|
|
6222
|
-
}
|
|
6223
|
-
: undefined
|
|
6224
|
-
);
|
|
6217
|
+
await this.webex.internal.llm.disconnectLLM({
|
|
6218
|
+
code: 3050,
|
|
6219
|
+
reason: 'done (permanent)',
|
|
6220
|
+
});
|
|
6225
6221
|
// @ts-ignore - Fix type
|
|
6226
6222
|
this.webex.internal.llm.off('event:relay.event', this.processRelayEvent);
|
|
6227
6223
|
// @ts-ignore - Fix type
|
|
@@ -165,7 +165,8 @@ describe('HashTreeParser', () => {
|
|
|
165
165
|
// Helper to create a HashTreeParser instance with common defaults
|
|
166
166
|
function createHashTreeParser(
|
|
167
167
|
initialLocus: any = exampleInitialLocus,
|
|
168
|
-
metadata: any = exampleMetadata
|
|
168
|
+
metadata: any = exampleMetadata,
|
|
169
|
+
excludedDataSets?: string[]
|
|
169
170
|
) {
|
|
170
171
|
return new HashTreeParser({
|
|
171
172
|
initialLocus,
|
|
@@ -173,6 +174,7 @@ describe('HashTreeParser', () => {
|
|
|
173
174
|
webexRequest,
|
|
174
175
|
locusInfoUpdateCallback: callback,
|
|
175
176
|
debugId: 'test',
|
|
177
|
+
excludedDataSets,
|
|
176
178
|
});
|
|
177
179
|
}
|
|
178
180
|
|
|
@@ -353,6 +355,66 @@ describe('HashTreeParser', () => {
|
|
|
353
355
|
expect(emptySet.hashTree).to.be.undefined;
|
|
354
356
|
});
|
|
355
357
|
|
|
358
|
+
it('should exclude datasets listed in excludedDataSets during initialization', () => {
|
|
359
|
+
const parser = createHashTreeParser(exampleInitialLocus, exampleMetadata, ['atd-unmuted']);
|
|
360
|
+
|
|
361
|
+
// 'atd-unmuted' should be excluded from visibleDataSets
|
|
362
|
+
expect(parser.visibleDataSets.some((vds) => vds.name === 'atd-unmuted')).to.be.false;
|
|
363
|
+
|
|
364
|
+
// 'main' and 'self' should still be visible
|
|
365
|
+
expect(parser.visibleDataSets.some((vds) => vds.name === 'main')).to.be.true;
|
|
366
|
+
expect(parser.visibleDataSets.some((vds) => vds.name === 'self')).to.be.true;
|
|
367
|
+
|
|
368
|
+
// 'atd-unmuted' dataset entry should exist but without a hash tree (because it's not visible)
|
|
369
|
+
expect(parser.dataSets['atd-unmuted']).to.exist;
|
|
370
|
+
expect(parser.dataSets['atd-unmuted'].hashTree).to.be.undefined;
|
|
371
|
+
|
|
372
|
+
// 'main' and 'self' should have hash trees
|
|
373
|
+
expect(parser.dataSets.main.hashTree).to.be.instanceOf(HashTree);
|
|
374
|
+
expect(parser.dataSets.self.hashTree).to.be.instanceOf(HashTree);
|
|
375
|
+
});
|
|
376
|
+
|
|
377
|
+
it('should exclude datasets listed in excludedDataSets when adding new visible datasets', async () => {
|
|
378
|
+
// Create parser without 'atd-unmuted' in initial metadata visibleDataSets
|
|
379
|
+
const metadataWithoutAtdUnmuted = {
|
|
380
|
+
...exampleMetadata,
|
|
381
|
+
visibleDataSets: exampleMetadata.visibleDataSets.filter((vds) => vds.name !== 'atd-unmuted'),
|
|
382
|
+
};
|
|
383
|
+
const parser = createHashTreeParser(exampleInitialLocus, metadataWithoutAtdUnmuted, [
|
|
384
|
+
'atd-unmuted',
|
|
385
|
+
]);
|
|
386
|
+
|
|
387
|
+
// 'atd-unmuted' should not be in visibleDataSets initially
|
|
388
|
+
expect(parser.visibleDataSets.some((vds) => vds.name === 'atd-unmuted')).to.be.false;
|
|
389
|
+
|
|
390
|
+
// Now simulate initializeDataSets which calls addToVisibleDataSetsList
|
|
391
|
+
const atdUnmutedDataSet = createDataSet('atd-unmuted', 16, 3000);
|
|
392
|
+
|
|
393
|
+
mockGetAllDataSetsMetadata(webexRequest, visibleDataSetsUrl, [
|
|
394
|
+
createDataSet('main', 16, 1000),
|
|
395
|
+
createDataSet('self', 1, 2000),
|
|
396
|
+
atdUnmutedDataSet,
|
|
397
|
+
]);
|
|
398
|
+
|
|
399
|
+
mockSyncRequest(
|
|
400
|
+
webexRequest,
|
|
401
|
+
'https://locus-a.wbx2.com/locus/api/v1/loci/97d64a5f/datasets/atd-unmuted'
|
|
402
|
+
);
|
|
403
|
+
|
|
404
|
+
const message = {
|
|
405
|
+
dataSets: [createDataSet('main', 16, 1000)],
|
|
406
|
+
visibleDataSetsUrl,
|
|
407
|
+
locusUrl,
|
|
408
|
+
};
|
|
409
|
+
await parser.initializeFromMessage(message);
|
|
410
|
+
|
|
411
|
+
// 'atd-unmuted' should still not be in visibleDataSets because it is excluded
|
|
412
|
+
expect(parser.visibleDataSets.some((vds) => vds.name === 'atd-unmuted')).to.be.false;
|
|
413
|
+
// but 'main' and 'self' should be there
|
|
414
|
+
expect(parser.visibleDataSets.some((vds) => vds.name === 'main')).to.be.true;
|
|
415
|
+
expect(parser.visibleDataSets.some((vds) => vds.name === 'self')).to.be.true;
|
|
416
|
+
});
|
|
417
|
+
|
|
356
418
|
// helper method, needed because both initializeFromMessage and initializeFromGetLociResponse
|
|
357
419
|
// do almost exactly the same thing
|
|
358
420
|
const testInitializationOfDatasetsAndHashTrees = async (testCallback) => {
|
|
@@ -12744,7 +12744,10 @@ describe('plugin-meetings', () => {
|
|
|
12744
12744
|
|
|
12745
12745
|
const result = await meeting.updateLLMConnection();
|
|
12746
12746
|
|
|
12747
|
-
assert.calledWith(webex.internal.llm.disconnectLLM,
|
|
12747
|
+
assert.calledWith(webex.internal.llm.disconnectLLM, {
|
|
12748
|
+
code: 3050,
|
|
12749
|
+
reason: 'done (permanent)',
|
|
12750
|
+
});
|
|
12748
12751
|
assert.notCalled(webex.internal.llm.registerAndConnect);
|
|
12749
12752
|
assert.equal(result, undefined);
|
|
12750
12753
|
assert.calledWithExactly(
|