@webex/plugin-meetings 3.6.0-next.1 → 3.6.0-next.10

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.
Files changed (48) hide show
  1. package/dist/breakouts/breakout.js +1 -1
  2. package/dist/breakouts/index.js +1 -1
  3. package/dist/common/errors/webinar-registration-error.js +50 -0
  4. package/dist/common/errors/webinar-registration-error.js.map +1 -0
  5. package/dist/constants.js +7 -0
  6. package/dist/constants.js.map +1 -1
  7. package/dist/index.js +7 -0
  8. package/dist/index.js.map +1 -1
  9. package/dist/interpretation/index.js +1 -1
  10. package/dist/interpretation/siLanguage.js +1 -1
  11. package/dist/locus-info/parser.js +5 -1
  12. package/dist/locus-info/parser.js.map +1 -1
  13. package/dist/meeting/index.js +146 -99
  14. package/dist/meeting/index.js.map +1 -1
  15. package/dist/meeting/muteState.js +5 -2
  16. package/dist/meeting/muteState.js.map +1 -1
  17. package/dist/meeting-info/meeting-info-v2.js +68 -17
  18. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  19. package/dist/meetings/index.js +2 -1
  20. package/dist/meetings/index.js.map +1 -1
  21. package/dist/metrics/constants.js +2 -1
  22. package/dist/metrics/constants.js.map +1 -1
  23. package/dist/multistream/remoteMedia.js +4 -0
  24. package/dist/multistream/remoteMedia.js.map +1 -1
  25. package/dist/types/common/errors/webinar-registration-error.d.ts +14 -0
  26. package/dist/types/constants.d.ts +6 -0
  27. package/dist/types/index.d.ts +2 -1
  28. package/dist/types/meeting/muteState.d.ts +2 -1
  29. package/dist/types/meeting-info/meeting-info-v2.d.ts +23 -0
  30. package/dist/types/metrics/constants.d.ts +1 -0
  31. package/dist/types/multistream/remoteMedia.d.ts +1 -0
  32. package/dist/webinar/index.js +1 -1
  33. package/package.json +21 -21
  34. package/src/common/errors/webinar-registration-error.ts +27 -0
  35. package/src/constants.ts +6 -0
  36. package/src/index.ts +2 -0
  37. package/src/locus-info/parser.ts +8 -1
  38. package/src/meeting/index.ts +40 -11
  39. package/src/meeting/muteState.ts +6 -2
  40. package/src/meeting-info/meeting-info-v2.ts +51 -0
  41. package/src/meetings/index.ts +3 -1
  42. package/src/metrics/constants.ts +1 -0
  43. package/src/multistream/remoteMedia.ts +5 -0
  44. package/test/unit/spec/locus-info/index.js +29 -0
  45. package/test/unit/spec/meeting/index.js +60 -1
  46. package/test/unit/spec/meeting/muteState.js +8 -4
  47. package/test/unit/spec/meeting-info/meetinginfov2.js +37 -0
  48. package/test/unit/spec/multistream/remoteMedia.ts +16 -2
@@ -99,6 +99,7 @@ var RemoteMedia = exports.RemoteMedia = /*#__PURE__*/function (_EventsScope) {
99
99
  * to restrict the requested resolution to this size
100
100
  * @param width width of the video element
101
101
  * @param height height of the video element
102
+ * @note width/height of 0 will be ignored
102
103
  */
103
104
  (0, _createClass2.default)(RemoteMedia, [{
104
105
  key: "setSizeHint",
@@ -106,6 +107,9 @@ var RemoteMedia = exports.RemoteMedia = /*#__PURE__*/function (_EventsScope) {
106
107
  var _this$receiveSlot;
107
108
  // only base on height for now
108
109
  var fs;
110
+ if (width === 0 || height === 0) {
111
+ return;
112
+ }
109
113
  if (height < 135) {
110
114
  fs = 60;
111
115
  } else if (height < 270) {
@@ -1 +1 @@
1
- {"version":3,"names":["_loggerProxy","_interopRequireDefault","require","_eventsScope","_receiveSlot","_createSuper","Derived","hasNativeReflectConstruct","_isNativeReflectConstruct","_createSuperInternal","Super","_getPrototypeOf2","default","result","NewTarget","constructor","_Reflect$construct","arguments","apply","_possibleConstructorReturn2","Reflect","sham","Proxy","Boolean","prototype","valueOf","call","e","RemoteMediaEvents","exports","SourceUpdate","ReceiveSlotEvents","Stopped","getMaxFs","paneSize","maxFs","LoggerProxy","logger","warn","concat","remoteMediaCounter","RemoteMedia","_EventsScope","_inherits2","_super","receiveSlot","mediaRequestManager","options","_this","_classCallCheck2","_defineProperty2","_assertThisInitialized2","setupEventListeners","id","_createClass2","key","value","setSizeHint","width","height","_this$receiveSlot","fs","setMaxFs","stop","_this$receiveSlot2","commit","length","undefined","cancelMediaRequest","removeAllListeners","emit","file","function","sendMediaRequest","csi","mediaRequestId","Error","addRequest","policyInfo","policy","receiveSlots","codecInfo","resolution","codec","cancelRequest","_this2","scope","on","data","get","_this$receiveSlot3","mediaType","_this$receiveSlot4","memberId","_this$receiveSlot5","_this$receiveSlot6","sourceState","_this$receiveSlot7","stream","getUnderlyingReceiveSlot","EventsScope"],"sources":["remoteMedia.ts"],"sourcesContent":["/* eslint-disable valid-jsdoc */\nimport {MediaType, StreamState} from '@webex/internal-media-core';\nimport LoggerProxy from '../common/logs/logger-proxy';\nimport EventsScope from '../common/events/events-scope';\n\nimport {MediaRequestId, MediaRequestManager} from './mediaRequestManager';\nimport {CSI, ReceiveSlot, ReceiveSlotEvents} from './receiveSlot';\n\nexport const RemoteMediaEvents = {\n SourceUpdate: ReceiveSlotEvents.SourceUpdate,\n Stopped: 'stopped',\n};\n\nexport type RemoteVideoResolution =\n | 'thumbnail' // the smallest possible resolution, 90p or less\n | 'very small' // 180p or less\n | 'small' // 360p or less\n | 'medium' // 720p or less\n | 'large' // 1080p or less\n | 'best'; // highest possible resolution\n\n/**\n * Converts pane size into h264 maxFs\n * @param {PaneSize} paneSize\n * @returns {number}\n */\nexport function getMaxFs(paneSize: RemoteVideoResolution): number {\n let maxFs;\n\n switch (paneSize) {\n case 'thumbnail':\n maxFs = 60;\n break;\n case 'very small':\n maxFs = 240;\n break;\n case 'small':\n maxFs = 920;\n break;\n case 'medium':\n maxFs = 3600;\n break;\n case 'large':\n maxFs = 8192;\n break;\n case 'best':\n maxFs = 8192; // for now 'best' is 1080p, so same as 'large'\n break;\n default:\n LoggerProxy.logger.warn(\n `RemoteMedia#getMaxFs --> unsupported paneSize: ${paneSize}, using \"medium\" instead`\n );\n maxFs = 3600;\n }\n\n return maxFs;\n}\n\ntype Options = {\n resolution?: RemoteVideoResolution; // applies only to groups of type MediaType.VideoMain and MediaType.VideoSlides\n};\n\nexport type RemoteMediaId = string;\n\nlet remoteMediaCounter = 0;\n\n/**\n * Class representing a remote audio/video stream.\n *\n * Internally it is associated with a specific receive slot\n * and a media request for it.\n */\nexport class RemoteMedia extends EventsScope {\n private receiveSlot?: ReceiveSlot;\n\n private readonly mediaRequestManager: MediaRequestManager;\n\n private readonly options: Options;\n\n private mediaRequestId?: MediaRequestId;\n\n public readonly id: RemoteMediaId;\n\n /**\n * Constructs RemoteMedia instance\n *\n * @param receiveSlot\n * @param mediaRequestManager\n * @param options\n */\n constructor(\n receiveSlot: ReceiveSlot,\n mediaRequestManager: MediaRequestManager,\n options?: Options\n ) {\n super();\n remoteMediaCounter += 1;\n this.receiveSlot = receiveSlot;\n this.mediaRequestManager = mediaRequestManager;\n this.options = options || {};\n this.setupEventListeners();\n this.id = `RM${remoteMediaCounter}-${this.receiveSlot.id}`;\n }\n\n /**\n * Supply the width and height of the video element\n * to restrict the requested resolution to this size\n * @param width width of the video element\n * @param height height of the video element\n */\n public setSizeHint(width, height) {\n // only base on height for now\n let fs: number;\n\n if (height < 135) {\n fs = 60;\n } else if (height < 270) {\n fs = 240;\n } else if (height < 540) {\n fs = 920;\n } else if (height <= 720) {\n fs = 3600;\n } else {\n fs = 8192;\n }\n\n this.receiveSlot?.setMaxFs(fs);\n }\n\n /**\n * Invalidates the remote media by clearing the reference to a receive slot and\n * cancelling the media request.\n * After this call the remote media is unusable.\n *\n * @param {boolean} commit - whether to commit the cancellation of the media request\n * @internal\n */\n public stop(commit = true) {\n this.cancelMediaRequest(commit);\n this.receiveSlot?.removeAllListeners();\n this.receiveSlot = undefined;\n this.emit(\n {\n file: 'multistream/remoteMedia',\n function: 'stop',\n },\n RemoteMediaEvents.Stopped,\n {}\n );\n }\n\n /**\n * Sends a new media request. This method can only be used for receiver-selected policy,\n * because only in that policy we have a 1-1 relationship between RemoteMedia and MediaRequest\n * and the request id is then stored in this RemoteMedia instance.\n * For active-speaker policy, the same request is shared among many RemoteMedia instances,\n * so it's managed through RemoteMediaGroup\n *\n * @internal\n */\n public sendMediaRequest(csi: CSI, commit: boolean) {\n if (this.mediaRequestId) {\n this.cancelMediaRequest(false);\n }\n\n if (!this.receiveSlot) {\n throw new Error('sendMediaRequest() called on an invalidated RemoteMedia instance');\n }\n\n this.mediaRequestId = this.mediaRequestManager.addRequest(\n {\n policyInfo: {\n policy: 'receiver-selected',\n csi,\n },\n receiveSlots: [this.receiveSlot],\n codecInfo: this.options.resolution && {\n codec: 'h264',\n maxFs: getMaxFs(this.options.resolution),\n },\n },\n commit\n );\n }\n\n /**\n * @internal\n */\n public cancelMediaRequest(commit: boolean) {\n if (this.mediaRequestId) {\n this.mediaRequestManager.cancelRequest(this.mediaRequestId, commit);\n this.mediaRequestId = undefined;\n }\n }\n\n /**\n * registers event listeners on the receive slot and forwards all the events\n */\n private setupEventListeners() {\n if (this.receiveSlot) {\n const scope = {\n file: 'multistream/remoteMedia',\n function: 'setupEventListeners',\n };\n\n this.receiveSlot.on(ReceiveSlotEvents.SourceUpdate, (data) => {\n this.emit(scope, RemoteMediaEvents.SourceUpdate, data);\n });\n }\n }\n\n /**\n * Getter for mediaType\n */\n public get mediaType(): MediaType {\n return this.receiveSlot?.mediaType;\n }\n\n /**\n * Getter for memberId\n */\n public get memberId() {\n return this.receiveSlot?.memberId;\n }\n\n /**\n * Getter for csi\n */\n public get csi() {\n return this.receiveSlot?.csi;\n }\n\n /**\n * Getter for source state\n */\n public get sourceState(): StreamState {\n return this.receiveSlot?.sourceState;\n }\n\n /**\n * Getter for remote media stream\n */\n public get stream() {\n return this.receiveSlot?.stream;\n }\n\n /**\n * @internal\n * @returns {ReceiveSlot}\n */\n public getUnderlyingReceiveSlot() {\n return this.receiveSlot;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"names":["_loggerProxy","_interopRequireDefault","require","_eventsScope","_receiveSlot","_createSuper","Derived","hasNativeReflectConstruct","_isNativeReflectConstruct","_createSuperInternal","Super","_getPrototypeOf2","default","result","NewTarget","constructor","_Reflect$construct","arguments","apply","_possibleConstructorReturn2","Reflect","sham","Proxy","Boolean","prototype","valueOf","call","e","RemoteMediaEvents","exports","SourceUpdate","ReceiveSlotEvents","Stopped","getMaxFs","paneSize","maxFs","LoggerProxy","logger","warn","concat","remoteMediaCounter","RemoteMedia","_EventsScope","_inherits2","_super","receiveSlot","mediaRequestManager","options","_this","_classCallCheck2","_defineProperty2","_assertThisInitialized2","setupEventListeners","id","_createClass2","key","value","setSizeHint","width","height","_this$receiveSlot","fs","setMaxFs","stop","_this$receiveSlot2","commit","length","undefined","cancelMediaRequest","removeAllListeners","emit","file","function","sendMediaRequest","csi","mediaRequestId","Error","addRequest","policyInfo","policy","receiveSlots","codecInfo","resolution","codec","cancelRequest","_this2","scope","on","data","get","_this$receiveSlot3","mediaType","_this$receiveSlot4","memberId","_this$receiveSlot5","_this$receiveSlot6","sourceState","_this$receiveSlot7","stream","getUnderlyingReceiveSlot","EventsScope"],"sources":["remoteMedia.ts"],"sourcesContent":["/* eslint-disable valid-jsdoc */\nimport {MediaType, StreamState} from '@webex/internal-media-core';\nimport LoggerProxy from '../common/logs/logger-proxy';\nimport EventsScope from '../common/events/events-scope';\n\nimport {MediaRequestId, MediaRequestManager} from './mediaRequestManager';\nimport {CSI, ReceiveSlot, ReceiveSlotEvents} from './receiveSlot';\n\nexport const RemoteMediaEvents = {\n SourceUpdate: ReceiveSlotEvents.SourceUpdate,\n Stopped: 'stopped',\n};\n\nexport type RemoteVideoResolution =\n | 'thumbnail' // the smallest possible resolution, 90p or less\n | 'very small' // 180p or less\n | 'small' // 360p or less\n | 'medium' // 720p or less\n | 'large' // 1080p or less\n | 'best'; // highest possible resolution\n\n/**\n * Converts pane size into h264 maxFs\n * @param {PaneSize} paneSize\n * @returns {number}\n */\nexport function getMaxFs(paneSize: RemoteVideoResolution): number {\n let maxFs;\n\n switch (paneSize) {\n case 'thumbnail':\n maxFs = 60;\n break;\n case 'very small':\n maxFs = 240;\n break;\n case 'small':\n maxFs = 920;\n break;\n case 'medium':\n maxFs = 3600;\n break;\n case 'large':\n maxFs = 8192;\n break;\n case 'best':\n maxFs = 8192; // for now 'best' is 1080p, so same as 'large'\n break;\n default:\n LoggerProxy.logger.warn(\n `RemoteMedia#getMaxFs --> unsupported paneSize: ${paneSize}, using \"medium\" instead`\n );\n maxFs = 3600;\n }\n\n return maxFs;\n}\n\ntype Options = {\n resolution?: RemoteVideoResolution; // applies only to groups of type MediaType.VideoMain and MediaType.VideoSlides\n};\n\nexport type RemoteMediaId = string;\n\nlet remoteMediaCounter = 0;\n\n/**\n * Class representing a remote audio/video stream.\n *\n * Internally it is associated with a specific receive slot\n * and a media request for it.\n */\nexport class RemoteMedia extends EventsScope {\n private receiveSlot?: ReceiveSlot;\n\n private readonly mediaRequestManager: MediaRequestManager;\n\n private readonly options: Options;\n\n private mediaRequestId?: MediaRequestId;\n\n public readonly id: RemoteMediaId;\n\n /**\n * Constructs RemoteMedia instance\n *\n * @param receiveSlot\n * @param mediaRequestManager\n * @param options\n */\n constructor(\n receiveSlot: ReceiveSlot,\n mediaRequestManager: MediaRequestManager,\n options?: Options\n ) {\n super();\n remoteMediaCounter += 1;\n this.receiveSlot = receiveSlot;\n this.mediaRequestManager = mediaRequestManager;\n this.options = options || {};\n this.setupEventListeners();\n this.id = `RM${remoteMediaCounter}-${this.receiveSlot.id}`;\n }\n\n /**\n * Supply the width and height of the video element\n * to restrict the requested resolution to this size\n * @param width width of the video element\n * @param height height of the video element\n * @note width/height of 0 will be ignored\n */\n public setSizeHint(width, height) {\n // only base on height for now\n let fs: number;\n\n if (width === 0 || height === 0) {\n return;\n }\n\n if (height < 135) {\n fs = 60;\n } else if (height < 270) {\n fs = 240;\n } else if (height < 540) {\n fs = 920;\n } else if (height <= 720) {\n fs = 3600;\n } else {\n fs = 8192;\n }\n\n this.receiveSlot?.setMaxFs(fs);\n }\n\n /**\n * Invalidates the remote media by clearing the reference to a receive slot and\n * cancelling the media request.\n * After this call the remote media is unusable.\n *\n * @param {boolean} commit - whether to commit the cancellation of the media request\n * @internal\n */\n public stop(commit = true) {\n this.cancelMediaRequest(commit);\n this.receiveSlot?.removeAllListeners();\n this.receiveSlot = undefined;\n this.emit(\n {\n file: 'multistream/remoteMedia',\n function: 'stop',\n },\n RemoteMediaEvents.Stopped,\n {}\n );\n }\n\n /**\n * Sends a new media request. This method can only be used for receiver-selected policy,\n * because only in that policy we have a 1-1 relationship between RemoteMedia and MediaRequest\n * and the request id is then stored in this RemoteMedia instance.\n * For active-speaker policy, the same request is shared among many RemoteMedia instances,\n * so it's managed through RemoteMediaGroup\n *\n * @internal\n */\n public sendMediaRequest(csi: CSI, commit: boolean) {\n if (this.mediaRequestId) {\n this.cancelMediaRequest(false);\n }\n\n if (!this.receiveSlot) {\n throw new Error('sendMediaRequest() called on an invalidated RemoteMedia instance');\n }\n\n this.mediaRequestId = this.mediaRequestManager.addRequest(\n {\n policyInfo: {\n policy: 'receiver-selected',\n csi,\n },\n receiveSlots: [this.receiveSlot],\n codecInfo: this.options.resolution && {\n codec: 'h264',\n maxFs: getMaxFs(this.options.resolution),\n },\n },\n commit\n );\n }\n\n /**\n * @internal\n */\n public cancelMediaRequest(commit: boolean) {\n if (this.mediaRequestId) {\n this.mediaRequestManager.cancelRequest(this.mediaRequestId, commit);\n this.mediaRequestId = undefined;\n }\n }\n\n /**\n * registers event listeners on the receive slot and forwards all the events\n */\n private setupEventListeners() {\n if (this.receiveSlot) {\n const scope = {\n file: 'multistream/remoteMedia',\n function: 'setupEventListeners',\n };\n\n this.receiveSlot.on(ReceiveSlotEvents.SourceUpdate, (data) => {\n this.emit(scope, RemoteMediaEvents.SourceUpdate, data);\n });\n }\n }\n\n /**\n * Getter for mediaType\n */\n public get mediaType(): MediaType {\n return this.receiveSlot?.mediaType;\n }\n\n /**\n * Getter for memberId\n */\n public get memberId() {\n return this.receiveSlot?.memberId;\n }\n\n /**\n * Getter for csi\n */\n public get csi() {\n return this.receiveSlot?.csi;\n }\n\n /**\n * Getter for source state\n */\n public get sourceState(): StreamState {\n return this.receiveSlot?.sourceState;\n }\n\n /**\n * Getter for remote media stream\n */\n public get stream() {\n return this.receiveSlot?.stream;\n }\n\n /**\n * @internal\n * @returns {ReceiveSlot}\n */\n public getUnderlyingReceiveSlot() {\n return this.receiveSlot;\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Error occurred while the webinar required registration
3
+ */
4
+ export default class WebinarRegistrationError extends Error {
5
+ code: number;
6
+ error: any;
7
+ sdkMessage: string;
8
+ /**
9
+ * @constructor
10
+ * @param {String} [message]
11
+ * @param {Object} [error]
12
+ */
13
+ constructor(message?: string, error?: any);
14
+ }
@@ -406,6 +406,11 @@ export declare const ERROR_DICTIONARY: {
406
406
  MESSAGE: string;
407
407
  CODE: number;
408
408
  };
409
+ WebinarRegistrationError: {
410
+ NAME: string;
411
+ MESSAGE: string;
412
+ CODE: number;
413
+ };
409
414
  };
410
415
  export declare const FLOOR_ACTION: {
411
416
  GRANTED: string;
@@ -1058,6 +1063,7 @@ export declare const MEETING_INFO_FAILURE_REASON: {
1058
1063
  WRONG_PASSWORD: string;
1059
1064
  WRONG_CAPTCHA: string;
1060
1065
  POLICY: string;
1066
+ WEBINAR_REGISTRATION: string;
1061
1067
  OTHER: string;
1062
1068
  };
1063
1069
  export declare const BNR_STATUS: {
@@ -3,6 +3,7 @@ import CaptchaError from './common/errors/captcha-error';
3
3
  import IntentToJoinError from './common/errors/intent-to-join';
4
4
  import PasswordError from './common/errors/password-error';
5
5
  import PermissionError from './common/errors/permission';
6
+ import WebinarRegistrationError from './common/errors/webinar-registration-error';
6
7
  import { ReclaimHostEmptyWrongKeyError, ReclaimHostIsHostAlreadyError, ReclaimHostNotAllowedError, ReclaimHostNotSupportedError } from './common/errors/reclaim-host-role-errors';
7
8
  import Meeting from './meeting';
8
9
  import MeetingInfoUtil from './meeting-info/utilv2';
@@ -14,6 +15,6 @@ export * as REACTIONS from './reactions/reactions';
14
15
  export * as sdkAnnotationTypes from './annotation/annotation.types';
15
16
  export * as MeetingInfoV2 from './meeting-info/meeting-info-v2';
16
17
  export { type Reaction } from './reactions/reactions.type';
17
- export { CaptchaError, IntentToJoinError, JoinMeetingError, PasswordError, PermissionError, ReclaimHostIsHostAlreadyError, ReclaimHostNotAllowedError, ReclaimHostNotSupportedError, ReclaimHostEmptyWrongKeyError, Meeting, MeetingInfoUtil, };
18
+ export { CaptchaError, IntentToJoinError, JoinMeetingError, PasswordError, PermissionError, ReclaimHostIsHostAlreadyError, ReclaimHostNotAllowedError, ReclaimHostNotSupportedError, ReclaimHostEmptyWrongKeyError, Meeting, MeetingInfoUtil, WebinarRegistrationError, };
18
19
  export { RemoteMedia } from './multistream/remoteMedia';
19
20
  export { default as TriggerProxy } from './common/events/trigger-proxy';
@@ -139,9 +139,10 @@ export declare class MuteState {
139
139
  * @public
140
140
  * @memberof MuteState
141
141
  * @param {Object} [meeting] the meeting object
142
+ * @param {Boolean} [unmuteAllowed] whether the user is allowed to unmute self
142
143
  * @returns {undefined}
143
144
  */
144
- handleServerLocalUnmuteRequired(meeting?: any): void;
145
+ handleServerLocalUnmuteRequired(meeting: any, unmuteAllowed: boolean): void;
145
146
  /**
146
147
  * Returns true if the user is locally or remotely muted.
147
148
  * It only checks the mute status, ignoring the fact whether audio/video is enabled.
@@ -64,6 +64,23 @@ export declare class MeetingInfoV2CaptchaError extends Error {
64
64
  */
65
65
  constructor(wbxAppApiErrorCode?: number, captchaInfo?: object, message?: string);
66
66
  }
67
+ /**
68
+ * Error preventing join because of a webinar registration error
69
+ */
70
+ export declare class MeetingInfoV2WebinarRegistrationError extends Error {
71
+ meetingInfo: any;
72
+ sdkMessage: any;
73
+ wbxAppApiCode: any;
74
+ body: any;
75
+ /**
76
+ *
77
+ * @constructor
78
+ * @param {Number} [wbxAppApiErrorCode]
79
+ * @param {Object} [meetingInfo]
80
+ * @param {String} [message]
81
+ */
82
+ constructor(wbxAppApiErrorCode?: number, meetingInfo?: object, message?: string);
83
+ }
67
84
  /**
68
85
  * @class MeetingInfo
69
86
  */
@@ -89,6 +106,12 @@ export default class MeetingInfoV2 {
89
106
  * @returns {void}
90
107
  */
91
108
  handlePolicyError: (err: any) => void;
109
+ /**
110
+ * Raises a handleWebinarRegistrationError for webinar registration error codes
111
+ * @param {any} err the error from the request
112
+ * @returns {void}
113
+ */
114
+ handleWebinarRegistrationError: (err: any) => void;
92
115
  /**
93
116
  * Creates adhoc space meetings for a space by fetching the conversation infomation
94
117
  * @param {String} conversationUrl conversationUrl to start adhoc meeting on
@@ -67,5 +67,6 @@ declare const BEHAVIORAL_METRICS: {
67
67
  ROAP_HTTP_RESPONSE_MISSING: string;
68
68
  TURN_DISCOVERY_REQUIRES_OK: string;
69
69
  REACHABILITY_COMPLETED: string;
70
+ WEBINAR_REGISTRATION_ERROR: string;
70
71
  };
71
72
  export { BEHAVIORAL_METRICS as default };
@@ -42,6 +42,7 @@ export declare class RemoteMedia extends EventsScope {
42
42
  * to restrict the requested resolution to this size
43
43
  * @param width width of the video element
44
44
  * @param height height of the video element
45
+ * @note width/height of 0 will be ignored
45
46
  */
46
47
  setSizeHint(width: any, height: any): void;
47
48
  /**
@@ -62,7 +62,7 @@ var Webinar = _webexCore.WebexPlugin.extend({
62
62
  updateCanManageWebcast: function updateCanManageWebcast(canManageWebcast) {
63
63
  this.set('canManageWebcast', canManageWebcast);
64
64
  },
65
- version: "3.6.0-next.1"
65
+ version: "3.6.0-next.10"
66
66
  });
67
67
  var _default = exports.default = Webinar;
68
68
  //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -43,13 +43,13 @@
43
43
  "@webex/eslint-config-legacy": "0.0.0",
44
44
  "@webex/jest-config-legacy": "0.0.0",
45
45
  "@webex/legacy-tools": "0.0.0",
46
- "@webex/plugin-meetings": "3.6.0-next.1",
47
- "@webex/plugin-rooms": "3.5.0-next.23",
48
- "@webex/test-helper-chai": "3.5.0-next.21",
49
- "@webex/test-helper-mocha": "3.5.0-next.21",
50
- "@webex/test-helper-mock-webex": "3.5.0-next.21",
51
- "@webex/test-helper-retry": "3.5.0-next.21",
52
- "@webex/test-helper-test-users": "3.5.0-next.21",
46
+ "@webex/plugin-meetings": "3.6.0-next.10",
47
+ "@webex/plugin-rooms": "3.6.0-next.4",
48
+ "@webex/test-helper-chai": "3.6.0-next.2",
49
+ "@webex/test-helper-mocha": "3.6.0-next.2",
50
+ "@webex/test-helper-mock-webex": "3.6.0-next.2",
51
+ "@webex/test-helper-retry": "3.6.0-next.2",
52
+ "@webex/test-helper-test-users": "3.6.0-next.2",
53
53
  "chai": "^4.3.4",
54
54
  "chai-as-promised": "^7.1.1",
55
55
  "eslint": "^8.24.0",
@@ -61,21 +61,21 @@
61
61
  "typescript": "^4.7.4"
62
62
  },
63
63
  "dependencies": {
64
- "@webex/common": "3.5.0-next.21",
64
+ "@webex/common": "3.6.0-next.2",
65
65
  "@webex/internal-media-core": "2.11.3",
66
- "@webex/internal-plugin-conversation": "3.5.0-next.23",
67
- "@webex/internal-plugin-device": "3.5.0-next.21",
68
- "@webex/internal-plugin-llm": "3.5.0-next.21",
69
- "@webex/internal-plugin-mercury": "3.5.0-next.21",
70
- "@webex/internal-plugin-metrics": "3.5.0-next.21",
71
- "@webex/internal-plugin-support": "3.5.0-next.23",
72
- "@webex/internal-plugin-user": "3.5.0-next.21",
73
- "@webex/internal-plugin-voicea": "3.6.0-next.1",
74
- "@webex/media-helpers": "3.5.0-next.22",
75
- "@webex/plugin-people": "3.5.0-next.21",
76
- "@webex/plugin-rooms": "3.5.0-next.23",
66
+ "@webex/internal-plugin-conversation": "3.6.0-next.4",
67
+ "@webex/internal-plugin-device": "3.6.0-next.2",
68
+ "@webex/internal-plugin-llm": "3.6.0-next.3",
69
+ "@webex/internal-plugin-mercury": "3.6.0-next.3",
70
+ "@webex/internal-plugin-metrics": "3.6.0-next.2",
71
+ "@webex/internal-plugin-support": "3.6.0-next.4",
72
+ "@webex/internal-plugin-user": "3.6.0-next.2",
73
+ "@webex/internal-plugin-voicea": "3.6.0-next.10",
74
+ "@webex/media-helpers": "3.6.0-next.2",
75
+ "@webex/plugin-people": "3.6.0-next.3",
76
+ "@webex/plugin-rooms": "3.6.0-next.4",
77
77
  "@webex/web-capabilities": "^1.4.0",
78
- "@webex/webex-core": "3.5.0-next.21",
78
+ "@webex/webex-core": "3.6.0-next.2",
79
79
  "ampersand-collection": "^2.0.2",
80
80
  "bowser": "^2.11.0",
81
81
  "btoa": "^1.2.1",
@@ -91,5 +91,5 @@
91
91
  "//": [
92
92
  "TODO: upgrade jwt-decode when moving to node 18"
93
93
  ],
94
- "version": "3.6.0-next.1"
94
+ "version": "3.6.0-next.10"
95
95
  }
@@ -0,0 +1,27 @@
1
+ import {ERROR_DICTIONARY} from '../../constants';
2
+
3
+ /**
4
+ * Error occurred while the webinar required registration
5
+ */
6
+ export default class WebinarRegistrationError extends Error {
7
+ code: number;
8
+ error: any;
9
+ sdkMessage: string;
10
+
11
+ /**
12
+ * @constructor
13
+ * @param {String} [message]
14
+ * @param {Object} [error]
15
+ */
16
+ constructor(
17
+ message: string = ERROR_DICTIONARY.WebinarRegistrationError.MESSAGE,
18
+ error: any = null
19
+ ) {
20
+ super(message);
21
+ this.name = ERROR_DICTIONARY.WebinarRegistrationError.NAME;
22
+ this.sdkMessage = ERROR_DICTIONARY.WebinarRegistrationError.MESSAGE;
23
+ this.error = error;
24
+ this.stack = error ? error.stack : new Error().stack;
25
+ this.code = ERROR_DICTIONARY.WebinarRegistrationError.CODE;
26
+ }
27
+ }
package/src/constants.ts CHANGED
@@ -524,6 +524,11 @@ export const ERROR_DICTIONARY = {
524
524
  'Reconnection was not started, because there is one already in progress or reconnections are disabled in config.',
525
525
  CODE: 15,
526
526
  },
527
+ WebinarRegistrationError: {
528
+ NAME: 'WebinarRegistrationError',
529
+ MESSAGE: 'An error occurred while the webinar required registration.',
530
+ CODE: 16,
531
+ },
527
532
  };
528
533
 
529
534
  export const FLOOR_ACTION = {
@@ -1269,6 +1274,7 @@ export const MEETING_INFO_FAILURE_REASON = {
1269
1274
  WRONG_PASSWORD: 'WRONG_PASSWORD', // meeting requires password and no password or wrong one was provided
1270
1275
  WRONG_CAPTCHA: 'WRONG_CAPTCHA', // wbxappapi requires a captcha code or a wrong captcha code was provided
1271
1276
  POLICY: 'POLICY', // meeting info request violates some meeting policy
1277
+ WEBINAR_REGISTRATION: 'WEBINAR_REGISTRATION', // webinar need registration
1272
1278
  OTHER: 'OTHER', // any other error (network, etc)
1273
1279
  };
1274
1280
 
package/src/index.ts CHANGED
@@ -8,6 +8,7 @@ import CaptchaError from './common/errors/captcha-error';
8
8
  import IntentToJoinError from './common/errors/intent-to-join';
9
9
  import PasswordError from './common/errors/password-error';
10
10
  import PermissionError from './common/errors/permission';
11
+ import WebinarRegistrationError from './common/errors/webinar-registration-error';
11
12
  import {
12
13
  ReclaimHostEmptyWrongKeyError,
13
14
  ReclaimHostIsHostAlreadyError,
@@ -68,6 +69,7 @@ export {
68
69
  ReclaimHostEmptyWrongKeyError,
69
70
  Meeting,
70
71
  MeetingInfoUtil,
72
+ WebinarRegistrationError,
71
73
  };
72
74
 
73
75
  export {RemoteMedia} from './multistream/remoteMedia';
@@ -771,7 +771,14 @@ export default class Parser {
771
771
  )}, Action: ${lociComparison}`
772
772
  );
773
773
 
774
- this.onDeltaAction(lociComparison, newLoci);
774
+ try {
775
+ this.onDeltaAction(lociComparison, newLoci);
776
+ } catch (error) {
777
+ LoggerProxy.logger.error(
778
+ 'Locus-info:parser#processDeltaEvent --> Error in onDeltaAction',
779
+ error
780
+ );
781
+ }
775
782
  }
776
783
 
777
784
  this.nextEvent();
@@ -128,6 +128,7 @@ import {
128
128
  MeetingInfoV2PasswordError,
129
129
  MeetingInfoV2CaptchaError,
130
130
  MeetingInfoV2PolicyError,
131
+ MeetingInfoV2WebinarRegistrationError,
131
132
  } from '../meeting-info/meeting-info-v2';
132
133
  import {CSI, ReceiveSlotManager} from '../multistream/receiveSlotManager';
133
134
  import SendSlotManager from '../multistream/sendSlotManager';
@@ -156,6 +157,7 @@ import ControlsOptionsManager from '../controls-options-manager';
156
157
  import PermissionError from '../common/errors/permission';
157
158
  import {LocusMediaRequest} from './locusMediaRequest';
158
159
  import {ConnectionStateHandler, ConnectionStateEvent} from './connectionStateHandler';
160
+ import WebinarRegistrationError from '../common/errors/webinar-registration-error';
159
161
 
160
162
  // default callback so we don't call an undefined function, but in practice it should never be used
161
163
  const DEFAULT_ICE_PHASE_CALLBACK = () => 'JOIN_MEETING_FINAL';
@@ -1759,8 +1761,16 @@ export default class Meeting extends StatelessWebexPlugin {
1759
1761
  if (err.meetingInfo) {
1760
1762
  this.meetingInfo = err.meetingInfo;
1761
1763
  }
1762
-
1763
1764
  throw new PermissionError();
1765
+ } else if (err instanceof MeetingInfoV2WebinarRegistrationError) {
1766
+ this.meetingInfoFailureReason = MEETING_INFO_FAILURE_REASON.WEBINAR_REGISTRATION;
1767
+ this.meetingInfoFailureCode = err.wbxAppApiCode;
1768
+
1769
+ if (err.meetingInfo) {
1770
+ this.meetingInfo = err.meetingInfo;
1771
+ }
1772
+
1773
+ throw new WebinarRegistrationError();
1764
1774
  } else if (err instanceof MeetingInfoV2PasswordError) {
1765
1775
  LoggerProxy.logger.info(
1766
1776
  // @ts-ignore
@@ -2739,6 +2749,9 @@ export default class Meeting extends StatelessWebexPlugin {
2739
2749
  newShareStatus = SHARE_STATUS.NO_SHARE;
2740
2750
  }
2741
2751
 
2752
+ LoggerProxy.logger.info(
2753
+ `Meeting:index#setUpLocusInfoMediaInactiveListener --> this.shareStatus=${this.shareStatus} newShareStatus=${newShareStatus}`
2754
+ );
2742
2755
  if (newShareStatus !== this.shareStatus) {
2743
2756
  const oldShareStatus = this.shareStatus;
2744
2757
 
@@ -3091,7 +3104,7 @@ export default class Meeting extends StatelessWebexPlugin {
3091
3104
  private setUpLocusInfoSelfListener() {
3092
3105
  this.locusInfo.on(LOCUSINFO.EVENTS.LOCAL_UNMUTE_REQUIRED, (payload) => {
3093
3106
  if (this.audio) {
3094
- this.audio.handleServerLocalUnmuteRequired(this);
3107
+ this.audio.handleServerLocalUnmuteRequired(this, payload.unmuteAllowed);
3095
3108
  Trigger.trigger(
3096
3109
  this,
3097
3110
  {
@@ -8182,6 +8195,9 @@ export default class Meeting extends StatelessWebexPlugin {
8182
8195
  * @returns {undefined}
8183
8196
  */
8184
8197
  private handleShareAudioStreamEnded = async () => {
8198
+ LoggerProxy.logger.info(
8199
+ `Meeting:index#handleShareAudioStreamEnded --> audio share stream ended`
8200
+ );
8185
8201
  // current share audio stream has ended, but there might be an active
8186
8202
  // share video stream. we only leave from wireless share if share has
8187
8203
  // completely ended, which means no share audio or video streams active
@@ -8224,6 +8240,9 @@ export default class Meeting extends StatelessWebexPlugin {
8224
8240
  * @returns {undefined}
8225
8241
  */
8226
8242
  private handleShareVideoStreamEnded = async () => {
8243
+ LoggerProxy.logger.info(
8244
+ `Meeting:index#handleShareVideoStreamEnded --> video share stream ended`
8245
+ );
8227
8246
  // current share video stream has ended, but there might be an active
8228
8247
  // share audio stream. we only leave from wireless share if share has
8229
8248
  // completely ended, which means no share audio or video streams active
@@ -8712,6 +8731,9 @@ export default class Meeting extends StatelessWebexPlugin {
8712
8731
  * @returns {Promise}
8713
8732
  */
8714
8733
  async publishStreams(streams: LocalStreams): Promise<void> {
8734
+ LoggerProxy.logger.info(
8735
+ `Meeting:index#publishStreams --> called with: ${JSON.stringify(streams)}`
8736
+ );
8715
8737
  this.checkMediaConnection();
8716
8738
  if (
8717
8739
  !streams.microphone &&
@@ -8723,15 +8745,19 @@ export default class Meeting extends StatelessWebexPlugin {
8723
8745
  return;
8724
8746
  }
8725
8747
 
8726
- if (
8727
- streams?.microphone?.readyState === 'ended' ||
8728
- streams?.camera?.readyState === 'ended' ||
8729
- streams?.screenShare?.audio?.readyState === 'ended' ||
8730
- streams?.screenShare?.video?.readyState === 'ended'
8731
- ) {
8732
- throw new Error(
8733
- `Attempted to publish stream with ended readyState, correlationId=${this.correlationId}`
8734
- );
8748
+ const streamChecks = [
8749
+ {stream: streams?.microphone, name: 'microphone'},
8750
+ {stream: streams?.camera, name: 'camera'},
8751
+ {stream: streams?.screenShare?.audio, name: 'screenShare audio'},
8752
+ {stream: streams?.screenShare?.video, name: 'screenShare video'},
8753
+ ];
8754
+
8755
+ for (const {stream, name} of streamChecks) {
8756
+ if (stream?.readyState === 'ended') {
8757
+ throw new Error(
8758
+ `Attempted to publish ${name} stream with ended readyState, correlationId=${this.correlationId}`
8759
+ );
8760
+ }
8735
8761
  }
8736
8762
 
8737
8763
  let floorRequestNeeded = false;
@@ -8793,6 +8819,9 @@ export default class Meeting extends StatelessWebexPlugin {
8793
8819
  * @returns {Promise}
8794
8820
  */
8795
8821
  async unpublishStreams(streams: LocalStream[]): Promise<void> {
8822
+ LoggerProxy.logger.info(
8823
+ `Meeting:index#unpublishStreams --> called with: ${JSON.stringify(streams)}`
8824
+ );
8796
8825
  this.checkMediaConnection();
8797
8826
 
8798
8827
  const promises = [];
@@ -394,21 +394,25 @@ export class MuteState {
394
394
  * @public
395
395
  * @memberof MuteState
396
396
  * @param {Object} [meeting] the meeting object
397
+ * @param {Boolean} [unmuteAllowed] whether the user is allowed to unmute self
397
398
  * @returns {undefined}
398
399
  */
399
- public handleServerLocalUnmuteRequired(meeting?: any) {
400
+ public handleServerLocalUnmuteRequired(meeting: any, unmuteAllowed: boolean) {
400
401
  if (!this.state.client.enabled) {
401
402
  LoggerProxy.logger.warn(
402
403
  `Meeting:muteState#handleServerLocalUnmuteRequired --> ${this.type}: localAudioUnmuteRequired received while ${this.type} is disabled -> local unmute will not result in ${this.type} being sent`
403
404
  );
404
405
  } else {
405
406
  LoggerProxy.logger.info(
406
- `Meeting:muteState#handleServerLocalUnmuteRequired --> ${this.type}: localAudioUnmuteRequired received -> doing local unmute`
407
+ `Meeting:muteState#handleServerLocalUnmuteRequired --> ${this.type}: localAudioUnmuteRequired received -> doing local unmute (unmuteAllowed=${unmuteAllowed})`
407
408
  );
408
409
  }
409
410
 
410
411
  // todo: I'm seeing "you can now unmute yourself " popup when this happens - but same thing happens on web.w.c so we can ignore for now
411
412
  this.state.server.remoteMute = false;
413
+ this.state.server.unmuteAllowed = unmuteAllowed;
414
+
415
+ this.applyUnmuteAllowedToStream(meeting);
412
416
 
413
417
  // change user mute state to false, but keep localMute true if overall mute state is still true
414
418
  this.muteLocalStream(meeting, false, 'localUnmuteRequired');
@@ -18,6 +18,7 @@ const ADHOC_MEETING_DEFAULT_ERROR =
18
18
  'Failed starting the adhoc meeting, Please contact support team ';
19
19
  const CAPTCHA_ERROR_REQUIRES_PASSWORD_CODES = [423005, 423006];
20
20
  const POLICY_ERROR_CODES = [403049, 403104, 403103, 403048, 403102, 403101];
21
+ const WEBINAR_REGISTRATION_ERROR_CODES = [403021, 403022, 403024];
21
22
  /**
22
23
  * Error to indicate that wbxappapi requires a password
23
24
  */
@@ -124,6 +125,31 @@ export class MeetingInfoV2CaptchaError extends Error {
124
125
  }
125
126
  }
126
127
 
128
+ /**
129
+ * Error preventing join because of a webinar registration error
130
+ */
131
+ export class MeetingInfoV2WebinarRegistrationError extends Error {
132
+ meetingInfo: any;
133
+ sdkMessage: any;
134
+ wbxAppApiCode: any;
135
+ body: any;
136
+ /**
137
+ *
138
+ * @constructor
139
+ * @param {Number} [wbxAppApiErrorCode]
140
+ * @param {Object} [meetingInfo]
141
+ * @param {String} [message]
142
+ */
143
+ constructor(wbxAppApiErrorCode?: number, meetingInfo?: object, message?: string) {
144
+ super(`${message}, code=${wbxAppApiErrorCode}`);
145
+ this.name = 'MeetingInfoV2WebinarRegistrationError';
146
+ this.sdkMessage = message;
147
+ this.stack = new Error().stack;
148
+ this.wbxAppApiCode = wbxAppApiErrorCode;
149
+ this.meetingInfo = meetingInfo;
150
+ }
151
+ }
152
+
127
153
  /**
128
154
  * @class MeetingInfo
129
155
  */
@@ -177,6 +203,29 @@ export default class MeetingInfoV2 {
177
203
  }
178
204
  };
179
205
 
206
+ /**
207
+ * Raises a handleWebinarRegistrationError for webinar registration error codes
208
+ * @param {any} err the error from the request
209
+ * @returns {void}
210
+ */
211
+ handleWebinarRegistrationError = (err) => {
212
+ if (!err.body) {
213
+ return;
214
+ }
215
+
216
+ if (WEBINAR_REGISTRATION_ERROR_CODES.includes(err.body?.code)) {
217
+ Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.WEBINAR_REGISTRATION_ERROR, {
218
+ code: err.body?.code,
219
+ });
220
+
221
+ throw new MeetingInfoV2WebinarRegistrationError(
222
+ err.body?.code,
223
+ err.body?.data?.meetingInfo,
224
+ err.body?.message
225
+ );
226
+ }
227
+ };
228
+
180
229
  /**
181
230
  * Creates adhoc space meetings for a space by fetching the conversation infomation
182
231
  * @param {String} conversationUrl conversationUrl to start adhoc meeting on
@@ -237,6 +286,7 @@ export default class MeetingInfoV2 {
237
286
  })
238
287
  .catch((err) => {
239
288
  this.handlePolicyError(err);
289
+ this.handleWebinarRegistrationError(err);
240
290
 
241
291
  Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.ADHOC_MEETING_FAILURE, {
242
292
  reason: err.message,
@@ -391,6 +441,7 @@ export default class MeetingInfoV2 {
391
441
 
392
442
  if (err?.statusCode === 403) {
393
443
  this.handlePolicyError(err);
444
+ this.handleWebinarRegistrationError(err);
394
445
 
395
446
  Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.VERIFY_PASSWORD_ERROR, {
396
447
  reason: err.message,
@@ -56,6 +56,7 @@ import MeetingCollection from './collection';
56
56
  import {MEETING_KEY, INoiseReductionEffect, IVirtualBackgroundEffect} from './meetings.types';
57
57
  import MeetingsUtil from './util';
58
58
  import PermissionError from '../common/errors/permission';
59
+ import WebinarRegistrationError from '../common/errors/webinar-registration-error';
59
60
  import {SpaceIDDeprecatedError} from '../common/errors/webex-errors';
60
61
  import NoMeetingInfoError from '../common/errors/no-meeting-info';
61
62
 
@@ -1397,7 +1398,8 @@ export default class Meetings extends WebexPlugin {
1397
1398
  if (
1398
1399
  !(err instanceof CaptchaError) &&
1399
1400
  !(err instanceof PasswordError) &&
1400
- !(err instanceof PermissionError)
1401
+ !(err instanceof PermissionError) &&
1402
+ !(err instanceof WebinarRegistrationError)
1401
1403
  ) {
1402
1404
  LoggerProxy.logger.info(
1403
1405
  `Meetings:index#createMeeting --> Info Unable to fetch meeting info for ${destination}.`
@@ -70,6 +70,7 @@ const BEHAVIORAL_METRICS = {
70
70
  ROAP_HTTP_RESPONSE_MISSING: 'js_sdk_roap_http_response_missing',
71
71
  TURN_DISCOVERY_REQUIRES_OK: 'js_sdk_turn_discovery_requires_ok',
72
72
  REACHABILITY_COMPLETED: 'js_sdk_reachability_completed',
73
+ WEBINAR_REGISTRATION_ERROR: 'js_sdk_webinar_registration_error',
73
74
  };
74
75
 
75
76
  export {BEHAVIORAL_METRICS as default};
@@ -107,11 +107,16 @@ export class RemoteMedia extends EventsScope {
107
107
  * to restrict the requested resolution to this size
108
108
  * @param width width of the video element
109
109
  * @param height height of the video element
110
+ * @note width/height of 0 will be ignored
110
111
  */
111
112
  public setSizeHint(width, height) {
112
113
  // only base on height for now
113
114
  let fs: number;
114
115
 
116
+ if (width === 0 || height === 0) {
117
+ return;
118
+ }
119
+
115
120
  if (height < 135) {
116
121
  fs = 60;
117
122
  } else if (height < 270) {