@webex/plugin-meetings 3.12.0-next.36 → 3.12.0-next.38
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/aiEnableRequest/index.js +1 -1
- package/dist/breakouts/breakout.js +1 -1
- package/dist/breakouts/index.js +1 -1
- package/dist/constants.js +2 -4
- package/dist/constants.js.map +1 -1
- package/dist/hashTree/hashTreeParser.js +4 -4
- 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 +2 -4
- package/dist/locus-info/index.js.map +1 -1
- package/dist/locus-info/types.js +16 -0
- package/dist/locus-info/types.js.map +1 -1
- package/dist/meetings/util.js +11 -1
- package/dist/meetings/util.js.map +1 -1
- package/dist/types/constants.d.ts +0 -1
- package/dist/types/locus-info/types.d.ts +17 -1
- package/dist/webinar/index.js +1 -1
- package/package.json +1 -1
- package/src/constants.ts +1 -2
- package/src/hashTree/hashTreeParser.ts +5 -6
- package/src/locus-info/index.ts +2 -7
- package/src/locus-info/types.ts +19 -1
- package/src/meetings/util.ts +14 -2
- package/test/unit/spec/hashTree/hashTreeParser.ts +143 -0
- package/test/unit/spec/locus-info/index.js +35 -8
- package/test/unit/spec/meetings/utils.js +13 -0
package/dist/locus-info/types.js
CHANGED
|
@@ -4,4 +4,20 @@ var _Object$defineProperty = require("@babel/runtime-corejs2/core-js/object/defi
|
|
|
4
4
|
_Object$defineProperty(exports, "__esModule", {
|
|
5
5
|
value: true
|
|
6
6
|
});
|
|
7
|
+
exports.EndMeetingReason = void 0;
|
|
8
|
+
var EndMeetingReason = exports.EndMeetingReason = {
|
|
9
|
+
maxMeetingDuration: 'MAX_MEETING_DURATION',
|
|
10
|
+
allParticipantsLeft: 'ALL_PARTICIPANTS_LEFT',
|
|
11
|
+
sipHostLeft: 'SIP_HOST_LEFT',
|
|
12
|
+
noHost: 'NO_HOST',
|
|
13
|
+
waitingForMpsEndMeetingTimeout: 'WAITING_FOR_MPS_END_MEETING_TIMEOUT',
|
|
14
|
+
fraudDetection: 'FRAUD_DETECTION',
|
|
15
|
+
meetingEndedByHost: 'MEETING_ENDED_BY_HOST',
|
|
16
|
+
meetingUpdated: 'MEETING_UPDATED',
|
|
17
|
+
// Locus code has comment about EndMeetingIfPossible reason for this one
|
|
18
|
+
meetingCancelled: 'MEETING_CANCELLED',
|
|
19
|
+
// Locus code has comment about EndMeetingIfPossible reason for this one
|
|
20
|
+
autoEndWithSingleParticipant: 'AUTO_END_WITH_SINGLE_PARTICIPANT',
|
|
21
|
+
breakoutEnded: 'BREAKOUT_ENDED' // indicates that only a breakout session ended, not the whole meeting
|
|
22
|
+
};
|
|
7
23
|
//# sourceMappingURL=types.js.map
|
|
@@ -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
|
|
1
|
+
{"version":3,"names":["EndMeetingReason","exports","maxMeetingDuration","allParticipantsLeft","sipHostLeft","noHost","waitingForMpsEndMeetingTimeout","fraudDetection","meetingEndedByHost","meetingUpdated","meetingCancelled","autoEndWithSingleParticipant","breakoutEnded"],"sources":["types.ts"],"sourcesContent":["import {Enum} from '../constants';\nimport {HtMeta} from '../hashTree/types';\n\nexport const EndMeetingReason = {\n maxMeetingDuration: 'MAX_MEETING_DURATION',\n allParticipantsLeft: 'ALL_PARTICIPANTS_LEFT',\n sipHostLeft: 'SIP_HOST_LEFT',\n noHost: 'NO_HOST',\n waitingForMpsEndMeetingTimeout: 'WAITING_FOR_MPS_END_MEETING_TIMEOUT',\n fraudDetection: 'FRAUD_DETECTION',\n meetingEndedByHost: 'MEETING_ENDED_BY_HOST',\n meetingUpdated: 'MEETING_UPDATED', // Locus code has comment about EndMeetingIfPossible reason for this one\n meetingCancelled: 'MEETING_CANCELLED', // Locus code has comment about EndMeetingIfPossible reason for this one\n autoEndWithSingleParticipant: 'AUTO_END_WITH_SINGLE_PARTICIPANT',\n breakoutEnded: 'BREAKOUT_ENDED', // indicates that only a breakout session ended, not the whole meeting\n} as const;\n\nexport type EndMeetingReason = Enum<typeof EndMeetingReason>;\n\nexport type LocusFullState = {\n active: boolean;\n count: number;\n lastActive: string;\n locked: boolean;\n sessionId: string;\n sessionIds: string[];\n startTime: number;\n state: string;\n type: string;\n endMeetingReason?: EndMeetingReason;\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 forceReplaceMembers?: boolean; // when true, forces a full replacement of meeting members (e.g. when switching to a new hash tree parser - when moving between breakouts)\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\nexport type ReplacesInfo = {\n locusUrl: string;\n replacedAt: string;\n sessionId: string;\n};\n"],"mappings":";;;;;;;AAGO,IAAMA,gBAAgB,GAAAC,OAAA,CAAAD,gBAAA,GAAG;EAC9BE,kBAAkB,EAAE,sBAAsB;EAC1CC,mBAAmB,EAAE,uBAAuB;EAC5CC,WAAW,EAAE,eAAe;EAC5BC,MAAM,EAAE,SAAS;EACjBC,8BAA8B,EAAE,qCAAqC;EACrEC,cAAc,EAAE,iBAAiB;EACjCC,kBAAkB,EAAE,uBAAuB;EAC3CC,cAAc,EAAE,iBAAiB;EAAE;EACnCC,gBAAgB,EAAE,mBAAmB;EAAE;EACvCC,4BAA4B,EAAE,kCAAkC;EAChEC,aAAa,EAAE,gBAAgB,CAAE;AACnC,CAAU","ignoreList":[]}
|
package/dist/meetings/util.js
CHANGED
|
@@ -15,6 +15,7 @@ var _triggerProxy = _interopRequireDefault(require("../common/events/trigger-pro
|
|
|
15
15
|
var _constants2 = _interopRequireDefault(require("../metrics/constants"));
|
|
16
16
|
var _metrics = _interopRequireDefault(require("../metrics"));
|
|
17
17
|
var _meetings = require("./meetings.types");
|
|
18
|
+
var _types = require("../locus-info/types");
|
|
18
19
|
/* globals window */
|
|
19
20
|
|
|
20
21
|
/**
|
|
@@ -274,6 +275,15 @@ MeetingsUtil.getThisDevice = function (newLocus, deviceUrl) {
|
|
|
274
275
|
return null;
|
|
275
276
|
};
|
|
276
277
|
|
|
278
|
+
/**
|
|
279
|
+
* Checks if the fullState indicates the meeting has fully ended (not just a breakout move).
|
|
280
|
+
* @param {Object} fullState locus fullState data
|
|
281
|
+
* @returns {boolean}
|
|
282
|
+
*/
|
|
283
|
+
MeetingsUtil.isWholeMeetingEnded = function (fullState) {
|
|
284
|
+
return fullState.state === _constants.LOCUS.STATE.INACTIVE && fullState.endMeetingReason !== _types.EndMeetingReason.breakoutEnded;
|
|
285
|
+
};
|
|
286
|
+
|
|
277
287
|
/**
|
|
278
288
|
* Checks if the self state in a locus indicates a breakout move or breakout end.
|
|
279
289
|
* Returns true when:
|
|
@@ -285,7 +295,7 @@ MeetingsUtil.getThisDevice = function (newLocus, deviceUrl) {
|
|
|
285
295
|
MeetingsUtil.isSelfMovedOrBreakoutEnded = function (locus) {
|
|
286
296
|
var _locus$self, _locus$self2, _locus$fullState, _locus$fullState2;
|
|
287
297
|
var isSelfLeftMoved = (locus === null || locus === void 0 ? void 0 : (_locus$self = locus.self) === null || _locus$self === void 0 ? void 0 : _locus$self.state) === _constants._LEFT_ && (locus === null || locus === void 0 ? void 0 : (_locus$self2 = locus.self) === null || _locus$self2 === void 0 ? void 0 : _locus$self2.reason) === _constants._MOVED_;
|
|
288
|
-
var isBreakoutEnded = (locus === null || locus === void 0 ? void 0 : (_locus$fullState = locus.fullState) === null || _locus$fullState === void 0 ? void 0 : _locus$fullState.state) === _constants.LOCUS.STATE.INACTIVE && (locus === null || locus === void 0 ? void 0 : (_locus$fullState2 = locus.fullState) === null || _locus$fullState2 === void 0 ? void 0 : _locus$fullState2.endMeetingReason) ===
|
|
298
|
+
var isBreakoutEnded = (locus === null || locus === void 0 ? void 0 : (_locus$fullState = locus.fullState) === null || _locus$fullState === void 0 ? void 0 : _locus$fullState.state) === _constants.LOCUS.STATE.INACTIVE && (locus === null || locus === void 0 ? void 0 : (_locus$fullState2 = locus.fullState) === null || _locus$fullState2 === void 0 ? void 0 : _locus$fullState2.endMeetingReason) === _types.EndMeetingReason.breakoutEnded;
|
|
289
299
|
return isSelfLeftMoved || isBreakoutEnded;
|
|
290
300
|
};
|
|
291
301
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_constants","require","_loggerProxy","_interopRequireDefault","_triggerProxy","_constants2","_metrics","_meetings","MeetingsUtil","getMeetingAddedType","type","DESTINATION_TYPE","LOCUS_ID","_INCOMING_","_CREATED_","handleRoapMercury","envelope","meetingCollection","data","eventType","LOCUSEVENT","MESSAGE_ROAP","meeting","getByKey","MEETING_KEY","CORRELATION_ID","correlationId","_data$message","message","seq","messageType","tieBreaker","errorType","errorCause","Metrics","sendBehavioralMetric","BEHAVIORAL_METRICS","ROAP_MERCURY_EVENT_RECEIVED","correlation_id","message_type","error_type","error_cause","ROAP","ROAP_TYPES","TURN_DISCOVERY_RESPONSE","roap","turnDiscovery","handleTurnDiscoveryResponse","_data$message$sdps","roapMessage","sdp","sdps","length","undefined","roapMessageReceived","getMediaServer","mediaServer","split","find","line","startsWith","shift","replace","toLowerCase","_unused","getMediaServerIp","mediaServerIp","_sdp$split$find$match","match","trim","_unused2","getCorrelationIdForDevice","deviceUrl","locusSelf","devices","foundDevice","device","url","parseDefaultSiteFromMeetingPreferences","userPreferences","_userPreferences$site","result","sites","defaultSite","site","default","siteUrl","hasH264Codec","_asyncToGenerator2","_regenerator","mark","_callee","hasCodec","pc","offer","_t","wrap","_context","prev","next","window","RTCPeerConnection","createOffer","offerToReceiveVideo","sent","close","LoggerProxy","logger","warn","abrupt","stop","checkH264Support","_checkH264Support","_callee2","options","_this","_ref2","firstChecked","disableNotifications","delay","maxDuration","shouldTrigger","shouldStopChecking","_context2","_now","Trigger","trigger","file","function","EVENT_TRIGGERS","MEDIA_CODEC_LOADED","log","error","MEDIA_CODEC_MISSING","setTimeout","timestamp","call","_x","apply","arguments","getThisDevice","newLocus","_newLocus$self","_newLocus$self$device","self","isSelfMovedOrBreakoutEnded","locus","_locus$self","_locus$self2","_locus$fullState","_locus$fullState2","isSelfLeftMoved","state","_LEFT_","reason","_MOVED_","isBreakoutEnded","fullState","LOCUS","STATE","INACTIVE","endMeetingReason","_BREAKOUT_ENDED_","joinedOnThisDevice","thisDevice","_JOINED_","isBreakoutLocusDTO","_newLocus$controls","_newLocus$controls$br","_newLocus$info","controls","breakout","sessionType","BREAKOUTS","SESSION_TYPES","BREAKOUT","info","isBreakout","isValidBreakoutLocus","_locus$fullState3","_locus$self3","inActiveStatus","isLocusAsBreakout","selfJoined","isMainAssociatedWithBreakout","mainLocus","breakoutLocus","_mainLocus$controls","_mainLocus$controls$b","_mainLocus$controls2","_mainLocus$controls2$","_breakoutLocus$contro","_breakoutLocus$contro2","_breakoutLocus$self","_MeetingsUtil$getThis","_MeetingsUtil$getThis2","replaceInfo","replaces","locusUrl","_default","exports"],"sources":["util.ts"],"sourcesContent":["/* globals window */\n\nimport {\n _CREATED_,\n _INCOMING_,\n _JOINED_,\n _LEFT_,\n DESTINATION_TYPE,\n _MOVED_,\n _BREAKOUT_ENDED_,\n BREAKOUTS,\n EVENT_TRIGGERS,\n LOCUS,\n LOCUSEVENT,\n ROAP,\n} from '../constants';\nimport LoggerProxy from '../common/logs/logger-proxy';\nimport Trigger from '../common/events/trigger-proxy';\nimport BEHAVIORAL_METRICS from '../metrics/constants';\nimport Metrics from '../metrics';\nimport {MEETING_KEY} from './meetings.types';\n\n/**\n * Meetings Media Codec Missing Event\n * Emitted when H.264 codec is not\n * found in the browser.\n * @event media:codec:missing\n * @instance\n * @memberof MeetingsUtil\n */\n\n/**\n * Meetings Media Codec Loaded Event\n * Emitted when H.264 codec has been\n * loaded in the browser.\n * @event media:codec:loaded\n * @instance\n * @memberof MeetingsUtil\n */\n\nconst MeetingsUtil: any = {};\n\nMeetingsUtil.getMeetingAddedType = (type: DESTINATION_TYPE) =>\n type === DESTINATION_TYPE.LOCUS_ID ? _INCOMING_ : _CREATED_;\n\nMeetingsUtil.handleRoapMercury = (envelope, meetingCollection) => {\n const {data} = envelope;\n const {eventType} = data;\n\n if (eventType === LOCUSEVENT.MESSAGE_ROAP) {\n const meeting = meetingCollection.getByKey(MEETING_KEY.CORRELATION_ID, data.correlationId);\n\n if (meeting) {\n const {seq, messageType, tieBreaker, errorType, errorCause} = data.message;\n\n Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.ROAP_MERCURY_EVENT_RECEIVED, {\n correlation_id: data.correlationId,\n seq,\n message_type: messageType,\n error_type: errorType,\n error_cause: errorCause,\n });\n\n if (messageType === ROAP.ROAP_TYPES.TURN_DISCOVERY_RESPONSE) {\n // turn discovery is not part of normal roap protocol and so we are not handling it\n // through the usual roap state machine\n meeting.roap.turnDiscovery.handleTurnDiscoveryResponse(data.message, 'from mercury');\n } else {\n const roapMessage = {\n seq,\n messageType,\n sdp: data.message.sdps?.length > 0 ? data.message.sdps[0] : undefined,\n tieBreaker,\n errorType,\n errorCause,\n };\n\n meeting.roapMessageReceived(roapMessage);\n }\n }\n }\n};\n\nMeetingsUtil.getMediaServer = (sdp) => {\n let mediaServer;\n\n // Attempt to collect the media server from the roap message.\n try {\n mediaServer = sdp\n .split('\\r\\n')\n .find((line) => line.startsWith('o='))\n .split(' ')\n .shift()\n .replace('o=', '')\n .toLowerCase();\n } catch {\n mediaServer = undefined;\n }\n\n return mediaServer;\n};\n\nMeetingsUtil.getMediaServerIp = (sdp) => {\n let mediaServerIp;\n\n // Attempt to collect the media server from the roap message.\n try {\n mediaServerIp = sdp\n .split('\\r\\n')\n .find((line) => line.startsWith('o='))\n .match(/o=\\S+ \\d+ \\d+ IN IP4 ([\\d.]+)/)?.[1]\n .toLowerCase()\n .trim();\n } catch {\n mediaServerIp = undefined;\n }\n\n return mediaServerIp;\n};\n\n/**\n * Finds correlationId of a device from locus self devices array\n * that matches the given deviceUrl\n * @param {string} deviceUrl\n * @param {object} locusSelf\n * @returns {string|false} correlationId or false if not found\n */\nMeetingsUtil.getCorrelationIdForDevice = (deviceUrl: string, locusSelf: any) => {\n if (locusSelf?.devices) {\n const foundDevice = locusSelf?.devices.find((device) => device.url === deviceUrl);\n\n if (foundDevice && foundDevice.correlationId) {\n return foundDevice.correlationId;\n }\n }\n\n return false;\n};\n\nMeetingsUtil.parseDefaultSiteFromMeetingPreferences = (userPreferences) => {\n let result = '';\n\n if (userPreferences?.sites?.length) {\n const defaultSite = userPreferences.sites.find((site) => site.default);\n\n if (defaultSite) {\n result = defaultSite.siteUrl;\n } else {\n result = userPreferences.sites[0].siteUrl;\n }\n }\n\n return result;\n};\n\n/**\n * Will check to see if the H.264 media codec is supported.\n * @async\n * @private\n * @returns {Promise<boolean>}\n */\nMeetingsUtil.hasH264Codec = async () => {\n let hasCodec = false;\n\n try {\n const pc = new window.RTCPeerConnection();\n const offer = await pc.createOffer({offerToReceiveVideo: true});\n\n if (offer.sdp.match(/^a=rtpmap:\\d+\\s+H264\\/\\d+/m)) {\n hasCodec = true;\n }\n pc.close();\n } catch (error) {\n LoggerProxy.logger.warn(\n 'Meetings:util#hasH264Codec --> Error creating peerConnection for H.264 test.'\n );\n }\n\n return hasCodec;\n};\n\n/**\n * Notifies the user whether or not the H.264\n * codec is present. Will continuously check\n * until max duration.\n * @async\n * @private\n * @param {object} options\n * @param {Number} options.firstChecked Timestamp in milliseconds\n * @param {boolean} options.disableNotifications Default is false. Boolean to enable/disable notification and events\n * @returns {undefined}\n */\nMeetingsUtil.checkH264Support = async function checkH264Support(options: {\n firstChecked: number;\n disableNotifications: boolean;\n}) {\n const {hasH264Codec} = MeetingsUtil;\n const {firstChecked, disableNotifications} = options || {};\n const delay = 5e3; // ms\n const maxDuration = 3e5; // ms\n const shouldTrigger = firstChecked === undefined;\n const shouldStopChecking = firstChecked && Date.now() - firstChecked >= maxDuration;\n\n // Disable notifications and start H.264 download only\n if (disableNotifications) {\n hasH264Codec();\n\n return;\n }\n\n // Codec loaded trigger event notification\n if (await hasH264Codec()) {\n Trigger.trigger(\n this,\n {\n file: 'meetings/util',\n function: 'checkH264Support',\n },\n EVENT_TRIGGERS.MEDIA_CODEC_LOADED\n );\n LoggerProxy.logger.log('Meetings:util#checkH264Support --> H264 codec loaded successfully.');\n\n return;\n }\n\n // Stop checking if past the timelimit\n if (shouldStopChecking) {\n LoggerProxy.logger.error(\n 'Meetings:util#checkH264Support --> Timed out waiting for H264 codec to load.'\n );\n\n return;\n }\n\n // Trigger only once\n if (shouldTrigger) {\n Trigger.trigger(\n this,\n {\n file: 'meetings/util',\n function: 'checkH264Support',\n },\n EVENT_TRIGGERS.MEDIA_CODEC_MISSING\n );\n LoggerProxy.logger.log('Meetings:util#checkH264Support --> H264 codec is missing.');\n }\n\n // Keep checking in intervals to see if codec loaded\n window.setTimeout(() => {\n const timestamp = firstChecked || Date.now();\n\n MeetingsUtil.checkH264Support.call(this, {firstChecked: timestamp});\n }, delay);\n};\n\n/**\n * get device from locus data\n * @param {Object} newLocus new locus data\n * @param {String} deviceUrl current device url\n * @returns {Object}\n */\nMeetingsUtil.getThisDevice = (newLocus: any, deviceUrl: string) => {\n if (newLocus?.self?.devices?.length > 0) {\n return newLocus.self.devices.find((device) => device.url === deviceUrl);\n }\n\n return null;\n};\n\n/**\n * Checks if the self state in a locus indicates a breakout move or breakout end.\n * Returns true when:\n * - self state is LEFT with reason MOVED (regular breakout move), OR\n * - fullState is INACTIVE with endMeetingReason BREAKOUT_ENDED (breakout session ended)\n * @param {Object} locus locus data\n * @returns {boolean}\n */\nMeetingsUtil.isSelfMovedOrBreakoutEnded = (locus: any): boolean => {\n const isSelfLeftMoved = locus?.self?.state === _LEFT_ && locus?.self?.reason === _MOVED_;\n const isBreakoutEnded =\n locus?.fullState?.state === LOCUS.STATE.INACTIVE &&\n locus?.fullState?.endMeetingReason === _BREAKOUT_ENDED_;\n\n return isSelfLeftMoved || isBreakoutEnded;\n};\n\n/**\n * get self device joined status from locus data\n * @param {Object} meeting current meeting data\n * @param {Object} newLocus new locus data\n * @param {String} deviceUrl current device url\n * @returns {Object}\n */\nMeetingsUtil.joinedOnThisDevice = (meeting: any, newLocus: any, deviceUrl: string) => {\n const thisDevice = MeetingsUtil.getThisDevice(newLocus, deviceUrl);\n if (thisDevice) {\n if (!thisDevice.correlationId || meeting?.correlationId === thisDevice.correlationId) {\n return (\n thisDevice.state === _JOINED_ ||\n (thisDevice.state === _LEFT_ && thisDevice.reason === _MOVED_)\n );\n }\n }\n\n return false;\n};\n\n/**\n * check the new locus is breakout session's one or not\n * @param {Object} newLocus new locus data\n * @returns {boolean}\n * @private\n */\nMeetingsUtil.isBreakoutLocusDTO = (newLocus: any) => {\n return (\n newLocus?.controls?.breakout?.sessionType === BREAKOUTS.SESSION_TYPES.BREAKOUT ||\n !!newLocus?.info?.isBreakout\n );\n};\n\n/**\n * check the locus is valid breakout locus or not\n * @param {Object} locus\n * @returns {boolean}\n * @private\n */\nMeetingsUtil.isValidBreakoutLocus = (locus: any) => {\n const inActiveStatus = locus?.fullState?.state === LOCUS.STATE.INACTIVE;\n const isLocusAsBreakout = MeetingsUtil.isBreakoutLocusDTO(locus);\n const selfJoined = locus.self?.state === _JOINED_;\n\n return isLocusAsBreakout && !inActiveStatus && selfJoined;\n};\n/**\n * check if the breakout locus is associated with the main locus by comparing the breakout control url or the replaces info in self device\n * @param {Object} mainLocus main locus data\n * @param {Object} breakoutLocus breakout locus data\n * @returns {boolean}\n * @private\n */\nMeetingsUtil.isMainAssociatedWithBreakout = (mainLocus: any, breakoutLocus: any) => {\n if (\n mainLocus.controls?.breakout?.url &&\n mainLocus.controls?.breakout?.url === breakoutLocus.controls?.breakout?.url\n ) {\n return true;\n }\n const deviceUrl = breakoutLocus?.self?.deviceUrl;\n const replaceInfo = MeetingsUtil.getThisDevice(breakoutLocus, deviceUrl)?.replaces?.[0];\n if (replaceInfo?.locusUrl && replaceInfo.locusUrl === mainLocus.url) {\n return true;\n }\n\n return false;\n};\nexport default MeetingsUtil;\n"],"mappings":";;;;;;;;;;;AAEA,IAAAA,UAAA,GAAAC,OAAA;AAcA,IAAAC,YAAA,GAAAC,sBAAA,CAAAF,OAAA;AACA,IAAAG,aAAA,GAAAD,sBAAA,CAAAF,OAAA;AACA,IAAAI,WAAA,GAAAF,sBAAA,CAAAF,OAAA;AACA,IAAAK,QAAA,GAAAH,sBAAA,CAAAF,OAAA;AACA,IAAAM,SAAA,GAAAN,OAAA;AApBA;;AAsBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,IAAMO,YAAiB,GAAG,CAAC,CAAC;AAE5BA,YAAY,CAACC,mBAAmB,GAAG,UAACC,IAAsB;EAAA,OACxDA,IAAI,KAAKC,2BAAgB,CAACC,QAAQ,GAAGC,qBAAU,GAAGC,oBAAS;AAAA;AAE7DN,YAAY,CAACO,iBAAiB,GAAG,UAACC,QAAQ,EAAEC,iBAAiB,EAAK;EAChE,IAAOC,IAAI,GAAIF,QAAQ,CAAhBE,IAAI;EACX,IAAOC,SAAS,GAAID,IAAI,CAAjBC,SAAS;EAEhB,IAAIA,SAAS,KAAKC,qBAAU,CAACC,YAAY,EAAE;IACzC,IAAMC,OAAO,GAAGL,iBAAiB,CAACM,QAAQ,CAACC,qBAAW,CAACC,cAAc,EAAEP,IAAI,CAACQ,aAAa,CAAC;IAE1F,IAAIJ,OAAO,EAAE;MACX,IAAAK,aAAA,GAA8DT,IAAI,CAACU,OAAO;QAAnEC,GAAG,GAAAF,aAAA,CAAHE,GAAG;QAAEC,WAAW,GAAAH,aAAA,CAAXG,WAAW;QAAEC,UAAU,GAAAJ,aAAA,CAAVI,UAAU;QAAEC,SAAS,GAAAL,aAAA,CAATK,SAAS;QAAEC,UAAU,GAAAN,aAAA,CAAVM,UAAU;MAE1DC,gBAAO,CAACC,oBAAoB,CAACC,mBAAkB,CAACC,2BAA2B,EAAE;QAC3EC,cAAc,EAAEpB,IAAI,CAACQ,aAAa;QAClCG,GAAG,EAAHA,GAAG;QACHU,YAAY,EAAET,WAAW;QACzBU,UAAU,EAAER,SAAS;QACrBS,WAAW,EAAER;MACf,CAAC,CAAC;MAEF,IAAIH,WAAW,KAAKY,eAAI,CAACC,UAAU,CAACC,uBAAuB,EAAE;QAC3D;QACA;QACAtB,OAAO,CAACuB,IAAI,CAACC,aAAa,CAACC,2BAA2B,CAAC7B,IAAI,CAACU,OAAO,EAAE,cAAc,CAAC;MACtF,CAAC,MAAM;QAAA,IAAAoB,kBAAA;QACL,IAAMC,WAAW,GAAG;UAClBpB,GAAG,EAAHA,GAAG;UACHC,WAAW,EAAXA,WAAW;UACXoB,GAAG,EAAE,EAAAF,kBAAA,GAAA9B,IAAI,CAACU,OAAO,CAACuB,IAAI,cAAAH,kBAAA,uBAAjBA,kBAAA,CAAmBI,MAAM,IAAG,CAAC,GAAGlC,IAAI,CAACU,OAAO,CAACuB,IAAI,CAAC,CAAC,CAAC,GAAGE,SAAS;UACrEtB,UAAU,EAAVA,UAAU;UACVC,SAAS,EAATA,SAAS;UACTC,UAAU,EAAVA;QACF,CAAC;QAEDX,OAAO,CAACgC,mBAAmB,CAACL,WAAW,CAAC;MAC1C;IACF;EACF;AACF,CAAC;AAEDzC,YAAY,CAAC+C,cAAc,GAAG,UAACL,GAAG,EAAK;EACrC,IAAIM,WAAW;;EAEf;EACA,IAAI;IACFA,WAAW,GAAGN,GAAG,CACdO,KAAK,CAAC,MAAM,CAAC,CACbC,IAAI,CAAC,UAACC,IAAI;MAAA,OAAKA,IAAI,CAACC,UAAU,CAAC,IAAI,CAAC;IAAA,EAAC,CACrCH,KAAK,CAAC,GAAG,CAAC,CACVI,KAAK,CAAC,CAAC,CACPC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CACjBC,WAAW,CAAC,CAAC;EAClB,CAAC,CAAC,OAAAC,OAAA,EAAM;IACNR,WAAW,GAAGH,SAAS;EACzB;EAEA,OAAOG,WAAW;AACpB,CAAC;AAEDhD,YAAY,CAACyD,gBAAgB,GAAG,UAACf,GAAG,EAAK;EACvC,IAAIgB,aAAa;;EAEjB;EACA,IAAI;IAAA,IAAAC,qBAAA;IACFD,aAAa,IAAAC,qBAAA,GAAGjB,GAAG,CAChBO,KAAK,CAAC,MAAM,CAAC,CACbC,IAAI,CAAC,UAACC,IAAI;MAAA,OAAKA,IAAI,CAACC,UAAU,CAAC,IAAI,CAAC;IAAA,EAAC,CACrCQ,KAAK,CAAC,+BAA+B,CAAC,cAAAD,qBAAA,uBAHzBA,qBAAA,CAG4B,CAAC,CAAC,CAC3CJ,WAAW,CAAC,CAAC,CACbM,IAAI,CAAC,CAAC;EACX,CAAC,CAAC,OAAAC,QAAA,EAAM;IACNJ,aAAa,GAAGb,SAAS;EAC3B;EAEA,OAAOa,aAAa;AACtB,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA1D,YAAY,CAAC+D,yBAAyB,GAAG,UAACC,SAAiB,EAAEC,SAAc,EAAK;EAC9E,IAAIA,SAAS,aAATA,SAAS,eAATA,SAAS,CAAEC,OAAO,EAAE;IACtB,IAAMC,WAAW,GAAGF,SAAS,aAATA,SAAS,uBAATA,SAAS,CAAEC,OAAO,CAAChB,IAAI,CAAC,UAACkB,MAAM;MAAA,OAAKA,MAAM,CAACC,GAAG,KAAKL,SAAS;IAAA,EAAC;IAEjF,IAAIG,WAAW,IAAIA,WAAW,CAACjD,aAAa,EAAE;MAC5C,OAAOiD,WAAW,CAACjD,aAAa;IAClC;EACF;EAEA,OAAO,KAAK;AACd,CAAC;AAEDlB,YAAY,CAACsE,sCAAsC,GAAG,UAACC,eAAe,EAAK;EAAA,IAAAC,qBAAA;EACzE,IAAIC,MAAM,GAAG,EAAE;EAEf,IAAIF,eAAe,aAAfA,eAAe,gBAAAC,qBAAA,GAAfD,eAAe,CAAEG,KAAK,cAAAF,qBAAA,eAAtBA,qBAAA,CAAwB5B,MAAM,EAAE;IAClC,IAAM+B,WAAW,GAAGJ,eAAe,CAACG,KAAK,CAACxB,IAAI,CAAC,UAAC0B,IAAI;MAAA,OAAKA,IAAI,CAACC,OAAO;IAAA,EAAC;IAEtE,IAAIF,WAAW,EAAE;MACfF,MAAM,GAAGE,WAAW,CAACG,OAAO;IAC9B,CAAC,MAAM;MACLL,MAAM,GAAGF,eAAe,CAACG,KAAK,CAAC,CAAC,CAAC,CAACI,OAAO;IAC3C;EACF;EAEA,OAAOL,MAAM;AACf,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACAzE,YAAY,CAAC+E,YAAY,oBAAAC,kBAAA,CAAAH,OAAA,eAAAI,YAAA,CAAAJ,OAAA,CAAAK,IAAA,CAAG,SAAAC,QAAA;EAAA,IAAAC,QAAA,EAAAC,EAAA,EAAAC,KAAA,EAAAC,EAAA;EAAA,OAAAN,YAAA,CAAAJ,OAAA,CAAAW,IAAA,WAAAC,QAAA;IAAA,kBAAAA,QAAA,CAAAC,IAAA,GAAAD,QAAA,CAAAE,IAAA;MAAA;QACtBP,QAAQ,GAAG,KAAK;QAAAK,QAAA,CAAAC,IAAA;QAGZL,EAAE,GAAG,IAAIO,MAAM,CAACC,iBAAiB,CAAC,CAAC;QAAAJ,QAAA,CAAAE,IAAA;QAAA,OACrBN,EAAE,CAACS,WAAW,CAAC;UAACC,mBAAmB,EAAE;QAAI,CAAC,CAAC;MAAA;QAAzDT,KAAK,GAAAG,QAAA,CAAAO,IAAA;QAEX,IAAIV,KAAK,CAAC5C,GAAG,CAACkB,KAAK,CAAC,4BAA4B,CAAC,EAAE;UACjDwB,QAAQ,GAAG,IAAI;QACjB;QACAC,EAAE,CAACY,KAAK,CAAC,CAAC;QAACR,QAAA,CAAAE,IAAA;QAAA;MAAA;QAAAF,QAAA,CAAAC,IAAA;QAAAH,EAAA,GAAAE,QAAA;QAEXS,oBAAW,CAACC,MAAM,CAACC,IAAI,CACrB,8EACF,CAAC;MAAC;QAAA,OAAAX,QAAA,CAAAY,MAAA,WAGGjB,QAAQ;MAAA;MAAA;QAAA,OAAAK,QAAA,CAAAa,IAAA;IAAA;EAAA,GAAAnB,OAAA;AAAA,CAChB;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACAnF,YAAY,CAACuG,gBAAgB;EAAA,IAAAC,iBAAA,OAAAxB,kBAAA,CAAAH,OAAA,eAAAI,YAAA,CAAAJ,OAAA,CAAAK,IAAA,CAAG,SAAAuB,SAAgCC,OAG/D;IAAA,IAAAC,KAAA;IAAA,IAAA5B,YAAA,EAAA6B,KAAA,EAAAC,YAAA,EAAAC,oBAAA,EAAAC,KAAA,EAAAC,WAAA,EAAAC,aAAA,EAAAC,kBAAA;IAAA,OAAAjC,YAAA,CAAAJ,OAAA,CAAAW,IAAA,WAAA2B,SAAA;MAAA,kBAAAA,SAAA,CAAAzB,IAAA,GAAAyB,SAAA,CAAAxB,IAAA;QAAA;UACQZ,YAAY,GAAI/E,YAAY,CAA5B+E,YAAY;UAAA6B,KAAA,GAC0BF,OAAO,IAAI,CAAC,CAAC,EAAnDG,YAAY,GAAAD,KAAA,CAAZC,YAAY,EAAEC,oBAAoB,GAAAF,KAAA,CAApBE,oBAAoB;UACnCC,KAAK,GAAG,GAAG,EAAE;UACbC,WAAW,GAAG,GAAG,EAAE;UACnBC,aAAa,GAAGJ,YAAY,KAAKhE,SAAS;UAC1CqE,kBAAkB,GAAGL,YAAY,IAAI,IAAAO,IAAA,CAAAvC,OAAA,EAAS,CAAC,GAAGgC,YAAY,IAAIG,WAAW,EAEnF;UAAA,KACIF,oBAAoB;YAAAK,SAAA,CAAAxB,IAAA;YAAA;UAAA;UACtBZ,YAAY,CAAC,CAAC;UAAC,OAAAoC,SAAA,CAAAd,MAAA;QAAA;UAAAc,SAAA,CAAAxB,IAAA;UAAA,OAMPZ,YAAY,CAAC,CAAC;QAAA;UAAA,KAAAoC,SAAA,CAAAnB,IAAA;YAAAmB,SAAA,CAAAxB,IAAA;YAAA;UAAA;UACtB0B,qBAAO,CAACC,OAAO,CACb,IAAI,EACJ;YACEC,IAAI,EAAE,eAAe;YACrBC,QAAQ,EAAE;UACZ,CAAC,EACDC,yBAAc,CAACC,kBACjB,CAAC;UACDxB,oBAAW,CAACC,MAAM,CAACwB,GAAG,CAAC,oEAAoE,CAAC;UAAC,OAAAR,SAAA,CAAAd,MAAA;QAAA;UAAA,KAM3Fa,kBAAkB;YAAAC,SAAA,CAAAxB,IAAA;YAAA;UAAA;UACpBO,oBAAW,CAACC,MAAM,CAACyB,KAAK,CACtB,8EACF,CAAC;UAAC,OAAAT,SAAA,CAAAd,MAAA;QAAA;UAKJ;UACA,IAAIY,aAAa,EAAE;YACjBI,qBAAO,CAACC,OAAO,CACb,IAAI,EACJ;cACEC,IAAI,EAAE,eAAe;cACrBC,QAAQ,EAAE;YACZ,CAAC,EACDC,yBAAc,CAACI,mBACjB,CAAC;YACD3B,oBAAW,CAACC,MAAM,CAACwB,GAAG,CAAC,2DAA2D,CAAC;UACrF;;UAEA;UACA/B,MAAM,CAACkC,UAAU,CAAC,YAAM;YACtB,IAAMC,SAAS,GAAGlB,YAAY,IAAI,IAAAO,IAAA,CAAAvC,OAAA,EAAS,CAAC;YAE5C7E,YAAY,CAACuG,gBAAgB,CAACyB,IAAI,CAACrB,KAAI,EAAE;cAACE,YAAY,EAAEkB;YAAS,CAAC,CAAC;UACrE,CAAC,EAAEhB,KAAK,CAAC;QAAC;QAAA;UAAA,OAAAI,SAAA,CAAAb,IAAA;MAAA;IAAA,GAAAG,QAAA;EAAA,CACX;EAAA,SA7D8CF,gBAAgBA,CAAA0B,EAAA;IAAA,OAAAzB,iBAAA,CAAA0B,KAAA,OAAAC,SAAA;EAAA;EAAA,OAAhB5B,gBAAgB;AAAA,GA6D9D;;AAED;AACA;AACA;AACA;AACA;AACA;AACAvG,YAAY,CAACoI,aAAa,GAAG,UAACC,QAAa,EAAErE,SAAiB,EAAK;EAAA,IAAAsE,cAAA,EAAAC,qBAAA;EACjE,IAAI,CAAAF,QAAQ,aAARA,QAAQ,wBAAAC,cAAA,GAARD,QAAQ,CAAEG,IAAI,cAAAF,cAAA,wBAAAC,qBAAA,GAAdD,cAAA,CAAgBpE,OAAO,cAAAqE,qBAAA,uBAAvBA,qBAAA,CAAyB3F,MAAM,IAAG,CAAC,EAAE;IACvC,OAAOyF,QAAQ,CAACG,IAAI,CAACtE,OAAO,CAAChB,IAAI,CAAC,UAACkB,MAAM;MAAA,OAAKA,MAAM,CAACC,GAAG,KAAKL,SAAS;IAAA,EAAC;EACzE;EAEA,OAAO,IAAI;AACb,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACAhE,YAAY,CAACyI,0BAA0B,GAAG,UAACC,KAAU,EAAc;EAAA,IAAAC,WAAA,EAAAC,YAAA,EAAAC,gBAAA,EAAAC,iBAAA;EACjE,IAAMC,eAAe,GAAG,CAAAL,KAAK,aAALA,KAAK,wBAAAC,WAAA,GAALD,KAAK,CAAEF,IAAI,cAAAG,WAAA,uBAAXA,WAAA,CAAaK,KAAK,MAAKC,iBAAM,IAAI,CAAAP,KAAK,aAALA,KAAK,wBAAAE,YAAA,GAALF,KAAK,CAAEF,IAAI,cAAAI,YAAA,uBAAXA,YAAA,CAAaM,MAAM,MAAKC,kBAAO;EACxF,IAAMC,eAAe,GACnB,CAAAV,KAAK,aAALA,KAAK,wBAAAG,gBAAA,GAALH,KAAK,CAAEW,SAAS,cAAAR,gBAAA,uBAAhBA,gBAAA,CAAkBG,KAAK,MAAKM,gBAAK,CAACC,KAAK,CAACC,QAAQ,IAChD,CAAAd,KAAK,aAALA,KAAK,wBAAAI,iBAAA,GAALJ,KAAK,CAAEW,SAAS,cAAAP,iBAAA,uBAAhBA,iBAAA,CAAkBW,gBAAgB,MAAKC,2BAAgB;EAEzD,OAAOX,eAAe,IAAIK,eAAe;AAC3C,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACApJ,YAAY,CAAC2J,kBAAkB,GAAG,UAAC7I,OAAY,EAAEuH,QAAa,EAAErE,SAAiB,EAAK;EACpF,IAAM4F,UAAU,GAAG5J,YAAY,CAACoI,aAAa,CAACC,QAAQ,EAAErE,SAAS,CAAC;EAClE,IAAI4F,UAAU,EAAE;IACd,IAAI,CAACA,UAAU,CAAC1I,aAAa,IAAI,CAAAJ,OAAO,aAAPA,OAAO,uBAAPA,OAAO,CAAEI,aAAa,MAAK0I,UAAU,CAAC1I,aAAa,EAAE;MACpF,OACE0I,UAAU,CAACZ,KAAK,KAAKa,mBAAQ,IAC5BD,UAAU,CAACZ,KAAK,KAAKC,iBAAM,IAAIW,UAAU,CAACV,MAAM,KAAKC,kBAAQ;IAElE;EACF;EAEA,OAAO,KAAK;AACd,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACAnJ,YAAY,CAAC8J,kBAAkB,GAAG,UAACzB,QAAa,EAAK;EAAA,IAAA0B,kBAAA,EAAAC,qBAAA,EAAAC,cAAA;EACnD,OACE,CAAA5B,QAAQ,aAARA,QAAQ,wBAAA0B,kBAAA,GAAR1B,QAAQ,CAAE6B,QAAQ,cAAAH,kBAAA,wBAAAC,qBAAA,GAAlBD,kBAAA,CAAoBI,QAAQ,cAAAH,qBAAA,uBAA5BA,qBAAA,CAA8BI,WAAW,MAAKC,oBAAS,CAACC,aAAa,CAACC,QAAQ,IAC9E,CAAC,EAAClC,QAAQ,aAARA,QAAQ,gBAAA4B,cAAA,GAAR5B,QAAQ,CAAEmC,IAAI,cAAAP,cAAA,eAAdA,cAAA,CAAgBQ,UAAU;AAEhC,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACAzK,YAAY,CAAC0K,oBAAoB,GAAG,UAAChC,KAAU,EAAK;EAAA,IAAAiC,iBAAA,EAAAC,YAAA;EAClD,IAAMC,cAAc,GAAG,CAAAnC,KAAK,aAALA,KAAK,wBAAAiC,iBAAA,GAALjC,KAAK,CAAEW,SAAS,cAAAsB,iBAAA,uBAAhBA,iBAAA,CAAkB3B,KAAK,MAAKM,gBAAK,CAACC,KAAK,CAACC,QAAQ;EACvE,IAAMsB,iBAAiB,GAAG9K,YAAY,CAAC8J,kBAAkB,CAACpB,KAAK,CAAC;EAChE,IAAMqC,UAAU,GAAG,EAAAH,YAAA,GAAAlC,KAAK,CAACF,IAAI,cAAAoC,YAAA,uBAAVA,YAAA,CAAY5B,KAAK,MAAKa,mBAAQ;EAEjD,OAAOiB,iBAAiB,IAAI,CAACD,cAAc,IAAIE,UAAU;AAC3D,CAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA/K,YAAY,CAACgL,4BAA4B,GAAG,UAACC,SAAc,EAAEC,aAAkB,EAAK;EAAA,IAAAC,mBAAA,EAAAC,qBAAA,EAAAC,oBAAA,EAAAC,qBAAA,EAAAC,qBAAA,EAAAC,sBAAA,EAAAC,mBAAA,EAAAC,qBAAA,EAAAC,sBAAA;EAClF,IACE,CAAAR,mBAAA,GAAAF,SAAS,CAACf,QAAQ,cAAAiB,mBAAA,gBAAAC,qBAAA,GAAlBD,mBAAA,CAAoBhB,QAAQ,cAAAiB,qBAAA,eAA5BA,qBAAA,CAA8B/G,GAAG,IACjC,EAAAgH,oBAAA,GAAAJ,SAAS,CAACf,QAAQ,cAAAmB,oBAAA,wBAAAC,qBAAA,GAAlBD,oBAAA,CAAoBlB,QAAQ,cAAAmB,qBAAA,uBAA5BA,qBAAA,CAA8BjH,GAAG,QAAAkH,qBAAA,GAAKL,aAAa,CAAChB,QAAQ,cAAAqB,qBAAA,wBAAAC,sBAAA,GAAtBD,qBAAA,CAAwBpB,QAAQ,cAAAqB,sBAAA,uBAAhCA,sBAAA,CAAkCnH,GAAG,GAC3E;IACA,OAAO,IAAI;EACb;EACA,IAAML,SAAS,GAAGkH,aAAa,aAAbA,aAAa,wBAAAO,mBAAA,GAAbP,aAAa,CAAE1C,IAAI,cAAAiD,mBAAA,uBAAnBA,mBAAA,CAAqBzH,SAAS;EAChD,IAAM4H,WAAW,IAAAF,qBAAA,GAAG1L,YAAY,CAACoI,aAAa,CAAC8C,aAAa,EAAElH,SAAS,CAAC,cAAA0H,qBAAA,wBAAAC,sBAAA,GAApDD,qBAAA,CAAsDG,QAAQ,cAAAF,sBAAA,uBAA9DA,sBAAA,CAAiE,CAAC,CAAC;EACvF,IAAIC,WAAW,aAAXA,WAAW,eAAXA,WAAW,CAAEE,QAAQ,IAAIF,WAAW,CAACE,QAAQ,KAAKb,SAAS,CAAC5G,GAAG,EAAE;IACnE,OAAO,IAAI;EACb;EAEA,OAAO,KAAK;AACd,CAAC;AAAC,IAAA0H,QAAA,GAAAC,OAAA,CAAAnH,OAAA,GACa7E,YAAY","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["_constants","require","_loggerProxy","_interopRequireDefault","_triggerProxy","_constants2","_metrics","_meetings","_types","MeetingsUtil","getMeetingAddedType","type","DESTINATION_TYPE","LOCUS_ID","_INCOMING_","_CREATED_","handleRoapMercury","envelope","meetingCollection","data","eventType","LOCUSEVENT","MESSAGE_ROAP","meeting","getByKey","MEETING_KEY","CORRELATION_ID","correlationId","_data$message","message","seq","messageType","tieBreaker","errorType","errorCause","Metrics","sendBehavioralMetric","BEHAVIORAL_METRICS","ROAP_MERCURY_EVENT_RECEIVED","correlation_id","message_type","error_type","error_cause","ROAP","ROAP_TYPES","TURN_DISCOVERY_RESPONSE","roap","turnDiscovery","handleTurnDiscoveryResponse","_data$message$sdps","roapMessage","sdp","sdps","length","undefined","roapMessageReceived","getMediaServer","mediaServer","split","find","line","startsWith","shift","replace","toLowerCase","_unused","getMediaServerIp","mediaServerIp","_sdp$split$find$match","match","trim","_unused2","getCorrelationIdForDevice","deviceUrl","locusSelf","devices","foundDevice","device","url","parseDefaultSiteFromMeetingPreferences","userPreferences","_userPreferences$site","result","sites","defaultSite","site","default","siteUrl","hasH264Codec","_asyncToGenerator2","_regenerator","mark","_callee","hasCodec","pc","offer","_t","wrap","_context","prev","next","window","RTCPeerConnection","createOffer","offerToReceiveVideo","sent","close","LoggerProxy","logger","warn","abrupt","stop","checkH264Support","_checkH264Support","_callee2","options","_this","_ref2","firstChecked","disableNotifications","delay","maxDuration","shouldTrigger","shouldStopChecking","_context2","_now","Trigger","trigger","file","function","EVENT_TRIGGERS","MEDIA_CODEC_LOADED","log","error","MEDIA_CODEC_MISSING","setTimeout","timestamp","call","_x","apply","arguments","getThisDevice","newLocus","_newLocus$self","_newLocus$self$device","self","isWholeMeetingEnded","fullState","state","LOCUS","STATE","INACTIVE","endMeetingReason","EndMeetingReason","breakoutEnded","isSelfMovedOrBreakoutEnded","locus","_locus$self","_locus$self2","_locus$fullState","_locus$fullState2","isSelfLeftMoved","_LEFT_","reason","_MOVED_","isBreakoutEnded","joinedOnThisDevice","thisDevice","_JOINED_","isBreakoutLocusDTO","_newLocus$controls","_newLocus$controls$br","_newLocus$info","controls","breakout","sessionType","BREAKOUTS","SESSION_TYPES","BREAKOUT","info","isBreakout","isValidBreakoutLocus","_locus$fullState3","_locus$self3","inActiveStatus","isLocusAsBreakout","selfJoined","isMainAssociatedWithBreakout","mainLocus","breakoutLocus","_mainLocus$controls","_mainLocus$controls$b","_mainLocus$controls2","_mainLocus$controls2$","_breakoutLocus$contro","_breakoutLocus$contro2","_breakoutLocus$self","_MeetingsUtil$getThis","_MeetingsUtil$getThis2","replaceInfo","replaces","locusUrl","_default","exports"],"sources":["util.ts"],"sourcesContent":["/* globals window */\n\nimport {\n _CREATED_,\n _INCOMING_,\n _JOINED_,\n _LEFT_,\n DESTINATION_TYPE,\n _MOVED_,\n BREAKOUTS,\n EVENT_TRIGGERS,\n LOCUS,\n LOCUSEVENT,\n ROAP,\n} from '../constants';\nimport LoggerProxy from '../common/logs/logger-proxy';\nimport Trigger from '../common/events/trigger-proxy';\nimport BEHAVIORAL_METRICS from '../metrics/constants';\nimport Metrics from '../metrics';\nimport {MEETING_KEY} from './meetings.types';\nimport {EndMeetingReason, LocusFullState} from '../locus-info/types';\n\n/**\n * Meetings Media Codec Missing Event\n * Emitted when H.264 codec is not\n * found in the browser.\n * @event media:codec:missing\n * @instance\n * @memberof MeetingsUtil\n */\n\n/**\n * Meetings Media Codec Loaded Event\n * Emitted when H.264 codec has been\n * loaded in the browser.\n * @event media:codec:loaded\n * @instance\n * @memberof MeetingsUtil\n */\n\nconst MeetingsUtil: any = {};\n\nMeetingsUtil.getMeetingAddedType = (type: DESTINATION_TYPE) =>\n type === DESTINATION_TYPE.LOCUS_ID ? _INCOMING_ : _CREATED_;\n\nMeetingsUtil.handleRoapMercury = (envelope, meetingCollection) => {\n const {data} = envelope;\n const {eventType} = data;\n\n if (eventType === LOCUSEVENT.MESSAGE_ROAP) {\n const meeting = meetingCollection.getByKey(MEETING_KEY.CORRELATION_ID, data.correlationId);\n\n if (meeting) {\n const {seq, messageType, tieBreaker, errorType, errorCause} = data.message;\n\n Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.ROAP_MERCURY_EVENT_RECEIVED, {\n correlation_id: data.correlationId,\n seq,\n message_type: messageType,\n error_type: errorType,\n error_cause: errorCause,\n });\n\n if (messageType === ROAP.ROAP_TYPES.TURN_DISCOVERY_RESPONSE) {\n // turn discovery is not part of normal roap protocol and so we are not handling it\n // through the usual roap state machine\n meeting.roap.turnDiscovery.handleTurnDiscoveryResponse(data.message, 'from mercury');\n } else {\n const roapMessage = {\n seq,\n messageType,\n sdp: data.message.sdps?.length > 0 ? data.message.sdps[0] : undefined,\n tieBreaker,\n errorType,\n errorCause,\n };\n\n meeting.roapMessageReceived(roapMessage);\n }\n }\n }\n};\n\nMeetingsUtil.getMediaServer = (sdp) => {\n let mediaServer;\n\n // Attempt to collect the media server from the roap message.\n try {\n mediaServer = sdp\n .split('\\r\\n')\n .find((line) => line.startsWith('o='))\n .split(' ')\n .shift()\n .replace('o=', '')\n .toLowerCase();\n } catch {\n mediaServer = undefined;\n }\n\n return mediaServer;\n};\n\nMeetingsUtil.getMediaServerIp = (sdp) => {\n let mediaServerIp;\n\n // Attempt to collect the media server from the roap message.\n try {\n mediaServerIp = sdp\n .split('\\r\\n')\n .find((line) => line.startsWith('o='))\n .match(/o=\\S+ \\d+ \\d+ IN IP4 ([\\d.]+)/)?.[1]\n .toLowerCase()\n .trim();\n } catch {\n mediaServerIp = undefined;\n }\n\n return mediaServerIp;\n};\n\n/**\n * Finds correlationId of a device from locus self devices array\n * that matches the given deviceUrl\n * @param {string} deviceUrl\n * @param {object} locusSelf\n * @returns {string|false} correlationId or false if not found\n */\nMeetingsUtil.getCorrelationIdForDevice = (deviceUrl: string, locusSelf: any) => {\n if (locusSelf?.devices) {\n const foundDevice = locusSelf?.devices.find((device) => device.url === deviceUrl);\n\n if (foundDevice && foundDevice.correlationId) {\n return foundDevice.correlationId;\n }\n }\n\n return false;\n};\n\nMeetingsUtil.parseDefaultSiteFromMeetingPreferences = (userPreferences) => {\n let result = '';\n\n if (userPreferences?.sites?.length) {\n const defaultSite = userPreferences.sites.find((site) => site.default);\n\n if (defaultSite) {\n result = defaultSite.siteUrl;\n } else {\n result = userPreferences.sites[0].siteUrl;\n }\n }\n\n return result;\n};\n\n/**\n * Will check to see if the H.264 media codec is supported.\n * @async\n * @private\n * @returns {Promise<boolean>}\n */\nMeetingsUtil.hasH264Codec = async () => {\n let hasCodec = false;\n\n try {\n const pc = new window.RTCPeerConnection();\n const offer = await pc.createOffer({offerToReceiveVideo: true});\n\n if (offer.sdp.match(/^a=rtpmap:\\d+\\s+H264\\/\\d+/m)) {\n hasCodec = true;\n }\n pc.close();\n } catch (error) {\n LoggerProxy.logger.warn(\n 'Meetings:util#hasH264Codec --> Error creating peerConnection for H.264 test.'\n );\n }\n\n return hasCodec;\n};\n\n/**\n * Notifies the user whether or not the H.264\n * codec is present. Will continuously check\n * until max duration.\n * @async\n * @private\n * @param {object} options\n * @param {Number} options.firstChecked Timestamp in milliseconds\n * @param {boolean} options.disableNotifications Default is false. Boolean to enable/disable notification and events\n * @returns {undefined}\n */\nMeetingsUtil.checkH264Support = async function checkH264Support(options: {\n firstChecked: number;\n disableNotifications: boolean;\n}) {\n const {hasH264Codec} = MeetingsUtil;\n const {firstChecked, disableNotifications} = options || {};\n const delay = 5e3; // ms\n const maxDuration = 3e5; // ms\n const shouldTrigger = firstChecked === undefined;\n const shouldStopChecking = firstChecked && Date.now() - firstChecked >= maxDuration;\n\n // Disable notifications and start H.264 download only\n if (disableNotifications) {\n hasH264Codec();\n\n return;\n }\n\n // Codec loaded trigger event notification\n if (await hasH264Codec()) {\n Trigger.trigger(\n this,\n {\n file: 'meetings/util',\n function: 'checkH264Support',\n },\n EVENT_TRIGGERS.MEDIA_CODEC_LOADED\n );\n LoggerProxy.logger.log('Meetings:util#checkH264Support --> H264 codec loaded successfully.');\n\n return;\n }\n\n // Stop checking if past the timelimit\n if (shouldStopChecking) {\n LoggerProxy.logger.error(\n 'Meetings:util#checkH264Support --> Timed out waiting for H264 codec to load.'\n );\n\n return;\n }\n\n // Trigger only once\n if (shouldTrigger) {\n Trigger.trigger(\n this,\n {\n file: 'meetings/util',\n function: 'checkH264Support',\n },\n EVENT_TRIGGERS.MEDIA_CODEC_MISSING\n );\n LoggerProxy.logger.log('Meetings:util#checkH264Support --> H264 codec is missing.');\n }\n\n // Keep checking in intervals to see if codec loaded\n window.setTimeout(() => {\n const timestamp = firstChecked || Date.now();\n\n MeetingsUtil.checkH264Support.call(this, {firstChecked: timestamp});\n }, delay);\n};\n\n/**\n * get device from locus data\n * @param {Object} newLocus new locus data\n * @param {String} deviceUrl current device url\n * @returns {Object}\n */\nMeetingsUtil.getThisDevice = (newLocus: any, deviceUrl: string) => {\n if (newLocus?.self?.devices?.length > 0) {\n return newLocus.self.devices.find((device) => device.url === deviceUrl);\n }\n\n return null;\n};\n\n/**\n * Checks if the fullState indicates the meeting has fully ended (not just a breakout move).\n * @param {Object} fullState locus fullState data\n * @returns {boolean}\n */\nMeetingsUtil.isWholeMeetingEnded = (fullState: LocusFullState): boolean => {\n return (\n fullState.state === LOCUS.STATE.INACTIVE &&\n fullState.endMeetingReason !== EndMeetingReason.breakoutEnded\n );\n};\n\n/**\n * Checks if the self state in a locus indicates a breakout move or breakout end.\n * Returns true when:\n * - self state is LEFT with reason MOVED (regular breakout move), OR\n * - fullState is INACTIVE with endMeetingReason BREAKOUT_ENDED (breakout session ended)\n * @param {Object} locus locus data\n * @returns {boolean}\n */\nMeetingsUtil.isSelfMovedOrBreakoutEnded = (locus: any): boolean => {\n const isSelfLeftMoved = locus?.self?.state === _LEFT_ && locus?.self?.reason === _MOVED_;\n const isBreakoutEnded =\n locus?.fullState?.state === LOCUS.STATE.INACTIVE &&\n locus?.fullState?.endMeetingReason === EndMeetingReason.breakoutEnded;\n\n return isSelfLeftMoved || isBreakoutEnded;\n};\n\n/**\n * get self device joined status from locus data\n * @param {Object} meeting current meeting data\n * @param {Object} newLocus new locus data\n * @param {String} deviceUrl current device url\n * @returns {Object}\n */\nMeetingsUtil.joinedOnThisDevice = (meeting: any, newLocus: any, deviceUrl: string) => {\n const thisDevice = MeetingsUtil.getThisDevice(newLocus, deviceUrl);\n if (thisDevice) {\n if (!thisDevice.correlationId || meeting?.correlationId === thisDevice.correlationId) {\n return (\n thisDevice.state === _JOINED_ ||\n (thisDevice.state === _LEFT_ && thisDevice.reason === _MOVED_)\n );\n }\n }\n\n return false;\n};\n\n/**\n * check the new locus is breakout session's one or not\n * @param {Object} newLocus new locus data\n * @returns {boolean}\n * @private\n */\nMeetingsUtil.isBreakoutLocusDTO = (newLocus: any) => {\n return (\n newLocus?.controls?.breakout?.sessionType === BREAKOUTS.SESSION_TYPES.BREAKOUT ||\n !!newLocus?.info?.isBreakout\n );\n};\n\n/**\n * check the locus is valid breakout locus or not\n * @param {Object} locus\n * @returns {boolean}\n * @private\n */\nMeetingsUtil.isValidBreakoutLocus = (locus: any) => {\n const inActiveStatus = locus?.fullState?.state === LOCUS.STATE.INACTIVE;\n const isLocusAsBreakout = MeetingsUtil.isBreakoutLocusDTO(locus);\n const selfJoined = locus.self?.state === _JOINED_;\n\n return isLocusAsBreakout && !inActiveStatus && selfJoined;\n};\n/**\n * check if the breakout locus is associated with the main locus by comparing the breakout control url or the replaces info in self device\n * @param {Object} mainLocus main locus data\n * @param {Object} breakoutLocus breakout locus data\n * @returns {boolean}\n * @private\n */\nMeetingsUtil.isMainAssociatedWithBreakout = (mainLocus: any, breakoutLocus: any) => {\n if (\n mainLocus.controls?.breakout?.url &&\n mainLocus.controls?.breakout?.url === breakoutLocus.controls?.breakout?.url\n ) {\n return true;\n }\n const deviceUrl = breakoutLocus?.self?.deviceUrl;\n const replaceInfo = MeetingsUtil.getThisDevice(breakoutLocus, deviceUrl)?.replaces?.[0];\n if (replaceInfo?.locusUrl && replaceInfo.locusUrl === mainLocus.url) {\n return true;\n }\n\n return false;\n};\nexport default MeetingsUtil;\n"],"mappings":";;;;;;;;;;;AAEA,IAAAA,UAAA,GAAAC,OAAA;AAaA,IAAAC,YAAA,GAAAC,sBAAA,CAAAF,OAAA;AACA,IAAAG,aAAA,GAAAD,sBAAA,CAAAF,OAAA;AACA,IAAAI,WAAA,GAAAF,sBAAA,CAAAF,OAAA;AACA,IAAAK,QAAA,GAAAH,sBAAA,CAAAF,OAAA;AACA,IAAAM,SAAA,GAAAN,OAAA;AACA,IAAAO,MAAA,GAAAP,OAAA;AApBA;;AAsBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,IAAMQ,YAAiB,GAAG,CAAC,CAAC;AAE5BA,YAAY,CAACC,mBAAmB,GAAG,UAACC,IAAsB;EAAA,OACxDA,IAAI,KAAKC,2BAAgB,CAACC,QAAQ,GAAGC,qBAAU,GAAGC,oBAAS;AAAA;AAE7DN,YAAY,CAACO,iBAAiB,GAAG,UAACC,QAAQ,EAAEC,iBAAiB,EAAK;EAChE,IAAOC,IAAI,GAAIF,QAAQ,CAAhBE,IAAI;EACX,IAAOC,SAAS,GAAID,IAAI,CAAjBC,SAAS;EAEhB,IAAIA,SAAS,KAAKC,qBAAU,CAACC,YAAY,EAAE;IACzC,IAAMC,OAAO,GAAGL,iBAAiB,CAACM,QAAQ,CAACC,qBAAW,CAACC,cAAc,EAAEP,IAAI,CAACQ,aAAa,CAAC;IAE1F,IAAIJ,OAAO,EAAE;MACX,IAAAK,aAAA,GAA8DT,IAAI,CAACU,OAAO;QAAnEC,GAAG,GAAAF,aAAA,CAAHE,GAAG;QAAEC,WAAW,GAAAH,aAAA,CAAXG,WAAW;QAAEC,UAAU,GAAAJ,aAAA,CAAVI,UAAU;QAAEC,SAAS,GAAAL,aAAA,CAATK,SAAS;QAAEC,UAAU,GAAAN,aAAA,CAAVM,UAAU;MAE1DC,gBAAO,CAACC,oBAAoB,CAACC,mBAAkB,CAACC,2BAA2B,EAAE;QAC3EC,cAAc,EAAEpB,IAAI,CAACQ,aAAa;QAClCG,GAAG,EAAHA,GAAG;QACHU,YAAY,EAAET,WAAW;QACzBU,UAAU,EAAER,SAAS;QACrBS,WAAW,EAAER;MACf,CAAC,CAAC;MAEF,IAAIH,WAAW,KAAKY,eAAI,CAACC,UAAU,CAACC,uBAAuB,EAAE;QAC3D;QACA;QACAtB,OAAO,CAACuB,IAAI,CAACC,aAAa,CAACC,2BAA2B,CAAC7B,IAAI,CAACU,OAAO,EAAE,cAAc,CAAC;MACtF,CAAC,MAAM;QAAA,IAAAoB,kBAAA;QACL,IAAMC,WAAW,GAAG;UAClBpB,GAAG,EAAHA,GAAG;UACHC,WAAW,EAAXA,WAAW;UACXoB,GAAG,EAAE,EAAAF,kBAAA,GAAA9B,IAAI,CAACU,OAAO,CAACuB,IAAI,cAAAH,kBAAA,uBAAjBA,kBAAA,CAAmBI,MAAM,IAAG,CAAC,GAAGlC,IAAI,CAACU,OAAO,CAACuB,IAAI,CAAC,CAAC,CAAC,GAAGE,SAAS;UACrEtB,UAAU,EAAVA,UAAU;UACVC,SAAS,EAATA,SAAS;UACTC,UAAU,EAAVA;QACF,CAAC;QAEDX,OAAO,CAACgC,mBAAmB,CAACL,WAAW,CAAC;MAC1C;IACF;EACF;AACF,CAAC;AAEDzC,YAAY,CAAC+C,cAAc,GAAG,UAACL,GAAG,EAAK;EACrC,IAAIM,WAAW;;EAEf;EACA,IAAI;IACFA,WAAW,GAAGN,GAAG,CACdO,KAAK,CAAC,MAAM,CAAC,CACbC,IAAI,CAAC,UAACC,IAAI;MAAA,OAAKA,IAAI,CAACC,UAAU,CAAC,IAAI,CAAC;IAAA,EAAC,CACrCH,KAAK,CAAC,GAAG,CAAC,CACVI,KAAK,CAAC,CAAC,CACPC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CACjBC,WAAW,CAAC,CAAC;EAClB,CAAC,CAAC,OAAAC,OAAA,EAAM;IACNR,WAAW,GAAGH,SAAS;EACzB;EAEA,OAAOG,WAAW;AACpB,CAAC;AAEDhD,YAAY,CAACyD,gBAAgB,GAAG,UAACf,GAAG,EAAK;EACvC,IAAIgB,aAAa;;EAEjB;EACA,IAAI;IAAA,IAAAC,qBAAA;IACFD,aAAa,IAAAC,qBAAA,GAAGjB,GAAG,CAChBO,KAAK,CAAC,MAAM,CAAC,CACbC,IAAI,CAAC,UAACC,IAAI;MAAA,OAAKA,IAAI,CAACC,UAAU,CAAC,IAAI,CAAC;IAAA,EAAC,CACrCQ,KAAK,CAAC,+BAA+B,CAAC,cAAAD,qBAAA,uBAHzBA,qBAAA,CAG4B,CAAC,CAAC,CAC3CJ,WAAW,CAAC,CAAC,CACbM,IAAI,CAAC,CAAC;EACX,CAAC,CAAC,OAAAC,QAAA,EAAM;IACNJ,aAAa,GAAGb,SAAS;EAC3B;EAEA,OAAOa,aAAa;AACtB,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA1D,YAAY,CAAC+D,yBAAyB,GAAG,UAACC,SAAiB,EAAEC,SAAc,EAAK;EAC9E,IAAIA,SAAS,aAATA,SAAS,eAATA,SAAS,CAAEC,OAAO,EAAE;IACtB,IAAMC,WAAW,GAAGF,SAAS,aAATA,SAAS,uBAATA,SAAS,CAAEC,OAAO,CAAChB,IAAI,CAAC,UAACkB,MAAM;MAAA,OAAKA,MAAM,CAACC,GAAG,KAAKL,SAAS;IAAA,EAAC;IAEjF,IAAIG,WAAW,IAAIA,WAAW,CAACjD,aAAa,EAAE;MAC5C,OAAOiD,WAAW,CAACjD,aAAa;IAClC;EACF;EAEA,OAAO,KAAK;AACd,CAAC;AAEDlB,YAAY,CAACsE,sCAAsC,GAAG,UAACC,eAAe,EAAK;EAAA,IAAAC,qBAAA;EACzE,IAAIC,MAAM,GAAG,EAAE;EAEf,IAAIF,eAAe,aAAfA,eAAe,gBAAAC,qBAAA,GAAfD,eAAe,CAAEG,KAAK,cAAAF,qBAAA,eAAtBA,qBAAA,CAAwB5B,MAAM,EAAE;IAClC,IAAM+B,WAAW,GAAGJ,eAAe,CAACG,KAAK,CAACxB,IAAI,CAAC,UAAC0B,IAAI;MAAA,OAAKA,IAAI,CAACC,OAAO;IAAA,EAAC;IAEtE,IAAIF,WAAW,EAAE;MACfF,MAAM,GAAGE,WAAW,CAACG,OAAO;IAC9B,CAAC,MAAM;MACLL,MAAM,GAAGF,eAAe,CAACG,KAAK,CAAC,CAAC,CAAC,CAACI,OAAO;IAC3C;EACF;EAEA,OAAOL,MAAM;AACf,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACAzE,YAAY,CAAC+E,YAAY,oBAAAC,kBAAA,CAAAH,OAAA,eAAAI,YAAA,CAAAJ,OAAA,CAAAK,IAAA,CAAG,SAAAC,QAAA;EAAA,IAAAC,QAAA,EAAAC,EAAA,EAAAC,KAAA,EAAAC,EAAA;EAAA,OAAAN,YAAA,CAAAJ,OAAA,CAAAW,IAAA,WAAAC,QAAA;IAAA,kBAAAA,QAAA,CAAAC,IAAA,GAAAD,QAAA,CAAAE,IAAA;MAAA;QACtBP,QAAQ,GAAG,KAAK;QAAAK,QAAA,CAAAC,IAAA;QAGZL,EAAE,GAAG,IAAIO,MAAM,CAACC,iBAAiB,CAAC,CAAC;QAAAJ,QAAA,CAAAE,IAAA;QAAA,OACrBN,EAAE,CAACS,WAAW,CAAC;UAACC,mBAAmB,EAAE;QAAI,CAAC,CAAC;MAAA;QAAzDT,KAAK,GAAAG,QAAA,CAAAO,IAAA;QAEX,IAAIV,KAAK,CAAC5C,GAAG,CAACkB,KAAK,CAAC,4BAA4B,CAAC,EAAE;UACjDwB,QAAQ,GAAG,IAAI;QACjB;QACAC,EAAE,CAACY,KAAK,CAAC,CAAC;QAACR,QAAA,CAAAE,IAAA;QAAA;MAAA;QAAAF,QAAA,CAAAC,IAAA;QAAAH,EAAA,GAAAE,QAAA;QAEXS,oBAAW,CAACC,MAAM,CAACC,IAAI,CACrB,8EACF,CAAC;MAAC;QAAA,OAAAX,QAAA,CAAAY,MAAA,WAGGjB,QAAQ;MAAA;MAAA;QAAA,OAAAK,QAAA,CAAAa,IAAA;IAAA;EAAA,GAAAnB,OAAA;AAAA,CAChB;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACAnF,YAAY,CAACuG,gBAAgB;EAAA,IAAAC,iBAAA,OAAAxB,kBAAA,CAAAH,OAAA,eAAAI,YAAA,CAAAJ,OAAA,CAAAK,IAAA,CAAG,SAAAuB,SAAgCC,OAG/D;IAAA,IAAAC,KAAA;IAAA,IAAA5B,YAAA,EAAA6B,KAAA,EAAAC,YAAA,EAAAC,oBAAA,EAAAC,KAAA,EAAAC,WAAA,EAAAC,aAAA,EAAAC,kBAAA;IAAA,OAAAjC,YAAA,CAAAJ,OAAA,CAAAW,IAAA,WAAA2B,SAAA;MAAA,kBAAAA,SAAA,CAAAzB,IAAA,GAAAyB,SAAA,CAAAxB,IAAA;QAAA;UACQZ,YAAY,GAAI/E,YAAY,CAA5B+E,YAAY;UAAA6B,KAAA,GAC0BF,OAAO,IAAI,CAAC,CAAC,EAAnDG,YAAY,GAAAD,KAAA,CAAZC,YAAY,EAAEC,oBAAoB,GAAAF,KAAA,CAApBE,oBAAoB;UACnCC,KAAK,GAAG,GAAG,EAAE;UACbC,WAAW,GAAG,GAAG,EAAE;UACnBC,aAAa,GAAGJ,YAAY,KAAKhE,SAAS;UAC1CqE,kBAAkB,GAAGL,YAAY,IAAI,IAAAO,IAAA,CAAAvC,OAAA,EAAS,CAAC,GAAGgC,YAAY,IAAIG,WAAW,EAEnF;UAAA,KACIF,oBAAoB;YAAAK,SAAA,CAAAxB,IAAA;YAAA;UAAA;UACtBZ,YAAY,CAAC,CAAC;UAAC,OAAAoC,SAAA,CAAAd,MAAA;QAAA;UAAAc,SAAA,CAAAxB,IAAA;UAAA,OAMPZ,YAAY,CAAC,CAAC;QAAA;UAAA,KAAAoC,SAAA,CAAAnB,IAAA;YAAAmB,SAAA,CAAAxB,IAAA;YAAA;UAAA;UACtB0B,qBAAO,CAACC,OAAO,CACb,IAAI,EACJ;YACEC,IAAI,EAAE,eAAe;YACrBC,QAAQ,EAAE;UACZ,CAAC,EACDC,yBAAc,CAACC,kBACjB,CAAC;UACDxB,oBAAW,CAACC,MAAM,CAACwB,GAAG,CAAC,oEAAoE,CAAC;UAAC,OAAAR,SAAA,CAAAd,MAAA;QAAA;UAAA,KAM3Fa,kBAAkB;YAAAC,SAAA,CAAAxB,IAAA;YAAA;UAAA;UACpBO,oBAAW,CAACC,MAAM,CAACyB,KAAK,CACtB,8EACF,CAAC;UAAC,OAAAT,SAAA,CAAAd,MAAA;QAAA;UAKJ;UACA,IAAIY,aAAa,EAAE;YACjBI,qBAAO,CAACC,OAAO,CACb,IAAI,EACJ;cACEC,IAAI,EAAE,eAAe;cACrBC,QAAQ,EAAE;YACZ,CAAC,EACDC,yBAAc,CAACI,mBACjB,CAAC;YACD3B,oBAAW,CAACC,MAAM,CAACwB,GAAG,CAAC,2DAA2D,CAAC;UACrF;;UAEA;UACA/B,MAAM,CAACkC,UAAU,CAAC,YAAM;YACtB,IAAMC,SAAS,GAAGlB,YAAY,IAAI,IAAAO,IAAA,CAAAvC,OAAA,EAAS,CAAC;YAE5C7E,YAAY,CAACuG,gBAAgB,CAACyB,IAAI,CAACrB,KAAI,EAAE;cAACE,YAAY,EAAEkB;YAAS,CAAC,CAAC;UACrE,CAAC,EAAEhB,KAAK,CAAC;QAAC;QAAA;UAAA,OAAAI,SAAA,CAAAb,IAAA;MAAA;IAAA,GAAAG,QAAA;EAAA,CACX;EAAA,SA7D8CF,gBAAgBA,CAAA0B,EAAA;IAAA,OAAAzB,iBAAA,CAAA0B,KAAA,OAAAC,SAAA;EAAA;EAAA,OAAhB5B,gBAAgB;AAAA,GA6D9D;;AAED;AACA;AACA;AACA;AACA;AACA;AACAvG,YAAY,CAACoI,aAAa,GAAG,UAACC,QAAa,EAAErE,SAAiB,EAAK;EAAA,IAAAsE,cAAA,EAAAC,qBAAA;EACjE,IAAI,CAAAF,QAAQ,aAARA,QAAQ,wBAAAC,cAAA,GAARD,QAAQ,CAAEG,IAAI,cAAAF,cAAA,wBAAAC,qBAAA,GAAdD,cAAA,CAAgBpE,OAAO,cAAAqE,qBAAA,uBAAvBA,qBAAA,CAAyB3F,MAAM,IAAG,CAAC,EAAE;IACvC,OAAOyF,QAAQ,CAACG,IAAI,CAACtE,OAAO,CAAChB,IAAI,CAAC,UAACkB,MAAM;MAAA,OAAKA,MAAM,CAACC,GAAG,KAAKL,SAAS;IAAA,EAAC;EACzE;EAEA,OAAO,IAAI;AACb,CAAC;;AAED;AACA;AACA;AACA;AACA;AACAhE,YAAY,CAACyI,mBAAmB,GAAG,UAACC,SAAyB,EAAc;EACzE,OACEA,SAAS,CAACC,KAAK,KAAKC,gBAAK,CAACC,KAAK,CAACC,QAAQ,IACxCJ,SAAS,CAACK,gBAAgB,KAAKC,uBAAgB,CAACC,aAAa;AAEjE,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACAjJ,YAAY,CAACkJ,0BAA0B,GAAG,UAACC,KAAU,EAAc;EAAA,IAAAC,WAAA,EAAAC,YAAA,EAAAC,gBAAA,EAAAC,iBAAA;EACjE,IAAMC,eAAe,GAAG,CAAAL,KAAK,aAALA,KAAK,wBAAAC,WAAA,GAALD,KAAK,CAAEX,IAAI,cAAAY,WAAA,uBAAXA,WAAA,CAAaT,KAAK,MAAKc,iBAAM,IAAI,CAAAN,KAAK,aAALA,KAAK,wBAAAE,YAAA,GAALF,KAAK,CAAEX,IAAI,cAAAa,YAAA,uBAAXA,YAAA,CAAaK,MAAM,MAAKC,kBAAO;EACxF,IAAMC,eAAe,GACnB,CAAAT,KAAK,aAALA,KAAK,wBAAAG,gBAAA,GAALH,KAAK,CAAET,SAAS,cAAAY,gBAAA,uBAAhBA,gBAAA,CAAkBX,KAAK,MAAKC,gBAAK,CAACC,KAAK,CAACC,QAAQ,IAChD,CAAAK,KAAK,aAALA,KAAK,wBAAAI,iBAAA,GAALJ,KAAK,CAAET,SAAS,cAAAa,iBAAA,uBAAhBA,iBAAA,CAAkBR,gBAAgB,MAAKC,uBAAgB,CAACC,aAAa;EAEvE,OAAOO,eAAe,IAAII,eAAe;AAC3C,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA5J,YAAY,CAAC6J,kBAAkB,GAAG,UAAC/I,OAAY,EAAEuH,QAAa,EAAErE,SAAiB,EAAK;EACpF,IAAM8F,UAAU,GAAG9J,YAAY,CAACoI,aAAa,CAACC,QAAQ,EAAErE,SAAS,CAAC;EAClE,IAAI8F,UAAU,EAAE;IACd,IAAI,CAACA,UAAU,CAAC5I,aAAa,IAAI,CAAAJ,OAAO,aAAPA,OAAO,uBAAPA,OAAO,CAAEI,aAAa,MAAK4I,UAAU,CAAC5I,aAAa,EAAE;MACpF,OACE4I,UAAU,CAACnB,KAAK,KAAKoB,mBAAQ,IAC5BD,UAAU,CAACnB,KAAK,KAAKc,iBAAM,IAAIK,UAAU,CAACJ,MAAM,KAAKC,kBAAQ;IAElE;EACF;EAEA,OAAO,KAAK;AACd,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA3J,YAAY,CAACgK,kBAAkB,GAAG,UAAC3B,QAAa,EAAK;EAAA,IAAA4B,kBAAA,EAAAC,qBAAA,EAAAC,cAAA;EACnD,OACE,CAAA9B,QAAQ,aAARA,QAAQ,wBAAA4B,kBAAA,GAAR5B,QAAQ,CAAE+B,QAAQ,cAAAH,kBAAA,wBAAAC,qBAAA,GAAlBD,kBAAA,CAAoBI,QAAQ,cAAAH,qBAAA,uBAA5BA,qBAAA,CAA8BI,WAAW,MAAKC,oBAAS,CAACC,aAAa,CAACC,QAAQ,IAC9E,CAAC,EAACpC,QAAQ,aAARA,QAAQ,gBAAA8B,cAAA,GAAR9B,QAAQ,CAAEqC,IAAI,cAAAP,cAAA,eAAdA,cAAA,CAAgBQ,UAAU;AAEhC,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA3K,YAAY,CAAC4K,oBAAoB,GAAG,UAACzB,KAAU,EAAK;EAAA,IAAA0B,iBAAA,EAAAC,YAAA;EAClD,IAAMC,cAAc,GAAG,CAAA5B,KAAK,aAALA,KAAK,wBAAA0B,iBAAA,GAAL1B,KAAK,CAAET,SAAS,cAAAmC,iBAAA,uBAAhBA,iBAAA,CAAkBlC,KAAK,MAAKC,gBAAK,CAACC,KAAK,CAACC,QAAQ;EACvE,IAAMkC,iBAAiB,GAAGhL,YAAY,CAACgK,kBAAkB,CAACb,KAAK,CAAC;EAChE,IAAM8B,UAAU,GAAG,EAAAH,YAAA,GAAA3B,KAAK,CAACX,IAAI,cAAAsC,YAAA,uBAAVA,YAAA,CAAYnC,KAAK,MAAKoB,mBAAQ;EAEjD,OAAOiB,iBAAiB,IAAI,CAACD,cAAc,IAAIE,UAAU;AAC3D,CAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACAjL,YAAY,CAACkL,4BAA4B,GAAG,UAACC,SAAc,EAAEC,aAAkB,EAAK;EAAA,IAAAC,mBAAA,EAAAC,qBAAA,EAAAC,oBAAA,EAAAC,qBAAA,EAAAC,qBAAA,EAAAC,sBAAA,EAAAC,mBAAA,EAAAC,qBAAA,EAAAC,sBAAA;EAClF,IACE,CAAAR,mBAAA,GAAAF,SAAS,CAACf,QAAQ,cAAAiB,mBAAA,gBAAAC,qBAAA,GAAlBD,mBAAA,CAAoBhB,QAAQ,cAAAiB,qBAAA,eAA5BA,qBAAA,CAA8BjH,GAAG,IACjC,EAAAkH,oBAAA,GAAAJ,SAAS,CAACf,QAAQ,cAAAmB,oBAAA,wBAAAC,qBAAA,GAAlBD,oBAAA,CAAoBlB,QAAQ,cAAAmB,qBAAA,uBAA5BA,qBAAA,CAA8BnH,GAAG,QAAAoH,qBAAA,GAAKL,aAAa,CAAChB,QAAQ,cAAAqB,qBAAA,wBAAAC,sBAAA,GAAtBD,qBAAA,CAAwBpB,QAAQ,cAAAqB,sBAAA,uBAAhCA,sBAAA,CAAkCrH,GAAG,GAC3E;IACA,OAAO,IAAI;EACb;EACA,IAAML,SAAS,GAAGoH,aAAa,aAAbA,aAAa,wBAAAO,mBAAA,GAAbP,aAAa,CAAE5C,IAAI,cAAAmD,mBAAA,uBAAnBA,mBAAA,CAAqB3H,SAAS;EAChD,IAAM8H,WAAW,IAAAF,qBAAA,GAAG5L,YAAY,CAACoI,aAAa,CAACgD,aAAa,EAAEpH,SAAS,CAAC,cAAA4H,qBAAA,wBAAAC,sBAAA,GAApDD,qBAAA,CAAsDG,QAAQ,cAAAF,sBAAA,uBAA9DA,sBAAA,CAAiE,CAAC,CAAC;EACvF,IAAIC,WAAW,aAAXA,WAAW,eAAXA,WAAW,CAAEE,QAAQ,IAAIF,WAAW,CAACE,QAAQ,KAAKb,SAAS,CAAC9G,GAAG,EAAE;IACnE,OAAO,IAAI;EACb;EAEA,OAAO,KAAK;AACd,CAAC;AAAC,IAAA4H,QAAA,GAAAC,OAAA,CAAArH,OAAA,GACa7E,YAAY","ignoreList":[]}
|
|
@@ -73,7 +73,6 @@ export declare const _JOINED_ = "JOINED";
|
|
|
73
73
|
export declare const _LOCUS_ID_ = "LOCUS_ID";
|
|
74
74
|
export declare const _LEFT_ = "LEFT";
|
|
75
75
|
export declare const _MOVED_ = "MOVED";
|
|
76
|
-
export declare const _BREAKOUT_ENDED_ = "BREAKOUT_ENDED";
|
|
77
76
|
export declare const _ON_HOLD_LOBBY_ = "ON_HOLD_LOBBY";
|
|
78
77
|
export declare const _MEETING_LINK_ = "MEETING_LINK";
|
|
79
78
|
export declare const _MEETING_UUID_ = "MEETING_UUID";
|
|
@@ -1,14 +1,30 @@
|
|
|
1
|
+
import { Enum } from '../constants';
|
|
1
2
|
import { HtMeta } from '../hashTree/types';
|
|
3
|
+
export declare const EndMeetingReason: {
|
|
4
|
+
readonly maxMeetingDuration: "MAX_MEETING_DURATION";
|
|
5
|
+
readonly allParticipantsLeft: "ALL_PARTICIPANTS_LEFT";
|
|
6
|
+
readonly sipHostLeft: "SIP_HOST_LEFT";
|
|
7
|
+
readonly noHost: "NO_HOST";
|
|
8
|
+
readonly waitingForMpsEndMeetingTimeout: "WAITING_FOR_MPS_END_MEETING_TIMEOUT";
|
|
9
|
+
readonly fraudDetection: "FRAUD_DETECTION";
|
|
10
|
+
readonly meetingEndedByHost: "MEETING_ENDED_BY_HOST";
|
|
11
|
+
readonly meetingUpdated: "MEETING_UPDATED";
|
|
12
|
+
readonly meetingCancelled: "MEETING_CANCELLED";
|
|
13
|
+
readonly autoEndWithSingleParticipant: "AUTO_END_WITH_SINGLE_PARTICIPANT";
|
|
14
|
+
readonly breakoutEnded: "BREAKOUT_ENDED";
|
|
15
|
+
};
|
|
16
|
+
export type EndMeetingReason = Enum<typeof EndMeetingReason>;
|
|
2
17
|
export type LocusFullState = {
|
|
3
18
|
active: boolean;
|
|
4
19
|
count: number;
|
|
5
20
|
lastActive: string;
|
|
6
21
|
locked: boolean;
|
|
7
22
|
sessionId: string;
|
|
8
|
-
|
|
23
|
+
sessionIds: string[];
|
|
9
24
|
startTime: number;
|
|
10
25
|
state: string;
|
|
11
26
|
type: string;
|
|
27
|
+
endMeetingReason?: EndMeetingReason;
|
|
12
28
|
};
|
|
13
29
|
export type Links = {
|
|
14
30
|
services: Record<'breakout' | 'record', {
|
package/dist/webinar/index.js
CHANGED
package/package.json
CHANGED
package/src/constants.ts
CHANGED
|
@@ -103,7 +103,6 @@ export const _JOINED_ = 'JOINED';
|
|
|
103
103
|
export const _LOCUS_ID_ = 'LOCUS_ID';
|
|
104
104
|
export const _LEFT_ = 'LEFT';
|
|
105
105
|
export const _MOVED_ = 'MOVED';
|
|
106
|
-
export const _BREAKOUT_ENDED_ = 'BREAKOUT_ENDED';
|
|
107
106
|
export const _ON_HOLD_LOBBY_ = 'ON_HOLD_LOBBY';
|
|
108
107
|
export const _MEETING_LINK_ = 'MEETING_LINK';
|
|
109
108
|
export const _MEETING_UUID_ = 'MEETING_UUID';
|
|
@@ -418,7 +417,7 @@ export const HEADERS = {
|
|
|
418
417
|
// Meeting actually ended
|
|
419
418
|
export const MEETING_REMOVED_REASON = {
|
|
420
419
|
SELF_REMOVED: 'SELF_REMOVED', // server or host removed you from the meeting
|
|
421
|
-
MEETING_INACTIVE_TERMINATING: 'MEETING_INACTIVE_TERMINATING', // Meeting got ended or everyone left the meeting
|
|
420
|
+
MEETING_INACTIVE_TERMINATING: 'MEETING_INACTIVE_TERMINATING', // Meeting got ended or everyone left the meeting (historically was sent on Locus TERMINATING or INACTIVE, but now only on INACTIVE as that's the final state)
|
|
422
421
|
CLIENT_LEAVE_REQUEST: 'CLIENT_LEAVE_REQUEST', // You triggered leave meeting
|
|
423
422
|
CLIENT_LEAVE_REQUEST_TAB_CLOSED: 'CLIENT_LEAVE_REQUEST_TAB_CLOSED', // You triggered leave meeting, such as closing the browser tab directly
|
|
424
423
|
USER_ENDED_SHARE_STREAMS: 'USER_ENDED_SHARE_STREAMS', // user triggered stop share
|
|
@@ -1249,7 +1249,11 @@ class HashTreeParser {
|
|
|
1249
1249
|
|
|
1250
1250
|
// sync API may return nothing (in that case data will arrive via messages)
|
|
1251
1251
|
// or it may return a response in the same format as messages
|
|
1252
|
+
// We still need to restart the sync timer as a safety net in case the messages don't arrive.
|
|
1253
|
+
this.runSyncAlgorithm(dataSet);
|
|
1254
|
+
|
|
1252
1255
|
if (syncResponse) {
|
|
1256
|
+
// the format of sync response is the same as messages, so we can reuse the same handler
|
|
1253
1257
|
this.handleMessage(syncResponse, 'via sync API');
|
|
1254
1258
|
}
|
|
1255
1259
|
} catch (error) {
|
|
@@ -1392,12 +1396,6 @@ class HashTreeParser {
|
|
|
1392
1396
|
|
|
1393
1397
|
dataSet.hashTree.resize(receivedDataSet.leafCount);
|
|
1394
1398
|
|
|
1395
|
-
// temporary log for the workshop // todo: remove
|
|
1396
|
-
const ourCurrentRootHash = dataSet.hashTree.getRootHash();
|
|
1397
|
-
LoggerProxy.logger.info(
|
|
1398
|
-
`HashTreeParser#runSyncAlgorithm --> ${this.debugId} dataSet="${dataSet.name}" version=${dataSet.version} hashes before starting timer: ours=${ourCurrentRootHash} Locus=${dataSet.root}`
|
|
1399
|
-
);
|
|
1400
|
-
|
|
1401
1399
|
const delay = dataSet.idleMs + this.getWeightedBackoffTime(dataSet.backoff);
|
|
1402
1400
|
|
|
1403
1401
|
if (delay > 0) {
|
|
@@ -1478,6 +1476,7 @@ class HashTreeParser {
|
|
|
1478
1476
|
);
|
|
1479
1477
|
|
|
1480
1478
|
this.enqueueSyncForDataset(dataSet.name, `heartbeat watchdog expired`);
|
|
1479
|
+
this.resetHeartbeatWatchdogs([dataSet]);
|
|
1481
1480
|
}, delay);
|
|
1482
1481
|
}
|
|
1483
1482
|
}
|
package/src/locus-info/index.ts
CHANGED
|
@@ -1820,14 +1820,9 @@ export default class LocusInfo extends EventsScope {
|
|
|
1820
1820
|
);
|
|
1821
1821
|
}
|
|
1822
1822
|
} else if (this.parsedLocus.fullState?.type === _MEETING_) {
|
|
1823
|
-
if (
|
|
1824
|
-
this.fullState &&
|
|
1825
|
-
(this.fullState.state === LOCUS.STATE.INACTIVE ||
|
|
1826
|
-
// @ts-ignore
|
|
1827
|
-
this.fullState.state === LOCUS.STATE.TERMINATING)
|
|
1828
|
-
) {
|
|
1823
|
+
if (this.fullState && MeetingsUtil.isWholeMeetingEnded(this.fullState)) {
|
|
1829
1824
|
LoggerProxy.logger.warn(
|
|
1830
|
-
'Locus-info:index#isMeetingActive --> Meeting is ending due to inactive
|
|
1825
|
+
'Locus-info:index#isMeetingActive --> Meeting is ending due to inactive'
|
|
1831
1826
|
);
|
|
1832
1827
|
|
|
1833
1828
|
// @ts-ignore
|
package/src/locus-info/types.ts
CHANGED
|
@@ -1,15 +1,33 @@
|
|
|
1
|
+
import {Enum} from '../constants';
|
|
1
2
|
import {HtMeta} from '../hashTree/types';
|
|
2
3
|
|
|
4
|
+
export const EndMeetingReason = {
|
|
5
|
+
maxMeetingDuration: 'MAX_MEETING_DURATION',
|
|
6
|
+
allParticipantsLeft: 'ALL_PARTICIPANTS_LEFT',
|
|
7
|
+
sipHostLeft: 'SIP_HOST_LEFT',
|
|
8
|
+
noHost: 'NO_HOST',
|
|
9
|
+
waitingForMpsEndMeetingTimeout: 'WAITING_FOR_MPS_END_MEETING_TIMEOUT',
|
|
10
|
+
fraudDetection: 'FRAUD_DETECTION',
|
|
11
|
+
meetingEndedByHost: 'MEETING_ENDED_BY_HOST',
|
|
12
|
+
meetingUpdated: 'MEETING_UPDATED', // Locus code has comment about EndMeetingIfPossible reason for this one
|
|
13
|
+
meetingCancelled: 'MEETING_CANCELLED', // Locus code has comment about EndMeetingIfPossible reason for this one
|
|
14
|
+
autoEndWithSingleParticipant: 'AUTO_END_WITH_SINGLE_PARTICIPANT',
|
|
15
|
+
breakoutEnded: 'BREAKOUT_ENDED', // indicates that only a breakout session ended, not the whole meeting
|
|
16
|
+
} as const;
|
|
17
|
+
|
|
18
|
+
export type EndMeetingReason = Enum<typeof EndMeetingReason>;
|
|
19
|
+
|
|
3
20
|
export type LocusFullState = {
|
|
4
21
|
active: boolean;
|
|
5
22
|
count: number;
|
|
6
23
|
lastActive: string;
|
|
7
24
|
locked: boolean;
|
|
8
25
|
sessionId: string;
|
|
9
|
-
|
|
26
|
+
sessionIds: string[];
|
|
10
27
|
startTime: number;
|
|
11
28
|
state: string;
|
|
12
29
|
type: string;
|
|
30
|
+
endMeetingReason?: EndMeetingReason;
|
|
13
31
|
};
|
|
14
32
|
|
|
15
33
|
export type Links = {
|
package/src/meetings/util.ts
CHANGED
|
@@ -7,7 +7,6 @@ import {
|
|
|
7
7
|
_LEFT_,
|
|
8
8
|
DESTINATION_TYPE,
|
|
9
9
|
_MOVED_,
|
|
10
|
-
_BREAKOUT_ENDED_,
|
|
11
10
|
BREAKOUTS,
|
|
12
11
|
EVENT_TRIGGERS,
|
|
13
12
|
LOCUS,
|
|
@@ -19,6 +18,7 @@ import Trigger from '../common/events/trigger-proxy';
|
|
|
19
18
|
import BEHAVIORAL_METRICS from '../metrics/constants';
|
|
20
19
|
import Metrics from '../metrics';
|
|
21
20
|
import {MEETING_KEY} from './meetings.types';
|
|
21
|
+
import {EndMeetingReason, LocusFullState} from '../locus-info/types';
|
|
22
22
|
|
|
23
23
|
/**
|
|
24
24
|
* Meetings Media Codec Missing Event
|
|
@@ -267,6 +267,18 @@ MeetingsUtil.getThisDevice = (newLocus: any, deviceUrl: string) => {
|
|
|
267
267
|
return null;
|
|
268
268
|
};
|
|
269
269
|
|
|
270
|
+
/**
|
|
271
|
+
* Checks if the fullState indicates the meeting has fully ended (not just a breakout move).
|
|
272
|
+
* @param {Object} fullState locus fullState data
|
|
273
|
+
* @returns {boolean}
|
|
274
|
+
*/
|
|
275
|
+
MeetingsUtil.isWholeMeetingEnded = (fullState: LocusFullState): boolean => {
|
|
276
|
+
return (
|
|
277
|
+
fullState.state === LOCUS.STATE.INACTIVE &&
|
|
278
|
+
fullState.endMeetingReason !== EndMeetingReason.breakoutEnded
|
|
279
|
+
);
|
|
280
|
+
};
|
|
281
|
+
|
|
270
282
|
/**
|
|
271
283
|
* Checks if the self state in a locus indicates a breakout move or breakout end.
|
|
272
284
|
* Returns true when:
|
|
@@ -279,7 +291,7 @@ MeetingsUtil.isSelfMovedOrBreakoutEnded = (locus: any): boolean => {
|
|
|
279
291
|
const isSelfLeftMoved = locus?.self?.state === _LEFT_ && locus?.self?.reason === _MOVED_;
|
|
280
292
|
const isBreakoutEnded =
|
|
281
293
|
locus?.fullState?.state === LOCUS.STATE.INACTIVE &&
|
|
282
|
-
locus?.fullState?.endMeetingReason ===
|
|
294
|
+
locus?.fullState?.endMeetingReason === EndMeetingReason.breakoutEnded;
|
|
283
295
|
|
|
284
296
|
return isSelfLeftMoved || isBreakoutEnded;
|
|
285
297
|
};
|
|
@@ -2052,6 +2052,79 @@ describe('HashTreeParser', () => {
|
|
|
2052
2052
|
},
|
|
2053
2053
|
});
|
|
2054
2054
|
});
|
|
2055
|
+
|
|
2056
|
+
it('restarts the sync timer when sync response is empty so that a future sync can be triggered', async () => {
|
|
2057
|
+
const parser = createHashTreeParser();
|
|
2058
|
+
|
|
2059
|
+
// Send a heartbeat with a mismatched root hash to trigger runSyncAlgorithm
|
|
2060
|
+
const heartbeatMessage = {
|
|
2061
|
+
dataSets: [
|
|
2062
|
+
{
|
|
2063
|
+
...createDataSet('main', 16, 1100),
|
|
2064
|
+
root: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1', // different from ours
|
|
2065
|
+
},
|
|
2066
|
+
],
|
|
2067
|
+
visibleDataSetsUrl,
|
|
2068
|
+
locusUrl,
|
|
2069
|
+
};
|
|
2070
|
+
|
|
2071
|
+
parser.handleMessage(heartbeatMessage, 'heartbeat with mismatch');
|
|
2072
|
+
|
|
2073
|
+
// The sync timer should be set
|
|
2074
|
+
expect(parser.dataSets.main.timer).to.not.be.undefined;
|
|
2075
|
+
|
|
2076
|
+
// Mock responses for the first sync - return null (204/empty body)
|
|
2077
|
+
const mainDataSetUrl = parser.dataSets.main.url;
|
|
2078
|
+
mockGetHashesFromLocusResponse(
|
|
2079
|
+
mainDataSetUrl,
|
|
2080
|
+
new Array(16).fill('00000000000000000000000000000000'),
|
|
2081
|
+
{
|
|
2082
|
+
...createDataSet('main', 16, 1101),
|
|
2083
|
+
root: 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb', // still mismatched
|
|
2084
|
+
}
|
|
2085
|
+
);
|
|
2086
|
+
mockSendSyncRequestResponse(mainDataSetUrl, null);
|
|
2087
|
+
|
|
2088
|
+
// Advance time to fire the sync timer (idleMs=1000 + backoff=0)
|
|
2089
|
+
await clock.tickAsync(1000);
|
|
2090
|
+
|
|
2091
|
+
// Verify sync was triggered
|
|
2092
|
+
assert.calledWith(
|
|
2093
|
+
webexRequest,
|
|
2094
|
+
sinon.match({
|
|
2095
|
+
method: 'POST',
|
|
2096
|
+
uri: `${mainDataSetUrl}/sync`,
|
|
2097
|
+
})
|
|
2098
|
+
);
|
|
2099
|
+
|
|
2100
|
+
// After empty response, runSyncAlgorithm should have been called,
|
|
2101
|
+
// setting a new sync timer as a safety net
|
|
2102
|
+
expect(parser.dataSets.main.timer).to.not.be.undefined;
|
|
2103
|
+
|
|
2104
|
+
// Reset and set up mocks for the second sync
|
|
2105
|
+
webexRequest.resetHistory();
|
|
2106
|
+
mockGetHashesFromLocusResponse(
|
|
2107
|
+
mainDataSetUrl,
|
|
2108
|
+
new Array(16).fill('00000000000000000000000000000000'),
|
|
2109
|
+
{
|
|
2110
|
+
...createDataSet('main', 16, 1102),
|
|
2111
|
+
root: 'cccccccccccccccccccccccccccccccc', // still mismatched
|
|
2112
|
+
}
|
|
2113
|
+
);
|
|
2114
|
+
mockSendSyncRequestResponse(mainDataSetUrl, null);
|
|
2115
|
+
|
|
2116
|
+
// Advance time again to fire the second sync timer
|
|
2117
|
+
await clock.tickAsync(1000);
|
|
2118
|
+
|
|
2119
|
+
// Verify a second sync was triggered
|
|
2120
|
+
assert.calledWith(
|
|
2121
|
+
webexRequest,
|
|
2122
|
+
sinon.match({
|
|
2123
|
+
method: 'POST',
|
|
2124
|
+
uri: `${mainDataSetUrl}/sync`,
|
|
2125
|
+
})
|
|
2126
|
+
);
|
|
2127
|
+
});
|
|
2055
2128
|
});
|
|
2056
2129
|
|
|
2057
2130
|
describe('handles visible data sets changes correctly', () => {
|
|
@@ -3119,7 +3192,77 @@ describe('HashTreeParser', () => {
|
|
|
3119
3192
|
expect(parser.dataSets.main.heartbeatWatchdogTimer).to.not.be.undefined;
|
|
3120
3193
|
expect(parser.dataSets['atd-active']?.heartbeatWatchdogTimer).to.be.undefined;
|
|
3121
3194
|
});
|
|
3195
|
+
|
|
3196
|
+
it('restarts the watchdog timer after it fires so that future missed heartbeats still trigger syncs', async () => {
|
|
3197
|
+
const parser = createHashTreeParser();
|
|
3198
|
+
const heartbeatIntervalMs = 5000;
|
|
3199
|
+
|
|
3200
|
+
// Send initial heartbeat for 'main'
|
|
3201
|
+
const heartbeatMessage = {
|
|
3202
|
+
dataSets: [
|
|
3203
|
+
{
|
|
3204
|
+
...createDataSet('main', 16, 1100),
|
|
3205
|
+
root: parser.dataSets.main.hashTree.getRootHash(),
|
|
3206
|
+
},
|
|
3207
|
+
],
|
|
3208
|
+
visibleDataSetsUrl,
|
|
3209
|
+
locusUrl,
|
|
3210
|
+
heartbeatIntervalMs,
|
|
3211
|
+
};
|
|
3212
|
+
|
|
3213
|
+
parser.handleMessage(heartbeatMessage, 'initial heartbeat');
|
|
3214
|
+
expect(parser.dataSets.main.heartbeatWatchdogTimer).to.not.be.undefined;
|
|
3215
|
+
|
|
3216
|
+
// Mock responses for performSync - return null (204/empty body)
|
|
3217
|
+
const mainDataSetUrl = parser.dataSets.main.url;
|
|
3218
|
+
mockGetHashesFromLocusResponse(
|
|
3219
|
+
mainDataSetUrl,
|
|
3220
|
+
new Array(16).fill('00000000000000000000000000000000'),
|
|
3221
|
+
createDataSet('main', 16, 1101)
|
|
3222
|
+
);
|
|
3223
|
+
mockSendSyncRequestResponse(mainDataSetUrl, null);
|
|
3224
|
+
|
|
3225
|
+
// Advance time past heartbeatIntervalMs to fire the watchdog
|
|
3226
|
+
await clock.tickAsync(heartbeatIntervalMs);
|
|
3227
|
+
|
|
3228
|
+
// Verify sync was triggered
|
|
3229
|
+
assert.calledWith(
|
|
3230
|
+
webexRequest,
|
|
3231
|
+
sinon.match({
|
|
3232
|
+
method: 'GET',
|
|
3233
|
+
uri: `${mainDataSetUrl}/hashtree`,
|
|
3234
|
+
})
|
|
3235
|
+
);
|
|
3236
|
+
|
|
3237
|
+
// The watchdog timer should have been restarted after firing
|
|
3238
|
+
expect(parser.dataSets.main.heartbeatWatchdogTimer).to.not.be.undefined;
|
|
3239
|
+
|
|
3240
|
+
// Reset call history and set up new mock responses for the second sync
|
|
3241
|
+
webexRequest.resetHistory();
|
|
3242
|
+
mockGetHashesFromLocusResponse(
|
|
3243
|
+
mainDataSetUrl,
|
|
3244
|
+
new Array(16).fill('00000000000000000000000000000000'),
|
|
3245
|
+
createDataSet('main', 16, 1102)
|
|
3246
|
+
);
|
|
3247
|
+
mockSendSyncRequestResponse(mainDataSetUrl, null);
|
|
3248
|
+
|
|
3249
|
+
// Advance time again to fire the watchdog a second time
|
|
3250
|
+
await clock.tickAsync(heartbeatIntervalMs);
|
|
3251
|
+
|
|
3252
|
+
// Verify a second sync was triggered
|
|
3253
|
+
assert.calledWith(
|
|
3254
|
+
webexRequest,
|
|
3255
|
+
sinon.match({
|
|
3256
|
+
method: 'GET',
|
|
3257
|
+
uri: `${mainDataSetUrl}/hashtree`,
|
|
3258
|
+
})
|
|
3259
|
+
);
|
|
3260
|
+
|
|
3261
|
+
// And the watchdog should still be running
|
|
3262
|
+
expect(parser.dataSets.main.heartbeatWatchdogTimer).to.not.be.undefined;
|
|
3263
|
+
});
|
|
3122
3264
|
});
|
|
3265
|
+
|
|
3123
3266
|
});
|
|
3124
3267
|
|
|
3125
3268
|
describe('#callLocusInfoUpdateCallback filtering', () => {
|
|
@@ -4718,6 +4718,9 @@ describe('plugin-meetings', () => {
|
|
|
4718
4718
|
});
|
|
4719
4719
|
|
|
4720
4720
|
describe('#isMeetingActive', () => {
|
|
4721
|
+
beforeEach(() => {
|
|
4722
|
+
webex.internal.newMetrics.submitClientEvent.resetHistory();
|
|
4723
|
+
});
|
|
4721
4724
|
forEach([_CALL_, _SIP_BRIDGE_, _SPACE_SHARE_], (type) => {
|
|
4722
4725
|
describe(`type = ${type}`, () => {
|
|
4723
4726
|
it('sends client event correctly for state = inactive', () => {
|
|
@@ -4784,7 +4787,7 @@ describe('plugin-meetings', () => {
|
|
|
4784
4787
|
});
|
|
4785
4788
|
});
|
|
4786
4789
|
|
|
4787
|
-
it('sends client event correctly for state =
|
|
4790
|
+
it('sends client event correctly for state = MEETING_INACTIVE', () => {
|
|
4788
4791
|
locusInfo.getLocusPartner = sinon.stub().returns({state: MEETING_STATE.STATES.LEFT});
|
|
4789
4792
|
locusInfo.parsedLocus = {
|
|
4790
4793
|
fullState: {
|
|
@@ -4806,7 +4809,7 @@ describe('plugin-meetings', () => {
|
|
|
4806
4809
|
});
|
|
4807
4810
|
});
|
|
4808
4811
|
|
|
4809
|
-
it('
|
|
4812
|
+
it('does not send client event when state = INACTIVE and endMeetingReason = BREAKOUT_ENDED', () => {
|
|
4810
4813
|
locusInfo.getLocusPartner = sinon.stub().returns({state: MEETING_STATE.STATES.LEFT});
|
|
4811
4814
|
locusInfo.parsedLocus = {
|
|
4812
4815
|
fullState: {
|
|
@@ -4815,17 +4818,41 @@ describe('plugin-meetings', () => {
|
|
|
4815
4818
|
};
|
|
4816
4819
|
|
|
4817
4820
|
locusInfo.fullState = {
|
|
4818
|
-
|
|
4821
|
+
state: LOCUS.STATE.INACTIVE,
|
|
4822
|
+
endMeetingReason: 'BREAKOUT_ENDED',
|
|
4819
4823
|
};
|
|
4820
4824
|
|
|
4821
4825
|
locusInfo.isMeetingActive();
|
|
4822
4826
|
|
|
4823
|
-
assert.
|
|
4824
|
-
|
|
4825
|
-
|
|
4826
|
-
|
|
4827
|
+
assert.notCalled(webex.internal.newMetrics.submitClientEvent);
|
|
4828
|
+
});
|
|
4829
|
+
|
|
4830
|
+
it('sends client event correctly for state self removed', () => {
|
|
4831
|
+
locusInfo.emitScoped = sinon.stub();
|
|
4832
|
+
locusInfo.parsedLocus = {
|
|
4833
|
+
fullState: {
|
|
4834
|
+
type: _MEETING_,
|
|
4827
4835
|
},
|
|
4828
|
-
|
|
4836
|
+
self: {
|
|
4837
|
+
removed: true,
|
|
4838
|
+
}
|
|
4839
|
+
};
|
|
4840
|
+
|
|
4841
|
+
locusInfo.isMeetingActive();
|
|
4842
|
+
|
|
4843
|
+
assert.notCalled(webex.internal.newMetrics.submitClientEvent);
|
|
4844
|
+
assert.calledOnceWithExactly(
|
|
4845
|
+
locusInfo.emitScoped,
|
|
4846
|
+
{
|
|
4847
|
+
file: 'locus-info',
|
|
4848
|
+
function: 'isMeetingActive',
|
|
4849
|
+
},
|
|
4850
|
+
EVENTS.DESTROY_MEETING,
|
|
4851
|
+
{
|
|
4852
|
+
reason: MEETING_REMOVED_REASON.SELF_REMOVED,
|
|
4853
|
+
shouldLeave: false,
|
|
4854
|
+
}
|
|
4855
|
+
);
|
|
4829
4856
|
});
|
|
4830
4857
|
});
|
|
4831
4858
|
|