@signalwire/js 3.28.0 → 3.28.1

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 (104) hide show
  1. package/dist/core/src/BaseSession.d.ts +1 -1
  2. package/dist/core/src/RPCMessages/VertoMessages.d.ts +7 -0
  3. package/dist/core/src/RPCMessages/VertoMessages.d.ts.map +1 -1
  4. package/dist/core/src/index.d.ts +2 -2
  5. package/dist/core/src/index.d.ts.map +1 -1
  6. package/dist/core/src/redux/features/component/componentSlice.d.ts +96 -0
  7. package/dist/core/src/redux/features/component/componentSlice.d.ts.map +1 -1
  8. package/dist/core/src/redux/rootReducer.d.ts +16 -0
  9. package/dist/core/src/redux/rootReducer.d.ts.map +1 -1
  10. package/dist/core/src/types/common.d.ts +16 -10
  11. package/dist/core/src/types/common.d.ts.map +1 -1
  12. package/dist/core/src/types/fabric.d.ts +0 -27
  13. package/dist/core/src/types/fabric.d.ts.map +1 -1
  14. package/dist/core/src/types/index.d.ts +67 -1
  15. package/dist/core/src/types/index.d.ts.map +1 -1
  16. package/dist/core/src/types/videoPlayback.d.ts +1 -7
  17. package/dist/core/src/types/videoPlayback.d.ts.map +1 -1
  18. package/dist/core/src/types/videoRecording.d.ts +1 -7
  19. package/dist/core/src/types/videoRecording.d.ts.map +1 -1
  20. package/dist/core/src/types/voice.d.ts +13 -2
  21. package/dist/core/src/types/voice.d.ts.map +1 -1
  22. package/dist/core/src/types/voiceCall.d.ts +96 -964
  23. package/dist/core/src/types/voiceCall.d.ts.map +1 -1
  24. package/dist/core/src/types/voiceCollect.d.ts +166 -0
  25. package/dist/core/src/types/voiceCollect.d.ts.map +1 -0
  26. package/dist/core/src/types/voiceConnect.d.ts +77 -0
  27. package/dist/core/src/types/voiceConnect.d.ts.map +1 -0
  28. package/dist/core/src/types/voiceDetect.d.ts +127 -0
  29. package/dist/core/src/types/voiceDetect.d.ts.map +1 -0
  30. package/dist/core/src/types/voicePlayback.d.ts +141 -0
  31. package/dist/core/src/types/voicePlayback.d.ts.map +1 -0
  32. package/dist/core/src/types/voicePrompt.d.ts +105 -0
  33. package/dist/core/src/types/voicePrompt.d.ts.map +1 -0
  34. package/dist/core/src/types/voiceRecording.d.ts +107 -0
  35. package/dist/core/src/types/voiceRecording.d.ts.map +1 -0
  36. package/dist/core/src/types/voiceSendDigits.d.ts +21 -0
  37. package/dist/core/src/types/voiceSendDigits.d.ts.map +1 -0
  38. package/dist/core/src/types/voiceTap.d.ts +116 -0
  39. package/dist/core/src/types/voiceTap.d.ts.map +1 -0
  40. package/dist/core/src/utils/constants.d.ts.map +1 -1
  41. package/dist/core/src/utils/eventUtils.d.ts +0 -2
  42. package/dist/core/src/utils/eventUtils.d.ts.map +1 -1
  43. package/dist/core/src/utils/interfaces.d.ts +19 -2
  44. package/dist/core/src/utils/interfaces.d.ts.map +1 -1
  45. package/dist/index.esm.js +636 -223
  46. package/dist/index.esm.js.map +4 -4
  47. package/dist/index.js +655 -233
  48. package/dist/index.js.map +4 -4
  49. package/dist/index.umd.js +26 -2
  50. package/dist/index.umd.js.map +1 -1
  51. package/dist/js/src/fabric/Conversation.d.ts +2 -2
  52. package/dist/js/src/fabric/Conversation.d.ts.map +1 -1
  53. package/dist/js/src/fabric/FabricRoomSession.d.ts +5 -4
  54. package/dist/js/src/fabric/FabricRoomSession.d.ts.map +1 -1
  55. package/dist/js/src/fabric/SignalWire.d.ts.map +1 -1
  56. package/dist/js/src/fabric/WSClient.d.ts +2 -2
  57. package/dist/js/src/fabric/WSClient.d.ts.map +1 -1
  58. package/dist/js/src/fabric/createWSClient.d.ts +1 -1
  59. package/dist/js/src/fabric/createWSClient.d.ts.map +1 -1
  60. package/dist/js/src/fabric/interfaces/capabilities.d.ts +28 -0
  61. package/dist/js/src/fabric/interfaces/capabilities.d.ts.map +1 -0
  62. package/dist/js/src/fabric/interfaces/conversation.d.ts +4 -4
  63. package/dist/js/src/fabric/interfaces/conversation.d.ts.map +1 -1
  64. package/dist/js/src/fabric/interfaces/index.d.ts +1 -0
  65. package/dist/js/src/fabric/interfaces/index.d.ts.map +1 -1
  66. package/dist/js/src/fabric/interfaces/wsClient.d.ts +2 -2
  67. package/dist/js/src/fabric/interfaces/wsClient.d.ts.map +1 -1
  68. package/dist/js/src/fabric/utils/capabilitiesHelpers.d.ts +28 -0
  69. package/dist/js/src/fabric/utils/capabilitiesHelpers.d.ts.map +1 -0
  70. package/dist/js/src/fabric/workers/callJoinWorker.d.ts.map +1 -1
  71. package/dist/js/src/fabric/workers/wsClientWorker.d.ts.map +1 -1
  72. package/dist/js/src/index.d.ts +2 -2
  73. package/dist/js/src/index.d.ts.map +1 -1
  74. package/dist/js/src/utils/interfaces/fabric.d.ts +6 -3
  75. package/dist/js/src/utils/interfaces/fabric.d.ts.map +1 -1
  76. package/dist/js/src/utils/paginatedResult.d.ts +4 -4
  77. package/dist/js/tsconfig.build.tsbuildinfo +1 -1
  78. package/dist/webrtc/src/BaseConnection.d.ts +78 -19
  79. package/dist/webrtc/src/BaseConnection.d.ts.map +1 -1
  80. package/dist/webrtc/src/RTCPeer.d.ts +11 -0
  81. package/dist/webrtc/src/RTCPeer.d.ts.map +1 -1
  82. package/dist/webrtc/src/utils/helpers.d.ts.map +1 -1
  83. package/dist/webrtc/src/utils/interfaces.d.ts +6 -0
  84. package/dist/webrtc/src/utils/interfaces.d.ts.map +1 -1
  85. package/dist/webrtc/src/utils/sdpHelpers.d.ts +27 -2
  86. package/dist/webrtc/src/utils/sdpHelpers.d.ts.map +1 -1
  87. package/package.json +3 -3
  88. package/src/fabric/Conversation.ts +9 -7
  89. package/src/fabric/FabricRoomSession.ts +32 -32
  90. package/src/fabric/SignalWire.test.ts +2 -0
  91. package/src/fabric/SignalWire.ts +2 -0
  92. package/src/fabric/WSClient.ts +6 -10
  93. package/src/fabric/interfaces/capabilities.ts +30 -0
  94. package/src/fabric/interfaces/conversation.ts +5 -4
  95. package/src/fabric/interfaces/index.ts +2 -1
  96. package/src/fabric/interfaces/wsClient.ts +2 -2
  97. package/src/fabric/utils/capabilitiesHelpers.test.ts +201 -0
  98. package/src/fabric/utils/capabilitiesHelpers.ts +190 -0
  99. package/src/fabric/workers/callJoinWorker.ts +7 -6
  100. package/src/fabric/workers/wsClientWorker.ts +35 -12
  101. package/src/index.ts +1 -1
  102. package/src/utils/interfaces/fabric.ts +10 -3
  103. package/dist/core/src/utils/eventUtils.test.d.ts +0 -2
  104. package/dist/core/src/utils/eventUtils.test.d.ts.map +0 -1
@@ -0,0 +1,30 @@
1
+
2
+ export interface CapabilityOnOffStateContract {
3
+ on: boolean
4
+ off: boolean
5
+ }
6
+
7
+ export interface MemberCapabilityContract {
8
+ muteAudio: CapabilityOnOffStateContract
9
+ muteVideo: CapabilityOnOffStateContract
10
+ microphoneVolume: boolean
11
+ microphoneSensitivity: boolean
12
+ speakerVolume: boolean
13
+ deaf: CapabilityOnOffStateContract
14
+ raisehand: CapabilityOnOffStateContract
15
+ position: boolean
16
+ meta: boolean
17
+ remove: boolean
18
+ }
19
+
20
+ export interface CallCapabilitiesContract {
21
+ self: MemberCapabilityContract
22
+ member: MemberCapabilityContract
23
+ end: boolean
24
+ setLayout: boolean
25
+ sendDigit: boolean
26
+ vmutedHide: CapabilityOnOffStateContract
27
+ lock: CapabilityOnOffStateContract
28
+ device: boolean
29
+ screenshare: boolean
30
+ }
@@ -49,20 +49,21 @@ export type GetConversationsResponse = PaginatedResponse<ConversationResponse>
49
49
 
50
50
  export type GetConversationsResult = PaginatedResult<ConversationContract>
51
51
 
52
- export type CoversationSubscribeCallback = (
52
+ export type ConversationSubscribeCallback = (
53
53
  event: ConversationEventParams
54
54
  ) => unknown
55
55
 
56
- export interface CoversationSubscribeResult {
56
+ export interface ConversationSubscribeResult {
57
57
  unsubscribe: () => void
58
58
  }
59
59
 
60
60
  export interface ConversationChatMessagesSubscribeParams {
61
61
  addressId: string
62
- onMessage: CoversationSubscribeCallback
62
+ onMessage: ConversationSubscribeCallback
63
63
  }
64
64
 
65
- export type ConversationChatMessagesSubscribeResult = CoversationSubscribeResult
65
+ export type ConversationChatMessagesSubscribeResult =
66
+ ConversationSubscribeResult
66
67
 
67
68
  export interface JoinConversationParams {
68
69
  addressId: string
@@ -76,6 +76,7 @@ export type GetSubscriberInfoResult = GetSubscriberInfoResponse
76
76
 
77
77
  // #endregion Subscriber info
78
78
 
79
+ export * from './capabilities'
79
80
  export * from './address'
80
81
  export * from './conversation'
81
82
  export * from './device'
@@ -90,4 +91,4 @@ export type {
90
91
  ConversationMessageEvent,
91
92
  ConversationEvent,
92
93
  ConversationEventParams,
93
- } from '@signalwire/core'
94
+ } from '@signalwire/core'
@@ -85,11 +85,11 @@ export interface CallParams {
85
85
  disableUdpIceServers?: boolean
86
86
  /** Audio constraints to use when joining the room. Default: `true`. */
87
87
  audio?: MediaStreamConstraints['audio']
88
- /** Video constraints to use when joining the room. Default: `true`. */
88
+ /** Video constraints to use when joining the room. Default: `true` for "video" channel. */
89
89
  video?: MediaStreamConstraints['video']
90
90
  /** Negotiate the incoming audio from the RTC. Default: `true`. */
91
91
  negotiateAudio?: boolean
92
- /** Negotiate the incoming video from the RTC. Default: `true`. */
92
+ /** Negotiate the incoming video from the RTC. Default: `true` for "video" channel. */
93
93
  negotiateVideo?: boolean
94
94
  /** User & UserAgent metadata */
95
95
  userVariables?: WSClientOptions['userVariables']
@@ -0,0 +1,201 @@
1
+ import { stripNamespacePrefix } from "@signalwire/core"
2
+ import { mapCapabilityPayload } from "./capabilitiesHelpers"
3
+
4
+ describe('eventUtils', () => {
5
+ describe('stripNamespacePrefix', () => {
6
+ it('should strip first word before dot', () => {
7
+ const event1 = 'random.event.foo'
8
+ const event2 = 'random.event.bar'
9
+ expect(stripNamespacePrefix(event1)).toBe('event.foo')
10
+ expect(stripNamespacePrefix(event2)).toBe('event.bar')
11
+ })
12
+
13
+ it('should not strip if there is no dot', () => {
14
+ const event1 = 'randomeventfoo'
15
+ const event2 = 'randomeventbar'
16
+ expect(stripNamespacePrefix(event1)).toBe('randomeventfoo')
17
+ expect(stripNamespacePrefix(event2)).toBe('randomeventbar')
18
+ })
19
+
20
+ it('should strip the namespace if passed', () => {
21
+ const event1 = 'video.event.foo'
22
+ const event2 = 'voice.event.bar'
23
+ expect(stripNamespacePrefix(event1, 'video')).toBe('event.foo')
24
+ expect(stripNamespacePrefix(event2, 'voice')).toBe('event.bar')
25
+ })
26
+ })
27
+
28
+ describe('mapCapabilitiesPayload', () => {
29
+ it('should have all capabilities', () => {
30
+ const callCapabilities = mapCapabilityPayload([
31
+ 'self',
32
+ 'member',
33
+ 'device',
34
+ 'screenshare',
35
+ 'lock',
36
+ 'end',
37
+ 'vmuted',
38
+ 'layout',
39
+ 'digit',
40
+ 'lock',
41
+ ])
42
+ expect(callCapabilities.member?.deaf?.on).toEqual(true)
43
+ expect(callCapabilities.member?.deaf?.off).toEqual(true)
44
+ expect(callCapabilities.member?.raisehand?.on).toEqual(true)
45
+ expect(callCapabilities.member?.raisehand?.off).toEqual(true)
46
+ expect(callCapabilities.member?.muteVideo?.on).toEqual(true)
47
+ expect(callCapabilities.member?.muteVideo?.off).toEqual(true)
48
+ expect(callCapabilities.member?.muteAudio?.on).toEqual(true)
49
+ expect(callCapabilities.member?.muteAudio?.off).toEqual(true)
50
+ expect(callCapabilities.member?.meta).toEqual(true)
51
+ expect(callCapabilities.member?.position).toEqual(true)
52
+ expect(callCapabilities.member?.remove).toEqual(true)
53
+ expect(callCapabilities.member?.microphoneSensitivity).toEqual(true)
54
+ expect(callCapabilities.member?.microphoneVolume).toEqual(true)
55
+ expect(callCapabilities.member?.speakerVolume).toEqual(true)
56
+
57
+ expect(callCapabilities.self?.deaf?.on).toEqual(true)
58
+ expect(callCapabilities.self?.deaf?.off).toEqual(true)
59
+ expect(callCapabilities.self?.raisehand?.on).toEqual(true)
60
+ expect(callCapabilities.self?.raisehand?.off).toEqual(true)
61
+ expect(callCapabilities.self?.muteVideo?.on).toEqual(true)
62
+ expect(callCapabilities.self?.muteVideo?.off).toEqual(true)
63
+ expect(callCapabilities.self?.muteAudio?.on).toEqual(true)
64
+ expect(callCapabilities.self?.muteAudio?.off).toEqual(true)
65
+ expect(callCapabilities.self?.meta).toEqual(true)
66
+ expect(callCapabilities.self?.position).toEqual(true)
67
+ expect(callCapabilities.self?.remove).toEqual(true)
68
+ expect(callCapabilities.self?.microphoneSensitivity).toEqual(true)
69
+ expect(callCapabilities.self?.microphoneVolume).toEqual(true)
70
+ expect(callCapabilities.self?.speakerVolume).toEqual(true)
71
+
72
+ expect(callCapabilities.device).toEqual(true)
73
+ expect(callCapabilities.screenshare).toEqual(true)
74
+ expect(callCapabilities.sendDigit).toEqual(true)
75
+ expect(callCapabilities.setLayout).toEqual(true)
76
+ expect(callCapabilities.end).toEqual(true)
77
+ expect(callCapabilities.lock?.on).toEqual(true)
78
+ expect(callCapabilities.lock?.off).toEqual(true)
79
+ expect(callCapabilities.vmutedHide?.on).toEqual(true)
80
+ expect(callCapabilities.vmutedHide?.off).toEqual(true)
81
+ })
82
+
83
+ it('should have some self capabilities and others member capabilities', () => {
84
+ const callCapabilities = mapCapabilityPayload([
85
+ 'member.deaf',
86
+ 'member.mute.video',
87
+ 'member.mute.audio.on',
88
+ 'self.remove',
89
+ 'self.microphone',
90
+ ])
91
+ expect(callCapabilities.member?.deaf?.on).toEqual(true)
92
+ expect(callCapabilities.member?.deaf?.off).toEqual(true)
93
+ expect(callCapabilities.member?.raisehand?.on).toEqual(true)
94
+ expect(callCapabilities.member?.raisehand?.off).toEqual(true)
95
+ expect(callCapabilities.member?.muteVideo?.on).toEqual(true)
96
+ expect(callCapabilities.member?.muteVideo?.off).toEqual(true)
97
+ expect(callCapabilities.member?.muteAudio?.on).toEqual(true)
98
+ expect(callCapabilities.member?.muteAudio?.off).toBeFalsy()
99
+ expect(callCapabilities.member?.meta).toBeFalsy()
100
+ expect(callCapabilities.member?.position).toBeFalsy()
101
+ expect(callCapabilities.member?.remove).toBeFalsy()
102
+ expect(callCapabilities.member?.microphoneSensitivity).toBeFalsy()
103
+ expect(callCapabilities.member?.microphoneVolume).toBeFalsy()
104
+ expect(callCapabilities.member?.speakerVolume).toBeFalsy()
105
+
106
+ expect(callCapabilities.self?.deaf?.on).toBeFalsy()
107
+ expect(callCapabilities.self?.deaf?.off).toBeFalsy()
108
+ expect(callCapabilities.self?.raisehand?.on).toEqual(true)
109
+ expect(callCapabilities.self?.raisehand?.off).toEqual(true)
110
+ expect(callCapabilities.self?.muteVideo?.on).toBeFalsy()
111
+ expect(callCapabilities.self?.muteVideo?.off).toBeFalsy()
112
+ expect(callCapabilities.self?.muteAudio?.on).toBeFalsy()
113
+ expect(callCapabilities.self?.muteAudio?.off).toBeFalsy()
114
+ expect(callCapabilities.self?.meta).toBeFalsy()
115
+ expect(callCapabilities.self?.position).toBeFalsy()
116
+ expect(callCapabilities.self?.remove).toEqual(true)
117
+ expect(callCapabilities.self?.microphoneSensitivity).toEqual(true)
118
+ expect(callCapabilities.self?.microphoneVolume).toEqual(true)
119
+ expect(callCapabilities.self?.speakerVolume).toBeFalsy()
120
+
121
+ expect(callCapabilities.device).toBeFalsy()
122
+ expect(callCapabilities.screenshare).toBeFalsy()
123
+ expect(callCapabilities.sendDigit).toBeFalsy()
124
+ expect(callCapabilities.setLayout).toBeFalsy()
125
+ expect(callCapabilities.end).toBeFalsy()
126
+ expect(callCapabilities.lock?.on).toBeFalsy()
127
+ expect(callCapabilities.lock?.off).toBeFalsy()
128
+ expect(callCapabilities.vmutedHide?.on).toBeFalsy()
129
+ expect(callCapabilities.vmutedHide?.off).toBeFalsy()
130
+ })
131
+
132
+ it('should have some both on and off', () => {
133
+ const callCapabilities = mapCapabilityPayload([
134
+ 'member.mute.video',
135
+ 'member.mute.audio.on',
136
+ 'member.mute.audio.off',
137
+ ])
138
+ expect(callCapabilities.member?.muteVideo?.on).toEqual(true)
139
+ expect(callCapabilities.member?.muteVideo?.off).toEqual(true)
140
+ expect(callCapabilities.member?.muteAudio?.on).toEqual(true)
141
+ expect(callCapabilities.member?.muteAudio?.off).toEqual(true)
142
+ })
143
+ })
144
+
145
+ it('should not break if the server send redundant capability', () => {
146
+ const callCapabilities = mapCapabilityPayload([
147
+ 'self',
148
+ 'self.deaf',
149
+ 'self.mute.audio',
150
+ 'self.mute.audio.on',
151
+ 'member',
152
+ 'device',
153
+ 'screenshare',
154
+ 'lock',
155
+ 'end',
156
+ 'vmuted',
157
+ 'layout',
158
+ 'digit',
159
+ 'lock',
160
+ ])
161
+ expect(callCapabilities.member?.deaf?.on).toEqual(true)
162
+ expect(callCapabilities.member?.deaf?.off).toEqual(true)
163
+ expect(callCapabilities.member?.raisehand?.on).toEqual(true)
164
+ expect(callCapabilities.member?.raisehand?.off).toEqual(true)
165
+ expect(callCapabilities.member?.muteVideo?.on).toEqual(true)
166
+ expect(callCapabilities.member?.muteVideo?.off).toEqual(true)
167
+ expect(callCapabilities.member?.muteAudio?.on).toEqual(true)
168
+ expect(callCapabilities.member?.muteAudio?.off).toEqual(true)
169
+ expect(callCapabilities.member?.meta).toEqual(true)
170
+ expect(callCapabilities.member?.position).toEqual(true)
171
+ expect(callCapabilities.member?.remove).toEqual(true)
172
+ expect(callCapabilities.member?.microphoneSensitivity).toEqual(true)
173
+ expect(callCapabilities.member?.microphoneVolume).toEqual(true)
174
+ expect(callCapabilities.member?.speakerVolume).toEqual(true)
175
+
176
+ expect(callCapabilities.self?.deaf?.on).toEqual(true)
177
+ expect(callCapabilities.self?.deaf?.off).toEqual(true)
178
+ expect(callCapabilities.self?.raisehand?.on).toEqual(true)
179
+ expect(callCapabilities.self?.raisehand?.off).toEqual(true)
180
+ expect(callCapabilities.self?.muteVideo?.on).toEqual(true)
181
+ expect(callCapabilities.self?.muteVideo?.off).toEqual(true)
182
+ expect(callCapabilities.self?.muteAudio?.on).toEqual(true)
183
+ expect(callCapabilities.self?.muteAudio?.off).toEqual(true)
184
+ expect(callCapabilities.self?.meta).toEqual(true)
185
+ expect(callCapabilities.self?.position).toEqual(true)
186
+ expect(callCapabilities.self?.remove).toEqual(true)
187
+ expect(callCapabilities.self?.microphoneSensitivity).toEqual(true)
188
+ expect(callCapabilities.self?.microphoneVolume).toEqual(true)
189
+ expect(callCapabilities.self?.speakerVolume).toEqual(true)
190
+
191
+ expect(callCapabilities.device).toEqual(true)
192
+ expect(callCapabilities.screenshare).toEqual(true)
193
+ expect(callCapabilities.sendDigit).toEqual(true)
194
+ expect(callCapabilities.setLayout).toEqual(true)
195
+ expect(callCapabilities.end).toEqual(true)
196
+ expect(callCapabilities.lock?.on).toEqual(true)
197
+ expect(callCapabilities.lock?.off).toEqual(true)
198
+ expect(callCapabilities.vmutedHide?.on).toEqual(true)
199
+ expect(callCapabilities.vmutedHide?.off).toEqual(true)
200
+ })
201
+ })
@@ -0,0 +1,190 @@
1
+ import { CallCapabilitiesContract, CapabilityOnOffStateContract, MemberCapabilityContract } from "../interfaces/capabilities"
2
+
3
+ class CapabilityOnOffState implements CapabilityOnOffStateContract {
4
+ constructor(private _flags: string[]) { }
5
+
6
+ get on() {
7
+ return this._flags.some((flag) => !flag.endsWith('.off'))
8
+ }
9
+
10
+ get off() {
11
+ return this._flags.some((flag) => !flag.endsWith('.on'))
12
+ }
13
+ }
14
+
15
+ class MemberCapability implements MemberCapabilityContract {
16
+ private _muteAudio?: CapabilityOnOffState
17
+ private _muteVideo?: CapabilityOnOffState
18
+ private _deaf?: CapabilityOnOffState
19
+
20
+ constructor(
21
+ private _flags: string[],
22
+ private _memberType: 'self' | 'member'
23
+ ) { }
24
+
25
+ get muteAudio() {
26
+ this._muteAudio =
27
+ this._muteAudio ??
28
+ new CapabilityOnOffState(
29
+ this._flags.filter(
30
+ (flag) => flag === this._memberType ||
31
+ flag === `${this._memberType}.mute` ||
32
+ flag.startsWith(`${this._memberType}.mute.audio`)
33
+ )
34
+ )
35
+ return this._muteAudio
36
+ }
37
+
38
+ get muteVideo() {
39
+ this._muteVideo =
40
+ this._muteVideo ??
41
+ new CapabilityOnOffState(
42
+ this._flags.filter(
43
+ (flag) => flag === this._memberType ||
44
+ flag === `${this._memberType}.mute` ||
45
+ flag.startsWith(`${this._memberType}.mute.video`)
46
+ )
47
+ )
48
+ return this._muteVideo
49
+ }
50
+
51
+ get microphoneVolume() {
52
+ return this._flags.some(
53
+ (flag) => flag === this._memberType ||
54
+ flag === `${this._memberType}.microphone` ||
55
+ flag.startsWith(`${this._memberType}.microphone.volume`)
56
+ )
57
+ }
58
+
59
+ get microphoneSensitivity() {
60
+ return this._flags.some(
61
+ (flag) => flag === this._memberType ||
62
+ flag === `${this._memberType}.microphone` ||
63
+ flag.startsWith(`${this._memberType}.microphone.sensitivity`)
64
+ )
65
+ }
66
+
67
+ get speakerVolume() {
68
+ return this._flags.some(
69
+ (flag) => flag === this._memberType ||
70
+ flag === `${this._memberType}.speaker` ||
71
+ flag.startsWith(`${this._memberType}.speaker.volume`)
72
+ )
73
+ }
74
+
75
+ get deaf() {
76
+ this._deaf =
77
+ this._deaf ??
78
+ new CapabilityOnOffState(
79
+ this._flags.filter(
80
+ (flag) => flag === this._memberType ||
81
+ flag.startsWith(`${this._memberType}.deaf`)
82
+ )
83
+ )
84
+ return this._deaf
85
+ }
86
+
87
+ get raisehand() {
88
+ return {
89
+ on: true,
90
+ off: true
91
+ }
92
+ // TODO: uncomment once the server add this capability
93
+ // this._raisehand =
94
+ // this._raisehand ??
95
+ // new CapabilityOnOffState(
96
+ // this._flags.filter(
97
+ // (flag) => flag === this._memberType ||
98
+ // flag.startsWith(`${this._memberType}.raisehand`)
99
+ // )
100
+ // )
101
+ // return this._raisehand
102
+ }
103
+
104
+ get position() {
105
+ return this._flags.some(
106
+ (flag) => flag === this._memberType ||
107
+ flag.startsWith(`${this._memberType}.position`)
108
+ )
109
+ }
110
+
111
+ get meta() {
112
+ return this._flags.some(
113
+ (flag) => flag === this._memberType || flag.startsWith(`${this._memberType}.meta`)
114
+ )
115
+ }
116
+
117
+ get remove() {
118
+ return this._flags.some(
119
+ (flag) => flag === this._memberType ||
120
+ flag.startsWith(`${this._memberType}.remove`)
121
+ )
122
+ }
123
+ }
124
+
125
+ export class CallCapabilities implements CallCapabilitiesContract {
126
+ private _self?: MemberCapabilityContract
127
+ private _member?: MemberCapabilityContract
128
+ private _vmutedHide?: CapabilityOnOffState
129
+ private _lock?: CapabilityOnOffState
130
+
131
+ constructor(private _flags: string[]) { }
132
+
133
+ private _buildMemberCapability(memberType: 'self' | 'member') {
134
+ return new MemberCapability(
135
+ this._flags.filter((flag) => flag.startsWith(memberType)),
136
+ memberType
137
+ )
138
+ }
139
+
140
+ get self() {
141
+ this._self = this._self ?? this._buildMemberCapability('self')
142
+ return this._self
143
+ }
144
+
145
+ get member() {
146
+ this._member = this._member ?? this._buildMemberCapability('member')
147
+ return this._member
148
+ }
149
+
150
+ get end() {
151
+ return this._flags.some((capability) => capability === 'end')
152
+ }
153
+
154
+ get setLayout() {
155
+ return this._flags.some((capability) => capability.startsWith('layout'))
156
+ }
157
+
158
+ get sendDigit() {
159
+ return this._flags.some((capability) => capability.startsWith('digit'))
160
+ }
161
+
162
+ get vmutedHide() {
163
+ this._vmutedHide =
164
+ this._vmutedHide ??
165
+ new CapabilityOnOffState(
166
+ this._flags.filter((flag) => flag.startsWith('vmuted'))
167
+ )
168
+ return this._vmutedHide
169
+ }
170
+
171
+ get lock() {
172
+ this._lock =
173
+ this._lock ??
174
+ new CapabilityOnOffState(
175
+ this._flags.filter((flag) => flag.startsWith('lock'))
176
+ )
177
+ return this._lock
178
+ }
179
+
180
+ get device() {
181
+ return this._flags.some((capability) => capability === 'device')
182
+ }
183
+
184
+ get screenshare() {
185
+ return this._flags.some((capability) => capability === 'screenshare')
186
+ }
187
+ }
188
+
189
+ export const mapCapabilityPayload = (capabilities: string[]) =>
190
+ new CallCapabilities(capabilities)
@@ -4,7 +4,6 @@ import {
4
4
  CallJoinedEvent,
5
5
  sagaEffects,
6
6
  MemberPosition,
7
- mapCapabilityPayload,
8
7
  stripNamespacePrefix,
9
8
  } from '@signalwire/core'
10
9
  import {
@@ -14,6 +13,7 @@ import {
14
13
  import { FabricWorkerParams } from './fabricWorker'
15
14
  import { fabricMemberWorker } from './fabricMemberWorker'
16
15
  import { mapCallJoinedToRoomSubscribedEventParams } from '../utils/helpers'
16
+ import { mapCapabilityPayload } from '../utils/capabilitiesHelpers'
17
17
 
18
18
  export const callJoinWorker = function* (
19
19
  options: FabricWorkerParams<CallJoinedEvent>
@@ -74,14 +74,15 @@ export const callJoinWorker = function* (
74
74
  })
75
75
 
76
76
  cfRoomSession.member = get<FabricRoomSessionMember>(payload.member_id)
77
- cfRoomSession.capabilities = mapCapabilityPayload(payload.capabilities || [])
77
+ // the server send the capabilities payload as an array of string
78
+ cfRoomSession.capabilities = mapCapabilityPayload(payload.capabilities)
78
79
 
79
- // FIXME: Capabilities type is incompatible.
80
- // @ts-expect-error
81
- cfRoomSession.emit('call.joined', {
80
+ const fabricEvent = {
82
81
  ...payload,
83
82
  capabilities: cfRoomSession.capabilities,
84
- })
83
+ }
84
+
85
+ cfRoomSession.emit('call.joined', fabricEvent)
85
86
 
86
87
  getLogger().trace('callJoinWorker ended')
87
88
  }
@@ -21,23 +21,46 @@ export type WSClientWorkerHooks = SDKWorkerHooks<
21
21
  export const wsClientWorker: SDKWorker<WSClient, WSClientWorkerHooks> =
22
22
  function* (options): SagaIterator {
23
23
  getLogger().debug('wsClientWorker started')
24
- const { channels, initialState } = options
24
+ const { channels, initialState, instance: client } = options
25
25
  const { swEventChannel } = channels
26
26
  const { handleIncomingInvite } = initialState
27
27
 
28
+ function* fireHoseWorker(action: SDKActions) {
29
+ // @ts-expect-error Emit all events - This is for internal usage
30
+ client.emit(action.type, action.payload)
31
+ }
32
+
33
+ function* vertoInviteWorker(action: MapToPubSubShape<WebRTCMessageParams>) {
34
+ // Invoke WSClient function to build and answer the invite
35
+ handleIncomingInvite(action.payload.params)
36
+ }
37
+
38
+ const isVertoInvite = (action: SDKActions) => {
39
+ if (action.type === 'webrtc.message') {
40
+ return action.payload.method === 'verto.invite'
41
+ }
42
+ return false
43
+ }
44
+
28
45
  try {
29
46
  while (true) {
30
- const action: MapToPubSubShape<WebRTCMessageParams> =
31
- yield sagaEffects.take(swEventChannel, (action: SDKActions) => {
32
- if (action.type === 'webrtc.message') {
33
- return action.payload.method === 'verto.invite'
34
- }
35
- return false
36
- })
37
- getLogger().debug('Receiving a new call over WebSocket', action)
38
-
39
- // Invoke WSClient function to build and answer the invite
40
- handleIncomingInvite(action.payload.params)
47
+ // Take all actions from the channel
48
+ const action: SDKActions = yield sagaEffects.take(
49
+ swEventChannel,
50
+ () => true
51
+ )
52
+
53
+ // Fire all the events with fireHoseWorker
54
+ yield sagaEffects.fork(fireHoseWorker, action)
55
+
56
+ // If the event is verto.invite, handle that with vertoInviteWorker
57
+ if (isVertoInvite(action)) {
58
+ getLogger().debug('Receiving a call over WebSocket', action)
59
+ yield sagaEffects.fork(
60
+ vertoInviteWorker,
61
+ action as MapToPubSubShape<WebRTCMessageParams>
62
+ )
63
+ }
41
64
  }
42
65
  } finally {
43
66
  getLogger().trace('wsClientWorker ended')
package/src/index.ts CHANGED
@@ -108,7 +108,6 @@ export type {
108
108
  /**
109
109
  * Call Fabric types
110
110
  */
111
- CallJoinedEventParams,
112
111
  CallUpdatedEventParams,
113
112
  CallLeftEventParams,
114
113
  CallStateEventParams,
@@ -136,6 +135,7 @@ export type {
136
135
  } from '@signalwire/webrtc'
137
136
 
138
137
  export type {
138
+ CallJoinedEventParams,
139
139
  RoomSessionObjectEventsHandlerMap,
140
140
  RoomSessionObjectEvents,
141
141
  // Just to keep backwards compatibility.
@@ -14,7 +14,7 @@ import {
14
14
  VideoRoomDeviceDisconnectedEventNames,
15
15
  VideoRoomDeviceUpdatedEventNames,
16
16
  CallJoined,
17
- CallJoinedEventParams,
17
+ CallJoinedEventParams as InternalCallJoinedEventParams,
18
18
  CallState,
19
19
  CallStateEventParams,
20
20
  CallUpdated,
@@ -41,7 +41,7 @@ import {
41
41
  CallRoomEventParams,
42
42
  } from '@signalwire/core'
43
43
  import { MediaEventNames } from '@signalwire/webrtc'
44
- import { FabricRoomSession } from '../../fabric'
44
+ import { CallCapabilitiesContract, FabricRoomSession } from '../../fabric'
45
45
 
46
46
  export interface ExecuteActionParams {
47
47
  method: JSONRPCMethod
@@ -73,6 +73,10 @@ export type FabricMemberListUpdatedParams = {
73
73
  members: InternalFabricMemberEntity[]
74
74
  }
75
75
 
76
+ export type CallJoinedEventParams = {
77
+ capabilities: CallCapabilitiesContract
78
+ } & Omit<InternalCallJoinedEventParams, 'capabilities'>
79
+
76
80
  export type FabricRoomSessionEventsHandlerMap = Record<
77
81
  VideoRoomDeviceUpdatedEventNames,
78
82
  (params: DeviceUpdatedEventParams) => void
@@ -91,7 +95,10 @@ export type FabricRoomSessionEventsHandlerMap = Record<
91
95
  Record<CallPlay, (stream: CallPlayEventParams) => void> &
92
96
  Record<CallConnect, (stream: CallConnectEventParams) => void> &
93
97
  Record<CallRoom, (stream: CallRoomEventParams) => void> &
94
- Record<RoomJoined | RoomSubscribed, (params: CallJoinedEventParams) => void> &
98
+ Record<
99
+ RoomJoined | RoomSubscribed,
100
+ (params: InternalCallJoinedEventParams) => void
101
+ > &
95
102
  Record<RoomUpdated, (params: CallUpdatedEventParams) => void> &
96
103
  Record<RoomLeft, (params?: CallLeftEventParams) => void> &
97
104
  Record<MemberJoined, (params: FabricMemberJoinedEventParams) => void> &
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=eventUtils.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"eventUtils.test.d.ts","sourceRoot":"","sources":["../../../../../core/src/utils/eventUtils.test.ts"],"names":[],"mappings":""}