mediasfu-shared 1.0.1 → 1.0.2

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 (125) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +103 -222
  3. package/dist/index.cjs +7500 -2163
  4. package/dist/index.cjs.map +1 -1
  5. package/dist/index.d.ts +4203 -273
  6. package/dist/index.js +7521 -2184
  7. package/dist/index.js.map +1 -1
  8. package/package.json +85 -78
  9. package/src/ProducerClient/producerClientEmits/joinRoomClient.ts +57 -0
  10. package/src/ProducerClient/producerClientEmits/updateRoomParametersClient.ts +401 -0
  11. package/src/consumers/addVideosGrid.ts +3 -2
  12. package/src/consumers/changeVids.ts +111 -41
  13. package/src/consumers/checkPermission.ts +35 -1
  14. package/src/consumers/connectRecvTransport.ts +42 -1
  15. package/src/consumers/consumerResume.ts +2 -2
  16. package/src/consumers/dispStreams.ts +83 -37
  17. package/src/consumers/frameworkConsumerContract.ts +6 -0
  18. package/src/consumers/generatePageContent.ts +24 -10
  19. package/src/consumers/getPipedProducersAlt.ts +112 -16
  20. package/src/consumers/gridLayout/addVideosGrid.engine.ts +42 -0
  21. package/src/consumers/gridLayout/prepopulateUserMedia.engine.ts +444 -0
  22. package/src/consumers/mixStreams.ts +45 -14
  23. package/src/consumers/onScreenChanges.ts +25 -10
  24. package/src/consumers/prepopulateUserMedia.ts +3 -2
  25. package/src/consumers/processConsumerTransports.ts +68 -23
  26. package/src/consumers/processConsumerTransportsAudio.ts +53 -16
  27. package/src/consumers/reUpdateInter.ts +61 -21
  28. package/src/consumers/readjust.ts +30 -14
  29. package/src/consumers/reorderStreams.ts +76 -42
  30. package/src/consumers/resumePauseAudioStreams.ts +66 -17
  31. package/src/consumers/resumePauseStreams.ts +53 -10
  32. package/src/consumers/socketReceiveMethods/joinConsumeRoom.ts +8 -0
  33. package/src/consumers/socketReceiveMethods/newPipeProducer.ts +114 -0
  34. package/src/consumers/socketReceiveMethods/producerClosed.ts +13 -0
  35. package/src/consumers/streamSuccessScreen.ts +2 -2
  36. package/src/consumers/streamSuccessVideo.ts +5 -0
  37. package/src/consumers/translationConsumerSwitch.ts +299 -0
  38. package/src/index.ts +85 -1
  39. package/src/methods/coHostMethods/modifyCoHostSettings.ts +9 -9
  40. package/src/methods/displaySettings/modifyDisplaySettings.ts +5 -0
  41. package/src/methods/index.ts +66 -0
  42. package/src/methods/message/sendMessage.ts +12 -29
  43. package/src/methods/panelists/focusPanelists.ts +83 -0
  44. package/src/methods/panelists/index.ts +3 -0
  45. package/src/methods/panelists/launchPanelists.ts +13 -0
  46. package/src/methods/panelists/updatePanelists.ts +135 -0
  47. package/src/methods/permissions/index.ts +3 -0
  48. package/src/methods/permissions/launchPermissions.ts +13 -0
  49. package/src/methods/permissions/updateParticipantPermission.ts +127 -0
  50. package/src/methods/permissions/updatePermissionConfig.ts +52 -0
  51. package/src/methods/polls/pollUpdated.ts +88 -0
  52. package/src/methods/recording/confirmRecording.ts +15 -12
  53. package/src/methods/recording/recordResumeTimer.ts +2 -2
  54. package/src/methods/recording/recordStartTimer.ts +2 -2
  55. package/src/methods/recording/timeLeftRecording.ts +25 -0
  56. package/src/methods/requests/hostRequestResponse.ts +153 -0
  57. package/src/methods/settings/modifySettings.ts +17 -17
  58. package/src/methods/socketReceive/allMembers.ts +450 -0
  59. package/src/methods/socketReceive/allMembersRest.ts +480 -0
  60. package/src/methods/socketReceive/allWaitingRoomMembers.ts +35 -0
  61. package/src/methods/socketReceive/banParticipant.ts +73 -0
  62. package/src/methods/socketReceive/controlMediaHost.ts +280 -0
  63. package/src/methods/socketReceive/disconnect.ts +40 -0
  64. package/src/methods/socketReceive/disconnectUserSelf.ts +56 -0
  65. package/src/methods/socketReceive/getDomains.ts +112 -0
  66. package/src/methods/socketReceive/meetingEnded.ts +49 -0
  67. package/src/methods/socketReceive/meetingStillThere.ts +26 -0
  68. package/src/methods/socketReceive/panelistReceiveMethods.ts +195 -0
  69. package/src/methods/socketReceive/participantRequested.ts +48 -0
  70. package/src/methods/socketReceive/permissionReceiveMethods.ts +59 -0
  71. package/src/methods/socketReceive/personJoined.ts +35 -0
  72. package/src/methods/socketReceive/producerMediaClosed.ts +223 -0
  73. package/src/methods/socketReceive/producerMediaPaused.ts +267 -0
  74. package/src/methods/socketReceive/producerMediaResumed.ts +157 -0
  75. package/src/methods/socketReceive/reInitiateRecording.ts +53 -0
  76. package/src/methods/socketReceive/receiveMessage.ts +117 -0
  77. package/src/methods/socketReceive/recordingNotice.ts +286 -0
  78. package/src/methods/socketReceive/roomRecordParams.ts +122 -0
  79. package/src/methods/socketReceive/screenProducerId.ts +61 -0
  80. package/src/methods/socketReceive/startRecords.ts +46 -0
  81. package/src/methods/socketReceive/stoppedRecording.ts +44 -0
  82. package/src/methods/socketReceive/translationReceiveMethods.ts +581 -0
  83. package/src/methods/socketReceive/updateConsumingDomains.ts +128 -0
  84. package/src/methods/socketReceive/updateMediaSettings.ts +45 -0
  85. package/src/methods/socketReceive/updatedCoHost.ts +75 -0
  86. package/src/methods/socketReceive/userWaiting.ts +45 -0
  87. package/src/methods/stream/clickAudio.ts +380 -0
  88. package/src/methods/stream/clickChat.ts +36 -0
  89. package/src/methods/stream/clickScreenShare.ts +173 -0
  90. package/src/methods/stream/clickVideo.ts +22 -5
  91. package/src/methods/stream/index.ts +1 -0
  92. package/src/methods/utils/SoundPlayer.ts +31 -0
  93. package/src/methods/utils/checkLimitsAndMakeRequest.ts +156 -2
  94. package/src/methods/utils/createResponseJoinRoom.ts +47 -0
  95. package/src/methods/utils/createRoomOnMediaSFU.ts +160 -0
  96. package/src/methods/utils/formatNumber.ts +42 -0
  97. package/src/methods/utils/generateRandomMessages.ts +70 -0
  98. package/src/methods/utils/generateRandomParticipants.ts +100 -0
  99. package/src/methods/utils/generateRandomPolls.ts +43 -0
  100. package/src/methods/utils/generateRandomRequestList.ts +51 -0
  101. package/src/methods/utils/generateRandomWaitingRoomList.ts +17 -0
  102. package/src/methods/utils/getModalPosition.ts +23 -0
  103. package/src/methods/utils/getOverlayPosition.ts +37 -0
  104. package/src/methods/utils/initialValuesState.ts +405 -0
  105. package/src/methods/utils/joinRoomOnMediaSFU.ts +124 -0
  106. package/src/methods/utils/liveSubtitle.ts +107 -0
  107. package/src/methods/utils/meetingTimeRemaining.ts +33 -0
  108. package/src/methods/utils/meetingTimer/startMeetingProgressTimer.ts +72 -0
  109. package/src/methods/utils/producer/aParams.ts +10 -0
  110. package/src/methods/utils/producer/hParams.ts +26 -0
  111. package/src/methods/utils/producer/screenParams.ts +13 -0
  112. package/src/methods/utils/producer/vParams.ts +26 -0
  113. package/src/methods/utils/producer/videoCaptureConstraints.ts +65 -0
  114. package/src/methods/utils/resolveMediaSFURoomApi.ts +16 -0
  115. package/src/methods/utils/sleep.ts +24 -0
  116. package/src/methods/utils/translationLanguages.ts +308 -0
  117. package/src/methods/utils/webrtc.ts +44 -0
  118. package/src/methods/welcome/handleWelcomeRequest.ts +11 -2
  119. package/src/methods/welcome/index.ts +5 -1
  120. package/src/methods/whiteboard/captureCanvasStream.ts +128 -0
  121. package/src/producers/producerEmits/joinConRoom.ts +2 -2
  122. package/src/producers/producerEmits/joinLocalRoom.ts +240 -0
  123. package/src/producers/producerEmits/joinRoom.ts +129 -0
  124. package/src/types/shared-base-types.ts +14 -3
  125. package/src/types/types.ts +255 -0
@@ -0,0 +1,128 @@
1
+ import type { Producer } from 'mediasoup-client/lib/types';
2
+ import type {
3
+ ConnectSendTransportScreenParameters,
4
+ ConnectSendTransportScreenType,
5
+ CreateSendTransportParameters,
6
+ CreateSendTransportType,
7
+ DisconnectSendTransportScreenParameters,
8
+ DisconnectSendTransportScreenType,
9
+ SleepType,
10
+ } from '../../types/types';
11
+ import type { Socket } from 'socket.io-client';
12
+
13
+ export interface CaptureCanvasStreamParameters
14
+ extends CreateSendTransportParameters,
15
+ DisconnectSendTransportScreenParameters,
16
+ ConnectSendTransportScreenParameters {
17
+ canvasWhiteboard: HTMLCanvasElement | null;
18
+ canvasStream: MediaStream | null;
19
+ updateCanvasStream: (stream: MediaStream | null) => void;
20
+ screenProducer: Producer | null;
21
+ localScreenProducer?: Producer | null;
22
+ transportCreated: boolean;
23
+ localTransportCreated?: boolean;
24
+ localSocket?: Socket;
25
+ updateScreenProducer: (producer: Producer | null) => void;
26
+ updateLocalScreenProducer?: (localProducer: Producer | null) => void;
27
+
28
+ sleep: SleepType;
29
+ createSendTransport: CreateSendTransportType;
30
+ connectSendTransportScreen: ConnectSendTransportScreenType;
31
+ disconnectSendTransportScreen: DisconnectSendTransportScreenType;
32
+
33
+ getUpdatedAllParams: () => CaptureCanvasStreamParameters;
34
+ [key: string]: any;
35
+ }
36
+
37
+ export interface CaptureCanvasStreamOptions {
38
+ parameters: CaptureCanvasStreamParameters;
39
+ start?: boolean;
40
+ }
41
+
42
+ export type CaptureCanvasStreamType = (options: CaptureCanvasStreamOptions) => Promise<void>;
43
+
44
+ /**
45
+ * Captures or tears down a whiteboard canvas stream used for screen-style sharing.
46
+ *
47
+ * When starting, this helper captures the canvas at 30 FPS and ensures the
48
+ * correct screen transport is created or reconnected. When stopping, it ends all
49
+ * canvas tracks and disconnects the corresponding transport.
50
+ *
51
+ * @param options Function options for starting or stopping the captured canvas stream.
52
+ * @returns A promise that resolves after the whiteboard stream lifecycle step completes.
53
+ */
54
+ export const captureCanvasStream = async ({
55
+ parameters,
56
+ start = true,
57
+ }: CaptureCanvasStreamOptions): Promise<void> => {
58
+ try {
59
+ let {
60
+ canvasWhiteboard,
61
+ canvasStream,
62
+ updateCanvasStream,
63
+ screenProducer,
64
+ localScreenProducer,
65
+ transportCreated,
66
+ localTransportCreated,
67
+ updateScreenProducer,
68
+ updateLocalScreenProducer,
69
+ localSocket,
70
+ sleep,
71
+ createSendTransport,
72
+ connectSendTransportScreen,
73
+ disconnectSendTransportScreen,
74
+ } = parameters;
75
+
76
+ if (start && !canvasStream) {
77
+ const stream = canvasWhiteboard!.captureStream(30);
78
+ canvasStream = stream;
79
+ updateCanvasStream(stream);
80
+
81
+ if (localSocket && !localSocket.id) {
82
+ try {
83
+ if (!localTransportCreated) {
84
+ await createSendTransport({ option: 'screen', parameters });
85
+ } else {
86
+ try {
87
+ if (localScreenProducer) {
88
+ localScreenProducer.close();
89
+ if (updateLocalScreenProducer) {
90
+ updateLocalScreenProducer(null);
91
+ }
92
+ await sleep({ ms: 500 });
93
+ }
94
+ } catch (error) {
95
+ console.error(error);
96
+ }
97
+ await connectSendTransportScreen({ stream, parameters });
98
+ }
99
+ } catch {
100
+ }
101
+
102
+ return;
103
+ }
104
+
105
+ if (!transportCreated) {
106
+ await createSendTransport({ option: 'screen', parameters });
107
+ } else {
108
+ try {
109
+ if (screenProducer) {
110
+ screenProducer.close();
111
+ updateScreenProducer(null);
112
+ await sleep({ ms: 500 });
113
+ }
114
+ } catch (error) {
115
+ console.error(error);
116
+ }
117
+ await connectSendTransportScreen({ stream, parameters });
118
+ }
119
+ } else if (canvasStream && !start) {
120
+ canvasStream.getTracks().forEach((track) => track.stop());
121
+ canvasStream = null;
122
+ updateCanvasStream(null);
123
+ disconnectSendTransportScreen({ parameters });
124
+ }
125
+ } catch (error) {
126
+ console.error(error, 'error in captureCanvasStream');
127
+ }
128
+ };
@@ -89,11 +89,11 @@ export async function joinConRoom(
89
89
  }
90
90
 
91
91
  // Validate roomName starts with 's' or 'p'
92
- if (!(roomName.startsWith("s") || roomName.startsWith("p"))) {
92
+ if (!(roomName.startsWith("s") || roomName.startsWith("p") || roomName.startsWith("d"))) {
93
93
  const validationError: JoinConRoomResponse = {
94
94
  success: false,
95
95
  rtpCapabilities: null,
96
- reason: "Invalid roomName, must start with s or p",
96
+ reason: "Invalid roomName, must start with s or p or d",
97
97
  };
98
98
  reject(validationError);
99
99
  return;
@@ -0,0 +1,240 @@
1
+ import { Socket } from 'socket.io-client';
2
+ import {
3
+ JoinMediaSFURoomOptions,
4
+ PreJoinPageParameters,
5
+ ResponseJoinLocalRoom,
6
+ } from '../../types/shared-base-types';
7
+ import { validateAlphanumeric } from '../../methods/utils/validateAlphanumeric';
8
+ import { joinRoomOnMediaSFU, JoinRoomOnMediaSFUType } from '../../methods/utils/joinRoomOnMediaSFU';
9
+ import { checkLimitsAndMakeRequest } from '../../methods/utils/checkLimitsAndMakeRequest';
10
+
11
+ export interface JoinLocalRoomOptions {
12
+ socket: Socket;
13
+ roomName: string;
14
+ islevel: string;
15
+ member: string;
16
+ sec: string;
17
+ apiUserName: string;
18
+ parameters: PreJoinPageParameters;
19
+ checkConnect?: boolean;
20
+ joinMediaSFURoom?: JoinRoomOnMediaSFUType;
21
+ localLink?: string;
22
+ }
23
+
24
+ export type JoinLocalRoomType = (
25
+ options: JoinLocalRoomOptions,
26
+ ) => Promise<ResponseJoinLocalRoom>;
27
+
28
+ export interface CheckMediasfuURLOptions {
29
+ data: ResponseJoinLocalRoom;
30
+ member: string;
31
+ roomName: string;
32
+ islevel: string;
33
+ socket: Socket;
34
+ parameters: PreJoinPageParameters;
35
+ joinMediaSFURoom?: JoinRoomOnMediaSFUType;
36
+ localLink?: string;
37
+ }
38
+
39
+ export type CheckMediasfuURLType = (options: CheckMediasfuURLOptions) => Promise<void>;
40
+
41
+ export async function checkMediasfuURL({
42
+ data,
43
+ member,
44
+ roomName,
45
+ islevel,
46
+ socket,
47
+ parameters,
48
+ joinMediaSFURoom = joinRoomOnMediaSFU,
49
+ localLink = '',
50
+ }: CheckMediasfuURLOptions): Promise<void> {
51
+ if (
52
+ data.mediasfuURL
53
+ && data.mediasfuURL !== ''
54
+ && data.mediasfuURL.length > 10
55
+ ) {
56
+ let link;
57
+ let secretCode;
58
+
59
+ try {
60
+ const splitTexts = ['/meet/', '/chat/', '/broadcast/'];
61
+ const splitText = splitTexts.find((text) => data.mediasfuURL.includes(text)) || '/meet/';
62
+
63
+ const urlParts = data.mediasfuURL.split(splitText);
64
+ link = urlParts[0];
65
+ secretCode = urlParts[1].split('/')[1];
66
+ } catch {
67
+ link = data.mediasfuURL;
68
+ return;
69
+ }
70
+
71
+ await checkLimitsAndMakeRequest({
72
+ apiUserName: roomName,
73
+ apiToken: secretCode,
74
+ link,
75
+ apiKey: '',
76
+ userName: member,
77
+ parameters,
78
+ validate: false,
79
+ });
80
+
81
+ return;
82
+ }
83
+
84
+ if (
85
+ (!data.mediasfuURL || data.mediasfuURL.length < 10)
86
+ && islevel !== '2'
87
+ && data.allowRecord
88
+ && (data.allowRecord === true || data.allowRecord === 'true')
89
+ && data.apiKey
90
+ && data.apiKey.length === 64
91
+ && data.apiUserName
92
+ && data.apiUserName.length > 5
93
+ && (roomName.startsWith('s') || roomName.startsWith('p'))
94
+ ) {
95
+ const payload: JoinMediaSFURoomOptions = {
96
+ action: 'join',
97
+ meetingID: roomName,
98
+ userName: member,
99
+ };
100
+
101
+ const response = await joinMediaSFURoom({
102
+ payload,
103
+ apiKey: data.apiKey,
104
+ apiUserName: data.apiUserName,
105
+ localLink,
106
+ });
107
+
108
+ if (response.success && response.data && 'roomName' in response.data) {
109
+ try {
110
+ socket.emit(
111
+ 'updateMediasfuURL',
112
+ { eventID: roomName, mediasfuURL: response.data.publicURL },
113
+ async () => {},
114
+ );
115
+ } catch {
116
+ // Do nothing
117
+ }
118
+
119
+ await checkLimitsAndMakeRequest({
120
+ apiUserName: response.data.roomName,
121
+ apiToken: response.data.secret,
122
+ link: response.data.link,
123
+ userName: member,
124
+ parameters,
125
+ validate: false,
126
+ });
127
+ parameters.updateApiToken(response.data.secret);
128
+ }
129
+ }
130
+ }
131
+
132
+ export async function joinLocalRoom({
133
+ socket,
134
+ roomName,
135
+ islevel,
136
+ member,
137
+ sec,
138
+ apiUserName,
139
+ parameters,
140
+ checkConnect = false,
141
+ joinMediaSFURoom = joinRoomOnMediaSFU,
142
+ localLink = '',
143
+ }: JoinLocalRoomOptions): Promise<ResponseJoinLocalRoom> {
144
+ return new Promise((resolve, reject) => {
145
+ if (!(sec && roomName && islevel && apiUserName && member)) {
146
+ const validationError = {
147
+ success: false,
148
+ rtpCapabilities: null,
149
+ reason: 'Missing required parameters',
150
+ };
151
+ reject(validationError);
152
+ return;
153
+ }
154
+
155
+ try {
156
+ validateAlphanumeric({ str: roomName });
157
+ validateAlphanumeric({ str: apiUserName });
158
+ validateAlphanumeric({ str: member });
159
+ } catch {
160
+ const validationError = {
161
+ success: false,
162
+ rtpCapabilities: null,
163
+ reason: 'Invalid roomName or apiUserName or member',
164
+ };
165
+ reject(validationError);
166
+ return;
167
+ }
168
+
169
+ if (!(roomName.startsWith('s') || roomName.startsWith('p') || roomName.startsWith('m') || roomName.startsWith('d'))) {
170
+ const validationError = {
171
+ success: false,
172
+ rtpCapabilities: null,
173
+ reason: 'Invalid roomName, must start with s or p or m or d',
174
+ };
175
+ reject(validationError);
176
+ return;
177
+ }
178
+
179
+ if (
180
+ !(
181
+ sec.length === 32
182
+ && roomName.length >= 8
183
+ && islevel.length === 1
184
+ && apiUserName.length >= 6
185
+ && (islevel === '0' || islevel === '1' || islevel === '2')
186
+ )
187
+ ) {
188
+ const validationError = {
189
+ success: false,
190
+ rtpCapabilities: null,
191
+ reason: 'Invalid roomName or islevel or apiUserName or secret',
192
+ };
193
+ reject(validationError);
194
+ return;
195
+ }
196
+
197
+ socket.emit(
198
+ 'joinRoom',
199
+ { roomName, islevel, member, sec, apiUserName },
200
+ async (data: ResponseJoinLocalRoom) => {
201
+ try {
202
+ if (data.rtpCapabilities === null) {
203
+ if (data.isBanned) {
204
+ throw new Error('User is banned.');
205
+ }
206
+ if (data.hostNotJoined) {
207
+ throw new Error('Host has not joined the room yet.');
208
+ }
209
+
210
+ resolve(data);
211
+ } else {
212
+ if (checkConnect) {
213
+ await checkMediasfuURL({
214
+ data,
215
+ member,
216
+ roomName,
217
+ islevel,
218
+ socket,
219
+ parameters,
220
+ joinMediaSFURoom,
221
+ localLink,
222
+ });
223
+ } else if (data.mediasfuURL && data.mediasfuURL !== '' && data.mediasfuURL.length > 10) {
224
+ const splitTexts = ['/meet/', '/chat/', '/broadcast/'];
225
+ const splitText = splitTexts.find((text) => data.mediasfuURL.includes(text)) || '/meet/';
226
+ const urlParts = data.mediasfuURL.split(splitText);
227
+ const secretCode = urlParts[1].split('/')[1];
228
+ parameters.updateApiToken(secretCode);
229
+ }
230
+
231
+ resolve(data);
232
+ }
233
+ } catch (error) {
234
+ console.log('Error joining room:', error);
235
+ reject(error);
236
+ }
237
+ },
238
+ );
239
+ });
240
+ }
@@ -0,0 +1,129 @@
1
+ import { Socket } from 'socket.io-client';
2
+ import type { RtpCapabilities } from 'mediasoup-client/lib/types';
3
+ import { validateAlphanumeric } from '../../methods/utils/validateAlphanumeric';
4
+
5
+ export interface JoinRoomOptions {
6
+ socket: Socket;
7
+ roomName: string;
8
+ islevel: string;
9
+ member: string;
10
+ sec: string;
11
+ apiUserName: string;
12
+ }
13
+
14
+ export interface JoinRoomResponse {
15
+ success: boolean;
16
+ rtpCapabilities: RtpCapabilities | null;
17
+ reason?: string;
18
+ banned?: boolean;
19
+ suspended?: boolean;
20
+ noAdmin?: boolean;
21
+ [key: string]: any;
22
+ }
23
+
24
+ export type JoinRoomType = (options: JoinRoomOptions) => Promise<JoinRoomResponse>;
25
+
26
+ /**
27
+ * Joins a user to a specified room via a socket connection.
28
+ *
29
+ * @param {JoinRoomOptions} options - The options for joining the room.
30
+ * @param {Socket} options.socket - The socket instance to use for communication.
31
+ * @param {string} options.roomName - The name of the room to join.
32
+ * @param {string} options.islevel - The level of the user.
33
+ * @param {string} options.member - The member identifier.
34
+ * @param {string} options.sec - The security token.
35
+ * @param {string} options.apiUserName - The API username of the user.
36
+ *
37
+ * @returns {Promise<JoinRoomResponse>} A promise that resolves with the data received from the 'joinRoom' event or rejects with a validation error.
38
+ */
39
+ export async function joinRoom({
40
+ socket,
41
+ roomName,
42
+ islevel,
43
+ member,
44
+ sec,
45
+ apiUserName,
46
+ }: JoinRoomOptions): Promise<JoinRoomResponse> {
47
+ return new Promise((resolve, reject) => {
48
+ if (!(sec && roomName && islevel && apiUserName && member)) {
49
+ const validationError: JoinRoomResponse = {
50
+ success: false,
51
+ rtpCapabilities: null,
52
+ reason: 'Missing required parameters',
53
+ };
54
+ reject(validationError);
55
+ return;
56
+ }
57
+
58
+ try {
59
+ validateAlphanumeric({ str: roomName });
60
+ validateAlphanumeric({ str: apiUserName });
61
+ validateAlphanumeric({ str: member });
62
+ } catch {
63
+ const validationError: JoinRoomResponse = {
64
+ success: false,
65
+ rtpCapabilities: null,
66
+ reason: 'Invalid roomName or apiUserName or member',
67
+ };
68
+ reject(validationError);
69
+ return;
70
+ }
71
+
72
+ if (!(roomName.startsWith('s') || roomName.startsWith('p') || roomName.startsWith('d'))) {
73
+ const validationError: JoinRoomResponse = {
74
+ success: false,
75
+ rtpCapabilities: null,
76
+ reason: 'Invalid roomName, must start with s or p or d',
77
+ };
78
+ reject(validationError);
79
+ return;
80
+ }
81
+
82
+ if (
83
+ !(
84
+ sec.length === 64
85
+ && roomName.length >= 8
86
+ && islevel.length === 1
87
+ && apiUserName.length >= 6
88
+ && (islevel === '0' || islevel === '1' || islevel === '2')
89
+ )
90
+ ) {
91
+ const validationError: JoinRoomResponse = {
92
+ success: false,
93
+ rtpCapabilities: null,
94
+ reason: 'Invalid roomName or islevel or apiUserName or secret',
95
+ };
96
+ reject(validationError);
97
+ return;
98
+ }
99
+
100
+ socket.emit(
101
+ 'joinRoom',
102
+ {
103
+ roomName, islevel, member, sec, apiUserName,
104
+ },
105
+ async (data: JoinRoomResponse) => {
106
+ try {
107
+ if (data.rtpCapabilities == null) {
108
+ if (data.banned) {
109
+ throw new Error('User is banned.');
110
+ }
111
+ if (data.suspended) {
112
+ throw new Error('User is suspended.');
113
+ }
114
+ if (data.noAdmin) {
115
+ throw new Error('Host has not joined the room yet.');
116
+ }
117
+
118
+ resolve(data);
119
+ } else {
120
+ resolve(data);
121
+ }
122
+ } catch (error) {
123
+ console.log('Error joining room:', error);
124
+ reject(error);
125
+ }
126
+ },
127
+ );
128
+ });
129
+ }
@@ -81,7 +81,7 @@ export interface AudioDecibels {
81
81
  averageLoudness: number;
82
82
  }
83
83
 
84
- export type ShowAlert = (options: { message: string; type: 'success' | 'danger'; duration?: number }) => void;
84
+ export type ShowAlert = (options: { message: string; type: 'success' | 'danger' | 'info'; duration?: number }) => void;
85
85
 
86
86
  export interface CoHostResponsibility {
87
87
  name: string;
@@ -679,6 +679,12 @@ export interface CreateJoinRoomResult {
679
679
  success: boolean;
680
680
  }
681
681
 
682
+ export interface PendingRequestStorage {
683
+ getItem: (key: string) => Promise<string | null>;
684
+ setItem: (key: string, value: string) => Promise<void>;
685
+ removeItem: (key: string) => Promise<void>;
686
+ }
687
+
682
688
  export type CreateJoinRoomType = (options: {
683
689
  payload: CreateMediaSFURoomOptions | JoinMediaSFURoomOptions;
684
690
  apiUserName: string;
@@ -686,12 +692,17 @@ export type CreateJoinRoomType = (options: {
686
692
  localLink?: string;
687
693
  }) => Promise<CreateJoinRoomResult>;
688
694
 
689
- export type CreateRoomOnMediaSFUType = (options: {
695
+ export interface CreateRoomOnMediaSFUOptions {
690
696
  payload: CreateMediaSFURoomOptions;
691
697
  apiUserName: string;
692
698
  apiKey: string;
693
699
  localLink?: string;
694
- }) => Promise<CreateJoinRoomResult>;
700
+ pendingRequestStorage?: PendingRequestStorage;
701
+ }
702
+
703
+ export type CreateRoomOnMediaSFUType = (
704
+ options: CreateRoomOnMediaSFUOptions,
705
+ ) => Promise<CreateJoinRoomResult>;
695
706
 
696
707
  export type JoinRoomOnMediaSFUType = (options: {
697
708
  payload: JoinMediaSFURoomOptions;