@signalwire/js 3.26.0 → 3.27.0-dev.202404301530.94a97d7.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 (181) hide show
  1. package/dist/core/src/BaseComponent.d.ts +10 -0
  2. package/dist/core/src/BaseComponent.d.ts.map +1 -1
  3. package/dist/core/src/BaseJWTSession.d.ts.map +1 -1
  4. package/dist/core/src/BaseSession.d.ts +3 -0
  5. package/dist/core/src/BaseSession.d.ts.map +1 -1
  6. package/dist/core/src/RPCMessages/RPCConnect.d.ts +14 -0
  7. package/dist/core/src/RPCMessages/RPCConnect.d.ts.map +1 -1
  8. package/dist/core/src/index.d.ts +4 -3
  9. package/dist/core/src/index.d.ts.map +1 -1
  10. package/dist/core/src/memberPosition/workers.d.ts.map +1 -1
  11. package/dist/core/src/redux/index.d.ts +5 -0
  12. package/dist/core/src/redux/index.d.ts.map +1 -1
  13. package/dist/core/src/redux/interfaces.d.ts +2 -0
  14. package/dist/core/src/redux/interfaces.d.ts.map +1 -1
  15. package/dist/core/src/redux/utils/useInstanceMap.d.ts +2 -0
  16. package/dist/core/src/redux/utils/useInstanceMap.d.ts.map +1 -1
  17. package/dist/core/src/rooms/RoomSessionMember.d.ts +39 -0
  18. package/dist/core/src/rooms/RoomSessionMember.d.ts.map +1 -0
  19. package/dist/core/src/rooms/index.d.ts +1 -0
  20. package/dist/core/src/rooms/index.d.ts.map +1 -1
  21. package/dist/core/src/rooms/methods.d.ts +2 -2
  22. package/dist/core/src/rooms/methods.d.ts.map +1 -1
  23. package/dist/core/src/testUtils.d.ts +8 -0
  24. package/dist/core/src/testUtils.d.ts.map +1 -1
  25. package/dist/core/src/types/callSegment.d.ts +21 -0
  26. package/dist/core/src/types/callSegment.d.ts.map +1 -0
  27. package/dist/core/src/types/callfabric.d.ts +337 -16
  28. package/dist/core/src/types/callfabric.d.ts.map +1 -1
  29. package/dist/core/src/types/conversation.d.ts +24 -0
  30. package/dist/core/src/types/conversation.d.ts.map +1 -0
  31. package/dist/core/src/types/index.d.ts +15 -1
  32. package/dist/core/src/types/index.d.ts.map +1 -1
  33. package/dist/core/src/types/unified.d.ts +36 -0
  34. package/dist/core/src/types/unified.d.ts.map +1 -0
  35. package/dist/core/src/types/utils.d.ts +3 -0
  36. package/dist/core/src/types/utils.d.ts.map +1 -1
  37. package/dist/core/src/types/videoMember.d.ts +11 -1
  38. package/dist/core/src/types/videoMember.d.ts.map +1 -1
  39. package/dist/core/src/types/videoRoomSession.d.ts +3 -0
  40. package/dist/core/src/types/videoRoomSession.d.ts.map +1 -1
  41. package/dist/core/src/utils/index.d.ts +1 -0
  42. package/dist/core/src/utils/index.d.ts.map +1 -1
  43. package/dist/core/src/utils/interfaces.d.ts +16 -9
  44. package/dist/core/src/utils/interfaces.d.ts.map +1 -1
  45. package/dist/core/src/utils/mapObject.d.ts +7 -0
  46. package/dist/core/src/utils/mapObject.d.ts.map +1 -0
  47. package/dist/core/src/utils/mapObject.test.d.ts +2 -0
  48. package/dist/core/src/utils/mapObject.test.d.ts.map +1 -0
  49. package/dist/core/src/workers/executeActionWorker.d.ts.map +1 -1
  50. package/dist/index.esm.js +1352 -527
  51. package/dist/index.esm.js.map +3 -3
  52. package/dist/index.js +1448 -642
  53. package/dist/index.js.map +3 -3
  54. package/dist/index.umd.js +3 -3
  55. package/dist/index.umd.js.map +1 -1
  56. package/dist/js/src/BaseRoomSession.d.ts +6 -4
  57. package/dist/js/src/BaseRoomSession.d.ts.map +1 -1
  58. package/dist/js/src/Client.d.ts +1 -0
  59. package/dist/js/src/Client.d.ts.map +1 -1
  60. package/dist/js/src/JWTSession.d.ts.map +1 -1
  61. package/dist/js/src/UnifiedJWTSession.d.ts +16 -0
  62. package/dist/js/src/UnifiedJWTSession.d.ts.map +1 -0
  63. package/dist/js/src/fabric/CallFabricBaseRoomSession.d.ts +30 -0
  64. package/dist/js/src/fabric/CallFabricBaseRoomSession.d.ts.map +1 -0
  65. package/dist/js/src/fabric/CallSegment.d.ts +26 -0
  66. package/dist/js/src/fabric/CallSegment.d.ts.map +1 -0
  67. package/dist/js/src/fabric/Conversation.d.ts +144 -0
  68. package/dist/js/src/fabric/Conversation.d.ts.map +1 -0
  69. package/dist/js/src/fabric/ConversationAPI.d.ts +61 -0
  70. package/dist/js/src/fabric/ConversationAPI.d.ts.map +1 -0
  71. package/dist/js/src/fabric/HTTPClient.d.ts +45 -27
  72. package/dist/js/src/fabric/HTTPClient.d.ts.map +1 -1
  73. package/dist/js/src/fabric/IncomingCallManager.d.ts +14 -0
  74. package/dist/js/src/fabric/IncomingCallManager.d.ts.map +1 -0
  75. package/dist/js/src/fabric/SignalWire.d.ts +1 -16
  76. package/dist/js/src/fabric/SignalWire.d.ts.map +1 -1
  77. package/dist/js/src/fabric/WSClient.d.ts +23 -28
  78. package/dist/js/src/fabric/WSClient.d.ts.map +1 -1
  79. package/dist/js/src/fabric/createHttpClient.d.ts +1 -0
  80. package/dist/js/src/fabric/createHttpClient.d.ts.map +1 -1
  81. package/dist/js/src/fabric/index.d.ts +3 -0
  82. package/dist/js/src/fabric/index.d.ts.map +1 -1
  83. package/dist/js/src/fabric/types.d.ts +93 -0
  84. package/dist/js/src/fabric/types.d.ts.map +1 -0
  85. package/dist/js/src/fabric/workers/callFabricWorker.d.ts +7 -0
  86. package/dist/js/src/fabric/workers/callFabricWorker.d.ts.map +1 -0
  87. package/dist/js/src/fabric/workers/callJoinWorker.d.ts +4 -0
  88. package/dist/js/src/fabric/workers/callJoinWorker.d.ts.map +1 -0
  89. package/dist/js/src/fabric/workers/callLeftWorker.d.ts +4 -0
  90. package/dist/js/src/fabric/workers/callLeftWorker.d.ts.map +1 -0
  91. package/dist/js/src/fabric/workers/callStateWorker.d.ts +4 -0
  92. package/dist/js/src/fabric/workers/callStateWorker.d.ts.map +1 -0
  93. package/dist/js/src/fabric/workers/conversationWorker.d.ts +4 -0
  94. package/dist/js/src/fabric/workers/conversationWorker.d.ts.map +1 -0
  95. package/dist/js/src/fabric/workers/index.d.ts +6 -0
  96. package/dist/js/src/fabric/workers/index.d.ts.map +1 -0
  97. package/dist/js/src/fabric/workers/mappers/unifiedEventsMapper.d.ts +3 -0
  98. package/dist/js/src/fabric/workers/mappers/unifiedEventsMapper.d.ts.map +1 -0
  99. package/dist/js/src/fabric/workers/unifiedEventsWatcher.d.ts +7 -0
  100. package/dist/js/src/fabric/workers/unifiedEventsWatcher.d.ts.map +1 -0
  101. package/dist/js/src/fabric/workers/unifiedTargetWorker.d.ts +3 -0
  102. package/dist/js/src/fabric/workers/unifiedTargetWorker.d.ts.map +1 -0
  103. package/dist/js/src/fabric/{WSClientWorker.d.ts → workers/wsClientWorker.d.ts} +3 -3
  104. package/dist/js/src/fabric/workers/wsClientWorker.d.ts.map +1 -0
  105. package/dist/js/src/features/mediaElements/mediaElementsSagas.d.ts.map +1 -1
  106. package/dist/js/src/index.d.ts +7 -8
  107. package/dist/js/src/index.d.ts.map +1 -1
  108. package/dist/js/src/testUtils.d.ts +17 -0
  109. package/dist/js/src/testUtils.d.ts.map +1 -1
  110. package/dist/js/src/utils/UnifiedRequestMapper.d.ts +4 -0
  111. package/dist/js/src/utils/UnifiedRequestMapper.d.ts.map +1 -0
  112. package/dist/js/src/utils/aspectRatioListener.d.ts +8 -0
  113. package/dist/js/src/utils/aspectRatioListener.d.ts.map +1 -0
  114. package/dist/js/src/utils/interfaces.d.ts +3 -1
  115. package/dist/js/src/utils/interfaces.d.ts.map +1 -1
  116. package/dist/js/src/utils/makeQueryParamsUrl.d.ts +9 -0
  117. package/dist/js/src/utils/makeQueryParamsUrl.d.ts.map +1 -0
  118. package/dist/js/src/utils/paginatedResult.d.ts +44 -0
  119. package/dist/js/src/utils/paginatedResult.d.ts.map +1 -0
  120. package/dist/js/src/utils/videoElement.d.ts +4 -0
  121. package/dist/js/src/utils/videoElement.d.ts.map +1 -1
  122. package/dist/js/src/video/videoMemberWorker.d.ts +6 -0
  123. package/dist/js/src/video/videoMemberWorker.d.ts.map +1 -0
  124. package/dist/js/src/video/videoRoomWorker.d.ts +4 -0
  125. package/dist/js/src/video/videoRoomWorker.d.ts.map +1 -0
  126. package/dist/js/src/video/videoWorker.d.ts.map +1 -1
  127. package/dist/js/src/video/videoWorkerUnifiedEventing.d.ts +4 -0
  128. package/dist/js/src/video/videoWorkerUnifiedEventing.d.ts.map +1 -0
  129. package/dist/js/src/video/workers.d.ts +5 -0
  130. package/dist/js/src/video/workers.d.ts.map +1 -1
  131. package/dist/js/tsconfig.build.tsbuildinfo +1 -1
  132. package/dist/webrtc/src/BaseConnection.d.ts.map +1 -1
  133. package/dist/webrtc/src/RTCPeer.d.ts.map +1 -1
  134. package/dist/webrtc/src/workers/roomSubscribedWorker.d.ts.map +1 -1
  135. package/package.json +6 -3
  136. package/src/BaseRoomSession.test.ts +3 -2
  137. package/src/BaseRoomSession.ts +8 -2
  138. package/src/Client.ts +10 -2
  139. package/src/JWTSession.test.ts +2 -2
  140. package/src/JWTSession.ts +1 -1
  141. package/src/UnifiedJWTSession.ts +78 -0
  142. package/src/fabric/CallFabricBaseRoomSession.test.ts +460 -0
  143. package/src/fabric/CallFabricBaseRoomSession.ts +269 -0
  144. package/src/fabric/CallSegment.ts +83 -0
  145. package/src/fabric/Conversation.test.ts +257 -0
  146. package/src/fabric/Conversation.ts +150 -0
  147. package/src/fabric/ConversationAPI.ts +44 -0
  148. package/src/fabric/HTTPClient.test.ts +23 -18
  149. package/src/fabric/HTTPClient.ts +52 -55
  150. package/src/fabric/IncomingCallManager.test.ts +245 -0
  151. package/src/fabric/IncomingCallManager.ts +89 -0
  152. package/src/fabric/SignalWire.ts +20 -17
  153. package/src/fabric/WSClient.ts +153 -117
  154. package/src/fabric/createHttpClient.ts +2 -0
  155. package/src/fabric/index.ts +3 -0
  156. package/src/fabric/types.ts +104 -0
  157. package/src/fabric/workers/callFabricWorker.ts +121 -0
  158. package/src/fabric/workers/callJoinWorker.ts +90 -0
  159. package/src/fabric/workers/callLeftWorker.ts +47 -0
  160. package/src/fabric/workers/callStateWorker.ts +39 -0
  161. package/src/fabric/workers/conversationWorker.ts +41 -0
  162. package/src/fabric/workers/index.ts +5 -0
  163. package/src/fabric/workers/mappers/unifiedEventsMapper.ts +54 -0
  164. package/src/fabric/workers/unifiedEventsWatcher.ts +75 -0
  165. package/src/fabric/workers/unifiedTargetWorker.ts +96 -0
  166. package/src/fabric/{WSClientWorker.ts → workers/wsClientWorker.ts} +14 -18
  167. package/src/features/mediaElements/mediaElementsSagas.ts +9 -15
  168. package/src/index.ts +25 -9
  169. package/src/testUtils.ts +83 -0
  170. package/src/utils/UnifiedRequestMapper.ts +149 -0
  171. package/src/utils/aspectRatioListener.ts +40 -0
  172. package/src/utils/interfaces.ts +3 -0
  173. package/src/utils/makeQueryParamsUrl.ts +14 -0
  174. package/src/utils/paginatedResult.ts +34 -0
  175. package/src/utils/videoElement.ts +4 -0
  176. package/src/video/videoMemberWorker.ts +107 -0
  177. package/src/video/videoRoomWorker.ts +103 -0
  178. package/src/video/videoWorker.ts +8 -3
  179. package/src/video/videoWorkerUnifiedEventing.ts +95 -0
  180. package/src/video/workers.ts +5 -0
  181. package/dist/js/src/fabric/WSClientWorker.d.ts.map +0 -1
package/src/index.ts CHANGED
@@ -30,8 +30,6 @@ import type {
30
30
  VideoMemberEntity,
31
31
  } from '@signalwire/core'
32
32
 
33
- import { SWClient, SignalWire } from './fabric'
34
-
35
33
  /** @ignore @deprecated */
36
34
  export type RoomStartedEventName = RoomStarted
37
35
  /** @ignore @deprecated */
@@ -59,10 +57,10 @@ export * as PubSub from './pubSub'
59
57
 
60
58
  /**
61
59
  * CallFabric namespace
62
- * @internal
63
60
  */
64
61
  export * as Fabric from './fabric'
65
- export { SWClient, SignalWire }
62
+ export { SWClient, SignalWire } from './fabric'
63
+ export * from './fabric/types'
66
64
 
67
65
  /**
68
66
  * The Video namespace contains the classes and functions that you need to
@@ -78,9 +76,6 @@ export * as Video from './video'
78
76
  */
79
77
  export * as WebRTC from './webrtc'
80
78
 
81
- export type { VideoPosition, VideoPositions } from '@signalwire/core'
82
-
83
- /** @ignore */
84
79
  export type {
85
80
  BaseComponentOptions,
86
81
  BaseConnectionState,
@@ -100,15 +95,36 @@ export type {
100
95
  MemberTalkingEventNames,
101
96
  VideoMemberTalkingEventParams,
102
97
  InternalVideoMemberEntity,
98
+ VideoPosition,
99
+ VideoPositions,
100
+ /**
101
+ * Call Fabric types
102
+ */
103
+ GetAddressesOptions,
104
+ Address,
105
+ FetchAddressResponse,
106
+ GetConversationsOptions,
107
+ Conversation,
108
+ FetchConversationsResponse,
109
+ GetMessagesOptions,
110
+ ConversationMessage,
111
+ FetchConversationMessagesResponse,
112
+ GetConversationMessagesOptions,
113
+ SubscriberInfoResponse,
114
+ ConversationMessageEventName,
115
+ ConversationMessageEvent,
116
+ ConversationEventParams,
117
+ ConversationEvent,
118
+ RegisterDeviceParams,
119
+ UnregisterDeviceParams,
120
+ RegisterDeviceResponse,
103
121
  } from '@signalwire/core'
104
122
 
105
- /** @ignore */
106
123
  export type {
107
124
  BaseConnectionOptions,
108
125
  ConnectionOptions,
109
126
  } from '@signalwire/webrtc'
110
127
 
111
- /** @ignore */
112
128
  export type {
113
129
  RoomSessionObjectEventsHandlerMap,
114
130
  RoomSessionObjectEvents,
package/src/testUtils.ts CHANGED
@@ -98,3 +98,86 @@ export const dispatchMockedRoomSubscribed = ({
98
98
 
99
99
  session.dispatch(actions.socketMessageAction(payload))
100
100
  }
101
+
102
+ export const dispatchMockedCallJoined = ({
103
+ session,
104
+ roomId,
105
+ roomSessionId,
106
+ memberId,
107
+ memberId2 = 'member-id-random',
108
+ callId,
109
+ nodeId,
110
+ }: {
111
+ session: any
112
+ roomSessionId: string
113
+ roomId: string
114
+ memberId: string
115
+ memberId2?: string
116
+ callId: string
117
+ nodeId: string
118
+ }) => {
119
+ const payload = {
120
+ jsonrpc: '2.0',
121
+ id: 'cb78f2eb-6468-48ed-979d-a94fca47befe',
122
+ method: 'signalwire.event',
123
+ params: {
124
+ event_type: 'call.joined',
125
+ event_channel:
126
+ 'signalwire_0c1c9852-b9d4-4a18-ba3b-eeafe1ffe504_13451811-bd4c-4646-b3ce-250581a7956e_94df1ecd-d073-473d-aa4d-a286e24f679b',
127
+ params: {
128
+ room_session: {
129
+ room_id: roomId,
130
+ room_session_id: roomSessionId,
131
+ event_channel:
132
+ 'signalwire_0c1c9852-b9d4-4a18-ba3b-eeafe1ffe504_13451811-bd4c-4646-b3ce-250581a7956e_94df1ecd-d073-473d-aa4d-a286e24f679b',
133
+ layout_name: '1x1',
134
+ meta: {},
135
+ members: [
136
+ {
137
+ type: 'member',
138
+ call_id: callId,
139
+ member_id: memberId,
140
+ node_id: nodeId,
141
+ name: 'sip:foo@94df1ecd-d073-473d-aa4d-a286e24f679b.call.signalwire.com;context=private',
142
+ room_id: roomId,
143
+ room_session_id: roomSessionId,
144
+ visible: true,
145
+ handraised: false,
146
+ audio_muted: false,
147
+ video_muted: false,
148
+ deaf: false,
149
+ meta: {},
150
+ },
151
+ {
152
+ type: 'member',
153
+ call_id: callId,
154
+ member_id: memberId2,
155
+ node_id: nodeId,
156
+ name: 'sip:foo@94df1ecd-d073-473d-aa4d-a286e24f679b.call.signalwire.com;context=private',
157
+ room_id: roomId,
158
+ room_session_id: roomSessionId,
159
+ visible: true,
160
+ handraised: false,
161
+ audio_muted: false,
162
+ video_muted: false,
163
+ deaf: false,
164
+ meta: {},
165
+ },
166
+ ],
167
+ recordings: [],
168
+ streams: [],
169
+ playbacks: [],
170
+ },
171
+ room_id: roomId,
172
+ room_session_id: roomSessionId,
173
+ call_id: callId,
174
+ member_id: memberId,
175
+ node_id: nodeId,
176
+ },
177
+ timestamp: 1712142454.67701,
178
+ },
179
+ }
180
+
181
+ // @ts-expect-error
182
+ session.dispatch(actions.socketMessageAction(payload))
183
+ }
@@ -0,0 +1,149 @@
1
+ import { InternalUnifiedMethodTarget } from '../../../core/src'
2
+
3
+ export type UnifiedResquestMapFunction = (
4
+ requestMessage: any,
5
+ self: InternalUnifiedMethodTarget,
6
+ targets?: InternalUnifiedMethodTarget[]
7
+ ) => void
8
+
9
+ const toServerUnifiedTarget = ({
10
+ memberId: member_id,
11
+ callId: call_id,
12
+ nodeId: node_id,
13
+ }: InternalUnifiedMethodTarget) => ({ member_id, call_id, node_id })
14
+
15
+ const toServerUnifedParams = (
16
+ self: InternalUnifiedMethodTarget,
17
+ targets: InternalUnifiedMethodTarget[] = []
18
+ ) => {
19
+ return {
20
+ self: toServerUnifiedTarget(self),
21
+ target: targets.length == 1 ? toServerUnifiedTarget(targets[0]) : undefined,
22
+ targets:
23
+ targets.length > 1 ? targets.map(toServerUnifiedTarget) : undefined,
24
+ }
25
+ }
26
+
27
+ const unifiedPayload = (
28
+ method: string,
29
+ id: string,
30
+ self: InternalUnifiedMethodTarget,
31
+ targets: InternalUnifiedMethodTarget[] = [],
32
+ extra = {}
33
+ ) => ({
34
+ jsonrpc: '2.0',
35
+ id,
36
+ method,
37
+ params: {
38
+ ...extra,
39
+ ...toServerUnifedParams(self, targets),
40
+ },
41
+ })
42
+
43
+ const withChannelsPayload = (
44
+ method: string,
45
+ channels: string[],
46
+ id: string,
47
+ self: InternalUnifiedMethodTarget,
48
+ targets: InternalUnifiedMethodTarget[]
49
+ ) => unifiedPayload(method, id, self, targets, { channels })
50
+
51
+ export const UnifiedRequestMapper: Record<string, UnifiedResquestMapFunction> =
52
+ {
53
+ 'video.member.audio_mute': (requestMessage, self, targets) =>
54
+ withChannelsPayload(
55
+ 'call.mute',
56
+ ['audio'],
57
+ requestMessage.id,
58
+ self,
59
+ targets!
60
+ ),
61
+
62
+ 'video.member.audio_unmute': (requestMessage, self, targets) =>
63
+ withChannelsPayload(
64
+ 'call.unmute',
65
+ ['audio'],
66
+ requestMessage.id,
67
+ self,
68
+ targets!
69
+ ),
70
+
71
+ 'video.member.video_mute': (requestMessage, self, targets) =>
72
+ withChannelsPayload(
73
+ 'call.mute',
74
+ ['video'],
75
+ requestMessage.id,
76
+ self,
77
+ targets!
78
+ ),
79
+
80
+ 'video.member.video_unmute': (requestMessage, self, targets) =>
81
+ withChannelsPayload(
82
+ 'call.unmute',
83
+ ['video'],
84
+ requestMessage.id,
85
+ self,
86
+ targets!
87
+ ),
88
+
89
+ 'video.member.deaf': (requestMessage, self, targets) =>
90
+ unifiedPayload('call.deaf', requestMessage.id, self, targets),
91
+
92
+ 'video.member.undeaf': (requestMessage, self, targets) =>
93
+ unifiedPayload('call.undeaf', requestMessage.id, self, targets),
94
+
95
+ 'video.list_available_layouts': (requestMessage, self) =>
96
+ unifiedPayload('call.layout.list', requestMessage, self),
97
+
98
+ 'video.members.get': (requestMessage, self) =>
99
+ unifiedPayload('call.member.list', requestMessage, self),
100
+
101
+ 'video.member.remove': (requestMessage, self, targets) =>
102
+ unifiedPayload('call.member.remove', requestMessage.id, self, targets),
103
+
104
+ 'video.set_layout': (requestMessage, self, targets) => {
105
+ const extra = {
106
+ layout: Object.values(requestMessage.params.positions)[0],
107
+ }
108
+ return unifiedPayload(
109
+ 'call.layout.set',
110
+ requestMessage.id,
111
+ self,
112
+ targets,
113
+ extra
114
+ )
115
+ },
116
+
117
+ 'video.member.set_input_volume': (requestMessage, self, targets) => {
118
+ const { volume } = requestMessage.params
119
+ return unifiedPayload(
120
+ 'call.microphone.volume.set',
121
+ requestMessage.id,
122
+ self,
123
+ targets,
124
+ { volume }
125
+ )
126
+ },
127
+
128
+ 'video.member.set_output_volume': (requestMessage, self, targets) => {
129
+ const { volume } = requestMessage.params
130
+ return unifiedPayload(
131
+ 'call.speaker.volume.set',
132
+ requestMessage.id,
133
+ self,
134
+ targets,
135
+ { volume }
136
+ )
137
+ },
138
+
139
+ 'video.member.set_input_sensitivity': (requestMessage, self, targets) => {
140
+ const { vslue: sensitivity } = requestMessage.params
141
+ return unifiedPayload(
142
+ 'call.microphone.sensitivity.set',
143
+ requestMessage.id,
144
+ self,
145
+ targets,
146
+ { sensitivity }
147
+ )
148
+ },
149
+ }
@@ -0,0 +1,40 @@
1
+ const VIDEO_SIZING_EVENTS = ['loadedmetadata', 'resize']
2
+
3
+ export function aspectRatioListener({videoElement, paddingWrapper, fixInLandscapeOrientation = false, debugDivElementId = 'videoDimensionsDebug', samplingInterval = 0}: {videoElement: HTMLVideoElement, paddingWrapper: HTMLDivElement, fixInLandscapeOrientation: boolean, debugDivElementId?: string, samplingInterval?: number}) {
4
+ const buildHtmlContent = (event:string, width: number, height: number) => `Video dimensions on <strong>${event} event</strong>:</strong> ${width}x${height}px - fixInLandscapeOrientation: ${fixInLandscapeOrientation}`
5
+ const appendDebugInfo = (containerElement: HTMLElement, event:string) => {
6
+ const pEl = document.createElement('p')
7
+ pEl.innerHTML = buildHtmlContent(event, videoElement.videoWidth, videoElement.videoHeight);
8
+ containerElement.appendChild(pEl);
9
+ }
10
+
11
+ let debugElement: HTMLElement|null;
12
+ try {
13
+ debugElement = document.getElementById(debugDivElementId);
14
+ } catch {}
15
+
16
+ VIDEO_SIZING_EVENTS.forEach(event => videoElement.addEventListener(event, () => {
17
+ const paddingBottom = fixInLandscapeOrientation ? '56.25' :
18
+ (videoElement.videoHeight / videoElement.videoWidth) * 100
19
+ paddingWrapper.style.paddingBottom = `${paddingBottom}%`
20
+ if(debugElement) {
21
+ appendDebugInfo(debugElement, event)
22
+ }
23
+ }));
24
+
25
+ if(samplingInterval > 0) {
26
+ setInterval(() => {
27
+ const paddingBottom = (videoElement.videoHeight / videoElement.videoWidth) * 100
28
+ paddingWrapper.style.paddingBottom = `${paddingBottom}%`
29
+ if(debugElement) {
30
+ let statsElement = debugElement.querySelector('.timer-values')
31
+ if(!statsElement) {
32
+ statsElement = document.createElement('div');
33
+ statsElement.className = 'timer-values'
34
+ debugElement.appendChild(statsElement);
35
+ }
36
+ appendDebugInfo(debugElement, 'timer')
37
+ }
38
+ });
39
+ }
40
+ }
@@ -37,6 +37,7 @@ import type {
37
37
  VideoRoomDeviceDisconnectedEventNames,
38
38
  DeviceDisconnectedEventParams,
39
39
  VideoRoomDeviceEventNames,
40
+ InternalUnifiedMethodTarget,
40
41
  } from '@signalwire/core'
41
42
  import { INTERNAL_MEMBER_UPDATABLE_PROPS } from '@signalwire/core'
42
43
  import type { MediaEvent } from '@signalwire/webrtc'
@@ -197,6 +198,8 @@ export interface MemberCommandWithValueParams extends MemberCommandParams {
197
198
  export interface BaseRoomInterface {
198
199
  join(): Promise<unknown>
199
200
  leave(): Promise<unknown>
201
+ self?: InternalUnifiedMethodTarget
202
+ target?: InternalUnifiedMethodTarget
200
203
  }
201
204
 
202
205
  export interface LocalOverlay {
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Constructs a URL with query parameters.
3
+ *
4
+ * @param path The base path of the URL.
5
+ * @param queryParams An instance of URLSearchParams containing all query parameters.
6
+ * @returns The constructed URL with query parameters.
7
+ */
8
+ export function makeQueryParamsUrls(
9
+ path: string,
10
+ queryParams: URLSearchParams
11
+ ): string {
12
+ const queryString = queryParams.toString()
13
+ return queryString ? `${path}?${queryString}` : path
14
+ }
@@ -0,0 +1,34 @@
1
+ import { PaginatedResponse } from '@signalwire/core'
2
+ import { CreateHttpClient } from '../fabric/createHttpClient'
3
+
4
+ export function buildPaginatedResult<T>(
5
+ body: PaginatedResponse<T>,
6
+ client: CreateHttpClient
7
+ ) {
8
+ const anotherPage = async <T>(url: string) => {
9
+ const { body } = await client<PaginatedResponse<T>>(url)
10
+ return buildPaginatedResult(body, client)
11
+ }
12
+
13
+ return {
14
+ data: body.data,
15
+ self: async () => {
16
+ const { self } = body.links
17
+ return self ? anotherPage(self) : undefined
18
+ },
19
+ nextPage: async () => {
20
+ const { next } = body.links
21
+ return next ? anotherPage(next) : undefined
22
+ },
23
+ prevPage: async () => {
24
+ const { prev } = body.links
25
+ return prev ? anotherPage(prev) : undefined
26
+ },
27
+ firstPage: async () => {
28
+ const { first } = body.links
29
+ return first ? anotherPage(first) : undefined
30
+ },
31
+ hasNext: Boolean(body.links.next),
32
+ hasPrev: Boolean(body.links.prev),
33
+ }
34
+ }
@@ -183,6 +183,10 @@ const setVideoMediaTrack = ({
183
183
  })
184
184
  }
185
185
 
186
+ /**
187
+ * @deprecated
188
+ * FIXME remove this in the future
189
+ */
186
190
  const createRootElementResizeObserver = ({
187
191
  video,
188
192
  rootElement,
@@ -0,0 +1,107 @@
1
+ import {
2
+ InternalVideoMemberUpdatedEvent,
3
+ MapToPubSubShape,
4
+ MemberTalkingEventNames,
5
+ RoomSessionMember,
6
+ Rooms,
7
+ SagaIterator,
8
+ VideoMemberEventNames,
9
+ VideoMemberJoinedEvent,
10
+ VideoMemberLeftEvent,
11
+ VideoMemberTalkingEvent,
12
+ VideoMemberUpdatedEvent,
13
+ getLogger,
14
+ stripNamespacePrefix,
15
+ } from '@signalwire/core'
16
+ import { VideoWorkerParams } from './videoWorker'
17
+
18
+ type VideoMemberEvents = MapToPubSubShape<
19
+ | VideoMemberJoinedEvent
20
+ | VideoMemberLeftEvent
21
+ | VideoMemberUpdatedEvent
22
+ | VideoMemberTalkingEvent
23
+ | InternalVideoMemberUpdatedEvent
24
+ >
25
+
26
+ export const videoMemberWorker = function* (
27
+ options: VideoWorkerParams<VideoMemberEvents>
28
+ ): SagaIterator {
29
+ getLogger().trace('videoMemberWorker started')
30
+ const {
31
+ instance: roomSession,
32
+ callSegments,
33
+ action: { type, payload },
34
+ instanceMap: { get, set, remove },
35
+ } = options
36
+
37
+ // For now, we are not storing the RoomSession object in the instance map
38
+
39
+ const memberId = payload.member?.id || payload.member?.member_id
40
+
41
+ let memberInstance = get<RoomSessionMember>(memberId!)
42
+ if (!memberInstance) {
43
+ memberInstance = Rooms.createRoomSessionMemberObject({
44
+ store: roomSession.store,
45
+ payload: payload as Rooms.RoomSessionMemberEventParams,
46
+ })
47
+ } else {
48
+ memberInstance.setPayload(payload as Rooms.RoomSessionMemberEventParams)
49
+ }
50
+ set<RoomSessionMember>(memberId!, memberInstance)
51
+
52
+ /**
53
+ * If the incoming event is for the self member
54
+ * Send the payload with a member id from the first call segment for a consistent member id
55
+ */
56
+ let newPayload = { ...payload }
57
+ const currentCallSegment = callSegments[callSegments.length - 1]
58
+ if (payload.member.member_id === currentCallSegment.memberId) {
59
+ // FIXME: We should emit the RoomSessionMember instance
60
+ // @ts-expect-error
61
+ newPayload = {
62
+ ...payload,
63
+ member: {
64
+ ...payload.member,
65
+ id: roomSession.callSegments[0].memberId,
66
+ member_id: roomSession.callSegments[0].memberId,
67
+ },
68
+ }
69
+ }
70
+
71
+ const event = stripNamespacePrefix(type) as VideoMemberEventNames
72
+
73
+ if (type.startsWith('video.member.updated.')) {
74
+ roomSession.emit(event, newPayload)
75
+ }
76
+
77
+ switch (type) {
78
+ case 'video.member.joined':
79
+ case 'video.member.updated':
80
+ roomSession.emit(event, newPayload)
81
+ break
82
+ case 'video.member.left':
83
+ roomSession.emit(event, newPayload)
84
+ remove<RoomSessionMember>(memberId!)
85
+ break
86
+ case 'video.member.talking':
87
+ roomSession.emit(event, newPayload)
88
+ if ('talking' in payload.member) {
89
+ const suffix = payload.member.talking ? 'started' : 'ended'
90
+ roomSession.emit(
91
+ `${event}.${suffix}` as MemberTalkingEventNames,
92
+ newPayload
93
+ )
94
+
95
+ // Keep for backwards compatibility
96
+ const deprecatedSuffix = payload.member.talking ? 'start' : 'stop'
97
+ roomSession.emit(
98
+ `${event}.${deprecatedSuffix}` as MemberTalkingEventNames,
99
+ newPayload
100
+ )
101
+ }
102
+ break
103
+ default:
104
+ break
105
+ }
106
+ getLogger().trace('videoMemberWorker ended')
107
+ }
@@ -0,0 +1,103 @@
1
+ import {
2
+ getLogger,
3
+ SagaIterator,
4
+ MapToPubSubShape,
5
+ Rooms,
6
+ RoomSessionMember,
7
+ VideoRoomEvent,
8
+ sagaEffects,
9
+ MemberPosition,
10
+ InternalMemberUpdatedEventNames,
11
+ InternalVideoMemberEntity,
12
+ } from '@signalwire/core'
13
+ import { VideoWorkerParams } from './videoWorker'
14
+ import { videoMemberWorker } from './videoMemberWorker'
15
+
16
+ export const videoRoomWorker = function* (
17
+ options: VideoWorkerParams<MapToPubSubShape<VideoRoomEvent>>
18
+ ): SagaIterator {
19
+ getLogger().trace('videoRoomWorker started')
20
+ const { action, ...memberPositionWorkerParams } = options
21
+ const { type, payload } = action
22
+ const {
23
+ instance: roomSession,
24
+ instanceMap: { get, set },
25
+ } = options
26
+
27
+ // For now, we are not storing the RoomSession object in the instance map
28
+
29
+ // Upsert member in the instance map
30
+ if ((payload.room_session?.members?.length || 0) > 0) {
31
+ ;(payload.room_session.members || []).forEach((member) => {
32
+ const memberId = member.id || member.member_id!
33
+ const roomSessionId =
34
+ payload.room_session.id || payload.room_session.room_session_id!
35
+
36
+ let memberInstance = get<RoomSessionMember>(memberId)
37
+ if (!memberInstance) {
38
+ memberInstance = Rooms.createRoomSessionMemberObject({
39
+ store: roomSession.store,
40
+ payload: {
41
+ room_id: payload.room_session.room_id,
42
+ room_session_id: roomSessionId,
43
+ member: member as InternalVideoMemberEntity & { talking: boolean },
44
+ },
45
+ })
46
+ } else {
47
+ memberInstance.setPayload({
48
+ room_id: payload.room_session.room_id,
49
+ room_session_id: roomSessionId,
50
+ member: member as InternalVideoMemberEntity & { talking: boolean },
51
+ })
52
+ }
53
+ set<RoomSessionMember>(memberId, memberInstance)
54
+ })
55
+ }
56
+
57
+ switch (type) {
58
+ case 'video.room.started': {
59
+ roomSession.emit('room.started', payload)
60
+ break
61
+ }
62
+ case 'video.room.updated': {
63
+ roomSession.emit('room.updated', payload)
64
+ break
65
+ }
66
+ case 'video.room.ended': {
67
+ roomSession.emit('room.ended', payload)
68
+ break
69
+ }
70
+ case 'video.room.subscribed': {
71
+ yield sagaEffects.spawn(MemberPosition.memberPositionWorker, {
72
+ ...memberPositionWorkerParams,
73
+ instance: roomSession,
74
+ initialState: payload,
75
+ dispatcher: function* (
76
+ subType: InternalMemberUpdatedEventNames,
77
+ subPayload
78
+ ) {
79
+ yield sagaEffects.fork(videoMemberWorker, {
80
+ ...options,
81
+ action: { type: subType, payload: subPayload },
82
+ })
83
+ },
84
+ })
85
+ for (const memberPayload of payload.room_session.members) {
86
+ //@ts-expect-error
87
+ yield sagaEffects.fork(videoMemberWorker, {
88
+ ...options,
89
+ action: {
90
+ type: 'video.member.joined',
91
+ payload: { member: memberPayload },
92
+ },
93
+ })
94
+ }
95
+ roomSession.emit('room.subscribed', payload)
96
+ break
97
+ }
98
+ default:
99
+ break
100
+ }
101
+
102
+ getLogger().trace('videoRoomWorker ended')
103
+ }
@@ -23,6 +23,8 @@ export type VideoWorkerParams<T> = SDKWorkerParams<RoomSessionConnection> & {
23
23
  export const videoWorker: SDKWorker<RoomSessionConnection> = function* (
24
24
  options
25
25
  ): SagaIterator {
26
+ getLogger().trace('videoWorker started')
27
+
26
28
  const { channels, instance: roomSession } = options
27
29
  const { swEventChannel } = channels
28
30
 
@@ -80,14 +82,17 @@ export const videoWorker: SDKWorker<RoomSessionConnection> = function* (
80
82
  break
81
83
  }
82
84
 
83
- roomSession.emit(stripNamespacePrefix(type) as VideoAPIEventNames, payload)
85
+ const event = stripNamespacePrefix(type, 'video') as VideoAPIEventNames
86
+ roomSession.emit(event, payload)
84
87
  }
85
88
 
86
- const isVideoEvent = (action: SDKActions) => action.type.startsWith('video.')
89
+ const isVideoOrCallEvent = (action: SDKActions) => {
90
+ return action.type.startsWith('video.') || action.type.startsWith('call.')
91
+ }
87
92
 
88
93
  while (true) {
89
94
  const action: MapToPubSubShape<VideoAPIEventParams> =
90
- yield sagaEffects.take(swEventChannel, isVideoEvent)
95
+ yield sagaEffects.take(swEventChannel, isVideoOrCallEvent)
91
96
 
92
97
  yield sagaEffects.fork(worker, action)
93
98
  }