mediasfu-shared 1.0.0

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 (141) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +228 -0
  3. package/dist/index.cjs +7707 -0
  4. package/dist/index.cjs.map +1 -0
  5. package/dist/index.d.ts +7285 -0
  6. package/dist/index.js +7690 -0
  7. package/dist/index.js.map +1 -0
  8. package/package.json +78 -0
  9. package/src/ProducerClient/producerClientEmits/createDeviceClient.ts +68 -0
  10. package/src/consumers/addVideosGrid.ts +18 -0
  11. package/src/consumers/autoAdjust.ts +100 -0
  12. package/src/consumers/calculateRowsAndColumns.ts +51 -0
  13. package/src/consumers/changeVids.ts +753 -0
  14. package/src/consumers/checkGrid.ts +100 -0
  15. package/src/consumers/checkPermission.ts +89 -0
  16. package/src/consumers/checkScreenShare.ts +114 -0
  17. package/src/consumers/closeAndResize.ts +401 -0
  18. package/src/consumers/compareActiveNames.ts +122 -0
  19. package/src/consumers/compareScreenStates.ts +117 -0
  20. package/src/consumers/connectIps.ts +175 -0
  21. package/src/consumers/connectLocalIps.ts +103 -0
  22. package/src/consumers/connectRecvTransport.ts +158 -0
  23. package/src/consumers/connectSendTransport.ts +150 -0
  24. package/src/consumers/connectSendTransportAudio.ts +161 -0
  25. package/src/consumers/connectSendTransportScreen.ts +169 -0
  26. package/src/consumers/connectSendTransportVideo.ts +149 -0
  27. package/src/consumers/consumerResume.ts +25 -0
  28. package/src/consumers/controlMedia.ts +118 -0
  29. package/src/consumers/createSendTransport.ts +312 -0
  30. package/src/consumers/disconnectSendTransportAudio.ts +170 -0
  31. package/src/consumers/disconnectSendTransportScreen.ts +130 -0
  32. package/src/consumers/disconnectSendTransportVideo.ts +161 -0
  33. package/src/consumers/dispStreams.ts +694 -0
  34. package/src/consumers/generatePageContent.ts +118 -0
  35. package/src/consumers/getEstimate.ts +124 -0
  36. package/src/consumers/getPipedProducersAlt.ts +96 -0
  37. package/src/consumers/getProducersPiped.ts +89 -0
  38. package/src/consumers/getVideos.ts +107 -0
  39. package/src/consumers/mixStreams.ts +97 -0
  40. package/src/consumers/onScreenChanges.ts +106 -0
  41. package/src/consumers/prepopulateUserMedia.ts +18 -0
  42. package/src/consumers/processConsumerTransports.ts +157 -0
  43. package/src/consumers/processConsumerTransportsAudio.ts +121 -0
  44. package/src/consumers/rePort.ts +123 -0
  45. package/src/consumers/reUpdateInter.ts +289 -0
  46. package/src/consumers/readjust.ts +170 -0
  47. package/src/consumers/receiveAllPipedTransports.ts +77 -0
  48. package/src/consumers/receiveRoomMessages.ts +55 -0
  49. package/src/consumers/reorderStreams.ts +246 -0
  50. package/src/consumers/requestScreenShare.ts +103 -0
  51. package/src/consumers/resumePauseAudioStreams.ts +174 -0
  52. package/src/consumers/resumePauseStreams.ts +110 -0
  53. package/src/consumers/resumeSendTransportAudio.ts +143 -0
  54. package/src/consumers/signalNewConsumerTransport.ts +179 -0
  55. package/src/consumers/socketReceiveMethods/joinConsumeRoom.ts +130 -0
  56. package/src/consumers/socketReceiveMethods/newPipeProducer.ts +138 -0
  57. package/src/consumers/socketReceiveMethods/producerClosed.ts +102 -0
  58. package/src/consumers/startShareScreen.ts +124 -0
  59. package/src/consumers/stopShareScreen.ts +241 -0
  60. package/src/consumers/streamSuccessAudio.ts +297 -0
  61. package/src/consumers/streamSuccessAudioSwitch.ts +315 -0
  62. package/src/consumers/streamSuccessScreen.ts +255 -0
  63. package/src/consumers/streamSuccessVideo.ts +373 -0
  64. package/src/consumers/switchUserAudio.ts +140 -0
  65. package/src/consumers/switchUserVideo.ts +201 -0
  66. package/src/consumers/switchUserVideoAlt.ts +331 -0
  67. package/src/consumers/trigger.ts +250 -0
  68. package/src/consumers/updateMiniCardsGrid.ts +150 -0
  69. package/src/consumers/updateParticipantAudioDecibels.ts +56 -0
  70. package/src/index.ts +119 -0
  71. package/src/methods/background/launchBackground.ts +16 -0
  72. package/src/methods/breakoutRooms/breakoutRoomUpdated.ts +161 -0
  73. package/src/methods/breakoutRooms/handleStartBreakout.ts +96 -0
  74. package/src/methods/breakoutRooms/handleStopBreakout.ts +72 -0
  75. package/src/methods/breakoutRooms/index.ts +4 -0
  76. package/src/methods/breakoutRooms/launchBreakoutRooms.ts +31 -0
  77. package/src/methods/coHost/launchCoHost.ts +28 -0
  78. package/src/methods/coHostMethods/index.ts +2 -0
  79. package/src/methods/coHostMethods/modifyCoHostSettings.ts +94 -0
  80. package/src/methods/displaySettings/index.ts +1 -0
  81. package/src/methods/displaySettings/launchDisplaySettings.ts +31 -0
  82. package/src/methods/displaySettings/modifyDisplaySettings.ts +242 -0
  83. package/src/methods/exit/confirmExit.ts +60 -0
  84. package/src/methods/exit/index.ts +2 -0
  85. package/src/methods/exit/launchConfirmExit.ts +29 -0
  86. package/src/methods/index.ts +5 -0
  87. package/src/methods/mediaSettings/launchMediaSettings.ts +61 -0
  88. package/src/methods/menu/launchMenuModal.ts +28 -0
  89. package/src/methods/message/index.ts +1 -0
  90. package/src/methods/message/launchMessages.ts +27 -0
  91. package/src/methods/message/sendMessage.ts +175 -0
  92. package/src/methods/participants/index.ts +3 -0
  93. package/src/methods/participants/launchParticipants.ts +25 -0
  94. package/src/methods/participants/messageParticipants.ts +78 -0
  95. package/src/methods/participants/muteParticipants.ts +79 -0
  96. package/src/methods/participants/removeParticipants.ts +97 -0
  97. package/src/methods/polls/handleCreatePoll.ts +66 -0
  98. package/src/methods/polls/handleEndPoll.ts +64 -0
  99. package/src/methods/polls/handleVotePoll.ts +76 -0
  100. package/src/methods/polls/index.ts +3 -0
  101. package/src/methods/polls/launchPoll.ts +25 -0
  102. package/src/methods/prejoin/handleCreateRoom.ts +441 -0
  103. package/src/methods/prejoin/handleJoinRoom.ts +153 -0
  104. package/src/methods/prejoin/index.ts +14 -0
  105. package/src/methods/recording/checkPauseState.ts +57 -0
  106. package/src/methods/recording/checkResumeState.ts +42 -0
  107. package/src/methods/recording/confirmRecording.ts +241 -0
  108. package/src/methods/recording/launchRecording.ts +114 -0
  109. package/src/methods/recording/recordPauseTimer.ts +52 -0
  110. package/src/methods/recording/recordResumeTimer.ts +92 -0
  111. package/src/methods/recording/recordStartTimer.ts +106 -0
  112. package/src/methods/recording/recordUpdateTimer.ts +49 -0
  113. package/src/methods/recording/startRecording.ts +268 -0
  114. package/src/methods/recording/stopRecording.ts +124 -0
  115. package/src/methods/recording/updateRecording.ts +245 -0
  116. package/src/methods/requests/index.ts +1 -0
  117. package/src/methods/requests/launchRequests.ts +25 -0
  118. package/src/methods/requests/respondToRequests.ts +108 -0
  119. package/src/methods/settings/index.ts +2 -0
  120. package/src/methods/settings/launchSettings.ts +25 -0
  121. package/src/methods/settings/modifySettings.ts +99 -0
  122. package/src/methods/stream/clickVideo.ts +337 -0
  123. package/src/methods/stream/index.ts +3 -0
  124. package/src/methods/stream/switchAudio.ts +73 -0
  125. package/src/methods/stream/switchVideo.ts +148 -0
  126. package/src/methods/stream/switchVideoAlt.ts +152 -0
  127. package/src/methods/utils/checkLimitsAndMakeRequest.ts +103 -0
  128. package/src/methods/utils/validateAlphanumeric.ts +41 -0
  129. package/src/methods/waiting/index.ts +1 -0
  130. package/src/methods/waiting/launchWaiting.ts +26 -0
  131. package/src/methods/waiting/respondToWaiting.ts +82 -0
  132. package/src/methods/welcome/handleWelcomeRequest.ts +189 -0
  133. package/src/methods/welcome/index.ts +5 -0
  134. package/src/methods/whiteboard/handleStartWhiteboard.ts +65 -0
  135. package/src/methods/whiteboard/handleStopWhiteboard.ts +48 -0
  136. package/src/methods/whiteboard/index.ts +4 -0
  137. package/src/methods/whiteboard/launchConfigureWhiteboard.ts +29 -0
  138. package/src/producers/producerEmits/joinConRoom.ts +153 -0
  139. package/src/sockets/SocketManager.ts +232 -0
  140. package/src/types/shared-base-types.ts +752 -0
  141. package/src/types/types.ts +84 -0
@@ -0,0 +1,148 @@
1
+ import type { ShowAlert, SwitchUserVideoType, SwitchUserVideoParameters } from '../../types/types'
2
+
3
+
4
+ export interface SwitchVideoParameters extends SwitchUserVideoParameters {
5
+ recordStarted: boolean
6
+ recordResumed: boolean
7
+ recordStopped: boolean
8
+ recordPaused: boolean
9
+ recordingMediaOptions: string
10
+ videoAlreadyOn: boolean
11
+ userDefaultVideoInputDevice: string
12
+ defVideoID: string
13
+ allowed: boolean
14
+ updateDefVideoID: (deviceId: string) => void
15
+ updatePrevVideoInputDevice: (deviceId: string) => void
16
+ updateUserDefaultVideoInputDevice: (deviceId: string) => void
17
+ updateIsMediaSettingsModalVisible: (isVisible: boolean) => void
18
+ showAlert?: ShowAlert
19
+
20
+ // Mediasfu functions
21
+ switchUserVideo: SwitchUserVideoType
22
+
23
+ [key: string]: any
24
+ }
25
+
26
+ export interface SwitchVideoOptions {
27
+ videoPreference: string
28
+ parameters: SwitchVideoParameters
29
+ }
30
+
31
+ // Export the type definition for the function
32
+ export type SwitchVideoType = (options: SwitchVideoOptions) => Promise<void>
33
+
34
+ /**
35
+ * Switches the user's video device based on the provided video preference.
36
+ *
37
+ * @param {SwitchVideoOptions} options - The function parameters.
38
+ * @returns {Promise<void>}
39
+ *
40
+ * @example
41
+ * ```typescript
42
+ * switchVideo({
43
+ * videoPreference: "newVideoDeviceID",
44
+ * parameters: {
45
+ * recordStarted: true,
46
+ * recordResumed: false,
47
+ * recordStopped: false,
48
+ * recordPaused: false,
49
+ * recordingMediaOptions: "video",
50
+ * videoAlreadyOn: true,
51
+ * userDefaultVideoInputDevice: "currentVideoDeviceID",
52
+ * defVideoID: "defaultVideoDeviceID",
53
+ * allowed: true,
54
+ * updateDefVideoID: (deviceId) => setDefVideoID(deviceId),
55
+ * updatePrevVideoInputDevice: (deviceId) => setPrevVideoDevice(deviceId),
56
+ * updateUserDefaultVideoInputDevice: (deviceId) => setUserDefaultVideo(deviceId),
57
+ * updateIsMediaSettingsModalVisible: (isVisible) => setMediaSettingsModal(isVisible),
58
+ * showAlert: (alertOptions) => showAlert(alertOptions),
59
+ * switchUserVideo: switchUserVideoFunction,
60
+ * }
61
+ * });
62
+ * ```
63
+ */
64
+
65
+ export const switchVideo = async ({
66
+ videoPreference,
67
+ parameters
68
+ }: SwitchVideoOptions): Promise<void> => {
69
+ let {
70
+ recordStarted,
71
+ recordResumed,
72
+ recordStopped,
73
+ recordPaused,
74
+ recordingMediaOptions,
75
+ videoAlreadyOn,
76
+ userDefaultVideoInputDevice,
77
+ defVideoID,
78
+ allowed,
79
+ updateDefVideoID,
80
+ updatePrevVideoInputDevice,
81
+ updateUserDefaultVideoInputDevice,
82
+ updateIsMediaSettingsModalVisible,
83
+
84
+ //mediasfu functions
85
+ showAlert,
86
+ switchUserVideo
87
+ } = parameters
88
+
89
+ // Check if recording is in progress and whether the selected video device is the default one
90
+ let checkoff = false
91
+ if ((recordStarted || recordResumed) && !recordStopped && !recordPaused) {
92
+ if (recordingMediaOptions === 'video') {
93
+ checkoff = true
94
+ }
95
+ }
96
+
97
+ // Check camera access permission
98
+ if (!allowed) {
99
+ showAlert?.({
100
+ message:
101
+ 'Allow access to your camera by starting it for the first time.',
102
+ type: 'danger',
103
+ duration: 3000
104
+ })
105
+ return
106
+ }
107
+
108
+ // Check video state and display appropriate alert messages
109
+ if (checkoff) {
110
+ if (videoAlreadyOn) {
111
+ showAlert?.({
112
+ message: 'Please turn off your video before switching.',
113
+ type: 'danger',
114
+ duration: 3000
115
+ })
116
+ return
117
+ }
118
+ } else {
119
+ if (!videoAlreadyOn) {
120
+ showAlert?.({
121
+ message: 'Please turn on your video before switching.',
122
+ type: 'danger',
123
+ duration: 3000
124
+ })
125
+ return
126
+ }
127
+ }
128
+
129
+ // Set default video ID if not already set
130
+ if (!defVideoID) {
131
+ defVideoID = userDefaultVideoInputDevice ?? 'default'
132
+ updateDefVideoID(defVideoID)
133
+ }
134
+
135
+ // Switch video only if the selected video device is different from the default
136
+ if (videoPreference !== defVideoID) {
137
+ const prevVideoInputDevice = userDefaultVideoInputDevice
138
+ updatePrevVideoInputDevice(prevVideoInputDevice)
139
+
140
+ userDefaultVideoInputDevice = videoPreference
141
+ updateUserDefaultVideoInputDevice(userDefaultVideoInputDevice)
142
+
143
+ if (defVideoID) {
144
+ updateIsMediaSettingsModalVisible(false)
145
+ await switchUserVideo({ videoPreference, checkoff, parameters })
146
+ }
147
+ }
148
+ }
@@ -0,0 +1,152 @@
1
+ import type { ShowAlert, SwitchUserVideoAltParameters, SwitchUserVideoAltType } from '../../types/types'
2
+
3
+
4
+ export interface SwitchVideoAltParameters extends SwitchUserVideoAltParameters {
5
+ recordStarted: boolean
6
+ recordResumed: boolean
7
+ recordStopped: boolean
8
+ recordPaused: boolean
9
+ recordingMediaOptions: string
10
+ videoAlreadyOn: boolean
11
+ currentFacingMode: string
12
+ prevFacingMode: string
13
+ allowed: boolean
14
+ audioOnlyRoom: boolean
15
+ updateCurrentFacingMode: (mode: string) => void
16
+ updatePrevFacingMode: (mode: string) => void
17
+ updateIsMediaSettingsModalVisible: (isVisible: boolean) => void
18
+ showAlert?: ShowAlert
19
+
20
+ // mediasfu functions
21
+ switchUserVideoAlt: SwitchUserVideoAltType
22
+
23
+ getUpdatedAllParams: () => SwitchVideoAltParameters
24
+ [key: string]: any
25
+ }
26
+
27
+ export interface SwitchVideoAltOptions {
28
+ parameters: SwitchVideoAltParameters
29
+ }
30
+
31
+ // Export the type definition for the function
32
+ export type SwitchVideoAltType = (
33
+ options: SwitchVideoAltOptions
34
+ ) => Promise<void>
35
+
36
+ /**
37
+ * Switches the user's video device with alternate logic, taking into account recording state and camera access permissions.
38
+ *
39
+ * @param {SwitchVideoAltOptions} options - The parameters object containing necessary variables.
40
+ * @returns {Promise<void>}
41
+ *
42
+ * @example
43
+ * ```typescript
44
+ * switchVideoAlt({
45
+ * parameters: {
46
+ * recordStarted: true,
47
+ * recordResumed: false,
48
+ * recordStopped: false,
49
+ * recordPaused: false,
50
+ * recordingMediaOptions: 'video',
51
+ * videoAlreadyOn: true,
52
+ * currentFacingMode: 'user',
53
+ * prevFacingMode: 'environment',
54
+ * allowed: true,
55
+ * audioOnlyRoom: false,
56
+ * updateCurrentFacingMode: (mode) => setCurrentFacingMode(mode),
57
+ * updatePrevFacingMode: (mode) => setPrevFacingMode(mode),
58
+ * updateIsMediaSettingsModalVisible: (isVisible) => setMediaSettingsModal(isVisible),
59
+ * showAlert: (alertOptions) => showAlert(alertOptions),
60
+ * switchUserVideoAlt: switchUserVideoAltFunction,
61
+ * }
62
+ * });
63
+ * ```
64
+ */
65
+
66
+ export const switchVideoAlt = async ({
67
+ parameters
68
+ }: SwitchVideoAltOptions): Promise<void> => {
69
+ let {
70
+ recordStarted,
71
+ recordResumed,
72
+ recordStopped,
73
+ recordPaused,
74
+ recordingMediaOptions,
75
+ videoAlreadyOn,
76
+ currentFacingMode,
77
+ prevFacingMode,
78
+ allowed,
79
+ audioOnlyRoom,
80
+ updateCurrentFacingMode,
81
+ updateIsMediaSettingsModalVisible,
82
+ updatePrevFacingMode,
83
+
84
+ showAlert,
85
+
86
+ //media functions
87
+ switchUserVideoAlt
88
+ } = parameters
89
+
90
+ if (audioOnlyRoom) {
91
+ showAlert?.({
92
+ message: 'You cannot turn on your camera in an audio-only event.',
93
+ type: 'danger',
94
+ duration: 3000
95
+ })
96
+ return
97
+ }
98
+
99
+ let checkoff = false
100
+ if (
101
+ (recordStarted || recordResumed) &&
102
+ !recordStopped &&
103
+ !recordPaused &&
104
+ recordingMediaOptions === 'video'
105
+ ) {
106
+ checkoff = true
107
+ }
108
+
109
+ if (!allowed) {
110
+ showAlert?.({
111
+ message:
112
+ 'Allow access to your camera by starting it for the first time.',
113
+ type: 'danger',
114
+ duration: 3000
115
+ })
116
+ return
117
+ }
118
+
119
+ if (checkoff) {
120
+ if (videoAlreadyOn) {
121
+ showAlert?.({
122
+ message: 'Please turn off your video before switching.',
123
+ type: 'danger',
124
+ duration: 3000
125
+ })
126
+ return
127
+ }
128
+ } else {
129
+ if (!videoAlreadyOn) {
130
+ showAlert?.({
131
+ message: 'Please turn on your video before switching.',
132
+ type: 'danger',
133
+ duration: 3000
134
+ })
135
+ return
136
+ }
137
+ }
138
+
139
+ // Camera switching logic
140
+ prevFacingMode = currentFacingMode
141
+ updatePrevFacingMode(prevFacingMode)
142
+
143
+ currentFacingMode = currentFacingMode === 'environment' ? 'user' : 'environment'
144
+ updateCurrentFacingMode(currentFacingMode)
145
+
146
+ updateIsMediaSettingsModalVisible(false)
147
+ await switchUserVideoAlt({
148
+ videoPreference: currentFacingMode,
149
+ checkoff,
150
+ parameters
151
+ })
152
+ }
@@ -0,0 +1,103 @@
1
+ import { PreJoinPageParameters } from "../../types/types";
2
+ import { Socket } from "socket.io-client";
3
+ import Cookies from "universal-cookie";
4
+
5
+
6
+ const cookies = new Cookies();
7
+ const MAX_ATTEMPTS = 10; // Maximum number of unsuccessful attempts before rate limiting
8
+ const RATE_LIMIT_DURATION = 3 * 60 * 60 * 1000; // 3 hours in milliseconds
9
+
10
+
11
+ export const checkLimitsAndMakeRequest = async ({
12
+ apiUserName,
13
+ apiToken,
14
+ link,
15
+ apiKey = "",
16
+ userName,
17
+ parameters,
18
+ validate = true,
19
+ }: {
20
+ apiUserName: string;
21
+ apiToken: string;
22
+ link: string;
23
+ apiKey?: string;
24
+ userName: string;
25
+ parameters: PreJoinPageParameters;
26
+ validate?: boolean;
27
+ }) => {
28
+ const TIMEOUT_DURATION = 10000; // 10 seconds
29
+ let unsuccessfulAttempts =
30
+ parseInt(cookies.get("unsuccessfulAttempts")) || 0;
31
+ let lastRequestTimestamp =
32
+ parseInt(cookies.get("lastRequestTimestamp")) || 0;
33
+
34
+ if (
35
+ unsuccessfulAttempts >= MAX_ATTEMPTS &&
36
+ Date.now() - lastRequestTimestamp < RATE_LIMIT_DURATION
37
+ ) {
38
+ parameters.showAlert?.({
39
+ message: "Too many unsuccessful attempts. Please try again later.",
40
+ type: "danger",
41
+ duration: 3000,
42
+ });
43
+ return;
44
+ } else {
45
+ unsuccessfulAttempts = 0;
46
+ cookies.set("unsuccessfulAttempts", unsuccessfulAttempts.toString());
47
+ cookies.set("lastRequestTimestamp", Date.now().toString());
48
+ }
49
+
50
+ try {
51
+ parameters.updateIsLoadingModalVisible(true);
52
+ const socketPromise = await parameters.connectSocket({
53
+ apiUserName,
54
+ apiKey,
55
+ apiToken,
56
+ link,
57
+ });
58
+ const timeoutPromise = new Promise<null>((_, reject) =>
59
+ setTimeout(
60
+ () => reject(new Error("Request timed out")),
61
+ TIMEOUT_DURATION
62
+ )
63
+ );
64
+
65
+ const socket = await Promise.race([socketPromise, timeoutPromise]);
66
+ if (socket && socket instanceof Socket && socket.id) {
67
+ unsuccessfulAttempts = 0;
68
+ cookies.set("unsuccessfulAttempts", unsuccessfulAttempts.toString());
69
+ cookies.set("lastRequestTimestamp", Date.now().toString());
70
+ if (validate){
71
+ // only one connection is established, no local socket
72
+ parameters.updateSocket(socket);
73
+ }else{
74
+ // local socket is also established, mediaSFU connection is now the local socket
75
+ parameters.updateLocalSocket?.(socket);
76
+ }
77
+ parameters.updateApiUserName(apiUserName);
78
+ parameters.updateApiToken(apiToken);
79
+ parameters.updateLink(link);
80
+ parameters.updateRoomName(apiUserName);
81
+ parameters.updateMember(userName);
82
+ if (validate) parameters.updateValidated(true);
83
+ } else {
84
+ unsuccessfulAttempts += 1;
85
+ cookies.set("unsuccessfulAttempts", unsuccessfulAttempts.toString());
86
+ parameters.updateIsLoadingModalVisible(false);
87
+ parameters.showAlert?.({
88
+ message: "Invalid credentials.",
89
+ type: "danger",
90
+ duration: 3000,
91
+ });
92
+ }
93
+ } catch {
94
+ parameters.showAlert?.({
95
+ message: "Unable to connect. Check your credentials and try again.",
96
+ type: "danger",
97
+ duration: 3000,
98
+ });
99
+ unsuccessfulAttempts += 1;
100
+ cookies.set("unsuccessfulAttempts", unsuccessfulAttempts.toString());
101
+ parameters.updateIsLoadingModalVisible(false);
102
+ }
103
+ };
@@ -0,0 +1,41 @@
1
+
2
+ export interface ValidateAlphanumericOptions {
3
+ str: string;
4
+ }
5
+
6
+ // Export the type definition for the function
7
+ export type ValidateAlphanumericType = (options: ValidateAlphanumericOptions) => Promise<boolean>;
8
+
9
+ /**
10
+ * Validates if the given string contains only alphanumeric characters.
11
+ *
12
+ * @param {ValidateAlphanumericOptions} options - The options containing the string to validate.
13
+ * @param {string} options.str - The string to be validated.
14
+ * @returns {Promise<boolean>} - A promise that resolves to `true` if the string is alphanumeric, otherwise `false`.
15
+ *
16
+ * @example
17
+ * ```typescript
18
+ * const isValid = await validateAlphanumeric({ str: "abc123" });
19
+ * console.log(isValid);
20
+ * // Output: true
21
+ * ```
22
+ */
23
+
24
+
25
+ const validateAlphanumeric = async ({ str }: ValidateAlphanumericOptions): Promise<boolean> => {
26
+ let code: number, i: number, len: number;
27
+
28
+ for (i = 0, len = str.length; i < len; i++) {
29
+ code = str.charCodeAt(i);
30
+ if (
31
+ !(code > 47 && code < 58) && // numeric (0-9)
32
+ !(code > 64 && code < 91) && // upper alpha (A-Z)
33
+ !(code > 96 && code < 123) // lower alpha (a-z)
34
+ ) {
35
+ return false;
36
+ }
37
+ }
38
+ return true;
39
+ };
40
+
41
+ export { validateAlphanumeric };
@@ -0,0 +1 @@
1
+ export { respondToWaiting, type RespondToWaitingType, type RespondToWaitingOptions } from './respondToWaiting';
@@ -0,0 +1,26 @@
1
+ export interface LaunchWaitingOptions {
2
+ updateIsWaitingModalVisible: (visible: boolean) => void
3
+ isWaitingModalVisible: boolean
4
+ }
5
+
6
+ export type LaunchWaitingType = (options: LaunchWaitingOptions) => void
7
+
8
+ /**
9
+ * Toggles the visibility of the waiting modal.
10
+ *
11
+ * @param {LaunchWaitingOptions} options - The options for toggling the waiting modal visibility.
12
+ * @param {Function} options.updateIsWaitingModalVisible - Function to update the visibility state of the waiting modal.
13
+ * @param {boolean} options.isWaitingModalVisible - Current visibility state of the waiting modal.
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * const options = {
18
+ * updateIsWaitingModalVisible: (visible: boolean) => console.log('Waiting modal visibility updated:', visible),
19
+ * isWaitingModalVisible: true,
20
+ * }
21
+ * launchWaiting(options)
22
+ * ```
23
+ */
24
+ export const launchWaiting: LaunchWaitingType = ({ updateIsWaitingModalVisible, isWaitingModalVisible }) => {
25
+ updateIsWaitingModalVisible(!isWaitingModalVisible)
26
+ }
@@ -0,0 +1,82 @@
1
+ import { Socket } from "socket.io-client";
2
+ import type { WaitingRoomParticipant } from "../../types/types";
3
+
4
+ export interface RespondToWaitingOptions {
5
+ participantId: string;
6
+ participantName: string;
7
+ updateWaitingList: (waitingList: WaitingRoomParticipant[]) => void;
8
+ waitingList?: WaitingRoomParticipant[];
9
+ type: string | boolean;
10
+ roomName: string;
11
+ socket: Socket;
12
+ }
13
+
14
+ // Export the type definition for the function
15
+ export type RespondToWaitingType = (options: RespondToWaitingOptions) => Promise<void>;
16
+
17
+ /**
18
+ * Responds to a participant waiting to join a room by either allowing or denying their entry.
19
+ *
20
+ * @param {RespondToWaitingOptions} options - The options for responding to the waiting participant.
21
+ * @param {string} options.participantId - The ID of the participant.
22
+ * @param {string} options.participantName - The name of the participant.
23
+ * @param {Function} options.updateWaitingList - The function to update the waiting list.
24
+ * @param {WaitingRoomParticipant[]} options.waitingList - The current waiting list of participants.
25
+ * @param {boolean | string} options.type - The type of response, either "true" or "false".
26
+ * @param {string} options.roomName - The name of the room.
27
+ * @param {Socket} options.socket - The socket instance to emit events.
28
+ *
29
+ * @example
30
+ * ```typescript
31
+ * const options = {
32
+ * participantId: "12345",
33
+ * participantName: "John Doe",
34
+ * updateWaitingList: (list) => console.log("Updated Waiting List:", list),
35
+ * waitingList: [{ id: "12345", name: "John Doe" }],
36
+ * type: true,
37
+ * roomName: "room1",
38
+ * socket: socketInstance,
39
+ * };
40
+ * respondToWaiting(options);
41
+ * ```
42
+ */
43
+
44
+ export const respondToWaiting = async ({
45
+ participantId,
46
+ participantName,
47
+ updateWaitingList,
48
+ waitingList = [],
49
+ type,
50
+ roomName,
51
+ socket,
52
+ }: RespondToWaitingOptions): Promise<void> => {
53
+ if (!participantId || !participantName) {
54
+ return;
55
+ }
56
+
57
+ if (!updateWaitingList) {
58
+ console.warn('[respondToWaiting] Missing updateWaitingList handler; aborting emit.');
59
+ return;
60
+ }
61
+
62
+ if (!socket || typeof (socket as Socket).emit !== 'function') {
63
+ console.warn('[respondToWaiting] Socket is not ready; skipping emit.');
64
+ return;
65
+ }
66
+
67
+ // Filter out the participant from the waiting list
68
+ const newWaitingList = waitingList.filter((item) => item.name !== participantName);
69
+
70
+ // Update the waiting list
71
+ updateWaitingList(newWaitingList);
72
+
73
+ const responseType = type === "true" || type === true ? "true" : "false";
74
+
75
+ // Emit an event to allow or deny the participant based on the response type
76
+ socket.emit("allowUserIn", {
77
+ participantId,
78
+ participantName,
79
+ type: responseType,
80
+ roomName,
81
+ });
82
+ };