@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
@@ -0,0 +1,121 @@
1
+ import {
2
+ SDKActions,
3
+ SDKWorker,
4
+ SagaIterator,
5
+ getLogger,
6
+ sagaEffects,
7
+ VideoAction,
8
+ CallFabricAction,
9
+ SDKWorkerParams,
10
+ VideoMemberEventNames,
11
+ VideoRoomSessionEventNames,
12
+ } from '@signalwire/core'
13
+ import { CallFabricRoomSessionConnection } from '../CallFabricBaseRoomSession'
14
+ import * as videoWorkers from '../../video/workers'
15
+ import { callJoinWorker } from './callJoinWorker'
16
+ import { callLeftWorker } from './callLeftWorker'
17
+ import { callStateWorker } from './callStateWorker'
18
+
19
+ export type CallFabricWorkerParams<T> =
20
+ SDKWorkerParams<CallFabricRoomSessionConnection> & {
21
+ action: T
22
+ }
23
+
24
+ export const callFabricWorker: SDKWorker<CallFabricRoomSessionConnection> =
25
+ function* (options): SagaIterator {
26
+ getLogger().trace('callFabricWorker started')
27
+
28
+ const { channels, instance: roomSession } = options
29
+ const { swEventChannel } = channels
30
+
31
+ function* worker(action: VideoAction | CallFabricAction) {
32
+ const { type, payload } = action
33
+
34
+ switch (type) {
35
+ case 'call.joined': {
36
+ yield sagaEffects.fork(callJoinWorker, {
37
+ action,
38
+ ...options,
39
+ })
40
+ return
41
+ }
42
+ case 'call.left': {
43
+ yield sagaEffects.fork(callLeftWorker, {
44
+ action,
45
+ ...options,
46
+ })
47
+ return
48
+ }
49
+ case 'call.state': {
50
+ yield sagaEffects.fork(callStateWorker, {
51
+ action,
52
+ ...options,
53
+ })
54
+ return
55
+ }
56
+ case 'call.started':
57
+ case 'call.updated':
58
+ case 'call.ended': {
59
+ const action = type.split('.')[1]
60
+ const newEventName = `room.${action}` as VideoRoomSessionEventNames
61
+ roomSession.emit(newEventName, payload)
62
+ break
63
+ }
64
+ case 'member.joined':
65
+ case 'member.left':
66
+ case 'member.updated':
67
+ case 'member.talking': {
68
+ const updatedAction = {
69
+ ...action,
70
+ type: `video.${type}` as VideoMemberEventNames,
71
+ }
72
+ // @ts-expect-error
73
+ yield sagaEffects.fork(videoWorkers.videoMemberWorker, {
74
+ action: updatedAction,
75
+ ...options,
76
+ })
77
+ return
78
+ }
79
+ case 'layout.changed': {
80
+ const updatedAction = {
81
+ ...action,
82
+ type: `video.${type}` as 'video.layout.changed',
83
+ }
84
+ yield sagaEffects.put(swEventChannel, updatedAction)
85
+ break
86
+ }
87
+ case 'member.demoted':
88
+ case 'member.promoted': {
89
+ const updatedAction = {
90
+ ...action,
91
+ type: `video.${type}` as
92
+ | 'video.member.demoted'
93
+ | 'video.member.promoted',
94
+ }
95
+ yield sagaEffects.put(swEventChannel, updatedAction)
96
+ return
97
+ }
98
+ default:
99
+ break
100
+ }
101
+
102
+ // @ts-expect-error
103
+ roomSession.emit(type, payload)
104
+ }
105
+
106
+ const isVideoOrCallEvent = (action: SDKActions) => {
107
+ return (
108
+ action.type.startsWith('call.') ||
109
+ action.type.startsWith('member.') ||
110
+ action.type.startsWith('layout.')
111
+ )
112
+ }
113
+
114
+ while (true) {
115
+ const action = yield sagaEffects.take(swEventChannel, isVideoOrCallEvent)
116
+
117
+ yield sagaEffects.fork(worker, action)
118
+ }
119
+
120
+ getLogger().trace('callFabricWorker ended')
121
+ }
@@ -0,0 +1,90 @@
1
+ import {
2
+ getLogger,
3
+ SagaIterator,
4
+ MapToPubSubShape,
5
+ CallJoinedEvent,
6
+ sagaEffects,
7
+ RoomSessionMember,
8
+ Rooms,
9
+ MemberPosition,
10
+ InternalMemberUpdatedEventNames,
11
+ } from '@signalwire/core'
12
+ import { CallFabricWorkerParams } from './callFabricWorker'
13
+ import { createCallSegmentObject } from '../CallSegment'
14
+ import { videoMemberWorker } from '../../video/videoMemberWorker'
15
+
16
+ export const callJoinWorker = function* (
17
+ options: CallFabricWorkerParams<MapToPubSubShape<CallJoinedEvent>>
18
+ ): SagaIterator {
19
+ getLogger().trace('callJoinWorker started')
20
+ const { action, callSegments, instanceMap, instance: cfRoomSession } = options
21
+ const { payload } = action
22
+ const { get, set } = instanceMap
23
+
24
+ const memberInstances = payload.room_session.members?.map((member: any) => {
25
+ let memberInstance = get<RoomSessionMember>(member.member_id!)
26
+ if (!memberInstance) {
27
+ memberInstance = Rooms.createRoomSessionMemberObject({
28
+ store: cfRoomSession.store,
29
+ payload: {
30
+ room_id: payload.room_id,
31
+ room_session_id: payload.room_session_id,
32
+ member,
33
+ },
34
+ })
35
+ } else {
36
+ memberInstance.setPayload({
37
+ room_id: payload.room_id,
38
+ room_session_id: payload.room_session_id,
39
+ member: member,
40
+ })
41
+ }
42
+ set<RoomSessionMember>(member.member_id, memberInstance)
43
+ return memberInstance
44
+ })
45
+
46
+ const callSegmentInstance = createCallSegmentObject({
47
+ store: cfRoomSession.store,
48
+ payload: {
49
+ ...payload,
50
+ members: memberInstances!,
51
+ },
52
+ })
53
+ callSegments.push(callSegmentInstance)
54
+
55
+ cfRoomSession.runWorker('memberPositionWorker', {
56
+ worker: MemberPosition.memberPositionWorker,
57
+ ...options,
58
+ // @ts-expect-error
59
+ instance: cfRoomSession,
60
+ initialState: payload,
61
+ dispatcher: function* (
62
+ subType: InternalMemberUpdatedEventNames,
63
+ // @ts-expect-error
64
+ subPayload
65
+ ) {
66
+ yield sagaEffects.fork(videoMemberWorker, {
67
+ ...options,
68
+ action: { type: subType, payload: subPayload },
69
+ })
70
+ },
71
+ })
72
+
73
+ // FIXME: Why do we need to emit member.joined from here?
74
+ for (const memberPayload of payload.room_session.members || []) {
75
+ // @ts-expect-error
76
+ yield sagaEffects.fork(videoMemberWorker, {
77
+ ...options,
78
+ action: {
79
+ type: 'video.member.joined',
80
+ payload: { member: memberPayload },
81
+ },
82
+ })
83
+ }
84
+ cfRoomSession.emit('room.subscribed', payload)
85
+
86
+ // @ts-expect-error
87
+ cfRoomSession.emit('call.joined', payload)
88
+
89
+ getLogger().trace('callJoinWorker ended')
90
+ }
@@ -0,0 +1,47 @@
1
+ import {
2
+ getLogger,
3
+ SagaIterator,
4
+ MapToPubSubShape,
5
+ CallLeftEvent,
6
+ RoomSessionMember,
7
+ Rooms,
8
+ } from '@signalwire/core'
9
+ import { CallFabricWorkerParams } from './callFabricWorker'
10
+
11
+ export const callLeftWorker = function* (
12
+ options: CallFabricWorkerParams<MapToPubSubShape<CallLeftEvent>>
13
+ ): SagaIterator {
14
+ getLogger().trace('callLeftWorker started')
15
+
16
+ const {
17
+ action: { payload },
18
+ instance: cfRoomSession,
19
+ callSegments,
20
+ instanceMap,
21
+ } = options
22
+
23
+ const { call_id, room_session_id } = payload
24
+
25
+ // Remove the call segment
26
+ const segmentToRemoveIndex = callSegments.findIndex(
27
+ (segment) => segment.callId == call_id
28
+ )
29
+ if (segmentToRemoveIndex >= 0) {
30
+ callSegments.splice(segmentToRemoveIndex, 1)
31
+ }
32
+
33
+ // Remove all the member instance where roomSessionId matches
34
+ instanceMap.getAll<RoomSessionMember>().forEach(([key, obj]) => {
35
+ if (
36
+ obj instanceof Rooms.RoomSessionMemberAPI &&
37
+ obj.roomSessionId === room_session_id
38
+ ) {
39
+ instanceMap.remove(key)
40
+ }
41
+ })
42
+
43
+ // @ts-expect-error
44
+ cfRoomSession.emit('call.left', payload)
45
+
46
+ getLogger().trace('callLeftWorker ended')
47
+ }
@@ -0,0 +1,39 @@
1
+ import {
2
+ getLogger,
3
+ SagaIterator,
4
+ MapToPubSubShape,
5
+ CallStateEvent,
6
+ } from '@signalwire/core'
7
+ import { CallFabricWorkerParams } from './callFabricWorker'
8
+
9
+ export const callStateWorker = function* (
10
+ options: CallFabricWorkerParams<MapToPubSubShape<CallStateEvent>>
11
+ ): SagaIterator {
12
+ getLogger().trace('callStateWorker started')
13
+
14
+ const {
15
+ instance: cfRoomSession,
16
+ action: { payload },
17
+ callSegments,
18
+ } = options
19
+
20
+ switch (payload.call_state) {
21
+ case 'ended': {
22
+ // @ts-expect-error
23
+ cfRoomSession.emit('call.state', payload)
24
+ // Perfrom the SDK cleanup if callSegments are empty and state is 'destroy'
25
+ // @ts-expect-error
26
+ if (callSegments.length < 1 && cfRoomSession.state === 'destroy') {
27
+ console.log('>> destroy')
28
+ cfRoomSession.destroy()
29
+ }
30
+ break
31
+ }
32
+ default:
33
+ // @ts-expect-error
34
+ cfRoomSession.emit('call.state', payload)
35
+ break
36
+ }
37
+
38
+ getLogger().trace('callStateWorker ended')
39
+ }
@@ -0,0 +1,41 @@
1
+ import {
2
+ getLogger,
3
+ sagaEffects,
4
+ SagaIterator,
5
+ SDKWorker,
6
+ SDKActions,
7
+ MapToPubSubShape,
8
+ ConversationEvent,
9
+ } from '@signalwire/core'
10
+ import { Conversation } from '../Conversation'
11
+ import { Client } from '../Client'
12
+
13
+ interface ConversationWorkerInitialState {
14
+ conversation: Conversation
15
+ }
16
+
17
+ export const conversationWorker: SDKWorker<Client> = function* (
18
+ options
19
+ ): SagaIterator {
20
+ getLogger().debug('conversationWorker started')
21
+ const {
22
+ channels: { swEventChannel },
23
+ initialState,
24
+ } = options
25
+
26
+ const { conversation } = initialState as ConversationWorkerInitialState
27
+
28
+ const isConversationEvent = (action: SDKActions) => {
29
+ return action.type === 'conversation.message'
30
+ }
31
+
32
+ while (true) {
33
+ const action: MapToPubSubShape<ConversationEvent> = yield sagaEffects.take(
34
+ swEventChannel,
35
+ isConversationEvent
36
+ )
37
+ conversation.handleEvent(action.payload)
38
+ }
39
+
40
+ getLogger().trace('conversationWorker ended')
41
+ }
@@ -0,0 +1,5 @@
1
+ export * from './wsClientWorker'
2
+ export * from './conversationWorker'
3
+ export * from './unifiedTargetWorker'
4
+ export * from './unifiedEventsWatcher'
5
+ export * from './callFabricWorker'
@@ -0,0 +1,54 @@
1
+ import { PubSubAction, MappableObject, mapObject } from '@signalwire/core'
2
+
3
+ const EVENT_MAPPINGS: Record<string, string[]> = {
4
+ // 'call.state': [
5
+ // 'call.state.[call_state]',
6
+ // 'video.room.[call_state]',
7
+ // 'video.room.[call_state(created:started)]',
8
+ // ],
9
+ // 'call.play': ['call.play.[state]'],
10
+ // 'call.collect': ['call.collect.[collect_state]'],
11
+ // 'call.connect': ['call.connect.[connect_state]'],
12
+ 'call.joined': ['video.room.subscribed'],
13
+ 'call.audience_count': ['video.room.audience_count'],
14
+ 'call.denoise': ['call.denoise'],
15
+ // 'call.detect': ['call.detect.[detect_state]'],
16
+ 'call.dial': ['call.dial.[dial_state]'],
17
+ 'call.send_digits': ['call.send_digits', 'video.room.send_digits'], //TODO double check
18
+ 'call.refer': ['calling.call.refer'],
19
+ 'call.received': ['call.received'],
20
+ // 'call.fax': ['call.fax.[fax_state]'],
21
+ // 'call.hold': ['call.hold.[fax_state]'],
22
+ // 'call.prompt': ['call.prompt.[prompt_state]'],
23
+ 'call.started': ['video.room.started'],
24
+ 'call.subscribed': ['video.room.subscribed'],
25
+ 'call.updated': ['video.room.updated'],
26
+ 'call.ended': ['video.room.ended'],
27
+ 'member.joined': ['video.member.joined'],
28
+ 'member.left': ['video.member.left'],
29
+ 'member.updated': ['video.member.updated'],
30
+ 'member.talking': ['video.member.talking'],
31
+ 'member.promoted': ['video.member.promoted'],
32
+ 'member.demoted': ['video.member.demoted'],
33
+ 'layout.changed': ['video.layout.changed'],
34
+ 'call.recording': ['video.room.recording.[recording_state]'],
35
+ 'call.playback': ['video.room.playback.[playback_state]'],
36
+ 'call.outbound_stream.started': ['video.stream.started'],
37
+ 'call.outbound_stream.ended': ['video.stream.ended'],
38
+ }
39
+
40
+ export function fromUnifiedEvent(action: MappableObject): PubSubAction[] {
41
+ const { type } = action
42
+
43
+ if (!Object.keys(EVENT_MAPPINGS).includes(type)) {
44
+ return []
45
+ }
46
+
47
+ const mapDefinitions = EVENT_MAPPINGS[type]
48
+ const allNewActions = mapDefinitions.map((eventTemplate) =>
49
+ mapObject(eventTemplate, action)
50
+ )
51
+
52
+ //@ts-expect-error
53
+ return allNewActions.filter((obj?) => !!obj)
54
+ }
@@ -0,0 +1,75 @@
1
+ import {
2
+ MapToPubSubShape,
3
+ SDKActions,
4
+ SDKWorker,
5
+ SagaIterator,
6
+ VideoAPIEventParams,
7
+ getLogger,
8
+ sagaEffects,
9
+ SDKWorkerParams,
10
+ SwEventChannel,
11
+ PubSubAction,
12
+ isMappableObject,
13
+ } from '@signalwire/core'
14
+ import { RoomSessionConnection } from '../../BaseRoomSession'
15
+ import { fromUnifiedEvent } from './mappers/unifiedEventsMapper'
16
+ // import { unifiedTargetWorker } from './unifiedTargetWorker'
17
+
18
+ export type VideoWorkerParams<T> = SDKWorkerParams<RoomSessionConnection> & {
19
+ action: T
20
+ }
21
+
22
+ function* eventMapperWorker({
23
+ action,
24
+ swEventChannel,
25
+ }: {
26
+ action: PubSubAction
27
+ swEventChannel: SwEventChannel
28
+ }) {
29
+ if (isMappableObject(action)) {
30
+ const mappedActions = fromUnifiedEvent(action)
31
+ for (const mappedAction of mappedActions) {
32
+ // @ts-expect-error
33
+ yield sagaEffects.put(swEventChannel, mappedAction)
34
+ }
35
+ }
36
+ }
37
+
38
+ export const unifiedEventsWatcher: SDKWorker<RoomSessionConnection> =
39
+ function* (options): SagaIterator {
40
+ const {
41
+ channels: { swEventChannel },
42
+ } = options
43
+
44
+ getLogger().debug('unifiedEventsWatcher started')
45
+
46
+ function* worker(action: any) {
47
+ yield sagaEffects.fork(eventMapperWorker, {
48
+ ...options,
49
+ action,
50
+ swEventChannel,
51
+ })
52
+
53
+ // // @ts-expect-error FIX ME
54
+ // yield sagaEffects.fork(unifiedTargetWorker, {
55
+ // ...options,
56
+ // action,
57
+ // })
58
+ }
59
+
60
+ const isUnifiedEvent = (action: SDKActions) =>
61
+ action.type.startsWith('member') ||
62
+ action.type.startsWith('layout') ||
63
+ action.type.startsWith('call')
64
+
65
+ while (true) {
66
+ const action: MapToPubSubShape<VideoAPIEventParams> =
67
+ yield sagaEffects.take(swEventChannel, isUnifiedEvent)
68
+
69
+ getLogger().debug('UnifiedEventsWatcher action:', action)
70
+
71
+ yield sagaEffects.fork(worker, action)
72
+ }
73
+
74
+ getLogger().trace('unifiedEventsWatcher ended')
75
+ }
@@ -0,0 +1,96 @@
1
+ import {
2
+ getLogger,
3
+ sagaEffects,
4
+ SagaIterator,
5
+ InternalUnifiedMethodTarget,
6
+ SDKWorker,
7
+ } from '@signalwire/core'
8
+ import { BaseConnection } from '@signalwire/webrtc'
9
+ import { isUnifedJWTSession } from '../../UnifiedJWTSession'
10
+ import { createClient } from '../../createClient'
11
+ import { WSClientWorkerHooks } from './wsClientWorker'
12
+
13
+ function getTarget(event: any): InternalUnifiedMethodTarget | undefined {
14
+ const { member_id } = event
15
+
16
+ if (!member_id) return undefined
17
+
18
+ const member = event.room_session.members.find(
19
+ (m: any) => m.member_id == member_id
20
+ )
21
+ return member
22
+ ? {
23
+ memberId: member.member_id,
24
+ callId: member.call_id,
25
+ nodeId: member.node_id,
26
+ }
27
+ : undefined
28
+ }
29
+
30
+ const segmentWatcher: SDKWorker<
31
+ ReturnType<typeof createClient<BaseConnection<any>>>,
32
+ WSClientWorkerHooks & { callId: string }
33
+ > = function* (options) {
34
+ const {
35
+ channels: { swEventChannel },
36
+ callId,
37
+ getSession,
38
+ } = options
39
+ getLogger().debug('call watcher started from call: ${callId}')
40
+
41
+ function isSegmentEvent(action: any) {
42
+ //we track segments by callId not segmentId
43
+ return action.payload.call_id == callId
44
+ }
45
+
46
+ function* handleCallEvent(action: any) {
47
+ const session = getSession()
48
+ getLogger().debug('segment event handler', action)
49
+ if (action.type === 'call.left') {
50
+ if (isUnifedJWTSession(session)) {
51
+ session.popCallInstanceRef()
52
+ return true; // stop this segements watcher
53
+ }
54
+ }
55
+ return false
56
+ }
57
+
58
+ while (true) {
59
+ const action: any = yield sagaEffects.take(swEventChannel, isSegmentEvent)
60
+ const shouldStop = yield sagaEffects.call(handleCallEvent, action)
61
+ if(shouldStop) break;
62
+ }
63
+
64
+ getLogger().debug(`call watcher ended for call: ${callId}`)
65
+ }
66
+
67
+ export const unifiedTargetWorker: SDKWorker<any> = function* (
68
+ options: any
69
+ ): SagaIterator {
70
+ const { getSession, action } = options
71
+ const logger = getLogger()
72
+ logger.debug('unifiedTargetWorker started', action)
73
+
74
+ if (action.type !== 'call.joined') return
75
+ const callId = action.payload.call_id
76
+ const session = getSession()
77
+
78
+ if (isUnifedJWTSession(session)) {
79
+ const target = getTarget(action.payload)
80
+ if (!!target) {
81
+ session.pushCallInstanceRef(target)
82
+ yield sagaEffects.spawn(segmentWatcher, {
83
+ ...options,
84
+ callId,
85
+ })
86
+ } else {
87
+ getLogger().warn(
88
+ 'No target found in a call.joined event, call stack compromised'
89
+ )
90
+ }
91
+ } else {
92
+ logger.warn('unifiedEventsWatcher is runnif in a non UnifedSession')
93
+ }
94
+
95
+ getLogger().debug('unifiedTargetWorker stoped')
96
+ }
@@ -6,12 +6,10 @@ import {
6
6
  SDKActions,
7
7
  MapToPubSubShape,
8
8
  SDKWorkerHooks,
9
- // VideoMemberJoinedEvent,
10
- // componentSelectors,
11
- // componentActions,
9
+ WebRTCMessageParams,
12
10
  } from '@signalwire/core'
13
- import { createClient } from '../createClient'
14
11
  import type { BaseConnection } from '@signalwire/webrtc'
12
+ import { createClient } from '../../createClient'
15
13
 
16
14
  type WSClientWorkerOnDone = () => void
17
15
  type WSClientWorkerOnFail = (args: { error: Error }) => void
@@ -21,30 +19,28 @@ export type WSClientWorkerHooks = SDKWorkerHooks<
21
19
  WSClientWorkerOnFail
22
20
  >
23
21
 
24
- export const WSClientWorker: SDKWorker<
22
+ export const wsClientWorker: SDKWorker<
25
23
  ReturnType<typeof createClient<BaseConnection<any>>>,
26
24
  WSClientWorkerHooks
27
25
  > = function* (options): SagaIterator {
28
- getLogger().debug('WSClientWorker started')
29
- const { channels, instance } = options
26
+ getLogger().trace('wsClientWorker started')
27
+ const { channels, initialState } = options
30
28
  const { swEventChannel } = channels
31
- getLogger().debug('WSClientWorker instance', instance)
29
+ const { buildInboundCall } = initialState
30
+
32
31
  while (true) {
33
- const action: MapToPubSubShape<any> = yield sagaEffects.take(
34
- swEventChannel,
35
- (action: SDKActions) => {
36
- getLogger().debug('WSClientWorker action', action)
32
+ const action: MapToPubSubShape<WebRTCMessageParams> =
33
+ yield sagaEffects.take(swEventChannel, (action: SDKActions) => {
37
34
  if (action.type === 'webrtc.message') {
38
35
  return action.payload.method === 'verto.invite'
39
36
  }
40
37
  return false
41
- }
42
- )
43
- getLogger().debug('Build new call to answer', action)
38
+ })
39
+ getLogger().debug('Receiving a new call over WebSocket', action)
44
40
 
45
- // TODO: invoke WSClient function to build and answer the invite
46
- // instance.buildInboundCall(action)
41
+ // Invoke WSClient function to build and answer the invite
42
+ buildInboundCall(action.payload.params)
47
43
  }
48
44
 
49
- getLogger().trace('WSClientWorker ended')
45
+ getLogger().trace('wsClientWorker ended')
50
46
  }
@@ -15,11 +15,11 @@ import {
15
15
  waitForVideoReady,
16
16
  LocalOverlay,
17
17
  addSDKPrefix,
18
- createRootElementResizeObserver,
19
18
  } from '../../utils/videoElement'
20
19
  import { setAudioMediaTrack } from '../../utils/audioElement'
21
20
  import { audioSetSpeakerAction } from '../actions'
22
21
  import type { RoomSessionConnection } from '../../BaseRoomSession'
22
+ import { aspectRatioListener } from '../../utils/aspectRatioListener'
23
23
 
24
24
  export const makeVideoElementSaga = ({
25
25
  rootElement,
@@ -354,7 +354,7 @@ function* videoElementSetupWorker({
354
354
 
355
355
  element.style.width = '100%'
356
356
  element.style.maxHeight = '100%'
357
-
357
+
358
358
  if (!applyLocalVideoOverlay) {
359
359
  rootElement.appendChild(element)
360
360
  return
@@ -374,11 +374,16 @@ function* videoElementSetupWorker({
374
374
 
375
375
  const paddingWrapper = document.createElement('div')
376
376
  paddingWrapper.classList.add('paddingWrapper')
377
- paddingWrapper.style.paddingBottom = '56.25%'
378
377
  paddingWrapper.style.position = 'relative'
379
378
  paddingWrapper.style.width = '100%'
380
379
  paddingWrapper.appendChild(mcuWrapper)
381
380
 
381
+ //for less then 3 participants video call, the video aspect ratio can change
382
+ aspectRatioListener({
383
+ videoElement: element,
384
+ paddingWrapper,
385
+ fixInLandscapeOrientation: rootElement.classList.contains('landscape-only') });
386
+
382
387
  const layersWrapper = document.createElement('div')
383
388
  layersWrapper.classList.add('mcuLayers')
384
389
  layersWrapper.style.display = 'none'
@@ -406,19 +411,8 @@ function* videoElementSetupWorker({
406
411
  }
407
412
  getLogger().debug('MCU is ready..')
408
413
 
409
- const rootElementResizeObserver = createRootElementResizeObserver({
410
- rootElement,
411
- video: element,
412
- paddingWrapper,
413
- })
414
- rootElementResizeObserver.start()
415
- track.addEventListener('ended', () => {
416
- if (rootElementResizeObserver) {
417
- rootElementResizeObserver.stop()
418
- }
419
- })
420
-
421
414
  layersWrapper.style.display = 'block'
415
+
422
416
  } catch (error) {
423
417
  getLogger().error('Handle video track error', error)
424
418
  }